package grenier
Module Maxtrie.PatMapSource
Immutable maps whose keys are non-negative integers.
Maps use the representation of PatSet, with one binding per node instead of a bitmap: Patricia tries in which every node hoists the largest key of its subtree. A map with n bindings has exactly n nodes, there are no internal branching nodes, and the depth of a tree is bounded by the number of bits of an integer. The binding with the largest key is at the root.
Keys must be non-negative: add, singleton, and update raise Invalid_argument on a negative key; the other operations treat negative keys as absent.
See PatMapSharing for a variant whose comparisons unify equal subtrees.
The interface follows Stdlib.Map.S. Functions that take a key-dependent function apply it in increasing order of keys.
The type of maps from key to 'a.
Construction
add k v m binds k to v. If k is already bound to a value that is physically equal to v, then m itself is returned.
update k f m binds k according to f, which receives the current binding of k, if any. If f returns its argument (or None when there was no binding), then m itself is returned.
remove k m removes the binding of k. If k is not bound, then m itself is returned.
union f m1 m2 has the bindings of m1 and m2. When a key k is bound in both, to v1 and v2, f k v1 v2 decides: None drops the key, Some v binds it to v. If the result has the same keys as m2 and physically equal values, then m2 itself is returned.
inter f m1 m2 has the keys bound in both m1 and m2; for each such key k, bound to v1 and v2, f k v1 v2 decides the binding.
diff m1 m2 is m1 deprived of the keys bound in m2. If no key is removed, then m1 itself is returned.
filter p m has the bindings of m that satisfy p. If all of them do, then m itself is returned.
split k m is (l, data, r) where l has the bindings of m whose keys are less than k, r those whose keys are greater than k, and data is the binding of k, if any.
Queries
is_singleton m determines whether m has exactly one binding. Constant time.
max_binding m is the binding with the greatest key. Constant time.
choose m is a binding of m (currently max_binding m, which takes constant time).
find_first p m is the binding with the least key that satisfies p. Unlike Stdlib.Map.find_first, p need not be monotonic.
disjoint m1 m2 determines whether m1 and m2 have no key in common.
equal eq m1 m2 determines whether m1 and m2 have the same keys, bound to values related by eq.
compare cmp is a total order on maps, compatible with equal. It is a structural order, not the lexicographic order on bindings.
changes f m1 m2 calls f k x y, in increasing order of keys, for every key k such that x, the binding of k in m1, and y, its binding in m2, are not physically equal (None when there is no binding). Subtrees that the two maps share are skipped without being visited, so when m2 was derived from m1 by a few updates, the cost depends on the number of updates (times the depth), not on the size of the maps. Does not allocate (besides what f does and the options it receives).
Iteration
bindings m is the list of the bindings of m in increasing order of keys.