Skip to content

Commit e0d513e

Browse files
committed
feat(dijkstra): discharge coin-of-{consumed,produced}Batch in UTXO PoV
Replace the two `coin-of-consumedBatch` / `coin-of-producedBatch` module parameters of `Utxo/Properties/PoV` with direct proofs. The proofs are organised as three layers: + Layer 1 — single-transaction coin equations `coin-producedTx : coin (producedTx t) ≡ cbalance (outs t) + DonationsOf t + getCoin (DirectDepositsOf t)` `coin-consumedTx : coin (MintedValueOf t) ≡ 0 → coin (consumedTx t utxo₀) ≡ cbalance (utxo₀ ∣ SpendInputsOf t) + getCoin (WithdrawalsOf t)` Each is a direct unfolding: repeated `∙-homo-Coin` to distribute `coin` across `+`, followed by `coin∘inject≗id` to strip each `inject`. The consumed version additionally uses `coin (MintedValueOf t) ≡ 0` to cancel the mint term (from UTXO premise p₆ / SUBUTXO premise). + Layer 2 — sum-over-sub-transactions coin equations `coin-∑-producedTx-sub` : pushes `coin` through the `∑ˡ`-indexed sum over `SubTransactionsOf tx` using the new `coin-∑ˡ` lemma (from `Utxo/Properties/Base`), then applies Layer 1 pointwise by list induction. `coin-∑-consumedTx-sub` : same shape, threading a `noMintingSubTxs tx` hypothesis (`∀ stx → stx ∈ˡ SubTransactionsOf tx → coin (MintedValueOf stx) ≡ 0`) through the induction so each element's Layer-1 application has its `noMint` premise available. + Layer 3 — the two batch-level coin equations `coin-of-consumedBatch` and `coin-of-producedBatch`: unfold the outer `+ inject _` / `+ ∑ˡ _` structure of `consumedBatch` / `producedBatch` by repeated `∙-homo-Coin` and `coin∘inject≗id`, substitute the Layer-1 top-level equation for the top-level summand, and substitute the Layer-2 equation for the sub-transaction sum. The produced-side proof ends with a small associative-commutative shuffle (`reshape-top`) that reorders the top-level fields from `(outs + Donations + DirectDeposits) + TxFees` to the stated `outs + TxFees + Donations + DirectDeposits`. The shuffle uses the same `swap-right` helper already used in `UTXO-V-mechanical`. + Supporting change Adds a small helper alias `noMintingSubTxs` at the top of the file to keep the sub-level mint-conservation hypothesis readable in the theorem statements. All proofs typecheck under `--safe`. The `UTXO-pov` placeholder remains; this commit delivers the coin-balance infrastructure that the eventual full proof (and the LEDGER-pov's `BatchUtxoAccounting` consumer) will depend on.
1 parent c6163a3 commit e0d513e

5 files changed

Lines changed: 384 additions & 146 deletions

File tree

src/Ledger/Dijkstra/Specification/Utxo.lagda.md

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,14 @@ record HasDepositsChange {a} (A : Type a) : Type a where
141141
field DepositsChangeOf : A → DepositsChange
142142
open HasDepositsChange ⦃...⦄ public
143143
144+
record HasDepositsChangeTop {a} (A : Type a) : Type a where
145+
field DepositsChangeTopOf : A → ℤ
146+
open HasDepositsChangeTop ⦃...⦄ public
147+
148+
record HasDepositsChangeSub {a} (A : Type a) : Type a where
149+
field DepositsChangeSubOf : A → ℤ
150+
open HasDepositsChangeSub ⦃...⦄ public
151+
144152
record HasScriptPool {a} (A : Type a) : Type a where
145153
field ScriptPoolOf : A → ℙ Script
146154
open HasScriptPool ⦃...⦄ public
@@ -209,6 +217,12 @@ instance
209217
HasDonations-UTxOState : HasDonations UTxOState
210218
HasDonations-UTxOState .DonationsOf = UTxOState.donations
211219
220+
HasDepositsChangeTop-DepositsChange : HasDepositsChangeTop DepositsChange
221+
HasDepositsChangeTop-DepositsChange .DepositsChangeTopOf = DepositsChange.depositsChangeTop
222+
223+
HasDepositsChangeSub-DepositsChange : HasDepositsChangeSub DepositsChange
224+
HasDepositsChangeSub-DepositsChange .DepositsChangeSubOf = DepositsChange.depositsChangeSub
225+
212226
unquoteDecl HasCast-DepositsChange
213227
HasCast-UTxOEnv
214228
HasCast-SubUTxOEnv
@@ -303,6 +317,16 @@ collateralCheck pp txTop utxo =
303317
× coin (balance (utxo ∣ CollateralInputsOf txTop)) * 100 ≥ (TxFeesOf txTop) * pp .collateralPercentage
304318
× (CollateralInputsOf txTop) ≢ ∅
305319
320+
producedTx : Tx ℓ → Value
321+
producedTx tx = balance (outs tx)
322+
+ inject (DonationsOf tx)
323+
+ inject (getCoin (DirectDepositsOf tx))
324+
325+
consumedTx : Tx ℓ → UTxO → Value
326+
consumedTx tx utxo = balance (utxo ∣ SpendInputsOf tx)
327+
+ MintedValueOf tx
328+
+ inject (getCoin (WithdrawalsOf tx))
329+
306330
module _ (depositsChange : DepositsChange) where
307331
308332
open DepositsChange depositsChange
@@ -319,11 +343,6 @@ module _ (depositsChange : DepositsChange) where
319343
depositRefundsTop : Coin
320344
depositRefundsTop = negPart depositsChangeTop
321345
322-
consumedTx : Tx ℓ → UTxO → Value
323-
consumedTx tx utxo = balance (utxo ∣ SpendInputsOf tx)
324-
+ MintedValueOf tx
325-
+ inject (getCoin (WithdrawalsOf tx))
326-
327346
consumed : TopLevelTx → UTxO → Value
328347
consumed txTop utxo = consumedTx txTop utxo
329348
+ inject depositRefundsTop
@@ -340,11 +359,6 @@ In the preservation-of-value equation, direct deposits appear on the
340359
the transaction and that amount is deposited into accounts.
341360

342361
```agda
343-
producedTx : Tx ℓ → Value
344-
producedTx tx = balance (outs tx)
345-
+ inject (DonationsOf tx)
346-
+ inject (getCoin (DirectDepositsOf tx))
347-
348362
produced : TopLevelTx → Value
349363
produced txTop = producedTx txTop
350364
+ inject (TxFeesOf txTop)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@ module Ledger.Dijkstra.Specification.Utxo.Properties where
1414

1515
```agda
1616
open import Ledger.Dijkstra.Specification.Utxo.Properties.Computational
17+
open import Ledger.Dijkstra.Specification.Utxo.Properties.Base
18+
open import Ledger.Dijkstra.Specification.Utxo.Properties.PoV
1719
```

src/Ledger/Dijkstra/Specification/Utxo/Properties/Base.lagda.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,22 @@ private variable
5858
∙-homo-Coin = IsMagmaHomomorphism.homo (isMagmaHomomorphism coinIsMonoidHomomorphism)
5959
```
6060

61+
## `coin-∑ˡ`
62+
63+
`coin`{.AgdaField} is a monoid homomorphism from `Value`{.AgdaField} (under `+ᵛ`/`ε`) to
64+
``{.AgdaDatatype} (under `+`/`0`), so it distributes over a list-indexed sum. This
65+
is the "coin version" of the generic fact that a monoid homomorphism commutes with
66+
`foldr _∙_ ε`.
67+
68+
```agda
69+
coin-∑ˡ : ∀ {A : Type} (f : A → Value) (xs : List A)
70+
→ coin (∑ˡ[ x ← xs ] f x) ≡ sum (map (coin ∘ f) xs)
71+
coin-∑ˡ f [] = ε-homo coinIsMonoidHomomorphism
72+
coin-∑ˡ f (x ∷ xs) = trans (∙-homo-Coin (f x) (∑ˡ[ z ← xs ] f z))
73+
(cong (coin (f x) +_) (coin-∑ˡ f xs))
74+
```
75+
76+
6177
## Freshness ⇒ disjointness
6278

6379
```agda

0 commit comments

Comments
 (0)