From 893dcc99c6c9b41246c6c2cad79d408718d0c455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9lio=20Brun?= <lelio.brun@isae-supaero.fr> Date: Wed, 18 May 2022 14:29:49 +0200 Subject: [PATCH] generate *_memory.h and *_spec.h headers --- src/backends/C/c_backend.ml | 36 ++- src/backends/C/c_backend_common.ml | 7 +- src/backends/C/c_backend_common.mli | 1 + src/backends/C/c_backend_header.ml | 103 ++++-- src/backends/C/c_backend_header.mli | 8 +- src/backends/C/c_backend_spec.ml | 474 ++++++++++++++-------------- src/backends/C/c_backend_src.ml | 35 +- src/backends/C/c_backend_src.mli | 3 +- 8 files changed, 369 insertions(+), 298 deletions(-) diff --git a/src/backends/C/c_backend.ml b/src/backends/C/c_backend.ml index 5e524fee..62c7014f 100644 --- a/src/backends/C/c_backend.ml +++ b/src/backends/C/c_backend.ml @@ -38,12 +38,26 @@ let with_main_node machines node f = f m let gen_files - ( print_alloc_header, + generate_spec_header + ( print_memory_header, + print_alloc_header, + print_spec_header, print_lib_c, print_main_c, print_makefile (* , print_cmake *) ) basename prog machines dependencies = let destname = !Options.dest_dir ^ "/" ^ basename in + (* Generating H spec file *) + if generate_spec_header then + let spec_header_file = destname ^ "_spec.h" in + with_out_file spec_header_file (fun header_fmt -> + print_spec_header header_fmt basename machines dependencies); + + (* Generating H memory file *) + let memory_header_file = destname ^ "_memory.h" in + with_out_file memory_header_file (fun header_fmt -> + print_memory_header header_fmt basename machines dependencies); + (* Generating H alloc file *) let alloc_header_file = destname ^ "_alloc.h" in (* Could be changed *) @@ -115,23 +129,25 @@ let print_c_header basename = (* Generating H file *) let lusic = Lusic.read_lusic destname ".lusic" in let header_file = destname ^ ".h" in - with_out_file header_file (fun header_fmt -> - assert (not lusic.obsolete); - Header.pp_header_from_header header_fmt basename lusic.contents) + with_out_file header_file @@ fun header_fmt -> + assert (not lusic.obsolete); + Header.pp_header_from_header header_fmt basename lusic.contents let translate_to_c generate_c_header basename prog machines dependencies = - let header_m, source_m, source_main_m, makefile_m, machines = + let generate_spec_header, header_m, source_m, source_main_m, makefile_m, machines = let open Options in match !spec with | SpecNo -> - ( C_backend_header.((module EmptyMod : MODIFIERS_HDR)), + ( false, + C_backend_header.((module EmptyMod : MODIFIERS_HDR)), C_backend_src.((module EmptyMod : MODIFIERS_SRC)), C_backend_main.((module EmptyMod : MODIFIERS_MAINSRC)), C_backend_makefile.((module EmptyMod : MODIFIERS_MKF)), machines ) | SpecACSL -> let open C_backend_spec in - ( C_backend_header.((module HdrMod : MODIFIERS_HDR)), + ( true, + C_backend_header.((module HdrMod : MODIFIERS_HDR)), C_backend_src.((module SrcMod : MODIFIERS_SRC)), C_backend_main.((module MainMod : MODIFIERS_MAINSRC)), C_backend_makefile.((module MakefileMod : MODIFIERS_MKF)), @@ -146,14 +162,16 @@ let translate_to_c generate_c_header basename prog machines dependencies = let module Makefile = C_backend_makefile.Main ((val makefile_m)) in (* let module CMakefile = C_backend_cmake.Main (MakefileMod) in *) let funs = - ( Header.pp_alloc_header, + ( Header.pp_memory_header, + Header.pp_alloc_header, + Header.pp_spec_header, Source.pp_lib_c, SourceMain.pp_main_c, Makefile.pp_makefile ) (* CMakefile.print_makefile *) in if generate_c_header then print_c_header basename; - gen_files funs basename prog machines dependencies + gen_files generate_spec_header funs basename prog machines dependencies (* Local Variables: *) (* compile-command:"make -C ../../.." *) diff --git a/src/backends/C/c_backend_common.ml b/src/backends/C/c_backend_common.ml index b74c6d95..bc26d978 100644 --- a/src/backends/C/c_backend_common.ml +++ b/src/backends/C/c_backend_common.ml @@ -931,10 +931,13 @@ module Protos (Mod : MODIFIERS_GHOST_PROTO) = struct outputs end -let pp_import_prototype fmt dep = fprintf fmt "#include \"%s.h\"" dep.name +let pp_import_prototype fmt dep = fprintf fmt "#include \"%s.h\"@," dep.name + +let pp_import_memory_prototype fmt dep = + if dep.is_stateful then fprintf fmt "#include \"%s_memory.h\"@," dep.name let pp_import_alloc_prototype fmt dep = - if dep.is_stateful then fprintf fmt "#include \"%s_alloc.h\"" dep.name + if dep.is_stateful then fprintf fmt "#include \"%s_alloc.h\"@," dep.name let pp_c_var m self pp_var fmt var = pp_c_val m self pp_var fmt (Machine_code_common.mk_val (Var var) var.var_type) diff --git a/src/backends/C/c_backend_common.mli b/src/backends/C/c_backend_common.mli index a0a5c28a..ef7c56af 100644 --- a/src/backends/C/c_backend_common.mli +++ b/src/backends/C/c_backend_common.mli @@ -25,6 +25,7 @@ val pp_alloc_prototype : formatter -> ident * var_decl list -> unit val pp_dealloc_prototype : formatter -> ident -> unit val pp_import_prototype : formatter -> dep_t -> unit val pp_import_alloc_prototype : formatter -> dep_t -> unit +val pp_import_memory_prototype : formatter -> dep_t -> unit val pp_c_var_read : ?test_output:bool -> machine_t -> formatter -> var_decl -> unit diff --git a/src/backends/C/c_backend_header.ml b/src/backends/C/c_backend_header.ml index 3d8400ea..7e08852b 100644 --- a/src/backends/C/c_backend_header.ml +++ b/src/backends/C/c_backend_header.ml @@ -24,8 +24,8 @@ module Mpfr = Lustrec_mpfr module type MODIFIERS_HDR = sig module GhostProto : MODIFIERS_GHOST_PROTO - val pp_machine_decl_prefix : formatter -> machine_t -> unit val pp_predicates : formatter -> machine_t list -> unit + val pp_machine_decl_prefix : formatter -> machine_t -> unit val pp_import_arrow : formatter -> unit -> unit val pp_machine_alloc_decl : formatter -> machine_t -> unit end @@ -33,9 +33,10 @@ end module EmptyMod = struct module GhostProto = EmptyGhostProto - let pp_machine_decl_prefix _ _ = () let pp_predicates _ _ = () + let pp_machine_decl_prefix _ _ = () + let pp_import_arrow fmt () = fprintf fmt @@ -244,48 +245,47 @@ functor (* Include once: start *) let machines' = List.filter (fun m -> not m.mis_contract) machines in let baseNAME = file_to_module_name basename in + let self_dep = { + local = true; + name = basename; + content = []; + is_stateful = true (* assuming it is stateful *); + } + in fprintf header_fmt "@[<v>%a@,\ - #ifndef _%s_alloc@,\ - #define _%s_alloc@,\ + #ifndef _%s_ALLOC@,\ + #define _%s_ALLOC@,\ @,\ /* Import header from %s */@,\ - %a@,\ + %a\ @,\ - %a%a%a%a%a#endif@]@." + /* Import memory header from %s */@,\ + %a\ + @,\ + %a%a%a#endif@]@." (* Print the svn version number and the supported C standard (C90 or C99) *) pp_print_version () baseNAME baseNAME - (* Import the header *) basename + (* Import the header *) + basename pp_import_prototype - { - local = true; - name = basename; - content = []; - is_stateful = true (* assuming it is staful *); - } - (* Print dependencies *) + self_dep + (* Import the memory header *) + basename + pp_import_memory_prototype + self_dep + (* Print dependencies *) (pp_print_list ~pp_open_box:pp_open_vbox0 ~pp_prologue:(pp_print_endcut "/* Import dependencies */") pp_import_alloc_prototype ~pp_epilogue:pp_print_cutcut) dependencies - (* Print the struct definitions of all machines. *) - (pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_prologue:(pp_print_endcut "/* Struct definitions */") - ~pp_sep:pp_print_cutcut - pp_machine_struct - ~pp_epilogue:pp_print_cutcut) - machines' - (* Copy the spec (valid and memory packs predicates). *) - Mod.pp_predicates - machines (* Print the prototypes of all machines *) (pp_print_list ~pp_open_box:pp_open_vbox0 @@ -399,6 +399,59 @@ functor pp_machine_decl_top_decl_from_header ~pp_epilogue:pp_print_cutcut) nodes + + let pp_memory_header header_fmt basename machines dependencies = + (* Include once: start *) + let machines' = List.filter (fun m -> not m.mis_contract) machines in + let baseNAME = file_to_module_name basename in + fprintf + header_fmt + "@[<v>%a@,\ + #ifndef _%s_MEMORY@,\ + #define _%s_MEMORY@,\ + @,\ + %a%a#endif@]@." + (* Print the svn version number and the supported C standard (C90 or + C99) *) + pp_print_version + () + baseNAME + baseNAME + (* Print dependencies *) + (pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_prologue:(pp_print_endcut "/* Import dependencies */") + pp_import_memory_prototype + ~pp_epilogue:pp_print_cutcut) + dependencies + (* Print the struct definitions of all machines. *) + (pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_prologue:(pp_print_endcut "/* Struct definitions */") + ~pp_sep:pp_print_cutcut + pp_machine_struct + ~pp_epilogue:pp_print_cutcut) + machines' + (* Include once: end *) + + let pp_spec_header header_fmt basename machines _dependencies = + let baseNAME = file_to_module_name basename in + fprintf + header_fmt + "@[<v>%a@,\ + #ifndef _%s_SPEC@,\ + #define _%s_SPEC@,\ + @,\ + %a#endif@]@." + (* Print the svn version number and the supported C standard (C90 or + C99) *) + pp_print_version + () + baseNAME + baseNAME + Mod.pp_predicates + machines + end (* Local Variables: *) (* compile-command:"make -C ../../.." *) diff --git a/src/backends/C/c_backend_header.mli b/src/backends/C/c_backend_header.mli index 4f4aa965..cda9efcb 100644 --- a/src/backends/C/c_backend_header.mli +++ b/src/backends/C/c_backend_header.mli @@ -6,8 +6,8 @@ open C_backend_common module type MODIFIERS_HDR = sig module GhostProto : MODIFIERS_GHOST_PROTO - val pp_machine_decl_prefix : formatter -> machine_t -> unit val pp_predicates : formatter -> machine_t list -> unit + val pp_machine_decl_prefix : formatter -> machine_t -> unit val pp_import_arrow : formatter -> unit -> unit val pp_machine_alloc_decl : formatter -> machine_t -> unit end @@ -19,4 +19,10 @@ module Main (Mod : MODIFIERS_HDR) : sig val pp_alloc_header : formatter -> string -> machine_t list -> dep_t list -> unit + + val pp_memory_header : + formatter -> string -> machine_t list -> dep_t list -> unit + + val pp_spec_header : + formatter -> string -> machine_t list -> dep_t list -> unit end diff --git a/src/backends/C/c_backend_spec.ml b/src/backends/C/c_backend_spec.ml index bcead9c2..fc8ae024 100644 --- a/src/backends/C/c_backend_spec.ml +++ b/src/backends/C/c_backend_spec.ml @@ -901,6 +901,209 @@ let pp_reset_flag_chain ?(indirect = true) ptr fmt mems = let pp_arrow_reset_ghost mem fmt inst = fprintf fmt "%s_reset_ghost(%a)" Arrow.arrow_id pp_indirect' (mem, inst) +let contract_of machines m = + match m.mspec.mnode_spec with + | Some spec -> ( + match spec with + | Contract c -> + Some c, None + | NodeSpec f -> ( + let m_f = find_machine f machines in + match m_f.mspec.mnode_spec with + | Some (Contract c) -> + Some c, Some m_f + | _ -> + None, None)) + | None -> + None, None + +let rename n x = sprintf "%s_%d" x n +let rename_var_decl n vd = { vd with var_id = rename n vd.var_id } + +let pp_k_induction_case base m m_c pp_mem_out pp_vars fmt + (n, mem_out) = + let name = m.mname.node_id in + fprintf + fmt + "%s_%s_%d(@[<hov>%a,@;%a@])" + name + (if base then "base" else "inductive") + n + pp_mem_out + mem_out + pp_vars + (List.map (rename_var_decl n) m_c.mstep.step_outputs) + +let pp_k_induction_case_def base m (_, m_c, _) fmt n = + let name = m.mname.node_id in + let name_c = m_c.mname.node_id in + let mem = mk_mem m in + let mem_c = mk_mem_c m in + let inputs = m.mstep.step_inputs in + let outputs = m.mstep.step_outputs in + let stateless = fst (get_stateless_status m) in + let stateless_c = fst (get_stateless_status m_c) in + let l = List.init (n + 1) Fun.id in + let l_pp = List.concat_map (function + | 0 -> + let pp = pp_reset_set' in + [ + fun fmt -> + (if stateless_c then fun fmt (x, _) -> pp fmt x + else pp_and pp pp) + fmt + ((name, rename 0 mem), (name_c, rename 0 mem_c)) + ] + | n' -> + let pp_var_c fmt (out, vd) = + if out && n' < n then pp_true_c_bool fmt () + else pp_var_decl fmt vd + in + let c_inputs = + List.map + (fun v -> false, rename_var_decl n' v) + m_c.mstep.step_inputs + in + let c_outputs = + List.map + (fun v -> true, rename_var_decl n' v) + m_c.mstep.step_outputs + in + let pp stateless pp_var = + pp_transition_aux + stateless + pp_print_string + pp_print_string + pp_var + in + [ + (fun fmt -> + pp stateless pp_var_decl fmt + ( name, + List.map (rename_var_decl n') (inputs @ outputs), + rename (n' - 1) mem, + rename n' mem )); + (fun fmt -> + pp stateless_c pp_var_c fmt + ( name_c, + c_inputs @ c_outputs, + rename (n' - 1) mem_c, + rename n' mem_c )) + ]) l + in + let l_pp = if base then l_pp else List.tl l_pp in + let pp fmt () = + let pp fmt () = pp_and_l (fun fmt f -> f fmt) fmt l_pp in + if stateless_c then pp fmt () + else + pp_exists + (pp_machine_decl + ~ghost:true + (pp_comma_list (fun fmt n -> + pp_print_string fmt (rename n mem_c)))) + pp + fmt + ((name_c, l), ()) + in + pp_predicate + (pp_k_induction_case + base + m + m_c + (pp_machine_decl' ~ghost:true) + (pp_locals m_c)) + (pp_exists + (fun fmt l -> + fprintf + fmt + "%a@,%a" + (pp_machine_decl + ~ghost:true + (pp_comma_list ~pp_eol:pp_print_comma (fun fmt n -> + pp_print_string fmt (rename (n - 1) mem)))) + (name, l) + (pp_locals m) + (List.concat_map (fun n -> + List.map (rename_var_decl n) (inputs @ outputs)) + l)) + pp) + fmt + ( (n, (name, rename n mem)), + ( List.tl l, () ) ) + +let pp_base_case_defs m fmt (_, _, k as c_m_k) = + let l = List.init (k - 1) succ in + pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_sep:pp_print_cutcut + (pp_k_induction_case_def true m c_m_k) + fmt + l + +let pp_inductive_case_def m fmt (_, _, k as c_m_k) = + pp_k_induction_case_def false m c_m_k fmt k + +let pp_k_induction_lemmas m fmt (_, m_c, k) = + let name = m.mname.node_id in + let mem = mk_mem m in + let l = List.init k (fun n -> n + 1) in + pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_sep:pp_print_cutcut + (fun fmt n -> + let outputs = List.map (rename_var_decl n) m_c.mstep.step_outputs in + pp_lemma + (fun fmt n -> fprintf fmt "%s_k_induction_%d" name n) + (pp_forall + (fun fmt () -> + fprintf + fmt + "%a,@;%a" + (pp_machine_decl' ~ghost:true) + (name, mem) + (pp_locals m_c) + outputs) + (pp_implies + (pp_k_induction_case + (n <> k) + m + m_c + pp_print_string + (pp_comma_list pp_var_decl)) + (pp_and_l + (fun fmt x -> + pp_equal pp_var_decl pp_print_int fmt (x, 1))))) + fmt + (n, ((), ((n, mem), outputs)))) + fmt + l + +let pp_k_induction m fmt c_m_k = + pp_acsl_cut + (fun fmt () -> + fprintf + fmt + "%a@,@,%a@,@,%a" + (pp_base_case_defs m) + c_m_k + (pp_inductive_case_def m) + c_m_k + (pp_k_induction_lemmas m) + c_m_k) + fmt + () + +let pp_proof_annotation m m_c fmt c = + let pp m_c fmt = function + | Kinduction k -> + pp_k_induction m fmt (c, m_c, k) + in + match m_c with + | Some m_c -> + pp_print_option (pp m_c) fmt c.mc_proof + | None -> + () + module GhostProto : MODIFIERS_GHOST_PROTO = struct let pp_ghost_parameters ?(cut = true) fmt vs = fprintf @@ -916,15 +1119,6 @@ end module HdrMod = struct module GhostProto = GhostProto - let pp_machine_decl_prefix _ _ = () - - let pp_import_arrow fmt () = - fprintf - fmt - "#include \"%s/arrow_spec.h%s\"" - (Arrow.arrow_top_decl ()).top_decl_owner - (if !Options.cpp then "pp" else "") - let pp_predicates fmt machines = let pp_preds comment pp = pp_print_list @@ -935,11 +1129,38 @@ module HdrMod = struct in fprintf fmt - "%a%a" + "%a%a%a%a%a%a%a%a" (pp_preds "/* ACSL `valid` predicates */" pp_mem_valid_def) machines (pp_preds "/* ACSL `memory pack` simulations */" pp_memory_pack_defs) machines + (pp_preds "/* ACSL initialization annotations */" pp_initialization_def) + machines + (pp_preds "/* ACSL reset cleared annotations */" pp_reset_cleared_def) + machines + (pp_preds "/* ACSL reset set annotations */" pp_reset_set_def) + machines + (pp_preds "/* ACSL transition annotations */" pp_transition_defs) + machines + (pp_preds + "/* ACSL transition memory footprints lemmas */" + pp_transition_footprint_lemmas) + machines + (pp_preds + "/* k-induction predicates and lemmas */" + (fun fmt m -> + let c, m_c = contract_of machines m in + (pp_print_option (pp_proof_annotation m m_c) fmt c))) + machines + + let pp_machine_decl_prefix _ _ = () + + let pp_import_arrow fmt () = + fprintf + fmt + "#include \"%s/arrow_spec.h%s\"" + (Arrow.arrow_top_decl ()).top_decl_owner + (if !Options.cpp then "pp" else "") let pp_machine_alloc_decl fmt m = pp_machine_decl_prefix fmt m; @@ -968,33 +1189,8 @@ end module SrcMod = struct module GhostProto = GhostProto - let pp_predicates fmt machines = - let pp_preds comment pp = - pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_prologue:(pp_print_endcut comment) - pp - ~pp_epilogue:pp_print_cutcut - in - fprintf - fmt - "%a%a%a%a%a%a%a" - (pp_preds "/* ACSL `valid` predicates */" pp_mem_valid_def) - machines - (pp_preds "/* ACSL `memory pack` simulations */" pp_memory_pack_defs) - machines - (pp_preds "/* ACSL initialization annotations */" pp_initialization_def) - machines - (pp_preds "/* ACSL reset cleared annotations */" pp_reset_cleared_def) - machines - (pp_preds "/* ACSL reset set annotations */" pp_reset_set_def) - machines - (pp_preds "/* ACSL transition annotations */" pp_transition_defs) - machines - (pp_preds - "/* ACSL transition memory footprints lemmas */" - pp_transition_footprint_lemmas) - machines + let pp_import_spec_prototype fmt dep = + fprintf fmt "#include \"%s_spec.h\"@," dep.name let pp_clear_reset_spec fmt self mem m = let name = m.mname.node_id in @@ -1060,25 +1256,6 @@ module SrcMod = struct (* let pp_contract m fmt c = *) (* PrintSpec.pp_spec PrintSpec.TransitionMode m fmt (spec_from_contract c) *) - let contract_of machines m = - match m.mspec.mnode_spec with - | Some spec -> ( - match spec with - | Contract c -> - Some c, None - | NodeSpec f -> ( - let m_f = find_machine f machines in - match m_f.mspec.mnode_spec with - | Some (Contract c) -> - Some c, Some m_f - | _ -> - None, None)) - | None -> - None, None - - let rename n x = sprintf "%s_%d" x n - let rename_var_decl n vd = { vd with var_id = rename n vd.var_id } - (** UNUSED *) (* let rec rename_value n v = *) (* { *) @@ -1144,190 +1321,6 @@ module SrcMod = struct (* mc_post = rename_formula n c.mc_post; *) (* } *) - let pp_k_induction_case base m m_c pp_mem_out pp_vars fmt - (n, mem_out) = - let name = m.mname.node_id in - fprintf - fmt - "%s_%s_%d(@[<hov>%a,@;%a@])" - name - (if base then "base" else "inductive") - n - pp_mem_out - mem_out - pp_vars - (List.map (rename_var_decl n) m_c.mstep.step_outputs) - - let pp_k_induction_case_def base m (_, m_c, _) fmt n = - let name = m.mname.node_id in - let name_c = m_c.mname.node_id in - let mem = mk_mem m in - let mem_c = mk_mem_c m in - let inputs = m.mstep.step_inputs in - let outputs = m.mstep.step_outputs in - let stateless = fst (get_stateless_status m) in - let stateless_c = fst (get_stateless_status m_c) in - let l = List.init (n + 1) Fun.id in - let l_pp = List.concat_map (function - | 0 -> - let pp = pp_reset_set' in - [ - fun fmt -> - (if stateless_c then fun fmt (x, _) -> pp fmt x - else pp_and pp pp) - fmt - ((name, rename 0 mem), (name_c, rename 0 mem_c)) - ] - | n' -> - let pp_var_c fmt (out, vd) = - if out && n' < n then pp_true_c_bool fmt () - else pp_var_decl fmt vd - in - let c_inputs = - List.map - (fun v -> false, rename_var_decl n' v) - m_c.mstep.step_inputs - in - let c_outputs = - List.map - (fun v -> true, rename_var_decl n' v) - m_c.mstep.step_outputs - in - let pp stateless pp_var = - pp_transition_aux - stateless - pp_print_string - pp_print_string - pp_var - in - [ - (fun fmt -> - pp stateless pp_var_decl fmt - ( name, - List.map (rename_var_decl n') (inputs @ outputs), - rename (n' - 1) mem, - rename n' mem )); - (fun fmt -> - pp stateless_c pp_var_c fmt - ( name_c, - c_inputs @ c_outputs, - rename (n' - 1) mem_c, - rename n' mem_c )) - ]) l - in - let l_pp = if base then l_pp else List.tl l_pp in - let pp fmt () = - let pp fmt () = pp_and_l (fun fmt f -> f fmt) fmt l_pp in - if stateless_c then pp fmt () - else - pp_exists - (pp_machine_decl - ~ghost:true - (pp_comma_list (fun fmt n -> - pp_print_string fmt (rename n mem_c)))) - pp - fmt - ((name_c, l), ()) - in - pp_predicate - (pp_k_induction_case - base - m - m_c - (pp_machine_decl' ~ghost:true) - (pp_locals m_c)) - (pp_exists - (fun fmt l -> - fprintf - fmt - "%a@,%a" - (pp_machine_decl - ~ghost:true - (pp_comma_list ~pp_eol:pp_print_comma (fun fmt n -> - pp_print_string fmt (rename (n - 1) mem)))) - (name, l) - (pp_locals m) - (List.concat_map (fun n -> - List.map (rename_var_decl n) (inputs @ outputs)) - l)) - pp) - fmt - ( (n, (name, rename n mem)), - ( List.tl l, () ) ) - - let pp_base_case_defs m fmt (_, _, k as c_m_k) = - let l = List.init (k - 1) succ in - pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_sep:pp_print_cutcut - (pp_k_induction_case_def true m c_m_k) - fmt - l - - let pp_inductive_case_def m fmt (_, _, k as c_m_k) = - pp_k_induction_case_def false m c_m_k fmt k - - let pp_k_induction_lemmas m fmt (_, m_c, k) = - let name = m.mname.node_id in - let mem = mk_mem m in - let l = List.init k (fun n -> n + 1) in - pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_sep:pp_print_cutcut - (fun fmt n -> - let outputs = List.map (rename_var_decl n) m_c.mstep.step_outputs in - pp_lemma - (fun fmt n -> fprintf fmt "%s_k_induction_%d" name n) - (pp_forall - (fun fmt () -> - fprintf - fmt - "%a,@;%a" - (pp_machine_decl' ~ghost:true) - (name, mem) - (pp_locals m_c) - outputs) - (pp_implies - (pp_k_induction_case - (n <> k) - m - m_c - pp_print_string - (pp_comma_list pp_var_decl)) - (pp_and_l - (fun fmt x -> - pp_equal pp_var_decl pp_print_int fmt (x, 1))))) - fmt - (n, ((), ((n, mem), outputs)))) - fmt - l - - let pp_k_induction m fmt c_m_k = - pp_acsl_cut - (fun fmt () -> - fprintf - fmt - "%a@,@,%a@,@,%a" - (pp_base_case_defs m) - c_m_k - (pp_inductive_case_def m) - c_m_k - (pp_k_induction_lemmas m) - c_m_k) - fmt - () - - let pp_proof_annotation m m_c fmt c = - let pp m_c fmt = function - | Kinduction k -> - pp_k_induction m fmt (c, m_c, k) - in - match m_c with - | Some m_c -> - pp_print_option (pp m_c) fmt c.mc_proof - | None -> - () - let pp_step_spec fmt machines self mem m = let name = m.mname.node_id in let insts = instances machines m in @@ -1420,7 +1413,6 @@ module SrcMod = struct (* | _ -> *) (* pp_print_nothing *) (* in *) - pp_print_option (pp_proof_annotation m m_c) fmt c; (* pp_spec_vars fmt (); *) pp_acsl_cut (fun fmt () -> diff --git a/src/backends/C/c_backend_src.ml b/src/backends/C/c_backend_src.ml index 4fa2b900..06da4eac 100644 --- a/src/backends/C/c_backend_src.ml +++ b/src/backends/C/c_backend_src.ml @@ -21,7 +21,8 @@ module Mpfr = Lustrec_mpfr module type MODIFIERS_SRC = sig module GhostProto : MODIFIERS_GHOST_PROTO - val pp_predicates : formatter -> machine_t list -> unit + val pp_import_spec_prototype : formatter -> dep_t -> unit + val pp_set_reset_spec : formatter -> ident -> ident -> machine_t -> unit val pp_clear_reset_spec : formatter -> ident -> ident -> machine_t -> unit @@ -41,7 +42,7 @@ end module EmptyMod = struct module GhostProto = EmptyGhostProto - let pp_predicates _ _ = () + let pp_import_spec_prototype _ _ = () let pp_set_reset_spec _ _ _ _ = () let pp_clear_reset_spec _ _ _ _ = () let pp_step_spec _ _ _ _ _ = () @@ -1000,18 +1001,24 @@ module Main (Mod : MODIFIERS_SRC) = struct ind.nodei_id let pp_lib_c source_fmt basename prog machines dependencies = + let self_dep = { + local = true; + name = basename; + content = []; + is_stateful = true (* assuming it is stateful *); + } + in fprintf source_fmt - "@[<v>%a%a@,@,%a@,%a%a%a%a%a%a%a@]@." + "@[<v>%a%a%a%a@,%a@,%a%a%a%a%a@]@." pp_import_standard () pp_import_prototype - { - local = true; - name = basename; - content = []; - is_stateful = true (* assuming it is stateful *); - } + self_dep + pp_import_memory_prototype + self_dep + Mod.pp_import_spec_prototype + self_dep (* Print the svn version number and the supported C standard (C90 or C99) *) pp_print_version @@ -1086,16 +1093,6 @@ module Main (Mod : MODIFIERS_SRC) = struct machines else pp_print_nothing) () - (* Print the struct definitions of all machines. *) - (pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_prologue:(pp_print_endcut "/* Struct definitions */") - ~pp_sep:pp_print_cutcut - pp_machine_struct - ~pp_epilogue:pp_print_cutcut) - (List.filter (fun m -> not m.mis_contract) machines) - (* Print the spec predicates *) Mod.pp_predicates - machines (* Print nodes one by one (in the previous order) *) (pp_print_list ~pp_open_box:pp_open_vbox0 diff --git a/src/backends/C/c_backend_src.mli b/src/backends/C/c_backend_src.mli index 1f0f9bcf..12d9fb78 100644 --- a/src/backends/C/c_backend_src.mli +++ b/src/backends/C/c_backend_src.mli @@ -7,7 +7,8 @@ open C_backend_common module type MODIFIERS_SRC = sig module GhostProto : MODIFIERS_GHOST_PROTO - val pp_predicates : formatter -> machine_t list -> unit + val pp_import_spec_prototype : formatter -> dep_t -> unit + val pp_set_reset_spec : formatter -> ident -> ident -> machine_t -> unit val pp_clear_reset_spec : formatter -> ident -> ident -> machine_t -> unit -- GitLab