+
+
+ 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)
+
+ 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 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
+ (`MANY(ll),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
+ (`MANY(cl),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 SListTable = Hashtbl.Make(struct type t = SList.t
+ let equal = (==)
+ let hash t = t.SList.Node.id
+ end)
+
+
+ module TransCacheOld =
+ struct
+ type 'a t = Obj.t array SListTable.t
+ let create n = SListTable.create n
+ let dummy = Obj.repr (fun _ -> assert false)
+ let find (h :'a t) tag slist : 'a =
+ let tab =
+ try
+ SListTable.find h slist
+ with
+ Not_found ->
+ SListTable.add h slist (Array.create 10000 dummy);
+ raise Not_found
+ in
+ let res = tab.(tag) in
+ if res == dummy then raise Not_found else (Obj.magic res)
+
+ let add (h : 'a t) tag slist (data : 'a) =
+ let tab =
+ try
+ SListTable.find h slist
+ with
+ Not_found ->
+ let arr = Array.create 10000 dummy in
+ SListTable.add h slist arr;
+ arr
+ in
+ tab.(tag) <- (Obj.repr data)
+
+
+ end
+
+ module TransCache =
+ struct
+ external get : 'a array -> int ->'a = "%array_unsafe_get"
+ external set : 'a array -> int -> 'a -> unit = "%array_unsafe_set"
+ type fun_tree = [`Tree] Tree.node -> [`Tree] Tree.node -> SList.t*RS.t array
+ type t = fun_tree array array
+ let dummy_cell = [||]
+ let create n = Array.create n dummy_cell
+ let dummy = fun _ _-> assert false
+ let find h tag slist =
+ let tab = get h slist.SList.Node.id in
+ if tab == dummy_cell then raise Not_found
+ else
+ let res = get tab tag in
+ if res == dummy then raise Not_found else res
+
+ let add (h : t) tag slist (data : fun_tree) =
+ let tab = get h slist.SList.Node.id in
+ let tab = if tab == dummy_cell then
+ let x = Array.create 10000 dummy in
+ (set h slist.SList.Node.id x;x)
+ else tab
+ in
+ set tab tag data
+ end
+
+ let td_trans = TransCache.create 10000 (* should be number of tags *number of states^2
+ in the document *)
+
+ 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
+
+ module FllTable = Hashtbl.Make (struct type t = Formlistlist.t
+ let equal = (==)
+ let hash t = t.Formlistlist.Node.id
+ end)