1 (***********************************************************************)
5 (* Kim Nguyen, LRI UMR8623 *)
6 (* Université Paris-Sud & CNRS *)
8 (* Copyright 2010-2013 Université Paris-Sud and Centre National de la *)
9 (* Recherche Scientifique. All rights reserved. This file is *)
10 (* distributed under the terms of the GNU Lesser General Public *)
11 (* License, with the special exception on linking described in file *)
14 (***********************************************************************)
20 module Make (T : Tree.S) =
23 let eval_form phi tree node fcs nss pars selfs =
26 match Ata.Formula.expr phi with
29 | Or (phi1, phi2) -> loop phi1 || loop phi2
30 | And (phi1, phi2) -> loop phi1 && loop phi2
31 | Atom (a, b) -> b == Ata.(
32 match Atom.node a with
33 Is_first_child -> let par = T.parent tree node in
34 (T.first_child tree par) == node
35 | Is_next_sibling -> let par = T.parent tree node in
36 (T.next_sibling tree par) == node
37 | Is k -> k == T.kind tree node
38 | Has_first_child -> T.nil != T.first_child tree node
39 | Has_next_sibling -> T.nil != T.next_sibling tree node
44 | `Next_sibling -> nss
46 | `Previous_sibling -> pars
55 let eval_trans_aux trans tree node fcs nss pars selfs =
57 TransList.fold (fun trs acc ->
58 let q, _ , phi = Transition.node trs in
59 let res = eval_form phi tree node fcs nss pars selfs in
61 Format.eprintf "Formula %a evaluates to %b with context: (fcs=%a, nss=%a, pars=%a, olds=%a) @\n@."
73 let eval_trans trans tree node fcs nss pars sstates =
76 let news = eval_trans_aux trans tree node fcs nss pars olds in
78 Format.eprintf "Saturating formula: olds=%a, news=%a@\n@."
82 if news == olds then olds else
85 let r = loop sstates in
87 Format.eprintf "Evaluating transitions (fcs=%a, nss=%a, pars=%a, olds=%a):@\n\t%a@."
91 StateSet.print sstates
92 (Ata.TransList.print ~sep:"\n\t") trans;
93 Format.eprintf "Got %a@\n@." StateSet.print r;
98 let auto_run auto tree prev_nodes td_states bu_states exit_states _i =
100 Format.eprintf "Doing a td (with states: %a) and a bu (with states: %a), exit states are: %a @\n@."
101 StateSet.print td_states
102 StateSet.print bu_states
103 StateSet.print exit_states;
104 let rec loop res node parset =
105 if node == T.nil then StateSet.empty else begin
107 if Sequence.is_empty prev_nodes then
108 StateSet.(empty,empty,empty)
110 let set,lset,rset, node' = Sequence.peek prev_nodes in
111 if node == node' then begin
112 ignore (Sequence.pop prev_nodes);
116 StateSet.(empty,empty,empty)
118 let tag = T.tag tree node in
119 let td_trans = Ata.get_trans auto tag td_states in
120 let status1 = eval_trans td_trans tree node lset rset parset set in
121 let fcs = loop res (T.first_child tree node) status1 in
122 let rres = Sequence.create () in
123 let nss = loop rres (T.next_sibling tree node) status1 in
124 let bu_trans = Ata.get_trans auto tag bu_states in
125 let status2 = eval_trans bu_trans tree node fcs nss parset status1 in
126 let mstates = StateSet.inter status2 exit_states in
128 Format.eprintf "On node %i (tag : %a) status0 = %a, status1 = %a, fcs = %a, nss = %a, par = %a, status2 = %a, mstates = %a@\n@."
129 (T.preorder tree node)
132 StateSet.print status1
135 StateSet.print parset
136 StateSet.print status2
137 StateSet.print mstates;
139 if mstates != StateSet.empty then
140 Sequence.push_front (mstates,
141 StateSet.inter exit_states fcs,
142 StateSet.inter exit_states nss, node) res;
143 Sequence.append res rres;
147 let res = Sequence.create () in
148 ignore (loop res (T.root tree) StateSet.empty);
149 if false then Format.eprintf "Finished pass: %i @\n-----------------------@\n@." _i;
154 let prepare_run auto l =
155 let res = Sequence.create () in
156 let start = Ata.get_starting_states auto in
157 Sequence.iter (fun n -> Sequence.push_back (start, StateSet.empty, StateSet.empty, n) res) l;
161 let main_eval auto tree nodes =
162 let s_nodes = prepare_run auto nodes in
164 let ranked_states = Ata.get_states_by_rank auto in
165 let acc = ref s_nodes in
166 let max_rank = Ata.get_max_rank auto in
167 for i = 0 to max_rank do
169 let { td; bu; exit } = ranked_states.(i) in
170 acc := auto_run auto tree !acc td bu exit i;
172 Format.eprintf "Intermediate result is: @\n";
173 Sequence.iter (fun (s,_,_, n) ->
174 Format.eprintf "{%a, %i (%a)} "
177 QName.print (T.tag tree n)) !acc;
178 Format.eprintf "@\n@.";
184 let eval auto tree nodes =
185 let res = main_eval auto tree nodes in
186 let r = Sequence.create () in
187 Sequence.iter (fun (_,_,_, n) -> Sequence.push_back n r) res;
190 let full_eval auto tree nodes =
191 let res = main_eval auto tree nodes in
192 let dummy = Sequence.create () in
193 let cache = Cache.N1.create dummy in
194 Sequence.iter (fun (set, _, _, n) ->
195 StateSet.iter (fun q ->
196 let qres = Cache.N1.find cache q in
198 if qres == dummy then begin
199 let s = Sequence.create () in
200 Cache.N1.add cache q s;
205 Sequence.push_back n qres) set )
207 let l = StateSet.fold (fun q acc ->
208 let res = Cache.N1.find cache q in
209 (q, res) :: acc) (Ata.get_selecting_states auto) []