From 7c7f66cd7b7b5598d0acfa53a1c98efa98a0fe8a Mon Sep 17 00:00:00 2001 From: Fardale Date: Fri, 26 Jan 2018 09:31:29 +0100 Subject: [PATCH 1/5] Add CCHeap.delete_all --- src/core/CCHeap.ml | 14 ++++++++++++++ src/core/CCHeap.mli | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/src/core/CCHeap.ml b/src/core/CCHeap.ml index db0409db..4917db07 100644 --- a/src/core/CCHeap.ml +++ b/src/core/CCHeap.ml @@ -118,6 +118,10 @@ module type S = sig (** Same as {!take}, but can fail. @raise Empty if the heap is empty *) + val delete_all : (elt -> elt -> bool) -> elt -> t -> t + (** Delete value if it exist in the heap. + [delete_all eq x h], use [eq] to find all [x] in [h] and delete them *) + val iter : (elt -> unit) -> t -> unit (** Iterate on elements *) @@ -243,6 +247,16 @@ module Make(E : PARTIAL_ORD) : S with type elt = E.t = struct | E -> raise Empty | N (_, x, l, r) -> merge l r, x + let rec delete_all eq x = function + | E -> E + | N (_, y, l, r) as h -> + if eq x y then merge (delete_all eq x l) (delete_all eq x r) + else begin + if E.leq y x + then _make_node y (delete_all eq x l) (delete_all eq x r) + else h + end + let rec iter f h = match h with | E -> () | N(_,x,l,r) -> f x; iter f l; iter f r diff --git a/src/core/CCHeap.mli b/src/core/CCHeap.mli index 663ff9f4..54d65353 100644 --- a/src/core/CCHeap.mli +++ b/src/core/CCHeap.mli @@ -55,6 +55,10 @@ module type S = sig (** Same as {!take}, but can fail. @raise Empty if the heap is empty *) + val delete_all : (elt -> elt -> bool) -> elt -> t -> t + (** Delete value if it exist in the heap. + [delete_all eq x h], use [eq] to find all [x] in [h] and delete them *) + val iter : (elt -> unit) -> t -> unit (** Iterate on elements *) From 4e9eeb50e5b50857802f2f7bd3cd80eabcff9603 Mon Sep 17 00:00:00 2001 From: Fardale Date: Sat, 27 Jan 2018 23:48:47 +0100 Subject: [PATCH 2/5] add @since for delete_all --- src/core/CCHeap.mli | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/CCHeap.mli b/src/core/CCHeap.mli index 54d65353..dca9f91e 100644 --- a/src/core/CCHeap.mli +++ b/src/core/CCHeap.mli @@ -57,7 +57,8 @@ module type S = sig val delete_all : (elt -> elt -> bool) -> elt -> t -> t (** Delete value if it exist in the heap. - [delete_all eq x h], use [eq] to find all [x] in [h] and delete them *) + [delete_all eq x h], use [eq] to find all [x] in [h] and delete them + @since NEXT_RELEASE *) val iter : (elt -> unit) -> t -> unit (** Iterate on elements *) From 50d970852e45957ca01bf94e33d930f41b9b930a Mon Sep 17 00:00:00 2001 From: Fardale Date: Sun, 28 Jan 2018 12:36:37 +0100 Subject: [PATCH 3/5] [CCHeap] update comment delete_all --- src/core/CCHeap.ml | 7 +++++-- src/core/CCHeap.mli | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/core/CCHeap.ml b/src/core/CCHeap.ml index 4917db07..b85ce53f 100644 --- a/src/core/CCHeap.ml +++ b/src/core/CCHeap.ml @@ -119,8 +119,11 @@ module type S = sig @raise Empty if the heap is empty *) val delete_all : (elt -> elt -> bool) -> elt -> t -> t - (** Delete value if it exist in the heap. - [delete_all eq x h], use [eq] to find all [x] in [h] and delete them *) + (** Delete all occurrences of a value in the heap. + [delete_all eq x h], use [eq] to find all [x] in [h] and delete them. + If [h] do not contain [x] then it return [h]. + The difference with {!filter} is that [delete_all] stops as soon as + it enters a subtree whose root is bigger than the element *) val iter : (elt -> unit) -> t -> unit (** Iterate on elements *) diff --git a/src/core/CCHeap.mli b/src/core/CCHeap.mli index dca9f91e..ac320aef 100644 --- a/src/core/CCHeap.mli +++ b/src/core/CCHeap.mli @@ -56,8 +56,11 @@ module type S = sig @raise Empty if the heap is empty *) val delete_all : (elt -> elt -> bool) -> elt -> t -> t - (** Delete value if it exist in the heap. - [delete_all eq x h], use [eq] to find all [x] in [h] and delete them + (** Delete all occurrences of a value in the heap. + [delete_all eq x h], use [eq] to find all [x] in [h] and delete them. + If [h] do not contain [x] then it return [h]. + The difference with {!filter} is that [delete_all] stops as soon as + it enters a subtree whose root is bigger than the element @since NEXT_RELEASE *) val iter : (elt -> unit) -> t -> unit From 8ac62ca04b1b34c32e895829833ccc09e3406438 Mon Sep 17 00:00:00 2001 From: Fardale Date: Sun, 28 Jan 2018 12:37:21 +0100 Subject: [PATCH 4/5] [CCHeap] add delete_once --- src/core/CCHeap.ml | 25 +++++++++++++++++++++++++ src/core/CCHeap.mli | 6 ++++++ 2 files changed, 31 insertions(+) diff --git a/src/core/CCHeap.ml b/src/core/CCHeap.ml index b85ce53f..238186e0 100644 --- a/src/core/CCHeap.ml +++ b/src/core/CCHeap.ml @@ -118,6 +118,11 @@ module type S = sig (** Same as {!take}, but can fail. @raise Empty if the heap is empty *) + val delete_once : (elt -> elt -> bool) -> elt -> t -> t + (** Delete one occurence of a value if it exist in the heap. + [delete_once eq x h], use [eq] to find one [x] in [h] and delete it. + If [h] do not contain [x] then it return [h]. *) + val delete_all : (elt -> elt -> bool) -> elt -> t -> t (** Delete all occurrences of a value in the heap. [delete_all eq x h], use [eq] to find all [x] in [h] and delete them. @@ -250,6 +255,26 @@ module Make(E : PARTIAL_ORD) : S with type elt = E.t = struct | E -> raise Empty | N (_, x, l, r) -> merge l r, x + let delete_once eq x h = + let rec aux = function + | E -> false, E + | N(_, y, l, r) as h -> begin + if eq x y then true, merge l r + else begin + if E.leq y x + then begin + let found_left, l1 = aux l in + let found, r1 = if found_left then true, r else aux r in + if found + then true, _make_node y l1 r1 + else false, h + end + else false, h + end + end + in + snd (aux h) + let rec delete_all eq x = function | E -> E | N (_, y, l, r) as h -> diff --git a/src/core/CCHeap.mli b/src/core/CCHeap.mli index ac320aef..d47a6899 100644 --- a/src/core/CCHeap.mli +++ b/src/core/CCHeap.mli @@ -55,6 +55,12 @@ module type S = sig (** Same as {!take}, but can fail. @raise Empty if the heap is empty *) + val delete_once : (elt -> elt -> bool) -> elt -> t -> t + (** Delete one occurence of a value if it exist in the heap. + [delete_once eq x h], use [eq] to find one [x] in [h] and delete it. + If [h] do not contain [x] then it return [h]. + @since NEXT_RELEASE *) + val delete_all : (elt -> elt -> bool) -> elt -> t -> t (** Delete all occurrences of a value in the heap. [delete_all eq x h], use [eq] to find all [x] in [h] and delete them. From 8c2cb3f24499487fb5e9ccff85c34847a084d41a Mon Sep 17 00:00:00 2001 From: Fardale Date: Sun, 28 Jan 2018 12:39:44 +0100 Subject: [PATCH 5/5] [CCHeap] delete_once -> delete_one --- src/core/CCHeap.ml | 6 +++--- src/core/CCHeap.mli | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core/CCHeap.ml b/src/core/CCHeap.ml index 238186e0..42949926 100644 --- a/src/core/CCHeap.ml +++ b/src/core/CCHeap.ml @@ -118,9 +118,9 @@ module type S = sig (** Same as {!take}, but can fail. @raise Empty if the heap is empty *) - val delete_once : (elt -> elt -> bool) -> elt -> t -> t + val delete_one : (elt -> elt -> bool) -> elt -> t -> t (** Delete one occurence of a value if it exist in the heap. - [delete_once eq x h], use [eq] to find one [x] in [h] and delete it. + [delete_one eq x h], use [eq] to find one [x] in [h] and delete it. If [h] do not contain [x] then it return [h]. *) val delete_all : (elt -> elt -> bool) -> elt -> t -> t @@ -255,7 +255,7 @@ module Make(E : PARTIAL_ORD) : S with type elt = E.t = struct | E -> raise Empty | N (_, x, l, r) -> merge l r, x - let delete_once eq x h = + let delete_one eq x h = let rec aux = function | E -> false, E | N(_, y, l, r) as h -> begin diff --git a/src/core/CCHeap.mli b/src/core/CCHeap.mli index d47a6899..6e8ae7f2 100644 --- a/src/core/CCHeap.mli +++ b/src/core/CCHeap.mli @@ -55,9 +55,9 @@ module type S = sig (** Same as {!take}, but can fail. @raise Empty if the heap is empty *) - val delete_once : (elt -> elt -> bool) -> elt -> t -> t + val delete_one : (elt -> elt -> bool) -> elt -> t -> t (** Delete one occurence of a value if it exist in the heap. - [delete_once eq x h], use [eq] to find one [x] in [h] and delete it. + [delete_one eq x h], use [eq] to find one [x] in [h] and delete it. If [h] do not contain [x] then it return [h]. @since NEXT_RELEASE *)