diff options
Diffstat (limited to 'abstract/transform.ml')
-rw-r--r-- | abstract/transform.ml | 229 |
1 files changed, 135 insertions, 94 deletions
diff --git a/abstract/transform.ml b/abstract/transform.ml index b9c173d..4a13e18 100644 --- a/abstract/transform.ml +++ b/abstract/transform.ml @@ -26,8 +26,8 @@ type ne_expr = (* f_of_neexpr : transform_data -> (string, string) -> (ne_expr list -> bool_expr) -> expr -> bool_expr *) -let rec f_of_neexpr td (node, prefix) where expr = - let sub = f_of_neexpr td (node, prefix) in +let rec f_of_neexpr td (node, prefix, clock_scope) where expr = + let sub = f_of_neexpr td (node, prefix, clock_scope) in let le = loc_error (snd expr) in match fst expr with (* ident *) @@ -71,24 +71,27 @@ let rec f_of_neexpr td (node, prefix) where expr = | TEnum _ -> EE(EIdent x)) typ) | AST_arrow(a, b) -> - if td.rp.init_scope (node^"/") + if td.rp.init_scope clock_scope then f_or - (f_and (f_e_eq (EIdent (node^"/"^prefix^"init")) (EItem bool_true)) + (f_and (f_e_eq (EIdent (clock_scope^"init")) (EItem bool_true)) (sub where a)) - (f_and (f_e_eq (EIdent (node^"/"^prefix^"init")) (EItem bool_false)) + (f_and (f_e_eq (EIdent (clock_scope^"init")) (EItem bool_false)) (sub where b)) - else + else if not (td.rp.no_time_scope clock_scope) + then f_or - (f_and (BRel(AST_EQ, NIdent(node^"/"^prefix^"time"), NIntConst 0)) + (f_and (BRel(AST_EQ, NIdent(clock_scope^"time"), NIntConst 0)) (sub where a)) - (f_and (BRel(AST_GE, NIdent(node^"/"^prefix^"time"), NIntConst 1)) + (f_and (BRel(AST_GE, NIdent(clock_scope^"time"), NIntConst 1)) (sub where b)) + else + f_or (sub where a) (sub where b) (* other *) | AST_if(c, a, b) -> f_or - (f_and (f_of_expr td (node, prefix) c) (sub where a)) - (f_and (BNot(f_of_expr td (node, prefix) c)) (sub where b)) + (f_and (f_of_expr td (node, prefix, clock_scope) c) (sub where a)) + (f_and (BNot(f_of_expr td (node, prefix, clock_scope) c)) (sub where b)) | AST_instance ((f, _), args, nid) -> let (n, _) = find_node_decl td.rp.p f in where @@ -107,8 +110,9 @@ let rec f_of_neexpr td (node, prefix) where expr = (* boolean values treated as enumerated types *) | _ when type_expr td.rp node expr = [bool_type] -> f_or - (f_and (f_of_expr td (node, prefix) expr) (where [EE (EItem bool_true)])) - (f_and (f_of_expr td (node, prefix) (AST_not(expr), snd expr)) + (f_and (f_of_expr td (node, prefix, clock_scope) expr) + (where [EE (EItem bool_true)])) + (f_and (f_of_expr td (node, prefix, clock_scope) (AST_not(expr), snd expr)) (where [EE (EItem bool_false)])) | _ -> le type_error "Expected numerical/enumerated value" @@ -120,8 +124,8 @@ let rec f_of_neexpr td (node, prefix) where expr = f_of_bexpr : transform_data -> (string, string) -> (bool_expr -> bool_expr) -> expr -> bool_expr *) -and f_of_bexpr td (node, prefix) where expr = - let sub = f_of_bexpr td (node, prefix) in +and f_of_bexpr td (node, prefix, clock_scope) where expr = + let sub = f_of_bexpr td (node, prefix, clock_scope) in match fst expr with | AST_bool_const b -> where (BConst b) | AST_binary_bool(AST_AND, a, b) -> f_and (sub where a) (sub where b) @@ -129,7 +133,7 @@ and f_of_bexpr td (node, prefix) where expr = | AST_not(a) -> BNot(sub where a) | AST_binary_rel(rel, a, b) -> where - (f_of_neexpr td (node, prefix) + (f_of_neexpr td (node, prefix, clock_scope) (function | [NE x; NE y] -> BRel(rel, x, y) | [EE x; EE y] -> @@ -142,11 +146,22 @@ and f_of_bexpr td (node, prefix) where expr = (AST_tuple [a; b], snd expr)) (* Temporal *) | AST_arrow(a, b) -> + if td.rp.init_scope clock_scope + then f_or - (f_and (BRel(AST_EQ, NIdent(node^"/"^prefix^"time"), NIntConst 0)) + (f_and (f_e_eq (EIdent (clock_scope^"init")) (EItem bool_true)) (sub where a)) - (f_and (BRel(AST_GE, NIdent(node^"/"^prefix^"time"), NIntConst 1)) + (f_and (f_e_eq (EIdent (clock_scope^"init")) (EItem bool_false)) (sub where b)) + else if not (td.rp.no_time_scope clock_scope) + then + f_or + (f_and (BRel(AST_EQ, NIdent(clock_scope^"time"), NIntConst 0)) + (sub where a)) + (f_and (BRel(AST_GE, NIdent(clock_scope^"time"), NIntConst 1)) + (sub where b)) + else + f_or (sub where a) (sub where b) (* Enumerations... *) | _ when type_expr td.rp node expr = [bool_type] -> let ff = function @@ -156,23 +171,53 @@ and f_of_bexpr td (node, prefix) where expr = (f_and (f_e_eq x (EItem bool_false)) (where (BConst false))) | _ -> assert false in - f_of_neexpr td (node, prefix) ff expr + f_of_neexpr td (node, prefix, clock_scope) ff expr | _ -> type_error "Expected boolean value." -and f_of_expr td (node, prefix) expr = - f_of_bexpr td (node, prefix) (fun x -> x) expr +and f_of_expr td (node, prefix, clock_scope) expr = + f_of_bexpr td (node, prefix, clock_scope) (fun x -> x) expr (* Translate program into one big formula *) -let rec f_of_scope active td (node, prefix, eqs) assume_guarantees = + +let clock_scope_here (node, prefix, _) = + node^"/"^prefix + +let gen_clock td (node, prefix, _) active = + let clock_scope = node^"/"^prefix in + let clock_eq = + if active then + f_and + (if not (td.rp.no_time_scope clock_scope) + then BRel(AST_EQ, NIdent("N"^clock_scope^"time"), + NBinary(AST_PLUS, NIntConst 1, NIdent(clock_scope^"time"))) + else BConst true) + (if td.rp.init_scope clock_scope + then f_e_eq (EIdent("N"^clock_scope^"init")) (EItem bool_false) + else BConst true) + else + f_and + (if not (td.rp.no_time_scope clock_scope) + then BRel(AST_EQ, + NIdent("N"^clock_scope^"time"), + NIdent(clock_scope^"time")) + else BConst true) + (if td.rp.init_scope clock_scope + then f_e_eq (EIdent("N"^clock_scope^"init")) + (EIdent (clock_scope^"init")) + else BConst true) + in + clock_scope, clock_eq + +let rec f_of_scope active td (node, prefix, eqs) clock_scope assume_guarantees = let expr_eq e = let instance_eq (_, id, eqs, args) = - let eq = f_of_scope active td (node^"/"^id, "", eqs) assume_guarantees in + let eq = f_of_scope active td (node^"/"^id, "", eqs) clock_scope assume_guarantees in if active then let arg_eq ((_,argname,_), expr) = - f_of_neexpr td (node, prefix) (function + f_of_neexpr td (node, prefix, clock_scope) (function | [NE v] -> BRel(AST_EQ, NIdent(node^"/"^id^"/"^argname), v) | [EE v] -> f_e_eq (EIdent(node^"/"^id^"/"^argname)) v | _ -> invalid_arity "in argument") @@ -186,7 +231,7 @@ let rec f_of_scope active td (node, prefix, eqs) assume_guarantees = let pre_expr (id, expr) = let id = node^"/"^id in if active then - f_of_neexpr td (node, prefix) (fun elist -> + f_of_neexpr td (node, prefix, clock_scope) (fun elist -> list_fold_op f_and (List.mapi (fun i v -> let x = ("N"^id^"."^(string_of_int i)) in @@ -222,7 +267,7 @@ let rec f_of_scope active td (node, prefix, eqs) assume_guarantees = in f_and_list rels in - f_of_neexpr td (node, prefix) apply_f e + f_of_neexpr td (node, prefix, clock_scope) apply_f e else BConst true in @@ -230,7 +275,7 @@ let rec f_of_scope active td (node, prefix, eqs) assume_guarantees = | AST_assume (_, e) -> let assume_eq = if active then - f_of_expr td (node, prefix) e + f_of_expr td (node, prefix, clock_scope) e else BConst true in @@ -239,13 +284,13 @@ let rec f_of_scope active td (node, prefix, eqs) assume_guarantees = let gn = node^"/g_"^id in let guarantee_eq = if active && assume_guarantees then - f_and (f_of_expr td (node, prefix) e) + f_and (f_of_expr td (node, prefix, clock_scope) e) (BEnumCons(E_EQ, gn, EItem bool_true)) else f_or - (f_and (f_of_expr td (node, prefix) e) + (f_and (f_of_expr td (node, prefix, clock_scope) e) (BEnumCons(E_EQ, gn, EItem bool_true))) - (f_and (BNot (f_of_expr td (node, prefix) e)) + (f_and (BNot (f_of_expr td (node, prefix, clock_scope) e)) (BEnumCons(E_EQ, gn, EItem bool_false))) in f_and (expr_eq e) guarantee_eq @@ -258,16 +303,20 @@ let rec f_of_scope active td (node, prefix, eqs) assume_guarantees = in let rec do_tree_act = function | AST_activate_body b -> - f_of_scope true td (node, b.act_id^".", b.body) assume_guarantees + let b_scope = node, b.act_id^".", b.body in + let clock_scope, clock_eq = gen_clock td b_scope true in + f_and clock_eq (f_of_scope true td b_scope clock_scope assume_guarantees) | AST_activate_if(c, a, b) -> f_or - (f_and (f_of_expr td (node, prefix) c) + (f_and (f_of_expr td (node, prefix, clock_scope) c) (f_and (do_tree_act a) (do_tree_inact b))) - (f_and (BNot(f_of_expr td (node, prefix) c)) + (f_and (BNot(f_of_expr td (node, prefix, clock_scope) c)) (f_and (do_tree_act b) (do_tree_inact a))) and do_tree_inact = function | AST_activate_body b -> - f_of_scope false td (node, b.act_id^".", b.body) assume_guarantees + let b_scope = node, b.act_id^".", b.body in + let clock_scope, clock_eq = gen_clock td b_scope false in + f_and clock_eq (f_of_scope false td b_scope clock_scope assume_guarantees) | AST_activate_if(_, a, b) -> f_and (do_tree_inact a) (do_tree_inact b) in @@ -276,24 +325,27 @@ let rec f_of_scope active td (node, prefix, eqs) assume_guarantees = let stv = node^"/"^aid^".state" in let nstv = "N"^node^"/"^aid^".state" in let st_eq_inact (st, _) = - f_and - (f_of_scope false td - (node, aid^"."^st.st_name^".", st.body) assume_guarantees) - (f_and_list (List.map (fun (c, _, _) -> expr_eq c) st.until)) + let st_scope = node, aid^"."^st.st_name^".", st.body in + let clock_scope, clock_eq = gen_clock td st_scope false in + f_and clock_eq + (f_and + (f_of_scope false td st_scope clock_scope assume_guarantees) + (f_and_list (List.map (fun (c, _, _) -> expr_eq c) st.until))) in if active then let st_eq_act (st, l) = let act_eq = - let st_eq = f_of_scope true td - (node, aid^"."^st.st_name^".", st.body) assume_guarantees in + let st_scope = node, aid^"."^st.st_name^".", st.body in + let clock_scope, clock_eq = gen_clock td st_scope true in + let st_eq = f_and clock_eq (f_of_scope true td st_scope clock_scope assume_guarantees) in let rec aux = function | [] -> BEnumCons(E_EQ, nstv, EItem st.st_name) | (c, (target, l), rst)::q -> if rst then loc_error l error "Resetting transitions not supported."; f_or - (f_and (f_of_expr td (node, prefix) c) + (f_and (f_of_expr td (node, prefix, clock_scope) c) (BEnumCons(E_EQ, nstv, EItem target))) - (f_and (BNot (f_of_expr td (node, prefix) c)) (aux q)) + (f_and (BNot (f_of_expr td (node, prefix, clock_scope) c)) (aux q)) in f_and st_eq (aux st.until) in f_or @@ -305,31 +357,7 @@ let rec f_of_scope active td (node, prefix, eqs) assume_guarantees = else f_and_list (List.map st_eq_inact states) in - let time_incr_eq = - if active then - f_and - (if not (td.rp.no_time_scope (node^"/")) - then BRel(AST_EQ, NIdent("N"^node^"/"^prefix^"time"), - NBinary(AST_PLUS, NIntConst 1, NIdent(node^"/"^prefix^"time"))) - else BConst true) - (if td.rp.init_scope (node^"/") - then f_e_eq (EIdent("N"^node^"/"^prefix^"init")) (EItem bool_false) - else BConst true) - else - f_and - (if not (td.rp.no_time_scope (node^"/")) - then BRel(AST_EQ, - NIdent("N"^node^"/"^prefix^"time"), - NIdent(node^"/"^prefix^"time")) - else BConst true) - (if td.rp.init_scope (node^"/") - then f_e_eq (EIdent("N"^node^"/"^prefix^"init")) - (EIdent (node^"/"^prefix^"init")) - else BConst true) - in - List.fold_left f_and - time_incr_eq - (List.map do_eq eqs) + f_and_list (List.map do_eq eqs) and f_of_prog rp assume_guarantees = let td = { @@ -337,15 +365,34 @@ and f_of_prog rp assume_guarantees = consts = I.consts rp; } in - f_of_scope true td td.rp.root_scope assume_guarantees + let clock_scope, clock_eq = gen_clock td rp.root_scope true in + + f_and clock_eq (f_of_scope true td td.rp.root_scope clock_scope assume_guarantees) (* Translate init state into a formula *) -let rec init_f_of_scope rp (node, prefix, eqs) = +let gen_clock_init rp (node, prefix, _) = + let clock_scope = node^"/"^prefix in + let time_eq = + f_and + (if not (rp.no_time_scope clock_scope) + then + BRel(AST_EQ, + NIdent(clock_scope^"time"), + NIntConst 0) + else BConst true) + (if rp.init_scope clock_scope + then + f_e_eq (EIdent(clock_scope^"init")) (EItem bool_true) + else BConst true) + in + clock_scope, time_eq + +let rec init_f_of_scope rp (node, prefix, eqs) clock_scope = let expr_eq e = let instance_eq (_, id, eqs, args) = - init_f_of_scope rp (node^"/"^id, "", eqs) + init_f_of_scope rp (node^"/"^id, "", eqs) clock_scope in List.fold_left (fun x i -> f_and (instance_eq i) x) (BConst true) (extract_instances rp.p e) @@ -356,7 +403,9 @@ let rec init_f_of_scope rp (node, prefix, eqs) = | AST_activate (b, _) -> let rec cond_eq = function | AST_activate_body b -> - init_f_of_scope rp (node, b.act_id^".", b.body) + let bscope = (node, b.act_id^".", b.body) in + let clock_scope, clock_eq = gen_clock_init rp bscope in + f_and clock_eq (init_f_of_scope rp bscope clock_scope) | AST_activate_if(c, a, b) -> f_and (expr_eq c) (f_and (cond_eq a) (cond_eq b)) @@ -367,37 +416,27 @@ let rec init_f_of_scope rp (node, prefix, eqs) = let init_eq = BEnumCons(E_EQ, node^"/"^aid^".state", EItem st.st_name) in let state_eq (st, _) = let sc_f = - init_f_of_scope rp (node, aid^"."^st.st_name^".", st.body) + let st_scope = (node, aid^"."^st.st_name^".", st.body) in + let clock_scope, clock_eq = gen_clock_init rp st_scope in + f_and clock_eq (init_f_of_scope rp st_scope clock_scope) in List.fold_left (fun f (c, _, _) -> f_and f (expr_eq c)) sc_f st.until in List.fold_left f_and init_eq (List.map state_eq states) in - let time_eq = - f_and - (if not (rp.no_time_scope (node^"/")) - then - BRel(AST_EQ, - NIdent(node^"/"^prefix^"time"), - NIntConst 0) - else BConst true) - (if rp.init_scope (node^"/") - then - f_e_eq (EIdent(node^"/"^prefix^"init")) (EItem bool_true) - else BConst true) - in - List.fold_left f_and time_eq (List.map do_eq eqs) + f_and_list (List.map do_eq eqs) and init_f_of_prog rp = - init_f_of_scope rp rp.root_scope + let clock_scope, clock_eq = gen_clock_init rp rp.root_scope in + f_and clock_eq (init_f_of_scope rp rp.root_scope clock_scope) (* Get expressions for guarantee violation *) -let rec g_of_scope td (node, prefix, eqs) cond = +let rec g_of_scope td (node, prefix, eqs) clock_scope cond = let expr_g e = let instance_g (_, id, eqs, args) = - g_of_scope td (node^"/"^id, "", eqs) cond + g_of_scope td (node^"/"^id, "", eqs) clock_scope cond in List.fold_left (fun x i -> (instance_g i) @ x) [] (extract_instances td.rp.p e) @@ -406,21 +445,23 @@ let rec g_of_scope td (node, prefix, eqs) cond = | AST_assign(_, e) | AST_assume(_, e) -> expr_g e | AST_guarantee((id, _), e) -> - (id, f_and cond (f_of_expr td (node, prefix) (AST_not(e), snd e))) + (id, f_and cond (f_of_expr td (node, prefix, clock_scope) (AST_not(e), snd e))) :: (expr_g e) | AST_activate (b, _) -> let rec cond_g cond = function | AST_activate_body b -> - g_of_scope td (node, b.act_id^".", b.body) cond + let bscope = node, b.act_id^".", b.body in + g_of_scope td bscope (clock_scope_here bscope) cond | AST_activate_if(c, a, b) -> - (cond_g (f_and cond (f_of_expr td (node, prefix) c)) a) @ - (cond_g (f_and cond (f_of_expr td (node, prefix) (AST_not(c), snd c))) b) @ + (cond_g (f_and cond (f_of_expr td (node, prefix, clock_scope) c)) a) @ + (cond_g (f_and cond (f_of_expr td (node, prefix, clock_scope) (AST_not(c), snd c))) b) @ (expr_g c) in cond_g cond b | AST_automaton (aid, states, _) -> let st_g (st, _) = - g_of_scope td (node, aid^"."^st.st_name^".", st.body) + let stscope = (node, aid^"."^st.st_name^".", st.body) in + g_of_scope td stscope (clock_scope_here stscope) (f_and cond (BEnumCons(E_EQ, node^"/"^aid^".state", EItem st.st_name))) in List.flatten (List.map st_g states) @@ -433,4 +474,4 @@ and guarantees_of_prog rp = consts = I.consts rp; } in - g_of_scope td rp.root_scope (BConst true) + g_of_scope td rp.root_scope "" (BConst true) |