From 70710795384a4c8dffa4dd07cbb952fed406fed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9lio=20Brun?= <lelio.brun@isae-supaero.fr> Date: Wed, 25 Aug 2021 12:00:21 +0200 Subject: [PATCH] first draft with translated cocospec --- dune-project | 2 +- lustrec.opam | 5 +++- src/backends/Ada/ada_backend.ml | 2 +- src/backends/C/c_backend_spec.ml | 30 ++++++++++++--------- src/backends/EMF/EMF_backend.ml | 4 +-- src/causality.ml | 2 +- src/compiler_common.ml | 11 ++++---- src/corelang.ml | 45 ++++++++++++++++++-------------- src/lustre_types.ml | 2 +- src/lustre_types.mli | 2 +- src/machine_code.ml | 11 ++++---- src/machine_code_common.ml | 12 +++++---- src/machine_code_types.mli | 7 ++++- src/printers.ml | 2 +- 14 files changed, 79 insertions(+), 58 deletions(-) diff --git a/dune-project b/dune-project index cc7c384e..30fd9b40 100644 --- a/dune-project +++ b/dune-project @@ -1,4 +1,4 @@ -(lang dune 2.8) +(lang dune 2.9) (name lustrec) (version 1.7) diff --git a/lustrec.opam b/lustrec.opam index cc55f8a6..de638737 100644 --- a/lustrec.opam +++ b/lustrec.opam @@ -25,7 +25,7 @@ depends: [ ] depopts: ["z3"] build: [ - ["dune" "subst"] {dev} + ["dune" "subst" "--root" "."] {dev} [ "dune" "build" @@ -33,9 +33,12 @@ build: [ name "-j" jobs + "--promote-install-files" + "false" "@install" "@runtest" {with-test} "@doc" {with-doc} ] + ["dune" "install" "-p" name "--create-install-files" name] ] dev-repo: "git+https://cavale.enseeiht.fr/git/lustrec#unstable" diff --git a/src/backends/Ada/ada_backend.ml b/src/backends/Ada/ada_backend.ml index a94b1b12..fde6f784 100644 --- a/src/backends/Ada/ada_backend.ml +++ b/src/backends/Ada/ada_backend.ml @@ -86,7 +86,7 @@ let extract_contract machines m = l) -> assert false | Expr_appl call -> assert false *) in match m.mspec.mnode_spec with - | Some (NodeSpec ident) -> + | Some (NodeSpec (ident, _)) -> let machine_spec = find_submachine_from_ident ident machines in let guarantees = match machine_spec.mspec.mnode_spec with diff --git a/src/backends/C/c_backend_spec.ml b/src/backends/C/c_backend_spec.ml index bc226541..ceddd0f9 100644 --- a/src/backends/C/c_backend_spec.ml +++ b/src/backends/C/c_backend_spec.ml @@ -585,7 +585,7 @@ module PrintSpec = struct fmt ((f, mk_mem_reset m), (rc, tr)) | Value v -> - pp_c_val m mem_in (pp_c_var_read ~test_output:false m) fmt v + pp_c_val m mem_in (pp_c_var_read ~test_output:true m) fmt v in pp_spec mode @@ -961,9 +961,10 @@ module SrcMod = struct () let pp_node_spec m fmt = function - | Contract c -> - PrintSpec.pp_spec PrintSpec.TransitionMode m fmt c - | NodeSpec f -> + | Contract c + | NodeSpec (_, Some c) -> + PrintSpec.pp_spec PrintSpec.TransitionMode m fmt (Imply (c.mc_pre, c.mc_post)) + | NodeSpec (f, None) -> pp_print_string fmt f let pp_step_spec fmt machines self mem m = @@ -981,12 +982,15 @@ module SrcMod = struct let pp_if_outputs pp = if outputs = [] then pp_print_nothing else pp in - (* prevent printing an ensures clause with contract name *) - let spec = - match m.mspec.mnode_spec with - | Some (NodeSpec _) -> None - | s -> s - in + let spec = m.mspec.mnode_spec in + (* (\* prevent printing an ensures clause with contract name *\) + * let spec = + * match m.mspec.mnode_spec with + * | Some (NodeSpec _) -> None + * | s -> s + * in *) + let pp_spec = pp_print_option + (if m.mis_contract then pp_print_nothing else pp_ensures (pp_node_spec m)) in pp_acsl_cut ~ghost:m.mis_contract (fun fmt () -> @@ -1002,7 +1006,7 @@ module SrcMod = struct outputs (pp_ensures (pp_transition_aux' m)) (name, inputs @ outputs, "", "") - (pp_print_option (pp_ensures (pp_node_spec m))) + pp_spec spec else fprintf @@ -1022,7 +1026,7 @@ module SrcMod = struct (pp_transition_aux m (pp_old pp_ptr) pp_ptr (fun fmt v -> (if is_output m v then pp_ptr_decl else pp_var_decl) fmt v))) (name, inputs @ outputs, mem, mem) - (pp_print_option (pp_ensures (pp_node_spec m))) + pp_spec spec (pp_assigns pp_ptr_decl) outputs @@ -1095,7 +1099,7 @@ module SrcMod = struct let pp_contract fmt machines _self m = match m.mspec.mnode_spec with - | Some (NodeSpec f) -> + | Some (NodeSpec (f, _)) -> let m_f = find_machine f machines in pp_acsl_cut (pp_ghost diff --git a/src/backends/EMF/EMF_backend.ml b/src/backends/EMF/EMF_backend.ml index a605cd13..d2353f05 100644 --- a/src/backends/EMF/EMF_backend.ml +++ b/src/backends/EMF/EMF_backend.ml @@ -489,7 +489,7 @@ let pp_machine fmt m = (* TODO *) (* assert (c.locals = [] && c.consts = [] && c.stmts = [] && c.imports = []); *) fprintf fmt "\"spec\": %a,@ " pp_emf_spec c - | Some (NodeSpec id) -> fprintf fmt "\"contract\": \"%s\",@ " id); + | Some (NodeSpec (id, _)) -> fprintf fmt "\"contract\": \"%s\",@ " id); fprintf fmt "\"annots\": {@[<v 0> %a@]@ }" (pp_emf_annots_list (ref 0)) m.mannot; @@ -519,7 +519,7 @@ let pp_emf_imported_node fmt top = (match ind.nodei_spec with | None -> fprintf fmt "@ " | Some (Contract _) -> assert false (* should have been processed *) - | Some (NodeSpec id) -> fprintf fmt ",@ \"coco_contract\": %s" id); + | Some (NodeSpec (id, _)) -> fprintf fmt ",@ \"coco_contract\": %s" id); fprintf fmt "@]@ }" (* XXX: UNUSED *) (* with Unhandled msg -> diff --git a/src/causality.ml b/src/causality.ml index 243447ff..3116b1ce 100644 --- a/src/causality.ml +++ b/src/causality.ml @@ -475,7 +475,7 @@ module NodeDep = struct match nd.node_spec with | None -> [] - | Some (NodeSpec id) -> + | Some (NodeSpec (id, _)) -> [ id ] | Some (Contract c) -> get_contract_calls (fun _ -> true) c diff --git a/src/compiler_common.ml b/src/compiler_common.ml index 2c087aef..0754aa04 100644 --- a/src/compiler_common.ml +++ b/src/compiler_common.ml @@ -330,7 +330,8 @@ let resolve_contracts prog = c.spec_loc top.top_decl_owner top.top_decl_itf - (Node nd) + (Node nd), + c (* { nd with * node_dec_stateless = stateless; * node_stateless = Some stateless; @@ -372,11 +373,11 @@ let resolve_contracts prog = | Some (Contract _) -> (* A contract: processing it *) (* we bind a fresh node *) - let new_nd = process_contract_new_node accu_contracts prog top in + let new_nd, new_c = process_contract_new_node accu_contracts prog top in (* Format.eprintf "Creating new contract node %s@." (node_name new_nd); *) let nd = - { nd with node_spec = Some (NodeSpec (node_name new_nd)) } + { nd with node_spec = Some (NodeSpec (node_name new_nd, Some new_c)) } in ( new_nd :: accu_contracts, { top with top_decl_desc = Node nd } :: accu_nodes )) @@ -391,9 +392,9 @@ let resolve_contracts prog = | Some (Contract _) -> (* A contract: processing it *) (* we bind a fresh node *) - let new_nd = process_contract_new_node accu_contracts prog top in + let new_nd, new_c = process_contract_new_node accu_contracts prog top in let ind = - { ind with nodei_spec = Some (NodeSpec (node_name new_nd)) } + { ind with nodei_spec = Some (NodeSpec (node_name new_nd, Some new_c)) } in ( new_nd :: accu_contracts, { top with top_decl_desc = ImportedNode ind } :: accu_nodes )) diff --git a/src/corelang.ml b/src/corelang.ml index 2c546608..e25a50ea 100644 --- a/src/corelang.ml +++ b/src/corelang.ml @@ -121,12 +121,12 @@ let mkeq loc (lhs, rhs) = { eq_lhs = lhs; eq_rhs = rhs; eq_loc = loc } let mkassert loc expr = { assert_loc = loc; assert_expr = expr } -let mktop_decl loc own itf d = +let mktop_decl top_decl_loc top_decl_owner top_decl_itf top_decl_desc = { - top_decl_desc = d; - top_decl_loc = loc; - top_decl_owner = own; - top_decl_itf = itf; + top_decl_desc; + top_decl_loc; + top_decl_owner; + top_decl_itf; } let mkpredef_call loc funname args = @@ -1057,6 +1057,22 @@ let rename_import f_node f_var imp = outputs = rename_expr imp.outputs; } +let rename_contract f_var f_node c = + let rename_var = rename_var f_var in + let rename_vars = List.map rename_var in + let rename_eexpr = rename_eexpr f_node f_var in + let rename_stmts = rename_stmts f_node f_var in + { + c with + consts = rename_vars c.consts; + locals = rename_vars c.locals; + stmts = rename_stmts c.stmts; + assume = List.map rename_eexpr c.assume; + guarantees = List.map rename_eexpr c.guarantees; + modes = List.map (rename_mode f_node f_var) c.modes; + imports = List.map (rename_import f_node f_var) c.imports; + } + let rename_node f_node f_var nd = let f_var x = (* checking that this is actually a local variable *) @@ -1066,7 +1082,6 @@ let rename_node f_node f_var nd = let rename_var = rename_var f_var in let rename_vars = List.map rename_var in let rename_expr = rename_expr f_node f_var in - let rename_eexpr = rename_eexpr f_node f_var in let rename_stmts = rename_stmts f_node f_var in let inputs = rename_vars nd.node_inputs in let outputs = rename_vars nd.node_outputs in @@ -1087,23 +1102,13 @@ let rename_node f_node f_var nd = let node_stmts = rename_stmts nd.node_stmts in let spec = - Utils.option_map + option_map (fun s -> match s with - | NodeSpec id -> - NodeSpec (f_node id) + | NodeSpec (id, oc) -> + NodeSpec (f_node id, option_map (rename_contract f_var f_node) oc) | Contract c -> - Contract - { - c with - consts = rename_vars c.consts; - locals = rename_vars c.locals; - stmts = rename_stmts c.stmts; - assume = List.map rename_eexpr c.assume; - guarantees = List.map rename_eexpr c.guarantees; - modes = List.map (rename_mode f_node f_var) c.modes; - imports = List.map (rename_import f_node f_var) c.imports; - }) + Contract (rename_contract f_var f_node c)) nd.node_spec in let annot = rename_annots f_node f_var nd.node_annot in diff --git a/src/lustre_types.ml b/src/lustre_types.ml index 3f8b8371..a408e00e 100644 --- a/src/lustre_types.ml +++ b/src/lustre_types.ml @@ -162,7 +162,7 @@ type contract_desc = { spec_loc : Location.t; } -type 'a node_spec_t = Contract of 'a | NodeSpec of ident +type 'a node_spec_t = Contract of 'a | NodeSpec of ident * 'a option type node_desc = { node_id : ident; diff --git a/src/lustre_types.mli b/src/lustre_types.mli index 1ad1a88f..563efec0 100644 --- a/src/lustre_types.mli +++ b/src/lustre_types.mli @@ -151,7 +151,7 @@ type contract_desc = { spec_loc : Location.t; } -type 'a node_spec_t = Contract of 'a | NodeSpec of ident +type 'a node_spec_t = Contract of 'a | NodeSpec of ident * 'a option type node_desc = { node_id : ident; diff --git a/src/machine_code.ml b/src/machine_code.ml index 77f52136..48e8600f 100644 --- a/src/machine_code.ml +++ b/src/machine_code.ml @@ -514,15 +514,16 @@ let translate_eexpr env e = e.eexpr_quantifiers (Value (translate_expr env e.eexpr_qfexpr)) -let translate_contract env c = - Imply (And (List.map (translate_eexpr env) c.Lustre_types.assume), - And (List.map (translate_eexpr env) c.Lustre_types.guarantees)) +let translate_contract env c = { + mc_pre = And (List.map (translate_eexpr env) c.Lustre_types.assume); + mc_post = And (List.map (translate_eexpr env) c.Lustre_types.guarantees) +} let translate_spec env = function | Contract c -> Contract (translate_contract env c) - | NodeSpec s -> - NodeSpec s + | NodeSpec (s, c) -> + NodeSpec (s, option_map (translate_contract env) c) let translate_decl nd sch = (* Format.eprintf "Translating node %s@." nd.node_id; *) diff --git a/src/machine_code_common.ml b/src/machine_code_common.ml index 3f0d6f7d..306be7b4 100644 --- a/src/machine_code_common.ml +++ b/src/machine_code_common.ml @@ -313,9 +313,10 @@ let pp_transitions m fmt = | _ -> fprintf fmt "@[<v 2>transitions:@ %a@]" (pp_print_list (pp_transition m)) -let pp_mspec m fmt spec = - fprintf fmt "@[<v>contract %a;]" - (PrintSpec.pp_spec m) spec +let pp_mspec m fmt c = + fprintf fmt "@[<v>contract: G (H (%a) => %a);]" + (PrintSpec.pp_spec m) c.mc_pre + (PrintSpec.pp_spec m) c.mc_post let pp_machine fmt m = fprintf @@ -338,8 +339,9 @@ let pp_machine fmt m = match m.mspec.mnode_spec with | None -> () - | Some (NodeSpec id) -> - fprintf fmt "cocospec: %s" id + | Some (NodeSpec (id, c)) -> + fprintf fmt "cocospec: %s@;%a" id + (pp_print_option (pp_mspec m)) c | Some (Contract spec) -> pp_mspec m fmt spec) (pp_memory_packs m) diff --git a/src/machine_code_types.mli b/src/machine_code_types.mli index 25d8e732..f9bd1744 100644 --- a/src/machine_code_types.mli +++ b/src/machine_code_types.mli @@ -57,8 +57,13 @@ type mc_transition_t = value_t transition_t type mc_memory_pack_t = value_t memory_pack_t +type mc_contract_t = { + mc_pre: mc_formula_t; + mc_post: mc_formula_t; +} + type machine_spec = { - mnode_spec : mc_formula_t node_spec_t option; + mnode_spec : mc_contract_t node_spec_t option; mtransitions : mc_transition_t list; mmemory_packs : mc_memory_pack_t list; } diff --git a/src/printers.ml b/src/printers.ml index 15bae926..4b6e89c4 100644 --- a/src/printers.ml +++ b/src/printers.ml @@ -581,7 +581,7 @@ let pp_spec_as_comment fmt (inl, outl, spec) = fprintf fmt "@[<hov 2>(*@contract@ "; pp_spec fmt c; fprintf fmt "@]*)@ " - | NodeSpec name -> + | NodeSpec (name, _) -> (* Pushing stmts in contract. We update the original information with the computed one in nd. *) let pp_l = pp_comma_list pp_var_name in -- GitLab