Skip to content

Commit 9dcfc2d

Browse files
authored
Merge branch 'master' into master-markdown
2 parents 849d421 + 657e03c commit 9dcfc2d

File tree

7 files changed

+257
-97
lines changed

7 files changed

+257
-97
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
{-# OPTIONS --safe #-}
2+
module stdlib.Data.Rational.Properties where
3+
4+
open import Data.Integer using (ℤ; _/ℕ_; +≤+)
5+
import Data.Integer as ℤ
6+
open import Data.Integer.DivMod using (div-pos-is-/ℕ; 0≤n⇒0≤n/ℕd)
7+
open import Data.Integer.Properties using (module ≤-Reasoning; *-identityʳ; *-zeroˡ)
8+
open import Data.Nat using (ℕ; z≤n)
9+
open import Data.Rational
10+
open import Data.Rational.Properties renaming (module ≤-Reasoning to ≤ℚ-Reasoning)
11+
using (*-monoˡ-≤-nonNeg; *-zeroʳ; 1/pos⇒pos; nonNeg∧nonZero⇒pos;
12+
nonNeg*nonNeg⇒nonNeg; pos⇒nonNeg; nonNegative⁻¹)
13+
open import Data.Unit.Base using (⊤)
14+
open import Relation.Binary.PropositionalEquality using (_≡_; refl; sym)
15+
16+
-- Natural number literals
17+
open import Agda.Builtin.FromNat
18+
import Data.Integer.Literals as ℤ
19+
import Data.Rational.Literals as ℚ
20+
open import Data.Rational.Literals using (fromℤ)
21+
instance Number-ℤ = ℤ.number
22+
instance Number-ℚ = ℚ.number
23+
open Number ℚ.number using () renaming (fromNat to fromℕ)
24+
25+
-- Properties of 'floor'
26+
27+
-- 'floor' is defined such that it typically does not normalize,
28+
-- but we can use its definition as a propositional equality.
29+
floor-def : (x : ℚ) floor x ≡ ↥ x ℤ./ ↧ x
30+
floor-def x@record{} = refl
31+
32+
-- A non-negative rational number has a non-negative numerator.
33+
0≤⇒0≤numerator : (x : ℚ) 0 ≤ x 0 ℤ.≤ ↥ x
34+
0≤⇒0≤numerator x 0≤x =
35+
begin
36+
0 ≡⟨ sym (*-zeroˡ (↧ x)) ⟩
37+
0 ℤ.* ↧ x ≤⟨ drop-*≤* 0≤x ⟩
38+
↥ x ℤ.* 1 ≡⟨ *-identityʳ _ ⟩
39+
↥ x ∎
40+
where open ≤-Reasoning
41+
42+
-- The 'floor' of a non-negative number is again non-negative.
43+
0≤⇒0≤floor : (x : ℚ) 0 ≤ x 0 ℤ.≤ floor x
44+
0≤⇒0≤floor x 0≤x =
45+
begin
46+
0 ≤⟨ 0≤n⇒0≤n/ℕd _ _ (0≤⇒0≤numerator x 0≤x) ⟩
47+
(↥ x /ℕ ↧ₙ x) ≡⟨ sym (div-pos-is-/ℕ (↥ x) (↧ₙ x)) ⟩
48+
(↥ x ℤ./ ↧ x) ≡⟨ sym (floor-def x) ⟩
49+
floor x ∎
50+
where open ≤-Reasoning
51+
52+
-- Properties related to non-negativity
53+
54+
-- Any non-negative integer is a non-negative rational number.
55+
fromℤ-0≤ : (i : ℤ) 0 ℤ.≤ i 0 ≤ fromℤ i
56+
fromℤ-0≤ i 0≤i = *≤* (begin
57+
0 ℤ.* i ≡⟨ sym (*-zeroˡ i) ⟩
58+
0 ≤⟨ 0≤i ⟩
59+
i ≡⟨ sym (*-identityʳ i) ⟩
60+
i ℤ.* 1 ∎)
61+
where open ≤-Reasoning
62+
63+
-- Any natural number is a non-negative rational number.
64+
fromℕ-0≤ : (n : ℕ) 0 ≤ fromℕ n
65+
fromℕ-0≤ n = fromℤ-0≤ (ℤ.+ n) (+≤+ z≤n)
66+
67+
-- The product of 2 non-negative numbers is non-negative.
68+
*-0≤⇒0≤ : (x y : ℚ) 0 ≤ x 0 ≤ y 0 ≤ (x * y)
69+
*-0≤⇒0≤ x y 0≤x 0≤y =
70+
begin
71+
0 ≡⟨ sym (*-zeroʳ x) ⟩
72+
x * 0 ≤⟨ *-monoˡ-≤-nonNeg x ⦃ nonNegative 0≤x ⦄ 0≤y ⟩
73+
x * y ∎
74+
where open ≤ℚ-Reasoning
75+
76+
-- The product of 3 non-negative numbers is non-negative.
77+
*-0≤-3⇒0≤ : (x y z : ℚ) 0 ≤ x 0 ≤ y 0 ≤ z 0 ≤ (x * y * z)
78+
*-0≤-3⇒0≤ x y z 0≤x 0≤y 0≤z =
79+
*-0≤⇒0≤ (x * y) z (*-0≤⇒0≤ x y 0≤x 0≤y) 0≤z
80+
81+
-- Division by a non-negative number
82+
÷-0≤⇒0≤ : (x y : ℚ) .{{_ : NonZero y}} 0 ≤ x 0 ≤ y 0 ≤ x ÷ y
83+
÷-0≤⇒0≤ x y 0≤x 0≤y = nonNegative⁻¹ (x ÷ y)
84+
where
85+
instance
86+
lemma-1/y : Positive (1/ y)
87+
lemma-1/y = 1/pos⇒pos y {{nonNeg∧nonZero⇒pos y {{nonNegative 0≤y}}}}
88+
89+
lemma-x÷y : NonNegative (x * 1/ y)
90+
lemma-x÷y = nonNeg*nonNeg⇒nonNeg x {{nonNegative 0≤x}} (1/ y) {{pos⇒nonNeg (1/ y)}}

src/Ledger/Conway/Epoch.lagda

Lines changed: 94 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,21 @@
55
\begin{code}[hide]
66
{-# OPTIONS --safe #-}
77

8-
open import Data.Nat.Properties using (+-0-monoid; +-0-commutativeMonoid)
98
open import Data.Integer using () renaming (+_ to pos)
9+
import Data.Integer as ℤ
10+
open import Data.Integer.Properties using (module ≤-Reasoning; +-mono-≤; neg-mono-≤; +-identityˡ)
11+
renaming (nonNegative⁻¹ to nonNegative⁻¹ℤ)
1012
open import Data.Nat.GeneralisedArithmetic using (iterate)
11-
open import Data.Rational using (ℚ; floor; _*_; _÷_; _/_)
13+
open import Data.Rational using (ℚ; floor; _*_; _÷_; _/_; _⊓_; _≟_; ≢-nonZero)
1214
open import Data.Rational.Literals using (number; fromℤ)
13-
import Data.Rational as ℚ renaming (_⊓_ to min)
15+
open import Data.Rational.Properties using (nonNegative⁻¹; pos⇒nonNeg; ⊓-glb)
16+
open import stdlib.Data.Rational.Properties using (0≤⇒0≤floor; ÷-0≤⇒0≤; fromℕ-0≤; *-0≤⇒0≤; fromℤ-0≤)
17+
18+
open import Data.Integer.Tactic.RingSolver using (solve-∀)
1419

1520
open import Agda.Builtin.FromNat
1621

17-
open import Ledger.Prelude hiding (iterate; _/_; _*_)
22+
open import Ledger.Prelude hiding (iterate; _/_; _*_; _⊓_; _≟_; ≢-nonZero)
1823
open Filter using (filter)
1924
open import Ledger.Conway.Abstract
2025
open import Ledger.Conway.Transaction
@@ -71,6 +76,12 @@ instance
7176

7277
Hastreasury-EpochState : Hastreasury EpochState
7378
Hastreasury-EpochState .treasuryOf = Acnt.treasury ∘ EpochState.acnt
79+
80+
Hasreserves-EpochState : Hasreserves EpochState
81+
Hasreserves-EpochState .reservesOf = Acnt.reserves ∘ EpochState.acnt
82+
83+
HasPParams-EpochState : HasPParams EpochState
84+
HasPParams-EpochState .PParamsOf = PParamsOf ∘ EnactStateOf
7485
\end{code}
7586
\begin{NoConway}
7687
\begin{code}
@@ -117,13 +128,10 @@ instance
117128
HasRewards-NewEpochState : HasRewards NewEpochState
118129
HasRewards-NewEpochState .RewardsOf = RewardsOf ∘ CertStateOf
119130

120-
unquoteDecl HasCast-RewardUpdate HasCast-EpochState HasCast-NewEpochState = derive-HasCast
121-
( (quote RewardUpdate , HasCast-RewardUpdate)
122-
∷ (quote EpochState , HasCast-EpochState)
131+
unquoteDecl HasCast-EpochState HasCast-NewEpochState = derive-HasCast
132+
( (quote EpochState , HasCast-EpochState)
123133
∷ [ (quote NewEpochState , HasCast-NewEpochState)])
124134

125-
instance _ = +-0-monoid; _ = +-0-commutativeMonoid
126-
127135
toRwdAddr : Credential → RwdAddr
128136
toRwdAddr x = record { net = NetworkId ; stake = x }
129137

@@ -175,35 +183,85 @@ described in \textcite[\sectionname~6.4]{shelley-delegation-design}.
175183
\begin{figure*}[h]
176184
\begin{AgdaMultiCode}
177185
\begin{code}
178-
179186
createRUpd : ℕ → BlocksMade → EpochState → Coin → RewardUpdate
180-
createRUpd slotsPerEpoch b es total
181-
= ⟦ Δt₁ , 0 - Δr₁ + Δr₂ , 0 - feeSS , rs ⟧
187+
createRUpd slotsPerEpoch b es total =
188+
record { Δt = Δt₁
189+
; Δr = 0 - Δr₁ + Δr₂
190+
; Δf = 0 - pos feeSS
191+
; rs = rs
192+
\end{code}
193+
\begin{code}[hide]
194+
; flowConservation = flowConservation
195+
; Δt-nonnegative = Δt-nonneg
196+
; Δf-nonpositive = Δf-nonpos
197+
\end{code}
198+
\begin{code}
199+
}
182200
where
183-
prevPp = PParamsOf (es .EpochState.es)
184-
reserves = es .EpochState.acnt .Acnt.reserves
185-
pstakego = es .EpochState.ss .Snapshots.go
186-
feeSS = es .EpochState.ss .Snapshots.feeSS
187-
stake = pstakego .Snapshot.stake
188-
delegs = pstakego .Snapshot.delegations
189-
poolParams = pstakego .Snapshot.poolParameters
190-
191-
blocksMade = ∑[ m ← b ] m
192-
193-
rho = fromUnitInterval (prevPp .PParams.monetaryExpansion)
194-
η = fromℕ blocksMade ÷₀ (fromℕ slotsPerEpoch * ActiveSlotCoeff)
195-
Δr₁ = floor (ℚ.min 1 η * rho * fromℕ reserves)
196-
197-
rewardPot = pos feeSS + Δr₁
198-
tau = fromUnitInterval (prevPp .PParams.treasuryCut)
199-
Δt₁ = floor (tau * fromℤ rewardPot)
200-
R = posPart (rewardPot - Δt₁)
201-
circulation = total - reserves
202-
203-
rs = reward prevPp b R poolParams stake delegs circulation
204-
Δr₂ = R - ∑[ c ← rs ] c
201+
prevPp = PParamsOf es
202+
reserves = reservesOf es
203+
pstakego = es .EpochState.ss .Snapshots.go
204+
feeSS = es .EpochState.ss .Snapshots.feeSS
205+
stake = pstakego .Snapshot.stake
206+
delegs = pstakego .Snapshot.delegations
207+
poolParams = pstakego .Snapshot.poolParameters
208+
blocksMade = ∑[ m ← b ] m
209+
ρ = fromUnitInterval (prevPp .PParams.monetaryExpansion)
210+
η = fromℕ blocksMade ÷₀ (fromℕ slotsPerEpoch * ActiveSlotCoeff)
211+
Δr₁ = floor (1 ⊓ η * ρ * fromℕ reserves)
212+
rewardPot = pos feeSS + Δr₁
213+
τ = fromUnitInterval (prevPp .PParams.treasuryCut)
214+
Δt₁ = floor (fromℤ rewardPot * τ)
215+
R = rewardPot - Δt₁
216+
circulation = total - reserves
217+
rs = reward prevPp b (posPart R) poolParams stake delegs circulation
218+
Δr₂ = R - pos (∑[ c ← rs ] c)
205219

206220
\end{code}
221+
\begin{code}[hide]
222+
-- Proofs
223+
-- Note: Overloading of + and - seems to interfere with
224+
-- the ring solver.
225+
lemmaFlow : ∀ (t₁ r₁ f z : ℤ)
226+
→ (t₁ ℤ.+ (0 ℤ.- r₁ ℤ.+ ((f ℤ.+ r₁ ℤ.- t₁) ℤ.- z)) ℤ.+ (0 ℤ.- f) ℤ.+ z) ≡ 0
227+
lemmaFlow = solve-∀
228+
flowConservation = lemmaFlow Δt₁ Δr₁ (pos feeSS) (pos (∑[ c ← rs ] c))
229+
230+
÷₀-0≤⇒0≤ : ∀ (x y : ℚ) → 0 ≤ x → 0 ≤ y → 0 ≤ (x ÷₀ y)
231+
÷₀-0≤⇒0≤ x y 0≤x 0≤y with y ≟ 0
232+
... | (yes y≡0) = nonNegative⁻¹ 0
233+
... | (no y≢0) = ÷-0≤⇒0≤ x y {{≢-nonZero y≢0}} 0≤x 0≤y
234+
235+
η-nonneg : 0 ≤ η
236+
η-nonneg = ÷₀-0≤⇒0≤ _ _ (fromℕ-0≤ blocksMade)
237+
(*-0≤⇒0≤ _ _
238+
(fromℕ-0≤ slotsPerEpoch)
239+
(nonNegative⁻¹ ActiveSlotCoeff {{pos⇒nonNeg ActiveSlotCoeff}}))
240+
241+
min1η-nonneg : 0 ≤ 1 ⊓ η
242+
min1η-nonneg = ⊓-glb (nonNegative⁻¹ 1) η-nonneg
243+
244+
Δr₁-nonneg : 0 ≤ Δr₁
245+
Δr₁-nonneg = 0≤⇒0≤floor _
246+
(*-0≤⇒0≤ (1 ⊓ η * ρ) (fromℕ reserves)
247+
(UnitInterval-*-0≤ (1 ⊓ η) (prevPp .PParams.monetaryExpansion) min1η-nonneg)
248+
(fromℕ-0≤ reserves))
249+
250+
rewardPot-nonneg : 0 ≤ rewardPot
251+
rewardPot-nonneg = +-mono-≤ (nonNegative⁻¹ℤ (pos feeSS)) Δr₁-nonneg
252+
253+
Δt-nonneg : 0 ≤ Δt₁
254+
Δt-nonneg = 0≤⇒0≤floor _
255+
(UnitInterval-*-0≤ (fromℤ rewardPot) (prevPp .PParams.treasuryCut)
256+
(fromℤ-0≤ rewardPot rewardPot-nonneg))
257+
258+
Δf-nonpos : (0 - pos feeSS) ≤ 0
259+
Δf-nonpos = begin
260+
0 - pos feeSS ≡⟨ +-identityˡ _ ⟩
261+
ℤ.- pos feeSS ≤⟨ neg-mono-≤ (ℤ.+≤+ z≤n) ⟩
262+
0 ∎
263+
where open ≤-Reasoning
264+
\end{code}
207265
\end{AgdaMultiCode}
208266
\caption{RewardUpdate Creation}
209267
\label{fig:functions:createRUpd}
@@ -215,7 +273,7 @@ createRUpd slotsPerEpoch b es total
215273
{\small
216274
\begin{code}
217275
applyRUpd : RewardUpdate → EpochState → EpochState
218-
applyRUpd ⟦ Δt , Δr , Δf , rs ⟧ʳᵘ
276+
applyRUpd rewardUpdate
219277
⟦ ⟦ treasury , reserves ⟧ᵃ
220278
, ss
221279
, ⟦ ⟦ utxo , fees , deposits , donations ⟧ᵘ
@@ -233,6 +291,7 @@ applyRUpd ⟦ Δt , Δr , Δf , rs ⟧ʳᵘ
233291
, es
234292
, fut ⟧
235293
where
294+
open RewardUpdate rewardUpdate using (Δt; Δr; Δf; rs)
236295
regRU = rs ∣ dom rewards
237296
unregRU = rs ∣ dom rewards ᶜ
238297
unregRU' = ∑[ x ← unregRU ] x

src/Ledger/Conway/Foreign/HSLedger/ExternalStructures.agda

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ open import Ledger.Conway.Foreign.ExternalFunctions
22

33
module Ledger.Conway.Foreign.HSLedger.ExternalStructures (externalFunctions : ExternalFunctions) where
44

5+
import Data.Rational as ℚ using (pos) -- import an instance
6+
57
open import Ledger.Conway.Crypto
68
open import Ledger.Conway.Types.Epoch
79
open import Ledger.Conway.Foreign.HSLedger.Core

src/Ledger/Conway/PParams.lagda

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ record Hastreasury {a} (A : Type a) : Type a where
5656
field treasuryOf : A → Coin
5757
open Hastreasury ⦃...⦄ public
5858

59+
record Hasreserves {a} (A : Type a) : Type a where
60+
field reservesOf : A → Coin
61+
open Hasreserves ⦃...⦄ public
62+
5963
ProtVer : Type
6064
ProtVer = ℕ × ℕ
6165

0 commit comments

Comments
 (0)