@lapxo/obligations 0.4.4 → 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 (212) hide show
  1. package/README.md +42 -3
  2. package/TARGET.bound +147 -4
  3. package/contracts/extension-lineage-participation.json +30 -0
  4. package/contracts/m0-allocation.json +6 -0
  5. package/contracts/m0-binomial-bridge.json +6 -0
  6. package/contracts/m0-diagonal-conditional.json +15 -0
  7. package/contracts/m0-finite-grid.json +6 -0
  8. package/contracts/m0-keff-interval.json +27 -0
  9. package/contracts/m0-limit-diag.json +6 -0
  10. package/contracts/m0-limit-offdiag.json +6 -0
  11. package/contracts/m0-moment-identification.json +42 -0
  12. package/contracts/m0-pair-coincidence.json +6 -0
  13. package/contracts/m1-diagonal-regions.json +45 -0
  14. package/contracts/m1-generator-binomial.json +26 -0
  15. package/contracts/m1-offdiag-limit.json +42 -0
  16. package/contracts/m1-subcauses.json +66 -0
  17. package/contracts/model-collapse-1a.json +16 -0
  18. package/contracts/projection-chain.json +20 -0
  19. package/docs/contracts/experiment1a-public-attribution.md +1 -0
  20. package/docs/contracts/extension-lineage-participation.md +13 -0
  21. package/docs/contracts/installation-046-inputs.md +1 -0
  22. package/docs/contracts/m0-allocation.md +1 -0
  23. package/docs/contracts/m0-binomial-bridge.md +1 -0
  24. package/docs/contracts/m0-diagonal-lindeberg.md +1 -0
  25. package/docs/contracts/m0-diagonal-moments.md +1 -0
  26. package/docs/contracts/m0-diagonal-symmetric.md +1 -0
  27. package/docs/contracts/m0-diagonal-threshold.md +1 -0
  28. package/docs/contracts/m0-finite-grid.md +1 -0
  29. package/docs/contracts/m0-keff-floor-refutation.md +1 -0
  30. package/docs/contracts/m0-keff-interval.md +1 -0
  31. package/docs/contracts/m0-limit-diag.md +1 -0
  32. package/docs/contracts/m0-limit-offdiag.md +1 -0
  33. package/docs/contracts/m0-moment-identification.md +1 -0
  34. package/docs/contracts/m0-pair-coincidence.md +1 -0
  35. package/docs/contracts/m0-refuted-inverses.md +1 -0
  36. package/docs/contracts/m0-wf-floor-refutation.md +1 -0
  37. package/docs/contracts/m1-diagonal-regions.md +1 -0
  38. package/docs/contracts/m1-generator-binomial.md +1 -0
  39. package/docs/contracts/m1-offdiag-limit.md +1 -0
  40. package/docs/contracts/model-collapse-1a.md +11 -0
  41. package/docs/contracts/projection-chain.md +1 -0
  42. package/docs/proofs/floor-limit-diag.proof.json +29 -0
  43. package/package.json +1 -1
  44. package/proofs/definitions-046/declaration.json +11 -0
  45. package/proofs/experiment1a-046/declaration.json +11 -0
  46. package/proofs/m0-045/Obligations045/ConsensusGrid.lean +72 -0
  47. package/proofs/m0-045/Obligations045/M0Coincidence.lean +39 -0
  48. package/proofs/m0-045/Obligations045/M0Diagonal.lean +18 -0
  49. package/proofs/m0-045/Obligations045/M0Limit.lean +134 -0
  50. package/proofs/m0-045/Obligations045/M0Offdiag.lean +171 -0
  51. package/proofs/m0-045/Obligations045.lean +5 -0
  52. package/proofs/m0-045/lake-manifest.json +116 -0
  53. package/proofs/m0-045/lakefile.toml +9 -0
  54. package/proofs/m0-045/lean-toolchain +1 -0
  55. package/proofs/m0-046/BridgeNegatives.lean +23 -0
  56. package/proofs/m0-046/M0Bridge.lean +300 -0
  57. package/proofs/m0-046/Obligations045/ConsensusGrid.lean +72 -0
  58. package/proofs/m0-046/Obligations045/M0Coincidence.lean +39 -0
  59. package/proofs/m0-046/Obligations045/M0Diagonal.lean +18 -0
  60. package/proofs/m0-046/Obligations045/M0Limit.lean +134 -0
  61. package/proofs/m0-046/Obligations045/M0Offdiag.lean +171 -0
  62. package/proofs/m0-046/Obligations045.lean +5 -0
  63. package/proofs/m0-046/lake-manifest.json +116 -0
  64. package/proofs/m0-046/lakefile.toml +14 -0
  65. package/proofs/m0-046/lean-toolchain +1 -0
  66. package/proofs/m0-046-diagonal/BridgeNegatives.lean +23 -0
  67. package/proofs/m0-046-diagonal/M0Bridge.lean +300 -0
  68. package/proofs/m0-046-diagonal/M0Diagonal046.lean +235 -0
  69. package/proofs/m0-046-diagonal/M0Lindeberg046.lean +92 -0
  70. package/proofs/m0-046-diagonal/M0Moments046.lean +295 -0
  71. package/proofs/m0-046-diagonal/M0Threshold046.lean +278 -0
  72. package/proofs/m0-046-diagonal/Obligations045/ConsensusGrid.lean +72 -0
  73. package/proofs/m0-046-diagonal/Obligations045/M0Coincidence.lean +39 -0
  74. package/proofs/m0-046-diagonal/Obligations045/M0Diagonal.lean +18 -0
  75. package/proofs/m0-046-diagonal/Obligations045/M0Limit.lean +134 -0
  76. package/proofs/m0-046-diagonal/Obligations045/M0Offdiag.lean +171 -0
  77. package/proofs/m0-046-diagonal/Obligations045.lean +5 -0
  78. package/proofs/m0-046-diagonal/lake-manifest.json +116 -0
  79. package/proofs/m0-046-diagonal/lakefile.toml +26 -0
  80. package/proofs/m0-046-diagonal/lean-toolchain +1 -0
  81. package/proofs/m0-046-identification/M0Identification046.lean +209 -0
  82. package/proofs/m0-046-identification/Obligations045/M0Coincidence.lean +39 -0
  83. package/proofs/m0-046-identification/lake-manifest.json +116 -0
  84. package/proofs/m0-046-identification/lakefile.toml +12 -0
  85. package/proofs/m0-046-identification/lean-toolchain +1 -0
  86. package/proofs/m0-046-uncertainty/BridgeNegatives.lean +23 -0
  87. package/proofs/m0-046-uncertainty/M0BlockCoverage046.lean +163 -0
  88. package/proofs/m0-046-uncertainty/M0Bridge.lean +300 -0
  89. package/proofs/m0-046-uncertainty/M0Diagonal046.lean +235 -0
  90. package/proofs/m0-046-uncertainty/M0FiniteDiscord046.lean +207 -0
  91. package/proofs/m0-046-uncertainty/M0Interval046.lean +82 -0
  92. package/proofs/m0-046-uncertainty/M0Lindeberg046.lean +92 -0
  93. package/proofs/m0-046-uncertainty/M0Moments046.lean +295 -0
  94. package/proofs/m0-046-uncertainty/M0Threshold046.lean +278 -0
  95. package/proofs/m0-046-uncertainty/Obligations045/ConsensusGrid.lean +72 -0
  96. package/proofs/m0-046-uncertainty/Obligations045/M0Coincidence.lean +39 -0
  97. package/proofs/m0-046-uncertainty/Obligations045/M0Diagonal.lean +18 -0
  98. package/proofs/m0-046-uncertainty/Obligations045/M0Limit.lean +134 -0
  99. package/proofs/m0-046-uncertainty/Obligations045/M0Offdiag.lean +171 -0
  100. package/proofs/m0-046-uncertainty/Obligations045.lean +5 -0
  101. package/proofs/m0-046-uncertainty/lake-manifest.json +116 -0
  102. package/proofs/m0-046-uncertainty/lakefile.toml +35 -0
  103. package/proofs/m0-046-uncertainty/lean-toolchain +1 -0
  104. package/proofs/m1-046-bridge/M0Bridge.lean +300 -0
  105. package/proofs/m1-046-bridge/M1Bridge046.lean +359 -0
  106. package/proofs/m1-046-bridge/Obligations045/M0Limit.lean +134 -0
  107. package/proofs/m1-046-bridge/Obligations045/M0Offdiag.lean +171 -0
  108. package/proofs/m1-046-bridge/lake-manifest.json +116 -0
  109. package/proofs/m1-046-bridge/lakefile.toml +29 -0
  110. package/proofs/m1-046-bridge/lean-toolchain +1 -0
  111. package/proofs/m1-046-diagonal/M0Bridge.lean +300 -0
  112. package/proofs/m1-046-diagonal/M0Diagonal046.lean +235 -0
  113. package/proofs/m1-046-diagonal/M0Lindeberg046.lean +92 -0
  114. package/proofs/m1-046-diagonal/M0Moments046.lean +295 -0
  115. package/proofs/m1-046-diagonal/M0Threshold046.lean +278 -0
  116. package/proofs/m1-046-diagonal/M1Bridge046.lean +359 -0
  117. package/proofs/m1-046-diagonal/M1Diagonal046.lean +334 -0
  118. package/proofs/m1-046-diagonal/M1Offdiag046.lean +270 -0
  119. package/proofs/m1-046-diagonal/Obligations045/M0Limit.lean +134 -0
  120. package/proofs/m1-046-diagonal/Obligations045/M0Offdiag.lean +171 -0
  121. package/proofs/m1-046-diagonal/lake-manifest.json +116 -0
  122. package/proofs/m1-046-diagonal/lakefile.toml +35 -0
  123. package/proofs/m1-046-diagonal/lean-toolchain +1 -0
  124. package/proofs/m1-046-offdiag/M0Bridge.lean +300 -0
  125. package/proofs/m1-046-offdiag/M0Diagonal046.lean +235 -0
  126. package/proofs/m1-046-offdiag/M0Moments046.lean +295 -0
  127. package/proofs/m1-046-offdiag/M1Bridge046.lean +359 -0
  128. package/proofs/m1-046-offdiag/M1Offdiag046.lean +270 -0
  129. package/proofs/m1-046-offdiag/Obligations045/M0Limit.lean +134 -0
  130. package/proofs/m1-046-offdiag/Obligations045/M0Offdiag.lean +171 -0
  131. package/proofs/m1-046-offdiag/lake-manifest.json +116 -0
  132. package/proofs/m1-046-offdiag/lakefile.toml +32 -0
  133. package/proofs/m1-046-offdiag/lean-toolchain +1 -0
  134. package/proofs/projection-chain.md +11 -0
  135. package/protocols/model-collapse-1a.json +108 -0
  136. package/receipts.bound +684 -208
  137. package/samples/laws/definitions/no/sample.json +26 -0
  138. package/samples/laws/definitions/yes/sample.json +12 -0
  139. package/samples/laws/experiment1a/no/sample.json +16 -0
  140. package/samples/laws/experiment1a/yes/sample.json +8 -0
  141. package/samples/laws/m0-allocation/no/sample.json +5 -0
  142. package/samples/laws/m0-allocation/yes/sample.json +7 -0
  143. package/samples/laws/m0-binomial-bridge/no/pairwise-is-not-joint.json +59 -0
  144. package/samples/laws/m0-binomial-bridge/no/sample.json +13 -0
  145. package/samples/laws/m0-binomial-bridge/yes/sample.json +16 -0
  146. package/samples/laws/m0-binomial-bridge/yes/small-binomial-table.json +100 -0
  147. package/samples/laws/m0-diagonal-conditional/no/sample.json +5 -0
  148. package/samples/laws/m0-diagonal-conditional/yes/sample.json +7 -0
  149. package/samples/laws/m0-finite-grid/no/sample.json +5 -0
  150. package/samples/laws/m0-finite-grid/yes/sample.json +7 -0
  151. package/samples/laws/m0-keff-interval/no/sample.json +215 -0
  152. package/samples/laws/m0-keff-interval/yes/api-rows.json +2002 -0
  153. package/samples/laws/m0-keff-interval/yes/sample.json +70 -0
  154. package/samples/laws/m0-limit-diag/no/sample.json +5 -0
  155. package/samples/laws/m0-limit-diag/yes/sample.json +7 -0
  156. package/samples/laws/m0-limit-offdiag/no/sample.json +5 -0
  157. package/samples/laws/m0-limit-offdiag/yes/sample.json +7 -0
  158. package/samples/laws/m0-moment-identification/no/sample.json +47 -0
  159. package/samples/laws/m0-moment-identification/yes/sample.json +97 -0
  160. package/samples/laws/m0-pair-coincidence/no/sample.json +5 -0
  161. package/samples/laws/m0-pair-coincidence/yes/sample.json +7 -0
  162. package/samples/laws/m1-diagonal-regions/no/sample.json +44 -0
  163. package/samples/laws/m1-diagonal-regions/yes/sample.json +45 -0
  164. package/samples/laws/m1-generator-binomial/no/sample.json +21 -0
  165. package/samples/laws/m1-generator-binomial/yes/sample.json +290 -0
  166. package/samples/laws/m1-offdiag-limit/no/sample.json +17 -0
  167. package/samples/laws/m1-offdiag-limit/yes/sample.json +87 -0
  168. package/samples/laws/projection-chain/no/sample.json +26 -0
  169. package/samples/laws/projection-chain/yes/sample.json +25 -0
  170. package/samples/no/installed-artifact.json +2 -2
  171. package/samples/yes/installed-artifact.json +2 -2
  172. package/src/laws/laws.bound +146 -0
  173. package/vectors/laws/a7-t90.json +72 -0
  174. package/vectors/laws/a9-t99.json +110 -0
  175. package/vectors/laws/definitions.native-capture.json +326 -0
  176. package/vectors/laws/definitions.native.json +82 -0
  177. package/vectors/laws/experiment1a-protocol.native-capture.json +391 -0
  178. package/vectors/laws/experiment1a-protocol.native.json +64 -0
  179. package/vectors/laws/experiment1a-public-input.native-capture.json +224 -0
  180. package/vectors/laws/m0-allocation.lean.json +150 -0
  181. package/vectors/laws/m0-allocation.native.json +104 -0
  182. package/vectors/laws/m0-binomial-bridge.lean.json +185 -0
  183. package/vectors/laws/m0-diagonal-lindeberg.lean.json +167 -0
  184. package/vectors/laws/m0-diagonal-moments.lean.json +185 -0
  185. package/vectors/laws/m0-diagonal-symmetric.lean.json +188 -0
  186. package/vectors/laws/m0-diagonal-threshold.lean.json +199 -0
  187. package/vectors/laws/m0-finite-grid.lean.json +144 -0
  188. package/vectors/laws/m0-finite-grid.native.json +104 -0
  189. package/vectors/laws/m0-identification.lean.json +136 -0
  190. package/vectors/laws/m0-identification.native-capture.json +230 -0
  191. package/vectors/laws/m0-keff-interval.json +569 -0
  192. package/vectors/laws/m0-limit-diag.lean.json +141 -0
  193. package/vectors/laws/m0-limit-diag.native.json +108 -0
  194. package/vectors/laws/m0-limit-offdiag.lean.json +143 -0
  195. package/vectors/laws/m0-limit-offdiag.native.json +104 -0
  196. package/vectors/laws/m0-pair-coincidence.lean.json +139 -0
  197. package/vectors/laws/m0-pair-coincidence.native.json +104 -0
  198. package/vectors/laws/m0-uncertainty-blocks.lean.json +201 -0
  199. package/vectors/laws/m0-uncertainty-finite-discord.lean.json +194 -0
  200. package/vectors/laws/m0-uncertainty-interval.lean.json +189 -0
  201. package/vectors/laws/m0-uncertainty.native-capture.json +651 -0
  202. package/vectors/laws/m1-diagonal-partial.lean.json +192 -0
  203. package/vectors/laws/m1-diagonal-partial.native-capture.json +275 -0
  204. package/vectors/laws/m1-generator-binomial.lean.json +162 -0
  205. package/vectors/laws/m1-generator-binomial.native-capture.json +245 -0
  206. package/vectors/laws/m1-offdiag-limit.lean.json +166 -0
  207. package/vectors/laws/m1-offdiag-limit.native-capture.json +260 -0
  208. package/vectors/laws/model-collapse-1a.json +12 -0
  209. package/vectors/laws/projection-chain.json +61 -0
  210. package/vectors/laws/projection-chain.native-capture.json +311 -0
  211. package/vectors/laws/projection-chain.native.json +56 -0
  212. package/vectors/measures/installed-artifact.cli.json +6 -6
@@ -0,0 +1,278 @@
1
+ import M0Lindeberg046
2
+ open scoped BigOperators
3
+ open Filter Topology MeasureTheory
4
+ noncomputable section
5
+ open Classical Obligations045.M0 Obligations046.Bridge Obligations046.Diagonal
6
+ namespace Obligations046.Threshold
7
+
8
+ /-- Threshold transfer, explicitly conditional on all fixed-cut distribution limits.
9
+ This is not a construction of a CLT or an M0 diagonal theorem. -/
10
+ theorem moving_cut_sandwich (C : ℕ → ℝ → ℝ) (F : ℝ → ℝ)
11
+ (t v : ℕ → ℝ) (hF : ContinuousAt F 0)
12
+ (hC : ∀ z, Tendsto (fun N => C N z) atTop (𝓝 (F z)))
13
+ (ht : Tendsto t atTop (𝓝 0))
14
+ (hl : ∀ᶠ N in atTop, ∀ z, z < t N → C N z ≤ v N)
15
+ (hu : ∀ᶠ N in atTop, ∀ z, t N < z → v N ≤ C N z) :
16
+ Tendsto v atTop (𝓝 (F 0)) := by
17
+ have hinv : Tendsto (fun j : ℕ => (1:ℝ)/((j:ℝ)+1)) atTop (𝓝 0) :=
18
+ tendsto_const_nhds.div_atTop (tendsto_atTop_mono
19
+ (fun j : ℕ => show (j:ℝ) ≤ (j:ℝ)+1 by linarith)
20
+ tendsto_natCast_atTop_atTop)
21
+ have hleft : Tendsto (fun j : ℕ => F (-((1:ℝ)/((j:ℝ)+1)))) atTop (𝓝 (F 0)) := by
22
+ exact hF.tendsto.comp (by simpa only [neg_zero] using hinv.neg)
23
+ have hright : Tendsto (fun j : ℕ => F ((1:ℝ)/((j:ℝ)+1))) atTop (𝓝 (F 0)) :=
24
+ hF.tendsto.comp hinv
25
+ apply tendsto_order.2
26
+ constructor
27
+ · intro b hb
28
+ obtain ⟨j,hj⟩ := (hleft.eventually (Ioi_mem_nhds hb)).exists
29
+ let δ : ℝ := (1:ℝ)/((j:ℝ)+1)
30
+ have hd : 0 < δ := by dsimp [δ]; positivity
31
+ have he := (hC (-δ)).eventually (Ioi_mem_nhds hj)
32
+ have hth := ht.eventually (Ioi_mem_nhds (show -δ < (0:ℝ) by linarith))
33
+ filter_upwards [he,hth,hl] with N hN htN hlN
34
+ exact lt_of_lt_of_le hN (hlN (-δ) htN)
35
+ · intro b hb
36
+ obtain ⟨j,hj⟩ := (hright.eventually (Iio_mem_nhds hb)).exists
37
+ let δ : ℝ := (1:ℝ)/((j:ℝ)+1)
38
+ have hd : 0 < δ := by dsimp [δ]; positivity
39
+ have he := (hC δ).eventually (Iio_mem_nhds hj)
40
+ have hth := ht.eventually (Iio_mem_nhds hd)
41
+ filter_upwards [he,hth,hu] with N hN htN huN
42
+ exact lt_of_le_of_lt (huN δ htN) hN
43
+
44
+ def sigma (M : Domain) (a : Fin M.K → Bool) (N : ℕ) : ℝ :=
45
+ Real.sqrt (Obligations046.Diagonal.variance M a N)
46
+ def threshold (M : Domain) (a : Fin M.K → Bool) (N : ℕ) : ℝ :=
47
+ ((N:ℝ)/2-mean M a N)/sigma M a N
48
+
49
+ theorem sigma_pos (M : Domain) (a : Fin M.K → Bool) (N : ℕ) (hN : 0<N) :
50
+ 0 < sigma M a N := by
51
+ apply Real.sqrt_pos.2
52
+ exact lt_of_lt_of_le (mul_pos (by exact_mod_cast hN) (variance_lower_pos M))
53
+ (finite_variance_lower M a N)
54
+
55
+ theorem threshold_limit (M : Domain) (a : Fin M.K → Bool)
56
+ (hdiag : score M a = (1:ℝ)/2) :
57
+ Tendsto (threshold M a) atTop (𝓝 0) := by
58
+ have h := Obligations046.Lindeberg.actual_mean_standardized_drift M a hdiag
59
+ apply (tendsto_zero_iff_norm_tendsto_zero).mpr
60
+ simpa only [threshold, sigma, Real.norm_eq_abs, abs_div,
61
+ abs_of_nonneg (Real.sqrt_nonneg _), abs_sub_comm,
62
+ Obligations046.Moments.model_mean, Obligations046.Moments.model_variance] using h
63
+
64
+ /-- This CDF uses the actual joint member law; the cut is in standard-deviation units. -/
65
+ def cdf (M : Domain) (a : Fin M.K → Bool) (N : ℕ) (z : ℝ) : ℝ :=
66
+ ∫ x, (if ((correctCount x:ℝ)-mean M a N)/sigma M a N ≤ z then (1:ℝ) else 0)
67
+ ∂(modelLaw M N a).toMeasure
68
+
69
+ theorem fair_loss_bounds (b N : ℕ) : 0 ≤ fairLoss b N ∧ fairLoss b N ≤ 1 := by
70
+ unfold fairLoss
71
+ split_ifs <;> norm_num
72
+
73
+ theorem lower_cut_pointwise (b N : ℕ) (μ σ z : ℝ) (hσ : 0<σ)
74
+ (hz : z < ((N:ℝ)/2-μ)/σ) :
75
+ (if ((b:ℝ)-μ)/σ ≤ z then (1:ℝ) else 0) ≤ fairLoss b N := by
76
+ split_ifs with hb
77
+ · have hreal : (b:ℝ)<(N:ℝ)/2 := by
78
+ have := (div_le_iff₀ hσ).mp hb
79
+ have := (lt_div_iff₀ hσ).mp hz
80
+ nlinarith
81
+ have hn : 2*b<N := by exact_mod_cast (show (2:ℝ)*(b:ℝ)<(N:ℝ) by linarith)
82
+ simp [fairLoss, hn]
83
+ · exact (fair_loss_bounds b N).1
84
+
85
+ theorem upper_cut_pointwise (b N : ℕ) (μ σ z : ℝ) (hσ : 0<σ)
86
+ (hz : ((N:ℝ)/2-μ)/σ < z) :
87
+ fairLoss b N ≤ (if ((b:ℝ)-μ)/σ ≤ z then (1:ℝ) else 0) := by
88
+ split_ifs with hb
89
+ · exact (fair_loss_bounds b N).2
90
+ · have hreal : (N:ℝ)/2 < (b:ℝ) := by
91
+ have := (div_lt_iff₀ hσ).mp hz
92
+ have := (lt_div_iff₀ hσ).mp (lt_of_not_ge hb)
93
+ nlinarith
94
+ have hn : N<2*b := by exact_mod_cast (show (N:ℝ)<(2:ℝ)*(b:ℝ) by linarith)
95
+ simp [fairLoss, not_lt.mpr hn.le, Ne.symm hn.ne]
96
+
97
+ theorem cdf_finite (M : Domain) (a : Fin M.K → Bool) (N : ℕ) (z : ℝ) :
98
+ cdf M a N z = ∑ x : World (sizes M N), jointMass (sizes M N)
99
+ (fun i => q M (a i)) x *
100
+ (if ((correctCount x:ℝ)-mean M a N)/sigma M a N ≤ z then (1:ℝ) else 0) := by
101
+ rw [cdf, modelLaw, memberLaw_expectation]
102
+
103
+ theorem error_finite (M : Domain) (a : Fin M.K → Bool) (N : ℕ) :
104
+ conditionalError M N a = ∑ x : World (sizes M N), jointMass (sizes M N)
105
+ (fun i => q M (a i)) x * fairLoss (correctCount x) N := by
106
+ rw [← conditional_error_representation, modelLaw, memberLaw_expectation]
107
+
108
+ theorem joint_nonneg (M : Domain) (a : Fin M.K → Bool) (N : ℕ) (x : World (sizes M N)) :
109
+ 0 ≤ jointMass (sizes M N) (fun i => q M (a i)) x :=
110
+ Finset.prod_nonneg (fun i _ => mass_nonneg _ (q_pos M (a i)).le (q_lt_one M (a i)).le _)
111
+
112
+ theorem lower_cut (M : Domain) (a : Fin M.K → Bool) (N : ℕ) (hN : 0<N)
113
+ (z : ℝ) (hz : z < threshold M a N) : cdf M a N z ≤ conditionalError M N a := by
114
+ rw [cdf_finite, error_finite]
115
+ apply Finset.sum_le_sum
116
+ intro x _
117
+ exact mul_le_mul_of_nonneg_left
118
+ (lower_cut_pointwise _ _ _ _ _ (sigma_pos M a N hN) hz) (joint_nonneg M a N x)
119
+
120
+ theorem upper_cut (M : Domain) (a : Fin M.K → Bool) (N : ℕ) (hN : 0<N)
121
+ (z : ℝ) (hz : threshold M a N < z) : conditionalError M N a ≤ cdf M a N z := by
122
+ rw [cdf_finite, error_finite]
123
+ apply Finset.sum_le_sum
124
+ intro x _
125
+ exact mul_le_mul_of_nonneg_left
126
+ (upper_cut_pointwise _ _ _ _ _ (sigma_pos M a N hN) hz) (joint_nonneg M a N x)
127
+
128
+ /-- Actual finite M0 law, actual majority with fair ties, unchanged quota rule.
129
+ The fixed-cut limit hCLT remains an explicit unpaid hypothesis, not a law claim. -/
130
+ theorem diagonal_transfer_of_fixed_cut_limits (M : Domain) (a : Fin M.K → Bool)
131
+ (hdiag : score M a = (1:ℝ)/2) (F : ℝ → ℝ) (hF : ContinuousAt F 0)
132
+ (hCLT : ∀ z, Tendsto (fun N => cdf M a N z) atTop (𝓝 (F z))) :
133
+ Tendsto (fun N => conditionalError M N a) atTop (𝓝 (F 0)) := by
134
+ apply moving_cut_sandwich (cdf M a) F (threshold M a)
135
+ (fun N => conditionalError M N a) hF hCLT (threshold_limit M a hdiag)
136
+ · filter_upwards [eventually_ge_atTop 1] with N hN
137
+ exact lower_cut M a N (by omega)
138
+ · filter_upwards [eventually_ge_atTop 1] with N hN
139
+ exact upper_cut M a N (by omega)
140
+
141
+ def strictCdf (M : Domain) (a : Fin M.K → Bool) (N : ℕ) (z : ℝ) : ℝ :=
142
+ ∑ x : World (sizes M N), jointMass (sizes M N) (fun i => q M (a i)) x *
143
+ (if ((correctCount x:ℝ)-mean M a N)/sigma M a N < z then (1:ℝ) else 0)
144
+
145
+ theorem cdf_mono (M : Domain) (a : Fin M.K → Bool) (N : ℕ) :
146
+ Monotone (cdf M a N) := by
147
+ intro z y hzy
148
+ rw [cdf_finite, cdf_finite]
149
+ apply Finset.sum_le_sum
150
+ intro x _
151
+ apply mul_le_mul_of_nonneg_left _ (joint_nonneg M a N x)
152
+ split_ifs <;> norm_num
153
+ linarith
154
+
155
+ theorem strict_lower_cut (M : Domain) (a : Fin M.K → Bool) (N : ℕ)
156
+ (z t : ℝ) (hzt : z<t) : cdf M a N z ≤ strictCdf M a N t := by
157
+ rw [cdf_finite, strictCdf]
158
+ apply Finset.sum_le_sum
159
+ intro x _
160
+ apply mul_le_mul_of_nonneg_left _ (joint_nonneg M a N x)
161
+ split_ifs <;> norm_num
162
+ linarith
163
+
164
+ theorem strict_upper_cut (M : Domain) (a : Fin M.K → Bool) (N : ℕ)
165
+ (t z : ℝ) (htz : t<z) : strictCdf M a N t ≤ cdf M a N z := by
166
+ rw [cdf_finite, strictCdf]
167
+ apply Finset.sum_le_sum
168
+ intro x _
169
+ apply mul_le_mul_of_nonneg_left _ (joint_nonneg M a N x)
170
+ split_ifs <;> norm_num
171
+ linarith
172
+
173
+ /-- Both versions at the moving threshold have the same limit, only IF fixed-cut
174
+ convergence to a continuous distribution is supplied. No atomless-limit axiom. -/
175
+ theorem threshold_cdf_limits_of_fixed_cut_limits (M : Domain) (a : Fin M.K → Bool)
176
+ (hdiag : score M a = (1:ℝ)/2) (F : ℝ → ℝ) (hF : ContinuousAt F 0)
177
+ (hCLT : ∀ z, Tendsto (fun N => cdf M a N z) atTop (𝓝 (F z))) :
178
+ Tendsto (fun N => cdf M a N (threshold M a N)) atTop (𝓝 (F 0)) ∧
179
+ Tendsto (fun N => strictCdf M a N (threshold M a N)) atTop (𝓝 (F 0)) := by
180
+ constructor
181
+ · apply moving_cut_sandwich (cdf M a) F (threshold M a)
182
+ (fun N => cdf M a N (threshold M a N)) hF hCLT (threshold_limit M a hdiag)
183
+ · filter_upwards [] with N
184
+ intro z hz
185
+ exact cdf_mono M a N hz.le
186
+ · filter_upwards [] with N
187
+ intro z hz
188
+ exact cdf_mono M a N hz.le
189
+ · apply moving_cut_sandwich (cdf M a) F (threshold M a)
190
+ (fun N => strictCdf M a N (threshold M a N)) hF hCLT (threshold_limit M a hdiag)
191
+ · filter_upwards [] with N
192
+ exact fun z hz => strict_lower_cut M a N z _ hz
193
+ · filter_upwards [] with N
194
+ exact fun z hz => strict_upper_cut M a N _ z hz
195
+
196
+ def tieMass (M : Domain) (a : Fin M.K → Bool) (N : ℕ) : ℝ :=
197
+ ∑ x : World (sizes M N), jointMass (sizes M N) (fun i => q M (a i)) x *
198
+ (if 2*correctCount x=N then (1:ℝ) else 0)
199
+
200
+ theorem standardized_eq_threshold (b N : ℕ) (μ σ : ℝ) (hσ : 0<σ) :
201
+ ((b:ℝ)-μ)/σ = ((N:ℝ)/2-μ)/σ ↔ 2*b=N := by
202
+ constructor
203
+ · intro h
204
+ have hm := congrArg (fun y : ℝ => y*σ) h
205
+ simp only [div_mul_cancel₀ _ hσ.ne'] at hm
206
+ exact_mod_cast (show (2:ℝ)*(b:ℝ)=(N:ℝ) by linarith)
207
+ · intro h
208
+ have hn : (2:ℝ)*(b:ℝ)=(N:ℝ) := by exact_mod_cast h
209
+ congr 1
210
+ linarith
211
+
212
+ theorem weak_strict_indicator_difference (r t : ℝ) :
213
+ (if r≤t then (1:ℝ) else 0) - (if r<t then (1:ℝ) else 0) =
214
+ if r=t then (1:ℝ) else 0 := by
215
+ rcases lt_trichotomy r t with h | h | h
216
+ · simp [h, h.le, h.ne]
217
+ · subst t; simp
218
+ · simp [not_le.mpr h, not_lt.mpr h.le, Ne.symm h.ne]
219
+
220
+ theorem tie_mass_difference (M : Domain) (a : Fin M.K → Bool) (N : ℕ) (hN : 0<N) :
221
+ tieMass M a N = cdf M a N (threshold M a N) -
222
+ strictCdf M a N (threshold M a N) := by
223
+ rw [cdf_finite, strictCdf, ← Finset.sum_sub_distrib]
224
+ unfold tieMass
225
+ apply Finset.sum_congr rfl
226
+ intro x _
227
+ rw [← mul_sub, weak_strict_indicator_difference]
228
+ simp only [show (((correctCount x:ℝ)-mean M a N)/sigma M a N = threshold M a N) ↔
229
+ 2*correctCount x=N from
230
+ standardized_eq_threshold _ _ _ _ (sigma_pos M a N hN)]
231
+
232
+ /-- The tie atom vanishes as a CONSEQUENCE of the explicit fixed-cut CLT hypothesis. -/
233
+ theorem tie_limit_of_fixed_cut_limits (M : Domain) (a : Fin M.K → Bool)
234
+ (hdiag : score M a = (1:ℝ)/2) (F : ℝ → ℝ) (hF : ContinuousAt F 0)
235
+ (hCLT : ∀ z, Tendsto (fun N => cdf M a N z) atTop (𝓝 (F z))) :
236
+ Tendsto (tieMass M a) atTop (𝓝 0) := by
237
+ have h := threshold_cdf_limits_of_fixed_cut_limits M a hdiag F hF hCLT
238
+ have hd := h.1.sub h.2
239
+ have he : (fun N => tieMass M a N) =ᶠ[atTop]
240
+ (fun N => cdf M a N (threshold M a N)-strictCdf M a N (threshold M a N)) := by
241
+ filter_upwards [eventually_ge_atTop 1] with N hN
242
+ exact tie_mass_difference M a N (by omega)
243
+ simpa only [sub_self] using hd.congr' he.symm
244
+
245
+ /-- The final value 1/2 requires F(0)=1/2 in addition to continuity and the unpaid CLT. -/
246
+ theorem floor_limit_diag_of_fixed_cut_limits (M : Domain) (a : Fin M.K → Bool)
247
+ (hdiag : score M a = (1:ℝ)/2) (F : ℝ → ℝ) (hF : ContinuousAt F 0)
248
+ (hF0 : F 0 = (1:ℝ)/2)
249
+ (hCLT : ∀ z, Tendsto (fun N => cdf M a N z) atTop (𝓝 (F z))) :
250
+ Tendsto (fun N => conditionalError M N a) atTop (𝓝 ((1:ℝ)/2)) := by
251
+ simpa only [hF0] using diagonal_transfer_of_fixed_cut_limits M a hdiag F hF hCLT
252
+
253
+ /-- A scalar regression outside the independent M0 law: LLN convergence alone does
254
+ not determine a discontinuous majority limit at the diagonal. -/
255
+ def above (N : ℕ) : ℝ := (1:ℝ)/2 + 1/((N:ℝ)+1)
256
+
257
+ theorem above_limit : Tendsto above atTop (𝓝 ((1:ℝ)/2)) := by
258
+ have hinv : Tendsto (fun N : ℕ => (1:ℝ)/((N:ℝ)+1)) atTop (𝓝 0) :=
259
+ tendsto_const_nhds.div_atTop (tendsto_atTop_mono
260
+ (fun N : ℕ => show (N:ℝ) ≤ (N:ℝ)+1 by linarith)
261
+ tendsto_natCast_atTop_atTop)
262
+ simpa only [above, add_zero] using tendsto_const_nhds.add hinv
263
+
264
+ theorem above_loss_zero (N : ℕ) : limitingLoss (above N) = 0 := by
265
+ have hp : 0 < (1:ℝ)/((N:ℝ)+1) := by positivity
266
+ have hg : (1:ℝ)/2 < above N := by dsimp [above]; linarith
267
+ simp only [limitingLoss, if_neg (not_lt.mpr hg.le), if_neg (Ne.symm hg.ne)]
268
+
269
+ theorem lgn_alone_does_not_give_half :
270
+ ¬ Tendsto (fun N => limitingLoss (above N)) atTop (𝓝 ((1:ℝ)/2)) := by
271
+ intro h
272
+ have hz : Tendsto (fun N => limitingLoss (above N)) atTop (𝓝 0) := by
273
+ simpa only [above_loss_zero] using
274
+ (tendsto_const_nhds : Tendsto (fun _ : ℕ => (0:ℝ)) atTop (𝓝 0))
275
+ have hbad := tendsto_nhds_unique hz h
276
+ norm_num at hbad
277
+
278
+ end Obligations046.Threshold
@@ -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