Skip to content

Commit bb92685

Browse files
committed
[Dijkstra] Ledger.Prelude: coin lemmas for additive-union singletons and entry removal
Adds getCoin-remove (splitting off a known entry), getCoin-∪⁺-singleton (getCoin (m ∪⁺ ❴ c , d ❵) ≡ getCoin m + d) with its private value-level scaffolding, resᶜ-singleton-∉, ∈-∪⁺-singleton(-∉), ∪⁺-singleton-resᶜ, and dom-∪ˡ-singleton. Consumed by the Dijkstra Certs PoV proofs. AI-assisted: Claude Fable 5 (Anthropic)
1 parent adaaf52 commit bb92685

1 file changed

Lines changed: 183 additions & 0 deletions

File tree

src/Ledger/Prelude.lagda.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)