summaryrefslogtreecommitdiff
path: root/verify
diff options
context:
space:
mode:
authorDana N. Xu <na.xu@inria.fr>2012-06-27 09:18:07 +0000
committerDana N. Xu <na.xu@inria.fr>2012-06-27 09:18:07 +0000
commit32851818f25f997f1909279de0d5b058bb8c2a04 (patch)
treea070c4bdd40d4ee972e5f43394661babcb4f4f13 /verify
parente1c3f3235fac2e0c110d873dace80ac35c50c848 (diff)
downloadocaml-32851818f25f997f1909279de0d5b058bb8c2a04.tar.gz
insert and riser work
git-svn-id: http://caml.inria.fr/svn/ocaml/branches/contracts@12648 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'verify')
-rw-r--r--verify/esc.ml408
-rw-r--r--verify/escSyn.ml319
-rw-r--r--verify/escSyn.mli3
-rw-r--r--verify/thmEnv.ml51
-rw-r--r--verify/thmEnv.mli10
-rw-r--r--verify/thmProvers.ml2
-rw-r--r--verify/toErgosrc.ml16
-rw-r--r--verify/toErgosrc.mli1
-rw-r--r--verify/verify.ml163
9 files changed, 660 insertions, 313 deletions
diff --git a/verify/esc.ml b/verify/esc.ml
index 8a1e8b387e..de401adb60 100644
--- a/verify/esc.ml
+++ b/verify/esc.ml
@@ -198,10 +198,10 @@ type outname = Path.t
(* Types for continuation *)
-type cont = (* e a1 HOLE an *)
- Cargs of ThmEnv.t (* same env for all args *)
- * inexp (* function *)
- * (inexp option * optional) list (* args done *)
+type cont = (* f a1 HOLE an *)
+ Cargs of ThmEnv.t (* env for undone args *)
+ * outexp (* function *)
+ * (outexp option * optional) list (* args done *)
* optional (* for current arg being simplified *)
* (inexp option * optional) list (*args not done *)
* type_expr (* result type *)
@@ -212,16 +212,21 @@ type cont = (* e a1 HOLE an *)
| CLam of expression (* original expression *)
* pattern *partial (* \x.HOLE *)
| Cprim of (inexp option * optional) list * type_expr (* op HOLE e2 *)
+ | Ccons of ThmEnv.t * expression * (* original expression *)
+ Path.t * constructor_description *
+ outexp list * inexp list (* K(HOLE,e) *)
| Cin of rec_flag * (pattern * outexp) list (* let x = e1 in HOLE *)
(* let x1 = a1
x = HOLE
x2 = a2
in e2 *)
- | Clet of rec_flag * (pattern * outexp) list *
+ | Clet of ThmEnv.t * rec_flag * (pattern * outexp) list *
pattern * (pattern * inexp) list * inexp
| Cmatch of (ThmEnv.t * expression (* original env and expression *)
* inalt list * partial) (* match HOLE with x alts *)
| Cif of (ThmEnv.t * expression * expression option) (* if HOLE then e1 else e2 *)
+ | Cthen of (ThmEnv.t * outexp * inexp option) (* if a0 then HOLE else e2 *)
+ | Celse of (outexp * outexp) (* if a0 then a1 else HOLE *)
| Ctry of inalt list
(* Symbolically simplify pure expression in Typedtree.expression *)
@@ -243,18 +248,25 @@ let is_contract_exception e = match e.exp_desc with
the senv contains both the mapping from variable to value and
the logical store *)
let rec simpl_expr (senv : ThmEnv.t) (exp : expression) (k: cont list) : expression =
- (* print_string "***esc.simpl_expr: \n"; print_expression exp; print_string "\n"; *)
+ trace "***esc.simpl_expr" print_expression exp;
let mkexp desc = {exp with exp_desc = desc} in
match exp.exp_desc with
- | Texp_constant (c) -> rebuild senv exp k
- | Texp_bad (bl) -> rebuild senv exp k
- | Texp_unr (bl) -> rebuild senv exp k
+ | Texp_constant (c) -> rebuild exp k
+ | Texp_bad (bl) -> rebuild exp k
+ | Texp_unr (bl) -> rebuild exp k
| Texp_ident (path, vdesc) ->
begin match path with
| Pident id ->
- let aval = lookup_senv id senv in
- rebuildVar senv (id, exp) aval k
- | _ -> rebuild senv exp k
+ begin
+ let aval = lookup_senv id senv in
+ match aval with
+ | NoVal -> if depth senv = 1
+ then rebuild (try lookup_nonrec_env id senv
+ with Not_found -> exp) k
+ else rebuild exp k
+ | _ -> rebuildVar (id, exp) aval k
+ end
+ | _ -> rebuild exp k
end
| Texp_function (pat_expr_list, ptial) ->
(* NEW: we generate logic v : <type of v>
@@ -264,7 +276,7 @@ let rec simpl_expr (senv : ThmEnv.t) (exp : expression) (k: cont list) : express
let env1 = add_tasks senv (bound_vars_to_logic p) in
(p, simpl_expr env1 e []))
pat_expr_list in
- rebuild senv {exp with exp_desc = Texp_function (simpl_list, ptial)} k
+ rebuild {exp with exp_desc = Texp_function (simpl_list, ptial)} k
| Texp_apply (e1, eopt_optl_list) ->
(* A-normalize the arguments *)
let rec genLet xs = match xs with
@@ -291,14 +303,16 @@ let rec simpl_expr (senv : ThmEnv.t) (exp : expression) (k: cont list) : express
let (args, p_e_list) = genLet eopt_optl_list in
begin match p_e_list with
| [] ->
- simpl_expr senv e1 (Capp (senv, [], eopt_optl_list, exp.exp_type)::k)
+ simpl_expr senv e1 (Capp (senv, [], args, exp.exp_type)::k)
| _ ->
simpl_expr senv ({exp with exp_desc = Texp_let (Nonrecursive, p_e_list,
{exp with exp_desc = Texp_apply(e1, args)})}) k
end
| Texp_match (e0, pat_expr_list, ptial) ->
begin match k with
- | (Capp (env, [], nds, res_type) :: k1) -> (* [matchR] *)
+ | (Capp (env, [], nds, res_type) :: k1) ->
+ (* (match e0 with pi -> ei) val ==> [matchL]
+ match e0 with pi -> ei val *)
let p_e_list = List.map (fun (p,e) -> (p,
{ exp_desc = Texp_apply(e, nds);
exp_loc = e.exp_loc;
@@ -308,33 +322,33 @@ let rec simpl_expr (senv : ThmEnv.t) (exp : expression) (k: cont list) : express
pat_expr_list in
let expr1 = {exp with exp_desc = Texp_match (e0, p_e_list, ptial)} in
simpl_expr senv expr1 k1
- | (Clet (rflag, ds, p, uds, e2) :: k1) ->
+ | (Clet (env, rflag, ds, p, uds, e2) :: k1) ->
(* let x = (match e0 with K x -> ei) in e2 ==> [let-match]
match e0 with K x -> let x = ei in e2 *)
- if rflag = Nonrecursive then
+ begin match rflag with
+ | Nonrecursive ->
let rhs = {exp with exp_desc = Texp_match(e0,
List.map (fun (pi,ei) -> (pi, {ei with exp_desc =
Texp_let (rflag, (p,ei)::uds, e2)})) pat_expr_list, ptial)}
in simpl_expr senv rhs (Cin (rflag, ds)::k1)
- else simpl_expr senv e0 (Cmatch (senv, exp, pat_expr_list, ptial) :: k)
+ | _ -> simpl_expr senv e0 (Cmatch (senv, exp, pat_expr_list, ptial) :: k)
+ end
| _ -> simpl_expr senv e0 (Cmatch (senv, exp, pat_expr_list, ptial) :: k)
end
| Texp_try (e, pat_expr_list) ->
simpl_expr senv e ((Ctry pat_expr_list) :: k)
| Texp_tuple (es) ->
let new_es = List.map (fun e -> simpl_expr senv e []) es in
- rebuild senv (mkexp (Texp_tuple new_es)) k
- | Texp_construct (path, constr_desc, es) ->
- let new_es = List.map (fun e -> simpl_expr senv e []) es in
- rebuild senv (mkexp (Texp_construct (path, constr_desc, new_es))) k
+ rebuild (mkexp (Texp_tuple new_es)) k
+ | Texp_construct (path, cdesc, es) ->
+ begin match es with
+ | [] -> rebuild exp k
+ | (e::l) -> simpl_expr senv e (Ccons(senv, exp, path, cdesc, [], l) :: k)
+ end
| Texp_ifthenelse (e0, e1, e2opt) ->
- (* if (if e0 then e1 else e2) then e11 else e22
- ==> [if-if]
- if e0 then (if e1 then e11 else e22)
- else (if e2 then e11 else e22)
- *)
begin match k with
| (Cif (env, e11, e22opt) :: k1) ->
+ (* [if-if] *)
let rhs = {e1 with exp_desc = Texp_ifthenelse (e0,
{ e1 with exp_desc = Texp_ifthenelse (e1, e11, e22opt) },
match e2opt with
@@ -353,32 +367,24 @@ let rec simpl_expr (senv : ThmEnv.t) (exp : expression) (k: cont list) : express
let rhs = {e_match with exp_desc = Texp_let (rflag, pat_expr_list,
{e_match with exp_desc = Texp_match (expr, alts, ptial)})}
in simpl_expr env rhs k1
- | (Cif (env, then_e, else_eopt):: k1) ->
- (* if (let x = e1 in e2) then .. else ..
- ==> [if-let]
- let x = e1 in if e2 then .. else ..
- *)
- let rhs = {then_e with exp_desc = Texp_let (rflag, pat_expr_list,
- {then_e with exp_desc = Texp_ifthenelse (expr, then_e, else_eopt)})}
- in simpl_expr env rhs k1
| _ -> begin match pat_expr_list with
| [] -> simpl_expr senv expr k
| (p,e)::l -> begin match (p.pat_desc, e.exp_desc) with
| (Tpat_var (id1), Texp_ident (Pident id2, _))
when rflag = Nonrecursive && id1 = id2 ->
simpl_expr senv ({exp with exp_desc = Texp_let (rflag, l, expr)}) k
- | _ -> simpl_expr senv e (Clet (rflag, [], p, l, expr) ::k)
+ | _ -> simpl_expr senv e (Clet (senv, rflag, [], p, l, expr) ::k)
end
end
end
| Texp_sequence (e1, e2) ->
let new_e1 = simpl_expr senv e1 k in
let new_e2 = simpl_expr senv e2 k in
- rebuild senv (mkexp (Texp_sequence (new_e1, new_e2))) k
+ rebuild (mkexp (Texp_sequence (new_e1, new_e2))) k
| Texp_array (es) ->
let new_es = List.map (fun e -> simpl_expr senv e []) es in
- rebuild senv (mkexp (Texp_array new_es)) k
- | others -> rebuild senv exp k
+ rebuild (mkexp (Texp_array new_es)) k
+ | others -> rebuild exp k
(* This is for dealing with primitive binary operators such as > , <, etc *)
and simpl_primitive_app senv exp f args k = match args with
@@ -429,9 +435,9 @@ and simpl_primitive_app senv exp f args k = match args with
simpl_expr senv ({exp with exp_desc = Texp_ifthenelse (e0,
{exp with exp_desc = new_e1}, Some {exp with exp_desc = new_e2})}) k
end
- | _ -> rebuild senv exp k
+ | _ -> rebuild exp k
end
-| _ -> rebuild senv exp k
+| _ -> rebuild exp k
and simpl_args senv f ds nds res_type k = match nds with
| [] -> (* this means all args are simplified *)
@@ -450,7 +456,7 @@ and simpl_args senv f ds nds res_type k = match nds with
exp_env = p.pat_env } in
let env2 = extend_senv senv id eid in
begin match ds with
- | [] -> rebuild senv f k
+ | [] -> rebuild f k
| [(None, optl)] ->
simpl_expr senv e k
| [(Some a, optl)] ->
@@ -474,12 +480,12 @@ and simpl_args senv f ds nds res_type k = match nds with
| (None, optl)::rest ->
simpl_args senv e rest [] e.exp_type k
end
- | _ -> rebuild senv expr k
+ | _ -> rebuild expr k
end
| Texp_ident(path, vd) ->
begin match vd.val_kind with
| Val_prim _ -> simpl_primitive_app senv expr f ds k
- | _ -> rebuild senv expr k
+ | _ -> rebuild expr k
end
| Texp_let(rflag, pat_exp_list, e2) ->
(* (let x = e1 in \y.e') a ==> let x = e1 in (\y.e') a *)
@@ -493,7 +499,7 @@ and simpl_args senv f ds nds res_type k = match nds with
| Some else_e -> Some { expr with exp_desc =
Texp_apply(else_e, ds) } in
simpl_expr senv ({expr with exp_desc = Texp_ifthenelse(e0, new_then, new_else)}) k
- | _ -> rebuild senv expr k
+ | _ -> rebuild expr k
end
| ((Some e, optl) :: l) ->
simpl_expr senv e (Cargs (senv, f, ds, optl, l, res_type) :: k)
@@ -502,8 +508,8 @@ and simpl_args senv f ds nds res_type k = match nds with
and rebuildMatch senv scrut aval alts ptial k =
let env1 = extend_denv senv scrut aval in
- let (_,e) = List.hd alts in
let goal_tasks = goalTasks senv in
+ let (_,e) = List.hd alts in
let new_alts = List.map (fun (p,e) ->
let env2 = add_tasks env1 (bound_vars_to_logic p) in
if is_bad e then
@@ -525,14 +531,14 @@ and rebuildMatch senv scrut aval alts ptial k =
let senv2 = extend_senv env4 id1 eid in
let senv3 = extend_denv senv2 eid (Inline ({scrut with exp_desc =
Texp_construct(path,cdesc,[])})) in
- (p, simpl_expr senv3 e k)
- | _ -> (p,simpl_expr env4 e k)
+ (p, simpl_expr senv3 e [])
+ | _ -> (p,simpl_expr env4 e [])
end
end
else let env4 = add_tasks env2 [toAxiom_peq scrut p] in
- (p,simpl_expr env4 e k)
+ (p,simpl_expr env4 e [])
) alts in
- {e with exp_desc = Texp_match (scrut, new_alts, ptial)}
+ rebuild {e with exp_desc = Texp_match (scrut, new_alts, ptial)} k
and ergo_counter = ref 1
@@ -553,24 +559,25 @@ and rebuildIf senv scrut e1 e2opt k =
match is_expression_true scrut with
| Ptrue -> simpl_expr senv e1 k
| Pfalse -> begin match e2opt with
- | None -> rebuild senv (mkexp (Texp_ifthenelse (scrut, unr_exp, None))) k
+ | None -> rebuild (mkexp (Texp_ifthenelse (scrut, unr_exp, None))) k
| Some e2 -> simpl_expr senv e2 k
end
| Pothers -> begin match e2opt with
| Some e2 -> begin match e2.exp_desc with
- | Texp_bad _ when (is_scrutinee_ergoble scrut) ->
+ | Texp_bad _ when (is_expression_ergoble scrut) ->
let goal_tasks = goalTasks senv in
let senv1 = if is_prop
then add_tasks senv (goal_tasks@[toGoal scrut])
else add_tasks senv (goal_tasks@[toGoal_beq scrut]) in
let ts1 = tasks senv1 in
let inits = (Location.toString scrut.exp_loc) in
- let filename = inits^"_"^(string_of_int !ergo_counter)^"_if.why" in
+ let filename = inits^"_"^(string_of_int !ergo_counter)^"_ifelse.why" in
ergo_counter := !ergo_counter + 1;
write_tasks_to_file filename ts1;
- (* print_string "call altergo: \n"; print_expression scrut; *)
+ (* trace ("call altergo "^filename^": \n") print_expression scrut; *)
begin match askErgo filename ts1 with
| Valid -> (* scrutinee is Valid *)
+ (* print_string "Valid"; *)
simpl_expr then_senv2 e1 k
| _ -> (* we omit the negation check for the moment
let senv2 = add_tasks senv (goal_tasks@[toGoal_bneg scrut]) in
@@ -583,22 +590,46 @@ and rebuildIf senv scrut e1 e2opt k =
let else_senv2 = add_tasks else_senv
[toAxiom_bneq scrut] in
simpl_expr else_senv2 e2 k
- | None -> rebuild senv (mkexp (Texp_ifthenelse
+ | None -> rebuild (mkexp (Texp_ifthenelse
((falseExpression scrut), unr_exp, None))) k
end
| _ -> *) (* no validity info about scrutinee *)
+ (* print_string "Don't know"; *)
let new_e1 = simpl_expr then_senv2 e1 [] in
- rebuild senv (mkexp (Texp_ifthenelse
+ rebuild (mkexp (Texp_ifthenelse
(scrut, new_e1, e2opt))) k
end
| _ ->
+ begin match e1.exp_desc with
+ | Texp_bad _ when (is_expression_ergoble scrut) ->
+ let goal_tasks = goalTasks senv in
+ let senv1 = if is_prop
+ then add_tasks senv (goal_tasks@[toGoal_neg scrut])
+ else add_tasks senv (goal_tasks@[toGoal_bneq scrut]) in
+ let ts1 = tasks senv1 in
+ let inits = (Location.toString scrut.exp_loc) in
+ let filename = inits^"_"^(string_of_int !ergo_counter)^"_ifthen.why" in
+ ergo_counter := !ergo_counter + 1;
+ write_tasks_to_file filename ts1;
+ (* trace ("call altergo "^filename^": \n") print_expression scrut; *)
+ begin match askErgo filename ts1 with
+ | Valid -> (* scrutinee is Valid *)
+ (* print_string "Valid"; *)
+ simpl_expr else_senv2 e2 k
+ | _ -> (* print_string "Don't know"; *)
+ let new_e2 = simpl_expr else_senv2 e2 [] in
+ rebuild (mkexp (Texp_ifthenelse
+ (scrut, e1, Some new_e2))) k
+ end
+ | _ ->
let new_e1 = simpl_expr then_senv2 e1 [] in
let new_e2 = Some (simpl_expr else_senv2 e2 []) in
- rebuild senv (mkexp (Texp_ifthenelse (scrut, new_e1, new_e2))) k
+ rebuild (mkexp (Texp_ifthenelse (scrut, new_e1, new_e2))) k
+ end
end
| None ->
let new_e1 = simpl_expr then_senv2 e1 [] in
- rebuild senv (mkexp (Texp_ifthenelse (scrut, new_e1, None))) k
+ rebuild (mkexp (Texp_ifthenelse (scrut, new_e1, None))) k
end
(*
@@ -617,6 +648,7 @@ and knownCon senv (path, cdesc) es alts k =
let xs = List.filter (fun (p,e) -> match p.pat_desc with
| Tpat_construct (path2, cdesc2, ps) -> cdesc.cstr_tag = cdesc2.cstr_tag
| _ -> false) alts in
+ print_string "No branch is matched";
let (p,e) = List.hd xs in
match p.pat_desc with
| Tpat_construct (path2, cdesc2, ps) ->
@@ -625,47 +657,94 @@ and knownCon senv (path, cdesc) es alts k =
| _ -> raise(Error(KnownCon_impossible_pattern))
-and rebuild senv a k =
+and rebuild a k =
+ trace "***esc.rebuild" print_expression a;
(* print_string "***esc.rebuild: \n"; print_expression a; print_string "\n"; *)
match (a.exp_desc, k) with
| (_, []) -> a
- | (Texp_bad (bl), Cmatch _ :: k1) -> rebuild senv a k1
- | (Texp_bad (bl), Cif _ :: k1) -> rebuild senv a k1
- | (Texp_bad (bl), Capp _ :: k1) -> rebuild senv a k1
- | (Texp_bad (bl), Cargs _ :: k1) -> rebuild senv a k1
- | (Texp_bad (bl), Clet _ :: k1) -> rebuild senv a k1
- | (Texp_bad (bl), Cin _ :: k1) -> rebuild senv a k1
- | (Texp_unr (bl), Cmatch _ :: k1) -> rebuild senv a k1
- | (Texp_unr (bl), Cif _ :: k1) -> rebuild senv a k1
- | (Texp_unr (bl), Capp _ :: k1) -> rebuild senv a k1
- | (Texp_unr (bl), Cargs _ :: k1) -> rebuild senv a k1
- | (Texp_unr (bl), Clet _ :: k1) -> rebuild senv a k1
- | (Texp_unr (bl), Cin _ :: k1) -> rebuild senv a k1
+ | (Texp_bad (bl), Cmatch _ :: k1) -> rebuild a k1
+ | (Texp_bad (bl), Cif _ :: k1) -> rebuild a k1
+ | (Texp_bad (bl), Capp _ :: k1) -> rebuild a k1
+ | (Texp_bad (bl), Cargs _ :: k1) -> rebuild a k1
+ | (Texp_bad (bl), Cprim _ :: k1) -> rebuild a k1
+ | (Texp_bad (bl), Ccons _ :: k1) -> rebuild a k1
+ | (Texp_bad (bl), Clet _ :: k1) -> rebuild a k1
+ | (Texp_bad (bl), Cin _ :: k1) -> rebuild a k1
+ | (Texp_unr (bl), Cmatch _ :: k1) -> rebuild a k1
+ | (Texp_unr (bl), Cif _ :: k1) -> rebuild a k1
+ | (Texp_unr (bl), Capp _ :: k1) -> rebuild a k1
+ | (Texp_unr (bl), Cargs _ :: k1) -> rebuild a k1
+ | (Texp_unr (bl), Cprim _ :: k1) -> rebuild a k1
+ | (Texp_unr (bl), Ccons _ :: k1) -> rebuild a k1
+ | (Texp_unr (bl), Clet _ :: k1) -> rebuild a k1
+ | (Texp_unr (bl), Cin _ :: k1) -> rebuild a k1
| (Texp_construct (path, cdesc, es),
Cmatch (matchenv, e_match, alts, ptial) :: k1) ->
knownCon matchenv (path, cdesc) es alts k1
| (_, CLam (e, p, ptial) :: k1) ->
- rebuild senv {e with exp_desc = Texp_function ([(p,a)], ptial)} k1
+ rebuild {e with exp_desc = Texp_function ([(p,a)], ptial)} k1
| (_, Cargs (env, f, ds, optl, nds, res_type) :: k1) ->
simpl_args env f (ds@[(Some a, optl)]) nds res_type k1
| (_, Capp (env, ds, nds, res_type) :: k1) ->
simpl_args env a ds nds res_type k1
- | (_, Clet (rflag, ds, p, uds, e3) :: k1) ->
+ | (_, Ccons(env, e, path, cdesc, ds, uds) :: k1) ->
+ begin match uds with
+ | [] -> if List.for_all is_expression_tvalue ds then
+ begin match a.exp_desc with
+ | Texp_match(e0, pat_exp_list, ptial) ->
+ rebuildMatch env e0 NoVal
+ (List.map (fun (pi,ei) -> (pi,
+ {ei with exp_desc=Texp_construct(path, cdesc, ds@[ei])}))
+ pat_exp_list) ptial k1
+ | Texp_ifthenelse(a0, a1, a2opt) ->
+ let new_a1 = {a1 with exp_desc=Texp_construct(path,cdesc,ds@[a1])} in
+ let new_a2opt = match a2opt with
+ | None -> None
+ | Some a2 -> Some ({a2 with exp_desc=Texp_construct(path,cdesc,ds@[a2])}) in
+ rebuildIf env a0 new_a1 new_a2opt k1
+ | Texp_let (rflag, pat_exp_list, expr) ->
+ let e2 = {e with exp_desc=Texp_construct(path,cdesc,ds@[expr])} in
+ rebuild ({expr with exp_desc=Texp_let(rflag, pat_exp_list, e2)}) k1
+ | _ ->
+ rebuild ({e with exp_desc=Texp_construct(path,cdesc,ds@[a])}) k1
+ end
+ else rebuild ({e with exp_desc=Texp_construct(path,cdesc,ds@[a])}) k1
+ | (x::l) ->
+ if List.for_all is_expression_tvalue ds then
+ begin match x.exp_desc with
+ | Texp_match(e0, pat_exp_list, ptial) ->
+ let alts = List.map (fun (pi,ei) -> (pi,
+ {ei with exp_desc=Texp_construct(path, cdesc, ds@[a;ei]@l)}))
+ pat_exp_list in
+ simpl_expr env x (Cmatch (env, x, alts, ptial) :: k1)
+ | Texp_ifthenelse(e0, e1, e2opt) ->
+ let new_e1 = {e1 with exp_desc=Texp_construct(path,cdesc,ds@[a;e1]@l)} in
+ let new_e2opt = match e2opt with
+ | None -> None
+ | Some e2 -> Some ({e2 with exp_desc=Texp_construct(path,cdesc,ds@[a;e2]@l)}) in
+ simpl_expr env e0 (Cif (env, new_e1, new_e2opt) :: k1)
+ | _ -> simpl_expr env x (Ccons(env,e,path,cdesc,ds@[a],l) :: k1)
+ end
+ else rebuild ({e with exp_desc=Texp_construct(path,cdesc,ds@[a])}) k1
+ end
+ | (_, Clet (senv, rflag, ds, p, uds, e3) :: k1) ->
begin match p.pat_desc with
- | Tpat_var (id1) when rflag = Nonrecursive &&
- ((is_expression_tvalue a) || (match e3.exp_desc with
+ | Tpat_var (id1) when rflag = Nonrecursive &&
+ ((is_expression_tvalue a) || (match e3.exp_desc with
| Texp_ident(Pident id2, vd) -> id2 = id1
| _ -> false)) ->
- let new_id = Ident.rename id1 in
- let vd = { val_type = a.exp_type; val_kind = Val_reg } in
- let eid = {a with exp_desc = Texp_ident(Pident new_id, vd)} in
- let env2 = extend_senv senv id1 eid in
- let env3 = extend_denv env2 eid (Inline a) in
+ let new_id = Ident.rename id1 in
+ let vd = { val_type = a.exp_type; val_kind = Val_reg } in
+ let eid = {a with exp_desc = Texp_ident(Pident new_id, vd)} in
+ let env2 = extend_senv senv id1 eid in
+ let new_senv = extend_denv env2 eid (Inline a) in
+ (* else extend_denv senv {a with exp_desc=Texp_ident(Pident id1, vd)} (Inline a) *)
+
begin match uds with
- | [] -> simpl_expr env3 e3 (Cin (rflag, ds) :: k1)
+ | [] -> simpl_expr new_senv e3 (Cin (rflag, ds) :: k1)
| ((x,e)::l) ->
- simpl_expr env3 e (Clet (rflag, ds, x, l, e3) :: k1)
- end
+ simpl_expr new_senv e (Clet (new_senv, rflag, ds, x, l, e3) :: k1)
+ end
| _ -> begin match a.exp_desc with
| Texp_let(rec_flag, pelist, a2) ->
(* let x = (let y = a1 in a2) in e3 ==> [let-let]
@@ -677,7 +756,7 @@ and rebuild senv a k =
simpl_expr env2 e3 (Cin (rflag, ds@pelist@[(p,a2)]) :: k1)
| ((x,e)::l) ->
let env2 = add_tasks senv ((bound_vars_to_logic p)@[toAxiom_peq a p]) in
- simpl_expr env2 e (Clet (rflag, ds@[(p,a2)], x, l, e3) :: k1)
+ simpl_expr env2 e (Clet (env2, rflag, ds@[(p,a2)], x, l, e3) :: k1)
end
| Texp_ifthenelse (a0, a1, a2opt) when rflag = Nonrecursive ->
(* let x1 = ..
@@ -685,13 +764,15 @@ and rebuild senv a k =
xn = ..
in e3 ==> [let-if]
let x1 = ..
- if a0 then let x = a1
+ in if a0 then let x = a1
xn = ..
in e3
else let x = a2
xn = ..
in e3 *)
- let e1 = {a1 with exp_desc = Texp_let (rflag, (p,a1)::uds, e3)} in
+ let e1 = match a1.exp_desc with
+ | Texp_bad _ | Texp_unr _ -> a1
+ | _ -> {a1 with exp_desc = Texp_let (rflag, (p,a1)::uds, e3)} in
let e2opt = match a2opt with
| None -> None
| Some a2 -> begin match a2.exp_desc with
@@ -700,28 +781,56 @@ and rebuild senv a k =
Texp_let (rflag, (p,a2)::uds, e3)}
end
in rebuildIf senv a0 e1 e2opt (Cin (rflag, ds) :: k1)
+ | Texp_match(a0, pat_exp_list, ptial) when rflag = Nonrecursive ->
+ (* let x1 = ..
+ x = match a0 with pi-> ei
+ xn = ..
+ in e3 ==> [let-match]
+ let x1 = ..
+ in match a0 with pi -> let x = a1
+ xn = ..
+ in e3
+ *)
+ let alts = List.map (fun (pi,ai) ->
+ (pi, match ai.exp_desc with
+ | Texp_bad _ | Texp_unr _ -> ai
+ | _ -> {ai with exp_desc = Texp_let (rflag, (p,ai)::uds, e3)}))
+ pat_exp_list in
+ rebuildMatch senv a0 NoVal alts ptial (Cin (rflag, ds) :: k1)
| _ ->
let env2 = add_tasks senv ((bound_vars_to_logic p)@[toAxiom_peq a p]) in
begin match uds with
| [] -> simpl_expr env2 e3 (Cin (rflag, ds@[(p,a)]) :: k1)
| ((x,e)::l) ->
- simpl_expr env2 e (Clet (rflag, ds@[(p,a)], x, l, e3) :: k1)
+ simpl_expr env2 e (Clet (env2, rflag, ds@[(p,a)], x, l, e3) :: k1)
end
end
end
| (_, Cin (rflag, ds) :: k1) ->
begin match ds with
- | [] -> rebuild senv a k1
- | _ -> rebuild senv ({a with exp_desc = Texp_let (rflag, ds, a)}) k1
+ | [] -> rebuild a k1
+ | _ -> rebuild ({a with exp_desc = Texp_let (rflag, ds, a)}) k1
end
| (_, Cmatch (matchenv, e_match, alts, ptial) :: k1) ->
+ let senv = matchenv in
begin match lookup_denv a senv with
| Inline e -> (* if scrutinee reappears, replace it by its aval *)
- rebuildMatch matchenv e NoVal alts ptial k1
+ rebuildMatch senv e NoVal alts ptial k1
| _ -> (* [[ a ]]_(K x) *)
+ begin match a.exp_desc with
+ | Texp_match (a0, pat_exp_list, ptial2) ->
+ (* match (match a0 with pi -> ai) with alts
+ ==> [match-match]
+ match a0 with pi -> match ai with alts
+ *)
+ let new_alts = List.map (fun (pi,ai) ->
+ (pi, {e_match with exp_desc=Texp_match(ai,alts,ptial)}))
+ pat_exp_list in
+ rebuildMatch matchenv a0 NoVal new_alts ptial k1
+ | _ ->
if a.exp_type = Predef.type_bool
then begin
- let goal_tasks = goalTasks senv in
+ let goal_tasks = goalTasks matchenv in
let senv1 = begin if is_expression_prop a
then add_tasks senv (goal_tasks@[toGoal a])
else add_tasks senv (goal_tasks@[toGoal_beq a]) end in
@@ -742,34 +851,63 @@ and rebuild senv a k =
rebuildMatch matchenv a NoVal alts ptial k1 end
else rebuildMatch matchenv a NoVal alts ptial k1
end
- | (_, Cif (ifenv, e1, e2opt) :: k1) ->
- begin match lookup_denv a senv with
+ end
+ | (_, Cif (env, e1, e2opt) :: k1) ->
+ begin match lookup_denv a env with
| Inline e -> (* if scrutinee reappears, replace it by its aval *)
- rebuildIf ifenv e e1 e2opt k1
+ rebuildIf env e e1 e2opt k1
| _ -> begin match a.exp_desc with
- | Texp_let (rflag, pelist, e) ->
+ | Texp_let (rflag, pelist, a2) ->
(* if (let x = a1 in a2) then .. else ..
==> [if-let]
let x = a1 in if a2 then .. else ..
*)
- rebuild senv e (Cif (ifenv, e1, e2opt):: Cin (rflag, pelist) :: k1)
- | _ -> rebuildIf ifenv a e1 e2opt k1
+ rebuildIf env a2 e1 e2opt (Cin (rflag, pelist) :: k1)
+ | Texp_ifthenelse (a0, a1, a2opt) ->
+ (* if (if a0 then a1 else a2) then e1 else e2
+ ==> [if-if]
+ if a0 then (if a1 then e1 else e2)
+ else (if a2 then e1 else e2)
+ *)
+ let new_e1 = {e1 with exp_desc = Texp_ifthenelse(a1,e1,e2opt)} in
+ let new_e2opt = match a2opt with
+ | None -> None
+ | Some a2 -> Some ({e1 with exp_desc = Texp_ifthenelse(a2,e1,e2opt)})
+ in rebuildIf env a0 new_e1 new_e2opt k1
+ | Texp_match(a0, pat_exp_list, ptial) ->
+ (* if (match a0 with pi -> ai) then e1 else e2
+ ==> [if-match]
+ match a0 with pi -> if ai then e1 else e2
+ *)
+ let alts = List.map (fun (pi,ai) ->
+ (pi, {e1 with exp_desc = Texp_ifthenelse(ai,e1,e2opt)})) pat_exp_list in
+ rebuildMatch env a0 NoVal alts ptial k1
+ | _ -> rebuildIf env a e1 e2opt k1
end
end
+ | (_, Cthen (env, a0, e2opt) :: k1) ->
+ begin match e2opt with
+ | None ->
+ rebuild ({a with exp_desc = Texp_ifthenelse(a0,a,None)}) k1
+ | Some e2 ->
+ simpl_expr env e2 (Celse (a0, a) :: k1)
+ end
+ | (_, Celse (a0, a1) :: k1) ->
+ rebuild ({a1 with exp_desc = Texp_ifthenelse(a0,a1,Some a)}) k1
| _ -> raise(Error(Rebuild_pattern_not_matched))
-and rebuildVar senv ((n, e):(Ident.t * expression))
+and rebuildVar ((n, e):(Ident.t * expression))
(v:aval) (k:cont list) : outexp =
(* e is the expression form of the ident n *)
match v with
- | Inline a -> rebuild senv a k
+ | Inline a -> rebuild a k
| NotCon (cs) -> begin match k with
| Cmatch (senv, e_match, alts, ptial) :: k1 ->
rebuildMatch senv e (NotCon cs) alts ptial k1
- | _ -> rebuild senv e k
+ | _ -> rebuild e k
end
- | _ -> rebuild senv e k
+ | _ -> rebuild e k
(* report static contract checking error message *)
@@ -848,6 +986,7 @@ let static_report (id, exp) validity =
let rec has_function_call gamma exp = match exp.exp_desc with
| Texp_ident (path, vd) -> if Tbl.mem path gamma then true else false
+| Texp_constant _ -> false
| Texp_bad (bl) -> false
| Texp_unr (bl) -> false
| Texp_let (rec_flag, pat_expr_list, expr1) ->
@@ -863,6 +1002,7 @@ let rec has_function_call gamma exp = match exp.exp_desc with
has_function_call (add_fnames pat_expr_list gamma) expr1
| Texp_function (pat_expr_list, partial) ->
List.exists (fun (p,e) -> has_function_call gamma e) pat_expr_list
+| Texp_apply (e1, _) -> has_function_call gamma e1
| Texp_match (expr1, pat_expr_list, partial) ->
if has_function_call gamma expr1 then true
else List.exists (fun (p,e) -> has_function_call gamma e) pat_expr_list
@@ -938,36 +1078,50 @@ let rec rmUNR exp =
| _ -> expr
in map_expression removeUNR exp
-let static_contract_checking env contract_flag (id, exp) =
+let inline_rec id exp exp1 =
+ let expand_id e = match e.exp_desc with
+ | Texp_ident(path, vd) ->
+ if Path.unique_name path = Ident.unique_name id
+ then begin
+ rename_boundvars Tbl.empty exp1
+ end
+ else e
+ | _ -> e
+ in map_expression expand_id exp
+
+let rec static_contract_checking env contract_flag (id, exp) =
try
- (* print_string "\n raw expression: \n"; print_expression exp; *)
- let sexp = simpl_expr (update_name env (Pident id)) exp [] in
- (* print_string "\n simplified expression: \n"; print_expression sexp; *)
+ trace "raw expression" print_expression exp;
+ let senv = update_name env (Pident id) in
+ let sexp = simpl_expr senv exp [] in
+ trace "simplified expression" print_expression sexp;
let cleaned_sexp = rmUNR sexp in
- (* print_string "\n**residual code: \n"; print_expression cleaned_sexp; *)
+ (* trace "***residual code" print_expression cleaned_sexp; *)
let (counter_example, has_bad) = check cleaned_sexp in
- let validity =
- if has_bad
- then begin
- if contract_flag = -1
- then begin print_string ("\n**residual code of "^(Ident.name id)^": \n");
- print_expression sexp;
- EscSyn.Unknown
- end
- else EscSyn.Unknown
+ if has_bad
+ then begin
+ let validity = EscSyn.Unknown in
+ let rpt = static_report (id, counter_example) validity in
+ print_string ("At depth "^string_of_int(depth env)^", ");
+ fprintf std_formatter "%s" rpt;
+ match ThmEnv.depth env with
+ | 0 ->
+ let new_senv = increase_depth env in
+ static_contract_checking new_senv contract_flag (id,sexp)
+ | 1 ->
+ let the_exp = lookup_rec_env id env in
+ let expanded_exp = inline_rec id sexp the_exp in
+ let new_senv = increase_depth env in
+ static_contract_checking new_senv contract_flag (id,expanded_exp)
+ | _ ->
+ (cleaned_sexp, validity)
end
- else EscSyn.Valid
- (* if has_function_call
- function_names counter_example
- then Unknown
- else Invalid *)
- in
- (* print_string "\n validity: "; print_validity validity; *)
- (* write_tasks_to_file ((Ident.name id)^".why") (tasks env); *)
- print_newline ();
- let rpt = static_report (id, counter_example) validity in
- fprintf std_formatter "%s" rpt;
- (cleaned_sexp, validity)
+ else
+ let validity = EscSyn.Valid in
+ let rpt = static_report (id, counter_example) validity in
+ print_string ("At depth "^string_of_int(depth env)^", ");
+ fprintf std_formatter "%s" rpt;
+ (cleaned_sexp, validity)
with Error(err) -> report_error std_formatter err;
raise (Error(err))
diff --git a/verify/escSyn.ml b/verify/escSyn.ml
index c94f85eb27..e287d3e36b 100644
--- a/verify/escSyn.ml
+++ b/verify/escSyn.ml
@@ -1,6 +1,14 @@
open Types
open Typedtree
open Path
+open Format
+
+let should_trace = false
+(* try ignore(Sys.getenv "-trace"); true
+ with Not_found -> false *)
+
+let trace msg fn arg = if should_trace
+ then (printf "%s:\n" msg; fn arg; print_newline())
type validity = Valid | Invalid | Unknown | HighFailure | Timeout
@@ -61,17 +69,324 @@ let rec is_expression_argable exp = match exp.exp_desc with
List.for_all (fun (eopt, _) -> match eopt with
| Some a -> is_expression_argable a
| None -> false) args
+| Texp_construct (path, cdesc, es) ->
+ List.for_all is_expression_argable es
| _ -> false
-let rec exn_to_bad exp =
+let exn_to_bad exp =
let new_desc = match exp.exp_desc with
- | Texp_ident (path, value_desc) ->
+ (* | Texp_ident (path, value_desc) ->
+ if (Path.name path) = "Pervasives.failwith"
+ then Texp_bad (Callee (exp.exp_loc, path))
+ else exp.exp_desc *)
+ | Texp_apply(e1,args) -> begin match e1.exp_desc with
+ | Texp_ident(path, value_desc) ->
if (Path.name path) = "Pervasives.failwith"
then Texp_bad (Callee (exp.exp_loc, path))
else exp.exp_desc
+ | _ -> exp.exp_desc
+ end
| others -> others
in {exp with exp_desc = new_desc}
let pre_processing exp = map_expression exn_to_bad exp
+let rec rename_path_ident boundvars path gamma = match path with
+ | Pident id -> if not(List.mem id boundvars)
+ then try Pident (Tbl.find id gamma)
+ with Not_found -> path
+ else path
+ | Pdot (p, s, pos) -> Pdot (rename_path_ident boundvars p gamma, s, pos)
+ | Papply (p1, p2) -> Papply(p1, rename_path_ident boundvars p2 gamma)
+
+(* subst replace free variables id1 in expr by id2 *)
+let rec subst bound_vars gamma expr = match expr.exp_desc with
+ | Texp_ident (path, vd) ->
+ {expr with exp_desc = Texp_ident (rename_path_ident bound_vars path gamma, vd)}
+ | Texp_constant (c) -> expr
+ | Texp_let (rec_flag, pat_expr_list, e2) ->
+ let bvars = let_bound_idents pat_expr_list in
+ let p_e_list = List.map (fun (p,e) -> (p, subst (bound_vars@bvars) gamma e))
+ pat_expr_list in
+ let new_e2 = subst bound_vars gamma e2 in
+ {expr with exp_desc = Texp_let (rec_flag, p_e_list, new_e2)}
+ | Texp_function (pat_expr_list, ptial) ->
+ let bvars = let_bound_idents pat_expr_list in
+ let p_e_list = List.map (fun (p,e) -> (p, subst (bound_vars@bvars) gamma e))
+ pat_expr_list in
+ {expr with exp_desc = Texp_function (p_e_list, ptial)}
+ | Texp_apply (e1, es) ->
+ let new_e1 = subst bound_vars gamma e1 in
+ let new_es = List.map (fun (e_opt, optl) -> match e_opt with
+ | Some e -> (Some (subst bound_vars gamma e), optl)
+ | None -> (None, optl)) es
+ in {expr with exp_desc = Texp_apply (new_e1, new_es)}
+ | Texp_match (e0, pat_expr_list, ptial) ->
+ let new_e0 = subst bound_vars gamma e0 in
+ let bvars = let_bound_idents pat_expr_list in
+ let p_e_list = List.map (fun (p,e) -> (p, subst (bound_vars@bvars) gamma e))
+ pat_expr_list in
+ {expr with exp_desc = Texp_match (new_e0, p_e_list, ptial)}
+ | Texp_try (e1, pat_expr_list) ->
+ let new_e1 = subst bound_vars gamma e1 in
+ let bvars = let_bound_idents pat_expr_list in
+ let p_e_list = List.map (fun (p,e) -> (p, subst (bound_vars@bvars) gamma e))
+ pat_expr_list in
+ {expr with exp_desc = Texp_try (new_e1, p_e_list)}
+ | Texp_tuple (es) ->
+ let new_es = List.map (subst bound_vars gamma) es in
+ {expr with exp_desc = Texp_tuple new_es}
+ | Texp_construct (path, cdesc, es) ->
+ let new_es = List.map (subst bound_vars gamma) es in
+ {expr with exp_desc = Texp_construct (path, cdesc, new_es)}
+ | Texp_variant (lbl, e_opt) ->
+ let new_e = match e_opt with
+ | Some e -> Some (subst bound_vars gamma e)
+ | None -> None
+ in {expr with exp_desc = Texp_variant (lbl, new_e)}
+ | Texp_record (ldesc_expr_list, e_opt) ->
+ let l_e_list = List.map (fun (p,e) -> (p, subst bound_vars gamma e))
+ ldesc_expr_list in
+ {expr with exp_desc = Texp_record (l_e_list, match e_opt with
+ | Some e -> Some (subst bound_vars gamma e)
+ | None -> None)}
+ | Texp_field (e, ldesc) ->
+ let new_e = subst bound_vars gamma e in
+ {expr with exp_desc = Texp_field (new_e, ldesc)}
+ | Texp_setfield (e1, ldesc, e2) ->
+ let new_e1 = subst bound_vars gamma e1 in
+ let new_e2 = subst bound_vars gamma e2 in
+ {expr with exp_desc = Texp_setfield (new_e1, ldesc, new_e2)}
+ | Texp_array (es) ->
+ let new_es = List.map (subst bound_vars gamma) es in
+ {expr with exp_desc = Texp_tuple new_es}
+ | Texp_ifthenelse (e0, e1, e2_opt) ->
+ let new_e0 = subst bound_vars gamma e0 in
+ let new_e1 = subst bound_vars gamma e1 in
+ let new_e2 = match e2_opt with
+ | Some e -> Some (subst bound_vars gamma e)
+ | None -> None
+ in {expr with exp_desc = Texp_ifthenelse (new_e0, new_e1, new_e2)}
+ | Texp_sequence (e1, e2) ->
+ let new_e1 = subst bound_vars gamma e1 in
+ let new_e2 = subst bound_vars gamma e2 in
+ {expr with exp_desc = Texp_sequence (new_e1, new_e2)}
+ | Texp_while (e1, e2) ->
+ let new_e1 = subst bound_vars gamma e1 in
+ let new_e2 = subst bound_vars gamma e2 in
+ {expr with exp_desc = Texp_while (new_e1, new_e2)}
+ | Texp_for (id, e1, e2, dflag, e3) ->
+ let new_e1 = subst bound_vars gamma e1 in
+ let new_e2 = subst bound_vars gamma e2 in
+ let new_e3 = subst bound_vars gamma e3 in
+ {expr with exp_desc = Texp_for (id, new_e1, new_e2, dflag, new_e3)}
+ | Texp_when (e1, e2) ->
+ let new_e1 = subst bound_vars gamma e1 in
+ let new_e2 = subst bound_vars gamma e2 in
+ {expr with exp_desc = Texp_when (new_e1, new_e2)}
+ | Texp_send (e, meth) ->
+ let new_e = subst bound_vars gamma e in
+ {expr with exp_desc = Texp_send (new_e, meth)}
+ | Texp_new _ -> expr
+ | Texp_instvar _ -> expr
+ | Texp_setinstvar (path1, path2, e) ->
+ let new_e = subst bound_vars gamma e in
+ {expr with exp_desc = Texp_setinstvar(path1, path2, new_e)}
+ | Texp_override (path1, path_expr_list) ->
+ let p_e_list = List.map (fun (p,e) -> (p, subst bound_vars gamma e))
+ path_expr_list in
+ {expr with exp_desc = Texp_override (path1, p_e_list)}
+ | Texp_letmodule (id, modexpr, e) ->
+ let new_e = subst bound_vars gamma e in
+ {expr with exp_desc = Texp_letmodule (id, modexpr, new_e)}
+ | Texp_assert (e) ->
+ let new_e = subst bound_vars gamma e in
+ {expr with exp_desc = Texp_assert(new_e)}
+ | Texp_assertfalse -> expr
+ | Texp_lazy (e) ->
+ let new_e = subst bound_vars gamma e in
+ {expr with exp_desc = Texp_assert(new_e)}
+ | Texp_object _ -> expr
+ | Texp_pack _ -> expr
+ | Texp_local_contract (c, e) ->
+ let new_e = subst bound_vars gamma e in
+ {expr with exp_desc = Texp_local_contract(c, new_e)}
+ | Texp_contract (c, e1, e2, e3) ->
+ let new_e1 = subst bound_vars gamma e1 in
+ let new_e2 = subst bound_vars gamma e2 in
+ let new_e3 = subst bound_vars gamma e3 in
+ {expr with exp_desc = Texp_contract (c, new_e1, new_e2, new_e3)}
+ | Texp_bad _ -> expr
+ | Texp_unr _ -> expr
+ | Texp_Lambda (ids, e) ->
+ let new_e = subst bound_vars gamma e in
+ {expr with exp_desc = Texp_Lambda (ids, new_e)}
+ | Texp_App (e1, es) ->
+ let new_e1 = subst bound_vars gamma e1 in
+ let new_es = List.map (subst bound_vars gamma) es in
+ {expr with exp_desc = Texp_App(new_e1, new_es)}
+ | Texp_raise (e) -> expr
+
+let rec rename_pattern gamma pat = match pat.pat_desc with
+| Tpat_var(id) ->
+ {pat with pat_desc = try Tpat_var (Tbl.find id gamma)
+ with Not_found -> Tpat_var(id)}
+
+| d -> {pat with pat_desc = map_pattern_desc (rename_pattern gamma) d}
+
+let rec rename_boundvars gamma expr = match expr.exp_desc with
+ | Texp_ident (path, vd) ->
+ let new_id = rename_path_ident [] path gamma in
+ {expr with exp_desc = Texp_ident (new_id, vd)}
+ | Texp_constant (c) -> expr
+ | Texp_let (rec_flag, pat_expr_list, e2) ->
+ let p_e_list = List.map (fun (p,e) -> (p, rename_boundvars gamma e))
+ pat_expr_list in
+ let new_e2 = rename_boundvars gamma e2 in
+ {expr with exp_desc = Texp_let (rec_flag, p_e_list, new_e2)}
+ | Texp_function (pat_expr_list, ptial) ->
+ let p_e_list = List.map (fun (p,e) ->
+ match p.pat_desc with
+ | Tpat_var(id) ->
+ let new_id = Ident.rename id in
+ let new_gamma = Tbl.add id new_id gamma in
+ ({p with pat_desc = Tpat_var(new_id)}, rename_boundvars new_gamma e)
+ | Tpat_construct(path, cdesc, ps) ->
+ let bvars = let_bound_idents pat_expr_list in
+ let new_gamma = List.fold_right (fun i default ->
+ Tbl.add i (Ident.rename i) default) bvars gamma in
+ let new_ps = List.map (rename_pattern new_gamma) ps in
+ ({p with pat_desc = Tpat_construct(path, cdesc, new_ps)},
+ rename_boundvars new_gamma e)
+ | _ -> (p, e))
+ pat_expr_list in
+ {expr with exp_desc = Texp_function (p_e_list, ptial)}
+ | Texp_apply (e1, es) ->
+ let new_e1 = rename_boundvars gamma e1 in
+ let new_es = List.map (fun (e_opt, optl) -> match e_opt with
+ | Some e -> (Some (rename_boundvars gamma e), optl)
+ | None -> (None, optl)) es
+ in {expr with exp_desc = Texp_apply (new_e1, new_es)}
+ | Texp_match (e0, pat_expr_list, ptial) ->
+ let new_e0 = rename_boundvars gamma e0 in
+ let p_e_list = List.map (fun (p,e) ->
+ match p.pat_desc with
+ | Tpat_var(id) ->
+ let new_id = Ident.rename id in
+ let new_gamma = Tbl.add id new_id gamma in
+ ({p with pat_desc = Tpat_var(new_id)}, rename_boundvars new_gamma e)
+ | Tpat_construct(path, cdesc, ps) ->
+ let bvars = List.fold_right (fun pi default ->
+ default@(pat_bound_idents pi)) ps [] in
+ let newbvars = List.map Ident.rename bvars in
+ let blist = List.combine bvars newbvars in
+ let new_gamma = List.fold_right (fun (i,ni) default ->
+ Tbl.add i ni default) blist gamma in
+ let new_ps = List.map (rename_pattern new_gamma) ps in
+ ({p with pat_desc = Tpat_construct(path, cdesc, new_ps)},
+ rename_boundvars new_gamma e)
+ | _ -> (p,e))
+ pat_expr_list in
+ {expr with exp_desc = Texp_match (new_e0, p_e_list, ptial)}
+ | Texp_try (e1, pat_expr_list) ->
+ let new_e1 = rename_boundvars gamma e1 in
+ let p_e_list = List.map (fun (p,e) -> (p, rename_boundvars gamma e))
+ pat_expr_list in
+ {expr with exp_desc = Texp_try (new_e1, p_e_list)}
+ | Texp_tuple (es) ->
+ let new_es = List.map (rename_boundvars gamma) es in
+ {expr with exp_desc = Texp_tuple new_es}
+ | Texp_construct (path, cdesc, es) ->
+ let new_es = List.map (rename_boundvars gamma) es in
+ {expr with exp_desc = Texp_construct (path, cdesc, new_es)}
+ | Texp_variant (lbl, e_opt) ->
+ let new_e = match e_opt with
+ | Some e -> Some (rename_boundvars gamma e)
+ | None -> None
+ in {expr with exp_desc = Texp_variant (lbl, new_e)}
+ | Texp_record (ldesc_expr_list, e_opt) ->
+ let l_e_list = List.map (fun (p,e) -> (p, rename_boundvars gamma e))
+ ldesc_expr_list in
+ {expr with exp_desc = Texp_record (l_e_list, match e_opt with
+ | Some e -> Some (rename_boundvars gamma e)
+ | None -> None)}
+ | Texp_field (e, ldesc) ->
+ let new_e = rename_boundvars gamma e in
+ {expr with exp_desc = Texp_field (new_e, ldesc)}
+ | Texp_setfield (e1, ldesc, e2) ->
+ let new_e1 = rename_boundvars gamma e1 in
+ let new_e2 = rename_boundvars gamma e2 in
+ {expr with exp_desc = Texp_setfield (new_e1, ldesc, new_e2)}
+ | Texp_array (es) ->
+ let new_es = List.map (rename_boundvars gamma) es in
+ {expr with exp_desc = Texp_tuple new_es}
+ | Texp_ifthenelse (e0, e1, e2_opt) ->
+ let new_e0 = rename_boundvars gamma e0 in
+ let new_e1 = rename_boundvars gamma e1 in
+ let new_e2 = match e2_opt with
+ | Some e -> Some (rename_boundvars gamma e)
+ | None -> None
+ in {expr with exp_desc = Texp_ifthenelse (new_e0, new_e1, new_e2)}
+ | Texp_sequence (e1, e2) ->
+ let new_e1 = rename_boundvars gamma e1 in
+ let new_e2 = rename_boundvars gamma e2 in
+ {expr with exp_desc = Texp_sequence (new_e1, new_e2)}
+ | Texp_while (e1, e2) ->
+ let new_e1 = rename_boundvars gamma e1 in
+ let new_e2 = rename_boundvars gamma e2 in
+ {expr with exp_desc = Texp_while (new_e1, new_e2)}
+ | Texp_for (id, e1, e2, dflag, e3) ->
+ let new_e1 = rename_boundvars gamma e1 in
+ let new_e2 = rename_boundvars gamma e2 in
+ let new_e3 = rename_boundvars gamma e3 in
+ {expr with exp_desc = Texp_for (id, new_e1, new_e2, dflag, new_e3)}
+ | Texp_when (e1, e2) ->
+ let new_e1 = rename_boundvars gamma e1 in
+ let new_e2 = rename_boundvars gamma e2 in
+ {expr with exp_desc = Texp_when (new_e1, new_e2)}
+ | Texp_send (e, meth) ->
+ let new_e = rename_boundvars gamma e in
+ {expr with exp_desc = Texp_send (new_e, meth)}
+ | Texp_new _ -> expr
+ | Texp_instvar _ -> expr
+ | Texp_setinstvar (path1, path2, e) ->
+ let new_e = rename_boundvars gamma e in
+ {expr with exp_desc = Texp_setinstvar(path1, path2, new_e)}
+ | Texp_override (path1, path_expr_list) ->
+ let p_e_list = List.map (fun (p,e) -> (p, rename_boundvars gamma e))
+ path_expr_list in
+ {expr with exp_desc = Texp_override (path1, p_e_list)}
+ | Texp_letmodule (id, modexpr, e) ->
+ let new_e = rename_boundvars gamma e in
+ {expr with exp_desc = Texp_letmodule (id, modexpr, new_e)}
+ | Texp_assert (e) ->
+ let new_e = rename_boundvars gamma e in
+ {expr with exp_desc = Texp_assert(new_e)}
+ | Texp_assertfalse -> expr
+ | Texp_lazy (e) ->
+ let new_e = rename_boundvars gamma e in
+ {expr with exp_desc = Texp_assert(new_e)}
+ | Texp_object _ -> expr
+ | Texp_pack _ -> expr
+ | Texp_local_contract (c, e) ->
+ let new_e = rename_boundvars gamma e in
+ {expr with exp_desc = Texp_local_contract(c, new_e)}
+ | Texp_contract (c, e1, e2, e3) ->
+ let new_e1 = rename_boundvars gamma e1 in
+ let new_e2 = rename_boundvars gamma e2 in
+ let new_e3 = rename_boundvars gamma e3 in
+ {expr with exp_desc = Texp_contract (c, new_e1, new_e2, new_e3)}
+ | Texp_bad _ -> expr
+ | Texp_unr _ -> expr
+ | Texp_Lambda (ids, e) ->
+ let new_e = rename_boundvars gamma e in
+ {expr with exp_desc = Texp_Lambda (ids, new_e)}
+ | Texp_App (e1, es) ->
+ let new_e1 = rename_boundvars gamma e1 in
+ let new_es = List.map (rename_boundvars gamma) es in
+ {expr with exp_desc = Texp_App(new_e1, new_es)}
+ | Texp_raise (e) -> expr
+
+
+
diff --git a/verify/escSyn.mli b/verify/escSyn.mli
index 2fda43f453..eed401773f 100644
--- a/verify/escSyn.mli
+++ b/verify/escSyn.mli
@@ -6,6 +6,7 @@ type validity = Valid | Invalid | Unknown | HighFailure | Timeout
type bool_info = Ptrue | Pfalse | Pothers
+val trace : string -> ('a -> unit) -> 'a -> unit
val getop : Path.t -> string
val is_pattern_true : pattern -> bool_info
val is_expression_true : expression -> bool_info
@@ -13,3 +14,5 @@ val is_expression_bool : expression -> bool
val is_expression_prop : expression -> bool
val is_expression_argable : expression -> bool
val pre_processing : expression -> expression
+val subst : Ident.t list -> (Ident.t, Ident.t) Tbl.t -> expression -> expression
+val rename_boundvars : (Ident.t, Ident.t) Tbl.t -> expression -> expression
diff --git a/verify/thmEnv.ml b/verify/thmEnv.ml
index 3900d4925d..bfe56016e6 100644
--- a/verify/thmEnv.ml
+++ b/verify/thmEnv.ml
@@ -49,28 +49,29 @@ type t = {
opened_contract_decls: (Path.t * Types.contract_declaration) Ident.tbl;
axioms: axiom_declaration list;
goalTasks: decl list;
- abinds: (Ident.t, expression) Tbl.t;
- vals: (expression, aval) Tbl.t; (* variable |-> value *)
+ abinds: (Ident.t, expression) Tbl.t; (* variable |-> tvalue *)
+ vals: (expression, aval) Tbl.t; (* variable |-> expression *)
+ nonrecs : (Ident.t, expression) Tbl.t; (* top-level nonrecursive functions *)
+ recs : (Ident.t, expression) Tbl.t; (* top-level recursive functions *)
}
+
let init_tasks =
- let a_list = PPTexternal ([PPTvarid ("'a", Location.none)], "list",
- Location.none) in
- let a_b_arrow = PPTexternal ([PPTvarid ("'a", Location.none);
- PPTvarid ("'b", Location.none)], "arrow",
- Location.none) in
- let a_b_tuple = PPTexternal ([PPTvarid ("'a", Location.none);
- PPTvarid ("'b", Location.none)], "tuple",
- Location.none) in
- [TypeDecl (Location.none, ["'a";"'b"], "arrow");
- TypeDecl (Location.none, ["'a";"'b"], "tuple");
- Logic (Location.none, false, ["apply"],
- PFunction ([a_b_arrow; PPTvarid ("'a", Location.none)],
- PPTvarid ("'b", Location.none)));
- TypeDecl (Location.none, ["'a"], "list");
- Logic (Location.none, false, ["nil"], PFunction ([], a_list));
- Logic (Location.none, false, ["cons"], PFunction ([PPTvarid ("'a", Location.none); a_list], a_list ));
- Logic (Location.none, false, ["tup"], PFunction ([PPTvarid ("'a", Location.none);PPTvarid ("'b", Location.none);], a_b_tuple));
+ let loc = Location.none in
+ let mklexpr desc = {pp_loc = loc; pp_desc = desc} in
+ let a = PPTvarid ("'a", loc) in
+ let b = PPTvarid ("'b", loc) in
+ let a_list = PPTexternal ([a], "list", loc) in
+ let a_b_arrow = PPTexternal ([a;b], "arrow", loc) in
+ let a_b_tuple = PPTexternal ([a;b], "tuple", loc) in
+ [TypeDecl (loc, ["'a";"'b"], "arrow");
+ TypeDecl (loc, ["'a";"'b"], "tuple");
+ Logic (loc, false, ["apply"], PFunction ([a_b_arrow; a], b));
+ TypeDecl (loc, ["'a"], "list");
+ Logic (loc, false, ["nil"], PFunction ([], a_list));
+ Logic (loc, false, ["cons"], PFunction ([a; a_list], a_list ));
+ Logic (loc, false, ["tup"], PFunction ([a;b], a_b_tuple));
+ Axiom (loc, "list_a0", mklexpr (PPforall(["x"], a, [], mklexpr(PPforall(["l"], a_list, [], mklexpr (PPinfix(mklexpr(PPvar "nil"), PPneq, mklexpr(PPapp("cons", [mklexpr(PPvar "x");mklexpr(PPvar "l")])))))))))
]
(* empty environment *)
@@ -86,18 +87,26 @@ let initEnv l1 l2 = {
goalTasks = []; (* represent a goal in terms of tasks *)
abinds = Tbl.empty;
vals = Tbl.empty;
+ nonrecs = Tbl.empty;
+ recs = Tbl.empty;
}
(* Insertion of bindings by identifier *)
let extend_senv env id1 id2 = {env with abinds = Tbl.add id1 id2 env.abinds}
let extend_denv env exp aval = {env with vals = Tbl.add exp aval env.vals}
+let extend_nonrec_env env id1 e = {env with nonrecs = Tbl.add id1 e env.nonrecs}
+let extend_rec_env env id1 e = {env with recs = Tbl.add id1 e env.recs}
+
(* the name of the current function under contract checking *)
let update_name env n = { env with name = n }
let update_contract_name env n = { env with contract_name = n }
+let decrease_depth env = { env with depth = env.depth - 1 }
+let increase_depth env = { env with depth = env.depth + 1 }
+
let add_dep_contracts env x c =
{ env with dep_contracts = Ident.add x c env.dep_contracts }
@@ -133,6 +142,10 @@ let lookup_senv id env = try let x = Tbl.find id env.abinds in
let lookup_denv exp env = try Tbl.find exp env.vals
with Not_found -> NoVal
+let lookup_nonrec_env id env = Tbl.find id env.nonrecs
+let lookup_rec_env id env = Tbl.find id env.recs
+let recs env = env.recs
+let nonrecs env = env.nonrecs
(* Error report *)
diff --git a/verify/thmEnv.mli b/verify/thmEnv.mli
index 52f396c36a..a01b6d5738 100644
--- a/verify/thmEnv.mli
+++ b/verify/thmEnv.mli
@@ -20,6 +20,8 @@ type t = {
goalTasks: decl list;
abinds: (Ident.t, expression) Tbl.t;
vals: (expression, aval) Tbl.t;
+ nonrecs: (Ident.t, expression) Tbl.t;
+ recs: (Ident.t, expression) Tbl.t
}
val initEnv : contract_declaration list ->
@@ -35,11 +37,19 @@ val goalTasks : t -> decl list
val add_tasks : t -> decl list-> t
val update_name : t -> Path.t -> t
val update_contract_name : t -> Path.t -> t
+val decrease_depth : t -> t
+val increase_depth : t -> t
val add_dep_contracts : t -> Ident.t -> Typedtree.core_contract -> t
val add_contract_decl : t -> contract_declaration -> t
val add_axiom : t -> axiom_declaration -> t
val add_goalTasks : t -> decl list -> t
val extend_senv : t -> Ident.t -> expression -> t
val extend_denv : t -> expression -> aval -> t
+val extend_nonrec_env : t -> Ident.t -> expression -> t
+val extend_rec_env : t -> Ident.t -> expression -> t
val lookup_senv : Ident.t -> t -> aval
val lookup_denv : expression -> t -> aval
+val lookup_nonrec_env : Ident.t -> t -> expression
+val lookup_rec_env : Ident.t -> t -> expression
+val nonrecs : t -> (Ident.t, expression) Tbl.t
+val recs : t -> (Ident.t, expression) Tbl.t
diff --git a/verify/thmProvers.ml b/verify/thmProvers.ml
index 4802cf689c..c5bec554dc 100644
--- a/verify/thmProvers.ml
+++ b/verify/thmProvers.ml
@@ -21,7 +21,7 @@ let askErgo tasks =
let outchnl = open_out filename in
out_ergotasks outchnl tasks;
close_out outchnl;
- ignore (Sys.command (Printf.sprintf "alt-ergo -redondance 4 %s" filename));
+ ignore (Sys.command (Printf.sprintf "alt-ergo -redondance 4 -stop 2 %s" filename));
let s = input_line stdin in
(* close_in stdin; *)
print_string ("the result"^s);
diff --git a/verify/toErgosrc.ml b/verify/toErgosrc.ml
index 6850456ca8..d3abd22a3f 100644
--- a/verify/toErgosrc.ml
+++ b/verify/toErgosrc.ml
@@ -178,12 +178,6 @@ else match exp.exp_desc with
| None -> true)
| _ -> false
-let is_scrutinee_ergoble exp = match exp.exp_desc with
-| Texp_ident _ -> false
-| Texp_match _ -> false
-| _ -> is_expression_ergoble exp
-
-
(* HOL, we introduce
type ('a, 'b) arrow
logic apply : ('a , 'b) arrow , 'a -> 'b *)
@@ -822,6 +816,7 @@ match e0.exp_desc with
end
| "=" -> begin match expop_optl_list with
| (Some x, _)::(Some y, _)::l ->
+ (*
if is_expression_argable x
then if is_expression_argable y
then let e1 = expression_to_lexpr x in
@@ -845,10 +840,11 @@ match e0.exp_desc with
let e1 = expression_to_eqlexpr xvar x in
let e2 = expression_to_eqlexpr yvar y in
f_exists x1 t1 (f_exists x2 t2 (f_and (f_and e1 e2) (f_eq xvar yvar)))
- (* let e1 = expression_to_lexpr x in
+ *)
+ let e1 = expression_to_lexpr x in
let e2 = expression_to_lexpr y in
f_iff (f_eq e1 e2)
- (f_eq f (mklexpr l0 etrue)) *)
+ (f_eq f (mklexpr l0 etrue))
| _ -> raise Not_primitive
end
| "<>" -> begin match expop_optl_list with
@@ -896,8 +892,8 @@ match e0.exp_desc with
end
| "not" -> begin match expop_optl_list with
| (Some x, _)::l ->
- let e1 = expression_to_lexpr x in
- f_eq f (f_not e1)
+ let e1 = expression_to_eqlexpr f x in
+ f_not e1
| _ -> raise Not_primitive
end
| _ -> raise Not_primitive
diff --git a/verify/toErgosrc.mli b/verify/toErgosrc.mli
index c930aeaae4..eb41f4f6bc 100644
--- a/verify/toErgosrc.mli
+++ b/verify/toErgosrc.mli
@@ -35,7 +35,6 @@ val type_to_typelogic : loc -> Ident.t * type_declaration -> decl list
val out_ergotasks : out_channel -> decl list -> unit
val report_error: Format.formatter -> error -> unit
val is_expression_ergoble: expression -> bool
-val is_scrutinee_ergoble: expression -> bool
val bound_vars_to_logic : pattern -> decl list
val toGoal_beq : expression -> decl
val toGoal_bneq : expression -> decl
diff --git a/verify/verify.ml b/verify/verify.ml
index 64e96ac8d9..647ced8e62 100644
--- a/verify/verify.ml
+++ b/verify/verify.ml
@@ -14,141 +14,6 @@ type error =
exception Error of Location.t * error
-let rec rename_path_ident bvars path id1 id2 = match path with
- | Pident id -> if not(List.mem id bvars) && id = id1
- then Pident id2
- else path
- | Pdot (p, s, pos) -> Pdot (rename_path_ident bvars p id1 id2, s, pos)
- | Papply (p1, p2) -> Papply(p1, rename_path_ident bvars p2 id1 id2)
-
-(* subst replace free variables id1 in expr by id2 *)
-let rec subst bound_vars id1 id2 expr = match expr.exp_desc with
- | Texp_ident (path, vd) ->
- {expr with exp_desc = Texp_ident (rename_path_ident bound_vars path id1 id2, vd)}
- | Texp_constant (c) -> expr
- | Texp_let (rec_flag, pat_expr_list, e2) ->
- let bvars = let_bound_idents pat_expr_list in
- let p_e_list = List.map (fun (p,e) -> (p, subst (bound_vars@bvars) id1 id2 e))
- pat_expr_list in
- let new_e2 = subst bound_vars id1 id2 e2 in
- {expr with exp_desc = Texp_let (rec_flag, p_e_list, new_e2)}
- | Texp_function (pat_expr_list, ptial) ->
- let bvars = let_bound_idents pat_expr_list in
- let p_e_list = List.map (fun (p,e) -> (p, subst (bound_vars@bvars) id1 id2 e))
- pat_expr_list in
- {expr with exp_desc = Texp_function (p_e_list, ptial)}
- | Texp_apply (e1, es) ->
- let new_e1 = subst bound_vars id1 id2 e1 in
- let new_es = List.map (fun (e_opt, optl) -> match e_opt with
- | Some e -> (Some (subst bound_vars id1 id2 e), optl)
- | None -> (None, optl)) es
- in {expr with exp_desc = Texp_apply (new_e1, new_es)}
- | Texp_match (e0, pat_expr_list, ptial) ->
- let new_e0 = subst bound_vars id1 id2 e0 in
- let bvars = let_bound_idents pat_expr_list in
- let p_e_list = List.map (fun (p,e) -> (p, subst (bound_vars@bvars) id1 id2 e))
- pat_expr_list in
- {expr with exp_desc = Texp_match (new_e0, p_e_list, ptial)}
- | Texp_try (e1, pat_expr_list) ->
- let new_e1 = subst bound_vars id1 id2 e1 in
- let bvars = let_bound_idents pat_expr_list in
- let p_e_list = List.map (fun (p,e) -> (p, subst (bound_vars@bvars) id1 id2 e))
- pat_expr_list in
- {expr with exp_desc = Texp_try (new_e1, p_e_list)}
- | Texp_tuple (es) ->
- let new_es = List.map (subst bound_vars id1 id2) es in
- {expr with exp_desc = Texp_tuple new_es}
- | Texp_construct (path, cdesc, es) ->
- let new_es = List.map (subst bound_vars id1 id2) es in
- {expr with exp_desc = Texp_construct (path, cdesc, new_es)}
- | Texp_variant (lbl, e_opt) ->
- let new_e = match e_opt with
- | Some e -> Some (subst bound_vars id1 id2 e)
- | None -> None
- in {expr with exp_desc = Texp_variant (lbl, new_e)}
- | Texp_record (ldesc_expr_list, e_opt) ->
- let l_e_list = List.map (fun (p,e) -> (p, subst bound_vars id1 id2 e))
- ldesc_expr_list in
- {expr with exp_desc = Texp_record (l_e_list, match e_opt with
- | Some e -> Some (subst bound_vars id1 id2 e)
- | None -> None)}
- | Texp_field (e, ldesc) ->
- let new_e = subst bound_vars id1 id2 e in
- {expr with exp_desc = Texp_field (new_e, ldesc)}
- | Texp_setfield (e1, ldesc, e2) ->
- let new_e1 = subst bound_vars id1 id2 e1 in
- let new_e2 = subst bound_vars id1 id2 e2 in
- {expr with exp_desc = Texp_setfield (new_e1, ldesc, new_e2)}
- | Texp_array (es) ->
- let new_es = List.map (subst bound_vars id1 id2) es in
- {expr with exp_desc = Texp_tuple new_es}
- | Texp_ifthenelse (e0, e1, e2_opt) ->
- let new_e0 = subst bound_vars id1 id2 e0 in
- let new_e1 = subst bound_vars id1 id2 e1 in
- let new_e2 = match e2_opt with
- | Some e -> Some (subst bound_vars id1 id2 e)
- | None -> None
- in {expr with exp_desc = Texp_ifthenelse (new_e0, new_e1, new_e2)}
- | Texp_sequence (e1, e2) ->
- let new_e1 = subst bound_vars id1 id2 e1 in
- let new_e2 = subst bound_vars id1 id2 e2 in
- {expr with exp_desc = Texp_sequence (new_e1, new_e2)}
- | Texp_while (e1, e2) ->
- let new_e1 = subst bound_vars id1 id2 e1 in
- let new_e2 = subst bound_vars id1 id2 e2 in
- {expr with exp_desc = Texp_while (new_e1, new_e2)}
- | Texp_for (id, e1, e2, dflag, e3) ->
- let new_e1 = subst bound_vars id1 id2 e1 in
- let new_e2 = subst bound_vars id1 id2 e2 in
- let new_e3 = subst bound_vars id1 id2 e3 in
- {expr with exp_desc = Texp_for (id, new_e1, new_e2, dflag, new_e3)}
- | Texp_when (e1, e2) ->
- let new_e1 = subst bound_vars id1 id2 e1 in
- let new_e2 = subst bound_vars id1 id2 e2 in
- {expr with exp_desc = Texp_when (new_e1, new_e2)}
- | Texp_send (e, meth) ->
- let new_e = subst bound_vars id1 id2 e in
- {expr with exp_desc = Texp_send (new_e, meth)}
- | Texp_new _ -> expr
- | Texp_instvar _ -> expr
- | Texp_setinstvar (path1, path2, e) ->
- let new_e = subst bound_vars id1 id2 e in
- {expr with exp_desc = Texp_setinstvar(path1, path2, new_e)}
- | Texp_override (path1, path_expr_list) ->
- let p_e_list = List.map (fun (p,e) -> (p, subst bound_vars id1 id2 e))
- path_expr_list in
- {expr with exp_desc = Texp_override (path1, p_e_list)}
- | Texp_letmodule (id, modexpr, e) ->
- let new_e = subst bound_vars id1 id2 e in
- {expr with exp_desc = Texp_letmodule (id, modexpr, new_e)}
- | Texp_assert (e) ->
- let new_e = subst bound_vars id1 id2 e in
- {expr with exp_desc = Texp_assert(new_e)}
- | Texp_assertfalse -> expr
- | Texp_lazy (e) ->
- let new_e = subst bound_vars id1 id2 e in
- {expr with exp_desc = Texp_assert(new_e)}
- | Texp_object _ -> expr
- | Texp_pack _ -> expr
- | Texp_local_contract (c, e) ->
- let new_e = subst bound_vars id1 id2 e in
- {expr with exp_desc = Texp_local_contract(c, new_e)}
- | Texp_contract (c, e1, e2, e3) ->
- let new_e1 = subst bound_vars id1 id2 e1 in
- let new_e2 = subst bound_vars id1 id2 e2 in
- let new_e3 = subst bound_vars id1 id2 e3 in
- {expr with exp_desc = Texp_contract (c, new_e1, new_e2, new_e3)}
- | Texp_bad _ -> expr
- | Texp_unr _ -> expr
- | Texp_Lambda (ids, e) ->
- let new_e = subst bound_vars id1 id2 e in
- {expr with exp_desc = Texp_Lambda (ids, new_e)}
- | Texp_App (e1, es) ->
- let new_e1 = subst bound_vars id1 id2 e1 in
- let new_es = List.map (subst bound_vars id1 id2) es in
- {expr with exp_desc = Texp_App(new_e1, new_es)}
- | Texp_raise (e) -> expr
-
(* Translate wrapped expression e |><| c to unwrapped expression
val transl_core_contract:
Typedtree.contract_declaration list -> % contract decls in this module
@@ -204,18 +69,18 @@ let rec transl_core_contract env cntr e callee caller =
*)
begin match is_expression_true p with
| Ptrue -> e.exp_desc
- | Pfalse -> callee.exp_desc
| _ ->
let new_x = Ident.create "x" in
let vd = { val_type = e.exp_type; val_kind = Val_reg } in
let xe = { e with exp_desc = Texp_ident(Pident new_x, vd) } in
(* let wrapped_p = contract_id_in_expr env p in
let expanded_p = deep_transl_contract env wrapped_p in
- *)
let cond = Texp_ifthenelse (subst [] x new_x p, xe, Some callee) in
+ *)
+ let cond = Texp_ifthenelse (subst [] (Tbl.add x new_x Tbl.empty) p, xe, Some callee) in
Texp_let (Nonrecursive, [(mkpat (Tpat_var new_x) cty, e)], mkexp cond cty)
end
- (* e |>r1,r2<| try {x | p} with [Ei -> booli]
+ (* e |>r1,r2<| try {x | p} with [Ei -> booli]
if (try let x = e in p
with Contract_exn (f,row,col,bl) -> raise Contract_exn (f,row,col,bl)
| Ei .. -> booli
@@ -229,13 +94,10 @@ let rec transl_core_contract env cntr e callee caller =
(*
begin match exnop with
| None ->
-
let xe = Texp_ident (Pident x, {val_type = cty; val_kind = Val_reg}) in
let cond = Texp_ifthenelse (p, mkexp xe cty, Some callee) in
Texp_let (Nonrecursive, [(mkpat (Tpat_var x) cty, e)], mkexp cond cty)
-
| Some exns ->
-
let letexp = Texp_let (Nonrecursive, [(mkpat (Tpat_var x) cty, e)], p) in
let ctr_exn = Texp_construct(cexn_path, cexn_cdesc,
[mkexp (Texp_tuple evars) dummy_tuple]) in
@@ -675,19 +537,14 @@ let rec transl_str_contracts contract_flag env strs =
| _ -> false)
pat_expr_list in *)
let env1 = add_tasks env (def_to_axioms pre_processed_list) in
- if depth env = 0 then env1
- else
- List.fold_right (fun (p,e) default ->
+ List.fold_right (fun (p,e) default ->
match p.pat_desc with
- | Tpat_var (id) when rec_flag = Nonrecursive ->
- let new_id = Ident.rename id in
- let vd = { val_type = p.pat_type; val_kind = Val_reg } in
- let eid = {exp_desc = Texp_ident(Pident new_id, vd);
- exp_type = p.pat_type;
- exp_loc = p.pat_loc;
- exp_env = p.pat_env } in
- let env2 = extend_senv default id eid in
- extend_denv env2 eid (Inline e)
+ | Tpat_var (id) ->
+ begin match rec_flag with
+ | Nonrecursive -> extend_nonrec_env default id e
+ | Recursive -> extend_rec_env default id e
+ | Default -> default
+ end
| _ -> default) pat_expr_list env1
with ToErgosrc.Error(loc,err) ->
ToErgosrc.report_error std_formatter err; env