@lapxo/obligations 0.4.5 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/README.md +42 -3
  2. package/TARGET.bound +148 -42
  3. package/contracts/extension-lineage-participation.json +30 -0
  4. package/contracts/m0-binomial-bridge.json +6 -0
  5. package/contracts/m0-diagonal-conditional.json +15 -0
  6. package/contracts/m0-keff-interval.json +27 -0
  7. package/contracts/m0-moment-identification.json +42 -0
  8. package/contracts/m1-diagonal-regions.json +45 -0
  9. package/contracts/m1-generator-binomial.json +26 -0
  10. package/contracts/m1-offdiag-limit.json +42 -0
  11. package/contracts/m1-subcauses.json +66 -0
  12. package/contracts/model-collapse-1a.json +16 -0
  13. package/contracts/projection-chain.json +20 -0
  14. package/docs/contracts/experiment1a-public-attribution.md +1 -0
  15. package/docs/contracts/extension-lineage-participation.md +13 -0
  16. package/docs/contracts/installation-046-inputs.md +1 -0
  17. package/docs/contracts/m0-binomial-bridge.md +1 -0
  18. package/docs/contracts/m0-diagonal-lindeberg.md +1 -0
  19. package/docs/contracts/m0-diagonal-moments.md +1 -0
  20. package/docs/contracts/m0-diagonal-symmetric.md +1 -0
  21. package/docs/contracts/m0-diagonal-threshold.md +1 -0
  22. package/docs/contracts/m0-keff-floor-refutation.md +1 -0
  23. package/docs/contracts/m0-keff-interval.md +1 -0
  24. package/docs/contracts/m0-moment-identification.md +1 -0
  25. package/docs/contracts/m0-refuted-inverses.md +1 -0
  26. package/docs/contracts/m0-wf-floor-refutation.md +1 -0
  27. package/docs/contracts/m1-diagonal-regions.md +1 -0
  28. package/docs/contracts/m1-generator-binomial.md +1 -0
  29. package/docs/contracts/m1-offdiag-limit.md +1 -0
  30. package/docs/contracts/model-collapse-1a.md +11 -0
  31. package/docs/contracts/projection-chain.md +1 -0
  32. package/package.json +1 -1
  33. package/proofs/definitions-046/declaration.json +11 -0
  34. package/proofs/experiment1a-046/declaration.json +11 -0
  35. package/proofs/m0-046/BridgeNegatives.lean +23 -0
  36. package/proofs/m0-046/M0Bridge.lean +300 -0
  37. package/proofs/m0-046/Obligations045/ConsensusGrid.lean +72 -0
  38. package/proofs/m0-046/Obligations045/M0Coincidence.lean +39 -0
  39. package/proofs/m0-046/Obligations045/M0Diagonal.lean +18 -0
  40. package/proofs/m0-046/Obligations045/M0Limit.lean +134 -0
  41. package/proofs/m0-046/Obligations045/M0Offdiag.lean +171 -0
  42. package/proofs/m0-046/Obligations045.lean +5 -0
  43. package/proofs/m0-046/lake-manifest.json +116 -0
  44. package/proofs/m0-046/lakefile.toml +14 -0
  45. package/proofs/m0-046/lean-toolchain +1 -0
  46. package/proofs/m0-046-diagonal/BridgeNegatives.lean +23 -0
  47. package/proofs/m0-046-diagonal/M0Bridge.lean +300 -0
  48. package/proofs/m0-046-diagonal/M0Diagonal046.lean +235 -0
  49. package/proofs/m0-046-diagonal/M0Lindeberg046.lean +92 -0
  50. package/proofs/m0-046-diagonal/M0Moments046.lean +295 -0
  51. package/proofs/m0-046-diagonal/M0Threshold046.lean +278 -0
  52. package/proofs/m0-046-diagonal/Obligations045/ConsensusGrid.lean +72 -0
  53. package/proofs/m0-046-diagonal/Obligations045/M0Coincidence.lean +39 -0
  54. package/proofs/m0-046-diagonal/Obligations045/M0Diagonal.lean +18 -0
  55. package/proofs/m0-046-diagonal/Obligations045/M0Limit.lean +134 -0
  56. package/proofs/m0-046-diagonal/Obligations045/M0Offdiag.lean +171 -0
  57. package/proofs/m0-046-diagonal/Obligations045.lean +5 -0
  58. package/proofs/m0-046-diagonal/lake-manifest.json +116 -0
  59. package/proofs/m0-046-diagonal/lakefile.toml +26 -0
  60. package/proofs/m0-046-diagonal/lean-toolchain +1 -0
  61. package/proofs/m0-046-identification/M0Identification046.lean +209 -0
  62. package/proofs/m0-046-identification/Obligations045/M0Coincidence.lean +39 -0
  63. package/proofs/m0-046-identification/lake-manifest.json +116 -0
  64. package/proofs/m0-046-identification/lakefile.toml +12 -0
  65. package/proofs/m0-046-identification/lean-toolchain +1 -0
  66. package/proofs/m0-046-uncertainty/BridgeNegatives.lean +23 -0
  67. package/proofs/m0-046-uncertainty/M0BlockCoverage046.lean +163 -0
  68. package/proofs/m0-046-uncertainty/M0Bridge.lean +300 -0
  69. package/proofs/m0-046-uncertainty/M0Diagonal046.lean +235 -0
  70. package/proofs/m0-046-uncertainty/M0FiniteDiscord046.lean +207 -0
  71. package/proofs/m0-046-uncertainty/M0Interval046.lean +82 -0
  72. package/proofs/m0-046-uncertainty/M0Lindeberg046.lean +92 -0
  73. package/proofs/m0-046-uncertainty/M0Moments046.lean +295 -0
  74. package/proofs/m0-046-uncertainty/M0Threshold046.lean +278 -0
  75. package/proofs/m0-046-uncertainty/Obligations045/ConsensusGrid.lean +72 -0
  76. package/proofs/m0-046-uncertainty/Obligations045/M0Coincidence.lean +39 -0
  77. package/proofs/m0-046-uncertainty/Obligations045/M0Diagonal.lean +18 -0
  78. package/proofs/m0-046-uncertainty/Obligations045/M0Limit.lean +134 -0
  79. package/proofs/m0-046-uncertainty/Obligations045/M0Offdiag.lean +171 -0
  80. package/proofs/m0-046-uncertainty/Obligations045.lean +5 -0
  81. package/proofs/m0-046-uncertainty/lake-manifest.json +116 -0
  82. package/proofs/m0-046-uncertainty/lakefile.toml +35 -0
  83. package/proofs/m0-046-uncertainty/lean-toolchain +1 -0
  84. package/proofs/m1-046-bridge/M0Bridge.lean +300 -0
  85. package/proofs/m1-046-bridge/M1Bridge046.lean +359 -0
  86. package/proofs/m1-046-bridge/Obligations045/M0Limit.lean +134 -0
  87. package/proofs/m1-046-bridge/Obligations045/M0Offdiag.lean +171 -0
  88. package/proofs/m1-046-bridge/lake-manifest.json +116 -0
  89. package/proofs/m1-046-bridge/lakefile.toml +29 -0
  90. package/proofs/m1-046-bridge/lean-toolchain +1 -0
  91. package/proofs/m1-046-diagonal/M0Bridge.lean +300 -0
  92. package/proofs/m1-046-diagonal/M0Diagonal046.lean +235 -0
  93. package/proofs/m1-046-diagonal/M0Lindeberg046.lean +92 -0
  94. package/proofs/m1-046-diagonal/M0Moments046.lean +295 -0
  95. package/proofs/m1-046-diagonal/M0Threshold046.lean +278 -0
  96. package/proofs/m1-046-diagonal/M1Bridge046.lean +359 -0
  97. package/proofs/m1-046-diagonal/M1Diagonal046.lean +334 -0
  98. package/proofs/m1-046-diagonal/M1Offdiag046.lean +270 -0
  99. package/proofs/m1-046-diagonal/Obligations045/M0Limit.lean +134 -0
  100. package/proofs/m1-046-diagonal/Obligations045/M0Offdiag.lean +171 -0
  101. package/proofs/m1-046-diagonal/lake-manifest.json +116 -0
  102. package/proofs/m1-046-diagonal/lakefile.toml +35 -0
  103. package/proofs/m1-046-diagonal/lean-toolchain +1 -0
  104. package/proofs/m1-046-offdiag/M0Bridge.lean +300 -0
  105. package/proofs/m1-046-offdiag/M0Diagonal046.lean +235 -0
  106. package/proofs/m1-046-offdiag/M0Moments046.lean +295 -0
  107. package/proofs/m1-046-offdiag/M1Bridge046.lean +359 -0
  108. package/proofs/m1-046-offdiag/M1Offdiag046.lean +270 -0
  109. package/proofs/m1-046-offdiag/Obligations045/M0Limit.lean +134 -0
  110. package/proofs/m1-046-offdiag/Obligations045/M0Offdiag.lean +171 -0
  111. package/proofs/m1-046-offdiag/lake-manifest.json +116 -0
  112. package/proofs/m1-046-offdiag/lakefile.toml +32 -0
  113. package/proofs/m1-046-offdiag/lean-toolchain +1 -0
  114. package/proofs/projection-chain.md +11 -0
  115. package/protocols/model-collapse-1a.json +108 -0
  116. package/receipts.bound +578 -210
  117. package/samples/laws/definitions/no/sample.json +26 -0
  118. package/samples/laws/definitions/yes/sample.json +12 -0
  119. package/samples/laws/experiment1a/no/sample.json +16 -0
  120. package/samples/laws/experiment1a/yes/sample.json +8 -0
  121. package/samples/laws/m0-binomial-bridge/no/pairwise-is-not-joint.json +59 -0
  122. package/samples/laws/m0-binomial-bridge/no/sample.json +13 -0
  123. package/samples/laws/m0-binomial-bridge/yes/sample.json +16 -0
  124. package/samples/laws/m0-binomial-bridge/yes/small-binomial-table.json +100 -0
  125. package/samples/laws/m0-diagonal-conditional/no/sample.json +5 -0
  126. package/samples/laws/m0-diagonal-conditional/yes/sample.json +7 -0
  127. package/samples/laws/m0-keff-interval/no/sample.json +215 -0
  128. package/samples/laws/m0-keff-interval/yes/api-rows.json +2002 -0
  129. package/samples/laws/m0-keff-interval/yes/sample.json +70 -0
  130. package/samples/laws/m0-moment-identification/no/sample.json +47 -0
  131. package/samples/laws/m0-moment-identification/yes/sample.json +97 -0
  132. package/samples/laws/m1-diagonal-regions/no/sample.json +44 -0
  133. package/samples/laws/m1-diagonal-regions/yes/sample.json +45 -0
  134. package/samples/laws/m1-generator-binomial/no/sample.json +21 -0
  135. package/samples/laws/m1-generator-binomial/yes/sample.json +290 -0
  136. package/samples/laws/m1-offdiag-limit/no/sample.json +17 -0
  137. package/samples/laws/m1-offdiag-limit/yes/sample.json +87 -0
  138. package/samples/laws/projection-chain/no/sample.json +26 -0
  139. package/samples/laws/projection-chain/yes/sample.json +25 -0
  140. package/samples/no/installed-artifact.json +2 -2
  141. package/samples/yes/installed-artifact.json +2 -2
  142. package/src/laws/laws.bound +146 -0
  143. package/vectors/laws/a7-t90.json +72 -0
  144. package/vectors/laws/a9-t99.json +110 -0
  145. package/vectors/laws/definitions.native-capture.json +326 -0
  146. package/vectors/laws/definitions.native.json +82 -0
  147. package/vectors/laws/experiment1a-protocol.native-capture.json +391 -0
  148. package/vectors/laws/experiment1a-protocol.native.json +64 -0
  149. package/vectors/laws/experiment1a-public-input.native-capture.json +224 -0
  150. package/vectors/laws/m0-binomial-bridge.lean.json +185 -0
  151. package/vectors/laws/m0-diagonal-lindeberg.lean.json +167 -0
  152. package/vectors/laws/m0-diagonal-moments.lean.json +185 -0
  153. package/vectors/laws/m0-diagonal-symmetric.lean.json +188 -0
  154. package/vectors/laws/m0-diagonal-threshold.lean.json +199 -0
  155. package/vectors/laws/m0-identification.lean.json +136 -0
  156. package/vectors/laws/m0-identification.native-capture.json +230 -0
  157. package/vectors/laws/m0-keff-interval.json +569 -0
  158. package/vectors/laws/m0-uncertainty-blocks.lean.json +201 -0
  159. package/vectors/laws/m0-uncertainty-finite-discord.lean.json +194 -0
  160. package/vectors/laws/m0-uncertainty-interval.lean.json +189 -0
  161. package/vectors/laws/m0-uncertainty.native-capture.json +651 -0
  162. package/vectors/laws/m1-diagonal-partial.lean.json +192 -0
  163. package/vectors/laws/m1-diagonal-partial.native-capture.json +275 -0
  164. package/vectors/laws/m1-generator-binomial.lean.json +162 -0
  165. package/vectors/laws/m1-generator-binomial.native-capture.json +245 -0
  166. package/vectors/laws/m1-offdiag-limit.lean.json +166 -0
  167. package/vectors/laws/m1-offdiag-limit.native-capture.json +260 -0
  168. package/vectors/laws/model-collapse-1a.json +12 -0
  169. package/vectors/laws/projection-chain.json +61 -0
  170. package/vectors/laws/projection-chain.native-capture.json +311 -0
  171. package/vectors/laws/projection-chain.native.json +56 -0
  172. package/vectors/measures/installed-artifact.cli.json +6 -6
  173. package/CHANGELOG.md +0 -10
@@ -0,0 +1,23 @@
1
+ import M0Bridge
2
+ namespace Obligations046.BridgeTests
3
+
4
+ def atoms : List (ℚ × ℚ × ℚ × ℚ) :=
5
+ [(0,0,0,1/16),(0,1,1,3/16),(1,0,1,3/16),(1,1,0,3/16),(1,1,1,6/16)]
6
+ def expect (f : ℚ → ℚ → ℚ → ℚ) : ℚ :=
7
+ (atoms.map (fun (a,b,c,w) => w*f a b c)).sum
8
+
9
+ /-- A normalized binary distribution with Bernoulli(3/4) pairwise marginals,
10
+ but not the jointly independent word law. Exact arithmetic, not simulation. -/
11
+ theorem pairwise_not_joint :
12
+ expect (fun _ _ _ => 1) = 1 ∧
13
+ expect (fun a _ _ => a) = 3/4 ∧
14
+ expect (fun _ b _ => b) = 3/4 ∧
15
+ expect (fun _ _ c => c) = 3/4 ∧
16
+ expect (fun a b _ => a*b) = 9/16 ∧
17
+ expect (fun a _ c => a*c) = 9/16 ∧
18
+ expect (fun _ b c => b*c) = 9/16 ∧
19
+ expect (fun a b c => (1-a)*(1-b)*(1-c)) = 1/16 ∧
20
+ expect (fun a b c => (1-a)*(1-b)*(1-c)) ≠ (1/4:ℚ)^3 := by
21
+ norm_num [expect, atoms]
22
+
23
+ end Obligations046.BridgeTests
@@ -0,0 +1,300 @@
1
+ import Obligations045.M0Offdiag
2
+ import Mathlib.Data.Nat.Choose.Sum
3
+ import Mathlib.Probability.ProbabilityMassFunction.Integrals
4
+ import Mathlib.Algebra.BigOperators.Group.Finset.Pi
5
+
6
+ open scoped BigOperators
7
+ open MeasureTheory ProbabilityTheory Filter Topology
8
+ noncomputable section
9
+ open Classical
10
+ namespace Obligations046.Bridge
11
+
12
+ def count {n : ℕ} (s : Finset (Fin n)) : Fin (n+1) :=
13
+ ⟨s.card, Nat.lt_succ_of_le (by simpa using s.card_le_univ)⟩
14
+ def mass (p : ℝ) {n : ℕ} (s : Finset (Fin n)) : ℝ :=
15
+ p^s.card*(1-p)^(n-s.card)
16
+ def binMass (p : ℝ) (n : ℕ) (k : Fin (n+1)) : ℝ :=
17
+ (n.choose k : ℝ)*p^(k:ℕ)*(1-p)^(n-(k:ℕ))
18
+
19
+ theorem count_fiber_mass (p : ℝ) (n : ℕ) (k : Fin (n+1)) :
20
+ (∑ s : Finset (Fin n), if count s = k then mass p s else 0) = binMass p n k := by
21
+ have hfilter : Finset.univ.filter (fun s : Finset (Fin n) => count s = k) =
22
+ Finset.powersetCard (k:ℕ) (Finset.univ : Finset (Fin n)) := by
23
+ ext s
24
+ simp [count, Fin.ext_iff, Finset.mem_powersetCard]
25
+ rw [← Finset.sum_filter, hfilter]
26
+ calc
27
+ _ = ∑ _s ∈ Finset.powersetCard (k:ℕ) (Finset.univ : Finset (Fin n)),
28
+ p^(k:ℕ)*(1-p)^(n-(k:ℕ)) := by
29
+ apply Finset.sum_congr rfl
30
+ intro s hs
31
+ simp only [Finset.mem_powersetCard] at hs
32
+ simp [mass, hs.2]
33
+ _ = binMass p n k := by
34
+ simp [binMass, Finset.card_powersetCard, nsmul_eq_mul, mul_assoc]
35
+
36
+ /-- Finite product-law pushforward, before any choice of Bernoulli parameters. -/
37
+ theorem product_pushforward {ι : Type*} [Fintype ι] [DecidableEq ι]
38
+ {S T : ι → Type*} [∀ i, Fintype (S i)] [∀ i, Fintype (T i)]
39
+ [∀ i, DecidableEq (T i)] (m : ∀ i, S i → ℝ) (c : ∀ i, S i → T i)
40
+ (f : (∀ i, T i) → ℝ) :
41
+ (∑ x : ∀ i, S i, (∏ i, m i (x i))*f (fun i => c i (x i))) =
42
+ ∑ k : ∀ i, T i, (∏ i, ∑ s : S i, if c i s = k i then m i s else 0)*f k := by
43
+ have gate (x : ∀ i, S i) (k : ∀ i, T i) :
44
+ (∏ i, if c i (x i) = k i then m i (x i) else 0) =
45
+ if (fun i => c i (x i)) = k then ∏ i, m i (x i) else 0 := by
46
+ by_cases h : (fun i => c i (x i)) = k
47
+ · subst k
48
+ simp
49
+ · rw [if_neg h]
50
+ have h' : ∃ i, c i (x i) ≠ k i := by
51
+ by_contra hn
52
+ push_neg at hn
53
+ exact h (funext hn)
54
+ obtain ⟨i, hi⟩ := h'
55
+ exact Finset.prod_eq_zero (Finset.mem_univ i) (by simp [hi])
56
+ symm
57
+ simp_rw [Fintype.prod_sum, Finset.sum_mul]
58
+ rw [Finset.sum_comm]
59
+ apply Finset.sum_congr rfl
60
+ intro x _
61
+ simp_rw [gate, ite_mul, zero_mul]
62
+ simp
63
+
64
+ /-- Raw individual Bernoulli outcomes are subsets of named member indices. -/
65
+ abbrev World {ι : Type*} (n : ι → ℕ) := ∀ i, Finset (Fin (n i))
66
+ instance worldMeasurableSpace {ι : Type*} (n : ι → ℕ) : MeasurableSpace (World n) := ⊤
67
+ instance worldDiscreteMeasurable {ι : Type*} (n : ι → ℕ) : DiscreteMeasurableSpace (World n) := ⟨fun _ => trivial⟩
68
+
69
+ def jointMass {ι : Type*} [Fintype ι] (n : ι → ℕ) (p : ι → ℝ)
70
+ (x : World n) : ℝ := ∏ i, mass (p i) (x i)
71
+
72
+ theorem joint_count_pushforward {ι : Type*} [Fintype ι] [DecidableEq ι]
73
+ (n : ι → ℕ) (p : ι → ℝ) (f : (∀ i, Fin (n i+1)) → ℝ) :
74
+ (∑ x : World n, jointMass n p x*f (fun i => count (x i))) =
75
+ ∑ k : ∀ i, Fin (n i+1), (∏ i, binMass (p i) (n i) (k i))*f k := by
76
+ simpa [jointMass, count_fiber_mass] using
77
+ product_pushforward (fun i => mass (p i)) (fun _ => count) f
78
+
79
+ theorem mass_sum (p : ℝ) (n : ℕ) :
80
+ ∑ s : Finset (Fin n), mass p s = 1 := by
81
+ have h := Finset.sum_powerset_apply_card (fun k => p^k*(1-p)^(n-k))
82
+ (x := (Finset.univ : Finset (Fin n)))
83
+ simp only [Finset.powerset_univ, Finset.card_univ, Fintype.card_fin, nsmul_eq_mul] at h
84
+ change (∑ s : Finset (Fin n), p^s.card*(1-p)^(n-s.card)) = 1
85
+ rw [h]
86
+ calc
87
+ _ = (p+(1-p))^n := by
88
+ rw [add_pow]
89
+ apply Finset.sum_congr rfl
90
+ intro k _
91
+ ring
92
+ _ = 1 := by simp
93
+
94
+ theorem mass_nonneg (p : ℝ) (hp : 0 ≤ p) (hp1 : p ≤ 1)
95
+ {n : ℕ} (s : Finset (Fin n)) : 0 ≤ mass p s :=
96
+ mul_nonneg (pow_nonneg hp _) (pow_nonneg (sub_nonneg.mpr hp1) _)
97
+
98
+ theorem jointMass_sum {ι : Type*} [Fintype ι] [DecidableEq ι]
99
+ (n : ι → ℕ) (p : ι → ℝ) : ∑ x : World n, jointMass n p x = 1 := by
100
+ simp only [jointMass, ← Fintype.prod_sum, mass_sum, Finset.prod_const_one]
101
+
102
+ def memberLaw {ι : Type*} [Fintype ι] [DecidableEq ι]
103
+ (n : ι → ℕ) (p : ι → ℝ) (hp : ∀ i, 0 ≤ p i) (hp1 : ∀ i, p i ≤ 1) :
104
+ PMF (World n) :=
105
+ PMF.ofFintype (fun x => ENNReal.ofReal (jointMass n p x)) (by
106
+ rw [← ENNReal.ofReal_sum_of_nonneg]
107
+ · simp [jointMass_sum]
108
+ · intro x _
109
+ exact Finset.prod_nonneg (fun i _ => mass_nonneg (p i) (hp i) (hp1 i) (x i)))
110
+
111
+ theorem memberLaw_expectation {ι : Type*} [Fintype ι] [DecidableEq ι]
112
+ (n : ι → ℕ) (p : ι → ℝ) (hp : ∀ i, 0 ≤ p i) (hp1 : ∀ i, p i ≤ 1)
113
+ (f : World n → ℝ) :
114
+ (∫ x, f x ∂(memberLaw n p hp hp1).toMeasure) =
115
+ ∑ x : World n, jointMass n p x*f x := by
116
+ rw [PMF.integral_eq_sum]
117
+ apply Finset.sum_congr rfl
118
+ intro x _
119
+ simp only [memberLaw, PMF.ofFintype_apply, smul_eq_mul]
120
+ have hm : 0 ≤ jointMass n p x := Finset.prod_nonneg
121
+ (fun i _ => mass_nonneg (p i) (hp i) (hp1 i) (x i))
122
+ rw [ENNReal.toReal_ofReal hm]
123
+
124
+ open Obligations045.M0
125
+ abbrev sizes (M : Domain) (N : ℕ) (i : Fin M.K) := allocation M.w N i
126
+ def modelLaw (M : Domain) (N : ℕ) (a : Fin M.K → Bool) : PMF (World (sizes M N)) :=
127
+ memberLaw (sizes M N) (fun i => q M (a i))
128
+ (fun i => (q_pos M (a i)).le) (fun i => (q_lt_one M (a i)).le)
129
+ def correctCount {ι : Type*} [Fintype ι] {n : ι → ℕ} (x : World n) : ℕ :=
130
+ ∑ i, (x i).card
131
+
132
+ /-- Exact finite expectation of individual Bernoulli member outcomes, not an assumed count law. -/
133
+ theorem conditional_error_representation (M : Domain) (N : ℕ) (a : Fin M.K → Bool) :
134
+ (∫ x, fairLoss (correctCount x) N ∂(modelLaw M N a).toMeasure) =
135
+ conditionalError M N a := by
136
+ rw [modelLaw, memberLaw_expectation]
137
+ have h := joint_count_pushforward (sizes M N) (fun i => q M (a i))
138
+ (fun k => fairLoss (∑ i, (k i : ℕ)) N)
139
+ simpa [conditionalError, binMass, count, correctCount, sizes] using h
140
+
141
+ /-- N=0 has fairLoss=1/2; it is not the average bridge. -/
142
+ theorem conditional_error_zero (M : Domain) (a : Fin M.K → Bool) :
143
+ conditionalError M 0 a = 1/2 := by
144
+ rw [← conditional_error_representation]
145
+ have hz : ∀ x : World (sizes M 0), correctCount x = 0 := by
146
+ intro x
147
+ have h : ∀ i, x i = ∅ := by
148
+ intro i
149
+ apply Finset.eq_empty_iff_forall_not_mem.mpr
150
+ intro j _
151
+ have hj := j.isLt
152
+ simp [sizes, allocation] at hj
153
+ simp [correctCount, h]
154
+ simp [hz, fairLoss]
155
+
156
+ theorem fair_loss_average_bridge (total N : ℕ) (hN : 0 < N) :
157
+ fairLoss total N = limitingLoss ((total:ℝ)/(N:ℝ)) := by
158
+ have hn : (0:ℝ) < N := by exact_mod_cast hN
159
+ have hlt : (total:ℝ)/(N:ℝ) < (1:ℝ)/2 ↔ 2*total < N := by
160
+ rw [div_lt_iff₀ hn]
161
+ constructor
162
+ · intro h
163
+ exact_mod_cast (show (2:ℝ)*total < N by linarith)
164
+ · intro h
165
+ have h' : (2:ℝ)*total < N := by exact_mod_cast h
166
+ linarith
167
+ have heq : (total:ℝ)/(N:ℝ) = (1:ℝ)/2 ↔ 2*total = N := by
168
+ rw [div_eq_iff hn.ne']
169
+ constructor
170
+ · intro h
171
+ exact_mod_cast (show (2:ℝ)*total = N by linarith)
172
+ · intro h
173
+ have h' : (2:ℝ)*total = N := by exact_mod_cast h
174
+ linarith
175
+ unfold fairLoss limitingLoss
176
+ simp only [hlt, heq]
177
+
178
+ /-- Probability of every joint count event, derived from raw member product probabilities. -/
179
+ theorem lineage_count_binomial_law {ι : Type*} [Fintype ι] [DecidableEq ι]
180
+ (n : ι → ℕ) (p : ι → ℝ) (hp : ∀ i, 0 ≤ p i) (hp1 : ∀ i, p i ≤ 1)
181
+ (k : ∀ i, Fin (n i+1)) :
182
+ (∫ x, if (fun i => count (x i)) = k then (1:ℝ) else 0
183
+ ∂(memberLaw n p hp hp1).toMeasure) = ∏ i, binMass (p i) (n i) (k i) := by
184
+ rw [memberLaw_expectation]
185
+ simpa using joint_count_pushforward n p (fun z => if z = k then (1:ℝ) else 0)
186
+
187
+ /-- The snapshot retains individual named Bernoulli outcomes; it is not a count-law certificate. -/
188
+ def snapshot {Ω : Type*} (M : Domain) (N : ℕ)
189
+ (X : Fin M.K → ℕ → Ω → Bool) (ω : Ω) : World (sizes M N) :=
190
+ fun i => Finset.univ.filter (fun j : Fin (sizes M N i) => X i j ω)
191
+ def indicator {Ω : Type*} {K : ℕ} (X : Fin K → ℕ → Ω → Bool) : Fin K → ℕ → Ω → ℝ :=
192
+ fun i j ω => if X i j ω then 1 else 0
193
+
194
+ theorem snapshot_card {Ω : Type*} (M : Domain) (N : ℕ)
195
+ (X : Fin M.K → ℕ → Ω → Bool) (ω : Ω) (i : Fin M.K) :
196
+ (((snapshot M N X ω) i).card : ℝ) =
197
+ ∑ j ∈ Finset.range (allocation M.w N i), indicator X i j ω := by
198
+ simp only [snapshot, Finset.card_filter, Nat.cast_sum, Nat.cast_ite,
199
+ Nat.cast_one, Nat.cast_zero, indicator]
200
+ exact Fin.sum_univ_eq_sum_range (fun j => if X i j ω then (1:ℝ) else 0) _
201
+
202
+ theorem snapshot_average {Ω : Type*} (M : Domain) (N : ℕ)
203
+ (X : Fin M.K → ℕ → Ω → Bool) (ω : Ω) :
204
+ memberAverage M (indicator X) N ω = (correctCount (snapshot M N X ω):ℝ)/(N:ℝ) := by
205
+ simp only [memberAverage, correctCount, Nat.cast_sum, snapshot_card, Finset.sum_div]
206
+
207
+ /-- Transfer from a declared joint Bernoulli MEMBER law on an ambient probability space.
208
+ hproduct names all raw bits, not counts, their expectation, or a tail/convergence law. -/
209
+ theorem ambient_conditional_error_representation {Ω : Type*} [MeasurableSpace Ω]
210
+ (M : Domain) (N : ℕ) (a : Fin M.K → Bool) (μ : Measure Ω)
211
+ (X : Fin M.K → ℕ → Ω → Bool) (hN : 0 < N)
212
+ (hmeas : AEMeasurable (snapshot M N X) μ)
213
+ (hproduct : Measure.map (snapshot M N X) μ = (modelLaw M N a).toMeasure) :
214
+ (∫ ω, limitingLoss (memberAverage M (indicator X) N ω) ∂μ) =
215
+ conditionalError M N a := by
216
+ have hpoint : (fun ω => limitingLoss (memberAverage M (indicator X) N ω)) =
217
+ (fun ω => fairLoss (correctCount (snapshot M N X ω)) N) := by
218
+ funext ω
219
+ rw [snapshot_average, fair_loss_average_bridge _ _ hN]
220
+ rw [hpoint]
221
+ have hf : AEStronglyMeasurable (fun x : World (sizes M N) => fairLoss (correctCount x) N)
222
+ (Measure.map (snapshot M N X) μ) := Measurable.of_discrete.stronglyMeasurable.aestronglyMeasurable
223
+ rw [← integral_map hmeas hf, hproduct, conditional_error_representation]
224
+
225
+ theorem mixture_error_representation {Ω : Type*} [MeasurableSpace Ω]
226
+ (M : Domain) (N : ℕ) (μ : Measure Ω)
227
+ (X : (Fin M.K → Bool) → Fin M.K → ℕ → Ω → Bool) (hN : 0 < N)
228
+ (hmeas : ∀ a, AEMeasurable (snapshot M N (X a)) μ)
229
+ (hproduct : ∀ a, Measure.map (snapshot M N (X a)) μ = (modelLaw M N a).toMeasure) :
230
+ error M N = ∑ a : Fin M.K → Bool, latentMass M a *
231
+ ∫ ω, limitingLoss (memberAverage M (indicator (X a)) N ω) ∂μ := by
232
+ unfold error
233
+ apply Finset.sum_congr rfl
234
+ intro a _
235
+ rw [ambient_conditional_error_representation M N a μ (X a) hN (hmeas a) (hproduct a)]
236
+
237
+ /-- The implementation limit follows from the old model theorem and the new representation bridge.
238
+ No CLT, diagonal theorem, count-law certificate, or convergence premise is assumed. -/
239
+ theorem computational_offdiag_limit {Ω : Type*} [MeasurableSpace Ω]
240
+ (M : Domain) (μ : Measure Ω) [IsProbabilityMeasure μ]
241
+ (X : (Fin M.K → Bool) → Fin M.K → ℕ → Ω → Bool)
242
+ (hsnapshot : ∀ a N, AEMeasurable (snapshot M N (X a)) μ)
243
+ (hproduct : ∀ a N, Measure.map (snapshot M N (X a)) μ = (modelLaw M N a).toMeasure)
244
+ (hint : ∀ a i, Integrable (indicator (X a) i 0) μ)
245
+ (hindep : ∀ a i, Pairwise (fun j k : ℕ => IndepFun (indicator (X a) i j) (indicator (X a) i k) μ))
246
+ (hident : ∀ a i j, IdentDistrib (indicator (X a) i j) (indicator (X a) i 0) μ μ)
247
+ (hmean : ∀ a i, ∫ ω, indicator (X a) i 0 ω ∂μ = q M (a i))
248
+ (hmeas : ∀ a N, AEStronglyMeasurable
249
+ (fun ω => limitingLoss (memberAverage M (indicator (X a)) N ω)) μ)
250
+ (hoff : ∀ a, score M a ≠ (1:ℝ)/2) :
251
+ Tendsto (error M) atTop (𝓝 (floor M)) := by
252
+ have h := floor_limit_offdiag_mixture M μ (fun a => indicator (X a))
253
+ hint hindep hident hmean hmeas hoff
254
+ have heq : (fun N => error M N) =ᶠ[atTop]
255
+ (fun N => ∑ a : Fin M.K → Bool, latentMass M a *
256
+ ∫ ω, limitingLoss (memberAverage M (indicator (X a)) N ω) ∂μ) := by
257
+ filter_upwards [eventually_ge_atTop 1] with N hN
258
+ exact mixture_error_representation M N μ X (lt_of_lt_of_le Nat.zero_lt_one hN)
259
+ (fun a => hsnapshot a N) (fun a => hproduct a N)
260
+ exact h.congr' heq.symm
261
+
262
+ /-- The starting probability is the product over NAMED INDIVIDUAL bits, with no binomial factor. -/
263
+ theorem mass_eq_individual_product (p : ℝ) {n : ℕ} (s : Finset (Fin n)) :
264
+ mass p s = ∏ j : Fin n, if j ∈ s then p else 1-p := by
265
+ have hc : (Finset.univ.filter (fun j : Fin n => j ∉ s)) = sᶜ := by
266
+ ext j
267
+ simp
268
+ rw [Finset.prod_ite]
269
+ simp [mass, Finset.filter_mem_eq_inter, hc, Finset.card_compl]
270
+
271
+ theorem memberLaw_individual_probability {ι : Type*} [Fintype ι] [DecidableEq ι]
272
+ (n : ι → ℕ) (p : ι → ℝ) (hp : ∀ i, 0 ≤ p i) (hp1 : ∀ i, p i ≤ 1)
273
+ (x : World n) :
274
+ ((memberLaw n p hp hp1) x).toReal =
275
+ ∏ i, ∏ j : Fin (n i), if j ∈ x i then p i else 1-p i := by
276
+ simp only [memberLaw, PMF.ofFintype_apply]
277
+ have hm : 0 ≤ jointMass n p x := Finset.prod_nonneg
278
+ (fun i _ => mass_nonneg (p i) (hp i) (hp1 i) (x i))
279
+ rw [ENNReal.toReal_ofReal hm]
280
+ simp only [jointMass, mass_eq_individual_product]
281
+
282
+ theorem zero_average_counterexample : fairLoss 0 0 ≠ limitingLoss ((0:ℝ)/0) := by
283
+ norm_num [fairLoss, limitingLoss]
284
+
285
+ theorem latentMass_sum (M : Domain) : ∑ a : Fin M.K → Bool, latentMass M a = 1 := by
286
+ have h := (Fintype.prod_sum (fun (_i : Fin M.K) (b : Bool) =>
287
+ if b then M.p else 1-M.p)).symm
288
+ simpa [latentMass] using h
289
+
290
+ /-- The finite mixture itself equals the existing implementation for EVERY N,
291
+ including zero. Its product-Bernoulli latent weights sum to one. -/
292
+ theorem model_mixture_error_representation (M : Domain) (N : ℕ) :
293
+ (∑ a : Fin M.K → Bool, latentMass M a *
294
+ ∫ x, fairLoss (correctCount x) N ∂(modelLaw M N a).toMeasure) = error M N := by
295
+ unfold error
296
+ apply Finset.sum_congr rfl
297
+ intro a _
298
+ rw [conditional_error_representation]
299
+
300
+ end Obligations046.Bridge
@@ -0,0 +1,72 @@
1
+ import Std
2
+ set_option maxRecDepth 10000
3
+ set_option maxHeartbeats 8000000
4
+ namespace Obligations045
5
+ -- Finite closed-form calculation only. This file does not assert a limit theorem.
6
+ def binom : Nat → Nat → Nat
7
+ | 0, 0 => 1
8
+ | 0, _ + 1 => 0
9
+ | _ + 1, 0 => 1
10
+ | n + 1, k + 1 => binom n k + binom n (k + 1)
11
+ def configs : Nat → List (List Bool)
12
+ | 0 => [[]]
13
+ | k + 1 => (configs k).flatMap (fun xs => [false :: xs, true :: xs])
14
+ def ones (xs : List Bool) : Nat := (xs.filter id).length
15
+ -- p=P/20, c=C/20. Below/equal/above 1/2 encoded as 2/1/0.
16
+ def loss2 (K P C m : Nat) : Nat :=
17
+ let lhs := 2 * (20 * C * m + (20-C) * P * K)
18
+ let rhs := 400 * K
19
+ if lhs < rhs then 2 else if lhs == rhs then 1 else 0
20
+ def grouped (K P C : Nat) : Nat :=
21
+ ((List.range (K+1)).map (fun m =>
22
+ binom K m * P^m * (20-P)^(K-m) * loss2 K P C m)).sum
23
+ def enumerated (K P C : Nat) : Nat :=
24
+ ((configs K).map (fun xs =>
25
+ P^(ones xs) * (20-P)^(K-ones xs) * loss2 K P C (ones xs))).sum
26
+ def grid : List (Nat × Nat × Nat) :=
27
+ ([1,2,3,4] : List Nat).flatMap (fun K =>
28
+ (List.range 9).flatMap (fun i =>
29
+ (List.range 20).map (fun j => (K,11+i,1+j))))
30
+ theorem grid_has_720_cases : grid.length = 720 := by decide
31
+ theorem closed_form_matches_full_configurations :
32
+ ∀ x ∈ grid, grouped x.1 x.2.1 x.2.2 = enumerated x.1 x.2.1 x.2.2 := by decide
33
+ theorem grid_probability_range :
34
+ ∀ x ∈ grid, grouped x.1 x.2.1 x.2.2 ≤ 2*20^x.1 := by decide
35
+ -- p=3/4, c=1/2: two distinct K have the same 1/64 floor.
36
+ theorem inverse_alias :
37
+ grouped 3 15 10 * (2*20^5) = grouped 5 15 10 * (2*20^3) := by decide
38
+ -- For p=3/4,c=9/10 and counts summing to N, compare score with 17*N/36.
39
+ def score (counts : List Nat) (zs : List Bool) : Nat :=
40
+ ((counts.zip zs).map (fun x => if x.2 then x.1 else 0)).sum
41
+ def floorNumerator (counts : List Nat) : Nat :=
42
+ ((configs counts.length).map (fun zs =>
43
+ let lhs := 36 * score counts zs
44
+ let rhs := 17 * counts.sum
45
+ let factor := if lhs < rhs then 2 else if lhs == rhs then 1 else 0
46
+ 3^(ones zs) * factor)).sum
47
+ -- Denominator is 2*4^3=128 in each three-lineage case.
48
+ theorem same_effective_participation_different_floor :
49
+ (1*1+4*4+4*4 : Nat) = 2*2+2*2+5*5 ∧
50
+ floorNumerator [1,4,4] = 20 ∧ floorNumerator [2,2,5] = 32 := by decide
51
+ -- WF population N=5, initial counts [3,1,1]; all 21 descendant count states.
52
+ def wfNumerator : Nat :=
53
+ ((List.range 6).map (fun a =>
54
+ ((List.range (6-a)).map (fun b =>
55
+ binom 5 a * binom (5-a) b * 3^a *
56
+ floorNumerator [a,b,5-a-b])).sum)).sum
57
+ theorem wf_transition_normalized :
58
+ ((List.range 6).map (fun a =>
59
+ ((List.range (6-a)).map (fun b =>
60
+ binom 5 a * binom (5-a) b * 3^a)).sum)).sum = 5^5 := by decide
61
+ theorem wf_floor_decreases_in_expectation :
62
+ floorNumerator [3,1,1] = 32 ∧ wfNumerator = 92440 ∧
63
+ wfNumerator < floorNumerator [3,1,1] * 5^5 := by decide
64
+ end Obligations045
65
+ #print axioms Obligations045.grid_has_720_cases
66
+ #print axioms Obligations045.closed_form_matches_full_configurations
67
+ #print axioms Obligations045.grid_probability_range
68
+ #print axioms Obligations045.inverse_alias
69
+
70
+ #print axioms Obligations045.same_effective_participation_different_floor
71
+ #print axioms Obligations045.wf_transition_normalized
72
+ #print axioms Obligations045.wf_floor_decreases_in_expectation
@@ -0,0 +1,39 @@
1
+ import Mathlib.Data.Real.Basic
2
+ import Mathlib.Tactic.Ring
3
+ namespace Obligations045.M0Coincidence
4
+ /-- Exact expectation over independent Bernoulli(p) latent lineages.
5
+ The recurrence keeps both branches and their actual probabilities. -/
6
+ def expect (p : ℝ) : List ℝ → (ℝ → ℝ) → ℝ
7
+ | [], f => f 0
8
+ | w :: ws, f => (1-p)*expect p ws f + p*expect p ws (fun x => f (w+x))
9
+ def squares (ws : List ℝ) : ℝ := (ws.map (fun w => w^2)).sum
10
+
11
+ theorem expect_quadratic (p : ℝ) (ws : List ℝ) (a b d : ℝ) :
12
+ expect p ws (fun x => a*x^2+b*x+d) =
13
+ a*(p^2*ws.sum^2+p*(1-p)*squares ws)+b*p*ws.sum+d := by
14
+ induction ws generalizing a b d with
15
+ | nil => simp [expect, squares]
16
+ | cons w ws ih =>
17
+ have hf : (fun x : ℝ => a*(w+x)^2+b*(w+x)+d) =
18
+ (fun x => a*x^2+(2*a*w+b)*x+(a*w^2+b*w+d)) := by
19
+ funext x
20
+ ring
21
+ simp only [expect, hf]
22
+ rw [ih, ih]
23
+ simp only [List.sum_cons, squares, List.map_cons]
24
+ ring
25
+
26
+ theorem pair_coincidence (p c : ℝ) (ws : List ℝ) (hw : ws.sum = 1) :
27
+ expect p ws (fun x => ((1-c)*p+c*x)^2+(1-((1-c)*p+c*x))^2) =
28
+ p^2+(1-p)^2+2*c^2*p*(1-p)*squares ws := by
29
+ have hf : (fun x : ℝ => ((1-c)*p+c*x)^2+(1-((1-c)*p+c*x))^2) =
30
+ (fun x => (2*c^2)*x^2+(2*c*(2*(1-c)*p-1))*x+
31
+ (((1-c)*p)^2+(1-(1-c)*p)^2)) := by
32
+ funext x
33
+ ring
34
+ rw [hf, expect_quadratic, hw]
35
+ ring
36
+
37
+ theorem triple_redundant (q : ℝ) :
38
+ q^3+(1-q)^3 = (3*(q^2+(1-q)^2)-1)/2 := by ring
39
+ end Obligations045.M0Coincidence
@@ -0,0 +1,18 @@
1
+ import Obligations045.ConsensusGrid
2
+ set_option maxRecDepth 10000
3
+ set_option maxHeartbeats 8000000
4
+ namespace Obligations045.Diagonal
5
+ /-- Finite diagonal vector only: K=1,p=3/4,c=1/3,w=[1].
6
+ A=false gives q=1/2, A=true gives q=5/6.
7
+ No general CLT or diagonal-limit theorem is declared in this file. -/
8
+ def loss2 (b N : Nat) : Nat := if 2*b < N then 2 else if 2*b == N then 1 else 0
9
+ def unbiasedNumerator (N : Nat) : Nat :=
10
+ ((List.range (N+1)).map (fun b => Obligations045.binom N b * loss2 b N)).sum
11
+ def cases : List Nat := [1,2,3,4,5,6,7,8,9,10,11,12]
12
+ theorem unbiased_diagonal_vector : ∀ N ∈ cases, unbiasedNumerator N = 2^N := by decide
13
+ -- Total error numerator has denominator 8*6^N; the target floor is 1/8.
14
+ def errorNumerator (N : Nat) : Nat :=
15
+ 6^N+3*((List.range (N+1)).map (fun b =>
16
+ Obligations045.binom N b * 5^b * loss2 b N)).sum
17
+ #eval cases.map (fun N => (N,errorNumerator N,8*6^N))
18
+ end Obligations045.Diagonal
@@ -0,0 +1,134 @@
1
+ import Mathlib.Topology.Instances.Real.Lemmas
2
+ import Mathlib.Data.Real.Archimedean
3
+ import Mathlib.Topology.Algebra.Order.Field
4
+ import Mathlib.Algebra.Order.Floor.Ring
5
+ import Mathlib.Tactic.Linarith
6
+ import Mathlib.Tactic.Ring
7
+ import Mathlib.Tactic.NormNum
8
+ import Mathlib.Tactic.Positivity
9
+
10
+ open scoped BigOperators
11
+ open Filter Topology
12
+ noncomputable section
13
+ open Classical
14
+ namespace Obligations045.M0
15
+
16
+ /-- Declared binary M0 domain. This structure contains no limiting-probability axiom. -/
17
+ structure Domain where
18
+ K : ℕ
19
+ K_pos : 0 < K
20
+ p : ℝ
21
+ c : ℝ
22
+ p_half : (1:ℝ)/2 < p
23
+ p_lt_one : p < 1
24
+ c_nonneg : 0 ≤ c
25
+ c_lt_one : c < 1
26
+ w : ℕ → ℝ
27
+ w_nonneg : ∀ i, 0 ≤ w i
28
+ weights_sum : ∑ i ∈ Finset.range K, w i = 1
29
+
30
+ def cumulative (w : ℕ → ℝ) (i : ℕ) : ℝ := ∑ j ∈ Finset.range i, w j
31
+
32
+ def allocation (w : ℕ → ℝ) (N i : ℕ) : ℕ :=
33
+ ⌊(N:ℝ) * cumulative w (i+1)⌋₊ - ⌊(N:ℝ) * cumulative w i⌋₊
34
+
35
+ theorem prefix_succ (w : ℕ → ℝ) (i : ℕ) :
36
+ cumulative w (i+1) = cumulative w i + w i := by simp [cumulative, Finset.sum_range_succ]
37
+
38
+ theorem prefix_monotone (w : ℕ → ℝ) (hw : ∀ i, 0 ≤ w i) : Monotone (cumulative w) := by
39
+ apply monotone_nat_of_le_succ
40
+ intro i
41
+ rw [prefix_succ]
42
+ exact le_add_of_nonneg_right (hw i)
43
+
44
+ theorem allocation_sum (M : Domain) (N : ℕ) :
45
+ ∑ i ∈ Finset.range M.K, allocation M.w N i = N := by
46
+ let f : ℕ → ℕ := fun i => ⌊(N:ℝ) * cumulative M.w i⌋₊
47
+ have hf : Monotone f := fun i j hij =>
48
+ Nat.floor_mono (mul_le_mul_of_nonneg_left (prefix_monotone M.w M.w_nonneg hij) (by positivity))
49
+ change ∑ i ∈ Finset.range M.K, (f (i+1) - f i) = N
50
+ rw [Finset.sum_range_tsub hf]
51
+ simp [f, cumulative, M.weights_sum]
52
+
53
+ theorem allocation_discrepancy (M : Domain) (N i : ℕ) :
54
+ -1 < (allocation M.w N i : ℝ) - (N:ℝ)*M.w i ∧
55
+ (allocation M.w N i : ℝ) - (N:ℝ)*M.w i < 1 := by
56
+ have hpre : 0 ≤ cumulative M.w i := Finset.sum_nonneg (fun j _ => M.w_nonneg j)
57
+ have hnext : 0 ≤ cumulative M.w (i+1) := Finset.sum_nonneg (fun j _ => M.w_nonneg j)
58
+ have hm : ⌊(N:ℝ)*cumulative M.w i⌋₊ ≤ ⌊(N:ℝ)*cumulative M.w (i+1)⌋₊ :=
59
+ Nat.floor_mono (mul_le_mul_of_nonneg_left (prefix_monotone M.w M.w_nonneg (Nat.le_succ i)) (by positivity))
60
+ have a := Nat.floor_le (mul_nonneg (Nat.cast_nonneg N) hpre)
61
+ have b := Nat.lt_floor_add_one ((N:ℝ)*cumulative M.w i)
62
+ have c := Nat.floor_le (mul_nonneg (Nat.cast_nonneg N) hnext)
63
+ have d := Nat.lt_floor_add_one ((N:ℝ)*cumulative M.w (i+1))
64
+ have hs := prefix_succ M.w i
65
+ simp only [allocation, Nat.cast_sub hm]
66
+ constructor <;> nlinarith
67
+
68
+ def q (M : Domain) (a : Bool) : ℝ := (1-M.c)*M.p + if a then M.c else 0
69
+
70
+ theorem q_pos (M : Domain) (a : Bool) : 0 < q M a := by
71
+ have hp : 0 < M.p := by linarith [M.p_half]
72
+ cases a <;> simp only [q, Bool.false_eq_true, ite_false, add_zero, ite_true] <;>
73
+ nlinarith [M.c_nonneg, M.c_lt_one]
74
+
75
+ theorem q_lt_one (M : Domain) (a : Bool) : q M a < 1 := by
76
+ have hp : 0 < M.p := by linarith [M.p_half]
77
+ cases a <;> simp only [q, Bool.false_eq_true, ite_false, add_zero, ite_true] <;>
78
+ nlinarith [M.c_nonneg, M.c_lt_one, M.p_lt_one]
79
+
80
+ def score (M : Domain) (a : Fin M.K → Bool) : ℝ :=
81
+ ∑ i : Fin M.K, M.w i * q M (a i)
82
+
83
+ def latentMass (M : Domain) (a : Fin M.K → Bool) : ℝ :=
84
+ ∏ i : Fin M.K, if a i then M.p else 1-M.p
85
+
86
+ def fairLoss (correct total : ℕ) : ℝ :=
87
+ if 2*correct < total then 1 else if 2*correct = total then 1/2 else 0
88
+
89
+ /-- The exact finite conditional error, using independent binomial counts in each lineage. -/
90
+ noncomputable def conditionalError (M : Domain) (N : ℕ) (a : Fin M.K → Bool) : ℝ :=
91
+ ∑ x : (i : Fin M.K) → Fin (allocation M.w N i + 1),
92
+ (∏ i : Fin M.K,
93
+ (Nat.choose (allocation M.w N i) (x i) : ℝ) *
94
+ q M (a i) ^ (x i : ℕ) *
95
+ (1-q M (a i)) ^ (allocation M.w N i - (x i : ℕ))) *
96
+ fairLoss (∑ i : Fin M.K, (x i : ℕ)) N
97
+
98
+ noncomputable def error (M : Domain) (N : ℕ) : ℝ :=
99
+ ∑ a : Fin M.K → Bool, latentMass M a * conditionalError M N a
100
+
101
+ noncomputable def limitingLoss (s : ℝ) : ℝ :=
102
+ if s < 1/2 then 1 else if s = 1/2 then 1/2 else 0
103
+
104
+ noncomputable def floor (M : Domain) : ℝ :=
105
+ ∑ a : Fin M.K → Bool, latentMass M a * limitingLoss (score M a)
106
+
107
+ /-- Explicit proof obligations, NOT assumptions hidden inside the generative model.
108
+ The strict branches require concentration. The equality branch requires a CLT.
109
+ This certificate has no constructed instance in this project. -/
110
+ def ConditionalTailLimits (M : Domain) : Prop :=
111
+ (∀ a, score M a < 1/2 → Tendsto (fun N => conditionalError M N a) atTop (𝓝 1)) ∧
112
+ (∀ a, 1/2 < score M a → Tendsto (fun N => conditionalError M N a) atTop (𝓝 0)) ∧
113
+ (∀ a, score M a = 1/2 → Tendsto (fun N => conditionalError M N a) atTop (𝓝 (1/2)))
114
+
115
+ /-- Kernel checked finite-mixture transfer. This is intentionally conditional;
116
+ it does not claim that ConditionalTailLimits follows from Domain. -/
117
+ theorem limit_of_conditional_tail_limits (M : Domain) (h : ConditionalTailLimits M) :
118
+ Tendsto (error M) atTop (𝓝 (floor M)) := by
119
+ have hcase : ∀ a, Tendsto (fun N => conditionalError M N a) atTop
120
+ (𝓝 (limitingLoss (score M a))) := by
121
+ intro a
122
+ by_cases hl : score M a < 1/2
123
+ · rw [limitingLoss, if_pos hl]
124
+ exact h.1 a hl
125
+ · by_cases he : score M a = 1/2
126
+ · rw [limitingLoss, if_neg hl, if_pos he]
127
+ exact h.2.2 a he
128
+ · have hg : 1/2 < score M a := lt_of_le_of_ne (le_of_not_gt hl) (Ne.symm he)
129
+ rw [limitingLoss, if_neg hl, if_neg he]
130
+ exact h.2.1 a hg
131
+ unfold error floor
132
+ exact tendsto_finset_sum _ (fun a _ => tendsto_const_nhds.mul (hcase a))
133
+
134
+ end Obligations045.M0