Skip to content
Snippets Groups Projects
Commit d29fbec5 authored by BRUN Lelio's avatar BRUN Lelio
Browse files

working version for stateful contracts

parent 4fef1a04
No related branches found
No related tags found
No related merge requests found
Showing
with 529 additions and 372 deletions
version=0.18.0 version=0.19.0
parens-tuple=multi-line-only parens-tuple=multi-line-only
wrap-comments=true wrap-comments=true
cases-exp-indent=2 cases-exp-indent=2
......
...@@ -88,7 +88,8 @@ let unless_read reads handler = ...@@ -88,7 +88,8 @@ let unless_read reads handler =
(* Format.eprintf "unless_reads %s = %a@." handler.hand_state (fprintf_list (* Format.eprintf "unless_reads %s = %a@." handler.hand_state (fprintf_list
~sep:" , " (fun fmt v -> Format.fprintf fmt "%s" v)) (ISet.elements reads); ~sep:" , " (fun fmt v -> Format.fprintf fmt "%s" v)) (ISet.elements reads);
Format.eprintf "unless_reads' %s = %a@." handler.hand_state (fprintf_list Format.eprintf "unless_reads' %s = %a@." handler.hand_state (fprintf_list
~sep:" , " (fun fmt v -> Format.fprintf fmt "%s" v)) (ISet.elements res); *) ~sep:" , " (fun fmt v -> Format.fprintf fmt "%s" v)) (ISet.elements
res); *)
res res
let until_read reads handler = let until_read reads handler =
...@@ -381,7 +382,7 @@ let node_of_assign_until nused used node aut_id aut_state handler = ...@@ -381,7 +382,7 @@ let node_of_assign_until nused used node aut_id aut_state handler =
node_gencalls = []; node_gencalls = [];
node_checks = []; node_checks = [];
node_asserts = handler.hand_asserts; node_asserts = handler.hand_asserts;
node_stmts = until_eq :: new_output_eqs @ handler.hand_stmts; node_stmts = (until_eq :: new_output_eqs) @ handler.hand_stmts;
node_dec_stateless = false; node_dec_stateless = false;
node_stateless = None; node_stateless = None;
node_spec = None; node_spec = None;
...@@ -544,7 +545,7 @@ let rec expand_decls_rec nused top_decls = ...@@ -544,7 +545,7 @@ let rec expand_decls_rec nused top_decls =
top_decl.top_decl_owner top_decl.top_decl_owner
nd nd
in in
top_types' @ top_decl' :: expand_decls_rec nused (top_nodes' @ q) top_types' @ (top_decl' :: expand_decls_rec nused (top_nodes' @ q))
| _ -> | _ ->
top_decl :: expand_decls_rec nused q) top_decl :: expand_decls_rec nused q)
......
...@@ -111,10 +111,9 @@ let pp_main_adb fmt machine = ...@@ -111,10 +111,9 @@ let pp_main_adb fmt machine =
let pp_loop fmt = let pp_loop fmt =
let args = let args =
pp_state_name pp_state_name
:: :: List.map
List.map pp_var_name
pp_var_name (machine.mstep.step_inputs @ machine.mstep.step_outputs)
(machine.mstep.step_inputs @ machine.mstep.step_outputs)
in in
fprintf fprintf
fmt fmt
......
...@@ -53,12 +53,11 @@ let fprintf_dependencies fmt (dep : dep_t list) = ...@@ -53,12 +53,11 @@ let fprintf_dependencies fmt (dep : dep_t list) =
(* Format.eprintf "Adding dependency: %s@." s; *) (* Format.eprintf "Adding dependency: %s@." s; *)
fprintf fmt "\t${GCC} -I${INC} -c %s@." s) fprintf fmt "\t${GCC} -I${INC} -c %s@." s)
("${INC}/io_frontend.c" ("${INC}/io_frontend.c"
:: :: (* IO functions when a main function is computed *)
(* IO functions when a main function is computed *) List.map
List.map (fun (Dep (local, s, _, _)) ->
(fun (Dep (local, s, _, _)) -> (if local then s else Version.include_path ^ "/" ^ s) ^ ".c")
(if local then s else Version.include_path ^ "/" ^ s) ^ ".c") compiled_dep)
compiled_dep)
module type MODIFIERS_MKF = sig module type MODIFIERS_MKF = sig
(* dep was (bool * ident * top_decl list) *) (* dep was (bool * ident * top_decl list) *)
......
...@@ -276,7 +276,8 @@ let pp_basic_c_type ?(pp_c_basic_type_desc = pp_c_basic_type_desc) ?var_opt fmt ...@@ -276,7 +276,8 @@ let pp_basic_c_type ?(pp_c_basic_type_desc = pp_c_basic_type_desc) ?var_opt fmt
| _ -> | _ ->
fprintf fmt "%s" (pp_c_basic_type_desc t) fprintf fmt "%s" (pp_c_basic_type_desc t)
let pp_c_type ?(var_is_contract=false) ?pp_c_basic_type_desc ?var_opt var_id fmt t = let pp_c_type ?(var_is_contract = false) ?pp_c_basic_type_desc ?var_opt var_id
fmt t =
let rec aux t pp_suffix = let rec aux t pp_suffix =
if is_basic_c_type t then if is_basic_c_type t then
fprintf fprintf
...@@ -439,7 +440,12 @@ let pp_c_decl_input_var fmt id = ...@@ -439,7 +440,12 @@ let pp_c_decl_input_var fmt id =
the case for generics *) the case for generics *)
let pp_c_decl_output_var fmt id = let pp_c_decl_output_var fmt id =
if (not !Options.ansi) && Types.is_address_type id.var_type then if (not !Options.ansi) && Types.is_address_type id.var_type then
pp_c_type ~var_is_contract:id.var_is_contract ~var_opt:id id.var_id fmt id.var_type pp_c_type
~var_is_contract:id.var_is_contract
~var_opt:id
id.var_id
fmt
id.var_type
else else
pp_c_type pp_c_type
~var_is_contract:id.var_is_contract ~var_is_contract:id.var_is_contract
...@@ -937,9 +943,7 @@ module Protos (Mod : MODIFIERS_GHOST_PROTO) = struct ...@@ -937,9 +943,7 @@ module Protos (Mod : MODIFIERS_GHOST_PROTO) = struct
name name
(pp_comma_list pp_c_decl_input_var) (pp_comma_list pp_c_decl_input_var)
inputs inputs
(pp_comma_list (pp_comma_list ~pp_prologue:pp_print_comma pp_c_decl_output_var)
~pp_prologue:pp_print_comma
pp_c_decl_output_var)
outputs outputs
end end
......
...@@ -72,7 +72,8 @@ functor ...@@ -72,7 +72,8 @@ functor
a predicate: function step and reset are associated to ACSL predicate - 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 associated to a refinement contract, wrt its ACSL sem - if
the node is a regular node associated to a contract, print the contract 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 *) as function contract. - do not print anything if this is a contract
node *)
let pp_machine_alloc_decl fmt m = let pp_machine_alloc_decl fmt m =
Mod.pp_machine_decl_prefix fmt m; Mod.pp_machine_decl_prefix fmt m;
if not (fst (get_stateless_status m)) then if not (fst (get_stateless_status m)) then
...@@ -125,7 +126,8 @@ functor ...@@ -125,7 +126,8 @@ functor
fprintf fmt "extern %a;" pp_stateless_C_prototype prototype fprintf fmt "extern %a;" pp_stateless_C_prototype prototype
else ( else (
(* TODO: raise proper error *) (* TODO: raise proper error *)
Format.eprintf "internal error: pp_machine_decl_top_decl_from_header"; Format.eprintf
"internal error: pp_machine_decl_top_decl_from_header";
assert false) assert false)
else if inode.nodei_stateless then else if inode.nodei_stateless then
fprintf fmt "extern %a;" Protos.pp_stateless_prototype prototype fprintf fmt "extern %a;" Protos.pp_stateless_prototype prototype
......
...@@ -481,7 +481,8 @@ module Main (Mod : MODIFIERS_MAINSRC) = struct ...@@ -481,7 +481,8 @@ module Main (Mod : MODIFIERS_MAINSRC) = struct
content = []; content = [];
is_stateful = true (* assuming it is stateful*); is_stateful = true (* assuming it is stateful*);
} }
(* Print the svn version number and the supported C standard (C90 or C99) *) (* Print the svn version number and the supported C standard (C90 or
C99) *)
pp_print_version pp_print_version
() ()
(pp_main_code machines) (pp_main_code machines)
......
...@@ -63,13 +63,13 @@ let fprintf_dependencies fmt (deps : dep_t list) = ...@@ -63,13 +63,13 @@ let fprintf_dependencies fmt (deps : dep_t list) =
Log.report ~level:1 (fun fmt -> fprintf fmt "Adding dependency: %s@." s); Log.report ~level:1 (fun fmt -> fprintf fmt "Adding dependency: %s@." s);
fprintf fmt "\t${GCC} -I${INC} -c %s@." s) fprintf fmt "\t${GCC} -I${INC} -c %s@." s)
("${INC}/io_frontend.c" ("${INC}/io_frontend.c"
:: :: (* IO functions when a main function is computed *)
(* IO functions when a main function is computed *) List.map
List.map (fun dep ->
(fun dep -> (if dep.local then dep.name
(if dep.local then dep.name else Version.include_path ^ "/" ^ dep.name) else Version.include_path ^ "/" ^ dep.name)
^ ".c") ^ ".c")
compiled_deps) compiled_deps)
module type MODIFIERS_MKF = sig module type MODIFIERS_MKF = sig
(* dep was (bool * ident * top_decl list) *) (* dep was (bool * ident * top_decl list) *)
......
This diff is collapsed.
...@@ -35,7 +35,8 @@ module type MODIFIERS_SRC = sig ...@@ -35,7 +35,8 @@ module type MODIFIERS_SRC = sig
val pp_ghost_parameter : ident -> formatter -> ident option -> unit val pp_ghost_parameter : ident -> formatter -> ident option -> unit
val pp_contract : formatter -> machine_t list -> ident -> ident -> machine_t -> unit val pp_contract :
formatter -> machine_t list -> ident -> ident -> machine_t -> unit
end end
module EmptyMod = struct module EmptyMod = struct
...@@ -323,12 +324,12 @@ module Main (Mod : MODIFIERS_SRC) = struct ...@@ -323,12 +324,12 @@ module Main (Mod : MODIFIERS_SRC) = struct
i i
(pp_print_parenthesized (pp_c_val m self (pp_c_var_read m))) (pp_print_parenthesized (pp_c_val m self (pp_c_var_read m)))
vl vl
| MStep (il, i, vl) -> | MStep (il, i, vl) -> (
begin match List.assoc_opt i m.minstances with match List.assoc_opt i m.minstances with
| Some (td, _) when Arrow.td_is_arrow td -> | Some (td, _) when Arrow.td_is_arrow td ->
pp_arrow_call m self mem fmt i il pp_arrow_call m self mem fmt i il
| _ -> pp_basic_instance_call m self mem fmt i vl il | _ ->
end pp_basic_instance_call m self mem fmt i vl il)
| MBranch (_, []) -> | MBranch (_, []) ->
eprintf eprintf
"internal error: C_backend_src.pp_machine_instr %a@." "internal error: C_backend_src.pp_machine_instr %a@."
...@@ -544,9 +545,8 @@ module Main (Mod : MODIFIERS_SRC) = struct ...@@ -544,9 +545,8 @@ module Main (Mod : MODIFIERS_SRC) = struct
check check
let pp_print_function ~pp_prototype ~prototype ?(is_contract = false) let pp_print_function ~pp_prototype ~prototype ?(is_contract = false)
?(pp_spec = pp_print_nothing) ?(pp_spec = pp_print_nothing) ?(pp_local = pp_print_nothing)
?(pp_local = pp_print_nothing) ?(base_locals = []) ?(base_locals = []) ?(pp_array_mem = pp_print_nothing) ?(array_mems = [])
?(pp_array_mem = pp_print_nothing) ?(array_mems = [])
?(pp_init_mpfr_local = pp_print_nothing) ?(pp_init_mpfr_local = pp_print_nothing)
?(pp_clear_mpfr_local = pp_print_nothing) ?(mpfr_locals = []) ?(pp_clear_mpfr_local = pp_print_nothing) ?(mpfr_locals = [])
?(pp_check = pp_print_nothing) ?(checks = []) ?(pp_check = pp_print_nothing) ?(checks = [])
...@@ -1004,7 +1004,8 @@ module Main (Mod : MODIFIERS_SRC) = struct ...@@ -1004,7 +1004,8 @@ module Main (Mod : MODIFIERS_SRC) = struct
content = []; content = [];
is_stateful = true (* assuming it is stateful *); is_stateful = true (* assuming it is stateful *);
} }
(* Print the svn version number and the supported C standard (C90 or C99) *) (* Print the svn version number and the supported C standard (C90 or
C99) *)
pp_print_version pp_print_version
() ()
(* Print dependencies *) (* Print dependencies *)
......
...@@ -21,7 +21,8 @@ module type MODIFIERS_SRC = sig ...@@ -21,7 +21,8 @@ module type MODIFIERS_SRC = sig
val pp_ghost_parameter : ident -> formatter -> ident option -> unit val pp_ghost_parameter : ident -> formatter -> ident option -> unit
val pp_contract : formatter -> machine_t list -> ident -> ident -> machine_t -> unit val pp_contract :
formatter -> machine_t list -> ident -> ident -> machine_t -> unit
end end
module EmptyMod : MODIFIERS_SRC module EmptyMod : MODIFIERS_SRC
......
...@@ -387,7 +387,8 @@ let rec pp_machine_instr machines reset_instances (m : machine_t) fmt instr : ...@@ -387,7 +387,8 @@ let rec pp_machine_instr machines reset_instances (m : machine_t) fmt instr :
other did. Am I clear ? *) other did. Am I clear ? *)
(* For each branch we obtain the logical encoding, and the information (* For each branch we obtain the logical encoding, and the information
whether a sub node has been reset or not. If a node has been reset in one whether a sub node has been reset or not. If a node has been reset in one
of the branch, then all others have to have the mem_m = mem_c statement. *) of the branch, then all others have to have the mem_m = mem_c
statement. *)
let self = m.mname.node_id in let self = m.mname.node_id in
let pp_branch fmt (tag, instrs) = let pp_branch fmt (tag, instrs) =
fprintf fprintf
......
...@@ -53,7 +53,8 @@ let machines_traces machines = ...@@ -53,7 +53,8 @@ let machines_traces machines =
let filtered = let filtered =
List.filter (fun (kwds, _) -> kwds = [ "traceability" ]) all_annots List.filter (fun (kwds, _) -> kwds = [ "traceability" ]) all_annots
in in
(* List.iter (eprintf "Annots: %a@." Printers.pp_expr_annot) (m.mannot); *) (* List.iter (eprintf "Annots: %a@." Printers.pp_expr_annot)
(m.mannot); *)
let content = List.map snd filtered in let content = List.map snd filtered in
(* Elements are supposed to be a pair (tuple): variable, expression *) (* Elements are supposed to be a pair (tuple): variable, expression *)
List.map List.map
......
...@@ -5,7 +5,8 @@ let setup () = ...@@ -5,7 +5,8 @@ let setup () =
if !Options.output = Options.OutEMF then ( if !Options.output = Options.OutEMF then (
(* Not merging branches *) (* Not merging branches *)
join_guards := false; join_guards := false;
(* In case of a default "int" type, substitute it with the legal int32 value *) (* In case of a default "int" type, substitute it with the legal int32
value *)
if !Options.int_type = "int" then Options.int_type := "int32"); if !Options.int_type = "int" then Options.int_type := "int32");
if !Options.optimization < 0 then join_guards := false if !Options.optimization < 0 then join_guards := false
......
...@@ -206,7 +206,8 @@ module ExprDep = struct ...@@ -206,7 +206,8 @@ module ExprDep = struct
(* mem/mem in g' *) (* mem/mem in g' *)
(* match (lhs_is_mem, ISet.mem x mems) with | (false, true ) -> (add_edges [x] (* match (lhs_is_mem, ISet.mem x mems) with | (false, true ) -> (add_edges [x]
lhs g, g') | (false, false) -> (add_edges lhs [x] g, g') | (true , false) lhs g, g') | (false, false) -> (add_edges lhs [x] g, g') | (true , false)
-> (add_edges lhs [x] g, g') | (true , true ) -> (g, add_edges [x] lhs g') *) -> (add_edges lhs [x] g, g') | (true , true ) -> (g, add_edges [x] lhs
g') *)
let add_eq_dependencies mems inputs node_vars eq (g, g') = let add_eq_dependencies mems inputs node_vars eq (g, g') =
let add_var lhs_is_mem lhs x (g, g') = let add_var lhs_is_mem lhs x (g, g') =
if is_instance_var x || ISet.mem x node_vars then if is_instance_var x || ISet.mem x node_vars then
...@@ -590,7 +591,8 @@ module CycleDetection = struct ...@@ -590,7 +591,8 @@ module CycleDetection = struct
(* Breaks cycles of the dependency graph [g] of memory variables [mems] (* Breaks cycles of the dependency graph [g] of memory variables [mems]
belonging in node [node]. Returns: - a list of new auxiliary variable belonging in node [node]. Returns: - a list of new auxiliary variable
declarations - a list of new equations - a modified acyclic version of [g] *) declarations - a list of new equations - a modified acyclic version of
[g] *)
let break_cycles node mems g = let break_cycles node mems g =
let eqs, auts = get_node_eqs node in let eqs, auts = get_node_eqs node in
assert (auts = []); assert (auts = []);
......
...@@ -327,7 +327,8 @@ let clean_al prog : program_t * bool * report = ...@@ -327,7 +327,8 @@ let clean_al prog : program_t * bool * report =
| Node nd -> ( | Node nd -> (
let error, max_inlines = let error, max_inlines =
try try
(* without exception the node is schedulable; nothing to declare *) (* without exception the node is schedulable; nothing to
declare *)
let _ = Scheduling.schedule_node nd in let _ = Scheduling.schedule_node nd in
None, max_inlines None, max_inlines
with Causality.Error (Causality.DataCycle partitions) -> with Causality.Error (Causality.DataCycle partitions) ->
......
...@@ -48,7 +48,8 @@ let pp_fanin fmt fanin = ...@@ -48,7 +48,8 @@ let pp_fanin fmt fanin =
Hashtbl.iter (fun s t -> Format.fprintf fmt "@ %s -> %d" s t) fanin; Hashtbl.iter (fun s t -> Format.fprintf fmt "@ %s -> %d" s t) fanin;
Format.fprintf fmt "@]@ }@]" Format.fprintf fmt "@]@ }@]"
(* computes the cone of influence of a given [var] wrt a dependency graph [g]. *) (* computes the cone of influence of a given [var] wrt a dependency graph
[g]. *)
let cone_of_influence g var = let cone_of_influence g var =
(*Format.printf "DEBUG coi: %s@." var;*) (*Format.printf "DEBUG coi: %s@." var;*)
let frontier = ref (ISet.add var ISet.empty) in let frontier = ref (ISet.add var ISet.empty) in
......
...@@ -62,8 +62,7 @@ let rec check_expr expr = ...@@ -62,8 +62,7 @@ let rec check_expr expr =
i); i);
check_expr e' && reset_opt && stateless_node check_expr e' && reset_opt && stateless_node
and check_eexpr e = and check_eexpr e = check_expr e.eexpr_qfexpr
check_expr e.eexpr_qfexpr
and compute_node nd = and compute_node nd =
(* returns true iff the node is stateless.*) (* returns true iff the node is stateless.*)
...@@ -76,18 +75,14 @@ and compute_contract nd = ...@@ -76,18 +75,14 @@ and compute_contract nd =
let c = node_as_contract nd in let c = node_as_contract nd in
let eqs, aut = get_contract_eqs c in let eqs, aut = get_contract_eqs c in
aut = [] aut = []
&& (* A node containinig an automaton will be stateful *) (* A node containinig an automaton will be stateful *)
List.for_all (fun eq -> check_expr eq.eq_rhs) eqs && List.for_all (fun eq -> check_expr eq.eq_rhs) eqs
&& && List.for_all check_eexpr c.assume
List.for_all check_eexpr c.assume && List.for_all check_eexpr c.guarantees
&&
List.for_all check_eexpr c.guarantees
and compute_node_or_contract nd = and compute_node_or_contract nd =
match nd.node_spec, nd.node_iscontract with match nd.node_spec, nd.node_iscontract with
| None, false | None, false | Some (NodeSpec _), false | Some (Contract _), false ->
| Some (NodeSpec _), false
| Some (Contract _), false ->
compute_node nd compute_node nd
| Some (Contract _), true -> | Some (Contract _), true ->
compute_contract nd compute_contract nd
...@@ -96,23 +91,22 @@ and compute_node_or_contract nd = ...@@ -96,23 +91,22 @@ and compute_node_or_contract nd =
and check_node td = and check_node td =
match td.top_decl_desc with match td.top_decl_desc with
| Node nd -> | Node nd -> (
begin match nd.node_stateless with match nd.node_stateless with
| None -> | None ->
let stateless = compute_node_or_contract nd in let stateless = compute_node_or_contract nd in
nd.node_stateless <- Some stateless; nd.node_stateless <- Some stateless;
if stateless if stateless then (
then (if not nd.node_dec_stateless if not nd.node_dec_stateless then
then Log.report ~level:2 (fun fmt -> Log.report ~level:2 (fun fmt ->
Format.fprintf fmt "%s: node -> function@;" nd.node_id)) Format.fprintf fmt "%s: node -> function@;" nd.node_id))
else if nd.node_dec_stateless else if nd.node_dec_stateless then
then raise (Error (td.top_decl_loc, Stateful_kwd nd.node_id)); raise (Error (td.top_decl_loc, Stateful_kwd nd.node_id));
nd.node_dec_stateless <- stateless; nd.node_dec_stateless <- stateless;
stateless stateless
| Some stl -> | Some stl ->
stl stl)
end | ImportedNode nd ->
| ImportedNode nd ->
if nd.nodei_prototype = Some "C" && not nd.nodei_stateless then if nd.nodei_prototype = Some "C" && not nd.nodei_stateless then
raise (Error (td.top_decl_loc, Stateful_ext_C nd.nodei_id)); raise (Error (td.top_decl_loc, Stateful_ext_C nd.nodei_id));
nd.nodei_stateless nd.nodei_stateless
......
...@@ -38,7 +38,8 @@ and carrier_expr = { ...@@ -38,7 +38,8 @@ and carrier_expr = {
type t = { mutable cdesc : clock_desc; mutable cscoped : bool; cid : int } type t = { mutable cdesc : clock_desc; mutable cscoped : bool; cid : int }
(* pck stands for periodic clock. Easier not to separate pck from other clocks *) (* pck stands for periodic clock. Easier not to separate pck from other
clocks *)
and clock_desc = and clock_desc =
| Carrow of t * t | Carrow of t * t
| Ctuple of t list | Ctuple of t list
...@@ -205,8 +206,10 @@ let split_arrow ck = ...@@ -205,8 +206,10 @@ let split_arrow ck =
(** Returns the clock corresponding to a clock list. *) (** Returns the clock corresponding to a clock list. *)
let clock_of_clock_list = function let clock_of_clock_list = function
| [ck] -> ck | [ ck ] ->
| ckl -> new_ck (Ctuple ckl) true ck
| ckl ->
new_ck (Ctuple ckl) true
let clock_list_of_clock ck = let clock_list_of_clock ck =
match (repr ck).cdesc with Ctuple cl -> cl | _ -> [ ck ] match (repr ck).cdesc with Ctuple cl -> cl | _ -> [ ck ]
......
...@@ -17,7 +17,8 @@ and carrier_expr = { ...@@ -17,7 +17,8 @@ and carrier_expr = {
type t = { mutable cdesc : clock_desc; mutable cscoped : bool; cid : int } type t = { mutable cdesc : clock_desc; mutable cscoped : bool; cid : int }
(* pck stands for periodic clock. Easier not to separate pck from other clocks *) (* pck stands for periodic clock. Easier not to separate pck from other
clocks *)
and clock_desc = and clock_desc =
| Carrow of t * t | Carrow of t * t
| Ctuple of t list | Ctuple of t list
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment