Commit 8adb1fdf authored by Laszlo Domoszlai's avatar Laszlo Domoszlai
Browse files

handle lazy "updates" -> old tonic example works again

parent d39898aa
......@@ -135,6 +135,12 @@ void create_thunk_select(Code* expr, Thunk** target, int frame_ptr)
*target = thunk;
}
void create_thunk_update(Code* expr, Thunk** target, int frame_ptr)
{
// it is always lifted to a function when at lazy position
assert(false);
}
void set_create_thunk_fun(Code* code)
{
switch(code->type)
......@@ -165,7 +171,8 @@ void set_create_thunk_fun(Code* code)
code->create_thunk = create_thunk_select;
break;
case CT_UPDATE:
// it is always lifted to a function when at lazy position
code->create_thunk = create_thunk_update;
break;
case CT_CASE_ADT:
case CT_CASE_LIT:
case CT_CASE_STR:
......@@ -430,9 +437,22 @@ void exec(Code* expr, int frame_ptr, int root_frame_ptr)
thunk->desc = slice;
assert(thunk->desc->arity == expr->nr_args);
int argmask = 1;
for (int i = 0; i < expr->nr_args; i++) {
((AppEntry*) expr)->args[i]->create_thunk(((AppEntry*) expr)->args[i], &thunk->_args[i], frame_ptr);
for (int i = 0; i < expr->nr_args; i++) {
// HACK: It also can be a RecordEntry. It works because the strictness field is at the same position, but it is very dirty
if(((ADTEntry*) (slice))->strictness & argmask)
{
push_a(NULL);
exec(((AppEntry*) expr)->args[i], frame_ptr, stack_top_a);
thunk->_args[i] = pop_a();
}
else
{
((AppEntry*) expr)->args[i]->create_thunk(((AppEntry*) expr)->args[i], &thunk->_args[i], frame_ptr);
}
argmask <<= 1;
}
destroy_stack_frame(root_frame_ptr);
......
definition module Lifting
import Sapl.SaplStruct
import Data.Map
// Returns True if a term can be inlined, i.e. no separate statement is needed
inline :: !SaplTerm -> Bool
prepareFun :: !FuncType -> FuncType
prepareExpr :: !SaplTerm -> SaplTerm
prepareFun :: (String Int Int -> Bool) !FuncType (Map String FuncType) -> (FuncType, Map String FuncType)
prepareExpr :: (String Int Int -> Bool) !SaplTerm (Map String FuncType) -> (SaplTerm, Map String FuncType)
......@@ -2,6 +2,7 @@ implementation module Lifting
import StdEnv
import Sapl.SaplStruct
import Data.Map
inline :: !SaplTerm -> Bool
inline (SLet _ _) = False
......@@ -10,73 +11,119 @@ inline (SCase cond [(PLit (LBool False), case1),(PLit (LBool True), case2)]) = i
inline (SCase _ _) = False
inline _ = True
prepareFun :: !FuncType -> FuncType
prepareFun (FTFunc name body args) = FTFunc name (prepareExpr body) args
prepareFun (FTCAF name body) = FTCAF name (prepareExpr body)
prepareFun ftype = ftype
prepareFun :: (String Int Int -> Bool) !FuncType (Map String FuncType) -> (FuncType, Map String FuncType)
prepareFun sf (FTFunc name body args) genfuns
# (body, genfuns) = prepareExpr sf body genfuns
= (FTFunc name body args,genfuns)
prepareFun sf (FTCAF name body) genfuns
# (body, genfuns) = prepareExpr sf body genfuns
= (FTCAF name body, genfuns)
prepareFun _ ftype genfuns = (ftype, genfuns)
:: LiftingState = {varidx :: Int}
:: LiftingState = {varidx :: Int, genfuns :: Map String FuncType}
prepareExpr :: !SaplTerm -> SaplTerm
prepareExpr t
# (t, st, defs) = walkTerm t {varidx = 1}
= case defs of
[] = t
defs = SLet t defs
walkTerm :: !SaplTerm !LiftingState -> (!SaplTerm, !LiftingState, ![SaplLetDef])
walkTerm c=:(SCase cond patterns) st
# (cond, st, defs) = walkTerm cond st
# (patterns, st) = walkPatterns patterns st
genUpdateFun :: SaplTerm -> FuncType
genUpdateFun (SUpdate _ ty updates)
= FTFunc (TypedVar (NormalVar funName 0) NoType)
(SUpdate (SVar (NormalVar "e" 0)) ty
[(idx, SVar (NormalVar ("a" +++ toString i) 0)) \\ i <- [1..length updates] & idx <- map fst updates])
[TypedVar (NormalVar "e" 0) NoType:[TypedVar (NormalVar ("a" +++ toString i) 0) NoType \\ i <- [1..length updates]]]
where
funName = case ty of
NoType = "update$" +++ toString (mask updates 0)
(Type tn) = "update$" +++ tn +++ "_" +++ toString (mask updates 0)
mask [] bits = bits
mask [(idx,_):us] bits = mask us ((1 << idx) bitor bits)
prepareExpr :: (String Int Int -> Bool) !SaplTerm (Map String FuncType) -> (SaplTerm, Map String FuncType)
prepareExpr sf t genfuns
# (t, st, defs) = walkTerm t True {varidx = 1, genfuns = genfuns}
= case defs of
[] = (SCase cond patterns, st, [])
defs = (SCase (SLet cond defs) patterns, st, [])
walkTerm (SLet expr bindings) st
# (expr, st, edefs) = walkTerm expr st
# (bindings, st, bdefs) = walkBindings bindings st
# defs = edefs ++ bdefs
= case defs of
[] = (SLet expr bindings, st, [])
// New defs can be added to the end, they will be ordered later on
defs = (SLet expr (bindings ++ defs), st, [])
walkTerm (SSelect expr ty idx) st
# (expr, st, defs) = walkTerm expr st
= (SSelect expr ty idx, st, defs)
walkTerm (SApplication sel=:(SSelect sexpr _ _) args) st
# (letvar, st) = genVar st
# selvar = SVar (removeTypeInfo letvar)
# (args, st, defs) = walkArgs args st
= (SApplication selvar args, st, [SaplLetDef letvar sel:defs])
[] = (t, st.genfuns)
defs = (SLet t defs, st.genfuns)
where
genVar {varidx} = (TypedVar (StrictVar ("$g"+++toString varidx) 0) NoType, {varidx = varidx + 1})
walkTerm :: !SaplTerm !Bool !LiftingState -> (!SaplTerm, !LiftingState, ![SaplLetDef])
walkTerm c=:(SCase cond patterns) _ st
# (cond, st, defs) = walkTerm cond True st
# (patterns, st) = walkPatterns patterns st
= case defs of
[] = (SCase cond patterns, st, [])
defs = (SCase (SLet cond defs) patterns, st, [])
walkTerm (SLet expr bindings) _ st
# (expr, st, edefs) = walkTerm expr True st
# (bindings, st, bdefs) = walkBindings bindings st
# defs = edefs ++ bdefs
= case defs of
[] = (SLet expr bindings, st, [])
// New defs can be added to the end, they will be ordered later on
defs = (SLet expr (bindings ++ defs), st, [])
walkTerm (SSelect expr ty idx) strictPosition st
# (expr, st, defs) = walkTerm expr strictPosition st
= (SSelect expr ty idx, st, defs)
walkTerm (SApplication name args) st
# (args, st, defs) = walkArgs args st
= (SApplication name args, st, defs)
walkTerm (SUpdate expr ty updates) False st
# (expr, st, edefs) = walkTerm expr False st
# (updates, st, udefs) = walkUpdates updates st
// Generate new fun and lift it in the same time
# (genfun, _) = prepareFun sf (genUpdateFun (SUpdate expr ty updates)) newMap
# funname = extractName genfun
= (SApplication (SVar funname) [expr:map snd updates],
{st & genfuns = put (unpackVar funname) genfun st.genfuns}, edefs ++ udefs)
where
extractName (FTFunc (TypedVar name _) _ _) = name
walkTerm t st = (t, st, [])
walkTerm (SUpdate expr ty updates) True st
# (expr, st, edefs) = walkTerm expr True st
# (updates, st, udefs) = walkUpdates updates st
= (SUpdate expr ty updates, st, edefs ++ udefs)
walkArgs [] st = ([], st, [])
walkArgs [t:ts] st
# (t, st, def) = walkTerm t st
# (ts, st, defs) = walkArgs ts st
= ([t:ts], st, def ++ defs)
// We always lift this select as strict, does not matter, it is free
// Arguments are treated as lazy, because we do not know anything about the actual functions
walkTerm (SApplication sel=:(SSelect sexpr _ _) args) _ st
# (letvar, st) = genVar st
# selvar = SVar (removeTypeInfo letvar)
# (args, st, defs) = walkArgs (repeat False) args st
= (SApplication selvar args, st, [SaplLetDef letvar sel:defs])
where
genVar {varidx} = (TypedVar (StrictVar ("$g"+++toString varidx) 0) NoType, {st & varidx = varidx + 1})
walkTerm (SApplication var=:(SVar name) args) True st
# (args, st, defs) = walkArgs [sf (unpackVar name) (length args) i \\ i <- [0..]] args st
= (SApplication var args, st, defs)
walkTerm (SApplication name args) False st
# (args, st, defs) = walkArgs (repeat False) args st
= (SApplication name args, st, defs)
walkTerm t _ st = (t, st, [])
walkArgs _ [] st = ([], st, [])
walkArgs [isStrict:si] [t:ts] st
# (t, st, def) = walkTerm t isStrict st
# (ts, st, defs) = walkArgs si ts st
= ([t:ts], st, def ++ defs)
walkPatterns [] st = ([], st)
walkPatterns [(p, t):ps] st
# (t, st, defs) = walkTerm t st
# t = case defs of
[] = t
defs = SLet t defs
# (ps, st) = walkPatterns ps st
= ([(p,t):ps], st)
walkBindings [] st = ([], st, [])
walkBindings [SaplLetDef var expr:bs] st
# (expr, st, def) = walkTerm expr st
# (bs, st, defs) = walkBindings bs st
= ([SaplLetDef var expr:bs], st, def ++ defs)
walkPatterns [] st = ([], st)
walkPatterns [(p, t):ps] st
# (t, st, defs) = walkTerm t True st
# t = case defs of
[] = t
defs = SLet t defs
# (ps, st) = walkPatterns ps st
= ([(p,t):ps], st)
walkBindings [] st = ([], st, [])
walkBindings [SaplLetDef var expr:bs] st
# (expr, st, def) = walkTerm expr (isStrictVar var) st
# (bs, st, defs) = walkBindings bs st
= ([SaplLetDef var expr:bs], st, def ++ defs)
walkUpdates [] st = ([], st, [])
walkUpdates [(idx,expr):us] st
# (expr, st, def) = walkTerm expr False st // TODO: check record type
# (us, st, defs) = walkUpdates us st
= ([(idx, expr):us], st, def ++ defs)
......@@ -207,8 +207,15 @@ Start world
// strictness propagation
# (fs, ps) = if no_strictness_prop (fs, ps) (doStrictnessPropagation ps isStrictArg fs)
// lifting
# fs = map prepareFun fs
# (fs, genfuns) = foldl (upd (isStrictArg ps)) ([], newMap) fs
# fs = reverse fs ++ elems genfuns
# (_, world) = writeFile (args!!(2+extra)) (toString (genDefs fs newAppender)) world
= world
\ No newline at end of file
where
upd :: (String Int Int -> Bool) ([FuncType], Map String FuncType) FuncType -> ([FuncType], Map String FuncType)
upd sf (nfs, genfuns) fun
= let (nfun, ngenfuns) = prepareFun sf fun genfuns in ([nfun:nfs], union genfuns ngenfuns)
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
["{"tf_comments":"","tf_module":"DynamicBPs","tf_name":"stepTest","tf_iclLineNo":99,"tf_resty":["TFApp",[],"Task",[["TPPExpr","Int"]],["TNoPrio"]],"tf_args":[[["TVar",[],"n",48169600],["TPPExpr","Int"]]],"tf_body":["TMApp",[0],["Just","Task"],"iTasks.API.Common.TaskCombinators",">>*",[["TMApp",[0,0],["Just","Task"],"iTasks.API.Common.InteractionTasks","updateInformation",[["TLit",["TString","\"step test\""]],["TFApp",[0,0,1],"_Nil",[],["TNoPrio"]],["TVar",[],"n",48169600]],["TNoPrio"],["Nothing"]],["TFApp",[0,1],"_Cons",[["TFApp",[0,1,0],"OnAction",[["TFApp",[0,1,0,0],"Action",[["TLit",["TString","\"Yes\""]],["TFApp",[0,1,0,0,1],"_Cons",[["TFApp",[0,1,0,0,1,0],"ActionIcon",[["TLit",["TString","\"yes\""]]],["TNoPrio"]],["TFApp",[0,1,0,0,1,1],"_Nil",[],["TNoPrio"]]],["TNoPrio"]]],["TNoPrio"]],["TMApp",[0,1,0,1],["Just","Maybe"],"iTasks.API.Common.TaskCombinators","always",[["TMApp",[0,1,0,1,0],["Just","Task"],"DynamicBPs","stepTest",[["TVar",[],"n",48169600]],["TNoPrio"],["Nothing"]]],["TNoPrio"],["Nothing"]]],["TNoPrio"]],["TFApp",[0,1,1],"_Cons",[["TFApp",[0,1,1,0],"OnAction",[["TFApp",[0,1,1,0,0],"Action",[["TLit",["TString","\"No\""]],["TFApp",[0,1,1,0,0,1],"_Cons",[["TFApp",[0,1,1,0,0,1,0],"ActionIcon",[["TLit",["TString","\"no\""]]],["TNoPrio"]],["TFApp",[0,1,1,0,0,1,1],"_Nil",[],["TNoPrio"]]],["TNoPrio"]]],["TNoPrio"]],["TMApp",[0,1,1,0,1],["Just","Maybe"],"iTasks.API.Common.TaskCombinators","always",[["TMApp",[0,1,1,0,1,0],["Just","Task"],"DynamicBPs","stepTest",[["TVar",[],"n",48169600]],["TNoPrio"],["Nothing"]]],["TNoPrio"],["Nothing"]]],["TNoPrio"]],["TFApp",[0,1,1,1],"_Cons",[["TFApp",[0,1,1,1,0],"OnAction",[["TFApp",[0,1,1,1,0,0],"Action",[["TLit",["TString","\"Pos\""]],["TFApp",[0,1,1,1,0,0,1],"_Nil",[],["TNoPrio"]]],["TNoPrio"]],["TMApp",[0,1,1,1,0,1],["Just","Maybe"],"iTasks.API.Common.TaskCombinators","ifValue",[["TFApp",[0,1,1,1,0,1,0],"<=",[["TLit",["TInt",0]]],["TPrio",["TNoAssoc"],4]],["TMApp",[0,1,1,1,0,1,1],["Just","Task"],"DynamicBPs","stepTest",[],["TNoPrio"],["Nothing"]]],["TNoPrio"],["Nothing"]]],["TNoPrio"]],["TFApp",[0,1,1,1,1],"_Cons",[["TFApp",[0,1,1,1,1,0],"OnAction",[["TFApp",[0,1,1,1,1,0,0],"Action",[["TLit",["TString","\"Neg\""]],["TFApp",[0,1,1,1,1,0,0,1],"_Nil",[],["TNoPrio"]]],["TNoPrio"]],["TMApp",[0,1,1,1,1,0,1],["Just","Maybe"],"iTasks.API.Common.TaskCombinators","ifValue",[["TFApp",[0,1,1,1,1,0,1,0],">=",[["TLit",["TInt",0]]],["TPrio",["TNoAssoc"],4]],["TLam",[["TVar",[],"n",48177696]],["TMApp",[0,1,1,1,1,0,1,1],["Just","Task"],"DynamicBPs","stepTest",[["TVar",[],"n",48177696]],["TNoPrio"],["Nothing"]]]],["TNoPrio"],["Nothing"]]],["TNoPrio"]],["TFApp",[0,1,1,1,1,1],"_Cons",[["TFApp",[0,1,1,1,1,1,0],"OnAction",[["TFApp",[0,1,1,1,1,1,0,0],"Action",[["TLit",["TString","\"Stable\""]],["TFApp",[0,1,1,1,1,1,0,0,1],"_Nil",[],["TNoPrio"]]],["TNoPrio"]],["TMApp",[0,1,1,1,1,1,0,1],["Just","Maybe"],"iTasks.API.Common.TaskCombinators","ifStable",[["TMApp",[0,1,1,1,1,1,0,1,0],["Just","Task"],"DynamicBPs","stepTest",[],["TNoPrio"],["Nothing"]]],["TNoPrio"],["Nothing"]]],["TNoPrio"]],["TFApp",[0,1,1,1,1,1,1],"_Cons",[["TFApp",[0,1,1,1,1,1,1,0],"OnAction",[["TFApp",[0,1,1,1,1,1,1,0,0],"Action",[["TLit",["TString","\"Unstable\""]],["TFApp",[0,1,1,1,1,1,1,0,0,1],"_Nil",[],["TNoPrio"]]],["TNoPrio"]],["TMApp",[0,1,1,1,1,1,1,0,1],["Just","Maybe"],"iTasks.API.Common.TaskCombinators","ifUnstable",[["TMApp",[0,1,1,1,1,1,1,0,1,0],["Just","Task"],"DynamicBPs","stepTest",[],["TNoPrio"],["Nothing"]]],["TNoPrio"],["Nothing"]]],["TNoPrio"]],["TFApp",[0,1,1,1,1,1,1,1],"_Cons",[["TFApp",[0,1,1,1,1,1,1,1,0],"OnAction",[["TFApp",[0,1,1,1,1,1,1,1,0,0],"Action",[["TLit",["TString","\"Cond\""]],["TFApp",[0,1,1,1,1,1,1,1,0,0,1],"_Nil",[],["TNoPrio"]]],["TNoPrio"]],["TMApp",[0,1,1,1,1,1,1,1,0,1],["Just","Maybe"],"iTasks.API.Common.TaskCombinators","ifCond",[["TFApp",[0,1,1,1,1,1,1,1,0,1,0],"<",[["TLit",["TInt",10]],["TVar",[],"n",48169600]],["TPrio",["TNoAssoc"],4]],["TMApp",[0,1,1,1,1,1,1,1,0,1,1],["Nothing"],"iTasks.API.Core.Types","return",[["TVar",[],"n",48169600]],["TNoPrio"],["Nothing"]]],["TNoPrio"],["Nothing"]]],["TNoPrio"]],["TFApp",[0,1,1,1,1,1,1,1,1],"_Cons",[["TFApp",[0,1,1,1,1,1,1,1,1,0],"OnValue",[["TMApp",[0,1,1,1,1,1,1,1,1,0,0],["Just","Maybe"],"iTasks.API.Common.TaskCombinators","ifCond",[["TFApp",[0,1,1,1,1,1,1,1,1,0,0,0],"<",[["TLit",["TInt",1000]],["TVar",[],"n",48169600]],["TPrio",["TNoAssoc"],4]],["TMApp",[0,1,1,1,1,1,1,1,1,0,0,1],["Nothing"],"iTasks.API.Core.Types","return",[["TVar",[],"n",48169600]],["TNoPrio"],["Nothing"]]],["TNoPrio"],["Nothing"]]],["TNoPrio"]],["TFApp",[0,1,1,1,1,1,1,1,1,1],"_Cons",[["TFApp",[0,1,1,1,1,1,1,1,1,1,0],"OnException",[["TLam",[["TVar",[],"n",48171456]],["TMApp",[0,1,1,1,1,1,1,1,1,1,0,0],["Nothing"],"iTasks.API.Core.Types","return",[["TVar",[],"n",48171456]],["TNoPrio"],["Nothing"]]]],["TNoPrio"]],["TFApp",[0,1,1,1,1,1,1,1,1,1,1],"_Nil",[],["TNoPrio"]]],["TNoPrio"]]],["TNoPrio"]]],["TNoPrio"]]],["TNoPrio"]]],["TNoPrio"]]],["TNoPrio"]]],["TNoPrio"]]],["TNoPrio"]]],["TNoPrio"]]],["TPrio",["TLeftAssoc"],1],["Nothing"]]}"]
\ No newline at end of file
This diff is collapsed.
[Data.Map.Bin [3] [Graphics.Scalable.Internal._FontDef ["Arial"] [10] ["normal"] ["normal"] ["normal"] ["bold"]] [Data.Map.Bin [14] [" "Yes""] [60] [Data.Map.Bin [6] [" "No""] [50] [Data.Map.Bin [2] [" "Neg""] [60] [Data.Map.Bin [1] [" "Cond""] [70] [Data.Map.Tip] [Data.Map.Tip]] [Data.Map.Tip]] [Data.Map.Bin [3] [" "Stable""] [90] [Data.Map.Bin [1] [" "Pos""] [60] [Data.Map.Tip] [Data.Map.Tip]] [Data.Map.Bin [1] [" "Unstable""] [110] [Data.Map.Tip] [Data.Map.Tip]]]] [Data.Map.Bin [7] ["return"] [60] [Data.Map.Bin [3] [" Stable"] [70] [Data.Map.Bin [1] [" Exception"] [100] [Data.Map.Tip] [Data.Map.Tip]] [Data.Map.Bin [1] [" Unstable"] [90] [Data.Map.Tip] [Data.Map.Tip]]] [Data.Map.Bin [3] ["stepTest :: Task Int"] [200] [Data.Map.Bin [1] ["stepTest"] [80] [Data.Map.Tip] [Data.Map.Tip]] [Data.Map.Bin [1] ["updateInformation"] [170] [Data.Map.Tip] [Data.Map.Tip]]]]] [Data.Map.Bin [1] [Graphics.Scalable.Internal._FontDef ["Arial"] [6] ["normal"] ["normal"] ["normal"] ["bold"]] [Data.Map.Bin [3] ["S"] [6] [Data.Map.Bin [1] ["E"] [6] [Data.Map.Tip] [Data.Map.Tip]] [Data.Map.Bin [1] ["U"] [6] [Data.Map.Tip] [Data.Map.Tip]]] [Data.Map.Tip] [Data.Map.Tip]] [Data.Map.Bin [1] [Graphics.Scalable.Internal._FontDef ["Arial"] [10] ["normal"] ["normal"] ["normal"] ["normal"]] [Data.Map.Bin [20] ["1000 < n"] [80] [Data.Map.Bin [12] [" "] [10] [Data.Map.Bin [8] [""] [0] [Data.Map.Bin [4] [""] [0] [Data.Map.Bin [2] [""] [0] [Data.Map.Bin [1] [""] [0] [Data.Map.Tip] [Data.Map.Tip]] [Data.Map.Tip]] [Data.Map.Bin [1] [""] [0] [Data.Map.Tip] [Data.Map.Tip]]] [Data.Map.Bin [3] [""] [0] [Data.Map.Bin [1] [""] [0] [Data.Map.Tip] [Data.Map.Tip]] [Data.Map.Bin [1] [""] [0] [Data.Map.Tip] [Data.Map.Tip]]]] [Data.Map.Bin [3] [""step test""] [110] [Data.Map.Bin [1] [" :: "] [40] [Data.Map.Tip] [Data.Map.Tip]] [Data.Map.Bin [1] ["10 < n"] [60] [Data.Map.Tip] [Data.Map.Tip]]]] [Data.Map.Bin [7] ["Int"] [30] [Data.Map.Bin [3] [">= 0"] [40] [Data.Map.Bin [1] ["<= 0"] [40] [Data.Map.Tip] [Data.Map.Tip]] [Data.Map.Bin [1] ["DynamicBPs."] [110] [Data.Map.Tip] [Data.Map.Tip]]] [Data.Map.Bin [3] ["n"] [10] [Data.Map.Bin [1] ["[]"] [20] [Data.Map.Tip] [Data.Map.Tip]] [Data.Map.Bin [1] ["n "] [20] [Data.Map.Tip] [Data.Map.Tip]]]]] [Data.Map.Tip] [Data.Map.Tip]]]
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
[record._R [2] [2] [2]]
\ No newline at end of file
[record._R [2] [3] [2]]
\ No newline at end of file
main = record.Start
record.Start = record.f 1 (update (record.r 1)::record._R [1:2,2:2])
:: record._R = {record.a::I, record.b::I, record.c::I}
record.r i_0::I = record._R (addI 1 i_0) (addI 2 i_0) (addI 3 i_0)
record.f !_x_0::I t_1 = case _x_0 (1 -> update t_1::record._R [1:3]) (2 -> record.r 1)
[record._R [2] [3] [2]]
\ No newline at end of file
main = record.Start
record.Start = record.f record.g
record.g = <{_Tuple2!3}> 1 (update (record.r 1)::record._R [1:2,2:2])
:: record._R = {record.a::I, record.b::I, record.c::I}
record.r i_0::I = record._R (addI 1 i_0) (addI 2 i_0) (addI 3 i_0)
record.f !_x_0 = case _x_0 (_Tuple2 _x_1_0 t_1_1 -> case _x_1_0 (1 -> update t_1_1::record._R [1:3]) (2 -> update t_1_1::record._R [1:4]) )
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment