Skip to content

Commit dcb9749

Browse files
committed
add props modules to barrel; other improvements
1 parent 1f1278b commit dcb9749

5 files changed

Lines changed: 94 additions & 97 deletions

File tree

src/Ledger/Dijkstra/Specification.lagda.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ import Ledger.Dijkstra.Specification.Enact.Properties
6969
import Ledger.Dijkstra.Specification.Entities
7070
import Ledger.Dijkstra.Specification.Entities.Properties
7171
```
72+
7273
## <span class="AgdaModule">Epoch</span>
7374

7475
```agda

src/Ledger/Dijkstra/Specification/Entities/Properties.lagda.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ module Ledger.Dijkstra.Specification.Entities.Properties where
1313
-->
1414

1515
```agda
16+
open import Ledger.Dijkstra.Specification.Entities.Properties.ApplyToRewardsPoV
1617
open import Ledger.Dijkstra.Specification.Entities.Properties.Computational
18+
open import Ledger.Dijkstra.Specification.Entities.Properties.PoV
1719
```

src/Ledger/Dijkstra/Specification/Entities/Properties/ApplyToRewardsPoV.lagda.md

Lines changed: 73 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,24 @@ source_path: src/Ledger/Dijkstra/Specification/Entities/Properties/ApplyToReward
55

66
# `applyToRewards` Preservation of Value {#sec:apply-to-rewards-pov}
77

8-
This module proves preservation of value for the two specialisations of
9-
`applyToRewards`{.AgdaFunction} used inside the `ENTITIES`{.AgdaDatatype} rule:
10-
11-
+ `applyWithdrawals-pov`{.AgdaFunction}: `applyWithdrawals`{.AgdaFunction}
12-
*decreases* the total rewards balance by exactly the sum of withdrawal
13-
amounts. Truncating subtraction (`_∸_`) means the per-step lemma requires
14-
`amt ≤ bal`, and the fold induction requires a `Unique`{.AgdaDatatype} witness on
15-
the stake-projected withdrawal list so that no already-reduced balance is
16-
revisited.
17-
+ `applyDirectDeposits-pov`{.AgdaFunction}: `applyDirectDeposits`{.AgdaFunction}
18-
*increases* the total rewards balance by exactly the sum of direct-deposit
19-
amounts. Because `_+_` is total and commutative, revisiting a credential is
20-
harmless, so neither the `NetworkId`{.AgdaFunction} witness nor the
21-
`Unique`{.AgdaDatatype} premise is needed.
8+
This module proves preservation of value for the two specializations of
9+
`applyToRewards`{.AgdaFunction} used inside the `ENTITIES`{.AgdaDatatype} rule.
10+
11+
+ `applyWithdrawals-pov`{.AgdaFunction}.
12+
13+
`applyWithdrawals`{.AgdaFunction} *decreases* the total rewards balance by exactly
14+
the sum of withdrawal amounts. Truncating subtraction (`_∸_`) means the per-step
15+
lemma requires `amt ≤ bal`, and the fold induction requires a
16+
`Unique`{.AgdaDatatype} witness on the stake-projected withdrawal list so that no
17+
already-reduced balance is revisited.
18+
19+
+ `applyDirectDeposits-pov`{.AgdaFunction}.
20+
21+
`applyDirectDeposits`{.AgdaFunction} *increases* the total rewards balance by
22+
exactly the sum of direct-deposit amounts. Because `_+_` is total and
23+
commutative, revisiting a credential is harmless, so neither the
24+
`NetworkId`{.AgdaFunction} witness nor the `Unique`{.AgdaDatatype} premise is
25+
needed.
2226

2327
Both lemmas share a common backbone: a per-step result about
2428
`applyOne`{.AgdaFunction} (the lambda body of `applyToRewards`{.AgdaFunction})
@@ -34,30 +38,26 @@ open import Ledger.Dijkstra.Specification.Gov.Base using (GovStructure)
3438
module Ledger.Dijkstra.Specification.Entities.Properties.ApplyToRewardsPoV
3539
(gs : GovStructure) (open GovStructure gs) where
3640
37-
open import Ledger.Prelude
38-
open import Ledger.Dijkstra.Specification.Account gs using (DirectDeposits)
39-
open import Ledger.Dijkstra.Specification.Certs gs
40-
open import Ledger.Dijkstra.Specification.Entities gs
41-
open import Ledger.Dijkstra.Specification.Gov.Actions gs hiding (yes; no)
42-
43-
open import Axiom.Set.Properties th
44-
45-
open import Data.Nat.Properties
46-
using (+-0-monoid; +-identityʳ; +-comm; +-assoc; m∸n+n≡m; n≤0⇒n≡0)
41+
open import Data.Nat.Properties using (+-identityʳ; +-comm; +-assoc; m∸n+n≡m; n≤0⇒n≡0)
4742
open import Data.Maybe.Properties using (just-injective)
48-
open import Data.List.Relation.Unary.Unique.Propositional
49-
using (Unique) renaming (_∷_ to _::_)
5043
open import Data.List.Membership.Propositional.Properties using (∈-map⁺)
5144
open import Data.List.Relation.Unary.Any using (Any)
52-
import Data.List.Relation.Unary.All as All
45+
open import Data.List.Relation.Unary.All using (lookup)
46+
open import Data.List.Relation.Unary.Unique.Propositional using (Unique) renaming (_∷_ to _::_)
5347
open import Relation.Binary using (IsEquivalence)
5448
49+
open import Ledger.Prelude hiding (lookup)
50+
51+
open import Ledger.Dijkstra.Specification.Account gs using (DirectDeposits)
52+
open import Ledger.Dijkstra.Specification.Certs gs using (Rewards)
53+
open import Ledger.Dijkstra.Specification.Entities gs
54+
using (applyWithdrawals; applyDirectDeposits)
55+
56+
open import Axiom.Set.Properties th
57+
5558
open RewardAddress
5659
open Any
5760
open ≡-Reasoning
58-
59-
instance
60-
_ = +-0-monoid
6161
```
6262
-->
6363

@@ -70,13 +70,9 @@ getCoin-∪ˡ-overwrite : (acc : Rewards) (c : Credential) (v : Coin)
7070

7171
<!--
7272
```agda
73-
-- After a recent refactor of applyToRewards, the fold body writes to its accumulator
74-
-- via ❴ k , v ❵ ∪ˡ acc; that is, a singleton-on-the-left union with no complement
75-
-- restriction on acc. Left-biasedness of ∪ˡ makes this extensionally equal to the
76-
-- older ❴ k , v ❵ ∪ˡ (acc ∣ ❴ k ❵ ᶜ) form (singleton wins; existing entries at k are
77-
-- shadowed). The lemma below is the corresponding getCoin-level equation, which
78-
-- both per-step lemmas (applyOne-pov, applyOne-pov-add) land on as a common
79-
-- right-hand side.
73+
-- The new applyToRewards writes to its accumulator via ❴ k , v ❵ ∪ˡ acc;
74+
-- left-biasedness of ∪ˡ makes this extensionally equal to the older
75+
-- ❴ k , v ❵ ∪ˡ (acc ∣ ❴ k ❵ ᶜ) form; the following proves this at the getCoin level.
8076
getCoin-∪ˡ-overwrite acc c v =
8177
begin
8278
getCoin (❴ c , v ❵ ∪ˡ acc)
@@ -91,14 +87,8 @@ getCoin-∪ˡ-overwrite acc c v =
9187
open Equivalence
9288
module ≡ᵉ = IsEquivalence (≡ᵉ-isEquivalence {Credential × Coin})
9389
94-
-- res-decomp (from Ledger.Prelude) gives
95-
-- (❴ c , v ❵ᵐ ∪ˡ acc) ˢ ≡ᵉ (❴ c , v ❵ᵐ ∪ˡ (acc ∣ dom (❴ c , v ❵ᵐ ˢ) ᶜ)) ˢ
96-
-- but the bridge wants acc ∣ ❴ c ❵ ᶜ on the right (set-singleton via the listing
97-
-- axiom), not acc ∣ dom (❴ c , v ❵ᵐ ˢ) ᶜ (set built via replacement/mapˢ).
98-
-- These two restriction sets are extensionally equal by dom-single≡single, so we
99-
-- chain res-decomp with an ∪ˡ-congruence on the right operand.
10090
restrict-cong-∪ˡ :
101-
(❴ c , v ❵ᵐ ∪ˡ (acc ∣ dom (❴ c , v ❵ᵐ ˢ) ᶜ)) ˢ ≡ᵉ (❴ c , v ❵ᵐ ∪ˡ (acc ∣ ❴ c ❵ ᶜ)) ˢ
91+
(❴ c , v ❵ᵐ ∪ˡ acc ∣ dom ❴ c , v ❵ᵐ ) ˢ ≡ᵉ (❴ c , v ❵ᵐ ∪ˡ (acc ∣ ❴ c ❵ ᶜ)) ˢ
10292
restrict-cong-∪ˡ =
10393
∪ˡ-cong {m = ❴ c , v ❵ᵐ} {m' = acc ∣ dom (❴ c , v ❵ᵐ ˢ) ᶜ}
10494
{m'' = ❴ c , v ❵ᵐ} {m''' = acc ∣ ❴ c ❵ ᶜ}
@@ -120,18 +110,14 @@ split-by-lookup : (acc : Rewards) (c : Credential) (bal : Coin)
120110
<!--
121111
```agda
122112
-- When lookupᵐ? acc c ≡ just bal, we can decompose getCoin acc into the contribution
123-
-- of c (which is bal) plus the contribution of every other credential
124-
-- (getCoin (acc ∣ ❴ c ❵ ᶜ)). This is the shared prefix used by both per-step lemmas,
125-
-- factored out to avoid duplication.
113+
-- of c (which is bal) plus the contribution of every other credential, getCoin (acc ∣ ❴ c ❵ ᶜ).
126114
split-by-lookup acc c bal lookup-eq =
127115
begin
128116
getCoin acc
129-
≡˘⟨ ≡ᵉ-getCoin decomp acc
130-
( ≡ᵉ.trans (disjoint-∪ˡ-∪ (disjoint-sym res-ex-disjoint))
131-
(≡ᵉ.trans ∪-sym (res-ex-∪ Dec-∈-singleton)) ) ⟩
117+
≡˘⟨ ≡ᵉ-getCoin decomp acc ( ≡ᵉ.trans (disjoint-∪ˡ-∪ (disjoint-sym res-ex-disjoint))
118+
(≡ᵉ.trans ∪-sym (res-ex-∪ Dec-∈-singleton)) ) ⟩
132119
getCoin decomp
133-
≡⟨ indexedSumᵛ'-∪ (acc ∣ ❴ c ❵ ᶜ) (acc ∣ ❴ c ❵)
134-
(disjoint-sym res-ex-disjoint) ⟩
120+
≡⟨ indexedSumᵛ'-∪ (acc ∣ ❴ c ❵ ᶜ) (acc ∣ ❴ c ❵) (disjoint-sym res-ex-disjoint) ⟩
135121
getCoin (acc ∣ ❴ c ❵ ᶜ) + getCoin (acc ∣ ❴ c ❵)
136122
≡⟨ cong (getCoin (acc ∣ ❴ c ❵ ᶜ) +_) acc∣c≡bal ⟩
137123
getCoin (acc ∣ ❴ c ❵ ᶜ) + bal
@@ -159,20 +145,17 @@ split-by-lookup acc c bal lookup-eq =
159145

160146
## The `ApplyToRewards-PoV` module
161147

162-
The three assumed identities below are the same set/map identities used
163-
by the Conway PoV proofs; they are stated as module parameters here to
164-
keep this commit focused on the fold-induction structure and to be
165-
discharged in a follow-up against the `agda-sets` library.
166-
167-
+ `∪ˡ-lookup-preserve`: lookup in a left-biased union with a singleton
168-
at `c` agrees with lookup in the right map for any key `c' ≠ c`.
169-
+ `sum-map-proj₂≡getCoin`: the `getCoin`{.AgdaFunction} representation
170-
of a `(RewardAddress ⇀ Coin)` map equals the list-sum of its second
171-
projections.
172-
+ `setToList-Unique`: stake-projection of a withdrawal/direct-deposit
173-
list is `Unique`{.AgdaDatatype}, assuming the per-batch
174-
`NetworkId`{.AgdaFunction} constraint. Used only by
175-
`applyWithdrawals-pov`.
148+
The three assumed identities below are the same set/map identities used by the Conway
149+
PoV proofs; they are stated as module parameters here, to be discharged in a
150+
follow-up against the `agda-sets` library.
151+
152+
+ `∪ˡ-lookup-preserve`: lookup in a left-biased union with a singleton at `c` agrees
153+
with lookup in the right map for any key `c' ≠ c`.
154+
+ `sum-map-proj₂≡getCoin`: the `getCoin`{.AgdaFunction} representation of a
155+
`(RewardAddress ⇀ Coin)` map equals the list-sum of its second projections.
156+
+ `setToList-Unique`: stake-projection of a withdrawal/direct-deposit list is
157+
`Unique`{.AgdaDatatype}, assuming the per-batch `NetworkId`{.AgdaFunction}
158+
constraint. (Used only by `applyWithdrawals-pov`.)
176159

177160
```agda
178161
module ApplyToRewards-PoV
@@ -191,7 +174,8 @@ module ApplyToRewards-PoV
191174
where
192175
```
193176

194-
A local convenience definitionally equal to the lambda body of `applyToRewards f`:
177+
The `applyOne`{.AgdaFunction} is a local convenience definitionally equal to the
178+
lambda body of `applyToRewards f`.
195179

196180
```agda
197181
applyOne : (Coin → Coin → Coin) → Rewards → RewardAddress × Coin → Rewards
@@ -201,10 +185,10 @@ A local convenience definitionally equal to the lambda body of `applyToRewards f
201185

202186
## Withdrawal preservation of value
203187

204-
### `applyOne-pov` (one withdrawal step decreases `getCoin` by `amt`)
188+
### `applyOne-pov`: one withdrawal step decreases `getCoin` by `amt`
205189

206-
When `lookupᵐ? acc (stake addr) ≡ just bal` and `amt ≤ bal`, applying a
207-
single withdrawal reduces the total by exactly `amt`.
190+
When `lookupᵐ? acc (stake addr) ≡ just bal` and `amt ≤ bal`, applying a single
191+
withdrawal reduces the total by exactly `amt`.
208192

209193
```agda
210194
applyOne-pov : (acc : Rewards) (addr : RewardAddress) (amt bal : Coin)
@@ -220,10 +204,10 @@ single withdrawal reduces the total by exactly `amt`.
220204
getCoin acc
221205
≡⟨ split-by-lookup acc c bal lookup-eq ⟩
222206
getCoin (acc ∣ ❴ c ❵ ᶜ) + bal
223-
≡⟨ cong (getCoin (acc ∣ ❴ c ❵ ᶜ) +_) (sym (m∸n+n≡m amt≤bal)) ⟩
207+
˘⟨ cong (getCoin (acc ∣ ❴ c ❵ ᶜ) +_) (m∸n+n≡m amt≤bal) ⟩
224208
getCoin (acc ∣ ❴ c ❵ ᶜ) + (bal ∸ amt + amt)
225-
≡⟨ trans (sym (+-assoc (getCoin (acc ∣ ❴ c ❵ ᶜ)) (bal ∸ amt) amt))
226-
(cong (_+ amt) (+-comm (getCoin (acc ∣ ❴ c ❵ ᶜ)) (bal ∸ amt))) ⟩
209+
≡⟨ trans (sym (+-assoc (getCoin (acc ∣ ❴ c ❵ ᶜ)) (bal ∸ amt) amt))
210+
(cong (_+ amt) (+-comm (getCoin (acc ∣ ❴ c ❵ ᶜ)) (bal ∸ amt))) ⟩
227211
(bal ∸ amt) + getCoin (acc ∣ ❴ c ❵ ᶜ) + amt
228212
≡˘⟨ cong (_+ amt) (getCoin-∪ˡ-overwrite acc c (bal ∸ amt)) ⟩
229213
getCoin (❴ c , bal ∸ amt ❵ ∪ˡ acc) + amt
@@ -233,23 +217,28 @@ single withdrawal reduces the total by exactly `amt`.
233217

234218
### `foldl-applyOne-pov` (fold induction)
235219

236-
The fold invariant tracks three things through the induction: every remaining
237-
withdrawal credential is in the current accumulator's domain; every remaining
238-
withdrawal amount is bounded by the current balance at that credential; and no
239-
credential is revisited (the `Unique`{.AgdaDatatype} witness on the stake-projected
240-
list). Uniqueness is essential here precisely because `applyOne _∸_` *modifies*
241-
the balance at the targeted credential — without it, a re-visit could attempt to
242-
subtract from an already-reduced balance for which the caller's original `amt ≤ bal`
243-
bound no longer holds.
220+
The fold invariant tracks three things through the induction:
221+
222+
1. every remaining withdrawal credential is in the current accumulator's domain;
223+
224+
2. every remaining withdrawal amount is bounded by the current balance at that
225+
credential;
226+
227+
3. no credential is revisited (the `Unique`{.AgdaDatatype} witness on the
228+
stake-projected list).
229+
230+
Uniqueness is essential here precisely because `applyOne _∸_` *modifies* the balance
231+
at the targeted credential — without it, a re-visit could attempt to subtract from an
232+
already-reduced balance for which the caller's original `amt ≤ bal` bound no longer
233+
holds.
244234

245235
```agda
246236
foldl-applyOne-pov : (acc : Rewards) (entries : List (RewardAddress × Coin))
247237
→ ( ∀ {addr amt} → (addr , amt) ∈ˡ entries
248238
→ stake addr ∈ dom acc
249239
× amt ≤ maybe id 0 (lookupᵐ? acc (stake addr)) )
250240
→ Unique (map (stake ∘ proj₁) entries)
251-
→ getCoin acc
252-
≡ getCoin (foldl (applyOne _∸_) acc entries) + sum (map proj₂ entries)
241+
→ getCoin acc ≡ getCoin (foldl (applyOne _∸_) acc entries) + sum (map proj₂ entries)
253242
```
254243

255244
<!--
@@ -299,7 +288,7 @@ bound no longer holds.
299288
ξ : stake addr' ∈ dom (acc ˢ) × amt' ≤ (maybe id 0 (lookupᵐ? acc (stake addr')))
300289
ξ = h (there mem)
301290
c'≢c : stake addr' ≢ c
302-
c'≢c = ≢-sym (All.lookup c∉xs (∈-map⁺ (stake ∘ proj₁) mem))
291+
c'≢c = ≢-sym (lookup c∉xs (∈-map⁺ (stake ∘ proj₁) mem))
303292
dom' : stake addr' ∈ dom acc'
304293
dom' = dom∪ˡʳ {m = ❴ c , bal ∸ amt ❵} {m' = acc} (proj₁ ξ)
305294
bal' : lookupᵐ? acc' (stake addr') ≡ lookupᵐ? acc (stake addr')

src/Ledger/Dijkstra/Specification/Entities/Properties/PoV.lagda.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,16 @@ open import Ledger.Dijkstra.Specification.Gov.Base using (GovStructure)
4646
module Ledger.Dijkstra.Specification.Entities.Properties.PoV
4747
(gs : GovStructure) (open GovStructure gs) where
4848
49+
open import Data.List.Relation.Unary.Unique.Propositional using (Unique)
50+
open import Data.Nat.Properties using (+-comm; +-assoc; +-0-monoid)
51+
4952
open import Ledger.Prelude
50-
open import Ledger.Dijkstra.Specification.Account gs -- using (DirectDeposits)
53+
54+
open import Ledger.Dijkstra.Specification.Account gs using (DirectDeposits; DirectDepositsOf)
5155
open import Ledger.Dijkstra.Specification.Certs gs
5256
open import Ledger.Dijkstra.Specification.Entities gs
53-
open import Ledger.Dijkstra.Specification.Gov.Actions gs hiding (yes; no)
54-
5557
open import Ledger.Dijkstra.Specification.Entities.Properties.ApplyToRewardsPoV gs
56-
57-
open import Data.List.Relation.Unary.Unique.Propositional using (Unique)
58-
open import Data.Nat.Properties using (+-comm; +-assoc; +-0-monoid)
58+
using (module ApplyToRewards-PoV)
5959
6060
open RewardAddress
6161
open ≡-Reasoning
@@ -91,7 +91,7 @@ module ENTITIES-PoV
9191
→ ∀[ a ∈ dom (m ˢ) ] NetworkIdOf a ≡ NetworkId
9292
→ Unique (map (stake ∘ proj₁) (setToList (m ˢ))) )
9393
94-
-- Certs-PoV stub (discharged later by #1210): preservation of value across
94+
-- Certs-PoV stub (discharged later by PR #1210): preservation of value across
9595
-- the reflexive-transitive `CERTS` closure. Formerly proved in
9696
-- `Certs.Properties.PoV`; lifted to a module parameter so this PR proves only
9797
-- the `ENTITIES`/`LEDGER` layer (top-down strategy).

src/Ledger/Dijkstra/Specification/Ledger/Properties/PoV.lagda.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,15 @@ source_path: src/Ledger/Dijkstra/Specification/Ledger/Properties/PoV.lagda.md
55

66
# Properties of `LEDGER`: Preservation of Value {#thm:LEDGER-PoV}
77

8-
This module proves the top-level preservation-of-value theorem for the Dijkstra
9-
`LEDGER`{.AgdaDatatype} rule. For any environment `Γ`{.AgdaBound}, top-level
10-
transaction `tx`{.AgdaBound}, and `LedgerState`{.AgdaRecord} pair `s`{.AgdaBound},
11-
`s'`{.AgdaBound} related by `LEDGER`{.AgdaDatatype}: `getCoin s ≡ getCoin s'`.
8+
This module proves the top-level preservation-of-value (PoV) theorem for the Dijkstra
9+
`LEDGER`{.AgdaDatatype} rule. If
10+
11+
+ `Γ`{.AgdaBound} is a ledger environment,
12+
+ `tx`{.AgdaBound} is top-level transaction, and
13+
+ `s`{.AgdaBound} and `s'`{.AgdaBound} are ledger states related by
14+
`LEDGER`{.AgdaDatatype},
15+
16+
then `getCoin s ≡ getCoin s'`.
1217

1318
Recall (from `Ledger.lagda.md`) that `getCoin (LedgerState)` is
1419

@@ -17,8 +22,8 @@ Recall (from `Ledger.lagda.md`) that `getCoin (LedgerState)` is
1722
+ coinFromDeposits (CertStateOf s)
1823
+ coinFromGovDeposit (GovStateOf s)
1924

20-
that is, UTxO coin, rewards balance, the `DState`/`PState`/`GState` deposit pots
21-
(`coinFromDeposits`{.AgdaFunction}), and the governance-action deposits
25+
This is the sum of UTxO coin, rewards balance, the deposits from `DState`, `PState`,
26+
and `GState` (`coinFromDeposits`{.AgdaFunction}), and the governance-action deposits
2227
(`coinFromGovDeposit`{.AgdaFunction}).
2328

2429
> **Status — complete.** `LEDGER-pov` typechecks end-to-end under `--safe` (no

0 commit comments

Comments
 (0)