aboutsummaryrefslogtreecommitdiffhomepage
path: root/clib
diff options
context:
space:
mode:
authorGravatar Emilio Jesus Gallego Arias <e+git@x80.org>2017-12-15 18:51:45 +0100
committerGravatar Emilio Jesus Gallego Arias <e+git@x80.org>2017-12-23 19:20:30 +0100
commit5ffa147bd2fe548df3ac9053fe497d0871a5f6df (patch)
treecc62882184c34e33e2995a5a4ff4ebfcbd0defe0 /clib
parentdea75d74c222c25f6aa6c38506ac7a51b339e9c6 (diff)
[lib] Split auxiliary libraries into Coq-specific and general.
Up to this point the `lib` directory contained two different library archives, `clib.cma` and `lib.cma`, which a rough splitting between Coq-specific libraries and general-purpose ones. We know split the directory in two, as to make the distinction clear: - `clib`: contains libraries that are not Coq specific and implement common data structures and programming patterns. These libraries could be eventually replace with external dependencies and the rest of the code base wouldn't notice much. - `lib`: contains Coq-specific common libraries in widespread use along the codebase, but that are not considered part of other components. Examples are printing, error handling, or flags. In some cases we have coupling due to utility files depending on Coq specific flags, however this commit doesn't modify any files, but only moves them around, further cleanup is welcome, as indeed a few files in `lib` should likely be placed in `clib`. Also note that `Deque` is not used ATM.
Diffstat (limited to 'clib')
-rw-r--r--clib/backtrace.ml117
-rw-r--r--clib/backtrace.mli96
-rw-r--r--clib/bigint.ml524
-rw-r--r--clib/bigint.mli50
-rw-r--r--clib/cArray.ml545
-rw-r--r--clib/cArray.mli155
-rw-r--r--clib/cEphemeron.ml89
-rw-r--r--clib/cEphemeron.mli52
-rw-r--r--clib/cList.ml889
-rw-r--r--clib/cList.mli263
-rw-r--r--clib/cMap.ml218
-rw-r--r--clib/cMap.mli88
-rw-r--r--clib/cObj.ml203
-rw-r--r--clib/cObj.mli59
-rw-r--r--clib/cSet.ml67
-rw-r--r--clib/cSet.mli31
-rw-r--r--clib/cSig.mli86
-rw-r--r--clib/cStack.ml42
-rw-r--r--clib/cStack.mli56
-rw-r--r--clib/cString.ml178
-rw-r--r--clib/cString.mli78
-rw-r--r--clib/cThread.ml97
-rw-r--r--clib/cThread.mli26
-rw-r--r--clib/cUnix.ml144
-rw-r--r--clib/cUnix.mli69
-rw-r--r--clib/canary.ml26
-rw-r--r--clib/canary.mli25
-rw-r--r--clib/clib.mllib38
-rw-r--r--clib/deque.ml97
-rw-r--r--clib/deque.mli58
-rw-r--r--clib/dyn.ml159
-rw-r--r--clib/dyn.mli66
-rw-r--r--clib/exninfo.ml104
-rw-r--r--clib/exninfo.mli39
-rw-r--r--clib/hMap.ml414
-rw-r--r--clib/hMap.mli28
-rw-r--r--clib/hashcons.ml186
-rw-r--r--clib/hashcons.mli90
-rw-r--r--clib/hashset.ml229
-rw-r--r--clib/hashset.mli56
-rw-r--r--clib/heap.ml134
-rw-r--r--clib/heap.mli52
-rw-r--r--clib/iStream.ml90
-rw-r--r--clib/iStream.mli81
-rw-r--r--clib/int.ml237
-rw-r--r--clib/int.mli79
-rw-r--r--clib/minisys.ml78
-rw-r--r--clib/monad.ml168
-rw-r--r--clib/monad.mli94
-rw-r--r--clib/option.ml206
-rw-r--r--clib/option.mli141
-rw-r--r--clib/predicate.ml98
-rw-r--r--clib/predicate.mli84
-rw-r--r--clib/segmenttree.ml138
-rw-r--r--clib/segmenttree.mli28
-rw-r--r--clib/store.ml87
-rw-r--r--clib/store.mli41
-rw-r--r--clib/terminal.ml298
-rw-r--r--clib/terminal.mli67
-rw-r--r--clib/trie.ml89
-rw-r--r--clib/trie.mli61
-rw-r--r--clib/unicode.ml385
-rw-r--r--clib/unicode.mli58
-rw-r--r--clib/unicodetable.ml7427
-rw-r--r--clib/unionfind.ml136
-rw-r--r--clib/unionfind.mli80
66 files changed, 16274 insertions, 0 deletions
diff --git a/clib/backtrace.ml b/clib/backtrace.ml
new file mode 100644
index 000000000..be9f40c1f
--- /dev/null
+++ b/clib/backtrace.ml
@@ -0,0 +1,117 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+[@@@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 000000000..dd82165b6
--- /dev/null
+++ b/clib/backtrace.mli
@@ -0,0 +1,96 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(** * 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 000000000..4f8b95d59
--- /dev/null
+++ b/clib/bigint.ml
@@ -0,0 +1,524 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(***************************************************)
+(* 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 000000000..2a5a5f122
--- /dev/null
+++ b/clib/bigint.mli
@@ -0,0 +1,50 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..013585735
--- /dev/null
+++ b/clib/cArray.ml
@@ -0,0 +1,545 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+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
+ val fold_map' : ('a -> 'c -> 'b * 'c) -> 'a array -> 'c -> 'b array * 'c
+ val fold_map2' :
+ ('a -> 'b -> 'c -> 'd * 'c) -> 'a array -> 'b array -> 'c -> 'd array * 'c
+ 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 000000000..325ff8edc
--- /dev/null
+++ b/clib/cArray.mli
@@ -0,0 +1,155 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+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
+ (** @deprecated Same as [fold_left_map] *)
+
+ val fold_map' : ('a -> 'c -> 'b * 'c) -> 'a array -> 'c -> 'b array * 'c
+ (** @deprecated Same as [fold_right_map] *)
+
+ val fold_map2' :
+ ('a -> 'b -> 'c -> 'd * 'c) -> 'a array -> 'b array -> 'c -> 'd array * 'c
+ (** @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 000000000..8b253a790
--- /dev/null
+++ b/clib/cEphemeron.ml
@@ -0,0 +1,89 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..d8a1f2757
--- /dev/null
+++ b/clib/cEphemeron.mli
@@ -0,0 +1,52 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(* 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 000000000..0ef7c3d8b
--- /dev/null
+++ b/clib/cList.ml
@@ -0,0 +1,889 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+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 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
+ val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
+ 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 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
+
+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)
+
+(* 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 000000000..f87db04cf
--- /dev/null
+++ b/clib/cList.mli
@@ -0,0 +1,263 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+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
+ 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]"] *)
+ (** @deprecated Same as [fold_left_map] *)
+
+ val fold_map' : ('b -> 'a -> 'c * 'a) -> 'b list -> 'a -> 'c list * 'a
+ (** @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 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 000000000..b4c4aedd0
--- /dev/null
+++ b/clib/cMap.ml
@@ -0,0 +1,218 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..5e65bd200
--- /dev/null
+++ b/clib/cMap.mli
@@ -0,0 +1,88 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** {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 000000000..7f3ee1855
--- /dev/null
+++ b/clib/cObj.ml
@@ -0,0 +1,203 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*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 000000000..16933a4aa
--- /dev/null
+++ b/clib/cObj.mli
@@ -0,0 +1,59 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(** {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 000000000..ed65edf16
--- /dev/null
+++ b/clib/cSet.ml
@@ -0,0 +1,67 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..2eb9bce86
--- /dev/null
+++ b/clib/cSet.mli
@@ -0,0 +1,31 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..32e9d2af0
--- /dev/null
+++ b/clib/cSig.mli
@@ -0,0 +1,86 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..4acb2930c
--- /dev/null
+++ b/clib/cStack.ml
@@ -0,0 +1,42 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..8dde1d1a1
--- /dev/null
+++ b/clib/cStack.mli
@@ -0,0 +1,56 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..f2242460e
--- /dev/null
+++ b/clib/cString.ml
@@ -0,0 +1,178 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..29d3a4499
--- /dev/null
+++ b/clib/cString.mli
@@ -0,0 +1,78 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..0221e690e
--- /dev/null
+++ b/clib/cThread.ml
@@ -0,0 +1,97 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..66f039bb5
--- /dev/null
+++ b/clib/cThread.mli
@@ -0,0 +1,26 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(* 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 000000000..34fb660db
--- /dev/null
+++ b/clib/cUnix.ml
@@ -0,0 +1,144 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(* 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 000000000..d08dc4c40
--- /dev/null
+++ b/clib/cUnix.mli
@@ -0,0 +1,69 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** {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 000000000..0ed1d28f3
--- /dev/null
+++ b/clib/canary.ml
@@ -0,0 +1,26 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..904b88213
--- /dev/null
+++ b/clib/canary.mli
@@ -0,0 +1,25 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..bd5ddb152
--- /dev/null
+++ b/clib/clib.mllib
@@ -0,0 +1,38 @@
+Canary
+CObj
+CEphemeron
+
+Hashset
+Hashcons
+
+CSet
+CMap
+CList
+CString
+CStack
+
+Int
+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/deque.ml b/clib/deque.ml
new file mode 100644
index 000000000..373269b4f
--- /dev/null
+++ b/clib/deque.ml
@@ -0,0 +1,97 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+exception Empty
+
+type 'a t = {
+ face : 'a list;
+ rear : 'a list;
+ lenf : int;
+ lenr : int;
+}
+
+let rec split i accu l = match l with
+| [] ->
+ if Int.equal i 0 then (accu, []) else invalid_arg "split"
+| t :: q ->
+ if Int.equal i 0 then (accu, l)
+ else split (pred i) (t :: accu) q
+
+let balance q =
+ let avg = (q.lenf + q.lenr) / 2 in
+ let dif = q.lenf + q.lenr - avg in
+ if q.lenf > succ (2 * q.lenr) then
+ let (ff, fr) = split avg [] q.face in
+ { face = List.rev ff ; rear = q.rear @ List.rev fr; lenf = avg; lenr = dif }
+ else if q.lenr > succ (2 * q.lenf) then
+ let (rf, rr) = split avg [] q.rear in
+ { face = q.face @ List.rev rr ; rear = List.rev rf; lenf = dif; lenr = avg }
+ else q
+
+let empty = {
+ face = [];
+ rear = [];
+ lenf = 0;
+ lenr = 0;
+}
+
+let lcons x q =
+ balance { q with lenf = succ q.lenf; face = x :: q.face }
+
+let lhd q = match q.face with
+| [] ->
+ begin match q.rear with
+ | [] -> raise Empty
+ | t :: _ -> t
+ end
+| t :: _ -> t
+
+let ltl q = match q.face with
+| [] ->
+ begin match q.rear with
+ | [] -> raise Empty
+ | t :: _ -> empty
+ end
+| t :: r -> balance { q with lenf = pred q.lenf; face = r }
+
+let rcons x q =
+ balance { q with lenr = succ q.lenr; rear = x :: q.rear }
+
+let rhd q = match q.rear with
+| [] ->
+ begin match q.face with
+ | [] -> raise Empty
+ | t :: r -> t
+ end
+| t :: _ -> t
+
+let rtl q = match q.rear with
+| [] ->
+ begin match q.face with
+ | [] -> raise Empty
+ | t :: r -> empty
+ end
+| t :: r ->
+ balance { q with lenr = pred q.lenr; rear = r }
+
+let rev q = {
+ face = q.rear;
+ rear = q.face;
+ lenf = q.lenr;
+ lenr = q.lenf;
+}
+
+let length q = q.lenf + q.lenr
+
+let is_empty q = Int.equal (length q) 0
+
+let filter f q =
+ let fold (accu, len) x = if f x then (x :: accu, succ len) else (accu, len) in
+ let (rf, lenf) = List.fold_left fold ([], 0) q.face in
+ let (rr, lenr) = List.fold_left fold ([], 0) q.rear in
+ balance { face = List.rev rf; rear = List.rev rr; lenf = lenf; lenr = lenr }
diff --git a/clib/deque.mli b/clib/deque.mli
new file mode 100644
index 000000000..23cb1e491
--- /dev/null
+++ b/clib/deque.mli
@@ -0,0 +1,58 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** * Purely functional, double-ended queues *)
+
+(** This module implements the banker's deque, from Okasaki. Most operations are
+ amortized O(1). *)
+
+type +'a t
+
+exception Empty
+
+(** {5 Constructor} *)
+
+val empty : 'a t
+
+(** The empty deque. *)
+
+(** {5 Left-side operations} *)
+
+val lcons : 'a -> 'a t -> 'a t
+(** Pushes an element on the left side of the deque. *)
+
+val lhd : 'a t -> 'a
+(** Returns the leftmost element in the deque. Raises [Empty] when empty. *)
+
+val ltl : 'a t -> 'a t
+(** Returns the left-tail of the deque. Raises [Empty] when empty. *)
+
+(** {5 Right-side operations} *)
+
+val rcons : 'a -> 'a t -> 'a t
+(** Same as [lcons] but on the right side. *)
+
+val rhd : 'a t -> 'a
+(** Same as [lhd] but on the right side. *)
+
+val rtl : 'a t -> 'a t
+(** Same as [ltl] but on the right side. *)
+
+(** {5 Operations} *)
+
+val rev : 'a t -> 'a t
+(** Reverse deque. *)
+
+val length : 'a t -> int
+(** Length of a deque. *)
+
+val is_empty : 'a t -> bool
+(** Emptyness of a deque. *)
+
+val filter : ('a -> bool) -> 'a t -> 'a t
+(** Filters the deque *)
diff --git a/clib/dyn.ml b/clib/dyn.ml
new file mode 100644
index 000000000..64535d35f
--- /dev/null
+++ b/clib/dyn.ml
@@ -0,0 +1,159 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..2206394e2
--- /dev/null
+++ b/clib/dyn.mli
@@ -0,0 +1,66 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..167d3d6dc
--- /dev/null
+++ b/clib/exninfo.ml
@@ -0,0 +1,104 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(** 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 000000000..c960ac7c0
--- /dev/null
+++ b/clib/exninfo.mli
@@ -0,0 +1,39 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(** 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 000000000..37079af78
--- /dev/null
+++ b/clib/hMap.ml
@@ -0,0 +1,414 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..c77bfced8
--- /dev/null
+++ b/clib/hMap.mli
@@ -0,0 +1,28 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..ee2232581
--- /dev/null
+++ b/clib/hashcons.ml
@@ -0,0 +1,186 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(* 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 000000000..fbd2ebcf9
--- /dev/null
+++ b/clib/hashcons.mli
@@ -0,0 +1,90 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..7f96627a6
--- /dev/null
+++ b/clib/hashset.ml
@@ -0,0 +1,229 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..ec79205a5
--- /dev/null
+++ b/clib/hashset.mli
@@ -0,0 +1,56 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..a6109972d
--- /dev/null
+++ b/clib/heap.ml
@@ -0,0 +1,134 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(*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 000000000..93d504c5a
--- /dev/null
+++ b/clib/heap.mli
@@ -0,0 +1,52 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..d3a54332a
--- /dev/null
+++ b/clib/iStream.ml
@@ -0,0 +1,90 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..cd7940e8d
--- /dev/null
+++ b/clib/iStream.mli
@@ -0,0 +1,81 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** {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 000000000..63f62154d
--- /dev/null
+++ b/clib/int.ml
@@ -0,0 +1,237 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..b65367f7d
--- /dev/null
+++ b/clib/int.mli
@@ -0,0 +1,79 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..389b18ad4
--- /dev/null
+++ b/clib/minisys.ml
@@ -0,0 +1,78 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..2e55e9698
--- /dev/null
+++ b/clib/monad.ml
@@ -0,0 +1,168 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+
+(** 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 000000000..7b0a3e600
--- /dev/null
+++ b/clib/monad.mli
@@ -0,0 +1,94 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+
+(** 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 000000000..98b168035
--- /dev/null
+++ b/clib/option.ml
@@ -0,0 +1,206 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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
+
+(** [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 000000000..66f05023f
--- /dev/null
+++ b/clib/option.mli
@@ -0,0 +1,141 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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
+
+(** [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
+
+(** [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/predicate.ml b/clib/predicate.ml
new file mode 100644
index 000000000..1aa7db6af
--- /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 000000000..cee3b0bd3
--- /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/segmenttree.ml b/clib/segmenttree.ml
new file mode 100644
index 000000000..d0ded4cb5
--- /dev/null
+++ b/clib/segmenttree.ml
@@ -0,0 +1,138 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..e274a6fdc
--- /dev/null
+++ b/clib/segmenttree.mli
@@ -0,0 +1,28 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..97a8fea08
--- /dev/null
+++ b/clib/store.ml
@@ -0,0 +1,87 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(** 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 000000000..5cc5bb859
--- /dev/null
+++ b/clib/store.mli
@@ -0,0 +1,41 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*** 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 000000000..34efddfbc
--- /dev/null
+++ b/clib/terminal.ml
@@ -0,0 +1,298 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..b1b76e6e2
--- /dev/null
+++ b/clib/terminal.mli
@@ -0,0 +1,67 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..0b0ba2761
--- /dev/null
+++ b/clib/trie.ml
@@ -0,0 +1,89 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+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 000000000..a87acc8a6
--- /dev/null
+++ b/clib/trie.mli
@@ -0,0 +1,61 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..f193c4e0f
--- /dev/null
+++ b/clib/unicode.ml
@@ -0,0 +1,385 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(** 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 000000000..32ffbb8e9
--- /dev/null
+++ b/clib/unicode.mli
@@ -0,0 +1,58 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..b607058c6
--- /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 000000000..f9c92d6a8
--- /dev/null
+++ b/clib/unionfind.ml
@@ -0,0 +1,136 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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 000000000..b242232ed
--- /dev/null
+++ b/clib/unionfind.mli
@@ -0,0 +1,80 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2017 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(** 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