+ let choose_jump tagset qtags1 qtagsn a f_nil f_text f_t1 f_s1 f_tn f_sn f_notext =
+ let tags1,hastext1,fin1 = inter_text tagset (tags a qtags1) in
+ let tagsn,hastextn,finn = inter_text tagset (tags a qtagsn) in
+(* Format.fprintf Format.err_formatter "Tags below states ";
+ pr_st Format.err_formatter (Ptset.elements qtags1);
+ Format.fprintf Format.err_formatter " are { ";
+ Ptset.iter (fun t -> Format.fprintf Format.err_formatter "%s " (Tag.to_string t)) tags1;
+ Format.fprintf Format.err_formatter "}, %b,%b\n%!" hastext1 fin1;
+
+ Format.fprintf Format.err_formatter "Tags below states ";
+ pr_st Format.err_formatter (Ptset.elements qtagsn);
+ Format.fprintf Format.err_formatter " are { ";
+ Ptset.iter (fun t -> Format.fprintf Format.err_formatter "%s " (Tag.to_string t)) tagsn;
+ Format.fprintf Format.err_formatter "}, %b,%b\n%!" hastextn finn;
+*)
+ if (hastext1||hastextn) then f_text (* jumping to text nodes doesn't work really well *)
+ else if (Ptset.is_empty tags1) && (Ptset.is_empty tagsn) then f_nil
+ else if (Ptset.is_empty tagsn) then
+ if (Ptset.is_singleton tags1) then f_t1 (Ptset.choose tags1) (* TaggedChild/Sibling *)
+ else f_s1 tags1 (* SelectChild/Sibling *)
+ else if (Ptset.is_empty tags1) then
+ if (Ptset.is_singleton tagsn) then f_tn (Ptset.choose tagsn) (* TaggedDesc/Following *)
+ else f_sn tagsn (* SelectDesc/Following *)
+ else f_notext
+
+ let choose_jump_down a b c d =
+ choose_jump a b c d
+ (Tree.mk_nil)
+ (Tree.text_below)
+ (*fun x -> let i,j = Tree.doc_ids x in
+ let res = Tree.text_below x in
+ Printf.printf "Calling text_below %s (tag=%s), docids= (%i,%i), res=%s\n"
+ (Tree.dump_node x) (Tag.to_string (Tree.tag x)) i j (Tree.dump_node res);
+ res*)
+ (fun _ -> Tree.node_child ) (* !! no tagged_child in Tree.ml *)
+ (fun _ -> Tree.node_child ) (* !! no select_child in Tree.ml *)
+ (Tree.tagged_desc)
+ (fun _ -> Tree.node_child ) (* !! no select_desc *)
+ (Tree.node_child)
+
+ let choose_jump_next a b c d =
+ choose_jump a b c d
+ (fun t _ -> Tree.mk_nil t)
+ (Tree.text_next)
+ (*fun x y -> let i,j = Tree.doc_ids x in
+ let res = Tree.text_next x y in
+ Printf.printf "Calling text_next %s (tag=%s) ctx=%s, docids= (%i,%i), res=%s\n"
+ (Tree.dump_node x) (Tag.to_string (Tree.tag x)) (Tree.dump_node y) i j (Tree.dump_node res);
+ res*)
+
+ (fun _ -> Tree.node_sibling_ctx) (* !! no tagged_sibling in Tree.ml *)
+ (fun _ -> Tree.node_sibling_ctx) (* !! no select_child in Tree.ml *)
+ (Tree.tagged_foll_below)
+ (fun _ -> Tree.node_sibling_ctx) (* !! no select_foll *)
+ (Tree.node_sibling_ctx)
+
+
+ let get_trans slist tag a t =
+ try
+ Hashtbl.find td_trans (tag,hpl slist)
+ with
+ | Not_found ->
+ let fl_list,llist,rlist,ca,da,sa,fa =
+ fold_pl
+ (fun set _ (fll_acc,lllacc,rllacc,ca,da,sa,fa) -> (* For each set *)
+ let fl,ll,rr,ca,da,sa,fa =
+ Ptset.fold
+ (fun q acc ->
+ fst (
+ List.fold_left
+ (fun (((fl_acc,ll_acc,rl_acc,c_acc,d_acc,s_acc,f_acc),h_acc) as acc)
+ (ts,(m,f,_)) ->
+ if (TagSet.mem tag ts)
+ then
+ let (child,desc,below),(sibl,foll,after) = f.st in
+ let h_acc = HASHINT3(h_acc,f.fid,HASHINT2(q,vb m)) in
+ ((Formlist.cons q f h_acc m fl_acc,
+ Ptset.union ll_acc below,
+ Ptset.union rl_acc after,
+ Ptset.union child c_acc,
+ Ptset.union desc d_acc,
+ Ptset.union sibl s_acc,
+ Ptset.union foll f_acc),
+ h_acc)
+ else acc ) (acc,0) (
+ try Hashtbl.find a.phi q
+ with
+ Not_found -> Printf.eprintf "Looking for state %i, doesn't exist!!!\n%!"
+ q;[]
+ ))
+
+ ) set (Formlist.nil,Ptset.empty,Ptset.empty,ca,da,sa,fa)
+ in fl::fll_acc, cons ll lllacc, cons rr rllacc,ca,da,sa,fa)
+ slist ([],Nil,Nil,Ptset.empty,Ptset.empty,Ptset.empty,Ptset.empty)
+ in
+ (* Logic to chose the first and next function *)
+ let tags_below,tags_after = Tree.tags t tag in
+ let first = choose_jump_down tags_below ca da a
+ and next = choose_jump_next tags_after sa fa a in
+ let v = (fl_list,llist,rlist,first,next) in
+ Hashtbl.add td_trans (tag, hpl slist) v; v
+
+ let merge rb rb1 rb2 mark t res1 res2 =
+ if rb
+ then
+ let res1 = if rb1 then res1 else RS.empty
+ and res2 = if rb2 then res2 else RS.empty
+ in
+ if mark then RS.cons t (RS.concat res1 res2)
+ else RS.concat res1 res2
+ else RS.empty
+
+ let top_down ?(noright=false) a t slist ctx slot_size =
+ let pempty = empty_size slot_size in
+ let eval_fold2_slist fll sl1 sl2 res1 res2 t =
+ let res = Array.copy res1 in
+ let rec fold l1 l2 fll i aq = match l1,l2,fll with
+ | Cons(s1,_,ll1), Cons(s2, _ ,ll2),fl::fll ->
+ let r',rb,rb1,rb2,mark = eval_formlist s1 s2 fl in
+(* let _ = pr "Evaluation context : "; pr_st fmt (Ptset.elements s1);
+ pr_st fmt (Ptset.elements s2);
+ pr "Formlist (%i) : " (Formlist.hash fl);
+ Formlist.pr fmt fl;
+ pr "Results : "; pr_st fmt (Ptset.elements r');
+ pr ", %b %b %b %b\n%!" rb rb1 rb2 mark
+ in *)
+ let _ = res.(i) <- merge rb rb1 rb2 mark t res1.(i) res2.(i)
+ in
+ fold ll1 ll2 fll (i+1) (cons r' aq)
+ | Nil, Nil,[] -> aq,res
+ | _ -> assert false
+ in
+ fold sl1 sl2 fll 0 Nil
+ in
+ let null_result() = (pempty,Array.make slot_size RS.empty) in
+ let rec loop t slist ctx =
+ let (a,b) =
+ if Tree.is_nil t then null_result()
+ else
+ let tag = Tree.tag t in
+ let fl_list,llist,rlist,first,next = get_trans slist tag a t in
+(* let _ = pr "For tag %s,node %s, returning formulae list: \n%!"
+ (Tag.to_string tag) (Tree.dump_node t);
+ List.iter (fun f -> Formlist.pr fmt f;pr "\n%!") fl_list
+ in*)
+ let sl1,res1 = loop (first t) llist t in
+ let sl2,res2 = loop (next t ctx) rlist ctx in
+ eval_fold2_slist fl_list sl1 sl2 res1 res2 t
+ in
+(* let _ = pr "Inside topdown call: tree was %s, tag = %s" (Tree.dump_node t) (if Tree.is_nil t then "###"
+ else Tag.to_string (Tree.tag t));
+ iter_pl (fun s -> (pr_st fmt (Ptset.elements s))) a;
+ Array.iter (fun i -> pr "%i" (RS.length i)) b;
+ pr "\n%!"; in*) (a,b)
+
+ in
+ let loop_no_right t slist ctx =
+ if Tree.is_nil t then null_result()
+ else
+ let tag = Tree.tag t in
+ let fl_list,llist,rlist,first,next = get_trans slist tag a t in
+ let sl1,res1 = loop (first t) llist t in
+ let sl2,res2 = null_result() in
+ eval_fold2_slist fl_list sl1 sl2 res1 res2 t
+ in
+ (if noright then loop_no_right else loop) t slist ctx
+
+ let run_top_down a t =
+ let init = cons a.init Nil in
+ let _,res = top_down a t init t 1
+ in res.(0)
+ ;;
+
+ module Configuration =
+ struct
+ module Ptss = Set.Make(Ptset)
+ module IMap = Map.Make(Ptset)
+ type t = { hash : int;
+ sets : Ptss.t;
+ results : RS.t IMap.t }
+ let empty = { hash = 0;
+ sets = Ptss.empty;
+ results = IMap.empty;
+ }
+ let is_empty c = Ptss.is_empty c.sets
+ let add c s r =
+ if Ptss.mem s c.sets then
+ { c with results = IMap.add s (RS.concat r (IMap.find s c.results)) c.results}
+ else
+ { hash = HASHINT2(c.hash,Ptset.hash s);
+ sets = Ptss.add s c.sets;
+ results = IMap.add s r c.results
+ }