- 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