Built with
doc-gen4, running Lean4.
Bubbles (
) indicate interactive fragments: hover for details, tap to reveal contents.
Use
Ctrl+βCtrl+βto navigate,
Ctrl+π±οΈto focus.
On Mac, use
Cmdinstead of
Ctrl.
/-
Copyright (c) 2022 Jannis Limperg. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jannis Limperg
-/
import Lean.Meta.DiscrTree
import Std.Data.Array.Merge
import Std.Data.Ord
import Std.Lean.Meta.Expr
import Std.Lean.PersistentHashMap
namespace Lean.Meta.DiscrTree
namespace Key
/--
Compare two `Key`s. The ordering is total but otherwise arbitrary. (It uses
`Name.quickCmp` internally.)
-/
protected def cmp : Key s β Key s β Ordering
| .lit vβ, .lit vβ => compare vβ vβ
| .fvar nβ aβ, .fvar nβ aβ => nβ.name.quickCmp nβ.name |>.then <| compare aβ aβ
| .const nβ aβ, .const nβ aβ => nβ.quickCmp nβ |>.then <| compare aβ aβ
| .proj sβ iβ aβ, .proj sβ iβ aβ =>
sβ.quickCmp sβ |>.then <| compare iβ iβ |>.then <| compare aβ aβ
| kβ, kβ => compare kβ.ctorIdx kβ.ctorIdx
instance : Ord (Key s) :=
β¨Key.cmpβ©
end Key
namespace Trie
-- This is just a partial function, but Lean doesn't realise that its type is
-- inhabited.
private unsafe def foldMUnsafe [Monad: (Type ?u.2168 β Type ?u.2167) β Type (max(?u.2168+1)?u.2167)
Monad m] (initialKeys : Array (Key s))
(f : Ο β Array (Key s) β Ξ± β m Ο) (init : Ο) : Trie Ξ± s β m Ο
| Trie.node vs children => do
let s β vs.foldlM (init := init) fun s v => f: Ο β Array (Key sβ) β Ξ± β m Ο
f s initialKeys v
children.foldlM (init := s) fun s (k, t) =>
t.foldMUnsafe (initialKeys.push k) f: Ο β Array (Key sβΒΉ) β Ξ± β m Ο
f s
/--
Monadically fold the keys and values stored in a `Trie`.
-/
@[implemented_by foldMUnsafe]
opaque foldM [Monad: (Type ?u.3045 β Type ?u.3044) β Type (max(?u.3045+1)?u.3044)
Monad m] (initalKeys : Array (Key s))
(f : Ο β Array (Key s) β Ξ± β m Ο) (init : Ο) (t : Trie Ξ± s) : m Ο :=
pure: {f : Type ?u.3076 β Type ?u.3075} β [self : Pure f] β {Ξ± : Type ?u.3076} β Ξ± β f Ξ±
pure init
/--
Fold the keys and values stored in a `Trie`.
-/
@[inline]
def fold (initialKeys : Array (Key s)) (f : Ο β Array (Key s) β Ξ± β Ο)
(init : Ο) (t : Trie Ξ± s) : Ο :=
Id.run: {Ξ± : Type ?u.3249} β Id Ξ± β Ξ±
Id.run <| t.foldM initialKeys (init := init) fun s k a => return f: Ο β Array (Key sβ) β Ξ± β Ο
f s k a
-- This is just a partial function, but Lean doesn't realise that its type is
-- inhabited.
private unsafe def foldValuesMUnsafe: {m : Type u_1 β Type u_2} β
{Ο : Type u_1} β {Ξ± : Type} β {s : Bool} β [inst : Monad m] β (Ο β Ξ± β m Ο) β Ο β Trie Ξ± s β m Ο
foldValuesMUnsafe [Monad: (Type ?u.3806 β Type ?u.3805) β Type (max(?u.3806+1)?u.3805)
Monad m] (f : Ο β Ξ± β m Ο) (init : Ο) :
Trie Ξ± s β m Ο
| node vs children => do
let s β vs.foldlM (init := init) f
children.foldlM (init := s) fun s (_, c) => c.foldValuesMUnsafe: {m : Type ?u.3824 β Type ?u.3823} β
{Ο : Type ?u.3824} β {Ξ± : Type} β {s : Bool} β [inst : Monad m] β (Ο β Ξ± β m Ο) β Ο β Trie Ξ± s β m Ο
foldValuesMUnsafe (init := s) f
/--
Monadically fold the values stored in a `Trie`.
-/
@[implemented_by foldValuesMUnsafe: {m : Type u_1 β Type u_2} β
{Ο : Type u_1} β {Ξ± : Type} β {s : Bool} β [inst : Monad m] β (Ο β Ξ± β m Ο) β Ο β Trie Ξ± s β m Ο
foldValuesMUnsafe]
opaque foldValuesM: {m : Type ?u.4572 β Type ?u.4571} β
{Ο : Type ?u.4572} β {Ξ± : Type} β {s : Bool} β [inst : Monad m] β (Ο β Ξ± β m Ο) β Ο β Trie Ξ± s β m Ο
foldValuesM [Monad: (Type ?u.4572 β Type ?u.4571) β Type (max(?u.4572+1)?u.4571)
Monad m] (f : Ο β Ξ± β m Ο) (init : Ο) (t : Trie Ξ± s) : m Ο := pure: {f : Type ?u.4596 β Type ?u.4595} β [self : Pure f] β {Ξ± : Type ?u.4596} β Ξ± β f Ξ±
pure init
/--
Fold the values stored in a `Trie`.
-/
@[inline]
def foldValues: {Ο : Sort ?u.4733} β {Ξ± : Type} β {s : Bool} β (Ο β Ξ± β Ο) β Ο β Trie Ξ± s β Ο
foldValues (f : Ο β Ξ± β Ο) (init : Ο) (t : Trie Ξ± s) : Ο :=
Id.run: {Ξ± : Type ?u.4750} β Id Ξ± β Ξ±
Id.run <| t.foldValuesM: {m : Type ?u.4753 β Type ?u.4752} β
{Ο : Type ?u.4753} β {Ξ± : Type} β {s : Bool} β [inst : Monad m] β (Ο β Ξ± β m Ο) β Ο β Trie Ξ± s β m Ο
foldValuesM (init := init) f
/--
The number of values stored in a `Trie`.
-/
partial def size : Trie Ξ± s β Nat
| Trie.node vs children =>
children.foldl (init := vs.size) fun n (_, c) => n + size c
/--
Merge two `Trie`s. Duplicate values are preserved.
-/
partial def mergePreservingDuplicates : Trie Ξ± s β Trie Ξ± s β Trie Ξ± s
| node vsβ csβ, node vsβ csβ =>
node (vsβ ++ vsβ) (mergeChildren csβ csβ)
where
/-- Auxiliary definition for `mergePreservingDuplicates`. -/
mergeChildren (csβ csβ : Array (Key s Γ Trie Ξ± s)) :
Array (Key s Γ Trie Ξ± s) :=
Array.mergeSortedMergingDuplicates: {Ξ± : Type ?u.5636} β [ord : Ord Ξ±] β Array Ξ± β Array Ξ± β (Ξ± β Ξ± β Ξ±) β Array Ξ±
Array.mergeSortedMergingDuplicates
(ord := β¨compareOn: {Ξ² : Type ?u.5645} β {Ξ± : Sort ?u.5644} β [ord : Ord Ξ²] β (Ξ± β Ξ²) β Ξ± β Ξ± β Ordering
compareOn (Β·.fst: {Ξ± : Type ?u.5659} β {Ξ² : Type ?u.5658} β Ξ± Γ Ξ² β Ξ±
fst)β©) csβ csβ
(fun (kβ, tβ) (_, tβ) => (kβ, mergePreservingDuplicates tβ tβ))
end Trie
/--
Monadically fold over the keys and values stored in a `DiscrTree`.
-/
@[inline]
def foldM [Monad: (Type ?u.6598 β Type ?u.6597) β Type (max(?u.6598+1)?u.6597)
Monad m] (f : Ο β Array (Key s) β Ξ± β m Ο) (init : Ο)
(t : DiscrTree Ξ± s) : m Ο :=
t.root.foldlM (init := init) fun s k t => t.foldM #[k] (init := s) f: Ο β Array (Key sβ) β Ξ± β m Ο
f
/--
Fold over the keys and values stored in a `DiscrTree`
-/
@[inline]
def fold (f : Ο β Array (Key s) β Ξ± β Ο) (init : Ο) (t : DiscrTree Ξ± s) : Ο :=
Id.run: {Ξ± : Type ?u.6995} β Id Ξ± β Ξ±
Id.run <| t.foldM (init := init) fun s keys a => return f: Ο β Array (Key sβ) β Ξ± β Ο
f s keys a
/--
Monadically fold over the values stored in a `DiscrTree`.
-/
@[inline]
def foldValuesM: {m : Type ?u.7537 β Type ?u.7536} β
{Ο : Type ?u.7537} β {Ξ± : Type} β {s : Bool} β [inst : Monad m] β (Ο β Ξ± β m Ο) β Ο β DiscrTree Ξ± s β m Ο
foldValuesM [Monad: (Type ?u.7498 β Type ?u.7497) β Type (max(?u.7498+1)?u.7497)
Monad m] (f : Ο β Ξ± β m Ο) (init : Ο) (t : DiscrTree Ξ± s) :
m Ο :=
t.root.foldlM (init := init) fun s _ t => t.foldValuesM: {m : Type ?u.7627 β Type ?u.7626} β
{Ο : Type ?u.7627} β {Ξ± : Type} β {s : Bool} β [inst : Monad m] β (Ο β Ξ± β m Ο) β Ο β Trie Ξ± s β m Ο
foldValuesM (init := s) f
/--
Fold over the values stored in a `DiscrTree`.
-/
@[inline]
def foldValues: {Ο : Sort ?u.7870} β {Ξ± : Type} β {s : Bool} β (Ο β Ξ± β Ο) β Ο β DiscrTree Ξ± s β Ο
foldValues (f : Ο β Ξ± β Ο) (init : Ο) (t : DiscrTree Ξ± s) : Ο :=
Id.run: {Ξ± : Type ?u.7887} β Id Ξ± β Ξ±
Id.run <| t.foldValuesM: {m : Type ?u.7890 β Type ?u.7889} β
{Ο : Type ?u.7890} β {Ξ± : Type} β {s : Bool} β [inst : Monad m] β (Ο β Ξ± β m Ο) β Ο β DiscrTree Ξ± s β m Ο
foldValuesM (init := init) f
/--
Extract the values stored in a `DiscrTree`.
-/
@[inline]
def values (t : DiscrTree Ξ± s) : Array Ξ± :=
t.foldValues: {Ο : Type ?u.8160} β {Ξ± : Type} β {s : Bool} β (Ο β Ξ± β Ο) β Ο β DiscrTree Ξ± s β Ο
foldValues (init := #[]) fun as a => as.push a
/--
Extract the keys and values stored in a `DiscrTree`.
-/
@[inline]
def toArray (t : DiscrTree Ξ± s) : Array (Array (Key s) Γ Ξ±) :=
t.fold (init := #[]) fun as keys a => as.push (keys, a)
/--
Get the number of values stored in a `DiscrTree`. O(n) in the size of the tree.
-/
@[inline]
def size (t : DiscrTree Ξ± s) : Nat :=
t.root.foldl (init := 0) fun n _ t => n + t.size
/--
Merge two `DiscrTree`s. Duplicate values are preserved.
-/
@[inline]
def mergePreservingDuplicates (t u : DiscrTree Ξ± s) : DiscrTree Ξ± s :=
β¨t.root.mergeWith u.root fun _ trieβ trieβ =>
trieβ.mergePreservingDuplicates trieββ©