Skip to content

Commit 04cf4c7

Browse files
committed
improvements
1 parent 3091c87 commit 04cf4c7

3 files changed

Lines changed: 47 additions & 53 deletions

File tree

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ source_branch: master
33
source_path: src/Ledger/Dijkstra/Specification/Entities/Properties/ApplyToRewardsPoV.lagda.md
44
---
55

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

88
This module proves preservation of value for the two specializations of
99
`applyToRewards`{.AgdaFunction} used inside the `ENTITIES`{.AgdaDatatype} rule.
@@ -60,7 +60,7 @@ open ≡-Reasoning
6060
```
6161
-->
6262

63-
### Shared helpers
63+
## Shared helpers
6464

6565
```agda
6666
getCoin-∪ˡ-overwrite : (acc : Rewards) (c : Credential) (v : Coin)
@@ -139,7 +139,7 @@ split-by-lookup acc c bal lookup-eq =
139139
```
140140
-->
141141

142-
### The `ApplyToRewards-PoV` module
142+
## The <span class="AgdaModule">ApplyToRewards-PoV</span> module
143143

144144
The three assumed identities below are the same set/map identities used by the Conway
145145
PoV proofs; they are stated as module parameters here.
@@ -290,7 +290,7 @@ holds.
290290
```
291291
-->
292292

293-
### `applyWithdrawals-pov`
293+
#### `applyWithdrawals-pov`
294294

295295
```agda
296296
applyWithdrawals-pov : (wdrls : Withdrawals) (rwds : Rewards)
@@ -327,9 +327,9 @@ holds.
327327
```
328328
-->
329329

330-
## Direct-deposit preservation of value
330+
### Direct-deposit preservation of value
331331

332-
### `applyOne-pov-add` (one direct-deposit step increases `getCoin` by `amt`)
332+
#### `applyOne-pov-add` (one direct-deposit step increases `getCoin` by `amt`)
333333

334334
For addition, no `amt ≤ bal` premise is needed (the operation is total),
335335
and the per-step equation is `getCoin (...) ≡ getCoin acc + amt`
@@ -360,7 +360,7 @@ balance.
360360
```
361361
-->
362362

363-
### `foldl-applyOne-pov-add` (fold induction, no `Unique` needed)
363+
#### `foldl-applyOne-pov-add` (fold induction, no `Unique` needed)
364364

365365
Unlike the withdrawal version, the additive fold induction needs only
366366
domain preservation — the `Unique`{.AgdaDatatype} witness drops out.
@@ -405,7 +405,7 @@ the same credential simply accumulates additions correctly.
405405
```
406406
-->
407407

408-
### `applyDirectDeposits-pov`
408+
#### `applyDirectDeposits-pov`
409409

410410
Note the slimmed-down signature relative to `applyWithdrawals-pov`: no
411411
`NetworkId`{.AgdaFunction} premise (none is needed), no

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

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,21 @@ source_path: src/Ledger/Dijkstra/Specification/Entities/Properties/PoV.lagda.md
66
## Properties of `ENTITIES`: Preservation of Value {#thm:ENTITIES-PoV}
77

88
This module proves preservation of value for the `ENTITIES`{.AgdaDatatype} and
9-
`SUBENTITIES`{.AgdaDatatype} rules. Each rule wraps the inner `CERTS`{.AgdaDatatype}
10-
step with the withdrawal and direct-deposit handling of the transaction given as the
11-
signal, and its value accounting splits into the two components of
12-
`getCoin`{.AgdaFunction} on a `CertState`{.AgdaRecord}:
9+
`SUBENTITIES`{.AgdaDatatype} rules.
10+
11+
Each rule wraps the inner `CERTS`{.AgdaDatatype} step with the withdrawal and
12+
direct-deposit handling of the transaction. Each rule's value accounting splits into
13+
the following two components of `getCoin`{.AgdaFunction} on a `CertState`{.AgdaRecord}:
1314

1415
+ **rewards flow** (`SUBENTITIES-pov`{.AgdaFunction}, `ENTITIES-pov`{.AgdaFunction}):
1516
the rewards balance grows by the transaction's direct deposits and shrinks by its
16-
withdrawals `CERTS`{.AgdaDatatype} itself preserves it;
17+
withdrawals, whereas `CERTS`{.AgdaDatatype} preserves rewards balance;
1718

1819
+ **deposit flow** (`SUBENTITIES-deposits-pov`{.AgdaFunction},
1920
`ENTITIES-deposits-pov`{.AgdaFunction}): the deposit pots change by exactly the
2021
new deposits minus the refunds of the transaction's certificates, in the closed
2122
form (`newCertDeposits`{.AgdaFunction}/`refundCertDeposits`{.AgdaFunction}) used
22-
by the `UTXO`{.AgdaDatatype} batch-balance equation.
23+
by the batch-balance equation of `UTXO`{.AgdaDatatype}.
2324

2425
`SUBENTITIES-pov-total`{.AgdaFunction} and `ENTITIES-pov-total`{.AgdaFunction}
2526
combine the two into a single equation for the full `CertState`{.AgdaRecord} coin.
@@ -30,9 +31,10 @@ Two hypotheses appear, both about the rule's *input* state:
3031
the account's balance. `applyWithdrawals`{.AgdaFunction} uses truncating
3132
subtraction (`_∸_`), so without this bound a withdrawal could claim more coin than
3233
actually leaves the rewards pot. The rules' own premises bound withdrawals
33-
against the *pre-batch* snapshot `rewards₀`{.AgdaField} (exactly, per account, in
34-
top-level legacy mode), which does not by itself bound them against the input
35-
state of a later step in the batch, so the bound is taken as a hypothesis here.
34+
against the *pre-batch* snapshot `rewards₀`{.AgdaField}, which does not by itself
35+
bound them against the input state of a later step in the batch, so the bound is
36+
taken as a hypothesis here. In legacy mode, however, the equality premise checks
37+
against the rule's current input rewards, not `rewards₀`{.AgdaField}.
3638

3739
+ `PoolDepositsRegistered`{.AgdaFunction}: every pool-deposit entry belongs to a
3840
registered pool (see `Certs`{.AgdaModule}). Without it,
@@ -77,11 +79,10 @@ private variable
7779
+ `CERTS-deposits-pov`: over a `CERTS` run, the deposit pots satisfy the closed-form
7880
accounting *pre + new ≡ post + refunds*, with `newCertDeposits`{.AgdaFunction}
7981
threading the run's initial registered-pool set;
80-
+ `CERTS-deposits-registered`: `CERTS` preserves
81-
`PoolDepositsRegistered`{.AgdaFunction};
82+
+ `CERTS-deposits-registered`: `CERTS` preserves `PoolDepositsRegistered`{.AgdaFunction};
8283
+ `CERTS-new-thread`: `newCertDeposits`{.AgdaFunction} over an appended certificate
8384
list splits at a `CERTS` run boundary, the second half against the run's *final*
84-
pool set this is what lets per-step accounting compose across a batch.
85+
pool set; this is what lets per-step accounting compose across a batch.
8586

8687
```agda
8788
module ENTITIES-PoV
@@ -132,10 +133,10 @@ account balance in `s`{.AgdaBound} (the `amts≤`{.AgdaBound} no-truncation
132133
hypothesis). Then,
133134

134135
coinFromRewards s + getCoin (DirectDepositsOf txSub)
135-
≡ coinFromRewards s' + getCoin (WithdrawalsOf txSub)
136+
≡ coinFromRewards s' + getCoin (WithdrawalsOf txSub)
136137

137-
All other ingredients the `NetworkId`{.AgdaFunction} witnesses and the two domain
138-
conditions are premises of the rule itself.
138+
All other ingredients (the `NetworkId`{.AgdaFunction} witnesses and the two domain
139+
conditions) are premises of the rule itself.
139140

140141
**Formally**.
141142

@@ -173,6 +174,7 @@ conditions — are premises of the rule itself.
173174
dd wdrls : Coin
174175
dd = getCoin (DirectDepositsOf txSub)
175176
wdrls = getCoin (WithdrawalsOf txSub)
177+
176178
aw : Rewards
177179
aw = applyWithdrawals (WithdrawalsOf txSub) r₀
178180
```

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

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ the direct-deposit trick (see *Proof Strategy*), and the gov-deposit growth
3535

3636
The `PoolDepositsRegistered`{.AgdaFunction} hypothesis is necessary, not an artifact
3737
of the proof: the batch balance charges `newCertDeposits`{.AgdaFunction} against the
38-
registered-pool set, while `POOL-reg`{.AgdaInductiveConstructor}'s left-biased pot
39-
update silently keeps a stale entry for an unregistered poolat a state with such
40-
an entry, a pool registration destroys the charged deposit and the theorem is false.
41-
On-chain states satisfy the hypothesis by construction.
38+
registered-pool set, while `POOL-reg`{.AgdaInductiveConstructor}'s left-biased update
39+
silently keeps a stale entry for an unregistered pool; at a state with such an entry,
40+
a pool registration destroys the charged deposit and the theorem is false. On-chain
41+
states satisfy the hypothesis by construction.
4242

4343
## Proof Strategy
4444

@@ -49,25 +49,24 @@ The Dijkstra `LEDGER-pov`{.AgdaFunction} does not decompose into independent
4949
may individually transfer value between UTxO and CertState without local balancing.
5050

5151
Instead, the `LEDGER-V` proof is a single equational chain at the
52-
`LedgerState`{.AgdaRecord} level, with the cancellation of total direct deposits as
53-
the central trick — direct-deposit value appears both on the UTxO side (via
52+
`LedgerState`{.AgdaRecord} level, and cancellation of the *total* direct deposits is
53+
the key to the proof. Direct-deposit value appears both on the UTxO side (via
5454
`producedBatch`) and on the CertState side (via `applyDirectDeposits` inside
5555
`ENTITIES`) and cancels in the total.
5656

5757
Concretely, the proof composes four inductions over the `SUBLEDGERS`{.AgdaDatatype}
5858
reflexive-transitive closure, plus one arithmetic identity.
5959

60-
+ **`SUBLEDGERS-utxo-coin`{.AgdaFunction}** threads the per-`SUBUTXOW` coin equation
61-
(`subutxow-step-coin`).
62-
+ **`SUBLEDGERS-certs-pov`{.AgdaFunction}** composes per-sub-transaction
60+
+ **`SUBLEDGERS-utxo-coin`{.AgdaFunction}** inducts over the subtransaction list,
61+
applying the per-`SUBUTXOW` coin equation (`subutxow-step-coin`) at each step.
62+
+ **`SUBLEDGERS-rewards-pov`{.AgdaFunction}** composes per-sub-transaction
6363
`SUBENTITIES-pov`{.AgdaFunction} invocations (the rewards flow).
6464
+ **`SUBLEDGERS-deposits`{.AgdaFunction}** (with `SUBLEDGERS-registered`{.AgdaFunction})
6565
telescopes the per-step closed-form deposit accounting into the batch-wide
6666
equation consumed by `bat'`.
67-
+ **`SUBLEDGERS-gov-coin`{.AgdaFunction}** accumulates the per-`GOVS` gov-deposit
68-
growth.
69-
+ **`posNeg-deposits`{.AgdaFunction}** equationally relates the pre-/post-batch deposit
70-
totals to the `posPart`/`negPart` of `calculateDepositsChange`.
67+
+ **`SUBLEDGERS-gov-coin`{.AgdaFunction}** accumulates the per-`GOVS` gov-deposit growth.
68+
+ **`posNeg-deposits`{.AgdaFunction}** relates the pre-/post-batch deposit totals to
69+
the `posPart`/`negPart` of `calculateDepositsChange`.
7170

7271
The `LEDGER-I` case is straightforward; `certState` and `govSt` are unchanged,
7372
`SUBLEDGERS` is a no-op, and only the `UTXOW` step affects `getCoin`, which it
@@ -106,10 +105,6 @@ open import Ledger.Dijkstra.Specification.Utxow txs abs
106105
107106
open import Ledger.Dijkstra.Specification.Entities.Properties.PoV txs
108107
109-
-- We will import the following once the UTXO/UTXOW PoV proofs land:
110-
-- open import Ledger.Dijkstra.Specification.Utxo.Properties.PoV txs abs
111-
-- open import Ledger.Dijkstra.Specification.Utxow.Properties.PoV txs abs
112-
113108
open import Interface.STS
114109
115110
open RewardAddress
@@ -394,8 +389,8 @@ same quantity (the sum of deposits across the batch), just rephrased to expose
394389

395390
## `SUBLEDGERS-utxo-coin`
396391

397-
Induct over the `SUBLEDGERS` reflexive-transitive closure, threading the
398-
per-`SUBUTXOW` coin equation:
392+
Induct over the `SUBLEDGERS` reflexive-transitive closure, applying the
393+
per-`SUBUTXOW` coin equation at each step:
399394

400395
```agda
401396
SUBLEDGERS-utxo-coin :
@@ -450,7 +445,7 @@ per-`SUBUTXOW` coin equation:
450445
ih = SUBLEDGERS-utxo-coin isV rest
451446
```
452447

453-
## `SUBLEDGERS-certs-pov`
448+
## `SUBLEDGERS-rewards-pov`
454449

455450
Parallel induction over `SUBLEDGERS`, composing per-sub-transaction `SUBENTITIES-pov`
456451
invocations. The `NetworkId` witnesses and domain conditions are premises of the
@@ -460,7 +455,7 @@ invocations. The `NetworkId` witnesses and domain conditions are premises of th
460455
```agda
461456
open SubLedgerEnv
462457
463-
SUBLEDGERS-certs-pov :
458+
SUBLEDGERS-rewards-pov :
464459
{Γ : SubLedgerEnv}
465460
{s₀ s₁ : LedgerState}
466461
{stxs : List SubLevelTx}
@@ -469,12 +464,12 @@ invocations. The `NetworkId` witnesses and domain conditions are premises of th
469464
→ coinFromRewards (CertStateOf s₀) + sum (map ddwl stxs)
470465
≡ coinFromRewards (CertStateOf s₁) + sum (map wdrwl stxs)
471466
472-
SUBLEDGERS-certs-pov _ (BS-base Id-nop) = refl
467+
SUBLEDGERS-rewards-pov _ (BS-base Id-nop) = refl
473468
474-
SUBLEDGERS-certs-pov isV (BS-ind (SUBLEDGER-I (isI , _)) _) =
469+
SUBLEDGERS-rewards-pov isV (BS-ind (SUBLEDGER-I (isI , _)) _) =
475470
⊥-elim (case trans (sym isV) isI of λ ())
476471
477-
SUBLEDGERS-certs-pov {Γ} isV (BS-ind {s = s₀} {s' = s₁} {sigs} {s'' = sₙ}
472+
SUBLEDGERS-rewards-pov {Γ} isV (BS-ind {s = s₀} {s' = s₁} {sigs} {s'' = sₙ}
478473
(SUBLEDGER-V {stx = stx} (_ , _ , entitiesStep , _)) rest) =
479474
begin
480475
coinFromRewards (CertStateOf s₀) + (getCoin (DirectDepositsOf stx) + sum (map ddwl sigs))
@@ -495,7 +490,7 @@ invocations. The `NetworkId` witnesses and domain conditions are premises of th
495490
where
496491
ih : coinFromRewards (CertStateOf s₁) + sum (map ddwl sigs)
497492
≡ coinFromRewards (CertStateOf sₙ) + sum (map wdrwl sigs)
498-
ih = SUBLEDGERS-certs-pov isV rest
493+
ih = SUBLEDGERS-rewards-pov isV rest
499494
```
500495

501496
## `SUBLEDGERS-deposits`
@@ -814,7 +809,7 @@ itself; the no-truncation bound comes from `ENTITIES-wdrls-bounded`.)
814809
coinFromRewards (CertStateOf s) + (subDirectDepsCoin + getCoin (DirectDepositsOf tx))
815810
≡˘⟨ +-assoc (coinFromRewards (CertStateOf s)) subDirectDepsCoin (getCoin (DirectDepositsOf tx)) ⟩
816811
coinFromRewards (CertStateOf s) + subDirectDepsCoin + getCoin (DirectDepositsOf tx)
817-
≡⟨ cong (_+ getCoin (DirectDepositsOf tx)) (SUBLEDGERS-certs-pov valid subStep) ⟩
812+
≡⟨ cong (_+ getCoin (DirectDepositsOf tx)) (SUBLEDGERS-rewards-pov valid subStep) ⟩
818813
coinFromRewards cs₁ + subWdrlsCoin + getCoin (DirectDepositsOf tx)
819814
≡⟨ swap-right (coinFromRewards cs₁) subWdrlsCoin (getCoin (DirectDepositsOf tx)) ⟩
820815
coinFromRewards cs₁ + getCoin (DirectDepositsOf tx) + subWdrlsCoin
@@ -1038,10 +1033,7 @@ The main inner chain, showing LHS + E ≡ RHS + E:
10381033
≡⟨ arithmetic-2 U₀ allWdrls D₀ ⟩
10391034
U₀ + Psub + allWdrls + (D₀ + posPart dct + posPart dcs) + Ctop
10401035
≡⟨ cong (λ x → x + allWdrls + (D₀ + posPart dct + posPart dcs) + Ctop)
1041-
(subst (λ u → U₀ + Psub ≡ U₁ + sum (map (λ stx → cbalance (u ∣ SpendInputsOf stx))
1042-
(SubTransactionsOf tx)))
1043-
(refl {x = UTxOOf (UTxOStateOf s)})
1044-
(SUBLEDGERS-utxo-coin valid subStep)) ⟩
1036+
(SUBLEDGERS-utxo-coin valid subStep) ⟩
10451037
U₁ + Csub + allWdrls + (D₀ + posPart dct + posPart dcs) + Ctop
10461038
≡⟨ cong (λ x → (U₁ + Csub) + allWdrls + x + Ctop) posneg ⟩
10471039
U₁ + Csub + allWdrls + (D₂ + negPart dct + negPart dcs) + Ctop

0 commit comments

Comments
 (0)