{-# OPTIONS --safe --no-import-sorts #-} open import Axiom.Set using (Theoryᵈ; Theory) module Axiom.Set.Map.Dec (thᵈ : Theoryᵈ) where open import abstract-set-theory.Prelude hiding (map; Monoid) import Data.Sum as Sum open import Data.These hiding (map) open Theoryᵈ thᵈ using (_∈?_; th; incl-set'; incl-set; incl-set-proj₁⊇) open Theory th open import Axiom.Set.Rel th using (dom; dom∈) open import Axiom.Set.Map th open import Data.Product.Properties using (×-≡,≡→≡; ×-≡,≡←≡) open Equivalence private variable A B C D : Type module Lookupᵐᵈ (sp-∈ : spec-∈ A) where open Lookupᵐ sp-∈ unionThese : ⦃ DecEq A ⦄ → (m : Map A B) (m' : Map A C) (x : A) → x ∈ dom (m ˢ) ∪ dom (m' ˢ) → These B C unionThese m m' x dp with x ∈? dom (m ˢ) | x ∈? dom (m' ˢ) ... | yes mr | yes mr' = these (lookupᵐ m x) (lookupᵐ m' x) ... | yes mr | no mr' = this (lookupᵐ m x) ... | no mr | yes mr' = that (lookupᵐ m' x) ... | no mr | no mr' = Sum.[ flip contradiction mr , flip contradiction mr' ] (from ∈-∪ dp) unionWith : ⦃ DecEq A ⦄ → (These B C → D) → Map A B → Map A C → Map A D unionWith f m@(r , p) m'@(r' , p') = m'' , helper where d = dom r ∪ dom r' m'' = map (λ (x , p) → x , f (unionThese m m' x p)) (incl-set d) helper : left-unique m'' helper q q' with _ , refl , t ← from ∈-map q with _ , refl , t' ← from ∈-map q' with from (∈-mapPartial {f = incl-set' _}) t | from (∈-mapPartial {f = incl-set' _}) t' ... | z , _ | z' , _ with z ∈? d in eq | z' ∈? d in eq' helper _ _ | _ , _ , refl | _ , _ , refl | yes _ | yes _ with refl ← trans (sym eq) eq' = refl module _ {V : Type} ⦃ mon : CommutativeMonoid 0ℓ 0ℓ V ⦄ ⦃ _ : DecEq A ⦄ where infixr 6 _∪⁺_ open CommutativeMonoid mon _∪⁺_ : Map A V → Map A V → Map A V _∪⁺_ = unionWith (fold id id _◇_) aggregate₊ : FinSet (A × V) → Map A V aggregate₊ (_ , l , _) = foldl (λ m x → m ∪⁺ ❴ x ❵ᵐ) ∅ᵐ l module _ {m m' : Map A V} where ∪dom-lookup : ∃[ a ] a ∈ dom (m ˢ) ∪ dom (m' ˢ) → A × V ∪dom-lookup (a , a∈) = a , (fold id id _◇_)(unionThese m m' a a∈) dom∪⁺⊆∪dom : dom ((m ∪⁺ m') ˢ) ⊆ dom (m ˢ) ∪ dom (m' ˢ) dom∪⁺⊆∪dom {a} a∈ = subst (_∈ dom (m ˢ) ∪ dom (m' ˢ)) (sym $ proj₁ (×-≡,≡←≡ $ proj₁ (proj₂ ∈-dom∪⁺))) (proj₂ $ proj₁ ∈-dom∪⁺) where ∈-dom∪⁺ : ∃[ c ] (a , proj₁ (from dom∈ a∈)) ≡ ∪dom-lookup c × c ∈ incl-set (dom (m ˢ) ∪ dom (m' ˢ)) ∈-dom∪⁺ = from ∈-map $ proj₂ $ from dom∈ a∈ ∪dom⊆dom∪⁺ : dom (m ˢ) ∪ dom (m' ˢ) ⊆ dom ((m ∪⁺ m') ˢ) ∪dom⊆dom∪⁺ {a} a∈ with from ∈-map (incl-set-proj₁⊇ a∈) ... | c' , a≡c₁' , c'∈ = to dom∈ (proj₂ (∪dom-lookup c') , to ∈-map (c' , ×-≡,≡→≡ (a≡c₁' , refl) , c'∈)) dom∪⁺⇔∪dom : ∀ {a} → a ∈ dom ((m ∪⁺ m')ˢ) ⇔ a ∈ dom (m ˢ) ∪ dom (m' ˢ) dom∪⁺⇔∪dom {a} = mk⇔ dom∪⁺⊆∪dom ∪dom⊆dom∪⁺ dom∪⁺≡∪dom : dom ((m ∪⁺ m')ˢ) ≡ᵉ dom (m ˢ) ∪ dom (m' ˢ) dom∪⁺≡∪dom = to dom∪⁺⇔∪dom , from dom∪⁺⇔∪dom