From cb8b7a6f846541963f903d7fb840013514d7343d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9lio=20Brun?= <lb@leliobrun.net> Date: Tue, 17 Jan 2023 15:41:03 +0900 Subject: [PATCH] Monolithic reset in Spec --- .ocamlformat | 2 +- src/automata.ml | 6 +- src/backends/Ada/misc_lustre_function.ml | 3 +- src/backends/C/c_backend.ml | 12 +- src/backends/C/c_backend_common.ml | 41 +- src/backends/C/c_backend_common.mli | 13 +- src/backends/C/c_backend_header.ml | 889 ++++++++++++----------- src/backends/C/c_backend_header.mli | 2 +- src/backends/C/c_backend_spec.ml | 332 ++++----- src/backends/C/c_backend_src.ml | 147 +++- src/backends/C/c_backend_src.mli | 15 +- src/machine_code.ml | 22 +- src/machine_code_common.ml | 22 +- src/spec_common.ml | 11 +- src/spec_types.ml | 9 +- src/spec_types.mli | 9 +- src/tools/tiny/tiny_verifier.ml | 1 - strategy.ml | 3 - 18 files changed, 806 insertions(+), 733 deletions(-) diff --git a/.ocamlformat b/.ocamlformat index c4a2f22e..bf730f69 100644 --- a/.ocamlformat +++ b/.ocamlformat @@ -1,4 +1,4 @@ -version=0.20.1 +version=0.24.1 parens-tuple=multi-line-only wrap-comments=true cases-exp-indent=2 diff --git a/src/automata.ml b/src/automata.ml index 1e3f48c3..493d91fe 100644 --- a/src/automata.ml +++ b/src/automata.ml @@ -217,8 +217,7 @@ let node_of_unless nused node aut_id aut_state handler = (*Format.eprintf "node_of_unless %s@." node.node_id;*) let inputs = unless_read ISet.empty handler in let var_inputs = - aut_state.incoming_r - (*:: aut_state.incoming_s*) + aut_state.incoming_r (*:: aut_state.incoming_s*) :: node_vars_of_idents node inputs in let var_outputs = [ aut_state.actual_r; aut_state.actual_s ] in @@ -310,8 +309,7 @@ let node_of_assign_until nused used node aut_id aut_state handler = in let frename = mk_frename used writes in let var_inputs = - aut_state.actual_r - (*:: aut_state.actual_s*) + aut_state.actual_r (*:: aut_state.actual_s*) :: node_vars_of_idents node inputs in let new_var_locals = node_vars_of_idents node writes in diff --git a/src/backends/Ada/misc_lustre_function.ml b/src/backends/Ada/misc_lustre_function.ml index e585fbbe..c321b673 100644 --- a/src/backends/Ada/misc_lustre_function.ml +++ b/src/backends/Ada/misc_lustre_function.ml @@ -129,7 +129,8 @@ let unification (substituion : (int * Types.t) list) (* We return the original substituion, it is already correct *) substituion (* If type_poly is not in the subsitution *)) - else (* We add it to the substituion *) + else + (* We add it to the substituion *) (type_poly.tid, typ) :: substituion (* iftype_poly is not polymorphic *) else ( (* We check that type_poly and typ are the same *) diff --git a/src/backends/C/c_backend.ml b/src/backends/C/c_backend.ml index 3c46ad1a..3e25da04 100644 --- a/src/backends/C/c_backend.ml +++ b/src/backends/C/c_backend.ml @@ -113,17 +113,19 @@ let gen_files generate_spec_header let print_c_header basename = let open Options in - let header_m = + let source_m, header_m = match !spec with | SpecNo -> - C_backend_header.((module EmptyMod : MODIFIERS_HDR)) + ( C_backend_src.((module EmptyMod : MODIFIERS_SRC)), + C_backend_header.((module EmptyMod : MODIFIERS_HDR)) ) | SpecACSL -> - C_backend_header.((module C_backend_spec.HdrMod : MODIFIERS_HDR)) + ( C_backend_src.((module C_backend_spec.SrcMod : MODIFIERS_SRC)), + C_backend_header.((module C_backend_spec.HdrMod : MODIFIERS_HDR)) ) | SpecC -> assert false (* not implemented yet *) in - let module Header = C_backend_header.Main ((val header_m)) in + let module Header = C_backend_header.Main ((val source_m)) ((val header_m)) in let destname = !dest_dir ^ "/" ^ basename in (* Generating H file *) let lusic = Lusic.read_lusic destname ".lusic" in @@ -160,7 +162,7 @@ let translate_to_c generate_c_header basename prog machines dependencies = assert false (* not implemented yet *) in - let module Header = C_backend_header.Main ((val header_m)) in + let module Header = C_backend_header.Main ((val source_m)) ((val header_m)) in let module Source = C_backend_src.Main ((val source_m)) in let module SourceMain = C_backend_main.Main ((val source_main_m)) in let module Makefile = C_backend_makefile.Main ((val makefile_m)) in diff --git a/src/backends/C/c_backend_common.ml b/src/backends/C/c_backend_common.ml index 4e955f73..d8081226 100644 --- a/src/backends/C/c_backend_common.ml +++ b/src/backends/C/c_backend_common.ml @@ -150,6 +150,7 @@ let pp_machine_static_alloc_name ?(ghost = false) fmt id = let pp_machine_set_reset_name fmt id = fprintf fmt "%s_set_reset" id let pp_machine_clear_reset_name fmt id = fprintf fmt "%s_clear_reset" id +let pp_machine_ghost_reset_name fmt id = fprintf fmt "%s_reset_ghost" id let pp_machine_init_name fmt id = fprintf fmt "%s_init" id let pp_machine_clear_name fmt id = fprintf fmt "%s_clear" id let pp_machine_step_name fmt id = fprintf fmt "%s_step" id @@ -773,7 +774,8 @@ let pp_machine_struct ?(ghost = false) fmt m = (* Define struct *) fprintf fmt - "@[<v 2>%a {@,_Bool _reset;%a%a@]@,};" + (if ghost then "@[<v 2>%a {%a%a@]@,};" + else "@[<v 2>%a {@,_Bool _reset;%a%a@]@,};") (pp_machine_memtype_name ~ghost) m.mname.node_id (if ghost && not m.mis_contract then @@ -866,17 +868,28 @@ module Protos (Mod : MODIFIERS_GHOST_PROTO) = struct (pp_print_only_if (not is_contract) (Mod.pp_ghost_parameters ~cut:true)) [ mem, pp_mem_ghost name ] - let pp_set_reset_prototype is_contract self mem fmt (name, static) = + (* let pp_set_reset_prototype is_contract self mem fmt (name, static) = *) + (* fprintf *) + (* fmt *) + (* "@[<v>void %a(%a%t)%a@]" *) + (* pp_machine_set_reset_name *) + (* name *) + (* (pp_comma_list ~pp_eol:pp_print_comma pp_c_decl_input_var) *) + (* static *) + (* (pp_self is_contract self mem name) *) + (* (pp_print_only_if (not is_contract) (Mod.pp_ghost_parameters ~cut:true)) *) + (* [ mem, pp_mem_ghost name ] *) + + let pp_ghost_reset_prototype mem fmt (name, static) = fprintf fmt - "@[<v>void %a(%a%t)%a@]" - pp_machine_set_reset_name + "@[<v>void %a(%a%a)@]" + pp_machine_ghost_reset_name name (pp_comma_list ~pp_eol:pp_print_comma pp_c_decl_input_var) static - (pp_self is_contract self mem name) - (pp_print_only_if (not is_contract) (Mod.pp_ghost_parameters ~cut:true)) - [ mem, pp_mem_ghost name ] + (pp_mem_ghost name) + mem let pp_ghost_proto fmt (mem_name, proto_c) = let ghost_c = @@ -896,13 +909,17 @@ module Protos (Mod : MODIFIERS_GHOST_PROTO) = struct l) in match mem_name, proto_c with - | None, None -> () + | None, None -> + () | _ -> - Mod.pp_ghost_parameters ~cut:true fmt + Mod.pp_ghost_parameters + ~cut:true + fmt (match mem_name with - | Some (mem, name) -> - (mem, pp_mem_ghost name) :: ghost_c - | None -> ghost_c) + | Some (mem, name) -> + (mem, pp_mem_ghost name) :: ghost_c + | None -> + ghost_c) let pp_step_prototype is_contract self mem fmt (name, inputs, outputs, proto_c) = diff --git a/src/backends/C/c_backend_common.mli b/src/backends/C/c_backend_common.mli index 8901985c..a8bdf18b 100644 --- a/src/backends/C/c_backend_common.mli +++ b/src/backends/C/c_backend_common.mli @@ -9,6 +9,7 @@ val pp_put_var : formatter -> string -> ident -> Types.t -> ident -> unit val pp_ptr : formatter -> ident -> unit val pp_machine_set_reset_name : formatter -> ident -> unit val pp_machine_clear_reset_name : formatter -> ident -> unit +val pp_machine_ghost_reset_name : formatter -> ident -> unit val pp_machine_init_name : formatter -> ident -> unit val pp_machine_clear_name : formatter -> ident -> unit val pp_machine_step_name : formatter -> ident -> unit @@ -220,15 +221,21 @@ module EmptyGhostProto : MODIFIERS_GHOST_PROTO module Protos (Mod : MODIFIERS_GHOST_PROTO) : sig val pp_stateless_prototype : - formatter -> ident * var_decl list * var_decl list + formatter -> + ident + * var_decl list + * var_decl list * (ident option * ident * var_decl list * var_decl list) option -> unit val pp_clear_reset_prototype : bool -> ident -> ident -> formatter -> ident * var_decl list -> unit - val pp_set_reset_prototype : - bool -> ident -> ident -> formatter -> ident * var_decl list -> unit + (* val pp_set_reset_prototype : *) + (* bool -> ident -> ident -> formatter -> ident * var_decl list -> unit *) + + val pp_ghost_reset_prototype : + ident -> formatter -> ident * var_decl list -> unit val pp_step_prototype : bool -> diff --git a/src/backends/C/c_backend_header.ml b/src/backends/C/c_backend_header.ml index bd88949a..002c58a2 100644 --- a/src/backends/C/c_backend_header.ml +++ b/src/backends/C/c_backend_header.ml @@ -48,466 +48,475 @@ module EmptyMod = struct let pp_machine_alloc_decl _ _ = () end -module Main = -functor - (Mod : MODIFIERS_HDR) - -> - struct - module Protos = Protos (Mod.GhostProto) +module Main (ModSrc : C_backend_src.MODIFIERS_SRC) (ModHdr : MODIFIERS_HDR) = +struct + module Protos = Protos (ModHdr.GhostProto) + module Src = C_backend_src.Main (ModSrc) - let pp_import_standard fmt () = - (* if Machine_types.has_machine_type () then *) - fprintf - fmt - "#include <stdint.h>@,%a%a" - (if !Options.mpfr then pp_print_endcut "#include <mpfr.h>" - else pp_print_nothing) - () - Mod.pp_import_arrow - () + let pp_import_standard fmt () = + (* if Machine_types.has_machine_type () then *) + fprintf + fmt + "#include <stdint.h>@,%a%a" + (if !Options.mpfr then pp_print_endcut "#include <mpfr.h>" + else pp_print_nothing) + () + ModHdr.pp_import_arrow + () - (* TODO: ACSL we do multiple things: - provide the semantics of the node as - a predicate: function step and reset are associated to ACSL predicate - - the node is associated to a refinement contract, wrt its ACSL sem - if - the node is a regular node associated to a contract, print the contract - as function contract. - do not print anything if this is a contract - node *) - let pp_machine_alloc_decl fmt m = - Mod.pp_machine_decl_prefix fmt m; - if not (fst (get_stateless_status m)) then - if !Options.static_mem then - (* Static allocation *) - let macro = m, mk_attribute m, mk_instance m in - fprintf - fmt - "%a@,%a@,%a" - (fun x -> pp_static_declare_macro x) - macro - (fun x -> pp_static_link_macro x) - macro - (fun x -> pp_static_alloc_macro x) - macro - else - (* Dynamic allocation *) - fprintf - fmt - "extern %a;@,extern %a" - pp_alloc_prototype - (m.mname.node_id, m.mstatic) - pp_dealloc_prototype - m.mname.node_id + (* TODO: ACSL we do multiple things: - provide the semantics of the node as a + predicate: function step and reset are associated to ACSL predicate - the + node is associated to a refinement contract, wrt its ACSL sem - if the node + is a regular node associated to a contract, print the contract as function + contract. - do not print anything if this is a contract node *) + let pp_machine_alloc_decl fmt m = + ModHdr.pp_machine_decl_prefix fmt m; + if not (fst (get_stateless_status m)) then + if !Options.static_mem then + (* Static allocation *) + let macro = m, mk_attribute m, mk_instance m in + fprintf + fmt + "%a@,%a@,%a" + (fun x -> pp_static_declare_macro x) + macro + (fun x -> pp_static_link_macro x) + macro + (fun x -> pp_static_alloc_macro x) + macro + else + (* Dynamic allocation *) + fprintf + fmt + "extern %a;@,extern %a" + pp_alloc_prototype + (m.mname.node_id, m.mstatic) + pp_dealloc_prototype + m.mname.node_id - let pp_machine_struct_top_decl_from_header fmt tdecl = - let inode = imported_node_of_top tdecl in - if not (inode.nodei_stateless || inode.nodei_iscontract) then - (* Declare struct *) - fprintf fmt "%a;" (pp_machine_memtype_name ~ghost:false) inode.nodei_id + let pp_machine_struct_top_decl_from_header fmt tdecl = + let inode = imported_node_of_top tdecl in + if not (inode.nodei_stateless || inode.nodei_iscontract) then + (* Declare struct *) + fprintf fmt "%a;" (pp_machine_memtype_name ~ghost:false) inode.nodei_id - let pp_stateless_C_prototype fmt (name, inputs, outputs) = - let output = match outputs with [ hd ] -> hd | _ -> assert false in - fprintf - fmt - "%a %s %a" - (fun x -> pp_basic_c_type ~pp_c_basic_type_desc x) - output.var_type - name - (pp_print_parenthesized pp_c_decl_input_var) - inputs + let pp_stateless_C_prototype fmt (name, inputs, outputs) = + let output = match outputs with [ hd ] -> hd | _ -> assert false in + fprintf + fmt + "%a %s %a" + (fun x -> pp_basic_c_type ~pp_c_basic_type_desc x) + output.var_type + name + (pp_print_parenthesized pp_c_decl_input_var) + inputs - let pp_machine_decl_top_decl_from_header nodes fmt tdecl = - let inode = imported_node_of_top tdecl in - (*Mod.print_machine_decl_prefix fmt m;*) - let used name = - List.exists - (fun v -> v.var_id = name) - (inode.nodei_inputs @ inode.nodei_outputs) - in - let self = mk_new_name used "self" in - let mem = mk_new_name used "mem" in - let proto_c = - match inode.nodei_spec with - | Some spec -> ( - match spec with - | Contract _ -> - None - | NodeSpec f -> ( - let td = - List.find - (fun td -> - match td.top_decl_desc with - | Node nd -> - nd.node_id = f - | ImportedNode ind -> - ind.nodei_id = f - | _ -> - false) - nodes - in - let stateless = fst (get_stateless_status_top_decl td) in - let mem_c = - if stateless then None else Some (mk_new_name used "mem_c") - in - match td.top_decl_desc with - | Node nd -> ( - match nd.node_spec with - | Some (Contract _) -> - Some (mem_c, f, nd.node_inputs, nd.node_outputs) - | _ -> - None) - | ImportedNode ind -> ( - match ind.nodei_spec with - | Some (Contract _) -> - Some (mem_c, f, ind.nodei_inputs, ind.nodei_outputs) - | _ -> - None) - | _ -> - None)) - | None -> + let pp_set_reset_macro self fmt name = + fprintf + fmt + "#define %a(%s) {%a = 1;}" + pp_machine_set_reset_name + name + self + (pp_reset_flag (fun fmt -> fprintf fmt "(%s)") ~indirect:true) + self + + let pp_machine_decl_top_decl_from_header nodes fmt tdecl = + let inode = imported_node_of_top tdecl in + (*ModHdr.print_machine_decl_prefix fmt m;*) + let used name = + List.exists + (fun v -> v.var_id = name) + (inode.nodei_inputs @ inode.nodei_outputs) + in + let self = mk_new_name used "self" in + let mem = mk_new_name used "mem" in + let proto_c = + match inode.nodei_spec with + | Some spec -> ( + match spec with + | Contract _ -> None - in - let prototype = inode.nodei_id, inode.nodei_inputs, inode.nodei_outputs in - let prototype' = - inode.nodei_id, inode.nodei_inputs, inode.nodei_outputs, proto_c - in - if not inode.nodei_iscontract then - if inode.nodei_prototype = Some "C" then - if inode.nodei_stateless then - fprintf fmt "extern %a;" pp_stateless_C_prototype prototype - else ( - (* TODO: raise proper error *) - Format.eprintf - "internal error: pp_machine_decl_top_decl_from_header"; - assert false) - else if inode.nodei_stateless then - fprintf fmt "extern %a;" Protos.pp_stateless_prototype prototype' - else - let static_inputs = - List.filter (fun v -> v.var_dec_const) inode.nodei_inputs + | NodeSpec f -> ( + let td = + List.find + (fun td -> + match td.top_decl_desc with + | Node nd -> + nd.node_id = f + | ImportedNode ind -> + ind.nodei_id = f + | _ -> + false) + nodes + in + let stateless = fst (get_stateless_status_top_decl td) in + let mem_c = + if stateless then None else Some (mk_new_name used "mem_c") in - let static_prototype = inode.nodei_id, static_inputs in - fprintf - fmt - "extern %a;@,extern %a;@,extern %a;@,extern %a;@,extern %a;" - (Protos.pp_set_reset_prototype false self mem) - static_prototype - (Protos.pp_clear_reset_prototype false self mem) - static_prototype - (Protos.pp_init_prototype self) - static_prototype - (Protos.pp_clear_prototype self) - static_prototype - (Protos.pp_step_prototype false self mem) - prototype' + match td.top_decl_desc with + | Node nd -> ( + match nd.node_spec with + | Some (Contract _) -> + Some (mem_c, f, nd.node_inputs, nd.node_outputs) + | _ -> + None) + | ImportedNode ind -> ( + match ind.nodei_spec with + | Some (Contract _) -> + Some (mem_c, f, ind.nodei_inputs, ind.nodei_outputs) + | _ -> + None) + | _ -> + None)) + | None -> + None + in + let prototype = inode.nodei_id, inode.nodei_inputs, inode.nodei_outputs in + let prototype' = + inode.nodei_id, inode.nodei_inputs, inode.nodei_outputs, proto_c + in + if not inode.nodei_iscontract then + if inode.nodei_prototype = Some "C" then + if inode.nodei_stateless then + fprintf fmt "extern %a;" pp_stateless_C_prototype prototype + else ( + (* TODO: raise proper error *) + Format.eprintf "internal error: pp_machine_decl_top_decl_from_header"; + assert false) + else if inode.nodei_stateless then + fprintf fmt "extern %a;" Protos.pp_stateless_prototype prototype' else - Mod.pp_is_contract - (fun fmt -> - if inode.nodei_stateless then - fprintf fmt "%a;" Protos.pp_stateless_prototype prototype' - else - let static_inputs = - List.filter (fun v -> v.var_dec_const) inode.nodei_inputs - in - let static_prototype = inode.nodei_id, static_inputs in - fprintf - fmt - "%a;@,%a;@,%a;" - (Protos.pp_set_reset_prototype true self mem) - static_prototype - (Protos.pp_clear_reset_prototype true self mem) - static_prototype - (Protos.pp_step_prototype true self mem) - prototype') + let static_inputs = + List.filter (fun v -> v.var_dec_const) inode.nodei_inputs + in + let static_prototype = inode.nodei_id, static_inputs in + fprintf fmt + "%a;@,extern %a;@,extern %a;@,extern %a;@,extern %a;" + (pp_set_reset_macro self) + inode.nodei_id + (Protos.pp_clear_reset_prototype false self mem) + static_prototype + (Protos.pp_init_prototype self) + static_prototype + (Protos.pp_clear_prototype self) + static_prototype + (Protos.pp_step_prototype false self mem) + prototype' + else + ModHdr.pp_is_contract + (fun fmt -> + if inode.nodei_stateless then + fprintf fmt "%a;" Protos.pp_stateless_prototype prototype' + else + let static_inputs = + List.filter (fun v -> v.var_dec_const) inode.nodei_inputs + in + let static_prototype = inode.nodei_id, static_inputs in + fprintf + fmt + "%a;@,%a;@,%a;" + (pp_set_reset_macro self) + inode.nodei_id + (Protos.pp_clear_reset_prototype true self mem) + static_prototype + (Protos.pp_step_prototype true self mem) + prototype') + fmt + + let pp_const_top_decl fmt tdecl = + let cdecl = const_of_top tdecl in + fprintf + fmt + "extern %a;" + (pp_c_type cdecl.const_id) + (if + !Options.mpfr && Types.(is_real_type (array_base_type cdecl.const_type)) + then Types.dynamic_type cdecl.const_type + else cdecl.const_type) - let pp_const_top_decl fmt tdecl = - let cdecl = const_of_top tdecl in + let rec pp_c_type_decl filename cpt var fmt tdecl = + match tdecl with + | Tydec_any -> + assert false + | Tydec_int -> + fprintf fmt "int %s" var + | Tydec_real when !Options.mpfr -> + fprintf fmt "%s %s" Mpfr.mpfr_t var + | Tydec_real -> + fprintf fmt "double %s" var + (* | Tydec_float -> fprintf fmt "float %s" var *) + | Tydec_bool -> + fprintf fmt "_Bool %s" var + | Tydec_clock ty -> + pp_c_type_decl filename cpt var fmt ty + | Tydec_const c -> + fprintf fmt "%s %s" c var + | Tydec_array (d, ty) -> + fprintf fmt "%a[%a]" (pp_c_type_decl filename cpt var) ty pp_c_dimension d + | Tydec_enum tl -> + incr cpt; fprintf fmt - "extern %a;" - (pp_c_type cdecl.const_id) - (if - !Options.mpfr - && Types.(is_real_type (array_base_type cdecl.const_type)) - then Types.dynamic_type cdecl.const_type - else cdecl.const_type) + "enum _enum_%s_%d %a %s" + (protect_filename filename) + !cpt + (pp_print_braced pp_print_string) + (List.sort compare tl) + var + | Tydec_struct fl -> + incr cpt; + fprintf + fmt + "struct _struct_%s_%d %a %s" + (protect_filename filename) + !cpt + (pp_print_braced ~pp_sep:pp_print_semicolon (fun fmt (label, tdesc) -> + pp_c_type_decl filename cpt label fmt tdesc)) + fl + var - let rec pp_c_type_decl filename cpt var fmt tdecl = - match tdecl with - | Tydec_any -> - assert false - | Tydec_int -> - fprintf fmt "int %s" var - | Tydec_real when !Options.mpfr -> - fprintf fmt "%s %s" Mpfr.mpfr_t var - | Tydec_real -> - fprintf fmt "double %s" var - (* | Tydec_float -> fprintf fmt "float %s" var *) - | Tydec_bool -> - fprintf fmt "_Bool %s" var - | Tydec_clock ty -> - pp_c_type_decl filename cpt var fmt ty - | Tydec_const c -> - fprintf fmt "%s %s" c var - | Tydec_array (d, ty) -> - fprintf - fmt - "%a[%a]" - (pp_c_type_decl filename cpt var) - ty - pp_c_dimension - d - | Tydec_enum tl -> - incr cpt; - fprintf - fmt - "enum _enum_%s_%d %a %s" - (protect_filename filename) - !cpt - (pp_print_braced pp_print_string) - (List.sort compare tl) - var - | Tydec_struct fl -> - incr cpt; + (* let print_type_definitions fmt filename = + * let cpt_type = ref 0 in + * Hashtbl.iter (fun typ decl -> + * match typ with + * | Tydec_const var -> + * begin match decl.top_decl_desc with + * | TypeDef tdef -> + * fprintf fmt "typedef %a;@.@." + * (pp_c_type_decl filename cpt_type var) tdef.tydef_desc + * | _ -> assert false + * end + * | _ -> ()) type_table *) + + let reset_type_definitions, pp_type_definition_top_decl_from_header = + let cpt_type = ref 0 in + ( (fun () -> cpt_type := 0), + fun filename fmt tdecl -> + let typ = typedef_of_top tdecl in fprintf fmt - "struct _struct_%s_%d %a %s" - (protect_filename filename) - !cpt - (pp_print_braced ~pp_sep:pp_print_semicolon (fun fmt (label, tdesc) -> - pp_c_type_decl filename cpt label fmt tdesc)) - fl - var - - (* let print_type_definitions fmt filename = - * let cpt_type = ref 0 in - * Hashtbl.iter (fun typ decl -> - * match typ with - * | Tydec_const var -> - * begin match decl.top_decl_desc with - * | TypeDef tdef -> - * fprintf fmt "typedef %a;@.@." - * (pp_c_type_decl filename cpt_type var) tdef.tydef_desc - * | _ -> assert false - * end - * | _ -> ()) type_table *) - - let reset_type_definitions, pp_type_definition_top_decl_from_header = - let cpt_type = ref 0 in - ( (fun () -> cpt_type := 0), - fun filename fmt tdecl -> - let typ = typedef_of_top tdecl in - fprintf - fmt - "typedef %a;" - (pp_c_type_decl filename cpt_type typ.tydef_id) - typ.tydef_desc ) + "typedef %a;" + (pp_c_type_decl filename cpt_type typ.tydef_id) + typ.tydef_desc ) - (********************************************************************************************) - (* MAIN Header Printing functions *) - (********************************************************************************************) + (********************************************************************************************) + (* MAIN Header Printing functions *) + (********************************************************************************************) - let pp_alloc_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 - 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@,\ - @,\ - /* Import header from %s */@,\ - %a@,\ - /* 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 - pp_import_prototype - 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 prototypes of all machines *) - (pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_prologue: - (pp_print_endcut "/* Node allocation function/macro prototypes */") - ~pp_sep:pp_print_cutcut - pp_machine_alloc_decl - ~pp_epilogue:pp_print_cutcut) - machines' - (* Print the spec prototypes of all machines *) - (pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_prologue: - (pp_print_endcut - "/* Node allocation function/macro ghost prototypes */") - ~pp_sep:pp_print_cutcut - Mod.pp_machine_alloc_decl - ~pp_epilogue:pp_print_cutcut) - machines' - (* Include once: end *) + let pp_alloc_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 + 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@,\ + @,\ + /* Import header from %s */@,\ + %a@,\ + /* 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 + pp_import_prototype + 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 prototypes of all machines *) + (pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_prologue: + (pp_print_endcut "/* Node allocation function/macro prototypes */") + ~pp_sep:pp_print_cutcut + pp_machine_alloc_decl + ~pp_epilogue:pp_print_cutcut) + machines' + (* Print the spec prototypes of all machines *) + (pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_prologue: + (pp_print_endcut + "/* Node allocation function/macro ghost prototypes */") + ~pp_sep:pp_print_cutcut + ModHdr.pp_machine_alloc_decl + ~pp_epilogue:pp_print_cutcut) + machines' + (* Include once: end *) - (* Function called when compiling a lusi file and generating the associated - C header. *) - let pp_header_from_header header_fmt basename header = - (* Include once: start *) - let baseNAME = file_to_module_name basename in - let types = get_typedefs header in - let consts = get_consts header in - let nodes = get_imported_nodes header in - let dependencies = get_dependencies header in - reset_type_definitions (); - fprintf - header_fmt - "@[<v>%a@,\ - #ifndef _%s@,\ - #define _%s@,\ - @,\ - /* Import standard library */@,\ - %a@,\ - @,\ - %a%a%a%a%a%a#endif@]@." - (* Print the version number and the supported C standard (C90 or C99) *) - pp_print_version - () - baseNAME - baseNAME - (* imports standard library definitions (arrow) *) - pp_import_standard - () - (* imports dependencies *) - (pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_prologue:(pp_print_endcut "/* Import dependencies */") - (fun fmt dep -> - let local, name = dependency_of_top dep in - pp_import_prototype - fmt - { - local; - name; - content = []; - is_stateful = true (* assuming it is stateful *); - }) - ~pp_epilogue:pp_print_cutcut) - dependencies - (* Print the type definitions from the type table *) - (pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_prologue:(pp_print_endcut "/* Types definitions */") - (pp_type_definition_top_decl_from_header basename) - ~pp_epilogue:pp_print_cutcut) - types - (* Print the global constant declarations. *) - (pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_prologue: - (pp_print_endcut - "/* Global constants (declarations, definitions are in C file) \ - */") - pp_const_top_decl - ~pp_epilogue:pp_print_cutcut) - consts - (* MPFR *) - (if !Options.mpfr then fun fmt () -> - fprintf - fmt - "/* Global initialization declaration */@,\ - extern %a;@,\ - @,\ - /* Global clear declaration */@,\ - extern %a;@,\ - @," - pp_global_init_prototype - baseNAME - pp_global_clear_prototype - baseNAME - else pp_print_nothing) - () - (* Print the struct declarations of all machines. *) - (pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_prologue:(pp_print_endcut "/* Struct declarations */") - pp_machine_struct_top_decl_from_header - ~pp_epilogue:pp_print_cutcut) - nodes - (* Print the prototypes of all machines *) - (pp_print_list - ~pp_open_box:pp_open_vbox0 - ~pp_prologue:(pp_print_endcut "/* Nodes declarations */") - ~pp_sep:pp_print_cutcut - (pp_machine_decl_top_decl_from_header nodes) - ~pp_epilogue:pp_print_cutcut) - nodes + (* Function called when compiling a lusi file and generating the associated C + header. *) + let pp_header_from_header header_fmt basename header = + (* Include once: start *) + let baseNAME = file_to_module_name basename in + let types = get_typedefs header in + let consts = get_consts header in + let nodes = List.rev (get_imported_nodes header) in + let dependencies = get_dependencies header in + reset_type_definitions (); + fprintf + header_fmt + "@[<v>%a@,\ + #ifndef _%s@,\ + #define _%s@,\ + @,\ + /* Import standard library */@,\ + %a@,\ + @,\ + %a%a%a%a%a%a#endif@]@." + (* Print the version number and the supported C standard (C90 or C99) *) + pp_print_version + () + baseNAME + baseNAME + (* imports standard library definitions (arrow) *) + pp_import_standard + () + (* imports dependencies *) + (pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_prologue:(pp_print_endcut "/* Import dependencies */") + (fun fmt dep -> + let local, name = dependency_of_top dep in + pp_import_prototype + fmt + { + local; + name; + content = []; + is_stateful = true (* assuming it is stateful *); + }) + ~pp_epilogue:pp_print_cutcut) + dependencies + (* Print the type definitions from the type table *) + (pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_prologue:(pp_print_endcut "/* Types definitions */") + (pp_type_definition_top_decl_from_header basename) + ~pp_epilogue:pp_print_cutcut) + types + (* Print the global constant declarations. *) + (pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_prologue: + (pp_print_endcut + "/* Global constants (declarations, definitions are in C file) */") + pp_const_top_decl + ~pp_epilogue:pp_print_cutcut) + consts + (* MPFR *) + (if !Options.mpfr then fun fmt () -> + fprintf + fmt + "/* Global initialization declaration */@,\ + extern %a;@,\ + @,\ + /* Global clear declaration */@,\ + extern %a;@,\ + @," + pp_global_init_prototype + baseNAME + pp_global_clear_prototype + baseNAME + else pp_print_nothing) + () + (* Print the struct declarations of all machines. *) + (pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_prologue:(pp_print_endcut "/* Struct declarations */") + pp_machine_struct_top_decl_from_header + ~pp_epilogue:pp_print_cutcut) + nodes + (* Print the prototypes of all machines *) + (pp_print_list + ~pp_open_box:pp_open_vbox0 + ~pp_prologue:(pp_print_endcut "/* Nodes declarations */") + ~pp_sep:pp_print_cutcut + (pp_machine_decl_top_decl_from_header nodes) + ~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_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 + let pp_spec_header header_fmt basename machines _dependencies = + let baseNAME = file_to_module_name basename in + 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 + header_fmt + "@[<v>%a@,#ifndef _%s_SPEC@,#define _%s_SPEC@,@,%a@,%a#endif@]@." + (* Print the svn version number and the supported C standard (C90 or + C99) *) + pp_print_version + () + baseNAME + baseNAME + ModHdr.pp_predicates + machines + (pp_preds "/* Monolithic ghost `reset` functions */" (fun fmt m -> + let mem = mk_mem m in + Src.pp_ghost_reset_spec_code machines mem fmt m)) + machines +end (* Local Variables: *) (* compile-command:"make -C ../../.." *) (* End: *) diff --git a/src/backends/C/c_backend_header.mli b/src/backends/C/c_backend_header.mli index e167ee2a..013eb746 100644 --- a/src/backends/C/c_backend_header.mli +++ b/src/backends/C/c_backend_header.mli @@ -15,7 +15,7 @@ end module EmptyMod : MODIFIERS_HDR -module Main (Mod : MODIFIERS_HDR) : sig +module Main (ModSrc : C_backend_src.MODIFIERS_SRC) (ModHdr : MODIFIERS_HDR) : sig val pp_header_from_header : formatter -> string -> top_decl list -> unit val pp_alloc_header : diff --git a/src/backends/C/c_backend_spec.ml b/src/backends/C/c_backend_spec.ml index 4668a9f6..534426bc 100644 --- a/src/backends/C/c_backend_spec.ml +++ b/src/backends/C/c_backend_spec.ml @@ -42,8 +42,7 @@ let pp_acsl ?(ghost = false) pp fmt x = let pp_acsl_cut ?ghost pp fmt = fprintf fmt "%a@," (pp_acsl ?ghost pp) let pp_acsl_line pp fmt = fprintf fmt "//%@ @[<h>%a@]" pp -let pp_acsl_line_cut pp fmt = - fprintf fmt "%a@," (pp_acsl_line pp) +let pp_acsl_line_cut pp fmt = fprintf fmt "%a@," (pp_acsl_line pp) let pp_acsl_line' ?(ghost = false) pp fmt x = let op = if ghost then "" else "*" in @@ -194,6 +193,8 @@ let pp_not pp fmt = fprintf fmt "!%a" pp let pp_valid pp = pp_and_l (fun fmt x -> fprintf fmt "\\valid(%a)" pp x) let pp_valid_read pp fmt = fprintf fmt "\\valid_read(%a)" pp let pp_old pp fmt = fprintf fmt "\\old(%a)" pp +let pre_label = "Pre" +let pp_at pp l fmt x = fprintf fmt "\\at(%a, %s)" pp x l let pp_ite pp_c pp_t pp_f fmt (c, t, f) = fprintf fmt "(%a @[<hov>? %a@ : %a)@]" pp_c c pp_t t pp_f f @@ -333,18 +334,6 @@ let pp_reset_set pp_mem fmt (name, mem) = let pp_reset_set' = pp_reset_set pp_print_string -let pp_reset_cleared pp_mem_in pp_mem_out fmt (name, mem_in, mem_out) = - fprintf - fmt - "%s_reset_cleared(@[<hov>%a,@ %a@])" - name - pp_mem_in - mem_in - pp_mem_out - mem_out - -let pp_reset_cleared' = pp_reset_cleared pp_print_string pp_print_string - let pp_functional_update mems insts fmt mem = let rec aux fmt = function | [] -> @@ -373,12 +362,6 @@ module PrintSpec = struct | ResetOut | InstrMode of ident - let pp_reg mem fmt = function - | ResetFlag -> - fprintf fmt "%s.%s" mem reset_flag_name - | StateVar x -> - fprintf fmt "%s.%a" mem pp_var_decl x - let not_var v = match v.value_desc with Var _ -> false | _ -> true let is_const v = match v.value_desc with Cst _ -> true | _ -> false @@ -398,7 +381,7 @@ module PrintSpec = struct | Var v -> pp_var_decl fmt v | Memory r -> - pp_reg mem fmt r + fprintf fmt "%s.%a" mem pp_var_decl r let pp_predicate mode m mem_in mem_in' mem_out mem_out' fmt p = let test_output, mem_update = @@ -433,13 +416,14 @@ module PrintSpec = struct (pp_expr test_output) fmt (f, vars, mem_in', mem_out') - | Reset (_f, inst, r) -> + | Reset (f, inst, r) -> pp_ite (pp_c_val m mem_in (pp_c_var_read m)) - (pp_equal (pp_reset_flag' ~indirect:false) pp_print_int) + pp_initialization' + (* (pp_equal (pp_reset_flag' ~indirect:false) pp_print_int) *) (pp_equal pp_print_string pp_access') fmt - (r, (mem_out, 1), (mem_out, (mem_in, inst))) + (r, (f, mem_out), (mem_out, (mem_in, inst))) | MemoryPackBase f -> pp_memory_pack_base_aux pp_print_string @@ -462,11 +446,6 @@ module PrintSpec = struct pp_print_string fmt (f, mem_in', mem_out, mem_in)) - | ResetCleared f -> - pp_reset_cleared' fmt (f, mem_in, mem_out) - (* fprintf fmt "ResetCleared_%a" pp_print_string f *) - | Initialization -> - () | GhostAssign (v1, v2) -> pp_ghost (pp_assign m mem_in (pp_c_var_read m)) fmt (v1, vdecl_to_val v2) @@ -479,10 +458,8 @@ module PrintSpec = struct id_to_tag t | Var v -> vdecl_to_val v - | Memory (StateVar v) -> + | Memory v -> vdecl_to_val v - | Memory ResetFlag -> - vdecl_to_val reset_flag let find_arrow_val = let bad_inits = Hashtbl.create 32 in @@ -536,7 +513,10 @@ module PrintSpec = struct | ResetOut -> mem_in, mem_in, false, mem_reset, mem_reset, false | InstrMode self -> - let mem = "(*" ^ mem ^ ")" in + pp_at pp_ptr pre_label str_formatter mem; + let mem_reset = flush_str_formatter () in + fprintf str_formatter "(%a)" pp_ptr mem; + let mem = flush_str_formatter () in self, mem_reset, false, mem, mem, false in let pp_expr fmt e = pp_expr m mem_in' fmt e in @@ -607,19 +587,7 @@ module PrintSpec = struct inst | Predicate p -> pp_predicate mode m mem_in mem_in' mem_out mem_out' fmt p - | StateVarPack (ResetFlag, _) -> - let r = vdecl_to_val reset_flag in - pp_assign_spec - m - mem_out - (pp_c_var_read ~test_output:false m) - indirect_l - mem_in - (pp_c_var_read ~test_output:false m) - indirect_r - fmt - (Type_predef.type_bool, r, r) - | StateVarPack (StateVar v, tainted) -> + | StateVarPack (v, tainted) -> let v' = vdecl_to_val v in let pp_eq fmt () = pp_assign_spec @@ -654,6 +622,17 @@ module PrintSpec = struct ((f, mk_mem_reset m), (rc, tr)) | Value v -> pp_c_val m mem_in (pp_c_var_read ~test_output:true m) fmt v + | MemoryPackToplevel (f, i) -> + pp_ite + (pp_reset_flag' ~indirect:true) + pp_initialization' + (pp_memory_pack_aux_taint + ~i + pp_print_string + pp_print_string + pp_print_string) + fmt + (mem_in, (f, mem_out), (f, mem_out, mem_out, mem_in)) in pp_spec mode fmt (Spec_common.red f) @@ -691,9 +670,11 @@ let pp_memory_pack_base_def m fmt f = (pp_memory_pack_base_aux (pp_machine_decl' ~ghost:true) (pp_machine_decl pp_ptr)) - (PrintSpec.pp_spec MemoryPackMode m)) + (pp_and + (pp_equal (pp_reset_flag' ~indirect:true) pp_print_int) + (PrintSpec.pp_spec MemoryPackMode m))) fmt - ((name, (name, mem), (name, self)), f) + ((name, (name, mem), (name, self)), ((self, 0), f)) let pp_memory_pack_def m fmt mp = if not (fst (get_stateless_status m) || m.mis_contract) then @@ -728,9 +709,7 @@ let pp_memory_pack_defs fmt m = if not (fst (get_stateless_status m)) then fprintf fmt - "%a@,%a%a" - pp_machine_ghost_struct - m + "%a%a" (pp_memory_pack_base_def m) m.mspec.mmemory_pack_base (pp_print_list @@ -845,48 +824,10 @@ let pp_initialization_def fmt m = (pp_predicate (pp_initialization (pp_machine_decl' ~ghost:true)) (pp_and_l (fun fmt (i, (td, _)) -> - if Arrow.td_is_arrow td then - pp_initialization pp_access' fmt (node_name td, (mem_in, i)) - else - pp_equal - (pp_reset_flag ~indirect:false pp_access') - pp_print_int - fmt - ((mem_in, i), 1)))) + pp_initialization pp_access' fmt (node_name td, (mem_in, i))))) fmt ((name, (name, mem_in)), m.minstances) -let pp_reset_set_def fmt m = - if not (fst (get_stateless_status m)) then - let name = m.mname.node_id in - let mem = mk_mem m in - pp_acsl - (pp_predicate - (pp_reset_set (pp_machine_decl' ~ghost:true)) - (pp_equal (pp_reset_flag' ~indirect:false) pp_print_int)) - fmt - ((name, (name, mem)), (mem, 1)) - -let pp_reset_cleared_def fmt m = - if not (fst (get_stateless_status m)) then - let name = m.mname.node_id in - let mem_in = mk_mem_in m in - let mem_out = mk_mem_out m in - pp_acsl - (pp_predicate - (pp_reset_cleared - (pp_machine_decl' ~ghost:true) - (pp_machine_decl' ~ghost:true)) - (pp_ite - (pp_reset_flag' ~indirect:false) - (pp_and - (pp_equal (pp_reset_flag' ~indirect:false) pp_print_int) - pp_initialization') - (pp_equal pp_print_string pp_print_string))) - fmt - ( (name, (name, mem_in), (name, mem_out)), - (mem_in, ((mem_out, 0), (name, mem_out)), (mem_out, mem_in)) ) - let pp_register_chain ?(indirect = true) ptr = pp_print_list ~pp_prologue:(fun fmt () -> fprintf fmt "%s->" ptr) @@ -1136,16 +1077,14 @@ module HdrMod = struct in fprintf fmt - "%a%a%a%a%a%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) + (pp_preds "/* ACSL ghost structures */" pp_machine_ghost_struct) 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) + (pp_preds "/* ACSL `memory pack` simulations */" pp_memory_pack_defs) machines (pp_preds "/* ACSL transition annotations */" pp_transition_defs) machines @@ -1236,7 +1175,7 @@ module SrcMod = struct (fun fmt () -> fprintf fmt - "%a%a%a%a%a%a%a%a%a%a%a" + "%a%a%a%a%a%a%a" (pp_if_not_contract (pp_requires pp_mem_valid')) (name, self) (pp_if_not_contract (pp_requires (pp_separated' self mem))) @@ -1252,39 +1191,67 @@ module SrcMod = struct pp_ptr pp_print_string))) (name, mem, mem, self) - (pp_ensures (pp_reset_cleared (pp_old pp_ptr) pp_ptr)) - (name, mem, mem) (pp_if_not_contract (pp_assigns pp_reset_flag')) [ self ] (pp_if_not_contract (pp_assigns (pp_register_chain self))) (mk_insts arws) (pp_if_not_contract (pp_assigns (pp_reset_flag_chain self))) - (mk_insts narws) - (pp_assigns pp_reset_flag') - [ mem ] - (pp_assigns (pp_register_chain ~indirect:false mem)) - (mk_insts arws) - (pp_assigns (pp_reset_flag_chain ~indirect:false mem)) (mk_insts narws)) fmt () - let pp_set_reset_spec fmt self mem m = + (* let pp_set_reset_spec fmt machines self mem m = *) + (* let name = m.mname.node_id in *) + (* let insts = instances machines m in *) + (* let stateful_insts = *) + (* List.( *) + (* filter *) + (* (fun path -> *) + (* let _, (_, mems) = hd (rev path) in *) + (* mems <> []) *) + (* insts) *) + (* in *) + (* let pp_if_not_contract pp = pp_print_only_if (not m.mis_contract) pp in *) + (* pp_acsl_cut *) + (* ~ghost:m.mis_contract *) + (* (fun fmt () -> *) + (* fprintf *) + (* fmt *) + (* "%a%a%a%a" *) + (* (pp_if_not_contract *) + (* (pp_ensures (pp_memory_pack_aux pp_ptr pp_print_string))) *) + (* (name, mem, self) *) + (* (pp_if_not_contract *) + (* (pp_ensures (pp_initialization pp_ptr))) *) + (* (name, mem) *) + (* (pp_assigns pp_reset_flag') *) + (* (if m.mis_contract then [ ] else [ self ]) *) + (* (pp_assigns (pp_reg ~indirect:false mem)) *) + (* stateful_insts) *) + (* fmt *) + (* () *) + + let pp_ghost_reset_spec fmt machines mem m = let name = m.mname.node_id in - let pp_if_not_contract pp = pp_print_only_if (not m.mis_contract) pp in + let insts = instances machines m in + let stateful_insts = + List.( + filter + (fun path -> + let _, (_, mems) = hd (rev path) in + mems <> []) + insts) + in pp_acsl_cut - ~ghost:m.mis_contract + ~ghost:true (fun fmt () -> fprintf fmt - "%a%a%a" - (pp_if_not_contract - (pp_ensures (pp_memory_pack_aux pp_ptr pp_print_string))) - (name, mem, self) - (pp_ensures (pp_reset_set pp_ptr)) + "%a%a" + (pp_ensures (pp_initialization pp_ptr)) (name, mem) - (pp_assigns pp_reset_flag') - (if m.mis_contract then [ mem ] else [ self; mem ])) + (pp_assigns (pp_reg ~indirect:false mem)) + stateful_insts) fmt () @@ -1466,7 +1433,7 @@ module SrcMod = struct else fprintf fmt - "%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a%a" + "%a%a%a%a%a%a%a%a%a%a%a%a%a%a" (pp_if_outputs (pp_requires (pp_valid pp_var_decl))) outputs (pp_if_not_contract (pp_requires pp_mem_valid')) @@ -1508,33 +1475,45 @@ module SrcMod = struct insts_no_arrow (pp_print_only_if (m.mmemory <> []) (pp_assigns (pp_reg mem))) [ [] ] - (pp_assigns pp_reset_flag') - [ mem ] (pp_assigns (pp_reg ~indirect:false mem)) - stateful_insts - (pp_assigns (pp_reset_flag_chain ~indirect:false mem)) - insts_no_arrow) + stateful_insts) fmt () - let pp_ghost_instr_code m self fmt instr = + let pp_ghost_reset pp_mem name fmt mem = + fprintf fmt "%a(%a);" pp_machine_ghost_reset_name name pp_mem mem + + let pp_ghost_instr_code m mem fmt instr = match instr.instr_desc with | MStateAssign (x, v) -> fprintf fmt "@,%a" - (pp_acsl_line (pp_ghost (pp_assign m self (pp_c_var_read m)))) + (pp_acsl_line' (pp_ghost (pp_assign m mem (pp_c_var_read m)))) (x, v) - | MResetAssign b -> - fprintf fmt "@,%a" (pp_acsl_line (pp_ghost (pp_reset_assign self))) b + (* | MResetAssign b -> *) + (* fprintf fmt "@,%a" (pp_acsl_line (pp_ghost (pp_reset_assign self))) b *) | MSetReset inst -> - let td, _ = List.assoc inst m.minstances in - if Arrow.td_is_arrow td then - fprintf - fmt - "@,%a;" - (pp_acsl_line (pp_ghost (pp_arrow_reset_ghost self))) - inst + let name = + let node, _ = + try List.assoc inst m.minstances with Not_found -> assert false + in + node_name node + in + fprintf + fmt + "@,%a" + (pp_acsl_line' + (pp_ghost + (pp_ghost_reset (pp_indirect pp_ref' pp_print_string) name))) + (mem, inst) + (* let td, _ = List.assoc inst m.minstances in *) + (* if Arrow.td_is_arrow td then *) + (* fprintf *) + (* fmt *) + (* "@,%a;" *) + (* (pp_acsl_line (pp_ghost (pp_arrow_reset_ghost self))) *) + (* inst *) | _ -> () @@ -1590,19 +1569,19 @@ module SrcMod = struct in List.fold_left gather VSet.empty m.mstep.step_instrs |> VSet.elements - let pp_ghost_reset_memory m fmt mem = - let name = m.mname.node_id in - let mem_r = mk_mem_reset m in - let pp fmt () = - fprintf - fmt - "%a = %a;" - (pp_machine_decl' ~ghost:true) - (name, mem_r) - pp_ptr - mem - in - (if m.mis_contract then pp else pp_acsl_line' (pp_ghost pp)) fmt () + (* let pp_ghost_reset_memory m fmt mem = *) + (* let name = m.mname.node_id in *) + (* let mem_r = mk_mem_reset m in *) + (* let pp fmt () = *) + (* fprintf *) + (* fmt *) + (* "%a = %a;" *) + (* (pp_machine_decl' ~ghost:true) *) + (* (name, mem_r) *) + (* pp_ptr *) + (* mem *) + (* in *) + (* (if m.mis_contract then pp else pp_acsl_line' (pp_ghost pp)) fmt () *) end module MainMod = struct @@ -1647,7 +1626,9 @@ module MainMod = struct (pp_print_option (fun fmt m_c -> let stateless_c = fst (get_stateless_status m_c) in let name_c = m_c.mname.node_id in - pp_print_only_if (not stateless_c) (fun fmt -> + pp_print_only_if + (not stateless_c) + (fun fmt -> fprintf fmt "@;%a" @@ -1677,17 +1658,17 @@ module MainMod = struct GhostProto.pp_ghost_parameters ~cut:false fmt - (if stateless then proto_c else - (mk_main_mem_ghost m, pp_ref pp_print_string) - :: proto_c) + (if stateless then proto_c + else (mk_main_mem_ghost m, pp_ref pp_print_string) :: proto_c) let pp_main_loop_invariants main_mem machines fmt m = let name = m.mname.node_id in let insts = instances machines m in let c, m_c = contract_of machines m in - let m_c_k = match c, m_c with + let m_c_k = + match c, m_c with | Some c, Some m_c -> ( - match c.mc_proof with Some (Kinduction k) -> Some (m_c, k) | _ -> None) + match c.mc_proof with Some (Kinduction k) -> Some (m_c, k) | _ -> None) | _ -> None in @@ -1697,7 +1678,8 @@ module MainMod = struct fmt "%a%a%a" (pp_print_option (fun fmt _ -> - pp_print_option (fun fmt m_c -> + pp_print_option + (fun fmt m_c -> pp_acsl_cut (pp_ghost (pp_print_list @@ -1707,7 +1689,8 @@ module MainMod = struct (pp_local m_c))) fmt m_c.mstep.step_outputs) - fmt m_c)) + fmt + m_c)) c (pp_print_option (fun fmt _ -> fprintf @@ -1720,22 +1703,27 @@ module MainMod = struct fprintf fmt "%a%a%a%a%a" - (pp_print_only_if (not stateless) (pp_loop_invariant pp_mem_valid')) + (pp_print_only_if + (not stateless) + (pp_loop_invariant pp_mem_valid')) (name, main_mem) - (pp_print_only_if (not stateless) + (pp_print_only_if + (not stateless) (pp_loop_invariant (pp_memory_pack_aux pp_print_string pp_print_string))) (name, mk_main_mem_ghost m, main_mem) - (fun fmt (_, _, _, outputs as x) -> - if stateless then - (if List.length outputs > 1 then - pp_loop_invariant pp_separated'' fmt outputs) - else - pp_loop_invariant + (fun fmt ((_, _, _, outputs) as x) -> + if stateless then ( + if List.length outputs > 1 then + pp_loop_invariant pp_separated'' fmt outputs) + else + pp_loop_invariant (pp_separated (pp_paren pp_print_string) pp_ref' - (pp_ref pp_var_decl)) fmt x) + (pp_ref pp_var_decl)) + fmt + x) (main_mem, mk_main_mem_ghost m, insts, m.mstep.step_outputs) (pp_loop_invariant (pp_or (pp_valid_read pp_stdout) (pp_equal pp_stdout pp_null))) @@ -1791,23 +1779,25 @@ module MainMod = struct fmt "@,%a" (pp_print_option (fun fmt c -> - pp_print_option (fun fmt _ -> + pp_print_option + (fun fmt _ -> fprintf fmt "%a%a" (match c.mc_proof with - | Some (Kinduction _) -> - pp_acsl_line_cut (pp_ghost (fun fmt -> fprintf fmt "%s++;")) - | None -> pp_print_nothing) + | Some (Kinduction _) -> + pp_acsl_line_cut (pp_ghost (fun fmt -> fprintf fmt "%s++;")) + | None -> + pp_print_nothing) (mk_k m) (pp_acsl_line' - (pp_assert - (PrintSpec.pp_spec TransitionMode m))) + (pp_assert (PrintSpec.pp_spec TransitionMode m))) (spec_from_contract c)) - (* (pp_and_l (fun fmt v -> *) - (* pp_equal pp_var_decl pp_print_int fmt (v, 1))))) *) - (* m_c.mstep.step_outputs) *) - fmt m_c)) + (* (pp_and_l (fun fmt v -> *) + (* pp_equal pp_var_decl pp_print_int fmt (v, 1))))) *) + (* m_c.mstep.step_outputs) *) + fmt + m_c)) c let pp_main_spec fmt = diff --git a/src/backends/C/c_backend_src.ml b/src/backends/C/c_backend_src.ml index 2cb2ce25..e47d1374 100644 --- a/src/backends/C/c_backend_src.ml +++ b/src/backends/C/c_backend_src.ml @@ -22,9 +22,14 @@ module type MODIFIERS_SRC = sig module GhostProto : MODIFIERS_GHOST_PROTO val pp_import_spec_prototype : formatter -> dep_t -> unit - val pp_set_reset_spec : formatter -> ident -> ident -> machine_t -> unit + + (* val pp_set_reset_spec : formatter -> machine_t list -> ident -> ident -> + machine_t -> unit *) val pp_clear_reset_spec : formatter -> ident -> ident -> machine_t -> unit + val pp_ghost_reset_spec : + formatter -> machine_t list -> ident -> machine_t -> unit + val pp_step_spec : formatter -> machine_t list -> ident -> ident -> machine_t -> unit @@ -34,7 +39,8 @@ module type MODIFIERS_SRC = sig val pp_ghost_parameter : ident -> formatter -> ident option -> unit val pp_c_decl_local_spec_var : machine_t -> formatter -> var_decl -> unit val get_spec_locals : machine_t -> var_decl list - val pp_ghost_reset_memory : machine_t -> formatter -> ident -> unit + + (* val pp_ghost_reset_memory : machine_t -> formatter -> ident -> unit *) val pp_is_contract : (formatter -> unit) -> formatter -> unit val pp_contract_arrow_reset_name : formatter -> unit val pp_contract_arrow_step_name : formatter -> unit @@ -45,24 +51,29 @@ module type MODIFIERS_SRC = sig formatter -> unit -> unit + + (* val pp_ghost_reset: machine_t -> ident -> formatter -> unit -> unit *) end module EmptyMod = struct module GhostProto = EmptyGhostProto let pp_import_spec_prototype _ _ = () - let pp_set_reset_spec _ _ _ _ = () + let pp_set_reset_spec _ _ _ _ _ = () let pp_clear_reset_spec _ _ _ _ = () + let pp_ghost_reset_spec _ _ _ _ = () let pp_step_spec _ _ _ _ _ = () let pp_step_instr_spec _ _ _ _ _ = () let pp_ghost_parameter _ _ _ = () let pp_c_decl_local_spec_var _ _ _ = () let get_spec_locals _ = [] - let pp_ghost_reset_memory _ _ _ = () + + (* let pp_ghost_reset_memory _ _ _ = () *) let pp_is_contract _ _ = () let pp_contract_arrow_reset_name _ = () let pp_contract_arrow_step_name _ = () let pp_contract_step_call _ _ _ _ = () + (* let pp_ghost_reset _ _ _ _ = () *) end module Main (Mod : MODIFIERS_SRC) = struct @@ -141,22 +152,23 @@ module Main (Mod : MODIFIERS_SRC) = struct | None -> m.mname.node_id, false, [] in - let is_arrow_reset = is_arrow && fn_name = "pp_machine_set_reset" in + let is_set_reset = fn_name = "pp_machine_set_reset" in + let is_ghost_reset = fn_name = "pp_machine_ghost_reset" in fprintf fmt "%a(%a%s%a)%a;" (fun fmt name -> - if is_arrow_reset then + if is_set_reset && is_arrow then if m.mis_contract then Mod.pp_contract_arrow_reset_name fmt else fprintf fmt "%s_reset" Arrow.arrow_id else pp_machine_name fmt name) name (pp_comma_list ~pp_eol:pp_print_comma Dimension.pp) static - self + (if is_ghost_reset && not is_arrow then "&" ^ self else self) (pp_print_option (fun fmt -> fprintf fmt "->%s")) inst - (if is_arrow_reset || m.mis_contract then pp_print_nothing + (if is_set_reset || m.mis_contract then pp_print_nothing else Mod.pp_ghost_parameter mem) inst @@ -179,6 +191,16 @@ module Main (Mod : MODIFIERS_SRC) = struct self mem + let pp_machine_ghost_reset m mem fmt inst = + pp_machine_ + pp_machine_ghost_reset_name + "pp_machine_ghost_reset" + { m with mis_contract = true } + fmt + ~inst + mem + mem + let pp_machine_init m self mem fmt inst = pp_machine_ pp_machine_init_name "pp_machine_init" m fmt ~inst self mem @@ -272,12 +294,13 @@ module Main (Mod : MODIFIERS_SRC) = struct reset_loop_counter (); aux [] fmt (List.hd inputs).Machine_code_types.value_type - let rec pp_conditional dependencies m self mem fmt c tl el = + let rec pp_conditional ?(with_spec = true) dependencies m self mem fmt c tl el + = let pp_machine_instrs = pp_print_list ~pp_open_box:pp_open_vbox0 ~pp_prologue:pp_print_cut - (pp_machine_instr dependencies m self mem) + (pp_machine_instr ~with_spec dependencies m self mem) in let pp_cond = pp_c_val m self (pp_c_var_read m) in match tl, el with @@ -296,7 +319,7 @@ module Main (Mod : MODIFIERS_SRC) = struct pp_machine_instrs el - and pp_machine_instr dependencies m self mem fmt instr = + and pp_machine_instr ?(with_spec = true) dependencies m self mem fmt instr = let self = if m.mis_contract then mem else self in let pp_instr fmt instr = match get_instr_desc instr with @@ -306,12 +329,12 @@ module Main (Mod : MODIFIERS_SRC) = struct pp_machine_set_reset m self mem fmt inst | MClearReset -> if not (fst (get_stateless_status m)) then - fprintf - fmt - "%t@,%a" - (pp_machine_clear_reset m self mem) - (Mod.pp_ghost_reset_memory m) - mem + (* fprintf *) + (* fmt *) + (* "%t@,%a" *) + (pp_machine_clear_reset m self mem) fmt + (* (Mod.pp_ghost_reset_memory m) *) + (* mem *) | MResetAssign b -> pp_reset_assign self fmt b | MLocalAssign (i, v) -> @@ -322,6 +345,7 @@ module Main (Mod : MODIFIERS_SRC) = struct when Basic_library.is_value_internal_fun (mk_val (Fun (i, vl)) i0.var_type) -> pp_machine_instr + ~with_spec dependencies m self @@ -369,6 +393,7 @@ module Main (Mod : MODIFIERS_SRC) = struct match i.instr_desc with MNoReset _ -> false | _ -> true) in pp_conditional + ~with_spec dependencies m self @@ -388,16 +413,30 @@ module Main (Mod : MODIFIERS_SRC) = struct g (pp_print_list_i ~pp_open_box:pp_open_vbox0 - (pp_machine_branch dependencies m self mem (List.length hl))) + (pp_machine_branch + ~with_spec + dependencies + m + self + mem + (List.length hl))) hl | MSpec s -> fprintf fmt "@[/*@@ %s */@]@ " s | MComment s -> fprintf fmt "/* %s */" s in - fprintf fmt "%a%a" pp_instr instr (Mod.pp_step_instr_spec m self mem) instr + fprintf + fmt + "%a%a" + pp_instr + instr + (if with_spec then Mod.pp_step_instr_spec m self mem + else pp_print_nothing) + instr - and pp_machine_branch dependencies m self mem n fmt i (t, h) = + and pp_machine_branch ?(with_spec = true) dependencies m self mem n fmt i + (t, h) = fprintf fmt (if n > 1 && i = n - 1 then "@[<v 2>default: // %a@,%a@]" @@ -406,7 +445,7 @@ module Main (Mod : MODIFIERS_SRC) = struct t (pp_print_list ~pp_open_box:pp_open_vbox0 - (pp_machine_instr dependencies m self mem)) + (pp_machine_instr ~with_spec dependencies m self mem)) h (* let pp_machine_nospec_instr dependencies m self fmt instr = @@ -636,11 +675,11 @@ module Main (Mod : MODIFIERS_SRC) = struct Option.bind c (fun _ -> Option.map (fun m_c -> - let stateless_c = fst (get_stateless_status m_c) in - ( (if stateless_c then None else Some (mk_mem_c m)), - m_c.mname.node_id, - m_c.mstep.step_inputs, - m_c.mstep.step_outputs )) + let stateless_c = fst (get_stateless_status m_c) in + ( (if stateless_c then None else Some (mk_mem_c m)), + m_c.mname.node_id, + m_c.mstep.step_inputs, + m_c.mstep.step_outputs )) m_c) let pp_stateless_code machines dependencies fmt m = @@ -653,7 +692,8 @@ module Main (Mod : MODIFIERS_SRC) = struct ~is_contract ~pp_spec:(fun fmt () -> Mod.pp_step_spec fmt machines self self m) ~pp_prototype:Protos.pp_stateless_prototype - ~prototype:(m.mname.node_id, m.mstep.step_inputs, m.mstep.step_outputs, proto_c) + ~prototype: + (m.mname.node_id, m.mstep.step_inputs, m.mstep.step_outputs, proto_c) ~pp_local:(pp_c_decl_local_var m) ~base_locals:m.mstep.step_locals ~pp_spec_local:(Mod.pp_c_decl_local_spec_var m) @@ -688,7 +728,7 @@ module Main (Mod : MODIFIERS_SRC) = struct ( m.mname.node_id, m.mstep.step_inputs @ gen_locals @ gen_calls, m.mstep.step_outputs, - proto_c) + proto_c ) ~pp_local:(pp_c_decl_local_var m) ~base_locals ~pp_init_mpfr_local:(pp_initialize m self (pp_c_var_read m)) @@ -710,7 +750,7 @@ module Main (Mod : MODIFIERS_SRC) = struct ~prototype:(m.mname.node_id, m.mstatic) ~pp_local:(pp_c_decl_local_var m) ~base_locals:(const_locals m) - ~pp_instr:(pp_machine_instr dependencies m self mem) + ~pp_instr:(pp_machine_instr ~with_spec:false dependencies m self mem) ~instrs: [ mk_branch @@ -719,17 +759,46 @@ module Main (Mod : MODIFIERS_SRC) = struct ] fmt - let pp_set_reset_code dependencies self mem fmt m = - let is_contract = m.mis_contract in + let pp_ghost_reset_spec_code machines mem fmt m = + let pp_instr fmt i = + match get_instr_desc i with + | MSetReset inst -> + pp_machine_ghost_reset m mem fmt inst + | _ -> + assert false + in pp_print_function - ~is_contract - ~pp_spec:(fun fmt () -> Mod.pp_set_reset_spec fmt self mem m) - ~pp_prototype:(Protos.pp_set_reset_prototype is_contract self mem) + ~is_contract:true + ~pp_spec:(fun fmt () -> Mod.pp_ghost_reset_spec fmt machines mem m) + ~pp_prototype:(Protos.pp_ghost_reset_prototype mem) ~prototype:(m.mname.node_id, m.mstatic) - ~pp_instr:(pp_machine_instr dependencies m self mem) - ~instrs:[ mkinstr (MResetAssign true) ] + ~pp_instr + ~instrs:m.minit fmt + (* let pp_set_reset_code machines dependencies self mem fmt m = *) + (* let prototype = m.mname.node_id, m.mstatic in *) + (* let pp_instr fmt i = *) + (* match get_instr_desc i with *) + (* | MSetReset inst -> *) + (* pp_machine_ghost_reset m mem fmt inst *) + (* | _ -> assert false *) + (* in *) + (* in *) + (* let is_contract = m.mis_contract in *) + (* pp_print_function *) + (* ~is_contract *) + (* ~pp_spec:(fun fmt () -> *) + (* fprintf fmt "%t@;%a" *) + (* pp_ghost_reset *) + (* (fun fmt () -> Mod.pp_set_reset_spec fmt machines self mem m) ()) *) + (* ~pp_prototype:(Protos.pp_set_reset_prototype is_contract self mem) *) + (* ~prototype *) + (* ~pp_instr:(pp_machine_instr dependencies m self mem) *) + (* ~instrs:[ mkinstr (MResetAssign true) ] *) + (* ~pp_extra:(Mod.pp_ghost_reset m mem) *) + (* fmt *) + let pp_init_code self fmt m = let minit = List.map @@ -1006,14 +1075,12 @@ module Main (Mod : MODIFIERS_SRC) = struct let mem = mk_mem m in fprintf fmt - "@[<v>%a%a@,@,%a@,@,%a%a@]" + "@[<v>%a%a@,@,%a%a@]" pp_alloc_function m - (* Reset functions *) + (* Reset function *) (pp_clear_reset_code dependencies self mem) m - (pp_set_reset_code dependencies self mem) - m (* Step function *) (pp_step_code machines dependencies self mem) m diff --git a/src/backends/C/c_backend_src.mli b/src/backends/C/c_backend_src.mli index d894abda..98168f33 100644 --- a/src/backends/C/c_backend_src.mli +++ b/src/backends/C/c_backend_src.mli @@ -8,9 +8,14 @@ module type MODIFIERS_SRC = sig module GhostProto : MODIFIERS_GHOST_PROTO val pp_import_spec_prototype : formatter -> dep_t -> unit - val pp_set_reset_spec : formatter -> ident -> ident -> machine_t -> unit + + (* val pp_set_reset_spec : formatter -> machine_t list -> ident -> ident -> + machine_t -> unit *) val pp_clear_reset_spec : formatter -> ident -> ident -> machine_t -> unit + val pp_ghost_reset_spec : + formatter -> machine_t list -> ident -> machine_t -> unit + val pp_step_spec : formatter -> machine_t list -> ident -> ident -> machine_t -> unit @@ -20,7 +25,8 @@ module type MODIFIERS_SRC = sig val pp_ghost_parameter : ident -> formatter -> ident option -> unit val pp_c_decl_local_spec_var : machine_t -> formatter -> var_decl -> unit val get_spec_locals : machine_t -> var_decl list - val pp_ghost_reset_memory : machine_t -> formatter -> ident -> unit + + (* val pp_ghost_reset_memory : machine_t -> formatter -> ident -> unit *) val pp_is_contract : (formatter -> unit) -> formatter -> unit val pp_contract_arrow_reset_name : formatter -> unit val pp_contract_arrow_step_name : formatter -> unit @@ -31,6 +37,8 @@ module type MODIFIERS_SRC = sig formatter -> unit -> unit + + (* val pp_ghost_reset: machine_t -> ident -> formatter -> unit -> unit *) end module EmptyMod : MODIFIERS_SRC @@ -38,4 +46,7 @@ module EmptyMod : MODIFIERS_SRC module Main (Mod : MODIFIERS_SRC) : sig val pp_lib_c : formatter -> string -> program_t -> machine_t list -> dep_t list -> unit + + val pp_ghost_reset_spec_code : + machine_t list -> ident -> formatter -> machine_t -> unit end diff --git a/src/machine_code.ml b/src/machine_code.ml index d90f135f..6338fbc4 100644 --- a/src/machine_code.ml +++ b/src/machine_code.ml @@ -212,9 +212,7 @@ let ctx_init = si = []; j = IMap.empty; s = []; - mp_base = - And - [ StateVarPack (ResetFlag, false); Equal (Memory ResetFlag, Val zero) ]; + mp_base = True; tainted = ISet.empty; mp = []; t = []; @@ -547,20 +545,14 @@ let memory_pack_0 nd mems = VSet.fold (fun v a -> And [ a; mk_state_variable_pack v ]) mems - (mk_memory_pack_base nd.node_id) - (* And [ StateVarPack (ResetFlag, false); Equal (Memory ResetFlag, Val - zero) ]; *); + (mk_memory_pack_base nd.node_id); } let memory_pack_toplevel nd i = { mpname = nd; mpindex = None; - mpformula = - Ternary - ( Memory ResetFlag, - StateVarPack (ResetFlag, false), - mk_memory_pack ~i nd.node_id ); + mpformula = MemoryPackToplevel (nd.node_id, i); } let transition_0 nd = @@ -568,9 +560,7 @@ let transition_0 nd = tname = nd; tindex = Some 0; tvars = nd.node_inputs; - tformula = - (if fst (get_stateless_status_node nd) then True - else StateVarPack (ResetFlag, false)); + tformula = True; tmem_footprint = ISet.empty; tinst_footprint = IMap.empty; } @@ -588,9 +578,7 @@ let transition_toplevel nd i = tname = nd; tindex = None; tvars = nd.node_inputs @ nd.node_outputs; - tformula = - (if fst (get_stateless_status_node nd) then tr - else ExistsMem (nd.node_id, Predicate (ResetCleared nd.node_id), tr)); + tformula = tr; tmem_footprint = ISet.empty; tinst_footprint = IMap.empty; } diff --git a/src/machine_code_common.ml b/src/machine_code_common.ml index c0110d9e..b6cc3e8c 100644 --- a/src/machine_code_common.ml +++ b/src/machine_code_common.ml @@ -37,12 +37,6 @@ let rec pp_val m fmt v = fprintf fmt "RESET" module PrintSpec = struct - let pp_reg fmt = function - | ResetFlag -> - pp_print_string fmt "{RESET}" - | StateVar v -> - fprintf fmt "{OUT:%a}" pp_vdecl v - let pp_expr m fmt = function | Val v -> pp_val m fmt v @@ -51,7 +45,7 @@ module PrintSpec = struct | Var v -> pp_vdecl fmt v | Memory r -> - pp_reg fmt r + fprintf fmt "{OUT:%a}" pp_vdecl r let pp_predicate m fmt p = let pp_expr fmt e = pp_expr m fmt e in @@ -94,10 +88,6 @@ module PrintSpec = struct inst (pp_print_option pp_print_int) i - | ResetCleared f -> - fprintf fmt "ResetCleared_%a" pp_print_string f - | Initialization -> - () | GhostAssign (v1, v2) -> fprintf fmt "Ghost %s = %s" v1.var_id v2.var_id @@ -161,12 +151,20 @@ module PrintSpec = struct "StateVarPack%a<%a>" (if tainted then pp_print_string else pp_print_nothing) "_tainted" - pp_reg + pp_vdecl r | ExistsMem (_f, a, b) -> fprintf fmt "@[<hv 2>∃ MEM,@ %a@]" pp_spec (And [ a; b ]) | Value v -> pp_val m fmt v + | MemoryPackToplevel (f, i) -> + fprintf + fmt + "If RESET Then FULLRESET(%a) Else (@[<hov>%a@])" + pp_print_string + f + (pp_predicate m) + (MemoryPack (f, None, Some i)) in pp_spec diff --git a/src/spec_common.ml b/src/spec_common.ml index 342fca6b..853e9a41 100644 --- a/src/spec_common.ml +++ b/src/spec_common.ml @@ -12,9 +12,7 @@ let type_of_value = function t | Var v -> v.var_type - | Memory ResetFlag -> - Type_predef.type_bool - | Memory (StateVar v) -> + | Memory v -> v.var_type let expr_eq a b = a = b @@ -110,11 +108,8 @@ let mk_transition ?(mems = ISet.empty) ?(insts = IMap.empty) ?r ?i ?inst let mk_memory_pack ?i ?inst id = mk_pred_call (MemoryPack (id, inst, i)) let mk_memory_pack_base id = mk_pred_call (MemoryPackBase id) - -let mk_state_variable_pack ?(tainted = false) x = - StateVarPack (StateVar x, tainted) - -let mk_state_assign_tr x v = Equal (Memory (StateVar x), Val v) +let mk_state_variable_pack ?(tainted = false) x = StateVarPack (x, tainted) +let mk_state_assign_tr x v = Equal (Memory x, Val v) let mk_conditional_tr v t f = Ternary (Val v, t, f) let mk_branch_tr x = diff --git a/src/spec_types.ml b/src/spec_types.ml index 5f0230b6..bdfcb53b 100644 --- a/src/spec_types.ml +++ b/src/spec_types.ml @@ -1,13 +1,11 @@ open Utils open Lustre_types -type register_t = ResetFlag | StateVar of var_decl - type 'a expression_t = | Val of 'a | Tag of ident * Types.t | Var of var_decl - | Memory of register_t + | Memory of var_decl type 'a predicate_t = | Transition : @@ -27,8 +25,6 @@ type 'a predicate_t = | Reset of ident * ident * 'a | MemoryPack of ident * ident option * int option | MemoryPackBase of ident - | Initialization - | ResetCleared of ident | GhostAssign of var_decl * var_decl type 'a formula_t = @@ -43,9 +39,10 @@ type 'a formula_t = | Forall of var_decl list * 'a formula_t | Ternary of 'a expression_t * 'a formula_t * 'a formula_t | Predicate : 'a predicate_t -> 'a formula_t - | StateVarPack of register_t * bool (* tainted or not *) + | StateVarPack of var_decl * bool (* tainted or not *) | ExistsMem of ident * 'a formula_t * 'a formula_t | Value of 'a + | MemoryPackToplevel of ident * int (* type 'a simulation_t = { * sname: node_desc; diff --git a/src/spec_types.mli b/src/spec_types.mli index faff8b07..41749288 100644 --- a/src/spec_types.mli +++ b/src/spec_types.mli @@ -1,13 +1,11 @@ open Utils open Lustre_types -type register_t = ResetFlag | StateVar of var_decl - type 'a expression_t = | Val of 'a | Tag of ident * Types.t | Var of var_decl - | Memory of register_t + | Memory of var_decl type 'a predicate_t = | Transition : @@ -27,8 +25,6 @@ type 'a predicate_t = | Reset of ident * ident * 'a | MemoryPack of ident * ident option * int option | MemoryPackBase of ident - | Initialization - | ResetCleared of ident | GhostAssign of var_decl * var_decl type 'a formula_t = @@ -43,9 +39,10 @@ type 'a formula_t = | Forall of var_decl list * 'a formula_t | Ternary of 'a expression_t * 'a formula_t * 'a formula_t | Predicate : 'a predicate_t -> 'a formula_t - | StateVarPack of register_t * bool (* tainted or not *) + | StateVarPack of var_decl * bool (* tainted or not *) | ExistsMem of ident * 'a formula_t * 'a formula_t | Value of 'a + | MemoryPackToplevel of ident * int type 'a transition_t = { tname : node_desc; diff --git a/src/tools/tiny/tiny_verifier.ml b/src/tools/tiny/tiny_verifier.ml index b10405e5..c18e1ed7 100644 --- a/src/tools/tiny/tiny_verifier.ml +++ b/src/tools/tiny/tiny_verifier.ml @@ -5,7 +5,6 @@ let descending = ref 1 let unrolling = ref 0 let output = ref false let reachtube = ref false (* used to produce a list of set iterates *) - let quiet () = Tiny.Report.verbosity := 0 let report = Tiny_utils.report diff --git a/strategy.ml b/strategy.ml index feec6326..c6a50d77 100644 --- a/strategy.ml +++ b/strategy.ml @@ -136,7 +136,6 @@ let rec unify (push : Strategy.strategy -> unit) (sequent : Conditions.sequent) class lustrec_transitions : Strategy.heuristic = object method id = "LustreC:Transitions" (* required, must be unique *) - method title = "LustreC Transitions" method descr = "Custom goal transformations for transition relations" @@ -166,7 +165,6 @@ class lustrec_transitions : Strategy.heuristic = class lustrec_reset_cleared : Strategy.heuristic = object method id = "LustreC:ResetCleared" (* required, must be unique *) - method title = "LustreC ResetCleared" method descr = "Custom goal transformations for reset_cleared relations" @@ -256,7 +254,6 @@ let unfold_rec_strategy = Strategy.make (new unfold_rec) ~arguments:[] class lustrec_memory_packs : Strategy.heuristic = object method id = "LustreC:MemoryPacks" (* required, must be unique *) - method title = "LustreC MemoryPacks" method descr = "Custom goal transformations for memory_pack relations" -- GitLab