X-Git-Url: http://git.nguyen.vg/gitweb/?p=tatoo.git;a=blobdiff_plain;f=src%2Fauto%2Feval.ml;fp=src%2Fauto%2Feval.ml;h=4647b84feec81f7c04c9545ba1ce60b12143656d;hp=0000000000000000000000000000000000000000;hb=8026ca9faaa968ced3c2e75ca1d6b55f7270ca50;hpb=74e8f4bcdd9e19a2ec434d82c1a6eb897b826632 diff --git a/src/auto/eval.ml b/src/auto/eval.ml new file mode 100644 index 0000000..4647b84 --- /dev/null +++ b/src/auto/eval.ml @@ -0,0 +1,105 @@ +(***********************************************************************) +(* *) +(* TAToo *) +(* *) +(* Kim Nguyen, LRI UMR8623 *) +(* Université Paris-Sud & CNRS *) +(* *) +(* Copyright 2010-2013 Université Paris-Sud and Centre National de la *) +(* Recherche Scientifique. All rights reserved. This file is *) +(* distributed under the terms of the GNU Lesser General Public *) +(* License, with the special exception on linking described in file *) +(* ../LICENSE. *) +(* *) +(***********************************************************************) + +(* + Time-stamp: +*) + +INCLUDE "utils.ml" +open Format +open Utils + +module Make (T : Tree.Sig.S) = struct + + type cache = (int, StateSet.t) Hashtbl.t + + let get c t n = + try Hashtbl.find c (T.preorder t n) + with Not_found -> StateSet.empty + + let set c t n v = Hashtbl.replace c (T.preorder t n) v + + let eval_trans l ctx acc = + List.fold_left (fun (acct, accs) ((q, phi) as trs) -> + if Ata.SFormula.eval ctx phi then + (acct, StateSet.add q accs) + else + (trs::acct, accs) + ) ([], acc) l + + let top_down_run auto tree node cache i = + let redo = ref false in + let rec loop node is_left = + if node != T.nil then begin + let parent = T.parent tree node in + let fc = T.first_child tree node in + let ns = T.next_sibling tree node in + let states0 = get cache tree node in + let tag = T.tag tree node in + let trans0 = Ata.get_trans auto auto.Ata.states tag in + let parent_states = if parent == T.nil then auto.Ata.top_states else get cache tree parent in + let fc_states = if fc == T.nil then auto.Ata.bottom_states else get cache tree fc in + let ns_states = if ns == T.nil then auto.Ata.bottom_states else get cache tree ns in + let ctx0 = + if is_left then + Ata.make_ctx fc_states ns_states parent_states StateSet.empty states0 + else + Ata.make_ctx fc_states ns_states StateSet.empty parent_states states0 + in + eprintf "[Iteration % 4d] node: %a, context: %a\n%!" + i T.print_node node Ata.print_ctx ctx0; + List.iter (fun (q, phi) -> eprintf "%a -> %a\n" State.print q Ata.SFormula.print phi) trans0; + eprintf "----------------------\n%!"; + let trans1, states1 = eval_trans trans0 ctx0 StateSet.empty in + if states1 != states0 then set cache tree node states1; + let () = loop fc true in + let ctx1 = {ctx0 with Ata.left = (get cache tree fc) ; Ata.epsilon = states1 } in + let trans2, states2 = eval_trans trans1 ctx1 states1 in + if states2 != states1 then set cache tree node states2; + let () = loop ns false in + let ctx2 = { ctx1 with Ata.right = (get cache tree ns); Ata.epsilon = states2 } in + let _, states3 = eval_trans trans2 ctx2 states2 in + if states3 != states2 then set cache tree node states3; + if states0 != states3 && (not !redo) then redo := true + end + in + loop node true; + !redo + + let get_results auto tree node cache = + let rec loop node acc = + if node == T.nil then acc + else + let acc0 = loop (T.next_sibling tree node) acc in + let acc1 = loop (T.first_child tree node) acc0 in + + if StateSet.intersect (get cache tree node) auto.Ata.selection_states then + node::acc1 + else + acc1 + in + loop node [] + + let eval auto tree node = + let cache = Hashtbl.create 511 in + let redo = ref true in + let iter = ref 0 in + while !redo do + redo := top_down_run auto tree node cache !iter; + incr iter; + done; + get_results auto tree node cache + +end