| Or of 'hcons * 'hcons
| And of 'hcons * 'hcons
| Atom of ([ `Left | `Right | `LLeft | `RRight ]*bool*State.t)
+
type 'hcons node = {
pos : 'hcons expr;
mutable neg : 'hcons;
}
external hash_const_variant : [> ] -> int = "%identity"
- module rec HNode : Hcons.S with type data = Node.t = Hcons.Make (Node)
- and Node : Hashtbl.HashedType with type t = HNode.t node =
+ module rec Node : Hcons.S with type data = Data.t = Hcons.Make (Data)
+ and Data : Hashtbl.HashedType with type t = Node.t node =
struct
- type t = HNode.t node
+ type t = Node.t node
let equal x y = x.size == y.size &&
match x.pos,y.pos with
- | False,False
- | True,True -> true
- | Or(xf1,xf2),Or(yf1,yf2)
- | And(xf1,xf2),And(yf1,yf2) -> (HNode.equal xf1 yf1) && (HNode.equal xf2 yf2)
- | Atom(d1,p1,s1), Atom(d2,p2,s2) -> d1 == d2 && (p1==p2) && s1 == s2
- | _ -> false
+ | a,b when a == b -> true
+ | 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 =
match f.pos with
| False -> 0
| True -> 1
- | Or (f1,f2) -> HASHINT3(PRIME2,HNode.uid f1,HNode.uid f2)
- | And (f1,f2) -> HASHINT3(PRIME3,HNode.uid f1,HNode.uid f2)
+ | Or (f1,f2) -> HASHINT3(PRIME2,f1.Node.id, f2.Node.id)
+ | And (f1,f2) -> HASHINT3(PRIME3,f1.Node.id,f2.Node.id)
| Atom(d,p,s) -> HASHINT4(PRIME4,hash_const_variant d,vb p,s)
end
- type t = HNode.t
- let hash = HNode.hash
- let uid = HNode.uid
- let equal = HNode.equal
- let expr f = (HNode.node f).pos
- let st f = (HNode.node f ).st
- let size f = (HNode.node f).size
+ 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 st f = f.Node.node.st
+ let size f = f.Node.node.size
let prio f =
match expr f with
let cons pos neg s1 s2 size1 size2 =
- let nnode = HNode.make { pos = neg; neg = (Obj.magic 0); st = s2; size = size2 } in
- let pnode = HNode.make { pos = pos; neg = nnode ; st = s1; size = size1 }
+ 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
- (HNode.node nnode).neg <- pnode; (* works because the neg field isn't taken into
+ (Node.node nnode).neg <- pnode; (* works because the neg field isn't taken into
account for hashing ! *)
pnode,nnode
| `RRight -> empty_triple,(StateSet.empty,si,si)
in fst (cons (Atom(d,p,s)) (Atom(d,not p,s)) ss ss 1 1)
- let not_ f = (HNode.node f).neg
+ let not_ f = f.Node.node.neg
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 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)
+ fst (cons (Or(f1,f2)) (And(not_ f1,not_ f2)) sp sn psize nsize)
let and_ f1 f2 =
module TransTable = Hashtbl
module Formlist = struct
- include Hlist.Make(Transition)
- type data = t node
- let make _ = failwith "make"
+ include Hlist.Make(Transition)
let print ppf fl =
iter (fun t -> Transition.print ppf t; Format.pp_print_newline ppf ()) fl
end
+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 = {
id : int;
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
- (TagSet.fold (fun t a -> a ^ " " ^ (Tag.to_string t)) cts "*\\{"
- )^ "}"
+ if TagSet.is_empty cts then "*" else
+ (TagSet.fold (fun t a -> a ^ " " ^ (Tag.to_string t)) cts "*\\{"
+ )^ "}"
in
let s = Printf.sprintf "(%s,%i)" s q in
let s_frm =
let hash (f,s,t) =
HASHINT3(Formula.uid f ,StateSet.uid s,StateSet.uid t)
end)
-(* Too slow
-module MemoForm = Memoizer.Make(
-
-module F = Formula
-(*
-let eval_form_bool =
- MemoForm.make_rec(
- fun eval (f, ((s1,s2) as sets)) ->
- match F.expr f with
- | 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)
- else false,false,false
- | F.Atom(_,b,q) ->
- if b == (StateSet.mem q s2)
- then (true,false,true)
- else false,false,false
- | F.Or(f1,f2) ->
- let b1,rl1,rr1 = eval (f1,sets)
- in
- if b1 && rl1 && rr1 then (true,true,true) else
- let b2,rl2,rr2 = eval (f2,sets) in
- 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) ->
- let b1,rl1,rr1 = eval (f1,sets) in
- if b1 && rl1 && rr1 then (true,true,true) else
- if b1 then
- let b2,rl2,rr2 = eval (f2,sets) in
- if b2 then (true,rl1||rl2,rr1||rr2) else (false,false,false)
- else (false,false,false)
- )
-
-*) *)
module F = Formula
let eval_form_bool =
module type ResultSet =
sig
type t
- type elt = [` Tree] Tree.node
+ type elt = [` Tree ] Tree.node
val empty : t
val cons : elt -> t -> t
val concat : t -> t -> t
let merge (rb,rb1,rb2,mark) t res1 res2 =
if rb then
let res1 = if rb1 then res1 else empty
- and res2 = if rb2 then res2 else empty
+ and res2 = if rb2 then res2 else empty
in
if mark then { node = Cons(t,(Concat(res1.node,res2.node)));
length = res1.length + res2.length + 1;}
end
-
+ module GResult = struct
+ type t
+ type elt = [` Tree] Tree.node
+ external create_empty : int -> t = "caml_result_set_create"
+ external set : t -> int -> t = "caml_result_set_set"
+ external next : t -> int -> int = "caml_result_set_next"
+ external clear : t -> int -> int -> unit = "caml_result_set_clear"
+ let empty = create_empty 100000000
+
+ let cons e t = set t (Obj.magic e)
+ let concat _ t = t
+ let iter f t =
+ let rec loop i =
+ if i == -1 then ()
+ else (f (Obj.magic i);loop (next t i))
+ in loop 0
+
+ let fold _ _ _ = failwith "noop"
+ let map _ _ = failwith "noop"
+ let length t = let cpt = ref ~-1 in
+ iter (fun _ -> incr cpt) t; !cpt
+
+ let merge (rb,rb1,rb2,mark) elt t1 t2 =
+ if mark then (set t1 (Obj.magic elt) ; t1) else t1
+
+ end
module Run (RS : ResultSet) =
struct
- module SList = struct
- include Hlist.Make (StateSet)
- type data = t node
- let make _ = failwith "make"
- end
+ module SList = Hlist.Make (StateSet)
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 mk_app_fun2 f arg1 arg2 s = let g = f arg1 arg2 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 "{")^ " }"
+(*
+ module Algebra =
+ struct
+ type jump = [ `LONG | `CLOSE | `NIL ]
+ type t = jump*Ptset.Int.t
+
+ let merge_jump (j1,l1) (j2,l2) =
+ match j1,j2 with
+ | _ when j1 = j2 -> (j1,Ptset.Int.union l1 l2)
+ | _,`NIL -> j1,l1
+ | `NIL,_ -> j2,l2
+ | _,_ -> (`CLOSE, Ptset.Int.union l1 l2)
+
+ let merge_jump_list = function
+ | [] -> `NIL,Ptset.Int.empty
+ | p::r -> List.fold_left (merge_jump) p r
+
+ let labels a s =
+ Hashtbl.fold
+ (
+ fun q l acc ->
+ if (q == s)
+ then
+
+ (List.fold_left
+ (fun acc (ts,f) ->
+ let _,_,_,bur = Transition.node f in
+ 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 =
+ List.exists
+ (fun (_,t) -> let _,_,f,_ = Transition.node t in
+ StateSet.mem s (access f)) (Hashtbl.find a.trans s)
+
+
+ let decide a c_label l_label dir_states access =
+
+ let l = StateSet.fold
+ (fun s l ->
+ let s_rec= is_rec a s access in
+ let tlabels,jmp =
+ if s_rec then l_label,`LONG
+ else c_label,`CLOSE in
+ let slabels = TagSet.positive ((TagSet.cap (labels a s) tlabels))
+ in
+ (if Ptset.Int.is_empty slabels
+ then `NIL,Ptset.Int.empty
+ else jmp,slabels)::l) dir_states []
+ in merge_jump_list l
+
+
+
+
+
+ end
+
+
let choose_jump tagset qtags1 qtagsn a f_nil f_t1 f_s1 f_tn f_sn f_notext f_maytext =
let tags1,hastext1,fin1 = inter_text tagset (tags a qtags1) in
let tagsn,hastextn,finn = inter_text tagset (tags a qtagsn) in
else if (hastext1||hastextn) then (`ANY,f_maytext)
else (`ANY,f_notext)
- let choose_jump_down tree a b c d =
+ let choose_jump_down tree a b c d =
choose_jump a b c d
(mk_fun (fun _ -> Tree.nil) "Tree.mk_nil")
(mk_fun (Tree.tagged_child tree) "Tree.tagged_child")
(mk_fun (Tree.select_foll_ctx tree) "Tree.select_foll_ctx")
(mk_fun (Tree.next_element_ctx tree) "Tree.node_element_ctx")
(mk_fun (Tree.next_sibling_ctx tree) "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 Algebra =
+ struct
+ type jump = [ `NIL | `ANY |`ANYNOTEXT | `JUMP ]
+ type t = jump*Ptset.Int.t*Ptset.Int.t
+ let jts = function
+ | `JUMP -> "JUMP"
+ | `NIL -> "NIL"
+ | `ANY -> "ANY"
+ | `ANYNOTEXT -> "ANYNOTEXT"
+ 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,_ ->
+ 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 ->
+ 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
+ | [] -> `NIL,Ptset.Int.empty,Ptset.Int.empty
+ | p::r ->
+ List.fold_left (merge_jump) p r
+
+ let labels a s =
+ Hashtbl.fold
+ (
+ fun q l acc ->
+ if (q == s)
+ then
+
+ (List.fold_left
+ (fun acc (ts,f) ->
+ let _,_,_,bur = Transition.node f in
+ 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 =
+ 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)
+
- module CachedTransTable = Hashtbl.Make(SetTagKey)
- let td_trans = CachedTransTable.create 4093
-
+ let decide a c_label l_label dir_states dir =
+
+ 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 =
+ 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
+ (TagSet.cap (TagSet.inj_positive l_label) s_lab))
+ 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
+ && 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
+
+
+
+ let choose_jump (d,cl,ll) f_nil f_t1 f_s1 f_tn f_sn f_s1n f_notext f_maytext =
+ match d with
+ | `NIL -> (`NIL,f_nil)
+ | `ANYNOTEXT -> `ANY,f_notext
+ | `ANY -> `ANY,f_maytext
+ | `JUMP ->
+ if Ptset.Int.is_empty cl then
+ if Ptset.Int.is_singleton ll then
+ let tag = Ptset.Int.choose ll in
+ (`TAG(tag),mk_app_fun f_tn tag (Tag.to_string tag))
+ else
+ (`ANY,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
+ (`TAG(tag),mk_app_fun f_t1 tag (Tag.to_string tag))
+ else
+ (`ANY,mk_app_fun f_s1 cl (string_of_ts cl))
+ else
+ (`ANY,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
+ (mk_fun (fun _ -> Tree.nil) "Tree.mk_nil")
+ (mk_fun (Tree.tagged_child tree) "Tree.tagged_child")
+ (mk_fun (Tree.select_child tree) "Tree.select_child")
+ (mk_fun (Tree.tagged_desc tree) "Tree.tagged_desc")
+ (mk_fun (Tree.select_desc tree) "Tree.select_desc")
+ (mk_fun (fun _ _ -> Tree.first_child tree) "[FIRSTCHILD]Tree.select_child_desc")
+ (mk_fun (Tree.first_element tree) "Tree.first_element")
+ (mk_fun (Tree.first_child tree) "Tree.first_child")
+
+ let choose_jump_next tree d =
+ choose_jump d
+ (mk_fun (fun _ _ -> Tree.nil) "Tree.mk_nil2")
+ (mk_fun (Tree.tagged_sibling_ctx tree) "Tree.tagged_sibling_ctx")
+ (mk_fun (Tree.select_sibling_ctx tree) "Tree.select_sibling_ctx")
+ (mk_fun (Tree.tagged_foll_ctx tree) "Tree.tagged_foll_ctx")
+ (mk_fun (Tree.select_foll_ctx tree) "Tree.select_foll_ctx")
+ (mk_fun (fun _ _ -> Tree.next_sibling_ctx tree) "[NEXTSIBLING]Tree.select_sibling_foll_ctx")
+ (mk_fun (Tree.next_element_ctx tree) "Tree.next_element_ctx")
+ (mk_fun (Tree.next_sibling_ctx tree) "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,s.SList.Node.id)
+ end
+
+ module CachedTransTable = Hashtbl.Make(SetTagKey)
+ let td_trans = CachedTransTable.create 4093
+
+
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 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
+
+ module Fold2Res = Hashtbl.Make(struct
+ type t = Formlistlist.t*SList.t*SList.t
+ let hash (f,s,t) = HASHINT3(f.Formlistlist.Node.id,
+ s.SList.Node.id,
+ t.SList.Node.id)
+ let equal (a,b,c) (d,e,f) = a==d && b == e && c == f
+ end)
+
+ let h_fold2 = Fold2Res.create BIG_H_SIZE
-
let top_down ?(noright=false) a tree t slist ctx slot_size =
let pempty = empty_size slot_size in
- (* evaluation starts from the right so we put sl1,res1 at the end *)
+ let 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 (sl2,res2) (sl1,res1) =
- let res = Array.copy res1 in
- let rec fold l1 l2 fll i aq =
- match SList.node l1,SList.node l2, fll with
- | SList.Cons(s1,ll1),
- SList.Cons(s2,ll2),
- fl::fll ->
- let r',flags = eval_formlist s1 s2 fl in
- let _ = res.(i) <- RS.merge flags t res1.(i) res2.(i)
- in
- fold ll1 ll2 fll (i+1) (SList.cons r' aq)
-
- | SList.Nil, SList.Nil,[] -> aq,res
- | _ -> assert false
- in
- fold sl1 sl2 fll 0 SList.nil
+ let res = Array.copy rempty in
+ try
+ let r,b,btab = Fold2Res.find h_fold2 (fll,sl1,sl2) in
+ if b then for i=0 to slot_size - 1 do
+ res.(i) <- RS.merge btab.(i) t res1.(i) res2.(i);
+ done;
+ r,res
+ with
+ Not_found ->
+ let btab = Array.make slot_size (false,false,false,false) in
+ let rec fold l1 l2 fll i aq ab =
+ match fll.Formlistlist.Node.node,
+ l1.SList.Node.node,
+ l2.SList.Node.node
+ with
+ | Formlistlist.Cons(fl,fll),
+ SList.Cons(s1,ll1),
+ SList.Cons(s2,ll2) ->
+ let r',((b,_,_,_) as flags) = eval_formlist s1 s2 fl in
+ let _ = btab.(i) <- flags
+ in
+ fold ll1 ll2 fll (i+1) (SList.cons r' aq) (b||ab)
+ | _ -> aq,ab
+ in
+ let r,b = fold sl1 sl2 fll 0 SList.nil false in
+ Fold2Res.add h_fold2 (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;
+ r,res
in
- let null_result() = (pempty,Array.make slot_size RS.empty) in
-
- let rec loop t slist ctx =
- if t == Tree.nil then null_result() else get_trans t slist (Tree.tag tree t) ctx
+ let null_result = (pempty,Array.copy rempty) in
+ let rec loop t slist ctx=
+ if t == Tree.nil then null_result else get_trans t slist (Tree.tag tree t) ctx
and loop_tag tag t slist ctx =
- if t == Tree.nil then null_result() else get_trans t slist tag ctx
+ if t == Tree.nil then null_result else get_trans t slist tag ctx
and loop_no_right t slist ctx =
- if t == Tree.nil then null_result() else get_trans ~noright:true t slist (Tree.tag tree t) ctx
+ if t == Tree.nil then null_result else get_trans ~noright:true t slist (Tree.tag tree t) ctx
and get_trans ?(noright=false) t slist tag ctx =
let cont =
try
)
) 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 (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
(* Logic to chose the first and next function *)
- let _,tags_below,_,tags_after = Tree.tags tree tag in
- let f_kind,first = choose_jump_down tree tags_below ca da a
+ 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 _ = Printf.eprintf "Tags below %s are : \n" (Tag.to_string tag) in
+ let _ = Ptset.Int.iter (fun i -> Printf.eprintf "%s " (Tag.to_string i)) tags_below in
+ let _ = Printf.eprintf "\n%!" in *)
+(* let tags_below = Ptset.Int.remove tag tags_below 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 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
-
-
+ else choose_jump_next tree d_n in
+ let empty_res = null_result in
+ let cont =
+ match f_kind,n_kind with
+ | `NIL,`NIL ->
+ (fun t _ -> 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_tag tag2 (next t ctx) rlist ctx)
+ (loop_tag tag1 (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 tree 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 tree =
let init = SList.cons a.init SList.nil in
let _,res = top_down a tree Tree.root init Tree.root 1
in
D_IGNORE_(
- output_trace a tree root "trace.html"
- (RS.fold (fun t a -> IntSet.add (Tree.id t) a) res.(0) IntSet.empty),
+ output_trace a tree "trace.html"
+ (RS.fold (fun t a -> IntSet.add (Tree.id tree t) a) res.(0) IntSet.empty),
res.(0))
;;
StateSet.print fmt k;
Format.fprintf fmt "-> %i\n" (RS.length d)) c.results;
Format.fprintf fmt "\n%!"
-
+
let merge c1 c2 =
- let acc1 = IMap.fold (fun s r acc ->
- IMap.add s
- (try
- RS.concat r (IMap.find s acc)
- with
- | Not_found -> r) acc) c1.results IMap.empty
+ let acc1 =
+ IMap.fold
+ ( fun s r acc ->
+ IMap.add s
+ (try
+ RS.concat r (IMap.find s acc)
+ with
+ | Not_found -> r) acc) c1.results IMap.empty
in
let imap =
- IMap.fold (fun s r acc ->
- IMap.add s
- (try
- RS.concat r (IMap.find s acc)
- with
- | Not_found -> r) acc) c2.results acc1
+ IMap.fold (fun s r acc ->
+ IMap.add s
+ (try
+ RS.concat r (IMap.find s acc)
+ with
+ | Not_found -> r) acc) c2.results acc1
in
let h,s =
Ptss.fold
|SList.Cons(s,sll), formlist::fll ->
let r',(rb,rb1,rb2,mark) =
let key = SList.hash sl,Formlist.hash formlist,dir in
- try
- Hashtbl.find h_fold key
- with
- Not_found -> let res =
- if dir then eval_formlist s Ptset.Int.empty formlist
- else eval_formlist Ptset.Int.empty s formlist
- in (Hashtbl.add h_fold key res;res)
+ try
+ Hashtbl.find h_fold key
+ with
+ Not_found -> let res =
+ if dir then eval_formlist s Ptset.Int.empty formlist
+ else eval_formlist Ptset.Int.empty s formlist
+ in (Hashtbl.add h_fold key res;res)
+ in
+ if rb && ((dir&&rb1)|| ((not dir) && rb2))
+ then
+ let acc =
+ let old_r =
+ try Configuration.IMap.find s conf.Configuration.results
+ with Not_found -> RS.empty
in
- if rb && ((dir&&rb1)|| ((not dir) && rb2))
- 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)
- in
- loop sll fll acc
- else loop sll fll acc
+ 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
| _ -> assert false
in
loop slist fl_list Configuration.empty
in
(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 =
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 =
- 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
+ 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
let sub =
if dotd then
- if below_right then prepare_topdown a tree t true
- else prepare_topdown a tree t false
+ if below_right then prepare_topdown a tree t true
+ else prepare_topdown a tree t false
else conf
in
let conf,next =
(Configuration.merge rightconf sub, next_of_next)
in
- if t == root then accu,conf,next
- else
+ if t == root then accu,conf,next else
let parent = Tree.binary_parent tree t in
let ptag = Tree.tag tree parent in
let dir = Tree.is_left tree t in
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
-(* pr "Going top down on tree with tag %s = %s "
- (if Tree.is_nil t then "###" else (Tag.to_string(Tree.tag t))) (Tree.dump_node t); *)
let r =
try
Hashtbl.find h_tdconf tag
let set = match SList.node set with
| SList.Cons(x,_) ->x
| _ -> assert false
- in
-(* pr "Result of topdown run is %!";
- StateSet.print fmt (Ptset.Int.elements set);
- pr ", number is %i\n%!" (RS.length res.(0)); *)
- Configuration.add Configuration.empty set res.(0)
+ in
+ Configuration.add Configuration.empty set res.(0)
let run_bottom_up a tree k =
let t = Tree.root in
- let trlist = Hashtbl.find a.trans (Ptset.Int.choose a.init)
+ let trlist = Hashtbl.find a.trans (StateSet.choose a.init)
in
let init = List.fold_left
(fun acc (_,t) ->
let _,_,f,_ = Transition.node t in
let _,_,l = fst ( Formula.st f ) in
- Ptset.Int.union acc l)
- Ptset.Int.empty trlist
+ StateSet.union acc l)
+ StateSet.empty trlist
in
let tree1,jump_fun =
match k with
(*Tree.tagged_lowest t tag, fun tree -> Tree.tagged_next tree tag*)
(Tree.tagged_desc tree tag t, let jump = Tree.tagged_foll_ctx tree tag
in fun n -> jump n t )
- | `CONTAINS(_) -> (Tree.first_child tree t,let jump = Tree.next_sibling_ctx 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 _ = pr "\n_________________________\nNew iteration\n" in
- let _ = pr "Jumping to %s\n%!" (Tree.dump_node tree) in *)
let acc,conf,next_of_next = bottom_up a tree t
Configuration.empty next jump_fun (Tree.root) true init acc
in
- (* let _ = pr "End of first iteration, conf is:\n%!";
- Configuration.pr fmt conf
- in *)
let acc = Configuration.IMap.fold
- ( fun s res acc -> if Ptset.Int.intersect init s
+ ( fun s res acc -> if StateSet.intersect init s
then RS.concat res acc else acc) conf.Configuration.results acc
in
if Tree.is_nil next_of_next (*|| Tree.equal next next_of_next *)then