Skip to content

Commit 64c710f

Browse files
committed
[Dijkstra] Utxo PoV: prove the UTxO balance algebra in Utxo.Properties.Base
Port the Conway balance lemmas to Dijkstra: balance-cong, balance-cong-coin, balance-∪ (additivity on disjoint unions) and split-balance (partition along a key-set restriction), plus the freshness lemmas newTxid⇒disj / outs-disjoint, the coin homomorphism law ∙-homo-Coin, and coin-∑ˡ (coin distributes over list-indexed Value sums). The Conway indexedSumᵐ proofs now port directly because the Dijkstra balance is again an indexed sum over a finite map of transaction outputs (∑[ x ← mapValues txOutToValue utxo ] x); the earlier ∑ˢ-over-ℙ-Value definition that blocked this port is gone. balance-∪, split-balance and outs-disjoint match the corresponding module parameters of Ledger.Properties.PoV (#1203), which they discharge (#1186). AI-assisted: Claude Fable 5 (Anthropic)
1 parent 6718d6a commit 64c710f

1 file changed

Lines changed: 166 additions & 0 deletions

File tree

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
---
2+
source_branch: master
3+
source_path: src/Ledger/Dijkstra/Specification/Utxo/Properties/Base.lagda.md
4+
---
5+
6+
# UTxO Properties: Base Lemmas
7+
8+
This module collects the pure `UTxO`{.AgdaFunction} algebra used by the
9+
preservation-of-value proofs in `Utxo.Properties.PoV`{.AgdaModule} and
10+
`Utxow.Properties.PoV`{.AgdaModule}:
11+
12+
+ `∙-homo-Coin`{.AgdaFunction}: `coin`{.AgdaField} distributes over `Value`{.AgdaField}
13+
addition (the `_∙_` law of the `coin`{.AgdaField} monoid homomorphism).
14+
+ `coin-∑ˡ`{.AgdaFunction}: `coin`{.AgdaField} distributes over a list-indexed sum of
15+
`Value`{.AgdaField}s.
16+
+ `newTxid⇒disj`{.AgdaFunction} / `outs-disjoint`{.AgdaFunction}: freshness of
17+
`TxIdOf tx` in a UTxO implies the outputs of `tx` are disjoint from it.
18+
+ `balance-cong`{.AgdaFunction} / `balance-cong-coin`{.AgdaFunction}:
19+
`balance`{.AgdaFunction} is invariant under extensional equality of UTxOs.
20+
+ `balance-∪`{.AgdaFunction}: `cbalance`{.AgdaFunction} is additive on disjoint unions.
21+
+ `split-balance`{.AgdaFunction}: `cbalance`{.AgdaFunction} splits along a key-set
22+
restriction and its complement.
23+
24+
The balance lemmas are ports of their Conway counterparts (in
25+
`Ledger.Conway.Specification.Utxo.Properties.Base`{.AgdaModule}): the Dijkstra
26+
`balance`{.AgdaFunction} is again an indexed sum over a finite map of transaction
27+
outputs (`∑[ x ← mapValues txOutToValue utxo ] x`), so the Conway proofs via
28+
`indexedSumᵐ-cong`{.AgdaFunction} and `indexedSumᵐ-∪`{.AgdaFunction} carry over,
29+
with `txOutToValue`{.AgdaFunction} in place of Conway's hashed outputs. The
30+
statements of `balance-∪`{.AgdaFunction}, `split-balance`{.AgdaFunction} and
31+
`outs-disjoint`{.AgdaFunction} match the corresponding module parameters of
32+
`Ledger.Properties.PoV`{.AgdaModule}, which they are intended to discharge.
33+
34+
<!--
35+
```agda
36+
{-# OPTIONS --safe #-}
37+
38+
open import Ledger.Dijkstra.Specification.Abstract using (AbstractFunctions)
39+
open import Ledger.Dijkstra.Specification.Transaction
40+
41+
module Ledger.Dijkstra.Specification.Utxo.Properties.Base
42+
(txs : _) (open TransactionStructure txs)
43+
(abs : AbstractFunctions txs) (open AbstractFunctions abs)
44+
where
45+
46+
open import Prelude; open Equivalence
47+
open import Ledger.Prelude hiding (≤-trans; ≤-antisym; All); open Properties
48+
open import Ledger.Dijkstra.Specification.Utxo txs abs
49+
50+
open import Algebra.Morphism using (module MonoidMorphisms; IsMagmaHomomorphism)
51+
open import Relation.Binary using (IsEquivalence)
52+
53+
open MonoidMorphisms.IsMonoidHomomorphism
54+
55+
private variable
56+
ℓ : TxLevel
57+
```
58+
-->
59+
60+
## `∙-homo-Coin`
61+
62+
```agda
63+
∙-homo-Coin : ∀ (x y : Value) → coin (x + y) ≡ coin x + coin y
64+
∙-homo-Coin = IsMagmaHomomorphism.homo (isMagmaHomomorphism coinIsMonoidHomomorphism)
65+
```
66+
67+
## `coin-∑ˡ`
68+
69+
`coin`{.AgdaField} is a monoid homomorphism from `Value`{.AgdaField} (under `+ᵛ`/`ε`) to
70+
``{.AgdaDatatype} (under `+`/`0`), so it distributes over a list-indexed sum. This
71+
is the "coin version" of the generic fact that a monoid homomorphism commutes with
72+
`foldr _∙_ ε`.
73+
74+
```agda
75+
coin-∑ˡ : ∀ {A : Type} (f : A → Value) (xs : List A)
76+
→ coin (∑ˡ[ x ← xs ] f x) ≡ sum (map (coin ∘ f) xs)
77+
coin-∑ˡ f [] = ε-homo coinIsMonoidHomomorphism
78+
coin-∑ˡ f (x ∷ xs) = trans (∙-homo-Coin (f x) (∑ˡ[ z ← xs ] f z))
79+
(cong (coin (f x) +_) (coin-∑ˡ f xs))
80+
```
81+
82+
## Freshness ⇒ disjointness
83+
84+
If the id of a transaction `tx` does not occur in `utxo`, then the outputs of
85+
`tx` (whose keys all have first component `TxIdOf tx`) are disjoint from
86+
`utxo`. The specialisation `outs-disjoint`{.AgdaFunction} is the form used by
87+
the PoV proofs: the restriction `utxo ∣ SpendInputsOf tx ᶜ` only shrinks the
88+
domain, so disjointness with `outs tx` persists.
89+
90+
```agda
91+
module _ (tx : Tx ℓ) (let open Tx tx; open TxBody txBody)
92+
{utxo : UTxO} where
93+
94+
newTxid⇒disj : TxIdOf tx ∉ mapˢ proj₁ (dom utxo)
95+
→ disjoint' (dom utxo) (dom (outs tx))
96+
newTxid⇒disj id∉utxo =
97+
disjoint⇒disjoint' λ h h' → id∉utxo $ to ∈-map
98+
(-, (case from ∈-map h' of λ where
99+
(_ , refl , h'') → case from ∈-map h'' of λ where (_ , refl , _) → refl) , h)
100+
101+
outs-disjoint : TxIdOf tx ∉ mapˢ proj₁ (dom utxo)
102+
→ disjoint (dom (utxo ∣ SpendInputsOf tx ᶜ)) (dom (outs tx))
103+
outs-disjoint fresh =
104+
λ h₁ h₂ → ∉-∅ $ proj₁ (newTxid⇒disj fresh) $ to ∈-∩ (res-comp-domᵐ h₁ , h₂)
105+
```
106+
107+
## Balance arithmetic
108+
109+
`balance`{.AgdaFunction} is the indexed sum of `txOutToValue`{.AgdaFunction} over the
110+
UTxO map, so it is invariant under extensional equality of the underlying maps
111+
(`balance-cong`{.AgdaFunction}), and — via `indexedSumᵐ-∪`{.AgdaFunction} —
112+
additive on unions with disjoint domains (`balance-∪`{.AgdaFunction}).
113+
114+
```agda
115+
module _ {utxo utxo' : UTxO} where
116+
117+
balance-cong : ∣ utxo ∣ ≡ᵉ ∣ utxo' ∣ → balance utxo ≈ balance utxo'
118+
balance-cong eq =
119+
indexedSumᵐ-cong {M = Value} {x = (mapValues txOutToValue utxo) ᶠᵐ}
120+
{(mapValues txOutToValue utxo') ᶠᵐ} (map-≡ᵉ eq)
121+
122+
balance-cong-coin : ∣ utxo ∣ ≡ᵉ ∣ utxo' ∣ → cbalance utxo ≡ cbalance utxo'
123+
balance-cong-coin eq = ⟦⟧-cong coinIsMonoidHomomorphism (balance-cong eq)
124+
125+
balance-∪ : disjoint (dom utxo) (dom utxo')
126+
→ cbalance (utxo ∪ˡ utxo') ≡ cbalance utxo + cbalance utxo'
127+
balance-∪ h = begin
128+
cbalance (utxo ∪ˡ utxo')
129+
≡⟨ ⟦⟧-cong coinIsMonoidHomomorphism
130+
$ indexedSumᵐ-cong {f = proj₂}
131+
{x = (mapValues txOutToValue (utxo ∪ˡ utxo')) ᶠᵐ}
132+
{((mapValues txOutToValue utxo) ᶠᵐ) ∪ˡᶠ ((mapValues txOutToValue utxo') ᶠᵐ)}
133+
(disjoint-∪ˡ-mapValues {M = utxo} {utxo'} _ h) ⟩
134+
coin (indexedSumᵐ _ (((mapValues txOutToValue utxo) ᶠᵐ) ∪ˡᶠ ((mapValues txOutToValue utxo') ᶠᵐ)))
135+
≡⟨ ⟦⟧-cong coinIsMonoidHomomorphism
136+
$ indexedSumᵐ-∪ {M = Value} {X = (mapValues txOutToValue utxo) ᶠᵐ}
137+
{(mapValues txOutToValue utxo') ᶠᵐ}
138+
(λ x x₁ → h (dom-mapʳ⊆ x) (dom-mapʳ⊆ x₁)) ⟩
139+
coin (balance utxo + balance utxo')
140+
≡⟨ ∙-homo-Coin _ _ ⟩
141+
cbalance utxo + cbalance utxo'
142+
143+
where open ≡-Reasoning
144+
```
145+
146+
Splitting a UTxO along a key set: restricting to a key set and to its
147+
complement partitions the map, so the two restricted balances add up to the
148+
whole.
149+
150+
```agda
151+
split-balance : ∀ (u : UTxO) (keys : ℙ TxIn)
152+
→ cbalance u ≡ cbalance (u ∣ keys ᶜ) + cbalance (u ∣ keys)
153+
split-balance u keys = begin
154+
cbalance u
155+
≡˘⟨ balance-cong-coin {utxo = (u ∣ keys ᶜ) ∪ˡ (u ∣ keys)} {u}
156+
$ disjoint-∪ˡ-∪ (disjoint-sym res-ex-disjoint)
157+
≡ᵉ-∘ ∪-sym
158+
≡ᵉ-∘ res-ex-∪ (_∈? keys) ⟩
159+
cbalance ((u ∣ keys ᶜ) ∪ˡ (u ∣ keys))
160+
≡⟨ balance-∪ {u ∣ keys ᶜ} {u ∣ keys} $ flip res-ex-disjoint ⟩
161+
cbalance (u ∣ keys ᶜ) + cbalance (u ∣ keys)
162+
163+
where
164+
open ≡-Reasoning
165+
open IsEquivalence ≡ᵉ-isEquivalence renaming (trans to infixl 4 _≡ᵉ-∘_)
166+
```

0 commit comments

Comments
 (0)