+ let top_down ?(noright=false) a t slist ctx slot_size =
+ let pempty = empty_size slot_size in
+ (* evaluation starts from the right so we put sl1,res1 at the end *)
+ let eval_fold2_slist fll t (sl2,res2) (sl1,res1) =
+ let res = Array.copy res1 in
+ let rec fold l1 l2 fll i aq =
+ match SList.node l1,SList.node l2, fll with
+ | SList.Cons(s1,ll1),
+ SList.Cons(s2,ll2),
+ fl::fll ->
+ let r',rb,rb1,rb2,mark = eval_formlist s1 s2 fl in
+ let _ = res.(i) <- merge rb rb1 rb2 mark t res1.(i) res2.(i)
+ in
+ fold ll1 ll2 fll (i+1) (SList.cons r' aq)
+
+ | SList.Nil, SList.Nil,[] -> aq,res
+ | _ -> assert false
+ in
+ fold sl1 sl2 fll 0 SList.nil
+ in
+ let null_result() = (pempty,Array.make slot_size RS.empty) in
+
+ let rec loop t slist ctx =
+ if Tree.is_nil t then null_result() else get_trans t slist (Tree.tag t) ctx
+
+ and loop_tag tag t slist ctx =
+ if Tree.is_nil t then null_result() else get_trans t slist tag ctx
+ and loop_no_right t slist ctx =
+ if Tree.is_nil t then null_result() else get_trans ~noright:true t slist (Tree.tag t) ctx
+ and get_trans ?(noright=false) t slist tag ctx =
+ let cont =
+ try
+ CachedTransTable.find td_trans (tag,slist)
+ with
+ | Not_found ->
+ let fl_list,llist,rlist,ca,da,sa,fa =
+ SList.fold
+ (fun set (fll_acc,lllacc,rllacc,ca,da,sa,fa) -> (* For each set *)
+ let fl,ll,rr,ca,da,sa,fa =
+ StateSet.fold
+ (fun q acc ->
+ List.fold_left
+ (fun ((fl_acc,ll_acc,rl_acc,c_acc,d_acc,s_acc,f_acc) as acc)
+ (ts,t) ->
+ if (TagSet.mem tag ts)
+ then
+ let _,_,f,_ = Transition.node t in
+ let (child,desc,below),(sibl,foll,after) = Formula.st f in
+ (Formlist.cons t fl_acc,
+ StateSet.union ll_acc below,
+ StateSet.union rl_acc after,
+ StateSet.union child c_acc,
+ StateSet.union desc d_acc,
+ StateSet.union sibl s_acc,
+ StateSet.union foll f_acc)
+ else acc ) acc (
+ try Hashtbl.find a.trans q
+ with
+ Not_found -> Printf.eprintf "Looking for state %i, doesn't exist!!!\n%!"
+ q;[]
+ )
+
+ ) set (Formlist.nil,StateSet.empty,StateSet.empty,ca,da,sa,fa)
+ in fl::fll_acc, (SList.cons ll lllacc), (SList.cons rr rllacc),ca,da,sa,fa)
+ slist ([],SList.nil,SList.nil,StateSet.empty,StateSet.empty,StateSet.empty,StateSet.empty)
+ in
+ (* Logic to chose the first and next function *)
+ let tags_below,tags_after = Tree.tags t tag in
+ let f_kind,first = choose_jump_down tags_below ca da a
+ and n_kind,next = if noright then (`NIL, fun t _ -> Tree.mk_nil t )
+ else choose_jump_next tags_after sa fa a in
+ let empty_res = null_result() in
+ let cont =
+ match f_kind,n_kind with
+ | `NIL,`NIL -> (fun _ _ -> null_result())
+ | _,`NIL -> (
+ match f_kind with
+ |`TAG(tag) ->
+ (fun t _ -> eval_fold2_slist fl_list t empty_res
+ (loop_tag tag (first t) llist t))
+ | `ANY ->
+ (fun t _ -> eval_fold2_slist fl_list t empty_res
+ (loop (first t) llist t))
+ | _ -> assert false)
+
+ | `NIL,_ -> (
+ match n_kind with
+ |`TAG(tag) ->
+ (fun t ctx -> eval_fold2_slist fl_list t
+ (loop_tag tag (next t ctx) rlist ctx) empty_res)
+
+ | `ANY ->
+ (fun t ctx -> eval_fold2_slist fl_list t
+ (loop (next t ctx) rlist ctx) empty_res)
+
+ | _ -> assert false)
+
+ | `TAG(tag1),`TAG(tag2) ->
+ (fun t ctx -> eval_fold2_slist fl_list t
+ (loop (next t ctx) rlist ctx)
+ (loop (first t) llist t))
+
+ | `TAG(tag),`ANY ->
+ (fun t ctx ->
+ eval_fold2_slist fl_list t
+ (loop (next t ctx) rlist ctx)
+ (loop_tag tag (first t) llist t))
+ | `ANY,`TAG(tag) ->
+ (fun t ctx ->
+ eval_fold2_slist fl_list t
+ (loop_tag tag (next t ctx) rlist ctx)
+ (loop (first t) llist t) )
+ | `ANY,`ANY ->
+ (fun t ctx ->
+ eval_fold2_slist fl_list t
+ (loop (next t ctx) rlist ctx)
+ (loop (first t) llist t) )
+ | _ -> assert false
+ in
+ (CachedTransTable.add td_trans (tag,slist) cont;cont)
+ in cont t ctx
+ in
+ (if noright then loop_no_right else loop) t slist ctx
+