Commit 79ce2417 authored by Kim Nguyễn's avatar Kim Nguyễn
Browse files

Re-factor the BoolVar module. Move it to bool.ml and factor as much code as possible with Bool

parent 5cace08c
...@@ -161,9 +161,9 @@ OBJECTS = \ ...@@ -161,9 +161,9 @@ OBJECTS = \
driver/cduce_config.cmo misc/stats.cmo misc/custom.cmo misc/encodings.cmo \ driver/cduce_config.cmo misc/stats.cmo misc/custom.cmo misc/encodings.cmo \
misc/upool.cmo misc/pretty.cmo misc/ns.cmo misc/imap.cmo misc/html.cmo misc/utils.cmo \ misc/upool.cmo misc/pretty.cmo misc/ns.cmo misc/imap.cmo misc/html.cmo misc/utils.cmo \
\ \
types/compunit.cmo types/sortedList.cmo misc/bool.cmo types/ident.cmo \ types/compunit.cmo types/sortedList.cmo types/ident.cmo types/var.cmo misc/bool.cmo \
types/intervals.cmo types/chars.cmo types/atoms.cmo types/normal.cmo \ types/intervals.cmo types/chars.cmo types/atoms.cmo types/normal.cmo \
types/var.cmo types/boolVar.cmo types/types.cmo compile/auto_pat.cmo \ types/types.cmo compile/auto_pat.cmo \
types/sequence.cmo types/builtin_defs.cmo \ types/sequence.cmo types/builtin_defs.cmo \
\ \
runtime/value.cmo \ runtime/value.cmo \
...@@ -347,9 +347,6 @@ misc/q_symbol.cmo: misc/q_symbol.ml ...@@ -347,9 +347,6 @@ misc/q_symbol.cmo: misc/q_symbol.ml
$(HIDE) $(CAMLC) -c -pp camlp4orf $< $(HIDE) $(CAMLC) -c -pp camlp4orf $<
types/boolVar.cmo: SYNTAX_PARSER=
types/boolVar.cmi: SYNTAX_PARSER=
types/boolVar.cmx: SYNTAX_PARSER=
parser/parser.$(EXTENSION): PACKAGES += camlp4.extend parser/parser.$(EXTENSION): PACKAGES += camlp4.extend
.ml.cmo: .ml.cmo:
......
...@@ -22,12 +22,16 @@ types/compunit.cmo : types/compunit.cmi ...@@ -22,12 +22,16 @@ types/compunit.cmo : types/compunit.cmi
types/compunit.cmx : types/compunit.cmi types/compunit.cmx : types/compunit.cmi
types/sortedList.cmo : misc/custom.cmo types/sortedList.cmi types/sortedList.cmo : misc/custom.cmo types/sortedList.cmi
types/sortedList.cmx : misc/custom.cmx types/sortedList.cmi types/sortedList.cmx : misc/custom.cmx types/sortedList.cmi
misc/bool.cmo : misc/custom.cmo misc/bool.cmi
misc/bool.cmx : misc/custom.cmx misc/bool.cmi
types/ident.cmo : misc/utils.cmo types/sortedList.cmi misc/ns.cmi \ types/ident.cmo : misc/utils.cmo types/sortedList.cmi misc/ns.cmi \
misc/encodings.cmi misc/encodings.cmi
types/ident.cmx : misc/utils.cmx types/sortedList.cmx misc/ns.cmx \ types/ident.cmx : misc/utils.cmx types/sortedList.cmx misc/ns.cmx \
misc/encodings.cmx misc/encodings.cmx
types/var.cmo : misc/utils.cmo types/sortedList.cmi types/ident.cmo \
misc/custom.cmo types/var.cmi
types/var.cmx : misc/utils.cmx types/sortedList.cmx types/ident.cmx \
misc/custom.cmx types/var.cmi
misc/bool.cmo : types/var.cmi misc/custom.cmo misc/bool.cmi
misc/bool.cmx : types/var.cmx misc/custom.cmx misc/bool.cmi
types/intervals.cmo : types/intervals.cmi types/intervals.cmo : types/intervals.cmi
types/intervals.cmx : types/intervals.cmi types/intervals.cmx : types/intervals.cmi
types/chars.cmo : misc/custom.cmo types/chars.cmi types/chars.cmo : misc/custom.cmo types/chars.cmi
...@@ -38,24 +42,16 @@ types/atoms.cmx : misc/upool.cmx types/sortedList.cmx misc/ns.cmx \ ...@@ -38,24 +42,16 @@ types/atoms.cmx : misc/upool.cmx types/sortedList.cmx misc/ns.cmx \
misc/imap.cmx misc/encodings.cmx types/atoms.cmi misc/imap.cmx misc/encodings.cmx types/atoms.cmi
types/normal.cmo : types/normal.cmi types/normal.cmo : types/normal.cmi
types/normal.cmx : types/normal.cmi types/normal.cmx : types/normal.cmi
types/var.cmo : misc/utils.cmo types/sortedList.cmi types/ident.cmo \
misc/custom.cmo types/var.cmi
types/var.cmx : misc/utils.cmx types/sortedList.cmx types/ident.cmx \
misc/custom.cmx types/var.cmi
types/boolVar.cmo : types/var.cmi misc/custom.cmo misc/bool.cmi \
types/boolVar.cmi
types/boolVar.cmx : types/var.cmx misc/custom.cmx misc/bool.cmx \
types/boolVar.cmi
types/types.cmo : types/var.cmi misc/utils.cmo misc/stats.cmi \ types/types.cmo : types/var.cmi misc/utils.cmo misc/stats.cmi \
types/sortedList.cmi misc/pretty.cmi misc/ns.cmi types/normal.cmi \ types/sortedList.cmi misc/pretty.cmi misc/ns.cmi types/normal.cmi \
types/intervals.cmi types/ident.cmo misc/encodings.cmi misc/custom.cmo \ types/intervals.cmi types/ident.cmo misc/encodings.cmi misc/custom.cmo \
types/compunit.cmi types/chars.cmi types/boolVar.cmi misc/bool.cmi \ types/compunit.cmi types/chars.cmi misc/bool.cmi types/atoms.cmi \
types/atoms.cmi types/types.cmi types/types.cmi
types/types.cmx : types/var.cmx misc/utils.cmx misc/stats.cmx \ types/types.cmx : types/var.cmx misc/utils.cmx misc/stats.cmx \
types/sortedList.cmx misc/pretty.cmx misc/ns.cmx types/normal.cmx \ types/sortedList.cmx misc/pretty.cmx misc/ns.cmx types/normal.cmx \
types/intervals.cmx types/ident.cmx misc/encodings.cmx misc/custom.cmx \ types/intervals.cmx types/ident.cmx misc/encodings.cmx misc/custom.cmx \
types/compunit.cmx types/chars.cmx types/boolVar.cmx misc/bool.cmx \ types/compunit.cmx types/chars.cmx misc/bool.cmx types/atoms.cmx \
types/atoms.cmx types/types.cmi types/types.cmi
compile/auto_pat.cmo : types/types.cmi types/ident.cmo types/chars.cmi \ compile/auto_pat.cmo : types/types.cmi types/ident.cmo types/chars.cmi \
types/atoms.cmi compile/auto_pat.cmi types/atoms.cmi compile/auto_pat.cmi
compile/auto_pat.cmx : types/types.cmx types/ident.cmx types/chars.cmx \ compile/auto_pat.cmx : types/types.cmx types/ident.cmx types/chars.cmx \
...@@ -368,16 +364,15 @@ misc/imap.cmi : ...@@ -368,16 +364,15 @@ misc/imap.cmi :
misc/html.cmi : misc/html.cmi :
types/compunit.cmi : types/compunit.cmi :
types/sortedList.cmi : misc/custom.cmo types/sortedList.cmi : misc/custom.cmo
misc/bool.cmi : misc/custom.cmo types/var.cmi : types/sortedList.cmi misc/custom.cmo
misc/bool.cmi : types/var.cmi misc/custom.cmo
types/intervals.cmi : misc/custom.cmo misc/bool.cmi types/intervals.cmi : misc/custom.cmo misc/bool.cmi
types/chars.cmi : misc/custom.cmo misc/bool.cmi types/chars.cmi : misc/custom.cmo misc/bool.cmi
types/atoms.cmi : misc/ns.cmi misc/encodings.cmi misc/custom.cmo \ types/atoms.cmi : misc/ns.cmi misc/encodings.cmi misc/custom.cmo \
misc/bool.cmi misc/bool.cmi
types/normal.cmi : types/normal.cmi :
types/var.cmi : types/sortedList.cmi misc/custom.cmo
types/boolVar.cmi : types/var.cmi misc/custom.cmo misc/bool.cmi
types/types.cmi : types/var.cmi misc/ns.cmi types/intervals.cmi \ types/types.cmi : types/var.cmi misc/ns.cmi types/intervals.cmi \
types/ident.cmo misc/custom.cmo types/chars.cmi types/boolVar.cmi \ types/ident.cmo misc/custom.cmo types/chars.cmi misc/bool.cmi \
types/atoms.cmi types/atoms.cmi
compile/auto_pat.cmi : types/types.cmi types/ident.cmo types/chars.cmi \ compile/auto_pat.cmi : types/types.cmi types/ident.cmo types/chars.cmi \
types/atoms.cmi types/atoms.cmi
......
This diff is collapsed.
...@@ -21,23 +21,25 @@ sig ...@@ -21,23 +21,25 @@ sig
val trivially_disjoint : t -> t -> bool val trivially_disjoint : t -> t -> bool
end end
module type MAKE = functor (X : Custom.T) -> S with type elem = X.t module Make (X : Custom.T) : S with type elem = X.t
module Make : MAKE module type V =
sig
(* module Atom : S
module type S' = sig
include S include S with type elem = Atom.t Var.var_or_atom
type bdd = False | True | Br of elem * t * t
val br: t -> bdd val var : Var.t -> t
end
(** returns the union of all leaves in the BDD *)
val leafconj: t -> Atom.t
val is_empty : t -> bool
module MakeBdd(X : Custom.T) : S' with type elem = X.t val extract : t -> [ `Empty | `Full | `Split of (elem * t * t * t) ]
module type S'' = sig
include S
val dnf: (elem list -> (elem list) list -> unit) -> t -> unit
end end
module Make2(X : Custom.T) : S'' with type elem = X.t module MakeVar (T : S) : V with module Atom = T and type elem = T.t Var.var_or_atom
*)
let (<) : int -> int -> bool = (<)
let (>) : int -> int -> bool = (>)
let (=) : int -> int -> bool = (=)
module type S = sig
module Atom : Bool.S
include Bool.S with type elem = Atom.t Var.var_or_atom
val var : Var.t -> t
(** returns the union of all leaves in the BDD *)
val leafconj: t -> Atom.t
val is_empty : t -> bool
val pp_print : Format.formatter -> t -> unit
val print : ?f:(Format.formatter -> elem -> unit) -> t -> (Format.formatter -> unit) list
val extract : t -> [ `Empty | `Full | `Split of (elem * t * t * t) ]
end
(* ternary BDD
* where the nodes are Atm of X.t | Var of String.t
* Variables are always before Values
* All the leaves are then base types
*
* we add a third case when two leaves of the bdd are of the same
* kind, that's it Val of t1 , Val of t2
*
* This representation can be used for all kinds.
* Intervals, Atoms and Chars can be always merged (for union and intersection)
* Products can be merged for intersections
* Arrows can be never merged
*
* extract_var : copy the orginal tree and on one copy put to zero all
* leaves that have an Atm on the other all leaves that have a Var
*
* *)
module Make (T : Bool.S) : S with module Atom = T and type elem = T.t Var.var_or_atom = struct
(* ternary decision trees . cf section 11.3.3 Frish PhD *)
(* plus variables *)
(* `Atm are containers (Atoms, Chars, Intervals, Pairs ... )
* `Var are String
*)
module Atom = T
type elem = T.t Var.var_or_atom
module X : Custom.T with type t = elem = Var.Make(T)
type 'a bdd = False
| True
| Split of int * 'a * ('a bdd) * ('a bdd) * ('a bdd)
type t = elem bdd
let rec equal_aux eq a b =
(a == b) ||
match (a,b) with
| Split (h1,x1,p1,i1,n1), Split (h2,x2,p2,i2,n2) ->
(h1 == h2) &&
(equal_aux eq p1 p2) && (equal_aux eq i1 i2) &&
(equal_aux eq n1 n2) && (eq x1 x2)
| _ -> false
let equal = equal_aux X.equal
(* Idea: add a mutable "unique" identifier and set it to
the minimum of the two when egality ... *)
let rec compare a b =
if (a == b) then 0
else match (a,b) with
| Split (h1,x1, p1,i1,n1), Split (h2,x2, p2,i2,n2) ->
if h1 < h2 then -1 else if h1 > h2 then 1
else let c = X.compare x1 x2 in if c <> 0 then c
else let c = compare p1 p2 in if c <> 0 then c
else let c = compare i1 i2 in if c <> 0 then c
else compare n1 n2
| True,_ -> -1
| _, True -> 1
| False,_ -> -1
| _,False -> 1
let rec hash = function
| True -> 1
| False -> 0
| Split(h,_,_,_,_) -> h
let compute_hash x p i n =
(X.hash x) + 17 * (hash p) + 257 * (hash i) + 16637 * (hash n)
let rec check = function
| True -> ()
| False -> ()
| Split (h,x,p,i,n) ->
assert (h = compute_hash x p i n);
(match p with Split (_,y,_,_,_) -> assert (X.compare x y < 0) | _ -> ());
(match i with Split (_,y,_,_,_) -> assert (X.compare x y < 0) | _ -> ());
(match n with Split (_,y,_,_,_) -> assert (X.compare x y < 0) | _ -> ());
X.check x; check p; check i; check n
let atom x =
let h = X.hash x + 17 in (* partial evaluation of compute_hash... *)
Split (h, x,True,False,False)
let var v =
let compute_hash x p i n =
(Var.hash x) + 17 * (hash p) + 257 * (hash i) + 16637 * (hash n)
in
let a = atom (`Atm T.full) in
let h = compute_hash v a False False in
( Split (h,`Var v,a,False,False) :> t )
let rec iter f = function
| Split (_, x, p,i,n) -> f x; iter f p; iter f i; iter f n
| _ -> ()
let rec dump ppf = function
| False -> Format.fprintf ppf "⊥"
| True -> Format.fprintf ppf "⊤"
| Split (_,x, p,i,n) ->
let fmt = format_of_string (
match x with
`Var _ ->
"@[{@[%a@]}{@[<hov>%a,@ %a,@ %a@]}@]"
| `Atm _ ->
"@[ {@[%a@]}@\n {@[<hov>%a,@ %a,@ %a@]}@]"
)
in
Format.fprintf ppf fmt
X.dump x dump p dump i dump n
let rec print f ppf = function
| True -> Format.fprintf ppf "Any"
| False -> Format.fprintf ppf "Empty"
| Split (_, x, p,i, n) ->
let flag = ref false in
let b () = if !flag then Format.fprintf ppf " | " else flag := true in
(match p with
| True -> b(); Format.fprintf ppf "%a" f x
| False -> ()
| _ -> b (); Format.fprintf ppf "%a & @[(%a)@]" f x (print f) p );
(match i with
| True -> assert false;
| False -> ()
| _ -> b(); print f ppf i);
(match n with
| True -> b (); Format.fprintf ppf "@[~%a@]" f x
| False -> ()
| _ -> b (); Format.fprintf ppf "@[~%a@] & @[(%a)@]" f x (print f) n)
let pp_print = print X.dump
let print ?(f=X.dump) = function
| True -> assert false (* [] a bdd cannot be of this type *)
| False -> [ fun ppf -> Format.fprintf ppf "Empty" ]
| c -> [ fun ppf -> print f ppf c ]
(* return a list of pairs, where each pair holds the list
* of positive and negative elements on a branch *)
let get x =
let rec aux accu pos neg = function
| True -> (List.rev pos, List.rev neg) :: accu
| False -> accu
| Split (_,x, p,i,n) ->
let accu = aux accu (x::pos) neg p in
let accu = aux accu pos (x::neg) n in
let accu = aux accu pos neg i in
accu
in aux [] [] [] x
let leafconj x =
let rec aux accu = function
| True -> accu
| False -> accu
| Split (_,`Atm x, True,False,False) -> x :: accu
| Split (_,`Atm x, _,_,_) -> assert false
| Split (_,`Var x, p,i,n) ->
let accu = aux accu p in
let accu = aux accu n in
let accu = aux accu i in
accu
in
List.fold_left T.cup T.empty (aux [] x)
let compute ~empty ~full ~cup ~cap ~diff ~atom b =
let rec aux = function
| True -> full
| False -> empty
| Split (_,`Atm x,True,_,_) when T.equal x T.empty -> empty
| Split (_,`Atm x,True,_,_) when T.equal x T.full -> full
| Split(_,x, p,i,n) ->
let x1 = atom x in
let p = cap x1 (aux p) in
let i = aux i in
let n = diff (aux n) x1 in
cup (cup p i) n
in
aux b
(* Invariant: correct hash value *)
let split0 x pos ign neg =
Split (compute_hash x pos ign neg, x, pos, ign, neg)
let empty = False
let full = split0 (`Atm T.full) True False False
let is_empty t = (t == empty)
(* Invariants:
Split (x, pos,ign,neg) ==> (ign <> True), (pos <> neg)
*)
let rec has_true = function
| [] -> false
| True :: _ -> true
| _ :: l -> has_true l
let rec has_same a = function
| [] -> false
| b :: l -> (equal a b) || (has_same a l)
(* split removes redundant subtrees from the positive and negative
* branch if they are present in the lazy union branch *)
let rec split x p i n =
if X.equal (`Atm T.empty) x then False
(* 0?p:i:n -> 0 *)
else if i == True then True
(* x?p:1:n -> 1 *)
else if equal p n then p ++ i
else let p = simplify p [i] and n = simplify n [i] in
(* x?p:i:n when p = n -> bdd of (p ++ i) *)
if equal p n then p ++ i
else split0 x p i n
(* simplify t l -> bdd of ( t // l ) *)
and simplify a l =
match a with
| False -> False
| True -> if has_true l then False else True
| Split (_,`Atm x, False,False,True) ->
split (`Atm(T.diff T.full x)) True False False
| Split (_,x,p,i,n) ->
if (has_true l) || (has_same a l) then False
else s_aux2 a x p i n [] [] [] l
and s_aux2 a x p i n ap ai an = function
| [] ->
let p = simplify p ap
and n = simplify n an
and i = simplify i ai in
if equal p n then p ++ i else split0 x p i n
| b :: l -> s_aux3 a x p i n ap ai an l b
and s_aux3 a x p i n ap ai an l = function
| False -> s_aux2 a x p i n ap ai an l
| True -> assert false
| Split (_,x2,p2,i2,n2) as b ->
if equal a b then False
else let c = X.compare x2 x in
if c < 0 then s_aux3 a x p i n ap ai an l i2
else if c > 0 then s_aux2 a x p i n (b :: ap) (b :: ai) (b :: an) l
else s_aux2 a x p i n (p2 :: i2 :: ap) (i2 :: ai) (n2 :: i2 :: an) l
(* Inv : all leafs are of type Atm and they are always merged *)
(* union *)
and ( ++ ) a b = if a == b then a
else match (a,b) with
| True, _ | _, True -> True
| False, a | a, False -> a
| Split (_,`Atm x1, True,False,False), Split (_,`Atm x2, True,False,False) ->
split (`Atm (T.cup x1 x2)) True False False
| Split (_,`Atm x1, False,False,True), Split (_,`Atm x2, False,False,True)
| Split (_,`Atm x1, True,False,False), Split (_,`Atm x2, False,False,True)
| Split (_,`Atm x1, False,False,True), Split (_,`Atm x2, True,False,False) ->
assert false
| Split (_,x1, p1,i1,n1), Split (_,x2, p2,i2,n2) ->
let c = X.compare x1 x2 in
if c = 0 then split x1 (p1 ++ p2) (i1 ++ i2) (n1 ++ n2)
else if c < 0 then split x1 p1 (i1 ++ b) n1
else split x2 p2 (i2 ++ a) n2
(* seems better not to make ++ and this split mutually recursive;
is the invariant still inforced ? *)
(* intersection *)
let rec ( ** ) a b = if a == b then a else match (a,b) with
| True, a | a, True -> a
| False, _ | _, False -> False
| Split (_,`Atm x1, True,False,False), Split (_,`Atm x2, True,False,False) ->
split (`Atm(T.cap x1 x2)) True False False
| Split (_,`Atm x1, False,False,True), Split (_,`Atm x2, False,False,True) ->
split (`Atm(T.cap (T.diff T.full x1) (T.diff T.full x2))) True False False
| Split (_,`Atm x1, True,False,False), Split (_,`Atm x2, False,False,True) ->
split (`Atm(T.cap x1 (T.diff T.full x2))) True False False
| Split (_,`Atm x1, False,False,True), Split (_,`Atm x2, True,False,False) ->
split (`Atm(T.cap (T.diff T.full x1) x2)) True False False
| Split (_,x1, p1,i1,n1), Split (_,x2, p2,i2,n2) ->
let c = X.compare x1 x2 in
if c = 0 then
split x1
(p1 ** (p2 ++ i2) ++ (p2 ** i1))
(i1 ** i2)
(n1 ** (n2 ++ i2) ++ (n2 ** i1))
else if c < 0 then split x1 (p1 ** b) (i1 ** b) (n1 ** b)
else split x2 (p2 ** a) (i2 ** a) (n2 ** a)
let rec trivially_disjoint a b =
if a == b then a == False
else match (a,b) with
| True, a | a, True -> a == False
| False, _ | _, False -> true
| Split (_,x1, p1,i1,n1), Split (_,x2, p2,i2,n2) ->
let c = X.compare x1 x2 in
if c = 0 then
(* try expanding -> p1 p2; p1 i2; i1 p2; i1 i2 ... *)
trivially_disjoint (p1 ++ i1) (p2 ++ i2) &&
trivially_disjoint (n1 ++ i1) (n2 ++ i2)
else if c < 0 then
trivially_disjoint p1 b &&
trivially_disjoint i1 b &&
trivially_disjoint n1 b
else
trivially_disjoint p2 a &&
trivially_disjoint i2 a &&
trivially_disjoint n2 a
let rec neg = function
| True -> False
| False -> True
| Split (_,`Atm x, True,False,False) -> split0 (`Atm(T.diff T.full x)) True False False
| Split (_,`Atm x, False,False,True) -> split0 (`Atm(T.diff T.full x)) True False False
| Split (_,x, p,i,False) -> split x False (neg (i ++ p)) (neg i)
| Split (_,x, False,i,n) -> split x (neg i) (neg (i ++ n)) False
| Split (_,x, p,False,n) -> split x (neg p) (neg (p ++ n)) (neg n)
| Split (_,x, p,i,n) -> split x (neg (i ++ p)) False (neg (i ++ n))
let rec ( // ) a b =
let negatm = T.diff T.full in
if a == b then False
else match (a,b) with
| False,_ | _, True -> False
| a, False -> a
| True, b -> neg b
| Split (_,`Atm x1, True,False,False), Split (_,`Atm x2, True,False,False) ->
split (`Atm(T.diff x1 x2)) True False False
| Split (_,`Atm x1, False,False,True), Split (_,`Atm x2, False,False,True) ->
split (`Atm(T.diff (negatm x1) (negatm x2))) True False False
| Split (_,`Atm x1, True,False,False), Split (_,`Atm x2, False,False,True) ->
split (`Atm(T.diff x1 (negatm x2))) True False False
| Split (_,`Atm x1, False,False,True), Split (_,`Atm x2, True,False,False) ->
split (`Atm(T.diff (negatm x1) x2)) True False False
| Split (_,x1, p1,i1,n1), Split (_,x2, p2,i2,n2) ->
let c = X.compare x1 x2 in
if c = 0 then
if (i2 == False) && (n2 == False)
then split x1 (p1 // p2) (i1 // p2) (n1 ++ i1)
else
split x1 ((p1++i1) // (p2 ++ i2)) False ((n1++i1) // (n2 ++ i2))
else if c < 0 then
split x1 (p1 // b) (i1 // b) (n1 // b)
else
split x2 (a // (i2 ++ p2)) False (a // (i2 ++ n2))
let cup = ( ++ )
let cap = ( ** )
let diff = ( // )
let extract =
function
| False -> `Empty
| True -> `Full
| Split (_,x,p,i,n) -> `Split (x,p,i,n)
end
module type S = sig
module Atom : Bool.S
include Bool.S with type elem = Atom.t Var.var_or_atom
val var : Var.t -> t
(** returns the union of all leaves in the BDD *)
val leafconj: t -> Atom.t
val is_empty : t -> bool
val pp_print : Format.formatter -> t -> unit
val print : ?f:(Format.formatter -> elem -> unit) -> t -> (Format.formatter -> unit) list
val extract : t -> [ `Empty | `Full | `Split of (elem * t * t * t) ]
end
module Make : functor (T : Bool.S) -> S with module Atom = T and type elem = T.t Var.var_or_atom
...@@ -134,10 +134,10 @@ end ...@@ -134,10 +134,10 @@ end
type pair_kind = [ `Normal | `XML ] type pair_kind = [ `Normal | `XML ]
module BoolAtoms = BoolVar.Make(Atoms) module BoolAtoms = Bool.MakeVar(Atoms)
module BoolIntervals = BoolVar.Make(Intervals) module BoolIntervals = Bool.MakeVar(Intervals)
module BoolChars = BoolVar.Make(Chars)