Correct scoping and typing with contracts
This commit is contained in:
parent
c77386d517
commit
2c4be9d42c
6 changed files with 47 additions and 19 deletions
|
@ -1025,14 +1025,14 @@ let typing_contract const_env h contract =
|
|||
c_assume = e_a;
|
||||
c_enforce = e_g;
|
||||
c_controllables = c }) ->
|
||||
let typed_b, defined_names, _ = typing_block const_env h b in
|
||||
let typed_b, defined_names, h' = typing_block const_env h b in
|
||||
(* check that the equations do not define other unexpected names *)
|
||||
included_env defined_names Env.empty;
|
||||
|
||||
(* assumption *)
|
||||
let typed_e_a = expect const_env h (Tid Initial.pbool) e_a in
|
||||
let typed_e_a = expect const_env h' (Tid Initial.pbool) e_a in
|
||||
(* property *)
|
||||
let typed_e_g = expect const_env h (Tid Initial.pbool) e_g in
|
||||
let typed_e_g = expect const_env h' (Tid Initial.pbool) e_g in
|
||||
|
||||
let typed_c, (c_names, h) = build const_env h c in
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ let rec print_type_def ff { t_name = name; t_desc = tdesc } =
|
|||
let print_contract ff { c_block = b;
|
||||
c_assume = e_a; c_enforce = e_g;
|
||||
c_controllables = c} =
|
||||
fprintf ff "@[<v2>contract@\n%a@ assume %a@ enforce %a@ with (%a)@]"
|
||||
fprintf ff "@[<v2>contract@\n%a@ assume %a@ enforce %a@ with (%a)@\n@]"
|
||||
print_block b
|
||||
print_exp e_a
|
||||
print_exp e_g
|
||||
|
|
|
@ -371,12 +371,17 @@ and translate_last = function
|
|||
| Last (None) -> Heptagon.Last None
|
||||
| Last (Some e) -> Heptagon.Last (Some (expect_static_exp e))
|
||||
|
||||
let translate_contract env ct =
|
||||
let b, _ = translate_block env ct.c_block in
|
||||
{ Heptagon.c_assume = translate_exp env ct.c_assume;
|
||||
Heptagon.c_enforce = translate_exp env ct.c_enforce;
|
||||
Heptagon.c_controllables = translate_vd_list env ct.c_controllables;
|
||||
Heptagon.c_block = b }
|
||||
let translate_contract env opt_ct =
|
||||
match opt_ct with
|
||||
| None -> None, env
|
||||
| Some ct ->
|
||||
let env' = Rename.append env ct.c_controllables in
|
||||
let b, env = translate_block env ct.c_block in
|
||||
Some
|
||||
{ Heptagon.c_assume = translate_exp env ct.c_assume;
|
||||
Heptagon.c_enforce = translate_exp env ct.c_enforce;
|
||||
Heptagon.c_controllables = translate_vd_list env' ct.c_controllables;
|
||||
Heptagon.c_block = b }, env'
|
||||
|
||||
let params_of_var_decs =
|
||||
List.map (fun vd -> Signature.mk_param
|
||||
|
@ -396,10 +401,9 @@ let translate_node node =
|
|||
let params = params_of_var_decs node.n_params in
|
||||
let inputs = translate_vd_list env0 node.n_input in
|
||||
let outputs = translate_vd_list env0 node.n_output in
|
||||
let b, env = translate_block env0 node.n_block in
|
||||
let contract =
|
||||
Misc.optional (translate_contract env) node.n_contract in
|
||||
(* the env of the block is used in the contract translation *)
|
||||
(* Enrich env with controllable variables (used in block) *)
|
||||
let contract, env = translate_contract env0 node.n_contract in
|
||||
let b, _ = translate_block env node.n_block in
|
||||
(* add the node signature to the environment *)
|
||||
let i = args_of_var_decs node.n_input in
|
||||
let o = args_of_var_decs node.n_output in
|
||||
|
|
|
@ -284,7 +284,23 @@ let block funs _ b =
|
|||
let _, (v_acc, eq_acc) = Hept_mapfold.block funs ([],[]) b in
|
||||
{ b with b_local = v_acc@b.b_local; b_equs = eq_acc}, ([], [])
|
||||
|
||||
let contract funs context c =
|
||||
let ({ c_block = b } as c), void_context =
|
||||
Hept_mapfold.contract funs context c in
|
||||
(* Non-void context could mean lost equations *)
|
||||
assert (void_context=([],[]));
|
||||
let context, e_a = translate Any ([],[]) c.c_assume in
|
||||
let context, e_e = translate Any context c.c_enforce in
|
||||
let (d_list, eq_list) = context in
|
||||
{ c with
|
||||
c_assume = e_a;
|
||||
c_enforce = e_e;
|
||||
c_block = { b with
|
||||
b_local = d_list@b.b_local;
|
||||
b_equs = eq_list@b.b_equs; }
|
||||
}, void_context
|
||||
|
||||
let program p =
|
||||
let funs = { defaults with block = block; eq = eq } in
|
||||
let funs = { defaults with block = block; eq = eq; contract = contract } in
|
||||
let p, _ = Hept_mapfold.program funs ([], []) p in
|
||||
p
|
||||
|
|
|
@ -585,12 +585,12 @@ let translate_contract map mem_var_tys =
|
|||
|
||||
(** Returns a map, mapping variables names to the variables
|
||||
where they will be stored. *)
|
||||
let subst_map inputs outputs locals mem_tys =
|
||||
let subst_map inputs outputs controllables c_locals locals mem_tys =
|
||||
(* Create a map that simply maps each var to itself *)
|
||||
let map =
|
||||
List.fold_left
|
||||
(fun m { Minils.v_ident = x; Minils.v_type = ty } -> Env.add x (mk_pattern ty (Lvar x)) m)
|
||||
Env.empty (inputs @ outputs @ locals)
|
||||
Env.empty (inputs @ outputs @ controllables @ c_locals @ locals)
|
||||
in
|
||||
List.fold_left (fun map (x, x_ty) -> Env.add x (mk_pattern x_ty (Lmem x)) map) map mem_tys
|
||||
|
||||
|
@ -601,7 +601,11 @@ let translate_node
|
|||
} as n) =
|
||||
Idents.enter_node f;
|
||||
let mem_var_tys = Mls_utils.node_memory_vars n in
|
||||
let subst_map = subst_map i_list o_list d_list mem_var_tys in
|
||||
let c_list, c_locals =
|
||||
match contract with
|
||||
| None -> [], []
|
||||
| Some c -> c.Minils.c_controllables, c.Minils.c_local in
|
||||
let subst_map = subst_map i_list o_list c_list c_locals d_list mem_var_tys in
|
||||
let (v, si, j, s_list) = translate_eq_list subst_map empty_call_context eq_list in
|
||||
let (si', j', s_list', d_list') = translate_contract subst_map mem_var_tys contract in
|
||||
let i_list = translate_var_dec i_list in
|
||||
|
|
|
@ -24,11 +24,15 @@ let eq _ (v, eqs) eq = match eq.eq_lhs, eq.eq_rhs.e_desc with
|
|||
| _, _ ->
|
||||
eq, (v, eq::eqs)
|
||||
|
||||
(* Leave contract unchanged (no output defined in it) *)
|
||||
let contract funs acc c = c, acc
|
||||
|
||||
let node funs acc nd =
|
||||
let nd, (v, eqs) = Mls_mapfold.node_dec funs (nd.n_local, []) nd in
|
||||
{ nd with n_local = v; n_equs = eqs }, acc
|
||||
|
||||
let program p =
|
||||
let funs = { Mls_mapfold.defaults with eq = eq; node_dec = node } in
|
||||
let funs = { Mls_mapfold.defaults with
|
||||
eq = eq; node_dec = node; contract = contract } in
|
||||
let p, _ = Mls_mapfold.program_it funs ([], []) p in
|
||||
p
|
||||
|
|
Loading…
Reference in a new issue