Random fixes
authorkim <kim@3cdefd35-fc62-479d-8e8d-bae585ffb9ca>
Mon, 7 Feb 2011 13:23:28 +0000 (13:23 +0000)
committerkim <kim@3cdefd35-fc62-479d-8e8d-bae585ffb9ca>
Mon, 7 Feb 2011 13:23:28 +0000 (13:23 +0000)
git-svn-id: svn+ssh://idea.nguyen.vg/svn/sxsi/trunk/xpathcomp@948 3cdefd35-fc62-479d-8e8d-bae585ffb9ca

ata.ml
tree.ml
tree.mli
xPath.ml

diff --git a/ata.ml b/ata.ml
index 1b310dc..c2a133b 100644 (file)
--- a/ata.ml
+++ b/ata.ml
@@ -6,14 +6,14 @@ type jump_kind = [ `TAG of Tag.t | `CONTAINS of string | `NOTHING ]
 (* Todo : move elsewhere *)
 external vb : bool -> int = "%identity"
 
-module State : 
-sig 
-  include Sigs.T with type t = int 
-  val make : unit -> t 
+module State :
+sig
+  include Sigs.T with type t = int
+  val make : unit -> t
 end =
 struct
   type t = int
-  let make = 
+  let make =
     let id = ref ~-1 in
     fun () -> incr id; !id
 
@@ -22,13 +22,13 @@ struct
   external hash : t -> int =  "%identity"
   let print fmt x = Format.fprintf fmt "%i" x
   let dump fmt x = print fmt x
-  let check x = 
+  let check x =
     if x < 0 then failwith (Printf.sprintf "State: Assertion %i < 0 failed" x)
 end
 
-module StateSet = 
+module StateSet =
 struct
-  include Ptset.Make ( struct type t = int 
+  include Ptset.Make ( struct type t = int
                              type data = t
                              external hash : t -> int = "%identity"
                              external uid : t -> Uid.t = "%identity"
@@ -37,8 +37,8 @@ struct
                              external node : t -> int = "%identity"
                              external with_id : Uid.t -> t = "%identity"
                       end
-                    ) 
-  let print ppf s = 
+                    )
+  let print ppf s =
     Format.pp_print_string ppf "{ ";
     iter (fun i -> Format.fprintf ppf "%i " i) s;
     Format.pp_print_string ppf "}";
@@ -47,7 +47,7 @@ end
 
 module Formula =
 struct
-    type 'hcons expr = 
+    type 'hcons expr =
       | False | True
       | Or of 'hcons * 'hcons
       | And of 'hcons * 'hcons
@@ -59,37 +59,37 @@ struct
       st : (StateSet.t*StateSet.t*StateSet.t)*(StateSet.t*StateSet.t*StateSet.t);
       size: int; (* Todo check if this is needed *)
     }
-       
-    external hash_const_variant : [> ] -> int = "%identity" 
+
+    external hash_const_variant : [> ] -> int = "%identity"
     module rec Node : Hcons.S with type data = Data.t = Hcons.Make (Data)
     and Data : Hashtbl.HashedType  with type t = Node.t node =
-    struct 
+    struct
     type t =  Node.t node
     let equal x y = x.size == y.size &&
       match x.pos,y.pos with
        | a,b when a == b -> true
-       | Or(xf1,xf2),Or(yf1,yf2) 
+       | Or(xf1,xf2),Or(yf1,yf2)
        | And(xf1,xf2),And(yf1,yf2)  -> (xf1 == yf1) && (xf2 == yf2)
        | Atom(d1,p1,s1), Atom(d2,p2,s2) -> d1 == d2 && (p1==p2) && s1 == s2
        | _ -> false
-    let hash f = 
+    let hash f =
       match f.pos with
        | False -> 0
        | True -> 1
        | Or (f1,f2) -> HASHINT3(PRIME2,Uid.to_int f1.Node.id, Uid.to_int f2.Node.id)
        | And (f1,f2) -> HASHINT3(PRIME3,Uid.to_int f1.Node.id, Uid.to_int f2.Node.id)
-       | Atom(d,p,s) -> HASHINT4(PRIME4,hash_const_variant d,vb p,s)       
+       | Atom(d,p,s) -> HASHINT4(PRIME4,hash_const_variant d,vb p,s)
     end
 
     type t = Node.t
     let hash x = x.Node.key
     let uid x = x.Node.id
-    let equal = Node.equal 
-    let expr f = f.Node.node.pos 
+    let equal = Node.equal
+    let expr f = f.Node.node.pos
     let st f = f.Node.node.st
     let size f = f.Node.node.size
-      
-    let prio f = 
+
+    let prio f =
       match expr f with
        | True | False -> 10
        | Atom _ -> 8
@@ -101,26 +101,26 @@ struct
       let _ = match expr f with
        | True -> Format.fprintf ppf "T"
        | False -> Format.fprintf ppf "F"
-       | And(f1,f2) -> 
+       | And(f1,f2) ->
            print ~parent:(prio f > prio f1) ppf f1;
            Format.fprintf ppf " ∧ ";
            print ~parent:(prio f > prio f2) ppf f2;
-       | Or(f1,f2) -> 
+       | Or(f1,f2) ->
            (print ppf f1);
            Format.fprintf ppf " ∨ ";
            (print ppf f2);
        | Atom(dir,b,s) -> Format.fprintf ppf "%s%s[%i]"
            (if b then "" else "¬")
-             (match  dir with 
-                | `Left ->  "↓₁" 
+             (match  dir with
+                | `Left ->  "↓₁"
                 | `Right -> "↓₂"
-                | `LLeft ->  "⇓₁" 
+                | `LLeft ->  "⇓₁"
                 | `RRight -> "⇓₂") s
       in
        if parent then Format.fprintf ppf ")"
-         
+
     let print ppf f =  print ~parent:false ppf f
-      
+
     let is_true f = (expr f) == True
     let is_false f = (expr f) == False
 
@@ -128,7 +128,7 @@ struct
     let cons pos neg s1 s2 size1 size2 =
       let nnode = Node.make { pos = neg; neg = (Obj.magic 0); st = s2; size = size2 } in
       let pnode = Node.make { pos = pos; neg = nnode ; st = s1; size = size1 }
-      in 
+      in
        (Node.node nnode).neg <- pnode; (* works because the neg field isn't taken into
                                            account for hashing ! *)
        pnode,nnode
@@ -136,7 +136,7 @@ struct
     let empty_triple = StateSet.empty,StateSet.empty,StateSet.empty
     let empty_hex = empty_triple,empty_triple
     let true_,false_ = cons True False empty_hex empty_hex 0 0
-    let atom_ d p s = 
+    let atom_ d p s =
       let si = StateSet.singleton s in
       let ss = match d with
        | `Left -> (si,StateSet.empty,si),empty_triple
@@ -149,21 +149,21 @@ struct
     let union_hex  ((l1,ll1,lll1),(r1,rr1,rrr1))  ((l2,ll2,lll2),(r2,rr2,rrr2)) =
       (StateSet.mem_union l1 l2 ,StateSet.mem_union ll1 ll2,StateSet.mem_union lll1 lll2),
       (StateSet.mem_union r1 r2 ,StateSet.mem_union rr1 rr2,StateSet.mem_union rrr1 rrr2)
-      
+
     let merge_states f1 f2 =
-      let sp = 
+      let sp =
        union_hex (st f1) (st f2)
-      and sn = 
+      and sn =
        union_hex (st (not_ f1)) (st (not_ f2))
       in
        sp,sn
 
-    let order f1 f2 = if uid f1  < uid f2 then f2,f1 else f1,f2 
+    let order f1 f2 = if uid f1  < uid f2 then f2,f1 else f1,f2
 
-    let or_ f1 f2 = 
+    let or_ f1 f2 =
       (* Tautologies: x|x, x|not(x) *)
 
-      if equal f1 f2 then f1 else        
+      if equal f1 f2 then f1 else
       if equal f1 (not_ f2) then true_ else
 
       (* simplification *)
@@ -173,19 +173,19 @@ struct
       if is_false f2 then f1 else
 
       (* commutativity of | *)
-      
+
       let f1,f2 = order f1 f2 in
       let psize = (size f1) + (size f2) in
       let nsize = (size (not_ f1)) + (size (not_ f2)) in
       let sp,sn = merge_states f1 f2 in
       fst (cons (Or(f1,f2)) (And(not_ f1,not_ f2)) sp sn psize nsize)
-             
-                     
-    let and_ f1 f2 = 
+
+
+    let and_ f1 f2 =
 
       (* Tautologies: x&x, x&not(x) *)
 
-      if equal f1 f2 then f1 else 
+      if equal f1 f2 then f1 else
       if equal f1 (not_ f2) then false_ else
 
        (* simplifications *)
@@ -194,14 +194,14 @@ struct
       if is_false f1 || is_false f2 then false_ else
       if is_true f1 then f2 else
       if is_true f2 then f1 else
-      
+
       (* commutativity of & *)
 
-      let f1,f2 = order f1 f2 in       
+      let f1,f2 = order f1 f2 in
       let psize = (size f1) + (size f2) in
       let nsize = (size (not_ f1)) + (size (not_ f2)) in
       let sp,sn = merge_states f1 f2 in
-       fst (cons (And(f1,f2)) (Or(not_ f1,not_ f2)) sp sn psize nsize)               
+       fst (cons (And(f1,f2)) (Or(not_ f1,not_ f2)) sp sn psize nsize)
     module Infix = struct
     let ( +| ) f1 f2 = or_ f1 f2
     let ( *& ) f1 f2 = and_ f1 f2
@@ -209,19 +209,19 @@ struct
     let ( *- ) d s = atom_ d false s
     end
 end
-  
+
 module Transition = struct
-  
+
   type node = State.t*TagSet.t*bool*Formula.t*bool
   include Hcons.Make(struct
                       type t = node
                       let hash (s,ts,m,f,b) = HASHINT5(s,Uid.to_int (TagSet.uid ts),
                                                        Uid.to_int (Formula.uid f),
                                                        vb m,vb b)
-                      let equal (s,ts,b,f,m) (s',ts',b',f',m') = 
+                      let equal (s,ts,b,f,m) (s',ts',b',f',m') =
                         s == s' && ts == ts' && b==b' && m==m' && f == f'
                     end)
-    
+
   let print ppf f = let (st,ts,mark,form,b) = node f in
     Format.fprintf ppf "(%i, " st;
     TagSet.print ppf ts;
@@ -239,20 +239,20 @@ module Transition = struct
 
 end
 
-module Formlist = struct 
+module Formlist = struct
   include Hlist.Make(Transition)
-  let print ppf fl = 
+  let print ppf fl =
     iter (fun t -> Transition.print ppf t; Format.pp_print_newline ppf ()) fl
 end
 
-module Formlistlist = 
+module Formlistlist =
 struct
   include Hlist.Make(Formlist)
   let print ppf fll =
     iter (fun fl -> Formlist.print ppf fl; Format.pp_print_newline ppf ())fll
 end
-  
-type 'a t = { 
+
+type 'a t = {
     id : int;
     mutable states : StateSet.t;
     init : StateSet.t;
@@ -262,21 +262,21 @@ type 'a t = {
     query_string: string;
  }
 
-       
-let dump ppf a = 
+
+let dump ppf a =
   Format.fprintf ppf "Automaton (%i) :\n" a.id;
   Format.fprintf ppf "States : "; StateSet.print ppf a.states;
   Format.fprintf ppf "\nInitial states : "; StateSet.print ppf a.init;
   Format.fprintf ppf "\nAlternating transitions :\n";
-  let l = Hashtbl.fold (fun k t acc -> 
+  let l = Hashtbl.fold (fun k t acc ->
                          (List.map (fun (ts,tr) -> (ts,k),Transition.node tr) t) @ acc) a.trans [] in
-  let l = List.sort (fun ((tsx,x),_) ((tsy,y),_) -> 
+  let l = List.sort (fun ((tsx,x),_) ((tsy,y),_) ->
                       if y-x == 0 then TagSet.compare tsy tsx else y-x) l in
-  let maxh,maxt,l_print = 
+  let maxh,maxt,l_print =
     List.fold_left (
-      fun (maxh,maxt,l) ((ts,q),(_,_,b,f,_)) ->                          
-       let s = 
-         if TagSet.is_finite ts 
+      fun (maxh,maxt,l) ((ts,q),(_,_,b,f,_)) ->
+       let s =
+         if TagSet.is_finite ts
          then "{" ^ (TagSet.fold (fun t a -> a ^ " '" ^ (Tag.to_string t)^"'") ts "") ^" }"
          else let cts = TagSet.neg ts in
          if TagSet.is_empty cts then "*" else
@@ -286,7 +286,7 @@ let dump ppf a =
        let s = Printf.sprintf "(%s,%i)" s q in
        let s_frm =
          Formula.print Format.str_formatter f;
-         Format.flush_str_formatter()     
+         Format.flush_str_formatter()
        in
          (max (String.length s) maxh, max (String.length s_frm) maxt,
           (s,(if b then "⇒" else "→"),s_frm)::l)) (0,0,[]) l
@@ -295,20 +295,20 @@ let dump ppf a =
     List.iter (fun (s,m,f) -> let s = s ^ (String.make (maxh-(String.length s)) ' ') in
                 Format.fprintf ppf "%s %s %s\n" s m f) l_print;
     Format.fprintf ppf "%s\n%!" (String.make (maxt+maxh+3) '_')
-    
+
 
 module FormTable = Hashtbl.Make(struct
                                  type t = Formula.t*StateSet.t*StateSet.t
                                  let equal (f1,s1,t1) (f2,s2,t2) =
                                    f1 == f2 && s1 == s2 && t1 == t2
-                                 let hash (f,s,t) = 
+                                 let hash (f,s,t) =
                                    HASHINT3(Uid.to_int (Formula.uid f),
                                             Uid.to_int (StateSet.uid s),
                                             Uid.to_int (StateSet.uid t))
                                end)
 module F = Formula
 
-let eval_form_bool = 
+let eval_form_bool =
   let h_f = FormTable.create BIG_H_SIZE in
     fun f s1 s2 ->
       let rec loop f =
@@ -316,18 +316,18 @@ let eval_form_bool =
          | F.True -> true,true,true
          | F.False -> false,false,false
          | F.Atom((`Left|`LLeft),b,q) ->
-             if b == (StateSet.mem q s1) 
-             then (true,true,false) 
+             if b == (StateSet.mem q s1)
+             then (true,true,false)
              else false,false,false
-         | F.Atom(_,b,q) -> 
-             if b == (StateSet.mem q s2) 
+         | F.Atom(_,b,q) ->
+             if b == (StateSet.mem q s2)
              then (true,false,true)
-             else false,false,false    
-         | f' -> 
+             else false,false,false
+         | f' ->
              try FormTable.find h_f (f,s1,s2)
              with Not_found -> let r =
                match f' with
-                 | F.Or(f1,f2) ->          
+                 | F.Or(f1,f2) ->
                      let b1,rl1,rr1 = loop f1
                      in
                        if b1 && rl1 && rr1 then (true,true,true)  else
@@ -335,11 +335,11 @@ let eval_form_bool =
                          let rl1,rr1 = if b1 then rl1,rr1 else false,false
                          and rl2,rr2 = if b2 then rl2,rr2 else false,false
                          in (b1 || b2, rl1||rl2,rr1||rr2)
-                              
-                 | F.And(f1,f2) -> 
+
+                 | F.And(f1,f2) ->
                      let b1,rl1,rr1 = loop f1 in
                        if b1 && rl1 && rr1 then (true,true,true) else
-                         if b1 then 
+                         if b1 then
                            let b2,rl2,rr2 = loop f2 in
                              if b2 then (true,rl1||rl2,rr1||rr2) else (false,false,false)
                          else (false,false,false)
@@ -347,31 +347,31 @@ let eval_form_bool =
              in FormTable.add h_f (f,s1,s2) r;r
       in loop f
 
-          
+
 module FTable = Hashtbl.Make(struct
                               type t = Tag.t*Formlist.t*StateSet.t*StateSet.t
                               let equal (tg1,f1,s1,t1) (tg2,f2,s2,t2) =
                                 tg1 == tg2 && f1 == f2 &&  s1 == s2 && t1 == t2;;
-                              let hash (tg,f,s,t) =  
+                              let hash (tg,f,s,t) =
                                 HASHINT4(tg, Uid.to_int (Formlist.uid f),
                                          Uid.to_int (StateSet.uid s),
                                          Uid.to_int (StateSet.uid t))
                             end)
 
 
-let h_f = FTable.create BIG_H_SIZE 
+let h_f = FTable.create BIG_H_SIZE
 type merge_conf = NO | ONLY1 | ONLY2 | ONLY12 | MARK | MARK1 | MARK2 | MARK12
 (* 000 001 010 011 100 101 110 111 *)
 let eval_formlist tag s1 s2 fl =
   let rec loop fl =
-          try 
+          try
            FTable.find h_f (tag,fl,s1,s2)
-         with 
-           | Not_found  -> 
+         with
+           | Not_found  ->
                match Formlist.node fl with
                  | Formlist.Cons(f,fll) ->
                      let q,ts,mark,f,_ = Transition.node f in
-                     let b,b1,b2 = 
+                     let b,b1,b2 =
                        if TagSet.mem tag ts then eval_form_bool f s1 s2 else (false,false,false)
                      in
                      let (s,(b',b1',b2',amark)) as res = loop fll in
@@ -379,7 +379,7 @@ let eval_formlist tag s1 s2 fl =
                      else res
                      in FTable.add h_f (tag,fl,s1,s2) r;r
                  | Formlist.Nil -> StateSet.empty,(false,false,false,false)
-  in 
+  in
   let r,conf = loop fl
   in
   r,(match  conf with
@@ -397,41 +397,41 @@ let bool_of_merge conf =
   match  conf with
     | NO -> false,false,false,false
     | ONLY1 -> true,true,false,false
-    | ONLY2 -> true,false,true,false 
-    | ONLY12 -> true,true,true,false 
+    | ONLY2 -> true,false,true,false
+    | ONLY12 -> true,true,true,false
     | MARK -> true,false,false,true
     | MARK1 -> true,true,false,true
     | MARK2 -> true,false,true,true
     | MARK12 -> true,true,true,true
 
 
-let tags_of_state a q = 
-  Hashtbl.fold  
-    (fun p l acc -> 
-       if p == q then List.fold_left 
-        (fun acc (ts,t) -> 
+let tags_of_state a q =
+  Hashtbl.fold
+    (fun p l acc ->
+       if p == q then List.fold_left
+        (fun acc (ts,t) ->
            let _,_,_,_,aux = Transition.node t in
              if aux then acc else
                TagSet.cup ts acc) acc l
-        
+
        else acc) a.trans TagSet.empty
-      
-      
 
-    let tags a qs = 
+
+
+    let tags a qs =
       let ts = Ptset.Int.fold (fun q acc -> TagSet.cup acc (tags_of_state a q)) qs TagSet.empty
       in
-       if TagSet.is_finite ts 
+       if TagSet.is_finite ts
        then `Positive(TagSet.positive ts)
        else `Negative(TagSet.negative ts)
-       
+
     let inter_text a b =
       match b with
        | `Positive s -> let r = Ptset.Int.inter a s in (r,Ptset.Int.mem Tag.pcdata r, true)
        | `Negative s -> let r = Ptset.Int.diff a s in (r, Ptset.Int.mem Tag.pcdata r, false)
-      
 
-    module type ResultSet = 
+
+    module type ResultSet =
     sig
       type t
       type elt = [` Tree ] Tree.node
@@ -442,10 +442,10 @@ let tags_of_state a q =
       val fold : ( elt -> 'a -> 'a) -> t -> 'a -> 'a
       val map : ( elt -> elt) -> t -> t
       val length : t -> int
-      val merge : merge_conf -> elt -> t -> t -> t 
+      val merge : merge_conf -> elt -> t -> t -> t
       val mk_quick_tag_loop : (elt -> elt -> 'a*t array) -> 'a -> int -> Tree.t -> Tag.t -> (elt -> elt -> 'a*t array)
       val mk_quick_star_loop : (elt -> elt -> 'a*t array) -> 'a -> int -> Tree.t -> (elt -> elt -> 'a*t array)
-      
+
     end
 
     module Integer : ResultSet =
@@ -460,7 +460,7 @@ let tags_of_state a q =
       let fold _ _ _ = failwith "fold not implemented"
       let map _ _ = failwith "map not implemented"
       let length x = x
-      let merge2 conf t res1 res2 = 
+      let merge2 conf t res1 res2 =
        let rb,rb1,rb2,mark = conf in
        if rb then
          let res1 = if rb1 then res1 else 0
@@ -469,18 +469,18 @@ let tags_of_state a q =
            if mark then 1+res1+res2
            else res1+res2
        else 0
-      let merge conf t res1 res2 = 
+      let merge conf t res1 res2 =
        match conf with
-         | NO -> 0                         
-         | ONLY1 -> res1                
-         | ONLY2 -> res2           
-         | ONLY12 -> res1+res2     
+         | NO -> 0
+         | ONLY1 -> res1
+         | ONLY2 -> res2
+         | ONLY12 -> res1+res2
          | MARK -> 1
-         | MARK1 -> res1+1         
-         | MARK2 -> res2+1         
-         | MARK12 -> res1+res2+1   
+         | MARK1 -> res1+1
+         | MARK2 -> res2+1
+         | MARK12 -> res1+res2+1
       let merge conf _ res1 res2 =
-       let conf = Obj.magic conf in 
+       let conf = Obj.magic conf in
        (conf lsr 2) + ((conf land 0b10) lsr 1)*res2 + (conf land 0b1)*res1
 
 
@@ -488,38 +488,38 @@ let tags_of_state a q =
        fun t ctx ->
          (sl, Array.make ss (Tree.subtree_tags tree tag t))
       let mk_quick_star_loop _ sl ss tree = ();
-       fun t ctx -> 
+       fun t ctx ->
          (sl, Array.make ss (Tree.subtree_elements tree t))
-               
+
     end
 
-    module IdSet : ResultSet= 
+    module IdSet : ResultSet=
     struct
       type elt = [`Tree] Tree.node
-      type node = Nil 
-                 | Cons of elt * node 
+      type node = Nil
+                 | Cons of elt * node
                  | Concat of node*node
-   
+
       and t = { node : node;
                length :  int }
 
       let empty = { node = Nil; length = 0 }
-       
+
       let cons e t = { node = Cons(e,t.node); length = t.length+1 }
       let concat t1 t2 = { node = Concat(t1.node,t2.node); length = t1.length+t2.length }
-      let append e t = { node = Concat(t.node,Cons(e,Nil)); length = t.length+1 } 
-       
-      let fold f l acc = 
+      let append e t = { node = Concat(t.node,Cons(e,Nil)); length = t.length+1 }
+
+      let fold f l acc =
        let rec loop acc t = match t with
          | Nil -> acc
          | Cons (e,t) -> loop (f e acc) t
          | Concat (t1,t2) -> loop (loop acc t1) t2
        in
          loop acc l.node
-           
+
       let length l = l.length
-       
-       
+
+
       let iter f l =
        let rec loop = function
          | Nil -> ()
@@ -528,14 +528,14 @@ let tags_of_state a q =
        in loop l.node
 
       let map f l =
-       let rec loop = function 
+       let rec loop = function
          | Nil -> Nil
          | Cons(e,t) -> Cons(f e, loop t)
          | Concat(t1,t2) -> Concat(loop t1,loop t2)
        in
          { l with node = loop l.node }
-           
-      let merge conf t res1 res2 = 
+
+      let merge conf t res1 res2 =
        match conf with
           NO -> empty
          | MARK -> cons t empty
@@ -561,25 +561,25 @@ let tags_of_state a q =
       external next : bits -> int -> int = "caml_result_set_next" "noalloc"
       external count : bits -> int  = "caml_result_set_count" "noalloc"
       external clear : bits -> elt -> elt -> unit = "caml_result_set_clear" "noalloc"
-        
+
       external set_tag_bits : bits -> Tag.t -> Tree.t -> elt -> elt = "caml_set_tag_bits" "noalloc"
-      type t = 
+      type t =
         { segments : elt list;
           bits : bits;
         }
 
-      let ebits = 
+      let ebits =
        let size = (Tree.subtree_size Doc.doc Tree.root) in
        create_empty (size*2+1)
 
       let empty = { segments = [];
                    bits = ebits }
-       
-      let cons e t = 
+
+      let cons e t =
        let rec loop l = match l with
          | [] -> { bits = (set t.bits (Obj.magic e);t.bits);
                    segments = [ e ] }
-         | p::r -> 
+         | p::r ->
              if Tree.is_binary_ancestor Doc.doc e p then
              loop r
              else
@@ -587,7 +587,7 @@ let tags_of_state a q =
                segments = e::l }
        in
        loop t.segments
-                   
+
       let concat t1 t2 =
        if t2.segments == [] then t1
        else
@@ -596,24 +596,24 @@ let tags_of_state a q =
        let h2 = List.hd t2.segments in
        let rec loop l = match l with
          | [] -> t2.segments
-         | p::r -> 
+         | p::r ->
              if Tree.is_binary_ancestor Doc.doc p h2 then
              l
              else
              p::(loop r)
        in
        { bits = t1.bits;
-         segments = loop t1.segments 
+         segments = loop t1.segments
        }
 
       let iter f t =
-       let rec loop i = 
+       let rec loop i =
          if i == -1 then ()
          else (f ((Obj.magic i):elt);loop (next t.bits i))
        in loop (next t.bits 0)
-         
-      let fold f t acc = 
-       let rec loop i acc = 
+
+      let fold f t acc =
+       let rec loop i acc =
          if i == -1 then acc
          else loop (next t.bits i) (f ((Obj.magic i):elt) acc)
        in loop (next t.bits 0) acc
@@ -621,9 +621,9 @@ let tags_of_state a q =
       let map _ _ = failwith "noop"
       (*let length t = let cpt = ref 0 in
       iter (fun _ -> incr cpt) t; !cpt *)
-      let length t = count t.bits 
-      
-      let clear_bits t = 
+      let length t = count t.bits
+
+      let clear_bits t =
        let rec loop l = match l with
           [] -> ()
          | idx::ll ->
@@ -642,7 +642,7 @@ let tags_of_state a q =
          | [], [_] when rb2 -> if mark then cons elt t2 else t2
          | [_],[_] when rb1 && rb2 -> if mark then cons elt empty else
            concat t1 t2
-         | _ -> 
+         | _ ->
        let t1 = if rb1 then t1 else clear_bits t1
        and t2 = if rb2 then t2 else clear_bits t2
        in
@@ -652,7 +652,7 @@ let tags_of_state a q =
        let _ = clear_bits t1 in
        clear_bits t2
 
-      let merge conf t t1 t2 = 
+      let merge conf t t1 t2 =
        match t1.segments,t2.segments,conf with
          | _,_,NO -> let _ = clear_bits t1 in clear_bits t2
          | [],[],(MARK1|MARK2|MARK12|MARK) -> cons t empty
@@ -663,7 +663,7 @@ let tags_of_state a q =
          | [],[_],(MARK2|MARK12) -> cons t t2
          | [_],[_],ONLY12 -> concat t1 t2
          | [_],[_],MARK12 -> cons t empty
-         | _,_,MARK -> let _ = clear_bits t2 in cons t (clear_bits t1)     
+         | _,_,MARK -> let _ = clear_bits t2 in cons t (clear_bits t1)
          | _,_,ONLY1 -> let _ = clear_bits t2 in t1
          | _,_,ONLY2 -> let _ = clear_bits t1 in t2
          | _,_,ONLY12 -> concat t1 t2
@@ -672,12 +672,12 @@ let tags_of_state a q =
          | _,_,MARK12 ->  cons t (concat t1 t2)
 
       let mk_quick_tag_loop _ sl ss tree tag = ();
-       fun t _ ->        
+       fun t _ ->
          let res = empty in
          let first = set_tag_bits empty.bits tag tree t in
-         let res = 
-           if first == Tree.nil then res else 
-           cons first res 
+         let res =
+           if first == Tree.nil then res else
+           cons first res
          in
          (sl, Array.make ss res)
 
@@ -686,21 +686,21 @@ let tags_of_state a q =
     module Run (RS : ResultSet) =
     struct
 
-      module SList = struct 
+      module SList = struct
        include Hlist.Make (StateSet)
-       let print ppf l = 
+       let print ppf l =
          Format.fprintf ppf "[ ";
          begin
            match l.Node.node with
              | Nil -> ()
-             | Cons(s,ll) -> 
+             | Cons(s,ll) ->
                  StateSet.print ppf s;
                  iter (fun s -> Format.fprintf ppf "; ";
                        StateSet.print ppf s) ll
          end;
          Format.fprintf ppf "]%!"
-               
-           
+
+
       end
 
 
@@ -708,8 +708,8 @@ IFDEF DEBUG
 THEN
       module IntSet = Set.Make(struct type t = int let compare = (-) end)
 INCLUDE "html_trace.ml"
-             
-END            
+
+END
       module Trace =
       struct
        module HFname = Hashtbl.Make (struct
@@ -717,22 +717,22 @@ END
                                        let hash = Hashtbl.hash
                                        let equal = (==)
                                      end)
-         
+
        let h_fname = HFname.create 401
-         
-       let register_funname f s = 
+
+       let register_funname f s =
          HFname.add h_fname (Obj.repr  f) s
        let get_funname f = try HFname.find h_fname  (Obj.repr f) with _ -> "[anon_fun]"
 
 
 
        let mk_fun f s = register_funname f s;f
-       let mk_app_fun f arg s = 
-         let g = f arg in 
+       let mk_app_fun f arg s =
+         let g = f arg in
+         register_funname g ((get_funname f) ^ " " ^ s); g
+       let mk_app_fun2 f arg1 arg2 s =
+         let g = f arg1 arg2 in
          register_funname g ((get_funname f) ^ " " ^ s); g
-       let mk_app_fun2 f arg1 arg2 s = 
-         let g = f arg1 arg2 in 
-         register_funname g ((get_funname f) ^ " " ^ s); g 
 
       end
 
@@ -743,91 +743,91 @@ END
        struct
          type jump = [ `NIL | `ANY |`ANYNOTEXT | `JUMP ]
          type t = jump*Ptset.Int.t*Ptset.Int.t
-         let jts = function 
+         let jts = function
          | `JUMP -> "JUMP"
          | `NIL -> "NIL"
          | `ANY -> "ANY"
          | `ANYNOTEXT -> "ANYNOTEXT"
-         let merge_jump (j1,c1,l1) (j2,c2,l2) = 
+         let merge_jump (j1,c1,l1) (j2,c2,l2) =
            match j1,j2 with
              | _,`NIL -> (j1,c1,l1)
              | `NIL,_ -> (j2,c2,l2)
              | `ANY,_ -> (`ANY,Ptset.Int.empty,Ptset.Int.empty)
              | _,`ANY -> (`ANY,Ptset.Int.empty,Ptset.Int.empty)
-             | `ANYNOTEXT,_ -> 
+             | `ANYNOTEXT,_ ->
                  if Ptset.Int.mem Tag.pcdata (Ptset.Int.union c2 l2) then
                  (`ANY,Ptset.Int.empty,Ptset.Int.empty)
                  else
                  (`ANYNOTEXT,Ptset.Int.empty,Ptset.Int.empty)
-             | _,`ANYNOTEXT -> 
+             | _,`ANYNOTEXT ->
                  if Ptset.Int.mem Tag.pcdata (Ptset.Int.union c1 l1) then
                  (`ANY,Ptset.Int.empty,Ptset.Int.empty)
                  else
                  (`ANYNOTEXT,Ptset.Int.empty,Ptset.Int.empty)
              | `JUMP,`JUMP -> (`JUMP, Ptset.Int.union c1 c2,Ptset.Int.union l1 l2)
 
-         let merge_jump_list = function 
+         let merge_jump_list = function
            | [] -> `NIL,Ptset.Int.empty,Ptset.Int.empty
-           | p::r -> 
+           | p::r ->
                List.fold_left (merge_jump) p r
-             
-         let labels a s = 
-           Hashtbl.fold 
+
+         let labels a s =
+           Hashtbl.fold
            (
-             fun q l acc -> 
+             fun q l acc ->
                if (q == s)
-               then 
+               then
 
-                 (List.fold_left 
+                 (List.fold_left
                      (fun acc (ts,f) ->
                        let _,_,_,_,bur = Transition.node f in
-                       if bur then acc else TagSet.cup acc ts) 
+                       if bur then acc else TagSet.cup acc ts)
                    acc l)
                else acc ) a.trans TagSet.empty
          exception Found
-           
-         let is_rec a s access = 
+
+         let is_rec a s access =
            List.exists
              (fun (_,t) -> let _,_,_,f,_ = Transition.node t in
-             StateSet.mem s ((fun (_,_,x) -> x) (access (Formula.st f)))) (Hashtbl.find a.trans s) 
-                    
+             StateSet.mem s ((fun (_,_,x) -> x) (access (Formula.st f)))) (Hashtbl.find a.trans s)
+
          let is_final_marking a s =
            List.exists (fun (_,t) -> let _,_,m,f,_ = Transition.node t in m&& (Formula.is_true f))
              (Hashtbl.find a.trans s)
-             
-             
+
+
          let decide a c_label l_label dir_states dir =
-                       
-           let l = StateSet.fold 
-             (fun s l -> 
+
+           let l = StateSet.fold
+             (fun s l ->
                 let s_rec = is_rec a s (if dir then fst else snd) in
                 let s_rec = if dir then s_rec else
                 (* right move *)
                 is_rec a s fst
                 in
                 let s_lab = labels a s in
-                let jmp,cc,ll = 
+                let jmp,cc,ll =
                   if (not (TagSet.is_finite s_lab)) then
                   if TagSet.mem Tag.pcdata s_lab then  (`ANY,Ptset.Int.empty,Ptset.Int.empty)
                   else (`ANYNOTEXT,Ptset.Int.empty,Ptset.Int.empty)
-                  else 
-                  if s_rec 
-                  then (`JUMP,Ptset.Int.empty, TagSet.positive 
+                  else
+                  if s_rec
+                  then (`JUMP,Ptset.Int.empty, TagSet.positive
                           (TagSet.cap (TagSet.inj_positive l_label) s_lab))
-                  else (`JUMP,TagSet.positive 
+                  else (`JUMP,TagSet.positive
                           (TagSet.cap (TagSet.inj_positive c_label) s_lab),
                         Ptset.Int.empty )
                 in
-                  (if jmp != `ANY 
-                   && jmp != `ANYNOTEXT 
-                   && Ptset.Int.is_empty cc 
+                  (if jmp != `ANY
+                   && jmp != `ANYNOTEXT
+                   && Ptset.Int.is_empty cc
                    && Ptset.Int.is_empty ll
                    then (`NIL,Ptset.Int.empty,Ptset.Int.empty)
                    else  (jmp,cc,ll))::l) dir_states []
-           in merge_jump_list l                            
-           
-             
-       end 
+           in merge_jump_list l
+
+
+       end
 
 
 
@@ -836,16 +836,16 @@ END
          | `NIL -> (`NIL,f_nil)
          | `ANYNOTEXT -> `ANY,f_notext
          | `ANY -> `ANY,f_maytext
-         | `JUMP -> 
+         | `JUMP ->
              if Ptset.Int.is_empty cl then
              if Ptset.Int.is_singleton ll then
-             let tag = Ptset.Int.choose ll in 
+             let tag = Ptset.Int.choose ll in
              (`TAG(tag),Trace.mk_app_fun f_tn tag (Tag.to_string tag))
              else
              (`MANY(ll),Trace.mk_app_fun f_sn ll (string_of_ts ll))
              else if Ptset.Int.is_empty ll then
              if Ptset.Int.is_singleton cl then
-             let tag = Ptset.Int.choose cl in 
+             let tag = Ptset.Int.choose cl in
              (`TAG(tag),Trace.mk_app_fun f_t1 tag (Tag.to_string tag))
              else
              (`MANY(cl),Trace.mk_app_fun f_s1 cl (string_of_ts cl))
@@ -853,19 +853,19 @@ END
              (`ANY,Trace.mk_app_fun2 f_s1n cl ll ((string_of_ts cl) ^ " " ^ (string_of_ts ll)))
 
          | _ -> assert false
-         
+
       let choose_jump_down tree d =
        choose_jump d
          (Trace.mk_fun (fun _ -> Tree.nil) "Tree.mk_nil")
-         (Trace.mk_fun (Tree.tagged_child tree) "Tree.tagged_child") 
+         (Trace.mk_fun (Tree.tagged_child tree) "Tree.tagged_child")
          (Trace.mk_fun (Tree.select_child tree) "Tree.select_child")
          (Trace.mk_fun (Tree.tagged_descendant tree) "Tree.tagged_desc")
-         (Trace.mk_fun (Tree.select_descendant tree) "Tree.select_desc") 
+         (Trace.mk_fun (Tree.select_descendant tree) "Tree.select_desc")
          (Trace.mk_fun (fun _ _ -> Tree.first_child tree) "[FIRSTCHILD]Tree.select_child_desc")
          (Trace.mk_fun (Tree.first_element tree) "Tree.first_element")
-         (Trace.mk_fun (Tree.first_child tree) "Tree.first_child") 
+         (Trace.mk_fun (Tree.first_child tree) "Tree.first_child")
 
-      let choose_jump_next tree d = 
+      let choose_jump_next tree d =
        choose_jump d
          (Trace.mk_fun (fun _ _ -> Tree.nil) "Tree.mk_nil2")
          (Trace.mk_fun (Tree.tagged_following_sibling_below tree) "Tree.tagged_sibling_ctx")
@@ -873,13 +873,13 @@ END
          (Trace.mk_fun (Tree.tagged_following_below tree) "Tree.tagged_foll_ctx")
          (Trace.mk_fun (Tree.select_following_below tree) "Tree.select_foll_ctx")
          (Trace.mk_fun (fun _ _ -> Tree.next_sibling_below tree) "[NEXTSIBLING]Tree.select_sibling_foll_ctx")
-         (Trace.mk_fun (Tree.next_element_below tree) "Tree.next_element_ctx")   
-         (Trace.mk_fun (Tree.next_sibling_below tree) "Tree.node_sibling_ctx")   
-                         
-         
+         (Trace.mk_fun (Tree.next_element_below tree) "Tree.next_element_ctx")
+         (Trace.mk_fun (Tree.next_sibling_below tree) "Tree.node_sibling_ctx")
 
 
-      module CodeCache = 
+
+
+      module CodeCache =
       struct
        let get = Array.unsafe_get
        let set = Array.set
@@ -889,13 +889,13 @@ END
 
        let dummy = fun _ _ _ _ _ -> failwith "Uninitializd CodeCache"
        let default_line = Array.create 1024 dummy (* 1024 = max_tag *)
-       let create n = Array.create n default_line 
-       let init f = 
+       let create n = Array.create n default_line
+       let init f =
          for i = 0 to (Array.length default_line) - 1
          do
            default_line.(i) <- f
          done
-           
+
        let get_fun h slist tag =
          get (get h (Uid.to_int slist.SList.Node.id)) tag
 
@@ -906,7 +906,7 @@ END
            (set h (Uid.to_int slist.SList.Node.id) x;x)
          else tab
          in
-         set line tag data       
+         set line tag data
 
       end
 
@@ -914,46 +914,46 @@ END
        let rec loop acc = function 0 -> acc
          | n -> loop (SList.cons StateSet.empty acc) (n-1)
        in loop SList.nil n
-            
-     
+
+
       module Fold2Res = struct
        let get = Array.unsafe_get
-       let set = Array.set 
+       let set = Array.set
        external field1 : Obj.t -> int = "%field1"
        type t = Obj.t array array array array
-       let dummy_val = Obj.repr ((),2,()) 
+       let dummy_val = Obj.repr ((),2,())
 
        let default_line3 = Array.create BIG_A_SIZE dummy_val
        let default_line2 = Array.create BIG_A_SIZE default_line3
        let default_line1 = Array.create BIG_A_SIZE default_line2
 
        let create n = Array.create n default_line1
-       
-       let find h tag fl s1 s2 : SList.t*bool*(merge_conf array) = 
+
+       let find h tag fl s1 s2 : SList.t*bool*(merge_conf array) =
          let l1 = get h tag in
          let l2 = get l1 (Uid.to_int fl.Formlistlist.Node.id) in
          let l3 = get l2 (Uid.to_int s1.SList.Node.id) in
          Obj.magic (get l3 (Uid.to_int s2.SList.Node.id))
-         
+
        let is_valid b = (Obj.magic b) != 2
        let get_replace tab idx default =
          let e = get tab idx in
          if e == default then
          let ne = Array.copy e in (set tab idx ne;ne)
          else e
-         
+
        let add h tag fl s1 s2 (data: SList.t*bool*(merge_conf array)) =
          let l1 = get_replace h tag default_line1 in
          let l2 = get_replace l1 (Uid.to_int fl.Formlistlist.Node.id) default_line2 in
-         let l3 = get_replace l2 (Uid.to_int s1.SList.Node.id) default_line3  in 
+         let l3 = get_replace l2 (Uid.to_int s1.SList.Node.id) default_line3  in
          set l3 (Uid.to_int s2.SList.Node.id) (Obj.repr data)
       end
 
-            
 
-      
-      let top_down ?(noright=false) a tree t slist ctx slot_size td_trans h_fold2=     
-       let pempty = empty_size slot_size in    
+
+
+      let top_down ?(noright=false) a tree t slist ctx slot_size td_trans h_fold2=
+       let pempty = empty_size slot_size in
        let rempty = Array.make slot_size RS.empty in
        (* evaluation starts from the right so we put sl1,res1 at the end *)
        let eval_fold2_slist fll t tag (sl2,res2) (sl1,res1) =
@@ -961,19 +961,19 @@ END
          let r,b,btab = Fold2Res.find h_fold2 tag fll sl1 sl2  in
          if Fold2Res.is_valid b then
          begin
-           if b then for i=0 to slot_size - 1 do 
+           if b then for i=0 to slot_size - 1 do
              res.(0) <- RS.merge btab.(0) t res1.(0) res2.(0);
            done;
            r,res
          end
          else
-         begin 
-           let btab = Array.make slot_size NO in           
-           let rec fold l1 l2 fll i aq ab = 
+         begin
+           let btab = Array.make slot_size NO in
+           let rec fold l1 l2 fll i aq ab =
              match fll.Formlistlist.Node.node,
                l1.SList.Node.node,
                l2.SList.Node.node
-             with           
+             with
                | Formlistlist.Cons(fl,fll),
                 SList.Cons(s1,ll1),
                 SList.Cons(s2,ll2) ->
@@ -984,7 +984,7 @@ END
                | _ -> aq,ab
            in
            let r,b = fold sl1 sl2 fll 0 SList.nil false in
-           Fold2Res.add h_fold2 tag fll sl1 sl2 (r,b,btab); 
+           Fold2Res.add h_fold2 tag fll sl1 sl2 (r,b,btab);
            if b then for i=0 to slot_size - 1 do
              res.(i) <- RS.merge btab.(i) t res1.(i) res2.(i);
            done;
@@ -1003,75 +1003,75 @@ END
            (CodeCache.get_opcode td_trans slist tag)
            *)
        and loop_tag t ctx slist tag  =
-         if t == Tree.nil then null_result else 
+         if t == Tree.nil then null_result else
          (CodeCache.get_fun td_trans slist tag) t ctx slist tag false
-           (* get_trans t ctx slist tag false 
+           (* get_trans t ctx slist tag false
            (CodeCache.get_opcode td_trans slist tag) *)
-         
-       and loop_no_right t ctx slist _  = 
-         if t == Tree.nil then null_result else 
+
+       and loop_no_right t ctx slist _  =
+         if t == Tree.nil then null_result else
          let tag = Tree.tag tree t in
          (CodeCache.get_fun td_trans slist tag) t ctx slist tag true
-           (* get_trans t ctx slist tag true 
+           (* get_trans t ctx slist tag true
               (CodeCache.get_opcode td_trans slist tag) *)
            (*
-       and get_trans t ctx slist tag noright opcode = 
+       and get_trans t ctx slist tag noright opcode =
          match opcode with
-           | OpCode.K0 fll -> 
+           | OpCode.K0 fll ->
                eval_fold2_slist fll t tag empty_res empty_res
 
-           | OpCode.K1 (fll,first,llist,tag1) -> 
+           | OpCode.K1 (fll,first,llist,tag1) ->
                eval_fold2_slist fll t tag empty_res
                  (loop_tag (first t) t llist tag1)
 
            | OpCode.K2 (fll,first,llist) ->
                eval_fold2_slist fll t tag empty_res
                  (loop (first t) t llist)
-                 
+
            | OpCode.K3 (fll,next,rlist,tag2) ->
-                eval_fold2_slist fll t tag 
+                eval_fold2_slist fll t tag
                  (loop_tag (next t ctx) ctx rlist tag2)
                  empty_res
            | OpCode.K4 (fll,next,rlist) ->
-               eval_fold2_slist fll t tag 
-                 (loop (next t ctx) ctx rlist)           
+               eval_fold2_slist fll t tag
+                 (loop (next t ctx) ctx rlist)
                  empty_res
 
            | OpCode.K5 (fll,next,rlist,tag2,first,llist,tag1) ->
                eval_fold2_slist fll t tag
-                 (loop_tag (next t ctx) ctx rlist tag2)                  
+                 (loop_tag (next t ctx) ctx rlist tag2)
                  (loop_tag (first t) t llist tag1)
 
            | OpCode.K6 (fll,next,rlist,first,llist,tag1) ->
                eval_fold2_slist fll t tag
-                 (loop (next t ctx) ctx rlist)           
+                 (loop (next t ctx) ctx rlist)
                  (loop_tag (first t) t llist tag1)
 
            | OpCode.K7 (fll,next,rlist,tag2,first,llist) ->
                eval_fold2_slist fll t tag
-                 (loop_tag (next t ctx) ctx rlist tag2)                  
+                 (loop_tag (next t ctx) ctx rlist tag2)
                  (loop (first t) t llist)
 
            | OpCode.K8 (fll,next,rlist,first,llist) ->
                eval_fold2_slist fll t tag
-                 (loop (next t ctx) ctx rlist)           
+                 (loop (next t ctx) ctx rlist)
                  (loop (first t) t llist)
 
-           | OpCode.KDefault _ -> 
+           | OpCode.KDefault _ ->
                mk_trans t ctx tag slist noright
            *)
-       and mk_trans t ctx slist tag noright = 
-         let fl_list,llist,rlist,ca,da,sa,fa = 
-           SList.fold 
+       and mk_trans t ctx slist tag noright =
+         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 = 
+                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) 
+                    (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 
+                            then
                             let _,_,_,f,_ = t.Transition.node in
                             let (child,desc,below),(sibl,foll,after) = Formula.st f in
                             (Formlist.cons t fl_acc,
@@ -1080,32 +1080,32 @@ END
                              StateSet.union child c_acc,
                              StateSet.union desc d_acc,
                              StateSet.union sibl s_acc,
-                             StateSet.union foll f_acc)                 
+                             StateSet.union foll f_acc)
                             else acc ) acc (
-                           try Hashtbl.find a.trans q 
+                           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 (Formlistlist.cons fl fll_acc), (SList.cons ll lllacc), (SList.cons rr rllacc),ca,da,sa,fa)
              slist (Formlistlist.nil,SList.nil,SList.nil,StateSet.empty,StateSet.empty,StateSet.empty,StateSet.empty)
-         in                    
+         in
          (* Logic to chose the first and next function *)
          let tags_child,tags_below,tags_siblings,tags_after = Tree.tags tree tag in
          let d_f = Algebra.decide a tags_child tags_below (StateSet.union ca da) true in
          let d_n = Algebra.decide a tags_siblings tags_after (StateSet.union sa fa) false in
          let f_kind,first = choose_jump_down tree d_f
          and n_kind,next = if noright then (`NIL, fun _ _ -> Tree.nil )
-         else choose_jump_next tree d_n in 
+         else choose_jump_next tree d_n in
          let empty_res = null_result in
          let fll = fl_list in
           let cont =
             match f_kind,n_kind with
               | `NIL,`NIL -> (*OpCode.K0(fl_list) *)
                  fun t _ _ tag _ -> eval_fold2_slist fll t tag empty_res empty_res
-               
+
              |  _,`NIL -> (
                    match f_kind with
                      |`TAG(tag1) -> (*OpCode.K1(fl_list,first,llist,tag1) *)
@@ -1119,41 +1119,41 @@ END
                   match n_kind with
                     |`TAG(tag2) -> (*OpCode.K3(fl_list,next,rlist,tag2) *)
                       fun t ctx _ tag _ ->
-                        eval_fold2_slist fll t tag 
+                        eval_fold2_slist fll t tag
                           (loop_tag (next t ctx) ctx rlist tag2)
                           empty_res
 
                     | _ -> (*OpCode.K4(fl_list,next,rlist) *)
                        fun t ctx _ tag _ ->
-                         eval_fold2_slist fll t tag 
+                         eval_fold2_slist fll t tag
                            (loop (next t ctx) ctx rlist tag)
                            empty_res
-                        
+
                )
-                 
+
               | `TAG(tag1),`TAG(tag2) -> (*OpCode.K5(fl_list,next,rlist,tag2,first,llist,tag1) *)
-                 fun t ctx _ tag _ -> 
+                 fun t ctx _ tag _ ->
                    eval_fold2_slist fll t tag
-                     (loop_tag (next t ctx) ctx rlist tag2)              
+                     (loop_tag (next t ctx) ctx rlist tag2)
                      (loop_tag (first t) t llist tag1)
+
               | `TAG(tag1),`ANY -> (* OpCode.K6(fl_list,next,rlist,first,llist,tag1) *)
-                 fun t ctx _ tag _ -> 
+                 fun t ctx _ tag _ ->
                    eval_fold2_slist fll t tag
                      (loop (next t ctx) ctx rlist tag)
                      (loop_tag (first t) t llist tag1)
 
               | `ANY,`TAG(tag2) -> (* OpCode.K7(fl_list,next,rlist,tag2,first,llist) *)
-                 fun t ctx _ tag _ -> 
+                 fun t ctx _ tag _ ->
                    eval_fold2_slist fll t tag
-                     (loop_tag (next t ctx) ctx rlist tag2)              
+                     (loop_tag (next t ctx) ctx rlist tag2)
                      (loop (first t) t llist tag)
-                         
-                                                                  
+
+
               | _,_ -> (*OpCode.K8(fl_list,next,rlist,first,llist) *)
                  (*if SList.equal slist rlist && SList.equal slist llist
                    then
-                   let rec loop t ctx = 
+                   let rec loop t ctx =
                    if t == Tree.nil then empty_res else
                    let r1 = loop (first t) t
                    and r2 = loop (next t ctx) ctx
@@ -1161,17 +1161,17 @@ END
                    eval_fold2_slist fl_list t (Tree.tag tree t) r2 r1
                    in loop
                    else *)
-                  fun t ctx _ tag _ -> 
+                  fun t ctx _ tag _ ->
                    eval_fold2_slist fll t tag
-                     (loop (next t ctx) ctx rlist tag)           
+                     (loop (next t ctx) ctx rlist tag)
                      (loop (first t) t llist tag)
 
-             
+
 
          in
-         CodeCache.set_fun td_trans slist tag cont; 
+         CodeCache.set_fun td_trans slist tag cont;
          cont t ctx slist tag noright
-       in 
+       in
        let _ = CodeCache.init mk_trans in
        (if noright then loop_no_right else loop) t ctx slist Tag.dummy
 
@@ -1179,20 +1179,20 @@ END
       let run_top_down a tree =
        let init = SList.cons a.init SList.nil in
        let _,res = top_down a tree Tree.root init Tree.root 1 (CodeCache.create BIG_A_SIZE) (Fold2Res.create 1024)
-       in 
+       in
        D_IGNORE_(
          output_trace a tree "trace.html"
            (RS.fold (fun t a -> IntSet.add (Tree.id tree t) a) res.(0) IntSet.empty),
              res.(0))
       ;;
-      
 
 
 
 
-      module Code3Cache = 
+
+      module Code3Cache =
       struct
-       let get = Array.get             
+       let get = Array.get
        let set = Array.set
        let realloc a new_size default =
          let old_size = Array.length a in
@@ -1211,8 +1211,8 @@ END
                 }
 
 
-       let create () = 
-         { table = [||]; 
+       let create () =
+         { table = [||];
            default_elm = (fun _ _ _ _ -> failwith "Uninitialized Code3Cache.t structure\n");
            default_line = [||];
            access = 0;
@@ -1227,19 +1227,19 @@ END
            h.access <- 0;
            h.miss <- 0
          end
-           
-       let next_power_of_2 n = 
-         let rec loop i acc = 
+
+       let next_power_of_2 n =
+         let rec loop i acc =
            if acc == 0 then i
            else loop (i+1) (acc lsr 1)
          in
          1 lsl (loop 0 n)
-       
+
        let get_fun h slist tag =
          let _ = h.access <- h.access + 1 in
          let idx = Uid.to_int slist.StateSet.Node.id in
-         let line = 
-           if idx >= Array.length h.table then 
+         let line =
+           if idx >= Array.length h.table then
            let new_tab = realloc h.table (next_power_of_2 idx) h.default_line in
            let _ =  h.miss <- h.miss + 1; h.table <- new_tab in h.default_line
            else Array.unsafe_get h.table idx
@@ -1251,13 +1251,13 @@ END
 
        let set_fun (h : t) slist tag (data : fun_tree) =
          let idx = Uid.to_int slist.StateSet.Node.id in
-         let line = 
-           if idx >= Array.length h.table then 
+         let line =
+           if idx >= Array.length h.table then
            let new_tab = realloc h.table (next_power_of_2 idx) h.default_line in
            let _ =  h.table <- new_tab in h.default_line
            else Array.unsafe_get h.table idx
          in
-         let line = if line == h.default_line then 
+         let line = if line == h.default_line then
          let l = Array.copy line in Array.unsafe_set h.table idx l;l
          else line in
          let line = if tag >= Array.length line then
@@ -1268,8 +1268,8 @@ END
          Array.unsafe_set line tag data
 
 
-       let dump h = Array.iteri 
-         (fun id line -> if line != h.default_line then 
+       let dump h = Array.iteri
+         (fun id line -> if line != h.default_line then
           begin
             StateSet.print Format.err_formatter (StateSet.with_id (Uid.of_int id));
             Format.fprintf Format.err_formatter " -> ";
@@ -1292,58 +1292,58 @@ END
       module StaticEnv =
       struct
 
-       type t = { stack : Obj.t array; 
+       type t = { stack : Obj.t array;
                   mutable top : int; }
 
        let create () = { stack = Array.create BIG_A_SIZE (Obj.repr 0); top = 0 }
-       let add t e = 
+       let add t e =
          let _ = if t.top >= Array.length t.stack then failwith "Static Env overflow" in
          let i = t.top in Array.unsafe_set t.stack i e; t.top <- i + 1; i
 
        let get t i :'a = Obj.magic (Array.unsafe_get t.stack i)
       end
-         
+
       module Fold3Res = struct
        let get = Array.unsafe_get
-       let set = Array.set 
+       let set = Array.set
        external field1 : Obj.t -> int = "%field1"
        type t = Obj.t array array array array
-       let dummy_val = Obj.repr ((),2,()) 
+       let dummy_val = Obj.repr ((),2,())
 
        let default_line3 = Array.create 1024 dummy_val
        let default_line2 = Array.create BIG_A_SIZE default_line3
        let default_line1 = Array.create BIG_A_SIZE default_line2
 
        let create n = Array.create n default_line1
-       
-       let find h tag fl s1 s2 : StateSet.t*bool*merge_conf = 
+
+       let find h tag fl s1 s2 : StateSet.t*bool*merge_conf =
          let l1 = get h (Uid.to_int fl.Formlist.Node.id) in
          let l2 = get l1 (Uid.to_int s1.StateSet.Node.id) in
          let l3 = get l2 (Uid.to_int s2.StateSet.Node.id) in
          Obj.magic (get l3 tag)
-         
+
        let is_valid b = b != (Obj.magic dummy_val)
        let get_replace tab idx default =
          let e = get tab idx in
          if e == default then
          let ne = Array.copy e in (set tab idx ne;ne)
          else e
-         
+
        let add h tag fl s1 s2 (data: StateSet.t*bool*merge_conf) =
          let l1 = get_replace h (Uid.to_int fl.Formlist.Node.id) default_line1 in
          let l2 = get_replace l1 (Uid.to_int s1.StateSet.Node.id) default_line2 in
-         let l3 = get_replace l2 (Uid.to_int s2.StateSet.Node.id) default_line3 in 
+         let l3 = get_replace l2 (Uid.to_int s2.StateSet.Node.id) default_line3 in
          set l3 tag (Obj.repr data)
       end
 
 
       let empty_res = StateSet.empty,RS.empty
 
-      let top_down1 a tree t slist ctx td_trans h_fold2  =     
+      let top_down1 a tree t slist ctx td_trans h_fold2  =
        (* evaluation starts from the right so we put sl1,res1 at the end *)
        let env = StaticEnv.create () in
        let slist_reg = ref StateSet.empty in
-       let eval_fold2_slist fll t tag (sl2,res2) (sl1,res1) =   
+       let eval_fold2_slist fll t tag (sl2,res2) (sl1,res1) =
          let data = Fold3Res.find h_fold2 tag fll sl1 sl2  in
          if Fold3Res.is_valid data then
          let r,b,conf = data in
@@ -1353,7 +1353,7 @@ END
          let b = conf <> NO in
          (Fold3Res.add h_fold2 tag fll sl1 sl2 (r,b,conf);
           (r, if b then RS.merge conf t res1 res2 else RS.empty))
-        
+
        in
        let loop t ctx slist _ =
          if t == Tree.nil then empty_res else
@@ -1362,19 +1362,19 @@ END
 
        in
        let loop_tag t ctx slist tag =
-         if t == Tree.nil then empty_res else 
+         if t == Tree.nil then empty_res else
          (Code3Cache.get_fun td_trans slist tag) t ctx slist tag
-         
+
        in
-       let mk_trans t ctx slist tag = 
-         let fl_list,llist,rlist,ca,da,sa,fa = 
+       let mk_trans t ctx slist tag =
+         let fl_list,llist,rlist,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) 
+             (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 
+                     then
                      let _,_,_,f,_ = t.Transition.node in
                      let (child,desc,below),(sibl,foll,after) = Formula.st f in
                      (Formlist.cons t fl_acc,
@@ -1383,33 +1383,34 @@ END
                       StateSet.union child c_acc,
                       StateSet.union desc d_acc,
                       StateSet.union sibl s_acc,
-                      StateSet.union foll f_acc)                
+                      StateSet.union foll f_acc)
                      else acc ) acc (
-                    try Hashtbl.find a.trans q 
+                    try Hashtbl.find a.trans q
                     with
                        Not_found -> Printf.eprintf "Looking for state %i, doesn't exist!!!\n%!"
                          q;[]
                   )
-                  
+
              ) slist (Formlist.nil,StateSet.empty,StateSet.empty,
                       StateSet.empty,StateSet.empty,StateSet.empty,StateSet.empty)
 
-         in                    
+         in
          (* Logic to chose the first and next function *)
          let tags_child,tags_below,tags_siblings,tags_after = Tree.tags tree tag in
          let d_f = Algebra.decide a tags_child tags_below (StateSet.union ca da) true in
          let d_n = Algebra.decide a tags_siblings tags_after (StateSet.union sa fa) false in
          let f_kind,first = choose_jump_down tree d_f
-         and n_kind,next = choose_jump_next tree d_n in 
-
+         and n_kind,next = choose_jump_next tree d_n in
+         let f_kind, first = `ANY, (Tree.first_element tree)
+         and n_kind, next = `ANY, (Tree.next_element_below tree) in
           let cont =
             match f_kind,n_kind with
-              | `NIL,`NIL -> 
+              | `NIL,`NIL ->
                  fun t _ _ tag -> eval_fold2_slist fl_list t tag empty_res empty_res
-               
+
              |  _,`NIL -> (
                    match f_kind with
-                     |`TAG(tag1) -> 
+                     |`TAG(tag1) ->
                        (fun t _ _ tag -> eval_fold2_slist fl_list t tag empty_res
                          (loop_tag (first t) t llist tag1))
                     | _ ->
@@ -1418,68 +1419,68 @@ END
                 )
               | `NIL,_ -> (
                   match n_kind with
-                    |`TAG(tag2) -> 
+                    |`TAG(tag2) ->
                       fun t ctx _ tag  ->
-                        eval_fold2_slist fl_list t tag 
+                        eval_fold2_slist fl_list t tag
                           (loop_tag (next t ctx) ctx rlist tag2)
                           empty_res
 
-                    | _ -> 
+                    | _ ->
                        fun t ctx _ tag ->
-                         eval_fold2_slist fl_list t tag 
+                         eval_fold2_slist fl_list t tag
                            (loop (next t ctx) ctx rlist tag)
                            empty_res
-                        
+
                )
-                 
-              | `TAG(tag1),`TAG(tag2) -> 
-                 fun t ctx _ tag -> 
+
+              | `TAG(tag1),`TAG(tag2) ->
+                 fun t ctx _ tag ->
                    eval_fold2_slist fl_list t tag
-                     (loop_tag (next t ctx) ctx rlist tag2)              
+                     (loop_tag (next t ctx) ctx rlist tag2)
                      (loop_tag (first t) t llist tag1)
-              | `TAG(tag1),`ANY -> 
-                 fun t ctx _ tag -> 
+
+              | `TAG(tag1),`ANY ->
+                 fun t ctx _ tag ->
                    eval_fold2_slist fl_list t tag
                      (loop (next t ctx) ctx rlist tag)
                      (loop_tag (first t) t llist tag1)
 
-              | `ANY,`TAG(tag2) -> 
-                 fun t ctx _ tag -> 
+              | `ANY,`TAG(tag2) ->
+                 fun t ctx _ tag ->
                    eval_fold2_slist fl_list t tag
-                     (loop_tag (next t ctx) ctx rlist tag2)              
+                     (loop_tag (next t ctx) ctx rlist tag2)
                      (loop (first t) t llist tag)
-                         
-                                                                  
-              | _,_ -> 
-                  fun t ctx _ tag -> 
+
+
+              | _,_ ->
+                  fun t ctx _ tag ->
                    eval_fold2_slist fl_list t tag
-                     (loop (next t ctx) ctx rlist tag)           
+                     (loop (next t ctx) ctx rlist tag)
                      (loop (first t) t llist tag)
 
-             
+
 
          in
-         let _ = Trace.register_funname cont 
+         let _ = Trace.register_funname cont
            (Printf.sprintf "{first=%s, next=%s}" (Trace.get_funname first)  (Trace.get_funname next))
          in
-         Code3Cache.set_fun td_trans slist tag cont; 
-         cont 
+         Code3Cache.set_fun td_trans slist tag cont;
+         cont
        in
-       let cache_take_trans t ctx slist tag = 
+       let cache_take_trans t ctx slist tag =
          let cont = mk_trans t ctx slist tag in
          cont t ctx slist tag
        in
        Code3Cache.init td_trans (cache_take_trans);
        loop t ctx slist Tag.dummy
-         
-      
+
+
       let run_top_down1 a tree =
        let code_cache = Code3Cache.create ()  in
        let fold_cache = Fold3Res.create BIG_A_SIZE in
        let _,res = top_down1 a tree Tree.root a.init Tree.root code_cache fold_cache
-       in 
-       (*Code3Cache.dump code_cache; *)
+       in
+       Code3Cache.dump code_cache; 
        res
 
 
@@ -1508,31 +1509,31 @@ END
            Ptss.iter (fun s -> StateSet.print fmt s;
                        Format.fprintf fmt "  ") c.sets;
            Format.fprintf fmt "}\n%!";
-           IMap.iter (fun k d -> 
+           IMap.iter (fun k d ->
                         StateSet.print fmt k;
-                        Format.fprintf fmt "-> %i\n" (RS.length d)) c.results;                  
+                        Format.fprintf fmt "-> %i\n" (RS.length d)) c.results;
            Format.fprintf fmt "\n%!"
-             
+
          let merge c1 c2  =
            let acc1 =
-             IMap.fold 
+             IMap.fold
                ( fun s r acc ->
                    IMap.add s
-                     (try 
+                     (try
                         RS.concat r (IMap.find s acc)
                       with
-                        | Not_found -> r) acc) c1.results IMap.empty 
+                        | Not_found -> r) acc) c1.results IMap.empty
            in
            let imap =
-               IMap.fold (fun s r acc -> 
+               IMap.fold (fun s r acc ->
                             IMap.add s
-                              (try 
+                              (try
                                  RS.concat r (IMap.find s acc)
                                with
                                  | Not_found -> r) acc)  c2.results acc1
            in
            let h,s =
-             Ptss.fold 
+             Ptss.fold
                (fun s (ah,ass) -> (HASHINT2(ah, Uid.to_int s.StateSet.Node.id ),
                                    Ptss.add s ass))
                (Ptss.union c1.sets c2.sets) (0,Ptss.empty)
@@ -1543,33 +1544,33 @@ END
 
        end
 
-       let h_fold = Hashtbl.create 511 
+       let h_fold = Hashtbl.create 511
 
-       let fold_f_conf  tree t slist fl_list conf dir= 
+       let fold_f_conf  tree t slist fl_list conf dir=
          let tag = Tree.tag tree t in
          let rec loop sl fl acc =
            match SList.node sl,fl with
              |SList.Nil,[] -> acc
              |SList.Cons(s,sll), formlist::fll ->
-                let r',mcnf = 
+                let r',mcnf =
                   let key = SList.hash sl,Formlist.hash formlist,dir in
-                  try 
+                  try
                     Hashtbl.find h_fold key
                   with
-                     Not_found -> let res = 
+                     Not_found -> let res =
                        if dir then eval_formlist tag s StateSet.empty formlist
-                       else eval_formlist tag StateSet.empty s formlist 
+                       else eval_formlist tag StateSet.empty s formlist
                      in (Hashtbl.add h_fold key res;res)
                 in
                 let (rb,rb1,rb2,mark) = bool_of_merge mcnf in
                 if rb && ((dir&&rb1)|| ((not dir) && rb2))
-                then 
-                let acc = 
-                  let old_r = 
+                then
+                let acc =
+                  let old_r =
                     try Configuration.IMap.find s conf.Configuration.results
                     with Not_found -> RS.empty
                   in
-                  Configuration.add acc r' (if mark then RS.cons t old_r else old_r)                   
+                  Configuration.add acc r' (if mark then RS.cons t old_r else old_r)
                 in
                 loop sll fll acc
                 else loop sll fll acc
@@ -1579,40 +1580,40 @@ END
 
        let h_trans = Hashtbl.create 4096
 
-       let get_up_trans slist ptag a tree =      
+       let get_up_trans slist ptag a tree =
          let key = (HASHINT2(Uid.to_int slist.SList.Node.id ,ptag)) in
            try
-         Hashtbl.find h_trans key              
+         Hashtbl.find h_trans key
          with
-         | Not_found ->  
+         | Not_found ->
              let f_list =
                Hashtbl.fold (fun q l acc ->
                                List.fold_left (fun fl_acc (ts,t)  ->
                                                  if TagSet.mem ptag ts then Formlist.cons t fl_acc
                                                  else fl_acc)
-                                 
+
                                  acc l)
                  a.trans Formlist.nil
              in
-             let res = SList.fold (fun _ acc -> f_list::acc) slist [] 
+             let res = SList.fold (fun _ acc -> f_list::acc) slist []
              in
-               (Hashtbl.add h_trans key res;res) 
-                 
+               (Hashtbl.add h_trans key res;res)
 
-             
-       let h_tdconf = Hashtbl.create 511 
-       let rec bottom_up a tree t conf next jump_fun root dotd init accu = 
+
+
+       let h_tdconf = Hashtbl.create 511
+       let rec bottom_up a tree t conf next jump_fun root dotd init accu =
          if (not dotd) && (Configuration.is_empty conf ) then
-         accu,conf,next 
+         accu,conf,next
          else
 
-         let below_right = Tree.is_below_right tree t next in 
-         
-         let accu,rightconf,next_of_next =         
+         let below_right = Tree.is_below_right tree t next in
+
+         let accu,rightconf,next_of_next =
            if below_right then (* jump to the next *)
            bottom_up a tree next conf (jump_fun next) jump_fun (Tree.next_sibling tree t) true init accu
            else accu,Configuration.empty,next
-         in 
+         in
          let sub =
            if dotd then
            if below_right then prepare_topdown a tree t true
@@ -1628,30 +1629,30 @@ END
          let dir = Tree.is_left tree t in
          let slist = Configuration.Ptss.fold (fun e a -> SList.cons e a) conf.Configuration.sets SList.nil in
          let fl_list = get_up_trans slist ptag a parent in
-         let slist = SList.rev (slist) in 
+         let slist = SList.rev (slist) in
          let newconf = fold_f_conf tree parent slist fl_list conf dir in
          let accu,newconf = Configuration.IMap.fold (fun s res (ar,nc) ->
                                                        if StateSet.intersect s init then
                                                          ( RS.concat res ar ,nc)
                                                        else (ar,Configuration.add nc s res))
-           (newconf.Configuration.results) (accu,Configuration.empty) 
+           (newconf.Configuration.results) (accu,Configuration.empty)
          in
 
            bottom_up a tree parent newconf next jump_fun root false init accu
-             
+
        and prepare_topdown a tree t noright =
          let tag = Tree.tag tree t in
-         let r = 
+         let r =
            try
              Hashtbl.find h_tdconf tag
            with
-             | Not_found -> 
-                 let res = Hashtbl.fold (fun q l acc -> 
+             | Not_found ->
+                 let res = Hashtbl.fold (fun q l acc ->
                                            if List.exists (fun (ts,_) -> TagSet.mem tag ts) l
                                            then StateSet.add q acc
                                            else acc) a.trans StateSet.empty
                  in Hashtbl.add h_tdconf tag res;res
-         in 
+         in
 (*       let _ = pr ", among ";
            StateSet.print fmt (Ptset.Int.elements r);
            pr "\n%!";
@@ -1660,9 +1661,9 @@ END
          let set,res = top_down (~noright:noright) a tree t r t 1 (CodeCache.create BIG_A_SIZE) (Fold2Res.create 1024) in
          let set = match SList.node set with
            | SList.Cons(x,_) ->x
-           | _ -> assert false 
+           | _ -> assert false
          in
-         Configuration.add Configuration.empty set res.(0) 
+         Configuration.add Configuration.empty set res.(0)
 
 
 
@@ -1670,29 +1671,29 @@ END
          let t = Tree.root in
          let trlist = Hashtbl.find a.trans (StateSet.choose a.init)
          in
-         let init = List.fold_left 
+         let init = List.fold_left
            (fun acc (_,t) ->
-              let _,_,_,f,_ = Transition.node t in 
+              let _,_,_,f,_ = Transition.node t in
               let _,_,l = fst ( Formula.st f ) in
                 StateSet.union acc l)
            StateSet.empty trlist
          in
          let tree1,jump_fun =
            match k with
-             | `TAG (tag) -> 
+             | `TAG (tag) ->
                  (*Tree.tagged_lowest t tag, fun tree -> Tree.tagged_next tree tag*)
                  (Tree.tagged_descendant tree tag t, let jump = Tree.tagged_following_below tree tag
                  in fun n -> jump n t )
-             | `CONTAINS(_) -> (Tree.text_below tree t,let jump = Tree.text_next tree 
+             | `CONTAINS(_) -> (Tree.text_below tree t,let jump = Tree.text_next tree
                                 in fun n -> jump n t)
              | _ -> assert false
          in
          let tree2 = jump_fun tree1 in
-         let rec loop t next acc = 
+         let rec loop t next acc =
            let acc,conf,next_of_next = bottom_up a tree t
              Configuration.empty next jump_fun (Tree.root) true init acc
-           in 
-           let acc = Configuration.IMap.fold 
+           in
+           let acc = Configuration.IMap.fold
              ( fun s res acc -> if StateSet.intersect init s
                then RS.concat res acc else acc) conf.Configuration.results acc
            in
@@ -1704,7 +1705,7 @@ END
 
 
     end
-          
+
     let top_down_count a t = let module RI = Run(Integer) in Integer.length (RI.run_top_down a t)
     let top_down_count1 a t = let module RI = Run(Integer) in Integer.length (RI.run_top_down1 a t)
     let top_down a t = let module RI = Run(IdSet) in (RI.run_top_down a t)
diff --git a/tree.ml b/tree.ml
index 20bd067..7ea6f03 100644 (file)
--- a/tree.ml
+++ b/tree.ml
@@ -132,7 +132,7 @@ external benchmark_jump : tree -> Tag.t -> unit = "caml_benchmark_jump" "noalloc
 
 let benchmark_jump t s = benchmark_jump t.doc s
 
-external benchmark_fcns : tree -> unit = "caml_benchmark_fcns" "noalloc"
+external benchmark_fcns : tree -> int = "caml_benchmark_fcns" "noalloc"
 
 let benchmark_fcns t = benchmark_fcns t.doc
 
index e4c60c8..24b8256 100644 (file)
--- a/tree.mli
+++ b/tree.mli
@@ -88,7 +88,7 @@ val closing : t -> [`Tree] node -> [`Tree] node
 val is_open : t -> [`Tree] node -> bool
 
 val benchmark_jump : t -> Tag.t -> unit
-val benchmark_fcns : t -> unit
+val benchmark_fcns : t -> int
 val benchmark_lcps : t -> unit
 val stats : t -> unit
 
index 2ac43b7..1c2c127 100644 (file)
--- a/xPath.ml
+++ b/xPath.ml
@@ -4,7 +4,7 @@
 (*  Copyright NICTA 2008                                                      *)
 (*  Distributed under the terms of the LGPL (see LICENCE)                     *)
 (******************************************************************************)
-#load "pa_extend.cmo";;      
+#load "pa_extend.cmo";;
 let contains = ref None
 module Ast =
 struct
@@ -13,12 +13,12 @@ struct
   and step = axis*test*predicate
   and axis = Self | Attribute | Child | Descendant | DescendantOrSelf | FollowingSibling
             | Parent | Ancestor | AncestorOrSelf | PrecedingSibling | Preceding | Following
-                
+
   and test = TagSet.t
-      
+
   and predicate = Or of predicate*predicate
                  | And of predicate*predicate
-                 | Not of predicate    
+                 | Not of predicate
                  | Expr of expression
   and expression =  Path of path
                    | Function of string*expression list
@@ -26,31 +26,31 @@ struct
                    | String of string
                    | True | False
   type t = path
-      
-      
 
-      
+
+
+
   let pp fmt = Format.fprintf fmt
   let print_list printer fmt sep l =
     match l with
        [] -> ()
       | [e] -> printer fmt e
       | e::es -> printer fmt e; List.iter (fun x -> pp fmt sep;printer fmt x) es
-         
-         
-  let rec print fmt p = 
-    let l = match p with 
-      | Absolute l -> pp fmt "/"; l 
-      | AbsoluteDoS l -> pp fmt "/"; 
+
+
+  let rec print fmt p =
+    let l = match p with
+      | Absolute l -> pp fmt "/"; l
+      | AbsoluteDoS l -> pp fmt "/";
          print_step fmt (DescendantOrSelf,TagSet.node,Expr True);
          pp fmt "/"; l
-      | Relative l -> l 
+      | Relative l -> l
     in
       print_list print_step fmt "/" (List.rev l)
   and print_step fmt (axis,test,predicate) =
     print_axis fmt axis;pp fmt "::";print_test fmt test;
     pp fmt "["; print_predicate fmt predicate; pp fmt "]"
-  and print_axis fmt a = pp fmt "%s" (match a with 
+  and print_axis fmt a = pp fmt "%s" (match a with
                                          Self -> "self"
                                        | Child -> "child"
                                        | Descendant -> "descendant"
@@ -63,42 +63,42 @@ struct
                                        | Parent -> "parent"
                                        | _ -> assert false
                                     )
-  and print_test fmt ts =  
-    try 
-      pp fmt "%s" (List.assoc ts 
+  and print_test fmt ts =
+    try
+      pp fmt "%s" (List.assoc ts
                     [ (TagSet.pcdata,"text()"); (TagSet.node,"node()");
                       (TagSet.star),"*"])
     with
        Not_found -> pp fmt "%s"
-         (if TagSet.is_finite ts 
+         (if TagSet.is_finite ts
           then Tag.to_string (TagSet.choose ts)
           else "<INFINITE>")
-         
+
   and print_predicate fmt = function
     | Or(p,q) -> print_predicate fmt p; pp fmt " or "; print_predicate fmt q
     | And(p,q) -> print_predicate fmt p; pp fmt " and "; print_predicate fmt q
     | Not p -> pp fmt "not "; print_predicate fmt p
     | Expr e -> print_expression fmt e
-       
+
   and print_expression fmt = function
     | Path p -> print fmt p
     | Function (f,l) -> pp fmt "%s(" f;print_list print_expression fmt "," l;pp fmt ")"
     | Int i -> pp fmt "%i" i
     | String s -> pp fmt "\"%s\"" s
     | t -> pp fmt "%b" (t== True)
-      
+
 end
-module Parser = 
+module Parser =
 struct
-  open Ast    
+  open Ast
   open Ulexer
   let predopt = function None -> Expr True | Some p -> p
 
   module Gram =  Camlp4.Struct.Grammar.Static.Make(Ulexer)
   let query = Gram.Entry.mk "query"
-    
+
   exception Error of Gram.Loc.t*string
-  let test_of_keyword t loc = 
+  let test_of_keyword t loc =
     match t with
       | "text()" -> TagSet.pcdata
       | "node()" -> TagSet.node
@@ -114,8 +114,8 @@ GLOBAL: query;
 
  query : [ [ p = path; `EOI -> p ]]
 ;
-     
- path : [ 
+
+ path : [
    [ "//" ; l = slist -> AbsoluteDoS l ]
  | [ "/" ; l = slist -> Absolute l ]
  | [ l = slist  -> Relative l ]
@@ -136,8 +136,8 @@ step : [
 [ axis = axis ; o = OPT ["::" ; t = test -> t ] ; p = top_pred  ->
     let a,t,p =
       match o with
-       | Some(t) ->  (axis,t,p) 
-       | None -> (Child,TagSet.singleton (Tag.tag (axis_to_string axis)),p) 
+       | Some(t) ->  (axis,t,p)
+       | None -> (Child,TagSet.singleton (Tag.tag (axis_to_string axis)),p)
     in match a with
       | Following -> [ (DescendantOrSelf,t,p);
                       (FollowingSibling,TagSet.star,Expr(True));
@@ -149,23 +149,23 @@ step : [
       | _ -> [ a,t,p ]
 
 ]
+
 | [ "." ; p = top_pred ->  [(Self,TagSet.node,p)]  ]
 | [ ".." ; p = top_pred ->  [(Parent,TagSet.star,p)]  ]
-| [ "contains"; "(" ; s = STRING ; ")";p=top_pred -> [ 
+| [ "contains"; "(" ; s = STRING ; ")";p=top_pred -> [
       let _ = contains := Some((`CONTAINS,s)) in  (Child,TagSet.singleton Tag.pcdata, p)]
   ]
-| [ "equals"; "(" ; s = STRING ; ")";p=top_pred -> [ 
+| [ "equals"; "(" ; s = STRING ; ")";p=top_pred -> [
       let _ = contains := Some((`EQUALS,s)) in  (Child,TagSet.singleton Tag.pcdata, p)]
   ]
-| [ "startswith"; "(" ; s = STRING ; ")";p=top_pred -> [ 
+| [ "startswith"; "(" ; s = STRING ; ")";p=top_pred -> [
       let _ = contains := Some((`STARTSWITH,s)) in  (Child,TagSet.singleton Tag.pcdata, p)]
   ]
-| [ "endswith"; "(" ; s = STRING ; ")";p=top_pred -> [ 
+| [ "endswith"; "(" ; s = STRING ; ")";p=top_pred -> [
       let _ = contains := Some((`ENDSWITH,s)) in  (Child,TagSet.singleton Tag.pcdata, p)]
   ]
 | [ test = test; p = top_pred  -> [(Child,test, p)] ]
-| [ att = ATT ; p = top_pred -> 
+| [ att = ATT ; p = top_pred ->
       match att with
        | "*" -> [(Attribute,TagSet.star,p)]
        | _ ->  [(Attribute, TagSet.singleton (Tag.tag att) ,p )]]
@@ -175,8 +175,8 @@ top_pred  : [
   [ p = OPT [ "["; p=predicate ;"]" -> p ] -> predopt p ]
 ]
 ;
-axis : [ 
-  [ "self" -> Self | "child" -> Child | "descendant" -> Descendant 
+axis : [
+  [ "self" -> Self | "child" -> Child | "descendant" -> Descendant
       | "descendant-or-self" -> DescendantOrSelf
       | "ancestor-or-self" -> AncestorOrSelf
       | "following-sibling" -> FollowingSibling
@@ -188,15 +188,15 @@ axis : [
       | "following" -> Following
   ]
 
-    
+
 ];
-test : [ 
+test : [
   [ s = KWD -> test_of_keyword s _loc  ]
 | [ t = TAG -> TagSet.singleton (Tag.tag t) ]
 ];
 
 
-predicate: [ 
+predicate: [
   [ p = predicate; "or"; q = predicate -> Or(p,q) ]
 | [ p = predicate; "and"; q = predicate -> And(p,q) ]
 | [ "not" ; p = predicate -> Not p ]
@@ -216,7 +216,7 @@ END
 ;;
   let parse_string = Gram.parse_string query (Ulexer.Loc.mk "<string>")
   let parse = Gram.parse_string query (Ulexer.Loc.mk "<string>")
-end    
+end
 
 
 module Compile = struct
@@ -251,7 +251,7 @@ let dummy_conf = { st_root = -1;
                   univ_states = [];
                   starstate = None;
                 }
-                  
+
 
 let _r =
   function (`Left|`Last) -> `Right
@@ -260,7 +260,7 @@ let _r =
     | `LLeft -> `RRight
 
 
-let _l =   
+let _l =
   function (`Left|`Last) -> `Left
     | `Right -> `Right
     | `RRight -> `RRight
@@ -276,12 +276,12 @@ let add_trans num htr ((q,ts,_)as tr) =
   Hashtbl.add htr q (num,[tr])
 
 let vpush x y = (x,[]) :: y
-let hpush x y = 
+let hpush x y =
   match y with
     | (z,r)::l -> (z,x::r) ::l
     | _ -> assert false
 
-let vpop = function 
+let vpop = function
     (x,_)::r -> x,r
   | _ -> assert false
 
@@ -289,68 +289,68 @@ let hpop = function
   | (x,z::y) ::r -> z,(x,y)::r
   | _-> assert false
 
-let rec compile_step  ?(existential=false) conf q_src dir ctx_path nrec step num  = 
+let rec compile_step  ?(existential=false) conf q_src dir ctx_path nrec step num  =
   let ex = existential in
   let axis,test,pred = step  in
   let is_last = dir = `Last in
   let { st_root = q_root;
-       st_univ = q_univ; 
-       st_from_root = q_frm_root } = conf 
+       st_univ = q_univ;
+       st_from_root = q_frm_root } = conf
   in
-  let q_dst = Ata.State.make() in 
-  let p_st, p_anc, p_par, p_pre, p_num, p_f = 
+  let q_dst = Ata.State.make() in
+  let p_st, p_anc, p_par, p_pre, p_num, p_f =
     compile_pred conf q_src num ctx_path dir pred q_dst
   in
-  let new_st,new_dst, new_ctx = 
+  let new_st,new_dst, new_ctx =
   match axis with
     | Child | Descendant ->
        if (TagSet.is_finite test)
-       then conf.entry_points <- (TagSet.choose test,Ata.StateSet.singleton q_src)::conf.entry_points;   
+       then conf.entry_points <- (TagSet.choose test,Ata.StateSet.singleton q_src)::conf.entry_points;
        let left,right =
          if nrec then `LLeft,`RRight
          else `Left,`Right
        in
        let _ = if is_last && axis=Descendant && TagSet.equal test TagSet.star
        then conf.starstate <- Some(Ata.StateSet.singleton q_src)
-       in        
+       in
        let t1,ldst = ?< q_src><(test, is_last && not(ex))>=>
          p_f *& ( if is_last then Ata.Formula.true_ else  (_l left) *+ q_dst),
          ( if is_last then [] else [q_dst])
        in
-       
-       let _ = add_trans num conf.tr t1 in  
+
+       let _ = add_trans num conf.tr t1 in
        let _ = if axis=Descendant then
          add_trans num conf.tr_aux (
            ?< q_src><@ ((if ex||nrec then TagSet.diff TagSet.star test
-                         else TagSet.star),false)>=> 
+                         else TagSet.star),false)>=>
              (if TagSet.equal test TagSet.star then
                `Left else `LLeft) *+ q_src )
-       in        
-       let t3 = 
-         ?< q_src><@ ((if ex then TagSet.diff TagSet.any test
-                       else TagSet.any), false)>=> 
-           (if axis=Descendant && (not (TagSet.equal test TagSet.star)) then 
-              `RRight else `Right) *+ q_src 
        in
-       let _ = add_trans num conf.tr_aux t3      
+       let t3 =
+         ?< q_src><@ ((if ex then TagSet.diff  TagSet.any test
+                       else TagSet.any), false)>=>
+           (if axis=Descendant && (not (TagSet.equal test TagSet.star)) then
+              `RRight else `Right) *+ q_src
        in
-         ldst, q_dst, 
+       let _ = add_trans num conf.tr_aux t3
+       in
+         ldst, q_dst,
        (if axis = FollowingSibling then hpush q_src ctx_path else vpush q_src ctx_path)
-         
-         
-    | Attribute -> 
+
+
+    | Attribute ->
        let q_dstreal = Ata.State.make() in
          (* attributes are always the first child *)
-       let t1 = ?< q_src><(TagSet.attribute,false)>=> 
+       let t1 = ?< q_src><(TagSet.attribute,false)>=>
          `Left *+ q_dst  in
        let t2 = ?< q_dst><(test, is_last && not(existential))>=>
          if is_last then Ata.Formula.true_ else `Left *+ q_dstreal in
-       let tsa = ?< q_dst><(TagSet.star, false)>=> `Right *+ q_dst       
+       let tsa = ?< q_dst><(TagSet.star, false)>=> `Right *+ q_dst
        in
          add_trans num conf.tr t1;
          add_trans num conf.tr_aux t2;
          add_trans num conf.tr_aux tsa;
-         [q_dst;q_dstreal], q_dstreal, 
+         [q_dst;q_dstreal], q_dstreal,
        ctx_path
 
 
@@ -362,19 +362,19 @@ let rec compile_step  ?(existential=false) conf q_src dir ctx_path nrec step num
      new_ctx)
 and is_rec  = function
     [] -> false
-  | ((axis,_,_),_)::_ -> 
+  | ((axis,_,_),_)::_ ->
       match axis with
          Descendant | Ancestor -> true
        | _ -> false
-           
-and compile_path ?(existential=false) annot_path config q_src states idx ctx_path = 
-  List.fold_left 
-    (fun (a_st,a_dst,anc_st,par_st,pre_st,ctx_path,num,has_backward,a_isrec) (step,dir) ->            
+
+and compile_path ?(existential=false) annot_path config q_src states idx ctx_path =
+  List.fold_left
+    (fun (a_st,a_dst,anc_st,par_st,pre_st,ctx_path,num,has_backward,a_isrec) (step,dir) ->
        let add_states,new_dst,new_ctx =
         compile_step ~existential:existential config a_dst dir ctx_path (is_rec a_isrec) step num
        in
        let new_states = Ata.StateSet.union (Ata.StateSet.from_list add_states) a_st in
-       let nanc_st,npar_st,npre_st,new_bw = 
+       let nanc_st,npar_st,npre_st,new_bw =
         match step with
           |PrecedingSibling,_,_ -> anc_st,par_st,Ata.StateSet.add a_dst pre_st,true
           |(Parent|Ancestor|AncestorOrSelf),_,_ -> Ata.StateSet.add a_dst anc_st,par_st,pre_st,true
@@ -384,11 +384,11 @@ and compile_path ?(existential=false) annot_path config q_src states idx ctx_pat
     )
     (states, q_src, Ata.StateSet.empty,Ata.StateSet.empty,Ata.StateSet.empty, ctx_path,idx, false,(List.tl annot_path) )
     annot_path
-    
+
 and binop_ conf q_src idx ctx_path dir pred p1 p2 f ddst =
   let a_st1,anc_st1,par_st1,pre_st1,idx1,f1 =
     compile_pred conf q_src idx ctx_path dir p1 ddst in
-  let a_st2,anc_st2,par_st2,pre_st2,idx2,f2 = 
+  let a_st2,anc_st2,par_st2,pre_st2,idx2,f2 =
     compile_pred conf q_src idx1 ctx_path dir p2 ddst
   in
         Ata.StateSet.union a_st1 a_st2,
@@ -397,26 +397,26 @@ and binop_ conf q_src idx ctx_path dir pred p1 p2 f ddst =
        Ata.StateSet.union pre_st1 pre_st2,
        idx2, (f f1 f2)
 
-and compile_pred conf q_src idx ctx_path dir pred qdst = 
+and compile_pred conf q_src idx ctx_path dir pred qdst =
   match pred with
-    | Or(p1,p2) -> 
+    | Or(p1,p2) ->
        binop_ conf q_src idx ctx_path dir pred p1 p2 (( +| )) qdst
-    | And(p1,p2) -> 
+    | And(p1,p2) ->
        binop_ conf q_src idx ctx_path dir pred p1 p2 (( *& )) qdst
     | Expr e -> compile_expr conf Ata.StateSet.empty q_src idx ctx_path dir e qdst
-    | Not(p) -> 
-       let a_st,anc_st,par_st,pre_st,idx,f = 
+    | Not(p) ->
+       let a_st,anc_st,par_st,pre_st,idx,f =
          compile_pred conf q_src idx ctx_path dir p qdst
        in a_st,anc_st,par_st,pre_st,idx, Ata.Formula.not_ f
 
 and compile_expr conf states q_src idx ctx_path dir e qdst =
   match e with
-    | Path (p) -> 
+    | Path (p) ->
        let q = Ata.State.make () in
        let annot_path = match p with Relative(r) -> dirannot (List.rev r) | _ -> assert false in
-       let a_st,a_dst,anc_st,par_st,pre_st,_,idx,has_backward,_ = 
+       let a_st,a_dst,anc_st,par_st,pre_st,_,idx,has_backward,_ =
            compile_path ~existential:true annot_path conf q states idx ctx_path
-       in 
+       in
        let ret_dir = match annot_path with
          | ((FollowingSibling,_,_),_)::_ -> `Right
          | _ -> `Left
@@ -438,9 +438,9 @@ and dirannot = function
   | p::l -> (p,`Left) :: (dirannot l)
 
 let compile ?(querystring="") path =
-  let steps = 
+  let steps =
   match path with
-    | Absolute(steps) 
+    | Absolute(steps)
     | Relative(steps) -> steps
     | AbsoluteDoS(steps) -> steps@[(DescendantOrSelf,TagSet.node,Expr(True))]
   in
@@ -453,40 +453,40 @@ let compile ?(querystring="") path =
                       has_backward = false;
                       tr_parent_loop = Hashtbl.create 5;
                       tr = Hashtbl.create 5;
-                      tr_aux =  Hashtbl.create 5; 
+                      tr_aux =  Hashtbl.create 5;
                       entry_points = [];
                       contains = None;
                       univ_states = [];
                       starstate = None;
-                    } 
+                    }
        in
        let q0 = Ata.State.make() in
-       let states = Ata.StateSet.from_list [config.st_univ;config.st_root] 
+       let states = Ata.StateSet.from_list [config.st_univ;config.st_root]
        in
        let num = 0 in
        (* add_trans num config.tr_aux (mk_star config.st_from_root `Left config.st_univ config.st_from_root);
             add_trans num config.tr_aux (mk_star config.st_from_root `Left config.st_from_root config.st_univ);
             add_trans num config.tr_aux (mk_step config.st_no_nil (TagSet.add Tag.pcdata TagSet.star) `Left config.st_univ config.st_univ);
          *)
-         let a_st,a_dst,anc_st,par_st,pre_st,_,_,has_backward,_ = 
+         let a_st,a_dst,anc_st,par_st,pre_st,_,_,has_backward,_ =
            compile_path dirsteps config q0 states 0 [(config.st_root,[]) ]
          in
-         let fst_tr = 
-           ?< (config.st_root) >< (TagSet.singleton (Tag.tag ""),false) >=> 
+         let fst_tr =
+           ?< (config.st_root) >< (TagSet.singleton (Tag.tag ""),false) >=>
              ((if is_rec dirsteps then `LLeft else `Left)*+ q0) *& (if config.has_backward then `LLeft *+ config.st_from_root else Ata.Formula.true_)
          in
            add_trans num config.tr fst_tr;
            if config.has_backward then begin
-             add_trans num config.tr_aux 
+             add_trans num config.tr_aux
                (?< (config.st_from_root) >< (TagSet.star,false) >=> `LLeft *+ config.st_from_root);
-             add_trans num config.tr_aux 
-               (?< (config.st_from_root) >< (TagSet.any,false) >=> 
-                    `RRight *+ config.st_from_root); 
-             
-           end; 
+             add_trans num config.tr_aux
+               (?< (config.st_from_root) >< (TagSet.any,false) >=>
+                    `RRight *+ config.st_from_root);
+
+           end;
          let phi = Hashtbl.create 37 in
-         let fadd = fun _ (_,l) -> List.iter (fun (s,t,tr) ->                                           
-                                                let lt = try 
+         let fadd = fun _ (_,l) -> List.iter (fun (s,t,tr) ->
+                                                let lt = try
                                                   Hashtbl.find phi s
                                                 with Not_found -> []
                                                 in
@@ -495,8 +495,8 @@ let compile ?(querystring="") path =
            Hashtbl.iter (fadd) config.tr;
            Hashtbl.iter (fadd) config.tr_aux;
            Hashtbl.iter (fadd) config.tr_parent_loop;
-           let final = 
-             let s = anc_st  
+           let final =
+             let s = anc_st
              in if has_backward then Ata.StateSet.add config.st_from_root s else s
            in { Ata.id = Oo.id (object end);
                 Ata.states = Hashtbl.fold (fun q _ acc -> Ata.StateSet.add q acc) phi Ata.StateSet.empty;
@@ -505,6 +505,6 @@ let compile ?(querystring="") path =
                 Ata.starstate = config.starstate;
                 Ata.query_string = querystring;
               },config.entry_points,!contains
-            
-                
+
+
 end