summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pretty_print_lem.ml6
-rw-r--r--src/rewrites.ml42
-rw-r--r--src/type_check.ml6
3 files changed, 24 insertions, 30 deletions
diff --git a/src/pretty_print_lem.ml b/src/pretty_print_lem.ml
index 1b91bb5d..822cc7b6 100644
--- a/src/pretty_print_lem.ml
+++ b/src/pretty_print_lem.ml
@@ -664,14 +664,12 @@ let doc_exp_lem, doc_let_lem =
match args with
| [exp1; exp2; exp3; ord_exp; vartuple; body] ->
let loopvar, body = match body with
- | E_aux (E_let (LB_aux (LB_val (_, _), _),
- E_aux (E_let (LB_aux (LB_val (_, _), _),
- E_aux (E_if (_,
+ | E_aux (E_if (_,
E_aux (E_let (LB_aux (LB_val (
((P_aux (P_typ (_, P_aux (P_var (P_aux (P_id id, _), _), _)), _))
| (P_aux (P_var (P_aux (P_id id, _), _), _))
| (P_aux (P_id id, _))), _), _),
- body), _), _), _)), _)), _) -> id, body
+ body), _), _), _) -> id, body
| _ -> raise (Reporting.err_unreachable l __POS__ ("Unable to find loop variable in " ^ string_of_exp body)) in
let step = match ord_exp with
| E_aux (E_lit (L_aux (L_false, _)), _) ->
diff --git a/src/rewrites.ml b/src/rewrites.ml
index 1ca39998..5fb1962e 100644
--- a/src/rewrites.ml
+++ b/src/rewrites.ml
@@ -3772,24 +3772,22 @@ let rec rewrite_var_updates ((E_aux (expaux,((l,_) as annot))) as exp) =
|> mk_var_exps_pats pl env
in
let exp4 = rewrite_var_updates (add_vars overwrite exp4 vars) in
- let ord_exp, kids, constr, lower, upper, lower_exp, upper_exp =
- match destruct_numeric (Env.expand_synonyms env (typ_of exp1)), destruct_numeric (Env.expand_synonyms env (typ_of exp2)) with
- | None, _ | _, None ->
- raise (Reporting.err_unreachable el __POS__ "Could not determine loop bounds")
- | Some (kids1, constr1, n1), Some (kids2, constr2, n2) ->
- let kids = kids1 @ kids2 in
- let constr = nc_and constr1 constr2 in
- let ord_exp, lower, upper, lower_exp, upper_exp =
- if is_order_inc order
- then (annot_exp (E_lit (mk_lit L_true)) el env bool_typ, n1, n2, exp1, exp2)
- else (annot_exp (E_lit (mk_lit L_false)) el env bool_typ, n2, n1, exp2, exp1)
- in
- ord_exp, kids, constr, lower, upper, lower_exp, upper_exp
- in
(* Bind the loop variable in the body, annotated with constraints *)
let lvar_kid = mk_kid ("loop_" ^ string_of_id id) in
- let lvar_nc = nc_and constr (nc_and (nc_lteq lower (nvar lvar_kid)) (nc_lteq (nvar lvar_kid) upper)) in
- let lvar_typ = mk_typ (Typ_exist (List.map (mk_kopt K_int) (lvar_kid :: kids), lvar_nc, atom_typ (nvar lvar_kid))) in
+ let lower_id = mk_id ("loop_" ^ string_of_id id ^ "_lower") in
+ let upper_id = mk_id ("loop_" ^ string_of_id id ^ "_upper") in
+ let lower_kid = mk_kid ("loop_" ^ string_of_id id ^ "_lower") in
+ let upper_kid = mk_kid ("loop_" ^ string_of_id id ^ "_upper") in
+ let lower_id_exp = annot_exp (E_id lower_id) el env (atom_typ (nvar lower_kid)) in
+ let upper_id_exp = annot_exp (E_id upper_id) el env (atom_typ (nvar upper_kid)) in
+ let annot_bool_lit lit = annot_exp (E_lit lit) el env bool_typ in
+ let ord_exp, lower_exp, upper_exp, exp1, exp2 =
+ if is_order_inc order
+ then annot_bool_lit (mk_lit L_true), exp1, exp2, lower_id_exp, upper_id_exp
+ else annot_bool_lit (mk_lit L_false), exp2, exp1, upper_id_exp, lower_id_exp
+ in
+ let lvar_nc = nc_and (nc_lteq (nvar lower_kid) (nvar lvar_kid)) (nc_lteq (nvar lvar_kid) (nvar upper_kid)) in
+ let lvar_typ = mk_typ (Typ_exist (List.map (mk_kopt K_int) [lvar_kid], lvar_nc, atom_typ (nvar lvar_kid))) in
let lvar_pat = unaux_pat (add_p_typ lvar_typ (annot_pat (P_var (
annot_pat (P_id id) el env (atom_typ (nvar lvar_kid)),
TP_aux (TP_var lvar_kid, gen_loc el))) el env lvar_typ)) in
@@ -3805,23 +3803,21 @@ let rec rewrite_var_updates ((E_aux (expaux,((l,_) as annot))) as exp) =
that would force the loop to be effectful, so we use an if-expression
instead. This code assumes that the loop bounds have (possibly
existential) atom types, and the loop body has type unit. *)
- let lower_kid = mk_kid ("loop_" ^ string_of_id id ^ "_lower") in
- let lower_pat = P_var (annot_pat P_wild el env (typ_of lower_exp), mk_typ_pat (TP_app (mk_id "atom", [mk_typ_pat (TP_var lower_kid)]))) in
+ let lower_pat = P_var (annot_pat (P_id lower_id) el env (typ_of lower_exp), mk_typ_pat (TP_app (mk_id "atom", [mk_typ_pat (TP_var lower_kid)]))) in
let lb_lower = annot_letbind (lower_pat, lower_exp) el env (typ_of lower_exp) in
- let upper_kid = mk_kid ("loop_" ^ string_of_id id ^ "_upper") in
- let upper_pat = P_var (annot_pat P_wild el env (typ_of upper_exp), mk_typ_pat (TP_app (mk_id "atom", [mk_typ_pat (TP_var upper_kid)]))) in
+ let upper_pat = P_var (annot_pat (P_id upper_id) el env (typ_of upper_exp), mk_typ_pat (TP_app (mk_id "atom", [mk_typ_pat (TP_var upper_kid)]))) in
let lb_upper = annot_letbind (upper_pat, upper_exp) el env (typ_of upper_exp) in
let guard = annot_exp (E_constraint (nc_lteq (nvar lower_kid) (nvar upper_kid))) el env bool_typ in
let unit_exp = annot_exp (E_lit (mk_lit L_unit)) el env unit_typ in
let skip_val = tuple_exp (if overwrite then vars else unit_exp :: vars) in
- let guarded_body =
+ let guarded_body = fix_eff_exp (annot_exp (E_if (guard, body, skip_val)) el env (typ_of exp4)) in
+ let v =
fix_eff_exp (annot_exp (E_let (lb_lower,
fix_eff_exp (annot_exp (E_let (lb_upper,
- fix_eff_exp (annot_exp (E_if (guard, body, skip_val))
+ fix_eff_exp (annot_exp (E_app (mk_id "foreach", [exp1; exp2; exp3; ord_exp; tuple_exp vars; guarded_body]))
el env (typ_of exp4))))
el env (typ_of exp4))))
el env (typ_of exp4)) in
- let v = fix_eff_exp (annot_exp (E_app (mk_id "foreach", [exp1; exp2; exp3; ord_exp; tuple_exp vars; guarded_body])) el env (typ_of body)) in
Added_vars (v, tuple_pat (if overwrite then varpats else pat :: varpats))
| E_loop(loop,cond,body) ->
(* Find variables that might be updated in the loop body and are used
diff --git a/src/type_check.ml b/src/type_check.ml
index 9ece1e25..4ac81528 100644
--- a/src/type_check.ml
+++ b/src/type_check.ml
@@ -1518,11 +1518,11 @@ and unify_constraint l env goals (NC_aux (aux1, _) as nc1) (NC_aux (aux2, _) as
List.fold_left (merge_uvars l) KBindings.empty (List.map2 (unify_typ_arg l env goals) args1 args2)
| NC_equal (n1a, n2a), NC_equal (n1b, n2b) ->
merge_uvars l (unify_nexp l env goals n1a n1b) (unify_nexp l env goals n2a n2b)
- | NC_not_equal (n1a, n2a), NC_equal (n1b, n2b) ->
+ | NC_not_equal (n1a, n2a), NC_not_equal (n1b, n2b) ->
merge_uvars l (unify_nexp l env goals n1a n1b) (unify_nexp l env goals n2a n2b)
- | NC_bounded_ge (n1a, n2a), NC_equal (n1b, n2b) ->
+ | NC_bounded_ge (n1a, n2a), NC_bounded_ge (n1b, n2b) ->
merge_uvars l (unify_nexp l env goals n1a n1b) (unify_nexp l env goals n2a n2b)
- | NC_bounded_le (n1a, n2a), NC_equal (n1b, n2b) ->
+ | NC_bounded_le (n1a, n2a), NC_bounded_le (n1b, n2b) ->
merge_uvars l (unify_nexp l env goals n1a n1b) (unify_nexp l env goals n2a n2b)
| NC_true, NC_true -> KBindings.empty
| NC_false, NC_false -> KBindings.empty