merge from local branch
[SXSI/xpathcomp.git] / ata.ml
diff --git a/ata.ml b/ata.ml
index bba3203..45f3761 100644 (file)
--- a/ata.ml
+++ b/ata.ml
@@ -1,6 +1,6 @@
 INCLUDE "debug.ml"
 INCLUDE "utils.ml"
-
+type jump_kind = [ `TAG of Tag.t | `CONTAINS of string | `NOTHING ]
 let cpt_trans = ref 0
 let miss_trans = ref 0
 let cpt_eval = ref 0
@@ -398,8 +398,8 @@ type 'a t = {
            let b,b1,b2 = eval_form_bool f s1 s2 in
            let r = if b then (Ptset.add q s, b, b1'||b1,b2'||b2,mark||amark)
            else s,b',b1',b2',amark
-           in
-(*           Format.fprintf Format.err_formatter "\nEvaluating formula (%i) %i %s" h q (if mark then "=>" else "->");
+           in(*
+             Format.fprintf Format.err_formatter "\nEvaluating formula (%i) %i %s" h q (if mark then "=>" else "->");
              pr_frm (Format.err_formatter) f;
              Format.fprintf Format.err_formatter " in context ";
              pr_st Format.err_formatter (Ptset.elements s1);
@@ -970,6 +970,8 @@ type 'a t = {
 
     module Run (RS : ResultSet) =
     struct
+      let fmt = Format.err_formatter
+      let pr x = Format.fprintf fmt x
       module Formlist = 
       struct
        type t = formlist
@@ -1010,6 +1012,11 @@ type 'a t = {
          function Nil -> Nil 
            | Cons(s,h,ll) -> cons (f s) (loop ll) 
        in loop l
+      let iter_pl f l = 
+       let rec loop =
+         function Nil -> ()
+           | Cons(s,h,ll) ->  (f s);(loop ll) 
+       in loop l
 
       let rev_pl l = 
        let rec loop acc l = match l with 
@@ -1104,6 +1111,7 @@ type 'a t = {
                                     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,
@@ -1111,7 +1119,7 @@ type 'a t = {
                                           Ptset.union desc d_acc,
                                           Ptset.union sibl s_acc,
                                           Ptset.union foll f_acc),
-                                         HASHINT3(h_acc,f.fid,HASHINT2(q,vb m)))
+                                         h_acc)                                 
                                   else acc ) (acc,0) (
                                  try Hashtbl.find a.phi q 
                                  with
@@ -1147,6 +1155,13 @@ type 'a t = {
          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)
@@ -1157,14 +1172,25 @@ type 'a t = {
        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 = if noright then null_result()
-           else loop (next t ctx) rlist ctx 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()
@@ -1240,8 +1266,7 @@ type 'a t = {
                results = imap }
 
        end
-       let fmt = Format.err_formatter
-       let pr x = Format.fprintf fmt x
+
        let h_fold = Hashtbl.create 511 
 
        let fold_f_conf  t slist fl_list conf dir= 
@@ -1296,8 +1321,10 @@ type 'a t = {
            Hashtbl.fold (fun q l acc ->
                            List.fold_left (fun  (fl_acc,h_acc) (ts,(m,f,_))  ->
                                              if TagSet.mem ptag ts                                    
-                                             then (Formlist.cons q f h_acc m fl_acc,
-                                                   HASHINT3(h_acc,f.fid,q))
+                                             then
+                                               let h_acc = HASHINT3(h_acc,f.fid,HASHINT2(q,vb m)) in
+                                                 (Formlist.cons q f h_acc m fl_acc,
+                                                  h_acc)
                                              else (fl_acc,h_acc))
                              acc l)
              a.phi (Formlist.nil,0)
@@ -1306,37 +1333,38 @@ type 'a t = {
          in
            (Hashtbl.add h_trans key res;res) 
                      
-
+             
+       let h_tdconf = Hashtbl.create 511 
        let rec bottom_up a tree conf next jump_fun root dotd init accu = 
          if (not dotd) && (Configuration.is_empty conf ) then
-        (*   let _ = pr "Returning early from %s, with accu %i, next is %s\n%!" 
-             (Tree.dump_node tree) (Obj.magic accu) (Tree.dump_node next)
-             in *)
-           accu,conf,next
+(*                 let _ = pr "Returning early from %s, with accu %i, next is %s\n%!" 
+                   (Tree.dump_node tree) (Obj.magic accu) (Tree.dump_node next)
+                   in *)
+           accu,conf,next 
          else
-(*       let _ =   
+(*         let _ =   
            pr "Going bottom up for tree with tag %s configuration is" 
-             (if Tree.is_nil tree then "###" else Tag.to_string (Tree.tag tree));
+           (if Tree.is_nil tree then "###" else Tag.to_string (Tree.tag tree));
            Configuration.pr fmt conf 
-         in *)
-         let below_right = Tree.is_below_right tree next in 
-(*       let _ = Format.fprintf Format.err_formatter "below_right %s %s = %b\n%!"
-           (Tree.dump_node tree) (Tree.dump_node next)  below_right
-         in *)
-         let accu,rightconf,next_of_next =         
+           in *)
+           let below_right = Tree.is_below_right tree next in 
+             (*          let _ = Format.fprintf Format.err_formatter "below_right %s %s = %b\n%!"
+                         (Tree.dump_node tree) (Tree.dump_node next)  below_right
+                         in *)
+           let accu,rightconf,next_of_next =       
            if below_right then (* jump to the next *)
-(*           let _ = pr "Jumping to %s\n%!" (Tree.dump_node next) in  *)
+(*           let _ = pr "Jumping to %s tag %s\n%!" (Tree.dump_node next) (Tag.to_string (Tree.tag next)) in   *)
              bottom_up a next conf (jump_fun next) jump_fun (Tree.next_sibling tree) true init accu
            else accu,Configuration.empty,next
          in 
-(*       let _ = if below_right then pr "Returning from jump to next\n" in  *)
+(*       let _ = if below_right then pr "Returning from jump to next = %s\n" (Tree.dump_node next)in   *)
          let sub =
            if dotd then
              if below_right then (* only recurse on the left subtree *)
-       (*      let _ = pr "Topdown on subtree\n%!" in     *)
+(*             let _ = pr "Topdown on left subtree\n%!" in      *)
                prepare_topdown a tree true
              else 
-(*             let _ = pr "Topdown on whole tree\n%!" in   *)
+(*             let _ = pr "Topdown on whole tree\n%!" in *)
                prepare_topdown a tree false
            else conf
          in
@@ -1344,10 +1372,10 @@ type 'a t = {
            (Configuration.merge rightconf sub, next_of_next)
          in
            if Tree.equal tree root then 
-(*           let _ = pr "Stopping at root, configuration after topdown is:" ;
+(*             let _ = pr "Stopping at root, configuration after topdown is:" ;
                Configuration.pr fmt conf;
                pr "\n%!"               
-             in  *) accu,conf,next 
+             in *)  accu,conf,next 
            else              
          let parent = Tree.binary_parent tree in
          let ptag = Tree.tag parent in
@@ -1355,7 +1383,7 @@ type 'a t = {
          let slist = Configuration.Ptss.fold (fun e a -> cons e a) conf.Configuration.sets Nil in
          let fl_list = get_up_trans slist ptag a parent in
          let slist = rev_pl (slist) in 
-(*       let _ = pr "Current conf is : %i " (Tree.id tree);
+(*       let _ = pr "Current conf is : %s " (Tree.dump_node tree); 
            Configuration.pr fmt conf;
            pr "\n" 
          in *)
@@ -1377,9 +1405,25 @@ type 'a t = {
            bottom_up a parent newconf next jump_fun root false init accu
 
        and prepare_topdown a t noright =
-(*       pr "Going top down on tree with tag %s\n%!" 
-           (if Tree.is_nil t then "###" else (Tag.to_string(Tree.tag t))); *)
-         let r = cons a.states Nil in
+         let tag = Tree.tag t in
+(*       pr "Going top down on tree with tag %s = %s "  
+           (if Tree.is_nil t then "###" else (Tag.to_string(Tree.tag t))) (Tree.dump_node t); *)
+         let r = 
+           try
+             Hashtbl.find h_tdconf tag
+           with
+             | Not_found -> 
+                 let res = Hashtbl.fold (fun q l acc -> 
+                                           if List.exists (fun (ts,_) -> TagSet.mem tag ts) l
+                                           then Ptset.add q acc
+                                           else acc) a.phi Ptset.empty
+                 in Hashtbl.add h_tdconf tag res;res
+         in 
+(*       let _ = pr ", among ";
+           pr_st fmt (Ptset.elements r);
+           pr "\n%!";
+         in *)
+         let r = cons r Nil in
          let set,res = top_down (~noright:noright) a t r t 1 in
          let set = match set with
            | Cons(x,_,Nil) ->x
@@ -1392,7 +1436,7 @@ type 'a t = {
 
 
 
-       let run_bottom_up_contains a t =
+       let run_bottom_up a t k =
          let trlist = Hashtbl.find a.phi (Ptset.choose a.init)
          in
          let init = List.fold_left 
@@ -1400,12 +1444,18 @@ type 'a t = {
               Ptset.union acc (let (_,_,l) = fst (f.st) in l))
            Ptset.empty trlist
          in
-         let tree1 = Tree.text_below t in
-         let jump_fun = fun tree -> Tree.text_next tree t  in
+         let tree1,jump_fun =
+           match k with
+             | `TAG (tag) -> 
+                 (*Tree.tagged_lowest t tag, fun tree -> Tree.tagged_next tree tag*)
+                 (Tree.tagged_desc tag t, fun tree -> Tree.tagged_foll_below tag tree t)
+             | `CONTAINS(_) -> (Tree.text_below t,fun tree -> Tree.text_next tree t)
+             | _ -> assert false
+         in
          let tree2 = jump_fun tree1 in
          let rec loop tree next acc = 
-(*         let _ = pr "\n_________________________\nNew iteration\n" in *)
-(*         let _ = pr "Jumping to %s\n%!" (Tree.dump_node tree) in  *)
+(*         let _ = pr "\n_________________________\nNew iteration\n" in 
+           let _ = pr "Jumping to %s\n%!" (Tree.dump_node tree) in  *)
            let acc,conf,next_of_next = bottom_up a tree 
              Configuration.empty next jump_fun (Tree.root tree) true init acc
            in 
@@ -1423,21 +1473,10 @@ type 'a t = {
          loop tree1 tree2 RS.empty
 
 
-
-
-
-
-
-
-
-
-
-
-
     end
           
     let top_down_count a t = let module RI = Run(Integer) in Integer.length (RI.run_top_down a t)
     let top_down a t = let module RI = Run(IdSet) in (RI.run_top_down a t)
-    let bottom_up_count_contains a t = let module RI = Run(Integer) in Integer.length (RI.run_bottom_up_contains a t)
-    let bottom_up_count a t = failwith "not implemented"
+    let bottom_up_count a t k = let module RI = Run(Integer) in Integer.length (RI.run_bottom_up a t k)
+