From 1eda3e78291f3a5b2f530ae6966e15efad297c39 Mon Sep 17 00:00:00 2001 From: xthirioux <xthirioux@041b043f-8d7c-46b2-b46e-ef0dd855326e> Date: Tue, 9 Sep 2014 16:03:36 +0000 Subject: [PATCH] - work in progress for automata... --- src/access.ml | 2 +- src/automata.ml | 91 ++++++++++++------------------ src/backends/C/c_backend_common.ml | 17 +++++- src/backends/C/c_backend_header.ml | 5 +- src/causality.ml | 20 ++++--- src/clock_calculus.ml | 2 +- src/corelang.ml | 35 +++++++++--- src/corelang.mli | 3 +- src/inliner.ml | 41 +++++++------- src/lustreSpec.ml | 16 +++--- src/machine_code.ml | 6 +- src/normalization.ml | 4 +- src/optimize_prog.ml | 4 +- src/parser_lustre.mly | 18 +++--- src/printers.ml | 45 ++++++++++++++- src/stateless.ml | 2 +- src/typing.ml | 2 +- 17 files changed, 189 insertions(+), 124 deletions(-) diff --git a/src/access.ml b/src/access.ml index 3efc7cae..0797d42e 100755 --- a/src/access.ml +++ b/src/access.ml @@ -80,7 +80,7 @@ let check_node nd = let checks = List.fold_left check_var_decl checks (get_node_vars nd) in let checks = - List.fold_left (fun checks eq -> check_expr checks eq.eq_rhs) checks nd.node_eqs in + List.fold_left (fun checks eq -> check_expr checks eq.eq_rhs) checks (get_node_eqs nd) in nd.node_checks <- CSet.elements checks let check_top_decl decl = diff --git a/src/automata.ml b/src/automata.ml index d587eede..3f1fedb0 100755 --- a/src/automata.ml +++ b/src/automata.ml @@ -13,40 +13,6 @@ open Utils open LustreSpec open Corelang -let pp_restart fmt restart = - Format.fprintf fmt "%s" (if restart then "restart" else "resume") - -let pp_unless fmt (_, expr, restart, st) = - Format.fprintf fmt "unless %a %a %s" - Printers.pp_expr expr - pp_restart restart - st - -let pp_until fmt (_, expr, restart, st) = - Format.fprintf fmt "until %a %a %s" - Printers.pp_expr expr - pp_restart restart - st - -let pp_handler fmt handler = - Format.fprintf fmt "state %s -> %a %a let %a tel %a" - handler.hand_state - (Utils.fprintf_list ~sep:"@ " pp_unless) handler.hand_unless - (fun fmt locals -> - match locals with [] -> () | _ -> - Format.fprintf fmt "@[<v 4>var %a@]@ " - (Utils.fprintf_list ~sep:"@ " - (fun fmt v -> Format.fprintf fmt "%a;" Printers.pp_node_var v)) - locals) - handler.hand_locals - Printers.pp_node_eqs handler.hand_eqs - (Utils.fprintf_list ~sep:"@ " pp_until) handler.hand_until - -let pp_automata fmt aut = - Format.fprintf fmt "automaton %s %a" - aut.aut_id - (Utils.fprintf_list ~sep:"@ " pp_handler) aut.aut_handlers - let mkbool loc b = mkexpr loc (Expr_const (const_of_bool b)) @@ -62,12 +28,12 @@ let init loc restart state = let add_branch (loc, expr, restart, st) cont = mkexpr loc (Expr_ite (expr, mkexpr loc (Expr_tuple [mkbool loc restart; mkident loc st]), cont)) -let mkhandler loc st unless until locals (eqs, asserts, annots) = +let mkhandler loc st unless until locals (stmts, asserts, annots) = {hand_state = st; hand_unless = unless; hand_until = until; hand_locals = locals; - hand_eqs = eqs; + hand_stmts = stmts; hand_asserts = asserts; hand_annots = annots; hand_loc = loc} @@ -77,27 +43,38 @@ let mkautomata loc id handlers = aut_handlers = handlers; aut_loc = loc} -let handler_read handler = - List.fold_left (fun read eq -> get_expr_vars read eq.eq_rhs) ISet.empty handler.hand_eqs - -let handler_write handler = - List.fold_left (fun write eq -> List.fold_left (fun write v -> ISet.add v write) write eq.eq_lhs) ISet.empty handler.hand_eqs +let rec handler_read reads handler = + let locals = List.fold_left (fun locals v -> ISet.add v.var_id locals) ISet.empty handler.hand_locals in + let allvars = + List.fold_left (fun read stmt -> + match stmt with + | Eq eq -> get_expr_vars read eq.eq_rhs + | Aut aut -> List.fold_left handler_read read aut.aut_handlers ) reads handler.hand_stmts + in ISet.diff allvars locals + +let rec handler_write writes handler = + let locals = List.fold_left (fun locals v -> ISet.add v.var_id locals) ISet.empty handler.hand_locals in + let allvars = + List.fold_left (fun write stmt -> + match stmt with + | Eq eq -> List.fold_left (fun write v -> ISet.add v write) write eq.eq_lhs + | Aut aut -> List.fold_left handler_write write aut.aut_handlers) writes handler.hand_stmts + in ISet.diff allvars locals let node_of_handler node aut_id handler = - let locals = List.fold_left (fun locals v -> ISet.add v.var_id locals) ISet.empty handler.hand_locals in - let inputs = handler_read handler in - let outputs = handler_write handler in + let inputs = handler_read ISet.empty handler in + let outputs = handler_write ISet.empty handler in { node_id = Format.sprintf "%s_%s_handler" aut_id handler.hand_state; node_type = Types.new_var (); node_clock = Clocks.new_var true; - node_inputs = List.map (fun v -> get_node_var v node) (ISet.elements (ISet.diff inputs locals)); - node_outputs = List.map (fun v -> get_node_var v node) (ISet.elements (ISet.diff outputs locals)); + node_inputs = List.map (fun v -> get_node_var v node) (ISet.elements inputs); + node_outputs = List.map (fun v -> get_node_var v node) (ISet.elements outputs); node_locals = handler.hand_locals; node_gencalls = []; node_checks = []; node_asserts = handler.hand_asserts; - node_eqs = handler.hand_eqs; + node_stmts = handler.hand_stmts; node_dec_stateless = false; node_stateless = None; node_spec = None; @@ -111,7 +88,7 @@ let expr_of_handler loc restart state node tag = let arg = mkexpr loc (Expr_tuple (List.map (fun v -> mkident loc v.var_id) node.node_inputs)) in mkexpr loc (Expr_when (mkexpr loc (Expr_appl (node.node_id, arg, Some (restart, tag_true))), state, tag)) -let assign_aut_handlers loc node actual_r actual_s hnodes = +let assign_aut_handlers loc actual_r actual_s hnodes = let outputs = (snd (List.hd hnodes)).node_outputs in let assign_handlers = List.map (fun (hs, n) -> (hs, expr_of_handler loc actual_r actual_s n hs)) hnodes in let assign_expr = mkexpr loc (Expr_merge (actual_s, assign_handlers)) in @@ -123,6 +100,12 @@ let typedef_of_automata node aut = { tydef_id = tname; tydef_desc = Tydec_enum (List.map (fun h -> h.hand_state) aut.aut_handlers) } +(* +let expand_automata_stmt (top_decls, locals, eqs) stmt = + match stmt with + | Eq eq -> (top_decls, locals, eq::eqs) + | Aut aut -> + let expand_automata top_node aut = let node = node_of_top top_node in @@ -141,7 +124,7 @@ let expand_automata top_node aut = let fby_until_expr = mkfby aut.aut_loc (init aut.aut_loc tag_false initial) until_expr in let until_eq = mkeq aut.aut_loc ([incoming_r; incoming_s], fby_until_expr) in let hnodes = List.map (fun h -> (h.hand_state, node_of_handler node aut.aut_id h)) aut.aut_handlers in - let assign_eq = assign_aut_handlers aut.aut_loc node actual_r actual_s hnodes in + let assign_eq = assign_aut_handlers aut.aut_loc actual_r actual_s hnodes in let tydec_bool = { ty_dec_desc = Tydec_bool; ty_dec_loc = aut.aut_loc } in let tydec_const id = { ty_dec_desc = Tydec_const id; ty_dec_loc = aut.aut_loc } in let ckdec_any = { ck_dec_desc = Ckdec_any; ck_dec_loc = aut.aut_loc } in @@ -149,15 +132,15 @@ let expand_automata top_node aut = mkvar_decl aut.aut_loc (actual_r , tydec_bool, ckdec_any, false); mkvar_decl aut.aut_loc (incoming_s, tydec_const typedef.tydef_id, ckdec_any, false); mkvar_decl aut.aut_loc (actual_s , tydec_const typedef.tydef_id, ckdec_any, false)] in - let eqs' = [unless_eq; assign_eq; until_eq] in - let node' = { node with node_locals = locals'@node.node_locals; node_eqs = eqs'@node.node_eqs } in + let eqs' = [Eq unless_eq; Eq assign_eq; Eq until_eq] in + let node' = { node with node_locals = locals'@node.node_locals; node_stmts = eqs'@node.node_stmts } in (mktop_decl aut.aut_loc owner false (TypeDef typedef)) :: { top_node with top_decl_desc = Node node' } :: (List.map2 (fun h (hs, n) -> mktop_decl h.hand_loc owner false (Node n)) aut.aut_handlers hnodes) - -let node_extract_automata top_decl = +*) +let rec node_extract_automata top_decl = match top_decl.top_decl_desc with - | Node nd -> [top_decl] + | Node nd -> [] | _ -> [top_decl] (* let extract_automata top_decls = diff --git a/src/backends/C/c_backend_common.ml b/src/backends/C/c_backend_common.ml index cced6a98..f6d17695 100644 --- a/src/backends/C/c_backend_common.ml +++ b/src/backends/C/c_backend_common.ml @@ -24,15 +24,26 @@ let print_version fmt = (* Generation of a non-clashing name for the self memory variable (for step and reset functions) *) let mk_self m = - mk_new_name (m.mstep.step_inputs@m.mstep.step_outputs@m.mstep.step_locals@m.mmemory) "self" + let used name = + (List.exists (fun v -> v.var_id = name) m.mstep.step_inputs) + || (List.exists (fun v -> v.var_id = name) m.mstep.step_outputs) + || (List.exists (fun v -> v.var_id = name) m.mstep.step_locals) + || (List.exists (fun v -> v.var_id = name) m.mmemory) in + mk_new_name used "self" (* Generation of a non-clashing name for the instance variable of static allocation macro *) let mk_instance m = - mk_new_name (m.mstep.step_inputs@m.mmemory) "inst" + let used name = + (List.exists (fun v -> v.var_id = name) m.mstep.step_inputs) + || (List.exists (fun v -> v.var_id = name) m.mmemory) in + mk_new_name used "inst" (* Generation of a non-clashing name for the attribute variable of static allocation macro *) let mk_attribute m = - mk_new_name (m.mstep.step_inputs@m.mmemory) "attr" + let used name = + (List.exists (fun v -> v.var_id = name) m.mstep.step_inputs) + || (List.exists (fun v -> v.var_id = name) m.mmemory) in + mk_new_name used "attr" let mk_call_var_decl loc id = { var_id = id; diff --git a/src/backends/C/c_backend_header.ml b/src/backends/C/c_backend_header.ml index 3a7d50d1..c3d67e6f 100644 --- a/src/backends/C/c_backend_header.ml +++ b/src/backends/C/c_backend_header.ml @@ -172,7 +172,10 @@ let print_machine_decl_from_header fmt inode = else begin let static_inputs = List.filter (fun v -> v.var_dec_const) inode.nodei_inputs in - let self = mk_new_name (inode.nodei_inputs@inode.nodei_outputs) "self" in + let used name = + (List.exists (fun v -> v.var_id = name) inode.nodei_inputs) + || (List.exists (fun v -> v.var_id = name) inode.nodei_outputs) in + let self = mk_new_name used "self" in fprintf fmt "extern %a;@.@." (print_reset_prototype self) (inode.nodei_id, static_inputs); diff --git a/src/causality.ml b/src/causality.ml index 0b69051a..2d09cce4 100644 --- a/src/causality.ml +++ b/src/causality.ml @@ -121,7 +121,7 @@ let eq_memory_variables mems eq = match_mem eq.eq_lhs eq.eq_rhs mems let node_memory_variables nd = - List.fold_left eq_memory_variables ISet.empty nd.node_eqs + List.fold_left eq_memory_variables ISet.empty (get_node_eqs nd) let node_input_variables nd = List.fold_left (fun inputs v -> ISet.add v.var_id inputs) ISet.empty nd.node_inputs @@ -149,7 +149,7 @@ let node_eq_equiv nd = let first = List.hd eq.eq_lhs in List.iter (fun v -> Hashtbl.add eq_equiv v first) eq.eq_lhs ) - nd.node_eqs; + (get_node_eqs nd); eq_equiv (* Create a tuple of right dimension, according to [expr] type, *) @@ -255,7 +255,7 @@ let dependence_graph mems inputs node_vars n = instance_var_cpt := 0; let g = new_graph (), new_graph () in (* Basic dependencies *) - let g = List.fold_right (add_eq_dependencies mems inputs node_vars) n.node_eqs g in + let g = List.fold_right (add_eq_dependencies mems inputs node_vars) (get_node_eqs n) g in g end @@ -312,7 +312,7 @@ module NodeDep = struct | Node nd -> (*Format.eprintf "Computing deps of node %s@.@?" nd.node_id; *) let accu = add_vertices [nd.node_id] accu in - let deps = List.map (fun e -> fst (desome (get_callee e))) (get_calls (fun _ -> true) nd.node_eqs) in + let deps = List.map (fun e -> fst (desome (get_callee e))) (get_calls (fun _ -> true) (get_node_eqs nd)) in (*Format.eprintf "%a@.@?" (Utils.fprintf_list ~sep:"@." Format.pp_print_string) deps; *) add_edges [nd.node_id] deps accu | _ -> assert false (* should not happen *) @@ -332,7 +332,7 @@ module NodeDep = struct match td.top_decl_desc with | Node nd -> let prednode n = is_generic_node (Hashtbl.find node_table n) in - nd.node_gencalls <- get_calls prednode nd.node_eqs + nd.node_gencalls <- get_calls prednode (get_node_eqs nd) | _ -> () ) prog @@ -345,7 +345,11 @@ module CycleDetection = struct module Cycles = Graph.Components.Make (IdentDepGraph) let mk_copy_var n id = - mk_new_name (get_node_vars n) id + let used name = + (List.exists (fun v -> v.var_id = name) n.node_locals) + || (List.exists (fun v -> v.var_id = name) n.node_inputs) + || (List.exists (fun v -> v.var_id = name) n.node_outputs) + in mk_new_name used id let mk_copy_eq n var = let var_decl = get_node_var var n in @@ -407,7 +411,7 @@ module CycleDetection = struct - a modified acyclic version of [g] *) let break_cycles node mems g = - let (mem_eqs, non_mem_eqs) = List.partition (fun eq -> List.exists (fun v -> ISet.mem v mems) eq.eq_lhs) node.node_eqs in + let (mem_eqs, non_mem_eqs) = List.partition (fun eq -> List.exists (fun v -> ISet.mem v mems) eq.eq_lhs) (get_node_eqs node) in let rec break vdecls mem_eqs g = let scc_l = Cycles.scc_list g in let wrong = List.filter (wrong_partition g) scc_l in @@ -553,7 +557,7 @@ let global_dependency node = begin merge_with g_non_mems g_mems'; add_external_dependency outputs mems g_non_mems; - { node with node_eqs = eqs'; node_locals = vdecls'@node.node_locals }, + { node with node_stmts = List.map (fun eq -> Eq eq) eqs'; node_locals = vdecls'@node.node_locals }, g_non_mems end diff --git a/src/clock_calculus.ml b/src/clock_calculus.ml index 42556941..a1bccd1e 100755 --- a/src/clock_calculus.ml +++ b/src/clock_calculus.ml @@ -771,7 +771,7 @@ let clock_node env loc nd = let new_env = clock_var_decl_list env false nd.node_inputs in let new_env = clock_var_decl_list new_env true nd.node_outputs in let new_env = clock_var_decl_list new_env true nd.node_locals in - List.iter (clock_eq new_env) nd.node_eqs; + List.iter (clock_eq new_env) (get_node_eqs nd); let ck_ins = clock_of_vlist nd.node_inputs in let ck_outs = clock_of_vlist nd.node_outputs in let ck_node = new_ck (Carrow (ck_ins,ck_outs)) false in diff --git a/src/corelang.ml b/src/corelang.ml index 173f33d2..8b794c25 100755 --- a/src/corelang.ml +++ b/src/corelang.ml @@ -68,9 +68,9 @@ let var_decl_of_const c = var_clock = Clocks.new_var false; var_loc = c.const_loc } -let mk_new_name vdecl_list id = +let mk_new_name used id = let rec new_name name cpt = - if List.exists (fun v -> v.var_id = name) vdecl_list + if used name then new_name (sprintf "_%s_%i" id cpt) (cpt+1) else name in new_name id 1 @@ -475,8 +475,29 @@ let get_var id var_list = let get_node_var id node = get_var id (get_node_vars node) +let get_node_eqs = + let get_eqs stmts = + List.fold_right + (fun stmt res -> + match stmt with + | Eq eq -> eq :: res + | Aut _ -> assert false) + stmts + [] in + let table_eqs = Hashtbl.create 23 in + (fun nd -> + try + let (old, res) = Hashtbl.find table_eqs nd.node_id + in if old == nd.node_stmts then res else raise Not_found + with Not_found -> + let res = get_eqs nd.node_stmts in + begin + Hashtbl.replace table_eqs nd.node_id (nd.node_stmts, res); + res + end) + let get_node_eq id node = - List.find (fun eq -> List.mem id eq.eq_lhs) node.node_eqs + List.find (fun eq -> List.mem id eq.eq_lhs) (get_node_eqs node) let get_nodes prog = List.fold_left ( @@ -639,7 +660,7 @@ let rename_node f_node f_var f_const nd = rename_expr f_node f_var f_const expr}) nd.node_asserts in - let eqs = List.map rename_eq nd.node_eqs in + let node_stmts = List.map (fun eq -> Eq (rename_eq eq)) (get_node_eqs nd) in let spec = Utils.option_map (fun s -> rename_node_annot f_node f_var f_const s) @@ -660,7 +681,7 @@ let rename_node f_node f_var f_const nd = node_gencalls = gen_calls; node_checks = node_checks; node_asserts = node_asserts; - node_eqs = eqs; + node_stmts = node_stmts; node_dec_stateless = nd.node_dec_stateless; node_stateless = nd.node_stateless; node_spec = spec; @@ -889,7 +910,7 @@ and get_calls_expr_desc nodes expr_desc = and get_eq_calls nodes eq = get_expr_calls nodes eq.eq_rhs and get_node_calls nodes node = - List.fold_left (fun accu eq -> Utils.ISet.union (get_eq_calls nodes eq) accu) Utils.ISet.empty node.node_eqs + List.fold_left (fun accu eq -> Utils.ISet.union (get_eq_calls nodes eq) accu) Utils.ISet.empty (get_node_eqs node) let rec get_expr_vars vars e = get_expr_desc_vars vars e.expr_desc @@ -932,7 +953,7 @@ and expr_desc_has_arrows expr_desc = and eq_has_arrows eq = expr_has_arrows eq.eq_rhs and node_has_arrows node = - List.exists (fun eq -> eq_has_arrows eq) node.node_eqs + List.exists (fun eq -> eq_has_arrows eq) (get_node_eqs node) (* Local Variables: *) (* compile-command:"make -C .." *) diff --git a/src/corelang.mli b/src/corelang.mli index 119accfd..d7f17031 100755 --- a/src/corelang.mli +++ b/src/corelang.mli @@ -26,7 +26,7 @@ val mkeq: Location.t -> ident list * expr -> eq val mkassert: Location.t -> expr -> assert_t val mktop_decl: Location.t -> ident -> bool -> top_decl_desc -> top_decl val mkpredef_call: Location.t -> ident -> expr list -> expr -val mk_new_name: var_decl list -> ident -> ident +val mk_new_name: (ident -> bool) -> ident -> ident val node_table : (ident, top_decl) Hashtbl.t @@ -65,6 +65,7 @@ val const_impl: constant -> constant -> constant val get_node_vars: node_desc -> var_decl list val get_node_var: ident -> node_desc -> var_decl +val get_node_eqs: node_desc -> eq list val get_node_eq: ident -> node_desc -> eq val get_node_interface: node_desc -> imported_node_desc diff --git a/src/inliner.ml b/src/inliner.ml index 39912ded..f948549e 100644 --- a/src/inliner.ml +++ b/src/inliner.ml @@ -46,7 +46,7 @@ let inline_call orig_expr args reset locals node = node.node_id uid v; Format.flush_str_formatter ()) in - let eqs' = List.map (rename_eq rename) node.node_eqs + let eqs' = List.map (rename_eq rename) (get_node_eqs node) in let rename_var v = { v with var_id = rename v.var_id } in let inputs' = List.map rename_var node.node_inputs in @@ -171,11 +171,11 @@ and inline_node nd nodes = inline_expr eq.eq_rhs locals nodes in locals', { eq with eq_rhs = eq_rhs' }::new_eqs'@eqs, asserts'@asserts - ) (nd.node_locals, [], nd.node_asserts) nd.node_eqs + ) (nd.node_locals, [], nd.node_asserts) (get_node_eqs nd) in { nd with node_locals = new_locals; - node_eqs = eqs; + node_stmts = List.map (fun eq -> Eq eq) eqs; node_asserts = asserts; } @@ -241,6 +241,23 @@ let witness filename main_name orig inlined type_env clock_env = (* Building main node *) + let ok_i_eq = + { eq_loc = loc; + eq_lhs = List.map (fun v -> v.var_id) ok_i; + eq_rhs = + let inputs = expr_of_expr_list loc (List.map (fun v -> mkexpr loc (Expr_ident v.var_id)) main_orig_node.node_inputs) in + let call_orig = + mkexpr loc (Expr_appl ("orig_" ^ main_name, inputs, None)) in + let call_inlined = + mkexpr loc (Expr_appl ("inlined_" ^ main_name, inputs, None)) in + let args = mkexpr loc (Expr_tuple [call_orig; call_inlined]) in + mkexpr loc (Expr_appl ("=", args, None)) + } in + let ok_eq = + { eq_loc = loc; + eq_lhs = [ok_ident]; + eq_rhs = main_ok_expr; + } in let main_node = { node_id = "check"; node_type = Types.new_var (); @@ -251,23 +268,7 @@ let witness filename main_name orig inlined type_env clock_env = node_gencalls = []; node_checks = []; node_asserts = []; - node_eqs = [ - { eq_loc = loc; - eq_lhs = List.map (fun v -> v.var_id) ok_i; - eq_rhs = - let inputs = expr_of_expr_list loc (List.map (fun v -> mkexpr loc (Expr_ident v.var_id)) main_orig_node.node_inputs) in - let call_orig = - mkexpr loc (Expr_appl ("orig_" ^ main_name, inputs, None)) in - let call_inlined = - mkexpr loc (Expr_appl ("inlined_" ^ main_name, inputs, None)) in - let args = mkexpr loc (Expr_tuple [call_orig; call_inlined]) in - mkexpr loc (Expr_appl ("=", args, None)) - }; - { eq_loc = loc; - eq_lhs = [ok_ident]; - eq_rhs = main_ok_expr; - } - ]; + node_stmts = [Eq ok_i_eq; Eq ok_eq]; node_dec_stateless = false; node_stateless = None; node_spec = Some diff --git a/src/lustreSpec.ml b/src/lustreSpec.ml index d9f3845f..b981156a 100644 --- a/src/lustreSpec.ml +++ b/src/lustreSpec.ml @@ -135,9 +135,13 @@ type assert_t = { assert_expr: expr; assert_loc: Location.t; - } + } + +type statement = +| Eq of eq +| Aut of automata_desc -type automata_desc = +and automata_desc = {aut_id : ident; aut_handlers: handler_desc list; aut_loc: Location.t} @@ -147,15 +151,11 @@ and handler_desc = hand_unless: (Location.t * expr * bool * ident) list; hand_until: (Location.t * expr * bool * ident) list; hand_locals: var_decl list; - hand_eqs: eq list; + hand_stmts: statement list; hand_asserts: assert_t list; hand_annots: expr_annot list; hand_loc: Location.t} -type statement = -| Eq of eq -| Aut of automata_desc - type node_desc = {node_id: ident; mutable node_type: Types.type_expr; @@ -166,7 +166,7 @@ type node_desc = mutable node_gencalls: expr list; mutable node_checks: Dimension.dim_expr list; node_asserts: assert_t list; - node_eqs: eq list; + node_stmts: statement list; mutable node_dec_stateless: bool; mutable node_stateless: bool option; node_spec: node_annot option; diff --git a/src/machine_code.ml b/src/machine_code.ml index 715dfc71..b5aaa764 100644 --- a/src/machine_code.ml +++ b/src/machine_code.ml @@ -156,7 +156,7 @@ let arrow_desc = node_gencalls = []; node_checks = []; node_asserts = []; - node_eqs= []; + node_stmts= []; node_dec_stateless = false; node_stateless = Some false; node_spec = None; @@ -428,7 +428,7 @@ let sort_equations_from_schedule nd sch = (* Format.eprintf "%s schedule: %a@." nd.node_id (Utils.fprintf_list ~sep:" ; " Scheduling.pp_eq_schedule) sch;*) - let split_eqs = Splitting.tuple_split_eq_list nd.node_eqs in + let split_eqs = Splitting.tuple_split_eq_list (get_node_eqs nd) in let eqs_rev, remainder = List.fold_left (fun (accu, node_eqs_remainder) vl -> @@ -446,7 +446,7 @@ let sort_equations_from_schedule nd sch = if List.length remainder > 0 then ( Format.eprintf "Equations not used are@.%a@.Full equation set is:@.%a@.@?" Printers.pp_node_eqs remainder - Printers.pp_node_eqs nd.node_eqs; + Printers.pp_node_eqs (get_node_eqs nd); assert false); List.rev eqs_rev end diff --git a/src/normalization.ml b/src/normalization.ml index 5aafac4d..1272f1da 100644 --- a/src/normalization.ml +++ b/src/normalization.ml @@ -349,7 +349,7 @@ let normalize_node node = List.for_all ((!=) v) inputs_outputs in let orig_vars = inputs_outputs@node.node_locals in let defs, vars = - List.fold_left (normalize_eq node) ([], orig_vars) node.node_eqs in + List.fold_left (normalize_eq node) ([], orig_vars) (get_node_eqs node) in (* Normalize the asserts *) let vars, assert_defs, asserts = List.fold_left ( @@ -391,7 +391,7 @@ let normalize_node node = let node = { node with node_locals = new_locals; - node_eqs = defs @ assert_defs; + node_stmts = List.map (fun eq -> Eq eq) (defs @ assert_defs); node_asserts = asserts; node_annot = norm_traceability::node.node_annot; } diff --git a/src/optimize_prog.ml b/src/optimize_prog.ml index 3ee97710..2214aa0f 100644 --- a/src/optimize_prog.ml +++ b/src/optimize_prog.ml @@ -46,7 +46,7 @@ let eq_unfold_consts consts eq = { eq with eq_rhs = expr_unfold_consts consts eq.eq_rhs } let node_unfold_consts consts node = - { node with node_eqs = List.map (eq_unfold_consts consts) node.node_eqs } + { node with node_stmts = List.map (fun eq -> Eq (eq_unfold_consts consts eq)) (get_node_eqs node) } let prog_unfold_consts prog = let consts = List.map const_of_top (get_consts prog) in @@ -89,7 +89,7 @@ let eq_distribute_when eq = { eq with eq_rhs = expr_distribute_when eq.eq_rhs } let node_distribute_when node = - { node with node_eqs = List.map eq_distribute_when node.node_eqs } + { node with node_stmts = List.map (fun eq -> Eq (eq_distribute_when eq)) (get_node_eqs node) } let prog_distribute_when prog = List.map ( diff --git a/src/parser_lustre.mly b/src/parser_lustre.mly index 2d79df3f..5644c382 100755 --- a/src/parser_lustre.mly +++ b/src/parser_lustre.mly @@ -188,8 +188,8 @@ in_lib_opt: top_decl: | CONST cdecl_list { List.rev ($2 false) } -| nodespec_list state_annot node_ident LPAR vdecl_list SCOL_opt RPAR RETURNS LPAR vdecl_list SCOL_opt RPAR SCOL_opt locals LET eq_list TEL - {let eqs, asserts, annots = $16 in +| nodespec_list state_annot node_ident LPAR vdecl_list SCOL_opt RPAR RETURNS LPAR vdecl_list SCOL_opt RPAR SCOL_opt locals LET stmt_list TEL + {let stmts, asserts, annots = $16 in let nd = mktop_decl false (Node {node_id = $3; node_type = Types.new_var (); @@ -200,7 +200,7 @@ top_decl: node_gencalls = []; node_checks = []; node_asserts = asserts; - node_eqs = eqs; + node_stmts = stmts; node_dec_stateless = $2; node_stateless = None; node_spec = $1; @@ -251,12 +251,12 @@ tag_list: field_list: { [] } | field_list IDENT COL typeconst SCOL { ($2, $4) :: $1 } -eq_list: +stmt_list: { [], [], [] } -| eq eq_list {let eql, assertl, annotl = $2 in ($1::eql), assertl, annotl} -| assert_ eq_list {let eql, assertl, annotl = $2 in eql, ($1::assertl), annotl} -| ANNOT eq_list {let eql, assertl, annotl = $2 in eql, assertl, $1::annotl} -| automaton eq_list {let eql, assertl, annotl = $2 in ($1::eql), assertl, annotl} +| eq stmt_list {let eql, assertl, annotl = $2 in ((Eq $1)::eql), assertl, annotl} +| assert_ stmt_list {let eql, assertl, annotl = $2 in eql, ($1::assertl), annotl} +| ANNOT stmt_list {let eql, assertl, annotl = $2 in eql, assertl, $1::annotl} +| automaton stmt_list {let eql, assertl, annotl = $2 in ((Aut $1)::eql), assertl, annotl} automaton: AUTOMATON type_ident handler_list { (Automata.mkautomata (get_loc ()) $2 $3); failwith "not implemented" } @@ -266,7 +266,7 @@ handler_list: | handler handler_list { $1::$2 } handler: - STATE UIDENT ARROW unless_list locals LET eq_list TEL until_list { Automata.mkhandler (get_loc ()) $2 $4 $9 $5 $7 } + STATE UIDENT ARROW unless_list locals LET stmt_list TEL until_list { Automata.mkhandler (get_loc ()) $2 $4 $9 $5 $7 } unless_list: { [] } diff --git a/src/printers.ml b/src/printers.ml index 7ea7105f..a26713e7 100644 --- a/src/printers.ml +++ b/src/printers.ml @@ -131,7 +131,48 @@ let pp_node_eq fmt eq = pp_eq_lhs eq.eq_lhs pp_expr eq.eq_rhs -let pp_node_eqs = fprintf_list ~sep:"@ " pp_node_eq +let pp_restart fmt restart = + Format.fprintf fmt "%s" (if restart then "restart" else "resume") + +let pp_unless fmt (_, expr, restart, st) = + Format.fprintf fmt "unless %a %a %s" + pp_expr expr + pp_restart restart + st + +let pp_until fmt (_, expr, restart, st) = + Format.fprintf fmt "until %a %a %s" + pp_expr expr + pp_restart restart + st + +let rec pp_handler fmt handler = + Format.fprintf fmt "state %s -> %a %a let %a tel %a" + handler.hand_state + (Utils.fprintf_list ~sep:"@ " pp_unless) handler.hand_unless + (fun fmt locals -> + match locals with [] -> () | _ -> + Format.fprintf fmt "@[<v 4>var %a@]@ " + (Utils.fprintf_list ~sep:"@ " + (fun fmt v -> Format.fprintf fmt "%a;" pp_node_var v)) + locals) + handler.hand_locals + pp_node_stmts handler.hand_stmts + (Utils.fprintf_list ~sep:"@ " pp_until) handler.hand_until + +and pp_node_stmt fmt stmt = + match stmt with + | Eq eq -> pp_node_eq fmt eq + | Aut aut -> pp_node_aut fmt aut + +and pp_node_stmts fmt stmts = fprintf_list ~sep:"@ " pp_node_stmt fmt stmts + +and pp_node_aut fmt aut = + Format.fprintf fmt "automaton %s %a" + aut.aut_id + (Utils.fprintf_list ~sep:"@ " pp_handler) aut.aut_handlers + +and pp_node_eqs fmt eqs = fprintf_list ~sep:"@ " pp_node_eq fmt eqs let rec pp_var_struct_type_field fmt (label, tdesc) = fprintf fmt "%a : %a;" pp_print_string label pp_var_type_dec_desc tdesc @@ -217,7 +258,7 @@ fprintf fmt "@[<v 0>%a%t%s %s (%a) returns (%a)@.%a%alet@.@[<h 2> @ @[<v>%a@ % checks ) nd.node_checks (fprintf_list ~sep:"@ " pp_expr_annot) nd.node_annot - pp_node_eqs nd.node_eqs + pp_node_stmts nd.node_stmts pp_asserts nd.node_asserts (*fprintf fmt "@ /* Scheduling: %a */ @ " (fprintf_list ~sep:", " pp_print_string) (Scheduling.schedule_node nd)*) diff --git a/src/stateless.ml b/src/stateless.ml index 5fcec93b..3148e032 100755 --- a/src/stateless.ml +++ b/src/stateless.ml @@ -36,7 +36,7 @@ let rec check_expr expr = check_expr e' && (Basic_library.is_internal_fun i || check_node (node_from_name i)) and compute_node nd = - List.for_all (fun eq -> check_expr eq.eq_rhs) nd.node_eqs + List.for_all (fun eq -> check_expr eq.eq_rhs) (get_node_eqs nd) and check_node td = match td.top_decl_desc with | Node nd -> ( diff --git a/src/typing.ml b/src/typing.ml index 718f1d2c..4aaf8fc0 100755 --- a/src/typing.ml +++ b/src/typing.ml @@ -619,7 +619,7 @@ let type_node env nd loc = (fun uvs v -> IMap.add v.var_id () uvs) IMap.empty vd_env_ol in let undefined_vars = - List.fold_left (type_eq (new_env, vd_env) is_main) undefined_vars_init nd.node_eqs + List.fold_left (type_eq (new_env, vd_env) is_main) undefined_vars_init (get_node_eqs nd) in (* Typing asserts *) List.iter (fun assert_ -> -- GitLab