summaryrefslogtreecommitdiff
path: root/clib
diff options
context:
space:
mode:
Diffstat (limited to 'clib')
-rw-r--r--clib/backtrace.ml119
-rw-r--r--clib/backtrace.mli98
-rw-r--r--clib/bigint.ml526
-rw-r--r--clib/bigint.mli52
-rw-r--r--clib/cArray.ml550
-rw-r--r--clib/cArray.mli157
-rw-r--r--clib/cEphemeron.ml91
-rw-r--r--clib/cEphemeron.mli54
-rw-r--r--clib/cList.ml917
-rw-r--r--clib/cList.mli277
-rw-r--r--clib/cMap.ml220
-rw-r--r--clib/cMap.mli90
-rw-r--r--clib/cObj.ml205
-rw-r--r--clib/cObj.mli61
-rw-r--r--clib/cSet.ml69
-rw-r--r--clib/cSet.mli33
-rw-r--r--clib/cSig.mli88
-rw-r--r--clib/cStack.ml44
-rw-r--r--clib/cStack.mli58
-rw-r--r--clib/cString.ml180
-rw-r--r--clib/cString.mli80
-rw-r--r--clib/cThread.ml99
-rw-r--r--clib/cThread.mli28
-rw-r--r--clib/cUnix.ml146
-rw-r--r--clib/cUnix.mli71
-rw-r--r--clib/canary.ml28
-rw-r--r--clib/canary.mli27
-rw-r--r--clib/clib.mllib40
-rw-r--r--clib/dyn.ml161
-rw-r--r--clib/dyn.mli68
-rw-r--r--clib/exninfo.ml106
-rw-r--r--clib/exninfo.mli41
-rw-r--r--clib/hMap.ml416
-rw-r--r--clib/hMap.mli30
-rw-r--r--clib/hashcons.ml188
-rw-r--r--clib/hashcons.mli92
-rw-r--r--clib/hashset.ml231
-rw-r--r--clib/hashset.mli58
-rw-r--r--clib/heap.ml136
-rw-r--r--clib/heap.mli54
-rw-r--r--clib/iStream.ml92
-rw-r--r--clib/iStream.mli83
-rw-r--r--clib/int.ml239
-rw-r--r--clib/int.mli81
-rw-r--r--clib/minisys.ml80
-rw-r--r--clib/monad.ml170
-rw-r--r--clib/monad.mli96
-rw-r--r--clib/option.ml211
-rw-r--r--clib/option.mli147
-rw-r--r--clib/orderedType.ml35
-rw-r--r--clib/orderedType.mli19
-rw-r--r--clib/predicate.ml98
-rw-r--r--clib/predicate.mli84
-rw-r--r--clib/range.ml93
-rw-r--r--clib/range.mli39
-rw-r--r--clib/segmenttree.ml140
-rw-r--r--clib/segmenttree.mli30
-rw-r--r--clib/store.ml89
-rw-r--r--clib/store.mli43
-rw-r--r--clib/terminal.ml300
-rw-r--r--clib/terminal.mli69
-rw-r--r--clib/trie.ml91
-rw-r--r--clib/trie.mli63
-rw-r--r--clib/unicode.ml387
-rw-r--r--clib/unicode.mli60
-rw-r--r--clib/unicodetable.ml7427
-rw-r--r--clib/unionfind.ml138
-rw-r--r--clib/unionfind.mli82
68 files changed, 16475 insertions, 0 deletions
diff --git a/clib/backtrace.ml b/clib/backtrace.ml
new file mode 100644
index 00000000..27ed6fbf
--- /dev/null
+++ b/clib/backtrace.ml
@@ -0,0 +1,119 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+[@@@ocaml.warning "-37"]
+
+type raw_frame =
+| Known_location of bool (* is_raise *)
+ * string (* filename *)
+ * int (* line number *)
+ * int (* start char *)
+ * int (* end char *)
+| Unknown_location of bool (*is_raise*)
+
+type location = {
+ loc_filename : string;
+ loc_line : int;
+ loc_start : int;
+ loc_end : int;
+}
+
+type frame = { frame_location : location option; frame_raised : bool; }
+
+external get_exception_backtrace: unit -> raw_frame array option
+ = "caml_get_exception_backtrace"
+
+type t = raw_frame array list
+(** List of partial raw stack frames, in reverse order *)
+
+let empty = []
+
+let of_raw = function
+| Unknown_location r ->
+ { frame_location = None; frame_raised = r; }
+| Known_location (r, file, line, st, en) ->
+ let loc = {
+ loc_filename = file;
+ loc_line = line;
+ loc_start = st;
+ loc_end = en;
+ } in
+ { frame_location = Some loc; frame_raised = r; }
+
+let rec repr_aux accu = function
+| [] -> accu
+| fragment :: stack ->
+ let len = Array.length fragment in
+ let rec append accu i =
+ if i = len then accu
+ else append (of_raw fragment.(i) :: accu) (succ i)
+ in
+ repr_aux (append accu 0) stack
+
+let repr bt = repr_aux [] (List.rev bt)
+
+let push stack = match get_exception_backtrace () with
+| None -> []
+| Some frames -> frames :: stack
+
+(** Utilities *)
+
+let print_frame frame =
+ let raise = if frame.frame_raised then "raise" else "frame" in
+ match frame.frame_location with
+ | None -> Printf.sprintf "%s @ unknown" raise
+ | Some loc ->
+ Printf.sprintf "%s @ file \"%s\", line %d, characters %d-%d"
+ raise loc.loc_filename loc.loc_line loc.loc_start loc.loc_end
+
+(** Exception manipulation *)
+
+let backtrace : t Exninfo.t = Exninfo.make ()
+
+let is_recording = ref false
+
+let record_backtrace b =
+ let () = Printexc.record_backtrace b in
+ is_recording := b
+
+let get_backtrace e =
+ Exninfo.get e backtrace
+
+let add_backtrace e =
+ if !is_recording then
+ (** This must be the first function call, otherwise the stack may be
+ destroyed *)
+ let current = get_exception_backtrace () in
+ let info = Exninfo.info e in
+ begin match current with
+ | None -> (e, info)
+ | Some fragment ->
+ let bt = match get_backtrace info with
+ | None -> []
+ | Some bt -> bt
+ in
+ let bt = fragment :: bt in
+ (e, Exninfo.add info backtrace bt)
+ end
+ else
+ let info = Exninfo.info e in
+ (e, info)
+
+let app_backtrace ~src ~dst =
+ if !is_recording then
+ match get_backtrace src with
+ | None -> dst
+ | Some bt ->
+ match get_backtrace dst with
+ | None ->
+ Exninfo.add dst backtrace bt
+ | Some nbt ->
+ let bt = bt @ nbt in
+ Exninfo.add dst backtrace bt
+ else dst
diff --git a/clib/backtrace.mli b/clib/backtrace.mli
new file mode 100644
index 00000000..cd315116
--- /dev/null
+++ b/clib/backtrace.mli
@@ -0,0 +1,98 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** * Low-level management of OCaml backtraces.
+
+ Currently, OCaml manages its backtraces in a very imperative way. That is to
+ say, it only keeps track of the stack destroyed by the last raised exception.
+ So we have to be very careful when using this module not to do silly things.
+
+ Basically, you need to manually handle the reraising of exceptions. In order
+ to do so, each time the backtrace is lost, you must [push] the stack fragment.
+ This essentially occurs whenever a [with] handler is crossed.
+
+*)
+
+(** {5 Backtrace information} *)
+
+type location = {
+ loc_filename : string;
+ loc_line : int;
+ loc_start : int;
+ loc_end : int;
+}
+(** OCaml debugging information for function calls. *)
+
+type frame = { frame_location : location option; frame_raised : bool; }
+(** A frame contains two informations: its optional physical location, and
+ whether it raised the exception or let it pass through. *)
+
+type t
+(** Type of backtraces. They're essentially stack of frames. *)
+
+val empty : t
+(** Empty frame stack. *)
+
+val push : t -> t
+(** Add the current backtrace information to a given backtrace. *)
+
+val repr : t -> frame list
+(** Represent a backtrace as a list of frames. Leftmost element is the outermost
+ call. *)
+
+(** {5 Utilities} *)
+
+val print_frame : frame -> string
+(** Represent a frame. *)
+
+(** {5 Exception handling} *)
+
+val record_backtrace : bool -> unit
+(** Whether to activate the backtrace recording mechanism. Note that it will
+ only work whenever the program was compiled with the [debug] flag. *)
+
+val get_backtrace : Exninfo.info -> t option
+(** Retrieve the optional backtrace coming with the exception. *)
+
+val add_backtrace : exn -> Exninfo.iexn
+(** Add the current backtrace information to the given exception.
+
+ The intended use case is of the form: {[
+
+ try foo
+ with
+ | Bar -> bar
+ | err -> let err = add_backtrace err in baz
+
+ ]}
+
+ WARNING: any intermediate code between the [with] and the handler may
+ modify the backtrace. Yes, that includes [when] clauses. Ideally, what you
+ should do is something like: {[
+
+ try foo
+ with err ->
+ let err = add_backtrace err in
+ match err with
+ | Bar -> bar
+ | err -> baz
+
+ ]}
+
+ I admit that's a bit heavy, but there is not much to do...
+
+*)
+
+val app_backtrace : src:Exninfo.info -> dst:Exninfo.info -> Exninfo.info
+(** Append the backtrace from [src] to [dst]. The returned exception is [dst]
+ except for its backtrace information. This is targeted at container
+ exceptions, that is, exceptions that contain exceptions. This way, one can
+ transfer the backtrace from the container to the underlying exception, as if
+ the latter was the one originally raised. *)
diff --git a/clib/bigint.ml b/clib/bigint.ml
new file mode 100644
index 00000000..9e7b44ee
--- /dev/null
+++ b/clib/bigint.ml
@@ -0,0 +1,526 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(***************************************************)
+(* Basic operations on (unbounded) integer numbers *)
+(***************************************************)
+
+(* An integer is canonically represented as an array of k-digits blocs,
+ i.e. in base 10^k.
+
+ 0 is represented by the empty array and -1 by the singleton [|-1|].
+ The first bloc is in the range ]0;base[ for positive numbers.
+ The first bloc is in the range [-base;-1[ for numbers < -1.
+ All other blocs are numbers in the range [0;base[.
+
+ Negative numbers are represented using 2's complementation :
+ one unit is "borrowed" from the top block for complementing
+ the other blocs. For instance, with 4-digits blocs,
+ [|-5;6789|] denotes -43211
+ since -5.10^4+6789=-((4.10^4)+(10000-6789)) = -43211
+
+ The base is a power of 10 in order to facilitate the parsing and printing
+ of numbers in digital notation.
+
+ All functions, to the exception of to_string and of_string should work
+ with an arbitrary base, even if not a power of 10.
+
+ In practice, we set k=4 on 32-bits machines, so that no overflow in ocaml
+ machine words (i.e. the interval [-2^30;2^30-1]) occur when multiplying two
+ numbers less than (10^k). On 64-bits machines, k=9.
+*)
+
+(* The main parameters *)
+
+let size =
+ let rec log10 n = if n < 10 then 0 else 1 + log10 (n / 10) in
+ (log10 max_int) / 2
+
+let format_size =
+ (* How to parametrize a printf format *)
+ if Int.equal size 4 then Printf.sprintf "%04d"
+ else if Int.equal size 9 then Printf.sprintf "%09d"
+ else fun n ->
+ let rec aux j l n =
+ if Int.equal j size then l else aux (j+1) (string_of_int (n mod 10) :: l) (n/10)
+ in String.concat "" (aux 0 [] n)
+
+(* The base is 10^size *)
+let base =
+ let rec exp10 = function 0 -> 1 | n -> 10 * exp10 (n-1) in exp10 size
+
+(******************************************************************)
+(* First, we represent all numbers by int arrays.
+ Later, we will optimize the particular case of small integers *)
+(******************************************************************)
+
+module ArrayInt = struct
+
+(* Basic numbers *)
+let zero = [||]
+
+let is_zero = function
+| [||] -> true
+| _ -> false
+
+(* An array is canonical when
+ - it is empty
+ - it is [|-1|]
+ - its first bloc is in [-base;-1[U]0;base[
+ and the other blocs are in [0;base[. *)
+(*
+let canonical n =
+ let ok x = (0 <= x && x < base) in
+ let rec ok_tail k = (Int.equal k 0) || (ok n.(k) && ok_tail (k-1)) in
+ let ok_init x = (-base <= x && x < base && not (Int.equal x (-1)) && not (Int.equal x 0))
+ in
+ (is_zero n) || (match n with [|-1|] -> true | _ -> false) ||
+ (ok_init n.(0) && ok_tail (Array.length n - 1))
+*)
+
+(* [normalize_pos] : removing initial blocks of 0 *)
+
+let normalize_pos n =
+ let k = ref 0 in
+ while !k < Array.length n && Int.equal n.(!k) 0 do incr k done;
+ Array.sub n !k (Array.length n - !k)
+
+(* [normalize_neg] : avoid (-1) as first bloc.
+ input: an array with -1 as first bloc and other blocs in [0;base[
+ output: a canonical array *)
+
+let normalize_neg n =
+ let k = ref 1 in
+ while !k < Array.length n && Int.equal n.(!k) (base - 1) do incr k done;
+ let n' = Array.sub n !k (Array.length n - !k) in
+ if Int.equal (Array.length n') 0 then [|-1|] else (n'.(0) <- n'.(0) - base; n')
+
+(* [normalize] : avoid 0 and (-1) as first bloc.
+ input: an array with first bloc in [-base;base[ and others in [0;base[
+ output: a canonical array *)
+
+let normalize n =
+ if Int.equal (Array.length n) 0 then n
+ else if Int.equal n.(0) (-1) then normalize_neg n
+ else if Int.equal n.(0) 0 then normalize_pos n
+ else n
+
+(* Opposite (expects and returns canonical arrays) *)
+
+let neg m =
+ if is_zero m then zero else
+ let n = Array.copy m in
+ let i = ref (Array.length m - 1) in
+ while !i > 0 && Int.equal n.(!i) 0 do decr i done;
+ if Int.equal !i 0 then begin
+ n.(0) <- - n.(0);
+ (* n.(0) cannot be 0 since m is canonical *)
+ if Int.equal n.(0) (-1) then normalize_neg n
+ else if Int.equal n.(0) base then (n.(0) <- 0; Array.append [| 1 |] n)
+ else n
+ end else begin
+ (* here n.(!i) <> 0, hence 0 < base - n.(!i) < base for n canonical *)
+ n.(!i) <- base - n.(!i); decr i;
+ while !i > 0 do n.(!i) <- base - 1 - n.(!i); decr i done;
+ (* since -base <= n.(0) <= base-1, hence -base <= -n.(0)-1 <= base-1 *)
+ n.(0) <- - n.(0) - 1;
+ (* since m is canonical, m.(0)<>0 hence n.(0)<>-1,
+ and m=-1 is already handled above, so here m.(0)<>-1 hence n.(0)<>0 *)
+ n
+ end
+
+let push_carry r j =
+ let j = ref j in
+ while !j > 0 && r.(!j) < 0 do
+ r.(!j) <- r.(!j) + base; decr j; r.(!j) <- r.(!j) - 1
+ done;
+ while !j > 0 && r.(!j) >= base do
+ r.(!j) <- r.(!j) - base; decr j; r.(!j) <- r.(!j) + 1
+ done;
+ (* here r.(0) could be in [-2*base;2*base-1] *)
+ if r.(0) >= base then (r.(0) <- r.(0) - base; Array.append [| 1 |] r)
+ else if r.(0) < -base then (r.(0) <- r.(0) + 2*base; Array.append [| -2 |] r)
+ else normalize r (* in case r.(0) is 0 or -1 *)
+
+let add_to r a j =
+ if is_zero a then r else begin
+ for i = Array.length r - 1 downto j+1 do
+ r.(i) <- r.(i) + a.(i-j);
+ if r.(i) >= base then (r.(i) <- r.(i) - base; r.(i-1) <- r.(i-1) + 1)
+ done;
+ r.(j) <- r.(j) + a.(0);
+ push_carry r j
+ end
+
+let add n m =
+ let d = Array.length n - Array.length m in
+ if d > 0 then add_to (Array.copy n) m d else add_to (Array.copy m) n (-d)
+
+let sub_to r a j =
+ if is_zero a then r else begin
+ for i = Array.length r - 1 downto j+1 do
+ r.(i) <- r.(i) - a.(i-j);
+ if r.(i) < 0 then (r.(i) <- r.(i) + base; r.(i-1) <- r.(i-1) - 1)
+ done;
+ r.(j) <- r.(j) - a.(0);
+ push_carry r j
+ end
+
+let sub n m =
+ let d = Array.length n - Array.length m in
+ if d >= 0 then sub_to (Array.copy n) m d
+ else let r = neg m in add_to r n (Array.length r - Array.length n)
+
+let mult m n =
+ if is_zero m || is_zero n then zero else
+ let l = Array.length m + Array.length n in
+ let r = Array.make l 0 in
+ for i = Array.length m - 1 downto 0 do
+ for j = Array.length n - 1 downto 0 do
+ let p = m.(i) * n.(j) + r.(i+j+1) in
+ let (q,s) =
+ if p < 0
+ then (p + 1) / base - 1, (p + 1) mod base + base - 1
+ else p / base, p mod base in
+ r.(i+j+1) <- s;
+ if not (Int.equal q 0) then r.(i+j) <- r.(i+j) + q;
+ done
+ done;
+ normalize r
+
+(* Comparisons *)
+
+let is_strictly_neg n = not (is_zero n) && n.(0) < 0
+let is_strictly_pos n = not (is_zero n) && n.(0) > 0
+let is_neg_or_zero n = is_zero n || n.(0) < 0
+let is_pos_or_zero n = is_zero n || n.(0) > 0
+
+(* Is m without its i first blocs less then n without its j first blocs ?
+ Invariant : |m|-i = |n|-j *)
+
+let rec less_than_same_size m n i j =
+ i < Array.length m &&
+ (m.(i) < n.(j) || (Int.equal m.(i) n.(j) && less_than_same_size m n (i+1) (j+1)))
+
+let less_than m n =
+ if is_strictly_neg m then
+ is_pos_or_zero n || Array.length m > Array.length n
+ || (Int.equal (Array.length m) (Array.length n) && less_than_same_size m n 0 0)
+ else
+ is_strictly_pos n && (Array.length m < Array.length n ||
+ (Int.equal (Array.length m) (Array.length n) && less_than_same_size m n 0 0))
+
+(* For this equality test it is critical that n and m are canonical *)
+
+let rec array_eq len v1 v2 i =
+ if Int.equal len i then true
+ else
+ Int.equal v1.(i) v2.(i) && array_eq len v1 v2 (succ i)
+
+let equal m n =
+ let lenm = Array.length m in
+ let lenn = Array.length n in
+ (Int.equal lenm lenn) && (array_eq lenm m n 0)
+
+(* Is m without its k top blocs less than n ? *)
+
+let less_than_shift_pos k m n =
+ (Array.length m - k < Array.length n)
+ || (Int.equal (Array.length m - k) (Array.length n) && less_than_same_size m n k 0)
+
+let rec can_divide k m d i =
+ (Int.equal i (Array.length d)) ||
+ (m.(k+i) > d.(i)) ||
+ (Int.equal m.(k+i) d.(i) && can_divide k m d (i+1))
+
+(* For two big nums m and d and a small number q,
+ computes m - d * q * base^(|m|-|d|-k) in-place (in m).
+ Both m d and q are positive. *)
+
+let sub_mult m d q k =
+ if not (Int.equal q 0) then
+ for i = Array.length d - 1 downto 0 do
+ let v = d.(i) * q in
+ m.(k+i) <- m.(k+i) - v mod base;
+ if m.(k+i) < 0 then (m.(k+i) <- m.(k+i) + base; m.(k+i-1) <- m.(k+i-1) -1);
+ if v >= base then begin
+ m.(k+i-1) <- m.(k+i-1) - v / base;
+ let j = ref (i-1) in
+ while m.(k + !j) < 0 do (* result is positive, hence !j remains >= 0 *)
+ m.(k + !j) <- m.(k + !j) + base; decr j; m.(k + !j) <- m.(k + !j) -1
+ done
+ end
+ done
+
+(** Euclid division m/d = (q,r), with m = q*d+r and |r|<|q|.
+ This is the "Trunc" variant (a.k.a "Truncated-Toward-Zero"),
+ as with ocaml's / (but not as ocaml's Big_int.quomod_big_int).
+ We have sign r = sign m *)
+
+let euclid m d =
+ let isnegm, m =
+ if is_strictly_neg m then (-1),neg m else 1,Array.copy m in
+ let isnegd, d = if is_strictly_neg d then (-1),neg d else 1,d in
+ if is_zero d then raise Division_by_zero;
+ let q,r =
+ if less_than m d then (zero,m) else
+ let ql = Array.length m - Array.length d in
+ let q = Array.make (ql+1) 0 in
+ let i = ref 0 in
+ while not (less_than_shift_pos !i m d) do
+ if Int.equal m.(!i) 0 then incr i else
+ if can_divide !i m d 0 then begin
+ let v =
+ if Array.length d > 1 && not (Int.equal d.(0) m.(!i)) then
+ (m.(!i) * base + m.(!i+1)) / (d.(0) * base + d.(1) + 1)
+ else
+ m.(!i) / d.(0) in
+ q.(!i) <- q.(!i) + v;
+ sub_mult m d v !i
+ end else begin
+ let v = (m.(!i) * base + m.(!i+1)) / (d.(0) + 1) in
+ q.(!i) <- q.(!i) + v / base;
+ sub_mult m d (v / base) !i;
+ q.(!i+1) <- q.(!i+1) + v mod base;
+ if q.(!i+1) >= base then
+ (q.(!i+1) <- q.(!i+1)-base; q.(!i) <- q.(!i)+1);
+ sub_mult m d (v mod base) (!i+1)
+ end
+ done;
+ (normalize q, normalize m) in
+ (if Int.equal (isnegd * isnegm) (-1) then neg q else q),
+ (if Int.equal isnegm (-1) then neg r else r)
+
+(* Parsing/printing ordinary 10-based numbers *)
+
+let of_string s =
+ let len = String.length s in
+ let isneg = len > 1 && s.[0] == '-' in
+ let d = ref (if isneg then 1 else 0) in
+ while !d < len && s.[!d] == '0' do incr d done;
+ if Int.equal !d len then zero else
+ let r = (len - !d) mod size in
+ let h = String.sub s (!d) r in
+ let e = match h with "" -> 0 | _ -> 1 in
+ let l = (len - !d) / size in
+ let a = Array.make (l + e) 0 in
+ if Int.equal e 1 then a.(0) <- int_of_string h;
+ for i = 1 to l do
+ a.(i+e-1) <- int_of_string (String.sub s ((i-1)*size + !d + r) size)
+ done;
+ if isneg then neg a else a
+
+let to_string_pos sgn n =
+ if Int.equal (Array.length n) 0 then "0" else
+ sgn ^
+ String.concat ""
+ (string_of_int n.(0) :: List.map format_size (List.tl (Array.to_list n)))
+
+let to_string n =
+ if is_strictly_neg n then to_string_pos "-" (neg n)
+ else to_string_pos "" n
+
+end
+
+(******************************************************************)
+(* Optimized operations on (unbounded) integer numbers *)
+(* integers smaller than base are represented as machine integers *)
+(******************************************************************)
+
+open ArrayInt
+
+type bigint = Obj.t
+
+(* Since base is the largest power of 10 such that base*base <= max_int,
+ we have max_int < 100*base*base : any int can be represented
+ by at most three blocs *)
+
+let small n = (-base <= n) && (n < base)
+
+let mkarray n =
+ (* n isn't small, this case is handled separately below *)
+ let lo = n mod base
+ and hi = n / base in
+ let t = if small hi then [|hi;lo|] else [|hi/base;hi mod base;lo|]
+ in
+ for i = Array.length t -1 downto 1 do
+ if t.(i) < 0 then (t.(i) <- t.(i) + base; t.(i-1) <- t.(i-1) -1)
+ done;
+ t
+
+let ints_of_int n =
+ if Int.equal n 0 then [| |]
+ else if small n then [| n |]
+ else mkarray n
+
+let of_int n =
+ if small n then Obj.repr n else Obj.repr (mkarray n)
+
+let of_ints n =
+ let n = normalize n in (* TODO: using normalize here seems redundant now *)
+ if is_zero n then Obj.repr 0 else
+ if Int.equal (Array.length n) 1 then Obj.repr n.(0) else
+ Obj.repr n
+
+let coerce_to_int = (Obj.magic : Obj.t -> int)
+let coerce_to_ints = (Obj.magic : Obj.t -> int array)
+
+let to_ints n =
+ if Obj.is_int n then ints_of_int (coerce_to_int n)
+ else coerce_to_ints n
+
+let int_of_ints =
+ let maxi = mkarray max_int and mini = mkarray min_int in
+ fun t ->
+ let l = Array.length t in
+ if (l > 3) || (Int.equal l 3 && (less_than maxi t || less_than t mini))
+ then failwith "Bigint.to_int: too large";
+ let sum = ref 0 in
+ let pow = ref 1 in
+ for i = l-1 downto 0 do
+ sum := !sum + t.(i) * !pow;
+ pow := !pow*base;
+ done;
+ !sum
+
+let to_int n =
+ if Obj.is_int n then coerce_to_int n
+ else int_of_ints (coerce_to_ints n)
+
+let app_pair f (m, n) =
+ (f m, f n)
+
+let add m n =
+ if Obj.is_int m && Obj.is_int n
+ then of_int (coerce_to_int m + coerce_to_int n)
+ else of_ints (add (to_ints m) (to_ints n))
+
+let sub m n =
+ if Obj.is_int m && Obj.is_int n
+ then of_int (coerce_to_int m - coerce_to_int n)
+ else of_ints (sub (to_ints m) (to_ints n))
+
+let mult m n =
+ if Obj.is_int m && Obj.is_int n
+ then of_int (coerce_to_int m * coerce_to_int n)
+ else of_ints (mult (to_ints m) (to_ints n))
+
+let euclid m n =
+ if Obj.is_int m && Obj.is_int n
+ then app_pair of_int
+ (coerce_to_int m / coerce_to_int n, coerce_to_int m mod coerce_to_int n)
+ else app_pair of_ints (euclid (to_ints m) (to_ints n))
+
+let less_than m n =
+ if Obj.is_int m && Obj.is_int n
+ then coerce_to_int m < coerce_to_int n
+ else less_than (to_ints m) (to_ints n)
+
+let neg n =
+ if Obj.is_int n then of_int (- (coerce_to_int n))
+ else of_ints (neg (to_ints n))
+
+let of_string m = of_ints (of_string m)
+let to_string m = to_string (to_ints m)
+
+let zero = of_int 0
+let one = of_int 1
+let two = of_int 2
+let sub_1 n = sub n one
+let add_1 n = add n one
+let mult_2 n = add n n
+
+let div2_with_rest n =
+ let (q,b) = euclid n two in
+ (q, b == one)
+
+let is_strictly_neg n = is_strictly_neg (to_ints n)
+let is_strictly_pos n = is_strictly_pos (to_ints n)
+let is_neg_or_zero n = is_neg_or_zero (to_ints n)
+let is_pos_or_zero n = is_pos_or_zero (to_ints n)
+
+let equal m n =
+ if Obj.is_block m && Obj.is_block n then
+ ArrayInt.equal (Obj.obj m) (Obj.obj n)
+ else m == n
+
+(* spiwack: computes n^m *)
+(* The basic idea of the algorithm is that n^(2m) = (n^2)^m *)
+(* In practice the algorithm performs :
+ k*n^0 = k
+ k*n^(2m) = k*(n*n)^m
+ k*n^(2m+1) = (n*k)*(n*n)^m *)
+let pow =
+ let rec pow_aux odd_rest n m = (* odd_rest is the k from above *)
+ if m<=0 then
+ odd_rest
+ else
+ let quo = m lsr 1 (* i.e. m/2 *)
+ and odd = not (Int.equal (m land 1) 0) in
+ pow_aux
+ (if odd then mult n odd_rest else odd_rest)
+ (mult n n)
+ quo
+ in
+ pow_aux one
+
+(** Testing suite w.r.t. OCaml's Big_int *)
+
+(*
+module B = struct
+ open Big_int
+ let zero = zero_big_int
+ let to_string = string_of_big_int
+ let of_string = big_int_of_string
+ let add = add_big_int
+ let opp = minus_big_int
+ let sub = sub_big_int
+ let mul = mult_big_int
+ let abs = abs_big_int
+ let sign = sign_big_int
+ let euclid n m =
+ let n' = abs n and m' = abs m in
+ let q',r' = quomod_big_int n' m' in
+ (if sign (mul n m) < 0 && sign q' <> 0 then opp q' else q'),
+ (if sign n < 0 then opp r' else r')
+end
+
+let check () =
+ let roots = [ 1; 100; base; 100*base; base*base ] in
+ let rands = [ 1234; 5678; 12345678; 987654321 ] in
+ let nums = (List.flatten (List.map (fun x -> [x-1;x;x+1]) roots)) @ rands in
+ let numbers =
+ List.map string_of_int nums @
+ List.map (fun n -> string_of_int (-n)) nums
+ in
+ let i = ref 0 in
+ let compare op x y n n' =
+ incr i;
+ let s = Printf.sprintf "%30s" (to_string n) in
+ let s' = Printf.sprintf "%30s" (B.to_string n') in
+ if s <> s' then Printf.printf "%s%s%s: %s <> %s\n" x op y s s' in
+ let test x y =
+ let n = of_string x and m = of_string y in
+ let n' = B.of_string x and m' = B.of_string y in
+ let a = add n m and a' = B.add n' m' in
+ let s = sub n m and s' = B.sub n' m' in
+ let p = mult n m and p' = B.mul n' m' in
+ let q,r = try euclid n m with Division_by_zero -> zero,zero
+ and q',r' = try B.euclid n' m' with Division_by_zero -> B.zero, B.zero
+ in
+ compare "+" x y a a';
+ compare "-" x y s s';
+ compare "*" x y p p';
+ compare "/" x y q q';
+ compare "%" x y r r'
+ in
+ List.iter (fun a -> List.iter (test a) numbers) numbers;
+ Printf.printf "%i tests done\n" !i
+*)
diff --git a/clib/bigint.mli b/clib/bigint.mli
new file mode 100644
index 00000000..ac66b41f
--- /dev/null
+++ b/clib/bigint.mli
@@ -0,0 +1,52 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Arbitrary large integer numbers *)
+
+type bigint
+
+val of_string : string -> bigint
+(** May raise a Failure just as [int_of_string] on non-numerical strings *)
+
+val to_string : bigint -> string
+
+val of_int : int -> bigint
+val to_int : bigint -> int (** May raise a Failure on oversized numbers *)
+
+val zero : bigint
+val one : bigint
+val two : bigint
+
+val div2_with_rest : bigint -> bigint * bool (** true=odd; false=even *)
+val add_1 : bigint -> bigint
+val sub_1 : bigint -> bigint
+val mult_2 : bigint -> bigint
+
+val add : bigint -> bigint -> bigint
+val sub : bigint -> bigint -> bigint
+val mult : bigint -> bigint -> bigint
+
+(** Euclid division m/d = (q,r), with m = q*d+r and |r|<|q|.
+ This is the "Trunc" variant (a.k.a "Truncated-Toward-Zero"),
+ as with ocaml's / (but not as ocaml's Big_int.quomod_big_int).
+ We have sign r = sign m *)
+
+val euclid : bigint -> bigint -> bigint * bigint
+
+val less_than : bigint -> bigint -> bool
+val equal : bigint -> bigint -> bool
+
+val is_strictly_pos : bigint -> bool
+val is_strictly_neg : bigint -> bool
+val is_pos_or_zero : bigint -> bool
+val is_neg_or_zero : bigint -> bool
+val neg : bigint -> bigint
+
+val pow : bigint -> int -> bigint
diff --git a/clib/cArray.ml b/clib/cArray.ml
new file mode 100644
index 00000000..e2b1a7be
--- /dev/null
+++ b/clib/cArray.ml
@@ -0,0 +1,550 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type S = module type of Array
+
+module type ExtS =
+sig
+ include S
+ val compare : ('a -> 'a -> int) -> 'a array -> 'a array -> int
+ val equal : ('a -> 'a -> bool) -> 'a array -> 'a array -> bool
+ val equal_norefl : ('a -> 'a -> bool) -> 'a array -> 'a array -> bool
+ val is_empty : 'a array -> bool
+ val exists : ('a -> bool) -> 'a array -> bool
+ val exists2 : ('a -> 'b -> bool) -> 'a array -> 'b array -> bool
+ val for_all : ('a -> bool) -> 'a array -> bool
+ val for_all2 : ('a -> 'b -> bool) -> 'a array -> 'b array -> bool
+ val for_all3 : ('a -> 'b -> 'c -> bool) ->
+ 'a array -> 'b array -> 'c array -> bool
+ val for_all4 : ('a -> 'b -> 'c -> 'd -> bool) ->
+ 'a array -> 'b array -> 'c array -> 'd array -> bool
+ val for_all_i : (int -> 'a -> bool) -> int -> 'a array -> bool
+ val findi : (int -> 'a -> bool) -> 'a array -> int option
+ val hd : 'a array -> 'a
+ val tl : 'a array -> 'a array
+ val last : 'a array -> 'a
+ val cons : 'a -> 'a array -> 'a array
+ val rev : 'a array -> unit
+ val fold_right_i :
+ (int -> 'b -> 'a -> 'a) -> 'b array -> 'a -> 'a
+ val fold_left_i : (int -> 'a -> 'b -> 'a) -> 'a -> 'b array -> 'a
+ val fold_right2 :
+ ('a -> 'b -> 'c -> 'c) -> 'a array -> 'b array -> 'c -> 'c
+ val fold_left2 :
+ ('a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
+ val fold_left3 :
+ ('a -> 'b -> 'c -> 'd -> 'a) -> 'a -> 'b array -> 'c array -> 'd array -> 'a
+ val fold_left2_i :
+ (int -> 'a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
+ val fold_left_from : int -> ('a -> 'b -> 'a) -> 'a -> 'b array -> 'a
+ val map_to_list : ('a -> 'b) -> 'a array -> 'b list
+ val map_of_list : ('a -> 'b) -> 'a list -> 'b array
+ val chop : int -> 'a array -> 'a array * 'a array
+ val smartmap : ('a -> 'a) -> 'a array -> 'a array
+ val smartfoldmap : ('r -> 'a -> 'r * 'a) -> 'r -> 'a array -> 'r * 'a array
+ val map2 : ('a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array
+ val map2_i : (int -> 'a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array
+ val map3 :
+ ('a -> 'b -> 'c -> 'd) -> 'a array -> 'b array -> 'c array -> 'd array
+ val map_left : ('a -> 'b) -> 'a array -> 'b array
+ val iter2 : ('a -> 'b -> unit) -> 'a array -> 'b array -> unit
+ val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b array -> 'a * 'c array
+ val fold_right_map : ('a -> 'c -> 'b * 'c) -> 'a array -> 'c -> 'b array * 'c
+ val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b array -> 'c array -> 'a * 'd array
+ val fold_right2_map : ('a -> 'b -> 'c -> 'd * 'c) -> 'a array -> 'b array -> 'c -> 'd array * 'c
+ val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b array -> 'a * 'c array
+ [@@ocaml.deprecated "Same as [fold_left_map]"]
+ val fold_map' : ('a -> 'c -> 'b * 'c) -> 'a array -> 'c -> 'b array * 'c
+ [@@ocaml.deprecated "Same as [fold_right_map]"]
+ val fold_map2' :
+ ('a -> 'b -> 'c -> 'd * 'c) -> 'a array -> 'b array -> 'c -> 'd array * 'c
+ [@@ocaml.deprecated "Same as [fold_right2_map]"]
+ val distinct : 'a array -> bool
+ val rev_of_list : 'a list -> 'a array
+ val rev_to_list : 'a array -> 'a list
+ val filter_with : bool list -> 'a array -> 'a array
+end
+
+include Array
+
+let uget = Array.unsafe_get
+
+(* Arrays *)
+
+let compare cmp v1 v2 =
+ if v1 == v2 then 0
+ else
+ let len = Array.length v1 in
+ let c = Int.compare len (Array.length v2) in
+ if c <> 0 then c else
+ let rec loop i =
+ if i < 0 then 0
+ else
+ let x = uget v1 i in
+ let y = uget v2 i in
+ let c = cmp x y in
+ if c <> 0 then c
+ else loop (i - 1)
+ in
+ loop (len - 1)
+
+let equal_norefl cmp t1 t2 =
+ let len = Array.length t1 in
+ if not (Int.equal len (Array.length t2)) then false
+ else
+ let rec aux i =
+ if i < 0 then true
+ else
+ let x = uget t1 i in
+ let y = uget t2 i in
+ cmp x y && aux (pred i)
+ in
+ aux (len - 1)
+
+let equal cmp t1 t2 =
+ if t1 == t2 then true else equal_norefl cmp t1 t2
+
+
+let is_empty array = Int.equal (Array.length array) 0
+
+let exists f v =
+ let rec exrec = function
+ | -1 -> false
+ | n -> f (uget v n) || (exrec (n-1))
+ in
+ exrec ((Array.length v)-1)
+
+let exists2 f v1 v2 =
+ let rec exrec = function
+ | -1 -> false
+ | n -> f (uget v1 n) (uget v2 n) || (exrec (n-1))
+ in
+ let lv1 = Array.length v1 in
+ lv1 = Array.length v2 && exrec (lv1-1)
+
+let for_all f v =
+ let rec allrec = function
+ | -1 -> true
+ | n ->
+ let ans = f (uget v n) in
+ ans && (allrec (n-1))
+ in
+ allrec ((Array.length v)-1)
+
+let for_all2 f v1 v2 =
+ let rec allrec = function
+ | -1 -> true
+ | n ->
+ let ans = f (uget v1 n) (uget v2 n) in
+ ans && (allrec (n-1))
+ in
+ let lv1 = Array.length v1 in
+ lv1 = Array.length v2 && allrec (pred lv1)
+
+let for_all3 f v1 v2 v3 =
+ let rec allrec = function
+ | -1 -> true
+ | n ->
+ let ans = f (uget v1 n)
+ (uget v2 n) (uget v3 n)
+ in
+ ans && (allrec (n-1))
+ in
+ let lv1 = Array.length v1 in
+ lv1 = Array.length v2 && lv1 = Array.length v3 && allrec (pred lv1)
+
+let for_all4 f v1 v2 v3 v4 =
+ let rec allrec = function
+ | -1 -> true
+ | n ->
+ let ans = f (uget v1 n)
+ (uget v2 n) (uget v3 n) (uget v4 n)
+ in
+ ans && (allrec (n-1))
+ in
+ let lv1 = Array.length v1 in
+ lv1 = Array.length v2 &&
+ lv1 = Array.length v3 &&
+ lv1 = Array.length v4 &&
+ allrec (pred lv1)
+
+let for_all_i f i v =
+ let len = Array.length v in
+ let rec allrec i n =
+ n = len || f i (uget v n) && allrec (i+1) (n+1) in
+ allrec i 0
+
+exception Found of int
+
+let findi (pred: int -> 'a -> bool) (arr: 'a array) : int option =
+ try
+ for i=0 to Array.length arr - 1 do
+ if pred i (uget arr i) then raise (Found i) done;
+ None
+ with Found i -> Some i
+
+let hd v =
+ match Array.length v with
+ | 0 -> failwith "Array.hd"
+ | _ -> uget v 0
+
+let tl v =
+ match Array.length v with
+ | 0 -> failwith "Array.tl"
+ | n -> Array.sub v 1 (pred n)
+
+let last v =
+ match Array.length v with
+ | 0 -> failwith "Array.last"
+ | n -> uget v (pred n)
+
+let cons e v =
+ let len = Array.length v in
+ let ans = Array.make (Array.length v + 1) e in
+ let () = Array.blit v 0 ans 1 len in
+ ans
+
+let rev t =
+ let n=Array.length t in
+ if n <=0 then ()
+ else
+ for i = 0 to pred (n/2) do
+ let tmp = uget t ((pred n)-i) in
+ Array.unsafe_set t ((pred n)-i) (uget t i);
+ Array.unsafe_set t i tmp
+ done
+
+let fold_right_i f v a =
+ let rec fold a n =
+ if n=0 then a
+ else
+ let k = n-1 in
+ fold (f k (uget v k) a) k in
+ fold a (Array.length v)
+
+let fold_left_i f v a =
+ let n = Array.length a in
+ let rec fold i v = if i = n then v else fold (succ i) (f i v (uget a i)) in
+ fold 0 v
+
+let fold_right2 f v1 v2 a =
+ let lv1 = Array.length v1 in
+ let rec fold a n =
+ if n=0 then a
+ else
+ let k = n-1 in
+ fold (f (uget v1 k) (uget v2 k) a) k in
+ if Array.length v2 <> lv1 then invalid_arg "Array.fold_right2";
+ fold a lv1
+
+let fold_left2 f a v1 v2 =
+ let lv1 = Array.length v1 in
+ let rec fold a n =
+ if n >= lv1 then a else fold (f a (uget v1 n) (uget v2 n)) (succ n)
+ in
+ if Array.length v2 <> lv1 then invalid_arg "Array.fold_left2";
+ fold a 0
+
+let fold_left2_i f a v1 v2 =
+ let lv1 = Array.length v1 in
+ let rec fold a n =
+ if n >= lv1 then a else fold (f n a (uget v1 n) (uget v2 n)) (succ n)
+ in
+ if Array.length v2 <> lv1 then invalid_arg "Array.fold_left2";
+ fold a 0
+
+let fold_left3 f a v1 v2 v3 =
+ let lv1 = Array.length v1 in
+ let rec fold a n =
+ if n >= lv1 then a
+ else fold (f a (uget v1 n) (uget v2 n) (uget v3 n)) (succ n)
+ in
+ if Array.length v2 <> lv1 || Array.length v3 <> lv1 then
+ invalid_arg "Array.fold_left2";
+ fold a 0
+
+let fold_left_from n f a v =
+ let len = Array.length v in
+ let () = if n < 0 then invalid_arg "Array.fold_left_from" in
+ let rec fold a n =
+ if n >= len then a else fold (f a (uget v n)) (succ n)
+ in
+ fold a n
+
+let rev_of_list = function
+| [] -> [| |]
+| x :: l ->
+ let len = List.length l in
+ let ans = Array.make (succ len) x in
+ let rec set i = function
+ | [] -> ()
+ | x :: l ->
+ Array.unsafe_set ans i x;
+ set (pred i) l
+ in
+ let () = set (len - 1) l in
+ ans
+
+let map_to_list = CList.map_of_array
+
+let map_of_list f l =
+ let len = List.length l in
+ let rec fill i v = function
+ | [] -> ()
+ | x :: l ->
+ Array.unsafe_set v i (f x);
+ fill (succ i) v l
+ in
+ match l with
+ | [] -> [||]
+ | x :: l ->
+ let ans = Array.make len (f x) in
+ let () = fill 1 ans l in
+ ans
+
+let chop n v =
+ let vlen = Array.length v in
+ if n > vlen then failwith "Array.chop";
+ (Array.sub v 0 n, Array.sub v n (vlen-n))
+
+(* If none of the elements is changed by f we return ar itself.
+ The while loop looks for the first such an element.
+ If found, we break here and the new array is produced,
+ but f is not re-applied to elements that are already checked *)
+let smartmap f (ar : 'a array) =
+ let len = Array.length ar in
+ let i = ref 0 in
+ let break = ref true in
+ let temp = ref None in
+ while !break && (!i < len) do
+ let v = Array.unsafe_get ar !i in
+ let v' = f v in
+ if v == v' then incr i
+ else begin
+ break := false;
+ temp := Some v';
+ end
+ done;
+ if !i < len then begin
+ (** The array is not the same as the original one *)
+ let ans : 'a array = Array.copy ar in
+ let v = match !temp with None -> assert false | Some x -> x in
+ Array.unsafe_set ans !i v;
+ incr i;
+ while !i < len do
+ let v = Array.unsafe_get ans !i in
+ let v' = f v in
+ if v != v' then Array.unsafe_set ans !i v';
+ incr i
+ done;
+ ans
+ end else ar
+
+(** Same as [smartmap] but threads a state meanwhile *)
+let smartfoldmap f accu (ar : 'a array) =
+ let len = Array.length ar in
+ let i = ref 0 in
+ let break = ref true in
+ let r = ref accu in
+ (** This variable is never accessed unset *)
+ let temp = ref None in
+ while !break && (!i < len) do
+ let v = Array.unsafe_get ar !i in
+ let (accu, v') = f !r v in
+ r := accu;
+ if v == v' then incr i
+ else begin
+ break := false;
+ temp := Some v';
+ end
+ done;
+ if !i < len then begin
+ let ans : 'a array = Array.copy ar in
+ let v = match !temp with None -> assert false | Some x -> x in
+ Array.unsafe_set ans !i v;
+ incr i;
+ while !i < len do
+ let v = Array.unsafe_get ar !i in
+ let (accu, v') = f !r v in
+ r := accu;
+ if v != v' then Array.unsafe_set ans !i v';
+ incr i
+ done;
+ !r, ans
+ end else !r, ar
+
+let map2 f v1 v2 =
+ let len1 = Array.length v1 in
+ let len2 = Array.length v2 in
+ let () = if not (Int.equal len1 len2) then invalid_arg "Array.map2" in
+ if Int.equal len1 0 then
+ [| |]
+ else begin
+ let res = Array.make len1 (f (uget v1 0) (uget v2 0)) in
+ for i = 1 to pred len1 do
+ Array.unsafe_set res i (f (uget v1 i) (uget v2 i))
+ done;
+ res
+ end
+
+let map2_i f v1 v2 =
+ let len1 = Array.length v1 in
+ let len2 = Array.length v2 in
+ let () = if not (Int.equal len1 len2) then invalid_arg "Array.map2" in
+ if Int.equal len1 0 then
+ [| |]
+ else begin
+ let res = Array.make len1 (f 0 (uget v1 0) (uget v2 0)) in
+ for i = 1 to pred len1 do
+ Array.unsafe_set res i (f i (uget v1 i) (uget v2 i))
+ done;
+ res
+ end
+
+let map3 f v1 v2 v3 =
+ let len1 = Array.length v1 in
+ let () =
+ if len1 <> Array.length v2 || len1 <> Array.length v3
+ then invalid_arg "Array.map3"
+ in
+ if Int.equal len1 0 then
+ [| |]
+ else begin
+ let res = Array.make len1 (f (uget v1 0) (uget v2 0) (uget v3 0)) in
+ for i = 1 to pred len1 do
+ Array.unsafe_set res i (f (uget v1 i) (uget v2 i) (uget v3 i))
+ done;
+ res
+ end
+
+let map_left f a = (* Ocaml does not guarantee Array.map is LR *)
+ let l = Array.length a in (* (even if so), then we rewrite it *)
+ if Int.equal l 0 then [||] else begin
+ let r = Array.make l (f (uget a 0)) in
+ for i = 1 to l - 1 do
+ Array.unsafe_set r i (f (uget a i))
+ done;
+ r
+ end
+
+let iter2 f v1 v2 =
+ let len1 = Array.length v1 in
+ let len2 = Array.length v2 in
+ let () = if not (Int.equal len2 len1) then invalid_arg "Array.iter2" in
+ for i = 0 to len1 - 1 do f (uget v1 i) (uget v2 i) done
+
+let pure_functional = false
+
+let fold_right_map f v e =
+if pure_functional then
+ let (l,e) =
+ Array.fold_right
+ (fun x (l,e) -> let (y,e) = f x e in (y::l,e))
+ v ([],e) in
+ (Array.of_list l,e)
+else
+ let e' = ref e in
+ let v' = Array.map (fun x -> let (y,e) = f x !e' in e' := e; y) v in
+ (v',!e')
+
+let fold_map' = fold_right_map
+
+let fold_left_map f e v =
+ let e' = ref e in
+ let v' = Array.map (fun x -> let (e,y) = f !e' x in e' := e; y) v in
+ (!e',v')
+
+let fold_map = fold_left_map
+
+let fold_right2_map f v1 v2 e =
+ let e' = ref e in
+ let v' =
+ map2 (fun x1 x2 -> let (y,e) = f x1 x2 !e' in e' := e; y) v1 v2
+ in
+ (v',!e')
+
+let fold_map2' = fold_right2_map
+
+let fold_left2_map f e v1 v2 =
+ let e' = ref e in
+ let v' = map2 (fun x1 x2 -> let (e,y) = f !e' x1 x2 in e' := e; y) v1 v2 in
+ (!e',v')
+
+let distinct v =
+ let visited = Hashtbl.create 23 in
+ try
+ Array.iter
+ (fun x ->
+ if Hashtbl.mem visited x then raise Exit
+ else Hashtbl.add visited x x)
+ v;
+ true
+ with Exit -> false
+
+let rev_to_list a =
+ let rec tolist i res =
+ if i >= Array.length a then res else tolist (i+1) (uget a i :: res) in
+ tolist 0 []
+
+let filter_with filter v =
+ Array.of_list (CList.filter_with filter (Array.to_list v))
+
+module Fun1 =
+struct
+
+ let map f arg v = match v with
+ | [| |] -> [| |]
+ | _ ->
+ let len = Array.length v in
+ let x0 = Array.unsafe_get v 0 in
+ let ans = Array.make len (f arg x0) in
+ for i = 1 to pred len do
+ let x = Array.unsafe_get v i in
+ Array.unsafe_set ans i (f arg x)
+ done;
+ ans
+
+ let smartmap f arg (ar : 'a array) =
+ let len = Array.length ar in
+ let i = ref 0 in
+ let break = ref true in
+ let temp = ref None in
+ while !break && (!i < len) do
+ let v = Array.unsafe_get ar !i in
+ let v' = f arg v in
+ if v == v' then incr i
+ else begin
+ break := false;
+ temp := Some v';
+ end
+ done;
+ if !i < len then begin
+ (** The array is not the same as the original one *)
+ let ans : 'a array = Array.copy ar in
+ let v = match !temp with None -> assert false | Some x -> x in
+ Array.unsafe_set ans !i v;
+ incr i;
+ while !i < len do
+ let v = Array.unsafe_get ans !i in
+ let v' = f arg v in
+ if v != v' then Array.unsafe_set ans !i v';
+ incr i
+ done;
+ ans
+ end else ar
+
+ let iter f arg v =
+ let len = Array.length v in
+ for i = 0 to pred len do
+ let x = uget v i in
+ f arg x
+ done
+
+end
diff --git a/clib/cArray.mli b/clib/cArray.mli
new file mode 100644
index 00000000..fa3978bd
--- /dev/null
+++ b/clib/cArray.mli
@@ -0,0 +1,157 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type S = module type of Array
+
+module type ExtS =
+sig
+ include S
+ val compare : ('a -> 'a -> int) -> 'a array -> 'a array -> int
+ (** First size comparison, then lexicographic order. *)
+
+ val equal : ('a -> 'a -> bool) -> 'a array -> 'a array -> bool
+ (** Lift equality to array type. *)
+
+ val equal_norefl : ('a -> 'a -> bool) -> 'a array -> 'a array -> bool
+ (** Like {!equal} but does not assume that equality is reflexive: no
+ optimisation is performed if both arrays are physically the
+ same. *)
+
+ val is_empty : 'a array -> bool
+ (** True whenever the array is empty. *)
+
+ val exists : ('a -> bool) -> 'a array -> bool
+ (** As [List.exists] but on arrays. *)
+
+ val exists2 : ('a -> 'b -> bool) -> 'a array -> 'b array -> bool
+
+ val for_all : ('a -> bool) -> 'a array -> bool
+ val for_all2 : ('a -> 'b -> bool) -> 'a array -> 'b array -> bool
+ val for_all3 : ('a -> 'b -> 'c -> bool) ->
+ 'a array -> 'b array -> 'c array -> bool
+ val for_all4 : ('a -> 'b -> 'c -> 'd -> bool) ->
+ 'a array -> 'b array -> 'c array -> 'd array -> bool
+ val for_all_i : (int -> 'a -> bool) -> int -> 'a array -> bool
+
+ val findi : (int -> 'a -> bool) -> 'a array -> int option
+
+ val hd : 'a array -> 'a
+ (** First element of an array, or [Failure "Array.hd"] if empty. *)
+
+ val tl : 'a array -> 'a array
+ (** Remaining part of [hd], or [Failure "Array.tl"] if empty. *)
+
+ val last : 'a array -> 'a
+ (** Last element of an array, or [Failure "Array.last"] if empty. *)
+
+ val cons : 'a -> 'a array -> 'a array
+ (** Append an element on the left. *)
+
+ val rev : 'a array -> unit
+ (** In place reversal. *)
+
+ val fold_right_i :
+ (int -> 'b -> 'a -> 'a) -> 'b array -> 'a -> 'a
+ val fold_left_i : (int -> 'a -> 'b -> 'a) -> 'a -> 'b array -> 'a
+ val fold_right2 :
+ ('a -> 'b -> 'c -> 'c) -> 'a array -> 'b array -> 'c -> 'c
+ val fold_left2 :
+ ('a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
+ val fold_left3 :
+ ('a -> 'b -> 'c -> 'd -> 'a) -> 'a -> 'b array -> 'c array -> 'd array -> 'a
+ val fold_left2_i :
+ (int -> 'a -> 'b -> 'c -> 'a) -> 'a -> 'b array -> 'c array -> 'a
+ val fold_left_from : int -> ('a -> 'b -> 'a) -> 'a -> 'b array -> 'a
+
+ val map_to_list : ('a -> 'b) -> 'a array -> 'b list
+ (** Composition of [map] and [to_list]. *)
+
+ val map_of_list : ('a -> 'b) -> 'a list -> 'b array
+ (** Composition of [map] and [of_list]. *)
+
+ val chop : int -> 'a array -> 'a array * 'a array
+ (** [chop i a] returns [(a1, a2)] s.t. [a = a1 + a2] and [length a1 = n].
+ Raise [Failure "Array.chop"] if [i] is not a valid index. *)
+
+ val smartmap : ('a -> 'a) -> 'a array -> 'a array
+ (** [smartmap f a] behaves as [map f a] but returns [a] instead of a copy when
+ [f x == x] for all [x] in [a]. *)
+
+ val smartfoldmap : ('r -> 'a -> 'r * 'a) -> 'r -> 'a array -> 'r * 'a array
+ (** Same as [smartmap] but threads an additional state left-to-right. *)
+
+ val map2 : ('a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array
+ val map2_i : (int -> 'a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array
+ val map3 :
+ ('a -> 'b -> 'c -> 'd) -> 'a array -> 'b array -> 'c array -> 'd array
+
+ val map_left : ('a -> 'b) -> 'a array -> 'b array
+ (** As [map] but guaranteed to be left-to-right. *)
+
+ val iter2 : ('a -> 'b -> unit) -> 'a array -> 'b array -> unit
+ (** Iter on two arrays. Raise [Invalid_argument "Array.iter2"] if sizes differ. *)
+
+ val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b array -> 'a * 'c array
+ (** [fold_left_map f e_0 [|l_1...l_n|] = e_n,[|k_1...k_n|]]
+ where [(e_i,k_i)=f e_{i-1} l_i] *)
+
+ val fold_right_map : ('a -> 'c -> 'b * 'c) -> 'a array -> 'c -> 'b array * 'c
+ (** Same, folding on the right *)
+
+ val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b array -> 'c array -> 'a * 'd array
+ (** Same with two arrays, folding on the left *)
+
+ val fold_right2_map : ('a -> 'b -> 'c -> 'd * 'c) -> 'a array -> 'b array -> 'c -> 'd array * 'c
+ (** Same with two arrays, folding on the left *)
+
+ val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b array -> 'a * 'c array
+ [@@ocaml.deprecated "Same as [fold_left_map]"]
+
+ val fold_map' : ('a -> 'c -> 'b * 'c) -> 'a array -> 'c -> 'b array * 'c
+ [@@ocaml.deprecated "Same as [fold_right_map]"]
+
+ val fold_map2' :
+ ('a -> 'b -> 'c -> 'd * 'c) -> 'a array -> 'b array -> 'c -> 'd array * 'c
+ [@@ocaml.deprecated "Same as [fold_right2_map]"]
+
+ val distinct : 'a array -> bool
+ (** Return [true] if every element of the array is unique (for default
+ equality). *)
+
+ val rev_of_list : 'a list -> 'a array
+ (** [rev_of_list l] is equivalent to [Array.of_list (List.rev l)]. *)
+
+ val rev_to_list : 'a array -> 'a list
+ (** [rev_to_list a] is equivalent to [List.rev (List.of_array a)]. *)
+
+ val filter_with : bool list -> 'a array -> 'a array
+ (** [filter_with b a] selects elements of [a] whose corresponding element in
+ [b] is [true]. Raise [Invalid_argument _] when sizes differ. *)
+
+end
+
+include ExtS
+
+module Fun1 :
+sig
+ val map : ('r -> 'a -> 'b) -> 'r -> 'a array -> 'b array
+ (** [Fun1.map f x v = map (f x) v] *)
+
+ val smartmap : ('r -> 'a -> 'a) -> 'r -> 'a array -> 'a array
+ (** [Fun1.smartmap f x v = smartmap (f x) v] *)
+
+ val iter : ('r -> 'a -> unit) -> 'r -> 'a array -> unit
+ (** [Fun1.iter f x v = iter (f x) v] *)
+
+end
+(** The functions defined in this module are the same as the main ones, except
+ that they are all higher-order, and their function arguments have an
+ additional parameter. This allows us to prevent closure creation in critical
+ cases. *)
diff --git a/clib/cEphemeron.ml b/clib/cEphemeron.ml
new file mode 100644
index 00000000..3136d66e
--- /dev/null
+++ b/clib/cEphemeron.ml
@@ -0,0 +1,91 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type key_type = int
+
+type boxed_key = key_type ref ref
+
+let mk_key : unit -> boxed_key =
+ (* TODO: take a random value here. Is there a random function in OCaml? *)
+ let bid = ref 0 in
+ (* According to OCaml Gc module documentation, Pervasives.ref is one of the
+ few ways of getting a boxed value the compiler will never alias. *)
+ fun () -> incr bid; Pervasives.ref (Pervasives.ref !bid)
+
+(* A phantom type to preserve type safety *)
+type 'a key = boxed_key
+
+(* Comparing keys with == grants that if a key is unmarshalled (in the same
+ process where it was created or in another one) it is not mistaken for
+ an already existing one (unmarshal has no right to alias). If the initial
+ value of bid is taken at random, then one also avoids potential collisions *)
+module HT = Hashtbl.Make(struct
+ type t = key_type ref
+ let equal k1 k2 = k1 == k2
+ let hash id = !id
+end)
+
+(* A key is the (unique) value inside a boxed key, hence it does not
+ keep its corresponding boxed key reachable (replacing key_type by boxed_key
+ would make the key always reachable) *)
+let values : Obj.t HT.t = HT.create 1001
+
+(* To avoid a race condition between the finalization function and
+ get/create on the values hashtable, the finalization function just
+ enqueues in an imperative list the item to be collected. Being the list
+ imperative, even if the Gc enqueues an item while run_collection is operating,
+ the tail of the list is eventually set to Empty on completion.
+ Kudos to the authors of Why3 that came up with this solution for their
+ implementation of weak hash tables! *)
+type imperative_list = cell ref
+and cell = Empty | Item of key_type ref * imperative_list
+
+let collection_queue : imperative_list ref = ref (ref Empty)
+
+let enqueue x = collection_queue := ref (Item (!x, !collection_queue))
+
+let run_collection () =
+ let rec aux l = match !l with
+ | Empty -> ()
+ | Item (k, tl) -> HT.remove values k; aux tl in
+ let l = !collection_queue in
+ aux l;
+ l := Empty
+
+(* The only reference to the boxed key is the one returned, when the user drops
+ it the value eventually disappears from the values table above *)
+let create (v : 'a) : 'a key =
+ run_collection ();
+ let k = mk_key () in
+ HT.add values !k (Obj.repr v);
+ Gc.finalise enqueue k;
+ k
+
+(* Avoid raising Not_found *)
+exception InvalidKey
+let get (k : 'a key) : 'a =
+ run_collection ();
+ try Obj.obj (HT.find values !k)
+ with Not_found -> raise InvalidKey
+
+(* Simple utils *)
+let default k v =
+ try get k
+ with InvalidKey -> v
+
+let iter_opt k f =
+ match
+ try Some (get k)
+ with InvalidKey -> None
+ with
+ | None -> ()
+ | Some v -> f v
+
+let clear () = run_collection ()
diff --git a/clib/cEphemeron.mli b/clib/cEphemeron.mli
new file mode 100644
index 00000000..8e753d0b
--- /dev/null
+++ b/clib/cEphemeron.mli
@@ -0,0 +1,54 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* Use case:
+ You have a data structure that needs to be marshalled but it contains
+ unmarshallable data (like a closure, or a file descriptor). Actually
+ you don't need this data to be preserved by marshalling, it just happens
+ to be there.
+ You could produced a trimmed down data structure, but then, once
+ unmarshalled, you can't used the very same code to process it, unless you
+ re-inject the trimmed down data structure into the standard one, using
+ dummy values for the unmarshallable stuff.
+ Similarly you could change your data structure turning all types [bad]
+ into [bad option], then just before marshalling you set all values of type
+ [bad option] to [None]. Still this pruning may be expensive and you have
+ to code it.
+
+ Desiderata:
+ The marshalling operation automatically discards values that cannot be
+ marshalled or cannot be properly unmarshalled.
+
+ Proposed solution:
+ Turn all occurrences of [bad] into [bad key] in your data structure.
+ Use [create bad_val] to obtain a unique key [k] for [bad_val], and store
+ [k] in the data structure. Use [get k] to obtain [bad_val].
+
+ An ['a key] can always be marshalled. When marshalled, a key loses its
+ value. The function [get] raises Not_found on unmarshalled keys.
+
+ If a key is garbage collected, the corresponding value is garbage
+ collected too (unless extra references to it exist).
+ In short no memory management hassle, keys can just replace their
+ corresponding value in the data structure. *)
+
+type 'a key
+
+val create : 'a -> 'a key
+
+(* May raise InvalidKey *)
+exception InvalidKey
+val get : 'a key -> 'a
+
+(* These never fail. *)
+val iter_opt : 'a key -> ('a -> unit) -> unit
+val default : 'a key -> 'a -> 'a
+
+val clear : unit -> unit
diff --git a/clib/cList.ml b/clib/cList.ml
new file mode 100644
index 00000000..b25c4ffd
--- /dev/null
+++ b/clib/cList.ml
@@ -0,0 +1,917 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type 'a cmp = 'a -> 'a -> int
+type 'a eq = 'a -> 'a -> bool
+
+module type S = module type of List
+
+module type ExtS =
+sig
+ include S
+ val compare : 'a cmp -> 'a list cmp
+ val equal : 'a eq -> 'a list eq
+ val is_empty : 'a list -> bool
+ val init : int -> (int -> 'a) -> 'a list
+ val mem_f : 'a eq -> 'a -> 'a list -> bool
+ val add_set : 'a eq -> 'a -> 'a list -> 'a list
+ val eq_set : 'a eq -> 'a list -> 'a list -> bool
+ val intersect : 'a eq -> 'a list -> 'a list -> 'a list
+ val union : 'a eq -> 'a list -> 'a list -> 'a list
+ val unionq : 'a list -> 'a list -> 'a list
+ val subtract : 'a eq -> 'a list -> 'a list -> 'a list
+ val subtractq : 'a list -> 'a list -> 'a list
+ val interval : int -> int -> int list
+ val make : int -> 'a -> 'a list
+ val assign : 'a list -> int -> 'a -> 'a list
+ val distinct : 'a list -> bool
+ val distinct_f : 'a cmp -> 'a list -> bool
+ val duplicates : 'a eq -> 'a list -> 'a list
+ val filter2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> 'a list * 'b list
+ val map_filter : ('a -> 'b option) -> 'a list -> 'b list
+ val map_filter_i : (int -> 'a -> 'b option) -> 'a list -> 'b list
+ val filter_with : bool list -> 'a list -> 'a list
+ val smartmap : ('a -> 'a) -> 'a list -> 'a list
+ val map_left : ('a -> 'b) -> 'a list -> 'b list
+ val map_i : (int -> 'a -> 'b) -> int -> 'a list -> 'b list
+ val map2_i :
+ (int -> 'a -> 'b -> 'c) -> int -> 'a list -> 'b list -> 'c list
+ val map3 :
+ ('a -> 'b -> 'c -> 'd) -> 'a list -> 'b list -> 'c list -> 'd list
+ val map4 :
+ ('a -> 'b -> 'c -> 'd -> 'e) -> 'a list -> 'b list -> 'c list -> 'd list -> 'e list
+ val filteri :
+ (int -> 'a -> bool) -> 'a list -> 'a list
+ val partitioni :
+ (int -> 'a -> bool) -> 'a list -> 'a list * 'a list
+ val map_of_array : ('a -> 'b) -> 'a array -> 'b list
+ val smartfilter : ('a -> bool) -> 'a list -> 'a list
+ val extend : bool list -> 'a -> 'a list -> 'a list
+ val count : ('a -> bool) -> 'a list -> int
+ val index : 'a eq -> 'a -> 'a list -> int
+ val index0 : 'a eq -> 'a -> 'a list -> int
+ val iteri : (int -> 'a -> unit) -> 'a list -> unit
+ val fold_left_until : ('c -> 'a -> 'c CSig.until) -> 'c -> 'a list -> 'c
+ val fold_right_i : (int -> 'a -> 'b -> 'b) -> int -> 'a list -> 'b -> 'b
+ val fold_left_i : (int -> 'a -> 'b -> 'a) -> int -> 'a -> 'b list -> 'a
+ val fold_right_and_left :
+ ('a -> 'b -> 'b list -> 'a) -> 'b list -> 'a -> 'a
+ val fold_left3 : ('a -> 'b -> 'c -> 'd -> 'a) -> 'a -> 'b list -> 'c list -> 'd list -> 'a
+ val fold_left2_set : exn -> ('a -> 'b -> 'c -> 'b list -> 'c list -> 'a) -> 'a -> 'b list -> 'c list -> 'a
+ val for_all_i : (int -> 'a -> bool) -> int -> 'a list -> bool
+ val except : 'a eq -> 'a -> 'a list -> 'a list
+ val remove : 'a eq -> 'a -> 'a list -> 'a list
+ val remove_first : ('a -> bool) -> 'a list -> 'a list
+ val extract_first : ('a -> bool) -> 'a list -> 'a list * 'a
+ val insert : ('a -> 'a -> bool) -> 'a -> 'a list -> 'a list
+ val for_all2eq : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool
+ val sep_last : 'a list -> 'a * 'a list
+ val find_map : ('a -> 'b option) -> 'a list -> 'b
+ val uniquize : 'a list -> 'a list
+ val sort_uniquize : 'a cmp -> 'a list -> 'a list
+ val merge_uniq : ('a -> 'a -> int) -> 'a list -> 'a list -> 'a list
+ val subset : 'a list -> 'a list -> bool
+ val chop : int -> 'a list -> 'a list * 'a list
+ exception IndexOutOfRange
+ val goto : int -> 'a list -> 'a list * 'a list
+ val split_when : ('a -> bool) -> 'a list -> 'a list * 'a list
+ val split3 : ('a * 'b * 'c) list -> 'a list * 'b list * 'c list
+ val firstn : int -> 'a list -> 'a list
+ val last : 'a list -> 'a
+ val lastn : int -> 'a list -> 'a list
+ val skipn : int -> 'a list -> 'a list
+ val skipn_at_least : int -> 'a list -> 'a list
+ val addn : int -> 'a -> 'a list -> 'a list
+ val prefix_of : 'a eq -> 'a list -> 'a list -> bool
+ val drop_prefix : 'a eq -> 'a list -> 'a list -> 'a list
+ val drop_last : 'a list -> 'a list
+ val map_append : ('a -> 'b list) -> 'a list -> 'b list
+ val map_append2 : ('a -> 'b -> 'c list) -> 'a list -> 'b list -> 'c list
+ val share_tails : 'a list -> 'a list -> 'a list * 'a list * 'a list
+ val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
+ val fold_right_map : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
+ val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b list -> 'c list -> 'a * 'd list
+ val fold_right2_map : ('b -> 'c -> 'a -> 'd * 'a) -> 'b list -> 'c list -> 'a -> 'd list * 'a
+ val fold_left3_map : ('a -> 'b -> 'c -> 'd -> 'a * 'e) -> 'a -> 'b list -> 'c list -> 'd list -> 'a * 'e list
+ val fold_left4_map : ('a -> 'b -> 'c -> 'd -> 'e -> 'a * 'r) -> 'a -> 'b list -> 'c list -> 'd list -> 'e list -> 'a * 'r list
+ val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
+ [@@ocaml.deprecated "Same as [fold_left_map]"]
+ val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
+ [@@ocaml.deprecated "Same as [fold_right_map]"]
+ val map_assoc : ('a -> 'b) -> ('c * 'a) list -> ('c * 'b) list
+ val assoc_f : 'a eq -> 'a -> ('a * 'b) list -> 'b
+ val remove_assoc_f : 'a eq -> 'a -> ('a * 'b) list -> ('a * 'b) list
+ val mem_assoc_f : 'a eq -> 'a -> ('a * 'b) list -> bool
+ val min : 'a cmp -> 'a list -> 'a
+ val cartesian : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
+ val cartesians : ('a -> 'b -> 'b) -> 'b -> 'a list list -> 'b list
+ val combinations : 'a list list -> 'a list list
+ val combine3 : 'a list -> 'b list -> 'c list -> ('a * 'b * 'c) list
+ val cartesians_filter :
+ ('a -> 'b -> 'b option) -> 'b -> 'a list list -> 'b list
+ val factorize_left : 'a eq -> ('a * 'b) list -> ('a * 'b list) list
+
+ module type MonoS = sig
+ type elt
+ val equal : elt list -> elt list -> bool
+ val mem : elt -> elt list -> bool
+ val assoc : elt -> (elt * 'a) list -> 'a
+ val mem_assoc : elt -> (elt * 'a) list -> bool
+ val remove_assoc : elt -> (elt * 'a) list -> (elt * 'a) list
+ val mem_assoc_sym : elt -> ('a * elt) list -> bool
+ end
+
+end
+
+include List
+
+(** Tail-rec implementation of usual functions. This is a well-known trick used
+ in, for instance, ExtLib and Batteries. *)
+
+type 'a cell = {
+ head : 'a;
+ mutable tail : 'a list;
+}
+
+external cast : 'a cell -> 'a list = "%identity"
+
+let rec map_loop f p = function
+| [] -> ()
+| x :: l ->
+ let c = { head = f x; tail = [] } in
+ p.tail <- cast c;
+ map_loop f c l
+
+let map f = function
+| [] -> []
+| x :: l ->
+ let c = { head = f x; tail = [] } in
+ map_loop f c l;
+ cast c
+
+let rec map2_loop f p l1 l2 = match l1, l2 with
+| [], [] -> ()
+| x :: l1, y :: l2 ->
+ let c = { head = f x y; tail = [] } in
+ p.tail <- cast c;
+ map2_loop f c l1 l2
+| _ -> invalid_arg "List.map2"
+
+let map2 f l1 l2 = match l1, l2 with
+| [], [] -> []
+| x :: l1, y :: l2 ->
+ let c = { head = f x y; tail = [] } in
+ map2_loop f c l1 l2;
+ cast c
+| _ -> invalid_arg "List.map2"
+
+let rec map_of_array_loop f p a i l =
+ if Int.equal i l then ()
+ else
+ let c = { head = f (Array.unsafe_get a i); tail = [] } in
+ p.tail <- cast c;
+ map_of_array_loop f c a (i + 1) l
+
+let map_of_array f a =
+ let l = Array.length a in
+ if Int.equal l 0 then []
+ else
+ let c = { head = f (Array.unsafe_get a 0); tail = [] } in
+ map_of_array_loop f c a 1 l;
+ cast c
+
+let rec append_loop p tl = function
+| [] -> p.tail <- tl
+| x :: l ->
+ let c = { head = x; tail = [] } in
+ p.tail <- cast c;
+ append_loop c tl l
+
+let append l1 l2 = match l1 with
+| [] -> l2
+| x :: l ->
+ let c = { head = x; tail = [] } in
+ append_loop c l2 l;
+ cast c
+
+let rec copy p = function
+| [] -> p
+| x :: l ->
+ let c = { head = x; tail = [] } in
+ p.tail <- cast c;
+ copy c l
+
+let rec init_loop len f p i =
+ if Int.equal i len then ()
+ else
+ let c = { head = f i; tail = [] } in
+ p.tail <- cast c;
+ init_loop len f c (succ i)
+
+let init len f =
+ if len < 0 then invalid_arg "List.init"
+ else if Int.equal len 0 then []
+ else
+ let c = { head = f 0; tail = [] } in
+ init_loop len f c 1;
+ cast c
+
+let rec concat_loop p = function
+| [] -> ()
+| x :: l -> concat_loop (copy p x) l
+
+let concat l =
+ let dummy = { head = Obj.magic 0; tail = [] } in
+ concat_loop dummy l;
+ dummy.tail
+
+let flatten = concat
+
+let rec split_loop p q = function
+| [] -> ()
+| (x, y) :: l ->
+ let cl = { head = x; tail = [] } in
+ let cr = { head = y; tail = [] } in
+ p.tail <- cast cl;
+ q.tail <- cast cr;
+ split_loop cl cr l
+
+let split = function
+| [] -> [], []
+| (x, y) :: l ->
+ let cl = { head = x; tail = [] } in
+ let cr = { head = y; tail = [] } in
+ split_loop cl cr l;
+ (cast cl, cast cr)
+
+let rec combine_loop p l1 l2 = match l1, l2 with
+| [], [] -> ()
+| x :: l1, y :: l2 ->
+ let c = { head = (x, y); tail = [] } in
+ p.tail <- cast c;
+ combine_loop c l1 l2
+| _ -> invalid_arg "List.combine"
+
+let combine l1 l2 = match l1, l2 with
+| [], [] -> []
+| x :: l1, y :: l2 ->
+ let c = { head = (x, y); tail = [] } in
+ combine_loop c l1 l2;
+ cast c
+| _ -> invalid_arg "List.combine"
+
+let rec filter_loop f p = function
+| [] -> ()
+| x :: l ->
+ if f x then
+ let c = { head = x; tail = [] } in
+ let () = p.tail <- cast c in
+ filter_loop f c l
+ else
+ filter_loop f p l
+
+let filter f l =
+ let c = { head = Obj.magic 0; tail = [] } in
+ filter_loop f c l;
+ c.tail
+
+(** FIXME: Already present in OCaml 4.00 *)
+
+let rec map_i_loop f i p = function
+| [] -> ()
+| x :: l ->
+ let c = { head = f i x; tail = [] } in
+ p.tail <- cast c;
+ map_i_loop f (succ i) c l
+
+let map_i f i = function
+| [] -> []
+| x :: l ->
+ let c = { head = f i x; tail = [] } in
+ map_i_loop f (succ i) c l;
+ cast c
+
+(** Extensions of OCaml Stdlib *)
+
+let rec compare cmp l1 l2 =
+ if l1 == l2 then 0 else
+ match l1,l2 with
+ [], [] -> 0
+ | _::_, [] -> 1
+ | [], _::_ -> -1
+ | x1::l1, x2::l2 ->
+ (match cmp x1 x2 with
+ | 0 -> compare cmp l1 l2
+ | c -> c)
+
+let rec equal cmp l1 l2 =
+ l1 == l2 ||
+ match l1, l2 with
+ | [], [] -> true
+ | x1 :: l1, x2 :: l2 ->
+ cmp x1 x2 && equal cmp l1 l2
+ | _ -> false
+
+let is_empty = function
+| [] -> true
+| _ -> false
+
+let mem_f cmp x l = List.exists (cmp x) l
+
+let intersect cmp l1 l2 =
+ filter (fun x -> mem_f cmp x l2) l1
+
+let union cmp l1 l2 =
+ let rec urec = function
+ | [] -> l2
+ | a::l -> if mem_f cmp a l2 then urec l else a::urec l
+ in
+ urec l1
+
+let subtract cmp l1 l2 =
+ if is_empty l2 then l1
+ else List.filter (fun x -> not (mem_f cmp x l2)) l1
+
+let unionq l1 l2 = union (==) l1 l2
+let subtractq l1 l2 = subtract (==) l1 l2
+
+let interval n m =
+ let rec interval_n (l,m) =
+ if n > m then l else interval_n (m::l, pred m)
+ in
+ interval_n ([], m)
+
+let addn n v =
+ let rec aux n l =
+ if Int.equal n 0 then l
+ else aux (pred n) (v :: l)
+ in
+ if n < 0 then invalid_arg "List.addn"
+ else aux n
+
+let make n v = addn n v []
+
+let assign l n e =
+ let rec assrec stk l i = match l, i with
+ | ((h::t), 0) -> List.rev_append stk (e :: t)
+ | ((h::t), n) -> assrec (h :: stk) t (pred n)
+ | ([], _) -> failwith "List.assign"
+ in
+ assrec [] l n
+
+let rec smartmap f l = match l with
+ [] -> l
+ | h::tl ->
+ let h' = f h and tl' = smartmap f tl in
+ if h'==h && tl'==tl then l
+ else h'::tl'
+
+let map_left = map
+
+let map2_i f i l1 l2 =
+ let rec map_i i = function
+ | ([], []) -> []
+ | ((h1::t1), (h2::t2)) -> let v = f i h1 h2 in v :: map_i (succ i) (t1,t2)
+ | (_, _) -> invalid_arg "map2_i"
+ in
+ map_i i (l1,l2)
+
+let map3 f l1 l2 l3 =
+ let rec map = function
+ | ([], [], []) -> []
+ | ((h1::t1), (h2::t2), (h3::t3)) -> let v = f h1 h2 h3 in v::map (t1,t2,t3)
+ | (_, _, _) -> invalid_arg "map3"
+ in
+ map (l1,l2,l3)
+
+let map4 f l1 l2 l3 l4 =
+ let rec map = function
+ | ([], [], [], []) -> []
+ | ((h1::t1), (h2::t2), (h3::t3), (h4::t4)) -> let v = f h1 h2 h3 h4 in v::map (t1,t2,t3,t4)
+ | (_, _, _, _) -> invalid_arg "map4"
+ in
+ map (l1,l2,l3,l4)
+
+let rec smartfilter f l = match l with
+ [] -> l
+ | h::tl ->
+ let tl' = smartfilter f tl in
+ if f h then
+ if tl' == tl then l
+ else h :: tl'
+ else tl'
+
+let rec extend l a l' = match l,l' with
+ | true::l, b::l' -> b :: extend l a l'
+ | false::l, l' -> a :: extend l a l'
+ | [], [] -> []
+ | _ -> invalid_arg "extend"
+
+let count f l =
+ let rec aux acc = function
+ | [] -> acc
+ | h :: t -> if f h then aux (acc + 1) t else aux acc t in
+ aux 0 l
+
+let rec index_f f x l n = match l with
+| [] -> raise Not_found
+| y :: l -> if f x y then n else index_f f x l (succ n)
+
+let index f x l = index_f f x l 1
+
+let index0 f x l = index_f f x l 0
+
+let fold_left_until f accu s =
+ let rec aux accu = function
+ | [] -> accu
+ | x :: xs -> match f accu x with CSig.Stop x -> x | CSig.Cont i -> aux i xs in
+ aux accu s
+
+let fold_right_i f i l =
+ let rec it_f i l a = match l with
+ | [] -> a
+ | b::l -> f (i-1) b (it_f (i-1) l a)
+ in
+ it_f (List.length l + i) l
+
+let fold_left_i f =
+ let rec it_list_f i a = function
+ | [] -> a
+ | b::l -> it_list_f (i+1) (f i a b) l
+ in
+ it_list_f
+
+let rec fold_left3 f accu l1 l2 l3 =
+ match (l1, l2, l3) with
+ ([], [], []) -> accu
+ | (a1::l1, a2::l2, a3::l3) -> fold_left3 f (f accu a1 a2 a3) l1 l2 l3
+ | (_, _, _) -> invalid_arg "List.fold_left3"
+
+let rec fold_left4 f accu l1 l2 l3 l4 =
+ match (l1, l2, l3, l4) with
+ ([], [], [], []) -> accu
+ | (a1::l1, a2::l2, a3::l3, a4::l4) -> fold_left4 f (f accu a1 a2 a3 a4) l1 l2 l3 l4
+ | (_,_, _, _) -> invalid_arg "List.fold_left4"
+
+(* [fold_right_and_left f [a1;...;an] hd =
+ f (f (... (f (f hd
+ an
+ [an-1;...;a1])
+ an-1
+ [an-2;...;a1])
+ ...)
+ a2
+ [a1])
+ a1
+ []] *)
+
+let fold_right_and_left f l hd =
+ let rec aux tl = function
+ | [] -> hd
+ | a::l -> let hd = aux (a::tl) l in f hd a tl
+ in aux [] l
+
+(* Match sets as lists according to a matching function, also folding a side effect *)
+let rec fold_left2_set e f x l1 l2 =
+ match l1 with
+ | a1::l1 ->
+ let rec find seen = function
+ | [] -> raise e
+ | a2::l2 ->
+ try fold_left2_set e f (f x a1 a2 l1 l2) l1 (List.rev_append seen l2)
+ with e' when e' = e -> find (a2::seen) l2 in
+ find [] l2
+ | [] ->
+ if l2 = [] then x else raise e
+
+let iteri f l = fold_left_i (fun i _ x -> f i x) 0 () l
+
+let for_all_i p =
+ let rec for_all_p i = function
+ | [] -> true
+ | a::l -> p i a && for_all_p (i+1) l
+ in
+ for_all_p
+
+let except cmp x l = List.filter (fun y -> not (cmp x y)) l
+
+let remove = except (* Alias *)
+
+let rec remove_first p = function
+ | b::l when p b -> l
+ | b::l -> b::remove_first p l
+ | [] -> raise Not_found
+
+let extract_first p li =
+ let rec loop rev_left = function
+ | [] -> raise Not_found
+ | x::right ->
+ if p x then List.rev_append rev_left right, x
+ else loop (x :: rev_left) right
+ in loop [] li
+
+let insert p v l =
+ let rec insrec = function
+ | [] -> [v]
+ | h::tl -> if p v h then v::h::tl else h::insrec tl
+ in
+ insrec l
+
+let add_set cmp x l = if mem_f cmp x l then l else x :: l
+
+(** List equality up to permutation (but considering multiple occurrences) *)
+
+let eq_set cmp l1 l2 =
+ let rec aux l1 = function
+ | [] -> is_empty l1
+ | a::l2 -> aux (remove_first (cmp a) l1) l2 in
+ try aux l1 l2 with Not_found -> false
+
+let for_all2eq f l1 l2 =
+ try List.for_all2 f l1 l2 with Invalid_argument _ -> false
+
+let filteri p =
+ let rec filter_i_rec i = function
+ | [] -> []
+ | x::l -> let l' = filter_i_rec (succ i) l in if p i x then x::l' else l'
+ in
+ filter_i_rec 0
+
+let partitioni p =
+ let rec aux i = function
+ | [] -> [], []
+ | x :: l ->
+ let (l1, l2) = aux (succ i) l in
+ if p i x then (x :: l1, l2)
+ else (l1, x :: l2)
+ in aux 0
+
+let rec sep_last = function
+ | [] -> failwith "sep_last"
+ | hd::[] -> (hd,[])
+ | hd::tl -> let (l,tl) = sep_last tl in (l,hd::tl)
+
+let rec find_map f = function
+| [] -> raise Not_found
+| x :: l ->
+ match f x with
+ | None -> find_map f l
+ | Some y -> y
+
+(* FIXME: we should avoid relying on the generic hash function,
+ just as we'd better avoid Pervasives.compare *)
+
+let uniquize l =
+ let visited = Hashtbl.create 23 in
+ let rec aux acc changed = function
+ | h::t -> if Hashtbl.mem visited h then aux acc true t else
+ begin
+ Hashtbl.add visited h h;
+ aux (h::acc) changed t
+ end
+ | [] -> if changed then List.rev acc else l
+ in aux [] false l
+
+(** [sort_uniquize] might be an alternative to the hashtbl-based
+ [uniquize], when the order of the elements is irrelevant *)
+
+let rec uniquize_sorted cmp = function
+ | a::b::l when Int.equal (cmp a b) 0 -> uniquize_sorted cmp (a::l)
+ | a::l -> a::uniquize_sorted cmp l
+ | [] -> []
+
+let sort_uniquize cmp l = uniquize_sorted cmp (List.sort cmp l)
+
+let min cmp l =
+ let rec aux cur = function
+ | [] -> cur
+ | x :: l -> if cmp x cur < 0 then aux x l else aux cur l
+ in
+ match l with
+ | x :: l -> aux x l
+ | [] -> raise Not_found
+
+(* FIXME: again, generic hash function *)
+
+let distinct l =
+ let visited = Hashtbl.create 23 in
+ let rec loop = function
+ | h::t ->
+ if Hashtbl.mem visited h then false
+ else
+ begin
+ Hashtbl.add visited h h;
+ loop t
+ end
+ | [] -> true
+ in loop l
+
+let distinct_f cmp l =
+ let rec loop = function
+ | a::b::_ when Int.equal (cmp a b) 0 -> false
+ | a::l -> loop l
+ | [] -> true
+ in loop (List.sort cmp l)
+
+let rec merge_uniq cmp l1 l2 =
+ match l1, l2 with
+ | [], l2 -> l2
+ | l1, [] -> l1
+ | h1 :: t1, h2 :: t2 ->
+ let c = cmp h1 h2 in
+ if Int.equal c 0
+ then h1 :: merge_uniq cmp t1 t2
+ else if c <= 0
+ then h1 :: merge_uniq cmp t1 l2
+ else h2 :: merge_uniq cmp l1 t2
+
+let rec duplicates cmp = function
+ | [] -> []
+ | x::l ->
+ let l' = duplicates cmp l in
+ if mem_f cmp x l then add_set cmp x l' else l'
+
+let rec filter2_loop f p q l1 l2 = match l1, l2 with
+| [], [] -> ()
+| x :: l1, y :: l2 ->
+ if f x y then
+ let c1 = { head = x; tail = [] } in
+ let c2 = { head = y; tail = [] } in
+ let () = p.tail <- cast c1 in
+ let () = q.tail <- cast c2 in
+ filter2_loop f c1 c2 l1 l2
+ else
+ filter2_loop f p q l1 l2
+| _ -> invalid_arg "List.filter2"
+
+let filter2 f l1 l2 =
+ let c1 = { head = Obj.magic 0; tail = [] } in
+ let c2 = { head = Obj.magic 0; tail = [] } in
+ filter2_loop f c1 c2 l1 l2;
+ (c1.tail, c2.tail)
+
+let rec map_filter_loop f p = function
+ | [] -> ()
+ | x :: l ->
+ match f x with
+ | None -> map_filter_loop f p l
+ | Some y ->
+ let c = { head = y; tail = [] } in
+ p.tail <- cast c;
+ map_filter_loop f c l
+
+let map_filter f l =
+ let c = { head = Obj.magic 0; tail = [] } in
+ map_filter_loop f c l;
+ c.tail
+
+let rec map_filter_i_loop f i p = function
+ | [] -> ()
+ | x :: l ->
+ match f i x with
+ | None -> map_filter_i_loop f (succ i) p l
+ | Some y ->
+ let c = { head = y; tail = [] } in
+ p.tail <- cast c;
+ map_filter_i_loop f (succ i) c l
+
+let map_filter_i f l =
+ let c = { head = Obj.magic 0; tail = [] } in
+ map_filter_i_loop f 0 c l;
+ c.tail
+
+let rec filter_with filter l = match filter, l with
+| [], [] -> []
+| true :: filter, x :: l -> x :: filter_with filter l
+| false :: filter, _ :: l -> filter_with filter l
+| _ -> invalid_arg "List.filter_with"
+
+(* FIXME: again, generic hash function *)
+
+let subset l1 l2 =
+ let t2 = Hashtbl.create 151 in
+ List.iter (fun x -> Hashtbl.add t2 x ()) l2;
+ let rec look = function
+ | [] -> true
+ | x::ll -> try Hashtbl.find t2 x; look ll with Not_found -> false
+ in
+ look l1
+
+(** [goto i l] splits [l] into two lists [(l1,l2)] such that
+ [(List.rev l1)++l2=l] and [l1] has length [i]. It raises
+ [IndexOutOfRange] when [i] is negative or greater than the
+ length of [l]. *)
+exception IndexOutOfRange
+let goto n l =
+ let rec goto i acc = function
+ | tl when Int.equal i 0 -> (acc, tl)
+ | h::t -> goto (pred i) (h::acc) t
+ | [] -> raise IndexOutOfRange
+ in
+ goto n [] l
+
+(* [chop i l] splits [l] into two lists [(l1,l2)] such that
+ [l1++l2=l] and [l1] has length [i].
+ It raises [Failure] when [i] is negative or greater than the length of [l] *)
+
+let chop n l =
+ try let (h,t) = goto n l in (List.rev h,t)
+ with IndexOutOfRange -> failwith "List.chop"
+ (* spiwack: should raise [IndexOutOfRange] but I'm afraid of missing
+ a try/with when replacing the exception. *)
+
+(* [split_when p l] splits [l] into two lists [(l1,a::l2)] such that
+ [l1++(a::l2)=l], [p a=true] and [p b = false] for every element [b] of [l1].
+ If there is no such [a], then it returns [(l,[])] instead *)
+let split_when p =
+ let rec split_when_loop x y =
+ match y with
+ | [] -> (List.rev x,[])
+ | (a::l) -> if (p a) then (List.rev x,y) else split_when_loop (a::x) l
+ in
+ split_when_loop []
+
+let rec split3 = function
+ | [] -> ([], [], [])
+ | (x,y,z)::l ->
+ let (rx, ry, rz) = split3 l in (x::rx, y::ry, z::rz)
+
+let firstn n l =
+ let rec aux acc n l =
+ match n, l with
+ | 0, _ -> List.rev acc
+ | n, h::t -> aux (h::acc) (pred n) t
+ | _ -> failwith "firstn"
+ in
+ aux [] n l
+
+let rec last = function
+ | [] -> failwith "List.last"
+ | [x] -> x
+ | _ :: l -> last l
+
+let lastn n l =
+ let len = List.length l in
+ let rec aux m l =
+ if Int.equal m n then l else aux (m - 1) (List.tl l)
+ in
+ if len < n then failwith "lastn" else aux len l
+
+let rec skipn n l = match n,l with
+ | 0, _ -> l
+ | _, [] -> failwith "List.skipn"
+ | n, _::l -> skipn (pred n) l
+
+let skipn_at_least n l =
+ try skipn n l with Failure _ -> []
+
+let prefix_of cmp prefl l =
+ let rec prefrec = function
+ | (h1::t1, h2::t2) -> cmp h1 h2 && prefrec (t1,t2)
+ | ([], _) -> true
+ | _ -> false
+ in
+ prefrec (prefl,l)
+
+(** if [l=p++t] then [drop_prefix p l] is [t] else [l] *)
+
+let drop_prefix cmp p l =
+ let rec drop_prefix_rec = function
+ | (h1::tp, h2::tl) when cmp h1 h2 -> drop_prefix_rec (tp,tl)
+ | ([], tl) -> tl
+ | _ -> l
+ in
+ drop_prefix_rec (p,l)
+
+let map_append f l = List.flatten (List.map f l)
+
+let map_append2 f l1 l2 = List.flatten (List.map2 f l1 l2)
+
+let share_tails l1 l2 =
+ let rec shr_rev acc = function
+ | ((x1::l1), (x2::l2)) when x1 == x2 -> shr_rev (x1::acc) (l1,l2)
+ | (l1,l2) -> (List.rev l1, List.rev l2, acc)
+ in
+ shr_rev [] (List.rev l1, List.rev l2)
+
+(* Poor man's monadic map *)
+let rec fold_left_map f e = function
+ | [] -> (e,[])
+ | h::t ->
+ let e',h' = f e h in
+ let e'',t' = fold_left_map f e' t in
+ e'',h'::t'
+
+let fold_map = fold_left_map
+
+(* (* tail-recursive version of the above function *)
+let fold_map f e l =
+ let g (e,b') h =
+ let (e',h') = f e h in
+ (e',h'::b')
+ in
+ let (e',lrev) = List.fold_left g (e,[]) l in
+ (e',List.rev lrev)
+*)
+
+(* The same, based on fold_right, with the effect accumulated on the right *)
+let fold_right_map f l e =
+ List.fold_right (fun x (l,e) -> let (y,e) = f x e in (y::l,e)) l ([],e)
+
+let fold_map' = fold_right_map
+
+let on_snd f (x,y) = (x,f y)
+
+let fold_left2_map f e l l' =
+ on_snd List.rev @@
+ List.fold_left2 (fun (e,l) x x' ->
+ let (e,y) = f e x x' in
+ (e, y::l)
+ ) (e, []) l l'
+
+let fold_right2_map f l l' e =
+ List.fold_right2 (fun x x' (l,e) -> let (y,e) = f x x' e in (y::l,e)) l l' ([],e)
+
+let fold_left3_map f e l l' l'' =
+ on_snd List.rev @@
+ fold_left3 (fun (e,l) x x' x'' -> let (e,y) = f e x x' x'' in (e,y::l)) (e,[]) l l' l''
+
+let fold_left4_map f e l1 l2 l3 l4 =
+ on_snd List.rev @@
+ fold_left4 (fun (e,l) x1 x2 x3 x4 -> let (e,y) = f e x1 x2 x3 x4 in (e,y::l)) (e,[]) l1 l2 l3 l4
+
+let map_assoc f = List.map (fun (x,a) -> (x,f a))
+
+let rec assoc_f f a = function
+ | (x, e) :: xs -> if f a x then e else assoc_f f a xs
+ | [] -> raise Not_found
+
+let remove_assoc_f f a l =
+ try remove_first (fun (x,_) -> f a x) l with Not_found -> l
+
+let mem_assoc_f f a l = List.exists (fun (x,_) -> f a x) l
+
+(* A generic cartesian product: for any operator (**),
+ [cartesian (**) [x1;x2] [y1;y2] = [x1**y1; x1**y2; x2**y1; x2**y1]],
+ and so on if there are more elements in the lists. *)
+
+let cartesian op l1 l2 =
+ map_append (fun x -> List.map (op x) l2) l1
+
+(* [cartesians] is an n-ary cartesian product: it iterates
+ [cartesian] over a list of lists. *)
+
+let cartesians op init ll =
+ List.fold_right (cartesian op) ll [init]
+
+(* combinations [[a;b];[c;d]] gives [[a;c];[a;d];[b;c];[b;d]] *)
+
+let combinations l = cartesians (fun x l -> x::l) [] l
+
+let rec combine3 x y z =
+ match x, y, z with
+ | [], [], [] -> []
+ | (x :: xs), (y :: ys), (z :: zs) ->
+ (x, y, z) :: combine3 xs ys zs
+ | _, _, _ -> invalid_arg "List.combine3"
+
+(* Keep only those products that do not return None *)
+
+let cartesian_filter op l1 l2 =
+ map_append (fun x -> map_filter (op x) l2) l1
+
+(* Keep only those products that do not return None *)
+
+let cartesians_filter op init ll =
+ List.fold_right (cartesian_filter op) ll [init]
+
+(* Drop the last element of a list *)
+
+let rec drop_last = function
+ | [] -> assert false
+ | hd :: [] -> []
+ | hd :: tl -> hd :: drop_last tl
+
+(* Factorize lists of pairs according to the left argument *)
+let rec factorize_left cmp = function
+ | (a,b)::l ->
+ let al,l' = partition (fun (a',_) -> cmp a a') l in
+ (a,(b::List.map snd al)) :: factorize_left cmp l'
+ | [] -> []
+
+module type MonoS = sig
+ type elt
+ val equal : elt list -> elt list -> bool
+ val mem : elt -> elt list -> bool
+ val assoc : elt -> (elt * 'a) list -> 'a
+ val mem_assoc : elt -> (elt * 'a) list -> bool
+ val remove_assoc : elt -> (elt * 'a) list -> (elt * 'a) list
+ val mem_assoc_sym : elt -> ('a * elt) list -> bool
+end
diff --git a/clib/cList.mli b/clib/cList.mli
new file mode 100644
index 00000000..e025f7b4
--- /dev/null
+++ b/clib/cList.mli
@@ -0,0 +1,277 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type 'a cmp = 'a -> 'a -> int
+type 'a eq = 'a -> 'a -> bool
+
+(** Module type [S] is the one from OCaml Stdlib. *)
+module type S = module type of List
+
+module type ExtS =
+sig
+ include S
+
+ val compare : 'a cmp -> 'a list cmp
+ (** Lexicographic order on lists. *)
+
+ val equal : 'a eq -> 'a list eq
+ (** Lifts equality to list type. *)
+
+ val is_empty : 'a list -> bool
+ (** Checks whether a list is empty *)
+
+ val init : int -> (int -> 'a) -> 'a list
+ (** [init n f] constructs the list [f 0; ... ; f (n - 1)]. *)
+
+ val mem_f : 'a eq -> 'a -> 'a list -> bool
+ (* Same as [List.mem], for some specific equality *)
+
+ val add_set : 'a eq -> 'a -> 'a list -> 'a list
+ (** [add_set x l] adds [x] in [l] if it is not already there, or returns [l]
+ otherwise. *)
+
+ val eq_set : 'a eq -> 'a list eq
+ (** Test equality up to permutation (but considering multiple occurrences) *)
+
+ val intersect : 'a eq -> 'a list -> 'a list -> 'a list
+ val union : 'a eq -> 'a list -> 'a list -> 'a list
+ val unionq : 'a list -> 'a list -> 'a list
+ val subtract : 'a eq -> 'a list -> 'a list -> 'a list
+ val subtractq : 'a list -> 'a list -> 'a list
+
+ val interval : int -> int -> int list
+ (** [interval i j] creates the list [[i; i + 1; ...; j]], or [[]] when
+ [j <= i]. *)
+
+ val make : int -> 'a -> 'a list
+ (** [make n x] returns a list made of [n] times [x]. Raise
+ [Invalid_argument "List.make"] if [n] is negative. *)
+
+ val assign : 'a list -> int -> 'a -> 'a list
+ (** [assign l i x] sets the [i]-th element of [l] to [x], starting from [0]. *)
+
+ val distinct : 'a list -> bool
+ (** Return [true] if all elements of the list are distinct. *)
+
+ val distinct_f : 'a cmp -> 'a list -> bool
+
+ val duplicates : 'a eq -> 'a list -> 'a list
+ (** Return the list of unique elements which appear at least twice. Elements
+ are kept in the order of their first appearance. *)
+
+ val filter2 : ('a -> 'b -> bool) -> 'a list -> 'b list -> 'a list * 'b list
+ val map_filter : ('a -> 'b option) -> 'a list -> 'b list
+ val map_filter_i : (int -> 'a -> 'b option) -> 'a list -> 'b list
+
+ val filter_with : bool list -> 'a list -> 'a list
+ (** [filter_with b a] selects elements of [a] whose corresponding element in
+ [b] is [true]. Raise [Invalid_argument _] when sizes differ. *)
+
+ val smartmap : ('a -> 'a) -> 'a list -> 'a list
+ (** [smartmap f [a1...an] = List.map f [a1...an]] but if for all i
+ [f ai == ai], then [smartmap f l == l] *)
+
+ val map_left : ('a -> 'b) -> 'a list -> 'b list
+ (** As [map] but ensures the left-to-right order of evaluation. *)
+
+ val map_i : (int -> 'a -> 'b) -> int -> 'a list -> 'b list
+ (** As [map] but with the index, which starts from [0]. *)
+
+ val map2_i :
+ (int -> 'a -> 'b -> 'c) -> int -> 'a list -> 'b list -> 'c list
+ val map3 :
+ ('a -> 'b -> 'c -> 'd) -> 'a list -> 'b list -> 'c list -> 'd list
+ val map4 : ('a -> 'b -> 'c -> 'd -> 'e) -> 'a list -> 'b list -> 'c list ->
+ 'd list -> 'e list
+ val filteri : (int -> 'a -> bool) -> 'a list -> 'a list
+ val partitioni : (int -> 'a -> bool) -> 'a list -> 'a list * 'a list
+
+ val map_of_array : ('a -> 'b) -> 'a array -> 'b list
+ (** [map_of_array f a] behaves as [List.map f (Array.to_list a)] *)
+
+ val smartfilter : ('a -> bool) -> 'a list -> 'a list
+ (** [smartfilter f [a1...an] = List.filter f [a1...an]] but if for all i
+ [f ai = true], then [smartfilter f l == l] *)
+
+ val extend : bool list -> 'a -> 'a list -> 'a list
+(** [extend l a [a1..an]] assumes that the number of [true] in [l] is [n];
+ it extends [a1..an] by inserting [a] at the position of [false] in [l] *)
+ val count : ('a -> bool) -> 'a list -> int
+
+ val index : 'a eq -> 'a -> 'a list -> int
+ (** [index] returns the 1st index of an element in a list (counting from 1). *)
+
+ val index0 : 'a eq -> 'a -> 'a list -> int
+ (** [index0] behaves as [index] except that it starts counting at 0. *)
+
+ val iteri : (int -> 'a -> unit) -> 'a list -> unit
+ (** As [iter] but with the index argument (starting from 0). *)
+
+ val fold_left_until : ('c -> 'a -> 'c CSig.until) -> 'c -> 'a list -> 'c
+ (** acts like [fold_left f acc s] while [f] returns
+ [Cont acc']; it stops returning [c] as soon as [f] returns [Stop c]. *)
+
+ val fold_right_i : (int -> 'a -> 'b -> 'b) -> int -> 'a list -> 'b -> 'b
+ val fold_left_i : (int -> 'a -> 'b -> 'a) -> int -> 'a -> 'b list -> 'a
+ val fold_right_and_left :
+ ('a -> 'b -> 'b list -> 'a) -> 'b list -> 'a -> 'a
+ val fold_left3 : ('a -> 'b -> 'c -> 'd -> 'a) -> 'a -> 'b list -> 'c list -> 'd list -> 'a
+
+ (** Fold sets, i.e. lists up to order; the folding function tells
+ when elements match by returning a value and raising the given
+ exception otherwise; sets should have the same size; raise the
+ given exception if no pairing of the two sets is found;;
+ complexity in O(n^2) *)
+ val fold_left2_set : exn -> ('a -> 'b -> 'c -> 'b list -> 'c list -> 'a) -> 'a -> 'b list -> 'c list -> 'a
+
+ val for_all_i : (int -> 'a -> bool) -> int -> 'a list -> bool
+ val except : 'a eq -> 'a -> 'a list -> 'a list
+ val remove : 'a eq -> 'a -> 'a list -> 'a list
+
+ val remove_first : ('a -> bool) -> 'a list -> 'a list
+ (** Remove the first element satisfying a predicate, or raise [Not_found] *)
+
+ val extract_first : ('a -> bool) -> 'a list -> 'a list * 'a
+ (** Remove and return the first element satisfying a predicate,
+ or raise [Not_found] *)
+
+ val insert : ('a -> 'a -> bool) -> 'a -> 'a list -> 'a list
+ (** Insert at the (first) position so that if the list is ordered wrt to the
+ total order given as argument, the order is preserved *)
+
+ val for_all2eq : ('a -> 'b -> bool) -> 'a list -> 'b list -> bool
+ val sep_last : 'a list -> 'a * 'a list
+
+ val find_map : ('a -> 'b option) -> 'a list -> 'b
+ (** Returns the first element that is mapped to [Some _]. Raise [Not_found] if
+ there is none. *)
+
+ val uniquize : 'a list -> 'a list
+ (** Return the list of elements without duplicates.
+ This is the list unchanged if there was none. *)
+
+ val sort_uniquize : 'a cmp -> 'a list -> 'a list
+ (** Return a sorted and de-duplicated version of a list,
+ according to some comparison function. *)
+
+ val merge_uniq : 'a cmp -> 'a list -> 'a list -> 'a list
+ (** Merge two sorted lists and preserves the uniqueness property. *)
+
+ val subset : 'a list -> 'a list -> bool
+
+ val chop : int -> 'a list -> 'a list * 'a list
+ (** [chop i l] splits [l] into two lists [(l1,l2)] such that
+ [l1++l2=l] and [l1] has length [i]. It raises [Failure] when [i]
+ is negative or greater than the length of [l] *)
+
+ exception IndexOutOfRange
+ val goto: int -> 'a list -> 'a list * 'a list
+ (** [goto i l] splits [l] into two lists [(l1,l2)] such that
+ [(List.rev l1)++l2=l] and [l1] has length [i]. It raises
+ [IndexOutOfRange] when [i] is negative or greater than the
+ length of [l]. *)
+
+
+ val split_when : ('a -> bool) -> 'a list -> 'a list * 'a list
+ val split3 : ('a * 'b * 'c) list -> 'a list * 'b list * 'c list
+ val firstn : int -> 'a list -> 'a list
+ val last : 'a list -> 'a
+ val lastn : int -> 'a list -> 'a list
+ val skipn : int -> 'a list -> 'a list
+ val skipn_at_least : int -> 'a list -> 'a list
+
+ val addn : int -> 'a -> 'a list -> 'a list
+ (** [addn n x l] adds [n] times [x] on the left of [l]. *)
+
+ val prefix_of : 'a eq -> 'a list -> 'a list -> bool
+ (** [prefix_of l1 l2] returns [true] if [l1] is a prefix of [l2], [false]
+ otherwise. *)
+
+ val drop_prefix : 'a eq -> 'a list -> 'a list -> 'a list
+ (** [drop_prefix p l] returns [t] if [l=p++t] else return [l]. *)
+
+ val drop_last : 'a list -> 'a list
+
+ val map_append : ('a -> 'b list) -> 'a list -> 'b list
+ (** [map_append f [x1; ...; xn]] returns [(f x1)@(f x2)@...@(f xn)]. *)
+
+ val map_append2 : ('a -> 'b -> 'c list) -> 'a list -> 'b list -> 'c list
+ (** As [map_append]. Raises [Invalid_argument _] if the two lists don't have
+ the same length. *)
+
+ val share_tails : 'a list -> 'a list -> 'a list * 'a list * 'a list
+
+ val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
+ (** [fold_left_map f e_0 [l_1...l_n] = e_n,[k_1...k_n]]
+ where [(e_i,k_i)=f e_{i-1} l_i] *)
+
+ val fold_right_map : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
+ (** Same, folding on the right *)
+
+ val fold_left2_map : ('a -> 'b -> 'c -> 'a * 'd) -> 'a -> 'b list -> 'c list -> 'a * 'd list
+ (** Same with two lists, folding on the left *)
+
+ val fold_right2_map : ('b -> 'c -> 'a -> 'd * 'a) -> 'b list -> 'c list -> 'a -> 'd list * 'a
+ (** Same with two lists, folding on the right *)
+
+ val fold_left3_map : ('a -> 'b -> 'c -> 'd -> 'a * 'e) -> 'a -> 'b list -> 'c list -> 'd list -> 'a * 'e list
+ (** Same with three lists, folding on the left *)
+
+ val fold_left4_map : ('a -> 'b -> 'c -> 'd -> 'e -> 'a * 'r) -> 'a -> 'b list -> 'c list -> 'd list -> 'e list -> 'a * 'r list
+ (** Same with four lists, folding on the left *)
+
+ val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b list -> 'a * 'c list
+ [@@ocaml.deprecated "Same as [fold_left_map]"]
+
+ val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
+ [@@ocaml.deprecated "Same as [fold_right_map]"]
+
+ val map_assoc : ('a -> 'b) -> ('c * 'a) list -> ('c * 'b) list
+ val assoc_f : 'a eq -> 'a -> ('a * 'b) list -> 'b
+ val remove_assoc_f : 'a eq -> 'a -> ('a * 'b) list -> ('a * 'b) list
+ val mem_assoc_f : 'a eq -> 'a -> ('a * 'b) list -> bool
+
+ val min : 'a cmp -> 'a list -> 'a
+ (** Return minimum element according to some comparison function.
+
+ @raise Not_found on an empty list. *)
+
+ val cartesian : ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list
+ (** A generic cartesian product: for any operator (**),
+ [cartesian (**) [x1;x2] [y1;y2] = [x1**y1; x1**y2; x2**y1; x2**y1]],
+ and so on if there are more elements in the lists. *)
+
+ val cartesians : ('a -> 'b -> 'b) -> 'b -> 'a list list -> 'b list
+ (** [cartesians] is an n-ary cartesian product: it iterates
+ [cartesian] over a list of lists. *)
+
+ val combinations : 'a list list -> 'a list list
+ (** combinations [[a;b];[c;d]] returns [[a;c];[a;d];[b;c];[b;d]] *)
+
+ val combine3 : 'a list -> 'b list -> 'c list -> ('a * 'b * 'c) list
+
+ val cartesians_filter :
+ ('a -> 'b -> 'b option) -> 'b -> 'a list list -> 'b list
+ (** Keep only those products that do not return None *)
+
+ val factorize_left : 'a eq -> ('a * 'b) list -> ('a * 'b list) list
+
+ module type MonoS = sig
+ type elt
+ val equal : elt list -> elt list -> bool
+ val mem : elt -> elt list -> bool
+ val assoc : elt -> (elt * 'a) list -> 'a
+ val mem_assoc : elt -> (elt * 'a) list -> bool
+ val remove_assoc : elt -> (elt * 'a) list -> (elt * 'a) list
+ val mem_assoc_sym : elt -> ('a * elt) list -> bool
+ end
+end
+
+include ExtS
diff --git a/clib/cMap.ml b/clib/cMap.ml
new file mode 100644
index 00000000..373e3f8f
--- /dev/null
+++ b/clib/cMap.ml
@@ -0,0 +1,220 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type OrderedType =
+sig
+ type t
+ val compare : t -> t -> int
+end
+
+module type MonadS =
+sig
+ type +'a t
+ val return : 'a -> 'a t
+ val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
+end
+
+module type S = Map.S
+
+module type ExtS =
+sig
+ include CSig.MapS
+ module Set : CSig.SetS with type elt = key
+ val get : key -> 'a t -> 'a
+ val set : key -> 'a -> 'a t -> 'a t
+ val modify : key -> (key -> 'a -> 'a) -> 'a t -> 'a t
+ val domain : 'a t -> Set.t
+ val bind : (key -> 'a) -> Set.t -> 'a t
+ val fold_left : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
+ val fold_right : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
+ val smartmap : ('a -> 'a) -> 'a t -> 'a t
+ val smartmapi : (key -> 'a -> 'a) -> 'a t -> 'a t
+ val height : 'a t -> int
+ module Unsafe :
+ sig
+ val map : (key -> 'a -> key * 'b) -> 'a t -> 'b t
+ end
+ module Monad(M : MonadS) :
+ sig
+ val fold : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ val fold_left : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ val fold_right : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ end
+end
+
+module MapExt (M : Map.OrderedType) :
+sig
+ type 'a map = 'a Map.Make(M).t
+ val set : M.t -> 'a -> 'a map -> 'a map
+ val modify : M.t -> (M.t -> 'a -> 'a) -> 'a map -> 'a map
+ val domain : 'a map -> Set.Make(M).t
+ val bind : (M.t -> 'a) -> Set.Make(M).t -> 'a map
+ val fold_left : (M.t -> 'a -> 'b -> 'b) -> 'a map -> 'b -> 'b
+ val fold_right : (M.t -> 'a -> 'b -> 'b) -> 'a map -> 'b -> 'b
+ val smartmap : ('a -> 'a) -> 'a map -> 'a map
+ val smartmapi : (M.t -> 'a -> 'a) -> 'a map -> 'a map
+ val height : 'a map -> int
+ module Unsafe :
+ sig
+ val map : (M.t -> 'a -> M.t * 'b) -> 'a map -> 'b map
+ end
+ module Monad(MS : MonadS) :
+ sig
+ val fold : (M.t -> 'a -> 'b -> 'b MS.t) -> 'a map -> 'b -> 'b MS.t
+ val fold_left : (M.t -> 'a -> 'b -> 'b MS.t) -> 'a map -> 'b -> 'b MS.t
+ val fold_right : (M.t -> 'a -> 'b -> 'b MS.t) -> 'a map -> 'b -> 'b MS.t
+ end
+end =
+struct
+ (** This unsafe module is a way to access to the actual implementations of
+ OCaml sets and maps without reimplementing them ourselves. It is quite
+ dubious that these implementations will ever be changed... Nonetheless,
+ if this happens, we can still implement a less clever version of [domain].
+ *)
+
+ type 'a map = 'a Map.Make(M).t
+ type set = Set.Make(M).t
+
+ type 'a _map =
+ | MEmpty
+ | MNode of 'a map * M.t * 'a * 'a map * int
+
+ type _set =
+ | SEmpty
+ | SNode of set * M.t * set * int
+
+ let map_prj : 'a map -> 'a _map = Obj.magic
+ let map_inj : 'a _map -> 'a map = Obj.magic
+ let set_prj : set -> _set = Obj.magic
+ let set_inj : _set -> set = Obj.magic
+
+ let rec set k v (s : 'a map) : 'a map = match map_prj s with
+ | MEmpty -> raise Not_found
+ | MNode (l, k', v', r, h) ->
+ let c = M.compare k k' in
+ if c < 0 then
+ let l' = set k v l in
+ if l == l' then s
+ else map_inj (MNode (l', k', v', r, h))
+ else if c = 0 then
+ if v' == v then s
+ else map_inj (MNode (l, k', v, r, h))
+ else
+ let r' = set k v r in
+ if r == r' then s
+ else map_inj (MNode (l, k', v', r', h))
+
+ let rec modify k f (s : 'a map) : 'a map = match map_prj s with
+ | MEmpty -> raise Not_found
+ | MNode (l, k', v, r, h) ->
+ let c = M.compare k k' in
+ if c < 0 then
+ let l' = modify k f l in
+ if l == l' then s
+ else map_inj (MNode (l', k', v, r, h))
+ else if c = 0 then
+ let v' = f k' v in
+ if v' == v then s
+ else map_inj (MNode (l, k', v', r, h))
+ else
+ let r' = modify k f r in
+ if r == r' then s
+ else map_inj (MNode (l, k', v, r', h))
+
+ let rec domain (s : 'a map) : set = match map_prj s with
+ | MEmpty -> set_inj SEmpty
+ | MNode (l, k, _, r, h) ->
+ set_inj (SNode (domain l, k, domain r, h))
+ (** This function is essentially identity, but OCaml current stdlib does not
+ take advantage of the similarity of the two structures, so we introduce
+ this unsafe loophole. *)
+
+ let rec bind f (s : set) : 'a map = match set_prj s with
+ | SEmpty -> map_inj MEmpty
+ | SNode (l, k, r, h) ->
+ map_inj (MNode (bind f l, k, f k, bind f r, h))
+ (** Dual operation of [domain]. *)
+
+ let rec fold_left f (s : 'a map) accu = match map_prj s with
+ | MEmpty -> accu
+ | MNode (l, k, v, r, h) ->
+ let accu = f k v (fold_left f l accu) in
+ fold_left f r accu
+
+ let rec fold_right f (s : 'a map) accu = match map_prj s with
+ | MEmpty -> accu
+ | MNode (l, k, v, r, h) ->
+ let accu = f k v (fold_right f r accu) in
+ fold_right f l accu
+
+ let rec smartmap f (s : 'a map) = match map_prj s with
+ | MEmpty -> map_inj MEmpty
+ | MNode (l, k, v, r, h) ->
+ let l' = smartmap f l in
+ let r' = smartmap f r in
+ let v' = f v in
+ if l == l' && r == r' && v == v' then s
+ else map_inj (MNode (l', k, v', r', h))
+
+ let rec smartmapi f (s : 'a map) = match map_prj s with
+ | MEmpty -> map_inj MEmpty
+ | MNode (l, k, v, r, h) ->
+ let l' = smartmapi f l in
+ let r' = smartmapi f r in
+ let v' = f k v in
+ if l == l' && r == r' && v == v' then s
+ else map_inj (MNode (l', k, v', r', h))
+
+ let height s = match map_prj s with
+ | MEmpty -> 0
+ | MNode (_, _, _, _, h) -> h
+
+ module Unsafe =
+ struct
+
+ let rec map f (s : 'a map) : 'b map = match map_prj s with
+ | MEmpty -> map_inj MEmpty
+ | MNode (l, k, v, r, h) ->
+ let (k, v) = f k v in
+ map_inj (MNode (map f l, k, v, map f r, h))
+
+ end
+
+ module Monad(M : MonadS) =
+ struct
+
+ open M
+
+ let rec fold_left f s accu = match map_prj s with
+ | MEmpty -> return accu
+ | MNode (l, k, v, r, h) ->
+ fold_left f l accu >>= fun accu ->
+ f k v accu >>= fun accu ->
+ fold_left f r accu
+
+ let rec fold_right f s accu = match map_prj s with
+ | MEmpty -> return accu
+ | MNode (l, k, v, r, h) ->
+ fold_right f r accu >>= fun accu ->
+ f k v accu >>= fun accu ->
+ fold_right f l accu
+
+ let fold = fold_left
+
+ end
+
+end
+
+module Make(M : Map.OrderedType) =
+struct
+ include Map.Make(M)
+ include MapExt(M)
+ let get k m = try find k m with Not_found -> assert false
+end
diff --git a/clib/cMap.mli b/clib/cMap.mli
new file mode 100644
index 00000000..bb0019bb
--- /dev/null
+++ b/clib/cMap.mli
@@ -0,0 +1,90 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** {5 Extended version of OCaml's maps} *)
+
+module type OrderedType =
+sig
+ type t
+ val compare : t -> t -> int
+end
+
+module type MonadS =
+sig
+ type +'a t
+ val return : 'a -> 'a t
+ val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
+end
+
+module type S = Map.S
+
+module type ExtS =
+sig
+ include CSig.MapS
+ (** The underlying Map library *)
+
+ module Set : CSig.SetS with type elt = key
+ (** Sets used by the domain function *)
+
+ val get : key -> 'a t -> 'a
+ (** Same as {!find} but fails an assertion instead of raising [Not_found] *)
+
+ val set : key -> 'a -> 'a t -> 'a t
+ (** Same as [add], but expects the key to be present, and thus faster.
+ @raise Not_found when the key is unbound in the map. *)
+
+ val modify : key -> (key -> 'a -> 'a) -> 'a t -> 'a t
+ (** Apply the given function to the binding of the given key.
+ @raise Not_found when the key is unbound in the map. *)
+
+ val domain : 'a t -> Set.t
+ (** Recover the set of keys defined in the map. *)
+
+ val bind : (key -> 'a) -> Set.t -> 'a t
+ (** [bind f s] transform the set [x1; ...; xn] into [x1 := f x1; ...;
+ xn := f xn]. *)
+
+ val fold_left : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
+ (** Alias for {!fold}, to easily track where we depend on fold order. *)
+
+ val fold_right : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
+ (** Folding keys in decreasing order. *)
+
+ val smartmap : ('a -> 'a) -> 'a t -> 'a t
+ (** As [map] but tries to preserve sharing. *)
+
+ val smartmapi : (key -> 'a -> 'a) -> 'a t -> 'a t
+ (** As [mapi] but tries to preserve sharing. *)
+
+ val height : 'a t -> int
+ (** An indication of the logarithmic size of a map *)
+
+ module Unsafe :
+ sig
+ val map : (key -> 'a -> key * 'b) -> 'a t -> 'b t
+ (** As the usual [map], but also allows modifying the key of a binding.
+ It is required that the mapping function [f] preserves key equality,
+ i.e.: for all (k : key) (x : 'a), compare (fst (f k x)) k = 0. *)
+ end
+
+ module Monad(M : MonadS) :
+ sig
+ val fold : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ val fold_left : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ val fold_right : (key -> 'a -> 'b -> 'b M.t) -> 'a t -> 'b -> 'b M.t
+ end
+ (** Fold operators parameterized by any monad. *)
+
+end
+
+module Make(M : Map.OrderedType) : ExtS with
+ type key = M.t
+ and type 'a t = 'a Map.Make(M).t
+ and module Set := Set.Make(M)
diff --git a/clib/cObj.ml b/clib/cObj.ml
new file mode 100644
index 00000000..e26f4811
--- /dev/null
+++ b/clib/cObj.ml
@@ -0,0 +1,205 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(*s Logical and physical size of ocaml values. *)
+
+(** {6 Logical sizes} *)
+
+let c = ref 0
+let s = ref 0
+let b = ref 0
+let m = ref 0
+
+let rec obj_stats d t =
+ if Obj.is_int t then m := max d !m
+ else if Obj.tag t >= Obj.no_scan_tag then
+ if Obj.tag t = Obj.string_tag then
+ (c := !c + Obj.size t; b := !b + 1; m := max d !m)
+ else if Obj.tag t = Obj.double_tag then
+ (s := !s + 2; b := !b + 1; m := max d !m)
+ else if Obj.tag t = Obj.double_array_tag then
+ (s := !s + 2 * Obj.size t; b := !b + 1; m := max d !m)
+ else (b := !b + 1; m := max d !m)
+ else
+ let n = Obj.size t in
+ s := !s + n; b := !b + 1;
+ block_stats (d + 1) (n - 1) t
+
+and block_stats d i t =
+ if i >= 0 then (obj_stats d (Obj.field t i); block_stats d (i-1) t)
+
+let obj_stats a =
+ c := 0; s:= 0; b:= 0; m:= 0;
+ obj_stats 0 (Obj.repr a);
+ (!c, !s + !b, !m)
+
+(** {6 Physical sizes} *)
+
+(*s Pointers already visited are stored in a hash-table, where
+ comparisons are done using physical equality. *)
+
+module H = Hashtbl.Make(
+ struct
+ type t = Obj.t
+ let equal = (==)
+ let hash = Hashtbl.hash
+ end)
+
+let node_table = (H.create 257 : unit H.t)
+
+let in_table o = try H.find node_table o; true with Not_found -> false
+
+let add_in_table o = H.add node_table o ()
+
+let reset_table () = H.clear node_table
+
+(*s Objects are traversed recursively, as soon as their tags are less than
+ [no_scan_tag]. [count] records the numbers of words already visited. *)
+
+let size_of_double = Obj.size (Obj.repr 1.0)
+
+let count = ref 0
+
+let rec traverse t =
+ if not (in_table t) && Obj.is_block t then begin
+ add_in_table t;
+ let n = Obj.size t in
+ let tag = Obj.tag t in
+ if tag < Obj.no_scan_tag then
+ begin
+ count := !count + 1 + n;
+ for i = 0 to n - 1 do traverse (Obj.field t i) done
+ end
+ else if tag = Obj.string_tag then
+ count := !count + 1 + n
+ else if tag = Obj.double_tag then
+ count := !count + size_of_double
+ else if tag = Obj.double_array_tag then
+ count := !count + 1 + size_of_double * n
+ else
+ incr count
+ end
+
+(*s Sizes of objects in words and in bytes. The size in bytes is computed
+ system-independently according to [Sys.word_size]. *)
+
+let size o =
+ reset_table ();
+ count := 0;
+ traverse (Obj.repr o);
+ !count
+
+let size_b o = (size o) * (Sys.word_size / 8)
+
+let size_kb o = (size o) / (8192 / Sys.word_size)
+
+(** {6 Physical sizes with sharing} *)
+
+(** This time, all the size of objects are computed with respect
+ to a larger object containing them all, and we only count
+ the new blocks not already seen earlier in the left-to-right
+ visit of the englobing object.
+
+ The very same object could have a zero size or not, depending
+ of the occurrence we're considering in the englobing object.
+ For speaking of occurrences, we use an [int list] for a path
+ of field indexes from the outmost block to the one we're looking.
+ In the list, the leftmost integer is the field index in the deepest
+ block.
+*)
+
+(** We now store in the hashtable the size (with sharing), and
+ also the position of the first occurrence of the object *)
+
+let node_sizes = (H.create 257 : (int*int list) H.t)
+let get_size o = H.find node_sizes o
+let add_size o n pos = H.replace node_sizes o (n,pos)
+let reset_sizes () = H.clear node_sizes
+let global_object = ref (Obj.repr 0)
+
+(** [sum n f] is [f 0 + f 1 + ... + f (n-1)], evaluated from left to right *)
+
+let sum n f =
+ let rec loop k acc = if k >= n then acc else loop (k+1) (acc + f k)
+ in loop 0 0
+
+(** Recursive visit of the main object, filling the hashtable *)
+
+let rec compute_size o pos =
+ if not (Obj.is_block o) then 0
+ else
+ try
+ let _ = get_size o in 0 (* already seen *)
+ with Not_found ->
+ let n = Obj.size o in
+ add_size o (-1) pos (* temp size, for cyclic values *);
+ let tag = Obj.tag o in
+ let size =
+ if tag < Obj.no_scan_tag then
+ 1 + n + sum n (fun i -> compute_size (Obj.field o i) (i::pos))
+ else if tag = Obj.string_tag then
+ 1 + n
+ else if tag = Obj.double_tag then
+ size_of_double
+ else if tag = Obj.double_array_tag then
+ size_of_double * n
+ else
+ 1
+ in
+ add_size o size pos;
+ size
+
+(** Provides the global object in which we'll search shared sizes *)
+
+let register_shared_size t =
+ let o = Obj.repr t in
+ reset_sizes ();
+ global_object := o;
+ ignore (compute_size o [])
+
+(** Shared size of an object with respect to the global object given
+ by the last [register_shared_size] *)
+
+let shared_size pos o =
+ if not (Obj.is_block o) then 0
+ else
+ let size,pos' =
+ try get_size o
+ with Not_found -> failwith "shared_size: unregistered structure ?"
+ in
+ match pos with
+ | Some p when p <> pos' -> 0
+ | _ -> size
+
+let shared_size_of_obj t = shared_size None (Obj.repr t)
+
+(** Shared size of the object at some positiion in the global object given
+ by the last [register_shared_size] *)
+
+let shared_size_of_pos pos =
+ let rec obj_of_pos o = function
+ | [] -> o
+ | n::pos' ->
+ let o' = obj_of_pos o pos' in
+ assert (Obj.is_block o' && n < Obj.size o');
+ Obj.field o' n
+ in
+ shared_size (Some pos) (obj_of_pos !global_object pos)
+
+
+(*s Total size of the allocated ocaml heap. *)
+
+let heap_size () =
+ let stat = Gc.stat ()
+ and control = Gc.get () in
+ let max_words_total = stat.Gc.heap_words + control.Gc.minor_heap_size in
+ (max_words_total * (Sys.word_size / 8))
+
+let heap_size_kb () = (heap_size () + 1023) / 1024
diff --git a/clib/cObj.mli b/clib/cObj.mli
new file mode 100644
index 00000000..27082f68
--- /dev/null
+++ b/clib/cObj.mli
@@ -0,0 +1,61 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** {6 Physical size of an ocaml value.}
+
+ These functions explore objects recursively and may allocate a lot. *)
+
+val size : 'a -> int
+(** Physical size of an object in words. *)
+
+val size_b : 'a -> int
+(** Same as [size] in bytes. *)
+
+val size_kb : 'a -> int
+(** Same as [size] in kilobytes. *)
+
+(** {6 Physical size of an ocaml value with sharing.} *)
+
+(** This time, all the size of objects are computed with respect
+ to a larger object containing them all, and we only count
+ the new blocks not already seen earlier in the left-to-right
+ visit of the englobing object. *)
+
+(** Provides the global object in which we'll search shared sizes *)
+
+val register_shared_size : 'a -> unit
+
+(** Shared size (in word) of an object with respect to the global object
+ given by the last [register_shared_size]. *)
+
+val shared_size_of_obj : 'a -> int
+
+(** Same, with an object indicated by its occurrence in the global
+ object. The very same object could have a zero size or not, depending
+ of the occurrence we're considering in the englobing object.
+ For speaking of occurrences, we use an [int list] for a path
+ of field indexes (leftmost = deepest block, rightmost = top block of the
+ global object). *)
+
+val shared_size_of_pos : int list -> int
+
+(** {6 Logical size of an OCaml value.} *)
+
+val obj_stats : 'a -> int * int * int
+(** Return the (logical) value size, the string size, and the maximum depth of
+ the object. This loops on cyclic structures. *)
+
+(** {6 Total size of the allocated ocaml heap. } *)
+
+val heap_size : unit -> int
+(** Heap size, in words. *)
+
+val heap_size_kb : unit -> int
+(** Heap size, in kilobytes. *)
diff --git a/clib/cSet.ml b/clib/cSet.ml
new file mode 100644
index 00000000..b276df1a
--- /dev/null
+++ b/clib/cSet.ml
@@ -0,0 +1,69 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type OrderedType =
+sig
+ type t
+ val compare : t -> t -> int
+end
+
+module type S = Set.S
+
+module Make(M : OrderedType)= Set.Make(M)
+
+module type HashedType =
+sig
+ type t
+ val hash : t -> int
+end
+
+module Hashcons(M : OrderedType)(H : HashedType with type t = M.t) =
+struct
+ module Set = Make(M)
+
+ type set = Set.t
+ type _set =
+ | SEmpty
+ | SNode of set * M.t * set * int
+
+ let set_prj : set -> _set = Obj.magic
+ let set_inj : _set -> set = Obj.magic
+
+ let rec spine s accu = match set_prj s with
+ | SEmpty -> accu
+ | SNode (l, v, r, _) -> spine l ((v, r) :: accu)
+
+ let rec umap f s = match set_prj s with
+ | SEmpty -> set_inj SEmpty
+ | SNode (l, v, r, h) ->
+ let l' = umap f l in
+ let r' = umap f r in
+ let v' = f v in
+ set_inj (SNode (l', v', r', h))
+
+ let rec eqeq s1 s2 = match s1, s2 with
+ | [], [] -> true
+ | (v1, r1) :: s1, (v2, r2) :: s2 ->
+ v1 == v2 && eqeq (spine r1 s1) (spine r2 s2)
+ | _ -> false
+
+ module Hashed =
+ struct
+ open Hashset.Combine
+ type t = set
+ type u = M.t -> M.t
+ let eq s1 s2 = s1 == s2 || eqeq (spine s1 []) (spine s2 [])
+ let hash s = Set.fold (fun v accu -> combine (H.hash v) accu) s 0
+ let hashcons = umap
+ end
+
+ include Hashcons.Make(Hashed)
+
+end
diff --git a/clib/cSet.mli b/clib/cSet.mli
new file mode 100644
index 00000000..ea99a791
--- /dev/null
+++ b/clib/cSet.mli
@@ -0,0 +1,33 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type OrderedType =
+sig
+ type t
+ val compare : t -> t -> int
+end
+
+module type S = Set.S
+
+module Make(M : OrderedType) : S
+ with type elt = M.t
+ and type t = Set.Make(M).t
+
+module type HashedType =
+sig
+ type t
+ val hash : t -> int
+end
+
+module Hashcons (M : OrderedType) (H : HashedType with type t = M.t) : Hashcons.S with
+ type t = Set.Make(M).t
+ and type u = M.t -> M.t
+(** Create hash-consing for sets. The hashing function provided must be
+ compatible with the comparison function. *)
diff --git a/clib/cSig.mli b/clib/cSig.mli
new file mode 100644
index 00000000..fb36cc5b
--- /dev/null
+++ b/clib/cSig.mli
@@ -0,0 +1,88 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Missing pervasive types from OCaml stdlib *)
+
+type ('a, 'b) union = Inl of 'a | Inr of 'b
+(** Union type *)
+
+type 'a until = Stop of 'a | Cont of 'a
+(** Used for browsable-until structures. *)
+
+type (_, _) eq = Refl : ('a, 'a) eq
+
+module type SetS =
+sig
+ type elt
+ type t
+ val empty: t
+ val is_empty: t -> bool
+ val mem: elt -> t -> bool
+ val add: elt -> t -> t
+ val singleton: elt -> t
+ val remove: elt -> t -> t
+ val union: t -> t -> t
+ val inter: t -> t -> t
+ val diff: t -> t -> t
+ val compare: t -> t -> int
+ val equal: t -> t -> bool
+ val subset: t -> t -> bool
+ val iter: (elt -> unit) -> t -> unit
+ val fold: (elt -> 'a -> 'a) -> t -> 'a -> 'a
+ val for_all: (elt -> bool) -> t -> bool
+ val exists: (elt -> bool) -> t -> bool
+ val filter: (elt -> bool) -> t -> t
+ val partition: (elt -> bool) -> t -> t * t
+ val cardinal: t -> int
+ val elements: t -> elt list
+ val min_elt: t -> elt
+ val max_elt: t -> elt
+ val choose: t -> elt
+ val split: elt -> t -> t * bool * t
+end
+(** Redeclaration of OCaml set signature, to preserve compatibility. See OCaml
+ documentation for more information. *)
+
+module type MapS =
+sig
+ type key
+ type (+'a) t
+ val empty: 'a t
+ val is_empty: 'a t -> bool
+ val mem: key -> 'a t -> bool
+ val add: key -> 'a -> 'a t -> 'a t
+ (* when Coq requires OCaml 4.06 or later, can add:
+
+ val update : key -> ('a option -> 'a option) -> 'a t -> 'a t
+
+ allowing Coq to use OCaml's "update"
+ *)
+ val singleton: key -> 'a -> 'a t
+ val remove: key -> 'a t -> 'a t
+ val merge:
+ (key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t
+ val compare: ('a -> 'a -> int) -> 'a t -> 'a t -> int
+ val equal: ('a -> 'a -> bool) -> 'a t -> 'a t -> bool
+ val iter: (key -> 'a -> unit) -> 'a t -> unit
+ val fold: (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
+ val for_all: (key -> 'a -> bool) -> 'a t -> bool
+ val exists: (key -> 'a -> bool) -> 'a t -> bool
+ val filter: (key -> 'a -> bool) -> 'a t -> 'a t
+ val partition: (key -> 'a -> bool) -> 'a t -> 'a t * 'a t
+ val cardinal: 'a t -> int
+ val bindings: 'a t -> (key * 'a) list
+ val min_binding: 'a t -> (key * 'a)
+ val max_binding: 'a t -> (key * 'a)
+ val choose: 'a t -> (key * 'a)
+ val split: key -> 'a t -> 'a t * 'a option * 'a t
+ val find: key -> 'a t -> 'a
+ val map: ('a -> 'b) -> 'a t -> 'b t
+ val mapi: (key -> 'a -> 'b) -> 'a t -> 'b t
+end
diff --git a/clib/cStack.ml b/clib/cStack.ml
new file mode 100644
index 00000000..b86b0024
--- /dev/null
+++ b/clib/cStack.ml
@@ -0,0 +1,44 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+exception Empty = Stack.Empty
+
+type 'a t = {
+ mutable stack : 'a list;
+}
+
+let create () = { stack = [] }
+
+let push x s = s.stack <- x :: s.stack
+
+let pop = function
+ | { stack = [] } -> raise Stack.Empty
+ | { stack = x::xs } as s -> s.stack <- xs; x
+
+let top = function
+ | { stack = [] } -> raise Stack.Empty
+ | { stack = x::_ } -> x
+
+let to_list { stack = s } = s
+
+let find f s = List.find f (to_list s)
+
+let find_map f s = CList.find_map f s.stack
+
+let fold_until f accu s = CList.fold_left_until f accu s.stack
+
+let is_empty { stack = s } = s = []
+
+let iter f { stack = s } = List.iter f s
+
+let clear s = s.stack <- []
+
+let length { stack = s } = List.length s
+
diff --git a/clib/cStack.mli b/clib/cStack.mli
new file mode 100644
index 00000000..d6b8464e
--- /dev/null
+++ b/clib/cStack.mli
@@ -0,0 +1,58 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Extended interface for OCaml stacks. *)
+
+type 'a t
+
+exception Empty
+(** Alias for Stack.Empty. *)
+
+val create : unit -> 'a t
+(** Create an empty stack. *)
+
+val push : 'a -> 'a t -> unit
+(** Add an element to a stack. *)
+
+val find : ('a -> bool) -> 'a t -> 'a
+(** Find the first element satisfying the predicate.
+ @raise Not_found it there is none. *)
+
+val is_empty : 'a t -> bool
+(** Whether a stack is empty. *)
+
+val iter : ('a -> unit) -> 'a t -> unit
+(** Iterate a function over elements, from the last added one. *)
+
+val clear : 'a t -> unit
+(** Empty a stack. *)
+
+val length : 'a t -> int
+(** Length of a stack. *)
+
+val pop : 'a t -> 'a
+(** Remove and returns the first element of the stack.
+ @raise Empty if empty. *)
+
+val top : 'a t -> 'a
+(** Remove the first element of the stack without modifying it.
+ @raise Empty if empty. *)
+
+val to_list : 'a t -> 'a list
+(** Convert to a list. *)
+
+val find_map : ('a -> 'b option) -> 'a t -> 'b
+(** Find the first element that returns [Some _].
+ @raise Not_found it there is none. *)
+
+val fold_until : ('c -> 'a -> 'c CSig.until) -> 'c -> 'a t -> 'c
+(** Like CList.fold_left_until.
+ The stack is traversed from the top and is not altered. *)
+
diff --git a/clib/cString.ml b/clib/cString.ml
new file mode 100644
index 00000000..dd33562f
--- /dev/null
+++ b/clib/cString.ml
@@ -0,0 +1,180 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type S = module type of String
+
+module type ExtS =
+sig
+ include S
+ [@@@ocaml.warning "-3"] (* [@@noalloc] since 4.03.0 GPR#240 *)
+ external equal : string -> string -> bool = "caml_string_equal" "noalloc"
+ [@@@ocaml.warning "+3"]
+ val hash : string -> int
+ val is_empty : string -> bool
+ val explode : string -> string list
+ val implode : string list -> string
+ val strip : string -> string
+ val drop_simple_quotes : string -> string
+ val string_index_from : string -> int -> string -> int
+ val string_contains : where:string -> what:string -> bool
+ val plural : int -> string -> string
+ val conjugate_verb_to_be : int -> string
+ val ordinal : int -> string
+ val split : char -> string -> string list
+ val is_sub : string -> string -> int -> bool
+ module Set : Set.S with type elt = t
+ module Map : CMap.ExtS with type key = t and module Set := Set
+ module List : CList.MonoS with type elt = t
+ val hcons : string -> string
+end
+
+include String
+
+[@@@ocaml.warning "-3"] (* [@@noalloc] since 4.03.0 GPR#240 *)
+external equal : string -> string -> bool = "caml_string_equal" "noalloc"
+[@@@ocaml.warning "+3"]
+
+let rec hash len s i accu =
+ if i = len then accu
+ else
+ let c = Char.code (String.unsafe_get s i) in
+ hash len s (succ i) (accu * 19 + c)
+
+let hash s =
+ let len = String.length s in
+ hash len s 0 0
+
+let explode s =
+ let rec explode_rec n =
+ if n >= String.length s then
+ []
+ else
+ String.make 1 (String.get s n) :: explode_rec (succ n)
+ in
+ explode_rec 0
+
+let implode sl = String.concat "" sl
+
+let is_blank = function
+ | ' ' | '\r' | '\t' | '\n' -> true
+ | _ -> false
+
+let is_empty s = String.length s = 0
+
+let strip s =
+ let n = String.length s in
+ let rec lstrip_rec i =
+ if i < n && is_blank s.[i] then
+ lstrip_rec (i+1)
+ else i
+ in
+ let rec rstrip_rec i =
+ if i >= 0 && is_blank s.[i] then
+ rstrip_rec (i-1)
+ else i
+ in
+ let a = lstrip_rec 0 and b = rstrip_rec (n-1) in
+ String.sub s a (b-a+1)
+
+let drop_simple_quotes s =
+ let n = String.length s in
+ if n > 2 && s.[0] = '\'' && s.[n-1] = '\'' then String.sub s 1 (n-2) else s
+
+(* substring searching... *)
+
+(* gdzie = where, co = what *)
+(* gdzie=gdzie(string) gl=gdzie(length) gi=gdzie(index) *)
+let rec raw_is_sub gdzie gl gi co cl ci =
+ (ci>=cl) ||
+ ((String.unsafe_get gdzie gi = String.unsafe_get co ci) &&
+ (raw_is_sub gdzie gl (gi+1) co cl (ci+1)))
+
+let rec raw_str_index i gdzie l c co cl =
+ (* First adapt to ocaml 3.11 new semantics of index_from *)
+ if (i+cl > l) then raise Not_found;
+ (* Then proceed as in ocaml < 3.11 *)
+ let i' = String.index_from gdzie i c in
+ if (i'+cl <= l) && (raw_is_sub gdzie l i' co cl 0) then i' else
+ raw_str_index (i'+1) gdzie l c co cl
+
+let string_index_from gdzie i co =
+ if co="" then i else
+ raw_str_index i gdzie (String.length gdzie)
+ (String.unsafe_get co 0) co (String.length co)
+
+let string_contains ~where ~what =
+ try
+ let _ = string_index_from where 0 what in true
+ with
+ Not_found -> false
+
+let is_sub p s off =
+ let lp = String.length p in
+ let ls = String.length s in
+ if ls < off + lp then false
+ else
+ let rec aux i =
+ if lp <= i then true
+ else
+ let cp = String.unsafe_get p i in
+ let cs = String.unsafe_get s (off + i) in
+ if cp = cs then aux (succ i) else false
+ in
+ aux 0
+
+let plural n s = if n<>1 then s^"s" else s
+
+let conjugate_verb_to_be n = if n<>1 then "are" else "is"
+
+let ordinal n =
+ let s =
+ if (n / 10) mod 10 = 1 then "th"
+ else match n mod 10 with
+ | 1 -> "st"
+ | 2 -> "nd"
+ | 3 -> "rd"
+ | _ -> "th"
+ in
+ string_of_int n ^ s
+
+(* string parsing *)
+
+let split c s =
+ let len = String.length s in
+ let rec split n =
+ try
+ let pos = String.index_from s n c in
+ let dir = String.sub s n (pos-n) in
+ dir :: split (succ pos)
+ with
+ | Not_found -> [String.sub s n (len-n)]
+ in
+ if Int.equal len 0 then [] else split 0
+
+module Self =
+struct
+ type t = string
+ let compare = compare
+end
+
+module Set = Set.Make(Self)
+module Map = CMap.Make(Self)
+
+module List = struct
+ type elt = string
+ let mem id l = List.exists (fun s -> equal id s) l
+ let assoc id l = CList.assoc_f equal id l
+ let remove_assoc id l = CList.remove_assoc_f equal id l
+ let mem_assoc id l = List.exists (fun (a,_) -> equal id a) l
+ let mem_assoc_sym id l = List.exists (fun (_,b) -> equal id b) l
+ let equal l l' = CList.equal equal l l'
+end
+
+let hcons = Hashcons.simple_hcons Hashcons.Hstring.generate Hashcons.Hstring.hcons ()
diff --git a/clib/cString.mli b/clib/cString.mli
new file mode 100644
index 00000000..2000dfaf
--- /dev/null
+++ b/clib/cString.mli
@@ -0,0 +1,80 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Module type [S] is the one from OCaml Stdlib. *)
+module type S = module type of String
+
+module type ExtS =
+sig
+ include S
+ (** We include the standard library *)
+
+ [@@@ocaml.warning "-3"] (* [@@noalloc] since 4.03.0 GPR#240 *)
+ external equal : string -> string -> bool = "caml_string_equal" "noalloc"
+ [@@@ocaml.warning "+3"]
+
+ (** Equality on strings *)
+
+ val hash : string -> int
+ (** Hashing on strings. Should be compatible with generic one. *)
+
+ val is_empty : string -> bool
+ (** Test whether a string is empty. *)
+
+ val explode : string -> string list
+ (** [explode "x1...xn"] returns [["x1"; ...; "xn"]] *)
+
+ val implode : string list -> string
+ (** [implode [s1; ...; sn]] returns [s1 ^ ... ^ sn] *)
+
+ val strip : string -> string
+ (** Remove the surrounding blank characters from a string *)
+
+ val drop_simple_quotes : string -> string
+ (** Remove the eventual first surrounding simple quotes of a string. *)
+
+ val string_index_from : string -> int -> string -> int
+ (** As [index_from], but takes a string instead of a char as pattern argument *)
+
+ val string_contains : where:string -> what:string -> bool
+ (** As [contains], but takes a string instead of a char as pattern argument *)
+
+ val plural : int -> string -> string
+ (** [plural n s] adds a optional 's' to the [s] when [2 <= n]. *)
+
+ val conjugate_verb_to_be : int -> string
+ (** [conjugate_verb_to_be] returns "is" when [n=1] and "are" otherwise *)
+
+ val ordinal : int -> string
+ (** Generate the ordinal number in English. *)
+
+ val split : char -> string -> string list
+ (** [split c s] splits [s] into sequences separated by [c], excluded. *)
+
+ val is_sub : string -> string -> int -> bool
+ (** [is_sub p s off] tests whether [s] contains [p] at offset [off]. *)
+
+ (** {6 Generic operations} **)
+
+ module Set : Set.S with type elt = t
+ (** Finite sets on [string] *)
+
+ module Map : CMap.ExtS with type key = t and module Set := Set
+ (** Finite maps on [string] *)
+
+ module List : CList.MonoS with type elt = t
+ (** Association lists with [string] as keys *)
+
+ val hcons : string -> string
+ (** Hashconsing on [string] *)
+
+end
+
+include ExtS
diff --git a/clib/cThread.ml b/clib/cThread.ml
new file mode 100644
index 00000000..0b7955aa
--- /dev/null
+++ b/clib/cThread.ml
@@ -0,0 +1,99 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type thread_ic = in_channel
+
+let prepare_in_channel_for_thread_friendly_io ic = ic
+
+let thread_friendly_read_fd fd s ~off ~len =
+ let rec loop () =
+ try Unix.read fd s off len
+ with Unix.Unix_error(Unix.EINTR,_,_) -> loop ()
+ in
+ loop ()
+
+let thread_friendly_read ic s ~off ~len =
+ try
+ let fd = Unix.descr_of_in_channel ic in
+ thread_friendly_read_fd fd s ~off ~len
+ with Unix.Unix_error _ -> 0
+
+let really_read_fd fd s off len =
+ let i = ref 0 in
+ while !i < len do
+ let off = off + !i in
+ let len = len - !i in
+ let r = thread_friendly_read_fd fd s ~off ~len in
+ if r = 0 then raise End_of_file;
+ i := !i + r
+ done
+
+let really_read_fd_2_oc fd oc len =
+ let i = ref 0 in
+ let size = 4096 in
+ let s = Bytes.create size in
+ while !i < len do
+ let len = len - !i in
+ let r = thread_friendly_read_fd fd s ~off:0 ~len:(min len size) in
+ if r = 0 then raise End_of_file;
+ i := !i + r;
+ output oc s 0 r;
+ done
+
+let thread_friendly_really_read ic s ~off ~len =
+ try
+ let fd = Unix.descr_of_in_channel ic in
+ really_read_fd fd s off len
+ with Unix.Unix_error _ -> raise End_of_file
+
+let thread_friendly_really_read_line ic =
+ try
+ let fd = Unix.descr_of_in_channel ic in
+ let b = Buffer.create 1024 in
+ let s = Bytes.make 1 '\000' in
+ let endl = Bytes.of_string "\n" in
+ (* Bytes.equal is in 4.03.0 *)
+ while Bytes.compare s endl <> 0 do
+ let n = thread_friendly_read_fd fd s ~off:0 ~len:1 in
+ if n = 0 then raise End_of_file;
+ if Bytes.compare s endl <> 0 then Buffer.add_bytes b s;
+ done;
+ Buffer.contents b
+ with Unix.Unix_error _ -> raise End_of_file
+
+let thread_friendly_input_value ic =
+ try
+ let fd = Unix.descr_of_in_channel ic in
+ let header = Bytes.create Marshal.header_size in
+ really_read_fd fd header 0 Marshal.header_size;
+ let body_size = Marshal.data_size header 0 in
+ let desired_size = body_size + Marshal.header_size in
+ if desired_size <= Sys.max_string_length then begin
+ let msg = Bytes.create desired_size in
+ Bytes.blit header 0 msg 0 Marshal.header_size;
+ really_read_fd fd msg Marshal.header_size body_size;
+ Marshal.from_bytes msg 0
+ end else begin
+ (* Workaround for 32 bit systems and data > 16M *)
+ let name, oc =
+ Filename.open_temp_file ~mode:[Open_binary] "coq" "marshal" in
+ try
+ output oc header 0 Marshal.header_size;
+ really_read_fd_2_oc fd oc body_size;
+ close_out oc;
+ let ic = open_in_bin name in
+ let data = Marshal.from_channel ic in
+ close_in ic;
+ Sys.remove name;
+ data
+ with e -> Sys.remove name; raise e
+ end
+ with Unix.Unix_error _ | Sys_error _ -> raise End_of_file
+
diff --git a/clib/cThread.mli b/clib/cThread.mli
new file mode 100644
index 00000000..acc5a60c
--- /dev/null
+++ b/clib/cThread.mli
@@ -0,0 +1,28 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* As of OCaml 4.01.0 input_value and input do not quite work well
+ * with threads. The symptom is the following. Two threads, each
+ * of them blocked on a read (on different channels). One is not
+ * woken up even if data is available. When the other one gets data
+ * then the stuck one is eventually unblocked too. Unix.select with
+ * an unbounded wait has the same problem. *)
+
+(* Use only the following functions on the channel *)
+type thread_ic
+val prepare_in_channel_for_thread_friendly_io : in_channel -> thread_ic
+
+val thread_friendly_input_value : thread_ic -> 'a
+val thread_friendly_read :
+ thread_ic -> Bytes.t -> off:int -> len:int -> int
+val thread_friendly_really_read :
+ thread_ic -> Bytes.t -> off:int -> len:int -> unit
+val thread_friendly_really_read_line : thread_ic -> string
+
diff --git a/clib/cUnix.ml b/clib/cUnix.ml
new file mode 100644
index 00000000..6b42e304
--- /dev/null
+++ b/clib/cUnix.ml
@@ -0,0 +1,146 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* Files and load path. *)
+
+type physical_path = string
+type load_path = physical_path list
+
+let physical_path_of_string s = s
+let string_of_physical_path p = p
+
+let escaped_string_of_physical_path p =
+ (* We assume a reasonable-enough path (typically utf8) and prevents
+ the presence of space; other escapings might be useful... *)
+ if String.contains p ' ' then "\"" ^ p ^ "\"" else p
+
+let path_to_list p =
+ let sep = Str.regexp (if Sys.os_type = "Win32" then ";" else ":") in
+ Str.split sep p
+
+(* Some static definitions concerning filenames *)
+
+let dirsep = Filename.dir_sep (* Unix: "/" *)
+let dirsep_len = String.length dirsep
+let curdir = Filename.concat Filename.current_dir_name "" (* Unix: "./" *)
+let curdir_len = String.length curdir
+
+(* Hints to partially detects if two paths refer to the same directory *)
+
+(** cut path [p] after all the [/] that come at position [pos]. *)
+let rec cut_after_dirsep p pos =
+ if CString.is_sub dirsep p pos then
+ cut_after_dirsep p (pos + dirsep_len)
+ else
+ String.sub p pos (String.length p - pos)
+
+(** remove all initial "./" in a path unless the path is exactly "./" *)
+let rec remove_path_dot p =
+ if CString.is_sub curdir p 0 then
+ if String.length p = curdir_len
+ then Filename.current_dir_name
+ else remove_path_dot (cut_after_dirsep p curdir_len)
+ else
+ p
+
+(** If a path [p] starts with the current directory $PWD then
+ [strip_path p] returns the sub-path relative to $PWD.
+ Any leading "./" are also removed from the result. *)
+let strip_path p =
+ let cwd = Filename.concat (Sys.getcwd ()) "" in (* Unix: "`pwd`/" *)
+ if CString.is_sub cwd p 0 then
+ remove_path_dot (cut_after_dirsep p (String.length cwd))
+ else
+ remove_path_dot p
+
+let canonical_path_name p =
+ let current = Sys.getcwd () in
+ try
+ Sys.chdir p;
+ let p' = Sys.getcwd () in
+ Sys.chdir current;
+ p'
+ with Sys_error _ ->
+ (* We give up to find a canonical name and just simplify it... *)
+ strip_path p
+
+let make_suffix name suffix =
+ if Filename.check_suffix name suffix then name else (name ^ suffix)
+
+let get_extension f =
+ let pos = try String.rindex f '.' with Not_found -> String.length f in
+ String.sub f pos (String.length f - pos)
+
+let correct_path f dir =
+ if Filename.is_relative f then Filename.concat dir f else f
+
+let file_readable_p name =
+ try Unix.access name [Unix.R_OK];true
+ with Unix.Unix_error (_, _, _) -> false
+
+(* As for [Unix.close_process], a [Unix.waipid] that ignores all [EINTR] *)
+
+let rec waitpid_non_intr pid =
+ try snd (Unix.waitpid [] pid)
+ with Unix.Unix_error (Unix.EINTR, _, _) -> waitpid_non_intr pid
+
+(** [run_command com] launches command [com] (via /bin/sh),
+ and returns the contents of stdout and stderr. If given, [~hook]
+ is called on each elements read on stdout or stderr. *)
+
+let run_command ?(hook=(fun _ ->())) c =
+ let result = Buffer.create 127 in
+ let cin,cout,cerr = Unix.open_process_full c (Unix.environment ()) in
+ let buff = Bytes.make 127 ' ' in
+ let buffe = Bytes.make 127 ' ' in
+ let n = ref 0 in
+ let ne = ref 0 in
+ while n:= input cin buff 0 127 ; ne := input cerr buffe 0 127 ;
+ !n+ !ne <> 0
+ do
+ let r = Bytes.sub buff 0 !n in (hook r; Buffer.add_bytes result r);
+ let r = Bytes.sub buffe 0 !ne in (hook r; Buffer.add_bytes result r);
+ done;
+ (Unix.close_process_full (cin,cout,cerr), Buffer.contents result)
+
+(** [sys_command] launches program [prog] with arguments [args].
+ It behaves like [Sys.command], except that we rely on
+ [Unix.create_process], it's hardly more complex and avoids dealing
+ with shells. In particular, no need to quote arguments
+ (against whitespace or other funny chars in paths), hence no need
+ to care about the different quoting conventions of /bin/sh and cmd.exe. *)
+
+let sys_command prog args =
+ let argv = Array.of_list (prog::args) in
+ let pid = Unix.create_process prog argv Unix.stdin Unix.stdout Unix.stderr in
+ waitpid_non_intr pid
+
+(*
+ checks if two file names refer to the same (existing) file by
+ comparing their device and inode.
+ It seems that under Windows, inode is always 0, so we cannot
+ accurately check if
+
+*)
+(* Optimised for partial application (in case many candidates must be
+ compared to f1). *)
+let same_file f1 =
+ try
+ let s1 = Unix.stat f1 in
+ (fun f2 ->
+ try
+ let s2 = Unix.stat f2 in
+ s1.Unix.st_dev = s2.Unix.st_dev &&
+ if Sys.os_type = "Win32" then f1 = f2
+ else s1.Unix.st_ino = s2.Unix.st_ino
+ with
+ Unix.Unix_error _ -> false)
+ with
+ Unix.Unix_error _ -> (fun _ -> false)
diff --git a/clib/cUnix.mli b/clib/cUnix.mli
new file mode 100644
index 00000000..1b185345
--- /dev/null
+++ b/clib/cUnix.mli
@@ -0,0 +1,71 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** {5 System utilities} *)
+
+type physical_path = string
+type load_path = physical_path list
+
+val physical_path_of_string : string -> physical_path
+val string_of_physical_path : physical_path -> string
+
+(** Escape what has to be escaped (e.g. surround with quotes if with spaces) *)
+val escaped_string_of_physical_path : physical_path -> string
+
+val canonical_path_name : string -> string
+
+(** Remove all initial "./" in a path *)
+val remove_path_dot : string -> string
+
+(** If a path [p] starts with the current directory $PWD then
+ [strip_path p] returns the sub-path relative to $PWD.
+ Any leading "./" are also removed from the result. *)
+val strip_path : string -> string
+
+(** correct_path f dir = dir/f if f is relative *)
+val correct_path : string -> string -> string
+
+val path_to_list : string -> string list
+
+(** [make_suffix file suf] catenate [file] with [suf] when
+ [file] does not already end with [suf]. *)
+val make_suffix : string -> string -> string
+
+(** Return the extension of a file, i.e. its smaller suffix starting
+ with "." if any, or "" otherwise. *)
+val get_extension : string -> string
+
+val file_readable_p : string -> bool
+
+(** {6 Executing commands } *)
+
+(** [run_command com] launches command [com], and returns
+ the contents of stdout and stderr. If given, [~hook]
+ is called on each elements read on stdout or stderr. *)
+
+val run_command :
+ ?hook:(bytes->unit) -> string -> Unix.process_status * string
+
+(** [sys_command] launches program [prog] with arguments [args].
+ It behaves like [Sys.command], except that we rely on
+ [Unix.create_process], it's hardly more complex and avoids dealing
+ with shells. In particular, no need to quote arguments
+ (against whitespace or other funny chars in paths), hence no need
+ to care about the different quoting conventions of /bin/sh and cmd.exe. *)
+
+val sys_command : string -> string list -> Unix.process_status
+
+(** A version of [Unix.waitpid] immune to EINTR exceptions *)
+
+val waitpid_non_intr : int -> Unix.process_status
+
+(** Check if two file names refer to the same (existing) file *)
+val same_file : string -> string -> bool
+
diff --git a/clib/canary.ml b/clib/canary.ml
new file mode 100644
index 00000000..b8b79ed7
--- /dev/null
+++ b/clib/canary.ml
@@ -0,0 +1,28 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type t = Obj.t
+
+let obj = Obj.new_block Obj.closure_tag 0
+ (** This is an empty closure block. In the current implementation, it is
+ sufficient to allow marshalling but forbid equality. Sadly still allows
+ hash. *)
+ (** FIXME : use custom blocks somehow. *)
+
+module type Obj = sig type t end
+
+module Make(M : Obj) =
+struct
+ type canary = t
+ type t = (canary * M.t)
+
+ let prj (_, x) = x
+ let inj x = (obj, x)
+end
diff --git a/clib/canary.mli b/clib/canary.mli
new file mode 100644
index 00000000..d993eabc
--- /dev/null
+++ b/clib/canary.mli
@@ -0,0 +1,27 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type t
+(** Type of canaries. Canaries are used to ensure that an object does not use
+ generic operations. *)
+
+val obj : t
+(** Canary. In the current implementation, this object is marshallable,
+ forbids generic comparison but still allows generic hashes. *)
+
+module type Obj = sig type t end
+
+module Make(M : Obj) :
+sig
+ type t
+ val prj : t -> M.t
+ val inj : M.t -> t
+end
+(** Adds a canary to any type. *)
diff --git a/clib/clib.mllib b/clib/clib.mllib
new file mode 100644
index 00000000..c9b4d72f
--- /dev/null
+++ b/clib/clib.mllib
@@ -0,0 +1,40 @@
+Canary
+CObj
+CEphemeron
+
+Hashset
+Hashcons
+
+OrderedType
+CSet
+CMap
+CList
+CString
+CStack
+
+Int
+Range
+HMap
+Bigint
+
+CArray
+Option
+CUnix
+
+Segmenttree
+Unicodetable
+Unicode
+Minisys
+CThread
+Trie
+Predicate
+Heap
+Unionfind
+
+Dyn
+Store
+Exninfo
+Backtrace
+IStream
+Terminal
+Monad
diff --git a/clib/dyn.ml b/clib/dyn.ml
new file mode 100644
index 00000000..e9b04198
--- /dev/null
+++ b/clib/dyn.ml
@@ -0,0 +1,161 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type TParam =
+sig
+ type 'a t
+end
+
+module type MapS =
+sig
+ type t
+ type 'a obj
+ type 'a key
+ val empty : t
+ val add : 'a key -> 'a obj -> t -> t
+ val remove : 'a key -> t -> t
+ val find : 'a key -> t -> 'a obj
+ val mem : 'a key -> t -> bool
+
+ type any = Any : 'a key * 'a obj -> any
+
+ type map = { map : 'a. 'a key -> 'a obj -> 'a obj }
+ val map : map -> t -> t
+
+ val iter : (any -> unit) -> t -> unit
+ val fold : (any -> 'r -> 'r) -> t -> 'r -> 'r
+end
+
+module type PreS =
+sig
+type 'a tag
+type t = Dyn : 'a tag * 'a -> t
+
+val create : string -> 'a tag
+val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
+val repr : 'a tag -> string
+
+type any = Any : 'a tag -> any
+
+val name : string -> any option
+
+module Map(M : TParam) : MapS with type 'a obj = 'a M.t with type 'a key = 'a tag
+
+val dump : unit -> (int * string) list
+
+end
+
+module type S =
+sig
+ include PreS
+
+ module Easy : sig
+
+ val make_dyn_tag : string -> ('a -> t) * (t -> 'a) * 'a tag
+ val make_dyn : string -> ('a -> t) * (t -> 'a)
+ val inj : 'a -> 'a tag -> t
+ val prj : t -> 'a tag -> 'a option
+ end
+
+end
+
+module Make () = struct
+module Self : PreS = struct
+(* Dynamics, programmed with DANGER !!! *)
+
+type 'a tag = int
+
+type t = Dyn : 'a tag * 'a -> t
+
+type any = Any : 'a tag -> any
+
+let dyntab = ref (Int.Map.empty : string Int.Map.t)
+(** Instead of working with tags as strings, which are costly, we use their
+ hash. We ensure unicity of the hash in the [create] function. If ever a
+ collision occurs, which is unlikely, it is sufficient to tweak the offending
+ dynamic tag. *)
+
+let create (s : string) =
+ let hash = Hashtbl.hash s in
+ let () =
+ if Int.Map.mem hash !dyntab then
+ let old = Int.Map.find hash !dyntab in
+ let () = Printf.eprintf "Dynamic tag collision: %s vs. %s\n%!" s old in
+ assert false
+ in
+ let () = dyntab := Int.Map.add hash s !dyntab in
+ hash
+
+let eq : 'a 'b. 'a tag -> 'b tag -> ('a, 'b) CSig.eq option =
+ fun h1 h2 -> if Int.equal h1 h2 then Some (Obj.magic CSig.Refl) else None
+
+let repr s =
+ try Int.Map.find s !dyntab
+ with Not_found ->
+ let () = Printf.eprintf "Unknown dynamic tag %i\n%!" s in
+ assert false
+
+let name s =
+ let hash = Hashtbl.hash s in
+ if Int.Map.mem hash !dyntab then Some (Any hash) else None
+
+let dump () = Int.Map.bindings !dyntab
+
+module Map(M : TParam) =
+struct
+type t = Obj.t M.t Int.Map.t
+type 'a obj = 'a M.t
+type 'a key = 'a tag
+let cast : 'a M.t -> 'b M.t = Obj.magic
+let empty = Int.Map.empty
+let add tag v m = Int.Map.add tag (cast v) m
+let remove tag m = Int.Map.remove tag m
+let find tag m = cast (Int.Map.find tag m)
+let mem = Int.Map.mem
+
+type any = Any : 'a tag * 'a M.t -> any
+
+type map = { map : 'a. 'a tag -> 'a M.t -> 'a M.t }
+let map f m = Int.Map.mapi f.map m
+
+let iter f m = Int.Map.iter (fun k v -> f (Any (k, v))) m
+let fold f m accu = Int.Map.fold (fun k v accu -> f (Any (k, v)) accu) m accu
+end
+
+end
+include Self
+
+module Easy = struct
+
+(* now tags are opaque, we can do the trick *)
+let make_dyn_tag (s : string) =
+ (fun (type a) (tag : a tag) ->
+ let infun : (a -> t) = fun x -> Dyn (tag, x) in
+ let outfun : (t -> a) = fun (Dyn (t, x)) ->
+ match eq tag t with
+ | None -> assert false
+ | Some CSig.Refl -> x
+ in
+ infun, outfun, tag)
+ (create s)
+
+let make_dyn (s : string) =
+ let inf, outf, _ = make_dyn_tag s in inf, outf
+
+let inj x tag = Dyn(tag,x)
+let prj : type a. t -> a tag -> a option =
+ fun (Dyn(tag',x)) tag ->
+ match eq tag tag' with
+ | None -> None
+ | Some CSig.Refl -> Some x
+end
+
+end
+
diff --git a/clib/dyn.mli b/clib/dyn.mli
new file mode 100644
index 00000000..51d30914
--- /dev/null
+++ b/clib/dyn.mli
@@ -0,0 +1,68 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Dynamically typed values *)
+
+module type TParam =
+sig
+ type 'a t
+end
+
+module type MapS =
+sig
+ type t
+ type 'a obj
+ type 'a key
+ val empty : t
+ val add : 'a key -> 'a obj -> t -> t
+ val remove : 'a key -> t -> t
+ val find : 'a key -> t -> 'a obj
+ val mem : 'a key -> t -> bool
+
+ type any = Any : 'a key * 'a obj -> any
+
+ type map = { map : 'a. 'a key -> 'a obj -> 'a obj }
+ val map : map -> t -> t
+
+ val iter : (any -> unit) -> t -> unit
+ val fold : (any -> 'r -> 'r) -> t -> 'r -> 'r
+end
+
+module type S =
+sig
+type 'a tag
+type t = Dyn : 'a tag * 'a -> t
+
+val create : string -> 'a tag
+val eq : 'a tag -> 'b tag -> ('a, 'b) CSig.eq option
+val repr : 'a tag -> string
+
+type any = Any : 'a tag -> any
+
+val name : string -> any option
+
+module Map(M : TParam) : MapS with type 'a obj = 'a M.t with type 'a key = 'a tag
+
+val dump : unit -> (int * string) list
+
+module Easy : sig
+
+ (* To create a dynamic type on the fly *)
+ val make_dyn_tag : string -> ('a -> t) * (t -> 'a) * 'a tag
+ val make_dyn : string -> ('a -> t) * (t -> 'a)
+
+ (* For types declared with the [create] function above *)
+ val inj : 'a -> 'a tag -> t
+ val prj : t -> 'a tag -> 'a option
+end
+
+end
+
+module Make () : S
diff --git a/clib/exninfo.ml b/clib/exninfo.ml
new file mode 100644
index 00000000..2d130498
--- /dev/null
+++ b/clib/exninfo.ml
@@ -0,0 +1,106 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Enriched exceptions have an additional field at the end of their usual data
+ containing a pair composed of the distinguishing [token] and the backtrace
+ information. We discriminate the token by pointer equality. *)
+
+module Store = Store.Make ()
+
+type 'a t = 'a Store.field
+
+type info = Store.t
+
+type iexn = exn * info
+
+let make = Store.field
+let add = Store.set
+let get = Store.get
+let null = Store.empty
+
+exception Unique
+
+let dummy = (Unique, Store.empty)
+
+let current : (int * iexn) list ref = ref []
+(** List associating to each thread id the latest exception raised by an
+ instrumented raise (i.e. {!raise} from this module). It is shared between
+ threads, so we must take care of this when modifying it.
+
+ Invariants: all index keys are unique in the list.
+*)
+
+let lock = Mutex.create ()
+
+let rec remove_assoc (i : int) = function
+| [] -> []
+| (j, v) :: rem as l ->
+ if i = j then rem
+ else
+ let ans = remove_assoc i rem in
+ if rem == ans then l
+ else (j, v) :: ans
+
+let rec find_and_remove_assoc (i : int) = function
+| [] -> dummy, []
+| (j, v) :: rem as l ->
+ if i = j then (v, rem)
+ else
+ let (r, ans) = find_and_remove_assoc i rem in
+ if rem == ans then (r, l)
+ else (r, (j, v) :: ans)
+
+let iraise e =
+ let () = Mutex.lock lock in
+ let id = Thread.id (Thread.self ()) in
+ let () = current := (id, e) :: remove_assoc id !current in
+ let () = Mutex.unlock lock in
+ raise (fst e)
+
+let raise ?info e = match info with
+| None ->
+ let () = Mutex.lock lock in
+ let id = Thread.id (Thread.self ()) in
+ let () = current := remove_assoc id !current in
+ let () = Mutex.unlock lock in
+ raise e
+| Some i ->
+ let () = Mutex.lock lock in
+ let id = Thread.id (Thread.self ()) in
+ let () = current := (id, (e, i)) :: remove_assoc id !current in
+ let () = Mutex.unlock lock in
+ raise e
+
+let find_and_remove () =
+ let () = Mutex.lock lock in
+ let id = Thread.id (Thread.self ()) in
+ let (v, l) = find_and_remove_assoc id !current in
+ let () = current := l in
+ let () = Mutex.unlock lock in
+ v
+
+let info e =
+ let (src, data) = find_and_remove () in
+ if src == e then
+ (** Slightly unsound, some exceptions may not be unique up to pointer
+ equality. Though, it should be quite exceptional to be in a situation
+ where the following holds:
+
+ 1. An argument-free exception is raised through the enriched {!raise};
+ 2. It is not captured by any enriched with-clause (which would reset
+ the current data);
+ 3. The same exception is raised through the standard raise, accessing
+ the wrong data.
+ . *)
+ data
+ else
+ (** Mismatch: the raised exception is not the one stored, either because the
+ previous raise was not instrumented, or because something went wrong. *)
+ Store.empty
diff --git a/clib/exninfo.mli b/clib/exninfo.mli
new file mode 100644
index 00000000..4a5a6095
--- /dev/null
+++ b/clib/exninfo.mli
@@ -0,0 +1,41 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Additional information worn by exceptions. *)
+
+type 'a t
+(** Information containing a given type. *)
+
+type info
+(** All information *)
+
+type iexn = exn * info
+(** Information-wearing exceptions *)
+
+val make : unit -> 'a t
+(** Create a new piece of information. *)
+
+val null : info
+(** No information *)
+
+val add : info -> 'a t -> 'a -> info
+(** Add information to an exception. *)
+
+val get : info -> 'a t -> 'a option
+(** Get information worn by an exception. Returns [None] if undefined. *)
+
+val info : exn -> info
+(** Retrieve the information of the last exception raised. *)
+
+val iraise : iexn -> 'a
+(** Raise the given enriched exception. *)
+
+val raise : ?info:info -> exn -> 'a
+(** Raise the given exception with additional information. *)
diff --git a/clib/hMap.ml b/clib/hMap.ml
new file mode 100644
index 00000000..37f867c6
--- /dev/null
+++ b/clib/hMap.ml
@@ -0,0 +1,416 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type HashedType =
+sig
+ type t
+ val compare : t -> t -> int
+ val hash : t -> int
+end
+
+module SetMake(M : HashedType) =
+struct
+ (** Hash Sets use hashes to prevent doing too many comparison tests. They
+ associate to each hash the set of keys having that hash.
+
+ Invariants:
+
+ 1. There is no empty set in the intmap.
+ 2. All values in the same set have the same hash, which is the int to
+ which it is associated in the intmap.
+ *)
+
+ module Set = Set.Make(M)
+
+ type elt = M.t
+
+ type t = Set.t Int.Map.t
+
+ let empty = Int.Map.empty
+
+ let is_empty = Int.Map.is_empty
+
+ let mem x s =
+ let h = M.hash x in
+ try
+ let m = Int.Map.find h s in
+ Set.mem x m
+ with Not_found -> false
+
+ let add x s =
+ let h = M.hash x in
+ try
+ let m = Int.Map.find h s in
+ let m = Set.add x m in
+ Int.Map.set h m s
+ with Not_found ->
+ let m = Set.singleton x in
+ Int.Map.add h m s
+
+ let singleton x =
+ let h = M.hash x in
+ let m = Set.singleton x in
+ Int.Map.singleton h m
+
+ let remove x s =
+ let h = M.hash x in
+ try
+ let m = Int.Map.find h s in
+ let m = Set.remove x m in
+ if Set.is_empty m then
+ Int.Map.remove h s
+ else
+ Int.Map.set h m s
+ with Not_found -> s
+
+ let height s = Int.Map.height s
+
+ let is_smaller s1 s2 = height s1 <= height s2 + 3
+
+ (** Assumes s1 << s2 *)
+ let fast_union s1 s2 =
+ let fold h s accu =
+ try Int.Map.modify h (fun _ s' -> Set.fold Set.add s s') accu
+ with Not_found -> Int.Map.add h s accu
+ in
+ Int.Map.fold fold s1 s2
+
+ let union s1 s2 =
+ if is_smaller s1 s2 then fast_union s1 s2
+ else if is_smaller s2 s1 then fast_union s2 s1
+ else
+ let fu _ m1 m2 = match m1, m2 with
+ | None, None -> None
+ | (Some _ as m), None | None, (Some _ as m) -> m
+ | Some m1, Some m2 -> Some (Set.union m1 m2)
+ in
+ Int.Map.merge fu s1 s2
+
+ (** Assumes s1 << s2 *)
+ let fast_inter s1 s2 =
+ let fold h s accu =
+ try
+ let s' = Int.Map.find h s2 in
+ let si = Set.filter (fun e -> Set.mem e s') s in
+ if Set.is_empty si then accu
+ else Int.Map.add h si accu
+ with Not_found -> accu
+ in
+ Int.Map.fold fold s1 Int.Map.empty
+
+ let inter s1 s2 =
+ if is_smaller s1 s2 then fast_inter s1 s2
+ else if is_smaller s2 s1 then fast_inter s2 s1
+ else
+ let fu _ m1 m2 = match m1, m2 with
+ | None, None -> None
+ | Some _, None | None, Some _ -> None
+ | Some m1, Some m2 ->
+ let m = Set.inter m1 m2 in
+ if Set.is_empty m then None else Some m
+ in
+ Int.Map.merge fu s1 s2
+
+ (** Assumes s1 << s2 *)
+ let fast_diff_l s1 s2 =
+ let fold h s accu =
+ try
+ let s' = Int.Map.find h s2 in
+ let si = Set.filter (fun e -> not (Set.mem e s')) s in
+ if Set.is_empty si then accu
+ else Int.Map.add h si accu
+ with Not_found -> Int.Map.add h s accu
+ in
+ Int.Map.fold fold s1 Int.Map.empty
+
+ (** Assumes s2 << s1 *)
+ let fast_diff_r s1 s2 =
+ let fold h s accu =
+ try
+ let s' = Int.Map.find h accu in
+ let si = Set.filter (fun e -> not (Set.mem e s)) s' in
+ if Set.is_empty si then Int.Map.remove h accu
+ else Int.Map.set h si accu
+ with Not_found -> accu
+ in
+ Int.Map.fold fold s2 s1
+
+ let diff s1 s2 =
+ if is_smaller s1 s2 then fast_diff_l s1 s2
+ else if is_smaller s2 s2 then fast_diff_r s1 s2
+ else
+ let fu _ m1 m2 = match m1, m2 with
+ | None, None -> None
+ | (Some _ as m), None -> m
+ | None, Some _ -> None
+ | Some m1, Some m2 ->
+ let m = Set.diff m1 m2 in
+ if Set.is_empty m then None else Some m
+ in
+ Int.Map.merge fu s1 s2
+
+ let compare s1 s2 = Int.Map.compare Set.compare s1 s2
+
+ let equal s1 s2 = Int.Map.equal Set.equal s1 s2
+
+ let subset s1 s2 =
+ let check h m1 =
+ let m2 = try Int.Map.find h s2 with Not_found -> Set.empty in
+ Set.subset m1 m2
+ in
+ Int.Map.for_all check s1
+
+ let iter f s =
+ let fi _ m = Set.iter f m in
+ Int.Map.iter fi s
+
+ let fold f s accu =
+ let ff _ m accu = Set.fold f m accu in
+ Int.Map.fold ff s accu
+
+ let for_all f s =
+ let ff _ m = Set.for_all f m in
+ Int.Map.for_all ff s
+
+ let exists f s =
+ let fe _ m = Set.exists f m in
+ Int.Map.exists fe s
+
+ let filter f s =
+ let ff m = Set.filter f m in
+ let s = Int.Map.map ff s in
+ Int.Map.filter (fun _ m -> not (Set.is_empty m)) s
+
+ let partition f s =
+ let fold h m (sl, sr) =
+ let (ml, mr) = Set.partition f m in
+ let sl = if Set.is_empty ml then sl else Int.Map.add h ml sl in
+ let sr = if Set.is_empty mr then sr else Int.Map.add h mr sr in
+ (sl, sr)
+ in
+ Int.Map.fold fold s (Int.Map.empty, Int.Map.empty)
+
+ let cardinal s =
+ let fold _ m accu = accu + Set.cardinal m in
+ Int.Map.fold fold s 0
+
+ let elements s =
+ let fold _ m accu = Set.fold (fun x accu -> x :: accu) m accu in
+ Int.Map.fold fold s []
+
+ let min_elt _ = assert false (** Cannot be implemented efficiently *)
+
+ let max_elt _ = assert false (** Cannot be implemented efficiently *)
+
+ let choose s =
+ let (_, m) = Int.Map.choose s in
+ Set.choose m
+
+ let split s x = assert false (** Cannot be implemented efficiently *)
+
+end
+
+module Make(M : HashedType) =
+struct
+ (** This module is essentially the same as SetMake, except that we have maps
+ instead of sets in the intmap. Invariants are the same. *)
+ module Set = SetMake(M)
+ module Map = CMap.Make(M)
+
+ type key = M.t
+
+ type 'a t = 'a Map.t Int.Map.t
+
+ let empty = Int.Map.empty
+
+ let is_empty = Int.Map.is_empty
+
+ let mem k s =
+ let h = M.hash k in
+ try
+ let m = Int.Map.find h s in
+ Map.mem k m
+ with Not_found -> false
+
+ let add k x s =
+ let h = M.hash k in
+ try
+ let m = Int.Map.find h s in
+ let m = Map.add k x m in
+ Int.Map.set h m s
+ with Not_found ->
+ let m = Map.singleton k x in
+ Int.Map.add h m s
+
+ (* when Coq requires OCaml 4.06 or later, the module type
+ CSig.MapS may include the signature of OCaml's "update",
+ requiring an implementation here, which could be just:
+
+ let update k f s = assert false (* not implemented *)
+
+ *)
+
+ let singleton k x =
+ let h = M.hash k in
+ Int.Map.singleton h (Map.singleton k x)
+
+ let remove k s =
+ let h = M.hash k in
+ try
+ let m = Int.Map.find h s in
+ let m = Map.remove k m in
+ if Map.is_empty m then
+ Int.Map.remove h s
+ else
+ Int.Map.set h m s
+ with Not_found -> s
+
+ let merge f s1 s2 =
+ let fm h m1 m2 = match m1, m2 with
+ | None, None -> None
+ | Some m, None ->
+ let m = Map.merge f m Map.empty in
+ if Map.is_empty m then None
+ else Some m
+ | None, Some m ->
+ let m = Map.merge f Map.empty m in
+ if Map.is_empty m then None
+ else Some m
+ | Some m1, Some m2 ->
+ let m = Map.merge f m1 m2 in
+ if Map.is_empty m then None
+ else Some m
+ in
+ Int.Map.merge fm s1 s2
+
+ let compare f s1 s2 =
+ let fc m1 m2 = Map.compare f m1 m2 in
+ Int.Map.compare fc s1 s2
+
+ let equal f s1 s2 =
+ let fe m1 m2 = Map.equal f m1 m2 in
+ Int.Map.equal fe s1 s2
+
+ let iter f s =
+ let fi _ m = Map.iter f m in
+ Int.Map.iter fi s
+
+ let fold f s accu =
+ let ff _ m accu = Map.fold f m accu in
+ Int.Map.fold ff s accu
+
+ let for_all f s =
+ let ff _ m = Map.for_all f m in
+ Int.Map.for_all ff s
+
+ let exists f s =
+ let fe _ m = Map.exists f m in
+ Int.Map.exists fe s
+
+ let filter f s =
+ let ff m = Map.filter f m in
+ let s = Int.Map.map ff s in
+ Int.Map.filter (fun _ m -> not (Map.is_empty m)) s
+
+ let partition f s =
+ let fold h m (sl, sr) =
+ let (ml, mr) = Map.partition f m in
+ let sl = if Map.is_empty ml then sl else Int.Map.add h ml sl in
+ let sr = if Map.is_empty mr then sr else Int.Map.add h mr sr in
+ (sl, sr)
+ in
+ Int.Map.fold fold s (Int.Map.empty, Int.Map.empty)
+
+ let cardinal s =
+ let fold _ m accu = accu + Map.cardinal m in
+ Int.Map.fold fold s 0
+
+ let bindings s =
+ let fold _ m accu = Map.fold (fun k x accu -> (k, x) :: accu) m accu in
+ Int.Map.fold fold s []
+
+ let min_binding _ = assert false (** Cannot be implemented efficiently *)
+
+ let max_binding _ = assert false (** Cannot be implemented efficiently *)
+
+ let fold_left _ _ _ = assert false (** Cannot be implemented efficiently *)
+
+ let fold_right _ _ _ = assert false (** Cannot be implemented efficiently *)
+
+ let choose s =
+ let (_, m) = Int.Map.choose s in
+ Map.choose m
+
+ let find k s =
+ let h = M.hash k in
+ let m = Int.Map.find h s in
+ Map.find k m
+
+ let get k s = try find k s with Not_found -> assert false
+
+ let split k s = assert false (** Cannot be implemented efficiently *)
+
+ let map f s =
+ let fs m = Map.map f m in
+ Int.Map.map fs s
+
+ let mapi f s =
+ let fs m = Map.mapi f m in
+ Int.Map.map fs s
+
+ let modify k f s =
+ let h = M.hash k in
+ let m = Int.Map.find h s in
+ let m = Map.modify k f m in
+ Int.Map.set h m s
+
+ let bind f s =
+ let fb m = Map.bind f m in
+ Int.Map.map fb s
+
+ let domain s = Int.Map.map Map.domain s
+
+ let set k x s =
+ let h = M.hash k in
+ let m = Int.Map.find h s in
+ let m = Map.set k x m in
+ Int.Map.set h m s
+
+ let smartmap f s =
+ let fs m = Map.smartmap f m in
+ Int.Map.smartmap fs s
+
+ let smartmapi f s =
+ let fs m = Map.smartmapi f m in
+ Int.Map.smartmap fs s
+
+ let height s = Int.Map.height s
+
+ module Unsafe =
+ struct
+ let map f s =
+ let fs m = Map.Unsafe.map f m in
+ Int.Map.map fs s
+ end
+
+ module Monad(M : CMap.MonadS) =
+ struct
+ module IntM = Int.Map.Monad(M)
+ module ExtM = Map.Monad(M)
+
+ let fold f s accu =
+ let ff _ m accu = ExtM.fold f m accu in
+ IntM.fold ff s accu
+
+ let fold_left _ _ _ = assert false
+ let fold_right _ _ _ = assert false
+ end
+
+end
diff --git a/clib/hMap.mli b/clib/hMap.mli
new file mode 100644
index 00000000..b26d0e04
--- /dev/null
+++ b/clib/hMap.mli
@@ -0,0 +1,30 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type HashedType =
+sig
+ type t
+ val compare : t -> t -> int
+ (** Total ordering *)
+ val hash : t -> int
+ (** Hashing function compatible with [compare], i.e. [compare x y = 0] implies
+ [hash x = hash y]. *)
+end
+
+(** Hash maps are maps that take advantage of having a hash on keys. This is
+ essentially a hash table, except that it uses purely functional maps instead
+ of arrays.
+
+ CAVEAT: order-related functions like [fold] or [iter] do not respect the
+ provided order anymore! It's your duty to do something sensible to prevent
+ this if you need it. In particular, [min_binding] and [max_binding] are now
+ made meaningless.
+*)
+module Make(M : HashedType) : CMap.ExtS with type key = M.t
diff --git a/clib/hashcons.ml b/clib/hashcons.ml
new file mode 100644
index 00000000..ec73c6d9
--- /dev/null
+++ b/clib/hashcons.ml
@@ -0,0 +1,188 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(* Hash consing of datastructures *)
+
+(* The generic hash-consing functions (does not use Obj) *)
+
+(* [t] is the type of object to hash-cons
+ * [u] is the type of hash-cons functions for the sub-structures
+ * of objects of type t (u usually has the form (t1->t1)*(t2->t2)*...).
+ * [hashcons u x] is a function that hash-cons the sub-structures of x using
+ * the hash-consing functions u provides.
+ * [eq] is a comparison function. It is allowed to use physical equality
+ * on the sub-terms hash-consed by the hashcons function.
+ * [hash] is the hash function given to the Hashtbl.Make function
+ *
+ * Note that this module type coerces to the argument of Hashtbl.Make.
+ *)
+
+module type HashconsedType =
+ sig
+ type t
+ type u
+ val hashcons : u -> t -> t
+ val eq : t -> t -> bool
+ val hash : t -> int
+ end
+
+(** The output is a function [generate] such that [generate args] creates a
+ hash-table of the hash-consed objects, together with [hcons], a function
+ taking a table and an object, and hashcons it. For simplicity of use, we use
+ the wrapper functions defined below. *)
+
+module type S =
+ sig
+ type t
+ type u
+ type table
+ val generate : u -> table
+ val hcons : table -> t -> t
+ val stats : table -> Hashset.statistics
+ end
+
+module Make (X : HashconsedType) : (S with type t = X.t and type u = X.u) =
+ struct
+ type t = X.t
+ type u = X.u
+
+ (* We create the type of hashtables for t, with our comparison fun.
+ * An invariant is that the table never contains two entries equals
+ * w.r.t (=), although the equality on keys is X.eq. This is
+ * granted since we hcons the subterms before looking up in the table.
+ *)
+ module Htbl = Hashset.Make(X)
+
+ type table = (Htbl.t * u)
+
+ let generate u =
+ let tab = Htbl.create 97 in
+ (tab, u)
+
+ let hcons (tab, u) x =
+ let y = X.hashcons u x in
+ Htbl.repr (X.hash y) y tab
+
+ let stats (tab, _) = Htbl.stats tab
+
+ end
+
+(* A few useful wrappers:
+ * takes as argument the function [generate] above and build a function of type
+ * u -> t -> t that creates a fresh table each time it is applied to the
+ * sub-hcons functions. *)
+
+(* For non-recursive types it is quite easy. *)
+let simple_hcons h f u =
+ let table = h u in
+ fun x -> f table x
+
+(* For a recursive type T, we write the module of sig Comp with u equals
+ * to (T -> T) * u0
+ * The first component will be used to hash-cons the recursive subterms
+ * The second one to hashcons the other sub-structures.
+ * We just have to take the fixpoint of h
+ *)
+let recursive_hcons h f u =
+ let loop = ref (fun _ -> assert false) in
+ let self x = !loop x in
+ let table = h (self, u) in
+ let hrec x = f table x in
+ let () = loop := hrec in
+ hrec
+
+(* Basic hashcons modules for string and obj. Integers do not need be
+ hashconsed. *)
+
+module type HashedType = sig type t val hash : t -> int end
+
+(* list *)
+module Hlist (D:HashedType) =
+ Make(
+ struct
+ type t = D.t list
+ type u = (t -> t) * (D.t -> D.t)
+ let hashcons (hrec,hdata) = function
+ | x :: l -> hdata x :: hrec l
+ | l -> l
+ let eq l1 l2 =
+ l1 == l2 ||
+ match l1, l2 with
+ | [], [] -> true
+ | x1::l1, x2::l2 -> x1==x2 && l1==l2
+ | _ -> false
+ let rec hash accu = function
+ | [] -> accu
+ | x :: l ->
+ let accu = Hashset.Combine.combine (D.hash x) accu in
+ hash accu l
+ let hash l = hash 0 l
+ end)
+
+(* string *)
+module Hstring = Make(
+ struct
+ type t = string
+ type u = unit
+ let hashcons () s =(* incr accesstr;*) s
+
+ [@@@ocaml.warning "-3"] (* [@@noalloc] since 4.03.0 GPR#240 *)
+ external eq : string -> string -> bool = "caml_string_equal" "noalloc"
+ [@@@ocaml.warning "+3"]
+
+ (** Copy from CString *)
+ let rec hash len s i accu =
+ if i = len then accu
+ else
+ let c = Char.code (String.unsafe_get s i) in
+ hash len s (succ i) (accu * 19 + c)
+
+ let hash s =
+ let len = String.length s in
+ hash len s 0 0
+ end)
+
+(* Obj.t *)
+exception NotEq
+
+(* From CAMLLIB/caml/mlvalues.h *)
+let no_scan_tag = 251
+let tuple_p obj = Obj.is_block obj && (Obj.tag obj < no_scan_tag)
+
+let comp_obj o1 o2 =
+ if tuple_p o1 && tuple_p o2 then
+ let n1 = Obj.size o1 and n2 = Obj.size o2 in
+ if n1=n2 then
+ try
+ for i = 0 to pred n1 do
+ if not (Obj.field o1 i == Obj.field o2 i) then raise NotEq
+ done; true
+ with NotEq -> false
+ else false
+ else o1=o2
+
+let hash_obj hrec o =
+ begin
+ if tuple_p o then
+ let n = Obj.size o in
+ for i = 0 to pred n do
+ Obj.set_field o i (hrec (Obj.field o i))
+ done
+ end;
+ o
+
+module Hobj = Make(
+ struct
+ type t = Obj.t
+ type u = (Obj.t -> Obj.t) * unit
+ let hashcons (hrec,_) = hash_obj hrec
+ let eq = comp_obj
+ let hash = Hashtbl.hash
+ end)
diff --git a/clib/hashcons.mli b/clib/hashcons.mli
new file mode 100644
index 00000000..3e396ff2
--- /dev/null
+++ b/clib/hashcons.mli
@@ -0,0 +1,92 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Generic hash-consing. *)
+
+(** {6 Hashconsing functorial interface} *)
+
+module type HashconsedType =
+ sig
+ (** {6 Generic hashconsing signature}
+
+ Given an equivalence relation [eq], a hashconsing function is a
+ function that associates the same canonical element to two elements
+ related by [eq]. Usually, the element chosen is canonical w.r.t.
+ physical equality [(==)], so as to reduce memory consumption and
+ enhance efficiency of equality tests.
+
+ In order to ensure canonicality, we need a way to remember the element
+ associated to a class of equivalence; this is done using the table type
+ generated by the [Make] functor.
+ *)
+
+ type t
+ (** Type of objects to hashcons. *)
+ type u
+ (** Type of hashcons functions for the sub-structures contained in [t].
+ Usually a tuple of functions. *)
+ val hashcons : u -> t -> t
+ (** The actual hashconsing function, using its fist argument to recursively
+ hashcons substructures. It should be compatible with [eq], that is
+ [eq x (hashcons f x) = true]. *)
+ val eq : t -> t -> bool
+ (** A comparison function. It is allowed to use physical equality
+ on the sub-terms hashconsed by the [hashcons] function, but it should be
+ insensible to shallow copy of the compared object. *)
+ val hash : t -> int
+ (** A hash function passed to the underlying hashtable structure. [hash]
+ should be compatible with [eq], i.e. if [eq x y = true] then
+ [hash x = hash y]. *)
+ end
+
+module type S =
+ sig
+ type t
+ (** Type of objects to hashcons. *)
+ type u
+ (** Type of hashcons functions for the sub-structures contained in [t]. *)
+ type table
+ (** Type of hashconsing tables *)
+ val generate : u -> table
+ (** This create a hashtable of the hashconsed objects. *)
+ val hcons : table -> t -> t
+ (** Perform the hashconsing of the given object within the table. *)
+ val stats : table -> Hashset.statistics
+ (** Recover statistics of the hashconsing table. *)
+ end
+
+module Make (X : HashconsedType) : (S with type t = X.t and type u = X.u)
+(** Create a new hashconsing, given canonicalization functions. *)
+
+(** {6 Wrappers} *)
+
+(** These are intended to be used together with instances of the [Make]
+ functor. *)
+
+val simple_hcons : ('u -> 'tab) -> ('tab -> 't -> 't) -> 'u -> 't -> 't
+(** [simple_hcons f sub obj] creates a new table each time it is applied to any
+ sub-hash function [sub]. *)
+
+val recursive_hcons : (('t -> 't) * 'u -> 'tab) -> ('tab -> 't -> 't) -> ('u -> 't -> 't)
+(** As [simple_hcons] but intended to be used with well-founded data structures. *)
+
+(** {6 Hashconsing of usual structures} *)
+
+module type HashedType = sig type t val hash : t -> int end
+
+module Hstring : (S with type t = string and type u = unit)
+(** Hashconsing of strings. *)
+
+module Hlist (D:HashedType) :
+ (S with type t = D.t list and type u = (D.t list -> D.t list)*(D.t->D.t))
+(** Hashconsing of lists. *)
+
+module Hobj : (S with type t = Obj.t and type u = (Obj.t -> Obj.t) * unit)
+(** Hashconsing of OCaml values. *)
diff --git a/clib/hashset.ml b/clib/hashset.ml
new file mode 100644
index 00000000..965cb67c
--- /dev/null
+++ b/clib/hashset.ml
@@ -0,0 +1,231 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Adapted from Damien Doligez, projet Para, INRIA Rocquencourt,
+ OCaml stdlib. *)
+
+(** The following functor is a specialized version of [Weak.Make].
+ Here, the responsibility of computing the hash function is now
+ given to the caller, which makes possible the interleaving of the
+ hash key computation and the hash-consing. *)
+
+module type EqType = sig
+ type t
+ val eq : t -> t -> bool
+end
+
+type statistics = {
+ num_bindings: int;
+ num_buckets: int;
+ max_bucket_length: int;
+ bucket_histogram: int array
+}
+
+module type S = sig
+ type elt
+ type t
+ val create : int -> t
+ val clear : t -> unit
+ val repr : int -> elt -> t -> elt
+ val stats : t -> statistics
+end
+
+module Make (E : EqType) =
+ struct
+
+ type elt = E.t
+
+ let emptybucket = Weak.create 0
+
+ type t = {
+ mutable table : elt Weak.t array;
+ mutable hashes : int array array;
+ mutable limit : int; (* bucket size limit *)
+ mutable oversize : int; (* number of oversize buckets *)
+ mutable rover : int; (* for internal bookkeeping *)
+ }
+
+ let get_index t h = (h land max_int) mod (Array.length t.table)
+
+ let limit = 7
+ let over_limit = 2
+
+ let create sz =
+ let sz = if sz < 7 then 7 else sz in
+ let sz = if sz > Sys.max_array_length then Sys.max_array_length else sz in
+ {
+ table = Array.make sz emptybucket;
+ hashes = Array.make sz [| |];
+ limit = limit;
+ oversize = 0;
+ rover = 0;
+ }
+
+ let clear t =
+ for i = 0 to Array.length t.table - 1 do
+ t.table.(i) <- emptybucket;
+ t.hashes.(i) <- [| |];
+ done;
+ t.limit <- limit;
+ t.oversize <- 0
+
+ let iter_weak f t =
+ let rec iter_bucket i j b =
+ if i >= Weak.length b then () else
+ match Weak.check b i with
+ | true -> f b t.hashes.(j) i; iter_bucket (i+1) j b
+ | false -> iter_bucket (i+1) j b
+ in
+ for i = 0 to pred (Array.length t.table) do
+ iter_bucket 0 i (Array.unsafe_get t.table i)
+ done
+
+ let rec count_bucket i b accu =
+ if i >= Weak.length b then accu else
+ count_bucket (i+1) b (accu + (if Weak.check b i then 1 else 0))
+
+ let min x y = if x - y < 0 then x else y
+
+ let next_sz n = min (3 * n / 2 + 3) Sys.max_array_length
+ let prev_sz n = ((n - 3) * 2 + 2) / 3
+
+ let test_shrink_bucket t =
+ let bucket = t.table.(t.rover) in
+ let hbucket = t.hashes.(t.rover) in
+ let len = Weak.length bucket in
+ let prev_len = prev_sz len in
+ let live = count_bucket 0 bucket 0 in
+ if live <= prev_len then begin
+ let rec loop i j =
+ if j >= prev_len then begin
+ if Weak.check bucket i then loop (i + 1) j
+ else if Weak.check bucket j then begin
+ Weak.blit bucket j bucket i 1;
+ hbucket.(i) <- hbucket.(j);
+ loop (i + 1) (j - 1);
+ end else loop i (j - 1);
+ end;
+ in
+ loop 0 (Weak.length bucket - 1);
+ if prev_len = 0 then begin
+ t.table.(t.rover) <- emptybucket;
+ t.hashes.(t.rover) <- [| |];
+ end else begin
+ Obj.truncate (Obj.repr bucket) (prev_len + 1);
+ Obj.truncate (Obj.repr hbucket) prev_len;
+ end;
+ if len > t.limit && prev_len <= t.limit then t.oversize <- t.oversize - 1;
+ end;
+ t.rover <- (t.rover + 1) mod (Array.length t.table)
+
+ let rec resize t =
+ let oldlen = Array.length t.table in
+ let newlen = next_sz oldlen in
+ if newlen > oldlen then begin
+ let newt = create newlen in
+ let add_weak ob oh oi =
+ let setter nb ni _ = Weak.blit ob oi nb ni 1 in
+ let h = oh.(oi) in
+ add_aux newt setter None h (get_index newt h);
+ in
+ iter_weak add_weak t;
+ t.table <- newt.table;
+ t.hashes <- newt.hashes;
+ t.limit <- newt.limit;
+ t.oversize <- newt.oversize;
+ t.rover <- t.rover mod Array.length newt.table;
+ end else begin
+ t.limit <- max_int; (* maximum size already reached *)
+ t.oversize <- 0;
+ end
+
+ and add_aux t setter d h index =
+ let bucket = t.table.(index) in
+ let hashes = t.hashes.(index) in
+ let sz = Weak.length bucket in
+ let rec loop i =
+ if i >= sz then begin
+ let newsz = min (3 * sz / 2 + 3) (Sys.max_array_length - 1) in
+ if newsz <= sz then failwith "Weak.Make: hash bucket cannot grow more";
+ let newbucket = Weak.create newsz in
+ let newhashes = Array.make newsz 0 in
+ Weak.blit bucket 0 newbucket 0 sz;
+ Array.blit hashes 0 newhashes 0 sz;
+ setter newbucket sz d;
+ newhashes.(sz) <- h;
+ t.table.(index) <- newbucket;
+ t.hashes.(index) <- newhashes;
+ if sz <= t.limit && newsz > t.limit then begin
+ t.oversize <- t.oversize + 1;
+ for _i = 0 to over_limit do test_shrink_bucket t done;
+ end;
+ if t.oversize > Array.length t.table / over_limit then resize t
+ end else if Weak.check bucket i then begin
+ loop (i + 1)
+ end else begin
+ setter bucket i d;
+ hashes.(i) <- h
+ end
+ in
+ loop 0
+
+ let find_or h t d ifnotfound =
+ let index = get_index t h in
+ let bucket = t.table.(index) in
+ let hashes = t.hashes.(index) in
+ let sz = Weak.length bucket in
+ let rec loop i =
+ if i >= sz then ifnotfound index
+ else if Int.equal h hashes.(i) then begin
+ match Weak.get bucket i with
+ | Some v when E.eq v d -> v
+ | _ -> loop (i + 1)
+ end else loop (i + 1)
+ in
+ loop 0
+
+ let repr h d t =
+ let ifnotfound index = add_aux t Weak.set (Some d) h index; d in
+ find_or h t d ifnotfound
+
+ let stats t =
+ let fold accu bucket = max (count_bucket 0 bucket 0) accu in
+ let max_length = Array.fold_left fold 0 t.table in
+ let histogram = Array.make (max_length + 1) 0 in
+ let iter bucket =
+ let len = count_bucket 0 bucket 0 in
+ histogram.(len) <- succ histogram.(len)
+ in
+ let () = Array.iter iter t.table in
+ let fold (num, len, i) k = (num + k * i, len + k, succ i) in
+ let (num, len, _) = Array.fold_left fold (0, 0, 0) histogram in
+ {
+ num_bindings = num;
+ num_buckets = len;
+ max_bucket_length = Array.length histogram;
+ bucket_histogram = histogram;
+ }
+
+end
+
+module Combine = struct
+ (* These are helper functions to combine the hash keys in a similar
+ way as [Hashtbl.hash] does. The constants [alpha] and [beta] must
+ be prime numbers. There were chosen empirically. Notice that the
+ problem of hashing trees is hard and there are plenty of study on
+ this topic. Therefore, there must be room for improvement here. *)
+ let alpha = 65599
+ let beta = 7
+ let combine x y = x * alpha + y
+ let combine3 x y z = combine x (combine y z)
+ let combine4 x y z t = combine x (combine3 y z t)
+ let combine5 x y z t u = combine x (combine4 y z t u)
+ let combinesmall x y = beta * x + y
+end
diff --git a/clib/hashset.mli b/clib/hashset.mli
new file mode 100644
index 00000000..0699d4e8
--- /dev/null
+++ b/clib/hashset.mli
@@ -0,0 +1,58 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Adapted from Damien Doligez, projet Para, INRIA Rocquencourt,
+ OCaml stdlib. *)
+
+(** The following functor is a specialized version of [Weak.Make].
+ Here, the responsibility of computing the hash function is now
+ given to the caller, which makes possible the interleaving of the
+ hash key computation and the hash-consing. *)
+
+module type EqType = sig
+ type t
+ val eq : t -> t -> bool
+end
+
+type statistics = {
+ num_bindings: int;
+ num_buckets: int;
+ max_bucket_length: int;
+ bucket_histogram: int array
+}
+
+module type S = sig
+ type elt
+ (** Type of hashsets elements. *)
+ type t
+ (** Type of hashsets. *)
+ val create : int -> t
+ (** [create n] creates a fresh hashset with initial size [n]. *)
+ val clear : t -> unit
+ (** Clear the contents of a hashset. *)
+ val repr : int -> elt -> t -> elt
+ (** [repr key constr set] uses [key] to look for [constr]
+ in the hashet [set]. If [constr] is in [set], returns the
+ specific representation that is stored in [set]. Otherwise,
+ [constr] is stored in [set] and will be used as the canonical
+ representation of this value in the future. *)
+ val stats : t -> statistics
+ (** Recover statistics on the table. *)
+end
+
+module Make (E : EqType) : S with type elt = E.t
+
+module Combine : sig
+ val combine : int -> int -> int
+ val combinesmall : int -> int -> int
+ val combine3 : int -> int -> int -> int
+ val combine4 : int -> int -> int -> int -> int
+ val combine5 : int -> int -> int -> int -> int -> int
+end
diff --git a/clib/heap.ml b/clib/heap.ml
new file mode 100644
index 00000000..49034bbc
--- /dev/null
+++ b/clib/heap.ml
@@ -0,0 +1,136 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(*s Heaps *)
+
+module type Ordered = sig
+ type t
+ val compare : t -> t -> int
+end
+
+module type S =sig
+
+ (* Type of functional heaps *)
+ type t
+
+ (* Type of elements *)
+ type elt
+
+ (* The empty heap *)
+ val empty : t
+
+ (* [add x h] returns a new heap containing the elements of [h], plus [x];
+ complexity $O(log(n))$ *)
+ val add : elt -> t -> t
+
+ (* [maximum h] returns the maximum element of [h]; raises [EmptyHeap]
+ when [h] is empty; complexity $O(1)$ *)
+ val maximum : t -> elt
+
+ (* [remove h] returns a new heap containing the elements of [h], except
+ the maximum of [h]; raises [EmptyHeap] when [h] is empty;
+ complexity $O(log(n))$ *)
+ val remove : t -> t
+
+ (* usual iterators and combinators; elements are presented in
+ arbitrary order *)
+ val iter : (elt -> unit) -> t -> unit
+
+ val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a
+
+end
+
+exception EmptyHeap
+
+(*s Functional implementation *)
+
+module Functional(X : Ordered) = struct
+
+ (* Heaps are encoded as Braun trees, that are binary trees
+ where size r <= size l <= size r + 1 for each node Node (l, x, r) *)
+
+ type t =
+ | Leaf
+ | Node of t * X.t * t
+
+ type elt = X.t
+
+ let empty = Leaf
+
+ let rec add x = function
+ | Leaf ->
+ Node (Leaf, x, Leaf)
+ | Node (l, y, r) ->
+ if X.compare x y >= 0 then
+ Node (add y r, x, l)
+ else
+ Node (add x r, y, l)
+
+ let rec extract = function
+ | Leaf ->
+ assert false
+ | Node (Leaf, y, r) ->
+ assert (r = Leaf);
+ y, Leaf
+ | Node (l, y, r) ->
+ let x, l = extract l in
+ x, Node (r, y, l)
+
+ let is_above x = function
+ | Leaf -> true
+ | Node (_, y, _) -> X.compare x y >= 0
+
+ let rec replace_min x = function
+ | Node (l, _, r) when is_above x l && is_above x r ->
+ Node (l, x, r)
+ | Node ((Node (_, lx, _) as l), _, r) when is_above lx r ->
+ (* lx <= x, rx necessarily *)
+ Node (replace_min x l, lx, r)
+ | Node (l, _, (Node (_, rx, _) as r)) ->
+ (* rx <= x, lx necessarily *)
+ Node (l, rx, replace_min x r)
+ | Leaf | Node (Leaf, _, _) | Node (_, _, Leaf) ->
+ assert false
+
+ (* merges two Braun trees [l] and [r],
+ with the assumption that [size r <= size l <= size r + 1] *)
+ let rec merge l r = match l, r with
+ | _, Leaf ->
+ l
+ | Node (ll, lx, lr), Node (_, ly, _) ->
+ if X.compare lx ly >= 0 then
+ Node (r, lx, merge ll lr)
+ else
+ let x, l = extract l in
+ Node (replace_min x r, ly, l)
+ | Leaf, _ ->
+ assert false (* contradicts the assumption *)
+
+ let maximum = function
+ | Leaf -> raise EmptyHeap
+ | Node (_, x, _) -> x
+
+ let remove = function
+ | Leaf ->
+ raise EmptyHeap
+ | Node (l, _, r) ->
+ merge l r
+
+ let rec iter f = function
+ | Leaf -> ()
+ | Node (l, x, r) -> iter f l; f x; iter f r
+
+ let rec fold f h x0 = match h with
+ | Leaf ->
+ x0
+ | Node (l, x, r) ->
+ fold f l (fold f r (f x x0))
+
+end
diff --git a/clib/heap.mli b/clib/heap.mli
new file mode 100644
index 00000000..ab0864c7
--- /dev/null
+++ b/clib/heap.mli
@@ -0,0 +1,54 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Heaps *)
+
+module type Ordered = sig
+ type t
+ val compare : t -> t -> int
+end
+
+module type S =sig
+
+ (** Type of functional heaps *)
+ type t
+
+ (** Type of elements *)
+ type elt
+
+ (** The empty heap *)
+ val empty : t
+
+ (** [add x h] returns a new heap containing the elements of [h], plus [x];
+ complexity {% $ %}O(log(n)){% $ %} *)
+ val add : elt -> t -> t
+
+ (** [maximum h] returns the maximum element of [h]; raises [EmptyHeap]
+ when [h] is empty; complexity {% $ %}O(1){% $ %} *)
+ val maximum : t -> elt
+
+ (** [remove h] returns a new heap containing the elements of [h], except
+ the maximum of [h]; raises [EmptyHeap] when [h] is empty;
+ complexity {% $ %}O(log(n)){% $ %} *)
+ val remove : t -> t
+
+ (** usual iterators and combinators; elements are presented in
+ arbitrary order *)
+ val iter : (elt -> unit) -> t -> unit
+
+ val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a
+
+end
+
+exception EmptyHeap
+
+(** {6 Functional implementation. } *)
+
+module Functional(X: Ordered) : S with type elt=X.t
diff --git a/clib/iStream.ml b/clib/iStream.ml
new file mode 100644
index 00000000..8daf2279
--- /dev/null
+++ b/clib/iStream.ml
@@ -0,0 +1,92 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type ('a,'r) u =
+| Nil
+| Cons of 'a * 'r
+
+type 'a node = ('a,'a t) u
+
+and 'a t = 'a node Lazy.t
+
+let empty = Lazy.from_val Nil
+
+let cons x s = Lazy.from_val (Cons (x, s))
+
+let thunk = Lazy.from_fun
+
+let rec make_node f s = match f s with
+| Nil -> Nil
+| Cons (x, s) -> Cons (x, make f s)
+
+and make f s = lazy (make_node f s)
+
+let rec force s = match Lazy.force s with
+| Nil -> ()
+| Cons (_, s) -> force s
+
+let force s = force s; s
+
+let is_empty s = match Lazy.force s with
+| Nil -> true
+| Cons (_, _) -> false
+
+let peek = Lazy.force
+
+let rec of_list = function
+| [] -> empty
+| x :: l -> cons x (of_list l)
+
+let rec to_list s = match Lazy.force s with
+| Nil -> []
+| Cons (x, s) -> x :: (to_list s)
+
+let rec iter f s = match Lazy.force s with
+| Nil -> ()
+| Cons (x, s) -> f x; iter f s
+
+let rec map_node f = function
+| Nil -> Nil
+| Cons (x, s) -> Cons (f x, map f s)
+
+and map f s = lazy (map_node f (Lazy.force s))
+
+let rec app_node n1 s2 = match n1 with
+| Nil -> Lazy.force s2
+| Cons (x, s1) -> Cons (x, app s1 s2)
+
+and app s1 s2 = lazy (app_node (Lazy.force s1) s2)
+
+let rec fold f accu s = match Lazy.force s with
+| Nil -> accu
+| Cons (x, s) -> fold f (f accu x) s
+
+let rec map_filter_node f = function
+| Nil -> Nil
+| Cons (x, s) ->
+ begin match f x with
+ | None -> map_filter_node f (Lazy.force s)
+ | Some y -> Cons (y, map_filter f s)
+ end
+
+and map_filter f s = lazy (map_filter_node f (Lazy.force s))
+
+let rec concat_node = function
+| Nil -> Nil
+| Cons (s, sl) -> app_node (Lazy.force s) (concat sl)
+
+and concat (s : 'a t t) =
+ lazy (concat_node (Lazy.force s))
+
+let rec concat_map_node f = function
+| Nil -> Nil
+| Cons (x,s) -> app_node (Lazy.force (f x)) (concat_map f s)
+
+and concat_map f l = lazy (concat_map_node f (Lazy.force l))
diff --git a/clib/iStream.mli b/clib/iStream.mli
new file mode 100644
index 00000000..40d579be
--- /dev/null
+++ b/clib/iStream.mli
@@ -0,0 +1,83 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** {5 Purely functional streams}
+
+ Contrarily to OCaml module [Stream], these are meant to be used purely
+ functionally. This implies in particular that accessing an element does not
+ discard it. *)
+
+type +'a t
+(** Type of pure streams. *)
+
+type ('a,'r) u =
+| Nil
+| Cons of 'a * 'r
+(** View type to decompose and build streams. *)
+
+(** {6 Constructors} *)
+
+val empty : 'a t
+(** The empty stream. *)
+
+val cons : 'a -> 'a t -> 'a t
+(** Append an element in front of a stream. *)
+
+val thunk : (unit -> ('a,'a t) u) -> 'a t
+(** Internalize the lazyness of a stream. *)
+
+val make : ('a -> ('b, 'a) u) -> 'a -> 'b t
+(** Coiteration constructor. *)
+
+(** {6 Destructors} *)
+
+val is_empty : 'a t -> bool
+(** Whethere a stream is empty. *)
+
+val peek : 'a t -> ('a , 'a t) u
+(** Return the head and the tail of a stream, if any. *)
+
+(** {6 Standard operations}
+
+ All stream-returning functions are lazy. The other ones are eager. *)
+
+val app : 'a t -> 'a t -> 'a t
+(** Append two streams. Not tail-rec. *)
+
+val map : ('a -> 'b) -> 'a t -> 'b t
+(** Mapping of streams. Not tail-rec. *)
+
+val iter : ('a -> unit) -> 'a t -> unit
+(** Iteration over streams. *)
+
+val fold : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
+(** Fold over streams. *)
+
+val concat : 'a t t -> 'a t
+(** Appends recursively a stream of streams. *)
+
+val map_filter : ('a -> 'b option) -> 'a t -> 'b t
+(** Mixing [map] and [filter]. Not tail-rec. *)
+
+val concat_map : ('a -> 'b t) -> 'a t -> 'b t
+(** [concat_map f l] is the same as [concat (map f l)]. *)
+
+(** {6 Conversions} *)
+
+val of_list : 'a list -> 'a t
+(** Convert a list into a stream. *)
+
+val to_list : 'a t -> 'a list
+(** Convert a stream into a list. *)
+
+(** {6 Other}*)
+
+val force : 'a t -> 'a t
+(** Forces the whole stream. *)
diff --git a/clib/int.ml b/clib/int.ml
new file mode 100644
index 00000000..3ae836ae
--- /dev/null
+++ b/clib/int.ml
@@ -0,0 +1,239 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type t = int
+
+external equal : int -> int -> bool = "%eq"
+
+external compare : int -> int -> int = "caml_int_compare"
+
+let hash i = i land 0x3FFFFFFF
+
+module Self =
+struct
+ type t = int
+ let compare = compare
+end
+
+module Set = Set.Make(Self)
+module Map =
+struct
+ include CMap.Make(Self)
+
+ type 'a map = 'a CMap.Make(Self).t
+
+ type 'a _map =
+ | MEmpty
+ | MNode of 'a map * int * 'a * 'a map * int
+
+ let map_prj : 'a map -> 'a _map = Obj.magic
+
+ let rec find i s = match map_prj s with
+ | MEmpty -> raise Not_found
+ | MNode (l, k, v, r, h) ->
+ if i < k then find i l
+ else if i = k then v
+ else find i r
+end
+
+module List = struct
+ let mem = List.memq
+ let assoc = List.assq
+ let mem_assoc = List.mem_assq
+ let remove_assoc = List.remove_assq
+end
+
+let min (i : int) j = if i < j then i else j
+
+(** Utility function *)
+let rec next from upto =
+ if from < upto then next (2 * from + 1) upto
+ else from
+
+
+module PArray =
+struct
+
+ type 'a t = 'a data ref
+ and 'a data =
+ | Root of 'a option array
+ | DSet of int * 'a option * 'a t
+
+ let empty n = ref (Root (Array.make n None))
+
+ let rec rerootk t k = match !t with
+ | Root _ -> k ()
+ | DSet (i, v, t') ->
+ let next () = match !t' with
+ | Root a as n ->
+ let v' = Array.unsafe_get a i in
+ let () = Array.unsafe_set a i v in
+ let () = t := n in
+ let () = t' := DSet (i, v', t) in
+ k ()
+ | DSet _ -> assert false
+ in
+ rerootk t' next
+
+ let reroot t = rerootk t (fun () -> ())
+
+ let get t i =
+ let () = assert (0 <= i) in
+ match !t with
+ | Root a ->
+ if Array.length a <= i then None
+ else Array.unsafe_get a i
+ | DSet _ ->
+ let () = reroot t in
+ match !t with
+ | Root a ->
+ if Array.length a <= i then None
+ else Array.unsafe_get a i
+ | DSet _ -> assert false
+
+ let set t i v =
+ let () = assert (0 <= i) in
+ let () = reroot t in
+ match !t with
+ | DSet _ -> assert false
+ | Root a as n ->
+ let len = Array.length a in
+ if i < len then
+ let old = Array.unsafe_get a i in
+ if old == v then t
+ else
+ let () = Array.unsafe_set a i v in
+ let res = ref n in
+ let () = t := DSet (i, old, res) in
+ res
+ else match v with
+ | None -> t (** Nothing to do! *)
+ | Some _ -> (** we must resize *)
+ let nlen = next len (succ i) in
+ let nlen = min nlen Sys.max_array_length in
+ let () = assert (i < nlen) in
+ let a' = Array.make nlen None in
+ let () = Array.blit a 0 a' 0 len in
+ let () = Array.unsafe_set a' i v in
+ let res = ref (Root a') in
+ let () = t := DSet (i, None, res) in
+ res
+
+end
+
+module PMap =
+struct
+
+ type key = int
+
+ (** Invariants:
+
+ 1. an empty map is always [Empty].
+ 2. the set of the [Map] constructor remembers the present keys.
+ *)
+ type 'a t = Empty | Map of Set.t * 'a PArray.t
+
+ let empty = Empty
+
+ let is_empty = function
+ | Empty -> true
+ | Map _ -> false
+
+ let singleton k x =
+ let len = next 19 (k + 1) in
+ let len = min Sys.max_array_length len in
+ let v = PArray.empty len in
+ let v = PArray.set v k (Some x) in
+ let s = Set.singleton k in
+ Map (s, v)
+
+ let add k x = function
+ | Empty -> singleton k x
+ | Map (s, v) ->
+ let s = match PArray.get v k with
+ | None -> Set.add k s
+ | Some _ -> s
+ in
+ let v = PArray.set v k (Some x) in
+ Map (s, v)
+
+ let remove k = function
+ | Empty -> Empty
+ | Map (s, v) ->
+ let s = Set.remove k s in
+ if Set.is_empty s then Empty
+ else
+ let v = PArray.set v k None in
+ Map (s, v)
+
+ let mem k = function
+ | Empty -> false
+ | Map (_, v) ->
+ match PArray.get v k with
+ | None -> false
+ | Some _ -> true
+
+ let find k = function
+ | Empty -> raise Not_found
+ | Map (_, v) ->
+ match PArray.get v k with
+ | None -> raise Not_found
+ | Some x -> x
+
+ let iter f = function
+ | Empty -> ()
+ | Map (s, v) ->
+ let iter k = match PArray.get v k with
+ | None -> ()
+ | Some x -> f k x
+ in
+ Set.iter iter s
+
+ let fold f m accu = match m with
+ | Empty -> accu
+ | Map (s, v) ->
+ let fold k accu = match PArray.get v k with
+ | None -> accu
+ | Some x -> f k x accu
+ in
+ Set.fold fold s accu
+
+ let exists f m = match m with
+ | Empty -> false
+ | Map (s, v) ->
+ let exists k = match PArray.get v k with
+ | None -> false
+ | Some x -> f k x
+ in
+ Set.exists exists s
+
+ let for_all f m = match m with
+ | Empty -> true
+ | Map (s, v) ->
+ let for_all k = match PArray.get v k with
+ | None -> true
+ | Some x -> f k x
+ in
+ Set.for_all for_all s
+
+ let cast = function
+ | Empty -> Map.empty
+ | Map (s, v) ->
+ let bind k = match PArray.get v k with
+ | None -> assert false
+ | Some x -> x
+ in
+ Map.bind bind s
+
+ let domain = function
+ | Empty -> Set.empty
+ | Map (s, _) -> s
+
+end
diff --git a/clib/int.mli b/clib/int.mli
new file mode 100644
index 00000000..76aecf05
--- /dev/null
+++ b/clib/int.mli
@@ -0,0 +1,81 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** A native integer module with usual utility functions. *)
+
+type t = int
+
+external equal : t -> t -> bool = "%eq"
+
+external compare : t -> t -> int = "caml_int_compare"
+
+val hash : t -> int
+
+module Set : Set.S with type elt = t
+module Map : CMap.ExtS with type key = t and module Set := Set
+
+module List : sig
+ val mem : int -> int list -> bool
+ val assoc : int -> (int * 'a) list -> 'a
+ val mem_assoc : int -> (int * 'a) list -> bool
+ val remove_assoc : int -> (int * 'a) list -> (int * 'a) list
+end
+
+module PArray :
+sig
+ type 'a t
+ (** Persistent, auto-resizable arrays. The [get] and [set] functions never
+ fail whenever the index is between [0] and [Sys.max_array_length - 1]. *)
+ val empty : int -> 'a t
+ (** The empty array, with a given starting size. *)
+ val get : 'a t -> int -> 'a option
+ (** Get a value at the given index. Returns [None] if undefined. *)
+ val set : 'a t -> int -> 'a option -> 'a t
+ (** Set/unset a value at the given index. *)
+end
+
+module PMap :
+sig
+ type key = int
+ type 'a t
+ val empty : 'a t
+ val is_empty : 'a t -> bool
+ val mem : key -> 'a t -> bool
+ val add : key -> 'a -> 'a t -> 'a t
+ val singleton : key -> 'a -> 'a t
+ val remove : key -> 'a t -> 'a t
+(* val merge : (key -> 'a option -> 'b option -> 'c option) -> 'a t -> 'b t -> 'c t *)
+(* val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int *)
+(* val equal : ('a -> 'a -> bool) -> 'a t -> 'a t -> bool *)
+ val iter : (key -> 'a -> unit) -> 'a t -> unit
+ val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
+ val for_all : (key -> 'a -> bool) -> 'a t -> bool
+ val exists : (key -> 'a -> bool) -> 'a t -> bool
+(* val filter : (key -> 'a -> bool) -> 'a t -> 'a t *)
+(* val partition : (key -> 'a -> bool) -> 'a t -> 'a t * 'a t *)
+(* val cardinal : 'a t -> int *)
+(* val bindings : 'a t -> (key * 'a) list *)
+(* val min_binding : 'a t -> key * 'a *)
+(* val max_binding : 'a t -> key * 'a *)
+(* val choose : 'a t -> key * 'a *)
+(* val split : key -> 'a t -> 'a t * 'a option * 'a t *)
+ val find : key -> 'a t -> 'a
+(* val map : ('a -> 'b) -> 'a t -> 'b t *)
+(* val mapi : (key -> 'a -> 'b) -> 'a t -> 'b t *)
+ val domain : 'a t -> Set.t
+ val cast : 'a t -> 'a Map.t
+end
+(** This is a (partial) implementation of a [Map] interface on integers, except
+ that it internally uses persistent arrays. This ensures O(1) accesses in
+ non-backtracking cases. It is thus better suited for zero-starting,
+ contiguous keys, or otherwise a lot of space will be empty. To keep track of
+ the present keys, a binary tree is also used, so that adding a key is
+ still logarithmic. It is therefore essential that most of the operations
+ are accesses and not add/removes. *)
diff --git a/clib/minisys.ml b/clib/minisys.ml
new file mode 100644
index 00000000..bbcf46b9
--- /dev/null
+++ b/clib/minisys.ml
@@ -0,0 +1,80 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Minisys regroups some code that used to be in System.
+ Unlike System, this module has no dependency and could
+ be used for initial compilation target such as coqdep_boot.
+ The functions here are still available in System thanks to
+ an include. For the signature, look at the top of system.mli
+*)
+
+(** Dealing with directories *)
+
+type unix_path = string (* path in unix-style, with '/' separator *)
+
+type file_kind =
+ | FileDir of unix_path * (* basename of path: *) string
+ | FileRegular of string (* basename of file *)
+
+(* Copy of Filename.concat but assuming paths to always be POSIX *)
+
+let (//) dirname filename =
+ let l = String.length dirname in
+ if l = 0 || dirname.[l-1] = '/'
+ then dirname ^ filename
+ else dirname ^ "/" ^ filename
+
+(* Excluding directories; We avoid directories starting with . as well
+ as CVS and _darcs and any subdirs given via -exclude-dir *)
+
+let skipped_dirnames = ref ["CVS"; "_darcs"]
+
+let exclude_directory f = skipped_dirnames := f :: !skipped_dirnames
+
+(* Note: this test is possibly used for Coq module/file names but also for
+ OCaml filenames, whose syntax as of today is more restrictive for
+ module names (only initial letter then letter, digits, _ or quote),
+ but more permissive (though disadvised) for file names *)
+
+let ok_dirname f =
+ not (f = "") && f.[0] != '.' &&
+ not (List.mem f !skipped_dirnames) &&
+ match Unicode.ident_refutation f with None -> true | _ -> false
+
+(* Check directory can be opened *)
+
+let exists_dir dir =
+ (* See BZ#5391 on windows failing on a trailing (back)slash *)
+ let rec strip_trailing_slash dir =
+ let len = String.length dir in
+ if len > 0 && (dir.[len-1] = '/' || dir.[len-1] = '\\')
+ then strip_trailing_slash (String.sub dir 0 (len-1)) else dir in
+ let dir = if Sys.os_type = "Win32" then strip_trailing_slash dir else dir in
+ try Sys.is_directory dir with Sys_error _ -> false
+
+let apply_subdir f path name =
+ (* we avoid all files and subdirs starting by '.' (e.g. .svn) *)
+ (* as well as skipped files like CVS, ... *)
+ let base = try Filename.chop_extension name with Invalid_argument _ -> name in
+ if ok_dirname base then
+ let path = if path = "." then name else path//name in
+ match try (Unix.stat path).Unix.st_kind with Unix.Unix_error _ -> Unix.S_BLK with
+ | Unix.S_DIR when name = base -> f (FileDir (path,name))
+ | Unix.S_REG -> f (FileRegular name)
+ | _ -> ()
+
+let readdir dir = try Sys.readdir dir with any -> [||]
+
+let process_directory f path =
+ Array.iter (apply_subdir f path) (readdir path)
+
+let process_subdirectories f path =
+ let f = function FileDir (path,base) -> f path base | FileRegular _ -> () in
+ process_directory f path
diff --git a/clib/monad.ml b/clib/monad.ml
new file mode 100644
index 00000000..8740cae0
--- /dev/null
+++ b/clib/monad.ml
@@ -0,0 +1,170 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+
+(** Combinators on monadic computations. *)
+
+
+(** A definition of monads, each of the combinators is used in the
+ [Make] functor. *)
+module type Def = sig
+
+ type +'a t
+ val return : 'a -> 'a t
+ val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
+ val (>>) : unit t -> 'a t -> 'a t
+ val map : ('a -> 'b) -> 'a t -> 'b t
+
+ (** The monadic laws must hold:
+ - [(x>>=f)>>=g] = [x>>=fun x' -> (f x'>>=g)]
+ - [return a >>= f] = [f a]
+ - [x>>=return] = [x]
+
+ As well as the following identities:
+ - [x >> y] = [x >>= fun () -> y]
+ - [map f x] = [x >>= fun x' -> f x'] *)
+
+end
+
+module type ListS = sig
+
+ type 'a t
+
+ (** [List.map f l] maps [f] on the elements of [l] in left to right
+ order. *)
+ val map : ('a -> 'b t) -> 'a list -> 'b list t
+
+ (** [List.map f l] maps [f] on the elements of [l] in right to left
+ order. *)
+ val map_right : ('a -> 'b t) -> 'a list -> 'b list t
+
+ (** Like the regular [List.fold_right]. The monadic effects are
+ threaded right to left.
+
+ Note: many monads behave poorly with right-to-left order. For
+ instance a failure monad would still have to traverse the
+ whole list in order to fail and failure needs to be propagated
+ through the rest of the list in binds which are now
+ spurious. It is also the worst case for substitution monads
+ (aka free monads), exposing the quadratic behaviour.*)
+ val fold_right : ('a -> 'b -> 'b t) -> 'a list -> 'b -> 'b t
+
+ (** Like the regular [List.fold_left]. The monadic effects are
+ threaded left to right. It is tail-recursive if the [(>>=)]
+ operator calls its second argument in a tail position. *)
+ val fold_left : ('a -> 'b -> 'a t) -> 'a -> 'b list -> 'a t
+
+ (** Like the regular [List.iter]. The monadic effects are threaded
+ left to right. It is tail-recurisve if the [>>] operator calls
+ its second argument in a tail position. *)
+ val iter : ('a -> unit t) -> 'a list -> unit t
+
+ (** Like the regular {!CList.map_filter}. The monadic effects are threaded left*)
+ val map_filter : ('a -> 'b option t) -> 'a list -> 'b list t
+
+
+ (** {6 Two-list iterators} *)
+
+ (** [fold_left2 r f s l1 l2] behaves like {!fold_left} but acts
+ simultaneously on two lists. Runs [r] (presumably an
+ exception-raising computation) if both lists do not have the
+ same length. *)
+ val fold_left2 : 'a t ->
+ ('a -> 'b -> 'c -> 'a t) -> 'a -> 'b list -> 'c list -> 'a t
+
+end
+
+module type S = sig
+
+ include Def
+
+ (** List combinators *)
+ module List : ListS with type 'a t := 'a t
+
+end
+
+
+module Make (M:Def) : S with type +'a t = 'a M.t = struct
+
+ include M
+
+ module List = struct
+
+ (* The combinators are loop-unrolled to spare a some monadic binds
+ (it is a common optimisation to treat the last of a list of
+ bind specially) and hopefully gain some efficiency using fewer
+ jump. *)
+
+ let rec map f = function
+ | [] -> return []
+ | [a] ->
+ M.map (fun a' -> [a']) (f a)
+ | a::b::l ->
+ f a >>= fun a' ->
+ f b >>= fun b' ->
+ M.map (fun l' -> a'::b'::l') (map f l)
+
+ let rec map_right f = function
+ | [] -> return []
+ | [a] ->
+ M.map (fun a' -> [a']) (f a)
+ | a::b::l ->
+ map_right f l >>= fun l' ->
+ f b >>= fun b' ->
+ M.map (fun a' -> a'::b'::l') (f a)
+
+ let rec fold_right f l x =
+ match l with
+ | [] -> return x
+ | [a] -> f a x
+ | a::b::l ->
+ fold_right f l x >>= fun acc ->
+ f b acc >>= fun acc ->
+ f a acc
+
+ let rec fold_left f x = function
+ | [] -> return x
+ | [a] -> f x a
+ | a::b::l ->
+ f x a >>= fun x' ->
+ f x' b >>= fun x'' ->
+ fold_left f x'' l
+
+ let rec iter f = function
+ | [] -> return ()
+ | [a] -> f a
+ | a::b::l -> f a >> f b >> iter f l
+
+
+ let rec map_filter f = function
+ | [] -> return []
+ | a::l ->
+ f a >>= function
+ | None -> map_filter f l
+ | Some b ->
+ map_filter f l >>= fun filtered ->
+ return (b::filtered)
+
+ let rec fold_left2 r f x l1 l2 =
+ match l1,l2 with
+ | [] , [] -> return x
+ | [a] , [b] -> f x a b
+ | a1::a2::l1 , b1::b2::l2 ->
+ f x a1 b1 >>= fun x' ->
+ f x' a2 b2 >>= fun x'' ->
+ fold_left2 r f x'' l1 l2
+ | _ , _ -> r
+
+ end
+
+end
+
+
+
diff --git a/clib/monad.mli b/clib/monad.mli
new file mode 100644
index 00000000..d1d42eb8
--- /dev/null
+++ b/clib/monad.mli
@@ -0,0 +1,96 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+
+(** Combinators on monadic computations. *)
+
+
+(** A definition of monads, each of the combinators is used in the
+ [Make] functor. *)
+module type Def = sig
+
+ type +'a t
+ val return : 'a -> 'a t
+ val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
+ val (>>) : unit t -> 'a t -> 'a t
+ val map : ('a -> 'b) -> 'a t -> 'b t
+
+(** The monadic laws must hold:
+ - [(x>>=f)>>=g] = [x>>=fun x' -> (f x'>>=g)]
+ - [return a >>= f] = [f a]
+ - [x>>=return] = [x]
+
+ As well as the following identities:
+ - [x >> y] = [x >>= fun () -> y]
+ - [map f x] = [x >>= fun x' -> f x'] *)
+
+end
+
+
+(** List combinators *)
+module type ListS = sig
+
+ type 'a t
+
+ (** [List.map f l] maps [f] on the elements of [l] in left to right
+ order. *)
+ val map : ('a -> 'b t) -> 'a list -> 'b list t
+
+ (** [List.map f l] maps [f] on the elements of [l] in right to left
+ order. *)
+ val map_right : ('a -> 'b t) -> 'a list -> 'b list t
+
+ (** Like the regular [List.fold_right]. The monadic effects are
+ threaded right to left.
+
+ Note: many monads behave poorly with right-to-left order. For
+ instance a failure monad would still have to traverse the
+ whole list in order to fail and failure needs to be propagated
+ through the rest of the list in binds which are now
+ spurious. It is also the worst case for substitution monads
+ (aka free monads), exposing the quadratic behaviour.*)
+ val fold_right : ('a -> 'b -> 'b t) -> 'a list -> 'b -> 'b t
+
+ (** Like the regular [List.fold_left]. The monadic effects are
+ threaded left to right. It is tail-recursive if the [(>>=)]
+ operator calls its second argument in a tail position. *)
+ val fold_left : ('a -> 'b -> 'a t) -> 'a -> 'b list -> 'a t
+
+ (** Like the regular [List.iter]. The monadic effects are threaded
+ left to right. It is tail-recurisve if the [>>] operator calls
+ its second argument in a tail position. *)
+ val iter : ('a -> unit t) -> 'a list -> unit t
+
+ (** Like the regular {!CList.map_filter}. The monadic effects are
+ threaded left to right. *)
+ val map_filter : ('a -> 'b option t) -> 'a list -> 'b list t
+
+
+ (** {6 Two-list iterators} *)
+
+ (** [fold_left2 r f s l1 l2] behaves like {!fold_left} but acts
+ simultaneously on two lists. Runs [r] (presumably an
+ exception-raising computation) if both lists do not have the
+ same length. *)
+ val fold_left2 : 'a t ->
+ ('a -> 'b -> 'c -> 'a t) -> 'a -> 'b list -> 'c list -> 'a t
+
+end
+
+module type S = sig
+
+ include Def
+
+ module List : ListS with type 'a t := 'a t
+
+end
+
+(** Expands the monadic definition to extra combinators. *)
+module Make (M:Def) : S with type +'a t = 'a M.t
diff --git a/clib/option.ml b/clib/option.ml
new file mode 100644
index 00000000..32fe2fc5
--- /dev/null
+++ b/clib/option.ml
@@ -0,0 +1,211 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Module implementing basic combinators for OCaml option type.
+ It tries follow closely the style of OCaml standard library.
+
+ Actually, some operations have the same name as [List] ones:
+ they actually are similar considering ['a option] as a type
+ of lists with at most one element. *)
+
+(** [has_some x] is [true] if [x] is of the form [Some y] and [false]
+ otherwise. *)
+let has_some = function
+ | None -> false
+ | _ -> true
+
+let is_empty = function
+ | None -> true
+ | Some _ -> false
+
+(** Lifting equality onto option types. *)
+let equal f x y = match x, y with
+ | None, None -> true
+ | Some x, Some y -> f x y
+ | _, _ -> false
+
+let compare f x y = match x, y with
+ | None, None -> 0
+ | Some x, Some y -> f x y
+ | None, Some _ -> -1
+ | Some _, None -> 1
+
+let hash f = function
+ | None -> 0
+ | Some x -> f x
+
+exception IsNone
+
+(** [get x] returns [y] where [x] is [Some y].
+ @raise IsNone if [x] equals [None]. *)
+let get = function
+ | Some y -> y
+ | _ -> raise IsNone
+
+(** [make x] returns [Some x]. *)
+let make x = Some x
+
+(** [bind x f] is [f y] if [x] is [Some y] and [None] otherwise *)
+let bind x f = match x with Some y -> f y | None -> None
+
+(** [init b x] returns [Some x] if [b] is [true] and [None] otherwise. *)
+let init b x =
+ if b then
+ Some x
+ else
+ None
+
+(** [flatten x] is [Some y] if [x] is [Some (Some y)] and [None] otherwise. *)
+let flatten = function
+ | Some (Some y) -> Some y
+ | _ -> None
+
+(** [append x y] is the first element of the concatenation of [x] and
+ [y] seen as lists. *)
+let append o1 o2 =
+ match o1 with
+ | Some _ -> o1
+ | None -> o2
+
+
+(** {6 "Iterators"} ***)
+
+(** [iter f x] executes [f y] if [x] equals [Some y]. It does nothing
+ otherwise. *)
+let iter f = function
+ | Some y -> f y
+ | _ -> ()
+
+
+exception Heterogeneous
+
+(** [iter2 f x y] executes [f z w] if [x] equals [Some z] and [y] equals
+ [Some w]. It does nothing if both [x] and [y] are [None]. And raises
+ [Heterogeneous] otherwise. *)
+let iter2 f x y =
+ match x,y with
+ | Some z, Some w -> f z w
+ | None,None -> ()
+ | _,_ -> raise Heterogeneous
+
+(** [map f x] is [None] if [x] is [None] and [Some (f y)] if [x] is [Some y]. *)
+let map f = function
+ | Some y -> Some (f y)
+ | _ -> None
+
+(** [smartmap f x] does the same as [map f x] except that it tries to share
+ some memory. *)
+let smartmap f = function
+ | Some y as x -> let y' = f y in if y' == y then x else Some y'
+ | _ -> None
+
+(** [fold_left f a x] is [f a y] if [x] is [Some y], and [a] otherwise. *)
+let fold_left f a = function
+ | Some y -> f a y
+ | _ -> a
+
+(** [fold_left2 f a x y] is [f z w] if [x] is [Some z] and [y] is [Some w].
+ It is [a] if both [x] and [y] are [None]. Otherwise it raises
+ [Heterogeneous]. *)
+let fold_left2 f a x y =
+ match x,y with
+ | Some x, Some y -> f a x y
+ | None, None -> a
+ | _ -> raise Heterogeneous
+
+(** [fold_right f x a] is [f y a] if [x] is [Some y], and [a] otherwise. *)
+let fold_right f x a =
+ match x with
+ | Some y -> f y a
+ | _ -> a
+
+(** [fold_left_map f a x] is [a, f y] if [x] is [Some y], and [a] otherwise. *)
+let fold_left_map f a x =
+ match x with
+ | Some y -> let a, z = f a y in a, Some z
+ | _ -> a, None
+
+let fold_right_map f x a =
+ match x with
+ | Some y -> let z, a = f y a in Some z, a
+ | _ -> None, a
+
+let fold_map = fold_left_map
+
+(** [cata f a x] is [a] if [x] is [None] and [f y] if [x] is [Some y]. *)
+let cata f a = function
+ | Some c -> f c
+ | None -> a
+
+
+(** {6 More Specific operations} ***)
+
+(** [default a x] is [y] if [x] is [Some y] and [a] otherwise. *)
+let default a = function
+ | Some y -> y
+ | _ -> a
+
+(** [lift f x] is the same as [map f x]. *)
+let lift = map
+
+(** [lift_right f a x] is [Some (f a y)] if [x] is [Some y], and
+ [None] otherwise. *)
+let lift_right f a = function
+ | Some y -> Some (f a y)
+ | _ -> None
+
+(** [lift_left f x a] is [Some (f y a)] if [x] is [Some y], and
+ [None] otherwise. *)
+let lift_left f x a =
+ match x with
+ | Some y -> Some (f y a)
+ | _ -> None
+
+(** [lift2 f x y] is [Some (f z w)] if [x] equals [Some z] and [y] equals
+ [Some w]. It is [None] otherwise. *)
+let lift2 f x y =
+ match x,y with
+ | Some z, Some w -> Some (f z w)
+ | _,_ -> None
+
+
+(** {6 Operations with Lists} *)
+
+module List =
+ struct
+ (** [List.cons x l] equals [y::l] if [x] is [Some y] and [l] otherwise. *)
+ let cons x l =
+ match x with
+ | Some y -> y::l
+ | _ -> l
+
+ (** [List.flatten l] is the list of all the [y]s such that [l] contains
+ [Some y] (in the same order). *)
+ let rec flatten = function
+ | x::l -> cons x (flatten l)
+ | [] -> []
+
+ let rec find f = function
+ | [] -> None
+ | h :: t -> match f h with
+ | None -> find f t
+ | x -> x
+
+ let map f l =
+ let rec aux f l = match l with
+ | [] -> []
+ | x :: l ->
+ match f x with
+ | None -> raise Exit
+ | Some y -> y :: aux f l
+ in
+ try Some (aux f l) with Exit -> None
+
+end
diff --git a/clib/option.mli b/clib/option.mli
new file mode 100644
index 00000000..14fa9da3
--- /dev/null
+++ b/clib/option.mli
@@ -0,0 +1,147 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Module implementing basic combinators for OCaml option type.
+ It tries follow closely the style of OCaml standard library.
+
+ Actually, some operations have the same name as [List] ones:
+ they actually are similar considering ['a option] as a type
+ of lists with at most one element. *)
+
+exception IsNone
+
+(** [has_some x] is [true] if [x] is of the form [Some y] and [false]
+ otherwise. *)
+val has_some : 'a option -> bool
+
+(** Negation of [has_some] *)
+val is_empty : 'a option -> bool
+
+(** [equal f x y] lifts the equality predicate [f] to
+ option types. That is, if both [x] and [y] are [None] then
+ it returns [true], if they are both [Some _] then
+ [f] is called. Otherwise it returns [false]. *)
+val equal : ('a -> 'a -> bool) -> 'a option -> 'a option -> bool
+
+(** Same as [equal], but with comparison. *)
+val compare : ('a -> 'a -> int) -> 'a option -> 'a option -> int
+
+(** Lift a hash to option types. *)
+val hash : ('a -> int) -> 'a option -> int
+
+(** [get x] returns [y] where [x] is [Some y].
+ @raise IsNone if [x] equals [None]. *)
+val get : 'a option -> 'a
+
+(** [make x] returns [Some x]. *)
+val make : 'a -> 'a option
+
+(** [bind x f] is [f y] if [x] is [Some y] and [None] otherwise *)
+val bind : 'a option -> ('a -> 'b option) -> 'b option
+
+(** [init b x] returns [Some x] if [b] is [true] and [None] otherwise. *)
+val init : bool -> 'a -> 'a option
+
+(** [flatten x] is [Some y] if [x] is [Some (Some y)] and [None] otherwise. *)
+val flatten : 'a option option -> 'a option
+
+(** [append x y] is the first element of the concatenation of [x] and
+ [y] seen as lists. In other words, [append (Some a) y] is [Some
+ a], [append None (Some b)] is [Some b], and [append None None] is
+ [None]. *)
+val append : 'a option -> 'a option -> 'a option
+
+
+(** {6 "Iterators"} *)
+
+(** [iter f x] executes [f y] if [x] equals [Some y]. It does nothing
+ otherwise. *)
+val iter : ('a -> unit) -> 'a option -> unit
+
+exception Heterogeneous
+
+(** [iter2 f x y] executes [f z w] if [x] equals [Some z] and [y] equals
+ [Some w]. It does nothing if both [x] and [y] are [None].
+ @raise Heterogeneous otherwise. *)
+val iter2 : ('a -> 'b -> unit) -> 'a option -> 'b option -> unit
+
+(** [map f x] is [None] if [x] is [None] and [Some (f y)] if [x] is [Some y]. *)
+val map : ('a -> 'b) -> 'a option -> 'b option
+
+(** [smartmap f x] does the same as [map f x] except that it tries to share
+ some memory. *)
+val smartmap : ('a -> 'a) -> 'a option -> 'a option
+
+(** [fold_left f a x] is [f a y] if [x] is [Some y], and [a] otherwise. *)
+val fold_left : ('b -> 'a -> 'b) -> 'b -> 'a option -> 'b
+
+(** [fold_left2 f a x y] is [f z w] if [x] is [Some z] and [y] is [Some w].
+ It is [a] if both [x] and [y] are [None].
+ @raise Heterogeneous otherwise. *)
+val fold_left2 : ('a -> 'b -> 'c -> 'a) -> 'a -> 'b option -> 'c option -> 'a
+
+(** [fold_right f x a] is [f y a] if [x] is [Some y], and [a] otherwise. *)
+val fold_right : ('a -> 'b -> 'b) -> 'a option -> 'b -> 'b
+
+(** [fold_left_map f a x] is [a, f y] if [x] is [Some y], and [a] otherwise. *)
+val fold_left_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b option -> 'a * 'c option
+
+(** Same as [fold_left_map] on the right *)
+val fold_right_map : ('b -> 'a -> 'c * 'a) -> 'b option -> 'a -> 'c option * 'a
+
+(** @deprecated Same as [fold_left_map] *)
+val fold_map : ('a -> 'b -> 'a * 'c) -> 'a -> 'b option -> 'a * 'c option
+[@@ocaml.deprecated "Same as [fold_left_map]"]
+
+(** [cata f e x] is [e] if [x] is [None] and [f a] if [x] is [Some a] *)
+val cata : ('a -> 'b) -> 'b -> 'a option -> 'b
+
+(** {6 More Specific Operations} *)
+
+(** [default a x] is [y] if [x] is [Some y] and [a] otherwise. *)
+val default : 'a -> 'a option -> 'a
+
+(** [lift] is the same as {!map}. *)
+val lift : ('a -> 'b) -> 'a option -> 'b option
+
+(** [lift_right f a x] is [Some (f a y)] if [x] is [Some y], and
+ [None] otherwise. *)
+val lift_right : ('a -> 'b -> 'c) -> 'a -> 'b option -> 'c option
+
+(** [lift_left f x a] is [Some (f y a)] if [x] is [Some y], and
+ [None] otherwise. *)
+val lift_left : ('a -> 'b -> 'c) -> 'a option -> 'b -> 'c option
+
+(** [lift2 f x y] is [Some (f z w)] if [x] equals [Some z] and [y] equals
+ [Some w]. It is [None] otherwise. *)
+val lift2 : ('a -> 'b -> 'c) -> 'a option -> 'b option -> 'c option
+
+
+(** {6 Operations with Lists} *)
+
+module List : sig
+ (** [List.cons x l] equals [y::l] if [x] is [Some y] and [l] otherwise. *)
+ val cons : 'a option -> 'a list -> 'a list
+
+ (** [List.flatten l] is the list of all the [y]s such that [l] contains
+ [Some y] (in the same order). *)
+ val flatten : 'a option list -> 'a list
+
+ (** [List.find f l] is the first [f a] different from [None],
+ scrolling through elements [a] of [l] in left-to-right order;
+ it is [None] if no such element exists. *)
+ val find : ('a -> 'b option) -> 'a list -> 'b option
+
+ (** [List.map f [a1;...;an]] is the list [Some [b1;...;bn]] if
+ for all i, there is a [bi] such that [f ai] is [Some bi]; it is
+ [None] if, for at least one i, [f ai] is [None]. *)
+ val map : ('a -> 'b option) -> 'a list -> 'b list option
+
+end
diff --git a/clib/orderedType.ml b/clib/orderedType.ml
new file mode 100644
index 00000000..922eb76a
--- /dev/null
+++ b/clib/orderedType.ml
@@ -0,0 +1,35 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type S =
+sig
+ type t
+ val compare : t -> t -> int
+end
+
+module Pair (M:S) (N:S) = struct
+ type t = M.t * N.t
+
+ let compare (a,b) (a',b') =
+ let i = M.compare a a' in
+ if Int.equal i 0 then N.compare b b'
+ else i
+end
+
+module UnorderedPair (M:S) = struct
+ type t = M.t * M.t
+
+ let reorder (a,b as p) =
+ if M.compare a b <= 0 then p else (b,a)
+
+ let compare p p' =
+ let p = reorder p and p' = reorder p' in
+ let module P = Pair(M)(M) in P.compare p p'
+end
diff --git a/clib/orderedType.mli b/clib/orderedType.mli
new file mode 100644
index 00000000..3578ea0d
--- /dev/null
+++ b/clib/orderedType.mli
@@ -0,0 +1,19 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type S =
+sig
+ type t
+ val compare : t -> t -> int
+end
+
+module Pair (M:S) (N:S) : S with type t = M.t * N.t
+
+module UnorderedPair (M:S) : S with type t = M.t * M.t
diff --git a/clib/predicate.ml b/clib/predicate.ml
new file mode 100644
index 00000000..1aa7db6a
--- /dev/null
+++ b/clib/predicate.ml
@@ -0,0 +1,98 @@
+(************************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the GNU Library General Public License. *)
+(* *)
+(************************************************************************)
+
+module type OrderedType =
+ sig
+ type t
+ val compare: t -> t -> int
+ end
+
+module type S =
+ sig
+ type elt
+ type t
+ val empty: t
+ val full: t
+ val is_empty: t -> bool
+ val is_full: t -> bool
+ val mem: elt -> t -> bool
+ val singleton: elt -> t
+ val add: elt -> t -> t
+ val remove: elt -> t -> t
+ val union: t -> t -> t
+ val inter: t -> t -> t
+ val diff: t -> t -> t
+ val complement: t -> t
+ val equal: t -> t -> bool
+ val subset: t -> t -> bool
+ val elements: t -> bool * elt list
+ end
+
+module Make(Ord: OrderedType) =
+ struct
+ module EltSet = Set.Make(Ord)
+
+ type elt = Ord.t
+
+ (* (false, s) represents a set which is equal to the set s
+ (true, s) represents a set which is equal to the complement of set s *)
+ type t = bool * EltSet.t
+
+ let elements (b,s) = (b, EltSet.elements s)
+
+ let empty = (false,EltSet.empty)
+ let full = (true,EltSet.empty)
+
+ (* assumes the set is infinite *)
+ let is_empty (b,s) = not b && EltSet.is_empty s
+ let is_full (b,s) = b && EltSet.is_empty s
+
+ let mem x (b,s) =
+ if b then not (EltSet.mem x s) else EltSet.mem x s
+
+ let singleton x = (false,EltSet.singleton x)
+
+ let add x (b,s) =
+ if b then (b,EltSet.remove x s)
+ else (b,EltSet.add x s)
+
+ let remove x (b,s) =
+ if b then (b,EltSet.add x s)
+ else (b,EltSet.remove x s)
+
+ let complement (b,s) = (not b, s)
+
+ let union s1 s2 =
+ match (s1,s2) with
+ ((false,p1),(false,p2)) -> (false,EltSet.union p1 p2)
+ | ((true,n1),(true,n2)) -> (true,EltSet.inter n1 n2)
+ | ((false,p1),(true,n2)) -> (true,EltSet.diff n2 p1)
+ | ((true,n1),(false,p2)) -> (true,EltSet.diff n1 p2)
+
+ let inter s1 s2 =
+ complement (union (complement s1) (complement s2))
+
+ let diff s1 s2 = inter s1 (complement s2)
+
+ (* assumes the set is infinite *)
+ let subset s1 s2 =
+ match (s1,s2) with
+ ((false,p1),(false,p2)) -> EltSet.subset p1 p2
+ | ((true,n1),(true,n2)) -> EltSet.subset n2 n1
+ | ((false,p1),(true,n2)) -> EltSet.is_empty (EltSet.inter p1 n2)
+ | ((true,_),(false,_)) -> false
+
+ (* assumes the set is infinite *)
+ let equal (b1,s1) (b2,s2) =
+ b1=b2 && EltSet.equal s1 s2
+
+ end
diff --git a/clib/predicate.mli b/clib/predicate.mli
new file mode 100644
index 00000000..cee3b0bd
--- /dev/null
+++ b/clib/predicate.mli
@@ -0,0 +1,84 @@
+(** Infinite sets over a chosen [OrderedType].
+
+ All operations over sets are purely applicative (no side-effects).
+ *)
+
+(** Input signature of the functor [Make]. *)
+module type OrderedType =
+ sig
+ type t
+ (** The type of the elements in the set.
+
+ The chosen [t] {b must be infinite}. *)
+
+ val compare : t -> t -> int
+ (** A total ordering function over the set elements.
+ This is a two-argument function [f] such that:
+ - [f e1 e2] is zero if the elements [e1] and [e2] are equal,
+ - [f e1 e2] is strictly negative if [e1] is smaller than [e2],
+ - and [f e1 e2] is strictly positive if [e1] is greater than [e2].
+ *)
+ end
+
+module type S =
+ sig
+ type elt
+ (** The type of the elements in the set. *)
+
+ type t
+ (** The type of sets. *)
+
+ val empty: t
+ (** The empty set. *)
+
+ val full: t
+ (** The set of all elements (of type [elm]). *)
+
+ val is_empty: t -> bool
+ (** Test whether a set is empty or not. *)
+
+ val is_full: t -> bool
+ (** Test whether a set contains the whole type or not. *)
+
+ val mem: elt -> t -> bool
+ (** [mem x s] tests whether [x] belongs to the set [s]. *)
+
+ val singleton: elt -> t
+ (** [singleton x] returns the one-element set containing only [x]. *)
+
+ val add: elt -> t -> t
+ (** [add x s] returns a set containing all elements of [s],
+ plus [x]. If [x] was already in [s], then [s] is returned unchanged. *)
+
+ val remove: elt -> t -> t
+ (** [remove x s] returns a set containing all elements of [s],
+ except [x]. If [x] was not in [s], then [s] is returned unchanged. *)
+
+ val union: t -> t -> t
+ (** Set union. *)
+
+ val inter: t -> t -> t
+ (** Set intersection. *)
+
+ val diff: t -> t -> t
+ (** Set difference. *)
+
+ val complement: t -> t
+ (** Set complement. *)
+
+ val equal: t -> t -> bool
+ (** [equal s1 s2] tests whether the sets [s1] and [s2] are
+ equal, that is, contain equal elements. *)
+
+ val subset: t -> t -> bool
+ (** [subset s1 s2] tests whether the set [s1] is a subset of
+ the set [s2]. *)
+
+ val elements: t -> bool * elt list
+ (** Gives a finite representation of the predicate: if the
+ boolean is false, then the predicate is given in extension.
+ if it is true, then the complement is given *)
+ end
+
+(** The [Make] functor constructs an implementation for any [OrderedType]. *)
+module Make (Ord : OrderedType) : (S with type elt = Ord.t)
diff --git a/clib/range.ml b/clib/range.ml
new file mode 100644
index 00000000..7271514f
--- /dev/null
+++ b/clib/range.ml
@@ -0,0 +1,93 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type 'a tree =
+| Leaf of 'a
+| Node of 'a * 'a tree * 'a tree
+
+type 'a t = Nil | Cons of int * 'a tree * 'a t
+
+let oob () = invalid_arg "index out of bounds"
+
+let empty = Nil
+
+let cons x l = match l with
+| Cons (h1, t1, Cons (h2, t2, rem)) ->
+ if Int.equal h1 h2 then Cons (1 + h1 + h2, Node (x, t1, t2), rem)
+ else Cons (1, Leaf x, l)
+| _ -> Cons (1, Leaf x, l)
+
+let is_empty = function
+| Nil -> true
+| _ -> false
+
+let rec tree_get h t i = match t with
+| Leaf x ->
+ if i = 0 then x else oob ()
+| Node (x, t1, t2) ->
+ if i = 0 then x
+ else
+ let h = h / 2 in
+ if i <= h then tree_get h t1 (i - 1) else tree_get h t2 (i - h - 1)
+
+let rec get l i = match l with
+| Nil -> oob ()
+| Cons (h, t, rem) ->
+ if i < h then tree_get h t i else get rem (i - h)
+
+let length l =
+ let rec length accu = function
+ | Nil -> accu
+ | Cons (h, _, l) -> length (h + accu) l
+ in
+ length 0 l
+
+let rec tree_map f = function
+| Leaf x -> Leaf (f x)
+| Node (x, t1, t2) -> Node (f x, tree_map f t1, tree_map f t2)
+
+let rec map f = function
+| Nil -> Nil
+| Cons (h, t, l) -> Cons (h, tree_map f t, map f l)
+
+let rec tree_fold_left f accu = function
+| Leaf x -> f accu x
+| Node (x, t1, t2) ->
+ tree_fold_left f (tree_fold_left f (f accu x) t1) t2
+
+let rec fold_left f accu = function
+| Nil -> accu
+| Cons (_, t, l) -> fold_left f (tree_fold_left f accu t) l
+
+let rec tree_fold_right f t accu = match t with
+| Leaf x -> f x accu
+| Node (x, t1, t2) ->
+ f x (tree_fold_right f t1 (tree_fold_right f t2 accu))
+
+let rec fold_right f l accu = match l with
+| Nil -> accu
+| Cons (_, t, l) -> tree_fold_right f t (fold_right f l accu)
+
+let hd = function
+| Nil -> failwith "hd"
+| Cons (_, Leaf x, _) -> x
+| Cons (_, Node (x, _, _), _) -> x
+
+let tl = function
+| Nil -> failwith "tl"
+| Cons (_, Leaf _, l) -> l
+| Cons (h, Node (_, t1, t2), l) ->
+ let h = h / 2 in
+ Cons (h, t1, Cons (h, t2, l))
+
+let rec skipn n l =
+ if n = 0 then l
+ else if is_empty l then failwith "List.skipn"
+ else skipn (pred n) (tl l)
diff --git a/clib/range.mli b/clib/range.mli
new file mode 100644
index 00000000..c14b0cf5
--- /dev/null
+++ b/clib/range.mli
@@ -0,0 +1,39 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Skewed lists
+
+ This is a purely functional datastructure isomorphic to usual lists, except
+ that it features a O(log n) lookup while preserving the O(1) cons operation.
+
+*)
+
+(** {5 Constructors} *)
+
+type +'a t
+
+val empty : 'a t
+val cons : 'a -> 'a t -> 'a t
+
+(** {5 List operations} *)
+
+val is_empty : 'a t -> bool
+val length : 'a t -> int
+val map : ('a -> 'b) -> 'a t -> 'b t
+val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'a
+val fold_right : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b
+val hd : 'a t -> 'a
+val tl : 'a t -> 'a t
+
+val skipn : int -> 'a t -> 'a t
+
+(** {5 Indexing operations} *)
+
+val get : 'a t -> int -> 'a
diff --git a/clib/segmenttree.ml b/clib/segmenttree.ml
new file mode 100644
index 00000000..24243b7a
--- /dev/null
+++ b/clib/segmenttree.ml
@@ -0,0 +1,140 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** This module is a very simple implementation of "segment trees".
+
+ A segment tree of type ['a t] represents a mapping from a union of
+ disjoint segments to some values of type 'a.
+*)
+
+(** Misc. functions. *)
+let list_iteri f l =
+ let rec loop i = function
+ | [] -> ()
+ | x :: xs -> f i x; loop (i + 1) xs
+ in
+ loop 0 l
+
+let log2 x = log x /. log 2.
+
+let log2n x = int_of_float (ceil (log2 (float_of_int x)))
+
+(** We focus on integers but this module can be generalized. *)
+type elt = int
+
+(** A value of type [domain] is interpreted differently given its position
+ in the tree. On internal nodes, a domain represents the set of
+ integers which are _not_ in the set of keys handled by the tree. On
+ leaves, a domain represents the st of integers which are in the set of
+ keys. *)
+type domain =
+ (** On internal nodes, a domain [Interval (a, b)] represents
+ the interval [a + 1; b - 1]. On leaves, it represents [a; b].
+ We always have [a] <= [b]. *)
+ | Interval of elt * elt
+ (** On internal node or root, a domain [Universe] represents all
+ the integers. When the tree is not a trivial root,
+ [Universe] has no interpretation on leaves. (The lookup
+ function should never reach the leaves.) *)
+ | Universe
+
+(** We use an array to store the almost complete tree. This array
+ contains at least one element. *)
+type 'a t = (domain * 'a option) array
+
+(** The root is the first item of the array. *)
+
+(** Standard layout for left child. *)
+let left_child i = 2 * i + 1
+
+(** Standard layout for right child. *)
+let right_child i = 2 * i + 2
+
+(** Extract the annotation of a node, be it internal or a leaf. *)
+let value_of i t = match t.(i) with (_, Some x) -> x | _ -> raise Not_found
+
+(** Initialize the array to store [n] leaves. *)
+let create n init =
+ Array.make (1 lsl (log2n n + 1) - 1) init
+
+(** Make a complete interval tree from a list of disjoint segments.
+ Precondition : the segments must be sorted. *)
+let make segments =
+ let nsegments = List.length segments in
+ let tree = create nsegments (Universe, None) in
+ let leaves_offset = (1 lsl (log2n nsegments)) - 1 in
+
+ (** The algorithm proceeds in two steps using an intermediate tree
+ to store minimum and maximum of each subtree as annotation of
+ the node. *)
+
+ (** We start from leaves: the last level of the tree is initialized
+ with the given segments... *)
+ list_iteri
+ (fun i ((start, stop), value) ->
+ let k = leaves_offset + i in
+ let i = Interval (start, stop) in
+ tree.(k) <- (i, Some i))
+ segments;
+ (** ... the remaining leaves are initialized with neutral information. *)
+ for k = leaves_offset + nsegments to Array.length tree -1 do
+ tree.(k) <- (Universe, Some Universe)
+ done;
+
+ (** We traverse the tree bottom-up and compute the interval and
+ annotation associated to each node from the annotations of its
+ children. *)
+ for k = leaves_offset - 1 downto 0 do
+ let node, annotation =
+ match value_of (left_child k) tree, value_of (right_child k) tree with
+ | Interval (left_min, left_max), Interval (right_min, right_max) ->
+ (Interval (left_max, right_min), Interval (left_min, right_max))
+ | Interval (min, max), Universe ->
+ (Interval (max, max), Interval (min, max))
+ | Universe, Universe -> Universe, Universe
+ | Universe, _ -> assert false
+ in
+ tree.(k) <- (node, Some annotation)
+ done;
+
+ (** Finally, annotation are replaced with the image related to each leaf. *)
+ let final_tree =
+ Array.mapi (fun i (segment, value) -> (segment, None)) tree
+ in
+ list_iteri
+ (fun i ((start, stop), value) ->
+ final_tree.(leaves_offset + i)
+ <- (Interval (start, stop), Some value))
+ segments;
+ final_tree
+
+(** [lookup k t] looks for an image for key [k] in the interval tree [t].
+ Raise [Not_found] if it fails. *)
+let lookup k t =
+ let i = ref 0 in
+ while (snd t.(!i) = None) do
+ match fst t.(!i) with
+ | Interval (start, stop) ->
+ if k <= start then i := left_child !i
+ else if k >= stop then i:= right_child !i
+ else raise Not_found
+ | Universe -> raise Not_found
+ done;
+ match fst t.(!i) with
+ | Interval (start, stop) ->
+ if k >= start && k <= stop then
+ match snd t.(!i) with
+ | Some v -> v
+ | None -> assert false
+ else
+ raise Not_found
+ | Universe -> assert false
+
+
diff --git a/clib/segmenttree.mli b/clib/segmenttree.mli
new file mode 100644
index 00000000..63c968f5
--- /dev/null
+++ b/clib/segmenttree.mli
@@ -0,0 +1,30 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** This module is a very simple implementation of "segment trees".
+
+ A segment tree of type ['a t] represents a mapping from a union of
+ disjoint segments to some values of type 'a.
+*)
+
+(** A mapping from a union of disjoint segments to some values of type ['a]. *)
+type 'a t
+
+(** [make [(i1, j1), v1; (i2, j2), v2; ...]] creates a mapping that
+ associates to every integer [x] the value [v1] if [i1 <= x <= j1],
+ [v2] if [i2 <= x <= j2], and so one.
+ Precondition: the segments must be sorted. *)
+val make : ((int * int) * 'a) list -> 'a t
+
+(** [lookup k t] looks for an image for key [k] in the interval tree [t].
+ Raise [Not_found] if it fails. *)
+val lookup : int -> 'a t -> 'a
+
+
diff --git a/clib/store.ml b/clib/store.ml
new file mode 100644
index 00000000..1469358c
--- /dev/null
+++ b/clib/store.ml
@@ -0,0 +1,89 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** This module implements an "untyped store", in this particular case
+ we see it as an extensible record whose fields are left
+ unspecified. ***)
+
+(** We use a dynamic "name" allocator. But if we needed to serialise
+ stores, we might want something static to avoid troubles with
+ plugins order. *)
+
+module type S =
+sig
+ type t
+ type 'a field
+ val empty : t
+ val set : t -> 'a field -> 'a -> t
+ val get : t -> 'a field -> 'a option
+ val remove : t -> 'a field -> t
+ val merge : t -> t -> t
+ val field : unit -> 'a field
+end
+
+module Make () : S =
+struct
+
+ let next =
+ let count = ref 0 in fun () ->
+ let n = !count in
+ incr count;
+ n
+
+ type t = Obj.t option array
+ (** Store are represented as arrays. For small values, which is typicial,
+ is slightly quicker than other implementations. *)
+
+type 'a field = int
+
+let allocate len : t = Array.make len None
+
+let empty : t = [||]
+
+let set (s : t) (i : 'a field) (v : 'a) : t =
+ let len = Array.length s in
+ let nlen = if i < len then len else succ i in
+ let () = assert (0 <= i) in
+ let ans = allocate nlen in
+ Array.blit s 0 ans 0 len;
+ Array.unsafe_set ans i (Some (Obj.repr v));
+ ans
+
+let get (s : t) (i : 'a field) : 'a option =
+ let len = Array.length s in
+ if len <= i then None
+ else Obj.magic (Array.unsafe_get s i)
+
+let remove (s : t) (i : 'a field) =
+ let len = Array.length s in
+ let () = assert (0 <= i) in
+ let ans = allocate len in
+ Array.blit s 0 ans 0 len;
+ if i < len then Array.unsafe_set ans i None;
+ ans
+
+let merge (s1 : t) (s2 : t) : t =
+ let len1 = Array.length s1 in
+ let len2 = Array.length s2 in
+ let nlen = if len1 < len2 then len2 else len1 in
+ let ans = allocate nlen in
+ (** Important: No more allocation from here. *)
+ Array.blit s2 0 ans 0 len2;
+ for i = 0 to pred len1 do
+ let v = Array.unsafe_get s1 i in
+ match v with
+ | None -> ()
+ | Some _ -> Array.unsafe_set ans i v
+ done;
+ ans
+
+let field () = next ()
+
+end
diff --git a/clib/store.mli b/clib/store.mli
new file mode 100644
index 00000000..0c2b2e08
--- /dev/null
+++ b/clib/store.mli
@@ -0,0 +1,43 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(*** This module implements an "untyped store", in this particular case we
+ see it as an extensible record whose fields are left unspecified. ***)
+
+module type S =
+sig
+ type t
+ (** Type of stores *)
+
+ type 'a field
+ (** Type of field of such stores *)
+
+ val empty : t
+ (** Empty store *)
+
+ val set : t -> 'a field -> 'a -> t
+ (** Set a field *)
+
+ val get : t -> 'a field -> 'a option
+ (** Get the value of a field, if any *)
+
+ val remove : t -> 'a field -> t
+ (** Unset the value of the field *)
+
+ val merge : t -> t -> t
+ (** [merge s1 s2] adds all the fields of [s1] into [s2]. *)
+
+ val field : unit -> 'a field
+ (** Create a new field *)
+
+end
+
+module Make () : S
+(** Create a new store type. *)
diff --git a/clib/terminal.ml b/clib/terminal.ml
new file mode 100644
index 00000000..1d946813
--- /dev/null
+++ b/clib/terminal.ml
@@ -0,0 +1,300 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type color = [
+ `DEFAULT
+| `BLACK
+| `RED
+| `GREEN
+| `YELLOW
+| `BLUE
+| `MAGENTA
+| `CYAN
+| `WHITE
+| `LIGHT_BLACK
+| `LIGHT_RED
+| `LIGHT_GREEN
+| `LIGHT_YELLOW
+| `LIGHT_BLUE
+| `LIGHT_MAGENTA
+| `LIGHT_CYAN
+| `LIGHT_WHITE
+| `INDEX of int
+| `RGB of (int * int * int)
+]
+
+type style = {
+ fg_color : color option;
+ bg_color : color option;
+ bold : bool option;
+ italic : bool option;
+ underline : bool option;
+ negative : bool option;
+ prefix : string option;
+ suffix : string option;
+}
+
+let set o1 o2 = match o1 with
+| None -> o2
+| Some _ ->
+ match o2 with
+ | None -> o1
+ | Some _ -> o2
+
+let default = {
+ fg_color = None;
+ bg_color = None;
+ bold = None;
+ italic = None;
+ underline = None;
+ negative = None;
+ prefix = None;
+ suffix = None;
+}
+
+let make ?fg_color ?bg_color ?bold ?italic ?underline ?negative ?style ?prefix ?suffix () =
+ let st = match style with
+ | None -> default
+ | Some st -> st
+ in
+ {
+ fg_color = set st.fg_color fg_color;
+ bg_color = set st.bg_color bg_color;
+ bold = set st.bold bold;
+ italic = set st.italic italic;
+ underline = set st.underline underline;
+ negative = set st.negative negative;
+ prefix = set st.prefix prefix;
+ suffix = set st.suffix suffix;
+ }
+
+let merge s1 s2 =
+ {
+ fg_color = set s1.fg_color s2.fg_color;
+ bg_color = set s1.bg_color s2.bg_color;
+ bold = set s1.bold s2.bold;
+ italic = set s1.italic s2.italic;
+ underline = set s1.underline s2.underline;
+ negative = set s1.negative s2.negative;
+ prefix = set s1.prefix s2.prefix;
+ suffix = set s1.suffix s2.suffix;
+ }
+
+let base_color = function
+| `DEFAULT -> 9
+| `BLACK -> 0
+| `RED -> 1
+| `GREEN -> 2
+| `YELLOW -> 3
+| `BLUE -> 4
+| `MAGENTA -> 5
+| `CYAN -> 6
+| `WHITE -> 7
+| `LIGHT_BLACK -> 0
+| `LIGHT_RED -> 1
+| `LIGHT_GREEN -> 2
+| `LIGHT_YELLOW -> 3
+| `LIGHT_BLUE -> 4
+| `LIGHT_MAGENTA -> 5
+| `LIGHT_CYAN -> 6
+| `LIGHT_WHITE -> 7
+| _ -> invalid_arg "base_color"
+
+let extended_color off = function
+| `INDEX i -> [off + 8; 5; i]
+| `RGB (r, g, b) -> [off + 8; 2; r; g; b]
+| _ -> invalid_arg "extended_color"
+
+let is_light = function
+| `LIGHT_BLACK
+| `LIGHT_RED
+| `LIGHT_GREEN
+| `LIGHT_YELLOW
+| `LIGHT_BLUE
+| `LIGHT_MAGENTA
+| `LIGHT_CYAN
+| `LIGHT_WHITE -> true
+| _ -> false
+
+let is_extended = function
+| `INDEX _ | `RGB _ -> true
+| _ -> false
+
+let repr st =
+ let fg = match st.fg_color with
+ | None -> []
+ | Some c ->
+ if is_light c then [90 + base_color c]
+ else if is_extended c then extended_color 30 c
+ else [30 + base_color c]
+ in
+ let bg = match st.bg_color with
+ | None -> []
+ | Some c ->
+ if is_light c then [100 + base_color c]
+ else if is_extended c then extended_color 40 c
+ else [40 + base_color c]
+ in
+ let bold = match st.bold with
+ | None -> []
+ | Some true -> [1]
+ | Some false -> [22]
+ in
+ let italic = match st.italic with
+ | None -> []
+ | Some true -> [3]
+ | Some false -> [23]
+ in
+ let underline = match st.underline with
+ | None -> []
+ | Some true -> [4]
+ | Some false -> [24]
+ in
+ let negative = match st.negative with
+ | None -> []
+ | Some true -> [7]
+ | Some false -> [27]
+ in
+ fg @ bg @ bold @ italic @ underline @ negative
+
+let eval st =
+ let tags = repr st in
+ let tags = List.map string_of_int tags in
+ Printf.sprintf "\027[%sm" (String.concat ";" tags)
+
+let reset = "\027[0m"
+
+let reset_style = {
+ fg_color = Some `DEFAULT;
+ bg_color = Some `DEFAULT;
+ bold = Some false;
+ italic = Some false;
+ underline = Some false;
+ negative = Some false;
+ prefix = None;
+ suffix = None;
+}
+
+let has_style t =
+ Unix.isatty t && Sys.os_type = "Unix"
+
+let split c s =
+ let len = String.length s in
+ let rec split n =
+ try
+ let pos = String.index_from s n c in
+ let dir = String.sub s n (pos-n) in
+ dir :: split (succ pos)
+ with
+ | Not_found -> [String.sub s n (len-n)]
+ in
+ if len = 0 then [] else split 0
+
+let check_char i = if i < 0 || i > 255 then invalid_arg "check_char"
+
+let parse_color off rem = match off with
+| 0 -> (`BLACK, rem)
+| 1 -> (`RED, rem)
+| 2 -> (`GREEN, rem)
+| 3 -> (`YELLOW, rem)
+| 4 -> (`BLUE, rem)
+| 5 -> (`MAGENTA, rem)
+| 6 -> (`CYAN, rem)
+| 7 -> (`WHITE, rem)
+| 9 -> (`DEFAULT, rem)
+| 8 ->
+ begin match rem with
+ | 5 :: i :: rem ->
+ check_char i;
+ (`INDEX i, rem)
+ | 2 :: r :: g :: b :: rem ->
+ check_char r;
+ check_char g;
+ check_char b;
+ (`RGB (r, g, b), rem)
+ | _ -> invalid_arg "parse_color"
+ end
+| _ -> invalid_arg "parse_color"
+
+let set_light = function
+| `BLACK -> `LIGHT_BLACK
+| `RED -> `LIGHT_RED
+| `GREEN -> `LIGHT_GREEN
+| `YELLOW -> `LIGHT_YELLOW
+| `BLUE -> `LIGHT_BLUE
+| `MAGENTA -> `LIGHT_MAGENTA
+| `CYAN -> `LIGHT_CYAN
+| `WHITE -> `LIGHT_WHITE
+| _ -> invalid_arg "parse_color"
+
+let rec parse_style style = function
+| [] -> style
+| 0 :: rem ->
+ let style = merge style reset_style in
+ parse_style style rem
+| 1 :: rem ->
+ let style = make ~style ~bold:true () in
+ parse_style style rem
+| 3 :: rem ->
+ let style = make ~style ~italic:true () in
+ parse_style style rem
+| 4 :: rem ->
+ let style = make ~style ~underline:true () in
+ parse_style style rem
+| 7 :: rem ->
+ let style = make ~style ~negative:true () in
+ parse_style style rem
+| 22 :: rem ->
+ let style = make ~style ~bold:false () in
+ parse_style style rem
+| 23 :: rem ->
+ let style = make ~style ~italic:false () in
+ parse_style style rem
+| 24 :: rem ->
+ let style = make ~style ~underline:false () in
+ parse_style style rem
+| 27 :: rem ->
+ let style = make ~style ~negative:false () in
+ parse_style style rem
+| code :: rem when (30 <= code && code < 40) ->
+ let color, rem = parse_color (code mod 10) rem in
+ let style = make ~style ~fg_color:color () in
+ parse_style style rem
+| code :: rem when (40 <= code && code < 50) ->
+ let color, rem = parse_color (code mod 10) rem in
+ let style = make ~style ~bg_color:color () in
+ parse_style style rem
+| code :: rem when (90 <= code && code < 100) ->
+ let color, rem = parse_color (code mod 10) rem in
+ let style = make ~style ~fg_color:(set_light color) () in
+ parse_style style rem
+| code :: rem when (100 <= code && code < 110) ->
+ let color, rem = parse_color (code mod 10) rem in
+ let style = make ~style ~bg_color:(set_light color) () in
+ parse_style style rem
+| _ :: rem -> parse_style style rem
+
+(** Parse LS_COLORS-like strings *)
+let parse s =
+ let defs = split ':' s in
+ let fold accu s = match split '=' s with
+ | [name; attrs] ->
+ let attrs = split ';' attrs in
+ let accu =
+ try
+ let attrs = List.map int_of_string attrs in
+ let attrs = parse_style (make ()) attrs in
+ (name, attrs) :: accu
+ with _ -> accu
+ in
+ accu
+ | _ -> accu
+ in
+ List.fold_left fold [] defs
diff --git a/clib/terminal.mli b/clib/terminal.mli
new file mode 100644
index 00000000..dbf8d464
--- /dev/null
+++ b/clib/terminal.mli
@@ -0,0 +1,69 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+type color = [
+ `DEFAULT
+| `BLACK
+| `RED
+| `GREEN
+| `YELLOW
+| `BLUE
+| `MAGENTA
+| `CYAN
+| `WHITE
+| `LIGHT_BLACK
+| `LIGHT_RED
+| `LIGHT_GREEN
+| `LIGHT_YELLOW
+| `LIGHT_BLUE
+| `LIGHT_MAGENTA
+| `LIGHT_CYAN
+| `LIGHT_WHITE
+| `INDEX of int
+| `RGB of (int * int * int)
+]
+
+type style = {
+ fg_color : color option;
+ bg_color : color option;
+ bold : bool option;
+ italic : bool option;
+ underline : bool option;
+ negative : bool option;
+ prefix : string option;
+ suffix : string option;
+}
+
+val make : ?fg_color:color -> ?bg_color:color ->
+ ?bold:bool -> ?italic:bool -> ?underline:bool ->
+ ?negative:bool -> ?style:style ->
+ ?prefix:string -> ?suffix:string -> unit -> style
+(** Create a style from the given flags. It is derived from the optional
+ [style] argument if given. *)
+
+val merge : style -> style -> style
+(** [merge s1 s2] returns [s1] with all defined values of [s2] overwritten. *)
+
+val repr : style -> int list
+(** Generate the ANSI code representing the given style. *)
+
+val eval : style -> string
+(** Generate an escape sequence from a style. *)
+
+val reset : string
+(** This escape sequence resets all attributes. *)
+
+val has_style : Unix.file_descr -> bool
+(** Whether an output file descriptor handles styles. Very heuristic, only
+ checks it is a terminal. *)
+
+val parse : string -> (string * style) list
+(** Parse strings describing terminal styles in the LS_COLORS syntax. For
+ robustness, ignore meaningless entries and drops undefined styles. *)
diff --git a/clib/trie.ml b/clib/trie.ml
new file mode 100644
index 00000000..ea43e9e0
--- /dev/null
+++ b/clib/trie.ml
@@ -0,0 +1,91 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+module type S =
+sig
+ type label
+ type data
+ type t
+ val empty : t
+ val get : t -> data
+ val next : t -> label -> t
+ val labels : t -> label list
+ val add : label list -> data -> t -> t
+ val remove : label list -> data -> t -> t
+ val iter : (label list -> data -> unit) -> t -> unit
+end
+
+module type Grp =
+sig
+ type t
+ val nil : t
+ val is_nil : t -> bool
+ val add : t -> t -> t
+ val sub : t -> t -> t
+end
+
+module Make (Y : Map.OrderedType) (X : Grp) =
+struct
+
+module T_codom = Map.Make(Y)
+
+type data = X.t
+type label = Y.t
+type t = Node of X.t * t T_codom.t
+
+let codom_for_all f m =
+ let fold key v accu = f v && accu in
+ T_codom.fold fold m true
+
+let empty = Node (X.nil, T_codom.empty)
+
+let next (Node (_,m)) lbl = T_codom.find lbl m
+
+let get (Node (hereset,_)) = hereset
+
+let labels (Node (_,m)) =
+ (** FIXME: this is order-dependent. Try to find a more robust presentation? *)
+ List.rev (T_codom.fold (fun x _ acc -> x::acc) m [])
+
+let is_empty_node (Node(a,b)) = (X.is_nil a) && (T_codom.is_empty b)
+
+let assure_arc m lbl =
+ if T_codom.mem lbl m then
+ m
+ else
+ T_codom.add lbl (Node (X.nil,T_codom.empty)) m
+
+let cleanse_arcs (Node (hereset,m)) =
+ let m = if codom_for_all is_empty_node m then T_codom.empty else m in
+ Node(hereset, m)
+
+let rec at_path f (Node (hereset,m)) = function
+ | [] ->
+ cleanse_arcs (Node(f hereset,m))
+ | h::t ->
+ let m = assure_arc m h in
+ cleanse_arcs (Node(hereset,
+ T_codom.add h (at_path f (T_codom.find h m) t) m))
+
+let add path v tm =
+ at_path (fun hereset -> X.add v hereset) tm path
+
+let remove path v tm =
+ at_path (fun hereset -> X.sub hereset v) tm path
+
+let iter f tlm =
+ let rec apprec pfx (Node(hereset,m)) =
+ let path = List.rev pfx in
+ f path hereset;
+ T_codom.iter (fun l tm -> apprec (l::pfx) tm) m
+ in
+ apprec [] tlm
+
+end
diff --git a/clib/trie.mli b/clib/trie.mli
new file mode 100644
index 00000000..dae346d3
--- /dev/null
+++ b/clib/trie.mli
@@ -0,0 +1,63 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Generic functorized trie data structure. *)
+
+module type S =
+sig
+ (** A trie is a generalization of the map data structure where the keys are
+ themselves lists. *)
+
+ type label
+ (** Keys of the trie structure are [label list]. *)
+
+ type data
+ (** Data on nodes of tries are finite sets of [data]. *)
+
+ type t
+ (** The trie data structure. Essentially a finite map with keys [label list]
+ and content [data Set.t]. *)
+
+ val empty : t
+ (** The empty trie. *)
+
+ val get : t -> data
+ (** Get the data at the current node. *)
+
+ val next : t -> label -> t
+ (** [next t lbl] returns the subtrie of [t] pointed by [lbl].
+ @raise Not_found if there is none. *)
+
+ val labels : t -> label list
+ (** Get the list of defined labels at the current node. *)
+
+ val add : label list -> data -> t -> t
+ (** [add t path v] adds [v] at path [path] in [t]. *)
+
+ val remove : label list -> data -> t -> t
+ (** [remove t path v] removes [v] from path [path] in [t]. *)
+
+ val iter : (label list -> data -> unit) -> t -> unit
+ (** Apply a function to all contents. *)
+
+end
+
+module type Grp =
+sig
+ type t
+ val nil : t
+ val is_nil : t -> bool
+ val add : t -> t -> t
+ val sub : t -> t -> t
+end
+
+module Make (Label : Set.OrderedType) (Data : Grp) : S
+ with type label = Label.t and type data = Data.t
+(** Generating functor, for a given type of labels and data. *)
diff --git a/clib/unicode.ml b/clib/unicode.ml
new file mode 100644
index 00000000..1e45c0d2
--- /dev/null
+++ b/clib/unicode.ml
@@ -0,0 +1,387 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Unicode utilities *)
+
+type status = Letter | IdentPart | Symbol | IdentSep | Unknown
+
+(* The following table stores classes of Unicode characters that
+ are used by the lexer. There are 5 different classes so 3 bits
+ are allocated for each character. We encode the masks of 8
+ characters per word, thus using 24 bits over the 31 available
+ bits. (This choice seems to be a good trade-off between speed
+ and space after some benchmarks.) *)
+
+(* A 256 KiB table, initially filled with zeros. *)
+let table = Array.make (1 lsl 17) 0
+
+(* Associate a 2-bit pattern to each status at position [i].
+ Only the 3 lowest bits of [i] are taken into account to
+ define the position of the pattern in the word.
+ Notice that pattern "00" means "undefined". *)
+let mask i = function
+ | Letter -> 1 lsl ((i land 7) * 3) (* 001 *)
+ | IdentPart -> 2 lsl ((i land 7) * 3) (* 010 *)
+ | Symbol -> 3 lsl ((i land 7) * 3) (* 011 *)
+ | IdentSep -> 4 lsl ((i land 7) * 3) (* 100 *)
+ | Unknown -> 0 lsl ((i land 7) * 3) (* 000 *)
+
+(* Helper to reset 3 bits in a word. *)
+let reset_mask i =
+ lnot (7 lsl ((i land 7) * 3))
+
+(* Initialize the lookup table from a list of segments, assigning
+ a status to every character of each segment. The order of these
+ assignments is relevant: it is possible to assign status [s] to
+ a segment [(c1, c2)] and later assign [s'] to [c] even if [c] is
+ between [c1] and [c2]. *)
+let mk_lookup_table_from_unicode_tables_for status tables =
+ List.iter
+ (List.iter
+ (fun (c1, c2) ->
+ for i = c1 to c2 do
+ table.(i lsr 3) <-
+ (table.(i lsr 3) land (reset_mask i)) lor (mask i status)
+ done))
+ tables
+
+(* Look up into the table and interpret the found pattern. *)
+let lookup x =
+ let v = (table.(x lsr 3) lsr ((x land 7) * 3)) land 7 in
+ if v = 1 then Letter
+ else if v = 2 then IdentPart
+ else if v = 3 then Symbol
+ else if v = 4 then IdentSep
+ else Unknown
+
+(* [classify] discriminates between 5 different kinds of
+ symbols based on the standard unicode classification (extracted from
+ Camomile). *)
+let classify =
+ let single c = [ (c, c) ] in
+ (* General tables. *)
+ mk_lookup_table_from_unicode_tables_for Symbol
+ [
+ Unicodetable.sm; (* Symbol, maths. *)
+ Unicodetable.sc; (* Symbol, currency. *)
+ Unicodetable.so; (* Symbol, modifier. *)
+ Unicodetable.pd; (* Punctuation, dash. *)
+ Unicodetable.pc; (* Punctuation, connector. *)
+ Unicodetable.pe; (* Punctuation, open. *)
+ Unicodetable.ps; (* Punctution, close. *)
+ Unicodetable.pi; (* Punctuation, initial quote. *)
+ Unicodetable.pf; (* Punctuation, final quote. *)
+ Unicodetable.po; (* Punctuation, other. *)
+ ];
+ mk_lookup_table_from_unicode_tables_for Letter
+ [
+ Unicodetable.lu; (* Letter, uppercase. *)
+ Unicodetable.ll; (* Letter, lowercase. *)
+ Unicodetable.lt; (* Letter, titlecase. *)
+ Unicodetable.lo; (* Letter, others. *)
+ ];
+ mk_lookup_table_from_unicode_tables_for IdentPart
+ [
+ Unicodetable.nd; (* Number, decimal digits. *)
+ Unicodetable.nl; (* Number, letter. *)
+ Unicodetable.no; (* Number, other. *)
+ ];
+
+ (* Workaround. Some characters seems to be missing in
+ Camomile's category tables. We add them manually. *)
+ mk_lookup_table_from_unicode_tables_for Letter
+ [
+ [(0x01D00, 0x01D7F)]; (* Phonetic Extensions. *)
+ [(0x01D80, 0x01DBF)]; (* Phonetic Extensions Suppl. *)
+ [(0x01DC0, 0x01DFF)]; (* Combining Diacritical Marks Suppl.*)
+ ];
+
+ (* Exceptions (from a previous version of this function). *)
+ mk_lookup_table_from_unicode_tables_for Symbol
+ [
+ [(0x000B2, 0x000B3)]; (* Superscript 2-3. *)
+ single 0x000B9; (* Superscript 1. *)
+ single 0x02070; (* Superscript 0. *)
+ [(0x02074, 0x02079)]; (* Superscript 4-9. *)
+ single 0x0002E; (* Dot. *)
+ ];
+ mk_lookup_table_from_unicode_tables_for IdentSep
+ [
+ single 0x005F; (* Underscore. *)
+ single 0x00A0; (* Non breaking space. *)
+ ];
+ mk_lookup_table_from_unicode_tables_for IdentPart
+ [
+ single 0x0027; (* Single quote. *)
+ ];
+ (* Lookup *)
+ lookup
+
+exception End_of_input
+
+let utf8_of_unicode n =
+ if n < 128 then
+ String.make 1 (Char.chr n)
+ else
+ let (m,s) = if n < 2048 then (2,192) else if n < 65536 then (3,224) else (4,240) in
+ String.init m (fun i ->
+ let j = (n lsr ((m - 1 - i) * 6)) land 63 in
+ Char.chr (j + if i = 0 then s else 128))
+
+(* If [s] is some UTF-8 encoded string
+ and [i] is a position of some UTF-8 character within [s]
+ then [next_utf8 s i] returns [(j,n)] where:
+ - [j] indicates the position of the next UTF-8 character
+ - [n] represents the UTF-8 character at index [i] *)
+let next_utf8 s i =
+ let err () = invalid_arg "utf8" in
+ let l = String.length s - i in
+ if l = 0 then raise End_of_input
+ else let a = Char.code s.[i] in if a <= 0x7F then
+ 1, a
+ else if a land 0x40 = 0 || l = 1 then err ()
+ else let b = Char.code s.[i+1] in if b land 0xC0 <> 0x80 then err ()
+ else if a land 0x20 = 0 then
+ 2, (a land 0x1F) lsl 6 + (b land 0x3F)
+ else if l = 2 then err ()
+ else let c = Char.code s.[i+2] in if c land 0xC0 <> 0x80 then err ()
+ else if a land 0x10 = 0 then
+ 3, (a land 0x0F) lsl 12 + (b land 0x3F) lsl 6 + (c land 0x3F)
+ else if l = 3 then err ()
+ else let d = Char.code s.[i+3] in if d land 0xC0 <> 0x80 then err ()
+ else if a land 0x08 = 0 then
+ 4, (a land 0x07) lsl 18 + (b land 0x3F) lsl 12 +
+ (c land 0x3F) lsl 6 + (d land 0x3F)
+ else err ()
+
+let is_utf8 s =
+ let rec check i =
+ let (off, _) = next_utf8 s i in
+ check (i + off)
+ in
+ try check 0 with End_of_input -> true | Invalid_argument _ -> false
+
+(* Escape string if it contains non-utf8 characters *)
+
+let escaped_non_utf8 s =
+ let mk_escape x = Printf.sprintf "%%%X" x in
+ let buff = Buffer.create (String.length s * 3) in
+ let rec process_trailing_aux i j =
+ if i = j then i else
+ match String.unsafe_get s i with
+ | '\128'..'\191' -> process_trailing_aux (i+1) j
+ | _ -> i in
+ let process_trailing i n =
+ let j = if i+n-1 >= String.length s then i+1 else process_trailing_aux (i+1) (i+n) in
+ (if j = i+n then
+ Buffer.add_string buff (String.sub s i n)
+ else
+ let v = Array.init (j-i) (fun k -> mk_escape (Char.code s.[i+k])) in
+ Buffer.add_string buff (String.concat "" (Array.to_list v)));
+ j in
+ let rec process i =
+ if i >= String.length s then Buffer.contents buff else
+ let c = String.unsafe_get s i in
+ match c with
+ | '\000'..'\127' -> Buffer.add_char buff c; process (i+1)
+ | '\128'..'\191' | '\248'..'\255' -> Buffer.add_string buff (mk_escape (Char.code c)); process (i+1)
+ | '\192'..'\223' -> process (process_trailing i 2)
+ | '\224'..'\239' -> process (process_trailing i 3)
+ | '\240'..'\247' -> process (process_trailing i 4)
+ in
+ process 0
+
+let escaped_if_non_utf8 s =
+ if is_utf8 s then s else escaped_non_utf8 s
+
+(* Check the well-formedness of an identifier *)
+
+let is_valid_ident_initial = function
+ | Letter | IdentSep -> true
+ | IdentPart | Symbol | Unknown -> false
+
+let initial_refutation j n s =
+ if is_valid_ident_initial (classify n) then None
+ else
+ let c = String.sub s 0 j in
+ Some (false,
+ "Invalid character '"^c^"' at beginning of identifier \""^s^"\".")
+
+let is_valid_ident_trailing = function
+ | Letter | IdentSep | IdentPart -> true
+ | Symbol | Unknown -> false
+
+let trailing_refutation i j n s =
+ if is_valid_ident_trailing (classify n) then None
+ else
+ let c = String.sub s i j in
+ Some (false,
+ "Invalid character '"^c^"' in identifier \""^s^"\".")
+
+let is_unknown = function
+ | Unknown -> true
+ | Letter | IdentSep | IdentPart | Symbol -> false
+
+let is_ident_part = function
+ | IdentPart -> true
+ | Letter | IdentSep | Symbol | Unknown -> false
+
+let is_ident_sep = function
+ | IdentSep -> true
+ | Letter | IdentPart | Symbol | Unknown -> false
+
+let ident_refutation s =
+ if s = ".." then None else try
+ let j, n = next_utf8 s 0 in
+ match initial_refutation j n s with
+ |None ->
+ begin try
+ let rec aux i =
+ let j, n = next_utf8 s i in
+ match trailing_refutation i j n s with
+ |None -> aux (i + j)
+ |x -> x
+ in aux j
+ with End_of_input -> None
+ end
+ |x -> x
+ with
+ | End_of_input -> Some (true,"The empty string is not an identifier.")
+ | Invalid_argument _ -> Some (true,escaped_non_utf8 s^": invalid utf8 sequence.")
+
+let lowercase_unicode =
+ let tree = Segmenttree.make Unicodetable.to_lower in
+ fun unicode ->
+ try
+ match Segmenttree.lookup unicode tree with
+ | `Abs c -> c
+ | `Delta d -> unicode + d
+ with Not_found -> unicode
+
+let lowercase_first_char s =
+ assert (s <> "");
+ let j, n = next_utf8 s 0 in
+ utf8_of_unicode (lowercase_unicode n)
+
+let split_at_first_letter s =
+ let n, v = next_utf8 s 0 in
+ if ((* optim *) n = 1 && s.[0] != '_') || not (is_ident_sep (classify v)) then None
+ else begin
+ let n = ref n in
+ let p = ref 0 in
+ while !n < String.length s &&
+ let n', v = next_utf8 s !n in
+ p := n';
+ (* Test if not letter *)
+ ((* optim *) n' = 1 && (s.[!n] = '_' || s.[!n] = '\''))
+ || let st = classify v in
+ is_ident_sep st || is_ident_part st
+ do n := !n + !p
+ done;
+ let s1 = String.sub s 0 !n in
+ let s2 = String.sub s !n (String.length s - !n) in
+ Some (s1,s2)
+ end
+
+(** For extraction, we need to encode unicode character into ascii ones *)
+
+let is_basic_ascii s =
+ let ok = ref true in
+ String.iter (fun c -> if Char.code c >= 128 then ok := false) s;
+ !ok
+
+let ascii_of_ident s =
+ let len = String.length s in
+ let has_UU i =
+ i+2 < len && s.[i]='_' && s.[i+1]='U' && s.[i+2]='U'
+ in
+ let i = ref 0 in
+ while !i < len && Char.code s.[!i] < 128 && not (has_UU !i) do
+ incr i
+ done;
+ if !i = len then s else
+ let out = Buffer.create (2*len) in
+ Buffer.add_substring out s 0 !i;
+ while !i < len do
+ let j, n = next_utf8 s !i in
+ if n >= 128 then
+ (Printf.bprintf out "_UU%04x_" n; i := !i + j)
+ else if has_UU !i then
+ (Buffer.add_string out "_UUU"; i := !i + 3)
+ else
+ (Buffer.add_char out s.[!i]; incr i)
+ done;
+ Buffer.contents out
+
+(* Compute length of an UTF-8 encoded string
+ Rem 1 : utf8_length <= String.length (equal if pure ascii)
+ Rem 2 : if used for an iso8859_1 encoded string, the result is
+ wrong in very rare cases. Such a wrong case corresponds to any
+ sequence of a character in range 192..253 immediately followed by a
+ character in range 128..191 (typical case in french is "déçu" which
+ is counted 3 instead of 4); then no real harm to use always
+ utf8_length even if using an iso8859_1 encoding *)
+
+(** FIXME: duplicate code with Pp *)
+
+let utf8_length s =
+ let len = String.length s
+ and cnt = ref 0
+ and nc = ref 0
+ and p = ref 0 in
+ while !p < len do
+ begin
+ match s.[!p] with
+ | '\000'..'\127' -> nc := 0 (* ascii char *)
+ | '\128'..'\191' -> nc := 0 (* cannot start with a continuation byte *)
+ | '\192'..'\223' -> nc := 1 (* expect 1 continuation byte *)
+ | '\224'..'\239' -> nc := 2 (* expect 2 continuation bytes *)
+ | '\240'..'\247' -> nc := 3 (* expect 3 continuation bytes *)
+ | '\248'..'\255' -> nc := 0 (* invalid byte *)
+ end ;
+ incr p ;
+ while !p < len && !nc > 0 do
+ match s.[!p] with
+ | '\128'..'\191' (* next continuation byte *) -> incr p ; decr nc
+ | _ (* not a continuation byte *) -> nc := 0
+ done ;
+ incr cnt
+ done ;
+ !cnt
+
+(* Variant of String.sub for UTF8 character positions *)
+let utf8_sub s start_u len_u =
+ let len_b = String.length s
+ and end_u = start_u + len_u
+ and cnt = ref 0
+ and nc = ref 0
+ and p = ref 0 in
+ let start_b = ref len_b in
+ while !p < len_b && !cnt < end_u do
+ if !cnt <= start_u then start_b := !p ;
+ begin
+ match s.[!p] with
+ | '\000'..'\127' -> nc := 0 (* ascii char *)
+ | '\128'..'\191' -> nc := 0 (* cannot start with a continuation byte *)
+ | '\192'..'\223' -> nc := 1 (* expect 1 continuation byte *)
+ | '\224'..'\239' -> nc := 2 (* expect 2 continuation bytes *)
+ | '\240'..'\247' -> nc := 3 (* expect 3 continuation bytes *)
+ | '\248'..'\255' -> nc := 0 (* invalid byte *)
+ end ;
+ incr p ;
+ while !p < len_b && !nc > 0 do
+ match s.[!p] with
+ | '\128'..'\191' (* next continuation byte *) -> incr p ; decr nc
+ | _ (* not a continuation byte *) -> nc := 0
+ done ;
+ incr cnt
+ done ;
+ let end_b = !p in
+ String.sub s !start_b (end_b - !start_b)
diff --git a/clib/unicode.mli b/clib/unicode.mli
new file mode 100644
index 00000000..23e168cd
--- /dev/null
+++ b/clib/unicode.mli
@@ -0,0 +1,60 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** Unicode utilities *)
+
+type status
+
+(** Classify a unicode char into 3 classes or unknown. *)
+val classify : int -> status
+
+(** Return [None] if a given string can be used as a (Coq) identifier.
+ Return [Some (b,s)] otherwise, where [s] is an explanation and [b] is severity. *)
+val ident_refutation : string -> (bool * string) option
+
+(** Tells if a valid initial character for an identifier *)
+val is_valid_ident_initial : status -> bool
+
+(** Tells if a valid non-initial character for an identifier *)
+val is_valid_ident_trailing : status -> bool
+
+(** Tells if a character is unclassified *)
+val is_unknown : status -> bool
+
+(** First char of a string, converted to lowercase
+ @raise Assert_failure if the input string is empty. *)
+val lowercase_first_char : string -> string
+
+(** Split a string supposed to be an ident at the first letter;
+ as an optimization, return None if the first character is a letter *)
+val split_at_first_letter : string -> (string * string) option
+
+(** Return [true] if all UTF-8 characters in the input string are just plain
+ ASCII characters. Returns [false] otherwise. *)
+val is_basic_ascii : string -> bool
+
+(** [ascii_of_ident s] maps UTF-8 string to a string composed solely from ASCII
+ characters. The non-ASCII characters are translated to ["_UUxxxx_"] where
+ {i xxxx} is the Unicode index of the character in hexadecimal (from four
+ to six hex digits). To avoid potential name clashes, any preexisting
+ substring ["_UU"] is turned into ["_UUU"]. *)
+val ascii_of_ident : string -> string
+
+(** Validate an UTF-8 string *)
+val is_utf8 : string -> bool
+
+(** Return the length of a valid UTF-8 string. *)
+val utf8_length : string -> int
+
+(** Variant of {!String.sub} for UTF-8 strings. *)
+val utf8_sub : string -> int -> int -> string
+
+(** Return a "%XX"-escaped string if it contains non UTF-8 characters. *)
+val escaped_if_non_utf8 : string -> string
diff --git a/clib/unicodetable.ml b/clib/unicodetable.ml
new file mode 100644
index 00000000..b607058c
--- /dev/null
+++ b/clib/unicodetable.ml
@@ -0,0 +1,7427 @@
+(** Unicode tables generated using UUCD. *)
+
+(* Letter, Uppercase *)
+let lu = [
+ (0x00041,0x0005A);
+ (0x000C0,0x000D6);
+ (0x000D8,0x000DE);
+ (0x00100,0x00100);
+ (0x00102,0x00102);
+ (0x00104,0x00104);
+ (0x00106,0x00106);
+ (0x00108,0x00108);
+ (0x0010A,0x0010A);
+ (0x0010C,0x0010C);
+ (0x0010E,0x0010E);
+ (0x00110,0x00110);
+ (0x00112,0x00112);
+ (0x00114,0x00114);
+ (0x00116,0x00116);
+ (0x00118,0x00118);
+ (0x0011A,0x0011A);
+ (0x0011C,0x0011C);
+ (0x0011E,0x0011E);
+ (0x00120,0x00120);
+ (0x00122,0x00122);
+ (0x00124,0x00124);
+ (0x00126,0x00126);
+ (0x00128,0x00128);
+ (0x0012A,0x0012A);
+ (0x0012C,0x0012C);
+ (0x0012E,0x0012E);
+ (0x00130,0x00130);
+ (0x00132,0x00132);
+ (0x00134,0x00134);
+ (0x00136,0x00136);
+ (0x00139,0x00139);
+ (0x0013B,0x0013B);
+ (0x0013D,0x0013D);
+ (0x0013F,0x0013F);
+ (0x00141,0x00141);
+ (0x00143,0x00143);
+ (0x00145,0x00145);
+ (0x00147,0x00147);
+ (0x0014A,0x0014A);
+ (0x0014C,0x0014C);
+ (0x0014E,0x0014E);
+ (0x00150,0x00150);
+ (0x00152,0x00152);
+ (0x00154,0x00154);
+ (0x00156,0x00156);
+ (0x00158,0x00158);
+ (0x0015A,0x0015A);
+ (0x0015C,0x0015C);
+ (0x0015E,0x0015E);
+ (0x00160,0x00160);
+ (0x00162,0x00162);
+ (0x00164,0x00164);
+ (0x00166,0x00166);
+ (0x00168,0x00168);
+ (0x0016A,0x0016A);
+ (0x0016C,0x0016C);
+ (0x0016E,0x0016E);
+ (0x00170,0x00170);
+ (0x00172,0x00172);
+ (0x00174,0x00174);
+ (0x00176,0x00176);
+ (0x00178,0x00179);
+ (0x0017B,0x0017B);
+ (0x0017D,0x0017D);
+ (0x00181,0x00182);
+ (0x00184,0x00184);
+ (0x00186,0x00187);
+ (0x00189,0x0018B);
+ (0x0018E,0x00191);
+ (0x00193,0x00194);
+ (0x00196,0x00198);
+ (0x0019C,0x0019D);
+ (0x0019F,0x001A0);
+ (0x001A2,0x001A2);
+ (0x001A4,0x001A4);
+ (0x001A6,0x001A7);
+ (0x001A9,0x001A9);
+ (0x001AC,0x001AC);
+ (0x001AE,0x001AF);
+ (0x001B1,0x001B3);
+ (0x001B5,0x001B5);
+ (0x001B7,0x001B8);
+ (0x001BC,0x001BC);
+ (0x001C4,0x001C4);
+ (0x001C7,0x001C7);
+ (0x001CA,0x001CA);
+ (0x001CD,0x001CD);
+ (0x001CF,0x001CF);
+ (0x001D1,0x001D1);
+ (0x001D3,0x001D3);
+ (0x001D5,0x001D5);
+ (0x001D7,0x001D7);
+ (0x001D9,0x001D9);
+ (0x001DB,0x001DB);
+ (0x001DE,0x001DE);
+ (0x001E0,0x001E0);
+ (0x001E2,0x001E2);
+ (0x001E4,0x001E4);
+ (0x001E6,0x001E6);
+ (0x001E8,0x001E8);
+ (0x001EA,0x001EA);
+ (0x001EC,0x001EC);
+ (0x001EE,0x001EE);
+ (0x001F1,0x001F1);
+ (0x001F4,0x001F4);
+ (0x001F6,0x001F8);
+ (0x001FA,0x001FA);
+ (0x001FC,0x001FC);
+ (0x001FE,0x001FE);
+ (0x00200,0x00200);
+ (0x00202,0x00202);
+ (0x00204,0x00204);
+ (0x00206,0x00206);
+ (0x00208,0x00208);
+ (0x0020A,0x0020A);
+ (0x0020C,0x0020C);
+ (0x0020E,0x0020E);
+ (0x00210,0x00210);
+ (0x00212,0x00212);
+ (0x00214,0x00214);
+ (0x00216,0x00216);
+ (0x00218,0x00218);
+ (0x0021A,0x0021A);
+ (0x0021C,0x0021C);
+ (0x0021E,0x0021E);
+ (0x00220,0x00220);
+ (0x00222,0x00222);
+ (0x00224,0x00224);
+ (0x00226,0x00226);
+ (0x00228,0x00228);
+ (0x0022A,0x0022A);
+ (0x0022C,0x0022C);
+ (0x0022E,0x0022E);
+ (0x00230,0x00230);
+ (0x00232,0x00232);
+ (0x0023A,0x0023B);
+ (0x0023D,0x0023E);
+ (0x00241,0x00241);
+ (0x00243,0x00246);
+ (0x00248,0x00248);
+ (0x0024A,0x0024A);
+ (0x0024C,0x0024C);
+ (0x0024E,0x0024E);
+ (0x00370,0x00370);
+ (0x00372,0x00372);
+ (0x00376,0x00376);
+ (0x0037F,0x0037F);
+ (0x00386,0x00386);
+ (0x00388,0x0038A);
+ (0x0038C,0x0038C);
+ (0x0038E,0x0038F);
+ (0x00391,0x003A1);
+ (0x003A3,0x003AB);
+ (0x003CF,0x003CF);
+ (0x003D2,0x003D4);
+ (0x003D8,0x003D8);
+ (0x003DA,0x003DA);
+ (0x003DC,0x003DC);
+ (0x003DE,0x003DE);
+ (0x003E0,0x003E0);
+ (0x003E2,0x003E2);
+ (0x003E4,0x003E4);
+ (0x003E6,0x003E6);
+ (0x003E8,0x003E8);
+ (0x003EA,0x003EA);
+ (0x003EC,0x003EC);
+ (0x003EE,0x003EE);
+ (0x003F4,0x003F4);
+ (0x003F7,0x003F7);
+ (0x003F9,0x003FA);
+ (0x003FD,0x0042F);
+ (0x00460,0x00460);
+ (0x00462,0x00462);
+ (0x00464,0x00464);
+ (0x00466,0x00466);
+ (0x00468,0x00468);
+ (0x0046A,0x0046A);
+ (0x0046C,0x0046C);
+ (0x0046E,0x0046E);
+ (0x00470,0x00470);
+ (0x00472,0x00472);
+ (0x00474,0x00474);
+ (0x00476,0x00476);
+ (0x00478,0x00478);
+ (0x0047A,0x0047A);
+ (0x0047C,0x0047C);
+ (0x0047E,0x0047E);
+ (0x00480,0x00480);
+ (0x0048A,0x0048A);
+ (0x0048C,0x0048C);
+ (0x0048E,0x0048E);
+ (0x00490,0x00490);
+ (0x00492,0x00492);
+ (0x00494,0x00494);
+ (0x00496,0x00496);
+ (0x00498,0x00498);
+ (0x0049A,0x0049A);
+ (0x0049C,0x0049C);
+ (0x0049E,0x0049E);
+ (0x004A0,0x004A0);
+ (0x004A2,0x004A2);
+ (0x004A4,0x004A4);
+ (0x004A6,0x004A6);
+ (0x004A8,0x004A8);
+ (0x004AA,0x004AA);
+ (0x004AC,0x004AC);
+ (0x004AE,0x004AE);
+ (0x004B0,0x004B0);
+ (0x004B2,0x004B2);
+ (0x004B4,0x004B4);
+ (0x004B6,0x004B6);
+ (0x004B8,0x004B8);
+ (0x004BA,0x004BA);
+ (0x004BC,0x004BC);
+ (0x004BE,0x004BE);
+ (0x004C0,0x004C1);
+ (0x004C3,0x004C3);
+ (0x004C5,0x004C5);
+ (0x004C7,0x004C7);
+ (0x004C9,0x004C9);
+ (0x004CB,0x004CB);
+ (0x004CD,0x004CD);
+ (0x004D0,0x004D0);
+ (0x004D2,0x004D2);
+ (0x004D4,0x004D4);
+ (0x004D6,0x004D6);
+ (0x004D8,0x004D8);
+ (0x004DA,0x004DA);
+ (0x004DC,0x004DC);
+ (0x004DE,0x004DE);
+ (0x004E0,0x004E0);
+ (0x004E2,0x004E2);
+ (0x004E4,0x004E4);
+ (0x004E6,0x004E6);
+ (0x004E8,0x004E8);
+ (0x004EA,0x004EA);
+ (0x004EC,0x004EC);
+ (0x004EE,0x004EE);
+ (0x004F0,0x004F0);
+ (0x004F2,0x004F2);
+ (0x004F4,0x004F4);
+ (0x004F6,0x004F6);
+ (0x004F8,0x004F8);
+ (0x004FA,0x004FA);
+ (0x004FC,0x004FC);
+ (0x004FE,0x004FE);
+ (0x00500,0x00500);
+ (0x00502,0x00502);
+ (0x00504,0x00504);
+ (0x00506,0x00506);
+ (0x00508,0x00508);
+ (0x0050A,0x0050A);
+ (0x0050C,0x0050C);
+ (0x0050E,0x0050E);
+ (0x00510,0x00510);
+ (0x00512,0x00512);
+ (0x00514,0x00514);
+ (0x00516,0x00516);
+ (0x00518,0x00518);
+ (0x0051A,0x0051A);
+ (0x0051C,0x0051C);
+ (0x0051E,0x0051E);
+ (0x00520,0x00520);
+ (0x00522,0x00522);
+ (0x00524,0x00524);
+ (0x00526,0x00526);
+ (0x00528,0x00528);
+ (0x0052A,0x0052A);
+ (0x0052C,0x0052C);
+ (0x0052E,0x0052E);
+ (0x00531,0x00556);
+ (0x010A0,0x010C5);
+ (0x010C7,0x010C7);
+ (0x010CD,0x010CD);
+ (0x013A0,0x013F5);
+ (0x01E00,0x01E00);
+ (0x01E02,0x01E02);
+ (0x01E04,0x01E04);
+ (0x01E06,0x01E06);
+ (0x01E08,0x01E08);
+ (0x01E0A,0x01E0A);
+ (0x01E0C,0x01E0C);
+ (0x01E0E,0x01E0E);
+ (0x01E10,0x01E10);
+ (0x01E12,0x01E12);
+ (0x01E14,0x01E14);
+ (0x01E16,0x01E16);
+ (0x01E18,0x01E18);
+ (0x01E1A,0x01E1A);
+ (0x01E1C,0x01E1C);
+ (0x01E1E,0x01E1E);
+ (0x01E20,0x01E20);
+ (0x01E22,0x01E22);
+ (0x01E24,0x01E24);
+ (0x01E26,0x01E26);
+ (0x01E28,0x01E28);
+ (0x01E2A,0x01E2A);
+ (0x01E2C,0x01E2C);
+ (0x01E2E,0x01E2E);
+ (0x01E30,0x01E30);
+ (0x01E32,0x01E32);
+ (0x01E34,0x01E34);
+ (0x01E36,0x01E36);
+ (0x01E38,0x01E38);
+ (0x01E3A,0x01E3A);
+ (0x01E3C,0x01E3C);
+ (0x01E3E,0x01E3E);
+ (0x01E40,0x01E40);
+ (0x01E42,0x01E42);
+ (0x01E44,0x01E44);
+ (0x01E46,0x01E46);
+ (0x01E48,0x01E48);
+ (0x01E4A,0x01E4A);
+ (0x01E4C,0x01E4C);
+ (0x01E4E,0x01E4E);
+ (0x01E50,0x01E50);
+ (0x01E52,0x01E52);
+ (0x01E54,0x01E54);
+ (0x01E56,0x01E56);
+ (0x01E58,0x01E58);
+ (0x01E5A,0x01E5A);
+ (0x01E5C,0x01E5C);
+ (0x01E5E,0x01E5E);
+ (0x01E60,0x01E60);
+ (0x01E62,0x01E62);
+ (0x01E64,0x01E64);
+ (0x01E66,0x01E66);
+ (0x01E68,0x01E68);
+ (0x01E6A,0x01E6A);
+ (0x01E6C,0x01E6C);
+ (0x01E6E,0x01E6E);
+ (0x01E70,0x01E70);
+ (0x01E72,0x01E72);
+ (0x01E74,0x01E74);
+ (0x01E76,0x01E76);
+ (0x01E78,0x01E78);
+ (0x01E7A,0x01E7A);
+ (0x01E7C,0x01E7C);
+ (0x01E7E,0x01E7E);
+ (0x01E80,0x01E80);
+ (0x01E82,0x01E82);
+ (0x01E84,0x01E84);
+ (0x01E86,0x01E86);
+ (0x01E88,0x01E88);
+ (0x01E8A,0x01E8A);
+ (0x01E8C,0x01E8C);
+ (0x01E8E,0x01E8E);
+ (0x01E90,0x01E90);
+ (0x01E92,0x01E92);
+ (0x01E94,0x01E94);
+ (0x01E9E,0x01E9E);
+ (0x01EA0,0x01EA0);
+ (0x01EA2,0x01EA2);
+ (0x01EA4,0x01EA4);
+ (0x01EA6,0x01EA6);
+ (0x01EA8,0x01EA8);
+ (0x01EAA,0x01EAA);
+ (0x01EAC,0x01EAC);
+ (0x01EAE,0x01EAE);
+ (0x01EB0,0x01EB0);
+ (0x01EB2,0x01EB2);
+ (0x01EB4,0x01EB4);
+ (0x01EB6,0x01EB6);
+ (0x01EB8,0x01EB8);
+ (0x01EBA,0x01EBA);
+ (0x01EBC,0x01EBC);
+ (0x01EBE,0x01EBE);
+ (0x01EC0,0x01EC0);
+ (0x01EC2,0x01EC2);
+ (0x01EC4,0x01EC4);
+ (0x01EC6,0x01EC6);
+ (0x01EC8,0x01EC8);
+ (0x01ECA,0x01ECA);
+ (0x01ECC,0x01ECC);
+ (0x01ECE,0x01ECE);
+ (0x01ED0,0x01ED0);
+ (0x01ED2,0x01ED2);
+ (0x01ED4,0x01ED4);
+ (0x01ED6,0x01ED6);
+ (0x01ED8,0x01ED8);
+ (0x01EDA,0x01EDA);
+ (0x01EDC,0x01EDC);
+ (0x01EDE,0x01EDE);
+ (0x01EE0,0x01EE0);
+ (0x01EE2,0x01EE2);
+ (0x01EE4,0x01EE4);
+ (0x01EE6,0x01EE6);
+ (0x01EE8,0x01EE8);
+ (0x01EEA,0x01EEA);
+ (0x01EEC,0x01EEC);
+ (0x01EEE,0x01EEE);
+ (0x01EF0,0x01EF0);
+ (0x01EF2,0x01EF2);
+ (0x01EF4,0x01EF4);
+ (0x01EF6,0x01EF6);
+ (0x01EF8,0x01EF8);
+ (0x01EFA,0x01EFA);
+ (0x01EFC,0x01EFC);
+ (0x01EFE,0x01EFE);
+ (0x01F08,0x01F0F);
+ (0x01F18,0x01F1D);
+ (0x01F28,0x01F2F);
+ (0x01F38,0x01F3F);
+ (0x01F48,0x01F4D);
+ (0x01F59,0x01F59);
+ (0x01F5B,0x01F5B);
+ (0x01F5D,0x01F5D);
+ (0x01F5F,0x01F5F);
+ (0x01F68,0x01F6F);
+ (0x01FB8,0x01FBB);
+ (0x01FC8,0x01FCB);
+ (0x01FD8,0x01FDB);
+ (0x01FE8,0x01FEC);
+ (0x01FF8,0x01FFB);
+ (0x02102,0x02102);
+ (0x02107,0x02107);
+ (0x0210B,0x0210D);
+ (0x02110,0x02112);
+ (0x02115,0x02115);
+ (0x02119,0x0211D);
+ (0x02124,0x02124);
+ (0x02126,0x02126);
+ (0x02128,0x02128);
+ (0x0212A,0x0212D);
+ (0x02130,0x02133);
+ (0x0213E,0x0213F);
+ (0x02145,0x02145);
+ (0x02183,0x02183);
+ (0x02C00,0x02C2E);
+ (0x02C60,0x02C60);
+ (0x02C62,0x02C64);
+ (0x02C67,0x02C67);
+ (0x02C69,0x02C69);
+ (0x02C6B,0x02C6B);
+ (0x02C6D,0x02C70);
+ (0x02C72,0x02C72);
+ (0x02C75,0x02C75);
+ (0x02C7E,0x02C80);
+ (0x02C82,0x02C82);
+ (0x02C84,0x02C84);
+ (0x02C86,0x02C86);
+ (0x02C88,0x02C88);
+ (0x02C8A,0x02C8A);
+ (0x02C8C,0x02C8C);
+ (0x02C8E,0x02C8E);
+ (0x02C90,0x02C90);
+ (0x02C92,0x02C92);
+ (0x02C94,0x02C94);
+ (0x02C96,0x02C96);
+ (0x02C98,0x02C98);
+ (0x02C9A,0x02C9A);
+ (0x02C9C,0x02C9C);
+ (0x02C9E,0x02C9E);
+ (0x02CA0,0x02CA0);
+ (0x02CA2,0x02CA2);
+ (0x02CA4,0x02CA4);
+ (0x02CA6,0x02CA6);
+ (0x02CA8,0x02CA8);
+ (0x02CAA,0x02CAA);
+ (0x02CAC,0x02CAC);
+ (0x02CAE,0x02CAE);
+ (0x02CB0,0x02CB0);
+ (0x02CB2,0x02CB2);
+ (0x02CB4,0x02CB4);
+ (0x02CB6,0x02CB6);
+ (0x02CB8,0x02CB8);
+ (0x02CBA,0x02CBA);
+ (0x02CBC,0x02CBC);
+ (0x02CBE,0x02CBE);
+ (0x02CC0,0x02CC0);
+ (0x02CC2,0x02CC2);
+ (0x02CC4,0x02CC4);
+ (0x02CC6,0x02CC6);
+ (0x02CC8,0x02CC8);
+ (0x02CCA,0x02CCA);
+ (0x02CCC,0x02CCC);
+ (0x02CCE,0x02CCE);
+ (0x02CD0,0x02CD0);
+ (0x02CD2,0x02CD2);
+ (0x02CD4,0x02CD4);
+ (0x02CD6,0x02CD6);
+ (0x02CD8,0x02CD8);
+ (0x02CDA,0x02CDA);
+ (0x02CDC,0x02CDC);
+ (0x02CDE,0x02CDE);
+ (0x02CE0,0x02CE0);
+ (0x02CE2,0x02CE2);
+ (0x02CEB,0x02CEB);
+ (0x02CED,0x02CED);
+ (0x02CF2,0x02CF2);
+ (0x0A640,0x0A640);
+ (0x0A642,0x0A642);
+ (0x0A644,0x0A644);
+ (0x0A646,0x0A646);
+ (0x0A648,0x0A648);
+ (0x0A64A,0x0A64A);
+ (0x0A64C,0x0A64C);
+ (0x0A64E,0x0A64E);
+ (0x0A650,0x0A650);
+ (0x0A652,0x0A652);
+ (0x0A654,0x0A654);
+ (0x0A656,0x0A656);
+ (0x0A658,0x0A658);
+ (0x0A65A,0x0A65A);
+ (0x0A65C,0x0A65C);
+ (0x0A65E,0x0A65E);
+ (0x0A660,0x0A660);
+ (0x0A662,0x0A662);
+ (0x0A664,0x0A664);
+ (0x0A666,0x0A666);
+ (0x0A668,0x0A668);
+ (0x0A66A,0x0A66A);
+ (0x0A66C,0x0A66C);
+ (0x0A680,0x0A680);
+ (0x0A682,0x0A682);
+ (0x0A684,0x0A684);
+ (0x0A686,0x0A686);
+ (0x0A688,0x0A688);
+ (0x0A68A,0x0A68A);
+ (0x0A68C,0x0A68C);
+ (0x0A68E,0x0A68E);
+ (0x0A690,0x0A690);
+ (0x0A692,0x0A692);
+ (0x0A694,0x0A694);
+ (0x0A696,0x0A696);
+ (0x0A698,0x0A698);
+ (0x0A69A,0x0A69A);
+ (0x0A722,0x0A722);
+ (0x0A724,0x0A724);
+ (0x0A726,0x0A726);
+ (0x0A728,0x0A728);
+ (0x0A72A,0x0A72A);
+ (0x0A72C,0x0A72C);
+ (0x0A72E,0x0A72E);
+ (0x0A732,0x0A732);
+ (0x0A734,0x0A734);
+ (0x0A736,0x0A736);
+ (0x0A738,0x0A738);
+ (0x0A73A,0x0A73A);
+ (0x0A73C,0x0A73C);
+ (0x0A73E,0x0A73E);
+ (0x0A740,0x0A740);
+ (0x0A742,0x0A742);
+ (0x0A744,0x0A744);
+ (0x0A746,0x0A746);
+ (0x0A748,0x0A748);
+ (0x0A74A,0x0A74A);
+ (0x0A74C,0x0A74C);
+ (0x0A74E,0x0A74E);
+ (0x0A750,0x0A750);
+ (0x0A752,0x0A752);
+ (0x0A754,0x0A754);
+ (0x0A756,0x0A756);
+ (0x0A758,0x0A758);
+ (0x0A75A,0x0A75A);
+ (0x0A75C,0x0A75C);
+ (0x0A75E,0x0A75E);
+ (0x0A760,0x0A760);
+ (0x0A762,0x0A762);
+ (0x0A764,0x0A764);
+ (0x0A766,0x0A766);
+ (0x0A768,0x0A768);
+ (0x0A76A,0x0A76A);
+ (0x0A76C,0x0A76C);
+ (0x0A76E,0x0A76E);
+ (0x0A779,0x0A779);
+ (0x0A77B,0x0A77B);
+ (0x0A77D,0x0A77E);
+ (0x0A780,0x0A780);
+ (0x0A782,0x0A782);
+ (0x0A784,0x0A784);
+ (0x0A786,0x0A786);
+ (0x0A78B,0x0A78B);
+ (0x0A78D,0x0A78D);
+ (0x0A790,0x0A790);
+ (0x0A792,0x0A792);
+ (0x0A796,0x0A796);
+ (0x0A798,0x0A798);
+ (0x0A79A,0x0A79A);
+ (0x0A79C,0x0A79C);
+ (0x0A79E,0x0A79E);
+ (0x0A7A0,0x0A7A0);
+ (0x0A7A2,0x0A7A2);
+ (0x0A7A4,0x0A7A4);
+ (0x0A7A6,0x0A7A6);
+ (0x0A7A8,0x0A7A8);
+ (0x0A7AA,0x0A7AE);
+ (0x0A7B0,0x0A7B4);
+ (0x0A7B6,0x0A7B6);
+ (0x0FF21,0x0FF3A);
+ (0x10400,0x10427);
+ (0x104B0,0x104D3);
+ (0x10C80,0x10CB2);
+ (0x118A0,0x118BF);
+ (0x1D400,0x1D419);
+ (0x1D434,0x1D44D);
+ (0x1D468,0x1D481);
+ (0x1D49C,0x1D49C);
+ (0x1D49E,0x1D49F);
+ (0x1D4A2,0x1D4A2);
+ (0x1D4A5,0x1D4A6);
+ (0x1D4A9,0x1D4AC);
+ (0x1D4AE,0x1D4B5);
+ (0x1D4D0,0x1D4E9);
+ (0x1D504,0x1D505);
+ (0x1D507,0x1D50A);
+ (0x1D50D,0x1D514);
+ (0x1D516,0x1D51C);
+ (0x1D538,0x1D539);
+ (0x1D53B,0x1D53E);
+ (0x1D540,0x1D544);
+ (0x1D546,0x1D546);
+ (0x1D54A,0x1D550);
+ (0x1D56C,0x1D585);
+ (0x1D5A0,0x1D5B9);
+ (0x1D5D4,0x1D5ED);
+ (0x1D608,0x1D621);
+ (0x1D63C,0x1D655);
+ (0x1D670,0x1D689);
+ (0x1D6A8,0x1D6C0);
+ (0x1D6E2,0x1D6FA);
+ (0x1D71C,0x1D734);
+ (0x1D756,0x1D76E);
+ (0x1D790,0x1D7A8);
+ (0x1D7CA,0x1D7CA)
+]
+(* Letter, Lowercase *)
+let ll = [
+ (0x00061,0x0007A);
+ (0x000B5,0x000B5);
+ (0x000DF,0x000F6);
+ (0x000F8,0x000FF);
+ (0x00101,0x00101);
+ (0x00103,0x00103);
+ (0x00105,0x00105);
+ (0x00107,0x00107);
+ (0x00109,0x00109);
+ (0x0010B,0x0010B);
+ (0x0010D,0x0010D);
+ (0x0010F,0x0010F);
+ (0x00111,0x00111);
+ (0x00113,0x00113);
+ (0x00115,0x00115);
+ (0x00117,0x00117);
+ (0x00119,0x00119);
+ (0x0011B,0x0011B);
+ (0x0011D,0x0011D);
+ (0x0011F,0x0011F);
+ (0x00121,0x00121);
+ (0x00123,0x00123);
+ (0x00125,0x00125);
+ (0x00127,0x00127);
+ (0x00129,0x00129);
+ (0x0012B,0x0012B);
+ (0x0012D,0x0012D);
+ (0x0012F,0x0012F);
+ (0x00131,0x00131);
+ (0x00133,0x00133);
+ (0x00135,0x00135);
+ (0x00137,0x00138);
+ (0x0013A,0x0013A);
+ (0x0013C,0x0013C);
+ (0x0013E,0x0013E);
+ (0x00140,0x00140);
+ (0x00142,0x00142);
+ (0x00144,0x00144);
+ (0x00146,0x00146);
+ (0x00148,0x00149);
+ (0x0014B,0x0014B);
+ (0x0014D,0x0014D);
+ (0x0014F,0x0014F);
+ (0x00151,0x00151);
+ (0x00153,0x00153);
+ (0x00155,0x00155);
+ (0x00157,0x00157);
+ (0x00159,0x00159);
+ (0x0015B,0x0015B);
+ (0x0015D,0x0015D);
+ (0x0015F,0x0015F);
+ (0x00161,0x00161);
+ (0x00163,0x00163);
+ (0x00165,0x00165);
+ (0x00167,0x00167);
+ (0x00169,0x00169);
+ (0x0016B,0x0016B);
+ (0x0016D,0x0016D);
+ (0x0016F,0x0016F);
+ (0x00171,0x00171);
+ (0x00173,0x00173);
+ (0x00175,0x00175);
+ (0x00177,0x00177);
+ (0x0017A,0x0017A);
+ (0x0017C,0x0017C);
+ (0x0017E,0x00180);
+ (0x00183,0x00183);
+ (0x00185,0x00185);
+ (0x00188,0x00188);
+ (0x0018C,0x0018D);
+ (0x00192,0x00192);
+ (0x00195,0x00195);
+ (0x00199,0x0019B);
+ (0x0019E,0x0019E);
+ (0x001A1,0x001A1);
+ (0x001A3,0x001A3);
+ (0x001A5,0x001A5);
+ (0x001A8,0x001A8);
+ (0x001AA,0x001AB);
+ (0x001AD,0x001AD);
+ (0x001B0,0x001B0);
+ (0x001B4,0x001B4);
+ (0x001B6,0x001B6);
+ (0x001B9,0x001BA);
+ (0x001BD,0x001BF);
+ (0x001C6,0x001C6);
+ (0x001C9,0x001C9);
+ (0x001CC,0x001CC);
+ (0x001CE,0x001CE);
+ (0x001D0,0x001D0);
+ (0x001D2,0x001D2);
+ (0x001D4,0x001D4);
+ (0x001D6,0x001D6);
+ (0x001D8,0x001D8);
+ (0x001DA,0x001DA);
+ (0x001DC,0x001DD);
+ (0x001DF,0x001DF);
+ (0x001E1,0x001E1);
+ (0x001E3,0x001E3);
+ (0x001E5,0x001E5);
+ (0x001E7,0x001E7);
+ (0x001E9,0x001E9);
+ (0x001EB,0x001EB);
+ (0x001ED,0x001ED);
+ (0x001EF,0x001F0);
+ (0x001F3,0x001F3);
+ (0x001F5,0x001F5);
+ (0x001F9,0x001F9);
+ (0x001FB,0x001FB);
+ (0x001FD,0x001FD);
+ (0x001FF,0x001FF);
+ (0x00201,0x00201);
+ (0x00203,0x00203);
+ (0x00205,0x00205);
+ (0x00207,0x00207);
+ (0x00209,0x00209);
+ (0x0020B,0x0020B);
+ (0x0020D,0x0020D);
+ (0x0020F,0x0020F);
+ (0x00211,0x00211);
+ (0x00213,0x00213);
+ (0x00215,0x00215);
+ (0x00217,0x00217);
+ (0x00219,0x00219);
+ (0x0021B,0x0021B);
+ (0x0021D,0x0021D);
+ (0x0021F,0x0021F);
+ (0x00221,0x00221);
+ (0x00223,0x00223);
+ (0x00225,0x00225);
+ (0x00227,0x00227);
+ (0x00229,0x00229);
+ (0x0022B,0x0022B);
+ (0x0022D,0x0022D);
+ (0x0022F,0x0022F);
+ (0x00231,0x00231);
+ (0x00233,0x00239);
+ (0x0023C,0x0023C);
+ (0x0023F,0x00240);
+ (0x00242,0x00242);
+ (0x00247,0x00247);
+ (0x00249,0x00249);
+ (0x0024B,0x0024B);
+ (0x0024D,0x0024D);
+ (0x0024F,0x00293);
+ (0x00295,0x002AF);
+ (0x00371,0x00371);
+ (0x00373,0x00373);
+ (0x00377,0x00377);
+ (0x0037B,0x0037D);
+ (0x00390,0x00390);
+ (0x003AC,0x003CE);
+ (0x003D0,0x003D1);
+ (0x003D5,0x003D7);
+ (0x003D9,0x003D9);
+ (0x003DB,0x003DB);
+ (0x003DD,0x003DD);
+ (0x003DF,0x003DF);
+ (0x003E1,0x003E1);
+ (0x003E3,0x003E3);
+ (0x003E5,0x003E5);
+ (0x003E7,0x003E7);
+ (0x003E9,0x003E9);
+ (0x003EB,0x003EB);
+ (0x003ED,0x003ED);
+ (0x003EF,0x003F3);
+ (0x003F5,0x003F5);
+ (0x003F8,0x003F8);
+ (0x003FB,0x003FC);
+ (0x00430,0x0045F);
+ (0x00461,0x00461);
+ (0x00463,0x00463);
+ (0x00465,0x00465);
+ (0x00467,0x00467);
+ (0x00469,0x00469);
+ (0x0046B,0x0046B);
+ (0x0046D,0x0046D);
+ (0x0046F,0x0046F);
+ (0x00471,0x00471);
+ (0x00473,0x00473);
+ (0x00475,0x00475);
+ (0x00477,0x00477);
+ (0x00479,0x00479);
+ (0x0047B,0x0047B);
+ (0x0047D,0x0047D);
+ (0x0047F,0x0047F);
+ (0x00481,0x00481);
+ (0x0048B,0x0048B);
+ (0x0048D,0x0048D);
+ (0x0048F,0x0048F);
+ (0x00491,0x00491);
+ (0x00493,0x00493);
+ (0x00495,0x00495);
+ (0x00497,0x00497);
+ (0x00499,0x00499);
+ (0x0049B,0x0049B);
+ (0x0049D,0x0049D);
+ (0x0049F,0x0049F);
+ (0x004A1,0x004A1);
+ (0x004A3,0x004A3);
+ (0x004A5,0x004A5);
+ (0x004A7,0x004A7);
+ (0x004A9,0x004A9);
+ (0x004AB,0x004AB);
+ (0x004AD,0x004AD);
+ (0x004AF,0x004AF);
+ (0x004B1,0x004B1);
+ (0x004B3,0x004B3);
+ (0x004B5,0x004B5);
+ (0x004B7,0x004B7);
+ (0x004B9,0x004B9);
+ (0x004BB,0x004BB);
+ (0x004BD,0x004BD);
+ (0x004BF,0x004BF);
+ (0x004C2,0x004C2);
+ (0x004C4,0x004C4);
+ (0x004C6,0x004C6);
+ (0x004C8,0x004C8);
+ (0x004CA,0x004CA);
+ (0x004CC,0x004CC);
+ (0x004CE,0x004CF);
+ (0x004D1,0x004D1);
+ (0x004D3,0x004D3);
+ (0x004D5,0x004D5);
+ (0x004D7,0x004D7);
+ (0x004D9,0x004D9);
+ (0x004DB,0x004DB);
+ (0x004DD,0x004DD);
+ (0x004DF,0x004DF);
+ (0x004E1,0x004E1);
+ (0x004E3,0x004E3);
+ (0x004E5,0x004E5);
+ (0x004E7,0x004E7);
+ (0x004E9,0x004E9);
+ (0x004EB,0x004EB);
+ (0x004ED,0x004ED);
+ (0x004EF,0x004EF);
+ (0x004F1,0x004F1);
+ (0x004F3,0x004F3);
+ (0x004F5,0x004F5);
+ (0x004F7,0x004F7);
+ (0x004F9,0x004F9);
+ (0x004FB,0x004FB);
+ (0x004FD,0x004FD);
+ (0x004FF,0x004FF);
+ (0x00501,0x00501);
+ (0x00503,0x00503);
+ (0x00505,0x00505);
+ (0x00507,0x00507);
+ (0x00509,0x00509);
+ (0x0050B,0x0050B);
+ (0x0050D,0x0050D);
+ (0x0050F,0x0050F);
+ (0x00511,0x00511);
+ (0x00513,0x00513);
+ (0x00515,0x00515);
+ (0x00517,0x00517);
+ (0x00519,0x00519);
+ (0x0051B,0x0051B);
+ (0x0051D,0x0051D);
+ (0x0051F,0x0051F);
+ (0x00521,0x00521);
+ (0x00523,0x00523);
+ (0x00525,0x00525);
+ (0x00527,0x00527);
+ (0x00529,0x00529);
+ (0x0052B,0x0052B);
+ (0x0052D,0x0052D);
+ (0x0052F,0x0052F);
+ (0x00561,0x00587);
+ (0x013F8,0x013FD);
+ (0x01C80,0x01C88);
+ (0x01D00,0x01D2B);
+ (0x01D6B,0x01D77);
+ (0x01D79,0x01D9A);
+ (0x01E01,0x01E01);
+ (0x01E03,0x01E03);
+ (0x01E05,0x01E05);
+ (0x01E07,0x01E07);
+ (0x01E09,0x01E09);
+ (0x01E0B,0x01E0B);
+ (0x01E0D,0x01E0D);
+ (0x01E0F,0x01E0F);
+ (0x01E11,0x01E11);
+ (0x01E13,0x01E13);
+ (0x01E15,0x01E15);
+ (0x01E17,0x01E17);
+ (0x01E19,0x01E19);
+ (0x01E1B,0x01E1B);
+ (0x01E1D,0x01E1D);
+ (0x01E1F,0x01E1F);
+ (0x01E21,0x01E21);
+ (0x01E23,0x01E23);
+ (0x01E25,0x01E25);
+ (0x01E27,0x01E27);
+ (0x01E29,0x01E29);
+ (0x01E2B,0x01E2B);
+ (0x01E2D,0x01E2D);
+ (0x01E2F,0x01E2F);
+ (0x01E31,0x01E31);
+ (0x01E33,0x01E33);
+ (0x01E35,0x01E35);
+ (0x01E37,0x01E37);
+ (0x01E39,0x01E39);
+ (0x01E3B,0x01E3B);
+ (0x01E3D,0x01E3D);
+ (0x01E3F,0x01E3F);
+ (0x01E41,0x01E41);
+ (0x01E43,0x01E43);
+ (0x01E45,0x01E45);
+ (0x01E47,0x01E47);
+ (0x01E49,0x01E49);
+ (0x01E4B,0x01E4B);
+ (0x01E4D,0x01E4D);
+ (0x01E4F,0x01E4F);
+ (0x01E51,0x01E51);
+ (0x01E53,0x01E53);
+ (0x01E55,0x01E55);
+ (0x01E57,0x01E57);
+ (0x01E59,0x01E59);
+ (0x01E5B,0x01E5B);
+ (0x01E5D,0x01E5D);
+ (0x01E5F,0x01E5F);
+ (0x01E61,0x01E61);
+ (0x01E63,0x01E63);
+ (0x01E65,0x01E65);
+ (0x01E67,0x01E67);
+ (0x01E69,0x01E69);
+ (0x01E6B,0x01E6B);
+ (0x01E6D,0x01E6D);
+ (0x01E6F,0x01E6F);
+ (0x01E71,0x01E71);
+ (0x01E73,0x01E73);
+ (0x01E75,0x01E75);
+ (0x01E77,0x01E77);
+ (0x01E79,0x01E79);
+ (0x01E7B,0x01E7B);
+ (0x01E7D,0x01E7D);
+ (0x01E7F,0x01E7F);
+ (0x01E81,0x01E81);
+ (0x01E83,0x01E83);
+ (0x01E85,0x01E85);
+ (0x01E87,0x01E87);
+ (0x01E89,0x01E89);
+ (0x01E8B,0x01E8B);
+ (0x01E8D,0x01E8D);
+ (0x01E8F,0x01E8F);
+ (0x01E91,0x01E91);
+ (0x01E93,0x01E93);
+ (0x01E95,0x01E9D);
+ (0x01E9F,0x01E9F);
+ (0x01EA1,0x01EA1);
+ (0x01EA3,0x01EA3);
+ (0x01EA5,0x01EA5);
+ (0x01EA7,0x01EA7);
+ (0x01EA9,0x01EA9);
+ (0x01EAB,0x01EAB);
+ (0x01EAD,0x01EAD);
+ (0x01EAF,0x01EAF);
+ (0x01EB1,0x01EB1);
+ (0x01EB3,0x01EB3);
+ (0x01EB5,0x01EB5);
+ (0x01EB7,0x01EB7);
+ (0x01EB9,0x01EB9);
+ (0x01EBB,0x01EBB);
+ (0x01EBD,0x01EBD);
+ (0x01EBF,0x01EBF);
+ (0x01EC1,0x01EC1);
+ (0x01EC3,0x01EC3);
+ (0x01EC5,0x01EC5);
+ (0x01EC7,0x01EC7);
+ (0x01EC9,0x01EC9);
+ (0x01ECB,0x01ECB);
+ (0x01ECD,0x01ECD);
+ (0x01ECF,0x01ECF);
+ (0x01ED1,0x01ED1);
+ (0x01ED3,0x01ED3);
+ (0x01ED5,0x01ED5);
+ (0x01ED7,0x01ED7);
+ (0x01ED9,0x01ED9);
+ (0x01EDB,0x01EDB);
+ (0x01EDD,0x01EDD);
+ (0x01EDF,0x01EDF);
+ (0x01EE1,0x01EE1);
+ (0x01EE3,0x01EE3);
+ (0x01EE5,0x01EE5);
+ (0x01EE7,0x01EE7);
+ (0x01EE9,0x01EE9);
+ (0x01EEB,0x01EEB);
+ (0x01EED,0x01EED);
+ (0x01EEF,0x01EEF);
+ (0x01EF1,0x01EF1);
+ (0x01EF3,0x01EF3);
+ (0x01EF5,0x01EF5);
+ (0x01EF7,0x01EF7);
+ (0x01EF9,0x01EF9);
+ (0x01EFB,0x01EFB);
+ (0x01EFD,0x01EFD);
+ (0x01EFF,0x01F07);
+ (0x01F10,0x01F15);
+ (0x01F20,0x01F27);
+ (0x01F30,0x01F37);
+ (0x01F40,0x01F45);
+ (0x01F50,0x01F57);
+ (0x01F60,0x01F67);
+ (0x01F70,0x01F7D);
+ (0x01F80,0x01F87);
+ (0x01F90,0x01F97);
+ (0x01FA0,0x01FA7);
+ (0x01FB0,0x01FB4);
+ (0x01FB6,0x01FB7);
+ (0x01FBE,0x01FBE);
+ (0x01FC2,0x01FC4);
+ (0x01FC6,0x01FC7);
+ (0x01FD0,0x01FD3);
+ (0x01FD6,0x01FD7);
+ (0x01FE0,0x01FE7);
+ (0x01FF2,0x01FF4);
+ (0x01FF6,0x01FF7);
+ (0x0210A,0x0210A);
+ (0x0210E,0x0210F);
+ (0x02113,0x02113);
+ (0x0212F,0x0212F);
+ (0x02134,0x02134);
+ (0x02139,0x02139);
+ (0x0213C,0x0213D);
+ (0x02146,0x02149);
+ (0x0214E,0x0214E);
+ (0x02184,0x02184);
+ (0x02C30,0x02C5E);
+ (0x02C61,0x02C61);
+ (0x02C65,0x02C66);
+ (0x02C68,0x02C68);
+ (0x02C6A,0x02C6A);
+ (0x02C6C,0x02C6C);
+ (0x02C71,0x02C71);
+ (0x02C73,0x02C74);
+ (0x02C76,0x02C7B);
+ (0x02C81,0x02C81);
+ (0x02C83,0x02C83);
+ (0x02C85,0x02C85);
+ (0x02C87,0x02C87);
+ (0x02C89,0x02C89);
+ (0x02C8B,0x02C8B);
+ (0x02C8D,0x02C8D);
+ (0x02C8F,0x02C8F);
+ (0x02C91,0x02C91);
+ (0x02C93,0x02C93);
+ (0x02C95,0x02C95);
+ (0x02C97,0x02C97);
+ (0x02C99,0x02C99);
+ (0x02C9B,0x02C9B);
+ (0x02C9D,0x02C9D);
+ (0x02C9F,0x02C9F);
+ (0x02CA1,0x02CA1);
+ (0x02CA3,0x02CA3);
+ (0x02CA5,0x02CA5);
+ (0x02CA7,0x02CA7);
+ (0x02CA9,0x02CA9);
+ (0x02CAB,0x02CAB);
+ (0x02CAD,0x02CAD);
+ (0x02CAF,0x02CAF);
+ (0x02CB1,0x02CB1);
+ (0x02CB3,0x02CB3);
+ (0x02CB5,0x02CB5);
+ (0x02CB7,0x02CB7);
+ (0x02CB9,0x02CB9);
+ (0x02CBB,0x02CBB);
+ (0x02CBD,0x02CBD);
+ (0x02CBF,0x02CBF);
+ (0x02CC1,0x02CC1);
+ (0x02CC3,0x02CC3);
+ (0x02CC5,0x02CC5);
+ (0x02CC7,0x02CC7);
+ (0x02CC9,0x02CC9);
+ (0x02CCB,0x02CCB);
+ (0x02CCD,0x02CCD);
+ (0x02CCF,0x02CCF);
+ (0x02CD1,0x02CD1);
+ (0x02CD3,0x02CD3);
+ (0x02CD5,0x02CD5);
+ (0x02CD7,0x02CD7);
+ (0x02CD9,0x02CD9);
+ (0x02CDB,0x02CDB);
+ (0x02CDD,0x02CDD);
+ (0x02CDF,0x02CDF);
+ (0x02CE1,0x02CE1);
+ (0x02CE3,0x02CE4);
+ (0x02CEC,0x02CEC);
+ (0x02CEE,0x02CEE);
+ (0x02CF3,0x02CF3);
+ (0x02D00,0x02D25);
+ (0x02D27,0x02D27);
+ (0x02D2D,0x02D2D);
+ (0x0A641,0x0A641);
+ (0x0A643,0x0A643);
+ (0x0A645,0x0A645);
+ (0x0A647,0x0A647);
+ (0x0A649,0x0A649);
+ (0x0A64B,0x0A64B);
+ (0x0A64D,0x0A64D);
+ (0x0A64F,0x0A64F);
+ (0x0A651,0x0A651);
+ (0x0A653,0x0A653);
+ (0x0A655,0x0A655);
+ (0x0A657,0x0A657);
+ (0x0A659,0x0A659);
+ (0x0A65B,0x0A65B);
+ (0x0A65D,0x0A65D);
+ (0x0A65F,0x0A65F);
+ (0x0A661,0x0A661);
+ (0x0A663,0x0A663);
+ (0x0A665,0x0A665);
+ (0x0A667,0x0A667);
+ (0x0A669,0x0A669);
+ (0x0A66B,0x0A66B);
+ (0x0A66D,0x0A66D);
+ (0x0A681,0x0A681);
+ (0x0A683,0x0A683);
+ (0x0A685,0x0A685);
+ (0x0A687,0x0A687);
+ (0x0A689,0x0A689);
+ (0x0A68B,0x0A68B);
+ (0x0A68D,0x0A68D);
+ (0x0A68F,0x0A68F);
+ (0x0A691,0x0A691);
+ (0x0A693,0x0A693);
+ (0x0A695,0x0A695);
+ (0x0A697,0x0A697);
+ (0x0A699,0x0A699);
+ (0x0A69B,0x0A69B);
+ (0x0A723,0x0A723);
+ (0x0A725,0x0A725);
+ (0x0A727,0x0A727);
+ (0x0A729,0x0A729);
+ (0x0A72B,0x0A72B);
+ (0x0A72D,0x0A72D);
+ (0x0A72F,0x0A731);
+ (0x0A733,0x0A733);
+ (0x0A735,0x0A735);
+ (0x0A737,0x0A737);
+ (0x0A739,0x0A739);
+ (0x0A73B,0x0A73B);
+ (0x0A73D,0x0A73D);
+ (0x0A73F,0x0A73F);
+ (0x0A741,0x0A741);
+ (0x0A743,0x0A743);
+ (0x0A745,0x0A745);
+ (0x0A747,0x0A747);
+ (0x0A749,0x0A749);
+ (0x0A74B,0x0A74B);
+ (0x0A74D,0x0A74D);
+ (0x0A74F,0x0A74F);
+ (0x0A751,0x0A751);
+ (0x0A753,0x0A753);
+ (0x0A755,0x0A755);
+ (0x0A757,0x0A757);
+ (0x0A759,0x0A759);
+ (0x0A75B,0x0A75B);
+ (0x0A75D,0x0A75D);
+ (0x0A75F,0x0A75F);
+ (0x0A761,0x0A761);
+ (0x0A763,0x0A763);
+ (0x0A765,0x0A765);
+ (0x0A767,0x0A767);
+ (0x0A769,0x0A769);
+ (0x0A76B,0x0A76B);
+ (0x0A76D,0x0A76D);
+ (0x0A76F,0x0A76F);
+ (0x0A771,0x0A778);
+ (0x0A77A,0x0A77A);
+ (0x0A77C,0x0A77C);
+ (0x0A77F,0x0A77F);
+ (0x0A781,0x0A781);
+ (0x0A783,0x0A783);
+ (0x0A785,0x0A785);
+ (0x0A787,0x0A787);
+ (0x0A78C,0x0A78C);
+ (0x0A78E,0x0A78E);
+ (0x0A791,0x0A791);
+ (0x0A793,0x0A795);
+ (0x0A797,0x0A797);
+ (0x0A799,0x0A799);
+ (0x0A79B,0x0A79B);
+ (0x0A79D,0x0A79D);
+ (0x0A79F,0x0A79F);
+ (0x0A7A1,0x0A7A1);
+ (0x0A7A3,0x0A7A3);
+ (0x0A7A5,0x0A7A5);
+ (0x0A7A7,0x0A7A7);
+ (0x0A7A9,0x0A7A9);
+ (0x0A7B5,0x0A7B5);
+ (0x0A7B7,0x0A7B7);
+ (0x0A7FA,0x0A7FA);
+ (0x0AB30,0x0AB5A);
+ (0x0AB60,0x0AB65);
+ (0x0AB70,0x0ABBF);
+ (0x0FB00,0x0FB06);
+ (0x0FB13,0x0FB17);
+ (0x0FF41,0x0FF5A);
+ (0x10428,0x1044F);
+ (0x104D8,0x104FB);
+ (0x10CC0,0x10CF2);
+ (0x118C0,0x118DF);
+ (0x1D41A,0x1D433);
+ (0x1D44E,0x1D454);
+ (0x1D456,0x1D467);
+ (0x1D482,0x1D49B);
+ (0x1D4B6,0x1D4B9);
+ (0x1D4BB,0x1D4BB);
+ (0x1D4BD,0x1D4C3);
+ (0x1D4C5,0x1D4CF);
+ (0x1D4EA,0x1D503);
+ (0x1D51E,0x1D537);
+ (0x1D552,0x1D56B);
+ (0x1D586,0x1D59F);
+ (0x1D5BA,0x1D5D3);
+ (0x1D5EE,0x1D607);
+ (0x1D622,0x1D63B);
+ (0x1D656,0x1D66F);
+ (0x1D68A,0x1D6A5);
+ (0x1D6C2,0x1D6DA);
+ (0x1D6DC,0x1D6E1);
+ (0x1D6FC,0x1D714);
+ (0x1D716,0x1D71B);
+ (0x1D736,0x1D74E);
+ (0x1D750,0x1D755);
+ (0x1D770,0x1D788);
+ (0x1D78A,0x1D78F);
+ (0x1D7AA,0x1D7C2);
+ (0x1D7C4,0x1D7C9);
+ (0x1D7CB,0x1D7CB)
+]
+(* Letter, Titlecase *)
+let lt = [
+ (0x001C5,0x001C5);
+ (0x001C8,0x001C8);
+ (0x001CB,0x001CB);
+ (0x001F2,0x001F2);
+ (0x01F88,0x01F8F);
+ (0x01F98,0x01F9F);
+ (0x01FA8,0x01FAF);
+ (0x01FBC,0x01FBC);
+ (0x01FCC,0x01FCC)
+]
+(* Mark, Non-Spacing *)
+let mn = [
+ (0x00300,0x0036F);
+ (0x00483,0x00487);
+ (0x00591,0x005BD);
+ (0x005BF,0x005BF);
+ (0x005C1,0x005C2);
+ (0x005C4,0x005C5);
+ (0x005C7,0x005C7);
+ (0x00610,0x0061A);
+ (0x0064B,0x0065F);
+ (0x00670,0x00670);
+ (0x006D6,0x006DC);
+ (0x006DF,0x006E4);
+ (0x006E7,0x006E8);
+ (0x006EA,0x006ED);
+ (0x00711,0x00711);
+ (0x00730,0x0074A);
+ (0x007A6,0x007B0);
+ (0x007EB,0x007F3);
+ (0x00816,0x00819);
+ (0x0081B,0x00823);
+ (0x00825,0x00827);
+ (0x00829,0x0082D);
+ (0x00859,0x0085B);
+ (0x008D4,0x008E1);
+ (0x008E3,0x00902);
+ (0x0093A,0x0093A);
+ (0x0093C,0x0093C);
+ (0x00941,0x00948);
+ (0x0094D,0x0094D);
+ (0x00951,0x00957);
+ (0x00962,0x00963);
+ (0x00981,0x00981);
+ (0x009BC,0x009BC);
+ (0x009C1,0x009C4);
+ (0x009CD,0x009CD);
+ (0x009E2,0x009E3);
+ (0x00A01,0x00A02);
+ (0x00A3C,0x00A3C);
+ (0x00A41,0x00A42);
+ (0x00A47,0x00A48);
+ (0x00A4B,0x00A4D);
+ (0x00A51,0x00A51);
+ (0x00A70,0x00A71);
+ (0x00A75,0x00A75);
+ (0x00A81,0x00A82);
+ (0x00ABC,0x00ABC);
+ (0x00AC1,0x00AC5);
+ (0x00AC7,0x00AC8);
+ (0x00ACD,0x00ACD);
+ (0x00AE2,0x00AE3);
+ (0x00B01,0x00B01);
+ (0x00B3C,0x00B3C);
+ (0x00B3F,0x00B3F);
+ (0x00B41,0x00B44);
+ (0x00B4D,0x00B4D);
+ (0x00B56,0x00B56);
+ (0x00B62,0x00B63);
+ (0x00B82,0x00B82);
+ (0x00BC0,0x00BC0);
+ (0x00BCD,0x00BCD);
+ (0x00C00,0x00C00);
+ (0x00C3E,0x00C40);
+ (0x00C46,0x00C48);
+ (0x00C4A,0x00C4D);
+ (0x00C55,0x00C56);
+ (0x00C62,0x00C63);
+ (0x00C81,0x00C81);
+ (0x00CBC,0x00CBC);
+ (0x00CBF,0x00CBF);
+ (0x00CC6,0x00CC6);
+ (0x00CCC,0x00CCD);
+ (0x00CE2,0x00CE3);
+ (0x00D01,0x00D01);
+ (0x00D41,0x00D44);
+ (0x00D4D,0x00D4D);
+ (0x00D62,0x00D63);
+ (0x00DCA,0x00DCA);
+ (0x00DD2,0x00DD4);
+ (0x00DD6,0x00DD6);
+ (0x00E31,0x00E31);
+ (0x00E34,0x00E3A);
+ (0x00E47,0x00E4E);
+ (0x00EB1,0x00EB1);
+ (0x00EB4,0x00EB9);
+ (0x00EBB,0x00EBC);
+ (0x00EC8,0x00ECD);
+ (0x00F18,0x00F19);
+ (0x00F35,0x00F35);
+ (0x00F37,0x00F37);
+ (0x00F39,0x00F39);
+ (0x00F71,0x00F7E);
+ (0x00F80,0x00F84);
+ (0x00F86,0x00F87);
+ (0x00F8D,0x00F97);
+ (0x00F99,0x00FBC);
+ (0x00FC6,0x00FC6);
+ (0x0102D,0x01030);
+ (0x01032,0x01037);
+ (0x01039,0x0103A);
+ (0x0103D,0x0103E);
+ (0x01058,0x01059);
+ (0x0105E,0x01060);
+ (0x01071,0x01074);
+ (0x01082,0x01082);
+ (0x01085,0x01086);
+ (0x0108D,0x0108D);
+ (0x0109D,0x0109D);
+ (0x0135D,0x0135F);
+ (0x01712,0x01714);
+ (0x01732,0x01734);
+ (0x01752,0x01753);
+ (0x01772,0x01773);
+ (0x017B4,0x017B5);
+ (0x017B7,0x017BD);
+ (0x017C6,0x017C6);
+ (0x017C9,0x017D3);
+ (0x017DD,0x017DD);
+ (0x0180B,0x0180D);
+ (0x01885,0x01886);
+ (0x018A9,0x018A9);
+ (0x01920,0x01922);
+ (0x01927,0x01928);
+ (0x01932,0x01932);
+ (0x01939,0x0193B);
+ (0x01A17,0x01A18);
+ (0x01A1B,0x01A1B);
+ (0x01A56,0x01A56);
+ (0x01A58,0x01A5E);
+ (0x01A60,0x01A60);
+ (0x01A62,0x01A62);
+ (0x01A65,0x01A6C);
+ (0x01A73,0x01A7C);
+ (0x01A7F,0x01A7F);
+ (0x01AB0,0x01ABD);
+ (0x01B00,0x01B03);
+ (0x01B34,0x01B34);
+ (0x01B36,0x01B3A);
+ (0x01B3C,0x01B3C);
+ (0x01B42,0x01B42);
+ (0x01B6B,0x01B73);
+ (0x01B80,0x01B81);
+ (0x01BA2,0x01BA5);
+ (0x01BA8,0x01BA9);
+ (0x01BAB,0x01BAD);
+ (0x01BE6,0x01BE6);
+ (0x01BE8,0x01BE9);
+ (0x01BED,0x01BED);
+ (0x01BEF,0x01BF1);
+ (0x01C2C,0x01C33);
+ (0x01C36,0x01C37);
+ (0x01CD0,0x01CD2);
+ (0x01CD4,0x01CE0);
+ (0x01CE2,0x01CE8);
+ (0x01CED,0x01CED);
+ (0x01CF4,0x01CF4);
+ (0x01CF8,0x01CF9);
+ (0x01DC0,0x01DF5);
+ (0x01DFB,0x01DFF);
+ (0x020D0,0x020DC);
+ (0x020E1,0x020E1);
+ (0x020E5,0x020F0);
+ (0x02CEF,0x02CF1);
+ (0x02D7F,0x02D7F);
+ (0x02DE0,0x02DFF);
+ (0x0302A,0x0302D);
+ (0x03099,0x0309A);
+ (0x0A66F,0x0A66F);
+ (0x0A674,0x0A67D);
+ (0x0A69E,0x0A69F);
+ (0x0A6F0,0x0A6F1);
+ (0x0A802,0x0A802);
+ (0x0A806,0x0A806);
+ (0x0A80B,0x0A80B);
+ (0x0A825,0x0A826);
+ (0x0A8C4,0x0A8C5);
+ (0x0A8E0,0x0A8F1);
+ (0x0A926,0x0A92D);
+ (0x0A947,0x0A951);
+ (0x0A980,0x0A982);
+ (0x0A9B3,0x0A9B3);
+ (0x0A9B6,0x0A9B9);
+ (0x0A9BC,0x0A9BC);
+ (0x0A9E5,0x0A9E5);
+ (0x0AA29,0x0AA2E);
+ (0x0AA31,0x0AA32);
+ (0x0AA35,0x0AA36);
+ (0x0AA43,0x0AA43);
+ (0x0AA4C,0x0AA4C);
+ (0x0AA7C,0x0AA7C);
+ (0x0AAB0,0x0AAB0);
+ (0x0AAB2,0x0AAB4);
+ (0x0AAB7,0x0AAB8);
+ (0x0AABE,0x0AABF);
+ (0x0AAC1,0x0AAC1);
+ (0x0AAEC,0x0AAED);
+ (0x0AAF6,0x0AAF6);
+ (0x0ABE5,0x0ABE5);
+ (0x0ABE8,0x0ABE8);
+ (0x0ABED,0x0ABED);
+ (0x0FB1E,0x0FB1E);
+ (0x0FE00,0x0FE0F);
+ (0x0FE20,0x0FE2F);
+ (0x101FD,0x101FD);
+ (0x102E0,0x102E0);
+ (0x10376,0x1037A);
+ (0x10A01,0x10A03);
+ (0x10A05,0x10A06);
+ (0x10A0C,0x10A0F);
+ (0x10A38,0x10A3A);
+ (0x10A3F,0x10A3F);
+ (0x10AE5,0x10AE6);
+ (0x11001,0x11001);
+ (0x11038,0x11046);
+ (0x1107F,0x11081);
+ (0x110B3,0x110B6);
+ (0x110B9,0x110BA);
+ (0x11100,0x11102);
+ (0x11127,0x1112B);
+ (0x1112D,0x11134);
+ (0x11173,0x11173);
+ (0x11180,0x11181);
+ (0x111B6,0x111BE);
+ (0x111CA,0x111CC);
+ (0x1122F,0x11231);
+ (0x11234,0x11234);
+ (0x11236,0x11237);
+ (0x1123E,0x1123E);
+ (0x112DF,0x112DF);
+ (0x112E3,0x112EA);
+ (0x11300,0x11301);
+ (0x1133C,0x1133C);
+ (0x11340,0x11340);
+ (0x11366,0x1136C);
+ (0x11370,0x11374);
+ (0x11438,0x1143F);
+ (0x11442,0x11444);
+ (0x11446,0x11446);
+ (0x114B3,0x114B8);
+ (0x114BA,0x114BA);
+ (0x114BF,0x114C0);
+ (0x114C2,0x114C3);
+ (0x115B2,0x115B5);
+ (0x115BC,0x115BD);
+ (0x115BF,0x115C0);
+ (0x115DC,0x115DD);
+ (0x11633,0x1163A);
+ (0x1163D,0x1163D);
+ (0x1163F,0x11640);
+ (0x116AB,0x116AB);
+ (0x116AD,0x116AD);
+ (0x116B0,0x116B5);
+ (0x116B7,0x116B7);
+ (0x1171D,0x1171F);
+ (0x11722,0x11725);
+ (0x11727,0x1172B);
+ (0x11C30,0x11C36);
+ (0x11C38,0x11C3D);
+ (0x11C3F,0x11C3F);
+ (0x11C92,0x11CA7);
+ (0x11CAA,0x11CB0);
+ (0x11CB2,0x11CB3);
+ (0x11CB5,0x11CB6);
+ (0x16AF0,0x16AF4);
+ (0x16B30,0x16B36);
+ (0x16F8F,0x16F92);
+ (0x1BC9D,0x1BC9E);
+ (0x1D167,0x1D169);
+ (0x1D17B,0x1D182);
+ (0x1D185,0x1D18B);
+ (0x1D1AA,0x1D1AD);
+ (0x1D242,0x1D244);
+ (0x1DA00,0x1DA36);
+ (0x1DA3B,0x1DA6C);
+ (0x1DA75,0x1DA75);
+ (0x1DA84,0x1DA84);
+ (0x1DA9B,0x1DA9F);
+ (0x1DAA1,0x1DAAF);
+ (0x1E000,0x1E006);
+ (0x1E008,0x1E018);
+ (0x1E01B,0x1E021);
+ (0x1E023,0x1E024);
+ (0x1E026,0x1E02A);
+ (0x1E8D0,0x1E8D6);
+ (0x1E944,0x1E94A)
+]
+(* Mark, Spacing Combining *)
+let mc = [
+ (0x00903,0x00903);
+ (0x0093B,0x0093B);
+ (0x0093E,0x00940);
+ (0x00949,0x0094C);
+ (0x0094E,0x0094F);
+ (0x00982,0x00983);
+ (0x009BE,0x009C0);
+ (0x009C7,0x009C8);
+ (0x009CB,0x009CC);
+ (0x009D7,0x009D7);
+ (0x00A03,0x00A03);
+ (0x00A3E,0x00A40);
+ (0x00A83,0x00A83);
+ (0x00ABE,0x00AC0);
+ (0x00AC9,0x00AC9);
+ (0x00ACB,0x00ACC);
+ (0x00B02,0x00B03);
+ (0x00B3E,0x00B3E);
+ (0x00B40,0x00B40);
+ (0x00B47,0x00B48);
+ (0x00B4B,0x00B4C);
+ (0x00B57,0x00B57);
+ (0x00BBE,0x00BBF);
+ (0x00BC1,0x00BC2);
+ (0x00BC6,0x00BC8);
+ (0x00BCA,0x00BCC);
+ (0x00BD7,0x00BD7);
+ (0x00C01,0x00C03);
+ (0x00C41,0x00C44);
+ (0x00C82,0x00C83);
+ (0x00CBE,0x00CBE);
+ (0x00CC0,0x00CC4);
+ (0x00CC7,0x00CC8);
+ (0x00CCA,0x00CCB);
+ (0x00CD5,0x00CD6);
+ (0x00D02,0x00D03);
+ (0x00D3E,0x00D40);
+ (0x00D46,0x00D48);
+ (0x00D4A,0x00D4C);
+ (0x00D57,0x00D57);
+ (0x00D82,0x00D83);
+ (0x00DCF,0x00DD1);
+ (0x00DD8,0x00DDF);
+ (0x00DF2,0x00DF3);
+ (0x00F3E,0x00F3F);
+ (0x00F7F,0x00F7F);
+ (0x0102B,0x0102C);
+ (0x01031,0x01031);
+ (0x01038,0x01038);
+ (0x0103B,0x0103C);
+ (0x01056,0x01057);
+ (0x01062,0x01064);
+ (0x01067,0x0106D);
+ (0x01083,0x01084);
+ (0x01087,0x0108C);
+ (0x0108F,0x0108F);
+ (0x0109A,0x0109C);
+ (0x017B6,0x017B6);
+ (0x017BE,0x017C5);
+ (0x017C7,0x017C8);
+ (0x01923,0x01926);
+ (0x01929,0x0192B);
+ (0x01930,0x01931);
+ (0x01933,0x01938);
+ (0x01A19,0x01A1A);
+ (0x01A55,0x01A55);
+ (0x01A57,0x01A57);
+ (0x01A61,0x01A61);
+ (0x01A63,0x01A64);
+ (0x01A6D,0x01A72);
+ (0x01B04,0x01B04);
+ (0x01B35,0x01B35);
+ (0x01B3B,0x01B3B);
+ (0x01B3D,0x01B41);
+ (0x01B43,0x01B44);
+ (0x01B82,0x01B82);
+ (0x01BA1,0x01BA1);
+ (0x01BA6,0x01BA7);
+ (0x01BAA,0x01BAA);
+ (0x01BE7,0x01BE7);
+ (0x01BEA,0x01BEC);
+ (0x01BEE,0x01BEE);
+ (0x01BF2,0x01BF3);
+ (0x01C24,0x01C2B);
+ (0x01C34,0x01C35);
+ (0x01CE1,0x01CE1);
+ (0x01CF2,0x01CF3);
+ (0x0302E,0x0302F);
+ (0x0A823,0x0A824);
+ (0x0A827,0x0A827);
+ (0x0A880,0x0A881);
+ (0x0A8B4,0x0A8C3);
+ (0x0A952,0x0A953);
+ (0x0A983,0x0A983);
+ (0x0A9B4,0x0A9B5);
+ (0x0A9BA,0x0A9BB);
+ (0x0A9BD,0x0A9C0);
+ (0x0AA2F,0x0AA30);
+ (0x0AA33,0x0AA34);
+ (0x0AA4D,0x0AA4D);
+ (0x0AA7B,0x0AA7B);
+ (0x0AA7D,0x0AA7D);
+ (0x0AAEB,0x0AAEB);
+ (0x0AAEE,0x0AAEF);
+ (0x0AAF5,0x0AAF5);
+ (0x0ABE3,0x0ABE4);
+ (0x0ABE6,0x0ABE7);
+ (0x0ABE9,0x0ABEA);
+ (0x0ABEC,0x0ABEC);
+ (0x11000,0x11000);
+ (0x11002,0x11002);
+ (0x11082,0x11082);
+ (0x110B0,0x110B2);
+ (0x110B7,0x110B8);
+ (0x1112C,0x1112C);
+ (0x11182,0x11182);
+ (0x111B3,0x111B5);
+ (0x111BF,0x111C0);
+ (0x1122C,0x1122E);
+ (0x11232,0x11233);
+ (0x11235,0x11235);
+ (0x112E0,0x112E2);
+ (0x11302,0x11303);
+ (0x1133E,0x1133F);
+ (0x11341,0x11344);
+ (0x11347,0x11348);
+ (0x1134B,0x1134D);
+ (0x11357,0x11357);
+ (0x11362,0x11363);
+ (0x11435,0x11437);
+ (0x11440,0x11441);
+ (0x11445,0x11445);
+ (0x114B0,0x114B2);
+ (0x114B9,0x114B9);
+ (0x114BB,0x114BE);
+ (0x114C1,0x114C1);
+ (0x115AF,0x115B1);
+ (0x115B8,0x115BB);
+ (0x115BE,0x115BE);
+ (0x11630,0x11632);
+ (0x1163B,0x1163C);
+ (0x1163E,0x1163E);
+ (0x116AC,0x116AC);
+ (0x116AE,0x116AF);
+ (0x116B6,0x116B6);
+ (0x11720,0x11721);
+ (0x11726,0x11726);
+ (0x11C2F,0x11C2F);
+ (0x11C3E,0x11C3E);
+ (0x11CA9,0x11CA9);
+ (0x11CB1,0x11CB1);
+ (0x11CB4,0x11CB4);
+ (0x16F51,0x16F7E);
+ (0x1D165,0x1D166)
+]
+(* Mark, Enclosing *)
+let me = [
+ (0x00488,0x00489);
+ (0x01ABE,0x01ABE);
+ (0x020DD,0x020E0);
+ (0x020E2,0x020E4)
+]
+(* Number, Decimal Digit *)
+let nd = [
+ (0x00030,0x00039);
+ (0x00660,0x00669);
+ (0x006F0,0x006F9);
+ (0x007C0,0x007C9);
+ (0x00966,0x0096F);
+ (0x009E6,0x009EF);
+ (0x00A66,0x00A6F);
+ (0x00AE6,0x00AEF);
+ (0x00B66,0x00B6F);
+ (0x00BE6,0x00BEF);
+ (0x00C66,0x00C6F);
+ (0x00CE6,0x00CEF);
+ (0x00D66,0x00D6F);
+ (0x00DE6,0x00DEF);
+ (0x00E50,0x00E59);
+ (0x00ED0,0x00ED9);
+ (0x00F20,0x00F29);
+ (0x01040,0x01049);
+ (0x01090,0x01099);
+ (0x017E0,0x017E9);
+ (0x01810,0x01819);
+ (0x01946,0x0194F);
+ (0x019D0,0x019D9);
+ (0x01A80,0x01A89);
+ (0x01A90,0x01A99);
+ (0x01B50,0x01B59);
+ (0x01BB0,0x01BB9);
+ (0x01C40,0x01C49);
+ (0x01C50,0x01C59);
+ (0x0A620,0x0A629);
+ (0x0A8D0,0x0A8D9);
+ (0x0A900,0x0A909);
+ (0x0A9D0,0x0A9D9);
+ (0x0A9F0,0x0A9F9);
+ (0x0AA50,0x0AA59);
+ (0x0ABF0,0x0ABF9);
+ (0x0FF10,0x0FF19);
+ (0x104A0,0x104A9);
+ (0x11066,0x1106F);
+ (0x110F0,0x110F9);
+ (0x11136,0x1113F);
+ (0x111D0,0x111D9);
+ (0x112F0,0x112F9);
+ (0x11450,0x11459);
+ (0x114D0,0x114D9);
+ (0x11650,0x11659);
+ (0x116C0,0x116C9);
+ (0x11730,0x11739);
+ (0x118E0,0x118E9);
+ (0x11C50,0x11C59);
+ (0x16A60,0x16A69);
+ (0x16B50,0x16B59);
+ (0x1D7CE,0x1D7FF)
+]
+(* Number, Letter *)
+let nl = [
+ (0x016EE,0x016F0);
+ (0x02160,0x02182);
+ (0x02185,0x02188);
+ (0x03007,0x03007);
+ (0x03021,0x03029);
+ (0x03038,0x0303A);
+ (0x0A6E6,0x0A6EF);
+ (0x10140,0x10174);
+ (0x10341,0x10341);
+ (0x1034A,0x1034A);
+ (0x103D1,0x103D5)
+]
+(* Number, Other *)
+let no = [
+ (0x000B2,0x000B3);
+ (0x000B9,0x000B9);
+ (0x000BC,0x000BE);
+ (0x009F4,0x009F9);
+ (0x00B72,0x00B77);
+ (0x00BF0,0x00BF2);
+ (0x00C78,0x00C7E);
+ (0x00D58,0x00D5E);
+ (0x00D70,0x00D78);
+ (0x00F2A,0x00F33);
+ (0x01369,0x0137C);
+ (0x017F0,0x017F9);
+ (0x019DA,0x019DA);
+ (0x02070,0x02070);
+ (0x02074,0x02079);
+ (0x02080,0x02089);
+ (0x02150,0x0215F);
+ (0x02189,0x02189);
+ (0x02460,0x0249B);
+ (0x024EA,0x024FF);
+ (0x02776,0x02793);
+ (0x02CFD,0x02CFD);
+ (0x03192,0x03195);
+ (0x03220,0x03229);
+ (0x03248,0x0324F);
+ (0x03251,0x0325F);
+ (0x03280,0x03289);
+ (0x032B1,0x032BF);
+ (0x0A830,0x0A835);
+ (0x10107,0x10133);
+ (0x10175,0x10178);
+ (0x1018A,0x1018B);
+ (0x102E1,0x102FB);
+ (0x10320,0x10323);
+ (0x10858,0x1085F);
+ (0x10879,0x1087F);
+ (0x108A7,0x108AF);
+ (0x108FB,0x108FF);
+ (0x10916,0x1091B);
+ (0x109BC,0x109BD);
+ (0x109C0,0x109CF);
+ (0x109D2,0x109FF);
+ (0x10A40,0x10A47);
+ (0x10A7D,0x10A7E);
+ (0x10A9D,0x10A9F);
+ (0x10AEB,0x10AEF);
+ (0x10B58,0x10B5F);
+ (0x10B78,0x10B7F);
+ (0x10BA9,0x10BAF);
+ (0x10CFA,0x10CFF);
+ (0x10E60,0x10E7E);
+ (0x11052,0x11065);
+ (0x111E1,0x111F4);
+ (0x1173A,0x1173B);
+ (0x118EA,0x118F2);
+ (0x11C5A,0x11C6C);
+ (0x16B5B,0x16B61);
+ (0x1D360,0x1D371);
+ (0x1E8C7,0x1E8CF)
+]
+(* Separator, Space *)
+let zs = [
+ (0x00020,0x00020);
+ (0x000A0,0x000A0);
+ (0x01680,0x01680);
+ (0x02000,0x0200A);
+ (0x0202F,0x0202F);
+ (0x0205F,0x0205F)
+]
+(* Separator, Line *)
+let zl = [
+
+]
+(* Separator, Paragraph *)
+let zp = [
+
+]
+(* Other, Control *)
+let cc = [
+ (0x00000,0x0001F)
+]
+(* Other, Format *)
+let cf = [
+ (0x000AD,0x000AD);
+ (0x00600,0x00605);
+ (0x0061C,0x0061C);
+ (0x006DD,0x006DD);
+ (0x0070F,0x0070F);
+ (0x008E2,0x008E2);
+ (0x0180E,0x0180E);
+ (0x0200B,0x0200F);
+ (0x0202A,0x0202E);
+ (0x02060,0x02064);
+ (0x02066,0x0206F);
+ (0x0FEFF,0x0FEFF);
+ (0x0FFF9,0x0FFFB);
+ (0x110BD,0x110BD);
+ (0x1BCA0,0x1BCA3);
+ (0x1D173,0x1D17A);
+ (0xE0001,0xE0001)
+]
+(* Other, Surrogate *)
+let cs = [
+
+]
+(* Other, Private Use *)
+let co = [
+ (0x0E000,0x0F8FF);
+ (0xF0000,0xFFFFD)
+]
+(* Other, Not Assigned *)
+let cn = [
+ (0x00378,0x00379);
+ (0x00380,0x00383);
+ (0x0038B,0x0038B);
+ (0x0038D,0x0038D);
+ (0x003A2,0x003A2);
+ (0x00530,0x00530);
+ (0x00557,0x00558);
+ (0x00560,0x00560);
+ (0x00588,0x00588);
+ (0x0058B,0x0058C);
+ (0x00590,0x00590);
+ (0x005C8,0x005CF);
+ (0x005EB,0x005EF);
+ (0x005F5,0x005FF);
+ (0x0061D,0x0061D);
+ (0x0070E,0x0070E);
+ (0x0074B,0x0074C);
+ (0x007B2,0x007BF);
+ (0x007FB,0x007FF);
+ (0x0082E,0x0082F);
+ (0x0083F,0x0083F);
+ (0x0085C,0x0085D);
+ (0x0085F,0x0089F);
+ (0x008B5,0x008B5);
+ (0x008BE,0x008D3);
+ (0x00984,0x00984);
+ (0x0098D,0x0098E);
+ (0x00991,0x00992);
+ (0x009A9,0x009A9);
+ (0x009B1,0x009B1);
+ (0x009B3,0x009B5);
+ (0x009BA,0x009BB);
+ (0x009C5,0x009C6);
+ (0x009C9,0x009CA);
+ (0x009CF,0x009D6);
+ (0x009D8,0x009DB);
+ (0x009DE,0x009DE);
+ (0x009E4,0x009E5);
+ (0x009FC,0x00A00);
+ (0x00A04,0x00A04);
+ (0x00A0B,0x00A0E);
+ (0x00A11,0x00A12);
+ (0x00A29,0x00A29);
+ (0x00A31,0x00A31);
+ (0x00A34,0x00A34);
+ (0x00A37,0x00A37);
+ (0x00A3A,0x00A3B);
+ (0x00A3D,0x00A3D);
+ (0x00A43,0x00A46);
+ (0x00A49,0x00A4A);
+ (0x00A4E,0x00A50);
+ (0x00A52,0x00A58);
+ (0x00A5D,0x00A5D);
+ (0x00A5F,0x00A65);
+ (0x00A76,0x00A80);
+ (0x00A84,0x00A84);
+ (0x00A8E,0x00A8E);
+ (0x00A92,0x00A92);
+ (0x00AA9,0x00AA9);
+ (0x00AB1,0x00AB1);
+ (0x00AB4,0x00AB4);
+ (0x00ABA,0x00ABB);
+ (0x00AC6,0x00AC6);
+ (0x00ACA,0x00ACA);
+ (0x00ACE,0x00ACF);
+ (0x00AD1,0x00ADF);
+ (0x00AE4,0x00AE5);
+ (0x00AF2,0x00AF8);
+ (0x00AFA,0x00B00);
+ (0x00B04,0x00B04);
+ (0x00B0D,0x00B0E);
+ (0x00B11,0x00B12);
+ (0x00B29,0x00B29);
+ (0x00B31,0x00B31);
+ (0x00B34,0x00B34);
+ (0x00B3A,0x00B3B);
+ (0x00B45,0x00B46);
+ (0x00B49,0x00B4A);
+ (0x00B4E,0x00B55);
+ (0x00B58,0x00B5B);
+ (0x00B5E,0x00B5E);
+ (0x00B64,0x00B65);
+ (0x00B78,0x00B81);
+ (0x00B84,0x00B84);
+ (0x00B8B,0x00B8D);
+ (0x00B91,0x00B91);
+ (0x00B96,0x00B98);
+ (0x00B9B,0x00B9B);
+ (0x00B9D,0x00B9D);
+ (0x00BA0,0x00BA2);
+ (0x00BA5,0x00BA7);
+ (0x00BAB,0x00BAD);
+ (0x00BBA,0x00BBD);
+ (0x00BC3,0x00BC5);
+ (0x00BC9,0x00BC9);
+ (0x00BCE,0x00BCF);
+ (0x00BD1,0x00BD6);
+ (0x00BD8,0x00BE5);
+ (0x00BFB,0x00BFF);
+ (0x00C04,0x00C04);
+ (0x00C0D,0x00C0D);
+ (0x00C11,0x00C11);
+ (0x00C29,0x00C29);
+ (0x00C3A,0x00C3C);
+ (0x00C45,0x00C45);
+ (0x00C49,0x00C49);
+ (0x00C4E,0x00C54);
+ (0x00C57,0x00C57);
+ (0x00C5B,0x00C5F);
+ (0x00C64,0x00C65);
+ (0x00C70,0x00C77);
+ (0x00C84,0x00C84);
+ (0x00C8D,0x00C8D);
+ (0x00C91,0x00C91);
+ (0x00CA9,0x00CA9);
+ (0x00CB4,0x00CB4);
+ (0x00CBA,0x00CBB);
+ (0x00CC5,0x00CC5);
+ (0x00CC9,0x00CC9);
+ (0x00CCE,0x00CD4);
+ (0x00CD7,0x00CDD);
+ (0x00CDF,0x00CDF);
+ (0x00CE4,0x00CE5);
+ (0x00CF0,0x00CF0);
+ (0x00CF3,0x00D00);
+ (0x00D04,0x00D04);
+ (0x00D0D,0x00D0D);
+ (0x00D11,0x00D11);
+ (0x00D3B,0x00D3C);
+ (0x00D45,0x00D45);
+ (0x00D49,0x00D49);
+ (0x00D50,0x00D53);
+ (0x00D64,0x00D65);
+ (0x00D80,0x00D81);
+ (0x00D84,0x00D84);
+ (0x00D97,0x00D99);
+ (0x00DB2,0x00DB2);
+ (0x00DBC,0x00DBC);
+ (0x00DBE,0x00DBF);
+ (0x00DC7,0x00DC9);
+ (0x00DCB,0x00DCE);
+ (0x00DD5,0x00DD5);
+ (0x00DD7,0x00DD7);
+ (0x00DE0,0x00DE5);
+ (0x00DF0,0x00DF1);
+ (0x00DF5,0x00E00);
+ (0x00E3B,0x00E3E);
+ (0x00E5C,0x00E80);
+ (0x00E83,0x00E83);
+ (0x00E85,0x00E86);
+ (0x00E89,0x00E89);
+ (0x00E8B,0x00E8C);
+ (0x00E8E,0x00E93);
+ (0x00E98,0x00E98);
+ (0x00EA0,0x00EA0);
+ (0x00EA4,0x00EA4);
+ (0x00EA6,0x00EA6);
+ (0x00EA8,0x00EA9);
+ (0x00EAC,0x00EAC);
+ (0x00EBA,0x00EBA);
+ (0x00EBE,0x00EBF);
+ (0x00EC5,0x00EC5);
+ (0x00EC7,0x00EC7);
+ (0x00ECE,0x00ECF);
+ (0x00EDA,0x00EDB);
+ (0x00EE0,0x00EFF);
+ (0x00F48,0x00F48);
+ (0x00F6D,0x00F70);
+ (0x00F98,0x00F98);
+ (0x00FBD,0x00FBD);
+ (0x00FCD,0x00FCD);
+ (0x00FDB,0x00FFF);
+ (0x010C6,0x010C6);
+ (0x010C8,0x010CC);
+ (0x010CE,0x010CF);
+ (0x01249,0x01249);
+ (0x0124E,0x0124F);
+ (0x01257,0x01257);
+ (0x01259,0x01259);
+ (0x0125E,0x0125F);
+ (0x01289,0x01289);
+ (0x0128E,0x0128F);
+ (0x012B1,0x012B1);
+ (0x012B6,0x012B7);
+ (0x012BF,0x012BF);
+ (0x012C1,0x012C1);
+ (0x012C6,0x012C7);
+ (0x012D7,0x012D7);
+ (0x01311,0x01311);
+ (0x01316,0x01317);
+ (0x0135B,0x0135C);
+ (0x0137D,0x0137F);
+ (0x0139A,0x0139F);
+ (0x013F6,0x013F7);
+ (0x013FE,0x013FF);
+ (0x0169D,0x0169F);
+ (0x016F9,0x016FF);
+ (0x0170D,0x0170D);
+ (0x01715,0x0171F);
+ (0x01737,0x0173F);
+ (0x01754,0x0175F);
+ (0x0176D,0x0176D);
+ (0x01771,0x01771);
+ (0x01774,0x0177F);
+ (0x017DE,0x017DF);
+ (0x017EA,0x017EF);
+ (0x017FA,0x017FF);
+ (0x0180F,0x0180F);
+ (0x0181A,0x0181F);
+ (0x01878,0x0187F);
+ (0x018AB,0x018AF);
+ (0x018F6,0x018FF);
+ (0x0191F,0x0191F);
+ (0x0192C,0x0192F);
+ (0x0193C,0x0193F);
+ (0x01941,0x01943);
+ (0x0196E,0x0196F);
+ (0x01975,0x0197F);
+ (0x019AC,0x019AF);
+ (0x019CA,0x019CF);
+ (0x019DB,0x019DD);
+ (0x01A1C,0x01A1D);
+ (0x01A5F,0x01A5F);
+ (0x01A7D,0x01A7E);
+ (0x01A8A,0x01A8F);
+ (0x01A9A,0x01A9F);
+ (0x01AAE,0x01AAF);
+ (0x01ABF,0x01AFF);
+ (0x01B4C,0x01B4F);
+ (0x01B7D,0x01B7F);
+ (0x01BF4,0x01BFB);
+ (0x01C38,0x01C3A);
+ (0x01C4A,0x01C4C);
+ (0x01C89,0x01CBF);
+ (0x01CC8,0x01CCF);
+ (0x01CF7,0x01CF7);
+ (0x01CFA,0x01CFF);
+ (0x01DF6,0x01DFA);
+ (0x01F16,0x01F17);
+ (0x01F1E,0x01F1F);
+ (0x01F46,0x01F47);
+ (0x01F4E,0x01F4F);
+ (0x01F58,0x01F58);
+ (0x01F5A,0x01F5A);
+ (0x01F5C,0x01F5C);
+ (0x01F5E,0x01F5E);
+ (0x01F7E,0x01F7F);
+ (0x01FB5,0x01FB5);
+ (0x01FC5,0x01FC5);
+ (0x01FD4,0x01FD5);
+ (0x01FDC,0x01FDC);
+ (0x01FF0,0x01FF1);
+ (0x01FF5,0x01FF5);
+ (0x01FFF,0x01FFF);
+ (0x02065,0x02065);
+ (0x02072,0x02073);
+ (0x0208F,0x0208F);
+ (0x0209D,0x0209F);
+ (0x020BF,0x020CF);
+ (0x020F1,0x020FF);
+ (0x0218C,0x0218F);
+ (0x023FF,0x023FF);
+ (0x02427,0x0243F);
+ (0x0244B,0x0245F);
+ (0x02B74,0x02B75);
+ (0x02B96,0x02B97);
+ (0x02BBA,0x02BBC);
+ (0x02BC9,0x02BC9);
+ (0x02BD2,0x02BEB);
+ (0x02BF0,0x02BFF);
+ (0x02C2F,0x02C2F);
+ (0x02C5F,0x02C5F);
+ (0x02CF4,0x02CF8);
+ (0x02D26,0x02D26);
+ (0x02D28,0x02D2C);
+ (0x02D2E,0x02D2F);
+ (0x02D68,0x02D6E);
+ (0x02D71,0x02D7E);
+ (0x02D97,0x02D9F);
+ (0x02DA7,0x02DA7);
+ (0x02DAF,0x02DAF);
+ (0x02DB7,0x02DB7);
+ (0x02DBF,0x02DBF);
+ (0x02DC7,0x02DC7);
+ (0x02DCF,0x02DCF);
+ (0x02DD7,0x02DD7);
+ (0x02DDF,0x02DDF);
+ (0x02E45,0x02E7F);
+ (0x02E9A,0x02E9A);
+ (0x02EF4,0x02EFF);
+ (0x02FD6,0x02FEF);
+ (0x02FFC,0x02FFF);
+ (0x03040,0x03040);
+ (0x03097,0x03098);
+ (0x03100,0x03104);
+ (0x0312E,0x03130);
+ (0x0318F,0x0318F);
+ (0x031BB,0x031BF);
+ (0x031E4,0x031EF);
+ (0x0321F,0x0321F);
+ (0x032FF,0x032FF);
+ (0x04DB6,0x04DBF);
+ (0x09FD6,0x09FFF);
+ (0x0A48D,0x0A48F);
+ (0x0A4C7,0x0A4CF);
+ (0x0A62C,0x0A63F);
+ (0x0A6F8,0x0A6FF);
+ (0x0A7AF,0x0A7AF);
+ (0x0A7B8,0x0A7F6);
+ (0x0A82C,0x0A82F);
+ (0x0A83A,0x0A83F);
+ (0x0A878,0x0A87F);
+ (0x0A8C6,0x0A8CD);
+ (0x0A8DA,0x0A8DF);
+ (0x0A8FE,0x0A8FF);
+ (0x0A954,0x0A95E);
+ (0x0A97D,0x0A97F);
+ (0x0A9CE,0x0A9CE);
+ (0x0A9DA,0x0A9DD);
+ (0x0A9FF,0x0A9FF);
+ (0x0AA37,0x0AA3F);
+ (0x0AA4E,0x0AA4F);
+ (0x0AA5A,0x0AA5B);
+ (0x0AAC3,0x0AADA);
+ (0x0AAF7,0x0AB00);
+ (0x0AB07,0x0AB08);
+ (0x0AB0F,0x0AB10);
+ (0x0AB17,0x0AB1F);
+ (0x0AB27,0x0AB27);
+ (0x0AB2F,0x0AB2F);
+ (0x0AB66,0x0AB6F);
+ (0x0ABEE,0x0ABEF);
+ (0x0ABFA,0x0ABFF);
+ (0x0D7A4,0x0D7AF);
+ (0x0D7C7,0x0D7CA);
+ (0x0D7FC,0x0D7FF);
+ (0x0FA6E,0x0FA6F);
+ (0x0FADA,0x0FAFF);
+ (0x0FB07,0x0FB12);
+ (0x0FB18,0x0FB1C);
+ (0x0FB37,0x0FB37);
+ (0x0FB3D,0x0FB3D);
+ (0x0FB3F,0x0FB3F);
+ (0x0FB42,0x0FB42);
+ (0x0FB45,0x0FB45);
+ (0x0FBC2,0x0FBD2);
+ (0x0FD40,0x0FD4F);
+ (0x0FD90,0x0FD91);
+ (0x0FDC8,0x0FDEF);
+ (0x0FDFE,0x0FDFF);
+ (0x0FE1A,0x0FE1F);
+ (0x0FE53,0x0FE53);
+ (0x0FE67,0x0FE67);
+ (0x0FE6C,0x0FE6F);
+ (0x0FE75,0x0FE75);
+ (0x0FEFD,0x0FEFE);
+ (0x0FF00,0x0FF00);
+ (0x0FFBF,0x0FFC1);
+ (0x0FFC8,0x0FFC9);
+ (0x0FFD0,0x0FFD1);
+ (0x0FFD8,0x0FFD9);
+ (0x0FFDD,0x0FFDF);
+ (0x0FFE7,0x0FFE7);
+ (0x0FFEF,0x0FFF8);
+ (0x0FFFE,0x0FFFF);
+ (0x1000C,0x1000C);
+ (0x10027,0x10027);
+ (0x1003B,0x1003B);
+ (0x1003E,0x1003E);
+ (0x1004E,0x1004F);
+ (0x1005E,0x1007F);
+ (0x100FB,0x100FF);
+ (0x10103,0x10106);
+ (0x10134,0x10136);
+ (0x1018F,0x1018F);
+ (0x1019C,0x1019F);
+ (0x101A1,0x101CF);
+ (0x101FE,0x1027F);
+ (0x1029D,0x1029F);
+ (0x102D1,0x102DF);
+ (0x102FC,0x102FF);
+ (0x10324,0x1032F);
+ (0x1034B,0x1034F);
+ (0x1037B,0x1037F);
+ (0x1039E,0x1039E);
+ (0x103C4,0x103C7);
+ (0x103D6,0x103FF);
+ (0x1049E,0x1049F);
+ (0x104AA,0x104AF);
+ (0x104D4,0x104D7);
+ (0x104FC,0x104FF);
+ (0x10528,0x1052F);
+ (0x10564,0x1056E);
+ (0x10570,0x105FF);
+ (0x10737,0x1073F);
+ (0x10756,0x1075F);
+ (0x10768,0x107FF);
+ (0x10806,0x10807);
+ (0x10809,0x10809);
+ (0x10836,0x10836);
+ (0x10839,0x1083B);
+ (0x1083D,0x1083E);
+ (0x10856,0x10856);
+ (0x1089F,0x108A6);
+ (0x108B0,0x108DF);
+ (0x108F3,0x108F3);
+ (0x108F6,0x108FA);
+ (0x1091C,0x1091E);
+ (0x1093A,0x1093E);
+ (0x10940,0x1097F);
+ (0x109B8,0x109BB);
+ (0x109D0,0x109D1);
+ (0x10A04,0x10A04);
+ (0x10A07,0x10A0B);
+ (0x10A14,0x10A14);
+ (0x10A18,0x10A18);
+ (0x10A34,0x10A37);
+ (0x10A3B,0x10A3E);
+ (0x10A48,0x10A4F);
+ (0x10A59,0x10A5F);
+ (0x10AA0,0x10ABF);
+ (0x10AE7,0x10AEA);
+ (0x10AF7,0x10AFF);
+ (0x10B36,0x10B38);
+ (0x10B56,0x10B57);
+ (0x10B73,0x10B77);
+ (0x10B92,0x10B98);
+ (0x10B9D,0x10BA8);
+ (0x10BB0,0x10BFF);
+ (0x10C49,0x10C7F);
+ (0x10CB3,0x10CBF);
+ (0x10CF3,0x10CF9);
+ (0x10D00,0x10E5F);
+ (0x10E7F,0x10FFF);
+ (0x1104E,0x11051);
+ (0x11070,0x1107E);
+ (0x110C2,0x110CF);
+ (0x110E9,0x110EF);
+ (0x110FA,0x110FF);
+ (0x11135,0x11135);
+ (0x11144,0x1114F);
+ (0x11177,0x1117F);
+ (0x111CE,0x111CF);
+ (0x111E0,0x111E0);
+ (0x111F5,0x111FF);
+ (0x11212,0x11212);
+ (0x1123F,0x1127F);
+ (0x11287,0x11287);
+ (0x11289,0x11289);
+ (0x1128E,0x1128E);
+ (0x1129E,0x1129E);
+ (0x112AA,0x112AF);
+ (0x112EB,0x112EF);
+ (0x112FA,0x112FF);
+ (0x11304,0x11304);
+ (0x1130D,0x1130E);
+ (0x11311,0x11312);
+ (0x11329,0x11329);
+ (0x11331,0x11331);
+ (0x11334,0x11334);
+ (0x1133A,0x1133B);
+ (0x11345,0x11346);
+ (0x11349,0x1134A);
+ (0x1134E,0x1134F);
+ (0x11351,0x11356);
+ (0x11358,0x1135C);
+ (0x11364,0x11365);
+ (0x1136D,0x1136F);
+ (0x11375,0x113FF);
+ (0x1145A,0x1145A);
+ (0x1145C,0x1145C);
+ (0x1145E,0x1147F);
+ (0x114C8,0x114CF);
+ (0x114DA,0x1157F);
+ (0x115B6,0x115B7);
+ (0x115DE,0x115FF);
+ (0x11645,0x1164F);
+ (0x1165A,0x1165F);
+ (0x1166D,0x1167F);
+ (0x116B8,0x116BF);
+ (0x116CA,0x116FF);
+ (0x1171A,0x1171C);
+ (0x1172C,0x1172F);
+ (0x11740,0x1189F);
+ (0x118F3,0x118FE);
+ (0x11900,0x11ABF);
+ (0x11AF9,0x11BFF);
+ (0x11C09,0x11C09);
+ (0x11C37,0x11C37);
+ (0x11C46,0x11C4F);
+ (0x11C6D,0x11C6F);
+ (0x11C90,0x11C91);
+ (0x11CA8,0x11CA8);
+ (0x11CB7,0x11FFF);
+ (0x1239A,0x123FF);
+ (0x1246F,0x1246F);
+ (0x12475,0x1247F);
+ (0x12544,0x12FFF);
+ (0x1342F,0x143FF);
+ (0x14647,0x167FF);
+ (0x16A39,0x16A3F);
+ (0x16A5F,0x16A5F);
+ (0x16A6A,0x16A6D);
+ (0x16A70,0x16ACF);
+ (0x16AEE,0x16AEF);
+ (0x16AF6,0x16AFF);
+ (0x16B46,0x16B4F);
+ (0x16B5A,0x16B5A);
+ (0x16B62,0x16B62);
+ (0x16B78,0x16B7C);
+ (0x16B90,0x16EFF);
+ (0x16F45,0x16F4F);
+ (0x16F7F,0x16F8E);
+ (0x16FA0,0x16FDF);
+ (0x16FE1,0x16FFF);
+ (0x187ED,0x187FF);
+ (0x18AF3,0x1AFFF);
+ (0x1B002,0x1BBFF);
+ (0x1BC6B,0x1BC6F);
+ (0x1BC7D,0x1BC7F);
+ (0x1BC89,0x1BC8F);
+ (0x1BC9A,0x1BC9B);
+ (0x1BCA4,0x1CFFF);
+ (0x1D0F6,0x1D0FF);
+ (0x1D127,0x1D128);
+ (0x1D1E9,0x1D1FF);
+ (0x1D246,0x1D2FF);
+ (0x1D357,0x1D35F);
+ (0x1D372,0x1D3FF);
+ (0x1D455,0x1D455);
+ (0x1D49D,0x1D49D);
+ (0x1D4A0,0x1D4A1);
+ (0x1D4A3,0x1D4A4);
+ (0x1D4A7,0x1D4A8);
+ (0x1D4AD,0x1D4AD);
+ (0x1D4BA,0x1D4BA);
+ (0x1D4BC,0x1D4BC);
+ (0x1D4C4,0x1D4C4);
+ (0x1D506,0x1D506);
+ (0x1D50B,0x1D50C);
+ (0x1D515,0x1D515);
+ (0x1D51D,0x1D51D);
+ (0x1D53A,0x1D53A);
+ (0x1D53F,0x1D53F);
+ (0x1D545,0x1D545);
+ (0x1D547,0x1D549);
+ (0x1D551,0x1D551);
+ (0x1D6A6,0x1D6A7);
+ (0x1D7CC,0x1D7CD);
+ (0x1DA8C,0x1DA9A);
+ (0x1DAA0,0x1DAA0);
+ (0x1DAB0,0x1DFFF);
+ (0x1E007,0x1E007);
+ (0x1E019,0x1E01A);
+ (0x1E022,0x1E022);
+ (0x1E025,0x1E025);
+ (0x1E02B,0x1E7FF);
+ (0x1E8C5,0x1E8C6);
+ (0x1E8D7,0x1E8FF);
+ (0x1E94B,0x1E94F);
+ (0x1E95A,0x1E95D);
+ (0x1E960,0x1EDFF);
+ (0x1EE04,0x1EE04);
+ (0x1EE20,0x1EE20);
+ (0x1EE23,0x1EE23);
+ (0x1EE25,0x1EE26);
+ (0x1EE28,0x1EE28);
+ (0x1EE33,0x1EE33);
+ (0x1EE38,0x1EE38);
+ (0x1EE3A,0x1EE3A);
+ (0x1EE3C,0x1EE41);
+ (0x1EE43,0x1EE46);
+ (0x1EE48,0x1EE48);
+ (0x1EE4A,0x1EE4A);
+ (0x1EE4C,0x1EE4C);
+ (0x1EE50,0x1EE50);
+ (0x1EE53,0x1EE53);
+ (0x1EE55,0x1EE56);
+ (0x1EE58,0x1EE58);
+ (0x1EE5A,0x1EE5A);
+ (0x1EE5C,0x1EE5C);
+ (0x1EE5E,0x1EE5E);
+ (0x1EE60,0x1EE60);
+ (0x1EE63,0x1EE63);
+ (0x1EE65,0x1EE66);
+ (0x1EE6B,0x1EE6B);
+ (0x1EE73,0x1EE73);
+ (0x1EE78,0x1EE78);
+ (0x1EE7D,0x1EE7D);
+ (0x1EE7F,0x1EE7F);
+ (0x1EE8A,0x1EE8A);
+ (0x1EE9C,0x1EEA0);
+ (0x1EEA4,0x1EEA4);
+ (0x1EEAA,0x1EEAA);
+ (0x1EEBC,0x1EEEF);
+ (0x1EEF2,0x1EFFF);
+ (0x1F02C,0x1F02F);
+ (0x1F094,0x1F09F);
+ (0x1F0AF,0x1F0B0);
+ (0x1F0C0,0x1F0C0);
+ (0x1F0D0,0x1F0D0);
+ (0x1F0F6,0x1F0FF);
+ (0x1F10D,0x1F10F);
+ (0x1F12F,0x1F12F);
+ (0x1F16C,0x1F16F);
+ (0x1F1AD,0x1F1E5);
+ (0x1F203,0x1F20F);
+ (0x1F23C,0x1F23F);
+ (0x1F249,0x1F24F);
+ (0x1F252,0x1F2FF);
+ (0x1F6D3,0x1F6DF);
+ (0x1F6ED,0x1F6EF);
+ (0x1F6F7,0x1F6FF);
+ (0x1F774,0x1F77F);
+ (0x1F7D5,0x1F7FF);
+ (0x1F80C,0x1F80F);
+ (0x1F848,0x1F84F);
+ (0x1F85A,0x1F85F);
+ (0x1F888,0x1F88F);
+ (0x1F8AE,0x1F90F);
+ (0x1F91F,0x1F91F);
+ (0x1F928,0x1F92F);
+ (0x1F931,0x1F932);
+ (0x1F93F,0x1F93F);
+ (0x1F94C,0x1F94F);
+ (0x1F95F,0x1F97F);
+ (0x1F992,0x1F9BF);
+ (0x1F9C1,0x1FFFF);
+ (0x2A6D7,0x2A6FF);
+ (0x2B735,0x2B73F);
+ (0x2B81E,0x2B81F);
+ (0x2CEA2,0x2F7FF);
+ (0x2FA1E,0xE0000);
+ (0xE0002,0xE001F);
+ (0xE0080,0xE00FF);
+ (0xE01F0,0xEFFFF);
+ (0xFFFFE,0xFFFFF)
+]
+(* Letter, Modifier *)
+let lm = [
+ (0x002B0,0x002C1);
+ (0x002C6,0x002D1);
+ (0x002E0,0x002E4);
+ (0x002EC,0x002EC);
+ (0x002EE,0x002EE);
+ (0x00374,0x00374);
+ (0x0037A,0x0037A);
+ (0x00559,0x00559);
+ (0x00640,0x00640);
+ (0x006E5,0x006E6);
+ (0x007F4,0x007F5);
+ (0x007FA,0x007FA);
+ (0x0081A,0x0081A);
+ (0x00824,0x00824);
+ (0x00828,0x00828);
+ (0x00971,0x00971);
+ (0x00E46,0x00E46);
+ (0x00EC6,0x00EC6);
+ (0x010FC,0x010FC);
+ (0x017D7,0x017D7);
+ (0x01843,0x01843);
+ (0x01AA7,0x01AA7);
+ (0x01C78,0x01C7D);
+ (0x01D2C,0x01D6A);
+ (0x01D78,0x01D78);
+ (0x01D9B,0x01DBF);
+ (0x02071,0x02071);
+ (0x0207F,0x0207F);
+ (0x02090,0x0209C);
+ (0x02C7C,0x02C7D);
+ (0x02D6F,0x02D6F);
+ (0x02E2F,0x02E2F);
+ (0x03005,0x03005);
+ (0x03031,0x03035);
+ (0x0303B,0x0303B);
+ (0x0309D,0x0309E);
+ (0x030FC,0x030FE);
+ (0x0A015,0x0A015);
+ (0x0A4F8,0x0A4FD);
+ (0x0A60C,0x0A60C);
+ (0x0A67F,0x0A67F);
+ (0x0A69C,0x0A69D);
+ (0x0A717,0x0A71F);
+ (0x0A770,0x0A770);
+ (0x0A788,0x0A788);
+ (0x0A7F8,0x0A7F9);
+ (0x0A9CF,0x0A9CF);
+ (0x0A9E6,0x0A9E6);
+ (0x0AA70,0x0AA70);
+ (0x0AADD,0x0AADD);
+ (0x0AAF3,0x0AAF4);
+ (0x0AB5C,0x0AB5F);
+ (0x0FF70,0x0FF70);
+ (0x0FF9E,0x0FF9F);
+ (0x16B40,0x16B43);
+ (0x16F93,0x16F9F)
+]
+(* Letter, Other *)
+let lo = [
+ (0x000AA,0x000AA);
+ (0x000BA,0x000BA);
+ (0x001BB,0x001BB);
+ (0x001C0,0x001C3);
+ (0x00294,0x00294);
+ (0x005D0,0x005EA);
+ (0x005F0,0x005F2);
+ (0x00620,0x0063F);
+ (0x00641,0x0064A);
+ (0x0066E,0x0066F);
+ (0x00671,0x006D3);
+ (0x006D5,0x006D5);
+ (0x006EE,0x006EF);
+ (0x006FA,0x006FC);
+ (0x006FF,0x006FF);
+ (0x00710,0x00710);
+ (0x00712,0x0072F);
+ (0x0074D,0x007A5);
+ (0x007B1,0x007B1);
+ (0x007CA,0x007EA);
+ (0x00800,0x00815);
+ (0x00840,0x00858);
+ (0x008A0,0x008B4);
+ (0x008B6,0x008BD);
+ (0x00904,0x00939);
+ (0x0093D,0x0093D);
+ (0x00950,0x00950);
+ (0x00958,0x00961);
+ (0x00972,0x00980);
+ (0x00985,0x0098C);
+ (0x0098F,0x00990);
+ (0x00993,0x009A8);
+ (0x009AA,0x009B0);
+ (0x009B2,0x009B2);
+ (0x009B6,0x009B9);
+ (0x009BD,0x009BD);
+ (0x009CE,0x009CE);
+ (0x009DC,0x009DD);
+ (0x009DF,0x009E1);
+ (0x009F0,0x009F1);
+ (0x00A05,0x00A0A);
+ (0x00A0F,0x00A10);
+ (0x00A13,0x00A28);
+ (0x00A2A,0x00A30);
+ (0x00A32,0x00A33);
+ (0x00A35,0x00A36);
+ (0x00A38,0x00A39);
+ (0x00A59,0x00A5C);
+ (0x00A5E,0x00A5E);
+ (0x00A72,0x00A74);
+ (0x00A85,0x00A8D);
+ (0x00A8F,0x00A91);
+ (0x00A93,0x00AA8);
+ (0x00AAA,0x00AB0);
+ (0x00AB2,0x00AB3);
+ (0x00AB5,0x00AB9);
+ (0x00ABD,0x00ABD);
+ (0x00AD0,0x00AD0);
+ (0x00AE0,0x00AE1);
+ (0x00AF9,0x00AF9);
+ (0x00B05,0x00B0C);
+ (0x00B0F,0x00B10);
+ (0x00B13,0x00B28);
+ (0x00B2A,0x00B30);
+ (0x00B32,0x00B33);
+ (0x00B35,0x00B39);
+ (0x00B3D,0x00B3D);
+ (0x00B5C,0x00B5D);
+ (0x00B5F,0x00B61);
+ (0x00B71,0x00B71);
+ (0x00B83,0x00B83);
+ (0x00B85,0x00B8A);
+ (0x00B8E,0x00B90);
+ (0x00B92,0x00B95);
+ (0x00B99,0x00B9A);
+ (0x00B9C,0x00B9C);
+ (0x00B9E,0x00B9F);
+ (0x00BA3,0x00BA4);
+ (0x00BA8,0x00BAA);
+ (0x00BAE,0x00BB9);
+ (0x00BD0,0x00BD0);
+ (0x00C05,0x00C0C);
+ (0x00C0E,0x00C10);
+ (0x00C12,0x00C28);
+ (0x00C2A,0x00C39);
+ (0x00C3D,0x00C3D);
+ (0x00C58,0x00C5A);
+ (0x00C60,0x00C61);
+ (0x00C80,0x00C80);
+ (0x00C85,0x00C8C);
+ (0x00C8E,0x00C90);
+ (0x00C92,0x00CA8);
+ (0x00CAA,0x00CB3);
+ (0x00CB5,0x00CB9);
+ (0x00CBD,0x00CBD);
+ (0x00CDE,0x00CDE);
+ (0x00CE0,0x00CE1);
+ (0x00CF1,0x00CF2);
+ (0x00D05,0x00D0C);
+ (0x00D0E,0x00D10);
+ (0x00D12,0x00D3A);
+ (0x00D3D,0x00D3D);
+ (0x00D4E,0x00D4E);
+ (0x00D54,0x00D56);
+ (0x00D5F,0x00D61);
+ (0x00D7A,0x00D7F);
+ (0x00D85,0x00D96);
+ (0x00D9A,0x00DB1);
+ (0x00DB3,0x00DBB);
+ (0x00DBD,0x00DBD);
+ (0x00DC0,0x00DC6);
+ (0x00E01,0x00E30);
+ (0x00E32,0x00E33);
+ (0x00E40,0x00E45);
+ (0x00E81,0x00E82);
+ (0x00E84,0x00E84);
+ (0x00E87,0x00E88);
+ (0x00E8A,0x00E8A);
+ (0x00E8D,0x00E8D);
+ (0x00E94,0x00E97);
+ (0x00E99,0x00E9F);
+ (0x00EA1,0x00EA3);
+ (0x00EA5,0x00EA5);
+ (0x00EA7,0x00EA7);
+ (0x00EAA,0x00EAB);
+ (0x00EAD,0x00EB0);
+ (0x00EB2,0x00EB3);
+ (0x00EBD,0x00EBD);
+ (0x00EC0,0x00EC4);
+ (0x00EDC,0x00EDF);
+ (0x00F00,0x00F00);
+ (0x00F40,0x00F47);
+ (0x00F49,0x00F6C);
+ (0x00F88,0x00F8C);
+ (0x01000,0x0102A);
+ (0x0103F,0x0103F);
+ (0x01050,0x01055);
+ (0x0105A,0x0105D);
+ (0x01061,0x01061);
+ (0x01065,0x01066);
+ (0x0106E,0x01070);
+ (0x01075,0x01081);
+ (0x0108E,0x0108E);
+ (0x010D0,0x010FA);
+ (0x010FD,0x01248);
+ (0x0124A,0x0124D);
+ (0x01250,0x01256);
+ (0x01258,0x01258);
+ (0x0125A,0x0125D);
+ (0x01260,0x01288);
+ (0x0128A,0x0128D);
+ (0x01290,0x012B0);
+ (0x012B2,0x012B5);
+ (0x012B8,0x012BE);
+ (0x012C0,0x012C0);
+ (0x012C2,0x012C5);
+ (0x012C8,0x012D6);
+ (0x012D8,0x01310);
+ (0x01312,0x01315);
+ (0x01318,0x0135A);
+ (0x01380,0x0138F);
+ (0x01401,0x0166C);
+ (0x0166F,0x0167F);
+ (0x01681,0x0169A);
+ (0x016A0,0x016EA);
+ (0x016F1,0x016F8);
+ (0x01700,0x0170C);
+ (0x0170E,0x01711);
+ (0x01720,0x01731);
+ (0x01740,0x01751);
+ (0x01760,0x0176C);
+ (0x0176E,0x01770);
+ (0x01780,0x017B3);
+ (0x017DC,0x017DC);
+ (0x01820,0x01842);
+ (0x01844,0x01877);
+ (0x01880,0x01884);
+ (0x01887,0x018A8);
+ (0x018AA,0x018AA);
+ (0x018B0,0x018F5);
+ (0x01900,0x0191E);
+ (0x01950,0x0196D);
+ (0x01970,0x01974);
+ (0x01980,0x019AB);
+ (0x019B0,0x019C9);
+ (0x01A00,0x01A16);
+ (0x01A20,0x01A54);
+ (0x01B05,0x01B33);
+ (0x01B45,0x01B4B);
+ (0x01B83,0x01BA0);
+ (0x01BAE,0x01BAF);
+ (0x01BBA,0x01BE5);
+ (0x01C00,0x01C23);
+ (0x01C4D,0x01C4F);
+ (0x01C5A,0x01C77);
+ (0x01CE9,0x01CEC);
+ (0x01CEE,0x01CF1);
+ (0x01CF5,0x01CF6);
+ (0x02135,0x02138);
+ (0x02D30,0x02D67);
+ (0x02D80,0x02D96);
+ (0x02DA0,0x02DA6);
+ (0x02DA8,0x02DAE);
+ (0x02DB0,0x02DB6);
+ (0x02DB8,0x02DBE);
+ (0x02DC0,0x02DC6);
+ (0x02DC8,0x02DCE);
+ (0x02DD0,0x02DD6);
+ (0x02DD8,0x02DDE);
+ (0x03006,0x03006);
+ (0x0303C,0x0303C);
+ (0x03041,0x03096);
+ (0x0309F,0x0309F);
+ (0x030A1,0x030FA);
+ (0x030FF,0x030FF);
+ (0x03105,0x0312D);
+ (0x03131,0x0318E);
+ (0x031A0,0x031BA);
+ (0x031F0,0x031FF);
+ (0x03400,0x04DB5);
+ (0x04E00,0x09FD5);
+ (0x0A000,0x0A014);
+ (0x0A016,0x0A48C);
+ (0x0A4D0,0x0A4F7);
+ (0x0A500,0x0A60B);
+ (0x0A610,0x0A61F);
+ (0x0A62A,0x0A62B);
+ (0x0A66E,0x0A66E);
+ (0x0A6A0,0x0A6E5);
+ (0x0A78F,0x0A78F);
+ (0x0A7F7,0x0A7F7);
+ (0x0A7FB,0x0A801);
+ (0x0A803,0x0A805);
+ (0x0A807,0x0A80A);
+ (0x0A80C,0x0A822);
+ (0x0A840,0x0A873);
+ (0x0A882,0x0A8B3);
+ (0x0A8F2,0x0A8F7);
+ (0x0A8FB,0x0A8FB);
+ (0x0A8FD,0x0A8FD);
+ (0x0A90A,0x0A925);
+ (0x0A930,0x0A946);
+ (0x0A960,0x0A97C);
+ (0x0A984,0x0A9B2);
+ (0x0A9E0,0x0A9E4);
+ (0x0A9E7,0x0A9EF);
+ (0x0A9FA,0x0A9FE);
+ (0x0AA00,0x0AA28);
+ (0x0AA40,0x0AA42);
+ (0x0AA44,0x0AA4B);
+ (0x0AA60,0x0AA6F);
+ (0x0AA71,0x0AA76);
+ (0x0AA7A,0x0AA7A);
+ (0x0AA7E,0x0AAAF);
+ (0x0AAB1,0x0AAB1);
+ (0x0AAB5,0x0AAB6);
+ (0x0AAB9,0x0AABD);
+ (0x0AAC0,0x0AAC0);
+ (0x0AAC2,0x0AAC2);
+ (0x0AADB,0x0AADC);
+ (0x0AAE0,0x0AAEA);
+ (0x0AAF2,0x0AAF2);
+ (0x0AB01,0x0AB06);
+ (0x0AB09,0x0AB0E);
+ (0x0AB11,0x0AB16);
+ (0x0AB20,0x0AB26);
+ (0x0AB28,0x0AB2E);
+ (0x0ABC0,0x0ABE2);
+ (0x0AC00,0x0D7A3);
+ (0x0D7B0,0x0D7C6);
+ (0x0D7CB,0x0D7FB);
+ (0x0F900,0x0FA6D);
+ (0x0FA70,0x0FAD9);
+ (0x0FB1D,0x0FB1D);
+ (0x0FB1F,0x0FB28);
+ (0x0FB2A,0x0FB36);
+ (0x0FB38,0x0FB3C);
+ (0x0FB3E,0x0FB3E);
+ (0x0FB40,0x0FB41);
+ (0x0FB43,0x0FB44);
+ (0x0FB46,0x0FBB1);
+ (0x0FBD3,0x0FD3D);
+ (0x0FD50,0x0FD8F);
+ (0x0FD92,0x0FDC7);
+ (0x0FDF0,0x0FDFB);
+ (0x0FE70,0x0FE74);
+ (0x0FE76,0x0FEFC);
+ (0x0FF66,0x0FF6F);
+ (0x0FF71,0x0FF9D);
+ (0x0FFA0,0x0FFBE);
+ (0x0FFC2,0x0FFC7);
+ (0x0FFCA,0x0FFCF);
+ (0x0FFD2,0x0FFD7);
+ (0x0FFDA,0x0FFDC);
+ (0x10000,0x1000B);
+ (0x1000D,0x10026);
+ (0x10028,0x1003A);
+ (0x1003C,0x1003D);
+ (0x1003F,0x1004D);
+ (0x10050,0x1005D);
+ (0x10080,0x100FA);
+ (0x10280,0x1029C);
+ (0x102A0,0x102D0);
+ (0x10300,0x1031F);
+ (0x10330,0x10340);
+ (0x10342,0x10349);
+ (0x10350,0x10375);
+ (0x10380,0x1039D);
+ (0x103A0,0x103C3);
+ (0x103C8,0x103CF);
+ (0x10450,0x1049D);
+ (0x10500,0x10527);
+ (0x10530,0x10563);
+ (0x10600,0x10736);
+ (0x10740,0x10755);
+ (0x10760,0x10767);
+ (0x10800,0x10805);
+ (0x10808,0x10808);
+ (0x1080A,0x10835);
+ (0x10837,0x10838);
+ (0x1083C,0x1083C);
+ (0x1083F,0x10855);
+ (0x10860,0x10876);
+ (0x10880,0x1089E);
+ (0x108E0,0x108F2);
+ (0x108F4,0x108F5);
+ (0x10900,0x10915);
+ (0x10920,0x10939);
+ (0x10980,0x109B7);
+ (0x109BE,0x109BF);
+ (0x10A00,0x10A00);
+ (0x10A10,0x10A13);
+ (0x10A15,0x10A17);
+ (0x10A19,0x10A33);
+ (0x10A60,0x10A7C);
+ (0x10A80,0x10A9C);
+ (0x10AC0,0x10AC7);
+ (0x10AC9,0x10AE4);
+ (0x10B00,0x10B35);
+ (0x10B40,0x10B55);
+ (0x10B60,0x10B72);
+ (0x10B80,0x10B91);
+ (0x10C00,0x10C48);
+ (0x11003,0x11037);
+ (0x11083,0x110AF);
+ (0x110D0,0x110E8);
+ (0x11103,0x11126);
+ (0x11150,0x11172);
+ (0x11176,0x11176);
+ (0x11183,0x111B2);
+ (0x111C1,0x111C4);
+ (0x111DA,0x111DA);
+ (0x111DC,0x111DC);
+ (0x11200,0x11211);
+ (0x11213,0x1122B);
+ (0x11280,0x11286);
+ (0x11288,0x11288);
+ (0x1128A,0x1128D);
+ (0x1128F,0x1129D);
+ (0x1129F,0x112A8);
+ (0x112B0,0x112DE);
+ (0x11305,0x1130C);
+ (0x1130F,0x11310);
+ (0x11313,0x11328);
+ (0x1132A,0x11330);
+ (0x11332,0x11333);
+ (0x11335,0x11339);
+ (0x1133D,0x1133D);
+ (0x11350,0x11350);
+ (0x1135D,0x11361);
+ (0x11400,0x11434);
+ (0x11447,0x1144A);
+ (0x11480,0x114AF);
+ (0x114C4,0x114C5);
+ (0x114C7,0x114C7);
+ (0x11580,0x115AE);
+ (0x115D8,0x115DB);
+ (0x11600,0x1162F);
+ (0x11644,0x11644);
+ (0x11680,0x116AA);
+ (0x11700,0x11719);
+ (0x118FF,0x118FF);
+ (0x11AC0,0x11AF8);
+ (0x11C00,0x11C08);
+ (0x11C0A,0x11C2E);
+ (0x11C40,0x11C40);
+ (0x11C72,0x11C8F);
+ (0x12000,0x12399);
+ (0x12480,0x12543);
+ (0x13000,0x1342E);
+ (0x14400,0x14646);
+ (0x16800,0x16A38);
+ (0x16A40,0x16A5E);
+ (0x16AD0,0x16AED);
+ (0x16B00,0x16B2F);
+ (0x16B63,0x16B77);
+ (0x16B7D,0x16B8F);
+ (0x16F00,0x16F44);
+ (0x16F50,0x16F50);
+ (0x17000,0x187EC);
+ (0x18800,0x18AF2);
+ (0x1B000,0x1B001);
+ (0x1BC00,0x1BC6A);
+ (0x1BC70,0x1BC7C);
+ (0x1BC80,0x1BC88);
+ (0x1BC90,0x1BC99);
+ (0x1E800,0x1E8C4);
+ (0x1EE00,0x1EE03);
+ (0x1EE05,0x1EE1F);
+ (0x1EE21,0x1EE22);
+ (0x1EE24,0x1EE24);
+ (0x1EE27,0x1EE27);
+ (0x1EE29,0x1EE32);
+ (0x1EE34,0x1EE37);
+ (0x1EE39,0x1EE39);
+ (0x1EE3B,0x1EE3B);
+ (0x1EE42,0x1EE42);
+ (0x1EE47,0x1EE47);
+ (0x1EE49,0x1EE49);
+ (0x1EE4B,0x1EE4B);
+ (0x1EE4D,0x1EE4F);
+ (0x1EE51,0x1EE52);
+ (0x1EE54,0x1EE54);
+ (0x1EE57,0x1EE57);
+ (0x1EE59,0x1EE59);
+ (0x1EE5B,0x1EE5B);
+ (0x1EE5D,0x1EE5D);
+ (0x1EE5F,0x1EE5F);
+ (0x1EE61,0x1EE62);
+ (0x1EE64,0x1EE64);
+ (0x1EE67,0x1EE6A);
+ (0x1EE6C,0x1EE72);
+ (0x1EE74,0x1EE77);
+ (0x1EE79,0x1EE7C);
+ (0x1EE7E,0x1EE7E);
+ (0x1EE80,0x1EE89);
+ (0x1EE8B,0x1EE9B);
+ (0x1EEA1,0x1EEA3);
+ (0x1EEA5,0x1EEA9);
+ (0x1EEAB,0x1EEBB);
+ (0x20000,0x2A6D6);
+ (0x2A700,0x2B734);
+ (0x2B740,0x2B81D);
+ (0x2B820,0x2CEA1)
+]
+(* Punctuation, Connector *)
+let pc = [
+ (0x0005F,0x0005F);
+ (0x0203F,0x02040);
+ (0x02054,0x02054);
+ (0x0FE33,0x0FE34);
+ (0x0FE4D,0x0FE4F)
+]
+(* Punctuation, Dash *)
+let pd = [
+ (0x0002D,0x0002D);
+ (0x0058A,0x0058A);
+ (0x005BE,0x005BE);
+ (0x01400,0x01400);
+ (0x01806,0x01806);
+ (0x02010,0x02015);
+ (0x02E17,0x02E17);
+ (0x02E1A,0x02E1A);
+ (0x02E3A,0x02E3B);
+ (0x02E40,0x02E40);
+ (0x0301C,0x0301C);
+ (0x03030,0x03030);
+ (0x030A0,0x030A0);
+ (0x0FE31,0x0FE32);
+ (0x0FE58,0x0FE58);
+ (0x0FE63,0x0FE63)
+]
+(* Punctuation, Open *)
+let ps = [
+ (0x00028,0x00028);
+ (0x0005B,0x0005B);
+ (0x0007B,0x0007B);
+ (0x00F3A,0x00F3A);
+ (0x00F3C,0x00F3C);
+ (0x0169B,0x0169B);
+ (0x0201A,0x0201A);
+ (0x0201E,0x0201E);
+ (0x02045,0x02045);
+ (0x0207D,0x0207D);
+ (0x0208D,0x0208D);
+ (0x02308,0x02308);
+ (0x0230A,0x0230A);
+ (0x02329,0x02329);
+ (0x02768,0x02768);
+ (0x0276A,0x0276A);
+ (0x0276C,0x0276C);
+ (0x0276E,0x0276E);
+ (0x02770,0x02770);
+ (0x02772,0x02772);
+ (0x02774,0x02774);
+ (0x027C5,0x027C5);
+ (0x027E6,0x027E6);
+ (0x027E8,0x027E8);
+ (0x027EA,0x027EA);
+ (0x027EC,0x027EC);
+ (0x027EE,0x027EE);
+ (0x02983,0x02983);
+ (0x02985,0x02985);
+ (0x02987,0x02987);
+ (0x02989,0x02989);
+ (0x0298B,0x0298B);
+ (0x0298D,0x0298D);
+ (0x0298F,0x0298F);
+ (0x02991,0x02991);
+ (0x02993,0x02993);
+ (0x02995,0x02995);
+ (0x02997,0x02997);
+ (0x029D8,0x029D8);
+ (0x029DA,0x029DA);
+ (0x029FC,0x029FC);
+ (0x02E22,0x02E22);
+ (0x02E24,0x02E24);
+ (0x02E26,0x02E26);
+ (0x02E28,0x02E28);
+ (0x02E42,0x02E42);
+ (0x03008,0x03008);
+ (0x0300A,0x0300A);
+ (0x0300C,0x0300C);
+ (0x0300E,0x0300E);
+ (0x03010,0x03010);
+ (0x03014,0x03014);
+ (0x03016,0x03016);
+ (0x03018,0x03018);
+ (0x0301A,0x0301A);
+ (0x0301D,0x0301D);
+ (0x0FD3F,0x0FD3F);
+ (0x0FE17,0x0FE17);
+ (0x0FE35,0x0FE35);
+ (0x0FE37,0x0FE37);
+ (0x0FE39,0x0FE39);
+ (0x0FE3B,0x0FE3B);
+ (0x0FE3D,0x0FE3D);
+ (0x0FE3F,0x0FE3F);
+ (0x0FE41,0x0FE41);
+ (0x0FE43,0x0FE43);
+ (0x0FE47,0x0FE47);
+ (0x0FE59,0x0FE59);
+ (0x0FE5B,0x0FE5B);
+ (0x0FE5D,0x0FE5D);
+ (0x0FF08,0x0FF08);
+ (0x0FF3B,0x0FF3B);
+ (0x0FF5B,0x0FF5B);
+ (0x0FF5F,0x0FF5F)
+]
+(* Punctuation, Close *)
+let pe = [
+ (0x00029,0x00029);
+ (0x0005D,0x0005D);
+ (0x0007D,0x0007D);
+ (0x00F3B,0x00F3B);
+ (0x00F3D,0x00F3D);
+ (0x0169C,0x0169C);
+ (0x02046,0x02046);
+ (0x0207E,0x0207E);
+ (0x0208E,0x0208E);
+ (0x02309,0x02309);
+ (0x0230B,0x0230B);
+ (0x0232A,0x0232A);
+ (0x02769,0x02769);
+ (0x0276B,0x0276B);
+ (0x0276D,0x0276D);
+ (0x0276F,0x0276F);
+ (0x02771,0x02771);
+ (0x02773,0x02773);
+ (0x02775,0x02775);
+ (0x027C6,0x027C6);
+ (0x027E7,0x027E7);
+ (0x027E9,0x027E9);
+ (0x027EB,0x027EB);
+ (0x027ED,0x027ED);
+ (0x027EF,0x027EF);
+ (0x02984,0x02984);
+ (0x02986,0x02986);
+ (0x02988,0x02988);
+ (0x0298A,0x0298A);
+ (0x0298C,0x0298C);
+ (0x0298E,0x0298E);
+ (0x02990,0x02990);
+ (0x02992,0x02992);
+ (0x02994,0x02994);
+ (0x02996,0x02996);
+ (0x02998,0x02998);
+ (0x029D9,0x029D9);
+ (0x029DB,0x029DB);
+ (0x029FD,0x029FD);
+ (0x02E23,0x02E23);
+ (0x02E25,0x02E25);
+ (0x02E27,0x02E27);
+ (0x02E29,0x02E29);
+ (0x03009,0x03009);
+ (0x0300B,0x0300B);
+ (0x0300D,0x0300D);
+ (0x0300F,0x0300F);
+ (0x03011,0x03011);
+ (0x03015,0x03015);
+ (0x03017,0x03017);
+ (0x03019,0x03019);
+ (0x0301B,0x0301B);
+ (0x0301E,0x0301F);
+ (0x0FD3E,0x0FD3E);
+ (0x0FE18,0x0FE18);
+ (0x0FE36,0x0FE36);
+ (0x0FE38,0x0FE38);
+ (0x0FE3A,0x0FE3A);
+ (0x0FE3C,0x0FE3C);
+ (0x0FE3E,0x0FE3E);
+ (0x0FE40,0x0FE40);
+ (0x0FE42,0x0FE42);
+ (0x0FE44,0x0FE44);
+ (0x0FE48,0x0FE48);
+ (0x0FE5A,0x0FE5A);
+ (0x0FE5C,0x0FE5C);
+ (0x0FE5E,0x0FE5E);
+ (0x0FF09,0x0FF09);
+ (0x0FF3D,0x0FF3D);
+ (0x0FF5D,0x0FF5D);
+ (0x0FF60,0x0FF60)
+]
+(* Punctuation, Initial quote *)
+let pi = [
+ (0x000AB,0x000AB);
+ (0x02018,0x02018);
+ (0x0201B,0x0201C);
+ (0x0201F,0x0201F);
+ (0x02039,0x02039);
+ (0x02E02,0x02E02);
+ (0x02E04,0x02E04);
+ (0x02E09,0x02E09);
+ (0x02E0C,0x02E0C);
+ (0x02E1C,0x02E1C)
+]
+(* Punctuation, Final quote *)
+let pf = [
+ (0x000BB,0x000BB);
+ (0x02019,0x02019);
+ (0x0201D,0x0201D);
+ (0x0203A,0x0203A);
+ (0x02E03,0x02E03);
+ (0x02E05,0x02E05);
+ (0x02E0A,0x02E0A);
+ (0x02E0D,0x02E0D);
+ (0x02E1D,0x02E1D)
+]
+(* Punctuation, Other *)
+let po = [
+ (0x00021,0x00023);
+ (0x00025,0x00027);
+ (0x0002A,0x0002A);
+ (0x0002C,0x0002C);
+ (0x0002E,0x0002F);
+ (0x0003A,0x0003B);
+ (0x0003F,0x00040);
+ (0x0005C,0x0005C);
+ (0x000A1,0x000A1);
+ (0x000A7,0x000A7);
+ (0x000B6,0x000B7);
+ (0x000BF,0x000BF);
+ (0x0037E,0x0037E);
+ (0x00387,0x00387);
+ (0x0055A,0x0055F);
+ (0x00589,0x00589);
+ (0x005C0,0x005C0);
+ (0x005C3,0x005C3);
+ (0x005C6,0x005C6);
+ (0x005F3,0x005F4);
+ (0x00609,0x0060A);
+ (0x0060C,0x0060D);
+ (0x0061B,0x0061B);
+ (0x0061E,0x0061F);
+ (0x0066A,0x0066D);
+ (0x006D4,0x006D4);
+ (0x00700,0x0070D);
+ (0x007F7,0x007F9);
+ (0x00830,0x0083E);
+ (0x0085E,0x0085E);
+ (0x00964,0x00965);
+ (0x00970,0x00970);
+ (0x00AF0,0x00AF0);
+ (0x00DF4,0x00DF4);
+ (0x00E4F,0x00E4F);
+ (0x00E5A,0x00E5B);
+ (0x00F04,0x00F12);
+ (0x00F14,0x00F14);
+ (0x00F85,0x00F85);
+ (0x00FD0,0x00FD4);
+ (0x00FD9,0x00FDA);
+ (0x0104A,0x0104F);
+ (0x010FB,0x010FB);
+ (0x01360,0x01368);
+ (0x0166D,0x0166E);
+ (0x016EB,0x016ED);
+ (0x01735,0x01736);
+ (0x017D4,0x017D6);
+ (0x017D8,0x017DA);
+ (0x01800,0x01805);
+ (0x01807,0x0180A);
+ (0x01944,0x01945);
+ (0x01A1E,0x01A1F);
+ (0x01AA0,0x01AA6);
+ (0x01AA8,0x01AAD);
+ (0x01B5A,0x01B60);
+ (0x01BFC,0x01BFF);
+ (0x01C3B,0x01C3F);
+ (0x01C7E,0x01C7F);
+ (0x01CC0,0x01CC7);
+ (0x01CD3,0x01CD3);
+ (0x02016,0x02017);
+ (0x02020,0x02027);
+ (0x02030,0x02038);
+ (0x0203B,0x0203E);
+ (0x02041,0x02043);
+ (0x02047,0x02051);
+ (0x02053,0x02053);
+ (0x02055,0x0205E);
+ (0x02CF9,0x02CFC);
+ (0x02CFE,0x02CFF);
+ (0x02D70,0x02D70);
+ (0x02E00,0x02E01);
+ (0x02E06,0x02E08);
+ (0x02E0B,0x02E0B);
+ (0x02E0E,0x02E16);
+ (0x02E18,0x02E19);
+ (0x02E1B,0x02E1B);
+ (0x02E1E,0x02E1F);
+ (0x02E2A,0x02E2E);
+ (0x02E30,0x02E39);
+ (0x02E3C,0x02E3F);
+ (0x02E41,0x02E41);
+ (0x02E43,0x02E44);
+ (0x03001,0x03003);
+ (0x0303D,0x0303D);
+ (0x030FB,0x030FB);
+ (0x0A4FE,0x0A4FF);
+ (0x0A60D,0x0A60F);
+ (0x0A673,0x0A673);
+ (0x0A67E,0x0A67E);
+ (0x0A6F2,0x0A6F7);
+ (0x0A874,0x0A877);
+ (0x0A8CE,0x0A8CF);
+ (0x0A8F8,0x0A8FA);
+ (0x0A8FC,0x0A8FC);
+ (0x0A92E,0x0A92F);
+ (0x0A95F,0x0A95F);
+ (0x0A9C1,0x0A9CD);
+ (0x0A9DE,0x0A9DF);
+ (0x0AA5C,0x0AA5F);
+ (0x0AADE,0x0AADF);
+ (0x0AAF0,0x0AAF1);
+ (0x0ABEB,0x0ABEB);
+ (0x0FE10,0x0FE16);
+ (0x0FE19,0x0FE19);
+ (0x0FE30,0x0FE30);
+ (0x0FE45,0x0FE46);
+ (0x0FE49,0x0FE4C);
+ (0x0FE50,0x0FE52);
+ (0x0FE54,0x0FE57);
+ (0x0FE5F,0x0FE61);
+ (0x0FE68,0x0FE68);
+ (0x0FE6A,0x0FE6B);
+ (0x0FF01,0x0FF03);
+ (0x0FF05,0x0FF07);
+ (0x0FF0A,0x0FF0A);
+ (0x0FF0C,0x0FF0C);
+ (0x0FF0E,0x0FF0F);
+ (0x0FF1A,0x0FF1B);
+ (0x0FF1F,0x0FF20);
+ (0x0FF3C,0x0FF3C);
+ (0x0FF61,0x0FF61);
+ (0x0FF64,0x0FF65);
+ (0x10100,0x10102);
+ (0x1039F,0x1039F);
+ (0x103D0,0x103D0);
+ (0x1056F,0x1056F);
+ (0x10857,0x10857);
+ (0x1091F,0x1091F);
+ (0x1093F,0x1093F);
+ (0x10A50,0x10A58);
+ (0x10A7F,0x10A7F);
+ (0x10AF0,0x10AF6);
+ (0x10B39,0x10B3F);
+ (0x10B99,0x10B9C);
+ (0x11047,0x1104D);
+ (0x110BB,0x110BC);
+ (0x110BE,0x110C1);
+ (0x11140,0x11143);
+ (0x11174,0x11175);
+ (0x111C5,0x111C9);
+ (0x111CD,0x111CD);
+ (0x111DB,0x111DB);
+ (0x111DD,0x111DF);
+ (0x11238,0x1123D);
+ (0x112A9,0x112A9);
+ (0x1144B,0x1144F);
+ (0x1145B,0x1145B);
+ (0x1145D,0x1145D);
+ (0x114C6,0x114C6);
+ (0x115C1,0x115D7);
+ (0x11641,0x11643);
+ (0x11660,0x1166C);
+ (0x1173C,0x1173E);
+ (0x11C41,0x11C45);
+ (0x11C70,0x11C71);
+ (0x12470,0x12474);
+ (0x16A6E,0x16A6F);
+ (0x16AF5,0x16AF5);
+ (0x16B37,0x16B3B);
+ (0x16B44,0x16B44);
+ (0x1BC9F,0x1BC9F);
+ (0x1DA87,0x1DA8B)
+]
+(* Symbol, Math *)
+let sm = [
+ (0x0002B,0x0002B);
+ (0x0003C,0x0003E);
+ (0x0007C,0x0007C);
+ (0x0007E,0x0007E);
+ (0x000AC,0x000AC);
+ (0x000B1,0x000B1);
+ (0x000D7,0x000D7);
+ (0x000F7,0x000F7);
+ (0x003F6,0x003F6);
+ (0x00606,0x00608);
+ (0x02044,0x02044);
+ (0x02052,0x02052);
+ (0x0207A,0x0207C);
+ (0x0208A,0x0208C);
+ (0x02118,0x02118);
+ (0x02140,0x02144);
+ (0x0214B,0x0214B);
+ (0x02190,0x02194);
+ (0x0219A,0x0219B);
+ (0x021A0,0x021A0);
+ (0x021A3,0x021A3);
+ (0x021A6,0x021A6);
+ (0x021AE,0x021AE);
+ (0x021CE,0x021CF);
+ (0x021D2,0x021D2);
+ (0x021D4,0x021D4);
+ (0x021F4,0x022FF);
+ (0x02320,0x02321);
+ (0x0237C,0x0237C);
+ (0x0239B,0x023B3);
+ (0x023DC,0x023E1);
+ (0x025B7,0x025B7);
+ (0x025C1,0x025C1);
+ (0x025F8,0x025FF);
+ (0x0266F,0x0266F);
+ (0x027C0,0x027C4);
+ (0x027C7,0x027E5);
+ (0x027F0,0x027FF);
+ (0x02900,0x02982);
+ (0x02999,0x029D7);
+ (0x029DC,0x029FB);
+ (0x029FE,0x02AFF);
+ (0x02B30,0x02B44);
+ (0x02B47,0x02B4C);
+ (0x0FB29,0x0FB29);
+ (0x0FE62,0x0FE62);
+ (0x0FE64,0x0FE66);
+ (0x0FF0B,0x0FF0B);
+ (0x0FF1C,0x0FF1E);
+ (0x0FF5C,0x0FF5C);
+ (0x0FF5E,0x0FF5E);
+ (0x0FFE2,0x0FFE2);
+ (0x0FFE9,0x0FFEC);
+ (0x1D6C1,0x1D6C1);
+ (0x1D6DB,0x1D6DB);
+ (0x1D6FB,0x1D6FB);
+ (0x1D715,0x1D715);
+ (0x1D735,0x1D735);
+ (0x1D74F,0x1D74F);
+ (0x1D76F,0x1D76F);
+ (0x1D789,0x1D789);
+ (0x1D7A9,0x1D7A9);
+ (0x1D7C3,0x1D7C3)
+]
+(* Symbol, Currency *)
+let sc = [
+ (0x00024,0x00024);
+ (0x000A2,0x000A5);
+ (0x0058F,0x0058F);
+ (0x0060B,0x0060B);
+ (0x009F2,0x009F3);
+ (0x009FB,0x009FB);
+ (0x00AF1,0x00AF1);
+ (0x00BF9,0x00BF9);
+ (0x00E3F,0x00E3F);
+ (0x017DB,0x017DB);
+ (0x020A0,0x020BE);
+ (0x0A838,0x0A838);
+ (0x0FDFC,0x0FDFC);
+ (0x0FE69,0x0FE69);
+ (0x0FF04,0x0FF04);
+ (0x0FFE0,0x0FFE1)
+]
+(* Symbol, Modifier *)
+let sk = [
+ (0x0005E,0x0005E);
+ (0x00060,0x00060);
+ (0x000A8,0x000A8);
+ (0x000AF,0x000AF);
+ (0x000B4,0x000B4);
+ (0x000B8,0x000B8);
+ (0x002C2,0x002C5);
+ (0x002D2,0x002DF);
+ (0x002E5,0x002EB);
+ (0x002ED,0x002ED);
+ (0x002EF,0x002FF);
+ (0x00375,0x00375);
+ (0x00384,0x00385);
+ (0x01FBD,0x01FBD);
+ (0x01FBF,0x01FC1);
+ (0x01FCD,0x01FCF);
+ (0x01FDD,0x01FDF);
+ (0x01FED,0x01FEF);
+ (0x01FFD,0x01FFE);
+ (0x0309B,0x0309C);
+ (0x0A700,0x0A716);
+ (0x0A720,0x0A721);
+ (0x0A789,0x0A78A);
+ (0x0AB5B,0x0AB5B);
+ (0x0FBB2,0x0FBC1);
+ (0x0FF3E,0x0FF3E);
+ (0x0FF40,0x0FF40);
+ (0x0FFE3,0x0FFE3)
+]
+(* Symbol, Other *)
+let so = [
+ (0x000A6,0x000A6);
+ (0x000A9,0x000A9);
+ (0x000AE,0x000AE);
+ (0x000B0,0x000B0);
+ (0x00482,0x00482);
+ (0x0058D,0x0058E);
+ (0x0060E,0x0060F);
+ (0x006DE,0x006DE);
+ (0x006E9,0x006E9);
+ (0x006FD,0x006FE);
+ (0x007F6,0x007F6);
+ (0x009FA,0x009FA);
+ (0x00B70,0x00B70);
+ (0x00BF3,0x00BF8);
+ (0x00BFA,0x00BFA);
+ (0x00C7F,0x00C7F);
+ (0x00D4F,0x00D4F);
+ (0x00D79,0x00D79);
+ (0x00F01,0x00F03);
+ (0x00F13,0x00F13);
+ (0x00F15,0x00F17);
+ (0x00F1A,0x00F1F);
+ (0x00F34,0x00F34);
+ (0x00F36,0x00F36);
+ (0x00F38,0x00F38);
+ (0x00FBE,0x00FC5);
+ (0x00FC7,0x00FCC);
+ (0x00FCE,0x00FCF);
+ (0x00FD5,0x00FD8);
+ (0x0109E,0x0109F);
+ (0x01390,0x01399);
+ (0x01940,0x01940);
+ (0x019DE,0x019FF);
+ (0x01B61,0x01B6A);
+ (0x01B74,0x01B7C);
+ (0x02100,0x02101);
+ (0x02103,0x02106);
+ (0x02108,0x02109);
+ (0x02114,0x02114);
+ (0x02116,0x02117);
+ (0x0211E,0x02123);
+ (0x02125,0x02125);
+ (0x02127,0x02127);
+ (0x02129,0x02129);
+ (0x0212E,0x0212E);
+ (0x0213A,0x0213B);
+ (0x0214A,0x0214A);
+ (0x0214C,0x0214D);
+ (0x0214F,0x0214F);
+ (0x0218A,0x0218B);
+ (0x02195,0x02199);
+ (0x0219C,0x0219F);
+ (0x021A1,0x021A2);
+ (0x021A4,0x021A5);
+ (0x021A7,0x021AD);
+ (0x021AF,0x021CD);
+ (0x021D0,0x021D1);
+ (0x021D3,0x021D3);
+ (0x021D5,0x021F3);
+ (0x02300,0x02307);
+ (0x0230C,0x0231F);
+ (0x02322,0x02328);
+ (0x0232B,0x0237B);
+ (0x0237D,0x0239A);
+ (0x023B4,0x023DB);
+ (0x023E2,0x023FE);
+ (0x02400,0x02426);
+ (0x02440,0x0244A);
+ (0x0249C,0x024E9);
+ (0x02500,0x025B6);
+ (0x025B8,0x025C0);
+ (0x025C2,0x025F7);
+ (0x02600,0x0266E);
+ (0x02670,0x02767);
+ (0x02794,0x027BF);
+ (0x02800,0x028FF);
+ (0x02B00,0x02B2F);
+ (0x02B45,0x02B46);
+ (0x02B4D,0x02B73);
+ (0x02B76,0x02B95);
+ (0x02B98,0x02BB9);
+ (0x02BBD,0x02BC8);
+ (0x02BCA,0x02BD1);
+ (0x02BEC,0x02BEF);
+ (0x02CE5,0x02CEA);
+ (0x02E80,0x02E99);
+ (0x02E9B,0x02EF3);
+ (0x02F00,0x02FD5);
+ (0x02FF0,0x02FFB);
+ (0x03004,0x03004);
+ (0x03012,0x03013);
+ (0x03020,0x03020);
+ (0x03036,0x03037);
+ (0x0303E,0x0303F);
+ (0x03190,0x03191);
+ (0x03196,0x0319F);
+ (0x031C0,0x031E3);
+ (0x03200,0x0321E);
+ (0x0322A,0x03247);
+ (0x03250,0x03250);
+ (0x03260,0x0327F);
+ (0x0328A,0x032B0);
+ (0x032C0,0x032FE);
+ (0x03300,0x033FF);
+ (0x04DC0,0x04DFF);
+ (0x0A490,0x0A4C6);
+ (0x0A828,0x0A82B);
+ (0x0A836,0x0A837);
+ (0x0A839,0x0A839);
+ (0x0AA77,0x0AA79);
+ (0x0FDFD,0x0FDFD);
+ (0x0FFE4,0x0FFE4);
+ (0x0FFE8,0x0FFE8);
+ (0x0FFED,0x0FFEE);
+ (0x0FFFC,0x0FFFD);
+ (0x10137,0x1013F);
+ (0x10179,0x10189);
+ (0x1018C,0x1018E);
+ (0x10190,0x1019B);
+ (0x101A0,0x101A0);
+ (0x101D0,0x101FC);
+ (0x10877,0x10878);
+ (0x10AC8,0x10AC8);
+ (0x1173F,0x1173F);
+ (0x16B3C,0x16B3F);
+ (0x16B45,0x16B45);
+ (0x1BC9C,0x1BC9C);
+ (0x1D000,0x1D0F5);
+ (0x1D100,0x1D126);
+ (0x1D129,0x1D164);
+ (0x1D16A,0x1D16C);
+ (0x1D183,0x1D184);
+ (0x1D18C,0x1D1A9);
+ (0x1D1AE,0x1D1E8);
+ (0x1D200,0x1D241);
+ (0x1D245,0x1D245);
+ (0x1D300,0x1D356);
+ (0x1D800,0x1D9FF);
+ (0x1DA37,0x1DA3A);
+ (0x1DA6D,0x1DA74);
+ (0x1DA76,0x1DA83);
+ (0x1DA85,0x1DA86);
+ (0x1F000,0x1F02B);
+ (0x1F030,0x1F093);
+ (0x1F0A0,0x1F0AE);
+ (0x1F0B1,0x1F0BF);
+ (0x1F0C1,0x1F0CF);
+ (0x1F0D1,0x1F0F5);
+ (0x1F110,0x1F12E);
+ (0x1F130,0x1F16B);
+ (0x1F170,0x1F1AC);
+ (0x1F1E6,0x1F202);
+ (0x1F210,0x1F23B);
+ (0x1F240,0x1F248);
+ (0x1F250,0x1F251);
+ (0x1F300,0x1F3FA);
+ (0x1F400,0x1F6D2);
+ (0x1F6E0,0x1F6EC);
+ (0x1F6F0,0x1F6F6);
+ (0x1F700,0x1F773);
+ (0x1F780,0x1F7D4);
+ (0x1F800,0x1F80B);
+ (0x1F810,0x1F847);
+ (0x1F850,0x1F859);
+ (0x1F860,0x1F887);
+ (0x1F890,0x1F8AD);
+ (0x1F910,0x1F91E);
+ (0x1F920,0x1F927);
+ (0x1F930,0x1F930);
+ (0x1F933,0x1F93E);
+ (0x1F940,0x1F94B);
+ (0x1F950,0x1F95E);
+ (0x1F980,0x1F991)
+]
+let to_lower = [
+ (0x00041,0x0005A), `Delta (32);
+ (0x000C0,0x000D6), `Delta (32);
+ (0x000D8,0x000DE), `Delta (32);
+ (0x00100,0x00100), `Abs (0x00101);
+ (0x00102,0x00102), `Abs (0x00103);
+ (0x00104,0x00104), `Abs (0x00105);
+ (0x00106,0x00106), `Abs (0x00107);
+ (0x00108,0x00108), `Abs (0x00109);
+ (0x0010A,0x0010A), `Abs (0x0010B);
+ (0x0010C,0x0010C), `Abs (0x0010D);
+ (0x0010E,0x0010E), `Abs (0x0010F);
+ (0x00110,0x00110), `Abs (0x00111);
+ (0x00112,0x00112), `Abs (0x00113);
+ (0x00114,0x00114), `Abs (0x00115);
+ (0x00116,0x00116), `Abs (0x00117);
+ (0x00118,0x00118), `Abs (0x00119);
+ (0x0011A,0x0011A), `Abs (0x0011B);
+ (0x0011C,0x0011C), `Abs (0x0011D);
+ (0x0011E,0x0011E), `Abs (0x0011F);
+ (0x00120,0x00120), `Abs (0x00121);
+ (0x00122,0x00122), `Abs (0x00123);
+ (0x00124,0x00124), `Abs (0x00125);
+ (0x00126,0x00126), `Abs (0x00127);
+ (0x00128,0x00128), `Abs (0x00129);
+ (0x0012A,0x0012A), `Abs (0x0012B);
+ (0x0012C,0x0012C), `Abs (0x0012D);
+ (0x0012E,0x0012E), `Abs (0x0012F);
+ (0x00130,0x00130), `Abs (0x00069);
+ (0x00132,0x00132), `Abs (0x00133);
+ (0x00134,0x00134), `Abs (0x00135);
+ (0x00136,0x00136), `Abs (0x00137);
+ (0x00139,0x00139), `Abs (0x0013A);
+ (0x0013B,0x0013B), `Abs (0x0013C);
+ (0x0013D,0x0013D), `Abs (0x0013E);
+ (0x0013F,0x0013F), `Abs (0x00140);
+ (0x00141,0x00141), `Abs (0x00142);
+ (0x00143,0x00143), `Abs (0x00144);
+ (0x00145,0x00145), `Abs (0x00146);
+ (0x00147,0x00147), `Abs (0x00148);
+ (0x0014A,0x0014A), `Abs (0x0014B);
+ (0x0014C,0x0014C), `Abs (0x0014D);
+ (0x0014E,0x0014E), `Abs (0x0014F);
+ (0x00150,0x00150), `Abs (0x00151);
+ (0x00152,0x00152), `Abs (0x00153);
+ (0x00154,0x00154), `Abs (0x00155);
+ (0x00156,0x00156), `Abs (0x00157);
+ (0x00158,0x00158), `Abs (0x00159);
+ (0x0015A,0x0015A), `Abs (0x0015B);
+ (0x0015C,0x0015C), `Abs (0x0015D);
+ (0x0015E,0x0015E), `Abs (0x0015F);
+ (0x00160,0x00160), `Abs (0x00161);
+ (0x00162,0x00162), `Abs (0x00163);
+ (0x00164,0x00164), `Abs (0x00165);
+ (0x00166,0x00166), `Abs (0x00167);
+ (0x00168,0x00168), `Abs (0x00169);
+ (0x0016A,0x0016A), `Abs (0x0016B);
+ (0x0016C,0x0016C), `Abs (0x0016D);
+ (0x0016E,0x0016E), `Abs (0x0016F);
+ (0x00170,0x00170), `Abs (0x00171);
+ (0x00172,0x00172), `Abs (0x00173);
+ (0x00174,0x00174), `Abs (0x00175);
+ (0x00176,0x00176), `Abs (0x00177);
+ (0x00178,0x00178), `Abs (0x000FF);
+ (0x00179,0x00179), `Abs (0x0017A);
+ (0x0017B,0x0017B), `Abs (0x0017C);
+ (0x0017D,0x0017D), `Abs (0x0017E);
+ (0x00181,0x00181), `Abs (0x00253);
+ (0x00182,0x00182), `Abs (0x00183);
+ (0x00184,0x00184), `Abs (0x00185);
+ (0x00186,0x00186), `Abs (0x00254);
+ (0x00187,0x00187), `Abs (0x00188);
+ (0x00189,0x0018A), `Delta (205);
+ (0x0018B,0x0018B), `Abs (0x0018C);
+ (0x0018E,0x0018E), `Abs (0x001DD);
+ (0x0018F,0x0018F), `Abs (0x00259);
+ (0x00190,0x00190), `Abs (0x0025B);
+ (0x00191,0x00191), `Abs (0x00192);
+ (0x00193,0x00193), `Abs (0x00260);
+ (0x00194,0x00194), `Abs (0x00263);
+ (0x00196,0x00196), `Abs (0x00269);
+ (0x00197,0x00197), `Abs (0x00268);
+ (0x00198,0x00198), `Abs (0x00199);
+ (0x0019C,0x0019C), `Abs (0x0026F);
+ (0x0019D,0x0019D), `Abs (0x00272);
+ (0x0019F,0x0019F), `Abs (0x00275);
+ (0x001A0,0x001A0), `Abs (0x001A1);
+ (0x001A2,0x001A2), `Abs (0x001A3);
+ (0x001A4,0x001A4), `Abs (0x001A5);
+ (0x001A6,0x001A6), `Abs (0x00280);
+ (0x001A7,0x001A7), `Abs (0x001A8);
+ (0x001A9,0x001A9), `Abs (0x00283);
+ (0x001AC,0x001AC), `Abs (0x001AD);
+ (0x001AE,0x001AE), `Abs (0x00288);
+ (0x001AF,0x001AF), `Abs (0x001B0);
+ (0x001B1,0x001B2), `Delta (217);
+ (0x001B3,0x001B3), `Abs (0x001B4);
+ (0x001B5,0x001B5), `Abs (0x001B6);
+ (0x001B7,0x001B7), `Abs (0x00292);
+ (0x001B8,0x001B8), `Abs (0x001B9);
+ (0x001BC,0x001BC), `Abs (0x001BD);
+ (0x001C4,0x001C4), `Abs (0x001C6);
+ (0x001C7,0x001C7), `Abs (0x001C9);
+ (0x001CA,0x001CA), `Abs (0x001CC);
+ (0x001CD,0x001CD), `Abs (0x001CE);
+ (0x001CF,0x001CF), `Abs (0x001D0);
+ (0x001D1,0x001D1), `Abs (0x001D2);
+ (0x001D3,0x001D3), `Abs (0x001D4);
+ (0x001D5,0x001D5), `Abs (0x001D6);
+ (0x001D7,0x001D7), `Abs (0x001D8);
+ (0x001D9,0x001D9), `Abs (0x001DA);
+ (0x001DB,0x001DB), `Abs (0x001DC);
+ (0x001DE,0x001DE), `Abs (0x001DF);
+ (0x001E0,0x001E0), `Abs (0x001E1);
+ (0x001E2,0x001E2), `Abs (0x001E3);
+ (0x001E4,0x001E4), `Abs (0x001E5);
+ (0x001E6,0x001E6), `Abs (0x001E7);
+ (0x001E8,0x001E8), `Abs (0x001E9);
+ (0x001EA,0x001EA), `Abs (0x001EB);
+ (0x001EC,0x001EC), `Abs (0x001ED);
+ (0x001EE,0x001EE), `Abs (0x001EF);
+ (0x001F1,0x001F1), `Abs (0x001F3);
+ (0x001F4,0x001F4), `Abs (0x001F5);
+ (0x001F6,0x001F6), `Abs (0x00195);
+ (0x001F7,0x001F7), `Abs (0x001BF);
+ (0x001F8,0x001F8), `Abs (0x001F9);
+ (0x001FA,0x001FA), `Abs (0x001FB);
+ (0x001FC,0x001FC), `Abs (0x001FD);
+ (0x001FE,0x001FE), `Abs (0x001FF);
+ (0x00200,0x00200), `Abs (0x00201);
+ (0x00202,0x00202), `Abs (0x00203);
+ (0x00204,0x00204), `Abs (0x00205);
+ (0x00206,0x00206), `Abs (0x00207);
+ (0x00208,0x00208), `Abs (0x00209);
+ (0x0020A,0x0020A), `Abs (0x0020B);
+ (0x0020C,0x0020C), `Abs (0x0020D);
+ (0x0020E,0x0020E), `Abs (0x0020F);
+ (0x00210,0x00210), `Abs (0x00211);
+ (0x00212,0x00212), `Abs (0x00213);
+ (0x00214,0x00214), `Abs (0x00215);
+ (0x00216,0x00216), `Abs (0x00217);
+ (0x00218,0x00218), `Abs (0x00219);
+ (0x0021A,0x0021A), `Abs (0x0021B);
+ (0x0021C,0x0021C), `Abs (0x0021D);
+ (0x0021E,0x0021E), `Abs (0x0021F);
+ (0x00220,0x00220), `Abs (0x0019E);
+ (0x00222,0x00222), `Abs (0x00223);
+ (0x00224,0x00224), `Abs (0x00225);
+ (0x00226,0x00226), `Abs (0x00227);
+ (0x00228,0x00228), `Abs (0x00229);
+ (0x0022A,0x0022A), `Abs (0x0022B);
+ (0x0022C,0x0022C), `Abs (0x0022D);
+ (0x0022E,0x0022E), `Abs (0x0022F);
+ (0x00230,0x00230), `Abs (0x00231);
+ (0x00232,0x00232), `Abs (0x00233);
+ (0x0023A,0x0023A), `Abs (0x02C65);
+ (0x0023B,0x0023B), `Abs (0x0023C);
+ (0x0023D,0x0023D), `Abs (0x0019A);
+ (0x0023E,0x0023E), `Abs (0x02C66);
+ (0x00241,0x00241), `Abs (0x00242);
+ (0x00243,0x00243), `Abs (0x00180);
+ (0x00244,0x00244), `Abs (0x00289);
+ (0x00245,0x00245), `Abs (0x0028C);
+ (0x00246,0x00246), `Abs (0x00247);
+ (0x00248,0x00248), `Abs (0x00249);
+ (0x0024A,0x0024A), `Abs (0x0024B);
+ (0x0024C,0x0024C), `Abs (0x0024D);
+ (0x0024E,0x0024E), `Abs (0x0024F);
+ (0x00370,0x00370), `Abs (0x00371);
+ (0x00372,0x00372), `Abs (0x00373);
+ (0x00376,0x00376), `Abs (0x00377);
+ (0x0037F,0x0037F), `Abs (0x003F3);
+ (0x00386,0x00386), `Abs (0x003AC);
+ (0x00388,0x0038A), `Delta (37);
+ (0x0038C,0x0038C), `Abs (0x003CC);
+ (0x0038E,0x0038F), `Delta (63);
+ (0x00391,0x003A1), `Delta (32);
+ (0x003A3,0x003AB), `Delta (32);
+ (0x003CF,0x003CF), `Abs (0x003D7);
+ (0x003D2,0x003D4), `Delta (0);
+ (0x003D8,0x003D8), `Abs (0x003D9);
+ (0x003DA,0x003DA), `Abs (0x003DB);
+ (0x003DC,0x003DC), `Abs (0x003DD);
+ (0x003DE,0x003DE), `Abs (0x003DF);
+ (0x003E0,0x003E0), `Abs (0x003E1);
+ (0x003E2,0x003E2), `Abs (0x003E3);
+ (0x003E4,0x003E4), `Abs (0x003E5);
+ (0x003E6,0x003E6), `Abs (0x003E7);
+ (0x003E8,0x003E8), `Abs (0x003E9);
+ (0x003EA,0x003EA), `Abs (0x003EB);
+ (0x003EC,0x003EC), `Abs (0x003ED);
+ (0x003EE,0x003EE), `Abs (0x003EF);
+ (0x003F4,0x003F4), `Abs (0x003B8);
+ (0x003F7,0x003F7), `Abs (0x003F8);
+ (0x003F9,0x003F9), `Abs (0x003F2);
+ (0x003FA,0x003FA), `Abs (0x003FB);
+ (0x003FD,0x003FF), `Delta (-130);
+ (0x00400,0x0040F), `Delta (80);
+ (0x00410,0x0042F), `Delta (32);
+ (0x00460,0x00460), `Abs (0x00461);
+ (0x00462,0x00462), `Abs (0x00463);
+ (0x00464,0x00464), `Abs (0x00465);
+ (0x00466,0x00466), `Abs (0x00467);
+ (0x00468,0x00468), `Abs (0x00469);
+ (0x0046A,0x0046A), `Abs (0x0046B);
+ (0x0046C,0x0046C), `Abs (0x0046D);
+ (0x0046E,0x0046E), `Abs (0x0046F);
+ (0x00470,0x00470), `Abs (0x00471);
+ (0x00472,0x00472), `Abs (0x00473);
+ (0x00474,0x00474), `Abs (0x00475);
+ (0x00476,0x00476), `Abs (0x00477);
+ (0x00478,0x00478), `Abs (0x00479);
+ (0x0047A,0x0047A), `Abs (0x0047B);
+ (0x0047C,0x0047C), `Abs (0x0047D);
+ (0x0047E,0x0047E), `Abs (0x0047F);
+ (0x00480,0x00480), `Abs (0x00481);
+ (0x0048A,0x0048A), `Abs (0x0048B);
+ (0x0048C,0x0048C), `Abs (0x0048D);
+ (0x0048E,0x0048E), `Abs (0x0048F);
+ (0x00490,0x00490), `Abs (0x00491);
+ (0x00492,0x00492), `Abs (0x00493);
+ (0x00494,0x00494), `Abs (0x00495);
+ (0x00496,0x00496), `Abs (0x00497);
+ (0x00498,0x00498), `Abs (0x00499);
+ (0x0049A,0x0049A), `Abs (0x0049B);
+ (0x0049C,0x0049C), `Abs (0x0049D);
+ (0x0049E,0x0049E), `Abs (0x0049F);
+ (0x004A0,0x004A0), `Abs (0x004A1);
+ (0x004A2,0x004A2), `Abs (0x004A3);
+ (0x004A4,0x004A4), `Abs (0x004A5);
+ (0x004A6,0x004A6), `Abs (0x004A7);
+ (0x004A8,0x004A8), `Abs (0x004A9);
+ (0x004AA,0x004AA), `Abs (0x004AB);
+ (0x004AC,0x004AC), `Abs (0x004AD);
+ (0x004AE,0x004AE), `Abs (0x004AF);
+ (0x004B0,0x004B0), `Abs (0x004B1);
+ (0x004B2,0x004B2), `Abs (0x004B3);
+ (0x004B4,0x004B4), `Abs (0x004B5);
+ (0x004B6,0x004B6), `Abs (0x004B7);
+ (0x004B8,0x004B8), `Abs (0x004B9);
+ (0x004BA,0x004BA), `Abs (0x004BB);
+ (0x004BC,0x004BC), `Abs (0x004BD);
+ (0x004BE,0x004BE), `Abs (0x004BF);
+ (0x004C0,0x004C0), `Abs (0x004CF);
+ (0x004C1,0x004C1), `Abs (0x004C2);
+ (0x004C3,0x004C3), `Abs (0x004C4);
+ (0x004C5,0x004C5), `Abs (0x004C6);
+ (0x004C7,0x004C7), `Abs (0x004C8);
+ (0x004C9,0x004C9), `Abs (0x004CA);
+ (0x004CB,0x004CB), `Abs (0x004CC);
+ (0x004CD,0x004CD), `Abs (0x004CE);
+ (0x004D0,0x004D0), `Abs (0x004D1);
+ (0x004D2,0x004D2), `Abs (0x004D3);
+ (0x004D4,0x004D4), `Abs (0x004D5);
+ (0x004D6,0x004D6), `Abs (0x004D7);
+ (0x004D8,0x004D8), `Abs (0x004D9);
+ (0x004DA,0x004DA), `Abs (0x004DB);
+ (0x004DC,0x004DC), `Abs (0x004DD);
+ (0x004DE,0x004DE), `Abs (0x004DF);
+ (0x004E0,0x004E0), `Abs (0x004E1);
+ (0x004E2,0x004E2), `Abs (0x004E3);
+ (0x004E4,0x004E4), `Abs (0x004E5);
+ (0x004E6,0x004E6), `Abs (0x004E7);
+ (0x004E8,0x004E8), `Abs (0x004E9);
+ (0x004EA,0x004EA), `Abs (0x004EB);
+ (0x004EC,0x004EC), `Abs (0x004ED);
+ (0x004EE,0x004EE), `Abs (0x004EF);
+ (0x004F0,0x004F0), `Abs (0x004F1);
+ (0x004F2,0x004F2), `Abs (0x004F3);
+ (0x004F4,0x004F4), `Abs (0x004F5);
+ (0x004F6,0x004F6), `Abs (0x004F7);
+ (0x004F8,0x004F8), `Abs (0x004F9);
+ (0x004FA,0x004FA), `Abs (0x004FB);
+ (0x004FC,0x004FC), `Abs (0x004FD);
+ (0x004FE,0x004FE), `Abs (0x004FF);
+ (0x00500,0x00500), `Abs (0x00501);
+ (0x00502,0x00502), `Abs (0x00503);
+ (0x00504,0x00504), `Abs (0x00505);
+ (0x00506,0x00506), `Abs (0x00507);
+ (0x00508,0x00508), `Abs (0x00509);
+ (0x0050A,0x0050A), `Abs (0x0050B);
+ (0x0050C,0x0050C), `Abs (0x0050D);
+ (0x0050E,0x0050E), `Abs (0x0050F);
+ (0x00510,0x00510), `Abs (0x00511);
+ (0x00512,0x00512), `Abs (0x00513);
+ (0x00514,0x00514), `Abs (0x00515);
+ (0x00516,0x00516), `Abs (0x00517);
+ (0x00518,0x00518), `Abs (0x00519);
+ (0x0051A,0x0051A), `Abs (0x0051B);
+ (0x0051C,0x0051C), `Abs (0x0051D);
+ (0x0051E,0x0051E), `Abs (0x0051F);
+ (0x00520,0x00520), `Abs (0x00521);
+ (0x00522,0x00522), `Abs (0x00523);
+ (0x00524,0x00524), `Abs (0x00525);
+ (0x00526,0x00526), `Abs (0x00527);
+ (0x00528,0x00528), `Abs (0x00529);
+ (0x0052A,0x0052A), `Abs (0x0052B);
+ (0x0052C,0x0052C), `Abs (0x0052D);
+ (0x0052E,0x0052E), `Abs (0x0052F);
+ (0x00531,0x00556), `Delta (48);
+ (0x010A0,0x010C5), `Delta (7264);
+ (0x010C7,0x010C7), `Abs (0x02D27);
+ (0x010CD,0x010CD), `Abs (0x02D2D);
+ (0x013A0,0x013EF), `Delta (38864);
+ (0x013F0,0x013F5), `Delta (8);
+ (0x01E00,0x01E00), `Abs (0x01E01);
+ (0x01E02,0x01E02), `Abs (0x01E03);
+ (0x01E04,0x01E04), `Abs (0x01E05);
+ (0x01E06,0x01E06), `Abs (0x01E07);
+ (0x01E08,0x01E08), `Abs (0x01E09);
+ (0x01E0A,0x01E0A), `Abs (0x01E0B);
+ (0x01E0C,0x01E0C), `Abs (0x01E0D);
+ (0x01E0E,0x01E0E), `Abs (0x01E0F);
+ (0x01E10,0x01E10), `Abs (0x01E11);
+ (0x01E12,0x01E12), `Abs (0x01E13);
+ (0x01E14,0x01E14), `Abs (0x01E15);
+ (0x01E16,0x01E16), `Abs (0x01E17);
+ (0x01E18,0x01E18), `Abs (0x01E19);
+ (0x01E1A,0x01E1A), `Abs (0x01E1B);
+ (0x01E1C,0x01E1C), `Abs (0x01E1D);
+ (0x01E1E,0x01E1E), `Abs (0x01E1F);
+ (0x01E20,0x01E20), `Abs (0x01E21);
+ (0x01E22,0x01E22), `Abs (0x01E23);
+ (0x01E24,0x01E24), `Abs (0x01E25);
+ (0x01E26,0x01E26), `Abs (0x01E27);
+ (0x01E28,0x01E28), `Abs (0x01E29);
+ (0x01E2A,0x01E2A), `Abs (0x01E2B);
+ (0x01E2C,0x01E2C), `Abs (0x01E2D);
+ (0x01E2E,0x01E2E), `Abs (0x01E2F);
+ (0x01E30,0x01E30), `Abs (0x01E31);
+ (0x01E32,0x01E32), `Abs (0x01E33);
+ (0x01E34,0x01E34), `Abs (0x01E35);
+ (0x01E36,0x01E36), `Abs (0x01E37);
+ (0x01E38,0x01E38), `Abs (0x01E39);
+ (0x01E3A,0x01E3A), `Abs (0x01E3B);
+ (0x01E3C,0x01E3C), `Abs (0x01E3D);
+ (0x01E3E,0x01E3E), `Abs (0x01E3F);
+ (0x01E40,0x01E40), `Abs (0x01E41);
+ (0x01E42,0x01E42), `Abs (0x01E43);
+ (0x01E44,0x01E44), `Abs (0x01E45);
+ (0x01E46,0x01E46), `Abs (0x01E47);
+ (0x01E48,0x01E48), `Abs (0x01E49);
+ (0x01E4A,0x01E4A), `Abs (0x01E4B);
+ (0x01E4C,0x01E4C), `Abs (0x01E4D);
+ (0x01E4E,0x01E4E), `Abs (0x01E4F);
+ (0x01E50,0x01E50), `Abs (0x01E51);
+ (0x01E52,0x01E52), `Abs (0x01E53);
+ (0x01E54,0x01E54), `Abs (0x01E55);
+ (0x01E56,0x01E56), `Abs (0x01E57);
+ (0x01E58,0x01E58), `Abs (0x01E59);
+ (0x01E5A,0x01E5A), `Abs (0x01E5B);
+ (0x01E5C,0x01E5C), `Abs (0x01E5D);
+ (0x01E5E,0x01E5E), `Abs (0x01E5F);
+ (0x01E60,0x01E60), `Abs (0x01E61);
+ (0x01E62,0x01E62), `Abs (0x01E63);
+ (0x01E64,0x01E64), `Abs (0x01E65);
+ (0x01E66,0x01E66), `Abs (0x01E67);
+ (0x01E68,0x01E68), `Abs (0x01E69);
+ (0x01E6A,0x01E6A), `Abs (0x01E6B);
+ (0x01E6C,0x01E6C), `Abs (0x01E6D);
+ (0x01E6E,0x01E6E), `Abs (0x01E6F);
+ (0x01E70,0x01E70), `Abs (0x01E71);
+ (0x01E72,0x01E72), `Abs (0x01E73);
+ (0x01E74,0x01E74), `Abs (0x01E75);
+ (0x01E76,0x01E76), `Abs (0x01E77);
+ (0x01E78,0x01E78), `Abs (0x01E79);
+ (0x01E7A,0x01E7A), `Abs (0x01E7B);
+ (0x01E7C,0x01E7C), `Abs (0x01E7D);
+ (0x01E7E,0x01E7E), `Abs (0x01E7F);
+ (0x01E80,0x01E80), `Abs (0x01E81);
+ (0x01E82,0x01E82), `Abs (0x01E83);
+ (0x01E84,0x01E84), `Abs (0x01E85);
+ (0x01E86,0x01E86), `Abs (0x01E87);
+ (0x01E88,0x01E88), `Abs (0x01E89);
+ (0x01E8A,0x01E8A), `Abs (0x01E8B);
+ (0x01E8C,0x01E8C), `Abs (0x01E8D);
+ (0x01E8E,0x01E8E), `Abs (0x01E8F);
+ (0x01E90,0x01E90), `Abs (0x01E91);
+ (0x01E92,0x01E92), `Abs (0x01E93);
+ (0x01E94,0x01E94), `Abs (0x01E95);
+ (0x01E9E,0x01E9E), `Abs (0x000DF);
+ (0x01EA0,0x01EA0), `Abs (0x01EA1);
+ (0x01EA2,0x01EA2), `Abs (0x01EA3);
+ (0x01EA4,0x01EA4), `Abs (0x01EA5);
+ (0x01EA6,0x01EA6), `Abs (0x01EA7);
+ (0x01EA8,0x01EA8), `Abs (0x01EA9);
+ (0x01EAA,0x01EAA), `Abs (0x01EAB);
+ (0x01EAC,0x01EAC), `Abs (0x01EAD);
+ (0x01EAE,0x01EAE), `Abs (0x01EAF);
+ (0x01EB0,0x01EB0), `Abs (0x01EB1);
+ (0x01EB2,0x01EB2), `Abs (0x01EB3);
+ (0x01EB4,0x01EB4), `Abs (0x01EB5);
+ (0x01EB6,0x01EB6), `Abs (0x01EB7);
+ (0x01EB8,0x01EB8), `Abs (0x01EB9);
+ (0x01EBA,0x01EBA), `Abs (0x01EBB);
+ (0x01EBC,0x01EBC), `Abs (0x01EBD);
+ (0x01EBE,0x01EBE), `Abs (0x01EBF);
+ (0x01EC0,0x01EC0), `Abs (0x01EC1);
+ (0x01EC2,0x01EC2), `Abs (0x01EC3);
+ (0x01EC4,0x01EC4), `Abs (0x01EC5);
+ (0x01EC6,0x01EC6), `Abs (0x01EC7);
+ (0x01EC8,0x01EC8), `Abs (0x01EC9);
+ (0x01ECA,0x01ECA), `Abs (0x01ECB);
+ (0x01ECC,0x01ECC), `Abs (0x01ECD);
+ (0x01ECE,0x01ECE), `Abs (0x01ECF);
+ (0x01ED0,0x01ED0), `Abs (0x01ED1);
+ (0x01ED2,0x01ED2), `Abs (0x01ED3);
+ (0x01ED4,0x01ED4), `Abs (0x01ED5);
+ (0x01ED6,0x01ED6), `Abs (0x01ED7);
+ (0x01ED8,0x01ED8), `Abs (0x01ED9);
+ (0x01EDA,0x01EDA), `Abs (0x01EDB);
+ (0x01EDC,0x01EDC), `Abs (0x01EDD);
+ (0x01EDE,0x01EDE), `Abs (0x01EDF);
+ (0x01EE0,0x01EE0), `Abs (0x01EE1);
+ (0x01EE2,0x01EE2), `Abs (0x01EE3);
+ (0x01EE4,0x01EE4), `Abs (0x01EE5);
+ (0x01EE6,0x01EE6), `Abs (0x01EE7);
+ (0x01EE8,0x01EE8), `Abs (0x01EE9);
+ (0x01EEA,0x01EEA), `Abs (0x01EEB);
+ (0x01EEC,0x01EEC), `Abs (0x01EED);
+ (0x01EEE,0x01EEE), `Abs (0x01EEF);
+ (0x01EF0,0x01EF0), `Abs (0x01EF1);
+ (0x01EF2,0x01EF2), `Abs (0x01EF3);
+ (0x01EF4,0x01EF4), `Abs (0x01EF5);
+ (0x01EF6,0x01EF6), `Abs (0x01EF7);
+ (0x01EF8,0x01EF8), `Abs (0x01EF9);
+ (0x01EFA,0x01EFA), `Abs (0x01EFB);
+ (0x01EFC,0x01EFC), `Abs (0x01EFD);
+ (0x01EFE,0x01EFE), `Abs (0x01EFF);
+ (0x01F08,0x01F0F), `Delta (-8);
+ (0x01F18,0x01F1D), `Delta (-8);
+ (0x01F28,0x01F2F), `Delta (-8);
+ (0x01F38,0x01F3F), `Delta (-8);
+ (0x01F48,0x01F4D), `Delta (-8);
+ (0x01F59,0x01F59), `Abs (0x01F51);
+ (0x01F5B,0x01F5B), `Abs (0x01F53);
+ (0x01F5D,0x01F5D), `Abs (0x01F55);
+ (0x01F5F,0x01F5F), `Abs (0x01F57);
+ (0x01F68,0x01F6F), `Delta (-8);
+ (0x01FB8,0x01FB9), `Delta (-8);
+ (0x01FBA,0x01FBB), `Delta (-74);
+ (0x01FC8,0x01FCB), `Delta (-86);
+ (0x01FD8,0x01FD9), `Delta (-8);
+ (0x01FDA,0x01FDB), `Delta (-100);
+ (0x01FE8,0x01FE9), `Delta (-8);
+ (0x01FEA,0x01FEB), `Delta (-112);
+ (0x01FEC,0x01FEC), `Abs (0x01FE5);
+ (0x01FF8,0x01FF9), `Delta (-128);
+ (0x01FFA,0x01FFB), `Delta (-126);
+ (0x02102,0x02102), `Abs (0x02102);
+ (0x02107,0x02107), `Abs (0x02107);
+ (0x0210B,0x0210D), `Delta (0);
+ (0x02110,0x02112), `Delta (0);
+ (0x02115,0x02115), `Abs (0x02115);
+ (0x02119,0x0211D), `Delta (0);
+ (0x02124,0x02124), `Abs (0x02124);
+ (0x02126,0x02126), `Abs (0x003C9);
+ (0x02128,0x02128), `Abs (0x02128);
+ (0x0212A,0x0212A), `Abs (0x0006B);
+ (0x0212B,0x0212B), `Abs (0x000E5);
+ (0x0212C,0x0212D), `Delta (0);
+ (0x02130,0x02131), `Delta (0);
+ (0x02132,0x02132), `Abs (0x0214E);
+ (0x02133,0x02133), `Abs (0x02133);
+ (0x0213E,0x0213F), `Delta (0);
+ (0x02145,0x02145), `Abs (0x02145);
+ (0x02183,0x02183), `Abs (0x02184);
+ (0x02C00,0x02C2E), `Delta (48);
+ (0x02C60,0x02C60), `Abs (0x02C61);
+ (0x02C62,0x02C62), `Abs (0x0026B);
+ (0x02C63,0x02C63), `Abs (0x01D7D);
+ (0x02C64,0x02C64), `Abs (0x0027D);
+ (0x02C67,0x02C67), `Abs (0x02C68);
+ (0x02C69,0x02C69), `Abs (0x02C6A);
+ (0x02C6B,0x02C6B), `Abs (0x02C6C);
+ (0x02C6D,0x02C6D), `Abs (0x00251);
+ (0x02C6E,0x02C6E), `Abs (0x00271);
+ (0x02C6F,0x02C6F), `Abs (0x00250);
+ (0x02C70,0x02C70), `Abs (0x00252);
+ (0x02C72,0x02C72), `Abs (0x02C73);
+ (0x02C75,0x02C75), `Abs (0x02C76);
+ (0x02C7E,0x02C7F), `Delta (-10815);
+ (0x02C80,0x02C80), `Abs (0x02C81);
+ (0x02C82,0x02C82), `Abs (0x02C83);
+ (0x02C84,0x02C84), `Abs (0x02C85);
+ (0x02C86,0x02C86), `Abs (0x02C87);
+ (0x02C88,0x02C88), `Abs (0x02C89);
+ (0x02C8A,0x02C8A), `Abs (0x02C8B);
+ (0x02C8C,0x02C8C), `Abs (0x02C8D);
+ (0x02C8E,0x02C8E), `Abs (0x02C8F);
+ (0x02C90,0x02C90), `Abs (0x02C91);
+ (0x02C92,0x02C92), `Abs (0x02C93);
+ (0x02C94,0x02C94), `Abs (0x02C95);
+ (0x02C96,0x02C96), `Abs (0x02C97);
+ (0x02C98,0x02C98), `Abs (0x02C99);
+ (0x02C9A,0x02C9A), `Abs (0x02C9B);
+ (0x02C9C,0x02C9C), `Abs (0x02C9D);
+ (0x02C9E,0x02C9E), `Abs (0x02C9F);
+ (0x02CA0,0x02CA0), `Abs (0x02CA1);
+ (0x02CA2,0x02CA2), `Abs (0x02CA3);
+ (0x02CA4,0x02CA4), `Abs (0x02CA5);
+ (0x02CA6,0x02CA6), `Abs (0x02CA7);
+ (0x02CA8,0x02CA8), `Abs (0x02CA9);
+ (0x02CAA,0x02CAA), `Abs (0x02CAB);
+ (0x02CAC,0x02CAC), `Abs (0x02CAD);
+ (0x02CAE,0x02CAE), `Abs (0x02CAF);
+ (0x02CB0,0x02CB0), `Abs (0x02CB1);
+ (0x02CB2,0x02CB2), `Abs (0x02CB3);
+ (0x02CB4,0x02CB4), `Abs (0x02CB5);
+ (0x02CB6,0x02CB6), `Abs (0x02CB7);
+ (0x02CB8,0x02CB8), `Abs (0x02CB9);
+ (0x02CBA,0x02CBA), `Abs (0x02CBB);
+ (0x02CBC,0x02CBC), `Abs (0x02CBD);
+ (0x02CBE,0x02CBE), `Abs (0x02CBF);
+ (0x02CC0,0x02CC0), `Abs (0x02CC1);
+ (0x02CC2,0x02CC2), `Abs (0x02CC3);
+ (0x02CC4,0x02CC4), `Abs (0x02CC5);
+ (0x02CC6,0x02CC6), `Abs (0x02CC7);
+ (0x02CC8,0x02CC8), `Abs (0x02CC9);
+ (0x02CCA,0x02CCA), `Abs (0x02CCB);
+ (0x02CCC,0x02CCC), `Abs (0x02CCD);
+ (0x02CCE,0x02CCE), `Abs (0x02CCF);
+ (0x02CD0,0x02CD0), `Abs (0x02CD1);
+ (0x02CD2,0x02CD2), `Abs (0x02CD3);
+ (0x02CD4,0x02CD4), `Abs (0x02CD5);
+ (0x02CD6,0x02CD6), `Abs (0x02CD7);
+ (0x02CD8,0x02CD8), `Abs (0x02CD9);
+ (0x02CDA,0x02CDA), `Abs (0x02CDB);
+ (0x02CDC,0x02CDC), `Abs (0x02CDD);
+ (0x02CDE,0x02CDE), `Abs (0x02CDF);
+ (0x02CE0,0x02CE0), `Abs (0x02CE1);
+ (0x02CE2,0x02CE2), `Abs (0x02CE3);
+ (0x02CEB,0x02CEB), `Abs (0x02CEC);
+ (0x02CED,0x02CED), `Abs (0x02CEE);
+ (0x02CF2,0x02CF2), `Abs (0x02CF3);
+ (0x0A640,0x0A640), `Abs (0x0A641);
+ (0x0A642,0x0A642), `Abs (0x0A643);
+ (0x0A644,0x0A644), `Abs (0x0A645);
+ (0x0A646,0x0A646), `Abs (0x0A647);
+ (0x0A648,0x0A648), `Abs (0x0A649);
+ (0x0A64A,0x0A64A), `Abs (0x0A64B);
+ (0x0A64C,0x0A64C), `Abs (0x0A64D);
+ (0x0A64E,0x0A64E), `Abs (0x0A64F);
+ (0x0A650,0x0A650), `Abs (0x0A651);
+ (0x0A652,0x0A652), `Abs (0x0A653);
+ (0x0A654,0x0A654), `Abs (0x0A655);
+ (0x0A656,0x0A656), `Abs (0x0A657);
+ (0x0A658,0x0A658), `Abs (0x0A659);
+ (0x0A65A,0x0A65A), `Abs (0x0A65B);
+ (0x0A65C,0x0A65C), `Abs (0x0A65D);
+ (0x0A65E,0x0A65E), `Abs (0x0A65F);
+ (0x0A660,0x0A660), `Abs (0x0A661);
+ (0x0A662,0x0A662), `Abs (0x0A663);
+ (0x0A664,0x0A664), `Abs (0x0A665);
+ (0x0A666,0x0A666), `Abs (0x0A667);
+ (0x0A668,0x0A668), `Abs (0x0A669);
+ (0x0A66A,0x0A66A), `Abs (0x0A66B);
+ (0x0A66C,0x0A66C), `Abs (0x0A66D);
+ (0x0A680,0x0A680), `Abs (0x0A681);
+ (0x0A682,0x0A682), `Abs (0x0A683);
+ (0x0A684,0x0A684), `Abs (0x0A685);
+ (0x0A686,0x0A686), `Abs (0x0A687);
+ (0x0A688,0x0A688), `Abs (0x0A689);
+ (0x0A68A,0x0A68A), `Abs (0x0A68B);
+ (0x0A68C,0x0A68C), `Abs (0x0A68D);
+ (0x0A68E,0x0A68E), `Abs (0x0A68F);
+ (0x0A690,0x0A690), `Abs (0x0A691);
+ (0x0A692,0x0A692), `Abs (0x0A693);
+ (0x0A694,0x0A694), `Abs (0x0A695);
+ (0x0A696,0x0A696), `Abs (0x0A697);
+ (0x0A698,0x0A698), `Abs (0x0A699);
+ (0x0A69A,0x0A69A), `Abs (0x0A69B);
+ (0x0A722,0x0A722), `Abs (0x0A723);
+ (0x0A724,0x0A724), `Abs (0x0A725);
+ (0x0A726,0x0A726), `Abs (0x0A727);
+ (0x0A728,0x0A728), `Abs (0x0A729);
+ (0x0A72A,0x0A72A), `Abs (0x0A72B);
+ (0x0A72C,0x0A72C), `Abs (0x0A72D);
+ (0x0A72E,0x0A72E), `Abs (0x0A72F);
+ (0x0A732,0x0A732), `Abs (0x0A733);
+ (0x0A734,0x0A734), `Abs (0x0A735);
+ (0x0A736,0x0A736), `Abs (0x0A737);
+ (0x0A738,0x0A738), `Abs (0x0A739);
+ (0x0A73A,0x0A73A), `Abs (0x0A73B);
+ (0x0A73C,0x0A73C), `Abs (0x0A73D);
+ (0x0A73E,0x0A73E), `Abs (0x0A73F);
+ (0x0A740,0x0A740), `Abs (0x0A741);
+ (0x0A742,0x0A742), `Abs (0x0A743);
+ (0x0A744,0x0A744), `Abs (0x0A745);
+ (0x0A746,0x0A746), `Abs (0x0A747);
+ (0x0A748,0x0A748), `Abs (0x0A749);
+ (0x0A74A,0x0A74A), `Abs (0x0A74B);
+ (0x0A74C,0x0A74C), `Abs (0x0A74D);
+ (0x0A74E,0x0A74E), `Abs (0x0A74F);
+ (0x0A750,0x0A750), `Abs (0x0A751);
+ (0x0A752,0x0A752), `Abs (0x0A753);
+ (0x0A754,0x0A754), `Abs (0x0A755);
+ (0x0A756,0x0A756), `Abs (0x0A757);
+ (0x0A758,0x0A758), `Abs (0x0A759);
+ (0x0A75A,0x0A75A), `Abs (0x0A75B);
+ (0x0A75C,0x0A75C), `Abs (0x0A75D);
+ (0x0A75E,0x0A75E), `Abs (0x0A75F);
+ (0x0A760,0x0A760), `Abs (0x0A761);
+ (0x0A762,0x0A762), `Abs (0x0A763);
+ (0x0A764,0x0A764), `Abs (0x0A765);
+ (0x0A766,0x0A766), `Abs (0x0A767);
+ (0x0A768,0x0A768), `Abs (0x0A769);
+ (0x0A76A,0x0A76A), `Abs (0x0A76B);
+ (0x0A76C,0x0A76C), `Abs (0x0A76D);
+ (0x0A76E,0x0A76E), `Abs (0x0A76F);
+ (0x0A779,0x0A779), `Abs (0x0A77A);
+ (0x0A77B,0x0A77B), `Abs (0x0A77C);
+ (0x0A77D,0x0A77D), `Abs (0x01D79);
+ (0x0A77E,0x0A77E), `Abs (0x0A77F);
+ (0x0A780,0x0A780), `Abs (0x0A781);
+ (0x0A782,0x0A782), `Abs (0x0A783);
+ (0x0A784,0x0A784), `Abs (0x0A785);
+ (0x0A786,0x0A786), `Abs (0x0A787);
+ (0x0A78B,0x0A78B), `Abs (0x0A78C);
+ (0x0A78D,0x0A78D), `Abs (0x00265);
+ (0x0A790,0x0A790), `Abs (0x0A791);
+ (0x0A792,0x0A792), `Abs (0x0A793);
+ (0x0A796,0x0A796), `Abs (0x0A797);
+ (0x0A798,0x0A798), `Abs (0x0A799);
+ (0x0A79A,0x0A79A), `Abs (0x0A79B);
+ (0x0A79C,0x0A79C), `Abs (0x0A79D);
+ (0x0A79E,0x0A79E), `Abs (0x0A79F);
+ (0x0A7A0,0x0A7A0), `Abs (0x0A7A1);
+ (0x0A7A2,0x0A7A2), `Abs (0x0A7A3);
+ (0x0A7A4,0x0A7A4), `Abs (0x0A7A5);
+ (0x0A7A6,0x0A7A6), `Abs (0x0A7A7);
+ (0x0A7A8,0x0A7A8), `Abs (0x0A7A9);
+ (0x0A7AA,0x0A7AA), `Abs (0x00266);
+ (0x0A7AB,0x0A7AB), `Abs (0x0025C);
+ (0x0A7AC,0x0A7AC), `Abs (0x00261);
+ (0x0A7AD,0x0A7AD), `Abs (0x0026C);
+ (0x0A7AE,0x0A7AE), `Abs (0x0026A);
+ (0x0A7B0,0x0A7B0), `Abs (0x0029E);
+ (0x0A7B1,0x0A7B1), `Abs (0x00287);
+ (0x0A7B2,0x0A7B2), `Abs (0x0029D);
+ (0x0A7B3,0x0A7B3), `Abs (0x0AB53);
+ (0x0A7B4,0x0A7B4), `Abs (0x0A7B5);
+ (0x0A7B6,0x0A7B6), `Abs (0x0A7B7);
+ (0x0FF21,0x0FF3A), `Delta (32);
+ (0x10400,0x10427), `Delta (40);
+ (0x104B0,0x104D3), `Delta (40);
+ (0x10C80,0x10CB2), `Delta (64);
+ (0x118A0,0x118BF), `Delta (32);
+ (0x1D400,0x1D419), `Delta (0);
+ (0x1D434,0x1D44D), `Delta (0);
+ (0x1D468,0x1D481), `Delta (0);
+ (0x1D49C,0x1D49C), `Abs (0x1D49C);
+ (0x1D49E,0x1D49F), `Delta (0);
+ (0x1D4A2,0x1D4A2), `Abs (0x1D4A2);
+ (0x1D4A5,0x1D4A6), `Delta (0);
+ (0x1D4A9,0x1D4AC), `Delta (0);
+ (0x1D4AE,0x1D4B5), `Delta (0);
+ (0x1D4D0,0x1D4E9), `Delta (0);
+ (0x1D504,0x1D505), `Delta (0);
+ (0x1D507,0x1D50A), `Delta (0);
+ (0x1D50D,0x1D514), `Delta (0);
+ (0x1D516,0x1D51C), `Delta (0);
+ (0x1D538,0x1D539), `Delta (0);
+ (0x1D53B,0x1D53E), `Delta (0);
+ (0x1D540,0x1D544), `Delta (0);
+ (0x1D546,0x1D546), `Abs (0x1D546);
+ (0x1D54A,0x1D550), `Delta (0);
+ (0x1D56C,0x1D585), `Delta (0);
+ (0x1D5A0,0x1D5B9), `Delta (0);
+ (0x1D5D4,0x1D5ED), `Delta (0);
+ (0x1D608,0x1D621), `Delta (0);
+ (0x1D63C,0x1D655), `Delta (0);
+ (0x1D670,0x1D689), `Delta (0);
+ (0x1D6A8,0x1D6C0), `Delta (0);
+ (0x1D6E2,0x1D6FA), `Delta (0);
+ (0x1D71C,0x1D734), `Delta (0);
+ (0x1D756,0x1D76E), `Delta (0);
+ (0x1D790,0x1D7A8), `Delta (0);
+ (0x1D7CA,0x1D7CA), `Abs (0x1D7CA);
+ (0x1E900,0x1E921), `Delta (34);
+ (0x00061,0x0007A), `Delta (0);
+ (0x000B5,0x000B5), `Abs (0x000B5);
+ (0x000DF,0x000F6), `Delta (0);
+ (0x000F8,0x000FF), `Delta (0);
+ (0x00101,0x00101), `Abs (0x00101);
+ (0x00103,0x00103), `Abs (0x00103);
+ (0x00105,0x00105), `Abs (0x00105);
+ (0x00107,0x00107), `Abs (0x00107);
+ (0x00109,0x00109), `Abs (0x00109);
+ (0x0010B,0x0010B), `Abs (0x0010B);
+ (0x0010D,0x0010D), `Abs (0x0010D);
+ (0x0010F,0x0010F), `Abs (0x0010F);
+ (0x00111,0x00111), `Abs (0x00111);
+ (0x00113,0x00113), `Abs (0x00113);
+ (0x00115,0x00115), `Abs (0x00115);
+ (0x00117,0x00117), `Abs (0x00117);
+ (0x00119,0x00119), `Abs (0x00119);
+ (0x0011B,0x0011B), `Abs (0x0011B);
+ (0x0011D,0x0011D), `Abs (0x0011D);
+ (0x0011F,0x0011F), `Abs (0x0011F);
+ (0x00121,0x00121), `Abs (0x00121);
+ (0x00123,0x00123), `Abs (0x00123);
+ (0x00125,0x00125), `Abs (0x00125);
+ (0x00127,0x00127), `Abs (0x00127);
+ (0x00129,0x00129), `Abs (0x00129);
+ (0x0012B,0x0012B), `Abs (0x0012B);
+ (0x0012D,0x0012D), `Abs (0x0012D);
+ (0x0012F,0x0012F), `Abs (0x0012F);
+ (0x00131,0x00131), `Abs (0x00131);
+ (0x00133,0x00133), `Abs (0x00133);
+ (0x00135,0x00135), `Abs (0x00135);
+ (0x00137,0x00138), `Delta (0);
+ (0x0013A,0x0013A), `Abs (0x0013A);
+ (0x0013C,0x0013C), `Abs (0x0013C);
+ (0x0013E,0x0013E), `Abs (0x0013E);
+ (0x00140,0x00140), `Abs (0x00140);
+ (0x00142,0x00142), `Abs (0x00142);
+ (0x00144,0x00144), `Abs (0x00144);
+ (0x00146,0x00146), `Abs (0x00146);
+ (0x00148,0x00149), `Delta (0);
+ (0x0014B,0x0014B), `Abs (0x0014B);
+ (0x0014D,0x0014D), `Abs (0x0014D);
+ (0x0014F,0x0014F), `Abs (0x0014F);
+ (0x00151,0x00151), `Abs (0x00151);
+ (0x00153,0x00153), `Abs (0x00153);
+ (0x00155,0x00155), `Abs (0x00155);
+ (0x00157,0x00157), `Abs (0x00157);
+ (0x00159,0x00159), `Abs (0x00159);
+ (0x0015B,0x0015B), `Abs (0x0015B);
+ (0x0015D,0x0015D), `Abs (0x0015D);
+ (0x0015F,0x0015F), `Abs (0x0015F);
+ (0x00161,0x00161), `Abs (0x00161);
+ (0x00163,0x00163), `Abs (0x00163);
+ (0x00165,0x00165), `Abs (0x00165);
+ (0x00167,0x00167), `Abs (0x00167);
+ (0x00169,0x00169), `Abs (0x00169);
+ (0x0016B,0x0016B), `Abs (0x0016B);
+ (0x0016D,0x0016D), `Abs (0x0016D);
+ (0x0016F,0x0016F), `Abs (0x0016F);
+ (0x00171,0x00171), `Abs (0x00171);
+ (0x00173,0x00173), `Abs (0x00173);
+ (0x00175,0x00175), `Abs (0x00175);
+ (0x00177,0x00177), `Abs (0x00177);
+ (0x0017A,0x0017A), `Abs (0x0017A);
+ (0x0017C,0x0017C), `Abs (0x0017C);
+ (0x0017E,0x00180), `Delta (0);
+ (0x00183,0x00183), `Abs (0x00183);
+ (0x00185,0x00185), `Abs (0x00185);
+ (0x00188,0x00188), `Abs (0x00188);
+ (0x0018C,0x0018D), `Delta (0);
+ (0x00192,0x00192), `Abs (0x00192);
+ (0x00195,0x00195), `Abs (0x00195);
+ (0x00199,0x0019B), `Delta (0);
+ (0x0019E,0x0019E), `Abs (0x0019E);
+ (0x001A1,0x001A1), `Abs (0x001A1);
+ (0x001A3,0x001A3), `Abs (0x001A3);
+ (0x001A5,0x001A5), `Abs (0x001A5);
+ (0x001A8,0x001A8), `Abs (0x001A8);
+ (0x001AA,0x001AB), `Delta (0);
+ (0x001AD,0x001AD), `Abs (0x001AD);
+ (0x001B0,0x001B0), `Abs (0x001B0);
+ (0x001B4,0x001B4), `Abs (0x001B4);
+ (0x001B6,0x001B6), `Abs (0x001B6);
+ (0x001B9,0x001BA), `Delta (0);
+ (0x001BD,0x001BF), `Delta (0);
+ (0x001C6,0x001C6), `Abs (0x001C6);
+ (0x001C9,0x001C9), `Abs (0x001C9);
+ (0x001CC,0x001CC), `Abs (0x001CC);
+ (0x001CE,0x001CE), `Abs (0x001CE);
+ (0x001D0,0x001D0), `Abs (0x001D0);
+ (0x001D2,0x001D2), `Abs (0x001D2);
+ (0x001D4,0x001D4), `Abs (0x001D4);
+ (0x001D6,0x001D6), `Abs (0x001D6);
+ (0x001D8,0x001D8), `Abs (0x001D8);
+ (0x001DA,0x001DA), `Abs (0x001DA);
+ (0x001DC,0x001DD), `Delta (0);
+ (0x001DF,0x001DF), `Abs (0x001DF);
+ (0x001E1,0x001E1), `Abs (0x001E1);
+ (0x001E3,0x001E3), `Abs (0x001E3);
+ (0x001E5,0x001E5), `Abs (0x001E5);
+ (0x001E7,0x001E7), `Abs (0x001E7);
+ (0x001E9,0x001E9), `Abs (0x001E9);
+ (0x001EB,0x001EB), `Abs (0x001EB);
+ (0x001ED,0x001ED), `Abs (0x001ED);
+ (0x001EF,0x001F0), `Delta (0);
+ (0x001F3,0x001F3), `Abs (0x001F3);
+ (0x001F5,0x001F5), `Abs (0x001F5);
+ (0x001F9,0x001F9), `Abs (0x001F9);
+ (0x001FB,0x001FB), `Abs (0x001FB);
+ (0x001FD,0x001FD), `Abs (0x001FD);
+ (0x001FF,0x001FF), `Abs (0x001FF);
+ (0x00201,0x00201), `Abs (0x00201);
+ (0x00203,0x00203), `Abs (0x00203);
+ (0x00205,0x00205), `Abs (0x00205);
+ (0x00207,0x00207), `Abs (0x00207);
+ (0x00209,0x00209), `Abs (0x00209);
+ (0x0020B,0x0020B), `Abs (0x0020B);
+ (0x0020D,0x0020D), `Abs (0x0020D);
+ (0x0020F,0x0020F), `Abs (0x0020F);
+ (0x00211,0x00211), `Abs (0x00211);
+ (0x00213,0x00213), `Abs (0x00213);
+ (0x00215,0x00215), `Abs (0x00215);
+ (0x00217,0x00217), `Abs (0x00217);
+ (0x00219,0x00219), `Abs (0x00219);
+ (0x0021B,0x0021B), `Abs (0x0021B);
+ (0x0021D,0x0021D), `Abs (0x0021D);
+ (0x0021F,0x0021F), `Abs (0x0021F);
+ (0x00221,0x00221), `Abs (0x00221);
+ (0x00223,0x00223), `Abs (0x00223);
+ (0x00225,0x00225), `Abs (0x00225);
+ (0x00227,0x00227), `Abs (0x00227);
+ (0x00229,0x00229), `Abs (0x00229);
+ (0x0022B,0x0022B), `Abs (0x0022B);
+ (0x0022D,0x0022D), `Abs (0x0022D);
+ (0x0022F,0x0022F), `Abs (0x0022F);
+ (0x00231,0x00231), `Abs (0x00231);
+ (0x00233,0x00239), `Delta (0);
+ (0x0023C,0x0023C), `Abs (0x0023C);
+ (0x0023F,0x00240), `Delta (0);
+ (0x00242,0x00242), `Abs (0x00242);
+ (0x00247,0x00247), `Abs (0x00247);
+ (0x00249,0x00249), `Abs (0x00249);
+ (0x0024B,0x0024B), `Abs (0x0024B);
+ (0x0024D,0x0024D), `Abs (0x0024D);
+ (0x0024F,0x00293), `Delta (0);
+ (0x00295,0x002AF), `Delta (0);
+ (0x00371,0x00371), `Abs (0x00371);
+ (0x00373,0x00373), `Abs (0x00373);
+ (0x00377,0x00377), `Abs (0x00377);
+ (0x0037B,0x0037D), `Delta (0);
+ (0x00390,0x00390), `Abs (0x00390);
+ (0x003AC,0x003CE), `Delta (0);
+ (0x003D0,0x003D1), `Delta (0);
+ (0x003D5,0x003D7), `Delta (0);
+ (0x003D9,0x003D9), `Abs (0x003D9);
+ (0x003DB,0x003DB), `Abs (0x003DB);
+ (0x003DD,0x003DD), `Abs (0x003DD);
+ (0x003DF,0x003DF), `Abs (0x003DF);
+ (0x003E1,0x003E1), `Abs (0x003E1);
+ (0x003E3,0x003E3), `Abs (0x003E3);
+ (0x003E5,0x003E5), `Abs (0x003E5);
+ (0x003E7,0x003E7), `Abs (0x003E7);
+ (0x003E9,0x003E9), `Abs (0x003E9);
+ (0x003EB,0x003EB), `Abs (0x003EB);
+ (0x003ED,0x003ED), `Abs (0x003ED);
+ (0x003EF,0x003F3), `Delta (0);
+ (0x003F5,0x003F5), `Abs (0x003F5);
+ (0x003F8,0x003F8), `Abs (0x003F8);
+ (0x003FB,0x003FC), `Delta (0);
+ (0x00430,0x0045F), `Delta (0);
+ (0x00461,0x00461), `Abs (0x00461);
+ (0x00463,0x00463), `Abs (0x00463);
+ (0x00465,0x00465), `Abs (0x00465);
+ (0x00467,0x00467), `Abs (0x00467);
+ (0x00469,0x00469), `Abs (0x00469);
+ (0x0046B,0x0046B), `Abs (0x0046B);
+ (0x0046D,0x0046D), `Abs (0x0046D);
+ (0x0046F,0x0046F), `Abs (0x0046F);
+ (0x00471,0x00471), `Abs (0x00471);
+ (0x00473,0x00473), `Abs (0x00473);
+ (0x00475,0x00475), `Abs (0x00475);
+ (0x00477,0x00477), `Abs (0x00477);
+ (0x00479,0x00479), `Abs (0x00479);
+ (0x0047B,0x0047B), `Abs (0x0047B);
+ (0x0047D,0x0047D), `Abs (0x0047D);
+ (0x0047F,0x0047F), `Abs (0x0047F);
+ (0x00481,0x00481), `Abs (0x00481);
+ (0x0048B,0x0048B), `Abs (0x0048B);
+ (0x0048D,0x0048D), `Abs (0x0048D);
+ (0x0048F,0x0048F), `Abs (0x0048F);
+ (0x00491,0x00491), `Abs (0x00491);
+ (0x00493,0x00493), `Abs (0x00493);
+ (0x00495,0x00495), `Abs (0x00495);
+ (0x00497,0x00497), `Abs (0x00497);
+ (0x00499,0x00499), `Abs (0x00499);
+ (0x0049B,0x0049B), `Abs (0x0049B);
+ (0x0049D,0x0049D), `Abs (0x0049D);
+ (0x0049F,0x0049F), `Abs (0x0049F);
+ (0x004A1,0x004A1), `Abs (0x004A1);
+ (0x004A3,0x004A3), `Abs (0x004A3);
+ (0x004A5,0x004A5), `Abs (0x004A5);
+ (0x004A7,0x004A7), `Abs (0x004A7);
+ (0x004A9,0x004A9), `Abs (0x004A9);
+ (0x004AB,0x004AB), `Abs (0x004AB);
+ (0x004AD,0x004AD), `Abs (0x004AD);
+ (0x004AF,0x004AF), `Abs (0x004AF);
+ (0x004B1,0x004B1), `Abs (0x004B1);
+ (0x004B3,0x004B3), `Abs (0x004B3);
+ (0x004B5,0x004B5), `Abs (0x004B5);
+ (0x004B7,0x004B7), `Abs (0x004B7);
+ (0x004B9,0x004B9), `Abs (0x004B9);
+ (0x004BB,0x004BB), `Abs (0x004BB);
+ (0x004BD,0x004BD), `Abs (0x004BD);
+ (0x004BF,0x004BF), `Abs (0x004BF);
+ (0x004C2,0x004C2), `Abs (0x004C2);
+ (0x004C4,0x004C4), `Abs (0x004C4);
+ (0x004C6,0x004C6), `Abs (0x004C6);
+ (0x004C8,0x004C8), `Abs (0x004C8);
+ (0x004CA,0x004CA), `Abs (0x004CA);
+ (0x004CC,0x004CC), `Abs (0x004CC);
+ (0x004CE,0x004CF), `Delta (0);
+ (0x004D1,0x004D1), `Abs (0x004D1);
+ (0x004D3,0x004D3), `Abs (0x004D3);
+ (0x004D5,0x004D5), `Abs (0x004D5);
+ (0x004D7,0x004D7), `Abs (0x004D7);
+ (0x004D9,0x004D9), `Abs (0x004D9);
+ (0x004DB,0x004DB), `Abs (0x004DB);
+ (0x004DD,0x004DD), `Abs (0x004DD);
+ (0x004DF,0x004DF), `Abs (0x004DF);
+ (0x004E1,0x004E1), `Abs (0x004E1);
+ (0x004E3,0x004E3), `Abs (0x004E3);
+ (0x004E5,0x004E5), `Abs (0x004E5);
+ (0x004E7,0x004E7), `Abs (0x004E7);
+ (0x004E9,0x004E9), `Abs (0x004E9);
+ (0x004EB,0x004EB), `Abs (0x004EB);
+ (0x004ED,0x004ED), `Abs (0x004ED);
+ (0x004EF,0x004EF), `Abs (0x004EF);
+ (0x004F1,0x004F1), `Abs (0x004F1);
+ (0x004F3,0x004F3), `Abs (0x004F3);
+ (0x004F5,0x004F5), `Abs (0x004F5);
+ (0x004F7,0x004F7), `Abs (0x004F7);
+ (0x004F9,0x004F9), `Abs (0x004F9);
+ (0x004FB,0x004FB), `Abs (0x004FB);
+ (0x004FD,0x004FD), `Abs (0x004FD);
+ (0x004FF,0x004FF), `Abs (0x004FF);
+ (0x00501,0x00501), `Abs (0x00501);
+ (0x00503,0x00503), `Abs (0x00503);
+ (0x00505,0x00505), `Abs (0x00505);
+ (0x00507,0x00507), `Abs (0x00507);
+ (0x00509,0x00509), `Abs (0x00509);
+ (0x0050B,0x0050B), `Abs (0x0050B);
+ (0x0050D,0x0050D), `Abs (0x0050D);
+ (0x0050F,0x0050F), `Abs (0x0050F);
+ (0x00511,0x00511), `Abs (0x00511);
+ (0x00513,0x00513), `Abs (0x00513);
+ (0x00515,0x00515), `Abs (0x00515);
+ (0x00517,0x00517), `Abs (0x00517);
+ (0x00519,0x00519), `Abs (0x00519);
+ (0x0051B,0x0051B), `Abs (0x0051B);
+ (0x0051D,0x0051D), `Abs (0x0051D);
+ (0x0051F,0x0051F), `Abs (0x0051F);
+ (0x00521,0x00521), `Abs (0x00521);
+ (0x00523,0x00523), `Abs (0x00523);
+ (0x00525,0x00525), `Abs (0x00525);
+ (0x00527,0x00527), `Abs (0x00527);
+ (0x00529,0x00529), `Abs (0x00529);
+ (0x0052B,0x0052B), `Abs (0x0052B);
+ (0x0052D,0x0052D), `Abs (0x0052D);
+ (0x0052F,0x0052F), `Abs (0x0052F);
+ (0x00561,0x00587), `Delta (0);
+ (0x013F8,0x013FD), `Delta (0);
+ (0x01C80,0x01C88), `Delta (0);
+ (0x01D00,0x01D2B), `Delta (0);
+ (0x01D6B,0x01D77), `Delta (0);
+ (0x01D79,0x01D9A), `Delta (0);
+ (0x01E01,0x01E01), `Abs (0x01E01);
+ (0x01E03,0x01E03), `Abs (0x01E03);
+ (0x01E05,0x01E05), `Abs (0x01E05);
+ (0x01E07,0x01E07), `Abs (0x01E07);
+ (0x01E09,0x01E09), `Abs (0x01E09);
+ (0x01E0B,0x01E0B), `Abs (0x01E0B);
+ (0x01E0D,0x01E0D), `Abs (0x01E0D);
+ (0x01E0F,0x01E0F), `Abs (0x01E0F);
+ (0x01E11,0x01E11), `Abs (0x01E11);
+ (0x01E13,0x01E13), `Abs (0x01E13);
+ (0x01E15,0x01E15), `Abs (0x01E15);
+ (0x01E17,0x01E17), `Abs (0x01E17);
+ (0x01E19,0x01E19), `Abs (0x01E19);
+ (0x01E1B,0x01E1B), `Abs (0x01E1B);
+ (0x01E1D,0x01E1D), `Abs (0x01E1D);
+ (0x01E1F,0x01E1F), `Abs (0x01E1F);
+ (0x01E21,0x01E21), `Abs (0x01E21);
+ (0x01E23,0x01E23), `Abs (0x01E23);
+ (0x01E25,0x01E25), `Abs (0x01E25);
+ (0x01E27,0x01E27), `Abs (0x01E27);
+ (0x01E29,0x01E29), `Abs (0x01E29);
+ (0x01E2B,0x01E2B), `Abs (0x01E2B);
+ (0x01E2D,0x01E2D), `Abs (0x01E2D);
+ (0x01E2F,0x01E2F), `Abs (0x01E2F);
+ (0x01E31,0x01E31), `Abs (0x01E31);
+ (0x01E33,0x01E33), `Abs (0x01E33);
+ (0x01E35,0x01E35), `Abs (0x01E35);
+ (0x01E37,0x01E37), `Abs (0x01E37);
+ (0x01E39,0x01E39), `Abs (0x01E39);
+ (0x01E3B,0x01E3B), `Abs (0x01E3B);
+ (0x01E3D,0x01E3D), `Abs (0x01E3D);
+ (0x01E3F,0x01E3F), `Abs (0x01E3F);
+ (0x01E41,0x01E41), `Abs (0x01E41);
+ (0x01E43,0x01E43), `Abs (0x01E43);
+ (0x01E45,0x01E45), `Abs (0x01E45);
+ (0x01E47,0x01E47), `Abs (0x01E47);
+ (0x01E49,0x01E49), `Abs (0x01E49);
+ (0x01E4B,0x01E4B), `Abs (0x01E4B);
+ (0x01E4D,0x01E4D), `Abs (0x01E4D);
+ (0x01E4F,0x01E4F), `Abs (0x01E4F);
+ (0x01E51,0x01E51), `Abs (0x01E51);
+ (0x01E53,0x01E53), `Abs (0x01E53);
+ (0x01E55,0x01E55), `Abs (0x01E55);
+ (0x01E57,0x01E57), `Abs (0x01E57);
+ (0x01E59,0x01E59), `Abs (0x01E59);
+ (0x01E5B,0x01E5B), `Abs (0x01E5B);
+ (0x01E5D,0x01E5D), `Abs (0x01E5D);
+ (0x01E5F,0x01E5F), `Abs (0x01E5F);
+ (0x01E61,0x01E61), `Abs (0x01E61);
+ (0x01E63,0x01E63), `Abs (0x01E63);
+ (0x01E65,0x01E65), `Abs (0x01E65);
+ (0x01E67,0x01E67), `Abs (0x01E67);
+ (0x01E69,0x01E69), `Abs (0x01E69);
+ (0x01E6B,0x01E6B), `Abs (0x01E6B);
+ (0x01E6D,0x01E6D), `Abs (0x01E6D);
+ (0x01E6F,0x01E6F), `Abs (0x01E6F);
+ (0x01E71,0x01E71), `Abs (0x01E71);
+ (0x01E73,0x01E73), `Abs (0x01E73);
+ (0x01E75,0x01E75), `Abs (0x01E75);
+ (0x01E77,0x01E77), `Abs (0x01E77);
+ (0x01E79,0x01E79), `Abs (0x01E79);
+ (0x01E7B,0x01E7B), `Abs (0x01E7B);
+ (0x01E7D,0x01E7D), `Abs (0x01E7D);
+ (0x01E7F,0x01E7F), `Abs (0x01E7F);
+ (0x01E81,0x01E81), `Abs (0x01E81);
+ (0x01E83,0x01E83), `Abs (0x01E83);
+ (0x01E85,0x01E85), `Abs (0x01E85);
+ (0x01E87,0x01E87), `Abs (0x01E87);
+ (0x01E89,0x01E89), `Abs (0x01E89);
+ (0x01E8B,0x01E8B), `Abs (0x01E8B);
+ (0x01E8D,0x01E8D), `Abs (0x01E8D);
+ (0x01E8F,0x01E8F), `Abs (0x01E8F);
+ (0x01E91,0x01E91), `Abs (0x01E91);
+ (0x01E93,0x01E93), `Abs (0x01E93);
+ (0x01E95,0x01E9D), `Delta (0);
+ (0x01E9F,0x01E9F), `Abs (0x01E9F);
+ (0x01EA1,0x01EA1), `Abs (0x01EA1);
+ (0x01EA3,0x01EA3), `Abs (0x01EA3);
+ (0x01EA5,0x01EA5), `Abs (0x01EA5);
+ (0x01EA7,0x01EA7), `Abs (0x01EA7);
+ (0x01EA9,0x01EA9), `Abs (0x01EA9);
+ (0x01EAB,0x01EAB), `Abs (0x01EAB);
+ (0x01EAD,0x01EAD), `Abs (0x01EAD);
+ (0x01EAF,0x01EAF), `Abs (0x01EAF);
+ (0x01EB1,0x01EB1), `Abs (0x01EB1);
+ (0x01EB3,0x01EB3), `Abs (0x01EB3);
+ (0x01EB5,0x01EB5), `Abs (0x01EB5);
+ (0x01EB7,0x01EB7), `Abs (0x01EB7);
+ (0x01EB9,0x01EB9), `Abs (0x01EB9);
+ (0x01EBB,0x01EBB), `Abs (0x01EBB);
+ (0x01EBD,0x01EBD), `Abs (0x01EBD);
+ (0x01EBF,0x01EBF), `Abs (0x01EBF);
+ (0x01EC1,0x01EC1), `Abs (0x01EC1);
+ (0x01EC3,0x01EC3), `Abs (0x01EC3);
+ (0x01EC5,0x01EC5), `Abs (0x01EC5);
+ (0x01EC7,0x01EC7), `Abs (0x01EC7);
+ (0x01EC9,0x01EC9), `Abs (0x01EC9);
+ (0x01ECB,0x01ECB), `Abs (0x01ECB);
+ (0x01ECD,0x01ECD), `Abs (0x01ECD);
+ (0x01ECF,0x01ECF), `Abs (0x01ECF);
+ (0x01ED1,0x01ED1), `Abs (0x01ED1);
+ (0x01ED3,0x01ED3), `Abs (0x01ED3);
+ (0x01ED5,0x01ED5), `Abs (0x01ED5);
+ (0x01ED7,0x01ED7), `Abs (0x01ED7);
+ (0x01ED9,0x01ED9), `Abs (0x01ED9);
+ (0x01EDB,0x01EDB), `Abs (0x01EDB);
+ (0x01EDD,0x01EDD), `Abs (0x01EDD);
+ (0x01EDF,0x01EDF), `Abs (0x01EDF);
+ (0x01EE1,0x01EE1), `Abs (0x01EE1);
+ (0x01EE3,0x01EE3), `Abs (0x01EE3);
+ (0x01EE5,0x01EE5), `Abs (0x01EE5);
+ (0x01EE7,0x01EE7), `Abs (0x01EE7);
+ (0x01EE9,0x01EE9), `Abs (0x01EE9);
+ (0x01EEB,0x01EEB), `Abs (0x01EEB);
+ (0x01EED,0x01EED), `Abs (0x01EED);
+ (0x01EEF,0x01EEF), `Abs (0x01EEF);
+ (0x01EF1,0x01EF1), `Abs (0x01EF1);
+ (0x01EF3,0x01EF3), `Abs (0x01EF3);
+ (0x01EF5,0x01EF5), `Abs (0x01EF5);
+ (0x01EF7,0x01EF7), `Abs (0x01EF7);
+ (0x01EF9,0x01EF9), `Abs (0x01EF9);
+ (0x01EFB,0x01EFB), `Abs (0x01EFB);
+ (0x01EFD,0x01EFD), `Abs (0x01EFD);
+ (0x01EFF,0x01F07), `Delta (0);
+ (0x01F10,0x01F15), `Delta (0);
+ (0x01F20,0x01F27), `Delta (0);
+ (0x01F30,0x01F37), `Delta (0);
+ (0x01F40,0x01F45), `Delta (0);
+ (0x01F50,0x01F57), `Delta (0);
+ (0x01F60,0x01F67), `Delta (0);
+ (0x01F70,0x01F7D), `Delta (0);
+ (0x01F80,0x01F87), `Delta (0);
+ (0x01F90,0x01F97), `Delta (0);
+ (0x01FA0,0x01FA7), `Delta (0);
+ (0x01FB0,0x01FB4), `Delta (0);
+ (0x01FB6,0x01FB7), `Delta (0);
+ (0x01FBE,0x01FBE), `Abs (0x01FBE);
+ (0x01FC2,0x01FC4), `Delta (0);
+ (0x01FC6,0x01FC7), `Delta (0);
+ (0x01FD0,0x01FD3), `Delta (0);
+ (0x01FD6,0x01FD7), `Delta (0);
+ (0x01FE0,0x01FE7), `Delta (0);
+ (0x01FF2,0x01FF4), `Delta (0);
+ (0x01FF6,0x01FF7), `Delta (0);
+ (0x0210A,0x0210A), `Abs (0x0210A);
+ (0x0210E,0x0210F), `Delta (0);
+ (0x02113,0x02113), `Abs (0x02113);
+ (0x0212F,0x0212F), `Abs (0x0212F);
+ (0x02134,0x02134), `Abs (0x02134);
+ (0x02139,0x02139), `Abs (0x02139);
+ (0x0213C,0x0213D), `Delta (0);
+ (0x02146,0x02149), `Delta (0);
+ (0x0214E,0x0214E), `Abs (0x0214E);
+ (0x02184,0x02184), `Abs (0x02184);
+ (0x02C30,0x02C5E), `Delta (0);
+ (0x02C61,0x02C61), `Abs (0x02C61);
+ (0x02C65,0x02C66), `Delta (0);
+ (0x02C68,0x02C68), `Abs (0x02C68);
+ (0x02C6A,0x02C6A), `Abs (0x02C6A);
+ (0x02C6C,0x02C6C), `Abs (0x02C6C);
+ (0x02C71,0x02C71), `Abs (0x02C71);
+ (0x02C73,0x02C74), `Delta (0);
+ (0x02C76,0x02C7B), `Delta (0);
+ (0x02C81,0x02C81), `Abs (0x02C81);
+ (0x02C83,0x02C83), `Abs (0x02C83);
+ (0x02C85,0x02C85), `Abs (0x02C85);
+ (0x02C87,0x02C87), `Abs (0x02C87);
+ (0x02C89,0x02C89), `Abs (0x02C89);
+ (0x02C8B,0x02C8B), `Abs (0x02C8B);
+ (0x02C8D,0x02C8D), `Abs (0x02C8D);
+ (0x02C8F,0x02C8F), `Abs (0x02C8F);
+ (0x02C91,0x02C91), `Abs (0x02C91);
+ (0x02C93,0x02C93), `Abs (0x02C93);
+ (0x02C95,0x02C95), `Abs (0x02C95);
+ (0x02C97,0x02C97), `Abs (0x02C97);
+ (0x02C99,0x02C99), `Abs (0x02C99);
+ (0x02C9B,0x02C9B), `Abs (0x02C9B);
+ (0x02C9D,0x02C9D), `Abs (0x02C9D);
+ (0x02C9F,0x02C9F), `Abs (0x02C9F);
+ (0x02CA1,0x02CA1), `Abs (0x02CA1);
+ (0x02CA3,0x02CA3), `Abs (0x02CA3);
+ (0x02CA5,0x02CA5), `Abs (0x02CA5);
+ (0x02CA7,0x02CA7), `Abs (0x02CA7);
+ (0x02CA9,0x02CA9), `Abs (0x02CA9);
+ (0x02CAB,0x02CAB), `Abs (0x02CAB);
+ (0x02CAD,0x02CAD), `Abs (0x02CAD);
+ (0x02CAF,0x02CAF), `Abs (0x02CAF);
+ (0x02CB1,0x02CB1), `Abs (0x02CB1);
+ (0x02CB3,0x02CB3), `Abs (0x02CB3);
+ (0x02CB5,0x02CB5), `Abs (0x02CB5);
+ (0x02CB7,0x02CB7), `Abs (0x02CB7);
+ (0x02CB9,0x02CB9), `Abs (0x02CB9);
+ (0x02CBB,0x02CBB), `Abs (0x02CBB);
+ (0x02CBD,0x02CBD), `Abs (0x02CBD);
+ (0x02CBF,0x02CBF), `Abs (0x02CBF);
+ (0x02CC1,0x02CC1), `Abs (0x02CC1);
+ (0x02CC3,0x02CC3), `Abs (0x02CC3);
+ (0x02CC5,0x02CC5), `Abs (0x02CC5);
+ (0x02CC7,0x02CC7), `Abs (0x02CC7);
+ (0x02CC9,0x02CC9), `Abs (0x02CC9);
+ (0x02CCB,0x02CCB), `Abs (0x02CCB);
+ (0x02CCD,0x02CCD), `Abs (0x02CCD);
+ (0x02CCF,0x02CCF), `Abs (0x02CCF);
+ (0x02CD1,0x02CD1), `Abs (0x02CD1);
+ (0x02CD3,0x02CD3), `Abs (0x02CD3);
+ (0x02CD5,0x02CD5), `Abs (0x02CD5);
+ (0x02CD7,0x02CD7), `Abs (0x02CD7);
+ (0x02CD9,0x02CD9), `Abs (0x02CD9);
+ (0x02CDB,0x02CDB), `Abs (0x02CDB);
+ (0x02CDD,0x02CDD), `Abs (0x02CDD);
+ (0x02CDF,0x02CDF), `Abs (0x02CDF);
+ (0x02CE1,0x02CE1), `Abs (0x02CE1);
+ (0x02CE3,0x02CE4), `Delta (0);
+ (0x02CEC,0x02CEC), `Abs (0x02CEC);
+ (0x02CEE,0x02CEE), `Abs (0x02CEE);
+ (0x02CF3,0x02CF3), `Abs (0x02CF3);
+ (0x02D00,0x02D25), `Delta (0);
+ (0x02D27,0x02D27), `Abs (0x02D27);
+ (0x02D2D,0x02D2D), `Abs (0x02D2D);
+ (0x0A641,0x0A641), `Abs (0x0A641);
+ (0x0A643,0x0A643), `Abs (0x0A643);
+ (0x0A645,0x0A645), `Abs (0x0A645);
+ (0x0A647,0x0A647), `Abs (0x0A647);
+ (0x0A649,0x0A649), `Abs (0x0A649);
+ (0x0A64B,0x0A64B), `Abs (0x0A64B);
+ (0x0A64D,0x0A64D), `Abs (0x0A64D);
+ (0x0A64F,0x0A64F), `Abs (0x0A64F);
+ (0x0A651,0x0A651), `Abs (0x0A651);
+ (0x0A653,0x0A653), `Abs (0x0A653);
+ (0x0A655,0x0A655), `Abs (0x0A655);
+ (0x0A657,0x0A657), `Abs (0x0A657);
+ (0x0A659,0x0A659), `Abs (0x0A659);
+ (0x0A65B,0x0A65B), `Abs (0x0A65B);
+ (0x0A65D,0x0A65D), `Abs (0x0A65D);
+ (0x0A65F,0x0A65F), `Abs (0x0A65F);
+ (0x0A661,0x0A661), `Abs (0x0A661);
+ (0x0A663,0x0A663), `Abs (0x0A663);
+ (0x0A665,0x0A665), `Abs (0x0A665);
+ (0x0A667,0x0A667), `Abs (0x0A667);
+ (0x0A669,0x0A669), `Abs (0x0A669);
+ (0x0A66B,0x0A66B), `Abs (0x0A66B);
+ (0x0A66D,0x0A66D), `Abs (0x0A66D);
+ (0x0A681,0x0A681), `Abs (0x0A681);
+ (0x0A683,0x0A683), `Abs (0x0A683);
+ (0x0A685,0x0A685), `Abs (0x0A685);
+ (0x0A687,0x0A687), `Abs (0x0A687);
+ (0x0A689,0x0A689), `Abs (0x0A689);
+ (0x0A68B,0x0A68B), `Abs (0x0A68B);
+ (0x0A68D,0x0A68D), `Abs (0x0A68D);
+ (0x0A68F,0x0A68F), `Abs (0x0A68F);
+ (0x0A691,0x0A691), `Abs (0x0A691);
+ (0x0A693,0x0A693), `Abs (0x0A693);
+ (0x0A695,0x0A695), `Abs (0x0A695);
+ (0x0A697,0x0A697), `Abs (0x0A697);
+ (0x0A699,0x0A699), `Abs (0x0A699);
+ (0x0A69B,0x0A69B), `Abs (0x0A69B);
+ (0x0A723,0x0A723), `Abs (0x0A723);
+ (0x0A725,0x0A725), `Abs (0x0A725);
+ (0x0A727,0x0A727), `Abs (0x0A727);
+ (0x0A729,0x0A729), `Abs (0x0A729);
+ (0x0A72B,0x0A72B), `Abs (0x0A72B);
+ (0x0A72D,0x0A72D), `Abs (0x0A72D);
+ (0x0A72F,0x0A731), `Delta (0);
+ (0x0A733,0x0A733), `Abs (0x0A733);
+ (0x0A735,0x0A735), `Abs (0x0A735);
+ (0x0A737,0x0A737), `Abs (0x0A737);
+ (0x0A739,0x0A739), `Abs (0x0A739);
+ (0x0A73B,0x0A73B), `Abs (0x0A73B);
+ (0x0A73D,0x0A73D), `Abs (0x0A73D);
+ (0x0A73F,0x0A73F), `Abs (0x0A73F);
+ (0x0A741,0x0A741), `Abs (0x0A741);
+ (0x0A743,0x0A743), `Abs (0x0A743);
+ (0x0A745,0x0A745), `Abs (0x0A745);
+ (0x0A747,0x0A747), `Abs (0x0A747);
+ (0x0A749,0x0A749), `Abs (0x0A749);
+ (0x0A74B,0x0A74B), `Abs (0x0A74B);
+ (0x0A74D,0x0A74D), `Abs (0x0A74D);
+ (0x0A74F,0x0A74F), `Abs (0x0A74F);
+ (0x0A751,0x0A751), `Abs (0x0A751);
+ (0x0A753,0x0A753), `Abs (0x0A753);
+ (0x0A755,0x0A755), `Abs (0x0A755);
+ (0x0A757,0x0A757), `Abs (0x0A757);
+ (0x0A759,0x0A759), `Abs (0x0A759);
+ (0x0A75B,0x0A75B), `Abs (0x0A75B);
+ (0x0A75D,0x0A75D), `Abs (0x0A75D);
+ (0x0A75F,0x0A75F), `Abs (0x0A75F);
+ (0x0A761,0x0A761), `Abs (0x0A761);
+ (0x0A763,0x0A763), `Abs (0x0A763);
+ (0x0A765,0x0A765), `Abs (0x0A765);
+ (0x0A767,0x0A767), `Abs (0x0A767);
+ (0x0A769,0x0A769), `Abs (0x0A769);
+ (0x0A76B,0x0A76B), `Abs (0x0A76B);
+ (0x0A76D,0x0A76D), `Abs (0x0A76D);
+ (0x0A76F,0x0A76F), `Abs (0x0A76F);
+ (0x0A771,0x0A778), `Delta (0);
+ (0x0A77A,0x0A77A), `Abs (0x0A77A);
+ (0x0A77C,0x0A77C), `Abs (0x0A77C);
+ (0x0A77F,0x0A77F), `Abs (0x0A77F);
+ (0x0A781,0x0A781), `Abs (0x0A781);
+ (0x0A783,0x0A783), `Abs (0x0A783);
+ (0x0A785,0x0A785), `Abs (0x0A785);
+ (0x0A787,0x0A787), `Abs (0x0A787);
+ (0x0A78C,0x0A78C), `Abs (0x0A78C);
+ (0x0A78E,0x0A78E), `Abs (0x0A78E);
+ (0x0A791,0x0A791), `Abs (0x0A791);
+ (0x0A793,0x0A795), `Delta (0);
+ (0x0A797,0x0A797), `Abs (0x0A797);
+ (0x0A799,0x0A799), `Abs (0x0A799);
+ (0x0A79B,0x0A79B), `Abs (0x0A79B);
+ (0x0A79D,0x0A79D), `Abs (0x0A79D);
+ (0x0A79F,0x0A79F), `Abs (0x0A79F);
+ (0x0A7A1,0x0A7A1), `Abs (0x0A7A1);
+ (0x0A7A3,0x0A7A3), `Abs (0x0A7A3);
+ (0x0A7A5,0x0A7A5), `Abs (0x0A7A5);
+ (0x0A7A7,0x0A7A7), `Abs (0x0A7A7);
+ (0x0A7A9,0x0A7A9), `Abs (0x0A7A9);
+ (0x0A7B5,0x0A7B5), `Abs (0x0A7B5);
+ (0x0A7B7,0x0A7B7), `Abs (0x0A7B7);
+ (0x0A7FA,0x0A7FA), `Abs (0x0A7FA);
+ (0x0AB30,0x0AB5A), `Delta (0);
+ (0x0AB60,0x0AB65), `Delta (0);
+ (0x0AB70,0x0ABBF), `Delta (0);
+ (0x0FB00,0x0FB06), `Delta (0);
+ (0x0FB13,0x0FB17), `Delta (0);
+ (0x0FF41,0x0FF5A), `Delta (0);
+ (0x10428,0x1044F), `Delta (0);
+ (0x104D8,0x104FB), `Delta (0);
+ (0x10CC0,0x10CF2), `Delta (0);
+ (0x118C0,0x118DF), `Delta (0);
+ (0x1D41A,0x1D433), `Delta (0);
+ (0x1D44E,0x1D454), `Delta (0);
+ (0x1D456,0x1D467), `Delta (0);
+ (0x1D482,0x1D49B), `Delta (0);
+ (0x1D4B6,0x1D4B9), `Delta (0);
+ (0x1D4BB,0x1D4BB), `Abs (0x1D4BB);
+ (0x1D4BD,0x1D4C3), `Delta (0);
+ (0x1D4C5,0x1D4CF), `Delta (0);
+ (0x1D4EA,0x1D503), `Delta (0);
+ (0x1D51E,0x1D537), `Delta (0);
+ (0x1D552,0x1D56B), `Delta (0);
+ (0x1D586,0x1D59F), `Delta (0);
+ (0x1D5BA,0x1D5D3), `Delta (0);
+ (0x1D5EE,0x1D607), `Delta (0);
+ (0x1D622,0x1D63B), `Delta (0);
+ (0x1D656,0x1D66F), `Delta (0);
+ (0x1D68A,0x1D6A5), `Delta (0);
+ (0x1D6C2,0x1D6DA), `Delta (0);
+ (0x1D6DC,0x1D6E1), `Delta (0);
+ (0x1D6FC,0x1D714), `Delta (0);
+ (0x1D716,0x1D71B), `Delta (0);
+ (0x1D736,0x1D74E), `Delta (0);
+ (0x1D750,0x1D755), `Delta (0);
+ (0x1D770,0x1D788), `Delta (0);
+ (0x1D78A,0x1D78F), `Delta (0);
+ (0x1D7AA,0x1D7C2), `Delta (0);
+ (0x1D7C4,0x1D7C9), `Delta (0);
+ (0x1D7CB,0x1D7CB), `Abs (0x1D7CB);
+ (0x1E922,0x1E943), `Delta (0);
+ (0x001C5,0x001C5), `Abs (0x001C6);
+ (0x001C8,0x001C8), `Abs (0x001C9);
+ (0x001CB,0x001CB), `Abs (0x001CC);
+ (0x001F2,0x001F2), `Abs (0x001F3);
+ (0x01F88,0x01F8F), `Delta (-8);
+ (0x01F98,0x01F9F), `Delta (-8);
+ (0x01FA8,0x01FAF), `Delta (-8);
+ (0x01FBC,0x01FBC), `Abs (0x01FB3);
+ (0x01FCC,0x01FCC), `Abs (0x01FC3);
+ (0x01FFC,0x01FFC), `Abs (0x01FF3);
+ (0x00300,0x0036F), `Delta (0);
+ (0x00483,0x00487), `Delta (0);
+ (0x00591,0x005BD), `Delta (0);
+ (0x005BF,0x005BF), `Abs (0x005BF);
+ (0x005C1,0x005C2), `Delta (0);
+ (0x005C4,0x005C5), `Delta (0);
+ (0x005C7,0x005C7), `Abs (0x005C7);
+ (0x00610,0x0061A), `Delta (0);
+ (0x0064B,0x0065F), `Delta (0);
+ (0x00670,0x00670), `Abs (0x00670);
+ (0x006D6,0x006DC), `Delta (0);
+ (0x006DF,0x006E4), `Delta (0);
+ (0x006E7,0x006E8), `Delta (0);
+ (0x006EA,0x006ED), `Delta (0);
+ (0x00711,0x00711), `Abs (0x00711);
+ (0x00730,0x0074A), `Delta (0);
+ (0x007A6,0x007B0), `Delta (0);
+ (0x007EB,0x007F3), `Delta (0);
+ (0x00816,0x00819), `Delta (0);
+ (0x0081B,0x00823), `Delta (0);
+ (0x00825,0x00827), `Delta (0);
+ (0x00829,0x0082D), `Delta (0);
+ (0x00859,0x0085B), `Delta (0);
+ (0x008D4,0x008E1), `Delta (0);
+ (0x008E3,0x00902), `Delta (0);
+ (0x0093A,0x0093A), `Abs (0x0093A);
+ (0x0093C,0x0093C), `Abs (0x0093C);
+ (0x00941,0x00948), `Delta (0);
+ (0x0094D,0x0094D), `Abs (0x0094D);
+ (0x00951,0x00957), `Delta (0);
+ (0x00962,0x00963), `Delta (0);
+ (0x00981,0x00981), `Abs (0x00981);
+ (0x009BC,0x009BC), `Abs (0x009BC);
+ (0x009C1,0x009C4), `Delta (0);
+ (0x009CD,0x009CD), `Abs (0x009CD);
+ (0x009E2,0x009E3), `Delta (0);
+ (0x00A01,0x00A02), `Delta (0);
+ (0x00A3C,0x00A3C), `Abs (0x00A3C);
+ (0x00A41,0x00A42), `Delta (0);
+ (0x00A47,0x00A48), `Delta (0);
+ (0x00A4B,0x00A4D), `Delta (0);
+ (0x00A51,0x00A51), `Abs (0x00A51);
+ (0x00A70,0x00A71), `Delta (0);
+ (0x00A75,0x00A75), `Abs (0x00A75);
+ (0x00A81,0x00A82), `Delta (0);
+ (0x00ABC,0x00ABC), `Abs (0x00ABC);
+ (0x00AC1,0x00AC5), `Delta (0);
+ (0x00AC7,0x00AC8), `Delta (0);
+ (0x00ACD,0x00ACD), `Abs (0x00ACD);
+ (0x00AE2,0x00AE3), `Delta (0);
+ (0x00B01,0x00B01), `Abs (0x00B01);
+ (0x00B3C,0x00B3C), `Abs (0x00B3C);
+ (0x00B3F,0x00B3F), `Abs (0x00B3F);
+ (0x00B41,0x00B44), `Delta (0);
+ (0x00B4D,0x00B4D), `Abs (0x00B4D);
+ (0x00B56,0x00B56), `Abs (0x00B56);
+ (0x00B62,0x00B63), `Delta (0);
+ (0x00B82,0x00B82), `Abs (0x00B82);
+ (0x00BC0,0x00BC0), `Abs (0x00BC0);
+ (0x00BCD,0x00BCD), `Abs (0x00BCD);
+ (0x00C00,0x00C00), `Abs (0x00C00);
+ (0x00C3E,0x00C40), `Delta (0);
+ (0x00C46,0x00C48), `Delta (0);
+ (0x00C4A,0x00C4D), `Delta (0);
+ (0x00C55,0x00C56), `Delta (0);
+ (0x00C62,0x00C63), `Delta (0);
+ (0x00C81,0x00C81), `Abs (0x00C81);
+ (0x00CBC,0x00CBC), `Abs (0x00CBC);
+ (0x00CBF,0x00CBF), `Abs (0x00CBF);
+ (0x00CC6,0x00CC6), `Abs (0x00CC6);
+ (0x00CCC,0x00CCD), `Delta (0);
+ (0x00CE2,0x00CE3), `Delta (0);
+ (0x00D01,0x00D01), `Abs (0x00D01);
+ (0x00D41,0x00D44), `Delta (0);
+ (0x00D4D,0x00D4D), `Abs (0x00D4D);
+ (0x00D62,0x00D63), `Delta (0);
+ (0x00DCA,0x00DCA), `Abs (0x00DCA);
+ (0x00DD2,0x00DD4), `Delta (0);
+ (0x00DD6,0x00DD6), `Abs (0x00DD6);
+ (0x00E31,0x00E31), `Abs (0x00E31);
+ (0x00E34,0x00E3A), `Delta (0);
+ (0x00E47,0x00E4E), `Delta (0);
+ (0x00EB1,0x00EB1), `Abs (0x00EB1);
+ (0x00EB4,0x00EB9), `Delta (0);
+ (0x00EBB,0x00EBC), `Delta (0);
+ (0x00EC8,0x00ECD), `Delta (0);
+ (0x00F18,0x00F19), `Delta (0);
+ (0x00F35,0x00F35), `Abs (0x00F35);
+ (0x00F37,0x00F37), `Abs (0x00F37);
+ (0x00F39,0x00F39), `Abs (0x00F39);
+ (0x00F71,0x00F7E), `Delta (0);
+ (0x00F80,0x00F84), `Delta (0);
+ (0x00F86,0x00F87), `Delta (0);
+ (0x00F8D,0x00F97), `Delta (0);
+ (0x00F99,0x00FBC), `Delta (0);
+ (0x00FC6,0x00FC6), `Abs (0x00FC6);
+ (0x0102D,0x01030), `Delta (0);
+ (0x01032,0x01037), `Delta (0);
+ (0x01039,0x0103A), `Delta (0);
+ (0x0103D,0x0103E), `Delta (0);
+ (0x01058,0x01059), `Delta (0);
+ (0x0105E,0x01060), `Delta (0);
+ (0x01071,0x01074), `Delta (0);
+ (0x01082,0x01082), `Abs (0x01082);
+ (0x01085,0x01086), `Delta (0);
+ (0x0108D,0x0108D), `Abs (0x0108D);
+ (0x0109D,0x0109D), `Abs (0x0109D);
+ (0x0135D,0x0135F), `Delta (0);
+ (0x01712,0x01714), `Delta (0);
+ (0x01732,0x01734), `Delta (0);
+ (0x01752,0x01753), `Delta (0);
+ (0x01772,0x01773), `Delta (0);
+ (0x017B4,0x017B5), `Delta (0);
+ (0x017B7,0x017BD), `Delta (0);
+ (0x017C6,0x017C6), `Abs (0x017C6);
+ (0x017C9,0x017D3), `Delta (0);
+ (0x017DD,0x017DD), `Abs (0x017DD);
+ (0x0180B,0x0180D), `Delta (0);
+ (0x01885,0x01886), `Delta (0);
+ (0x018A9,0x018A9), `Abs (0x018A9);
+ (0x01920,0x01922), `Delta (0);
+ (0x01927,0x01928), `Delta (0);
+ (0x01932,0x01932), `Abs (0x01932);
+ (0x01939,0x0193B), `Delta (0);
+ (0x01A17,0x01A18), `Delta (0);
+ (0x01A1B,0x01A1B), `Abs (0x01A1B);
+ (0x01A56,0x01A56), `Abs (0x01A56);
+ (0x01A58,0x01A5E), `Delta (0);
+ (0x01A60,0x01A60), `Abs (0x01A60);
+ (0x01A62,0x01A62), `Abs (0x01A62);
+ (0x01A65,0x01A6C), `Delta (0);
+ (0x01A73,0x01A7C), `Delta (0);
+ (0x01A7F,0x01A7F), `Abs (0x01A7F);
+ (0x01AB0,0x01ABD), `Delta (0);
+ (0x01B00,0x01B03), `Delta (0);
+ (0x01B34,0x01B34), `Abs (0x01B34);
+ (0x01B36,0x01B3A), `Delta (0);
+ (0x01B3C,0x01B3C), `Abs (0x01B3C);
+ (0x01B42,0x01B42), `Abs (0x01B42);
+ (0x01B6B,0x01B73), `Delta (0);
+ (0x01B80,0x01B81), `Delta (0);
+ (0x01BA2,0x01BA5), `Delta (0);
+ (0x01BA8,0x01BA9), `Delta (0);
+ (0x01BAB,0x01BAD), `Delta (0);
+ (0x01BE6,0x01BE6), `Abs (0x01BE6);
+ (0x01BE8,0x01BE9), `Delta (0);
+ (0x01BED,0x01BED), `Abs (0x01BED);
+ (0x01BEF,0x01BF1), `Delta (0);
+ (0x01C2C,0x01C33), `Delta (0);
+ (0x01C36,0x01C37), `Delta (0);
+ (0x01CD0,0x01CD2), `Delta (0);
+ (0x01CD4,0x01CE0), `Delta (0);
+ (0x01CE2,0x01CE8), `Delta (0);
+ (0x01CED,0x01CED), `Abs (0x01CED);
+ (0x01CF4,0x01CF4), `Abs (0x01CF4);
+ (0x01CF8,0x01CF9), `Delta (0);
+ (0x01DC0,0x01DF5), `Delta (0);
+ (0x01DFB,0x01DFF), `Delta (0);
+ (0x020D0,0x020DC), `Delta (0);
+ (0x020E1,0x020E1), `Abs (0x020E1);
+ (0x020E5,0x020F0), `Delta (0);
+ (0x02CEF,0x02CF1), `Delta (0);
+ (0x02D7F,0x02D7F), `Abs (0x02D7F);
+ (0x02DE0,0x02DFF), `Delta (0);
+ (0x0302A,0x0302D), `Delta (0);
+ (0x03099,0x0309A), `Delta (0);
+ (0x0A66F,0x0A66F), `Abs (0x0A66F);
+ (0x0A674,0x0A67D), `Delta (0);
+ (0x0A69E,0x0A69F), `Delta (0);
+ (0x0A6F0,0x0A6F1), `Delta (0);
+ (0x0A802,0x0A802), `Abs (0x0A802);
+ (0x0A806,0x0A806), `Abs (0x0A806);
+ (0x0A80B,0x0A80B), `Abs (0x0A80B);
+ (0x0A825,0x0A826), `Delta (0);
+ (0x0A8C4,0x0A8C5), `Delta (0);
+ (0x0A8E0,0x0A8F1), `Delta (0);
+ (0x0A926,0x0A92D), `Delta (0);
+ (0x0A947,0x0A951), `Delta (0);
+ (0x0A980,0x0A982), `Delta (0);
+ (0x0A9B3,0x0A9B3), `Abs (0x0A9B3);
+ (0x0A9B6,0x0A9B9), `Delta (0);
+ (0x0A9BC,0x0A9BC), `Abs (0x0A9BC);
+ (0x0A9E5,0x0A9E5), `Abs (0x0A9E5);
+ (0x0AA29,0x0AA2E), `Delta (0);
+ (0x0AA31,0x0AA32), `Delta (0);
+ (0x0AA35,0x0AA36), `Delta (0);
+ (0x0AA43,0x0AA43), `Abs (0x0AA43);
+ (0x0AA4C,0x0AA4C), `Abs (0x0AA4C);
+ (0x0AA7C,0x0AA7C), `Abs (0x0AA7C);
+ (0x0AAB0,0x0AAB0), `Abs (0x0AAB0);
+ (0x0AAB2,0x0AAB4), `Delta (0);
+ (0x0AAB7,0x0AAB8), `Delta (0);
+ (0x0AABE,0x0AABF), `Delta (0);
+ (0x0AAC1,0x0AAC1), `Abs (0x0AAC1);
+ (0x0AAEC,0x0AAED), `Delta (0);
+ (0x0AAF6,0x0AAF6), `Abs (0x0AAF6);
+ (0x0ABE5,0x0ABE5), `Abs (0x0ABE5);
+ (0x0ABE8,0x0ABE8), `Abs (0x0ABE8);
+ (0x0ABED,0x0ABED), `Abs (0x0ABED);
+ (0x0FB1E,0x0FB1E), `Abs (0x0FB1E);
+ (0x0FE00,0x0FE0F), `Delta (0);
+ (0x0FE20,0x0FE2F), `Delta (0);
+ (0x101FD,0x101FD), `Abs (0x101FD);
+ (0x102E0,0x102E0), `Abs (0x102E0);
+ (0x10376,0x1037A), `Delta (0);
+ (0x10A01,0x10A03), `Delta (0);
+ (0x10A05,0x10A06), `Delta (0);
+ (0x10A0C,0x10A0F), `Delta (0);
+ (0x10A38,0x10A3A), `Delta (0);
+ (0x10A3F,0x10A3F), `Abs (0x10A3F);
+ (0x10AE5,0x10AE6), `Delta (0);
+ (0x11001,0x11001), `Abs (0x11001);
+ (0x11038,0x11046), `Delta (0);
+ (0x1107F,0x11081), `Delta (0);
+ (0x110B3,0x110B6), `Delta (0);
+ (0x110B9,0x110BA), `Delta (0);
+ (0x11100,0x11102), `Delta (0);
+ (0x11127,0x1112B), `Delta (0);
+ (0x1112D,0x11134), `Delta (0);
+ (0x11173,0x11173), `Abs (0x11173);
+ (0x11180,0x11181), `Delta (0);
+ (0x111B6,0x111BE), `Delta (0);
+ (0x111CA,0x111CC), `Delta (0);
+ (0x1122F,0x11231), `Delta (0);
+ (0x11234,0x11234), `Abs (0x11234);
+ (0x11236,0x11237), `Delta (0);
+ (0x1123E,0x1123E), `Abs (0x1123E);
+ (0x112DF,0x112DF), `Abs (0x112DF);
+ (0x112E3,0x112EA), `Delta (0);
+ (0x11300,0x11301), `Delta (0);
+ (0x1133C,0x1133C), `Abs (0x1133C);
+ (0x11340,0x11340), `Abs (0x11340);
+ (0x11366,0x1136C), `Delta (0);
+ (0x11370,0x11374), `Delta (0);
+ (0x11438,0x1143F), `Delta (0);
+ (0x11442,0x11444), `Delta (0);
+ (0x11446,0x11446), `Abs (0x11446);
+ (0x114B3,0x114B8), `Delta (0);
+ (0x114BA,0x114BA), `Abs (0x114BA);
+ (0x114BF,0x114C0), `Delta (0);
+ (0x114C2,0x114C3), `Delta (0);
+ (0x115B2,0x115B5), `Delta (0);
+ (0x115BC,0x115BD), `Delta (0);
+ (0x115BF,0x115C0), `Delta (0);
+ (0x115DC,0x115DD), `Delta (0);
+ (0x11633,0x1163A), `Delta (0);
+ (0x1163D,0x1163D), `Abs (0x1163D);
+ (0x1163F,0x11640), `Delta (0);
+ (0x116AB,0x116AB), `Abs (0x116AB);
+ (0x116AD,0x116AD), `Abs (0x116AD);
+ (0x116B0,0x116B5), `Delta (0);
+ (0x116B7,0x116B7), `Abs (0x116B7);
+ (0x1171D,0x1171F), `Delta (0);
+ (0x11722,0x11725), `Delta (0);
+ (0x11727,0x1172B), `Delta (0);
+ (0x11C30,0x11C36), `Delta (0);
+ (0x11C38,0x11C3D), `Delta (0);
+ (0x11C3F,0x11C3F), `Abs (0x11C3F);
+ (0x11C92,0x11CA7), `Delta (0);
+ (0x11CAA,0x11CB0), `Delta (0);
+ (0x11CB2,0x11CB3), `Delta (0);
+ (0x11CB5,0x11CB6), `Delta (0);
+ (0x16AF0,0x16AF4), `Delta (0);
+ (0x16B30,0x16B36), `Delta (0);
+ (0x16F8F,0x16F92), `Delta (0);
+ (0x1BC9D,0x1BC9E), `Delta (0);
+ (0x1D167,0x1D169), `Delta (0);
+ (0x1D17B,0x1D182), `Delta (0);
+ (0x1D185,0x1D18B), `Delta (0);
+ (0x1D1AA,0x1D1AD), `Delta (0);
+ (0x1D242,0x1D244), `Delta (0);
+ (0x1DA00,0x1DA36), `Delta (0);
+ (0x1DA3B,0x1DA6C), `Delta (0);
+ (0x1DA75,0x1DA75), `Abs (0x1DA75);
+ (0x1DA84,0x1DA84), `Abs (0x1DA84);
+ (0x1DA9B,0x1DA9F), `Delta (0);
+ (0x1DAA1,0x1DAAF), `Delta (0);
+ (0x1E000,0x1E006), `Delta (0);
+ (0x1E008,0x1E018), `Delta (0);
+ (0x1E01B,0x1E021), `Delta (0);
+ (0x1E023,0x1E024), `Delta (0);
+ (0x1E026,0x1E02A), `Delta (0);
+ (0x1E8D0,0x1E8D6), `Delta (0);
+ (0x1E944,0x1E94A), `Delta (0);
+ (0xE0100,0xE01EF), `Delta (0);
+ (0x00903,0x00903), `Abs (0x00903);
+ (0x0093B,0x0093B), `Abs (0x0093B);
+ (0x0093E,0x00940), `Delta (0);
+ (0x00949,0x0094C), `Delta (0);
+ (0x0094E,0x0094F), `Delta (0);
+ (0x00982,0x00983), `Delta (0);
+ (0x009BE,0x009C0), `Delta (0);
+ (0x009C7,0x009C8), `Delta (0);
+ (0x009CB,0x009CC), `Delta (0);
+ (0x009D7,0x009D7), `Abs (0x009D7);
+ (0x00A03,0x00A03), `Abs (0x00A03);
+ (0x00A3E,0x00A40), `Delta (0);
+ (0x00A83,0x00A83), `Abs (0x00A83);
+ (0x00ABE,0x00AC0), `Delta (0);
+ (0x00AC9,0x00AC9), `Abs (0x00AC9);
+ (0x00ACB,0x00ACC), `Delta (0);
+ (0x00B02,0x00B03), `Delta (0);
+ (0x00B3E,0x00B3E), `Abs (0x00B3E);
+ (0x00B40,0x00B40), `Abs (0x00B40);
+ (0x00B47,0x00B48), `Delta (0);
+ (0x00B4B,0x00B4C), `Delta (0);
+ (0x00B57,0x00B57), `Abs (0x00B57);
+ (0x00BBE,0x00BBF), `Delta (0);
+ (0x00BC1,0x00BC2), `Delta (0);
+ (0x00BC6,0x00BC8), `Delta (0);
+ (0x00BCA,0x00BCC), `Delta (0);
+ (0x00BD7,0x00BD7), `Abs (0x00BD7);
+ (0x00C01,0x00C03), `Delta (0);
+ (0x00C41,0x00C44), `Delta (0);
+ (0x00C82,0x00C83), `Delta (0);
+ (0x00CBE,0x00CBE), `Abs (0x00CBE);
+ (0x00CC0,0x00CC4), `Delta (0);
+ (0x00CC7,0x00CC8), `Delta (0);
+ (0x00CCA,0x00CCB), `Delta (0);
+ (0x00CD5,0x00CD6), `Delta (0);
+ (0x00D02,0x00D03), `Delta (0);
+ (0x00D3E,0x00D40), `Delta (0);
+ (0x00D46,0x00D48), `Delta (0);
+ (0x00D4A,0x00D4C), `Delta (0);
+ (0x00D57,0x00D57), `Abs (0x00D57);
+ (0x00D82,0x00D83), `Delta (0);
+ (0x00DCF,0x00DD1), `Delta (0);
+ (0x00DD8,0x00DDF), `Delta (0);
+ (0x00DF2,0x00DF3), `Delta (0);
+ (0x00F3E,0x00F3F), `Delta (0);
+ (0x00F7F,0x00F7F), `Abs (0x00F7F);
+ (0x0102B,0x0102C), `Delta (0);
+ (0x01031,0x01031), `Abs (0x01031);
+ (0x01038,0x01038), `Abs (0x01038);
+ (0x0103B,0x0103C), `Delta (0);
+ (0x01056,0x01057), `Delta (0);
+ (0x01062,0x01064), `Delta (0);
+ (0x01067,0x0106D), `Delta (0);
+ (0x01083,0x01084), `Delta (0);
+ (0x01087,0x0108C), `Delta (0);
+ (0x0108F,0x0108F), `Abs (0x0108F);
+ (0x0109A,0x0109C), `Delta (0);
+ (0x017B6,0x017B6), `Abs (0x017B6);
+ (0x017BE,0x017C5), `Delta (0);
+ (0x017C7,0x017C8), `Delta (0);
+ (0x01923,0x01926), `Delta (0);
+ (0x01929,0x0192B), `Delta (0);
+ (0x01930,0x01931), `Delta (0);
+ (0x01933,0x01938), `Delta (0);
+ (0x01A19,0x01A1A), `Delta (0);
+ (0x01A55,0x01A55), `Abs (0x01A55);
+ (0x01A57,0x01A57), `Abs (0x01A57);
+ (0x01A61,0x01A61), `Abs (0x01A61);
+ (0x01A63,0x01A64), `Delta (0);
+ (0x01A6D,0x01A72), `Delta (0);
+ (0x01B04,0x01B04), `Abs (0x01B04);
+ (0x01B35,0x01B35), `Abs (0x01B35);
+ (0x01B3B,0x01B3B), `Abs (0x01B3B);
+ (0x01B3D,0x01B41), `Delta (0);
+ (0x01B43,0x01B44), `Delta (0);
+ (0x01B82,0x01B82), `Abs (0x01B82);
+ (0x01BA1,0x01BA1), `Abs (0x01BA1);
+ (0x01BA6,0x01BA7), `Delta (0);
+ (0x01BAA,0x01BAA), `Abs (0x01BAA);
+ (0x01BE7,0x01BE7), `Abs (0x01BE7);
+ (0x01BEA,0x01BEC), `Delta (0);
+ (0x01BEE,0x01BEE), `Abs (0x01BEE);
+ (0x01BF2,0x01BF3), `Delta (0);
+ (0x01C24,0x01C2B), `Delta (0);
+ (0x01C34,0x01C35), `Delta (0);
+ (0x01CE1,0x01CE1), `Abs (0x01CE1);
+ (0x01CF2,0x01CF3), `Delta (0);
+ (0x0302E,0x0302F), `Delta (0);
+ (0x0A823,0x0A824), `Delta (0);
+ (0x0A827,0x0A827), `Abs (0x0A827);
+ (0x0A880,0x0A881), `Delta (0);
+ (0x0A8B4,0x0A8C3), `Delta (0);
+ (0x0A952,0x0A953), `Delta (0);
+ (0x0A983,0x0A983), `Abs (0x0A983);
+ (0x0A9B4,0x0A9B5), `Delta (0);
+ (0x0A9BA,0x0A9BB), `Delta (0);
+ (0x0A9BD,0x0A9C0), `Delta (0);
+ (0x0AA2F,0x0AA30), `Delta (0);
+ (0x0AA33,0x0AA34), `Delta (0);
+ (0x0AA4D,0x0AA4D), `Abs (0x0AA4D);
+ (0x0AA7B,0x0AA7B), `Abs (0x0AA7B);
+ (0x0AA7D,0x0AA7D), `Abs (0x0AA7D);
+ (0x0AAEB,0x0AAEB), `Abs (0x0AAEB);
+ (0x0AAEE,0x0AAEF), `Delta (0);
+ (0x0AAF5,0x0AAF5), `Abs (0x0AAF5);
+ (0x0ABE3,0x0ABE4), `Delta (0);
+ (0x0ABE6,0x0ABE7), `Delta (0);
+ (0x0ABE9,0x0ABEA), `Delta (0);
+ (0x0ABEC,0x0ABEC), `Abs (0x0ABEC);
+ (0x11000,0x11000), `Abs (0x11000);
+ (0x11002,0x11002), `Abs (0x11002);
+ (0x11082,0x11082), `Abs (0x11082);
+ (0x110B0,0x110B2), `Delta (0);
+ (0x110B7,0x110B8), `Delta (0);
+ (0x1112C,0x1112C), `Abs (0x1112C);
+ (0x11182,0x11182), `Abs (0x11182);
+ (0x111B3,0x111B5), `Delta (0);
+ (0x111BF,0x111C0), `Delta (0);
+ (0x1122C,0x1122E), `Delta (0);
+ (0x11232,0x11233), `Delta (0);
+ (0x11235,0x11235), `Abs (0x11235);
+ (0x112E0,0x112E2), `Delta (0);
+ (0x11302,0x11303), `Delta (0);
+ (0x1133E,0x1133F), `Delta (0);
+ (0x11341,0x11344), `Delta (0);
+ (0x11347,0x11348), `Delta (0);
+ (0x1134B,0x1134D), `Delta (0);
+ (0x11357,0x11357), `Abs (0x11357);
+ (0x11362,0x11363), `Delta (0);
+ (0x11435,0x11437), `Delta (0);
+ (0x11440,0x11441), `Delta (0);
+ (0x11445,0x11445), `Abs (0x11445);
+ (0x114B0,0x114B2), `Delta (0);
+ (0x114B9,0x114B9), `Abs (0x114B9);
+ (0x114BB,0x114BE), `Delta (0);
+ (0x114C1,0x114C1), `Abs (0x114C1);
+ (0x115AF,0x115B1), `Delta (0);
+ (0x115B8,0x115BB), `Delta (0);
+ (0x115BE,0x115BE), `Abs (0x115BE);
+ (0x11630,0x11632), `Delta (0);
+ (0x1163B,0x1163C), `Delta (0);
+ (0x1163E,0x1163E), `Abs (0x1163E);
+ (0x116AC,0x116AC), `Abs (0x116AC);
+ (0x116AE,0x116AF), `Delta (0);
+ (0x116B6,0x116B6), `Abs (0x116B6);
+ (0x11720,0x11721), `Delta (0);
+ (0x11726,0x11726), `Abs (0x11726);
+ (0x11C2F,0x11C2F), `Abs (0x11C2F);
+ (0x11C3E,0x11C3E), `Abs (0x11C3E);
+ (0x11CA9,0x11CA9), `Abs (0x11CA9);
+ (0x11CB1,0x11CB1), `Abs (0x11CB1);
+ (0x11CB4,0x11CB4), `Abs (0x11CB4);
+ (0x16F51,0x16F7E), `Delta (0);
+ (0x1D165,0x1D166), `Delta (0);
+ (0x1D16D,0x1D172), `Delta (0);
+ (0x00488,0x00489), `Delta (0);
+ (0x01ABE,0x01ABE), `Abs (0x01ABE);
+ (0x020DD,0x020E0), `Delta (0);
+ (0x020E2,0x020E4), `Delta (0);
+ (0x0A670,0x0A672), `Delta (0);
+ (0x00030,0x00039), `Delta (0);
+ (0x00660,0x00669), `Delta (0);
+ (0x006F0,0x006F9), `Delta (0);
+ (0x007C0,0x007C9), `Delta (0);
+ (0x00966,0x0096F), `Delta (0);
+ (0x009E6,0x009EF), `Delta (0);
+ (0x00A66,0x00A6F), `Delta (0);
+ (0x00AE6,0x00AEF), `Delta (0);
+ (0x00B66,0x00B6F), `Delta (0);
+ (0x00BE6,0x00BEF), `Delta (0);
+ (0x00C66,0x00C6F), `Delta (0);
+ (0x00CE6,0x00CEF), `Delta (0);
+ (0x00D66,0x00D6F), `Delta (0);
+ (0x00DE6,0x00DEF), `Delta (0);
+ (0x00E50,0x00E59), `Delta (0);
+ (0x00ED0,0x00ED9), `Delta (0);
+ (0x00F20,0x00F29), `Delta (0);
+ (0x01040,0x01049), `Delta (0);
+ (0x01090,0x01099), `Delta (0);
+ (0x017E0,0x017E9), `Delta (0);
+ (0x01810,0x01819), `Delta (0);
+ (0x01946,0x0194F), `Delta (0);
+ (0x019D0,0x019D9), `Delta (0);
+ (0x01A80,0x01A89), `Delta (0);
+ (0x01A90,0x01A99), `Delta (0);
+ (0x01B50,0x01B59), `Delta (0);
+ (0x01BB0,0x01BB9), `Delta (0);
+ (0x01C40,0x01C49), `Delta (0);
+ (0x01C50,0x01C59), `Delta (0);
+ (0x0A620,0x0A629), `Delta (0);
+ (0x0A8D0,0x0A8D9), `Delta (0);
+ (0x0A900,0x0A909), `Delta (0);
+ (0x0A9D0,0x0A9D9), `Delta (0);
+ (0x0A9F0,0x0A9F9), `Delta (0);
+ (0x0AA50,0x0AA59), `Delta (0);
+ (0x0ABF0,0x0ABF9), `Delta (0);
+ (0x0FF10,0x0FF19), `Delta (0);
+ (0x104A0,0x104A9), `Delta (0);
+ (0x11066,0x1106F), `Delta (0);
+ (0x110F0,0x110F9), `Delta (0);
+ (0x11136,0x1113F), `Delta (0);
+ (0x111D0,0x111D9), `Delta (0);
+ (0x112F0,0x112F9), `Delta (0);
+ (0x11450,0x11459), `Delta (0);
+ (0x114D0,0x114D9), `Delta (0);
+ (0x11650,0x11659), `Delta (0);
+ (0x116C0,0x116C9), `Delta (0);
+ (0x11730,0x11739), `Delta (0);
+ (0x118E0,0x118E9), `Delta (0);
+ (0x11C50,0x11C59), `Delta (0);
+ (0x16A60,0x16A69), `Delta (0);
+ (0x16B50,0x16B59), `Delta (0);
+ (0x1D7CE,0x1D7FF), `Delta (0);
+ (0x1E950,0x1E959), `Delta (0);
+ (0x016EE,0x016F0), `Delta (0);
+ (0x02160,0x0216F), `Delta (16);
+ (0x02170,0x02182), `Delta (0);
+ (0x02185,0x02188), `Delta (0);
+ (0x03007,0x03007), `Abs (0x03007);
+ (0x03021,0x03029), `Delta (0);
+ (0x03038,0x0303A), `Delta (0);
+ (0x0A6E6,0x0A6EF), `Delta (0);
+ (0x10140,0x10174), `Delta (0);
+ (0x10341,0x10341), `Abs (0x10341);
+ (0x1034A,0x1034A), `Abs (0x1034A);
+ (0x103D1,0x103D5), `Delta (0);
+ (0x12400,0x1246E), `Delta (0);
+ (0x000B2,0x000B3), `Delta (0);
+ (0x000B9,0x000B9), `Abs (0x000B9);
+ (0x000BC,0x000BE), `Delta (0);
+ (0x009F4,0x009F9), `Delta (0);
+ (0x00B72,0x00B77), `Delta (0);
+ (0x00BF0,0x00BF2), `Delta (0);
+ (0x00C78,0x00C7E), `Delta (0);
+ (0x00D58,0x00D5E), `Delta (0);
+ (0x00D70,0x00D78), `Delta (0);
+ (0x00F2A,0x00F33), `Delta (0);
+ (0x01369,0x0137C), `Delta (0);
+ (0x017F0,0x017F9), `Delta (0);
+ (0x019DA,0x019DA), `Abs (0x019DA);
+ (0x02070,0x02070), `Abs (0x02070);
+ (0x02074,0x02079), `Delta (0);
+ (0x02080,0x02089), `Delta (0);
+ (0x02150,0x0215F), `Delta (0);
+ (0x02189,0x02189), `Abs (0x02189);
+ (0x02460,0x0249B), `Delta (0);
+ (0x024EA,0x024FF), `Delta (0);
+ (0x02776,0x02793), `Delta (0);
+ (0x02CFD,0x02CFD), `Abs (0x02CFD);
+ (0x03192,0x03195), `Delta (0);
+ (0x03220,0x03229), `Delta (0);
+ (0x03248,0x0324F), `Delta (0);
+ (0x03251,0x0325F), `Delta (0);
+ (0x03280,0x03289), `Delta (0);
+ (0x032B1,0x032BF), `Delta (0);
+ (0x0A830,0x0A835), `Delta (0);
+ (0x10107,0x10133), `Delta (0);
+ (0x10175,0x10178), `Delta (0);
+ (0x1018A,0x1018B), `Delta (0);
+ (0x102E1,0x102FB), `Delta (0);
+ (0x10320,0x10323), `Delta (0);
+ (0x10858,0x1085F), `Delta (0);
+ (0x10879,0x1087F), `Delta (0);
+ (0x108A7,0x108AF), `Delta (0);
+ (0x108FB,0x108FF), `Delta (0);
+ (0x10916,0x1091B), `Delta (0);
+ (0x109BC,0x109BD), `Delta (0);
+ (0x109C0,0x109CF), `Delta (0);
+ (0x109D2,0x109FF), `Delta (0);
+ (0x10A40,0x10A47), `Delta (0);
+ (0x10A7D,0x10A7E), `Delta (0);
+ (0x10A9D,0x10A9F), `Delta (0);
+ (0x10AEB,0x10AEF), `Delta (0);
+ (0x10B58,0x10B5F), `Delta (0);
+ (0x10B78,0x10B7F), `Delta (0);
+ (0x10BA9,0x10BAF), `Delta (0);
+ (0x10CFA,0x10CFF), `Delta (0);
+ (0x10E60,0x10E7E), `Delta (0);
+ (0x11052,0x11065), `Delta (0);
+ (0x111E1,0x111F4), `Delta (0);
+ (0x1173A,0x1173B), `Delta (0);
+ (0x118EA,0x118F2), `Delta (0);
+ (0x11C5A,0x11C6C), `Delta (0);
+ (0x16B5B,0x16B61), `Delta (0);
+ (0x1D360,0x1D371), `Delta (0);
+ (0x1E8C7,0x1E8CF), `Delta (0);
+ (0x1F100,0x1F10C), `Delta (0);
+ (0x00020,0x00020), `Abs (0x00020);
+ (0x000A0,0x000A0), `Abs (0x000A0);
+ (0x01680,0x01680), `Abs (0x01680);
+ (0x02000,0x0200A), `Delta (0);
+ (0x0202F,0x0202F), `Abs (0x0202F);
+ (0x0205F,0x0205F), `Abs (0x0205F);
+ (0x03000,0x03000), `Abs (0x03000);
+ (0x02028,0x02029), `Delta (0);
+ (0x00001,0x0001F), `Delta (0);
+ (0x0007F,0x0009F), `Delta (0);
+ (0x000AD,0x000AD), `Abs (0x000AD);
+ (0x00600,0x00605), `Delta (0);
+ (0x0061C,0x0061C), `Abs (0x0061C);
+ (0x006DD,0x006DD), `Abs (0x006DD);
+ (0x0070F,0x0070F), `Abs (0x0070F);
+ (0x008E2,0x008E2), `Abs (0x008E2);
+ (0x0180E,0x0180E), `Abs (0x0180E);
+ (0x0200B,0x0200F), `Delta (0);
+ (0x0202A,0x0202E), `Delta (0);
+ (0x02060,0x02064), `Delta (0);
+ (0x02066,0x0206F), `Delta (0);
+ (0x0FEFF,0x0FEFF), `Abs (0x0FEFF);
+ (0x0FFF9,0x0FFFB), `Delta (0);
+ (0x110BD,0x110BD), `Abs (0x110BD);
+ (0x1BCA0,0x1BCA3), `Delta (0);
+ (0x1D173,0x1D17A), `Delta (0);
+ (0xE0001,0xE0001), `Abs (0xE0001);
+ (0xE0020,0xE007F), `Delta (0);
+ (0x0D800,0x0F8FF), `Delta (0);
+ (0xF0000,0xFFFFD), `Delta (0);
+ (0x100000,0x10FFFD), `Delta (0);
+ (0x00378,0x00379), `Delta (0);
+ (0x00380,0x00383), `Delta (0);
+ (0x0038B,0x0038B), `Abs (0x0038B);
+ (0x0038D,0x0038D), `Abs (0x0038D);
+ (0x003A2,0x003A2), `Abs (0x003A2);
+ (0x00530,0x00530), `Abs (0x00530);
+ (0x00557,0x00558), `Delta (0);
+ (0x00560,0x00560), `Abs (0x00560);
+ (0x00588,0x00588), `Abs (0x00588);
+ (0x0058B,0x0058C), `Delta (0);
+ (0x00590,0x00590), `Abs (0x00590);
+ (0x005C8,0x005CF), `Delta (0);
+ (0x005EB,0x005EF), `Delta (0);
+ (0x005F5,0x005FF), `Delta (0);
+ (0x0061D,0x0061D), `Abs (0x0061D);
+ (0x0070E,0x0070E), `Abs (0x0070E);
+ (0x0074B,0x0074C), `Delta (0);
+ (0x007B2,0x007BF), `Delta (0);
+ (0x007FB,0x007FF), `Delta (0);
+ (0x0082E,0x0082F), `Delta (0);
+ (0x0083F,0x0083F), `Abs (0x0083F);
+ (0x0085C,0x0085D), `Delta (0);
+ (0x0085F,0x0089F), `Delta (0);
+ (0x008B5,0x008B5), `Abs (0x008B5);
+ (0x008BE,0x008D3), `Delta (0);
+ (0x00984,0x00984), `Abs (0x00984);
+ (0x0098D,0x0098E), `Delta (0);
+ (0x00991,0x00992), `Delta (0);
+ (0x009A9,0x009A9), `Abs (0x009A9);
+ (0x009B1,0x009B1), `Abs (0x009B1);
+ (0x009B3,0x009B5), `Delta (0);
+ (0x009BA,0x009BB), `Delta (0);
+ (0x009C5,0x009C6), `Delta (0);
+ (0x009C9,0x009CA), `Delta (0);
+ (0x009CF,0x009D6), `Delta (0);
+ (0x009D8,0x009DB), `Delta (0);
+ (0x009DE,0x009DE), `Abs (0x009DE);
+ (0x009E4,0x009E5), `Delta (0);
+ (0x009FC,0x00A00), `Delta (0);
+ (0x00A04,0x00A04), `Abs (0x00A04);
+ (0x00A0B,0x00A0E), `Delta (0);
+ (0x00A11,0x00A12), `Delta (0);
+ (0x00A29,0x00A29), `Abs (0x00A29);
+ (0x00A31,0x00A31), `Abs (0x00A31);
+ (0x00A34,0x00A34), `Abs (0x00A34);
+ (0x00A37,0x00A37), `Abs (0x00A37);
+ (0x00A3A,0x00A3B), `Delta (0);
+ (0x00A3D,0x00A3D), `Abs (0x00A3D);
+ (0x00A43,0x00A46), `Delta (0);
+ (0x00A49,0x00A4A), `Delta (0);
+ (0x00A4E,0x00A50), `Delta (0);
+ (0x00A52,0x00A58), `Delta (0);
+ (0x00A5D,0x00A5D), `Abs (0x00A5D);
+ (0x00A5F,0x00A65), `Delta (0);
+ (0x00A76,0x00A80), `Delta (0);
+ (0x00A84,0x00A84), `Abs (0x00A84);
+ (0x00A8E,0x00A8E), `Abs (0x00A8E);
+ (0x00A92,0x00A92), `Abs (0x00A92);
+ (0x00AA9,0x00AA9), `Abs (0x00AA9);
+ (0x00AB1,0x00AB1), `Abs (0x00AB1);
+ (0x00AB4,0x00AB4), `Abs (0x00AB4);
+ (0x00ABA,0x00ABB), `Delta (0);
+ (0x00AC6,0x00AC6), `Abs (0x00AC6);
+ (0x00ACA,0x00ACA), `Abs (0x00ACA);
+ (0x00ACE,0x00ACF), `Delta (0);
+ (0x00AD1,0x00ADF), `Delta (0);
+ (0x00AE4,0x00AE5), `Delta (0);
+ (0x00AF2,0x00AF8), `Delta (0);
+ (0x00AFA,0x00B00), `Delta (0);
+ (0x00B04,0x00B04), `Abs (0x00B04);
+ (0x00B0D,0x00B0E), `Delta (0);
+ (0x00B11,0x00B12), `Delta (0);
+ (0x00B29,0x00B29), `Abs (0x00B29);
+ (0x00B31,0x00B31), `Abs (0x00B31);
+ (0x00B34,0x00B34), `Abs (0x00B34);
+ (0x00B3A,0x00B3B), `Delta (0);
+ (0x00B45,0x00B46), `Delta (0);
+ (0x00B49,0x00B4A), `Delta (0);
+ (0x00B4E,0x00B55), `Delta (0);
+ (0x00B58,0x00B5B), `Delta (0);
+ (0x00B5E,0x00B5E), `Abs (0x00B5E);
+ (0x00B64,0x00B65), `Delta (0);
+ (0x00B78,0x00B81), `Delta (0);
+ (0x00B84,0x00B84), `Abs (0x00B84);
+ (0x00B8B,0x00B8D), `Delta (0);
+ (0x00B91,0x00B91), `Abs (0x00B91);
+ (0x00B96,0x00B98), `Delta (0);
+ (0x00B9B,0x00B9B), `Abs (0x00B9B);
+ (0x00B9D,0x00B9D), `Abs (0x00B9D);
+ (0x00BA0,0x00BA2), `Delta (0);
+ (0x00BA5,0x00BA7), `Delta (0);
+ (0x00BAB,0x00BAD), `Delta (0);
+ (0x00BBA,0x00BBD), `Delta (0);
+ (0x00BC3,0x00BC5), `Delta (0);
+ (0x00BC9,0x00BC9), `Abs (0x00BC9);
+ (0x00BCE,0x00BCF), `Delta (0);
+ (0x00BD1,0x00BD6), `Delta (0);
+ (0x00BD8,0x00BE5), `Delta (0);
+ (0x00BFB,0x00BFF), `Delta (0);
+ (0x00C04,0x00C04), `Abs (0x00C04);
+ (0x00C0D,0x00C0D), `Abs (0x00C0D);
+ (0x00C11,0x00C11), `Abs (0x00C11);
+ (0x00C29,0x00C29), `Abs (0x00C29);
+ (0x00C3A,0x00C3C), `Delta (0);
+ (0x00C45,0x00C45), `Abs (0x00C45);
+ (0x00C49,0x00C49), `Abs (0x00C49);
+ (0x00C4E,0x00C54), `Delta (0);
+ (0x00C57,0x00C57), `Abs (0x00C57);
+ (0x00C5B,0x00C5F), `Delta (0);
+ (0x00C64,0x00C65), `Delta (0);
+ (0x00C70,0x00C77), `Delta (0);
+ (0x00C84,0x00C84), `Abs (0x00C84);
+ (0x00C8D,0x00C8D), `Abs (0x00C8D);
+ (0x00C91,0x00C91), `Abs (0x00C91);
+ (0x00CA9,0x00CA9), `Abs (0x00CA9);
+ (0x00CB4,0x00CB4), `Abs (0x00CB4);
+ (0x00CBA,0x00CBB), `Delta (0);
+ (0x00CC5,0x00CC5), `Abs (0x00CC5);
+ (0x00CC9,0x00CC9), `Abs (0x00CC9);
+ (0x00CCE,0x00CD4), `Delta (0);
+ (0x00CD7,0x00CDD), `Delta (0);
+ (0x00CDF,0x00CDF), `Abs (0x00CDF);
+ (0x00CE4,0x00CE5), `Delta (0);
+ (0x00CF0,0x00CF0), `Abs (0x00CF0);
+ (0x00CF3,0x00D00), `Delta (0);
+ (0x00D04,0x00D04), `Abs (0x00D04);
+ (0x00D0D,0x00D0D), `Abs (0x00D0D);
+ (0x00D11,0x00D11), `Abs (0x00D11);
+ (0x00D3B,0x00D3C), `Delta (0);
+ (0x00D45,0x00D45), `Abs (0x00D45);
+ (0x00D49,0x00D49), `Abs (0x00D49);
+ (0x00D50,0x00D53), `Delta (0);
+ (0x00D64,0x00D65), `Delta (0);
+ (0x00D80,0x00D81), `Delta (0);
+ (0x00D84,0x00D84), `Abs (0x00D84);
+ (0x00D97,0x00D99), `Delta (0);
+ (0x00DB2,0x00DB2), `Abs (0x00DB2);
+ (0x00DBC,0x00DBC), `Abs (0x00DBC);
+ (0x00DBE,0x00DBF), `Delta (0);
+ (0x00DC7,0x00DC9), `Delta (0);
+ (0x00DCB,0x00DCE), `Delta (0);
+ (0x00DD5,0x00DD5), `Abs (0x00DD5);
+ (0x00DD7,0x00DD7), `Abs (0x00DD7);
+ (0x00DE0,0x00DE5), `Delta (0);
+ (0x00DF0,0x00DF1), `Delta (0);
+ (0x00DF5,0x00E00), `Delta (0);
+ (0x00E3B,0x00E3E), `Delta (0);
+ (0x00E5C,0x00E80), `Delta (0);
+ (0x00E83,0x00E83), `Abs (0x00E83);
+ (0x00E85,0x00E86), `Delta (0);
+ (0x00E89,0x00E89), `Abs (0x00E89);
+ (0x00E8B,0x00E8C), `Delta (0);
+ (0x00E8E,0x00E93), `Delta (0);
+ (0x00E98,0x00E98), `Abs (0x00E98);
+ (0x00EA0,0x00EA0), `Abs (0x00EA0);
+ (0x00EA4,0x00EA4), `Abs (0x00EA4);
+ (0x00EA6,0x00EA6), `Abs (0x00EA6);
+ (0x00EA8,0x00EA9), `Delta (0);
+ (0x00EAC,0x00EAC), `Abs (0x00EAC);
+ (0x00EBA,0x00EBA), `Abs (0x00EBA);
+ (0x00EBE,0x00EBF), `Delta (0);
+ (0x00EC5,0x00EC5), `Abs (0x00EC5);
+ (0x00EC7,0x00EC7), `Abs (0x00EC7);
+ (0x00ECE,0x00ECF), `Delta (0);
+ (0x00EDA,0x00EDB), `Delta (0);
+ (0x00EE0,0x00EFF), `Delta (0);
+ (0x00F48,0x00F48), `Abs (0x00F48);
+ (0x00F6D,0x00F70), `Delta (0);
+ (0x00F98,0x00F98), `Abs (0x00F98);
+ (0x00FBD,0x00FBD), `Abs (0x00FBD);
+ (0x00FCD,0x00FCD), `Abs (0x00FCD);
+ (0x00FDB,0x00FFF), `Delta (0);
+ (0x010C6,0x010C6), `Abs (0x010C6);
+ (0x010C8,0x010CC), `Delta (0);
+ (0x010CE,0x010CF), `Delta (0);
+ (0x01249,0x01249), `Abs (0x01249);
+ (0x0124E,0x0124F), `Delta (0);
+ (0x01257,0x01257), `Abs (0x01257);
+ (0x01259,0x01259), `Abs (0x01259);
+ (0x0125E,0x0125F), `Delta (0);
+ (0x01289,0x01289), `Abs (0x01289);
+ (0x0128E,0x0128F), `Delta (0);
+ (0x012B1,0x012B1), `Abs (0x012B1);
+ (0x012B6,0x012B7), `Delta (0);
+ (0x012BF,0x012BF), `Abs (0x012BF);
+ (0x012C1,0x012C1), `Abs (0x012C1);
+ (0x012C6,0x012C7), `Delta (0);
+ (0x012D7,0x012D7), `Abs (0x012D7);
+ (0x01311,0x01311), `Abs (0x01311);
+ (0x01316,0x01317), `Delta (0);
+ (0x0135B,0x0135C), `Delta (0);
+ (0x0137D,0x0137F), `Delta (0);
+ (0x0139A,0x0139F), `Delta (0);
+ (0x013F6,0x013F7), `Delta (0);
+ (0x013FE,0x013FF), `Delta (0);
+ (0x0169D,0x0169F), `Delta (0);
+ (0x016F9,0x016FF), `Delta (0);
+ (0x0170D,0x0170D), `Abs (0x0170D);
+ (0x01715,0x0171F), `Delta (0);
+ (0x01737,0x0173F), `Delta (0);
+ (0x01754,0x0175F), `Delta (0);
+ (0x0176D,0x0176D), `Abs (0x0176D);
+ (0x01771,0x01771), `Abs (0x01771);
+ (0x01774,0x0177F), `Delta (0);
+ (0x017DE,0x017DF), `Delta (0);
+ (0x017EA,0x017EF), `Delta (0);
+ (0x017FA,0x017FF), `Delta (0);
+ (0x0180F,0x0180F), `Abs (0x0180F);
+ (0x0181A,0x0181F), `Delta (0);
+ (0x01878,0x0187F), `Delta (0);
+ (0x018AB,0x018AF), `Delta (0);
+ (0x018F6,0x018FF), `Delta (0);
+ (0x0191F,0x0191F), `Abs (0x0191F);
+ (0x0192C,0x0192F), `Delta (0);
+ (0x0193C,0x0193F), `Delta (0);
+ (0x01941,0x01943), `Delta (0);
+ (0x0196E,0x0196F), `Delta (0);
+ (0x01975,0x0197F), `Delta (0);
+ (0x019AC,0x019AF), `Delta (0);
+ (0x019CA,0x019CF), `Delta (0);
+ (0x019DB,0x019DD), `Delta (0);
+ (0x01A1C,0x01A1D), `Delta (0);
+ (0x01A5F,0x01A5F), `Abs (0x01A5F);
+ (0x01A7D,0x01A7E), `Delta (0);
+ (0x01A8A,0x01A8F), `Delta (0);
+ (0x01A9A,0x01A9F), `Delta (0);
+ (0x01AAE,0x01AAF), `Delta (0);
+ (0x01ABF,0x01AFF), `Delta (0);
+ (0x01B4C,0x01B4F), `Delta (0);
+ (0x01B7D,0x01B7F), `Delta (0);
+ (0x01BF4,0x01BFB), `Delta (0);
+ (0x01C38,0x01C3A), `Delta (0);
+ (0x01C4A,0x01C4C), `Delta (0);
+ (0x01C89,0x01CBF), `Delta (0);
+ (0x01CC8,0x01CCF), `Delta (0);
+ (0x01CF7,0x01CF7), `Abs (0x01CF7);
+ (0x01CFA,0x01CFF), `Delta (0);
+ (0x01DF6,0x01DFA), `Delta (0);
+ (0x01F16,0x01F17), `Delta (0);
+ (0x01F1E,0x01F1F), `Delta (0);
+ (0x01F46,0x01F47), `Delta (0);
+ (0x01F4E,0x01F4F), `Delta (0);
+ (0x01F58,0x01F58), `Abs (0x01F58);
+ (0x01F5A,0x01F5A), `Abs (0x01F5A);
+ (0x01F5C,0x01F5C), `Abs (0x01F5C);
+ (0x01F5E,0x01F5E), `Abs (0x01F5E);
+ (0x01F7E,0x01F7F), `Delta (0);
+ (0x01FB5,0x01FB5), `Abs (0x01FB5);
+ (0x01FC5,0x01FC5), `Abs (0x01FC5);
+ (0x01FD4,0x01FD5), `Delta (0);
+ (0x01FDC,0x01FDC), `Abs (0x01FDC);
+ (0x01FF0,0x01FF1), `Delta (0);
+ (0x01FF5,0x01FF5), `Abs (0x01FF5);
+ (0x01FFF,0x01FFF), `Abs (0x01FFF);
+ (0x02065,0x02065), `Abs (0x02065);
+ (0x02072,0x02073), `Delta (0);
+ (0x0208F,0x0208F), `Abs (0x0208F);
+ (0x0209D,0x0209F), `Delta (0);
+ (0x020BF,0x020CF), `Delta (0);
+ (0x020F1,0x020FF), `Delta (0);
+ (0x0218C,0x0218F), `Delta (0);
+ (0x023FF,0x023FF), `Abs (0x023FF);
+ (0x02427,0x0243F), `Delta (0);
+ (0x0244B,0x0245F), `Delta (0);
+ (0x02B74,0x02B75), `Delta (0);
+ (0x02B96,0x02B97), `Delta (0);
+ (0x02BBA,0x02BBC), `Delta (0);
+ (0x02BC9,0x02BC9), `Abs (0x02BC9);
+ (0x02BD2,0x02BEB), `Delta (0);
+ (0x02BF0,0x02BFF), `Delta (0);
+ (0x02C2F,0x02C2F), `Abs (0x02C2F);
+ (0x02C5F,0x02C5F), `Abs (0x02C5F);
+ (0x02CF4,0x02CF8), `Delta (0);
+ (0x02D26,0x02D26), `Abs (0x02D26);
+ (0x02D28,0x02D2C), `Delta (0);
+ (0x02D2E,0x02D2F), `Delta (0);
+ (0x02D68,0x02D6E), `Delta (0);
+ (0x02D71,0x02D7E), `Delta (0);
+ (0x02D97,0x02D9F), `Delta (0);
+ (0x02DA7,0x02DA7), `Abs (0x02DA7);
+ (0x02DAF,0x02DAF), `Abs (0x02DAF);
+ (0x02DB7,0x02DB7), `Abs (0x02DB7);
+ (0x02DBF,0x02DBF), `Abs (0x02DBF);
+ (0x02DC7,0x02DC7), `Abs (0x02DC7);
+ (0x02DCF,0x02DCF), `Abs (0x02DCF);
+ (0x02DD7,0x02DD7), `Abs (0x02DD7);
+ (0x02DDF,0x02DDF), `Abs (0x02DDF);
+ (0x02E45,0x02E7F), `Delta (0);
+ (0x02E9A,0x02E9A), `Abs (0x02E9A);
+ (0x02EF4,0x02EFF), `Delta (0);
+ (0x02FD6,0x02FEF), `Delta (0);
+ (0x02FFC,0x02FFF), `Delta (0);
+ (0x03040,0x03040), `Abs (0x03040);
+ (0x03097,0x03098), `Delta (0);
+ (0x03100,0x03104), `Delta (0);
+ (0x0312E,0x03130), `Delta (0);
+ (0x0318F,0x0318F), `Abs (0x0318F);
+ (0x031BB,0x031BF), `Delta (0);
+ (0x031E4,0x031EF), `Delta (0);
+ (0x0321F,0x0321F), `Abs (0x0321F);
+ (0x032FF,0x032FF), `Abs (0x032FF);
+ (0x04DB6,0x04DBF), `Delta (0);
+ (0x09FD6,0x09FFF), `Delta (0);
+ (0x0A48D,0x0A48F), `Delta (0);
+ (0x0A4C7,0x0A4CF), `Delta (0);
+ (0x0A62C,0x0A63F), `Delta (0);
+ (0x0A6F8,0x0A6FF), `Delta (0);
+ (0x0A7AF,0x0A7AF), `Abs (0x0A7AF);
+ (0x0A7B8,0x0A7F6), `Delta (0);
+ (0x0A82C,0x0A82F), `Delta (0);
+ (0x0A83A,0x0A83F), `Delta (0);
+ (0x0A878,0x0A87F), `Delta (0);
+ (0x0A8C6,0x0A8CD), `Delta (0);
+ (0x0A8DA,0x0A8DF), `Delta (0);
+ (0x0A8FE,0x0A8FF), `Delta (0);
+ (0x0A954,0x0A95E), `Delta (0);
+ (0x0A97D,0x0A97F), `Delta (0);
+ (0x0A9CE,0x0A9CE), `Abs (0x0A9CE);
+ (0x0A9DA,0x0A9DD), `Delta (0);
+ (0x0A9FF,0x0A9FF), `Abs (0x0A9FF);
+ (0x0AA37,0x0AA3F), `Delta (0);
+ (0x0AA4E,0x0AA4F), `Delta (0);
+ (0x0AA5A,0x0AA5B), `Delta (0);
+ (0x0AAC3,0x0AADA), `Delta (0);
+ (0x0AAF7,0x0AB00), `Delta (0);
+ (0x0AB07,0x0AB08), `Delta (0);
+ (0x0AB0F,0x0AB10), `Delta (0);
+ (0x0AB17,0x0AB1F), `Delta (0);
+ (0x0AB27,0x0AB27), `Abs (0x0AB27);
+ (0x0AB2F,0x0AB2F), `Abs (0x0AB2F);
+ (0x0AB66,0x0AB6F), `Delta (0);
+ (0x0ABEE,0x0ABEF), `Delta (0);
+ (0x0ABFA,0x0ABFF), `Delta (0);
+ (0x0D7A4,0x0D7AF), `Delta (0);
+ (0x0D7C7,0x0D7CA), `Delta (0);
+ (0x0D7FC,0x0D7FF), `Delta (0);
+ (0x0FA6E,0x0FA6F), `Delta (0);
+ (0x0FADA,0x0FAFF), `Delta (0);
+ (0x0FB07,0x0FB12), `Delta (0);
+ (0x0FB18,0x0FB1C), `Delta (0);
+ (0x0FB37,0x0FB37), `Abs (0x0FB37);
+ (0x0FB3D,0x0FB3D), `Abs (0x0FB3D);
+ (0x0FB3F,0x0FB3F), `Abs (0x0FB3F);
+ (0x0FB42,0x0FB42), `Abs (0x0FB42);
+ (0x0FB45,0x0FB45), `Abs (0x0FB45);
+ (0x0FBC2,0x0FBD2), `Delta (0);
+ (0x0FD40,0x0FD4F), `Delta (0);
+ (0x0FD90,0x0FD91), `Delta (0);
+ (0x0FDC8,0x0FDEF), `Delta (0);
+ (0x0FDFE,0x0FDFF), `Delta (0);
+ (0x0FE1A,0x0FE1F), `Delta (0);
+ (0x0FE53,0x0FE53), `Abs (0x0FE53);
+ (0x0FE67,0x0FE67), `Abs (0x0FE67);
+ (0x0FE6C,0x0FE6F), `Delta (0);
+ (0x0FE75,0x0FE75), `Abs (0x0FE75);
+ (0x0FEFD,0x0FEFE), `Delta (0);
+ (0x0FF00,0x0FF00), `Abs (0x0FF00);
+ (0x0FFBF,0x0FFC1), `Delta (0);
+ (0x0FFC8,0x0FFC9), `Delta (0);
+ (0x0FFD0,0x0FFD1), `Delta (0);
+ (0x0FFD8,0x0FFD9), `Delta (0);
+ (0x0FFDD,0x0FFDF), `Delta (0);
+ (0x0FFE7,0x0FFE7), `Abs (0x0FFE7);
+ (0x0FFEF,0x0FFF8), `Delta (0);
+ (0x0FFFE,0x0FFFF), `Delta (0);
+ (0x1000C,0x1000C), `Abs (0x1000C);
+ (0x10027,0x10027), `Abs (0x10027);
+ (0x1003B,0x1003B), `Abs (0x1003B);
+ (0x1003E,0x1003E), `Abs (0x1003E);
+ (0x1004E,0x1004F), `Delta (0);
+ (0x1005E,0x1007F), `Delta (0);
+ (0x100FB,0x100FF), `Delta (0);
+ (0x10103,0x10106), `Delta (0);
+ (0x10134,0x10136), `Delta (0);
+ (0x1018F,0x1018F), `Abs (0x1018F);
+ (0x1019C,0x1019F), `Delta (0);
+ (0x101A1,0x101CF), `Delta (0);
+ (0x101FE,0x1027F), `Delta (0);
+ (0x1029D,0x1029F), `Delta (0);
+ (0x102D1,0x102DF), `Delta (0);
+ (0x102FC,0x102FF), `Delta (0);
+ (0x10324,0x1032F), `Delta (0);
+ (0x1034B,0x1034F), `Delta (0);
+ (0x1037B,0x1037F), `Delta (0);
+ (0x1039E,0x1039E), `Abs (0x1039E);
+ (0x103C4,0x103C7), `Delta (0);
+ (0x103D6,0x103FF), `Delta (0);
+ (0x1049E,0x1049F), `Delta (0);
+ (0x104AA,0x104AF), `Delta (0);
+ (0x104D4,0x104D7), `Delta (0);
+ (0x104FC,0x104FF), `Delta (0);
+ (0x10528,0x1052F), `Delta (0);
+ (0x10564,0x1056E), `Delta (0);
+ (0x10570,0x105FF), `Delta (0);
+ (0x10737,0x1073F), `Delta (0);
+ (0x10756,0x1075F), `Delta (0);
+ (0x10768,0x107FF), `Delta (0);
+ (0x10806,0x10807), `Delta (0);
+ (0x10809,0x10809), `Abs (0x10809);
+ (0x10836,0x10836), `Abs (0x10836);
+ (0x10839,0x1083B), `Delta (0);
+ (0x1083D,0x1083E), `Delta (0);
+ (0x10856,0x10856), `Abs (0x10856);
+ (0x1089F,0x108A6), `Delta (0);
+ (0x108B0,0x108DF), `Delta (0);
+ (0x108F3,0x108F3), `Abs (0x108F3);
+ (0x108F6,0x108FA), `Delta (0);
+ (0x1091C,0x1091E), `Delta (0);
+ (0x1093A,0x1093E), `Delta (0);
+ (0x10940,0x1097F), `Delta (0);
+ (0x109B8,0x109BB), `Delta (0);
+ (0x109D0,0x109D1), `Delta (0);
+ (0x10A04,0x10A04), `Abs (0x10A04);
+ (0x10A07,0x10A0B), `Delta (0);
+ (0x10A14,0x10A14), `Abs (0x10A14);
+ (0x10A18,0x10A18), `Abs (0x10A18);
+ (0x10A34,0x10A37), `Delta (0);
+ (0x10A3B,0x10A3E), `Delta (0);
+ (0x10A48,0x10A4F), `Delta (0);
+ (0x10A59,0x10A5F), `Delta (0);
+ (0x10AA0,0x10ABF), `Delta (0);
+ (0x10AE7,0x10AEA), `Delta (0);
+ (0x10AF7,0x10AFF), `Delta (0);
+ (0x10B36,0x10B38), `Delta (0);
+ (0x10B56,0x10B57), `Delta (0);
+ (0x10B73,0x10B77), `Delta (0);
+ (0x10B92,0x10B98), `Delta (0);
+ (0x10B9D,0x10BA8), `Delta (0);
+ (0x10BB0,0x10BFF), `Delta (0);
+ (0x10C49,0x10C7F), `Delta (0);
+ (0x10CB3,0x10CBF), `Delta (0);
+ (0x10CF3,0x10CF9), `Delta (0);
+ (0x10D00,0x10E5F), `Delta (0);
+ (0x10E7F,0x10FFF), `Delta (0);
+ (0x1104E,0x11051), `Delta (0);
+ (0x11070,0x1107E), `Delta (0);
+ (0x110C2,0x110CF), `Delta (0);
+ (0x110E9,0x110EF), `Delta (0);
+ (0x110FA,0x110FF), `Delta (0);
+ (0x11135,0x11135), `Abs (0x11135);
+ (0x11144,0x1114F), `Delta (0);
+ (0x11177,0x1117F), `Delta (0);
+ (0x111CE,0x111CF), `Delta (0);
+ (0x111E0,0x111E0), `Abs (0x111E0);
+ (0x111F5,0x111FF), `Delta (0);
+ (0x11212,0x11212), `Abs (0x11212);
+ (0x1123F,0x1127F), `Delta (0);
+ (0x11287,0x11287), `Abs (0x11287);
+ (0x11289,0x11289), `Abs (0x11289);
+ (0x1128E,0x1128E), `Abs (0x1128E);
+ (0x1129E,0x1129E), `Abs (0x1129E);
+ (0x112AA,0x112AF), `Delta (0);
+ (0x112EB,0x112EF), `Delta (0);
+ (0x112FA,0x112FF), `Delta (0);
+ (0x11304,0x11304), `Abs (0x11304);
+ (0x1130D,0x1130E), `Delta (0);
+ (0x11311,0x11312), `Delta (0);
+ (0x11329,0x11329), `Abs (0x11329);
+ (0x11331,0x11331), `Abs (0x11331);
+ (0x11334,0x11334), `Abs (0x11334);
+ (0x1133A,0x1133B), `Delta (0);
+ (0x11345,0x11346), `Delta (0);
+ (0x11349,0x1134A), `Delta (0);
+ (0x1134E,0x1134F), `Delta (0);
+ (0x11351,0x11356), `Delta (0);
+ (0x11358,0x1135C), `Delta (0);
+ (0x11364,0x11365), `Delta (0);
+ (0x1136D,0x1136F), `Delta (0);
+ (0x11375,0x113FF), `Delta (0);
+ (0x1145A,0x1145A), `Abs (0x1145A);
+ (0x1145C,0x1145C), `Abs (0x1145C);
+ (0x1145E,0x1147F), `Delta (0);
+ (0x114C8,0x114CF), `Delta (0);
+ (0x114DA,0x1157F), `Delta (0);
+ (0x115B6,0x115B7), `Delta (0);
+ (0x115DE,0x115FF), `Delta (0);
+ (0x11645,0x1164F), `Delta (0);
+ (0x1165A,0x1165F), `Delta (0);
+ (0x1166D,0x1167F), `Delta (0);
+ (0x116B8,0x116BF), `Delta (0);
+ (0x116CA,0x116FF), `Delta (0);
+ (0x1171A,0x1171C), `Delta (0);
+ (0x1172C,0x1172F), `Delta (0);
+ (0x11740,0x1189F), `Delta (0);
+ (0x118F3,0x118FE), `Delta (0);
+ (0x11900,0x11ABF), `Delta (0);
+ (0x11AF9,0x11BFF), `Delta (0);
+ (0x11C09,0x11C09), `Abs (0x11C09);
+ (0x11C37,0x11C37), `Abs (0x11C37);
+ (0x11C46,0x11C4F), `Delta (0);
+ (0x11C6D,0x11C6F), `Delta (0);
+ (0x11C90,0x11C91), `Delta (0);
+ (0x11CA8,0x11CA8), `Abs (0x11CA8);
+ (0x11CB7,0x11FFF), `Delta (0);
+ (0x1239A,0x123FF), `Delta (0);
+ (0x1246F,0x1246F), `Abs (0x1246F);
+ (0x12475,0x1247F), `Delta (0);
+ (0x12544,0x12FFF), `Delta (0);
+ (0x1342F,0x143FF), `Delta (0);
+ (0x14647,0x167FF), `Delta (0);
+ (0x16A39,0x16A3F), `Delta (0);
+ (0x16A5F,0x16A5F), `Abs (0x16A5F);
+ (0x16A6A,0x16A6D), `Delta (0);
+ (0x16A70,0x16ACF), `Delta (0);
+ (0x16AEE,0x16AEF), `Delta (0);
+ (0x16AF6,0x16AFF), `Delta (0);
+ (0x16B46,0x16B4F), `Delta (0);
+ (0x16B5A,0x16B5A), `Abs (0x16B5A);
+ (0x16B62,0x16B62), `Abs (0x16B62);
+ (0x16B78,0x16B7C), `Delta (0);
+ (0x16B90,0x16EFF), `Delta (0);
+ (0x16F45,0x16F4F), `Delta (0);
+ (0x16F7F,0x16F8E), `Delta (0);
+ (0x16FA0,0x16FDF), `Delta (0);
+ (0x16FE1,0x16FFF), `Delta (0);
+ (0x187ED,0x187FF), `Delta (0);
+ (0x18AF3,0x1AFFF), `Delta (0);
+ (0x1B002,0x1BBFF), `Delta (0);
+ (0x1BC6B,0x1BC6F), `Delta (0);
+ (0x1BC7D,0x1BC7F), `Delta (0);
+ (0x1BC89,0x1BC8F), `Delta (0);
+ (0x1BC9A,0x1BC9B), `Delta (0);
+ (0x1BCA4,0x1CFFF), `Delta (0);
+ (0x1D0F6,0x1D0FF), `Delta (0);
+ (0x1D127,0x1D128), `Delta (0);
+ (0x1D1E9,0x1D1FF), `Delta (0);
+ (0x1D246,0x1D2FF), `Delta (0);
+ (0x1D357,0x1D35F), `Delta (0);
+ (0x1D372,0x1D3FF), `Delta (0);
+ (0x1D455,0x1D455), `Abs (0x1D455);
+ (0x1D49D,0x1D49D), `Abs (0x1D49D);
+ (0x1D4A0,0x1D4A1), `Delta (0);
+ (0x1D4A3,0x1D4A4), `Delta (0);
+ (0x1D4A7,0x1D4A8), `Delta (0);
+ (0x1D4AD,0x1D4AD), `Abs (0x1D4AD);
+ (0x1D4BA,0x1D4BA), `Abs (0x1D4BA);
+ (0x1D4BC,0x1D4BC), `Abs (0x1D4BC);
+ (0x1D4C4,0x1D4C4), `Abs (0x1D4C4);
+ (0x1D506,0x1D506), `Abs (0x1D506);
+ (0x1D50B,0x1D50C), `Delta (0);
+ (0x1D515,0x1D515), `Abs (0x1D515);
+ (0x1D51D,0x1D51D), `Abs (0x1D51D);
+ (0x1D53A,0x1D53A), `Abs (0x1D53A);
+ (0x1D53F,0x1D53F), `Abs (0x1D53F);
+ (0x1D545,0x1D545), `Abs (0x1D545);
+ (0x1D547,0x1D549), `Delta (0);
+ (0x1D551,0x1D551), `Abs (0x1D551);
+ (0x1D6A6,0x1D6A7), `Delta (0);
+ (0x1D7CC,0x1D7CD), `Delta (0);
+ (0x1DA8C,0x1DA9A), `Delta (0);
+ (0x1DAA0,0x1DAA0), `Abs (0x1DAA0);
+ (0x1DAB0,0x1DFFF), `Delta (0);
+ (0x1E007,0x1E007), `Abs (0x1E007);
+ (0x1E019,0x1E01A), `Delta (0);
+ (0x1E022,0x1E022), `Abs (0x1E022);
+ (0x1E025,0x1E025), `Abs (0x1E025);
+ (0x1E02B,0x1E7FF), `Delta (0);
+ (0x1E8C5,0x1E8C6), `Delta (0);
+ (0x1E8D7,0x1E8FF), `Delta (0);
+ (0x1E94B,0x1E94F), `Delta (0);
+ (0x1E95A,0x1E95D), `Delta (0);
+ (0x1E960,0x1EDFF), `Delta (0);
+ (0x1EE04,0x1EE04), `Abs (0x1EE04);
+ (0x1EE20,0x1EE20), `Abs (0x1EE20);
+ (0x1EE23,0x1EE23), `Abs (0x1EE23);
+ (0x1EE25,0x1EE26), `Delta (0);
+ (0x1EE28,0x1EE28), `Abs (0x1EE28);
+ (0x1EE33,0x1EE33), `Abs (0x1EE33);
+ (0x1EE38,0x1EE38), `Abs (0x1EE38);
+ (0x1EE3A,0x1EE3A), `Abs (0x1EE3A);
+ (0x1EE3C,0x1EE41), `Delta (0);
+ (0x1EE43,0x1EE46), `Delta (0);
+ (0x1EE48,0x1EE48), `Abs (0x1EE48);
+ (0x1EE4A,0x1EE4A), `Abs (0x1EE4A);
+ (0x1EE4C,0x1EE4C), `Abs (0x1EE4C);
+ (0x1EE50,0x1EE50), `Abs (0x1EE50);
+ (0x1EE53,0x1EE53), `Abs (0x1EE53);
+ (0x1EE55,0x1EE56), `Delta (0);
+ (0x1EE58,0x1EE58), `Abs (0x1EE58);
+ (0x1EE5A,0x1EE5A), `Abs (0x1EE5A);
+ (0x1EE5C,0x1EE5C), `Abs (0x1EE5C);
+ (0x1EE5E,0x1EE5E), `Abs (0x1EE5E);
+ (0x1EE60,0x1EE60), `Abs (0x1EE60);
+ (0x1EE63,0x1EE63), `Abs (0x1EE63);
+ (0x1EE65,0x1EE66), `Delta (0);
+ (0x1EE6B,0x1EE6B), `Abs (0x1EE6B);
+ (0x1EE73,0x1EE73), `Abs (0x1EE73);
+ (0x1EE78,0x1EE78), `Abs (0x1EE78);
+ (0x1EE7D,0x1EE7D), `Abs (0x1EE7D);
+ (0x1EE7F,0x1EE7F), `Abs (0x1EE7F);
+ (0x1EE8A,0x1EE8A), `Abs (0x1EE8A);
+ (0x1EE9C,0x1EEA0), `Delta (0);
+ (0x1EEA4,0x1EEA4), `Abs (0x1EEA4);
+ (0x1EEAA,0x1EEAA), `Abs (0x1EEAA);
+ (0x1EEBC,0x1EEEF), `Delta (0);
+ (0x1EEF2,0x1EFFF), `Delta (0);
+ (0x1F02C,0x1F02F), `Delta (0);
+ (0x1F094,0x1F09F), `Delta (0);
+ (0x1F0AF,0x1F0B0), `Delta (0);
+ (0x1F0C0,0x1F0C0), `Abs (0x1F0C0);
+ (0x1F0D0,0x1F0D0), `Abs (0x1F0D0);
+ (0x1F0F6,0x1F0FF), `Delta (0);
+ (0x1F10D,0x1F10F), `Delta (0);
+ (0x1F12F,0x1F12F), `Abs (0x1F12F);
+ (0x1F16C,0x1F16F), `Delta (0);
+ (0x1F1AD,0x1F1E5), `Delta (0);
+ (0x1F203,0x1F20F), `Delta (0);
+ (0x1F23C,0x1F23F), `Delta (0);
+ (0x1F249,0x1F24F), `Delta (0);
+ (0x1F252,0x1F2FF), `Delta (0);
+ (0x1F6D3,0x1F6DF), `Delta (0);
+ (0x1F6ED,0x1F6EF), `Delta (0);
+ (0x1F6F7,0x1F6FF), `Delta (0);
+ (0x1F774,0x1F77F), `Delta (0);
+ (0x1F7D5,0x1F7FF), `Delta (0);
+ (0x1F80C,0x1F80F), `Delta (0);
+ (0x1F848,0x1F84F), `Delta (0);
+ (0x1F85A,0x1F85F), `Delta (0);
+ (0x1F888,0x1F88F), `Delta (0);
+ (0x1F8AE,0x1F90F), `Delta (0);
+ (0x1F91F,0x1F91F), `Abs (0x1F91F);
+ (0x1F928,0x1F92F), `Delta (0);
+ (0x1F931,0x1F932), `Delta (0);
+ (0x1F93F,0x1F93F), `Abs (0x1F93F);
+ (0x1F94C,0x1F94F), `Delta (0);
+ (0x1F95F,0x1F97F), `Delta (0);
+ (0x1F992,0x1F9BF), `Delta (0);
+ (0x1F9C1,0x1FFFF), `Delta (0);
+ (0x2A6D7,0x2A6FF), `Delta (0);
+ (0x2B735,0x2B73F), `Delta (0);
+ (0x2B81E,0x2B81F), `Delta (0);
+ (0x2CEA2,0x2F7FF), `Delta (0);
+ (0x2FA1E,0xE0000), `Delta (0);
+ (0xE0002,0xE001F), `Delta (0);
+ (0xE0080,0xE00FF), `Delta (0);
+ (0xE01F0,0xEFFFF), `Delta (0);
+ (0xFFFFE,0xFFFFF), `Delta (0);
+ (0x10FFFE,0x10FFFF), `Delta (0);
+ (0x002B0,0x002C1), `Delta (0);
+ (0x002C6,0x002D1), `Delta (0);
+ (0x002E0,0x002E4), `Delta (0);
+ (0x002EC,0x002EC), `Abs (0x002EC);
+ (0x002EE,0x002EE), `Abs (0x002EE);
+ (0x00374,0x00374), `Abs (0x00374);
+ (0x0037A,0x0037A), `Abs (0x0037A);
+ (0x00559,0x00559), `Abs (0x00559);
+ (0x00640,0x00640), `Abs (0x00640);
+ (0x006E5,0x006E6), `Delta (0);
+ (0x007F4,0x007F5), `Delta (0);
+ (0x007FA,0x007FA), `Abs (0x007FA);
+ (0x0081A,0x0081A), `Abs (0x0081A);
+ (0x00824,0x00824), `Abs (0x00824);
+ (0x00828,0x00828), `Abs (0x00828);
+ (0x00971,0x00971), `Abs (0x00971);
+ (0x00E46,0x00E46), `Abs (0x00E46);
+ (0x00EC6,0x00EC6), `Abs (0x00EC6);
+ (0x010FC,0x010FC), `Abs (0x010FC);
+ (0x017D7,0x017D7), `Abs (0x017D7);
+ (0x01843,0x01843), `Abs (0x01843);
+ (0x01AA7,0x01AA7), `Abs (0x01AA7);
+ (0x01C78,0x01C7D), `Delta (0);
+ (0x01D2C,0x01D6A), `Delta (0);
+ (0x01D78,0x01D78), `Abs (0x01D78);
+ (0x01D9B,0x01DBF), `Delta (0);
+ (0x02071,0x02071), `Abs (0x02071);
+ (0x0207F,0x0207F), `Abs (0x0207F);
+ (0x02090,0x0209C), `Delta (0);
+ (0x02C7C,0x02C7D), `Delta (0);
+ (0x02D6F,0x02D6F), `Abs (0x02D6F);
+ (0x02E2F,0x02E2F), `Abs (0x02E2F);
+ (0x03005,0x03005), `Abs (0x03005);
+ (0x03031,0x03035), `Delta (0);
+ (0x0303B,0x0303B), `Abs (0x0303B);
+ (0x0309D,0x0309E), `Delta (0);
+ (0x030FC,0x030FE), `Delta (0);
+ (0x0A015,0x0A015), `Abs (0x0A015);
+ (0x0A4F8,0x0A4FD), `Delta (0);
+ (0x0A60C,0x0A60C), `Abs (0x0A60C);
+ (0x0A67F,0x0A67F), `Abs (0x0A67F);
+ (0x0A69C,0x0A69D), `Delta (0);
+ (0x0A717,0x0A71F), `Delta (0);
+ (0x0A770,0x0A770), `Abs (0x0A770);
+ (0x0A788,0x0A788), `Abs (0x0A788);
+ (0x0A7F8,0x0A7F9), `Delta (0);
+ (0x0A9CF,0x0A9CF), `Abs (0x0A9CF);
+ (0x0A9E6,0x0A9E6), `Abs (0x0A9E6);
+ (0x0AA70,0x0AA70), `Abs (0x0AA70);
+ (0x0AADD,0x0AADD), `Abs (0x0AADD);
+ (0x0AAF3,0x0AAF4), `Delta (0);
+ (0x0AB5C,0x0AB5F), `Delta (0);
+ (0x0FF70,0x0FF70), `Abs (0x0FF70);
+ (0x0FF9E,0x0FF9F), `Delta (0);
+ (0x16B40,0x16B43), `Delta (0);
+ (0x16F93,0x16F9F), `Delta (0);
+ (0x16FE0,0x16FE0), `Abs (0x16FE0);
+ (0x000AA,0x000AA), `Abs (0x000AA);
+ (0x000BA,0x000BA), `Abs (0x000BA);
+ (0x001BB,0x001BB), `Abs (0x001BB);
+ (0x001C0,0x001C3), `Delta (0);
+ (0x00294,0x00294), `Abs (0x00294);
+ (0x005D0,0x005EA), `Delta (0);
+ (0x005F0,0x005F2), `Delta (0);
+ (0x00620,0x0063F), `Delta (0);
+ (0x00641,0x0064A), `Delta (0);
+ (0x0066E,0x0066F), `Delta (0);
+ (0x00671,0x006D3), `Delta (0);
+ (0x006D5,0x006D5), `Abs (0x006D5);
+ (0x006EE,0x006EF), `Delta (0);
+ (0x006FA,0x006FC), `Delta (0);
+ (0x006FF,0x006FF), `Abs (0x006FF);
+ (0x00710,0x00710), `Abs (0x00710);
+ (0x00712,0x0072F), `Delta (0);
+ (0x0074D,0x007A5), `Delta (0);
+ (0x007B1,0x007B1), `Abs (0x007B1);
+ (0x007CA,0x007EA), `Delta (0);
+ (0x00800,0x00815), `Delta (0);
+ (0x00840,0x00858), `Delta (0);
+ (0x008A0,0x008B4), `Delta (0);
+ (0x008B6,0x008BD), `Delta (0);
+ (0x00904,0x00939), `Delta (0);
+ (0x0093D,0x0093D), `Abs (0x0093D);
+ (0x00950,0x00950), `Abs (0x00950);
+ (0x00958,0x00961), `Delta (0);
+ (0x00972,0x00980), `Delta (0);
+ (0x00985,0x0098C), `Delta (0);
+ (0x0098F,0x00990), `Delta (0);
+ (0x00993,0x009A8), `Delta (0);
+ (0x009AA,0x009B0), `Delta (0);
+ (0x009B2,0x009B2), `Abs (0x009B2);
+ (0x009B6,0x009B9), `Delta (0);
+ (0x009BD,0x009BD), `Abs (0x009BD);
+ (0x009CE,0x009CE), `Abs (0x009CE);
+ (0x009DC,0x009DD), `Delta (0);
+ (0x009DF,0x009E1), `Delta (0);
+ (0x009F0,0x009F1), `Delta (0);
+ (0x00A05,0x00A0A), `Delta (0);
+ (0x00A0F,0x00A10), `Delta (0);
+ (0x00A13,0x00A28), `Delta (0);
+ (0x00A2A,0x00A30), `Delta (0);
+ (0x00A32,0x00A33), `Delta (0);
+ (0x00A35,0x00A36), `Delta (0);
+ (0x00A38,0x00A39), `Delta (0);
+ (0x00A59,0x00A5C), `Delta (0);
+ (0x00A5E,0x00A5E), `Abs (0x00A5E);
+ (0x00A72,0x00A74), `Delta (0);
+ (0x00A85,0x00A8D), `Delta (0);
+ (0x00A8F,0x00A91), `Delta (0);
+ (0x00A93,0x00AA8), `Delta (0);
+ (0x00AAA,0x00AB0), `Delta (0);
+ (0x00AB2,0x00AB3), `Delta (0);
+ (0x00AB5,0x00AB9), `Delta (0);
+ (0x00ABD,0x00ABD), `Abs (0x00ABD);
+ (0x00AD0,0x00AD0), `Abs (0x00AD0);
+ (0x00AE0,0x00AE1), `Delta (0);
+ (0x00AF9,0x00AF9), `Abs (0x00AF9);
+ (0x00B05,0x00B0C), `Delta (0);
+ (0x00B0F,0x00B10), `Delta (0);
+ (0x00B13,0x00B28), `Delta (0);
+ (0x00B2A,0x00B30), `Delta (0);
+ (0x00B32,0x00B33), `Delta (0);
+ (0x00B35,0x00B39), `Delta (0);
+ (0x00B3D,0x00B3D), `Abs (0x00B3D);
+ (0x00B5C,0x00B5D), `Delta (0);
+ (0x00B5F,0x00B61), `Delta (0);
+ (0x00B71,0x00B71), `Abs (0x00B71);
+ (0x00B83,0x00B83), `Abs (0x00B83);
+ (0x00B85,0x00B8A), `Delta (0);
+ (0x00B8E,0x00B90), `Delta (0);
+ (0x00B92,0x00B95), `Delta (0);
+ (0x00B99,0x00B9A), `Delta (0);
+ (0x00B9C,0x00B9C), `Abs (0x00B9C);
+ (0x00B9E,0x00B9F), `Delta (0);
+ (0x00BA3,0x00BA4), `Delta (0);
+ (0x00BA8,0x00BAA), `Delta (0);
+ (0x00BAE,0x00BB9), `Delta (0);
+ (0x00BD0,0x00BD0), `Abs (0x00BD0);
+ (0x00C05,0x00C0C), `Delta (0);
+ (0x00C0E,0x00C10), `Delta (0);
+ (0x00C12,0x00C28), `Delta (0);
+ (0x00C2A,0x00C39), `Delta (0);
+ (0x00C3D,0x00C3D), `Abs (0x00C3D);
+ (0x00C58,0x00C5A), `Delta (0);
+ (0x00C60,0x00C61), `Delta (0);
+ (0x00C80,0x00C80), `Abs (0x00C80);
+ (0x00C85,0x00C8C), `Delta (0);
+ (0x00C8E,0x00C90), `Delta (0);
+ (0x00C92,0x00CA8), `Delta (0);
+ (0x00CAA,0x00CB3), `Delta (0);
+ (0x00CB5,0x00CB9), `Delta (0);
+ (0x00CBD,0x00CBD), `Abs (0x00CBD);
+ (0x00CDE,0x00CDE), `Abs (0x00CDE);
+ (0x00CE0,0x00CE1), `Delta (0);
+ (0x00CF1,0x00CF2), `Delta (0);
+ (0x00D05,0x00D0C), `Delta (0);
+ (0x00D0E,0x00D10), `Delta (0);
+ (0x00D12,0x00D3A), `Delta (0);
+ (0x00D3D,0x00D3D), `Abs (0x00D3D);
+ (0x00D4E,0x00D4E), `Abs (0x00D4E);
+ (0x00D54,0x00D56), `Delta (0);
+ (0x00D5F,0x00D61), `Delta (0);
+ (0x00D7A,0x00D7F), `Delta (0);
+ (0x00D85,0x00D96), `Delta (0);
+ (0x00D9A,0x00DB1), `Delta (0);
+ (0x00DB3,0x00DBB), `Delta (0);
+ (0x00DBD,0x00DBD), `Abs (0x00DBD);
+ (0x00DC0,0x00DC6), `Delta (0);
+ (0x00E01,0x00E30), `Delta (0);
+ (0x00E32,0x00E33), `Delta (0);
+ (0x00E40,0x00E45), `Delta (0);
+ (0x00E81,0x00E82), `Delta (0);
+ (0x00E84,0x00E84), `Abs (0x00E84);
+ (0x00E87,0x00E88), `Delta (0);
+ (0x00E8A,0x00E8A), `Abs (0x00E8A);
+ (0x00E8D,0x00E8D), `Abs (0x00E8D);
+ (0x00E94,0x00E97), `Delta (0);
+ (0x00E99,0x00E9F), `Delta (0);
+ (0x00EA1,0x00EA3), `Delta (0);
+ (0x00EA5,0x00EA5), `Abs (0x00EA5);
+ (0x00EA7,0x00EA7), `Abs (0x00EA7);
+ (0x00EAA,0x00EAB), `Delta (0);
+ (0x00EAD,0x00EB0), `Delta (0);
+ (0x00EB2,0x00EB3), `Delta (0);
+ (0x00EBD,0x00EBD), `Abs (0x00EBD);
+ (0x00EC0,0x00EC4), `Delta (0);
+ (0x00EDC,0x00EDF), `Delta (0);
+ (0x00F00,0x00F00), `Abs (0x00F00);
+ (0x00F40,0x00F47), `Delta (0);
+ (0x00F49,0x00F6C), `Delta (0);
+ (0x00F88,0x00F8C), `Delta (0);
+ (0x01000,0x0102A), `Delta (0);
+ (0x0103F,0x0103F), `Abs (0x0103F);
+ (0x01050,0x01055), `Delta (0);
+ (0x0105A,0x0105D), `Delta (0);
+ (0x01061,0x01061), `Abs (0x01061);
+ (0x01065,0x01066), `Delta (0);
+ (0x0106E,0x01070), `Delta (0);
+ (0x01075,0x01081), `Delta (0);
+ (0x0108E,0x0108E), `Abs (0x0108E);
+ (0x010D0,0x010FA), `Delta (0);
+ (0x010FD,0x01248), `Delta (0);
+ (0x0124A,0x0124D), `Delta (0);
+ (0x01250,0x01256), `Delta (0);
+ (0x01258,0x01258), `Abs (0x01258);
+ (0x0125A,0x0125D), `Delta (0);
+ (0x01260,0x01288), `Delta (0);
+ (0x0128A,0x0128D), `Delta (0);
+ (0x01290,0x012B0), `Delta (0);
+ (0x012B2,0x012B5), `Delta (0);
+ (0x012B8,0x012BE), `Delta (0);
+ (0x012C0,0x012C0), `Abs (0x012C0);
+ (0x012C2,0x012C5), `Delta (0);
+ (0x012C8,0x012D6), `Delta (0);
+ (0x012D8,0x01310), `Delta (0);
+ (0x01312,0x01315), `Delta (0);
+ (0x01318,0x0135A), `Delta (0);
+ (0x01380,0x0138F), `Delta (0);
+ (0x01401,0x0166C), `Delta (0);
+ (0x0166F,0x0167F), `Delta (0);
+ (0x01681,0x0169A), `Delta (0);
+ (0x016A0,0x016EA), `Delta (0);
+ (0x016F1,0x016F8), `Delta (0);
+ (0x01700,0x0170C), `Delta (0);
+ (0x0170E,0x01711), `Delta (0);
+ (0x01720,0x01731), `Delta (0);
+ (0x01740,0x01751), `Delta (0);
+ (0x01760,0x0176C), `Delta (0);
+ (0x0176E,0x01770), `Delta (0);
+ (0x01780,0x017B3), `Delta (0);
+ (0x017DC,0x017DC), `Abs (0x017DC);
+ (0x01820,0x01842), `Delta (0);
+ (0x01844,0x01877), `Delta (0);
+ (0x01880,0x01884), `Delta (0);
+ (0x01887,0x018A8), `Delta (0);
+ (0x018AA,0x018AA), `Abs (0x018AA);
+ (0x018B0,0x018F5), `Delta (0);
+ (0x01900,0x0191E), `Delta (0);
+ (0x01950,0x0196D), `Delta (0);
+ (0x01970,0x01974), `Delta (0);
+ (0x01980,0x019AB), `Delta (0);
+ (0x019B0,0x019C9), `Delta (0);
+ (0x01A00,0x01A16), `Delta (0);
+ (0x01A20,0x01A54), `Delta (0);
+ (0x01B05,0x01B33), `Delta (0);
+ (0x01B45,0x01B4B), `Delta (0);
+ (0x01B83,0x01BA0), `Delta (0);
+ (0x01BAE,0x01BAF), `Delta (0);
+ (0x01BBA,0x01BE5), `Delta (0);
+ (0x01C00,0x01C23), `Delta (0);
+ (0x01C4D,0x01C4F), `Delta (0);
+ (0x01C5A,0x01C77), `Delta (0);
+ (0x01CE9,0x01CEC), `Delta (0);
+ (0x01CEE,0x01CF1), `Delta (0);
+ (0x01CF5,0x01CF6), `Delta (0);
+ (0x02135,0x02138), `Delta (0);
+ (0x02D30,0x02D67), `Delta (0);
+ (0x02D80,0x02D96), `Delta (0);
+ (0x02DA0,0x02DA6), `Delta (0);
+ (0x02DA8,0x02DAE), `Delta (0);
+ (0x02DB0,0x02DB6), `Delta (0);
+ (0x02DB8,0x02DBE), `Delta (0);
+ (0x02DC0,0x02DC6), `Delta (0);
+ (0x02DC8,0x02DCE), `Delta (0);
+ (0x02DD0,0x02DD6), `Delta (0);
+ (0x02DD8,0x02DDE), `Delta (0);
+ (0x03006,0x03006), `Abs (0x03006);
+ (0x0303C,0x0303C), `Abs (0x0303C);
+ (0x03041,0x03096), `Delta (0);
+ (0x0309F,0x0309F), `Abs (0x0309F);
+ (0x030A1,0x030FA), `Delta (0);
+ (0x030FF,0x030FF), `Abs (0x030FF);
+ (0x03105,0x0312D), `Delta (0);
+ (0x03131,0x0318E), `Delta (0);
+ (0x031A0,0x031BA), `Delta (0);
+ (0x031F0,0x031FF), `Delta (0);
+ (0x03400,0x04DB5), `Delta (0);
+ (0x04E00,0x09FD5), `Delta (0);
+ (0x0A000,0x0A014), `Delta (0);
+ (0x0A016,0x0A48C), `Delta (0);
+ (0x0A4D0,0x0A4F7), `Delta (0);
+ (0x0A500,0x0A60B), `Delta (0);
+ (0x0A610,0x0A61F), `Delta (0);
+ (0x0A62A,0x0A62B), `Delta (0);
+ (0x0A66E,0x0A66E), `Abs (0x0A66E);
+ (0x0A6A0,0x0A6E5), `Delta (0);
+ (0x0A78F,0x0A78F), `Abs (0x0A78F);
+ (0x0A7F7,0x0A7F7), `Abs (0x0A7F7);
+ (0x0A7FB,0x0A801), `Delta (0);
+ (0x0A803,0x0A805), `Delta (0);
+ (0x0A807,0x0A80A), `Delta (0);
+ (0x0A80C,0x0A822), `Delta (0);
+ (0x0A840,0x0A873), `Delta (0);
+ (0x0A882,0x0A8B3), `Delta (0);
+ (0x0A8F2,0x0A8F7), `Delta (0);
+ (0x0A8FB,0x0A8FB), `Abs (0x0A8FB);
+ (0x0A8FD,0x0A8FD), `Abs (0x0A8FD);
+ (0x0A90A,0x0A925), `Delta (0);
+ (0x0A930,0x0A946), `Delta (0);
+ (0x0A960,0x0A97C), `Delta (0);
+ (0x0A984,0x0A9B2), `Delta (0);
+ (0x0A9E0,0x0A9E4), `Delta (0);
+ (0x0A9E7,0x0A9EF), `Delta (0);
+ (0x0A9FA,0x0A9FE), `Delta (0);
+ (0x0AA00,0x0AA28), `Delta (0);
+ (0x0AA40,0x0AA42), `Delta (0);
+ (0x0AA44,0x0AA4B), `Delta (0);
+ (0x0AA60,0x0AA6F), `Delta (0);
+ (0x0AA71,0x0AA76), `Delta (0);
+ (0x0AA7A,0x0AA7A), `Abs (0x0AA7A);
+ (0x0AA7E,0x0AAAF), `Delta (0);
+ (0x0AAB1,0x0AAB1), `Abs (0x0AAB1);
+ (0x0AAB5,0x0AAB6), `Delta (0);
+ (0x0AAB9,0x0AABD), `Delta (0);
+ (0x0AAC0,0x0AAC0), `Abs (0x0AAC0);
+ (0x0AAC2,0x0AAC2), `Abs (0x0AAC2);
+ (0x0AADB,0x0AADC), `Delta (0);
+ (0x0AAE0,0x0AAEA), `Delta (0);
+ (0x0AAF2,0x0AAF2), `Abs (0x0AAF2);
+ (0x0AB01,0x0AB06), `Delta (0);
+ (0x0AB09,0x0AB0E), `Delta (0);
+ (0x0AB11,0x0AB16), `Delta (0);
+ (0x0AB20,0x0AB26), `Delta (0);
+ (0x0AB28,0x0AB2E), `Delta (0);
+ (0x0ABC0,0x0ABE2), `Delta (0);
+ (0x0AC00,0x0D7A3), `Delta (0);
+ (0x0D7B0,0x0D7C6), `Delta (0);
+ (0x0D7CB,0x0D7FB), `Delta (0);
+ (0x0F900,0x0FA6D), `Delta (0);
+ (0x0FA70,0x0FAD9), `Delta (0);
+ (0x0FB1D,0x0FB1D), `Abs (0x0FB1D);
+ (0x0FB1F,0x0FB28), `Delta (0);
+ (0x0FB2A,0x0FB36), `Delta (0);
+ (0x0FB38,0x0FB3C), `Delta (0);
+ (0x0FB3E,0x0FB3E), `Abs (0x0FB3E);
+ (0x0FB40,0x0FB41), `Delta (0);
+ (0x0FB43,0x0FB44), `Delta (0);
+ (0x0FB46,0x0FBB1), `Delta (0);
+ (0x0FBD3,0x0FD3D), `Delta (0);
+ (0x0FD50,0x0FD8F), `Delta (0);
+ (0x0FD92,0x0FDC7), `Delta (0);
+ (0x0FDF0,0x0FDFB), `Delta (0);
+ (0x0FE70,0x0FE74), `Delta (0);
+ (0x0FE76,0x0FEFC), `Delta (0);
+ (0x0FF66,0x0FF6F), `Delta (0);
+ (0x0FF71,0x0FF9D), `Delta (0);
+ (0x0FFA0,0x0FFBE), `Delta (0);
+ (0x0FFC2,0x0FFC7), `Delta (0);
+ (0x0FFCA,0x0FFCF), `Delta (0);
+ (0x0FFD2,0x0FFD7), `Delta (0);
+ (0x0FFDA,0x0FFDC), `Delta (0);
+ (0x10000,0x1000B), `Delta (0);
+ (0x1000D,0x10026), `Delta (0);
+ (0x10028,0x1003A), `Delta (0);
+ (0x1003C,0x1003D), `Delta (0);
+ (0x1003F,0x1004D), `Delta (0);
+ (0x10050,0x1005D), `Delta (0);
+ (0x10080,0x100FA), `Delta (0);
+ (0x10280,0x1029C), `Delta (0);
+ (0x102A0,0x102D0), `Delta (0);
+ (0x10300,0x1031F), `Delta (0);
+ (0x10330,0x10340), `Delta (0);
+ (0x10342,0x10349), `Delta (0);
+ (0x10350,0x10375), `Delta (0);
+ (0x10380,0x1039D), `Delta (0);
+ (0x103A0,0x103C3), `Delta (0);
+ (0x103C8,0x103CF), `Delta (0);
+ (0x10450,0x1049D), `Delta (0);
+ (0x10500,0x10527), `Delta (0);
+ (0x10530,0x10563), `Delta (0);
+ (0x10600,0x10736), `Delta (0);
+ (0x10740,0x10755), `Delta (0);
+ (0x10760,0x10767), `Delta (0);
+ (0x10800,0x10805), `Delta (0);
+ (0x10808,0x10808), `Abs (0x10808);
+ (0x1080A,0x10835), `Delta (0);
+ (0x10837,0x10838), `Delta (0);
+ (0x1083C,0x1083C), `Abs (0x1083C);
+ (0x1083F,0x10855), `Delta (0);
+ (0x10860,0x10876), `Delta (0);
+ (0x10880,0x1089E), `Delta (0);
+ (0x108E0,0x108F2), `Delta (0);
+ (0x108F4,0x108F5), `Delta (0);
+ (0x10900,0x10915), `Delta (0);
+ (0x10920,0x10939), `Delta (0);
+ (0x10980,0x109B7), `Delta (0);
+ (0x109BE,0x109BF), `Delta (0);
+ (0x10A00,0x10A00), `Abs (0x10A00);
+ (0x10A10,0x10A13), `Delta (0);
+ (0x10A15,0x10A17), `Delta (0);
+ (0x10A19,0x10A33), `Delta (0);
+ (0x10A60,0x10A7C), `Delta (0);
+ (0x10A80,0x10A9C), `Delta (0);
+ (0x10AC0,0x10AC7), `Delta (0);
+ (0x10AC9,0x10AE4), `Delta (0);
+ (0x10B00,0x10B35), `Delta (0);
+ (0x10B40,0x10B55), `Delta (0);
+ (0x10B60,0x10B72), `Delta (0);
+ (0x10B80,0x10B91), `Delta (0);
+ (0x10C00,0x10C48), `Delta (0);
+ (0x11003,0x11037), `Delta (0);
+ (0x11083,0x110AF), `Delta (0);
+ (0x110D0,0x110E8), `Delta (0);
+ (0x11103,0x11126), `Delta (0);
+ (0x11150,0x11172), `Delta (0);
+ (0x11176,0x11176), `Abs (0x11176);
+ (0x11183,0x111B2), `Delta (0);
+ (0x111C1,0x111C4), `Delta (0);
+ (0x111DA,0x111DA), `Abs (0x111DA);
+ (0x111DC,0x111DC), `Abs (0x111DC);
+ (0x11200,0x11211), `Delta (0);
+ (0x11213,0x1122B), `Delta (0);
+ (0x11280,0x11286), `Delta (0);
+ (0x11288,0x11288), `Abs (0x11288);
+ (0x1128A,0x1128D), `Delta (0);
+ (0x1128F,0x1129D), `Delta (0);
+ (0x1129F,0x112A8), `Delta (0);
+ (0x112B0,0x112DE), `Delta (0);
+ (0x11305,0x1130C), `Delta (0);
+ (0x1130F,0x11310), `Delta (0);
+ (0x11313,0x11328), `Delta (0);
+ (0x1132A,0x11330), `Delta (0);
+ (0x11332,0x11333), `Delta (0);
+ (0x11335,0x11339), `Delta (0);
+ (0x1133D,0x1133D), `Abs (0x1133D);
+ (0x11350,0x11350), `Abs (0x11350);
+ (0x1135D,0x11361), `Delta (0);
+ (0x11400,0x11434), `Delta (0);
+ (0x11447,0x1144A), `Delta (0);
+ (0x11480,0x114AF), `Delta (0);
+ (0x114C4,0x114C5), `Delta (0);
+ (0x114C7,0x114C7), `Abs (0x114C7);
+ (0x11580,0x115AE), `Delta (0);
+ (0x115D8,0x115DB), `Delta (0);
+ (0x11600,0x1162F), `Delta (0);
+ (0x11644,0x11644), `Abs (0x11644);
+ (0x11680,0x116AA), `Delta (0);
+ (0x11700,0x11719), `Delta (0);
+ (0x118FF,0x118FF), `Abs (0x118FF);
+ (0x11AC0,0x11AF8), `Delta (0);
+ (0x11C00,0x11C08), `Delta (0);
+ (0x11C0A,0x11C2E), `Delta (0);
+ (0x11C40,0x11C40), `Abs (0x11C40);
+ (0x11C72,0x11C8F), `Delta (0);
+ (0x12000,0x12399), `Delta (0);
+ (0x12480,0x12543), `Delta (0);
+ (0x13000,0x1342E), `Delta (0);
+ (0x14400,0x14646), `Delta (0);
+ (0x16800,0x16A38), `Delta (0);
+ (0x16A40,0x16A5E), `Delta (0);
+ (0x16AD0,0x16AED), `Delta (0);
+ (0x16B00,0x16B2F), `Delta (0);
+ (0x16B63,0x16B77), `Delta (0);
+ (0x16B7D,0x16B8F), `Delta (0);
+ (0x16F00,0x16F44), `Delta (0);
+ (0x16F50,0x16F50), `Abs (0x16F50);
+ (0x17000,0x187EC), `Delta (0);
+ (0x18800,0x18AF2), `Delta (0);
+ (0x1B000,0x1B001), `Delta (0);
+ (0x1BC00,0x1BC6A), `Delta (0);
+ (0x1BC70,0x1BC7C), `Delta (0);
+ (0x1BC80,0x1BC88), `Delta (0);
+ (0x1BC90,0x1BC99), `Delta (0);
+ (0x1E800,0x1E8C4), `Delta (0);
+ (0x1EE00,0x1EE03), `Delta (0);
+ (0x1EE05,0x1EE1F), `Delta (0);
+ (0x1EE21,0x1EE22), `Delta (0);
+ (0x1EE24,0x1EE24), `Abs (0x1EE24);
+ (0x1EE27,0x1EE27), `Abs (0x1EE27);
+ (0x1EE29,0x1EE32), `Delta (0);
+ (0x1EE34,0x1EE37), `Delta (0);
+ (0x1EE39,0x1EE39), `Abs (0x1EE39);
+ (0x1EE3B,0x1EE3B), `Abs (0x1EE3B);
+ (0x1EE42,0x1EE42), `Abs (0x1EE42);
+ (0x1EE47,0x1EE47), `Abs (0x1EE47);
+ (0x1EE49,0x1EE49), `Abs (0x1EE49);
+ (0x1EE4B,0x1EE4B), `Abs (0x1EE4B);
+ (0x1EE4D,0x1EE4F), `Delta (0);
+ (0x1EE51,0x1EE52), `Delta (0);
+ (0x1EE54,0x1EE54), `Abs (0x1EE54);
+ (0x1EE57,0x1EE57), `Abs (0x1EE57);
+ (0x1EE59,0x1EE59), `Abs (0x1EE59);
+ (0x1EE5B,0x1EE5B), `Abs (0x1EE5B);
+ (0x1EE5D,0x1EE5D), `Abs (0x1EE5D);
+ (0x1EE5F,0x1EE5F), `Abs (0x1EE5F);
+ (0x1EE61,0x1EE62), `Delta (0);
+ (0x1EE64,0x1EE64), `Abs (0x1EE64);
+ (0x1EE67,0x1EE6A), `Delta (0);
+ (0x1EE6C,0x1EE72), `Delta (0);
+ (0x1EE74,0x1EE77), `Delta (0);
+ (0x1EE79,0x1EE7C), `Delta (0);
+ (0x1EE7E,0x1EE7E), `Abs (0x1EE7E);
+ (0x1EE80,0x1EE89), `Delta (0);
+ (0x1EE8B,0x1EE9B), `Delta (0);
+ (0x1EEA1,0x1EEA3), `Delta (0);
+ (0x1EEA5,0x1EEA9), `Delta (0);
+ (0x1EEAB,0x1EEBB), `Delta (0);
+ (0x20000,0x2A6D6), `Delta (0);
+ (0x2A700,0x2B734), `Delta (0);
+ (0x2B740,0x2B81D), `Delta (0);
+ (0x2B820,0x2CEA1), `Delta (0);
+ (0x2F800,0x2FA1D), `Delta (0);
+ (0x0005F,0x0005F), `Abs (0x0005F);
+ (0x0203F,0x02040), `Delta (0);
+ (0x02054,0x02054), `Abs (0x02054);
+ (0x0FE33,0x0FE34), `Delta (0);
+ (0x0FE4D,0x0FE4F), `Delta (0);
+ (0x0FF3F,0x0FF3F), `Abs (0x0FF3F);
+ (0x0002D,0x0002D), `Abs (0x0002D);
+ (0x0058A,0x0058A), `Abs (0x0058A);
+ (0x005BE,0x005BE), `Abs (0x005BE);
+ (0x01400,0x01400), `Abs (0x01400);
+ (0x01806,0x01806), `Abs (0x01806);
+ (0x02010,0x02015), `Delta (0);
+ (0x02E17,0x02E17), `Abs (0x02E17);
+ (0x02E1A,0x02E1A), `Abs (0x02E1A);
+ (0x02E3A,0x02E3B), `Delta (0);
+ (0x02E40,0x02E40), `Abs (0x02E40);
+ (0x0301C,0x0301C), `Abs (0x0301C);
+ (0x03030,0x03030), `Abs (0x03030);
+ (0x030A0,0x030A0), `Abs (0x030A0);
+ (0x0FE31,0x0FE32), `Delta (0);
+ (0x0FE58,0x0FE58), `Abs (0x0FE58);
+ (0x0FE63,0x0FE63), `Abs (0x0FE63);
+ (0x0FF0D,0x0FF0D), `Abs (0x0FF0D);
+ (0x00028,0x00028), `Abs (0x00028);
+ (0x0005B,0x0005B), `Abs (0x0005B);
+ (0x0007B,0x0007B), `Abs (0x0007B);
+ (0x00F3A,0x00F3A), `Abs (0x00F3A);
+ (0x00F3C,0x00F3C), `Abs (0x00F3C);
+ (0x0169B,0x0169B), `Abs (0x0169B);
+ (0x0201A,0x0201A), `Abs (0x0201A);
+ (0x0201E,0x0201E), `Abs (0x0201E);
+ (0x02045,0x02045), `Abs (0x02045);
+ (0x0207D,0x0207D), `Abs (0x0207D);
+ (0x0208D,0x0208D), `Abs (0x0208D);
+ (0x02308,0x02308), `Abs (0x02308);
+ (0x0230A,0x0230A), `Abs (0x0230A);
+ (0x02329,0x02329), `Abs (0x02329);
+ (0x02768,0x02768), `Abs (0x02768);
+ (0x0276A,0x0276A), `Abs (0x0276A);
+ (0x0276C,0x0276C), `Abs (0x0276C);
+ (0x0276E,0x0276E), `Abs (0x0276E);
+ (0x02770,0x02770), `Abs (0x02770);
+ (0x02772,0x02772), `Abs (0x02772);
+ (0x02774,0x02774), `Abs (0x02774);
+ (0x027C5,0x027C5), `Abs (0x027C5);
+ (0x027E6,0x027E6), `Abs (0x027E6);
+ (0x027E8,0x027E8), `Abs (0x027E8);
+ (0x027EA,0x027EA), `Abs (0x027EA);
+ (0x027EC,0x027EC), `Abs (0x027EC);
+ (0x027EE,0x027EE), `Abs (0x027EE);
+ (0x02983,0x02983), `Abs (0x02983);
+ (0x02985,0x02985), `Abs (0x02985);
+ (0x02987,0x02987), `Abs (0x02987);
+ (0x02989,0x02989), `Abs (0x02989);
+ (0x0298B,0x0298B), `Abs (0x0298B);
+ (0x0298D,0x0298D), `Abs (0x0298D);
+ (0x0298F,0x0298F), `Abs (0x0298F);
+ (0x02991,0x02991), `Abs (0x02991);
+ (0x02993,0x02993), `Abs (0x02993);
+ (0x02995,0x02995), `Abs (0x02995);
+ (0x02997,0x02997), `Abs (0x02997);
+ (0x029D8,0x029D8), `Abs (0x029D8);
+ (0x029DA,0x029DA), `Abs (0x029DA);
+ (0x029FC,0x029FC), `Abs (0x029FC);
+ (0x02E22,0x02E22), `Abs (0x02E22);
+ (0x02E24,0x02E24), `Abs (0x02E24);
+ (0x02E26,0x02E26), `Abs (0x02E26);
+ (0x02E28,0x02E28), `Abs (0x02E28);
+ (0x02E42,0x02E42), `Abs (0x02E42);
+ (0x03008,0x03008), `Abs (0x03008);
+ (0x0300A,0x0300A), `Abs (0x0300A);
+ (0x0300C,0x0300C), `Abs (0x0300C);
+ (0x0300E,0x0300E), `Abs (0x0300E);
+ (0x03010,0x03010), `Abs (0x03010);
+ (0x03014,0x03014), `Abs (0x03014);
+ (0x03016,0x03016), `Abs (0x03016);
+ (0x03018,0x03018), `Abs (0x03018);
+ (0x0301A,0x0301A), `Abs (0x0301A);
+ (0x0301D,0x0301D), `Abs (0x0301D);
+ (0x0FD3F,0x0FD3F), `Abs (0x0FD3F);
+ (0x0FE17,0x0FE17), `Abs (0x0FE17);
+ (0x0FE35,0x0FE35), `Abs (0x0FE35);
+ (0x0FE37,0x0FE37), `Abs (0x0FE37);
+ (0x0FE39,0x0FE39), `Abs (0x0FE39);
+ (0x0FE3B,0x0FE3B), `Abs (0x0FE3B);
+ (0x0FE3D,0x0FE3D), `Abs (0x0FE3D);
+ (0x0FE3F,0x0FE3F), `Abs (0x0FE3F);
+ (0x0FE41,0x0FE41), `Abs (0x0FE41);
+ (0x0FE43,0x0FE43), `Abs (0x0FE43);
+ (0x0FE47,0x0FE47), `Abs (0x0FE47);
+ (0x0FE59,0x0FE59), `Abs (0x0FE59);
+ (0x0FE5B,0x0FE5B), `Abs (0x0FE5B);
+ (0x0FE5D,0x0FE5D), `Abs (0x0FE5D);
+ (0x0FF08,0x0FF08), `Abs (0x0FF08);
+ (0x0FF3B,0x0FF3B), `Abs (0x0FF3B);
+ (0x0FF5B,0x0FF5B), `Abs (0x0FF5B);
+ (0x0FF5F,0x0FF5F), `Abs (0x0FF5F);
+ (0x0FF62,0x0FF62), `Abs (0x0FF62);
+ (0x00029,0x00029), `Abs (0x00029);
+ (0x0005D,0x0005D), `Abs (0x0005D);
+ (0x0007D,0x0007D), `Abs (0x0007D);
+ (0x00F3B,0x00F3B), `Abs (0x00F3B);
+ (0x00F3D,0x00F3D), `Abs (0x00F3D);
+ (0x0169C,0x0169C), `Abs (0x0169C);
+ (0x02046,0x02046), `Abs (0x02046);
+ (0x0207E,0x0207E), `Abs (0x0207E);
+ (0x0208E,0x0208E), `Abs (0x0208E);
+ (0x02309,0x02309), `Abs (0x02309);
+ (0x0230B,0x0230B), `Abs (0x0230B);
+ (0x0232A,0x0232A), `Abs (0x0232A);
+ (0x02769,0x02769), `Abs (0x02769);
+ (0x0276B,0x0276B), `Abs (0x0276B);
+ (0x0276D,0x0276D), `Abs (0x0276D);
+ (0x0276F,0x0276F), `Abs (0x0276F);
+ (0x02771,0x02771), `Abs (0x02771);
+ (0x02773,0x02773), `Abs (0x02773);
+ (0x02775,0x02775), `Abs (0x02775);
+ (0x027C6,0x027C6), `Abs (0x027C6);
+ (0x027E7,0x027E7), `Abs (0x027E7);
+ (0x027E9,0x027E9), `Abs (0x027E9);
+ (0x027EB,0x027EB), `Abs (0x027EB);
+ (0x027ED,0x027ED), `Abs (0x027ED);
+ (0x027EF,0x027EF), `Abs (0x027EF);
+ (0x02984,0x02984), `Abs (0x02984);
+ (0x02986,0x02986), `Abs (0x02986);
+ (0x02988,0x02988), `Abs (0x02988);
+ (0x0298A,0x0298A), `Abs (0x0298A);
+ (0x0298C,0x0298C), `Abs (0x0298C);
+ (0x0298E,0x0298E), `Abs (0x0298E);
+ (0x02990,0x02990), `Abs (0x02990);
+ (0x02992,0x02992), `Abs (0x02992);
+ (0x02994,0x02994), `Abs (0x02994);
+ (0x02996,0x02996), `Abs (0x02996);
+ (0x02998,0x02998), `Abs (0x02998);
+ (0x029D9,0x029D9), `Abs (0x029D9);
+ (0x029DB,0x029DB), `Abs (0x029DB);
+ (0x029FD,0x029FD), `Abs (0x029FD);
+ (0x02E23,0x02E23), `Abs (0x02E23);
+ (0x02E25,0x02E25), `Abs (0x02E25);
+ (0x02E27,0x02E27), `Abs (0x02E27);
+ (0x02E29,0x02E29), `Abs (0x02E29);
+ (0x03009,0x03009), `Abs (0x03009);
+ (0x0300B,0x0300B), `Abs (0x0300B);
+ (0x0300D,0x0300D), `Abs (0x0300D);
+ (0x0300F,0x0300F), `Abs (0x0300F);
+ (0x03011,0x03011), `Abs (0x03011);
+ (0x03015,0x03015), `Abs (0x03015);
+ (0x03017,0x03017), `Abs (0x03017);
+ (0x03019,0x03019), `Abs (0x03019);
+ (0x0301B,0x0301B), `Abs (0x0301B);
+ (0x0301E,0x0301F), `Delta (0);
+ (0x0FD3E,0x0FD3E), `Abs (0x0FD3E);
+ (0x0FE18,0x0FE18), `Abs (0x0FE18);
+ (0x0FE36,0x0FE36), `Abs (0x0FE36);
+ (0x0FE38,0x0FE38), `Abs (0x0FE38);
+ (0x0FE3A,0x0FE3A), `Abs (0x0FE3A);
+ (0x0FE3C,0x0FE3C), `Abs (0x0FE3C);
+ (0x0FE3E,0x0FE3E), `Abs (0x0FE3E);
+ (0x0FE40,0x0FE40), `Abs (0x0FE40);
+ (0x0FE42,0x0FE42), `Abs (0x0FE42);
+ (0x0FE44,0x0FE44), `Abs (0x0FE44);
+ (0x0FE48,0x0FE48), `Abs (0x0FE48);
+ (0x0FE5A,0x0FE5A), `Abs (0x0FE5A);
+ (0x0FE5C,0x0FE5C), `Abs (0x0FE5C);
+ (0x0FE5E,0x0FE5E), `Abs (0x0FE5E);
+ (0x0FF09,0x0FF09), `Abs (0x0FF09);
+ (0x0FF3D,0x0FF3D), `Abs (0x0FF3D);
+ (0x0FF5D,0x0FF5D), `Abs (0x0FF5D);
+ (0x0FF60,0x0FF60), `Abs (0x0FF60);
+ (0x0FF63,0x0FF63), `Abs (0x0FF63);
+ (0x000AB,0x000AB), `Abs (0x000AB);
+ (0x02018,0x02018), `Abs (0x02018);
+ (0x0201B,0x0201C), `Delta (0);
+ (0x0201F,0x0201F), `Abs (0x0201F);
+ (0x02039,0x02039), `Abs (0x02039);
+ (0x02E02,0x02E02), `Abs (0x02E02);
+ (0x02E04,0x02E04), `Abs (0x02E04);
+ (0x02E09,0x02E09), `Abs (0x02E09);
+ (0x02E0C,0x02E0C), `Abs (0x02E0C);
+ (0x02E1C,0x02E1C), `Abs (0x02E1C);
+ (0x02E20,0x02E20), `Abs (0x02E20);
+ (0x000BB,0x000BB), `Abs (0x000BB);
+ (0x02019,0x02019), `Abs (0x02019);
+ (0x0201D,0x0201D), `Abs (0x0201D);
+ (0x0203A,0x0203A), `Abs (0x0203A);
+ (0x02E03,0x02E03), `Abs (0x02E03);
+ (0x02E05,0x02E05), `Abs (0x02E05);
+ (0x02E0A,0x02E0A), `Abs (0x02E0A);
+ (0x02E0D,0x02E0D), `Abs (0x02E0D);
+ (0x02E1D,0x02E1D), `Abs (0x02E1D);
+ (0x02E21,0x02E21), `Abs (0x02E21);
+ (0x00021,0x00023), `Delta (0);
+ (0x00025,0x00027), `Delta (0);
+ (0x0002A,0x0002A), `Abs (0x0002A);
+ (0x0002C,0x0002C), `Abs (0x0002C);
+ (0x0002E,0x0002F), `Delta (0);
+ (0x0003A,0x0003B), `Delta (0);
+ (0x0003F,0x00040), `Delta (0);
+ (0x0005C,0x0005C), `Abs (0x0005C);
+ (0x000A1,0x000A1), `Abs (0x000A1);
+ (0x000A7,0x000A7), `Abs (0x000A7);
+ (0x000B6,0x000B7), `Delta (0);
+ (0x000BF,0x000BF), `Abs (0x000BF);
+ (0x0037E,0x0037E), `Abs (0x0037E);
+ (0x00387,0x00387), `Abs (0x00387);
+ (0x0055A,0x0055F), `Delta (0);
+ (0x00589,0x00589), `Abs (0x00589);
+ (0x005C0,0x005C0), `Abs (0x005C0);
+ (0x005C3,0x005C3), `Abs (0x005C3);
+ (0x005C6,0x005C6), `Abs (0x005C6);
+ (0x005F3,0x005F4), `Delta (0);
+ (0x00609,0x0060A), `Delta (0);
+ (0x0060C,0x0060D), `Delta (0);
+ (0x0061B,0x0061B), `Abs (0x0061B);
+ (0x0061E,0x0061F), `Delta (0);
+ (0x0066A,0x0066D), `Delta (0);
+ (0x006D4,0x006D4), `Abs (0x006D4);
+ (0x00700,0x0070D), `Delta (0);
+ (0x007F7,0x007F9), `Delta (0);
+ (0x00830,0x0083E), `Delta (0);
+ (0x0085E,0x0085E), `Abs (0x0085E);
+ (0x00964,0x00965), `Delta (0);
+ (0x00970,0x00970), `Abs (0x00970);
+ (0x00AF0,0x00AF0), `Abs (0x00AF0);
+ (0x00DF4,0x00DF4), `Abs (0x00DF4);
+ (0x00E4F,0x00E4F), `Abs (0x00E4F);
+ (0x00E5A,0x00E5B), `Delta (0);
+ (0x00F04,0x00F12), `Delta (0);
+ (0x00F14,0x00F14), `Abs (0x00F14);
+ (0x00F85,0x00F85), `Abs (0x00F85);
+ (0x00FD0,0x00FD4), `Delta (0);
+ (0x00FD9,0x00FDA), `Delta (0);
+ (0x0104A,0x0104F), `Delta (0);
+ (0x010FB,0x010FB), `Abs (0x010FB);
+ (0x01360,0x01368), `Delta (0);
+ (0x0166D,0x0166E), `Delta (0);
+ (0x016EB,0x016ED), `Delta (0);
+ (0x01735,0x01736), `Delta (0);
+ (0x017D4,0x017D6), `Delta (0);
+ (0x017D8,0x017DA), `Delta (0);
+ (0x01800,0x01805), `Delta (0);
+ (0x01807,0x0180A), `Delta (0);
+ (0x01944,0x01945), `Delta (0);
+ (0x01A1E,0x01A1F), `Delta (0);
+ (0x01AA0,0x01AA6), `Delta (0);
+ (0x01AA8,0x01AAD), `Delta (0);
+ (0x01B5A,0x01B60), `Delta (0);
+ (0x01BFC,0x01BFF), `Delta (0);
+ (0x01C3B,0x01C3F), `Delta (0);
+ (0x01C7E,0x01C7F), `Delta (0);
+ (0x01CC0,0x01CC7), `Delta (0);
+ (0x01CD3,0x01CD3), `Abs (0x01CD3);
+ (0x02016,0x02017), `Delta (0);
+ (0x02020,0x02027), `Delta (0);
+ (0x02030,0x02038), `Delta (0);
+ (0x0203B,0x0203E), `Delta (0);
+ (0x02041,0x02043), `Delta (0);
+ (0x02047,0x02051), `Delta (0);
+ (0x02053,0x02053), `Abs (0x02053);
+ (0x02055,0x0205E), `Delta (0);
+ (0x02CF9,0x02CFC), `Delta (0);
+ (0x02CFE,0x02CFF), `Delta (0);
+ (0x02D70,0x02D70), `Abs (0x02D70);
+ (0x02E00,0x02E01), `Delta (0);
+ (0x02E06,0x02E08), `Delta (0);
+ (0x02E0B,0x02E0B), `Abs (0x02E0B);
+ (0x02E0E,0x02E16), `Delta (0);
+ (0x02E18,0x02E19), `Delta (0);
+ (0x02E1B,0x02E1B), `Abs (0x02E1B);
+ (0x02E1E,0x02E1F), `Delta (0);
+ (0x02E2A,0x02E2E), `Delta (0);
+ (0x02E30,0x02E39), `Delta (0);
+ (0x02E3C,0x02E3F), `Delta (0);
+ (0x02E41,0x02E41), `Abs (0x02E41);
+ (0x02E43,0x02E44), `Delta (0);
+ (0x03001,0x03003), `Delta (0);
+ (0x0303D,0x0303D), `Abs (0x0303D);
+ (0x030FB,0x030FB), `Abs (0x030FB);
+ (0x0A4FE,0x0A4FF), `Delta (0);
+ (0x0A60D,0x0A60F), `Delta (0);
+ (0x0A673,0x0A673), `Abs (0x0A673);
+ (0x0A67E,0x0A67E), `Abs (0x0A67E);
+ (0x0A6F2,0x0A6F7), `Delta (0);
+ (0x0A874,0x0A877), `Delta (0);
+ (0x0A8CE,0x0A8CF), `Delta (0);
+ (0x0A8F8,0x0A8FA), `Delta (0);
+ (0x0A8FC,0x0A8FC), `Abs (0x0A8FC);
+ (0x0A92E,0x0A92F), `Delta (0);
+ (0x0A95F,0x0A95F), `Abs (0x0A95F);
+ (0x0A9C1,0x0A9CD), `Delta (0);
+ (0x0A9DE,0x0A9DF), `Delta (0);
+ (0x0AA5C,0x0AA5F), `Delta (0);
+ (0x0AADE,0x0AADF), `Delta (0);
+ (0x0AAF0,0x0AAF1), `Delta (0);
+ (0x0ABEB,0x0ABEB), `Abs (0x0ABEB);
+ (0x0FE10,0x0FE16), `Delta (0);
+ (0x0FE19,0x0FE19), `Abs (0x0FE19);
+ (0x0FE30,0x0FE30), `Abs (0x0FE30);
+ (0x0FE45,0x0FE46), `Delta (0);
+ (0x0FE49,0x0FE4C), `Delta (0);
+ (0x0FE50,0x0FE52), `Delta (0);
+ (0x0FE54,0x0FE57), `Delta (0);
+ (0x0FE5F,0x0FE61), `Delta (0);
+ (0x0FE68,0x0FE68), `Abs (0x0FE68);
+ (0x0FE6A,0x0FE6B), `Delta (0);
+ (0x0FF01,0x0FF03), `Delta (0);
+ (0x0FF05,0x0FF07), `Delta (0);
+ (0x0FF0A,0x0FF0A), `Abs (0x0FF0A);
+ (0x0FF0C,0x0FF0C), `Abs (0x0FF0C);
+ (0x0FF0E,0x0FF0F), `Delta (0);
+ (0x0FF1A,0x0FF1B), `Delta (0);
+ (0x0FF1F,0x0FF20), `Delta (0);
+ (0x0FF3C,0x0FF3C), `Abs (0x0FF3C);
+ (0x0FF61,0x0FF61), `Abs (0x0FF61);
+ (0x0FF64,0x0FF65), `Delta (0);
+ (0x10100,0x10102), `Delta (0);
+ (0x1039F,0x1039F), `Abs (0x1039F);
+ (0x103D0,0x103D0), `Abs (0x103D0);
+ (0x1056F,0x1056F), `Abs (0x1056F);
+ (0x10857,0x10857), `Abs (0x10857);
+ (0x1091F,0x1091F), `Abs (0x1091F);
+ (0x1093F,0x1093F), `Abs (0x1093F);
+ (0x10A50,0x10A58), `Delta (0);
+ (0x10A7F,0x10A7F), `Abs (0x10A7F);
+ (0x10AF0,0x10AF6), `Delta (0);
+ (0x10B39,0x10B3F), `Delta (0);
+ (0x10B99,0x10B9C), `Delta (0);
+ (0x11047,0x1104D), `Delta (0);
+ (0x110BB,0x110BC), `Delta (0);
+ (0x110BE,0x110C1), `Delta (0);
+ (0x11140,0x11143), `Delta (0);
+ (0x11174,0x11175), `Delta (0);
+ (0x111C5,0x111C9), `Delta (0);
+ (0x111CD,0x111CD), `Abs (0x111CD);
+ (0x111DB,0x111DB), `Abs (0x111DB);
+ (0x111DD,0x111DF), `Delta (0);
+ (0x11238,0x1123D), `Delta (0);
+ (0x112A9,0x112A9), `Abs (0x112A9);
+ (0x1144B,0x1144F), `Delta (0);
+ (0x1145B,0x1145B), `Abs (0x1145B);
+ (0x1145D,0x1145D), `Abs (0x1145D);
+ (0x114C6,0x114C6), `Abs (0x114C6);
+ (0x115C1,0x115D7), `Delta (0);
+ (0x11641,0x11643), `Delta (0);
+ (0x11660,0x1166C), `Delta (0);
+ (0x1173C,0x1173E), `Delta (0);
+ (0x11C41,0x11C45), `Delta (0);
+ (0x11C70,0x11C71), `Delta (0);
+ (0x12470,0x12474), `Delta (0);
+ (0x16A6E,0x16A6F), `Delta (0);
+ (0x16AF5,0x16AF5), `Abs (0x16AF5);
+ (0x16B37,0x16B3B), `Delta (0);
+ (0x16B44,0x16B44), `Abs (0x16B44);
+ (0x1BC9F,0x1BC9F), `Abs (0x1BC9F);
+ (0x1DA87,0x1DA8B), `Delta (0);
+ (0x1E95E,0x1E95F), `Delta (0);
+ (0x0002B,0x0002B), `Abs (0x0002B);
+ (0x0003C,0x0003E), `Delta (0);
+ (0x0007C,0x0007C), `Abs (0x0007C);
+ (0x0007E,0x0007E), `Abs (0x0007E);
+ (0x000AC,0x000AC), `Abs (0x000AC);
+ (0x000B1,0x000B1), `Abs (0x000B1);
+ (0x000D7,0x000D7), `Abs (0x000D7);
+ (0x000F7,0x000F7), `Abs (0x000F7);
+ (0x003F6,0x003F6), `Abs (0x003F6);
+ (0x00606,0x00608), `Delta (0);
+ (0x02044,0x02044), `Abs (0x02044);
+ (0x02052,0x02052), `Abs (0x02052);
+ (0x0207A,0x0207C), `Delta (0);
+ (0x0208A,0x0208C), `Delta (0);
+ (0x02118,0x02118), `Abs (0x02118);
+ (0x02140,0x02144), `Delta (0);
+ (0x0214B,0x0214B), `Abs (0x0214B);
+ (0x02190,0x02194), `Delta (0);
+ (0x0219A,0x0219B), `Delta (0);
+ (0x021A0,0x021A0), `Abs (0x021A0);
+ (0x021A3,0x021A3), `Abs (0x021A3);
+ (0x021A6,0x021A6), `Abs (0x021A6);
+ (0x021AE,0x021AE), `Abs (0x021AE);
+ (0x021CE,0x021CF), `Delta (0);
+ (0x021D2,0x021D2), `Abs (0x021D2);
+ (0x021D4,0x021D4), `Abs (0x021D4);
+ (0x021F4,0x022FF), `Delta (0);
+ (0x02320,0x02321), `Delta (0);
+ (0x0237C,0x0237C), `Abs (0x0237C);
+ (0x0239B,0x023B3), `Delta (0);
+ (0x023DC,0x023E1), `Delta (0);
+ (0x025B7,0x025B7), `Abs (0x025B7);
+ (0x025C1,0x025C1), `Abs (0x025C1);
+ (0x025F8,0x025FF), `Delta (0);
+ (0x0266F,0x0266F), `Abs (0x0266F);
+ (0x027C0,0x027C4), `Delta (0);
+ (0x027C7,0x027E5), `Delta (0);
+ (0x027F0,0x027FF), `Delta (0);
+ (0x02900,0x02982), `Delta (0);
+ (0x02999,0x029D7), `Delta (0);
+ (0x029DC,0x029FB), `Delta (0);
+ (0x029FE,0x02AFF), `Delta (0);
+ (0x02B30,0x02B44), `Delta (0);
+ (0x02B47,0x02B4C), `Delta (0);
+ (0x0FB29,0x0FB29), `Abs (0x0FB29);
+ (0x0FE62,0x0FE62), `Abs (0x0FE62);
+ (0x0FE64,0x0FE66), `Delta (0);
+ (0x0FF0B,0x0FF0B), `Abs (0x0FF0B);
+ (0x0FF1C,0x0FF1E), `Delta (0);
+ (0x0FF5C,0x0FF5C), `Abs (0x0FF5C);
+ (0x0FF5E,0x0FF5E), `Abs (0x0FF5E);
+ (0x0FFE2,0x0FFE2), `Abs (0x0FFE2);
+ (0x0FFE9,0x0FFEC), `Delta (0);
+ (0x1D6C1,0x1D6C1), `Abs (0x1D6C1);
+ (0x1D6DB,0x1D6DB), `Abs (0x1D6DB);
+ (0x1D6FB,0x1D6FB), `Abs (0x1D6FB);
+ (0x1D715,0x1D715), `Abs (0x1D715);
+ (0x1D735,0x1D735), `Abs (0x1D735);
+ (0x1D74F,0x1D74F), `Abs (0x1D74F);
+ (0x1D76F,0x1D76F), `Abs (0x1D76F);
+ (0x1D789,0x1D789), `Abs (0x1D789);
+ (0x1D7A9,0x1D7A9), `Abs (0x1D7A9);
+ (0x1D7C3,0x1D7C3), `Abs (0x1D7C3);
+ (0x1EEF0,0x1EEF1), `Delta (0);
+ (0x00024,0x00024), `Abs (0x00024);
+ (0x000A2,0x000A5), `Delta (0);
+ (0x0058F,0x0058F), `Abs (0x0058F);
+ (0x0060B,0x0060B), `Abs (0x0060B);
+ (0x009F2,0x009F3), `Delta (0);
+ (0x009FB,0x009FB), `Abs (0x009FB);
+ (0x00AF1,0x00AF1), `Abs (0x00AF1);
+ (0x00BF9,0x00BF9), `Abs (0x00BF9);
+ (0x00E3F,0x00E3F), `Abs (0x00E3F);
+ (0x017DB,0x017DB), `Abs (0x017DB);
+ (0x020A0,0x020BE), `Delta (0);
+ (0x0A838,0x0A838), `Abs (0x0A838);
+ (0x0FDFC,0x0FDFC), `Abs (0x0FDFC);
+ (0x0FE69,0x0FE69), `Abs (0x0FE69);
+ (0x0FF04,0x0FF04), `Abs (0x0FF04);
+ (0x0FFE0,0x0FFE1), `Delta (0);
+ (0x0FFE5,0x0FFE6), `Delta (0);
+ (0x0005E,0x0005E), `Abs (0x0005E);
+ (0x00060,0x00060), `Abs (0x00060);
+ (0x000A8,0x000A8), `Abs (0x000A8);
+ (0x000AF,0x000AF), `Abs (0x000AF);
+ (0x000B4,0x000B4), `Abs (0x000B4);
+ (0x000B8,0x000B8), `Abs (0x000B8);
+ (0x002C2,0x002C5), `Delta (0);
+ (0x002D2,0x002DF), `Delta (0);
+ (0x002E5,0x002EB), `Delta (0);
+ (0x002ED,0x002ED), `Abs (0x002ED);
+ (0x002EF,0x002FF), `Delta (0);
+ (0x00375,0x00375), `Abs (0x00375);
+ (0x00384,0x00385), `Delta (0);
+ (0x01FBD,0x01FBD), `Abs (0x01FBD);
+ (0x01FBF,0x01FC1), `Delta (0);
+ (0x01FCD,0x01FCF), `Delta (0);
+ (0x01FDD,0x01FDF), `Delta (0);
+ (0x01FED,0x01FEF), `Delta (0);
+ (0x01FFD,0x01FFE), `Delta (0);
+ (0x0309B,0x0309C), `Delta (0);
+ (0x0A700,0x0A716), `Delta (0);
+ (0x0A720,0x0A721), `Delta (0);
+ (0x0A789,0x0A78A), `Delta (0);
+ (0x0AB5B,0x0AB5B), `Abs (0x0AB5B);
+ (0x0FBB2,0x0FBC1), `Delta (0);
+ (0x0FF3E,0x0FF3E), `Abs (0x0FF3E);
+ (0x0FF40,0x0FF40), `Abs (0x0FF40);
+ (0x0FFE3,0x0FFE3), `Abs (0x0FFE3);
+ (0x1F3FB,0x1F3FF), `Delta (0);
+ (0x000A6,0x000A6), `Abs (0x000A6);
+ (0x000A9,0x000A9), `Abs (0x000A9);
+ (0x000AE,0x000AE), `Abs (0x000AE);
+ (0x000B0,0x000B0), `Abs (0x000B0);
+ (0x00482,0x00482), `Abs (0x00482);
+ (0x0058D,0x0058E), `Delta (0);
+ (0x0060E,0x0060F), `Delta (0);
+ (0x006DE,0x006DE), `Abs (0x006DE);
+ (0x006E9,0x006E9), `Abs (0x006E9);
+ (0x006FD,0x006FE), `Delta (0);
+ (0x007F6,0x007F6), `Abs (0x007F6);
+ (0x009FA,0x009FA), `Abs (0x009FA);
+ (0x00B70,0x00B70), `Abs (0x00B70);
+ (0x00BF3,0x00BF8), `Delta (0);
+ (0x00BFA,0x00BFA), `Abs (0x00BFA);
+ (0x00C7F,0x00C7F), `Abs (0x00C7F);
+ (0x00D4F,0x00D4F), `Abs (0x00D4F);
+ (0x00D79,0x00D79), `Abs (0x00D79);
+ (0x00F01,0x00F03), `Delta (0);
+ (0x00F13,0x00F13), `Abs (0x00F13);
+ (0x00F15,0x00F17), `Delta (0);
+ (0x00F1A,0x00F1F), `Delta (0);
+ (0x00F34,0x00F34), `Abs (0x00F34);
+ (0x00F36,0x00F36), `Abs (0x00F36);
+ (0x00F38,0x00F38), `Abs (0x00F38);
+ (0x00FBE,0x00FC5), `Delta (0);
+ (0x00FC7,0x00FCC), `Delta (0);
+ (0x00FCE,0x00FCF), `Delta (0);
+ (0x00FD5,0x00FD8), `Delta (0);
+ (0x0109E,0x0109F), `Delta (0);
+ (0x01390,0x01399), `Delta (0);
+ (0x01940,0x01940), `Abs (0x01940);
+ (0x019DE,0x019FF), `Delta (0);
+ (0x01B61,0x01B6A), `Delta (0);
+ (0x01B74,0x01B7C), `Delta (0);
+ (0x02100,0x02101), `Delta (0);
+ (0x02103,0x02106), `Delta (0);
+ (0x02108,0x02109), `Delta (0);
+ (0x02114,0x02114), `Abs (0x02114);
+ (0x02116,0x02117), `Delta (0);
+ (0x0211E,0x02123), `Delta (0);
+ (0x02125,0x02125), `Abs (0x02125);
+ (0x02127,0x02127), `Abs (0x02127);
+ (0x02129,0x02129), `Abs (0x02129);
+ (0x0212E,0x0212E), `Abs (0x0212E);
+ (0x0213A,0x0213B), `Delta (0);
+ (0x0214A,0x0214A), `Abs (0x0214A);
+ (0x0214C,0x0214D), `Delta (0);
+ (0x0214F,0x0214F), `Abs (0x0214F);
+ (0x0218A,0x0218B), `Delta (0);
+ (0x02195,0x02199), `Delta (0);
+ (0x0219C,0x0219F), `Delta (0);
+ (0x021A1,0x021A2), `Delta (0);
+ (0x021A4,0x021A5), `Delta (0);
+ (0x021A7,0x021AD), `Delta (0);
+ (0x021AF,0x021CD), `Delta (0);
+ (0x021D0,0x021D1), `Delta (0);
+ (0x021D3,0x021D3), `Abs (0x021D3);
+ (0x021D5,0x021F3), `Delta (0);
+ (0x02300,0x02307), `Delta (0);
+ (0x0230C,0x0231F), `Delta (0);
+ (0x02322,0x02328), `Delta (0);
+ (0x0232B,0x0237B), `Delta (0);
+ (0x0237D,0x0239A), `Delta (0);
+ (0x023B4,0x023DB), `Delta (0);
+ (0x023E2,0x023FE), `Delta (0);
+ (0x02400,0x02426), `Delta (0);
+ (0x02440,0x0244A), `Delta (0);
+ (0x0249C,0x024B5), `Delta (0);
+ (0x024B6,0x024CF), `Delta (26);
+ (0x024D0,0x024E9), `Delta (0);
+ (0x02500,0x025B6), `Delta (0);
+ (0x025B8,0x025C0), `Delta (0);
+ (0x025C2,0x025F7), `Delta (0);
+ (0x02600,0x0266E), `Delta (0);
+ (0x02670,0x02767), `Delta (0);
+ (0x02794,0x027BF), `Delta (0);
+ (0x02800,0x028FF), `Delta (0);
+ (0x02B00,0x02B2F), `Delta (0);
+ (0x02B45,0x02B46), `Delta (0);
+ (0x02B4D,0x02B73), `Delta (0);
+ (0x02B76,0x02B95), `Delta (0);
+ (0x02B98,0x02BB9), `Delta (0);
+ (0x02BBD,0x02BC8), `Delta (0);
+ (0x02BCA,0x02BD1), `Delta (0);
+ (0x02BEC,0x02BEF), `Delta (0);
+ (0x02CE5,0x02CEA), `Delta (0);
+ (0x02E80,0x02E99), `Delta (0);
+ (0x02E9B,0x02EF3), `Delta (0);
+ (0x02F00,0x02FD5), `Delta (0);
+ (0x02FF0,0x02FFB), `Delta (0);
+ (0x03004,0x03004), `Abs (0x03004);
+ (0x03012,0x03013), `Delta (0);
+ (0x03020,0x03020), `Abs (0x03020);
+ (0x03036,0x03037), `Delta (0);
+ (0x0303E,0x0303F), `Delta (0);
+ (0x03190,0x03191), `Delta (0);
+ (0x03196,0x0319F), `Delta (0);
+ (0x031C0,0x031E3), `Delta (0);
+ (0x03200,0x0321E), `Delta (0);
+ (0x0322A,0x03247), `Delta (0);
+ (0x03250,0x03250), `Abs (0x03250);
+ (0x03260,0x0327F), `Delta (0);
+ (0x0328A,0x032B0), `Delta (0);
+ (0x032C0,0x032FE), `Delta (0);
+ (0x03300,0x033FF), `Delta (0);
+ (0x04DC0,0x04DFF), `Delta (0);
+ (0x0A490,0x0A4C6), `Delta (0);
+ (0x0A828,0x0A82B), `Delta (0);
+ (0x0A836,0x0A837), `Delta (0);
+ (0x0A839,0x0A839), `Abs (0x0A839);
+ (0x0AA77,0x0AA79), `Delta (0);
+ (0x0FDFD,0x0FDFD), `Abs (0x0FDFD);
+ (0x0FFE4,0x0FFE4), `Abs (0x0FFE4);
+ (0x0FFE8,0x0FFE8), `Abs (0x0FFE8);
+ (0x0FFED,0x0FFEE), `Delta (0);
+ (0x0FFFC,0x0FFFD), `Delta (0);
+ (0x10137,0x1013F), `Delta (0);
+ (0x10179,0x10189), `Delta (0);
+ (0x1018C,0x1018E), `Delta (0);
+ (0x10190,0x1019B), `Delta (0);
+ (0x101A0,0x101A0), `Abs (0x101A0);
+ (0x101D0,0x101FC), `Delta (0);
+ (0x10877,0x10878), `Delta (0);
+ (0x10AC8,0x10AC8), `Abs (0x10AC8);
+ (0x1173F,0x1173F), `Abs (0x1173F);
+ (0x16B3C,0x16B3F), `Delta (0);
+ (0x16B45,0x16B45), `Abs (0x16B45);
+ (0x1BC9C,0x1BC9C), `Abs (0x1BC9C);
+ (0x1D000,0x1D0F5), `Delta (0);
+ (0x1D100,0x1D126), `Delta (0);
+ (0x1D129,0x1D164), `Delta (0);
+ (0x1D16A,0x1D16C), `Delta (0);
+ (0x1D183,0x1D184), `Delta (0);
+ (0x1D18C,0x1D1A9), `Delta (0);
+ (0x1D1AE,0x1D1E8), `Delta (0);
+ (0x1D200,0x1D241), `Delta (0);
+ (0x1D245,0x1D245), `Abs (0x1D245);
+ (0x1D300,0x1D356), `Delta (0);
+ (0x1D800,0x1D9FF), `Delta (0);
+ (0x1DA37,0x1DA3A), `Delta (0);
+ (0x1DA6D,0x1DA74), `Delta (0);
+ (0x1DA76,0x1DA83), `Delta (0);
+ (0x1DA85,0x1DA86), `Delta (0);
+ (0x1F000,0x1F02B), `Delta (0);
+ (0x1F030,0x1F093), `Delta (0);
+ (0x1F0A0,0x1F0AE), `Delta (0);
+ (0x1F0B1,0x1F0BF), `Delta (0);
+ (0x1F0C1,0x1F0CF), `Delta (0);
+ (0x1F0D1,0x1F0F5), `Delta (0);
+ (0x1F110,0x1F12E), `Delta (0);
+ (0x1F130,0x1F16B), `Delta (0);
+ (0x1F170,0x1F1AC), `Delta (0);
+ (0x1F1E6,0x1F202), `Delta (0);
+ (0x1F210,0x1F23B), `Delta (0);
+ (0x1F240,0x1F248), `Delta (0);
+ (0x1F250,0x1F251), `Delta (0);
+ (0x1F300,0x1F3FA), `Delta (0);
+ (0x1F400,0x1F6D2), `Delta (0);
+ (0x1F6E0,0x1F6EC), `Delta (0);
+ (0x1F6F0,0x1F6F6), `Delta (0);
+ (0x1F700,0x1F773), `Delta (0);
+ (0x1F780,0x1F7D4), `Delta (0);
+ (0x1F800,0x1F80B), `Delta (0);
+ (0x1F810,0x1F847), `Delta (0);
+ (0x1F850,0x1F859), `Delta (0);
+ (0x1F860,0x1F887), `Delta (0);
+ (0x1F890,0x1F8AD), `Delta (0);
+ (0x1F910,0x1F91E), `Delta (0);
+ (0x1F920,0x1F927), `Delta (0);
+ (0x1F930,0x1F930), `Abs (0x1F930);
+ (0x1F933,0x1F93E), `Delta (0);
+ (0x1F940,0x1F94B), `Delta (0);
+ (0x1F950,0x1F95E), `Delta (0);
+ (0x1F980,0x1F991), `Delta (0)
+];;
diff --git a/clib/unionfind.ml b/clib/unionfind.ml
new file mode 100644
index 00000000..980064a6
--- /dev/null
+++ b/clib/unionfind.ml
@@ -0,0 +1,138 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** An imperative implementation of partitions via Union-Find *)
+
+(** Paths are compressed imperatively at each lookup of a
+ canonical representative. Each union also modifies in-place
+ the partition structure.
+
+ Nota: For the moment we use Pervasive's comparison for
+ choosing the smallest object as representative. This could
+ be made more generic.
+*)
+
+
+
+module type PartitionSig = sig
+
+ (** The type of elements in the partition *)
+ type elt
+
+ (** A set structure over elements *)
+ type set
+
+ (** The type of partitions *)
+ type t
+
+ (** Initialise an empty partition *)
+ val create : unit -> t
+
+ (** Add (in place) an element in the partition, or do nothing
+ if the element is already in the partition. *)
+ val add : elt -> t -> unit
+
+ (** Find the canonical representative of an element.
+ Raise [not_found] if the element isn't known yet. *)
+ val find : elt -> t -> elt
+
+ (** Merge (in place) the equivalence classes of two elements.
+ This will add the elements in the partition if necessary. *)
+ val union : elt -> elt -> t -> unit
+
+ (** Merge (in place) the equivalence classes of many elements. *)
+ val union_set : set -> t -> unit
+
+ (** Listing the different components of the partition *)
+ val partition : t -> set list
+
+end
+
+module type SetS =
+sig
+ type t
+ type elt
+ val singleton : elt -> t
+ val union : t -> t -> t
+ val choose : t -> elt
+ val iter : (elt -> unit) -> t -> unit
+end
+
+module type MapS =
+sig
+ type key
+ type +'a t
+ val empty : 'a t
+ val find : key -> 'a t -> 'a
+ val add : key -> 'a -> 'a t -> 'a t
+ val mem : key -> 'a t -> bool
+ val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
+end
+
+module Make (S:SetS)(M:MapS with type key = S.elt) = struct
+
+ type elt = S.elt
+ type set = S.t
+
+ type node =
+ | Canon of set
+ | Equiv of elt
+
+ type t = node ref M.t ref
+
+ let create () = ref (M.empty : node ref M.t)
+
+ let fresh x p =
+ let node = ref (Canon (S.singleton x)) in
+ p := M.add x node !p;
+ x, node
+
+ let rec lookup x p =
+ let node = M.find x !p in
+ match !node with
+ | Canon _ -> x, node
+ | Equiv y ->
+ let ((z,_) as res) = lookup y p in
+ if not (z == y) then node := Equiv z;
+ res
+
+ let add x p = if not (M.mem x !p) then ignore (fresh x p)
+
+ let find x p = fst (lookup x p)
+
+ let canonical x p = try lookup x p with Not_found -> fresh x p
+
+ let union x y p =
+ let ((x,_) as xcan) = canonical x p in
+ let ((y,_) as ycan) = canonical y p in
+ if x = y then ()
+ else
+ let xcan, ycan = if x < y then xcan, ycan else ycan, xcan in
+ let x,xnode = xcan and y,ynode = ycan in
+ match !xnode, !ynode with
+ | Canon lx, Canon ly ->
+ xnode := Canon (S.union lx ly);
+ ynode := Equiv x;
+ | _ -> assert false
+
+ let union_set s p =
+ try
+ let x = S.choose s in
+ S.iter (fun y -> union x y p) s
+ with Not_found -> ()
+
+ let partition p =
+ List.rev (M.fold
+ (fun x node acc -> match !node with
+ | Equiv _ -> acc
+ | Canon lx -> lx::acc)
+ !p [])
+
+end
diff --git a/clib/unionfind.mli b/clib/unionfind.mli
new file mode 100644
index 00000000..e5a3a438
--- /dev/null
+++ b/clib/unionfind.mli
@@ -0,0 +1,82 @@
+(************************************************************************)
+(* * The Coq Proof Assistant / The Coq Development Team *)
+(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
+(* <O___,, * (see CREDITS file for the list of authors) *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(* * (see LICENSE file for the text of the license) *)
+(************************************************************************)
+
+(** An imperative implementation of partitions via Union-Find *)
+
+(** Paths are compressed imperatively at each lookup of a
+ canonical representative. Each union also modifies in-place
+ the partition structure.
+
+ Nota: for the moment we use Pervasive's comparison for
+ choosing the smallest object as representative. This could
+ be made more generic.
+*)
+
+module type PartitionSig = sig
+
+ (** The type of elements in the partition *)
+ type elt
+
+ (** A set structure over elements *)
+ type set
+
+ (** The type of partitions *)
+ type t
+
+ (** Initialise an empty partition *)
+ val create : unit -> t
+
+ (** Add (in place) an element in the partition, or do nothing
+ if the element is already in the partition. *)
+ val add : elt -> t -> unit
+
+ (** Find the canonical representative of an element.
+ Raise [not_found] if the element isn't known yet. *)
+ val find : elt -> t -> elt
+
+ (** Merge (in place) the equivalence classes of two elements.
+ This will add the elements in the partition if necessary. *)
+ val union : elt -> elt -> t -> unit
+
+ (** Merge (in place) the equivalence classes of many elements. *)
+ val union_set : set -> t -> unit
+
+ (** Listing the different components of the partition *)
+ val partition : t -> set list
+
+end
+
+module type SetS =
+sig
+ type t
+ type elt
+ val singleton : elt -> t
+ val union : t -> t -> t
+ val choose : t -> elt
+ val iter : (elt -> unit) -> t -> unit
+end
+(** Minimal interface for sets, subtype of stdlib's Set. *)
+
+module type MapS =
+sig
+ type key
+ type +'a t
+ val empty : 'a t
+ val find : key -> 'a t -> 'a
+ val add : key -> 'a -> 'a t -> 'a t
+ val mem : key -> 'a t -> bool
+ val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
+end
+(** Minimal interface for maps, subtype of stdlib's Map. *)
+
+module Make :
+ functor (S:SetS) ->
+ functor (M:MapS with type key = S.elt) ->
+ PartitionSig with type elt = S.elt and type set = S.t