1 (******************************************************************************)
2 (* SXSI : XPath evaluator *)
3 (* Kim Nguyen (Kim.Nguyen@nicta.com.au) *)
4 (* Copyright NICTA 2008 *)
5 (* Distributed under the terms of the LGPL (see LICENCE) *)
6 (******************************************************************************)
10 type t = private Finite of S.t | CoFinite of S.t
11 exception InfiniteTagSet
14 val is_empty : t -> bool
15 val is_any : t -> bool
16 val is_finite : t -> bool
17 val singleton : S.elt -> t
18 val mem : S.elt -> t -> bool
19 val add : S.elt -> t -> t
20 val remove : S.elt -> t -> t
23 val diff : t -> t -> t
25 val compare : t -> t -> int
26 val subset : t -> t -> bool
27 val kind_split : t list -> t * t
28 val fold : (S.elt -> 'a -> 'a) -> t -> 'a -> 'a
29 val for_all : (S.elt -> bool) -> t -> bool
30 val exists : (S.elt -> bool) -> t -> bool
31 val filter : (S.elt -> bool) -> t -> S.t
32 val partition : (S.elt -> bool) -> t -> S.t * S.t
33 val cardinal : t -> int
34 val elements : t -> S.elt list
35 val from_list : S.elt list -> t
36 val choose : t -> S.elt
39 module Make (Symbol : Set.OrderedType) =
41 module S = Set.Make(Symbol)
42 type t = Finite of S.t | CoFinite of S.t
44 exception InfiniteTagSet
46 let empty = Finite S.empty
47 let any = CoFinite S.empty
49 let is_empty = function
50 Finite s when S.is_empty s -> true
53 CoFinite s when S.is_empty s -> true
55 let is_finite = function
56 | Finite _ -> true | _ -> false
58 let mem x = function Finite s -> S.mem x s
59 | CoFinite s -> not (S.mem x s)
61 let singleton x = Finite (S.singleton x)
63 | Finite s -> Finite (S.add e s)
64 | CoFinite s -> CoFinite (S.remove e s)
65 let remove e = function
66 | Finite s -> Finite (S.remove e s)
67 | CoFinite s -> CoFinite (S.add e s)
69 let cup s t = match (s,t) with
70 | Finite s, Finite t -> Finite (S.union s t)
71 | CoFinite s, CoFinite t -> CoFinite ( S.inter s t)
72 | Finite s, CoFinite t -> CoFinite (S.diff t s)
73 | CoFinite s, Finite t-> CoFinite (S.diff s t)
75 let cap s t = match (s,t) with
76 | Finite s, Finite t -> Finite (S.inter s t)
77 | CoFinite s, CoFinite t -> CoFinite (S.union s t)
78 | Finite s, CoFinite t -> Finite (S.diff s t)
79 | CoFinite s, Finite t-> Finite (S.diff t s)
81 let diff s t = match (s,t) with
82 | Finite s, Finite t -> Finite (S.diff s t)
83 | Finite s, CoFinite t -> Finite(S.inter s t)
84 | CoFinite s, Finite t -> CoFinite(S.union t s)
85 | CoFinite s, CoFinite t -> Finite (S.diff t s)
88 | Finite s -> CoFinite s
89 | CoFinite s -> Finite s
91 let compare s t = match (s,t) with
92 | Finite s , Finite t -> S.compare s t
93 | CoFinite s , CoFinite t -> S.compare s t
94 | Finite _, CoFinite _ -> -1
95 | CoFinite _, Finite _ -> 1
97 let subset s t = match (s,t) with
98 | Finite s , Finite t -> S.subset s t
99 | CoFinite s , CoFinite t -> S.subset t s
100 | Finite s, CoFinite t -> S.is_empty (S.inter s t)
101 | CoFinite _, Finite _ -> false
103 (* given a list l of type t list,
104 returns two sets (f,c) where :
105 - f is the union of all the finite sets of l
106 - c is the union of all the cofinite sets of l
107 - f and c are disjoint
108 Invariant : cup f c = List.fold_left cup empty l
110 We treat the CoFinite part explicitely :
115 let rec next_finite_cofinite facc cacc = function
116 | [] -> Finite facc, CoFinite (S.diff cacc facc)
117 | Finite s ::r -> next_finite_cofinite (S.union s facc) cacc r
118 | CoFinite _ ::r when S.is_empty cacc -> next_finite_cofinite facc cacc r
119 | CoFinite s ::r -> next_finite_cofinite facc (S.inter cacc s) r
121 let rec first_cofinite facc = function
123 | Finite s :: r-> first_cofinite (S.union s facc) r
124 | CoFinite s :: r -> next_finite_cofinite facc s r
126 first_cofinite S.empty l
128 let fold f t a = match t with
129 | Finite s -> S.fold f s a
130 | CoFinite _ -> raise InfiniteTagSet
132 let for_all f = function
133 | Finite s -> S.for_all f s
134 | CoFinite _ -> raise InfiniteTagSet
136 let exists f = function
137 | Finite s -> S.exists f s
138 | CoFinite _ -> raise InfiniteTagSet
140 let filter f = function
141 | Finite s -> S.filter f s
142 | CoFinite _ -> raise InfiniteTagSet
144 let partition f = function
145 | Finite s -> S.partition f s
146 | CoFinite _ -> raise InfiniteTagSet
148 let cardinal = function
149 | Finite s -> S.cardinal s
150 | CoFinite _ -> raise InfiniteTagSet
152 let elements = function
153 | Finite s -> S.elements s
154 | CoFinite _ -> raise InfiniteTagSet
157 Finite(List.fold_left (fun x a -> S.add a x ) S.empty l)
159 let choose = function
160 Finite s -> S.choose s
161 | _ -> raise InfiniteTagSet
168 let star = diff any (from_list [ Tag.pcdata; Tag.attribute ])
169 let node = remove Tag.attribute any
170 let pcdata = singleton Tag.pcdata
171 let attribute = singleton Tag.attribute