From b01145ad9f0cad8c6c3a6b0258b1ce2ad65501aa Mon Sep 17 00:00:00 2001 From: Hongbo Zhang Date: Fri, 5 Jan 2018 15:39:02 +0800 Subject: [PATCH] better union/inter/diff algorithm --- jscomp/others/bs_internalSetInt.ml | 164 ++++++++------ jscomp/others/bs_internalSetString.ml | 164 ++++++++------ jscomp/others/internal_set.cppo.ml | 164 ++++++++------ lib/js/bs_internalSetInt.js | 307 +++++++++++++++----------- lib/js/bs_internalSetString.js | 307 +++++++++++++++----------- 5 files changed, 629 insertions(+), 477 deletions(-) diff --git a/jscomp/others/bs_internalSetInt.ml b/jscomp/others/bs_internalSetInt.ml index ececce8071..cd564b8d7b 100644 --- a/jscomp/others/bs_internalSetInt.ml +++ b/jscomp/others/bs_internalSetInt.ml @@ -35,39 +35,6 @@ let rec add (t : t) (x : elt) : t = -(* Splitting. split x s returns a triple (l, present, r) where - - l is the set of elements of s that are < x - - r is the set of elements of s that are > x - - present is false if s contains no element equal to x, - or true if s contains an element equal to x. *) - -let rec splitAux (n : _ N.node) (x : elt) : t * bool * t = - let l,v,r = N.(left n , key n, right n) in - if x = v then (l, true, r) - else if x < v then - match N.toOpt l with - | None -> - N.(empty , false, return n) - | Some l -> - let (ll, pres, rl) = splitAux l x in - ll, pres, N.join rl v r - else - match N.toOpt r with - | None -> - N.return n, false, N.empty - | Some r -> - let (lr, pres, rr) = splitAux r x in - N.join l v lr, pres, rr - - -let split (t : t) (x : elt) : t * bool * t = - match N.toOpt t with - None -> - N.(empty, false, empty) - | Some n -> - splitAux n x - - let rec mem (t : t) (x : elt) = match N.toOpt t with | None -> false @@ -98,6 +65,83 @@ let rec remove (t : t) (x : elt) : t = if rr == r then t else N.bal l v rr + +let rec compare_aux e1 e2 = + match (e1, e2) with + (End, End) -> 0 + | (End, _) -> -1 + | (_, End) -> 1 + | (More(v1, r1, e1), More(v2, r2, e2)) -> + if (v1 : elt) <> v2 + then if v1 < v2 then -1 else 1 + else compare_aux (N.toEnum r1 e1) (N.toEnum r2 e2) + +let cmp s1 s2 = + compare_aux (N.toEnum s1 End) (N.toEnum s2 End) + +let rec eqAux (e1 : enumeration) e2 = + match (e1, e2) with + (End, End) -> true + | (End, More _) -> false + | (More _, End) -> false + | (More(v1, r1, e1), More(v2, r2, e2)) -> + v1 = v2 && + eqAux (N.toEnum r1 e1) (N.toEnum r2 e2) + +let eq s1 s2 = + eqAux (N.toEnum s1 End) (N.toEnum s2 End) + +let rec splitAuxNoPivot (n : _ N.node) (x : elt) : t * t = + let l,v,r = N.(left n , key n, right n) in + if x = v then l, r + else if x < v then + match N.toOpt l with + | None -> + N.empty , N.return n + | Some l -> + let ll, rl = splitAuxNoPivot l x in + ll, N.join rl v r + else + match N.toOpt r with + | None -> + N.return n, N.empty + | Some r -> + let lr, rr = splitAuxNoPivot r x in + N.join l v lr, rr + + +let rec splitAuxPivot (n : _ N.node) (x : elt) pres : t * t = + let l,v,r = N.(left n , key n, right n) in + if x = v then begin + pres := true; + (l, r) + end + else if x < v then + match N.toOpt l with + | None -> + N.empty, N.return n + | Some l -> + let ll, rl = splitAuxPivot l x pres in + ll, N.join rl v r + else + match N.toOpt r with + | None -> + N.return n, N.empty + | Some r -> + let lr, rr = splitAuxPivot r x pres in + N.join l v lr, rr + +(* TODO: fix me, change the api to (t * t ) * bool *) +let split (t : t) (x : elt) : t * bool * t = + match N.toOpt t with + None -> + N.empty, false, N.empty + | Some n -> + let pres = ref false in + let l,r = splitAuxPivot n x pres in + l, !pres, r + + let rec union (s1 : t) (s2 : t) = match N.(toOpt s1, toOpt s2) with (None, _) -> s2 @@ -107,27 +151,28 @@ let rec union (s1 : t) (s2 : t) = if h1 >= h2 then if h2 = 1 then add s1 (N.key n2) else begin let l1, v1, r1 = N.(left n1, key n1, right n1) in - let (l2, _, r2) = splitAux n2 v1 in + let (l2, r2) = splitAuxNoPivot n2 v1 in N.join (union l1 l2) v1 (union r1 r2) end else if h1 = 1 then add s2 (N.key n1) else begin let l2, v2, r2 = N.(left n2 , key n2, right n2) in - let (l1, _, r1) = splitAux n1 v2 in + let (l1, r1) = splitAuxNoPivot n1 v2 in N.join (union l1 l2) v2 (union r1 r2) end let rec inter (s1 : t) (s2 : t) = match N.(toOpt s1, toOpt s2) with - (None, _) -> s1 - | (_, None) -> s2 + (None, _) + | (_, None) -> N.empty | Some n1, Some n2 (* (Node(l1, v1, r1, _), t2) *) -> let l1,v1,r1 = N.(left n1, key n1, right n1) in - match splitAux n2 v1 with - (l2, false, r2) -> - N.concat (inter l1 l2) (inter r1 r2) - | (l2, true, r2) -> - N.join (inter l1 l2) v1 (inter r1 r2) + let pres = ref false in + let l2,r2 = splitAuxPivot n2 v1 pres in + let ll = inter l1 l2 in + let rr = inter r1 r2 in + if !pres then N.join ll v1 rr + else N.concat ll rr let rec diff (s1 : t) (s2 : t) = match N.(toOpt s1, toOpt s2) with @@ -135,37 +180,14 @@ let rec diff (s1 : t) (s2 : t) = | (_, None) -> s1 | Some n1, Some n2 (* (Node(l1, v1, r1, _), t2) *) -> let l1,v1,r1 = N.(left n1, key n1, right n1) in - match splitAux n2 v1 with - (l2, false, r2) -> - N.join (diff l1 l2) v1 (diff r1 r2) - | (l2, true, r2) -> - N.concat (diff l1 l2) (diff r1 r2) + let pres = ref false in + let l2, r2 = splitAuxPivot n2 v1 pres in + let ll = diff l1 l2 in + let rr = diff r1 r2 in + if !pres then N.concat ll rr + else N.join ll v1 rr -let rec compare_aux e1 e2 = - match (e1, e2) with - (End, End) -> 0 - | (End, _) -> -1 - | (_, End) -> 1 - | (More(v1, r1, e1), More(v2, r2, e2)) -> - if (v1 : elt) <> v2 - then if v1 < v2 then -1 else 1 - else compare_aux (N.toEnum r1 e1) (N.toEnum r2 e2) - -let cmp s1 s2 = - compare_aux (N.toEnum s1 End) (N.toEnum s2 End) - -let rec eqAux (e1 : enumeration) e2 = - match (e1, e2) with - (End, End) -> true - | (End, More _) -> false - | (More _, End) -> false - | (More(v1, r1, e1), More(v2, r2, e2)) -> - v1 = v2 && - eqAux (N.toEnum r1 e1) (N.toEnum r2 e2) - -let eq s1 s2 = - eqAux (N.toEnum s1 End) (N.toEnum s2 End) (* This algorithm applies to BST, it does not need to be balanced tree *) let rec subset (s1 : t) (s2 : t) = diff --git a/jscomp/others/bs_internalSetString.ml b/jscomp/others/bs_internalSetString.ml index 1e055a0346..4239590e78 100644 --- a/jscomp/others/bs_internalSetString.ml +++ b/jscomp/others/bs_internalSetString.ml @@ -35,39 +35,6 @@ let rec add (t : t) (x : elt) : t = -(* Splitting. split x s returns a triple (l, present, r) where - - l is the set of elements of s that are < x - - r is the set of elements of s that are > x - - present is false if s contains no element equal to x, - or true if s contains an element equal to x. *) - -let rec splitAux (n : _ N.node) (x : elt) : t * bool * t = - let l,v,r = N.(left n , key n, right n) in - if x = v then (l, true, r) - else if x < v then - match N.toOpt l with - | None -> - N.(empty , false, return n) - | Some l -> - let (ll, pres, rl) = splitAux l x in - ll, pres, N.join rl v r - else - match N.toOpt r with - | None -> - N.return n, false, N.empty - | Some r -> - let (lr, pres, rr) = splitAux r x in - N.join l v lr, pres, rr - - -let split (t : t) (x : elt) : t * bool * t = - match N.toOpt t with - None -> - N.(empty, false, empty) - | Some n -> - splitAux n x - - let rec mem (t : t) (x : elt) = match N.toOpt t with | None -> false @@ -98,6 +65,83 @@ let rec remove (t : t) (x : elt) : t = if rr == r then t else N.bal l v rr + +let rec compare_aux e1 e2 = + match (e1, e2) with + (End, End) -> 0 + | (End, _) -> -1 + | (_, End) -> 1 + | (More(v1, r1, e1), More(v2, r2, e2)) -> + if (v1 : elt) <> v2 + then if v1 < v2 then -1 else 1 + else compare_aux (N.toEnum r1 e1) (N.toEnum r2 e2) + +let cmp s1 s2 = + compare_aux (N.toEnum s1 End) (N.toEnum s2 End) + +let rec eqAux (e1 : enumeration) e2 = + match (e1, e2) with + (End, End) -> true + | (End, More _) -> false + | (More _, End) -> false + | (More(v1, r1, e1), More(v2, r2, e2)) -> + v1 = v2 && + eqAux (N.toEnum r1 e1) (N.toEnum r2 e2) + +let eq s1 s2 = + eqAux (N.toEnum s1 End) (N.toEnum s2 End) + +let rec splitAuxNoPivot (n : _ N.node) (x : elt) : t * t = + let l,v,r = N.(left n , key n, right n) in + if x = v then l, r + else if x < v then + match N.toOpt l with + | None -> + N.empty , N.return n + | Some l -> + let ll, rl = splitAuxNoPivot l x in + ll, N.join rl v r + else + match N.toOpt r with + | None -> + N.return n, N.empty + | Some r -> + let lr, rr = splitAuxNoPivot r x in + N.join l v lr, rr + + +let rec splitAuxPivot (n : _ N.node) (x : elt) pres : t * t = + let l,v,r = N.(left n , key n, right n) in + if x = v then begin + pres := true; + (l, r) + end + else if x < v then + match N.toOpt l with + | None -> + N.empty, N.return n + | Some l -> + let ll, rl = splitAuxPivot l x pres in + ll, N.join rl v r + else + match N.toOpt r with + | None -> + N.return n, N.empty + | Some r -> + let lr, rr = splitAuxPivot r x pres in + N.join l v lr, rr + +(* TODO: fix me, change the api to (t * t ) * bool *) +let split (t : t) (x : elt) : t * bool * t = + match N.toOpt t with + None -> + N.empty, false, N.empty + | Some n -> + let pres = ref false in + let l,r = splitAuxPivot n x pres in + l, !pres, r + + let rec union (s1 : t) (s2 : t) = match N.(toOpt s1, toOpt s2) with (None, _) -> s2 @@ -107,27 +151,28 @@ let rec union (s1 : t) (s2 : t) = if h1 >= h2 then if h2 = 1 then add s1 (N.key n2) else begin let l1, v1, r1 = N.(left n1, key n1, right n1) in - let (l2, _, r2) = splitAux n2 v1 in + let (l2, r2) = splitAuxNoPivot n2 v1 in N.join (union l1 l2) v1 (union r1 r2) end else if h1 = 1 then add s2 (N.key n1) else begin let l2, v2, r2 = N.(left n2 , key n2, right n2) in - let (l1, _, r1) = splitAux n1 v2 in + let (l1, r1) = splitAuxNoPivot n1 v2 in N.join (union l1 l2) v2 (union r1 r2) end let rec inter (s1 : t) (s2 : t) = match N.(toOpt s1, toOpt s2) with - (None, _) -> s1 - | (_, None) -> s2 + (None, _) + | (_, None) -> N.empty | Some n1, Some n2 (* (Node(l1, v1, r1, _), t2) *) -> let l1,v1,r1 = N.(left n1, key n1, right n1) in - match splitAux n2 v1 with - (l2, false, r2) -> - N.concat (inter l1 l2) (inter r1 r2) - | (l2, true, r2) -> - N.join (inter l1 l2) v1 (inter r1 r2) + let pres = ref false in + let l2,r2 = splitAuxPivot n2 v1 pres in + let ll = inter l1 l2 in + let rr = inter r1 r2 in + if !pres then N.join ll v1 rr + else N.concat ll rr let rec diff (s1 : t) (s2 : t) = match N.(toOpt s1, toOpt s2) with @@ -135,37 +180,14 @@ let rec diff (s1 : t) (s2 : t) = | (_, None) -> s1 | Some n1, Some n2 (* (Node(l1, v1, r1, _), t2) *) -> let l1,v1,r1 = N.(left n1, key n1, right n1) in - match splitAux n2 v1 with - (l2, false, r2) -> - N.join (diff l1 l2) v1 (diff r1 r2) - | (l2, true, r2) -> - N.concat (diff l1 l2) (diff r1 r2) + let pres = ref false in + let l2, r2 = splitAuxPivot n2 v1 pres in + let ll = diff l1 l2 in + let rr = diff r1 r2 in + if !pres then N.concat ll rr + else N.join ll v1 rr -let rec compare_aux e1 e2 = - match (e1, e2) with - (End, End) -> 0 - | (End, _) -> -1 - | (_, End) -> 1 - | (More(v1, r1, e1), More(v2, r2, e2)) -> - if (v1 : elt) <> v2 - then if v1 < v2 then -1 else 1 - else compare_aux (N.toEnum r1 e1) (N.toEnum r2 e2) - -let cmp s1 s2 = - compare_aux (N.toEnum s1 End) (N.toEnum s2 End) - -let rec eqAux (e1 : enumeration) e2 = - match (e1, e2) with - (End, End) -> true - | (End, More _) -> false - | (More _, End) -> false - | (More(v1, r1, e1), More(v2, r2, e2)) -> - v1 = v2 && - eqAux (N.toEnum r1 e1) (N.toEnum r2 e2) - -let eq s1 s2 = - eqAux (N.toEnum s1 End) (N.toEnum s2 End) (* This algorithm applies to BST, it does not need to be balanced tree *) let rec subset (s1 : t) (s2 : t) = diff --git a/jscomp/others/internal_set.cppo.ml b/jscomp/others/internal_set.cppo.ml index f36a2bfa5a..f94e5b44fc 100644 --- a/jscomp/others/internal_set.cppo.ml +++ b/jscomp/others/internal_set.cppo.ml @@ -39,39 +39,6 @@ let rec add (t : t) (x : elt) : t = -(* Splitting. split x s returns a triple (l, present, r) where - - l is the set of elements of s that are < x - - r is the set of elements of s that are > x - - present is false if s contains no element equal to x, - or true if s contains an element equal to x. *) - -let rec splitAux (n : _ N.node) (x : elt) : t * bool * t = - let l,v,r = N.(left n , key n, right n) in - if x = v then (l, true, r) - else if x < v then - match N.toOpt l with - | None -> - N.(empty , false, return n) - | Some l -> - let (ll, pres, rl) = splitAux l x in - ll, pres, N.join rl v r - else - match N.toOpt r with - | None -> - N.return n, false, N.empty - | Some r -> - let (lr, pres, rr) = splitAux r x in - N.join l v lr, pres, rr - - -let split (t : t) (x : elt) : t * bool * t = - match N.toOpt t with - None -> - N.(empty, false, empty) - | Some n -> - splitAux n x - - let rec mem (t : t) (x : elt) = match N.toOpt t with | None -> false @@ -102,6 +69,83 @@ let rec remove (t : t) (x : elt) : t = if rr == r then t else N.bal l v rr + +let rec compare_aux e1 e2 = + match (e1, e2) with + (End, End) -> 0 + | (End, _) -> -1 + | (_, End) -> 1 + | (More(v1, r1, e1), More(v2, r2, e2)) -> + if (v1 : elt) <> v2 + then if v1 < v2 then -1 else 1 + else compare_aux (N.toEnum r1 e1) (N.toEnum r2 e2) + +let cmp s1 s2 = + compare_aux (N.toEnum s1 End) (N.toEnum s2 End) + +let rec eqAux (e1 : enumeration) e2 = + match (e1, e2) with + (End, End) -> true + | (End, More _) -> false + | (More _, End) -> false + | (More(v1, r1, e1), More(v2, r2, e2)) -> + v1 = v2 && + eqAux (N.toEnum r1 e1) (N.toEnum r2 e2) + +let eq s1 s2 = + eqAux (N.toEnum s1 End) (N.toEnum s2 End) + +let rec splitAuxNoPivot (n : _ N.node) (x : elt) : t * t = + let l,v,r = N.(left n , key n, right n) in + if x = v then l, r + else if x < v then + match N.toOpt l with + | None -> + N.empty , N.return n + | Some l -> + let ll, rl = splitAuxNoPivot l x in + ll, N.join rl v r + else + match N.toOpt r with + | None -> + N.return n, N.empty + | Some r -> + let lr, rr = splitAuxNoPivot r x in + N.join l v lr, rr + + +let rec splitAuxPivot (n : _ N.node) (x : elt) pres : t * t = + let l,v,r = N.(left n , key n, right n) in + if x = v then begin + pres := true; + (l, r) + end + else if x < v then + match N.toOpt l with + | None -> + N.empty, N.return n + | Some l -> + let ll, rl = splitAuxPivot l x pres in + ll, N.join rl v r + else + match N.toOpt r with + | None -> + N.return n, N.empty + | Some r -> + let lr, rr = splitAuxPivot r x pres in + N.join l v lr, rr + +(* TODO: fix me, change the api to (t * t ) * bool *) +let split (t : t) (x : elt) : t * bool * t = + match N.toOpt t with + None -> + N.empty, false, N.empty + | Some n -> + let pres = ref false in + let l,r = splitAuxPivot n x pres in + l, !pres, r + + let rec union (s1 : t) (s2 : t) = match N.(toOpt s1, toOpt s2) with (None, _) -> s2 @@ -111,27 +155,28 @@ let rec union (s1 : t) (s2 : t) = if h1 >= h2 then if h2 = 1 then add s1 (N.key n2) else begin let l1, v1, r1 = N.(left n1, key n1, right n1) in - let (l2, _, r2) = splitAux n2 v1 in + let (l2, r2) = splitAuxNoPivot n2 v1 in N.join (union l1 l2) v1 (union r1 r2) end else if h1 = 1 then add s2 (N.key n1) else begin let l2, v2, r2 = N.(left n2 , key n2, right n2) in - let (l1, _, r1) = splitAux n1 v2 in + let (l1, r1) = splitAuxNoPivot n1 v2 in N.join (union l1 l2) v2 (union r1 r2) end let rec inter (s1 : t) (s2 : t) = match N.(toOpt s1, toOpt s2) with - (None, _) -> s1 - | (_, None) -> s2 + (None, _) + | (_, None) -> N.empty | Some n1, Some n2 (* (Node(l1, v1, r1, _), t2) *) -> let l1,v1,r1 = N.(left n1, key n1, right n1) in - match splitAux n2 v1 with - (l2, false, r2) -> - N.concat (inter l1 l2) (inter r1 r2) - | (l2, true, r2) -> - N.join (inter l1 l2) v1 (inter r1 r2) + let pres = ref false in + let l2,r2 = splitAuxPivot n2 v1 pres in + let ll = inter l1 l2 in + let rr = inter r1 r2 in + if !pres then N.join ll v1 rr + else N.concat ll rr let rec diff (s1 : t) (s2 : t) = match N.(toOpt s1, toOpt s2) with @@ -139,37 +184,14 @@ let rec diff (s1 : t) (s2 : t) = | (_, None) -> s1 | Some n1, Some n2 (* (Node(l1, v1, r1, _), t2) *) -> let l1,v1,r1 = N.(left n1, key n1, right n1) in - match splitAux n2 v1 with - (l2, false, r2) -> - N.join (diff l1 l2) v1 (diff r1 r2) - | (l2, true, r2) -> - N.concat (diff l1 l2) (diff r1 r2) + let pres = ref false in + let l2, r2 = splitAuxPivot n2 v1 pres in + let ll = diff l1 l2 in + let rr = diff r1 r2 in + if !pres then N.concat ll rr + else N.join ll v1 rr -let rec compare_aux e1 e2 = - match (e1, e2) with - (End, End) -> 0 - | (End, _) -> -1 - | (_, End) -> 1 - | (More(v1, r1, e1), More(v2, r2, e2)) -> - if (v1 : elt) <> v2 - then if v1 < v2 then -1 else 1 - else compare_aux (N.toEnum r1 e1) (N.toEnum r2 e2) - -let cmp s1 s2 = - compare_aux (N.toEnum s1 End) (N.toEnum s2 End) - -let rec eqAux (e1 : enumeration) e2 = - match (e1, e2) with - (End, End) -> true - | (End, More _) -> false - | (More _, End) -> false - | (More(v1, r1, e1), More(v2, r2, e2)) -> - v1 = v2 && - eqAux (N.toEnum r1 e1) (N.toEnum r2 e2) - -let eq s1 s2 = - eqAux (N.toEnum s1 End) (N.toEnum s2 End) (* This algorithm applies to BST, it does not need to be balanced tree *) let rec subset (s1 : t) (s2 : t) = diff --git a/lib/js/bs_internalSetInt.js b/lib/js/bs_internalSetInt.js index 4729032cc1..673ccfbb40 100644 --- a/lib/js/bs_internalSetInt.js +++ b/lib/js/bs_internalSetInt.js @@ -36,59 +36,6 @@ function add(t, x) { } } -function splitAux(n, x) { - var l = n.left; - var v = n.key; - var r = n.right; - if (x === v) { - return /* tuple */[ - l, - /* true */1, - r - ]; - } else if (x < v) { - if (l !== null) { - var match = splitAux(l, x); - return /* tuple */[ - match[0], - match[1], - Bs_internalAVLset.join(match[2], v, r) - ]; - } else { - return /* tuple */[ - null, - /* false */0, - n - ]; - } - } else if (r !== null) { - var match$1 = splitAux(r, x); - return /* tuple */[ - Bs_internalAVLset.join(l, v, match$1[0]), - match$1[1], - match$1[2] - ]; - } else { - return /* tuple */[ - n, - /* false */0, - null - ]; - } -} - -function split(t, x) { - if (t !== null) { - return splitAux(t, x); - } else { - return /* tuple */[ - null, - /* false */0, - null - ]; - } -} - function mem(_t, x) { while(true) { var t = _t; @@ -144,80 +91,6 @@ function remove(t, x) { } } -function union(s1, s2) { - if (s1 !== null) { - if (s2 !== null) { - var h1 = s1.h; - var h2 = s2.h; - if (h1 >= h2) { - if (h2 === 1) { - return add(s1, s2.key); - } else { - var l1 = s1.left; - var v1 = s1.key; - var r1 = s1.right; - var match = splitAux(s2, v1); - return Bs_internalAVLset.join(union(l1, match[0]), v1, union(r1, match[2])); - } - } else if (h1 === 1) { - return add(s2, s1.key); - } else { - var l2 = s2.left; - var v2 = s2.key; - var r2 = s2.right; - var match$1 = splitAux(s1, v2); - return Bs_internalAVLset.join(union(match$1[0], l2), v2, union(match$1[2], r2)); - } - } else { - return s1; - } - } else { - return s2; - } -} - -function inter(s1, s2) { - if (s1 !== null) { - if (s2 !== null) { - var l1 = s1.left; - var v1 = s1.key; - var r1 = s1.right; - var match = splitAux(s2, v1); - var l2 = match[0]; - if (match[1] !== 0) { - return Bs_internalAVLset.join(inter(l1, l2), v1, inter(r1, match[2])); - } else { - return Bs_internalAVLset.concat(inter(l1, l2), inter(r1, match[2])); - } - } else { - return s2; - } - } else { - return s1; - } -} - -function diff(s1, s2) { - if (s1 !== null) { - if (s2 !== null) { - var l1 = s1.left; - var v1 = s1.key; - var r1 = s1.right; - var match = splitAux(s2, v1); - var l2 = match[0]; - if (match[1] !== 0) { - return Bs_internalAVLset.concat(diff(l1, l2), diff(r1, match[2])); - } else { - return Bs_internalAVLset.join(diff(l1, l2), v1, diff(r1, match[2])); - } - } else { - return s1; - } - } else { - return s1; - } -} - function compare_aux(_e1, _e2) { while(true) { var e2 = _e2; @@ -282,6 +155,175 @@ function eq(s1, s2) { return eqAux(Bs_internalAVLset.toEnum(s1, /* End */0), Bs_internalAVLset.toEnum(s2, /* End */0)); } +function splitAuxNoPivot(n, x) { + var l = n.left; + var v = n.key; + var r = n.right; + if (x === v) { + return /* tuple */[ + l, + r + ]; + } else if (x < v) { + if (l !== null) { + var match = splitAuxNoPivot(l, x); + return /* tuple */[ + match[0], + Bs_internalAVLset.join(match[1], v, r) + ]; + } else { + return /* tuple */[ + null, + n + ]; + } + } else if (r !== null) { + var match$1 = splitAuxNoPivot(r, x); + return /* tuple */[ + Bs_internalAVLset.join(l, v, match$1[0]), + match$1[1] + ]; + } else { + return /* tuple */[ + n, + null + ]; + } +} + +function splitAuxPivot(n, x, pres) { + var l = n.left; + var v = n.key; + var r = n.right; + if (x === v) { + pres[0] = /* true */1; + return /* tuple */[ + l, + r + ]; + } else if (x < v) { + if (l !== null) { + var match = splitAuxPivot(l, x, pres); + return /* tuple */[ + match[0], + Bs_internalAVLset.join(match[1], v, r) + ]; + } else { + return /* tuple */[ + null, + n + ]; + } + } else if (r !== null) { + var match$1 = splitAuxPivot(r, x, pres); + return /* tuple */[ + Bs_internalAVLset.join(l, v, match$1[0]), + match$1[1] + ]; + } else { + return /* tuple */[ + n, + null + ]; + } +} + +function split(t, x) { + if (t !== null) { + var pres = [/* false */0]; + var match = splitAuxPivot(t, x, pres); + return /* tuple */[ + match[0], + pres[0], + match[1] + ]; + } else { + return /* tuple */[ + null, + /* false */0, + null + ]; + } +} + +function union(s1, s2) { + if (s1 !== null) { + if (s2 !== null) { + var h1 = s1.h; + var h2 = s2.h; + if (h1 >= h2) { + if (h2 === 1) { + return add(s1, s2.key); + } else { + var l1 = s1.left; + var v1 = s1.key; + var r1 = s1.right; + var match = splitAuxNoPivot(s2, v1); + return Bs_internalAVLset.join(union(l1, match[0]), v1, union(r1, match[1])); + } + } else if (h1 === 1) { + return add(s2, s1.key); + } else { + var l2 = s2.left; + var v2 = s2.key; + var r2 = s2.right; + var match$1 = splitAuxNoPivot(s1, v2); + return Bs_internalAVLset.join(union(match$1[0], l2), v2, union(match$1[1], r2)); + } + } else { + return s1; + } + } else { + return s2; + } +} + +function inter(s1, s2) { + if (s1 !== null) { + if (s2 !== null) { + var l1 = s1.left; + var v1 = s1.key; + var r1 = s1.right; + var pres = [/* false */0]; + var match = splitAuxPivot(s2, v1, pres); + var ll = inter(l1, match[0]); + var rr = inter(r1, match[1]); + if (pres[0]) { + return Bs_internalAVLset.join(ll, v1, rr); + } else { + return Bs_internalAVLset.concat(ll, rr); + } + } else { + return null; + } + } else { + return null; + } +} + +function diff(s1, s2) { + if (s1 !== null) { + if (s2 !== null) { + var l1 = s1.left; + var v1 = s1.key; + var r1 = s1.right; + var pres = [/* false */0]; + var match = splitAuxPivot(s2, v1, pres); + var ll = diff(l1, match[0]); + var rr = diff(r1, match[1]); + if (pres[0]) { + return Bs_internalAVLset.concat(ll, rr); + } else { + return Bs_internalAVLset.join(ll, v1, rr); + } + } else { + return s1; + } + } else { + return s1; + } +} + function subset(_s1, _s2) { while(true) { var s2 = _s2; @@ -509,17 +551,18 @@ var A = 0; exports.N = N; exports.A = A; exports.add = add; -exports.splitAux = splitAux; -exports.split = split; exports.mem = mem; exports.remove = remove; -exports.union = union; -exports.inter = inter; -exports.diff = diff; exports.compare_aux = compare_aux; exports.cmp = cmp; exports.eqAux = eqAux; exports.eq = eq; +exports.splitAuxNoPivot = splitAuxNoPivot; +exports.splitAuxPivot = splitAuxPivot; +exports.split = split; +exports.union = union; +exports.inter = inter; +exports.diff = diff; exports.subset = subset; exports.findOpt = findOpt; exports.findAssert = findAssert; diff --git a/lib/js/bs_internalSetString.js b/lib/js/bs_internalSetString.js index 4729032cc1..673ccfbb40 100644 --- a/lib/js/bs_internalSetString.js +++ b/lib/js/bs_internalSetString.js @@ -36,59 +36,6 @@ function add(t, x) { } } -function splitAux(n, x) { - var l = n.left; - var v = n.key; - var r = n.right; - if (x === v) { - return /* tuple */[ - l, - /* true */1, - r - ]; - } else if (x < v) { - if (l !== null) { - var match = splitAux(l, x); - return /* tuple */[ - match[0], - match[1], - Bs_internalAVLset.join(match[2], v, r) - ]; - } else { - return /* tuple */[ - null, - /* false */0, - n - ]; - } - } else if (r !== null) { - var match$1 = splitAux(r, x); - return /* tuple */[ - Bs_internalAVLset.join(l, v, match$1[0]), - match$1[1], - match$1[2] - ]; - } else { - return /* tuple */[ - n, - /* false */0, - null - ]; - } -} - -function split(t, x) { - if (t !== null) { - return splitAux(t, x); - } else { - return /* tuple */[ - null, - /* false */0, - null - ]; - } -} - function mem(_t, x) { while(true) { var t = _t; @@ -144,80 +91,6 @@ function remove(t, x) { } } -function union(s1, s2) { - if (s1 !== null) { - if (s2 !== null) { - var h1 = s1.h; - var h2 = s2.h; - if (h1 >= h2) { - if (h2 === 1) { - return add(s1, s2.key); - } else { - var l1 = s1.left; - var v1 = s1.key; - var r1 = s1.right; - var match = splitAux(s2, v1); - return Bs_internalAVLset.join(union(l1, match[0]), v1, union(r1, match[2])); - } - } else if (h1 === 1) { - return add(s2, s1.key); - } else { - var l2 = s2.left; - var v2 = s2.key; - var r2 = s2.right; - var match$1 = splitAux(s1, v2); - return Bs_internalAVLset.join(union(match$1[0], l2), v2, union(match$1[2], r2)); - } - } else { - return s1; - } - } else { - return s2; - } -} - -function inter(s1, s2) { - if (s1 !== null) { - if (s2 !== null) { - var l1 = s1.left; - var v1 = s1.key; - var r1 = s1.right; - var match = splitAux(s2, v1); - var l2 = match[0]; - if (match[1] !== 0) { - return Bs_internalAVLset.join(inter(l1, l2), v1, inter(r1, match[2])); - } else { - return Bs_internalAVLset.concat(inter(l1, l2), inter(r1, match[2])); - } - } else { - return s2; - } - } else { - return s1; - } -} - -function diff(s1, s2) { - if (s1 !== null) { - if (s2 !== null) { - var l1 = s1.left; - var v1 = s1.key; - var r1 = s1.right; - var match = splitAux(s2, v1); - var l2 = match[0]; - if (match[1] !== 0) { - return Bs_internalAVLset.concat(diff(l1, l2), diff(r1, match[2])); - } else { - return Bs_internalAVLset.join(diff(l1, l2), v1, diff(r1, match[2])); - } - } else { - return s1; - } - } else { - return s1; - } -} - function compare_aux(_e1, _e2) { while(true) { var e2 = _e2; @@ -282,6 +155,175 @@ function eq(s1, s2) { return eqAux(Bs_internalAVLset.toEnum(s1, /* End */0), Bs_internalAVLset.toEnum(s2, /* End */0)); } +function splitAuxNoPivot(n, x) { + var l = n.left; + var v = n.key; + var r = n.right; + if (x === v) { + return /* tuple */[ + l, + r + ]; + } else if (x < v) { + if (l !== null) { + var match = splitAuxNoPivot(l, x); + return /* tuple */[ + match[0], + Bs_internalAVLset.join(match[1], v, r) + ]; + } else { + return /* tuple */[ + null, + n + ]; + } + } else if (r !== null) { + var match$1 = splitAuxNoPivot(r, x); + return /* tuple */[ + Bs_internalAVLset.join(l, v, match$1[0]), + match$1[1] + ]; + } else { + return /* tuple */[ + n, + null + ]; + } +} + +function splitAuxPivot(n, x, pres) { + var l = n.left; + var v = n.key; + var r = n.right; + if (x === v) { + pres[0] = /* true */1; + return /* tuple */[ + l, + r + ]; + } else if (x < v) { + if (l !== null) { + var match = splitAuxPivot(l, x, pres); + return /* tuple */[ + match[0], + Bs_internalAVLset.join(match[1], v, r) + ]; + } else { + return /* tuple */[ + null, + n + ]; + } + } else if (r !== null) { + var match$1 = splitAuxPivot(r, x, pres); + return /* tuple */[ + Bs_internalAVLset.join(l, v, match$1[0]), + match$1[1] + ]; + } else { + return /* tuple */[ + n, + null + ]; + } +} + +function split(t, x) { + if (t !== null) { + var pres = [/* false */0]; + var match = splitAuxPivot(t, x, pres); + return /* tuple */[ + match[0], + pres[0], + match[1] + ]; + } else { + return /* tuple */[ + null, + /* false */0, + null + ]; + } +} + +function union(s1, s2) { + if (s1 !== null) { + if (s2 !== null) { + var h1 = s1.h; + var h2 = s2.h; + if (h1 >= h2) { + if (h2 === 1) { + return add(s1, s2.key); + } else { + var l1 = s1.left; + var v1 = s1.key; + var r1 = s1.right; + var match = splitAuxNoPivot(s2, v1); + return Bs_internalAVLset.join(union(l1, match[0]), v1, union(r1, match[1])); + } + } else if (h1 === 1) { + return add(s2, s1.key); + } else { + var l2 = s2.left; + var v2 = s2.key; + var r2 = s2.right; + var match$1 = splitAuxNoPivot(s1, v2); + return Bs_internalAVLset.join(union(match$1[0], l2), v2, union(match$1[1], r2)); + } + } else { + return s1; + } + } else { + return s2; + } +} + +function inter(s1, s2) { + if (s1 !== null) { + if (s2 !== null) { + var l1 = s1.left; + var v1 = s1.key; + var r1 = s1.right; + var pres = [/* false */0]; + var match = splitAuxPivot(s2, v1, pres); + var ll = inter(l1, match[0]); + var rr = inter(r1, match[1]); + if (pres[0]) { + return Bs_internalAVLset.join(ll, v1, rr); + } else { + return Bs_internalAVLset.concat(ll, rr); + } + } else { + return null; + } + } else { + return null; + } +} + +function diff(s1, s2) { + if (s1 !== null) { + if (s2 !== null) { + var l1 = s1.left; + var v1 = s1.key; + var r1 = s1.right; + var pres = [/* false */0]; + var match = splitAuxPivot(s2, v1, pres); + var ll = diff(l1, match[0]); + var rr = diff(r1, match[1]); + if (pres[0]) { + return Bs_internalAVLset.concat(ll, rr); + } else { + return Bs_internalAVLset.join(ll, v1, rr); + } + } else { + return s1; + } + } else { + return s1; + } +} + function subset(_s1, _s2) { while(true) { var s2 = _s2; @@ -509,17 +551,18 @@ var A = 0; exports.N = N; exports.A = A; exports.add = add; -exports.splitAux = splitAux; -exports.split = split; exports.mem = mem; exports.remove = remove; -exports.union = union; -exports.inter = inter; -exports.diff = diff; exports.compare_aux = compare_aux; exports.cmp = cmp; exports.eqAux = eqAux; exports.eq = eq; +exports.splitAuxNoPivot = splitAuxNoPivot; +exports.splitAuxPivot = splitAuxPivot; +exports.split = split; +exports.union = union; +exports.inter = inter; +exports.diff = diff; exports.subset = subset; exports.findOpt = findOpt; exports.findAssert = findAssert;