@@ -13,7 +13,7 @@ transition rule `CERT`{.AgdaDatatype}:
1313 (` CERT-coinFromDeposits-step ` {.AgdaFunction}): the post-step
1414 ` coinFromDeposits ` {.AgdaFunction} is equal to the coin-valuation of the
1515 closed-form ` updateCertDeposit ` {.AgdaFunction} applied to the pre-step
16- deposit-pot triple.
16+ deposits triple.
1717
1818The first is the per-step ingredient of ` CERTS-pov ` {.AgdaFunction} in
1919` Certs.Properties.PoV ` {.AgdaModule}. The second is the per-step ingredient
@@ -26,32 +26,21 @@ quantities appearing in the UTXO batch-balance equation.
2626## Why coin form, and why the ` ≡ᵐ ` -componentwise scaffolding
2727
2828A naïve triple-form bridging lemma would say
29-
30- pots s' ≡ updateCertDeposit pp dCert (pots s)
31-
32- ** propositionally** . For the ` POOL-rereg ` case, the rule leaves the
33- pool-deposit pot unchanged, but ` updateCertDeposit ` {.AgdaFunction} appends
34- ` ❴ kh , poolDeposit ❵ ` . Closing this gap requires the equation
35-
36- m ∪ˡ ❴ k , v ❵ ≡ m (when k ∈ dom m),
37-
38- which ` agda-sets ` only provides up to ` ≡ᵐ ` {.AgdaFunction} (extensional map
39- equality), ** not** propositional ` ≡ ` .
29+ ` pots s' ≡ updateCertDeposit pp dCert (pots s) ` ** propositionally** .
30+ For the ` POOL-rereg ` case, the rule leaves the pool-deposit pot unchanged, but
31+ ` updateCertDeposit ` {.AgdaFunction} appends ` ❴ kh , poolDeposit ❵ ` . Closing this gap
32+ requires the equation ` m ∪ˡ ❴ k , v ❵ ≡ m ` (when ` k ∈ dom m ` ), which ` agda-sets ` only
33+ provides up to ` ≡ᵐ ` (extensional map equality), ** not** propositional ` ≡ ` .
4034
4135To avoid introducing a deferred propositional version of that fact, we work
4236at two levels:
4337
4438+ The ** per-step triple-form bridge** ` CERT-pots-≡ᵐᵗ ` {.AgdaFunction} states
45- ` pots s' ` {.AgdaFunction} and the closed-form output agree
46- ** componentwise modulo ` ≡ᵐ ` ** . The ` POOL-rereg ` case uses
47- ` singleton-∈-∪ˡ ` {.AgdaFunction} from ` agda-sets `
48-
49- a ∈ dom m → m ∪ˡ ❴ (a , b) ❵ᵐ ≡ᵐ m
50-
51- — a parameter-free fact.
39+ ` pots s' ` {.AgdaFunction} and the ` updateCertDeposits ` output agree
40+ ** componentwise modulo ` ≡ᵐ ` ** .
5241+ The ** per-step coin-form bridge** ` CERT-coinFromDeposits-step ` {.AgdaFunction}
5342 is derived from ` CERT-pots-≡ᵐᵗ ` {.AgdaFunction} by collapsing each
54- ` ≡ᵐ ` {.AgdaFunction} component to a coin equality via ` ≡ᵉ-getCoin ` {.AgdaFunction},
43+ ` ≡ᵐ ` component to a coin equality via ` ≡ᵉ-getCoin ` {.AgdaFunction},
5544 and summing the three resulting equalities.
5645
5746The ` ≡ᵐ ` -componentwise relation ` _≡ᵐᵗ_ ` threads through the list-iterated closed
@@ -66,35 +55,6 @@ pool-deposit-alignment invariant under one `CERT` step), consumed in
6655` Certs.Properties.PoV ` {.AgdaModule} and discharged at the ` CHAIN ` -invariant
6756layer in a follow-up issue.
6857
69- ## A note on unresolved-implicit hygiene
70-
71- Several lemmas in this module rely on ` agda-sets ` ` Map ` -respecting cong
72- operations (` ∪ˡ-cong ` {.AgdaFunction}, ` restrict-cong ` {.AgdaFunction},
73- ` ∪⁺-cong-r ` {.AgdaFunction}, ` ≡ᵐ-refl ` {.AgdaFunction}, ` ≡ᵉ-getCoin ` {.AgdaFunction}).
74- A subtle interaction with the definition of ` _≡ᵐ_ ` {.AgdaFunction} —
75- ` m ≡ᵐ m' ` unfolds to ` m ˢ ≡ᵉ m' ˢ ` , which only constrains the ** relation**
76- projection of the ` Map ` Σ — means that unification through ` _≡ᵐ_ ` does not
77- propagate ` left-unique ` {.AgdaFunction} witnesses. Two patterns avoid the
78- resulting unresolved metas:
79-
80- + When a lemma has ** implicit** ` Map ` arguments (like the four maps of ` ∪ˡ-cong ` ),
81- we pass them explicitly at the call site:
82- ` ∪ˡ-cong {m = b} {m' = sing} {m'' = b'} {m''' = sing} … ` .
83- + When defining lemmas whose implicit ` Triple ` arguments would be decomposed
84- by an LHS pattern (` {a , b , g} ` ), we instead bind the triple variable
85- directly (` {t} ` ) and project explicitly in the body (` proj₁ t ` , etc.).
86- Pattern destructuring at an ** implicit** position introduces three fresh
87- implicit Map metas — one per component — whose ` .proj₂ ` (` left-unique ` )
88- doesn't get pinned by the usual ` _≡ᵐ_ ` -based unification. Projection
89- terms have no such gap because the ` Map ` Σ remains atomically referenced
90- through ` t ` .
91-
92- The two patterns combined keep all ` Σ ` -level facts concrete at every call
93- site — relation ** and** ` left-unique ` — and the module typechecks meta-free.
94- (` pots s' ` for ` ≡ᵐᵗ-refl ` in the seven refl cases of ` CERT-pots-≡ᵐᵗ ` , and
95- explicit ` depᵖ ` /` depᵖ ∪ˡ ❴ kh , pp .poolDeposit ❵ᵐ ` to ` ≡ᵐ-sym ` in the
96- ` POOL-rereg ` case, follow the same principle.)
97-
9858<!--
9959```agda
10060{-# OPTIONS --safe #-}
@@ -104,24 +64,19 @@ open import Ledger.Dijkstra.Specification.Gov.Base using (GovStructure)
10464module Ledger.Dijkstra.Specification.Certs.Properties.PoVLemmas
10565 (gs : GovStructure) (open GovStructure gs) where
10666
107- open import Ledger.Prelude
108- open import Ledger.Dijkstra.Specification.Certs gs
109- open import Ledger.Dijkstra.Specification.Gov.Actions gs hiding (yes; no)
110-
111- -- `_∪⁺_`- and `_∣_ᶜ`-respecting `≡ᵐ`-cong lemmas. These live in the
112- -- `Extra` module of `abstract-set-theory`; named explicitly so we don't
113- -- depend on whichever subset `Ledger.Prelude` re-exports today.
114- open import abstract-set-theory.Axiom.Set.Map.Extra
115- using (∪⁺-cong-r; restrict-cong)
116-
117- open import Axiom.Set.Properties th
11867open import Algebra using (CommutativeMonoid)
11968import Algebra.Structures as AlgStruct
12069open import Data.Maybe using (Is-just)
12170open import Data.Nat.Properties using (+-0-monoid; +-identityʳ)
12271open import Relation.Binary using (IsEquivalence)
12372open import Relation.Nullary.Decidable
12473
74+ open import Ledger.Prelude
75+ open import Ledger.Dijkstra.Specification.Certs gs
76+ open import Ledger.Dijkstra.Specification.Gov.Actions gs hiding (yes; no)
77+ open import abstract-set-theory.Axiom.Set.Map.Extra using (∪⁺-cong-r; restrict-cong)
78+ open import Axiom.Set.Properties th
79+
12580-- TODO: some hoop-jumping required since the Map proofs need the
12681-- stdlib IsCommutativeSemigroup for Coin.
12782open AlgStruct {A = Coin} _≡_ using (IsCommutativeSemigroup)
@@ -147,39 +102,15 @@ open Equivalence
147102```
148103-->
149104
150- ## Deposit-pot triple and closed-form helpers {#sec: triple-helpers }
151-
152- The three deposit pots carried by a ` CertState ` {.AgdaRecord} live in
153- distinct map types (` Credential ⇀ Coin ` , ` KeyHash ⇀ Coin ` , ` Credential ⇀ Coin ` ),
154- so we package them as a single ` Triple ` {.AgdaFunction}, inhabitants of which are
155- constructed via ` pots ` {.AgdaFunction}, and values of which are computed via
156- ` coinFromDeposits-pots ` {.AgdaFunction}. By definition,
157-
158- coinFromDeposits cs ≡ coinFromDeposits-pots (pots cs).
159-
160- ``` agda
161- Triple : Type
162- Triple = (Credential ⇀ Coin) × (KeyHash ⇀ Coin) × (Credential ⇀ Coin)
163-
164- pots : CertState → Triple
165- pots cs =
166- ( DepositsOf (DStateOf cs)
167- , DepositsOf (PStateOf cs)
168- , DepositsOf (GStateOf cs)
169- )
170-
171- coinFromDeposits-pots : Triple → Coin
172- coinFromDeposits-pots (depᵈ , depᵖ , depᵍ) =
173- getCoin depᵈ + getCoin depᵖ + getCoin depᵍ
174- ```
105+ ## Deposit triple and helpers {#sec: triple-helpers }
175106
176- The per-step pots equation
107+ The per-step deposit update equation
177108
178109 pots (updateCertDepositsStep pp s c) ≡ updateCertDeposit pp c (pots s)
179110
180- is ** propositional** : by Σ-η on ` Triple ` {.AgdaFunction } and record-η on the three
181- ` record dState { deposits = ... } ` updates inside
182- ` updateCertDepositsStep ` {.AgdaFunction}, both sides reduce to the same expression.
111+ is ** propositional** : by Σ-η on ` DepositTriple ` {.AgdaDatatype } and record-η on the three
112+ record updates inside ` updateCertDepositsStep ` {.AgdaFunction}, both sides reduce to
113+ the same expression.
183114
184115``` agda
185116pots-updateCertDepositsStep : (pp : PParams) (s : CertState) (c : DCert)
@@ -192,7 +123,7 @@ The triple-level closed-form iteration mirrors the rule-level
192123over a list of certificates.
193124
194125``` agda
195- updateCertDeposit-list : PParams → Triple → List DCert → Triple
126+ updateCertDeposit-list : PParams → DepositsTriple → List DCert → DepositsTriple
196127updateCertDeposit-list pp t = foldl (λ t' c → updateCertDeposit pp c t') t
197128```
198129
@@ -217,7 +148,7 @@ pots-updateCertDeposits pp s (c ∷ cs') =
217148
218149``` agda
219150-- Componentwise extensional map equality on `Triple`.
220- _≡ᵐᵗ_ : Triple → Triple → Type
151+ _≡ᵐᵗ_ : DepositsTriple → DepositsTriple → Type
221152(a₁ , b₁ , c₁) ≡ᵐᵗ (a₂ , b₂ , c₂) =
222153 (a₁ ≡ᵐ a₂) × (b₁ ≡ᵐ b₂) × (c₁ ≡ᵐ c₂)
223154
@@ -261,41 +192,30 @@ and `kh` explicitly and pass the fully-constructed singleton
261192` ❴ kh , pp .poolDeposit ❵ᵐ ` to ` ≡ᵐ-refl ` {.AgdaFunction}.
262193
263194``` agda
264- updateCertDeposit-≡ᵐᵗ : (pp : PParams) (c : DCert) {t t' : Triple}
265- → t ≡ᵐᵗ t'
266- → updateCertDeposit pp c t ≡ᵐᵗ updateCertDeposit pp c t'
267- updateCertDeposit-≡ᵐᵗ _ (delegate _ _ _ _) (a≡ , b≡ , g≡) =
268- ∪⁺-cong-r a≡ , b≡ , g≡
269- updateCertDeposit-≡ᵐᵗ _ (dereg _ _) {a , _ , _} {a' , _ , _} (a≡ , b≡ , g≡) =
195+ updateCertDeposit-≡ᵐᵗ : (pp : PParams) (c : DCert) {t t' : DepositsTriple}
196+ → t ≡ᵐᵗ t' → updateCertDeposit pp c t ≡ᵐᵗ updateCertDeposit pp c t'
197+ updateCertDeposit-≡ᵐᵗ _ (delegate _ _ _ _) (a≡ , b≡ , g≡) = ∪⁺-cong-r a≡ , b≡ , g≡
198+ updateCertDeposit-≡ᵐᵗ _ (dereg _ _) {a , _ , _} {a' , _ , _} (a≡ , b≡ , g≡) =
270199 restrict-cong a a' a≡ , b≡ , g≡
271- updateCertDeposit-≡ᵐᵗ pp (regpool kh _) {t = t} {t' = t'} (a≡ , b≡ , g≡) =
272- -- `∪ˡ-cong` has four **implicit** Map arguments {m m' m'' m'''}. Inferring
273- -- them only from `b≡ : … ≡ᵐ …` and `≡ᵐ-refl sing : sing ≡ᵐ sing` pins each
274- -- meta's `.proj₁` (the relation) but leaves its `.proj₂` (`left-unique`)
275- -- as a separate meta — `_≡ᵐ_`'s definition `m ˢ ≡ᵉ m' ˢ` simply doesn't
276- -- mention the Σ-tail. We pass all four explicitly: `b` and `b'` projected
277- -- from `t` and `t'` (the projection form keeps the Σ atomically referenced
278- -- and avoids the implicit-pattern-meta issue), and the singleton itself
279- -- for both `m'` and `m'''`.
280- let sing = ❴ kh , pp .poolDeposit ❵ᵐ
281- b = proj₁ (proj₂ t)
282- b' = proj₁ (proj₂ t')
283- in a≡ , ∪ˡ-cong {m = b} {m' = sing} {m'' = b'} {m''' = sing} b≡ (≡ᵐ-refl sing) , g≡
284- updateCertDeposit-≡ᵐᵗ _ (regdrep _ _ _) (a≡ , b≡ , g≡) =
285- a≡ , b≡ , ∪⁺-cong-r g≡
286- updateCertDeposit-≡ᵐᵗ _ (deregdrep _ _) {_ , _ , g} {_ , _ , g'} (a≡ , b≡ , g≡) =
200+ updateCertDeposit-≡ᵐᵗ
201+ pp (regpool kh _) {t = (_ , b , _)} {t' = (_ , b' , _)} (a≡ , b≡ , g≡) =
202+ a≡ , ∪ˡ-cong {m = b} {m' = sngl} {m'' = b'} {m''' = sngl} b≡ (≡ᵐ-refl sngl) , g≡
203+ where
204+ sngl : KeyHash ⇀ Coin
205+ sngl = ❴ kh , pp .poolDeposit ❵ᵐ
206+ updateCertDeposit-≡ᵐᵗ _ (regdrep _ _ _) (a≡ , b≡ , g≡) = a≡ , b≡ , ∪⁺-cong-r g≡
207+ updateCertDeposit-≡ᵐᵗ _ (deregdrep _ _) {_ , _ , g} {_ , _ , g'} (a≡ , b≡ , g≡) =
287208 a≡ , b≡ , restrict-cong g g' g≡
288- updateCertDeposit-≡ᵐᵗ _ (retirepool _ _) eq = eq
289- updateCertDeposit-≡ᵐᵗ _ (ccreghot _ _) eq = eq
209+ updateCertDeposit-≡ᵐᵗ _ (retirepool _ _) eq = eq
210+ updateCertDeposit-≡ᵐᵗ _ (ccreghot _ _) eq = eq
290211```
291212
292213The list-iterated version is straightforward induction on the list,
293214delegating to ` updateCertDeposit-≡ᵐᵗ ` {.AgdaFunction} at each step.
294215
295216``` agda
296- updateCertDeposit-list-≡ᵐᵗ : (pp : PParams) (cs : List DCert) {t t' : Triple}
297- → t ≡ᵐᵗ t'
298- → updateCertDeposit-list pp t cs ≡ᵐᵗ updateCertDeposit-list pp t' cs
217+ updateCertDeposit-list-≡ᵐᵗ : (pp : PParams) (cs : List DCert) {t t' : DepositsTriple}
218+ → t ≡ᵐᵗ t' → updateCertDeposit-list pp t cs ≡ᵐᵗ updateCertDeposit-list pp t' cs
299219updateCertDeposit-list-≡ᵐᵗ _ [] eq = eq
300220updateCertDeposit-list-≡ᵐᵗ pp (c ∷ cs') eq =
301221 updateCertDeposit-list-≡ᵐᵗ pp cs' (updateCertDeposit-≡ᵐᵗ pp c eq)
@@ -305,15 +225,9 @@ Finally, `≡ᵐᵗ`-equal triples have equal coin valuations: collapse each
305225component via ` ≡ᵉ-getCoin ` {.AgdaFunction} and sum.
306226
307227``` agda
308- coinFromDeposits-pots-cong : {t t' : Triple }
228+ coinFromDeposits-pots-cong : {t t' : DepositsTriple }
309229 → t ≡ᵐᵗ t' → coinFromDeposits-pots t ≡ coinFromDeposits-pots t'
310230coinFromDeposits-pots-cong {t} {t'} (a≡ , b≡ , g≡) =
311- -- We bind `{t}` `{t'}` and project, rather than pattern-matching
312- -- `{a , b , g}` `{a' , b' , g'}`. An implicit-position pattern on a
313- -- `Triple` introduces three fresh implicit Map metas (one per component)
314- -- whose `left-unique` Σ-fields aren't propagated by Agda's unification;
315- -- the projection form leaves each component as a concrete projection
316- -- term, fully determining both Σ-fields.
317231 cong₂ _+_
318232 (cong₂ _+_ (≡ᵉ-getCoin (proj₁ t) (proj₁ t') a≡)
319233 (≡ᵉ-getCoin (proj₁ (proj₂ t)) (proj₁ (proj₂ t')) b≡))
0 commit comments