{-# OPTIONS --cubical-compatible --sized-types #-}
open import Relation.Binary.Core using (Rel)
open import Relation.Binary.Bundles using (StrictTotalOrder)
module Data.Trie {k e r} (S : StrictTotalOrder k e r) where
open import Level
open import Size
open import Data.List.Base using (List; []; _∷_; _++_)
import Data.List.NonEmpty as List⁺
open import Data.Maybe.Base as Maybe using (Maybe; just; nothing; maybe′)
open import Data.Product.Base using (∃)
open import Data.These.Base as These using (These)
open import Function.Base using (_∘′_; const)
open import Relation.Unary using (IUniversal; _⇒_)
open StrictTotalOrder S
using (module Eq)
renaming (Carrier to Key)
open import Data.List.Relation.Binary.Equality.Setoid Eq.setoid
open import Data.Tree.AVL.Value ≋-setoid using (Value)
open import Data.Trie.NonEmpty S as Trie⁺ public
using (Trie⁺; Tries⁺; Word; eat)
Trie : ∀ {v} (V : Value v) → Size → Set (v ⊔ k ⊔ e ⊔ r)
Trie V i = Maybe (Trie⁺ V i)
module _ {v} {V : Value v} where
private Val = Value.family V
lookup : Trie V ∞ → ∀ ks → Maybe (These (Val ks) (Tries⁺ (eat V ks) ∞))
lookup t ks = t Maybe.>>= λ ts → Trie⁺.lookup ts ks
lookupValue : Trie V ∞ → ∀ ks → Maybe (Val ks)
lookupValue t ks = t Maybe.>>= λ ts → Trie⁺.lookupValue ts ks
lookupTries⁺ : Trie V ∞ → ∀ ks → Maybe (Tries⁺ (eat V ks) ∞)
lookupTries⁺ t ks = t Maybe.>>= λ ts → Trie⁺.lookupTries⁺ ts ks
lookupTrie : Trie V ∞ → ∀ k → Trie (eat V (k ∷ [])) ∞
lookupTrie t k = t Maybe.>>= λ ts → Trie⁺.lookupTrie⁺ ts k
empty : Trie V ∞
empty = nothing
singleton : ∀ ks → Val ks → Trie V ∞
singleton ks v = just (Trie⁺.singleton ks v)
insertWith : ∀ ks → (Maybe (Val ks) → Val ks) → Trie V ∞ → Trie V ∞
insertWith ks f (just t) = just (Trie⁺.insertWith ks f t)
insertWith ks f nothing = singleton ks (f nothing)
insert : ∀ ks → Val ks → Trie V ∞ → Trie V ∞
insert ks = insertWith ks ∘′ const
fromList : List (∃ Val) → Trie V ∞
fromList = Maybe.map Trie⁺.fromList⁺ ∘′ List⁺.fromList
toList : Trie V ∞ → List (∃ Val)
toList (just t) = List⁺.toList (Trie⁺.toList⁺ t)
toList nothing = []
module _ {v w} {V : Value v} {W : Value w} where
private
Val = Value.family V
Wal = Value.family W
map : ∀ {i} → ∀[ Val ⇒ Wal ] → Trie V i → Trie W i
map = Maybe.map ∘′ Trie⁺.map V W
module _ {v} {V : Value v} where
deleteWith : ∀ {i} (ks : Word) →
(∀ {i} → Trie⁺ (eat V ks) i → Maybe (Trie⁺ (eat V ks) i)) →
Trie V i → Trie V i
deleteWith ks f t = t Maybe.>>= Trie⁺.deleteWith ks f
deleteTrie⁺ : ∀ {i} (ks : Word) → Trie V i → Trie V i
deleteTrie⁺ ks t = t Maybe.>>= Trie⁺.deleteTrie⁺ ks
deleteValue : ∀ {i} (ks : Word) → Trie V i → Trie V i
deleteValue ks t = t Maybe.>>= Trie⁺.deleteValue ks
deleteTries⁺ : ∀ {i} (ks : Word) → Trie V i → Trie V i
deleteTries⁺ ks t = t Maybe.>>= Trie⁺.deleteTries⁺ ks