@@ -207,4 +207,187 @@ sum-map-+ f g (x ∷ xs) =
207207 f x + g x + (sum (map f xs) + sum (map g xs)) ≡⟨ +-interleave {f x} ⟩
208208 f x + sum (map f xs) + (g x + sum (map g xs)) ∎
209209 where open ≡-Reasoning
210+
211+ module _ {A B : Type} ⦃ _ : DecEq A ⦄ where
212+
213+ open Equivalence
214+
215+ -- The domain of a left-biased union with a singleton adds exactly the singleton's key.
216+ dom-∪ˡ-singleton : (m : A ⇀ B) {k : A} {v : B}
217+ → dom ((m ∪ˡ ❴ k , v ❵ᵐ) ˢ) ≡ᵉ dom (m ˢ) ∪ ❴ k ❵
218+ dom-∪ˡ-singleton m {k} {v} = ⊆-dir , ⊇-dir
219+ where
220+ ⊆-dir : ∀ {a} → a ∈ dom ((m ∪ˡ ❴ k , v ❵ᵐ) ˢ) → a ∈ dom (m ˢ) ∪ ❴ k ❵
221+ ⊆-dir {a} a∈ with from ∈-∪ (proj₁ dom∪ a∈)
222+ ... | inj₁ h = to ∈-∪ (inj₁ h)
223+ ... | inj₂ h with from dom∈ h
224+ ... | b , ab∈f =
225+ to ∈-∪ (inj₂ (to ∈-singleton
226+ (from ∈-dom-singleton-pair (to dom∈ (b , proj₂ (from ∈-filter ab∈f))))))
227+
228+ ⊇-dir : ∀ {a} → a ∈ dom (m ˢ) ∪ ❴ k ❵ → a ∈ dom ((m ∪ˡ ❴ k , v ❵ᵐ) ˢ)
229+ ⊇-dir {a} a∈ with from ∈-∪ a∈
230+ ... | inj₁ a∈m = proj₂ dom∪ (to ∈-∪ (inj₁ a∈m))
231+ ... | inj₂ a∈k with a ∈? dom (m ˢ)
232+ ... | yes a∈m = proj₂ dom∪ (to ∈-∪ (inj₁ a∈m))
233+ ... | no a∉m = proj₂ dom∪ (to ∈-∪ (inj₂ (to dom∈
234+ (v , to ∈-filter (a∉m , to ∈-singleton (cong (_, v) (from ∈-singleton a∈k)))))))
235+
236+ module _ {A : Type} ⦃ _ : DecEq A ⦄ where
237+
238+ open import Axiom.Set.Properties th
239+ using (∪-sym; disjoint-sym; Dec-∈-singleton; ≡ᵉ-isEquivalence)
240+ open import Relation.Binary using (IsEquivalence)
241+ import Algebra.Structures as AlgStructs
242+ open AlgStructs {A = Coin} _≡_ using (IsCommutativeSemigroup)
243+ open import Data.Nat.Properties using (+-isCommutativeSemigroup)
244+ open Equivalence
245+
246+ private instance
247+ Coin-CommutativeSemigroup : IsCommutativeSemigroup _+_
248+ Coin-CommutativeSemigroup = +-isCommutativeSemigroup
249+
250+ -- Removing an entry with known value from a map splits its coin total.
251+ getCoin-remove : (m : A ⇀ Coin) {c : A} {d : Coin}
252+ → (c , d) ∈ m ˢ
253+ → getCoin m ≡ getCoin (m ∣ ❴ c ❵ ᶜ) + d
254+ getCoin-remove m {c} {d} cd∈ = begin
255+ getCoin m
256+ ≡˘⟨ ≡ᵉ-getCoin ((m ∣ ❴ c ❵ ᶜ) ∪ˡ (m ∣ ❴ c ❵)) m decomp≡ᵉ ⟩
257+ getCoin ((m ∣ ❴ c ❵ ᶜ) ∪ˡ (m ∣ ❴ c ❵))
258+ ≡⟨ indexedSumᵛ'-∪ (m ∣ ❴ c ❵ ᶜ) (m ∣ ❴ c ❵) (disjoint-sym res-ex-disjoint) ⟩
259+ getCoin (m ∣ ❴ c ❵ ᶜ) + getCoin (m ∣ ❴ c ❵)
260+ ≡⟨ cong (getCoin (m ∣ ❴ c ❵ ᶜ) +_)
261+ (trans (≡ᵉ-getCoin (m ∣ ❴ c ❵) ❴ c , d ❵ᵐ (res-singleton' {m = m} cd∈))
262+ getCoin-singleton) ⟩
263+ getCoin (m ∣ ❴ c ❵ ᶜ) + d ∎
264+ where
265+ open ≡-Reasoning
266+ module ≡ᵉ = IsEquivalence (≡ᵉ-isEquivalence {A × Coin})
267+ decomp≡ᵉ : ((m ∣ ❴ c ❵ ᶜ) ∪ˡ (m ∣ ❴ c ❵)) ˢ ≡ᵉ m ˢ
268+ decomp≡ᵉ = ≡ᵉ.trans (disjoint-∪ˡ-∪ (disjoint-sym res-ex-disjoint))
269+ (≡ᵉ.trans ∪-sym (res-ex-∪ Dec-∈-singleton))
270+
271+ -- Restricting away an absent key changes nothing.
272+ resᶜ-singleton-∉ : (m : A ⇀ Coin) {c : A}
273+ → c ∉ dom (m ˢ)
274+ → (m ∣ ❴ c ❵ ᶜ) ˢ ≡ᵉ m ˢ
275+ resᶜ-singleton-∉ m {c} c∉ = ex-⊆ , ⊇-dir
276+ where
277+ ⊇-dir : ∀ {x} → x ∈ m ˢ → x ∈ (m ∣ ❴ c ❵ ᶜ) ˢ
278+ ⊇-dir {(a , w)} aw∈ = resᶜ-dom∉⁺ m
279+ (aw∈ , λ a∈c → c∉ (subst (_∈ dom (m ˢ)) (from ∈-singleton a∈c) (to dom∈ (w , aw∈))))
280+
281+ -- Value of an additive union at a key present in only one operand, or in both.
282+ private
283+ ∥∪⁺∥-∉ˡ : (m m' : A ⇀ Coin) {a : A} {v : Coin}
284+ → a ∉ dom (m ˢ) → (a , v) ∈ m' ˢ
285+ → (q : a ∈ dom (m ˢ) ∪ dom (m' ˢ))
286+ → ∥ m ∪⁺ m' ∥ q ≡ v
287+ ∥∪⁺∥-∉ˡ m m' {a} {v} a∉m av∈m' q with a ∈? dom (m ˢ) | a ∈? dom (m' ˢ)
288+ ... | yes a∈m | _ = ⊥-elim (a∉m a∈m)
289+ ... | no _ | yes a∈m' = proj₂ m' (proj₂ (from dom∈ a∈m')) av∈m'
290+ ... | no _ | no a∉m' = ⊥-elim (a∉m' (to dom∈ (v , av∈m')))
291+
292+ ∥∪⁺∥-∉ʳ : (m m' : A ⇀ Coin) {a : A} {v : Coin}
293+ → (a , v) ∈ m ˢ → a ∉ dom (m' ˢ)
294+ → (q : a ∈ dom (m ˢ) ∪ dom (m' ˢ))
295+ → ∥ m ∪⁺ m' ∥ q ≡ v
296+ ∥∪⁺∥-∉ʳ m m' {a} {v} av∈m a∉m' q with a ∈? dom (m ˢ) | a ∈? dom (m' ˢ)
297+ ... | _ | yes a∈m' = ⊥-elim (a∉m' a∈m')
298+ ... | yes a∈m | no _ = proj₂ m (proj₂ (from dom∈ a∈m)) av∈m
299+ ... | no a∉m | no _ = ⊥-elim (a∉m (to dom∈ (v , av∈m)))
300+
301+ ∥∪⁺∥-∈-both : (m m' : A ⇀ Coin) {a : A} {v w : Coin}
302+ → (a , v) ∈ m ˢ → (a , w) ∈ m' ˢ
303+ → (q : a ∈ dom (m ˢ) ∪ dom (m' ˢ))
304+ → ∥ m ∪⁺ m' ∥ q ≡ v + w
305+ ∥∪⁺∥-∈-both m m' {a} {v} {w} av∈m aw∈m' q with a ∈? dom (m ˢ) | a ∈? dom (m' ˢ)
306+ ... | yes a∈m | yes a∈m' = cong₂ _+_ (proj₂ m (proj₂ (from dom∈ a∈m)) av∈m)
307+ (proj₂ m' (proj₂ (from dom∈ a∈m')) aw∈m')
308+ ... | yes _ | no a∉m' = ⊥-elim (a∉m' (to dom∈ (w , aw∈m')))
309+ ... | no a∉m | _ = ⊥-elim (a∉m (to dom∈ (v , av∈m)))
310+
311+ -- Membership in an additive union with a singleton, value made explicit.
312+ ∈-∪⁺-singleton : (m : A ⇀ Coin) {c : A} {v d : Coin}
313+ → (c , v) ∈ m ˢ
314+ → (c , v + d) ∈ (m ∪⁺ ❴ c , d ❵ᵐ) ˢ
315+ ∈-∪⁺-singleton m {c} {v} {d} cv∈ =
316+ subst (λ z → (c , z) ∈ (m ∪⁺ ❴ c , d ❵ᵐ) ˢ)
317+ (∥∪⁺∥-∈-both m ❴ c , d ❵ᵐ cv∈ (to ∈-singleton refl) (∈-incl-set q .proj₁))
318+ (k×∥∪⁺∥∈∪⁺' q)
319+ where
320+ q : c ∈ dom (m ˢ) ∪ dom (❴ c , d ❵ᵐ ˢ)
321+ q = to ∈-∪ (inj₁ (to dom∈ (v , cv∈)))
322+
323+ ∈-∪⁺-singleton-∉ : (m : A ⇀ Coin) {c : A} {d : Coin}
324+ → c ∉ dom (m ˢ)
325+ → (c , d) ∈ (m ∪⁺ ❴ c , d ❵ᵐ) ˢ
326+ ∈-∪⁺-singleton-∉ m {c} {d} c∉ =
327+ subst (λ z → (c , z) ∈ (m ∪⁺ ❴ c , d ❵ᵐ) ˢ)
328+ (∥∪⁺∥-∉ˡ m ❴ c , d ❵ᵐ c∉ (to ∈-singleton refl) (∈-incl-set q .proj₁))
329+ (k×∥∪⁺∥∈∪⁺' q)
330+ where
331+ q : c ∈ dom (m ˢ) ∪ dom (❴ c , d ❵ᵐ ˢ)
332+ q = to ∈-∪ (inj₂ (to dom∈ (d , to ∈-singleton refl)))
333+
334+ -- Adding at a key does not disturb the restriction away from that key.
335+ ∪⁺-singleton-resᶜ : (m : A ⇀ Coin) {c : A} {d : Coin}
336+ → ((m ∪⁺ ❴ c , d ❵ᵐ) ∣ ❴ c ❵ ᶜ) ˢ ≡ᵉ (m ∣ ❴ c ❵ ᶜ) ˢ
337+ ∪⁺-singleton-resᶜ m {c} {d} = ⊆-dir , ⊇-dir
338+ where
339+ a∉sing-dom : ∀ {a} → a ∉ ❴ c ❵ → a ∉ dom (❴ c , d ❵ᵐ ˢ)
340+ a∉sing-dom a∉ a∈ = a∉ (to ∈-singleton (from ∈-dom-singleton-pair a∈))
341+
342+ ⊆-dir : ∀ {x} → x ∈ ((m ∪⁺ ❴ c , d ❵ᵐ) ∣ ❴ c ❵ ᶜ) ˢ → x ∈ (m ∣ ❴ c ❵ ᶜ) ˢ
343+ ⊆-dir {(a , w)} x∈ with resᶜ-dom∉⁻ (m ∪⁺ ❴ c , d ❵ᵐ) x∈
344+ ... | aw∈m⁺ , a∉c with from ∈-∪ (∪⁺-dom∪ aw∈m⁺)
345+ ... | inj₂ h = ⊥-elim (a∉sing-dom a∉c h)
346+ ... | inj₁ a∈m = resᶜ-dom∉⁺ m
347+ (subst (λ z → (a , z) ∈ m ˢ) (sym w≡v) (proj₂ (from dom∈ a∈m)) , a∉c)
348+ where
349+ q : _ ∈ dom (m ˢ) ∪ dom (❴ c , d ❵ᵐ ˢ)
350+ q = to ∈-∪ (inj₁ a∈m)
351+ w≡v : w ≡ proj₁ (from dom∈ a∈m)
352+ w≡v = trans (proj₂ (m ∪⁺ ❴ c , d ❵ᵐ) aw∈m⁺ (k×∥∪⁺∥∈∪⁺' q))
353+ (∥∪⁺∥-∉ʳ m ❴ c , d ❵ᵐ (proj₂ (from dom∈ a∈m)) (a∉sing-dom a∉c)
354+ (∈-incl-set q .proj₁))
355+
356+ ⊇-dir : ∀ {x} → x ∈ (m ∣ ❴ c ❵ ᶜ) ˢ → x ∈ ((m ∪⁺ ❴ c , d ❵ᵐ) ∣ ❴ c ❵ ᶜ) ˢ
357+ ⊇-dir {(a , w)} x∈ with resᶜ-dom∉⁻ m x∈
358+ ... | aw∈m , a∉c = resᶜ-dom∉⁺ (m ∪⁺ ❴ c , d ❵ᵐ)
359+ (subst (λ z → (a , z) ∈ (m ∪⁺ ❴ c , d ❵ᵐ) ˢ) v≡w (k×∥∪⁺∥∈∪⁺' q) , a∉c)
360+ where
361+ q : _ ∈ dom (m ˢ) ∪ dom (❴ c , d ❵ᵐ ˢ)
362+ q = to ∈-∪ (inj₁ (to dom∈ (w , aw∈m)))
363+ v≡w : ∥ m ∪⁺ ❴ c , d ❵ᵐ ∥ (∈-incl-set q .proj₁) ≡ w
364+ v≡w = ∥∪⁺∥-∉ʳ m ❴ c , d ❵ᵐ aw∈m (a∉sing-dom a∉c) (∈-incl-set q .proj₁)
365+
366+ -- Additive union with a singleton adds its coin to the total.
367+ getCoin-∪⁺-singleton : (m : A ⇀ Coin) {c : A} {d : Coin}
368+ → getCoin (m ∪⁺ ❴ c , d ❵ᵐ) ≡ getCoin m + d
369+ getCoin-∪⁺-singleton m {c} {d} with c ∈? dom (m ˢ)
370+ ... | no c∉m = begin
371+ getCoin (m ∪⁺ ❴ c , d ❵ᵐ)
372+ ≡⟨ getCoin-remove (m ∪⁺ ❴ c , d ❵ᵐ) (∈-∪⁺-singleton-∉ m c∉m) ⟩
373+ getCoin ((m ∪⁺ ❴ c , d ❵ᵐ) ∣ ❴ c ❵ ᶜ) + d
374+ ≡⟨ cong (_+ d) (≡ᵉ-getCoin ((m ∪⁺ ❴ c , d ❵ᵐ) ∣ ❴ c ❵ ᶜ) (m ∣ ❴ c ❵ ᶜ)
375+ (∪⁺-singleton-resᶜ m)) ⟩
376+ getCoin (m ∣ ❴ c ❵ ᶜ) + d
377+ ≡⟨ cong (_+ d) (≡ᵉ-getCoin (m ∣ ❴ c ❵ ᶜ) m (resᶜ-singleton-∉ m c∉m)) ⟩
378+ getCoin m + d ∎
379+ where open ≡-Reasoning
380+ ... | yes c∈m = begin
381+ getCoin (m ∪⁺ ❴ c , d ❵ᵐ)
382+ ≡⟨ getCoin-remove (m ∪⁺ ❴ c , d ❵ᵐ) (∈-∪⁺-singleton m (proj₂ (from dom∈ c∈m))) ⟩
383+ getCoin ((m ∪⁺ ❴ c , d ❵ᵐ) ∣ ❴ c ❵ ᶜ) + (proj₁ (from dom∈ c∈m) + d)
384+ ≡⟨ cong (_+ (proj₁ (from dom∈ c∈m) + d))
385+ (≡ᵉ-getCoin ((m ∪⁺ ❴ c , d ❵ᵐ) ∣ ❴ c ❵ ᶜ) (m ∣ ❴ c ❵ ᶜ)
386+ (∪⁺-singleton-resᶜ m)) ⟩
387+ getCoin (m ∣ ❴ c ❵ ᶜ) + (proj₁ (from dom∈ c∈m) + d)
388+ ≡˘⟨ +-assoc (getCoin (m ∣ ❴ c ❵ ᶜ)) (proj₁ (from dom∈ c∈m)) d ⟩
389+ getCoin (m ∣ ❴ c ❵ ᶜ) + proj₁ (from dom∈ c∈m) + d
390+ ≡˘⟨ cong (_+ d) (getCoin-remove m (proj₂ (from dom∈ c∈m))) ⟩
391+ getCoin m + d ∎
392+ where open ≡-Reasoning
210393```
0 commit comments