end
-module SetTagKey =
-struct
- type t = Ptset.Int.t*Tag.t
- let equal (s1,t1) (s2,t2) = (t1 == t2) && Ptset.Int.equal s1 s2
- let hash (s,t) = HASHINT2(Ptset.Int.uid s, t)
-end
-
module TransTable = Hashtbl
-module CachedTransTable = Hashtbl.Make(SetTagKey)
module Formlist = struct
include Hlist.Make(Transition)
+ type data = t node
+ let make _ = failwith "make"
let print ppf fl =
iter (fun t -> Transition.print ppf t; Format.pp_print_newline ppf ()) fl
end
module FormTable = Hashtbl.Make(struct
type t = Formula.t*StateSet.t*StateSet.t
let equal (f1,s1,t1) (f2,s2,t2) =
- Formula.equal f1 f2 && StateSet.equal s1 s2 && StateSet.equal t1 t2
+ f1 == f2 && s1 == s2 && t1 == t2
let hash (f,s,t) =
HASHINT3(Formula.uid f ,StateSet.uid s,StateSet.uid t)
end)
| _ -> assert false
in FormTable.add h_f (f,s1,s2) r;r
in loop f
+
-module FTable = Hashtbl.Make(
- struct
- type t = Formlist.t*StateSet.t*StateSet.t
- let equal (f1,s1,t1) (f2,s2,t2) =
- Formlist.equal f1 f2 && StateSet.equal s1 s2 && StateSet.equal t1 t2;;
- let hash (f,s,t) = HASHINT3(Formlist.uid f ,StateSet.uid s,StateSet.uid t);;
- end)
+module FTable = Hashtbl.Make( struct
+ type t = Formlist.t*StateSet.t*StateSet.t
+ let equal (f1,s1,t1) (f2,s2,t2) =
+ f1 == f2 && s1 == s2 && t1 == t2;;
+ let hash (f,s,t) = HASHINT3(Formlist.uid f ,StateSet.uid s,StateSet.uid t);;
+ end)
(*
module MemoFormlist = Memoizer.Make(FTable)
*)
-
- let eval_formlist =
- let h_f = FTable.create BIG_H_SIZE in
- fun s1 s2 fl ->
- let rec loop fl =
- let key = (fl,s1,s2) in
- try
- FTable.find h_f key
- with
- | Not_found ->
- match Formlist.node fl with
- | Formlist.Nil -> StateSet.empty,false,false,false,false
- | Formlist.Cons(f,fll) ->
- let q,mark,f,_ = Transition.node f in
- let b,b1,b2 = eval_form_bool f s1 s2 in
- let s,b',b1',b2',amark = loop fll in
- let r = if b then (StateSet.add q s, b, b1'||b1,b2'||b2,mark||amark)
- else s,b',b1',b2',amark
- in FTable.add h_f key r;r
- in loop fl
+let h_f = FTable.create BIG_H_SIZE
+
+let eval_formlist s1 s2 fl =
+ let rec loop fl =
+ try
+ FTable.find h_f (fl,s1,s2)
+ with
+ | Not_found ->
+ match Formlist.node fl with
+ | Formlist.Cons(f,fll) ->
+ let q,mark,f,_ = Transition.node f in
+ let b,b1,b2 = eval_form_bool f s1 s2 in
+ let s,b',b1',b2',amark = loop fll in
+ let r = if b then (StateSet.add q s, b, b1'||b1,b2'||b2,mark||amark)
+ else s,b',b1',b2',amark
+ in FTable.add h_f (fl,s1,s2) r;r
+ | Formlist.Nil -> StateSet.empty,false,false,false,false
+ in loop fl
- 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_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
module Run (RS : ResultSet) =
struct
- module SList = Hlist.Make (StateSet)
+ module SList = struct
+ include Hlist.Make (StateSet)
+ type data = t node
+ let make _ = failwith "make"
+ end
INCLUDE "html_trace.ml"
END
-
- let td_trans = Hashtbl.create 4096
let mk_fun f s = D_IGNORE_(register_funname f s,f)
let mk_app_fun f arg s = let g = f arg in
D_IGNORE_(register_funname g ((get_funname f) ^ " " ^ s), g)
let string_of_ts tags = (Ptset.Int.fold (fun t a -> a ^ " " ^ (Tag.to_string t) ) tags "{")^ " }"
-
+
+
let choose_jump tagset qtags1 qtagsn a f_nil f_text f_t1 f_s1 f_tn f_sn f_notext =
let tags1,hastext1,fin1 = inter_text tagset (tags a qtags1) in
let tagsn,hastextn,finn = inter_text tagset (tags a qtagsn) in
- if (hastext1||hastextn) then f_text (* jumping to text nodes doesn't work really well *)
- else if (Ptset.Int.is_empty tags1) && (Ptset.Int.is_empty tagsn) then f_nil
+ if (hastext1||hastextn) then (`ANY,f_text) (* jumping to text nodes doesn't work really well *)
+ else if (Ptset.Int.is_empty tags1) && (Ptset.Int.is_empty tagsn) then (`NIL,f_nil)
else if (Ptset.Int.is_empty tagsn) then
if (Ptset.Int.is_singleton tags1)
then (* TaggedChild/Sibling *)
- let tag = (Ptset.Int.choose tags1) in mk_app_fun f_t1 tag (Tag.to_string tag)
+ let tag = (Ptset.Int.choose tags1) in (`TAG(tag),mk_app_fun f_t1 tag (Tag.to_string tag))
else (* SelectChild/Sibling *)
- mk_app_fun f_s1 tags1 (string_of_ts tags1)
+ (`ANY,mk_app_fun f_s1 tags1 (string_of_ts tags1))
else if (Ptset.Int.is_empty tags1) then
if (Ptset.Int.is_singleton tagsn)
then (* TaggedDesc/Following *)
- let tag = (Ptset.Int.choose tagsn) in mk_app_fun f_tn tag (Tag.to_string tag)
+ let tag = (Ptset.Int.choose tagsn) in (`TAG(tag),mk_app_fun f_tn tag (Tag.to_string tag))
else (* SelectDesc/Following *)
- mk_app_fun f_sn tagsn (string_of_ts tagsn)
- else f_notext
+ (`ANY,mk_app_fun f_sn tagsn (string_of_ts tagsn))
+ else (`ANY,f_notext)
let choose_jump_down a b c d =
choose_jump a b c d
(mk_fun (Tree.mk_nil) "Tree.mk_nil")
- (mk_fun (Tree.text_below) "Tree.text_below")
- (mk_fun (fun _ -> Tree.node_child) "[TaggedChild]Tree.node_child") (* !! no tagged_child in Tree.ml *)
- (mk_fun (fun _ -> Tree.node_child) "[SelectChild]Tree.node_child") (* !! no select_child in Tree.ml *)
+ (mk_fun (Tree.first_child) "Tree.text_below")
+ (mk_fun (Tree.tagged_child) "Tree.tagged_child")
+ (mk_fun (Tree.select_child) "Tree.select_child") (* !! no select_child in Tree.ml *)
(mk_fun (Tree.tagged_desc) "Tree.tagged_desc")
- (mk_fun (fun _ -> Tree.node_child ) "[SelectDesc]Tree.node_child") (* !! no select_desc *)
- (mk_fun (Tree.node_child) "Tree.node_child")
+ (mk_fun (Tree.select_desc) "Tree.select_desc") (* !! no select_desc *)
+ (mk_fun (Tree.first_child) "Tree.first_child")
let choose_jump_next a b c d =
choose_jump a b c d
(mk_fun (fun t _ -> Tree.mk_nil t) "Tree.mk_nil2")
- (mk_fun (Tree.text_next) "Tree.text_next")
- (mk_fun (fun _ -> Tree.node_sibling_ctx) "[TaggedSibling]Tree.node_sibling_ctx")(* !! no tagged_sibling in Tree.ml *)
- (mk_fun (fun _ -> Tree.node_sibling_ctx) "[SelectSibling]Tree.node_sibling_ctx")(* !! no select_sibling in Tree.ml *)
+ (mk_fun (Tree.next_sibling_ctx) "Tree.text_next")
+ (mk_fun (Tree.tagged_sibling_ctx) "Tree.tagged_sibling_ctx")(* !! no tagged_sibling in Tree.ml *)
+ (mk_fun (Tree.select_sibling_ctx) "Tree.select_sibling_ctx")(* !! no select_sibling in Tree.ml *)
(mk_fun (Tree.tagged_foll_ctx) "Tree.tagged_foll_ctx")
- (mk_fun (fun _ -> Tree.node_sibling_ctx) "[SelectFoll]Tree.node_sibling_ctx")(* !! no select_foll *)
- (mk_fun (Tree.node_sibling_ctx) "Tree.node_sibling_ctx")
-
- let get_trans slist tag a t =
- try
- Hashtbl.find td_trans (tag,SList.hash slist)
- with
- | Not_found ->
- let fl_list,llist,rlist,ca,da,sa,fa =
- SList.fold
- (fun set (fll_acc,lllacc,rllacc,ca,da,sa,fa) -> (* For each set *)
- let fl,ll,rr,ca,da,sa,fa =
- StateSet.fold
- (fun q acc ->
- List.fold_left
- (fun ((fl_acc,ll_acc,rl_acc,c_acc,d_acc,s_acc,f_acc) as acc)
- (ts,t) ->
- if (TagSet.mem tag ts)
- then
- let _,_,f,_ = Transition.node t in
- let (child,desc,below),(sibl,foll,after) = Formula.st f in
- (Formlist.cons t fl_acc,
- StateSet.union ll_acc below,
- StateSet.union rl_acc after,
- StateSet.union child c_acc,
- StateSet.union desc d_acc,
- StateSet.union sibl s_acc,
- StateSet.union foll f_acc)
- else acc ) acc (
- try Hashtbl.find a.trans q
- with
- Not_found -> Printf.eprintf "Looking for state %i, doesn't exist!!!\n%!"
- q;[]
- )
-
- ) set (Formlist.nil,StateSet.empty,StateSet.empty,ca,da,sa,fa)
- in fl::fll_acc, (SList.cons ll lllacc), (SList.cons rr rllacc),ca,da,sa,fa)
- slist ([],SList.nil,SList.nil,StateSet.empty,StateSet.empty,StateSet.empty,StateSet.empty)
- in
- (* Logic to chose the first and next function *)
- let tags_below,tags_after = Tree.tags t tag in
- let first = choose_jump_down tags_below ca da a
- and next = choose_jump_next tags_after sa fa a in
- let v = (fl_list,llist,rlist,first,next) in
- Hashtbl.add td_trans (tag, SList.hash slist) v; v
-
- let merge rb rb1 rb2 mark t res1 res2 =
- if rb
- then
- let res1 = if rb1 then res1 else RS.empty
- and res2 = if rb2 then res2 else RS.empty
- in
- if mark then RS.cons t (RS.concat res1 res2)
- else RS.concat res1 res2
- else RS.empty
+ (mk_fun (Tree.select_foll_ctx) "Tree.select_foll_ctx")(* !! no select_foll *)
+ (mk_fun (Tree.next_sibling_ctx) "Tree.node_sibling_ctx")
+
+ module SetTagKey =
+ struct
+ type t = Tag.t*SList.t
+ let equal (t1,s1) (t2,s2) = t1 == t2 && s1 == s2
+ let hash (t,s) = HASHINT2(t,SList.uid s)
+ end
+
+ module CachedTransTable = Hashtbl.Make(SetTagKey)
+ let td_trans = CachedTransTable.create 4093
+
+ let merge rb rb1 rb2 mark t res1 res2 =
+ if rb
+ then
+ let res1 = if rb1 then res1 else RS.empty
+ and res2 = if rb2 then res2 else RS.empty
+ in
+ if mark then RS.cons t (RS.concat res1 res2)
+ else RS.concat res1 res2
+ else RS.empty
+
let empty_size n =
let rec loop acc = function 0 -> acc
| n -> loop (SList.cons StateSet.empty acc) (n-1)
in loop SList.nil n
-
+
+
let top_down ?(noright=false) a t slist ctx slot_size =
let pempty = empty_size slot_size in
- let eval_fold2_slist fll sl1 sl2 res1 res2 t =
+ (* evaluation starts from the right so we put sl1,res1 at the end *)
+ let eval_fold2_slist fll t (sl2,res2) (sl1,res1) =
let res = Array.copy res1 in
let rec fold l1 l2 fll i aq =
match SList.node l1,SList.node l2, fll with
let _ = res.(i) <- merge rb rb1 rb2 mark t res1.(i) res2.(i)
in
fold ll1 ll2 fll (i+1) (SList.cons r' aq)
- | SList.Nil, SList.Nil,[] -> aq,res
- | _ -> assert false
+
+ | SList.Nil, SList.Nil,[] -> aq,res
+ | _ -> assert false
in
fold sl1 sl2 fll 0 SList.nil
in
let null_result() = (pempty,Array.make slot_size RS.empty) in
- let rec loop t slist ctx =
- if Tree.is_nil t then null_result()
- else
- let tag = Tree.tag t in
- let fl_list,llist,rlist,first,next = get_trans slist tag a t in
- let sl1,res1 = loop (first t) llist t in
- let sl2,res2 = loop (next t ctx) rlist ctx in
- let res = eval_fold2_slist fl_list sl1 sl2 res1 res2 t
- in
- D_IGNORE_(
- register_trace t (slist,(fst res),sl1,sl2,fl_list,first,next,ctx),
- res)
- in
- let loop_no_right t slist ctx =
- if Tree.is_nil t then null_result()
- else
- let tag = Tree.tag t in
- let fl_list,llist,_,first,next = get_trans slist tag a t in
- let sl1,res1 = loop (first t) llist t in
- let sl2,res2 = null_result() in
- let res = eval_fold2_slist fl_list sl1 sl2 res1 res2 t
- in
- D_IGNORE_(
- register_trace t (slist,(fst res),sl1,sl2,fl_list,first,next,ctx),
- res)
- in
- (if noright then loop_no_right else loop) t slist ctx
+
+ let rec loop t slist ctx =
+ if Tree.is_nil t then null_result() else get_trans t slist (Tree.tag t) ctx
+
+ and loop_tag tag t slist ctx =
+ if Tree.is_nil t then null_result() else get_trans t slist tag ctx
+ and loop_no_right t slist ctx =
+ if Tree.is_nil t then null_result() else get_trans ~noright:true t slist (Tree.tag t) ctx
+ and get_trans ?(noright=false) t slist tag ctx =
+ let cont =
+ try
+ CachedTransTable.find td_trans (tag,slist)
+ with
+ | Not_found ->
+ let fl_list,llist,rlist,ca,da,sa,fa =
+ SList.fold
+ (fun set (fll_acc,lllacc,rllacc,ca,da,sa,fa) -> (* For each set *)
+ let fl,ll,rr,ca,da,sa,fa =
+ StateSet.fold
+ (fun q acc ->
+ List.fold_left
+ (fun ((fl_acc,ll_acc,rl_acc,c_acc,d_acc,s_acc,f_acc) as acc)
+ (ts,t) ->
+ if (TagSet.mem tag ts)
+ then
+ let _,_,f,_ = Transition.node t in
+ let (child,desc,below),(sibl,foll,after) = Formula.st f in
+ (Formlist.cons t fl_acc,
+ StateSet.union ll_acc below,
+ StateSet.union rl_acc after,
+ StateSet.union child c_acc,
+ StateSet.union desc d_acc,
+ StateSet.union sibl s_acc,
+ StateSet.union foll f_acc)
+ else acc ) acc (
+ try Hashtbl.find a.trans q
+ with
+ Not_found -> Printf.eprintf "Looking for state %i, doesn't exist!!!\n%!"
+ q;[]
+ )
+
+ ) set (Formlist.nil,StateSet.empty,StateSet.empty,ca,da,sa,fa)
+ in fl::fll_acc, (SList.cons ll lllacc), (SList.cons rr rllacc),ca,da,sa,fa)
+ slist ([],SList.nil,SList.nil,StateSet.empty,StateSet.empty,StateSet.empty,StateSet.empty)
+ in
+ (* Logic to chose the first and next function *)
+ let tags_below,tags_after = Tree.tags t tag in
+ let f_kind,first = choose_jump_down tags_below ca da a
+ and n_kind,next = if noright then (`NIL, fun t _ -> Tree.mk_nil t )
+ else choose_jump_next tags_after sa fa a in
+ let empty_res = null_result() in
+ let cont =
+ match f_kind,n_kind with
+ | `NIL,`NIL ->
+ (fun _ _ -> eval_fold2_slist fl_list t empty_res empty_res )
+ | _,`NIL -> (
+ match f_kind with
+ |`TAG(tag) ->
+ (fun t _ -> eval_fold2_slist fl_list t empty_res
+ (loop_tag tag (first t) llist t))
+ | `ANY ->
+ (fun t _ -> eval_fold2_slist fl_list t empty_res
+ (loop (first t) llist t))
+ | _ -> assert false)
+
+ | `NIL,_ -> (
+ match n_kind with
+ |`TAG(tag) ->
+ (fun t ctx -> eval_fold2_slist fl_list t
+ (loop_tag tag (next t ctx) rlist ctx) empty_res)
+
+ | `ANY ->
+ (fun t ctx -> eval_fold2_slist fl_list t
+ (loop (next t ctx) rlist ctx) empty_res)
+
+ | _ -> assert false)
+
+ | `TAG(tag1),`TAG(tag2) ->
+ (fun t ctx -> eval_fold2_slist fl_list t
+ (loop (next t ctx) rlist ctx)
+ (loop (first t) llist t))
+
+ | `TAG(tag),`ANY ->
+ (fun t ctx ->
+ eval_fold2_slist fl_list t
+ (loop (next t ctx) rlist ctx)
+ (loop_tag tag (first t) llist t))
+ | `ANY,`TAG(tag) ->
+ (fun t ctx ->
+ eval_fold2_slist fl_list t
+ (loop_tag tag (next t ctx) rlist ctx)
+ (loop (first t) llist t) )
+ | `ANY,`ANY ->
+ (fun t ctx ->
+ eval_fold2_slist fl_list t
+ (loop (next t ctx) rlist ctx)
+ (loop (first t) llist t) )
+ | _ -> assert false
+ in
+ let cont = D_IF_( (fun t ctx ->
+ let a,b = cont t ctx in
+ register_trace t (slist,a,fl_list,first,next,ctx);
+ (a,b)
+ ) ,cont)
+ in
+ (CachedTransTable.add td_trans (tag,slist) cont;cont)
+ in cont t ctx
+ in
+ (if noright then loop_no_right else loop) t slist ctx
let run_top_down a t =
| `TAG (tag) ->
(*Tree.tagged_lowest t tag, fun tree -> Tree.tagged_next tree tag*)
(Tree.tagged_desc tag t, fun tree -> Tree.tagged_foll_ctx tag tree t)
- | `CONTAINS(_) -> (Tree.text_below t,fun tree -> Tree.text_next tree t)
+ | `CONTAINS(_) -> (Tree.first_child t,fun tree -> Tree.next_sibling_ctx tree t)
| _ -> assert false
in
let tree2 = jump_fun tree1 in