remove

fun remove(element: E): Patch<ORSet<E>>

Remove element — and return the change: the dots currently on it, retired, and nothing else. Absorbing that patch drops the element; the retired dots stay witnessed, so the removal propagates on merge. To hold the resulting set locally, set.piece(set.remove(…)).

The context carries exactly element's live dots — never the sender's full history. A delta that carried the whole context would be indistinguishable from "I have removed everything I ever saw", and joining it would empty the receiver's set.

Removing an element that is absent yields the lattice identity — an empty store and an empty context — so absorbing it changes nothing.

Samples

val a = ReplicaId("A")
val b = ReplicaId("B")

// Two peers have converged: "alice" is present on both, added by B.
var alpha = ORSet.empty<String>().piece { it.add(b, "alice") }
var bravo = alpha

// A re-adds "alice" and puts only the change on the wire. The delta names A's new dot
// *and* B's older one, which the re-add supersedes — so both peers drop the old dot.
val readd = alpha.add(a, "alice")
alpha = alpha.piece(readd)
bravo = bravo.piece(readd)
check(alpha == bravo)

// A concurrent add beats a concurrent remove: B's re-add mints a dot A's remove never saw.
val concurrent = alpha.add(b, "alice")
check(alpha.piece(alpha.remove("alice")).piece(concurrent).contains("alice"))

// A remove lands everywhere, because both peers agree on which dot is live. Had the delta
// above kept quiet about B's dot, it would still be alive on bravo — and "alice" would come
// back from the dead there.
val forget = alpha.remove("alice")
alpha = alpha.piece(forget)
bravo = bravo.piece(forget)
check(!alpha.contains("alice"))
check(!bravo.contains("alice"))