{-# OPTIONS --safe --no-import-sorts #-}
open import Axiom.Set using (Theory)
module Axiom.Set.TotalMapOn (th : Theory) where
open import abstract-set-theory.Prelude hiding (lookup; map)
open import Axiom.Set.Map th using (left-unique ; Map ; mapWithKey-uniq)
open import Axiom.Set.Rel th using (Rel ; dom ; dom∈)
open import Class.DecEq using (DecEq ; _≟_)
open Theory th using ( Set ; _⊆_ ; _∈_ ; map ; ∈-map′ )
open Equivalence using (from)
private variable A B : Type
_TotalOn_ : Rel A B → Set A → Type
R TotalOn X = X ⊆ dom R
record TotalMapOn {A : Type}(X : Set A)(B : Type) : Type where
field rel : Set (A × B)
left-unique-rel : left-unique rel
total-rel : rel TotalOn X
toMap : Map A B
toMap = rel , left-unique-rel
lookup : Σ A (_∈ X) → B
lookup (_ , a∈X) = proj₁ (from dom∈ (total-rel a∈X))
lookup∈rel : {a : A} (a∈X : a ∈ X) → (a , lookup (a , a∈X)) ∈ rel
lookup∈rel a∈X = proj₂ (from dom∈ (total-rel a∈X))
rel⇒lookup : {a : A} {a∈dom : a ∈ X} {b : B} → (a , b) ∈ rel → lookup (a , a∈dom) ≡ b
rel⇒lookup {a} {a∈dom} ab∈rel = sym (left-unique-rel ab∈rel (proj₂ (from dom∈ (total-rel a∈dom))))
module UpdateOn {B : Type} ⦃ _ : DecEq A ⦄ where
private
updateFn : A × B → A → B → B
updateFn (a , b) x y with (x ≟ a)
... | yes _ = b
... | no _ = y
open TotalMapOn
mapWithKeyOn : {X : Set A}{B' : Type} → (A → B → B') → TotalMapOn X B → TotalMapOn X B'
mapWithKeyOn f tm .rel = map (λ{(x , y) → x , f x y}) (rel tm)
mapWithKeyOn _ tm .left-unique-rel = mapWithKey-uniq (left-unique-rel tm)
mapWithKeyOn _ tm .total-rel a∈X = ∈-map′ (∈-map′ (proj₂ (from dom∈ ((total-rel tm) a∈X))))
update : {X : Set A} → A → B → TotalMapOn X B → TotalMapOn X B
update a b = mapWithKeyOn (updateFn (a , b))