summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristopher Pulte2015-11-22 18:27:27 +0000
committerChristopher Pulte2015-11-22 18:27:27 +0000
commit10321a2cf266b57dfa5ebe3606d24ac3d6bc7d74 (patch)
tree671f8b1332bf4935a34cec314d9aeeb0afa1105a /src
parent0c876cfde45de90b5cd0a5ef7c638d900eef6488 (diff)
do effect annotation updates more systematically, fix dedup
Diffstat (limited to 'src')
-rw-r--r--src/rewriter.ml551
1 files changed, 286 insertions, 265 deletions
diff --git a/src/rewriter.ml b/src/rewriter.ml
index 1761bcc5..288410e0 100644
--- a/src/rewriter.ml
+++ b/src/rewriter.ml
@@ -27,18 +27,116 @@ let fresh_name () =
let reset_fresh_name_counter () =
fresh_name_counter := 0
-let geteffs_annot (_,t) = match t with
+let get_effsum_annot (_,t) = match t with
| Base (_,_,_,_,effs,_) -> effs
| NoTyp -> failwith "no effect information"
| _ -> failwith "a_normalise doesn't support Overload"
-let gettype_annot (_,t) = match t with
+let get_type_annot (_,t) = match t with
| Base((_,t),_,_,_,_,_) -> t
| NoTyp -> failwith "no type information"
| _ -> failwith "a_normalise doesn't support Overload"
-let gettype (E_aux (_,a)) = gettype_annot a
-let geteffs (E_aux (_,a)) = geteffs_annot a
+let get_type (E_aux (_,a)) = get_type_annot a
+
+let get_effsum_exp (E_aux (_,a)) = get_effsum_annot a
+let get_effsum_fpat (FP_aux (_,a)) = get_effsum_annot a
+let get_effsum_lexp (LEXP_aux (_,a)) = get_effsum_annot a
+let get_effsum_fexp (FE_aux (_,a)) = get_effsum_annot a
+let get_effsum_fexps (FES_aux (_,a)) = get_effsum_annot a
+let get_effsum_opt_default (Def_val_aux (_,a)) = get_effsum_annot a
+let get_effsum_pexp (Pat_aux (_,a)) = get_effsum_annot a
+let get_effsum_lb (LB_aux (_,a)) = get_effsum_annot a
+
+let union_effs effs =
+ List.fold_left (fun acc eff -> union_effects acc eff) pure_e effs
+
+let eff_union_exps es =
+ union_effs (List.map get_effsum_exp es)
+
+let fix_effsum_exp (E_aux (e,(l,annot))) =
+ let (Base (t,tag,nexps,eff,_,bounds)) = annot in
+ let effsum = match e with
+ | E_block es -> eff_union_exps es
+ | E_nondet es -> eff_union_exps es
+ | E_id _
+ | E_lit _ -> pure_e
+ | E_cast (_,e) -> get_effsum_exp e
+ | E_app (_,es)
+ | E_tuple es -> eff_union_exps es
+ | E_app_infix (e1,_,e2) -> eff_union_exps [e1;e2]
+ | E_if (e1,e2,e3) -> eff_union_exps [e1;e2;e3]
+ | E_for (_,e1,e2,e3,_,e4) -> eff_union_exps [e1;e2;e3;e4]
+ | E_vector es -> eff_union_exps es
+ | E_vector_indexed (ies,opt_default) ->
+ let (_,es) = List.split ies in
+ union_effs (get_effsum_opt_default opt_default :: List.map get_effsum_exp es)
+ | E_vector_access (e1,e2) -> eff_union_exps [e1;e2]
+ | E_vector_subrange (e1,e2,e3) -> eff_union_exps [e1;e2;e3]
+ | E_vector_update (e1,e2,e3) -> eff_union_exps [e1;e2;e3]
+ | E_vector_update_subrange (e1,e2,e3,e4) -> eff_union_exps [e1;e2;e3;e4]
+ | E_vector_append (e1,e2) -> eff_union_exps [e1;e2]
+ | E_list es -> eff_union_exps es
+ | E_cons (e1,e2) -> eff_union_exps [e1;e2]
+ | E_record fexps -> get_effsum_fexps fexps
+ | E_field (e,_) -> get_effsum_exp e
+ | E_case (e,pexps) -> union_effs (get_effsum_exp e :: List.map get_effsum_pexp pexps)
+ | E_let (lb,e) -> union_effs [get_effsum_lb lb;get_effsum_exp e]
+ | E_assign (lexp,e) -> union_effs [get_effsum_lexp lexp;get_effsum_exp e]
+ | E_exit e -> get_effsum_exp e
+ | E_internal_cast (_,e) -> get_effsum_exp e
+ | E_internal_exp _ -> pure_e
+ | E_internal_exp_user _ -> pure_e
+ | E_internal_let (lexp,e1,e2) -> union_effs [get_effsum_lexp lexp;
+ get_effsum_exp e1;get_effsum_exp e2]
+ | E_internal_plet (_,e1,e2) -> union_effs [get_effsum_exp e1;get_effsum_exp e2]
+ | E_internal_return e1 -> get_effsum_exp e1
+ in
+ E_aux (e,(l,(Base (t,tag,nexps,eff,union_effects eff effsum,bounds))))
+
+let fix_effsum_lexp (LEXP_aux (lexp,(l,annot))) =
+ let (Base (t,tag,nexps,eff,_,bounds)) = annot in
+ let effsum = match lexp with
+ | LEXP_id _ -> pure_e
+ | LEXP_cast _ -> pure_e
+ | LEXP_memory (_,es) -> eff_union_exps es
+ | LEXP_vector (lexp,e) -> union_effs [get_effsum_lexp lexp;get_effsum_exp e]
+ | LEXP_vector_range (lexp,e1,e2) -> union_effs [get_effsum_lexp lexp;get_effsum_exp e1;
+ get_effsum_exp e2]
+ | LEXP_field (lexp,_) -> get_effsum_lexp lexp in
+ LEXP_aux (lexp,(l,(Base (t,tag,nexps,eff,union_effects eff effsum,bounds))))
+
+let fix_effsum_fexp (FE_aux (fexp,(l,annot))) =
+ let (Base (t,tag,nexps,eff,_,bounds)) = annot in
+ let effsum = match fexp with
+ | FE_Fexp (_,e) -> get_effsum_exp e in
+ FE_aux (fexp,(l,(Base (t,tag,nexps,eff,union_effects eff effsum,bounds))))
+
+let fix_effsum_fexps (FES_aux (fexps,(l,annot))) =
+ let (Base (t,tag,nexps,eff,_,bounds)) = annot in
+ let effsum = match fexps with
+ | FES_Fexps (fexps,_) -> union_effs (List.map get_effsum_fexp fexps) in
+ FES_aux (fexps,(l,(Base (t,tag,nexps,eff,union_effects eff effsum,bounds))))
+
+let fix_effsum_opt_default (Def_val_aux (opt_default,(l,annot))) =
+ let (Base (t,tag,nexps,eff,_,bounds)) = annot in
+ let effsum = match opt_default with
+ | Def_val_empty -> pure_e
+ | Def_val_dec e -> get_effsum_exp e in
+ Def_val_aux (opt_default,(l,(Base (t,tag,nexps,eff,union_effects eff effsum,bounds))))
+
+let fix_effsum_pexp (Pat_aux (pexp,(l,annot))) =
+ let (Base (t,tag,nexps,eff,_,bounds)) = annot in
+ let effsum = match pexp with
+ | Pat_exp (_,e) -> get_effsum_exp e in
+ Pat_aux (pexp,(l,(Base (t,tag,nexps,eff,union_effects eff effsum,bounds))))
+
+let fix_effsum_lb (LB_aux (lb,(l,annot))) =
+ let (Base (t,tag,nexps,eff,_,bounds)) = annot in
+ let effsum = match lb with
+ | LB_val_explicit (_,_,e) -> get_effsum_exp e
+ | LB_val_implicit (_,e) -> get_effsum_exp e in
+ LB_aux (lb,(l,(Base (t,tag,nexps,eff,union_effects eff effsum,bounds))))
let effectful_effs {effect = Eset effs} =
List.exists
@@ -48,8 +146,7 @@ let effectful_effs {effect = Eset effs} =
| _ -> true
) effs
-let effectful eaux =
- effectful_effs (geteffs eaux)
+let effectful eaux = effectful_effs (get_effsum_exp eaux)
let updates_vars_effs {effect = Eset effs} =
List.exists
@@ -59,11 +156,8 @@ let updates_vars_effs {effect = Eset effs} =
| _ -> false
) effs
-let updates_vars eaux =
- updates_vars_effs (geteffs eaux)
+let updates_vars eaux = updates_vars_effs (get_effsum_exp eaux)
-let eff_union es =
- List.fold_left (fun acc e -> union_effects acc (geteffs e)) pure_e es
let rec partial_assoc (eq: 'a -> 'a -> bool) (v: 'a) (ls : ('a *'b) list ) : 'b option = match ls with
| [] -> None
@@ -928,6 +1022,9 @@ let rewrite_defs_remove_vector_concat defs = rewrite_defs_base
*)
let rewrite_exp_lift_assign_intro rewriters nmap ((E_aux (exp,(l,annot))) as full_exp) =
let rewrap e = E_aux (e,(l,annot)) in
+ let rewrap_effects e effsum =
+ let (Base (t,tag,nexps,eff,_,bounds)) = annot in
+ E_aux (e,(l,Base (t,tag,nexps,eff,effsum,bounds))) in
let rewrite_rec = rewriters.rewrite_exp rewriters nmap in
let rewrite_base = rewrite_exp rewriters nmap in
match exp with
@@ -938,9 +1035,9 @@ let rewrite_exp_lift_assign_intro rewriters nmap ((E_aux (exp,(l,annot))) as ful
let le' = rewriters.rewrite_lexp rewriters nmap le in
let e' = rewrite_base e in
let exps' = walker exps in
- let effects = eff_union exps' in
+ let effects = eff_union_exps exps' in
[E_aux (E_internal_let(le', e', E_aux(E_block exps', (l, simple_annot_efr {t=Tid "unit"} effects))),
- (l, simple_annot_efr t (eff_union (e::exps'))))]
+ (l, simple_annot_efr t (eff_union_exps (e::exps'))))]
| ((E_aux(E_if(c,t,e),(l,annot))) as exp)::exps ->
let vars_t = introduced_variables t in
let vars_e = introduced_variables e in
@@ -976,13 +1073,13 @@ let rewrite_exp_lift_assign_intro rewriters nmap ((E_aux (exp,(l,annot))) as ful
(Parse_ast.Unknown,simple_annot bit_t))),
(Parse_ast.Unknown, simple_annot t))
| _ -> e in
- let unioneffs = union_effects effects (geteffs set_exp) in
+ let unioneffs = union_effects effects (get_effsum_exp set_exp) in
([E_aux (E_internal_let (LEXP_aux (LEXP_id (Id_aux (Id i, Parse_ast.Unknown)),
(Parse_ast.Unknown, (tag_annot t Emp_intro))),
set_exp,
E_aux (E_block res, (Parse_ast.Unknown, (simple_annot_efr unit_t effects)))),
(Parse_ast.Unknown, simple_annot_efr unit_t unioneffs))],unioneffs)))
- (E_aux(E_if(c',t',e'), (Parse_ast.Unknown, annot))::exps',eff_union exps') new_vars)
+ (E_aux(E_if(c',t',e'),(Unknown, annot))::exps',eff_union_exps exps') new_vars)
| e::exps -> (rewrite_rec e)::(walker exps)
in
rewrap (E_block (walker exps))
@@ -992,8 +1089,11 @@ let rewrite_exp_lift_assign_intro rewriters nmap ((E_aux (exp,(l,annot))) as ful
let le' = rewriters.rewrite_lexp rewriters nmap le in
(match le' with
| LEXP_aux(_, (_,Base(_,Emp_intro,_,_,_,_))) ->
- let e' = rewrite_base e in
- rewrap (E_internal_let(le', e', E_aux(E_block [], (l, simple_annot_efr unit_t (geteffs e')))))
+ let e' = rewrite_base e in
+ let effects = get_effsum_exp e' in
+ rewrap_effects
+ (E_internal_let(le', e', E_aux(E_block [], (l, simple_annot_efr unit_t effects))))
+ effects
| _ -> E_aux((E_assign(le', rewrite_base e)),(l, tag_annot unit_t Emp_set)))
| _ -> rewrite_base full_exp)
| _ -> rewrite_base full_exp
@@ -1034,9 +1134,9 @@ let rewrite_defs_ocaml defs =
let remove_blocks =
let letbind_wild v body =
- let annot_pat = (Parse_ast.Unknown,simple_annot (gettype v)) in
- let annot_lb = (Parse_ast.Unknown,simple_annot_efr (gettype v) (geteffs v)) in
- let annot_let = (Parse_ast.Unknown,simple_annot_efr (gettype body) (eff_union [v;body])) in
+ let annot_pat = (Parse_ast.Unknown,simple_annot (get_type v)) in
+ let annot_lb = (Parse_ast.Unknown,simple_annot_efr (get_type v) (get_effsum_exp v)) in
+ let annot_let = (Parse_ast.Unknown,simple_annot_efr (get_type body) (eff_union_exps [v;body])) in
E_aux (E_let (LB_aux (LB_val_implicit (P_aux (P_wild,annot_pat),v),annot_lb),body),annot_let) in
let rec f = function
@@ -1054,19 +1154,19 @@ let remove_blocks =
let fresh_id annot =
let current = fresh_name () in
let id = Id_aux (Id ("__w" ^ string_of_int current), Parse_ast.Unknown) in
- let annot_var = (Parse_ast.Unknown,simple_annot (gettype_annot annot)) in
+ let annot_var = (Parse_ast.Unknown,simple_annot (get_type_annot annot)) in
E_aux (E_id id, annot_var)
let letbind (v : 'a exp) (body : 'a exp -> 'a exp) : 'a exp =
(* body is a function : E_id variable -> actual body *)
- match gettype v with
+ match get_type v with
| {t = Tid "unit"} ->
let (E_aux (_,annot)) = v in
let e = E_aux (E_lit (L_aux (L_unit,Unknown)),(Unknown,simple_annot unit_t)) in
let body = body e in
let annot_pat = (Parse_ast.Unknown,simple_annot unit_t) in
let annot_lb = annot_pat in
- let annot_let = (Parse_ast.Unknown,simple_annot_efr (gettype body) (eff_union [v;body])) in
+ let annot_let = (Parse_ast.Unknown,simple_annot_efr (get_type body) (eff_union_exps [v;body])) in
let pat = P_aux (P_wild,annot_pat) in
if effectful v
@@ -1077,9 +1177,9 @@ let letbind (v : 'a exp) (body : 'a exp -> 'a exp) : 'a exp =
let ((E_aux (E_id id,_)) as e_id) = fresh_id annot in
let body = body e_id in
- let annot_pat = (Parse_ast.Unknown,simple_annot (gettype v)) in
+ let annot_pat = (Parse_ast.Unknown,simple_annot (get_type v)) in
let annot_lb = annot_pat in
- let annot_let = (Parse_ast.Unknown,simple_annot_efr (gettype body) (eff_union [v;body])) in
+ let annot_let = (Parse_ast.Unknown,simple_annot_efr (get_type body) (eff_union_exps [v;body])) in
let pat = P_aux (P_id id,annot_pat) in
if effectful v
@@ -1087,7 +1187,7 @@ let letbind (v : 'a exp) (body : 'a exp -> 'a exp) : 'a exp =
else E_aux (E_let (LB_aux (LB_val_implicit (pat,v),annot_lb),body),annot_let)
let rec value ((E_aux (exp_aux,_)) as exp) =
- not (effectful exp) (* && not (updates_vars exp) *) &&
+ not (effectful exp) && not (updates_vars exp) &&
match exp_aux with
| E_id _
| E_lit _ -> true
@@ -1118,13 +1218,6 @@ and value_optdefault (Def_val_aux (o,_)) = match o with
| Def_val_dec e -> value e
and value_fexps (FES_aux (FES_Fexps (fexps,_),_)) =
List.fold_left (fun b (FE_aux (FE_Fexp (_,e),_)) -> b && value e) true fexps
-
-let only_local_eff (l,(Base ((t_params,t),tag,nexps,eff,effsum,bounds))) =
- (l,Base ((t_params,t),tag,nexps,eff,eff,bounds))
-
-let local_eff_plus eff2 (l,(Base ((t_params,t),tag,nexps,eff,effsum,bounds))) =
- let effsum = union_effects eff eff2 in
- (l,Base ((t_params,t),tag,nexps,eff,effsum,bounds))
let rec mapCont (f : 'b -> ('b -> 'a exp) -> 'a exp) (l : 'b list) (k : 'b list -> 'a exp) : 'a exp =
match l with
@@ -1142,104 +1235,96 @@ and n_exp_nameL (exps : 'a exp list) (k : 'a exp list -> 'a exp) : 'a exp =
and n_fexp (fexp : 'a fexp) (k : 'a fexp -> 'a exp) : 'a exp =
let (FE_aux (FE_Fexp (id,exp),annot)) = fexp in
- n_exp_name exp (fun exp -> k (FE_aux (FE_Fexp (id,exp),annot)))
+ n_exp_name exp (fun exp ->
+ k (fix_effsum_fexp (FE_aux (FE_Fexp (id,exp),annot))))
and n_fexpL (fexps : 'a fexp list) (k : 'a fexp list -> 'a exp) : 'a exp =
mapCont n_fexp fexps k
-and n_pexp (new_return : bool) (pexp : 'a pexp) (k : 'a pexp -> 'a exp) : 'a exp =
+and n_pexp (newreturn : bool) (pexp : 'a pexp) (k : 'a pexp -> 'a exp) : 'a exp =
let (Pat_aux (Pat_exp (pat,exp),annot)) = pexp in
- k (Pat_aux (Pat_exp (pat,n_exp_term new_return exp), annot))
+ k (fix_effsum_pexp (Pat_aux (Pat_exp (pat,n_exp_term newreturn exp), annot)))
and n_pexpL (newreturn : bool) (pexps : 'a pexp list) (k : 'a pexp list -> 'a exp) : 'a exp =
- let geteffs (Pat_aux (_,(_,Base (_,_,_,_,{effect = Eset effs},_)))) = effs in
- let effs = {effect = Eset (List.flatten (List.map geteffs pexps))} in
mapCont (n_pexp newreturn) pexps k
and n_fexps (fexps : 'a fexps) (k : 'a fexps -> 'a exp) : 'a exp =
let (FES_aux (FES_Fexps (fexps_aux,b),annot)) = fexps in
- n_fexpL fexps_aux (fun fexps_aux -> k (FES_aux (FES_Fexps (fexps_aux,b),only_local_eff annot)))
+ n_fexpL fexps_aux (fun fexps_aux ->
+ k (fix_effsum_fexps (FES_aux (FES_Fexps (fexps_aux,b),annot))))
and n_opt_default (opt_default : 'a opt_default) (k : 'a opt_default -> 'a exp) : 'a exp =
let (Def_val_aux (opt_default,annot)) = opt_default in
match opt_default with
| Def_val_empty -> k (Def_val_aux (Def_val_empty,annot))
| Def_val_dec exp ->
- n_exp_name exp (fun exp -> k (Def_val_aux (Def_val_dec exp,only_local_eff annot)))
+ n_exp_name exp (fun exp ->
+ k (fix_effsum_opt_default (Def_val_aux (Def_val_dec exp,annot))))
and n_lb (lb : 'a letbind) (k : 'a letbind -> 'a exp) : 'a exp =
let (LB_aux (lb,annot)) = lb in
match lb with
| LB_val_explicit (typ,pat,exp1) ->
- n_exp exp1 (fun exp1 -> k (LB_aux (LB_val_explicit (typ,pat,exp1),only_local_eff annot)))
+ n_exp exp1 (fun exp1 ->
+ k (fix_effsum_lb (LB_aux (LB_val_explicit (typ,pat,exp1),annot))))
| LB_val_implicit (pat,exp1) ->
- n_exp exp1 (fun exp1 -> k (LB_aux (LB_val_implicit (pat,exp1),only_local_eff annot)))
+ n_exp exp1 (fun exp1 ->
+ k (fix_effsum_lb (LB_aux (LB_val_implicit (pat,exp1),annot))))
and n_lexp (lexp : 'a lexp) (k : 'a lexp -> 'a exp) : 'a exp =
let (LEXP_aux (lexp_aux,annot)) = lexp in
match lexp_aux with
| LEXP_id _ -> k lexp
| LEXP_memory (id,es) ->
- n_exp_nameL es (fun es -> k (LEXP_aux (LEXP_memory (id,es),only_local_eff annot)))
- | LEXP_cast (typ,id) -> k (LEXP_aux (LEXP_cast (typ,id),only_local_eff annot))
+ n_exp_nameL es (fun es ->
+ k (fix_effsum_lexp (LEXP_aux (LEXP_memory (id,es),annot))))
+ | LEXP_cast (typ,id) ->
+ k (fix_effsum_lexp (LEXP_aux (LEXP_cast (typ,id),annot)))
| LEXP_vector (lexp,id) ->
- let (LEXP_aux (_,annot)) = lexp in
- let effs = geteffs_annot annot in
- n_lexp lexp (fun lexp -> k (LEXP_aux (LEXP_vector (lexp,id),local_eff_plus effs annot)))
+ n_lexp lexp (fun lexp ->
+ k (fix_effsum_lexp (LEXP_aux (LEXP_vector (lexp,id),annot))))
| LEXP_vector_range (lexp,exp1,exp2) ->
n_lexp lexp (fun lexp ->
- let (LEXP_aux (_,annot)) = lexp in
- let effs = geteffs_annot annot in
n_exp_name exp1 (fun exp1 ->
n_exp_name exp2 (fun exp2 ->
- k (LEXP_aux (LEXP_vector_range (lexp,exp1,exp2),local_eff_plus effs annot)))))
+ k (fix_effsum_lexp (LEXP_aux (LEXP_vector_range (lexp,exp1,exp2),annot))))))
| LEXP_field (lexp,id) ->
n_lexp lexp (fun lexp ->
- let (LEXP_aux (_,annot)) = lexp in
- let effs = geteffs_annot annot in
- k (LEXP_aux (LEXP_field (lexp,id),local_eff_plus effs annot)))
+ k (fix_effsum_lexp (LEXP_aux (LEXP_field (lexp,id),annot))))
and n_exp_term (new_return : bool) (exp : 'a exp) : 'a exp =
let exp =
- if new_return
- then E_aux (E_internal_return exp,(Unknown,simple_annot_efr (gettype exp) (geteffs exp)))
- else exp in
- (* changed this from n_exp to n_exp_name so that when we return updated variables
+ if new_return then
+ E_aux (E_internal_return exp,(Unknown,simple_annot_efr (get_type exp) (get_effsum_exp exp)))
+ else
+ exp in
+ (* changed this from n_exp to n_exp_pure so that when we return updated variables
* from a for-loop, for example, we can just add those into the returned tuple and
* don't need to a-normalise again *)
n_exp_pure exp (fun exp -> exp)
-and n_exp (exp : 'a exp) (k : 'a exp -> 'a exp) : 'a exp =
-
-(* if not (effectful exp) then k exp else comment out this line for full a-normalisation *)
-
- let (E_aux (exp_aux,annot)) = exp in
+and n_exp (E_aux (exp_aux,annot) as exp : 'a exp) (k : 'a exp -> 'a exp) : 'a exp =
- let rewrap_effs effsum exp_aux = (* explicitly give effect sum *)
- let (l,Base (t,tag,nexps,eff,_,bounds)) = annot in
- E_aux (exp_aux, (l,Base (t,tag,nexps,eff,effsum,bounds))) in
-
- let rewrap_localeff exp_aux = (* give exp_aux the local effect as the effect sum *)
- E_aux (exp_aux,only_local_eff annot) in
+ let rewrap e = fix_effsum_exp (E_aux (e,annot)) in
match exp_aux with
| E_block es -> failwith "E_block should have been removed till now"
| E_nondet _ -> failwith "E_nondet not supported"
- | E_id id -> k exp (* if value exp then return exp else letbind exp *)
+ | E_id id -> k exp
| E_lit _ -> k exp
| E_cast (typ,exp') ->
n_exp exp' (fun exp' ->
- k (rewrap_localeff (E_cast (typ,exp'))))
+ k (rewrap (E_cast (typ,exp'))))
| E_app (id,exps) ->
n_exp_nameL exps (fun exps ->
- k (rewrap_localeff (E_app (id,exps))))
+ k (rewrap (E_app (id,exps))))
| E_app_infix (exp1,id,exp2) ->
n_exp_name exp1 (fun exp1 ->
n_exp_name exp2 (fun exp2 ->
- k (rewrap_localeff (E_app_infix (exp1,id,exp2)))))
+ k (rewrap (E_app_infix (exp1,id,exp2)))))
| E_tuple exps ->
n_exp_nameL exps (fun exps ->
- k (rewrap_localeff (E_tuple exps)))
+ k (rewrap (E_tuple exps)))
| E_if (exp1,exp2,exp3) ->
n_exp_name exp1 (fun exp1 ->
let (E_aux (_,annot2)) = exp2 in
@@ -1247,101 +1332,98 @@ and n_exp (exp : 'a exp) (k : 'a exp -> 'a exp) : 'a exp =
let new_return = effectful exp2 || effectful exp3 in
let exp2 = n_exp_term new_return exp2 in
let exp3 = n_exp_term new_return exp3 in
- k (rewrap_effs (eff_union [exp2;exp3]) (E_if (exp1,exp2,exp3))))
+ k (rewrap (E_if (exp1,exp2,exp3))))
| E_for (id,start,stop,by,dir,body) ->
n_exp_name start (fun start ->
n_exp_name stop (fun stop ->
n_exp_name by (fun by ->
let body = n_exp_term (effectful body) body in
- k (rewrap_effs (geteffs body) (E_for (id,start,stop,by,dir,body))))))
+ k (rewrap (E_for (id,start,stop,by,dir,body))))))
| E_vector exps ->
n_exp_nameL exps (fun exps ->
- k (rewrap_localeff (E_vector exps)))
+ k (rewrap (E_vector exps)))
| E_vector_indexed (exps,opt_default) ->
let (is,exps) = List.split exps in
n_exp_nameL exps (fun exps ->
n_opt_default opt_default (fun opt_default ->
let exps = List.combine is exps in
- k (rewrap_localeff (E_vector_indexed (exps,opt_default)))))
+ k (rewrap (E_vector_indexed (exps,opt_default)))))
| E_vector_access (exp1,exp2) ->
n_exp_name exp1 (fun exp1 ->
n_exp_name exp2 (fun exp2 ->
- k (rewrap_localeff (E_vector_access (exp1,exp2)))))
+ k (rewrap (E_vector_access (exp1,exp2)))))
| E_vector_subrange (exp1,exp2,exp3) ->
n_exp_name exp1 (fun exp1 ->
n_exp_name exp2 (fun exp2 ->
n_exp_name exp3 (fun exp3 ->
- k (rewrap_localeff (E_vector_subrange (exp1,exp2,exp3))))))
+ k (rewrap (E_vector_subrange (exp1,exp2,exp3))))))
| E_vector_update (exp1,exp2,exp3) ->
n_exp_name exp1 (fun exp1 ->
n_exp_name exp2 (fun exp2 ->
n_exp_name exp3 (fun exp3 ->
- k (rewrap_localeff (E_vector_update (exp1,exp2,exp3))))))
+ k (rewrap (E_vector_update (exp1,exp2,exp3))))))
| E_vector_update_subrange (exp1,exp2,exp3,exp4) ->
n_exp_name exp1 (fun exp1 ->
n_exp_name exp2 (fun exp2 ->
n_exp_name exp3 (fun exp3 ->
n_exp_name exp4 (fun exp4 ->
- k (rewrap_localeff (E_vector_update_subrange (exp1,exp2,exp3,exp4)))))))
+ k (rewrap (E_vector_update_subrange (exp1,exp2,exp3,exp4)))))))
| E_vector_append (exp1,exp2) ->
n_exp_name exp1 (fun exp1 ->
n_exp_name exp2 (fun exp2 ->
- k (rewrap_localeff (E_vector_append (exp1,exp2)))))
+ k (rewrap (E_vector_append (exp1,exp2)))))
| E_list exps ->
n_exp_nameL exps (fun exps ->
- k (rewrap_localeff (E_list exps)))
+ k (rewrap (E_list exps)))
| E_cons (exp1,exp2) ->
n_exp_name exp1 (fun exp1 ->
n_exp_name exp2 (fun exp2 ->
- k (rewrap_localeff (E_cons (exp1,exp2)))))
+ k (rewrap (E_cons (exp1,exp2)))))
| E_record fexps ->
n_fexps fexps (fun fexps ->
- k (rewrap_localeff (E_record fexps)))
+ k (rewrap (E_record fexps)))
| E_record_update (exp1,fexps) ->
n_exp_name exp1 (fun exp1 ->
n_fexps fexps (fun fexps ->
- k (rewrap_localeff (E_record fexps))))
+ k (rewrap (E_record fexps))))
| E_field (exp1,id) ->
n_exp_name exp1 (fun exp1 ->
- k (rewrap_localeff (E_field (exp1,id))))
+ k (rewrap (E_field (exp1,id))))
| E_case (exp1,pexps) ->
- (* PROBABLY NEED to insert E_returns here *)
let newreturn =
List.fold_left
(fun b (Pat_aux (_,(_,Base (_,_,_,_,effs,_)))) -> b || effectful_effs effs)
false pexps in
n_exp_name exp1 (fun exp1 ->
n_pexpL newreturn pexps (fun pexps ->
- let geteffs (Pat_aux (_,(_,Base (_,_,_,_,eff,_)))) = eff in
- let effsum = List.fold_left union_effects {effect = Eset []} (List.map geteffs pexps) in
- k (rewrap_effs effsum (E_case (exp1,pexps)))))
+ k (rewrap (E_case (exp1,pexps)))))
| E_let (lb,body) ->
n_lb lb (fun lb ->
(match lb with
| LB_aux (LB_val_explicit (_,pat,exp'),annot')
| LB_aux (LB_val_implicit (pat,exp'),annot') ->
if effectful exp'
- then (rewrap_effs (eff_union [exp';body]) (E_internal_plet (pat,exp',n_exp body k)))
- else (rewrap_effs (geteffs body) (E_let (lb,n_exp body k)))
+ then (rewrap (E_internal_plet (pat,exp',n_exp body k)))
+ else (rewrap (E_let (lb,n_exp body k)))
))
| E_assign (lexp,exp1) ->
n_lexp lexp (fun lexp ->
n_exp_name exp1 (fun exp1 ->
- k (rewrap_localeff (E_assign (lexp,exp1)))))
+ k (rewrap (E_assign (lexp,exp1)))))
| E_exit exp' -> k (E_aux (E_exit (n_exp_term (effectful exp') exp'),annot))
| E_internal_cast (annot',exp') ->
n_exp_name exp' (fun exp' ->
- k (rewrap_localeff (E_internal_cast (annot',exp'))))
+ k (rewrap (E_internal_cast (annot',exp'))))
| E_internal_exp _ -> k exp
| E_internal_exp_user _ -> k exp
| E_internal_let (lexp,exp1,exp2) ->
(if effectful exp1
then n_exp_name exp1
else n_exp exp1) (fun exp1 ->
- rewrap_effs (geteffs exp2) (E_internal_let (lexp,exp1,n_exp exp2 k)))
+ rewrap (E_internal_let (lexp,exp1,n_exp exp2 k)))
| E_internal_return exp1 ->
n_exp_name exp1 (fun exp1 ->
- k (rewrap_localeff (E_internal_return exp1)))
+ k (rewrap (E_internal_return exp1)))
| E_internal_plet _ -> failwith "E_internal_plet should not be here yet"
@@ -1363,76 +1445,77 @@ let rewrite_defs_a_normalise =
* internal let-expressions, or internal plet-expressions ended by a term that does not
* access memory or registers and does not update variables *)
-let dedup eq = List.fold_left (fun acc e -> if List.exists (eq e) acc then acc else e :: acc) []
+let dedup eq =
+ List.fold_left (fun acc e -> if List.exists (eq e) acc then acc else e :: acc) []
let eqidtyp (id1,_) (id2,_) =
let name1 = match id1 with Id_aux ((Id name | DeIid name),_) -> name in
- let name2 = match id1 with Id_aux ((Id name | DeIid name),_) -> name in
+ let name2 = match id2 with Id_aux ((Id name | DeIid name),_) -> name in
name1 = name2
let find_updated_vars exp =
- let names =
+ let ( @@ ) (a,b) (a',b') = (a @ a',b @ b') in
+ let lapp2 (l : (('a list * 'b list) list)) : ('a list * 'b list) =
+ List.fold_left
+ (fun ((intros_acc : 'a list),(updates_acc : 'b list)) (intros,updates) ->
+ (intros_acc @ intros, updates_acc @ updates)) ([],[]) l in
+
+ let (intros,updates) =
fold_exp
- { e_block = (fun es -> List.flatten es)
- ; e_nondet = (fun es -> List.flatten es)
- ; e_id = (fun _ -> [])
- ; e_lit = (fun _ -> [])
+ { e_aux = (fun (e,_) -> e)
+ ; e_id = (fun _ -> ([],[]))
+ ; e_lit = (fun _ -> ([],[]))
; e_cast = (fun (_,e) -> e)
- ; e_app = (fun (_,es) -> List.flatten es)
- ; e_app_infix = (fun (e1,_,e2) -> e1 @ e2)
- ; e_tuple = (fun es -> List.flatten es)
- ; e_if = (fun (e1,e2,e3) -> e1 @ e2 @ e3)
- ; e_for = (fun (_,e1,e2,e3,_,e4) -> e1 @ e2 @ e3 @ e4)
- ; e_vector = (fun es -> List.flatten es)
- ; e_vector_indexed = (fun (es,opt2) -> (List.flatten (List.map snd es)) @ opt2)
- ; e_vector_access = (fun (e1,e2) -> e1 @ e2)
- ; e_vector_subrange = (fun (e1,e2,e3) -> e1 @ e2 @ e3)
- ; e_vector_update = (fun (e1,e2,e3) -> e1 @ e2 @ e3)
- ; e_vector_update_subrange = (fun (e1,e2,e3,e4) -> e1 @ e2 @ e3 @ e4)
- ; e_vector_append = (fun (e1,e2) -> e1 @ e2)
- ; e_list = (fun es -> List.flatten es)
- ; e_cons = (fun (e1,e2) -> e1 @ e2)
- ; e_record = (fun fexps -> fexps)
- ; e_record_update = (fun (e1,fexp) -> e1 @ fexp)
+ ; e_block = (fun es -> lapp2 es)
+ ; e_nondet = (fun es -> lapp2 es)
+ ; e_app = (fun (_,es) -> lapp2 es)
+ ; e_app_infix = (fun (e1,_,e2) -> e1 @@ e2)
+ ; e_tuple = (fun es -> lapp2 es)
+ ; e_if = (fun (e1,e2,e3) -> e1 @@ e2 @@ e3)
+ ; e_for = (fun (_,e1,e2,e3,_,e4) -> e1 @@ e2 @@ e3 @@ e4)
+ ; e_vector = (fun es -> lapp2 es)
+ ; e_vector_indexed = (fun (es,opt) -> opt @@ lapp2 (List.map snd es))
+ ; e_vector_access = (fun (e1,e2) -> e1 @@ e2)
+ ; e_vector_subrange = (fun (e1,e2,e3) -> e1 @@ e2 @@ e3)
+ ; e_vector_update = (fun (e1,e2,e3) -> e1 @@ e2 @@ e3)
+ ; e_vector_update_subrange = (fun (e1,e2,e3,e4) -> e1 @@ e2 @@ e3 @@ e4)
+ ; e_vector_append = (fun (e1,e2) -> e1 @@ e2)
+ ; e_list = (fun es -> lapp2 es)
+ ; e_cons = (fun (e1,e2) -> e1 @@ e2)
+ ; e_record = (fun fexps -> fexps)
+ ; e_record_update = (fun (e1,fexp) -> e1 @@ fexp)
; e_field = (fun (e1,id) -> e1)
- ; e_case = (fun (e1,pexps) -> e1 @ List.flatten pexps)
- ; e_let = (fun (lb,e2) -> lb @ e2)
- ; e_assign =
- (function
- | ((None,[(id,b)]),e2) -> if b then id :: e2 else e2
- | ((None,[]),e2) -> e2
- )
- ; e_exit = (fun e1 -> e1)
+ ; e_case = (fun (e1,pexps) -> e1 @@ lapp2 pexps)
+ ; e_let = (fun (lb,e2) -> lb @@ e2)
+ ; e_assign = (fun ((ids,acc),e2) -> ([],ids) @@ acc @@ e2)
+ ; e_exit = (fun e1 -> ([],[]))
; e_internal_cast = (fun (_,e1) -> e1)
- ; e_internal_exp = (fun _ -> [])
- ; e_internal_exp_user = (fun _ -> [])
- ; e_internal_let = (fun ((None,[(id,_)]), e2, e3) ->
- List.filter (fun id2 -> not (eqidtyp id id2)) (e2 @ e3))
- ; e_internal_plet = (fun (_, e1, e2) -> e1 @ e2)
+ ; e_internal_exp = (fun _ -> ([],[]))
+ ; e_internal_exp_user = (fun _ -> ([],[]))
+ ; e_internal_let =
+ (fun (([id],acc),e2,e3) ->
+ let (xs,ys) = ([id],[]) @@ acc @@ e2 @@ e3 in
+ let ys = List.filter (fun id2 -> not (eqidtyp id id2)) ys in
+ (xs,ys))
+ ; e_internal_plet = (fun (_, e1, e2) -> e1 @@ e2)
; e_internal_return = (fun e -> e)
- ; e_aux = (fun (e,_) -> e)
- ; lEXP_id = (fun id -> (Some id,[]))
- ; lEXP_memory = (fun (_,_) -> (None,[]))
- ; lEXP_cast = (fun (_,id) -> (Some id,[]))
- ; lEXP_vector = (fun ((None,lexp),_) -> (None,lexp))
- ; lEXP_vector_range = (fun ((None,lexp),_,_) -> (None,lexp))
- ; lEXP_field = (fun ((None,lexp),_) -> (None,lexp))
+ ; lEXP_id = (fun id -> (Some id,[],([],[])))
+ ; lEXP_memory = (fun (_,es) -> (None,[],lapp2 es))
+ ; lEXP_cast = (fun (_,id) -> (Some id,[],([],[])))
+ ; lEXP_vector = (fun ((ids,acc),e1) -> (None,ids,acc @@ e1))
+ ; lEXP_vector_range = (fun ((ids,acc),e1,e2) -> (None,ids,acc @@ e1 @@ e2))
+ ; lEXP_field = (fun ((ids,acc),_) -> (None,ids,acc))
; lEXP_aux =
(function
- | ((Some id,[]),annot) ->
- let effs = geteffs_annot annot in
- let b =
- match effs with
- | {effect = Eset [BE_aux (BE_lset,_)]} -> true
- | _ -> false in
- (None,[((id,annot),b)])
- | ((None,es),_) -> (None,es)
+ | ((Some id,ids,acc),((_,Base (_,(Emp_set | Emp_intro),_,_,_,_)) as annot)) ->
+ ((id,annot) :: ids,acc)
+ | ((_,ids,acc),_) -> (ids,acc)
)
; fE_Fexp = (fun (_,e) -> e)
; fE_aux = (fun (fexp,_) -> fexp)
- ; fES_Fexps = (fun (fexps,_) -> List.flatten fexps)
+ ; fES_Fexps = (fun (fexps,_) -> lapp2 fexps)
; fES_aux = (fun (fexp,_) -> fexp)
- ; def_val_empty = []
+ ; def_val_empty = ([],[])
; def_val_dec = (fun e -> e)
; def_val_aux = (fun (defval,_) -> defval)
; pat_exp = (fun (_,e) -> e)
@@ -1442,7 +1525,7 @@ let find_updated_vars exp =
; lB_aux = (fun (lb,_) -> lb)
; pat_alg = id_pat_alg
} exp in
- dedup eqidtyp names
+ dedup eqidtyp updates
let swaptyp t (l,(Base ((t_params,_),tag,nexps,eff,effsum,bounds))) =
(l,Base ((t_params,t),tag,nexps,eff,effsum,bounds))
@@ -1451,17 +1534,18 @@ let mktup es =
if es = [] then
E_aux (E_lit (L_aux (L_unit,Unknown)),(Unknown,simple_annot unit_t))
else
- let effs = List.fold_left (fun acc e -> union_effects acc (geteffs e)) {effect = Eset []} es in
- let typs = List.map gettype es in
+ let effs =
+ List.fold_left (fun acc e -> union_effects acc (get_effsum_exp e)) {effect = Eset []} es in
+ let typs = List.map get_type es in
E_aux (E_tuple es,(Parse_ast.Unknown,simple_annot_efr {t = Ttup typs} effs))
let mktup_pat es =
if es = [] then
P_aux (P_wild,(Unknown,simple_annot unit_t))
else
- let typs = List.map gettype es in
+ let typs = List.map get_type es in
let pats = List.map (fun (E_aux (E_id id,_) as exp) ->
- P_aux (P_id id,(Unknown,simple_annot (gettype exp)))) es in
+ P_aux (P_id id,(Unknown,simple_annot (get_type exp)))) es in
P_aux (P_tup pats,(Parse_ast.Unknown,simple_annot {t = Ttup typs}))
@@ -1475,16 +1559,16 @@ let rec rewrite_var_updates ((E_aux (expaux,annot)) as exp) =
match expaux with
| E_let (lb,exp) ->
let exp = add_vars (*overwrite*) exp vars in
- E_aux (E_let (lb,exp),swaptyp (gettype exp) annot)
+ E_aux (E_let (lb,exp),swaptyp (get_type exp) annot)
| E_internal_let (lexp,exp1,exp2) ->
let exp2 = add_vars (*overwrite*) exp2 vars in
- E_aux (E_internal_let (lexp,exp1,exp2), swaptyp (gettype exp2) annot)
+ E_aux (E_internal_let (lexp,exp1,exp2), swaptyp (get_type exp2) annot)
| E_internal_plet (pat,exp1,exp2) ->
let exp2 = add_vars (*overwrite*) exp2 vars in
- E_aux (E_internal_plet (pat,exp1,exp2), swaptyp (gettype exp2) annot)
+ E_aux (E_internal_plet (pat,exp1,exp2), swaptyp (get_type exp2) annot)
| E_internal_return exp2 ->
let exp2 = add_vars (*overwrite*) exp2 vars in
- E_aux (E_internal_return exp2,swaptyp (gettype exp2) annot)
+ E_aux (E_internal_return exp2,swaptyp (get_type exp2) annot)
| _ ->
(* after a-normalisation this will be pure:
* if the whole body of the function/if-expression/case-expression/for-loop was
@@ -1492,21 +1576,25 @@ let rec rewrite_var_updates ((E_aux (expaux,annot)) as exp) =
* and (in this case) exp is a name contained in E_return that by definition of
* value must be pure
*)
- let () = assert (not (effectful exp)) in
+ let () =
+ if (effectful exp) then
+ failwith (e_to_string (get_effsum_exp exp))
+ else
+ () in
(* if overwrite then
(* let () = match expaux with
- | E_id _ when gettype exp = {t = Tid "unit"} -> ()
+ | E_id _ when get_type exp = {t = Tid "unit"} -> ()
| _ -> failwith "nono" in *)
vars
else*)
- E_aux (E_tuple [exp;vars],swaptyp {t = Ttup [gettype exp;gettype vars]} annot) in
+ E_aux (E_tuple [exp;vars],swaptyp {t = Ttup [get_type exp;get_type vars]} annot) in
let rewrite (E_aux (expaux,annot)) (P_aux (_,pannot) as pat) =
match expaux with
| E_for(id,exp1,exp2,exp3,order,exp4) ->
let vars = List.map (fun (var,(l,t)) -> E_aux (E_id var,(l,t))) (find_updated_vars exp4) in
let vartuple = mktup vars in
-(* let overwrite = match gettype exp with
+(* let overwrite = match get_type exp with
| {t = Tid "unit"} -> true
| _ -> false in*)
let exp4 = rewrite_var_updates (add_vars (*overwrite*) exp4 vartuple) in
@@ -1517,13 +1605,13 @@ let rec rewrite_var_updates ((E_aux (expaux,annot)) as exp) =
| false -> Id_aux (Id (if orderb then "foreach_inc" else "foreach_dec"),Unknown)
| true -> Id_aux (Id (if orderb then "foreachM_inc" else "foreachM_dec"),Unknown) in
let loopvar =
- let (bf,tf) = match gettype exp1 with
+ let (bf,tf) = match get_type exp1 with
| {t = Tapp ("atom",[TA_nexp f])} -> (TA_nexp f,TA_nexp f)
| {t = Tapp ("reg", [TA_typ {t = Tapp ("atom",[TA_nexp f])}])} -> (TA_nexp f,TA_nexp f)
| {t = Tapp ("range",[TA_nexp bf;TA_nexp tf])} -> (TA_nexp bf,TA_nexp tf)
| {t = Tapp ("reg", [TA_typ {t = Tapp ("range",[TA_nexp bf;TA_nexp tf])}])} -> (TA_nexp bf,TA_nexp tf)
| {t = Tapp (name,_)} -> failwith (name ^ " shouldn't be here") in
- let (bt,tt) = match gettype exp2 with
+ let (bt,tt) = match get_type exp2 with
| {t = Tapp ("atom",[TA_nexp t])} -> (TA_nexp t,TA_nexp t)
| {t = Tapp ("atom",[TA_typ {t = Tapp ("atom", [TA_nexp t])}])} -> (TA_nexp t,TA_nexp t)
| {t = Tapp ("range",[TA_nexp bt;TA_nexp tt])} -> (TA_nexp bt,TA_nexp tt)
@@ -1532,12 +1620,12 @@ let rec rewrite_var_updates ((E_aux (expaux,annot)) as exp) =
let t = {t = Tapp ("range",if orderb then [bf;tt] else [tf;bt])} in
E_aux (E_id id,(Unknown,simple_annot t)) in
let v = E_aux (E_app (funcl,[loopvar;mktup [exp1;exp2;exp3];exp4;vartuple]),
- (Unknown,simple_annot_efr (gettype exp4) (geteffs exp4))) in
+ (Unknown,simple_annot_efr (get_type exp4) (get_effsum_exp exp4))) in
let pat =
(* if overwrite then
mktup_pat vars
else *)
- P_aux (P_tup [pat; mktup_pat vars], (Unknown,simple_annot (gettype v))) in
+ P_aux (P_tup [pat; mktup_pat vars], (Unknown,simple_annot (get_type v))) in
Added_vars (v,pat)
| E_if (c,e1,e2) ->
let vars = List.map (fun (var,(l,t)) -> E_aux (E_id var,(l,t)))
@@ -1546,20 +1634,20 @@ let rec rewrite_var_updates ((E_aux (expaux,annot)) as exp) =
(Same_vars (E_aux (E_if (c,rewrite_var_updates e1,rewrite_var_updates e2),annot)))
else
let vartuple = mktup vars in
-(* let overwrite = match gettype exp with
+(* let overwrite = match get_type exp with
| {t = Tid "unit"} -> true
| _ -> false in *)
let e1 = rewrite_var_updates (add_vars (*overwrite*) e1 vartuple) in
let e2 = rewrite_var_updates (add_vars (*overwrite*) e2 vartuple) in
(* after a-normalisation c shouldn't need rewriting *)
- let t = gettype e1 in
- (* let () = assert (simple_annot t = simple_annot (gettype e2)) in *)
- let v = E_aux (E_if (c,e1,e2), (Unknown,simple_annot_efr t (eff_union [e1;e2]))) in
+ let t = get_type e1 in
+ (* let () = assert (simple_annot t = simple_annot (get_type e2)) in *)
+ let v = E_aux (E_if (c,e1,e2), (Unknown,simple_annot_efr t (eff_union_exps [e1;e2]))) in
let pat =
(* if overwrite then
mktup_pat vars
else*)
- P_aux (P_tup [pat; mktup_pat vars],(Unknown,simple_annot (gettype v))) in
+ P_aux (P_tup [pat; mktup_pat vars],(Unknown,simple_annot (get_type v))) in
Added_vars (v,pat)
| E_case (e1,ps) ->
(* after a-normalisation e1 shouldn't need rewriting *)
@@ -1572,51 +1660,51 @@ let rec rewrite_var_updates ((E_aux (expaux,annot)) as exp) =
Same_vars (E_aux (E_case (e1,ps),annot))
else
let vartuple = mktup vars in
-(* let overwrite = match gettype exp with
+(* let overwrite = match get_type exp with
| {t = Tid "unit"} -> true
| _ -> false in*)
let typ =
let (Pat_aux (Pat_exp (_,first),_)) = List.hd ps in
- gettype first in
+ get_type first in
let (ps,typ,effs) =
let f (acc,typ,effs) (Pat_aux (Pat_exp (p,e),pannot)) =
- let etyp = gettype e in
+ let etyp = get_type e in
let () = assert (simple_annot etyp = simple_annot typ) in
let e = rewrite_var_updates (add_vars (*overwrite*) e vartuple) in
- let pannot = (Parse_ast.Unknown,simple_annot (gettype e)) in
- let effs = union_effects effs (geteffs e) in
+ let pannot = (Parse_ast.Unknown,simple_annot (get_type e)) in
+ let effs = union_effects effs (get_effsum_exp e) in
let pat' = Pat_aux (Pat_exp (p,e),pannot) in
(acc @ [pat'],typ,effs) in
List.fold_left f ([],typ,{effect = Eset []}) ps in
let v = E_aux (E_case (e1,ps), (Unknown,simple_annot_efr typ effs)) in
let pat =
(* if overwrite then
- P_aux (P_tup [mktup_pat vars],(Unknown,simple_annot (gettype v)))
+ P_aux (P_tup [mktup_pat vars],(Unknown,simple_annot (get_type v)))
else*)
- P_aux (P_tup [pat; mktup_pat vars],(Unknown,simple_annot (gettype v))) in
+ P_aux (P_tup [pat; mktup_pat vars],(Unknown,simple_annot (get_type v))) in
Added_vars (v,pat)
| E_assign (lexp,vexp) ->
- let {effect = Eset effs} = geteffs_annot annot in
+ let {effect = Eset effs} = get_effsum_annot annot in
if not (List.exists (function BE_aux (BE_lset,_) -> true | _ -> false) effs) then
Same_vars (E_aux (E_assign (lexp,vexp),annot))
else
(match lexp with
| LEXP_aux (LEXP_id id,annot) ->
- let pat = P_aux (P_id id,(Unknown,simple_annot (gettype vexp))) in
+ let pat = P_aux (P_id id,(Unknown,simple_annot (get_type vexp))) in
Added_vars (vexp,pat)
| LEXP_aux (LEXP_cast (_,id),annot) ->
- let pat = P_aux (P_id id,(Unknown,simple_annot (gettype vexp))) in
+ let pat = P_aux (P_id id,(Unknown,simple_annot (get_type vexp))) in
Added_vars (vexp,pat)
| LEXP_aux (LEXP_vector (LEXP_aux (LEXP_id id,annot2),i),annot) ->
- let eid = E_aux (E_id id,(Unknown,simple_annot (gettype_annot annot2))) in
- let vexp = E_aux (E_vector_update (eid,i,vexp),(Unknown,simple_annot (gettype_annot annot))) in
- let pat = P_aux (P_id id,(Unknown,simple_annot (gettype vexp))) in
+ let eid = E_aux (E_id id,(Unknown,simple_annot (get_type_annot annot2))) in
+ let vexp = E_aux (E_vector_update (eid,i,vexp),(Unknown,simple_annot (get_type_annot annot))) in
+ let pat = P_aux (P_id id,(Unknown,simple_annot (get_type vexp))) in
Added_vars (vexp,pat)
| LEXP_aux (LEXP_vector_range (LEXP_aux (LEXP_id id,annot2),i,j),annot) ->
- let eid = E_aux (E_id id,(Unknown,simple_annot (gettype_annot annot2))) in
+ let eid = E_aux (E_id id,(Unknown,simple_annot (get_type_annot annot2))) in
let vexp = E_aux (E_vector_update_subrange (eid,i,j,vexp),
- (Unknown,simple_annot (gettype_annot annot))) in
- let pat = P_aux (P_id id,(Unknown,simple_annot (gettype vexp))) in
+ (Unknown,simple_annot (get_type_annot annot))) in
+ let pat = P_aux (P_id id,(Unknown,simple_annot (get_type vexp))) in
Added_vars (vexp,pat))
| _ ->
(* assumes everying's a-normlised: an expression is a sequence of let-expressions,
@@ -1630,23 +1718,23 @@ let rec rewrite_var_updates ((E_aux (expaux,annot)) as exp) =
| LB_aux (LB_val_implicit (pat,v),lbannot) ->
(match rewrite v pat with
| Added_vars (v,pat) ->
- let lbannot = (Parse_ast.Unknown,simple_annot (gettype v)) in
- (geteffs v,LB_aux (LB_val_implicit (pat,v),lbannot))
- | Same_vars v -> (geteffs v,LB_aux (LB_val_implicit (pat,v),lbannot)))
+ let lbannot = (Parse_ast.Unknown,simple_annot (get_type v)) in
+ (get_effsum_exp v,LB_aux (LB_val_implicit (pat,v),lbannot))
+ | Same_vars v -> (get_effsum_exp v,LB_aux (LB_val_implicit (pat,v),lbannot)))
| LB_aux (LB_val_explicit (typ,pat,v),lbannot) ->
(match rewrite v pat with
| Added_vars (v,pat) ->
- let lbannot = (Parse_ast.Unknown,simple_annot (gettype v)) in
- (geteffs v,LB_aux (LB_val_implicit (pat,v),lbannot))
- | Same_vars v -> (geteffs v,LB_aux (LB_val_explicit (typ,pat,v),lbannot))) in
+ let lbannot = (Parse_ast.Unknown,simple_annot (get_type v)) in
+ (get_effsum_exp v,LB_aux (LB_val_implicit (pat,v),lbannot))
+ | Same_vars v -> (get_effsum_exp v,LB_aux (LB_val_explicit (typ,pat,v),lbannot))) in
E_aux (E_let (lb,body),
- (Unknown,simple_annot_efr (gettype body) (union_effects eff (geteffs body))))
+ (Unknown,simple_annot_efr (get_type body) (union_effects eff (get_effsum_exp body))))
| E_internal_plet (pat,v,body) ->
let body = rewrite_var_updates body in
(match rewrite v pat with
| Added_vars (v,pat) ->
E_aux (E_internal_plet (pat,v,body),
- (Unknown,simple_annot_efr (gettype body) (eff_union [v;body])))
+ (Unknown,simple_annot_efr (get_type body) (eff_union_exps [v;body])))
| Same_vars v -> E_aux (E_internal_plet (pat,v,body),annot))
| E_internal_let (lexp,v,body) ->
(* After a-normalisation E_internal_lets can only bind values to names, those don't
@@ -1655,10 +1743,10 @@ let rec rewrite_var_updates ((E_aux (expaux,annot)) as exp) =
let id = match lexp with
| LEXP_aux (LEXP_id id,_) -> id
| LEXP_aux (LEXP_cast (_,id),_) -> id in
- let pat = P_aux (P_id id, (Parse_ast.Unknown,simple_annot (gettype v))) in
- let lbannot = (Parse_ast.Unknown,simple_annot_efr (gettype v) (geteffs v)) in
+ let pat = P_aux (P_id id, (Parse_ast.Unknown,simple_annot (get_type v))) in
+ let lbannot = (Parse_ast.Unknown,simple_annot_efr (get_type v) (get_effsum_exp v)) in
let lb = LB_aux (LB_val_implicit (pat,v),lbannot) in
- E_aux (E_let (lb,body),(Unknown,simple_annot_efr (gettype body) (eff_union [v;body])))
+ E_aux (E_let (lb,body),(Unknown,simple_annot_efr (get_type body) (eff_union_exps [v;body])))
(* In tail-position there shouldn't be anything we need to do as the terms after
* a-normalisation are pure and don't update local variables. There can't be any variable
* assignments in tail-position (because of the effect), there could be pure pattern-match
@@ -1667,73 +1755,6 @@ let rec rewrite_var_updates ((E_aux (expaux,annot)) as exp) =
* update variables. *)
| _ -> exp
-(* | E_for _ ->
- let (Some (exp,_)) = rewrite exp in
- let annot_pat = (Parse_ast.Unknown,simple_annot (gettype exp)) in
- let pat = (P_aux (P_wild,annot_pat)) in
- let body = E_aux (E_lit (L_aux (L_unit,Unknown)),(Unknown,simple_annot unit_t)) in
- let annot_lb = annot_pat in
- let annot_let = (Parse_ast.Unknown,simple_annot unit_t) in
- if effectful exp
- then E_aux (E_internal_plet (pat,exp,body),annot_let)
- else E_aux (E_let (LB_aux (LB_val_implicit (pat,exp),annot_lb),body),annot_let) *)
-
-(*
-let replace_var_update_e_assign =
-
- let e_aux (expaux,annot) =
-
- let f v body lexp =
-
- let letbind (E_aux (E_id id,_) as e_id) (v : 'a exp) (body : 'a exp) : 'a exp =
- (* body is a function : E_id variable -> actual body *)
- let (E_aux (_,annot)) = v in
- let annot_pat = (Parse_ast.Unknown,simple_annot (gettype v)) in
- let annot_lb = annot_pat in
- let annot_let = (Parse_ast.Unknown,simple_annot_efr (gettype body) (geteffs body)) in
- let pat = P_aux (P_id id,annot_pat) in
- E_aux (E_let (LB_aux (LB_val_implicit (pat,v),annot_lb),body),annot_let) in
-
- match lexp with
- | LEXP_aux (LEXP_id id,annot) ->
- let eid = E_aux (E_id id,(Unknown,simple_annot (gettype v))) in
- letbind eid v body
- | LEXP_aux (LEXP_cast (_,id),annot) ->
- let eid = E_aux (E_id id,(Unknown,simple_annot (gettype v))) in
- letbind eid v body
- | LEXP_aux (LEXP_vector (LEXP_aux (LEXP_id id,annot2),i),annot) ->
- let eid = E_aux (E_id id,(Unknown,simple_annot (gettype_annot annot2))) in
- let v = E_aux (E_vector_update (eid,i,v),(Unknown,simple_annot (gettype_annot annot))) in
- letbind eid v body
- | LEXP_aux (LEXP_vector_range (LEXP_aux (LEXP_id id,annot2),i,j),annot) ->
- let eid = E_aux (E_id id,(Unknown,simple_annot (gettype_annot annot2))) in
- let v = E_aux (E_vector_update_subrange (eid,i,j,v),
- (Unknown,simple_annot (gettype_annot annot))) in
- letbind eid v body in
-
- match expaux with
- | E_let (LB_aux (LB_val_explicit (_,_,E_aux (E_assign (lexp,v),annot2)),_),body)
- | E_let (LB_aux (LB_val_implicit (_,E_aux (E_assign (lexp,v),annot2)),_),body)
- when let {effect = Eset effs} = geteffs_annot annot2 in
- List.exists (function BE_aux (BE_lset,_) -> true | _ -> false) effs ->
- f v body lexp
- | E_let (lb,body) -> E_aux (E_let (lb,body),annot)
- (* E_internal_plet is only used for effectful terms, shouldn't be needed to deal with here *)
- | E_internal_let (LEXP_aux ((LEXP_id id | LEXP_cast (_,id)),_),v,body) ->
- let (E_aux (_,pannot)) = v in
- let lbannot = (Parse_ast.Unknown,simple_annot_efr (gettype body) (geteffs body)) in
- E_aux (E_let (LB_aux (LB_val_implicit (P_aux (P_id id,pannot),v),lbannot),body),annot)
- | E_assign (lexp,v)
- when let {effect = Eset effs} = geteffs_annot annot in
- List.exists (function BE_aux (BE_lset,_) -> true | _ -> false) effs ->
- f v (E_aux (E_lit (L_aux (L_unit,Unknown)), (Unknown,simple_annot ({t = Tid "unit"})))) lexp
-
-
- | _ -> E_aux (expaux,annot) in
-
- { id_exp_alg with e_aux = e_aux }
- *)
-
let replace_memwrite_e_assign exp =
let e_aux = fun (expaux,annot) ->
match expaux with