This PR corrects some inconsistencies in `TreeMap`/`HashMap` grind annotations, for `isSome_get?_eq_contains` and `empty_eq_emptyc`.
1156 lines
44 KiB
Text
1156 lines
44 KiB
Text
/-
|
||
Copyright (c) 2024 Lean FRO, LLC. All rights reserved.
|
||
Released under Apache 2.0 license as described in the file LICENSE.
|
||
Authors: Markus Himmel, Paul Reichert
|
||
-/
|
||
prelude
|
||
import Std.Data.DTreeMap.Internal.WF.Defs
|
||
|
||
/-!
|
||
# Dependent tree maps
|
||
|
||
This file develops the type `Std.DTreeMap` of dependent tree maps.
|
||
|
||
Lemmas about the operations on `Std.DTreeMap` will be available in the
|
||
module `Std.Data.DTreeMap.Lemmas`.
|
||
|
||
See the module `Std.Data.DTreeMap.Raw.Basic` for a variant of this type which is safe to use in
|
||
nested inductive types and `Std.Data.ExtDTreeMap.Basic` for a variant with extensionality.
|
||
-/
|
||
|
||
set_option autoImplicit false
|
||
set_option linter.missingDocs true
|
||
|
||
universe u v w w₂
|
||
|
||
variable {α : Type u} {β : α → Type v} {cmp : α → α → Ordering}
|
||
private local instance : Coe (Type v) (α → Type v) where coe γ := fun _ => γ
|
||
|
||
namespace Std
|
||
|
||
/--
|
||
Dependent tree maps.
|
||
|
||
A tree map stores an assignment of keys to values. It depends on a comparator function that
|
||
defines an ordering on the keys and provides efficient order-dependent queries, such as retrieval
|
||
of the minimum or maximum.
|
||
|
||
To ensure that the operations behave as expected, the comparator function `cmp` should satisfy
|
||
certain laws that ensure a consistent ordering:
|
||
|
||
* If `a` is less than (or equal) to `b`, then `b` is greater than (or equal) to `a`
|
||
and vice versa (see the `OrientedCmp` typeclass).
|
||
* If `a` is less than or equal to `b` and `b` is, in turn, less than or equal to `c`, then `a`
|
||
is less than or equal to `c` (see the `TransCmp` typeclass).
|
||
|
||
Keys for which `cmp a b = Ordering.eq` are considered the same, i.e., there can be only one entry
|
||
with key either `a` or `b` in a tree map. Looking up either `a` or `b` always yields the same entry,
|
||
if any is present. The `get` operations of the _dependent_ tree map additionally require a
|
||
`LawfulEqCmp` instance to ensure that `cmp a b = .eq` always implies `a = b`, so that their
|
||
respective value types are equal.
|
||
|
||
To avoid expensive copies, users should make sure that the tree map is used linearly.
|
||
|
||
Internally, the tree maps are represented as size-bounded trees, a type of self-balancing binary
|
||
search tree with efficient order statistic lookups.
|
||
|
||
For use in proofs, the type `Std.ExtDTreeMap` of extensional dependent tree maps should be
|
||
preferred. This type comes with several extensionality lemmas and provides the same functions but
|
||
requires a `TransCmp` instance to work with.
|
||
|
||
These tree maps contain a bundled well-formedness invariant, which means that they cannot
|
||
be used in nested inductive types. For these use cases, `Std.DTreeMap.Raw` and
|
||
`Std.DTreeMap.Raw.WF` unbundle the invariant from the tree map. When in doubt, prefer
|
||
`DTreeMap` over `DTreeMap.Raw`.
|
||
-/
|
||
structure DTreeMap (α : Type u) (β : α → Type v) (cmp : α → α → Ordering := by exact compare) where
|
||
/-- Internal implementation detail of the tree map. -/
|
||
inner : DTreeMap.Internal.Impl α β
|
||
/-- Internal implementation detail of the tree map. -/
|
||
wf : letI : Ord α := ⟨cmp⟩; inner.WF
|
||
|
||
namespace DTreeMap
|
||
open Internal (Impl)
|
||
|
||
/--
|
||
Creates a new empty tree map. It is also possible and recommended to
|
||
use the empty collection notations `∅` and `{}` to create an empty tree map. `simp` replaces
|
||
`empty` with `∅`.
|
||
-/
|
||
@[inline]
|
||
def empty : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨Internal.Impl.empty, .empty⟩
|
||
|
||
instance : EmptyCollection (DTreeMap α β cmp) where
|
||
emptyCollection := empty
|
||
|
||
instance : Inhabited (DTreeMap α β cmp) where
|
||
default := ∅
|
||
|
||
@[inherit_doc Impl.Equiv]
|
||
structure Equiv (m₁ m₂ : DTreeMap α β cmp) where
|
||
/-- Internal implementation detail of the tree map -/
|
||
inner : m₁.1.Equiv m₂.1
|
||
|
||
@[inherit_doc] scoped infix:50 " ~m " => Equiv
|
||
|
||
@[simp, grind =]
|
||
theorem empty_eq_emptyc : (empty : DTreeMap α β cmp) = ∅ :=
|
||
rfl
|
||
|
||
/--
|
||
Inserts the given mapping into the map. If there is already a mapping for the given key, then both
|
||
key and value will be replaced.
|
||
-/
|
||
@[inline]
|
||
def insert (t : DTreeMap α β cmp) (a : α) (b : β a) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨(t.inner.insert a b t.wf.balanced).impl, .insert t.wf⟩
|
||
|
||
instance : Singleton ((a : α) × β a) (DTreeMap α β cmp) where
|
||
singleton e := (∅ : DTreeMap α β cmp).insert e.1 e.2
|
||
|
||
instance : Insert ((a : α) × β a) (DTreeMap α β cmp) where
|
||
insert e s := s.insert e.1 e.2
|
||
|
||
instance : LawfulSingleton ((a : α) × β a) (DTreeMap α β cmp) where
|
||
insert_empty_eq _ := rfl
|
||
|
||
/--
|
||
If there is no mapping for the given key, inserts the given mapping into the map. Otherwise,
|
||
returns the map unaltered.
|
||
-/
|
||
@[inline]
|
||
def insertIfNew (t : DTreeMap α β cmp) (a : α) (b : β a) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨(t.inner.insertIfNew a b t.wf.balanced).impl, t.wf.insertIfNew⟩
|
||
|
||
/--
|
||
Checks whether a key is present in a map and unconditionally inserts a value for the key.
|
||
|
||
Equivalent to (but potentially faster than) calling `contains` followed by `insert`.
|
||
-/
|
||
@[inline]
|
||
def containsThenInsert (t : DTreeMap α β cmp) (a : α) (b : β a) : Bool × DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩
|
||
let p := t.inner.containsThenInsert a b t.wf.balanced
|
||
(p.1, ⟨p.2.impl, t.wf.containsThenInsert⟩)
|
||
|
||
/--
|
||
Checks whether a key is present in a map and inserts a value for the key if it was not found.
|
||
If the returned `Bool` is `true`, then the returned map is unaltered. If the `Bool` is `false`,
|
||
then the returned map has a new value inserted.
|
||
|
||
Equivalent to (but potentially faster than) calling `contains` followed by `insertIfNew`.
|
||
-/
|
||
@[inline]
|
||
def containsThenInsertIfNew (t : DTreeMap α β cmp) (a : α) (b : β a) :
|
||
Bool × DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩
|
||
let p := t.inner.containsThenInsertIfNew a b t.wf.balanced
|
||
(p.1, ⟨p.2.impl, t.wf.containsThenInsertIfNew⟩)
|
||
|
||
/--
|
||
Checks whether a key is present in a map, returning the associated value, and inserts a value for
|
||
the key if it was not found.
|
||
|
||
If the returned value is `some v`, then the returned map is unaltered. If it is `none`, then the
|
||
returned map has a new value inserted.
|
||
|
||
Equivalent to (but potentially faster than) calling `get?` followed by `insertIfNew`.
|
||
|
||
Uses the `LawfulEqCmp` instance to cast the retrieved value to the correct type.
|
||
-/
|
||
@[inline]
|
||
def getThenInsertIfNew? [LawfulEqCmp cmp] (t : DTreeMap α β cmp) (a : α) (b : β a) :
|
||
Option (β a) × DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩
|
||
let p := t.inner.getThenInsertIfNew? a b t.wf.balanced
|
||
(p.1, ⟨p.2, t.wf.getThenInsertIfNew?⟩)
|
||
|
||
/--
|
||
Returns `true` if there is a mapping for the given key `a` or a key that is equal to `a` according
|
||
to the comparator `cmp`. There is also a `Prop`-valued version
|
||
of this: `a ∈ t` is equivalent to `t.contains a = true`.
|
||
|
||
Observe that this is different behavior than for lists: for lists, `∈` uses `=` and `contains` uses
|
||
`==` for equality checks, while for tree maps, both use the given comparator `cmp`.
|
||
-/
|
||
@[inline]
|
||
def contains (t : DTreeMap α β cmp) (a : α) : Bool :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.contains a
|
||
|
||
instance : Membership α (DTreeMap α β cmp) where
|
||
mem m a := m.contains a
|
||
|
||
instance {m : DTreeMap α β cmp} {a : α} : Decidable (a ∈ m) :=
|
||
inferInstanceAs <| Decidable (m.contains a)
|
||
|
||
/-- Returns the number of mappings present in the map. -/
|
||
@[inline]
|
||
def size (t : DTreeMap α β cmp) : Nat :=
|
||
t.inner.size
|
||
|
||
/-- Returns `true` if the tree map contains no mappings. -/
|
||
@[inline]
|
||
def isEmpty (t : DTreeMap α β cmp) : Bool :=
|
||
t.inner.isEmpty
|
||
|
||
/-- Removes the mapping for the given key if it exists. -/
|
||
@[inline]
|
||
def erase (t : DTreeMap α β cmp) (a : α) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨(t.inner.erase a t.wf.balanced).impl, .erase t.wf⟩
|
||
|
||
/--
|
||
Tries to retrieve the mapping for the given key, returning `none` if no such mapping is present.
|
||
|
||
Uses the `LawfulEqCmp` instance to cast the retrieved value to the correct type.
|
||
-/
|
||
@[inline]
|
||
def get? [LawfulEqCmp cmp] (t : DTreeMap α β cmp) (a : α) : Option (β a) :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.get? a
|
||
|
||
@[inline, inherit_doc get?, deprecated get? (since := "2025-02-12")]
|
||
def find? [LawfulEqCmp cmp] (t : DTreeMap α β cmp) (a : α) : Option (β a) :=
|
||
t.get? a
|
||
|
||
/--
|
||
Given a proof that a mapping for the given key is present, retrieves the mapping for the given key.
|
||
|
||
Uses the `LawfulEqCmp` instance to cast the retrieved value to the correct type.
|
||
-/
|
||
@[inline]
|
||
def get [LawfulEqCmp cmp] (t : DTreeMap α β cmp) (a : α) (h : a ∈ t) : β a :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.get a h
|
||
|
||
/--
|
||
Tries to retrieve the mapping for the given key, panicking if no such mapping is present.
|
||
|
||
Uses the `LawfulEqCmp` instance to cast the retrieved value to the correct type.
|
||
-/
|
||
@[inline]
|
||
def get! [LawfulEqCmp cmp] (t : DTreeMap α β cmp) (a : α) [Inhabited (β a)] : β a :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.get! a
|
||
|
||
@[inline, inherit_doc get!, deprecated get! (since := "2025-02-12")]
|
||
def find! [LawfulEqCmp cmp] (t : DTreeMap α β cmp) (a : α) [Inhabited (β a)] : β a :=
|
||
t.get! a
|
||
|
||
/--
|
||
Tries to retrieve the mapping for the given key, returning `fallback` if no such mapping is present.
|
||
|
||
Uses the `LawfulEqCmp` instance to cast the retrieved value to the correct type.
|
||
-/
|
||
@[inline]
|
||
def getD [LawfulEqCmp cmp] (t : DTreeMap α β cmp) (a : α) (fallback : β a) : β a :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.getD a fallback
|
||
|
||
@[inline, inherit_doc getD, deprecated getD (since := "2025-02-12")]
|
||
def findD [LawfulEqCmp cmp] (t : DTreeMap α β cmp) (a : α) (fallback : β a) : β a :=
|
||
t.getD a fallback
|
||
|
||
/--
|
||
Checks if a mapping for the given key exists and returns the key if it does, otherwise `none`.
|
||
The result in the `some` case is guaranteed to be pointer equal to the key in the map.
|
||
-/
|
||
@[inline]
|
||
def getKey? (t : DTreeMap α β cmp) (a : α) : Option α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.getKey? a
|
||
|
||
/--
|
||
Retrieves the key from the mapping that matches `a`. Ensures that such a mapping exists by
|
||
requiring a proof of `a ∈ m`. The result is guaranteed to be pointer equal to the key in the map.
|
||
-/
|
||
@[inline]
|
||
def getKey (t : DTreeMap α β cmp) (a : α) (h : a ∈ t) : α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.getKey a h
|
||
|
||
/--
|
||
Checks if a mapping for the given key exists and returns the key if it does, otherwise panics.
|
||
If no panic occurs the result is guaranteed to be pointer equal to the key in the map.
|
||
-/
|
||
@[inline]
|
||
def getKey! [Inhabited α] (t : DTreeMap α β cmp) (a : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.getKey! a
|
||
|
||
/--
|
||
Checks if a mapping for the given key exists and returns the key if it does, otherwise `fallback`.
|
||
If a mapping exists the result is guaranteed to be pointer equal to the key in the map.
|
||
-/
|
||
@[inline]
|
||
def getKeyD (t : DTreeMap α β cmp) (a : α) (fallback : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.getKeyD a fallback
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the smallest key in the tree map, returning `none` if the
|
||
map is empty.
|
||
-/
|
||
@[inline]
|
||
def minEntry? (t : DTreeMap α β cmp) : Option ((a : α) × β a) :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.minEntry?
|
||
|
||
@[inline, inherit_doc minEntry?, deprecated minEntry? (since := "2025-03-13")]
|
||
def min? (t : DTreeMap α β cmp) : Option ((a : α) × β a) :=
|
||
t.minEntry?
|
||
|
||
/--
|
||
Given a proof that the tree map is not empty, retrieves the key-value pair with the smallest key.
|
||
-/
|
||
@[inline]
|
||
def minEntry (t : DTreeMap α β cmp) (h : t.isEmpty = false) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.minEntry h
|
||
|
||
@[inline, inherit_doc minEntry, deprecated minEntry (since := "2025-03-13")]
|
||
def min (t : DTreeMap α β cmp) (h : t.isEmpty = false) : (a : α) × β a :=
|
||
t.minEntry h
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the smallest key in the tree map, panicking if the map is
|
||
empty.
|
||
-/
|
||
@[inline]
|
||
def minEntry! [Inhabited ((a : α) × β a)] (t : DTreeMap α β cmp) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.minEntry!
|
||
|
||
@[inline, inherit_doc minEntry!, deprecated minEntry! (since := "2025-03-13")]
|
||
def min! [Inhabited ((a : α) × β a)] (t : DTreeMap α β cmp) : (a : α) × β a :=
|
||
t.minEntry!
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the smallest key in the tree map, returning `fallback` if
|
||
the tree map is empty.
|
||
-/
|
||
@[inline]
|
||
def minEntryD (t : DTreeMap α β cmp) (fallback : (a : α) × β a) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.minEntryD fallback
|
||
|
||
@[inline, inherit_doc minEntryD, deprecated minEntryD (since := "2025-03-13")]
|
||
def minD (t : DTreeMap α β cmp) (fallback : (a : α) × β a) : (a : α) × β a :=
|
||
t.minEntryD fallback
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the largest key in the tree map, returning `none` if the
|
||
map is empty.
|
||
-/
|
||
@[inline]
|
||
def maxEntry? (t : DTreeMap α β cmp) : Option ((a : α) × β a) :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.maxEntry?
|
||
|
||
@[inline, inherit_doc maxEntry?, deprecated maxEntry? (since := "2025-03-13")]
|
||
def max? (t : DTreeMap α β cmp) : Option ((a : α) × β a) :=
|
||
t.maxEntry?
|
||
|
||
/--
|
||
Given a proof that the tree map is not empty, retrieves the key-value pair with the largest key.
|
||
-/
|
||
@[inline]
|
||
def maxEntry (t : DTreeMap α β cmp) (h : t.isEmpty = false) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.maxEntry h
|
||
|
||
@[inline, inherit_doc maxEntry, deprecated maxEntry (since := "2025-03-13")]
|
||
def max (t : DTreeMap α β cmp) (h : t.isEmpty = false) : (a : α) × β a :=
|
||
t.maxEntry h
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the largest key in the tree map, panicking if the map is
|
||
empty.
|
||
-/
|
||
@[inline]
|
||
def maxEntry! [Inhabited ((a : α) × β a)] (t : DTreeMap α β cmp) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.maxEntry!
|
||
|
||
@[inline, inherit_doc maxEntry!, deprecated maxEntry! (since := "2025-03-13")]
|
||
def max! [Inhabited ((a : α) × β a)] (t : DTreeMap α β cmp) : (a : α) × β a :=
|
||
t.maxEntry!
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the largest key in the tree map, returning `fallback` if
|
||
the tree map is empty.
|
||
-/
|
||
@[inline]
|
||
def maxEntryD (t : DTreeMap α β cmp) (fallback : (a : α) × β a) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.maxEntryD fallback
|
||
|
||
@[inline, inherit_doc maxEntryD, deprecated maxEntryD (since := "2025-03-13")]
|
||
def maxD (t : DTreeMap α β cmp) (fallback : (a : α) × β a) : (a : α) × β a :=
|
||
t.maxEntryD fallback
|
||
|
||
/--
|
||
Tries to retrieve the smallest key in the tree map, returning `none` if the map is empty.
|
||
-/
|
||
@[inline]
|
||
def minKey? (t : DTreeMap α β cmp) : Option α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.minKey?
|
||
|
||
/--
|
||
Given a proof that the tree map is not empty, retrieves the smallest key.
|
||
-/
|
||
@[inline]
|
||
def minKey (t : DTreeMap α β cmp) (h : t.isEmpty = false) : α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.minKey h
|
||
|
||
/--
|
||
Tries to retrieve the smallest key in the tree map, panicking if the map is empty.
|
||
-/
|
||
@[inline]
|
||
def minKey! [Inhabited α] (t : DTreeMap α β cmp) : α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.minKey!
|
||
|
||
/--
|
||
Tries to retrieve the smallest key in the tree map, returning `fallback` if the tree map is empty.
|
||
-/
|
||
@[inline]
|
||
def minKeyD (t : DTreeMap α β cmp) (fallback : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.minKeyD fallback
|
||
|
||
/--
|
||
Tries to retrieve the largest key in the tree map, returning `none` if the map is empty.
|
||
-/
|
||
@[inline]
|
||
def maxKey? (t : DTreeMap α β cmp) : Option α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.maxKey?
|
||
|
||
/--
|
||
Given a proof that the tree map is not empty, retrieves the largest key.
|
||
-/
|
||
@[inline]
|
||
def maxKey (t : DTreeMap α β cmp) (h : t.isEmpty = false) : α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.maxKey h
|
||
|
||
/--
|
||
Tries to retrieve the largest key in the tree map, panicking if the map is empty.
|
||
-/
|
||
@[inline]
|
||
def maxKey! [Inhabited α] (t : DTreeMap α β cmp) : α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.maxKey!
|
||
|
||
/--
|
||
Tries to retrieve the largest key in the tree map, returning `fallback` if the tree map is empty.
|
||
-/
|
||
@[inline]
|
||
def maxKeyD (t : DTreeMap α β cmp) (fallback : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.maxKeyD fallback
|
||
|
||
/-- Returns the key-value pair with the `n`-th smallest key, or `none` if `n` is at least `t.size`. -/
|
||
@[inline]
|
||
def entryAtIdx? (t : DTreeMap α β cmp) (n : Nat) : Option ((a : α) × β a) :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.entryAtIdx? n
|
||
|
||
/-- Returns the key-value pair with the `n`-th smallest key. -/
|
||
@[inline]
|
||
def entryAtIdx (t : DTreeMap α β cmp) (n : Nat) (h : n < t.size) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.entryAtIdx t.inner t.wf.balanced n h
|
||
|
||
/-- Returns the key-value pair with the `n`-th smallest key, or panics if `n` is at least `t.size`. -/
|
||
@[inline]
|
||
def entryAtIdx! [Inhabited ((a : α) × β a)] (t : DTreeMap α β cmp) (n : Nat) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.entryAtIdx! n
|
||
|
||
/-- Returns the key-value pair with the `n`-th smallest key, or `fallback` if `n` is at least `t.size`. -/
|
||
@[inline]
|
||
def entryAtIdxD (t : DTreeMap α β cmp) (n : Nat)
|
||
(fallback : (a : α) × β a) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.entryAtIdxD n fallback
|
||
|
||
/-- Returns the `n`-th smallest key, or `none` if `n` is at least `t.size`. -/
|
||
@[inline]
|
||
def keyAtIdx? (t : DTreeMap α β cmp) (n : Nat) : Option α :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.keyAtIdx? t.inner n
|
||
|
||
@[inline, inherit_doc keyAtIdx?, deprecated keyAtIdx? (since := "2025-03-25")]
|
||
def keyAtIndex? (t : DTreeMap α β cmp) (n : Nat) : Option α :=
|
||
keyAtIdx? t n
|
||
|
||
/-- Returns the `n`-th smallest key. -/
|
||
@[inline]
|
||
def keyAtIdx (t : DTreeMap α β cmp) (n : Nat) (h : n < t.size) : α :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.keyAtIdx t.inner t.wf.balanced n h
|
||
|
||
@[inline, inherit_doc keyAtIdx, deprecated keyAtIdx (since := "2025-03-25")]
|
||
def keyAtIndex (t : DTreeMap α β cmp) (n : Nat) (h : n < t.size) : α :=
|
||
keyAtIdx t n h
|
||
|
||
/-- Returns the `n`-th smallest key, or panics if `n` is at least `t.size`. -/
|
||
@[inline]
|
||
def keyAtIdx! [Inhabited α] (t : DTreeMap α β cmp) (n : Nat) : α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.keyAtIdx! n
|
||
|
||
@[inline, inherit_doc keyAtIdx!, deprecated keyAtIdx! (since := "2025-03-25")]
|
||
def keyAtIndex! [Inhabited α] (t : DTreeMap α β cmp) (n : Nat) : α :=
|
||
keyAtIdx! t n
|
||
|
||
/-- Returns the `n`-th smallest key, or `fallback` if `n` is at least `t.size`. -/
|
||
@[inline]
|
||
def keyAtIdxD (t : DTreeMap α β cmp) (n : Nat) (fallback : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.keyAtIdxD n fallback
|
||
|
||
@[inline, inherit_doc keyAtIdxD, deprecated keyAtIdxD (since := "2025-03-25")]
|
||
def keyAtIndexD (t : DTreeMap α β cmp) (n : Nat) (fallback : α) : α :=
|
||
keyAtIdxD t n fallback
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the smallest key that is greater than or equal to the
|
||
given key, returning `none` if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryGE? (t : DTreeMap α β cmp) (k : α) : Option ((a : α) × β a) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryGE? k t.inner
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the smallest key that is greater than the given key,
|
||
returning `none` if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryGT? (t : DTreeMap α β cmp) (k : α) : Option ((a : α) × β a) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryGT? k t.inner
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the largest key that is less than or equal to the
|
||
given key, returning `none` if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryLE? (t : DTreeMap α β cmp) (k : α) : Option ((a : α) × β a) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryLE? k t.inner
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the largest key that is less than the given key,
|
||
returning `none` if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryLT? (t : DTreeMap α β cmp) (k : α) : Option ((a : α) × β a) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryLT? k t.inner
|
||
|
||
/-!
|
||
`getEntryGE`, `getEntryGT`, `getEntryLE`, `getEntryLT` can be found in
|
||
`Std.Data.DTreeMap.AdditionalOperations`.
|
||
-/
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the smallest key that is greater than or equal to the
|
||
given key, panicking if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryGE! [Inhabited (Sigma β)] (t : DTreeMap α β cmp) (k : α) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryGE! k t.inner
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the smallest key that is greater than the given key,
|
||
panicking if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryGT! [Inhabited (Sigma β)] (t : DTreeMap α β cmp) (k : α) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryGT! k t.inner
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the largest key that is less than or equal to the
|
||
given key, panicking if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryLE! [Inhabited (Sigma β)] (t : DTreeMap α β cmp) (k : α) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryLE! k t.inner
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the largest key that is less than the given key,
|
||
panicking if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryLT! [Inhabited (Sigma β)] (t : DTreeMap α β cmp) (k : α) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryLT! k t.inner
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the smallest key that is greater than or equal to the
|
||
given key, returning `fallback` if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryGED (t : DTreeMap α β cmp) (k : α) (fallback : Sigma β) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryGED k t.inner fallback
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the smallest key that is greater than the given key,
|
||
returning `fallback` if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryGTD (t : DTreeMap α β cmp) (k : α) (fallback : Sigma β) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryGTD k t.inner fallback
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the largest key that is less than or equal to the
|
||
given key, returning `fallback` if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryLED (t : DTreeMap α β cmp) (k : α) (fallback : Sigma β) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryLED k t.inner fallback
|
||
|
||
/--
|
||
Tries to retrieve the key-value pair with the largest key that is less than the given key,
|
||
returning `fallback` if no such pair exists.
|
||
-/
|
||
@[inline]
|
||
def getEntryLTD (t : DTreeMap α β cmp) (k : α) (fallback : Sigma β) : (a : α) × β a :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getEntryLTD k t.inner fallback
|
||
|
||
/--
|
||
Tries to retrieve the smallest key that is greater than or equal to the
|
||
given key, returning `none` if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyGE? (t : DTreeMap α β cmp) (k : α) : Option α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.getKeyGE? k
|
||
|
||
/--
|
||
Tries to retrieve the smallest key that is greater than the given key,
|
||
returning `none` if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyGT? (t : DTreeMap α β cmp) (k : α) : Option α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.getKeyGT? k
|
||
|
||
/--
|
||
Tries to retrieve the largest key that is less than or equal to the
|
||
given key, returning `none` if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyLE? (t : DTreeMap α β cmp) (k : α) : Option α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.getKeyLE? k
|
||
|
||
/--
|
||
Tries to retrieve the largest key that is less than the given key,
|
||
returning `none` if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyLT? (t : DTreeMap α β cmp) (k : α) : Option α :=
|
||
letI : Ord α := ⟨cmp⟩; t.inner.getKeyLT? k
|
||
|
||
/-!
|
||
`getKeyGE`, `getKeyGT`, `getKeyLE`, `getKeyLT` can be found in
|
||
`Std.Data.DTreeMap.AdditionalOperations`.
|
||
-/
|
||
|
||
/--
|
||
Tries to retrieve the smallest key that is greater than or equal to the
|
||
given key, panicking if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyGE! [Inhabited α] (t : DTreeMap α β cmp) (k : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getKeyGE! k t.inner
|
||
|
||
/--
|
||
Tries to retrieve the smallest key that is greater than the given key,
|
||
panicking if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyGT! [Inhabited α] (t : DTreeMap α β cmp) (k : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getKeyGT! k t.inner
|
||
|
||
/--
|
||
Tries to retrieve the largest key that is less than or equal to the
|
||
given key, panicking if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyLE! [Inhabited α] (t : DTreeMap α β cmp) (k : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getKeyLE! k t.inner
|
||
|
||
/--
|
||
Tries to retrieve the largest key that is less than the given key,
|
||
panicking if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyLT! [Inhabited α] (t : DTreeMap α β cmp) (k : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getKeyLT! k t.inner
|
||
|
||
/--
|
||
Tries to retrieve the smallest key that is greater than or equal to the
|
||
given key, returning `fallback` if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyGED (t : DTreeMap α β cmp) (k : α) (fallback : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getKeyGED k t.inner fallback
|
||
|
||
/--
|
||
Tries to retrieve the smallest key that is greater than the given key,
|
||
returning `fallback` if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyGTD (t : DTreeMap α β cmp) (k : α) (fallback : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getKeyGTD k t.inner fallback
|
||
|
||
/--
|
||
Tries to retrieve the largest key that is less than or equal to the
|
||
given key, returning `fallback` if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyLED (t : DTreeMap α β cmp) (k : α) (fallback : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getKeyLED k t.inner fallback
|
||
|
||
/--
|
||
Tries to retrieve the largest key that is less than the given key,
|
||
returning `fallback` if no such key exists.
|
||
-/
|
||
@[inline]
|
||
def getKeyLTD (t : DTreeMap α β cmp) (k : α) (fallback : α) : α :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.getKeyLTD k t.inner fallback
|
||
|
||
namespace Const
|
||
|
||
variable {β : Type v}
|
||
|
||
@[inline, inherit_doc DTreeMap.getThenInsertIfNew?]
|
||
def getThenInsertIfNew? (t : DTreeMap α β cmp) (a : α) (b : β) :
|
||
Option β × DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩
|
||
let p := Impl.Const.getThenInsertIfNew? t.inner a b t.wf.balanced
|
||
(p.1, ⟨p.2, t.wf.constGetThenInsertIfNew?⟩)
|
||
|
||
@[inline, inherit_doc DTreeMap.get?]
|
||
def get? (t : DTreeMap α β cmp) (a : α) : Option β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.get? t.inner a
|
||
|
||
@[inline, inherit_doc get?, deprecated get? (since := "2025-02-12")]
|
||
def find? (t : DTreeMap α β cmp) (a : α) : Option β :=
|
||
get? t a
|
||
|
||
@[inline, inherit_doc DTreeMap.get]
|
||
def get (t : DTreeMap α β cmp) (a : α) (h : a ∈ t) : β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.get t.inner a h
|
||
|
||
@[inline, inherit_doc DTreeMap.get!]
|
||
def get! (t : DTreeMap α β cmp) (a : α) [Inhabited β] : β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.get! t.inner a
|
||
|
||
@[inline, inherit_doc get!, deprecated get! (since := "2025-02-12")]
|
||
def find! (t : DTreeMap α β cmp) (a : α) [Inhabited β] : β :=
|
||
get! t a
|
||
|
||
@[inline, inherit_doc DTreeMap.getD]
|
||
def getD (t : DTreeMap α β cmp) (a : α) (fallback : β) : β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getD t.inner a fallback
|
||
|
||
@[inline, inherit_doc getD, deprecated getD (since := "2025-02-12")]
|
||
def findD (t : DTreeMap α β cmp) (a : α) (fallback : β) : β :=
|
||
getD t a fallback
|
||
|
||
@[inline, inherit_doc DTreeMap.minEntry?]
|
||
def minEntry? (t : DTreeMap α β cmp) : Option (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.minEntry? t.inner
|
||
|
||
@[inline, inherit_doc minEntry?, deprecated minEntry? (since := "2025-03-13")]
|
||
def min? (t : DTreeMap α β cmp) : Option (α × β) :=
|
||
minEntry? t
|
||
|
||
@[inline, inherit_doc DTreeMap.minEntry]
|
||
def minEntry (t : DTreeMap α β cmp) (h : t.isEmpty = false) : α × β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.minEntry t.inner h
|
||
|
||
@[inline, inherit_doc minEntry, deprecated minEntry (since := "2025-03-13")]
|
||
def min (t : DTreeMap α β cmp) (h : t.isEmpty = false) : α × β :=
|
||
minEntry t h
|
||
|
||
@[inline, inherit_doc DTreeMap.minEntry!]
|
||
def minEntry! [Inhabited (α × β)] (t : DTreeMap α β cmp) : α × β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.minEntry! t.inner
|
||
|
||
@[inline, inherit_doc minEntry!, deprecated minEntry! (since := "2025-03-13")]
|
||
def min! [Inhabited (α × β)] (t : DTreeMap α β cmp) : α × β :=
|
||
minEntry! t
|
||
|
||
@[inline, inherit_doc DTreeMap.minEntryD]
|
||
def minEntryD (t : DTreeMap α β cmp) (fallback : α × β) : α × β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.minEntryD t.inner fallback
|
||
|
||
@[inline, inherit_doc minEntryD, deprecated minEntryD (since := "2025-03-13")]
|
||
def minD (t : DTreeMap α β cmp) (fallback : α × β) : α × β :=
|
||
minEntryD t fallback
|
||
|
||
@[inline, inherit_doc DTreeMap.maxEntry?]
|
||
def maxEntry? (t : DTreeMap α β cmp) : Option (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.maxEntry? t.inner
|
||
|
||
@[inline, inherit_doc maxEntry?, deprecated maxEntry? (since := "2025-03-13")]
|
||
def max? (t : DTreeMap α β cmp) : Option (α × β) :=
|
||
maxEntry? t
|
||
|
||
@[inline, inherit_doc DTreeMap.maxEntry]
|
||
def maxEntry (t : DTreeMap α β cmp) (h : t.isEmpty = false) : α × β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.maxEntry t.inner h
|
||
|
||
@[inline, inherit_doc maxEntry, deprecated maxEntry (since := "2025-03-13")]
|
||
def max (t : DTreeMap α β cmp) (h : t.isEmpty = false) : α × β :=
|
||
maxEntry t h
|
||
|
||
@[inline, inherit_doc DTreeMap.maxEntry!]
|
||
def maxEntry! [Inhabited (α × β)] (t : DTreeMap α β cmp) : α × β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.maxEntry! t.inner
|
||
|
||
@[inline, inherit_doc maxEntry!, deprecated maxEntry! (since := "2025-03-13")]
|
||
def max! [Inhabited (α × β)] (t : DTreeMap α β cmp) : α × β :=
|
||
maxEntry! t
|
||
|
||
@[inline, inherit_doc DTreeMap.maxEntryD]
|
||
def maxEntryD (t : DTreeMap α β cmp) (fallback : α × β) : α × β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.maxEntryD t.inner fallback
|
||
|
||
@[inline, inherit_doc maxEntryD, deprecated maxEntryD (since := "2025-03-13")]
|
||
def maxD (t : DTreeMap α β cmp) (fallback : α × β) : α × β :=
|
||
maxEntryD t fallback
|
||
|
||
@[inline, inherit_doc DTreeMap.entryAtIdx?]
|
||
def entryAtIdx? (t : DTreeMap α β cmp) (n : Nat) : Option (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.entryAtIdx? t.inner n
|
||
|
||
@[inline, inherit_doc DTreeMap.entryAtIdx]
|
||
def entryAtIdx (t : DTreeMap α β cmp) (n : Nat) (h : n < t.size) : α × β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.entryAtIdx t.inner t.wf.balanced n h
|
||
|
||
@[inline, inherit_doc DTreeMap.entryAtIdx!]
|
||
def entryAtIdx! [Inhabited (α × β)] (t : DTreeMap α β cmp) (n : Nat) : α × β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.entryAtIdx! t.inner n
|
||
|
||
@[inline, inherit_doc DTreeMap.entryAtIdxD]
|
||
def entryAtIdxD (t : DTreeMap α β cmp) (n : Nat)
|
||
(fallback : α × β) : α × β :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.entryAtIdxD t.inner n fallback
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryGE?]
|
||
def getEntryGE? (t : DTreeMap α β cmp) (k : α) : Option (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryGE? k t.inner
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryGT?]
|
||
def getEntryGT? (t : DTreeMap α β cmp) (k : α) : Option (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryGT? k t.inner
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryLE?]
|
||
def getEntryLE? (t : DTreeMap α β cmp) (k : α) : Option (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryLE? k t.inner
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryLT?]
|
||
def getEntryLT? (t : DTreeMap α β cmp) (k : α) : Option (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryLT? k t.inner
|
||
|
||
/-!
|
||
`getEntryGE`, `getEntryGT`, `getEntryLE`, `getEntryLT` can be found in
|
||
`Std.Data.DTreeMap.AdditionalOperations`.
|
||
-/
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryGE!]
|
||
def getEntryGE! [Inhabited (α × β)] (t : DTreeMap α β cmp) (k : α) : (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryGE! k t.inner
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryGT!]
|
||
def getEntryGT! [Inhabited (α × β)] (t : DTreeMap α β cmp) (k : α) : (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryGT! k t.inner
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryLE!]
|
||
def getEntryLE! [Inhabited (α × β)] (t : DTreeMap α β cmp) (k : α) : (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryLE! k t.inner
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryLT!]
|
||
def getEntryLT! [Inhabited (α × β)] (t : DTreeMap α β cmp) (k : α) : (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryLT! k t.inner
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryGED]
|
||
def getEntryGED (t : DTreeMap α β cmp) (k : α) (fallback : α × β) : (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryGED k t.inner fallback
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryGTD]
|
||
def getEntryGTD (t : DTreeMap α β cmp) (k : α) (fallback : α × β) : (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryGTD k t.inner fallback
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryLED]
|
||
def getEntryLED (t : DTreeMap α β cmp) (k : α) (fallback : α × β) : (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryLED k t.inner fallback
|
||
|
||
@[inline, inherit_doc DTreeMap.getEntryLTD]
|
||
def getEntryLTD (t : DTreeMap α β cmp) (k : α) (fallback : α × β) : (α × β) :=
|
||
letI : Ord α := ⟨cmp⟩; Impl.Const.getEntryLTD k t.inner fallback
|
||
|
||
end Const
|
||
|
||
variable {δ : Type w} {m : Type w → Type w₂} [Monad m]
|
||
|
||
/-- Removes all mappings of the map for which the given function returns `false`. -/
|
||
@[inline]
|
||
def filter (f : (a : α) → β a → Bool) (t : DTreeMap α β cmp) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨t.inner.filter f t.wf.balanced |>.impl, t.wf.filter⟩
|
||
|
||
/-- Folds the given monadic function over the mappings in the map in ascending order. -/
|
||
@[inline]
|
||
def foldlM (f : δ → (a : α) → β a → m δ) (init : δ) (t : DTreeMap α β cmp) : m δ :=
|
||
t.inner.foldlM f init
|
||
|
||
@[inline, inherit_doc foldlM, deprecated foldlM (since := "2025-02-12")]
|
||
def foldM (f : δ → (a : α) → β a → m δ) (init : δ) (t : DTreeMap α β cmp) : m δ :=
|
||
t.foldlM f init
|
||
|
||
/-- Folds the given function over the mappings in the map in ascending order. -/
|
||
@[inline]
|
||
def foldl (f : δ → (a : α) → β a → δ) (init : δ) (t : DTreeMap α β cmp) : δ :=
|
||
t.inner.foldl f init
|
||
|
||
@[inline, inherit_doc foldl, deprecated foldl (since := "2025-02-12")]
|
||
def fold (f : δ → (a : α) → β a → δ) (init : δ) (t : DTreeMap α β cmp) : δ :=
|
||
t.foldl f init
|
||
|
||
/-- Folds the given monadic function over the mappings in the map in descending order. -/
|
||
@[inline]
|
||
def foldrM (f : (a : α) → β a → δ → m δ) (init : δ) (t : DTreeMap α β cmp) : m δ :=
|
||
t.inner.foldrM f init
|
||
|
||
/-- Folds the given function over the mappings in the map in descending order. -/
|
||
@[inline]
|
||
def foldr (f : (a : α) → β a → δ → δ) (init : δ) (t : DTreeMap α β cmp) : δ :=
|
||
t.inner.foldr f init
|
||
|
||
@[inline, inherit_doc foldr, deprecated foldr (since := "2025-02-12")]
|
||
def revFold (f : δ → (a : α) → β a → δ) (init : δ) (t : DTreeMap α β cmp) : δ :=
|
||
foldr (fun k v acc => f acc k v) init t
|
||
|
||
/-- Partitions a tree map into two tree maps based on a predicate. -/
|
||
@[inline] def partition (f : (a : α) → β a → Bool)
|
||
(t : DTreeMap α β cmp) : DTreeMap α β cmp × DTreeMap α β cmp :=
|
||
t.foldl (init := (∅, ∅)) fun ⟨l, r⟩ a b =>
|
||
if f a b then
|
||
(l.insert a b, r)
|
||
else
|
||
(l, r.insert a b)
|
||
|
||
/-- Carries out a monadic action on each mapping in the tree map in ascending order. -/
|
||
@[inline]
|
||
def forM (f : (a : α) → β a → m PUnit) (t : DTreeMap α β cmp) : m PUnit :=
|
||
t.inner.forM f
|
||
|
||
/-- Support for the `for` loop construct in `do` blocks. Iteration happens in ascending order. -/
|
||
@[inline]
|
||
def forIn (f : (a : α) → β a → δ → m (ForInStep δ)) (init : δ) (t : DTreeMap α β cmp) : m δ :=
|
||
t.inner.forIn f init
|
||
|
||
instance : ForM m (DTreeMap α β cmp) ((a : α) × β a) where
|
||
forM t f := t.forM (fun a b => f ⟨a, b⟩)
|
||
|
||
instance : ForIn m (DTreeMap α β cmp) ((a : α) × β a) where
|
||
forIn m init f := m.forIn (fun a b acc => f ⟨a, b⟩ acc) init
|
||
|
||
namespace Const
|
||
|
||
variable {β : Type v}
|
||
|
||
/-!
|
||
We do not define `ForM` and `ForIn` instances that are specialized to constant `β`. Instead, we
|
||
define uncurried versions of `forM` and `forIn` that will be used in the `Const` lemmas and to
|
||
define the `ForM` and `ForIn` instances for `DTreeMap`.
|
||
-/
|
||
|
||
@[inline, inherit_doc DTreeMap.forM]
|
||
def forMUncurried (f : α × β → m PUnit) (t : DTreeMap α β cmp) : m PUnit :=
|
||
t.inner.forM fun a b => f ⟨a, b⟩
|
||
|
||
@[inline, inherit_doc DTreeMap.forIn]
|
||
def forInUncurried (f : α × β → δ → m (ForInStep δ)) (init : δ) (t : DTreeMap α β cmp) : m δ :=
|
||
t.inner.forIn (fun a b acc => f ⟨a, b⟩ acc) init
|
||
|
||
end Const
|
||
|
||
/-- Check if any element satisfes the predicate, short-circuiting if a predicate fails. -/
|
||
@[inline]
|
||
def any (t : DTreeMap α β cmp) (p : (a : α) → β a → Bool) : Bool := Id.run $ do
|
||
for ⟨a, b⟩ in t do
|
||
if p a b then return true
|
||
return false
|
||
|
||
/-- Check if all elements satisfy the predicate, short-circuiting if a predicate fails. -/
|
||
@[inline]
|
||
def all (t : DTreeMap α β cmp) (p : (a : α) → β a → Bool) : Bool := Id.run $ do
|
||
for ⟨a, b⟩ in t do
|
||
if p a b = false then return false
|
||
return true
|
||
|
||
/-- Returns a list of all keys present in the tree map in ascending order. -/
|
||
@[inline]
|
||
def keys (t : DTreeMap α β cmp) : List α :=
|
||
t.inner.keys
|
||
|
||
/-- Returns an array of all keys present in the tree map in ascending order. -/
|
||
@[inline]
|
||
def keysArray (t : DTreeMap α β cmp) : Array α :=
|
||
t.inner.keysArray
|
||
|
||
/-- Returns a list of all values present in the tree map in ascending order. -/
|
||
@[inline]
|
||
def values {β : Type v} (t : DTreeMap α β cmp) : List β :=
|
||
t.inner.values
|
||
|
||
/-- Returns an array of all values present in the tree map in ascending order. -/
|
||
@[inline]
|
||
def valuesArray {β : Type v} (t : DTreeMap α β cmp) : Array β :=
|
||
t.inner.valuesArray
|
||
|
||
/-- Transforms the tree map into a list of mappings in ascending order. -/
|
||
@[inline]
|
||
def toList (t : DTreeMap α β cmp) : List ((a : α) × β a) :=
|
||
t.inner.toList
|
||
|
||
/-- Transforms a list of mappings into a tree map. -/
|
||
@[inline]
|
||
def ofList (l : List ((a : α) × β a)) (cmp : α → α → Ordering := by exact compare) :
|
||
DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨Impl.ofList l, Impl.WF.empty.insertMany⟩
|
||
|
||
@[inline, inherit_doc ofList, deprecated ofList (since := "2025-02-12")]
|
||
def fromList (l : List ((a : α) × β a)) (cmp : α → α → Ordering) : DTreeMap α β cmp :=
|
||
ofList l cmp
|
||
|
||
/-- Transforms the tree map into a list of mappings in ascending order. -/
|
||
@[inline]
|
||
def toArray (t : DTreeMap α β cmp) : Array ((a : α) × β a) :=
|
||
t.inner.toArray
|
||
|
||
/-- Transforms an array of mappings into a tree map. -/
|
||
@[inline]
|
||
def ofArray (a : Array ((a : α) × β a)) (cmp : α → α → Ordering := by exact compare) :
|
||
DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨Impl.ofArray a, Impl.WF.empty.insertMany⟩
|
||
|
||
@[inline, inherit_doc ofArray, deprecated ofArray (since := "2025-02-12")]
|
||
def fromArray (a : Array ((a : α) × β a)) (cmp : α → α → Ordering) : DTreeMap α β cmp :=
|
||
ofArray a cmp
|
||
|
||
/--
|
||
Modifies in place the value associated with a given key.
|
||
|
||
This function ensures that the value is used linearly.
|
||
-/
|
||
@[inline]
|
||
def modify [LawfulEqCmp cmp] (t : DTreeMap α β cmp) (a : α) (f : β a → β a) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨t.inner.modify a f, t.wf.modify⟩
|
||
|
||
/--
|
||
Modifies in place the value associated with a given key,
|
||
allowing creating new values and deleting values via an `Option` valued replacement function.
|
||
|
||
This function ensures that the value is used linearly.
|
||
-/
|
||
@[inline]
|
||
def alter [LawfulEqCmp cmp] (t : DTreeMap α β cmp) (a : α) (f : Option (β a) → Option (β a)) :
|
||
DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨t.inner.alter a f t.wf.balanced |>.impl, t.wf.alter⟩
|
||
|
||
/--
|
||
Returns a map that contains all mappings of `t₁` and `t₂`. In case that both maps contain the
|
||
same key `k` with respect to `cmp`, the provided function is used to determine the new value from
|
||
the respective values in `t₁` and `t₂`.
|
||
|
||
This function ensures that `t₁` is used linearly. It also uses the individual values in `t₁`
|
||
linearly if the merge function uses the second argument (i.e. the first of type `β a`) linearly.
|
||
Hence, as long as `t₁` is unshared, the performance characteristics follow the following imperative
|
||
description: Iterate over all mappings in `t₂`, inserting them into `t₁` if `t₁` does not contain a
|
||
conflicting mapping yet. If `t₁` does contain a conflicting mapping, use the given merge function to
|
||
merge the mapping in `t₂` into the mapping in `t₁`. Then return `t₁`.
|
||
|
||
Hence, the runtime of this method scales logarithmically in the size of `t₁` and linearly in the size of
|
||
`t₂` as long as `t₁` is unshared.
|
||
-/
|
||
@[inline]
|
||
def mergeWith [LawfulEqCmp cmp] (mergeFn : (a : α) → β a → β a → β a) (t₁ t₂ : DTreeMap α β cmp) :
|
||
DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨t₁.inner.mergeWith mergeFn t₂.inner t₁.wf.balanced |>.impl, t₁.wf.mergeWith⟩
|
||
|
||
@[inline, inherit_doc mergeWith, deprecated mergeWith (since := "2025-02-12")]
|
||
def mergeBy [LawfulEqCmp cmp] (mergeFn : (a : α) → β a → β a → β a) (t₁ t₂ : DTreeMap α β cmp) :
|
||
DTreeMap α β cmp :=
|
||
mergeWith mergeFn t₁ t₂
|
||
|
||
namespace Const
|
||
|
||
variable {β : Type v}
|
||
|
||
@[inline, inherit_doc DTreeMap.toList]
|
||
def toList (t : DTreeMap α β cmp) : List (α × β) :=
|
||
Impl.Const.toList t.inner
|
||
|
||
@[inline, inherit_doc DTreeMap.ofList]
|
||
def ofList (l : List (α × β)) (cmp : α → α → Ordering := by exact compare) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩
|
||
⟨Impl.Const.ofList l, Impl.WF.empty.constInsertMany⟩
|
||
|
||
@[inline, inherit_doc DTreeMap.toArray]
|
||
def toArray (t : DTreeMap α β cmp) : Array (α × β) :=
|
||
t.foldl (init := ∅) fun acc k v => acc.push ⟨k,v⟩
|
||
|
||
@[inline, inherit_doc DTreeMap.ofList]
|
||
def ofArray (a : Array (α × β)) (cmp : α → α → Ordering := by exact compare) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩
|
||
⟨Impl.Const.ofArray a, Impl.WF.empty.constInsertMany⟩
|
||
|
||
/-- Transforms a list of keys into a tree map. -/
|
||
@[inline]
|
||
def unitOfList (l : List α) (cmp : α → α → Ordering := by exact compare) : DTreeMap α Unit cmp :=
|
||
letI : Ord α := ⟨cmp⟩
|
||
⟨Impl.Const.unitOfList l, Impl.WF.empty.constInsertManyIfNewUnit⟩
|
||
|
||
/-- Transforms an array of keys into a tree map. -/
|
||
@[inline]
|
||
def unitOfArray (a : Array α) (cmp : α → α → Ordering := by exact compare) : DTreeMap α Unit cmp :=
|
||
letI : Ord α := ⟨cmp⟩
|
||
⟨Impl.Const.unitOfArray a, Impl.WF.empty.constInsertManyIfNewUnit⟩
|
||
|
||
@[inline, inherit_doc DTreeMap.modify]
|
||
def modify (t : DTreeMap α β cmp) (a : α) (f : β → β) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨Impl.Const.modify a f t.inner, t.wf.constModify⟩
|
||
|
||
@[inline, inherit_doc DTreeMap.alter]
|
||
def alter (t : DTreeMap α β cmp) (a : α) (f : Option β → Option β) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨Impl.Const.alter a f t.inner t.wf.balanced |>.impl, t.wf.constAlter⟩
|
||
|
||
@[inline, inherit_doc DTreeMap.mergeWith]
|
||
def mergeWith (mergeFn : α → β → β → β) (t₁ t₂ : DTreeMap α β cmp) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩;
|
||
⟨Impl.Const.mergeWith mergeFn t₁.inner t₂.inner t₁.wf.balanced |>.impl, t₁.wf.constMergeWith⟩
|
||
|
||
@[inline, inherit_doc mergeWith, deprecated mergeWith (since := "2025-02-12")]
|
||
def mergeBy (mergeFn : α → β → β → β) (t₁ t₂ : DTreeMap α β cmp) : DTreeMap α β cmp :=
|
||
mergeWith mergeFn t₁ t₂
|
||
|
||
end Const
|
||
|
||
/--
|
||
Inserts multiple mappings into the tree map by iterating over the given collection and calling
|
||
`insert`. If the same key appears multiple times, the last occurrence takes precedence.
|
||
|
||
Note: this precedence behavior is true for `TreeMap`, `DTreeMap`, `TreeMap.Raw` and `DTreeMap.Raw`.
|
||
The `insertMany` function on `TreeSet` and `TreeSet.Raw` behaves differently: it will prefer the first
|
||
appearance.
|
||
-/
|
||
@[inline]
|
||
def insertMany {ρ} [ForIn Id ρ ((a : α) × β a)] (t : DTreeMap α β cmp) (l : ρ) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨t.inner.insertMany l t.wf.balanced, t.wf.insertMany⟩
|
||
|
||
/--
|
||
Erases multiple mappings from the tree map by iterating over the given collection and calling
|
||
`erase`.
|
||
-/
|
||
@[inline]
|
||
def eraseMany {ρ} [ForIn Id ρ α] (t : DTreeMap α β cmp) (l : ρ) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨t.inner.eraseMany l t.wf.balanced, t.wf.eraseMany⟩
|
||
|
||
namespace Const
|
||
|
||
variable {β : Type v}
|
||
|
||
@[inline, inherit_doc DTreeMap.insertMany]
|
||
def insertMany {ρ} [ForIn Id ρ (α × β)] (t : DTreeMap α β cmp) (l : ρ) : DTreeMap α β cmp :=
|
||
letI : Ord α := ⟨cmp⟩; ⟨Impl.Const.insertMany t.inner l t.wf.balanced, t.wf.constInsertMany⟩
|
||
|
||
/--
|
||
Inserts multiple elements into the tree map by iterating over the given collection and calling
|
||
`insertIfNew`. If the same key appears multiple times, the first occurrence takes precedence.
|
||
-/
|
||
@[inline]
|
||
def insertManyIfNewUnit {ρ} [ForIn Id ρ α] (t : DTreeMap α Unit cmp) (l : ρ) : DTreeMap α Unit cmp :=
|
||
letI : Ord α := ⟨cmp⟩;
|
||
⟨Impl.Const.insertManyIfNewUnit t.inner l t.wf.balanced, t.wf.constInsertManyIfNewUnit⟩
|
||
|
||
end Const
|
||
|
||
instance [Repr α] [(a : α) → Repr (β a)] : Repr (DTreeMap α β cmp) where
|
||
reprPrec m prec := Repr.addAppParen ("Std.DTreeMap.ofList " ++ repr m.toList) prec
|
||
|
||
end DTreeMap
|
||
|
||
end Std
|