@@ -5,17 +5,66 @@ import Batteries.Lean.HashMap
55open Std (HashMap)
66
77
8+ private partial def erf (x : Float) : Float :=
9+ if x < 0
10+ then - erf (- x)
11+ else
12+ let p := 0 .3275911
13+ let a₁ := 0 .254829592
14+ let a₂ := -0 .284496736
15+ let a₃ := 1 .421413741
16+ let a₄ := -1 .453152027
17+ let a₅ := 1 .061405429
18+ let t := 1 / (1 + p * x)
19+ 1 - (a₁ * t + a₂ * t^2 + a₃ * t^3 + a₄ * t^4 + a₅ * t^5 ) * Float.exp (- x^2 )
20+
21+ private def cdfGaussian (x μ σ : Float) : Float :=
22+ (1 + erf ((x - μ) / σ / Float.sqrt 2 )) / 2
23+
24+ private def bisectionSearch (f : Float → Float) (low high : Float) (ε : Float) (maxIter : Nat) : Float :=
25+ match maxIter with
26+ | 0 => (low + high) / 2
27+ | maxIter' + 1 =>
28+ let mid := (low + high) / 2
29+ let fmid := f mid
30+ if high - low < ε || Float.abs fmid < ε then
31+ mid
32+ else if f low * fmid < 0 then
33+ bisectionSearch f low mid ε maxIter'
34+ else
35+ bisectionSearch f mid high ε maxIter'
36+ termination_by maxIter
37+
38+
839abbrev Probability := Float
940
1041
11- def approxCommittee (committeeSize : Float) : Float × Float :=
12- let nPools : Nat := 2500
13- let stakes : List Float := (List.range nPools).map (fun k => ((k + 1 ).toFloat / nPools.toFloat)^10 - (k.toFloat / nPools.toFloat)^10 )
14- let ps : List Float := stakes.map (fun s => 1 - Float.exp (- committeeSize * s))
15- let μ : Float := ps.sum
42+ def nPools : Nat := 2500
43+
44+ def stakeDistribution (nPools : Nat) : List Float :=
45+ (List.range nPools).map (fun k => ((k + 1 ).toFloat / nPools.toFloat)^10 - (k.toFloat / nPools.toFloat)^10 )
46+
47+ private def calibrateCommittee (committeeSize : Float) : Float :=
48+ let stakes : List Float := stakeDistribution nPools
49+ let f (m : Float) : Float :=
50+ let ps : List Float := stakes.map (fun s => 1 - Float.exp (- m * s))
51+ ps.sum - committeeSize
52+ bisectionSearch f committeeSize nPools.toFloat 0 .5 10
53+
54+ private def committeeDistribution (pSuccessfulVote committeeSize : Float) : Float × Float :=
55+ let stakes : List Float := stakeDistribution nPools
56+ let m := calibrateCommittee committeeSize
57+ let ps : List Float := stakes.map (fun s => pSuccessfulVote * (1 - Float.exp (- m * s)))
58+ let μ := ps.sum
1659 let σ := (ps.map (fun p => p * (1 - p))).sum.sqrt
1760 ⟨ μ , σ ⟩
1861
62+ def pQuorum (pSuccessfulVote committeeSize τ : Float) : Float :=
63+ let ⟨ μ , σ ⟩ := committeeDistribution pSuccessfulVote committeeSize
64+ 1 - cdfGaussian (τ * committeeSize) μ σ
65+
66+ #eval pQuorum 0 .90 600 0 .75
67+
1968
2069structure Environment where
2170 activeSlotCoefficient : Probability
0 commit comments