X-Git-Url: http://git.nguyen.vg/gitweb/?p=tatoo.git;a=blobdiff_plain;f=src%2Fata.ml;fp=src%2Fata.ml;h=939586f34ab31d691bc399cf563a9dad43860aec;hp=9ad2b129f544226813f665b983664e2326456184;hb=3b9dbcd9318dba41999dc6cc43093edbe5bc4c5d;hpb=05af95627d36110724ec6a2a6439c4842a228d19 diff --git a/src/ata.ml b/src/ata.ml index 9ad2b12..939586f 100644 --- a/src/ata.ml +++ b/src/ata.ml @@ -212,6 +212,9 @@ struct Formula.print f sep) l end +type rank = { td : StateSet.t; + bu : StateSet.t; + exit : StateSet.t } type t = { @@ -220,7 +223,7 @@ type t = { mutable starting_states : StateSet.t; mutable selecting_states: StateSet.t; transitions: (State.t, (QNameSet.t*Formula.t) list) Hashtbl.t; - mutable ranked_states : (StateSet.t*StateSet.t) array + mutable ranked_states : rank array } let uid t = t.id @@ -252,8 +255,10 @@ let print fmt a = (StateSet.cardinal a.states) StateSet.print a.starting_states StateSet.print a.selecting_states - (let r = ref 0 in Pretty.print_array ~sep:", " (fun ppf (s1,s2) -> - fprintf ppf "(%i:%a,%a)" !r StateSet.print s1 StateSet.print s2; incr r)) a.ranked_states; + (let r = ref 0 in Pretty.print_array ~sep:", " (fun ppf s -> + fprintf ppf "(%i:{td=%a,bu=%a,exit=%a)" !r + StateSet.print s.td StateSet.print s.bu StateSet.print s.exit; + incr r)) a.ranked_states; let trs = Hashtbl.fold (fun q t acc -> List.fold_left (fun acc (s , f) -> (q,s,f)::acc) acc t) @@ -453,6 +458,7 @@ let state_prerequisites dir auto q = StateSet.union prereq acc) StateSet.empty trans + let compute_rank auto = let dependencies = compute_dependencies auto in let upward = [ `Stay ; `Parent ; `Previous_sibling ] in @@ -503,24 +509,37 @@ let compute_rank auto = let set = try Hashtbl.find by_rank r with Not_found -> StateSet.empty in Hashtbl.replace by_rank r (StateSet.union s set)) !rank_list; let rank = Hashtbl.length by_rank in - auto.ranked_states <- - Array.init rank - (fun i -> - let set = try Hashtbl.find by_rank i with Not_found -> StateSet.empty in - let source = - if i + 1 == rank then auto.selecting_states else - let post_set = Hashtbl.find by_rank (i+1) in - let source = if i + 1 == rank then post_set else - StateSet.fold (fun q acc -> - List.fold_left (fun acc m -> - StateSet.union acc (state_prerequisites m auto q )) - acc [`First_child; `Next_sibling; `Parent; `Previous_sibling; `Stay] - ) post_set StateSet.empty - in - StateSet.inter set source - in - (source, set) - ) + if rank mod 2 == 1 then Hashtbl.replace by_rank rank StateSet.empty; + let rank = Hashtbl.length by_rank in + assert (rank mod 2 == 0); + let rank_array = + Array.init (rank / 2) + (fun i -> + let td_set = Hashtbl.find by_rank (2 * i) in + let bu_set = Hashtbl.find by_rank (2 * i + 1) in + { td = td_set; bu = bu_set ; exit = StateSet.empty } + ) + in + let max_rank = Array.length rank_array - 1 in + for i = 0 to max_rank do + let this_rank = rank_array.(i) in + let exit = if i == max_rank then auto.selecting_states else + let next = rank_array.(i+1) in + let res = + StateSet.fold (fun q acc -> + List.fold_left (fun acc m -> + StateSet.union acc (state_prerequisites m auto q )) + acc [`First_child; `Next_sibling; `Parent; `Previous_sibling; `Stay] + ) (StateSet.union next.td next.bu) StateSet.empty + in + + StateSet.( + union auto.selecting_states ( inter res (union this_rank.td this_rank.bu))) + + in + rank_array.(i) <- {this_rank with exit = exit }; + done; + auto.ranked_states <- rank_array module Builder = @@ -608,7 +627,11 @@ let rename_states mapper a = (fun l -> (List.map (fun (labels, form) -> (labels, map_form rename form)) l)) a.transitions; - ranked_states = Array.map (fun (a,b) -> map_set rename a, map_set rename b) a.ranked_states + ranked_states = Array.map (fun s -> + { td = map_set rename s.td; + bu = map_set rename s.bu; + exit = map_set rename s.exit; + }) a.ranked_states } let copy a =