summaryrefslogtreecommitdiff
path: root/abstract/abs_interp_dynpart.ml
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ansys.com>2014-07-11 14:50:18 +0200
committerAlex Auvolat <alex.auvolat@ansys.com>2014-07-11 14:50:18 +0200
commitfd027ca593bdfb2d2db811730521b4f5d52c8593 (patch)
tree94982e74c74a480e9bafd235101d1934a330439e /abstract/abs_interp_dynpart.ml
parent9ca8bcb35eb0385c8f9852045bb282c445bd6901 (diff)
downloadscade-analyzer-fd027ca593bdfb2d2db811730521b4f5d52c8593.tar.gz
scade-analyzer-fd027ca593bdfb2d2db811730521b4f5d52c8593.zip
Acceptable heuristic.
Diffstat (limited to 'abstract/abs_interp_dynpart.ml')
-rw-r--r--abstract/abs_interp_dynpart.ml176
1 files changed, 124 insertions, 52 deletions
diff --git a/abstract/abs_interp_dynpart.ml b/abstract/abs_interp_dynpart.ml
index 006854e..bc0755b 100644
--- a/abstract/abs_interp_dynpart.ml
+++ b/abstract/abs_interp_dynpart.ml
@@ -48,7 +48,7 @@ end = struct
(* program expressions *)
f : bool_expr;
- guarantees : (id * bool_expr) list;
+ guarantees : (id * bool_expr * id) list;
(* data *)
loc : (int, location) Hashtbl.t;
@@ -168,7 +168,7 @@ end = struct
Format.printf "Complete formula:@.%a@.@." Formula_printer.print_expr f;
let facts = get_root_true f in
- let f, rp, _ = List.fold_left
+ let f, rp, repls = List.fold_left
(fun (f, (rp : rooted_prog), repls) eq ->
match eq with
| BEnumCons(E_EQ, a, EIdent b)
@@ -190,7 +190,7 @@ end = struct
let rp =
{ rp with all_vars =
List.filter (fun (_, id, _) -> id <> repl) rp.all_vars } in
- let repls = (repl, keep)::
+ let repls = [repl, keep; "L"^repl, "L"^keep]@
(List.map (fun (r, k) -> r, if k = repl then keep else k) repls) in
f, rp, repls
end
@@ -203,8 +203,11 @@ end = struct
Formula_printer.print_expr f;
let guarantees = Transform.guarantees_of_prog rp in
+ let guarantees = List.map
+ (fun (id, f, v) -> id, formula_replace_evars repls f, v)
+ guarantees in
Format.printf "Guarantees:@.";
- List.iter (fun (id, f) ->
+ List.iter (fun (id, f, _) ->
Format.printf " %s: %a@." id Formula_printer.print_expr f)
guarantees;
Format.printf "@.";
@@ -266,7 +269,7 @@ end = struct
*)
let rec ternary_conds = function
| BAnd(a, b) -> ternary_conds a @ ternary_conds b
- | BTernary(c, a, b) -> [c]
+ | BTernary(c, a, b) as x -> [c, x]
| _ -> []
(*
@@ -328,7 +331,7 @@ end = struct
(fun id loc ->
Format.printf "@.";
Format.printf "q%d (depth = %d):@. D: @[<v 2>%a@]@." id loc.depth print_v loc.def;
- Format.printf " F: (%a)@." Formula_printer.print_expr loc.f;
+ (*Format.printf " F: (%a)@." Formula_printer.print_expr loc.f;*)
Format.printf " V: %a@." print_v loc.v;
Format.printf " -> @[<hov>[%a]@]@."
(print_list (fun fmt i -> Format.fprintf fmt "q%d" i) ", ") loc.out_t;
@@ -338,20 +341,30 @@ end = struct
let dump_graphwiz_trans_graph e file =
let o = open_out file in
let fmt = Format.formatter_of_out_channel o in
- Format.fprintf fmt "digraph G{@[<v 4>@ ";
+ Format.fprintf fmt "digraph G{@.";
Hashtbl.iter
(fun id loc ->
if loc.is_init then
- Format.fprintf fmt "q%d [shape=doublecircle, label=\"q%d [%a]\"];@ "
+ Format.fprintf fmt " q%d [shape=doublecircle, label=\"q%d [%a]\"];@."
id id (print_list Format.pp_print_string ", ") loc.violate_g
else
- Format.fprintf fmt "q%d [label=\"q%d [%a]\"];@ "
+ Format.fprintf fmt " q%d [label=\"q%d [%a]\"];@."
id id (print_list Format.pp_print_string ", ") loc.violate_g;
- List.iter (fun v -> Format.fprintf fmt "q%d -> q%d;@ " id v) loc.out_t)
+ let n1 = List.length loc.violate_g in
+ List.iter
+ (fun v ->
+ let n2 = List.length (Hashtbl.find e.loc v).violate_g in
+ let c, w =
+ if n2 > n1 then "#770000", 1
+ else "black", 2
+ in
+ Format.fprintf fmt " q%d -> q%d [color = \"%s\", weight = %d];@."
+ id v c w)
+ loc.out_t)
e.loc;
- Format.fprintf fmt "@]@.}@.";
+ Format.fprintf fmt "}@.";
close_out o
@@ -376,7 +389,7 @@ end = struct
loc.v <- bottom e)
e.loc;
- print_locs_defs e;
+ (*print_locs_defs e;*)
(* Iterate *)
let it_counter = ref 0 in
@@ -413,7 +426,7 @@ end = struct
else iter (n+1) j
in
let y = iter 0 start in
- let z = fix eq_v f y in
+ let z = f y in
let u = pass_cycle e.ve z in
if e.opt.verbose_ci then
@@ -463,15 +476,17 @@ end = struct
Hashtbl.iter
(fun _ loc ->
let verif, violate = List.partition
- (fun (_, f) ->
+ (fun (_, f, _) ->
is_bot (apply_cl loc.v (conslist_of_f f)))
e.guarantees
in
- loc.verif_g <- List.map fst verif;
- loc.violate_g <- List.map fst violate)
+ loc.verif_g <- List.map (fun (a, b, c) -> a) verif;
+ loc.violate_g <- List.map (fun (a, b, c) -> a) violate)
e.loc;
- print_locs e
+ print_locs e;
+
+ ()
@@ -491,8 +506,8 @@ end = struct
(fun q (loc : location) ->
let rec iter () =
try
- let cond = List.find
- (fun c ->
+ let cond, _ = List.find
+ (fun (c, _) ->
is_bot (apply_cl loc.v (conslist_of_f c))
|| is_bot (apply_cl loc.v (conslist_of_f (BNot c))))
(ternary_conds loc.f)
@@ -512,56 +527,113 @@ end = struct
e.loc;
(* find splitting condition *)
+ let voi = List.map (fun (a, b, c) -> c) e.guarantees in
+
Hashtbl.iter
(fun q (loc:location) ->
if loc.depth < e.opt.max_dp_depth then
let cs = ternary_conds loc.f in
List.iter
- (fun c ->
+ (fun (c, exprs) ->
let cases_t = apply_cl_all_cases (top e) (conslist_of_f c) in
let cases_f = apply_cl_all_cases (top e) (conslist_of_f (BNot c)) in
- let cases = cases_t @ cases_f in
+ let cases = List.mapi (fun i c -> i, c) (cases_t @ cases_f) in
if
List.length
(List.filter
- (fun case -> not (is_bot (meet loc.v case)))
+ (fun (_, case) -> not (is_bot (meet loc.v case)))
cases)
>= 2
then
- let score =
- let w1 = List.fold_left (+.) 0.
- (List.map
- (fun qi ->
- let loci = Hashtbl.find e.loc qi in
- let v = apply_cl
- (meet (pass_cycle e.ve loci.v) loc.def)
- loc.cl in
- let n = List.length @@ List.filter
- (fun case -> is_bot (meet v case))
- cases
- in if n > 0 then 1. else 0.)
- loc.in_t)
- in
- let w2 = List.fold_left (+.) 0.
- (List.map
- (fun qo ->
- let loco = Hashtbl.find e.loc qo in
- let n = List.length @@ List.filter
- (fun case ->
- let v = meet loc.v case in
+ (* calculate which transitions qi -> q stay or are destroyed (approximation) *)
+ let in_tc =
+ List.flatten @@ List.map
+ (fun qi ->
+ let loci = Hashtbl.find e.loc qi in
+ let v = apply_cl
+ (meet (pass_cycle e.ve loci.v) loc.def)
+ loc.cl in
+ List.map
+ (fun (ci, case) -> qi, ci, not (is_bot (meet v case)))
+ cases)
+ loc.in_t
+ in
+ (* calculate which transitions q -> qo stay or are destroyed (approximation) *)
+ let out_tc =
+ List.flatten @@ List.map
+ (fun (ci, case) ->
+ let v = meet loc.v case in
+ List.map
+ (fun qo ->
+ let loco = Hashtbl.find e.loc qo in
let w = apply_cl
(meet (pass_cycle e.ve v) loco.def)
loco.cl
- in is_bot w)
- cases
- in if n > 0 then 1. else 0.)
- loc.out_t)
+ in qo, ci, not (is_bot w))
+ loc.out_t)
+ cases
+ in
+ (* calculate which cases have a good number of disappearing transitions *)
+ let fa =
+ let cs_sc =
+ List.map
+ (fun (ci, case) ->
+ let a =
+ List.length
+ (List.filter (fun (qi, c, a) -> not a && c = ci) in_tc)
+ in
+ let b =
+ List.length
+ (List.filter (fun (qo, c, a) -> not a && c = ci) out_tc)
+ in
+ a + b + a * b)
+ cases
in
- ((w1 /. 1. (*(float_of_int (List.length loc.in_t))*))
- +. (w2 /. 1. (*(float_of_int (List.length loc.out_t))*)))
- /. (float_of_int (List.length cases))
+ 5 * List.fold_left max 0 cs_sc
+ in
+ (* calculate which states become inaccessible *)
+ let fb =
+ if fa = 0 || List.for_all (fun (_, _, a) -> a) out_tc
+ then 0
+ else
+ let ff id = (* transition function for new graph *)
+ if id >= 1000000 then
+ let case = id - 1000000 in
+ List.map (fun (qo, _, _) -> qo)
+ (List.filter (fun (_, c, a) -> c = case && a) out_tc)
+ else
+ let out_t = (Hashtbl.find e.loc id).out_t in
+ if List.mem loc.id out_t then
+ (List.map (fun (_, c, _) -> c + 1000000)
+ (List.filter (fun (qi, _, a) -> qi = id && a) in_tc))
+ @ (List.filter ((<>) id) out_t)
+ else out_t
+ in
+ let memo = Hashtbl.create 12 in
+ let rec do_x id =
+ if not (Hashtbl.mem memo id) then begin
+ Hashtbl.add memo id ();
+ List.iter do_x (ff id)
+ end
+ in
+ Hashtbl.iter (fun i loc2 -> if loc2.is_init && i <> loc.id then do_x i) e.loc;
+ if loc.is_init then List.iter (fun (ci, _) -> do_x (ci+1000000)) cases;
+ let disappear_count = (Hashtbl.length e.loc + List.length cases) - (Hashtbl.length memo) in
+ 21 * disappear_count
+ in
+ (* calculate number of VOI (variables of interest) that are affected *)
+ let fc =
+ let vlist = refd_evars_of_f exprs in
+ 10 * List.length
+ (List.filter (fun v -> List.mem v vlist) voi) in
+ (* give score to split *)
+ let fd = 2 * List.length loc.out_t + List.length loc.in_t in
+ let score =
+ if fa = 0 then 0 else
+ fa + fb + fc + fd
in
- if
+ Format.printf " %5d + %5d + %5d + %5d = %5d (q%d)@." fa fb fc fd score loc.id;
+ if score > 0 &&
match !qc with
| None -> true
| Some (s, _, _, _, _) -> score >= s
@@ -604,7 +676,7 @@ end = struct
in iter 0;
(* Check guarantees *)
- let check_guarantee (id, f) =
+ let check_guarantee (id, f, _) =
Format.printf "@[<v 4>";
let cl = Formula.conslist_of_f f in
Format.printf "%s:@ %a ⇒ ⊥ @ "