Lean sources / Tests / Regression.lean
Regression guards for the universal density expressions
1/-2Copyright (c) 2026 Asvin G, Claude (Anthropic), GPT-6-Astra (OpenAI). All rights reserved.3Released under Apache 2.0 license as described in the file LICENSE.4Authors: Asvin G, Claude (Anthropic), GPT-6-Astra (OpenAI)5-/6import SurfaceBlowup.Main7import Tests.NonVacuity8 9/-!10# Regression guards for the universal density expressions11 12Pins the statement-level definitions of `SurfaceBlowup.Basic` (the recursion `stateLaw`, the global13laws and the universal expressions `monicExpr n σ`, `projectiveExpr n σ`) to independently known14numbers, and turns them, via `SurfaceBlowup.main_dvr`, into explicit density statements. Any change15to the definitions that alters these values breaks this file.16 17## Main results18 19* `SurfaceBlowup.Tests.monicExpr_two_eval`, `SurfaceBlowup.Tests.projectiveExpr_two_eval`: the20 quadratic expressions as rational functions of `q > 1`.21* `SurfaceBlowup.Tests.monicExpr_three_eval`: the cubic monic expressions for `q > 1`.22* `SurfaceBlowup.Tests.monicExpr_four_eval_two`, `SurfaceBlowup.Tests.projectiveExpr_four_eval_two`:23 all quartic values at `q = 2`.24* Point values, e.g. `SurfaceBlowup.Tests.monicExpr_three_totally_ramified_eval_three`25 (`10/121`), `SurfaceBlowup.Tests.monicExpr_four_totally_ramified_eval_two` (`107/1533`),26 `SurfaceBlowup.Tests.projectiveExpr_four_totally_ramified_eval_two` (`856/15841`).27* Density corollaries, e.g. `SurfaceBlowup.Tests.monicDensity_two_ramified` (`1/(q+1)` over every28 complete DVR with residue field of order `q`),29 `SurfaceBlowup.Tests.monicDensity_four_totally_ramified_of_card_eq_two`, and the end-to-end30 `SurfaceBlowup.Tests.monicDensity_powerSeries_zmod_two_four_totally_ramified` over `𝔽₂⟦X⟧`.31 32## Implementation notes33 34The expressions are not computable by brute force (`allowedPatterns` filters a Fintype of size35about `5^19` with classical decidability), so the values are computed by unfolding the recursion36state by state: the coefficient algebra of laws, a one-step unfolding of `stateLaw` (re-derived37here: fuel stability and the rank decrease of children), explicit enumerations of the allowed38tangent and residue patterns (children lists are computed by `decide` through an explicit39enumeration of the cells), and the laws of the small states `S(a;1)`, `S(a;2)`, `T(a,b;1,h)`,40`T(a,b;c,1)`, `T(1,1;2,2)`, `S(1;3)` and (at `q = 2`) `S(1;4)`. Final identities are checked as41linear combinations of type indicators. All of this is private and depends only on42`SurfaceBlowup.Basic` (plus `main_dvr` for the corollaries).43 44Provenance: port of the certified Prove2Me theorems `SurfaceBlowupV2.{quadratic_monic_formula,45quadratic_projective_formula, cubic_monic_formula, quartic_monic_law_at_two,46quartic_projective_law_at_two}` and their point-value corollaries, with their helper closure.47-/48 49set_option autoImplicit false50 51open scoped BigOperators ENNReal52 53namespace SurfaceBlowup.Tests54 55/-- `coeffAt q L σ` is the value at `q` of the coefficient of the type `σ` in the law `L`. -/56local notation "coeffAt " q:max L:max σ:max => Expr.eval q (lawCoeff L σ)57 58/-- Sorts the types `K` of the indicators `indicator σ K` into a canonical form. -/59local macro "sort_types" : tactic => `(tactic| simp only [Multiset.insert_eq_cons,60 Multiset.singleton_add, Multiset.cons_add, zero_add, ← Multiset.cons_zero, Multiset.cons_swap])61 62-- `hygiene false`: the macro names private lemmas of this file declared further below.63set_option hygiene false in64/-- Evaluates coefficients of products of laws of children, terminal ones first. -/65local macro "simp_children" : tactic => `(tactic| simp only [childProd, List.map_cons,66 List.map_nil, stateLaw_terminal, lawDescend_lawAtom, lawProd_cons, lawProd_nil, coeff_mul_lawOne,67 coeff_descend_one, coeff_mul_atom, coeff_lawAtom, coeff_lawOne, ite_mem_erase, ite_add_zero,68 Multiset.cons_zero])69 70/-! ### Evaluating expressions -/71 72section Eval73 74private theorem eval_sum (q : ℚ) (xs : List Expr) :75 (Expr.sum xs).eval q = (xs.map (Expr.eval q)).sum := by76 induction xs with77 | nil => rfl78 | cons x xs ih => rw [Expr.sum, List.foldr_cons, Expr.eval, ← Expr.sum, ih]; rfl79 80private theorem eval_prod (q : ℚ) (xs : List Expr) :81 (Expr.prod xs).eval q = (xs.map (Expr.eval q)).prod := by82 induction xs with83 | nil => rfl84 | cons x xs ih => rw [Expr.prod, List.foldr_cons, Expr.eval, ← Expr.prod, ih]; rfl85 86private theorem eval_pow (q : ℚ) (x : Expr) (n : ℕ) : (x.pow n).eval q = x.eval q ^ n := by87 induction n with88 | zero => simp [Expr.pow, Expr.eval]89 | succ n ih => rw [Expr.pow, Expr.eval, ih, pow_succ]90 91private theorem eval_subst (q : ℚ) (x y : Expr) : (x.subst y).eval q = x.eval (y.eval q) := by92 induction x with93 | const r => rfl94 | var => rfl95 | add x z hx hz => simp only [Expr.subst, Expr.eval, hx, hz]96 | mul x z hx hz => simp only [Expr.subst, Expr.eval, hx, hz]97 | inv x hx => simp only [Expr.subst, Expr.eval, hx]98 99private theorem pointCount_eval (q : ℚ) (n : ℕ) : (pointCount n).eval q =100 1 / n * ∑ j ∈ n.divisors, ((ArithmeticFunction.moebius j : ℤ) : ℚ) * q ^ (n / j) := by101 simp only [pointCount, Expr.eval, eval_sum, List.map_map]102 rw [Finset.sum_map_toList]103 simp [Function.comp_def, Expr.eval, eval_pow]104 105private theorem pointCount_two (q : ℚ) : (pointCount 2).eval q = (q ^ 2 - q) / 2 := by106 rw [pointCount_eval, show Nat.divisors 2 = {1, 2} by decide]107 simp [ArithmeticFunction.moebius_apply_prime Nat.prime_two]108 ring109 110private theorem pointCount_three (q : ℚ) : (pointCount 3).eval q = (q ^ 3 - q) / 3 := by111 rw [pointCount_eval, show Nat.divisors 3 = {1, 3} by decide]112 simp [ArithmeticFunction.moebius_apply_prime Nat.prime_three]113 ring114 115private theorem pointCount_four (q : ℚ) : (pointCount 4).eval q = (q ^ 4 - q ^ 2) / 4 := by116 have h4 : ArithmeticFunction.moebius 4 = 0 :=117 ArithmeticFunction.moebius_apply_prime_pow Nat.prime_two (k := 2) (by norm_num)118 rw [pointCount_eval, show Nat.divisors 4 = {1, 2, 4} by decide]119 simp [ArithmeticFunction.moebius_apply_prime Nat.prime_two, h4]120 ring121 122end Eval123 124/-! ### Coefficients of laws -/125 126section Coefficients127 128private theorem coeff_nil (q : ℚ) (σ : FactorType) : coeffAt q [] σ = 0 := rfl129 130private theorem coeff_cons (q : ℚ) (z : FactorType × Expr) (L : Law) (σ : FactorType) :131 coeffAt q (z :: L) σ = (if z.1 = σ then z.2.eval q else 0) + coeffAt q L σ := by132 simp only [lawCoeff, List.map_cons, Expr.sum, List.foldr_cons, Expr.eval]133 split_ifs <;> rfl134 135private theorem coeff_append (q : ℚ) (L M : Law) (σ : FactorType) :136 coeffAt q (L ++ M) σ = coeffAt q L σ + coeffAt q M σ := by137 induction L with138 | nil => simp [coeff_nil]139 | cons z L ih => rw [List.cons_append, coeff_cons, coeff_cons, ih, add_assoc]140 141private theorem coeff_flatMap {α : Type} (q : ℚ) (l : List α) (f : α → Law) (σ : FactorType) :142 coeffAt q (l.flatMap f) σ = (l.map fun x ↦ coeffAt q (f x) σ).sum := by143 induction l with144 | nil => rfl145 | cons x l ih => rw [List.flatMap_cons, coeff_append, ih, List.map_cons, List.sum_cons]146 147private theorem coeff_scale (q : ℚ) (x : Expr) (L : Law) (σ : FactorType) :148 coeffAt q (lawScale x L) σ = x.eval q * coeffAt q L σ := by149 induction L with150 | nil => simp [coeff_nil, lawScale]151 | cons z L ih =>152 simp only [lawScale, List.map_cons] at *153 rw [coeff_cons, coeff_cons, ih]; simp only [Expr.eval]; split_ifs <;> ring154 155private theorem coeff_lawOne (q : ℚ) (σ : FactorType) :156 coeffAt q lawOne σ = if σ = 0 then 1 else 0 := by157 simp only [lawOne, coeff_cons, coeff_nil, Expr.eval, add_zero, eq_comm]158 159private theorem coeff_prod_singleton (q : ℚ) (L : Law) (σ : FactorType) :160 coeffAt q (lawProd [L]) σ = coeffAt q L σ := by161 induction L with162 | nil => rfl163 | cons z L ih =>164 simp only [lawProd, List.foldr_cons, List.foldr_nil, lawMul, lawOne, List.flatMap_cons,165 List.map_cons, List.map_nil] at *166 rw [List.singleton_append, coeff_cons, coeff_cons, ih]; simp [Expr.eval]167 168private theorem lawProd_cons (L : Law) (Ls : List Law) :169 lawProd (L :: Ls) = lawMul L (lawProd Ls) := rfl170 171private theorem scaleType_injective {δ : ℕ} (hδ : 0 < δ) : Function.Injective (scaleType δ) :=172 Multiset.map_injective fun _ _ h ↦173 Prod.ext (Prod.mk.inj h).1 (Nat.eq_of_mul_eq_mul_left hδ (Prod.mk.inj h).2)174 175private theorem coeff_descend_scaleType (q : ℚ) {δ : ℕ} (hδ : 0 < δ) (L : Law) (τ : FactorType) :176 coeffAt q (lawDescend δ L) (scaleType δ τ) = coeffAt (q ^ δ) L τ := by177 induction L with178 | nil => rfl179 | cons z L ih =>180 simp only [lawDescend, List.map_cons] at *181 rw [coeff_cons, coeff_cons, ih]182 simp only [(scaleType_injective hδ).eq_iff, eval_subst, eval_pow]183 rfl184 185private theorem coeff_descend_of_ne (q : ℚ) (δ : ℕ) (L : Law) (σ : FactorType)186 (h : ∀ τ, σ ≠ scaleType δ τ) : coeffAt q (lawDescend δ L) σ = 0 := by187 induction L with188 | nil => rfl189 | cons z L ih =>190 simp only [lawDescend, List.map_cons] at *191 rw [coeff_cons, ih, if_neg fun e ↦ h _ e.symm, zero_add]192 193private theorem coeff_descend_one (q : ℚ) (L : Law) (σ : FactorType) :194 coeffAt q (lawDescend 1 L) σ = coeffAt q L σ := by195 simpa [scaleType] using coeff_descend_scaleType q one_pos L σ196 197private theorem lawDescend_lawAtom (δ a : ℕ) : lawDescend δ (lawAtom a 1) = lawAtom a δ := by198 simp [lawDescend, lawAtom, scaleType, Expr.subst]199 200private theorem lawProd_nil : lawProd [] = lawOne := rfl201 202private theorem coeff_mul_lawOne (q : ℚ) (L : Law) (σ : FactorType) :203 coeffAt q (lawMul L lawOne) σ = coeffAt q L σ :=204 coeff_prod_singleton q L σ205 206private theorem coeff_lawAtom (q : ℚ) (e f : ℕ) (σ : FactorType) :207 coeffAt q (lawAtom e f) σ = if σ = {(e, f)} then 1 else 0 := by208 simp [lawAtom, coeff_cons, coeff_nil, Expr.eval, eq_comm]209 210private theorem coeff_mul_atom (q : ℚ) (e f : ℕ) (M : Law) (σ : FactorType) :211 coeffAt q (lawMul (lawAtom e f) M) σ =212 if (e, f) ∈ σ then coeffAt q M (σ.erase (e, f)) else 0 := by213 have key : ∀ t : FactorType, {(e, f)} + t = σ ↔ (e, f) ∈ σ ∧ σ.erase (e, f) = t := fun t ↦214 ⟨by rintro rfl; simp [Multiset.singleton_add],215 by rintro ⟨h, rfl⟩; rw [Multiset.singleton_add, Multiset.cons_erase h]⟩216 simp only [lawAtom, lawMul, List.flatMap_cons, List.flatMap_nil, List.append_nil]217 induction M with218 | nil => simp [coeff_nil]219 | cons w M ih =>220 rw [List.map_cons, coeff_cons, ih, coeff_cons]221 simp only [key, Expr.eval, one_mul]222 by_cases h : (e, f) ∈ σ <;> simp [h, eq_comm]223 224private theorem coeff_eq_zero_of_not_mem (q : ℚ) (L : Law) (τ : FactorType)225 (h : τ ∉ (L.map Prod.fst).toFinset) : coeffAt q L τ = 0 := by226 induction L with227 | nil => rfl228 | cons z L ih =>229 simp only [List.map_cons, List.toFinset_cons, Finset.mem_insert, not_or] at h230 rw [coeff_cons, ih h.2, if_neg (Ne.symm h.1), add_zero]231 232private theorem coeff_map_add (q : ℚ) (z : FactorType × Expr) (M : Law) (σ : FactorType) :233 coeffAt q (M.map fun w ↦ (z.1 + w.1, Expr.mul z.2 w.2)) σ =234 if z.1 ≤ σ then z.2.eval q * coeffAt q M (σ - z.1) else 0 := by235 induction M with236 | nil => simp [coeff_nil]237 | cons w M ih =>238 rw [List.map_cons, coeff_cons, coeff_cons, ih]239 by_cases h : z.1 ≤ σ240 · have e : z.1 + w.1 = σ ↔ w.1 = σ - z.1 :=241 ⟨fun e ↦ by rw [← e, add_tsub_cancel_left], fun e ↦ by rw [e, add_tsub_cancel_of_le h]⟩242 simp only [e, if_pos h, Expr.eval]; split_ifs <;> ring243 · have e : ¬ z.1 + w.1 = σ := fun e ↦ h (e ▸ le_self_add)244 simp [h, e]245 246private theorem coeff_mul_of_mem (q : ℚ) (L M : Law) (σ : FactorType) (S : Finset FactorType)247 (hS : ∀ z ∈ L, z.1 ∈ S) : coeffAt q (lawMul L M) σ =248 ∑ τ ∈ S, if τ ≤ σ then coeffAt q L τ * coeffAt q M (σ - τ) else 0 := by249 induction L with250 | nil => simp [lawMul, coeff_nil]251 | cons z L ih =>252 have e : lawMul (z :: L) M = (M.map fun w ↦ (z.1 + w.1, Expr.mul z.2 w.2)) ++ lawMul L M := by253 simp [lawMul]254 rw [e, coeff_append, coeff_map_add, ih fun y hy ↦ hS y (List.mem_cons_of_mem _ hy)]255 have : ∀ τ ∈ S, (if τ ≤ σ then coeffAt q (z :: L) τ * coeffAt q M (σ - τ) else 0) =256 (if z.1 = τ then (if τ ≤ σ then z.2.eval q * coeffAt q M (σ - τ) else 0) else 0) +257 (if τ ≤ σ then coeffAt q L τ * coeffAt q M (σ - τ) else 0) := by258 intro τ _; rw [coeff_cons]; split_ifs <;> ring259 rw [Finset.sum_congr rfl this, Finset.sum_add_distrib, Finset.sum_ite_eq,260 if_pos (hS z (by simp))]261 262/-- The coefficients of a product, summed over any finite set containing the support of the263first factor. -/264private theorem coeff_mul (q : ℚ) (L M : Law) (S : Finset FactorType)265 (hS : ∀ τ ∉ S, coeffAt q L τ = 0) (σ : FactorType) : coeffAt q (lawMul L M) σ =266 ∑ τ ∈ S, if τ ≤ σ then coeffAt q L τ * coeffAt q M (σ - τ) else 0 := by267 set T := (L.map Prod.fst).toFinset268 rw [coeff_mul_of_mem q L M σ T fun z hz ↦ List.mem_toFinset.2 (List.mem_map_of_mem hz)]269 rw [Finset.sum_subset (Finset.subset_union_left (s₂ := S)) fun τ _ hτ ↦ by270 simp [coeff_eq_zero_of_not_mem q L τ hτ],271 ← Finset.sum_subset (Finset.subset_union_right (s₁ := T)) fun τ _ hτ ↦ by simp [hS τ hτ]]272 273/-- The coefficient of `σ` in the law `M` with all types shifted by `τ`. -/274private noncomputable def shiftedCoeff (q : ℚ) (M : Law) (τ σ : FactorType) : ℚ :=275 (M.map fun w ↦ if τ + w.1 = σ then w.2.eval q else 0).sum276 277private theorem shiftedCoeff_mul (q : ℚ) (L M : Law) (τ σ : FactorType) :278 shiftedCoeff q (lawMul L M) τ σ =279 (L.map fun z ↦ z.2.eval q * shiftedCoeff q M (τ + z.1) σ).sum := by280 induction L with281 | nil => simp [shiftedCoeff, lawMul]282 | cons z L ih =>283 have : lawMul (z :: L) M = (M.map fun w ↦ (z.1 + w.1, Expr.mul z.2 w.2)) ++ lawMul L M := by284 simp [lawMul]285 rw [this]286 unfold shiftedCoeff at ih ⊢287 rw [List.map_append, List.sum_append, ih, List.map_cons, List.sum_cons, List.map_map,288 ← List.sum_map_mul_left]289 congr 2290 refine List.map_congr_left fun w _ ↦ ?_291 simp only [Function.comp, add_assoc]292 split_ifs <;> simp [Expr.eval]293 294private theorem list_sum_comm {α β : Type} (l : List α) (m : List β) (f : α → β → ℚ) :295 (l.map fun a ↦ (m.map fun b ↦ f a b).sum).sum =296 (m.map fun b ↦ (l.map fun a ↦ f a b).sum).sum := by297 induction l with298 | nil => simp299 | cons a l ih =>300 simp only [List.map_cons, List.sum_cons, ih]301 clear ih302 induction m with303 | nil => simp304 | cons b m ihm => simp only [List.map_cons, List.sum_cons]; rw [← ihm]; ring305 306private theorem shiftedCoeff_prod_perm (q : ℚ) {Ls Ls' : List Law} (hperm : Ls.Perm Ls') :307 ∀ τ σ, shiftedCoeff q (lawProd Ls) τ σ = shiftedCoeff q (lawProd Ls') τ σ := by308 induction hperm with309 | nil => intros; rfl310 | cons x _ ih =>311 intro τ σ312 simp only [lawProd_cons, shiftedCoeff_mul, ih]313 | swap x y l =>314 intro τ σ315 simp only [lawProd_cons, shiftedCoeff_mul, ← List.sum_map_mul_left]316 rw [list_sum_comm]317 refine congrArg _ (List.map_congr_left fun w _ ↦318 congrArg _ (List.map_congr_left fun z _ ↦ ?_))319 rw [add_right_comm τ w.1 z.1]320 ring321 | trans _ _ ih1 ih2 => intro τ σ; rw [ih1, ih2]322 323/-- Coefficients of products of laws do not depend on the order of the factors. -/324private theorem coeff_prod_perm {Ls Ls' : List Law} (hperm : Ls.Perm Ls') (q : ℚ)325 (σ : FactorType) : coeffAt q (lawProd Ls) σ = coeffAt q (lawProd Ls') σ := by326 have h : ∀ M : Law, coeffAt q M σ = shiftedCoeff q M 0 σ := fun M ↦ by327 unfold lawCoeff shiftedCoeff328 rw [eval_sum, List.map_map]329 exact congrArg _ (List.map_congr_left fun w _ ↦ by330 by_cases h : w.1 = σ <;> simp [h, Expr.eval])331 rw [h, h, shiftedCoeff_prod_perm q hperm]332 333/-- The indicator `[σ = K]`. -/334private def indicator (σ K : FactorType) : ℚ := if σ = K then 1 else 0335 336private theorem ite_eq_mul_indicator (σ K : FactorType) (c : ℚ) [Decidable (σ = K)] :337 (if σ = K then c else 0) = c * indicator σ K := by338 unfold indicator; split_ifs <;> simp339 340private theorem ite_mem_erase (p : ℕ × ℕ) (σ t : FactorType) (x : ℚ) :341 (if p ∈ σ then (if σ.erase p = t then x else 0) else 0) = if σ = p ::ₘ t then x else 0 := by342 by_cases h : p ∈ σ343 · rw [if_pos h]344 by_cases h2 : σ.erase p = t345 · rw [if_pos h2, if_pos]; rw [← h2, Multiset.cons_erase h]346 · rw [if_neg h2, if_neg]; rintro rfl; exact h2 (by simp)347 · rw [if_neg h, if_neg]; rintro rfl; exact h (by simp)348 349private theorem ite_add_zero (c : Prop) [Decidable c] (a b : ℚ) :350 (if c then a + b else 0) = (if c then a else 0) + (if c then b else 0) := by351 split_ifs <;> simp352 353private theorem ite_le_sub (t σ u : FactorType) (c d : ℚ) :354 (if t ≤ σ then c * (if σ - t = u then d else 0) else 0) = if σ = t + u then c * d else 0 := by355 by_cases h : σ = t + u356 · subst h; simp357 · rw [if_neg h]358 split_ifs with h1 h2359 · exact absurd (by rw [← h2, add_tsub_cancel_of_le h1]) h360 · simp361 · rfl362 363private theorem ite_le_sub_one (t σ u : FactorType) (d : ℚ) :364 (if t ≤ σ then (if σ - t = u then d else 0) else 0) = if σ = t + u then d else 0 := by365 simpa using ite_le_sub t σ u 1 d366 367end Coefficients368 369/-! ### Patterns -/370 371section Patterns372 373/-- The pattern with the single nonzero entry `v` at `ij₀`. -/374private def spat {n : ℕ} (ij₀ : Fin n × Fin n) (v : Fin (n + 1)) : Pattern n :=375 fun ij ↦ if ij = ij₀ then v else 0376 377private theorem spat_val {n : ℕ} (ij₀ : Fin n × Fin n) (v : Fin (n + 1)) (ij : Fin n × Fin n) :378 ((spat ij₀ v ij : Fin (n+1)) : ℕ) = if ij = ij₀ then (v : ℕ) else 0 := by379 unfold spat; split_ifs <;> simp380 381private theorem eq_spat {n : ℕ} (m : Pattern n) (ij₀ : Fin n × Fin n) (v : Fin (n + 1))382 (h₀ : (m ij₀).val = v.val) (h : ∀ ij, ij ≠ ij₀ → (m ij).val = 0) : m = spat ij₀ v := by383 funext ij; apply Fin.ext; rw [spat_val]384 split_ifs with hij385 · subst hij; exact h₀386 · exact h ij hij387 388private theorem flatMap_replicate_eq {α β : Type} (l : List α) (x₀ : α) (g : α → β) (f : α → ℕ)389 (hf : ∀ x, x ≠ x₀ → f x = 0) (hnd : l.Nodup) (hm : x₀ ∈ l) :390 l.flatMap (fun x ↦ List.replicate (f x) (g x)) = List.replicate (f x₀) (g x₀) := by391 induction l with392 | nil => simp at hm393 | cons y l ih =>394 rw [List.flatMap_cons]395 rw [List.nodup_cons] at hnd396 by_cases h : y = x₀397 · subst h398 rw [List.flatMap_eq_nil_iff.2]399 · simp400 · intro x hx; rw [hf x (fun e ↦ hnd.1 (e ▸ hx))]; rfl401 · rw [hf y h, ih hnd.2 ((List.mem_cons.1 hm).resolve_left (Ne.symm h))]; rfl402 403private theorem otherChildren_spat {n : ℕ} (a : ℕ) (ij₀ : Fin n × Fin n) (v : Fin (n + 1)) :404 otherChildren a (spat ij₀ v) = List.replicate v (ij₀.1.val+1, .single a (ij₀.2.val+1)) := by405 unfold otherChildren406 rw [flatMap_replicate_eq _ ij₀407 (fun ij : Fin n × Fin n ↦ (ij.1.val+1, State.single a (ij.2.val+1)))408 (fun ij ↦ (spat ij₀ v ij : ℕ)) (fun x hx ↦ by rw [spat_val, if_neg hx])409 (Finset.nodup_toList _) (Finset.mem_toList.2 (Finset.mem_univ _)), spat_val, if_pos rfl]410 411private theorem patternWeight_spat {n : ℕ} (ij₀ : Fin n × Fin n) (v : Fin (n + 1)) :412 patternWeight (spat ij₀ v) = (ij₀.1.val+1)*(ij₀.2.val+1)*v := by413 unfold patternWeight414 rw [Finset.sum_eq_single ij₀]415 · rw [spat_val, if_pos rfl]416 · intro ij _ h; rw [spat_val, if_neg h]; simp417 · simp418 419private theorem divisorCount_eval {n : ℕ} (q : ℚ) (off : ℤ) (m : Pattern n) :420 (divisorCount off m).eval q = ∏ i : Fin n,421 (falling (availablePoints off (i.val+1)) (∑ j, (m (i, j)).val)).eval q *422 (1 / ∏ j, ((m (i, j)).val.factorial : ℚ)) := by423 simp only [divisorCount, eval_prod, List.map_map, Finset.prod_map_toList]424 rfl425 426private theorem divisorCount_spat {n : ℕ} (q : ℚ) (off : ℤ) (ij₀ : Fin n × Fin n)427 (v : Fin (n + 1)) :428 (divisorCount off (spat ij₀ v)).eval q =429 (falling (availablePoints off (ij₀.1.val+1)) v).eval q / ((v : ℕ).factorial : ℚ) := by430 rw [divisorCount_eval, Finset.prod_eq_single ij₀.1 _ (by simp)]431 · have h1 : (∑ j, ((spat ij₀ v (ij₀.1, j)) : ℕ)) = v := by432 rw [Finset.sum_eq_single ij₀.2 (fun j _ hj ↦ by simp [spat_val, Prod.ext_iff, hj]) (by simp),433 spat_val, if_pos rfl]434 have h2 : (∏ j, (((spat ij₀ v (ij₀.1, j)) : ℕ).factorial : ℚ)) = ((v : ℕ).factorial : ℚ) := by435 rw [Finset.prod_eq_single ij₀.2 (fun j _ hj ↦ by simp [spat_val, Prod.ext_iff, hj])436 (by simp), spat_val, if_pos rfl]437 rw [h1, h2]; ring438 · intro i _ hi439 have h1 : (∑ j, ((spat ij₀ v (i, j)) : ℕ)) = 0 :=440 Finset.sum_eq_zero fun j _ ↦ by simp [spat_val, Prod.ext_iff, hi]441 have h2 : (∏ j, (((spat ij₀ v (i, j)) : ℕ).factorial : ℚ)) = 1 :=442 Finset.prod_eq_one fun j _ ↦ by simp [spat_val, Prod.ext_iff, hi]443 simp [h1, h2, falling, Expr.prod, Expr.eval]444 445private theorem divisorCount_zero {n : ℕ} (q : ℚ) (off : ℤ) :446 (divisorCount off fun _ : Fin n × Fin n ↦ (0 : Fin (n+1))).eval q = 1 := by447 simp [divisorCount_eval, falling, Expr.prod, Expr.eval]448 449private theorem divisorCount_cell {n : ℕ} (q : ℚ) (off : ℤ) (a b : ℕ) (ha : a < n) (hb : b < n)450 (v : Fin (n + 1)) :451 (divisorCount off fun ij : Fin n × Fin n ↦452 if ij.1.val = a ∧ ij.2.val = b then v else 0).eval q =453 (falling (availablePoints off (a+1)) v).eval q / ((v : ℕ).factorial : ℚ) := by454 rw [show (fun ij : Fin n × Fin n ↦ if ij.1.val = a ∧ ij.2.val = b then v else 0) =455 spat (⟨a, ha⟩, ⟨b, hb⟩) v from funext fun ij ↦ by simp [spat, Prod.ext_iff, Fin.ext_iff],456 divisorCount_spat]457 458/-- A cell whose weight `(i + 1)(j + 1)` exceeds the total weight is empty. -/459private theorem cell_eq_zero {n : ℕ} (m : Pattern n) (ij : Fin n × Fin n)460 (h : patternWeight m < (ij.1.val + 1) * (ij.2.val + 1)) : (m ij).val = 0 := by461 have hle : (ij.1.val+1)*(ij.2.val+1)*(m ij).val ≤ patternWeight m :=462 Finset.single_le_sum (f := fun ij : Fin n × Fin n ↦ (ij.1.val+1)*(ij.2.val+1)*(m ij).val)463 (fun _ _ ↦ Nat.zero_le _) (Finset.mem_univ ij)464 by_contra hc465 exact absurd (hle.trans_lt h) (not_lt.2 (Nat.le_mul_of_pos_right _ (Nat.pos_of_ne_zero hc)))466 467private theorem pattern_eq_zero {n : ℕ} (m : Pattern n) (h : patternWeight m = 0)468 (ij₀ : Fin n × Fin n) : m = spat ij₀ 0 :=469 eq_spat _ _ _ (cell_eq_zero m ij₀ (by rw [h]; positivity))470 fun ij _ ↦ cell_eq_zero m ij (by rw [h]; positivity)471 472private theorem pattern_eq_of_weight_one {n : ℕ} (hn : 0 < n) (m : Pattern n)473 (h : patternWeight m = 1) : m = spat (⟨0, hn⟩, ⟨0, hn⟩) ⟨1, by omega⟩ := by474 have hz : ∀ ij, ij ≠ (⟨0, hn⟩, ⟨0, hn⟩) → (m ij).val = 0 := by475 rintro ⟨i, j⟩ hij476 have : 0 < i.val ∨ 0 < j.val := by477 by_contra hc; push Not at hc478 exact hij (Prod.ext (Fin.ext (by simp; omega)) (Fin.ext (by simp; omega)))479 refine cell_eq_zero m _ ?_480 rw [h]; change 1 < (i.val+1)*(j.val+1)481 rcases this with hi | hi <;> nlinarith482 refine eq_spat _ _ _ ?_ hz483 have : patternWeight m = (m (⟨0, hn⟩, ⟨0, hn⟩)).val := by484 rw [patternWeight, Finset.sum_eq_single (⟨0, hn⟩, ⟨0, hn⟩) (fun ij _ hij ↦ by simp [hz ij hij])485 (by simp)]486 simp487 simp only; omega488 489private theorem pattern_eq_of_weight_two {n : ℕ} (hn : 2 ≤ n) (m : Pattern n)490 (h : patternWeight m = 2) :491 m = spat (⟨0, Nat.lt_of_lt_of_le Nat.two_pos hn⟩, ⟨0, Nat.lt_of_lt_of_le Nat.two_pos hn⟩)492 ⟨2, Nat.lt_succ_of_le hn⟩ ∨493 m = spat (⟨0, Nat.lt_of_lt_of_le Nat.two_pos hn⟩, ⟨1, Nat.lt_of_lt_of_le Nat.one_lt_two hn⟩)494 ⟨1, Nat.succ_lt_succ (Nat.lt_of_lt_of_le Nat.two_pos hn)⟩ ∨495 m = spat (⟨1, Nat.lt_of_lt_of_le Nat.one_lt_two hn⟩, ⟨0, Nat.lt_of_lt_of_le Nat.two_pos hn⟩)496 ⟨1, Nat.succ_lt_succ (Nat.lt_of_lt_of_le Nat.two_pos hn)⟩ := by497 set x00 : Fin n × Fin n := (⟨0, by omega⟩, ⟨0, by omega⟩)498 set x01 : Fin n × Fin n := (⟨0, by omega⟩, ⟨1, by omega⟩)499 set x10 : Fin n × Fin n := (⟨1, by omega⟩, ⟨0, by omega⟩)500 have hz : ∀ ij, ij ≠ x00 → ij ≠ x01 → ij ≠ x10 → (m ij).val = 0 := by501 rintro ⟨⟨i, hi⟩, ⟨j, hj⟩⟩ h0 h1 h2502 refine cell_eq_zero m _ (h ▸ ?_)503 simp only [x00, x01, x10, ne_eq, Prod.mk.injEq, Fin.mk.injEq] at h0 h1 h2 ⊢504 rcases i with _ | _ | i <;> rcases j with _ | _ | j <;> simp_all505 nlinarith506 have hsum : patternWeight m = (m x00).val + 2*(m x01).val + 2*(m x10).val := by507 unfold patternWeight508 rw [← Finset.sum_subset (Finset.subset_univ ({x00, x01, x10} : Finset (Fin n × Fin n)))]509 · rw [Finset.sum_insert (by simp [x00, x01, x10]), Finset.sum_insert (by simp [x01, x10]),510 Finset.sum_singleton]511 simp [x00, x01, x10]; ring512 · intro ij _ hij513 simp only [Finset.mem_insert, Finset.mem_singleton, not_or] at hij514 rw [hz ij hij.1 hij.2.1 hij.2.2]; simp515 rcases (by omega : ((m x00).val = 2 ∧ (m x01).val = 0 ∧ (m x10).val = 0) ∨516 ((m x00).val = 0 ∧ (m x01).val = 1 ∧ (m x10).val = 0) ∨517 ((m x00).val = 0 ∧ (m x01).val = 0 ∧ (m x10).val = 1))518 with ⟨e0, e1, e2⟩ | ⟨e0, e1, e2⟩ | ⟨e0, e1, e2⟩519 · refine .inl (eq_spat _ _ _ e0 fun ij hij ↦ ?_)520 by_cases h1 : ij = x01; · rw [h1, e1]521 by_cases h2 : ij = x10; · rw [h2, e2]522 exact hz ij hij h1 h2523 · refine .inr (.inl (eq_spat _ _ _ e1 fun ij hij ↦ ?_))524 by_cases h1 : ij = x00; · rw [h1, e0]525 by_cases h2 : ij = x10; · rw [h2, e2]526 exact hz ij h1 hij h2527 · refine .inr (.inr (eq_spat _ _ _ e2 fun ij hij ↦ ?_))528 by_cases h1 : ij = x00; · rw [h1, e0]529 by_cases h2 : ij = x01; · rw [h2, e1]530 exact hz ij h1 h2 hij531 532private theorem univ_toList_perm (n : ℕ) :533 (Finset.univ : Finset (Fin n × Fin n)).toList.Perm (List.finRange n ×ˢ List.finRange n) :=534 List.perm_of_nodup_nodup_toFinset_eq (Finset.nodup_toList _)535 ((List.nodup_finRange n).product (List.nodup_finRange n))536 (by ext ⟨a, b⟩; simp [List.mem_product])537 538/-- `otherChildren` with an explicit enumeration of the cells (computable by `decide`). -/539private def otherChildrenList {n : ℕ} (a : ℕ) (m : Pattern n) : List (ℕ × State) :=540 (List.finRange n ×ˢ List.finRange n).flatMap fun ij ↦541 List.replicate (m ij).val (ij.1.val+1, State.single a (ij.2.val+1))542 543private theorem otherChildren_perm {n : ℕ} (a : ℕ) (m : Pattern n) {l : List (ℕ × State)}544 (h : (otherChildrenList a m).Perm l) : (otherChildren a m).Perm l :=545 ((univ_toList_perm n).flatMap_right _).trans h546 547/-- The product of the descended laws of a list of children. -/548private noncomputable def childProd (l : List (ℕ × State)) : Law :=549 lawProd (l.map fun z ↦ lawDescend z.1 (stateLaw z.2))550 551private theorem coeff_childProd_perm {l l' : List (ℕ × State)} (h : l.Perm l') (q : ℚ)552 (σ : FactorType) : coeffAt q (childProd l) σ = coeffAt q (childProd l') σ :=553 coeff_prod_perm (h.map _) q σ554 555private theorem coeff_otherChildren {n : ℕ} (m : Pattern n) (l : List (ℕ × State))556 (h : (otherChildrenList 1 m).Perm l) (q : ℚ) (σ : FactorType) :557 coeffAt q (childProd (otherChildren 1 m)) σ = coeffAt q (childProd l) σ :=558 coeff_childProd_perm (otherChildren_perm 1 m h) q σ559 560end Patterns561 562/-! ### Unfolding the recursion563 564These facts are re-derived here (and not imported from the development) so that this file depends565only on the definitions in `SurfaceBlowup.Basic`. -/566 567section Recursion568 569private theorem mem_otherChildren {n : ℕ} {a : ℕ} {m : Pattern n} {z : ℕ × State}570 (h : z ∈ otherChildren a m) :571 ∃ ij : Fin n × Fin n, z = (ij.1.val+1, .single a (ij.2.val+1)) := by572 simp only [otherChildren, List.mem_flatMap, List.mem_replicate] at h573 obtain ⟨ij, -, -, rfl⟩ := h574 exact ⟨ij, rfl⟩575 576private theorem children_valid (s : State) (hs : s.Valid) (P : TangentPattern s.degree)577 (hP : Allowed s P) (z : ℕ × State) (hz : z ∈ children s P) : z.2.Valid := by578 have other : ∀ a (m : Pattern s.degree), 0 < a → z ∈ otherChildren a m → z.2.Valid :=579 fun a m ha h ↦ by obtain ⟨ij, rfl⟩ := mem_otherChildren h; exact ⟨ha, Nat.succ_pos _⟩580 obtain ⟨-, -, hrest⟩ := hP581 cases s with582 | single a c =>583 obtain ⟨ha, hc⟩ := hs584 obtain ⟨-, -, hrt⟩ := hrest585 rcases List.mem_append.1 hz with hz | hz586 · split_ifs at hz with h0587 · simp at hz588 · obtain rfl := List.mem_singleton.1 hz589 exact ⟨ha, ha, Nat.pos_of_ne_zero h0, by have := hrt.mp (Nat.pos_of_ne_zero h0); omega⟩590 · exact other a _ ha hz591 | crossing a b c h =>592 obtain ⟨ha, hb, hc, hh⟩ := hs593 obtain ⟨-, -, hrt, hrx⟩ := hrest594 simp only [children, List.mem_append] at hz595 rcases hz with (hz | hz) | hz596 · split_ifs at hz with h0597 · simp at hz598 · obtain rfl := List.mem_singleton.1 hz599 exact ⟨by omega, ha, Nat.pos_of_ne_zero h0,600 by have := hrt.mp (Nat.pos_of_ne_zero h0); omega⟩601 · split_ifs at hz with h0602 · simp at hz603 · obtain rfl := List.mem_singleton.1 hz604 exact ⟨by omega, hb, Nat.pos_of_ne_zero h0,605 by have := hrx.mp (Nat.pos_of_ne_zero h0); omega⟩606 · exact other (a+b) _ (by omega) hz607 608private theorem weight_le_degree (s : State) (hs : s.Valid) : s.weight ≤ s.degree := by609 cases s with610 | single a c => exact Nat.le_mul_of_pos_right a hs.2611 | crossing a b c h =>612 exact Nat.add_le_add (Nat.le_mul_of_pos_right a hs.2.2.1) (Nat.le_mul_of_pos_right b hs.2.2.2)613 614private theorem degree_pos (s : State) (hs : s.Valid) : 0 < s.degree := by615 cases s with616 | single a c => exact Nat.mul_pos hs.1 hs.2617 | crossing a b c h => exact Nat.add_pos_left (Nat.mul_pos hs.1 hs.2.2.1) _618 619private theorem tag_le_one (s : State) : s.tag ≤ 1 := by cases s <;> simp [State.tag]620 621private theorem rank_lt_of_degree_lt (s u : State) (h : u.degree < s.degree) : u.rank < s.rank := by622 have := tag_le_one u623 have h3 : (u.degree + 1) * (u.degree + 1) ≤ s.degree * s.degree := Nat.mul_le_mul h h624 unfold State.rank625 have := Nat.sub_le u.degree u.weight626 nlinarith627 628private theorem rank_lt_of_weight_lt (s u : State) (hs : s.Valid) (hu : u.Valid)629 (hN : u.degree = s.degree) (hw : s.weight < u.weight) : u.rank < s.rank := by630 have := weight_le_degree s hs631 have := weight_le_degree u hu632 have := tag_le_one u633 unfold State.rank634 rw [hN] at *635 omega636 637private theorem otherChildren_degree_sum {n : ℕ} (a : ℕ) (m : Pattern n) :638 ((otherChildren a m).map fun z ↦ z.1*z.2.degree).sum = a * patternWeight m := by639 unfold otherChildren patternWeight640 rw [List.map_flatMap, List.flatMap_def, List.sum_flatten, List.map_map, Finset.mul_sum,641 Finset.sum_map_toList]642 refine Finset.sum_congr rfl fun ij _ ↦ ?_643 simp [List.map_replicate, List.sum_replicate, State.degree]644 ring645 646private theorem children_degree_sum (s : State) (P : TangentPattern s.degree) (hP : Allowed s P) :647 ((children s P).map fun z ↦ z.1*z.2.degree).sum = s.degree := by648 obtain ⟨-, hsum, hrest⟩ := hP649 cases s with650 | single a c =>651 obtain ⟨hdc, hrx, hrt⟩ := hrest652 obtain ⟨W, hW⟩ : ∃ W, patternWeight P.other = W := ⟨_, rfl⟩653 simp only [children, List.map_append, List.sum_append, otherChildren_degree_sum, hW]654 rw [hW] at hsum655 simp only [State.degree]656 generalize P.d.val = D at *657 generalize P.rt.val = R at *658 generalize P.rx.val = X at *659 subst hrx660 obtain ⟨k, rfl⟩ : ∃ k, c = D + k := ⟨c - D, by omega⟩661 subst hsum662 split_ifs with h0663 · obtain rfl : k = 0 := by omega664 subst h0; simp665 · simp only [List.map_cons, List.map_nil, List.sum_cons, List.sum_nil]666 rw [Nat.add_sub_cancel_left]; ring667 | crossing a b c h =>668 obtain ⟨hdc, hdh, hrt, hrx⟩ := hrest669 obtain ⟨W, hW⟩ : ∃ W, patternWeight P.other = W := ⟨_, rfl⟩670 simp only [children, List.map_append, List.sum_append, otherChildren_degree_sum, hW]671 rw [hW] at hsum672 simp only [State.degree]673 generalize P.d.val = D at *674 generalize P.rt.val = R at *675 generalize P.rx.val = X at *676 obtain ⟨k, rfl⟩ : ∃ k, c = D + k := ⟨c - D, by omega⟩677 obtain ⟨l, rfl⟩ : ∃ l, h = D + l := ⟨h - D, by omega⟩678 subst hsum679 simp only [Nat.add_sub_cancel_left]680 have e1 : R = 0 → k = 0 := by omega681 have e2 : X = 0 → l = 0 := by omega682 split_ifs <;>683 simp only [List.map_cons, List.map_nil, List.sum_cons, List.sum_nil] <;>684 (try (obtain rfl := e1 ‹R = 0›; subst ‹R = 0›)) <;>685 (try (obtain rfl := e2 ‹X = 0›; subst ‹X = 0›)) <;> ring686 687private theorem children_fst_pos (s : State) (P : TangentPattern s.degree) (z : ℕ × State)688 (hz : z ∈ children s P) : 0 < z.1 := by689 cases s with690 | single a c =>691 rcases List.mem_append.1 hz with hz | hz692 · split_ifs at hz <;> simp at hz; simp [hz]693 · obtain ⟨ij, rfl⟩ := mem_otherChildren hz; simp694 | crossing a b c h =>695 simp only [children, List.mem_append] at hz696 rcases hz with (hz | hz) | hz697 · split_ifs at hz <;> simp at hz; simp [hz]698 · split_ifs at hz <;> simp at hz; simp [hz]699 · obtain ⟨ij, rfl⟩ := mem_otherChildren hz; simp700 701/-- A child of the same degree as its parent is the only child, with residue degree one. -/702private theorem children_eq_singleton (s : State) (hs : s.Valid) (P : TangentPattern s.degree)703 (hP : Allowed s P) (z : ℕ × State) (hz : z ∈ children s P) (heq : z.2.degree = s.degree) :704 children s P = [z] ∧ z.1 = 1 := by705 have hsum := children_degree_sum s P hP706 have hD := degree_pos s hs707 have hpos : ∀ w ∈ children s P, 0 < w.1 * w.2.degree := fun w hw ↦708 Nat.mul_pos (children_fst_pos s P w hw) (degree_pos _ (children_valid s hs P hP w hw))709 have hz1 := children_fst_pos s P z hz710 obtain ⟨l1, l2, hL⟩ := List.append_of_mem hz711 have empty : ∀ l : List (ℕ × State), (∀ w ∈ l, w ∈ children s P) →712 (l.map fun z ↦ z.1*z.2.degree).sum = 0 → l = [] := by713 rintro (_ | ⟨a, t⟩) hl h0714 · rfl715 · have := hpos a (hl a (by simp))716 simp only [List.map_cons, List.sum_cons] at h0717 omega718 rw [hL] at hsum719 simp only [List.map_append, List.map_cons, List.sum_append, List.sum_cons, heq] at hsum720 have hge : s.degree ≤ z.1 * s.degree := Nat.le_mul_of_pos_left _ hz1721 obtain rfl := empty l1 (fun w hw ↦ by rw [hL]; simp [hw]) (by omega)722 obtain rfl := empty l2 (fun w hw ↦ by rw [hL]; simp [hw]) (by omega)723 refine ⟨by simpa using hL, Nat.eq_of_mul_eq_mul_right hD ?_⟩724 simp at hsum725 omega726 727private theorem nonself_child_rank_lt (s : State) (hs : s.Valid) (P : TangentPattern s.degree)728 (hP : Allowed s P) (hself : ¬ SelfPattern s P) (z : ℕ × State) (hz : z ∈ children s P) :729 z.2.rank < s.rank := by730 have hv := children_valid s hs P hP z hz731 have hle : z.2.degree ≤ s.degree := calc732 z.2.degree ≤ z.1 * z.2.degree := Nat.le_mul_of_pos_left _ (children_fst_pos s P z hz)733 _ ≤ ((children s P).map fun z ↦ z.1*z.2.degree).sum :=734 List.single_le_sum (fun _ _ ↦ Nat.zero_le _) _ (List.mem_map.2 ⟨z, hz, rfl⟩)735 _ = s.degree := children_degree_sum s P hP736 rcases Nat.lt_or_eq_of_le hle with hlt | heq737 · exact rank_lt_of_degree_lt s z.2 hlt738 obtain ⟨hch, hz1⟩ := children_eq_singleton s hs P hP z hz heq739 have hw : ∀ u : State, s.weight < u.weight → z.2 = u → z.2.rank < s.rank := by740 rintro u hwu rfl741 exact rank_lt_of_weight_lt s z.2 hs hv heq hwu742 cases s with743 | single a c =>744 simp only [children, otherChildren, List.mem_append, List.mem_flatMap,745 List.mem_replicate] at hz746 rcases hz with hz | ⟨ij, -, -, rfl⟩747 · split_ifs at hz with h0748 · simp at hz749 · obtain rfl := List.mem_singleton.1 hz750 exact hw _ (by have := hs.1; simp [State.weight]; omega) rfl751 · refine absurd ⟨a, c, rfl, ?_⟩ hself752 have hj : ij.2.val + 1 = c :=753 Nat.eq_of_mul_eq_mul_left hs.1 (by simpa [State.degree] using heq)754 rw [hch]755 simp only at hz1756 rw [hz1, hj]757 | crossing a b c h =>758 simp only [children, otherChildren, List.mem_append, List.mem_flatMap,759 List.mem_replicate] at hz760 rcases hz with (hz | hz) | ⟨ij, -, -, rfl⟩761 · split_ifs at hz with h0762 · simp at hz763 · obtain rfl := List.mem_singleton.1 hz764 exact hw _ (by have := hs.1; simp [State.weight]; omega) rfl765 · split_ifs at hz with h0766 · simp at hz767 · obtain rfl := List.mem_singleton.1 hz768 exact hw _ (by have := hs.2.1; simp [State.weight]; omega) rfl769 · simp only [State.rank, State.weight, State.tag] at heq ⊢770 rw [heq]771 omega772 773open scoped Classical in774/-- The recursion sum of a state with fuel `k` for the children. -/775private noncomputable def exitLawFuel (k : ℕ) (s : State) : Law :=776 (allowedPatterns s).toList.flatMap fun P ↦777 if SelfPattern s P then [] else778 lawScale (.mul (tangentCount s P) (divisorProbability s P.d.val))779 (lawProd ((children s P).map fun z ↦ lawDescend z.1 (stateLawFuel k z.2)))780 781open scoped Classical in782/-- The non-self part of the recursion sum of a state, with the children's laws `stateLaw`. -/783private noncomputable def exitLaw (s : State) : Law :=784 (allowedPatterns s).toList.flatMap fun P ↦785 if SelfPattern s P then [] else786 lawScale (.mul (tangentCount s P) (divisorProbability s P.d.val))787 (lawProd ((children s P).map fun z ↦ lawDescend z.1 (stateLaw z.2)))788 789private theorem exitLawFuel_congr (s : State) (hs : s.Valid) (k₁ k₂ : ℕ)790 (h : ∀ z : ℕ × State, z.2.Valid → z.2.rank < s.rank →791 stateLawFuel k₁ z.2 = stateLawFuel k₂ z.2) :792 exitLawFuel k₁ s = exitLawFuel k₂ s := by793 refine List.flatMap_congr fun P hP ↦ ?_794 have hA : Allowed s P := by simpa [allowedPatterns] using hP795 split_ifs with hself796 · rfl797 · refine congrArg _ (congrArg _ (List.map_congr_left fun z hz ↦ ?_))798 rw [h z (children_valid s hs P hA z hz) (nonself_child_rank_lt s hs P hA hself z hz)]799 800/-- One step of the fuelled recursion at a non-terminal state `s`: the recursion sum801`exitLawFuel k s`, scaled by `(1 - returnWeight c)⁻¹` when `s` is a single state of contact `c`. -/802noncomputable def stateLawFuelStep (k : ℕ) (s : State) : Law :=803 match s with804 | .single _ c => lawScale (.inv (.sub (.const 1) (returnWeight c))) (exitLawFuel k s)805 | .crossing _ _ _ _ => exitLawFuel k s806 807private theorem stateLawFuel_succ (k : ℕ) (s : State) (hnt : s.terminal = false) :808 stateLawFuel (k+1) s = stateLawFuelStep k s := by809 rcases s with ⟨a, _ | _ | c⟩ | ⟨a, b, c, h⟩810 · rfl811 · simp [State.terminal] at hnt812 · rfl813 · rfl814 815private theorem stateLawFuel_eq (k : ℕ) (s : State) (hs : s.Valid) (hk : s.rank < k) :816 stateLawFuel k s = stateLaw s := by817 suffices ∀ n s, s.Valid → s.rank < n → ∀ k₁ k₂, s.rank < k₁ → s.rank < k₂ →818 stateLawFuel k₁ s = stateLawFuel k₂ s from this _ s hs (Nat.lt_succ_self _) _ _ hk819 (Nat.lt_succ_self _)820 intro n821 induction n with822 | zero => intro s _ h; omega823 | succ n ih =>824 intro s hs hn k₁ k₂ h₁ h₂825 obtain ⟨j₁, rfl⟩ : ∃ j, k₁ = j + 1 := ⟨k₁ - 1, by omega⟩826 obtain ⟨j₂, rfl⟩ : ∃ j, k₂ = j + 1 := ⟨k₂ - 1, by omega⟩827 have := exitLawFuel_congr s hs j₁ j₂ fun z hz hlt ↦828 ih z.2 hz (by omega) j₁ j₂ (by omega) (by omega)829 rcases s with ⟨a, _ | _ | c⟩ | ⟨a, b, c, h⟩ <;>830 first | rw [stateLawFuel_succ _ _ rfl, stateLawFuel_succ _ _ rfl, stateLawFuelStep,831 stateLawFuelStep, this] | rfl832 833private theorem exitLawFuel_rank (s : State) (hs : s.Valid) : exitLawFuel s.rank s = exitLaw s :=834 List.flatMap_congr fun P hP ↦ by835 have hA : Allowed s P := by simpa [allowedPatterns] using hP836 split_ifs with hself837 · rfl838 · refine congrArg _ (congrArg _ (List.map_congr_left fun z hz ↦ ?_))839 rw [stateLawFuel_eq _ _ (children_valid s hs P hA z hz)840 (nonself_child_rank_lt s hs P hA hself z hz)]841 842private theorem stateLaw_single (a c : ℕ) (hs : (State.single a c).Valid) (hc : c ≠ 1) :843 stateLaw (.single a c) =844 lawScale (.inv (.sub (.const 1) (returnWeight c))) (exitLaw (.single a c)) := by845 rw [stateLaw, stateLawFuel_succ _ _ (by rcases c with _ | _ | c <;> simp_all [State.terminal]),846 stateLawFuelStep, exitLawFuel_rank _ hs]847 848private theorem stateLaw_crossing (a b c h : ℕ) (hs : (State.crossing a b c h).Valid) :849 stateLaw (.crossing a b c h) = exitLaw (.crossing a b c h) := by850 rw [stateLaw, stateLawFuel_succ _ _ rfl, stateLawFuelStep, exitLawFuel_rank _ hs]851 852private theorem stateLaw_terminal (a : ℕ) : stateLaw (.single a 1) = lawAtom a 1 := by853 rw [stateLaw, State.rank, stateLawFuel]854 855open scoped Classical in856/-- The coefficients of `exitLaw s`, as a sum over the allowed patterns. -/857private theorem coeff_exitLaw (q : ℚ) (s : State) (σ : FactorType) : coeffAt q (exitLaw s) σ =858 ∑ P ∈ allowedPatterns s, if SelfPattern s P then 0 else859 ((tangentCount s P).mul (divisorProbability s P.d.val)).eval q *860 coeffAt q (childProd (children s P)) σ := by861 rw [exitLaw, coeff_flatMap, Finset.sum_map_toList]862 refine Finset.sum_congr rfl fun P _ ↦ ?_863 split_ifs864 · rfl865 · rw [coeff_scale]; rfl866 867/-- The coefficients of the global law, as a sum over the residue patterns. -/868private theorem coeff_globalLaw (proj : Bool) (n : ℕ) (q : ℚ) (σ : FactorType) :869 coeffAt q (globalLaw proj n) σ =870 (Expr.inv (if proj then projectiveNormalizer n else .pow .var n)).eval q *871 ∑ m ∈ residuePatterns n, (divisorCount (if proj then 1 else 0) m).eval q *872 coeffAt q (childProd (otherChildren 1 m)) σ := by873 rw [globalLaw, coeff_scale, coeff_flatMap, Finset.sum_map_toList]874 simp only [coeff_scale]; rfl875 876end Recursion877 878/-! ### The laws of the crossing states `T(a,b;c,h)` with `c = 1` or `h = 1` -/879 880section Crossing881 882/-- A crossing state with a unique allowed pattern, of weight one, with a unique child of residue883degree one has the law of that child. -/884private theorem coeff_crossing_of_unique {a b c h : ℕ} (hv : (State.crossing a b c h).Valid)885 (P : TangentPattern (State.crossing a b c h).degree)886 (hA : allowedPatterns (.crossing a b c h) = {P}) (s' : State)887 (hch : children (.crossing a b c h) P = [(1, s')]) (q : ℚ)888 (hX : ((tangentCount (.crossing a b c h) P).mul889 (divisorProbability (.crossing a b c h) P.d.val)).eval q = 1) (σ : FactorType) :890 coeffAt q (stateLaw (.crossing a b c h)) σ = coeffAt q (stateLaw s') σ := by891 rw [stateLaw_crossing _ _ _ _ hv, coeff_exitLaw, hA, Finset.sum_singleton,892 if_neg (by rintro ⟨_, _, h, _⟩; cases h), hX, one_mul, hch, childProd, List.map_singleton,893 coeff_prod_singleton, coeff_descend_one]894 895/-- `T(a,b;1,1)` has the law of the terminal state `S(a+b;1)`. -/896private theorem crossing_one_one_law (a b : ℕ) (ha : 0 < a) (hb : 0 < b) (q : ℚ) (hq : 1 < q)897 (σ : FactorType) :898 coeffAt q (stateLaw (.crossing a b 1 1)) σ = if σ = {(a+b, 1)} then 1 else 0 := by899 have hn : 0 < (State.crossing a b 1 1).degree := by simp [State.degree]; omega900 set D := (State.crossing a b 1 1).degree901 let x : Fin D × Fin D := (⟨0, hn⟩, ⟨0, hn⟩)902 let P : TangentPattern D := ⟨⟨1, by omega⟩, 0, 0, spat x ⟨1, by omega⟩⟩903 have hA : allowedPatterns (.crossing a b 1 1) = {P} := by904 ext Q905 simp only [allowedPatterns, Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_singleton]906 constructor907 · obtain ⟨d, rt, rx, other⟩ := Q908 rintro ⟨h0, hw, h1, h2, h3, h4⟩909 simp only at h0 hw h1 h2 h3 h4910 have hrt : rt.val = 0 := by by_contra h; have := h3.1 (by omega); omega911 have hrx : rx.val = 0 := by by_contra h; have := h4.1 (by omega); omega912 rw [pattern_eq_of_weight_one hn other (by omega)]913 simp only [P, x, TangentPattern.mk.injEq, Fin.ext_iff, Fin.val_zero, and_true]914 omega915 · rintro rfl916 exact ⟨by simp [P], by simp [P, patternWeight_spat, x], by simp [P]⟩917 rw [coeff_crossing_of_unique ⟨ha, hb, one_pos, one_pos⟩ P hA (.single (a+b) 1) ?_ q ?_ σ,918 stateLaw_terminal, coeff_lawAtom]919 · simp [children, P, otherChildren_spat, x]920 · have hq1 : q + -1 ≠ 0 := by linarith921 simp [P, tangentCount, divisorCount_spat, divisorProbability, chooseTwo, falling,922 availablePoints, x, Expr.eval, eminusOne, Expr.sub, Expr.neg, Expr.pow, Expr.prod, hq1]923 924/-- For `c = 1` or `h = 1` (not both) the unique allowed pattern of `T(a,b;c,h)` has weight one925and a unique child, of residue degree one. -/926private theorem crossing_unique_pattern (a b c h : ℕ) (ha : 0 < a) (hb : 0 < b) (hc : 0 < c)927 (hh : 0 < h) (q : ℚ) (hone : c = 1 ∨ h = 1) (hnot : ¬ (c = 1 ∧ h = 1)) :928 ∃ P : TangentPattern (State.crossing a b c h).degree,929 allowedPatterns (State.crossing a b c h) = {P} ∧930 children (State.crossing a b c h) P =931 (if 1 < c then [(1, .crossing (a+b) a 1 (c-1))] else []) ++932 (if 1 < h then [(1, .crossing (a+b) b 1 (h-1))] else []) ∧933 ((tangentCount (State.crossing a b c h) P).mul934 (divisorProbability (State.crossing a b c h) P.d.val)).eval q = 1 := by935 have hn : 1 < (State.crossing a b c h).degree := by936 change 1 < a*c+b*h937 have := Nat.mul_pos ha hc; have := Nat.mul_pos hb hh; omega938 let P : TangentPattern (State.crossing a b c h).degree :=939 ⟨⟨1, by omega⟩, ⟨if 1 < c then 1 else 0, by split_ifs <;> omega⟩,940 ⟨if 1 < h then 1 else 0, by split_ifs <;> omega⟩, fun _ ↦ 0⟩941 have hpw0 : patternWeight P.other = 0 := by simp [patternWeight, P]942 refine ⟨P, ?_, ?_, ?_⟩943 · ext Q944 simp only [allowedPatterns, Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_singleton]945 constructor946 · obtain ⟨d, rt, rx, other⟩ := Q947 rintro ⟨h0, hw, h1, h2, h3, h4⟩948 simp only at h0 hw h1 h2 h3 h4949 have hrt : rt.val = if 1 < c then 1 else 0 := by950 split_ifs with hc1951 · have := h3.2 (by omega); omega952 · by_contra hne; have := h3.1 (by omega); omega953 have hrx : rx.val = if 1 < h then 1 else 0 := by954 split_ifs with hh1955 · have := h4.2 (by omega); omega956 · by_contra hne; have := h4.1 (by omega); omega957 have hpw : patternWeight other = 0 := by rw [hrt, hrx] at hw; split_ifs at hw <;> omega958 have := pattern_eq_zero other hpw (⟨0, by omega⟩, ⟨0, by omega⟩)959 simp only [P, TangentPattern.mk.injEq, Fin.ext_iff, hrt, hrx, true_and]960 refine ⟨by omega, this.trans (funext fun _ ↦ ?_)⟩961 simp [spat]962 · rintro rfl963 refine ⟨by simp [P], ?_, ?_⟩964 · rw [hpw0]; simp only [P]; split_ifs <;> omega965 · simp only [P]; refine ⟨by omega, by omega, ?_, ?_⟩ <;> split_ifs <;> omega966 · simp only [children, show otherChildren (a+b) P.other = [] by simp [otherChildren, P], P,967 List.append_nil]968 rcases hone with rfl | rfl969 · simp [show 1 < h by omega]970 · simp [show 1 < c by omega]971 · have hj : (if 1 < c then 1 else 0) + (if 1 < h then 1 else 0) = 1 := by split_ifs <;> omega972 simp only [Expr.eval, divisorProbability, P, chooseTwo, hj, tangentCount, divisorCount, falling,973 eval_prod]974 simp [Expr.prod, Expr.pow, Expr.eval]975 976/-- `T(a,b;1,h)` has the law of the terminal state `S(a+hb;1)`. -/977private theorem crossing_left_one_law (a b h : ℕ) (ha : 0 < a) (hb : 0 < b) (hh : 0 < h) (q : ℚ)Lemma 2.2978 (hq : 1 < q) (σ : FactorType) :979 coeffAt q (stateLaw (.crossing a b 1 h)) σ = if σ = {(a+h*b, 1)} then 1 else 0 := by980 induction h generalizing a with981 | zero => omega982 | succ h ih =>983 rcases Nat.eq_zero_or_pos h with rfl | h0984 · simpa using crossing_one_one_law a b ha hb q hq σ985 obtain ⟨P, hA, hch, hX⟩ :=986 crossing_unique_pattern a b 1 (h+1) ha hb one_pos (by omega) q (.inl rfl) (by omega)987 rw [if_neg (by omega), if_pos (by omega), List.nil_append, Nat.add_sub_cancel] at hch988 rw [coeff_crossing_of_unique ⟨ha, hb, one_pos, by omega⟩ P hA _ hch q hX,989 ih (a+b) (by omega) h0]990 congr 2; ring_nf991 992/-- `T(a,b;c,1)` has the law of the terminal state `S(ca+b;1)`. -/993private theorem crossing_right_one_law (a b c : ℕ) (ha : 0 < a) (hb : 0 < b) (hc : 0 < c) (q : ℚ)Lemma 2.2994 (hq : 1 < q) (σ : FactorType) :995 coeffAt q (stateLaw (.crossing a b c 1)) σ = if σ = {(c*a+b, 1)} then 1 else 0 := by996 rcases Nat.lt_or_ge 1 c with hc1 | hc1997 · obtain ⟨P, hA, hch, hX⟩ :=998 crossing_unique_pattern a b c 1 ha hb hc one_pos q (.inr rfl) (by omega)999 rw [if_pos hc1, if_neg (by omega), List.append_nil] at hch1000 rw [coeff_crossing_of_unique ⟨ha, hb, hc, one_pos⟩ P hA _ hch q hX,1001 crossing_left_one_law (a+b) a (c-1) (by omega) ha (by omega) q hq]1002 obtain ⟨k, rfl⟩ : ∃ k, c = k+1 := ⟨c-1, by omega⟩1003 simp only [Nat.add_sub_cancel]1004 congr 2; ring_nf1005 · obtain rfl : c = 1 := by omega1006 simpa using crossing_one_one_law a b ha hb q hq σ1007 1008end Crossing1009 1010/-! ### The law of `S(a;2)` -/1011 1012section SingleTwo1013 1014private theorem returnWeight_eval (q : ℚ) (c : ℕ) :1015 (Expr.inv (.sub (.const 1) (returnWeight c))).eval q = (1 - q / q ^ tri c)⁻¹ := by1016 simp [returnWeight, Expr.eval, Expr.sub, Expr.neg, eval_pow, div_eq_mul_inv, sub_eq_add_neg]1017 1018/-- The tangent-point patterns of `S(a;2)`: a transverse tangent with a node, a double point, a1019point of contact two (a self pattern) and a point of degree two. -/1020private theorem single_two_law (a : ℕ) (ha : 0 < a) (q : ℚ) (hq : 1 < q) (σ : FactorType) :(1.3)Example 6.4Example 7.31021 coeffAt q (stateLaw (.single a 2)) σ = (if σ = {(2*a,1)} then q/(q+1) else 0) +1022 (if σ = {(a,1),(a,1)} then 1/(2*(q+1)) else 0) +1023 (if σ = {(a,2)} then 1/(2*(q+1)) else 0) := by1024 have hn : 2 ≤ (State.single a 2).degree := by simp [State.degree]; omega1025 set D := (State.single a 2).degree1026 let i0 : Fin D := ⟨0, by omega⟩1027 let i1 : Fin D := ⟨1, by omega⟩1028 let f1 : Fin (D+1) := ⟨1, by omega⟩1029 let f2 : Fin (D+1) := ⟨2, by omega⟩1030 let P1 : TangentPattern D := ⟨f1, f1, 0, spat (i0, i0) 0⟩1031 let P2 : TangentPattern D := ⟨f2, 0, 0, spat (i0, i0) f2⟩1032 let P3 : TangentPattern D := ⟨f2, 0, 0, spat (i0, i1) f1⟩1033 let P4 : TangentPattern D := ⟨f2, 0, 0, spat (i1, i0) f1⟩1034 have hA : allowedPatterns (.single a 2) = {P1, P2, P3, P4} := by1035 ext P1036 simp only [allowedPatterns, Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_insert,1037 Finset.mem_singleton]1038 constructor1039 · obtain ⟨d, rt, rx, other⟩ := P1040 rintro ⟨h0, hw, h1, h2, h3⟩1041 simp only at h0 hw h1 h2 h31042 obtain rfl : rx = 0 := Fin.ext h21043 rcases (by omega : d.val = 1 ∨ d.val = 2) with hd | hd1044 · have hrt : rt.val = 1 := by have := h3.1 (by omega); simp at hw; omega1045 left1046 rw [pattern_eq_zero other (by simp at hw; omega) (i0, i0)]1047 simp only [P1, TangentPattern.mk.injEq, Fin.ext_iff, and_true]1048 exact ⟨hd, hrt⟩1049 · obtain rfl : rt = 0 := Fin.ext (by by_contra hc; have := h3.2 (by omega); omega)1050 obtain rfl : d = f2 := Fin.ext hd1051 right1052 rcases pattern_eq_of_weight_two hn other (by simp at hw; omega) with ho | ho | ho <;>1053 rw [ho]1054 · left; rfl1055 · right; left; rfl1056 · right; right; rfl1057 · rintro (rfl | rfl | rfl | rfl) <;> refine ⟨by simp [P1, P2, P3, P4, f1, f2], ?_, ?_⟩ <;>1058 simp [P1, P2, P3, P4, patternWeight_spat, f1, f2, i0, i1]1059 have hi01 : i0 ≠ i1 := by simp [i0, i1]1060 have hne : P1 ≠ P2 ∧ P1 ≠ P3 ∧ P1 ≠ P4 ∧ P2 ≠ P3 ∧ P2 ≠ P4 ∧ P3 ≠ P4 := by1061 refine ⟨by simp [P1, P2, f1, f2], by simp [P1, P3, f1, f2], by simp [P1, P4, f1, f2],1062 ?_, ?_, ?_⟩1063 all_goals intro h1064 · simpa [P2, P3, spat, hi01, f2] using congrArg (fun P ↦ (P.other (i0, i0)).val) h1065 · simpa [P2, P4, spat, hi01, f2] using congrArg (fun P ↦ (P.other (i0, i0)).val) h1066 · simpa [P3, P4, spat, hi01, f1] using congrArg (fun P ↦ (P.other (i0, i1)).val) h1067 rw [stateLaw_single _ _ ⟨ha, two_pos⟩ (by norm_num), coeff_scale, coeff_exitLaw, hA,1068 Finset.sum_insert (by simp [hne]), Finset.sum_insert (by simp [hne]),1069 Finset.sum_insert (by simp [hne]), Finset.sum_singleton]1070 have hch1 : children (.single a 2) P1 = [(1, .crossing a a 1 1)] := by1071 simp [children, P1, f1, otherChildren_spat]1072 have hch2 : children (.single a 2) P2 = [(1, .single a 1), (1, .single a 1)] := by1073 simp [children, P2, f2, otherChildren_spat, i0]1074 have hch3 : children (.single a 2) P3 = [(1, .single a 2)] := by1075 simp [children, P3, f1, otherChildren_spat, i0, i1]1076 have hch4 : children (.single a 2) P4 = [(2, .single a 1)] := by1077 simp [children, P4, f1, otherChildren_spat, i0, i1]1078 have notSelf (P : TangentPattern D) (z : ℕ × State) (hz : children (.single a 2) P = [z])1079 (h : z ≠ (1, .single a 2)) : ¬ SelfPattern (.single a 2) P := by1080 rintro ⟨_, _, he, h'⟩; rw [hz] at h'; simp only [List.cons.injEq] at h'; exact h (he ▸ h'.1)1081 have hS2 : ¬ SelfPattern (.single a 2) P2 := by1082 rintro ⟨_, _, _, h⟩; rw [hch2] at h; simp at h1083 rw [if_neg (notSelf P1 _ hch1 (by simp)), if_neg hS2,1084 if_pos (show SelfPattern (.single a 2) P3 from ⟨a, 2, rfl, hch3⟩),1085 if_neg (notSelf P4 _ hch4 (by simp)), hch1, hch2, hch4]1086 simp only [childProd, List.map_cons, List.map_nil, stateLaw_terminal, lawDescend_lawAtom,1087 lawProd_cons, lawProd_nil, coeff_mul_lawOne, coeff_descend_one,1088 crossing_one_one_law a a ha ha q hq,1089 coeff_mul_atom, coeff_lawAtom, ite_mem_erase]1090 have hq0 : q ≠ 0 := by positivity1091 have hq1 : q - 1 ≠ 0 := by linarith1092 have hN1 : ((tangentCount (.single a 2) P1).mul1093 (divisorProbability (.single a 2) P1.d.val)).eval q = (q - 1) / q := by1094 simp [tangentCount, divisorCount_spat, P1, f1, divisorProbability, tri, Expr.eval, Expr.pow,1095 eminusOne, Expr.sub, Expr.neg, falling, Expr.prod]1096 field_simp; ring1097 have hN2 : ((tangentCount (.single a 2) P2).mul1098 (divisorProbability (.single a 2) P2.d.val)).eval q = q * (q - 1) / 2 / q ^ 3 := by1099 simp [tangentCount, divisorCount_spat, P2, f2, divisorProbability, tri, Expr.eval, Expr.pow,1100 Expr.sub, Expr.neg, falling, Expr.prod, availablePoints, i0, List.range_succ]1101 ring1102 have hN4 : ((tangentCount (.single a 2) P4).mul1103 (divisorProbability (.single a 2) P4.d.val)).eval q = (q ^ 2 - q) / 2 / q ^ 3 := by1104 simp [tangentCount, divisorCount_spat, P4, f1, f2, divisorProbability, tri, Expr.eval, Expr.pow,1105 falling, Expr.prod, availablePoints, i1, pointCount_two, List.range_succ, Expr.sub, Expr.neg]1106 ring1107 have hR : (1 - q / q ^ tri 2)⁻¹ = q ^ 2 / ((q - 1) * (q + 1)) := by1108 rw [show tri 2 = 3 from rfl, inv_eq_iff_eq_inv, inv_div]; field_simp; ring1109 rw [hN1, hN2, hN4, returnWeight_eval, hR, ← two_mul]1110 simp only [Multiset.insert_eq_cons, ite_eq_mul_indicator]1111 have : q + 1 ≠ 0 := by linarith1112 field_simp1113 ring1114 1115end SingleTwo1116 1117/-! ### Quadratic expressions -/1118 1119section Quadratic1120 1121private theorem residuePatterns_two :1122 residuePatterns 2 = {spat (0, 0) 2, spat (1, 0) 1, spat (0, 1) 1} := by1123 unfold residuePatterns; decide1124 1125/-- The global law in degree two: two rational points, a point of degree two, or a point of1126contact two (with the law of `S(1;2)`). -/1127private theorem coeff_globalLaw_two (proj : Bool) (q : ℚ) (σ : FactorType) :1128 coeffAt q (globalLaw proj 2) σ =1129 (Expr.inv (if proj then projectiveNormalizer 2 else .pow .var 2)).eval q *1130 ((divisorCount (if proj then 1 else 0) (spat (n := 2) (0, 0) 2)).eval q *1131 (if σ = {(1,1), (1,1)} then 1 else 0) +1132 ((divisorCount (if proj then 1 else 0) (spat (n := 2) (1, 0) 1)).eval q *1133 (if σ = {(1,2)} then 1 else 0) +1134 (divisorCount (if proj then 1 else 0) (spat (n := 2) (0, 1) 1)).eval q *1135 coeffAt q (stateLaw (.single 1 2)) σ)) := by1136 rw [globalLaw, coeff_scale, coeff_flatMap, Finset.sum_map_toList, residuePatterns_two,1137 Finset.sum_insert (by decide), Finset.sum_insert (by decide), Finset.sum_singleton]1138 simp only [coeff_scale, otherChildren_spat]1139 simp [List.replicate, stateLaw_terminal, lawDescend_lawAtom, lawProd_cons, lawProd_nil,1140 coeff_mul_lawOne, coeff_descend_one, coeff_mul_atom, coeff_lawAtom, ite_mem_erase,1141 Multiset.insert_eq_cons]1142 1143/-- **Quadratic monic densities.** For every `q > 1`, the universal monic expressions of degree `2`1144take the values `q / (2(q + 1))` (split and inert types) and `1 / (q + 1)` (ramified type), and1145vanish on every other type. -/1146theorem monicExpr_two_eval (q : ℚ) (hq : 1 < q) (σ : FactorType) :(1.3)Example 7.3(10.8)(11.8)(11.9)–(11.10)1147 (monicExpr 2 σ).eval q =1148 (if σ = {(1,1), (1,1)} then q / (2 * (q + 1)) else 0) +1149 (if σ = {(1,2)} then q / (2 * (q + 1)) else 0) +1150 (if σ = {(2,1)} then 1 / (q + 1) else 0) := by1151 rw [monicExpr, coeff_globalLaw_two, single_two_law 1 one_pos q hq]1152 simp [divisorCount_spat, falling, availablePoints, Expr.eval, eval_prod, eval_pow, pointCount_two,1153 Expr.sub, Expr.neg, List.range_succ, Multiset.insert_eq_cons, ite_eq_mul_indicator]1154 have : q + 1 ≠ 0 := by positivity1155 have : q ≠ 0 := by positivity1156 field_simp1157 ring1158 1159/-- **Quadratic projective densities.** For every `q > 1`, the universal projective expressions of1160degree `2` take the values `1/2` (split), `(q² - q + 1) / (2(q² + q + 1))` (inert) and1161`q / (q² + q + 1)` (ramified), and vanish on every other type. -/1162theorem projectiveExpr_two_eval (q : ℚ) (hq : 1 < q) (σ : FactorType) :Example 7.3(11.8)1163 (projectiveExpr 2 σ).eval q =1164 (if σ = {(1,1), (1,1)} then 1 / 2 else 0) +1165 (if σ = {(1,2)} then (q ^ 2 - q + 1) / (2 * (q ^ 2 + q + 1)) else 0) +1166 (if σ = {(2,1)} then q / (q ^ 2 + q + 1) else 0) := by1167 rw [projectiveExpr, coeff_globalLaw_two, single_two_law 1 one_pos q hq]1168 simp [divisorCount_spat, falling, availablePoints, Expr.eval, eval_prod, eval_pow, pointCount_two,1169 Expr.sub, Expr.neg, List.range_succ, Multiset.insert_eq_cons, ite_eq_mul_indicator,1170 projectiveNormalizer,1171 eval_sum]1172 have : q + 1 ≠ 0 := by positivity1173 have : q ^ 2 + q + 1 ≠ 0 := by positivity1174 field_simp1175 ring1176 1177end Quadratic1178 1179/-! ### Children of single-boundary states -/1180 1181section SingleChildren1182 1183private theorem children_single_perm {a c : ℕ} (P : TangentPattern (State.single a c).degree)1184 {l : List (ℕ × State)}1185 (h : ((if P.rt.val = 0 then [] else [(1, State.crossing a a P.rt.val (c - P.d.val))]) ++1186 otherChildrenList a P.other).Perm l) : (children (.single a c) P).Perm l :=1187 (List.Perm.append_left _ ((univ_toList_perm _).flatMap_right _)).trans h1188 1189/-- Self patterns, decidably. -/1190private theorem selfPattern_single_iff {a c : ℕ} (P : TangentPattern (State.single a c).degree) :1191 SelfPattern (.single a c) P ↔1192 ((if P.rt.val = 0 then [] else [(1, State.crossing a a P.rt.val (c - P.d.val))]) ++1193 otherChildrenList a P.other).Perm [(1, .single a c)] := by1194 have hp := children_single_perm P (List.Perm.refl _)1195 constructor1196 · rintro ⟨_, _, -, h⟩; exact hp.symm.trans (h ▸ List.Perm.refl _)1197 · intro h; exact ⟨a, c, rfl, List.perm_singleton.1 (hp.trans h)⟩1198 1199end SingleChildren1200 1201/-! ### Degree three: patterns1202 1203Cells `(i, j)` of a pattern record points of degree `i + 1` and contact `j + 1`. -/1204 1205section DegreeThree1206 1207/-- One rational point of contact three (the self pattern of `S(1;3)`). -/1208private abbrev m3Contact : Pattern 3 := fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 2 then 1 else 01209/-- One point of degree three. -/1210private abbrev m3Inert : Pattern 3 := fun ij ↦ if ij.1.val = 2 ∧ ij.2.val = 0 then 1 else 01211/-- Two rational points, of contacts one and two. -/1212private abbrev m3Tangent : Pattern 3 := fun ij ↦1213 if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else if ij.1.val = 0 ∧ ij.2.val = 1 then 1 else 01214/-- A rational point and a point of degree two. -/1215private abbrev m3Quadratic : Pattern 3 := fun ij ↦1216 if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else if ij.1.val = 1 ∧ ij.2.val = 0 then 1 else 01217/-- Three rational points. -/1218private abbrev m3Split : Pattern 3 := fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 3 else 01219 1220private theorem allowed_single_one_three_iff (d rt rx : Fin 4) (m : Pattern 3) :1221 Allowed (State.single 1 3) (⟨d, rt, rx, m⟩ : TangentPattern 3) ↔1222 (⟨d, rt, rx, m⟩ : TangentPattern 3) ∈ ({⟨1, 1, 0, fun _ ↦ 0⟩, ⟨2, 2, 0, fun _ ↦ 0⟩,1223 ⟨2, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else 0⟩, ⟨3, 0, 0, m3Inert⟩,1224 ⟨3, 0, 0, m3Quadratic⟩, ⟨3, 0, 0, m3Tangent⟩, ⟨3, 0, 0, m3Split⟩, ⟨3, 0, 0, m3Contact⟩} :1225 Finset (TangentPattern 3)) := by1226 change 0 < d.val ∧ rt.val + rx.val + patternWeight m = d.val ∧ d.val ≤ 3 ∧ rx.val = 0 ∧1227 (0 < rt.val ↔ d.val < 3) ↔ _1228 simp only [patternWeight, Fintype.sum_prod_type, Fin.sum_univ_three, Finset.mem_insert,1229 Finset.mem_singleton, TangentPattern.mk.injEq, funext_iff, Prod.forall, Fin.forall_fin_succ,1230 Fin.ext_iff, Fin.succ_zero_eq_one, Fin.succ_one_eq_two, IsEmpty.forall_iff, and_true,1231 m3Inert, m3Quadratic, m3Tangent, m3Split, m3Contact]1232 simp only [Fin.isValue, Fin.val_zero, Fin.val_one, Fin.val_two, and_self, and_true, and_false,1233 ↓reduceIte, Nat.reduceEqDiff, show ((3 : Fin 4) : ℕ) = 3 from rfl]1234 have := (m (0,0)).isLt; have := (m (0,1)).isLt; have := (m (0,2)).isLt1235 have := (m (1,0)).isLt; have := (m (1,1)).isLt; have := (m (1,2)).isLt1236 have := (m (2,0)).isLt; have := (m (2,1)).isLt; have := (m (2,2)).isLt1237 have := d.isLt; have := rt.isLt; have := rx.isLt1238 generalize (m (0,0)).val = a00 at *; generalize (m (0,1)).val = a01 at *1239 generalize (m (0,2)).val = a02 at *; generalize (m (1,0)).val = a10 at *1240 generalize (m (1,1)).val = a11 at *; generalize (m (1,2)).val = a12 at *1241 generalize (m (2,0)).val = a20 at *; generalize (m (2,1)).val = a21 at *1242 generalize (m (2,2)).val = a22 at *1243 generalize d.val = dd at *; generalize rt.val = r at *; generalize rx.val = x at *1244 constructor1245 · rintro ⟨h1, h2, h3, h4, h5⟩1246 obtain ⟨rfl, rfl, rfl, rfl, rfl⟩ : a11 = 0 ∧ a12 = 0 ∧ a21 = 0 ∧ a22 = 0 ∧ x = 0 := by omega1247 have : a01 ≤ 1 := by omega1248 have : a10 ≤ 1 := by omega1249 have : a02 ≤ 1 := by omega1250 have : a20 ≤ 1 := by omega1251 have : r ≤ 2 := by omega1252 interval_cases dd <;> interval_cases r <;> (try (exfalso; omega)) <;>1253 interval_cases a00 <;> (try (exfalso; omega)) <;> interval_cases a01 <;>1254 (try (exfalso; omega)) <;> interval_cases a10 <;> (try (exfalso; omega)) <;>1255 interval_cases a02 <;> (try (exfalso; omega)) <;> interval_cases a20 <;>1256 (try (exfalso; omega)) <;> simp1257 · rintro (h|h|h|h|h|h|h|h) <;> omega1258 1259open scoped Classical in1260private def allowedThree : Finset (TangentPattern (State.single 1 3).degree) :=1261 {⟨1, 1, 0, fun _ ↦ 0⟩, ⟨2, 2, 0, fun _ ↦ 0⟩,1262 ⟨2, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else 0⟩, ⟨3, 0, 0, m3Inert⟩,1263 ⟨3, 0, 0, m3Quadratic⟩, ⟨3, 0, 0, m3Tangent⟩, ⟨3, 0, 0, m3Split⟩, ⟨3, 0, 0, m3Contact⟩}1264 1265private theorem allowedPatterns_single_one_three :1266 allowedPatterns (.single 1 3) = allowedThree := by1267 classical1268 ext ⟨d, rt, rx, m⟩1269 exact Finset.mem_filter.trans ((and_iff_right (Finset.mem_univ _)).trans1270 (allowed_single_one_three_iff d rt rx m))1271 1272private theorem residuePatterns_three :1273 residuePatterns 3 = {m3Inert, m3Quadratic, m3Tangent, m3Split, m3Contact} := by1274 ext m1275 have h := allowed_single_one_three_iff 3 0 0 m1276 change 0 < 3 ∧ 0 + 0 + patternWeight m = 3 ∧ 3 ≤ 3 ∧ 0 = 0 ∧ (0 < 0 ↔ 3 < 3) ↔ _ at h1277 simp only [residuePatterns, Finset.mem_filter, Finset.mem_univ, true_and]1278 simpa using h1279 1280open scoped Classical in1281private theorem sum_allowed_single_one_three (f : TangentPattern (State.single 1 3).degree → ℚ) :1282 ∑ P ∈ allowedPatterns (.single 1 3), (if SelfPattern (.single 1 3) P then 0 else f P) =1283 f ⟨1, 1, 0, fun _ ↦ 0⟩ + f ⟨2, 2, 0, fun _ ↦ 0⟩ +1284 f ⟨2, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else 0⟩ +1285 f ⟨3, 0, 0, m3Inert⟩ + f ⟨3, 0, 0, m3Quadratic⟩ + f ⟨3, 0, 0, m3Tangent⟩ +1286 f ⟨3, 0, 0, m3Split⟩ := by1287 rw [allowedPatterns_single_one_three, allowedThree]1288 repeat rw [Finset.sum_insert (by decide)]1289 rw [Finset.sum_singleton]1290 simp +decide only [selfPattern_single_iff, if_true, if_false, add_zero, add_assoc]1291 1292/-! ### Degree three: laws -/1293 1294private theorem coeff_m3Inert (q : ℚ) (σ : FactorType) :1295 coeffAt q (childProd (otherChildren 1 m3Inert)) σ = if σ = {(1,3)} then 1 else 0 := by1296 rw [coeff_otherChildren _ [(3, .single 1 1)] (by decide)]; simp_children1297 1298private theorem coeff_m3Quadratic (q : ℚ) (σ : FactorType) :1299 coeffAt q (childProd (otherChildren 1 m3Quadratic)) σ =1300 if σ = (1,1) ::ₘ {(1,2)} then 1 else 0 := by1301 rw [coeff_otherChildren _ [(1, .single 1 1), (2, .single 1 1)] (by decide)]; simp_children1302 1303private theorem coeff_m3Split (q : ℚ) (σ : FactorType) :1304 coeffAt q (childProd (otherChildren 1 m3Split)) σ =1305 if σ = (1,1) ::ₘ (1,1) ::ₘ {(1,1)} then 1 else 0 := by1306 rw [coeff_otherChildren _ [(1, .single 1 1), (1, .single 1 1), (1, .single 1 1)] (by decide)]1307 simp_children1308 1309private theorem coeff_m3Tangent (q : ℚ) (hq : 1 < q) (σ : FactorType) :1310 coeffAt q (childProd (otherChildren 1 m3Tangent)) σ =1311 (if σ = (1,1) ::ₘ {(2,1)} then q/(q+1) else 0) +1312 (if σ = (1,1) ::ₘ (1,1) ::ₘ {(1,1)} then 1/(2*(q+1)) else 0) +1313 (if σ = (1,1) ::ₘ {(1,2)} then 1/(2*(q+1)) else 0) := by1314 rw [coeff_otherChildren _ [(1, .single 1 1), (1, .single 1 2)] (by decide)]1315 simp_children1316 rw [single_two_law 1 one_pos q hq]1317 simp only [ite_add_zero, ite_mem_erase, Multiset.insert_eq_cons]1318 1319private theorem divisorCount_m3 (q : ℚ) :1320 (divisorCount 0 m3Inert).eval q = (q^3 - q) / 3 ∧1321 (divisorCount 0 m3Quadratic).eval q = q * ((q^2 - q) / 2) ∧1322 (divisorCount 0 m3Tangent).eval q = q * (q - 1) ∧1323 (divisorCount 0 m3Split).eval q = q * (q - 1) * (q - 2) / 6 ∧1324 (divisorCount 0 m3Contact).eval q = q := by1325 refine ⟨?_, ?_, ?_, ?_, ?_⟩ <;>1326 simp [divisorCount_eval, Fin.prod_univ_three, Fin.sum_univ_three, falling, eval_prod,1327 availablePoints, Expr.eval, Expr.sub, Expr.neg, List.range_succ, pointCount_two,1328 pointCount_three, m3Inert, m3Quadratic, m3Tangent, m3Split, m3Contact,1329 -mul_eq_mul_left_iff] <;>1330 ring_nf1331 1332private theorem children_single_one_three (m : Pattern 3) :1333 children (.single 1 3) ⟨3, 0, 0, m⟩ = otherChildren (n := 3) 1 m := rfl1334 1335private theorem tangentCount_single_one_three (m : Pattern 3) :1336 tangentCount (.single 1 3) ⟨3, 0, 0, m⟩ = divisorCount (n := 3) 0 m := rfl1337 1338private theorem single_three_law (q : ℚ) (hq : 1 < q) (σ : FactorType) :1339 coeffAt q (stateLaw (.single 1 3)) σ =1340 (if σ = {(3,1)} then q^2*(q^2+1)/(q^4+q^3+q^2+q+1) else 0) +1341 (if σ = {(1,3)} then (q+1)/(3*(q^4+q^3+q^2+q+1)) else 0) +1342 (if σ = {(1,1),(2,1)} then q*(q^3+q^2+1)/((q+1)*(q^4+q^3+q^2+q+1)) else 0) +1343 (if σ = {(1,1),(1,2)} then (q^2+q+1)/(2*(q+1)*(q^4+q^3+q^2+q+1)) else 0) +1344 (if σ = {(1,1),(1,1),(1,1)} then (q^2-q+1)/(6*(q+1)*(q^4+q^3+q^2+q+1)) else 0) := by1345 obtain ⟨d1, d2, d3, d4, -⟩ := divisorCount_m3 q1346 have hq0 : q ≠ 0 := by positivity1347 have h5 : q ^ 5 - 1 ≠ 0 := by have : 1 < q ^ 5 := one_lt_pow₀ hq (by norm_num); linarith1348 have hR : (Expr.inv (.sub (.const 1) (returnWeight 3))).eval q = q ^ 5 / (q ^ 5 - 1) := by1349 rw [returnWeight_eval, show tri 3 = 6 from rfl, inv_eq_iff_eq_inv, inv_div]; field_simp1350 rw [stateLaw_single 1 3 ⟨one_pos, by norm_num⟩ (by norm_num), coeff_scale, coeff_exitLaw,1351 sum_allowed_single_one_three, hR]1352 simp only [children_single_one_three, coeff_m3Inert, coeff_m3Quadratic, coeff_m3Split,1353 coeff_m3Tangent q hq]1354 rw [coeff_childProd_perm (children_single_perm _ (l := [(1, .crossing 1 1 1 2)]) (by decide)),1355 coeff_childProd_perm (children_single_perm _ (l := [(1, .crossing 1 1 2 1)]) (by decide)),1356 coeff_childProd_perm1357 (children_single_perm _ (l := [(1, .single 1 1), (1, .crossing 1 1 1 1)]) (by decide))]1358 simp_children1359 rw [crossing_left_one_law 1 1 2 one_pos one_pos two_pos q hq,1360 crossing_right_one_law 1 1 2 one_pos one_pos two_pos q hq,1361 crossing_one_one_law 1 1 one_pos one_pos q hq]1362 simp only [Expr.eval, tangentCount_single_one_three, d1, d2, d3, d4, ite_mem_erase]1363 simp (disch := decide) only [tangentCount, divisorCount_zero, divisorCount_cell]1364 simp [falling, availablePoints, Expr.prod, divisorProbability, tri, Expr.eval, eval_pow,1365 eminusOne, Expr.sub, Expr.neg, State.degree, Multiset.insert_eq_cons, ite_eq_mul_indicator]1366 have : q + 1 ≠ 0 := by positivity1367 have : q ^ 4 + q ^ 3 + q ^ 2 + q + 1 ≠ 0 := by positivity1368 field_simp1369 ring1370 1371/-- **Cubic monic densities.** For every `q > 1`, the universal monic expressions of degree `3` on1372the five valid cubic types, with `Φ₅(q) = q⁴ + q³ + q² + q + 1`; they vanish on every other type. -/1373theorem monicExpr_three_eval (q : ℚ) (hq : 1 < q) (σ : FactorType) :1374 (monicExpr 3 σ).eval q =1375 (if σ = {(3,1)} then (q ^ 2 + 1) / (q ^ 4 + q ^ 3 + q ^ 2 + q + 1) else 0) +1376 (if σ = {(1,3)} then q ^ 3 * (q + 1) / (3 * (q ^ 4 + q ^ 3 + q ^ 2 + q + 1)) else 0) +1377 (if σ = {(1,1), (2,1)} then1378 q * (q ^ 3 + q + 1) / ((q + 1) * (q ^ 4 + q ^ 3 + q ^ 2 + q + 1)) else 0) +1379 (if σ = {(1,1), (1,2)} then1380 q ^ 3 * (q ^ 2 + q + 1) / (2 * (q + 1) * (q ^ 4 + q ^ 3 + q ^ 2 + q + 1)) else 0) +1381 (if σ = {(1,1), (1,1), (1,1)} then1382 q ^ 3 * (q ^ 2 - q + 1) / (6 * (q + 1) * (q ^ 4 + q ^ 3 + q ^ 2 + q + 1)) else 0) := by1383 obtain ⟨d1, d2, d3, d4, d5⟩ := divisorCount_m3 q1384 rw [monicExpr, coeff_globalLaw, residuePatterns_three]1385 repeat rw [Finset.sum_insert (by decide)]1386 rw [Finset.sum_singleton, coeff_m3Inert, coeff_m3Quadratic, coeff_m3Tangent q hq, coeff_m3Split,1387 coeff_otherChildren _ [(1, .single 1 3)] (by decide)]1388 simp only [childProd, List.map_cons, List.map_nil, lawProd_cons, lawProd_nil, coeff_mul_lawOne,1389 coeff_descend_one, single_three_law q hq, Bool.false_eq_true, if_false]1390 simp [d1, d2, d3, d4, d5, Expr.eval, eval_pow, Multiset.insert_eq_cons, ite_eq_mul_indicator]1391 have : q ≠ 0 := by positivity1392 have : q + 1 ≠ 0 := by positivity1393 have : q ^ 4 + q ^ 3 + q ^ 2 + q + 1 ≠ 0 := by positivity1394 field_simp1395 ring1396 1397end DegreeThree1398 1399/-! ### The law of `T(1,1;2,2)` -/1400 1401/-- The crossing state `T(1,1;2,2)` (tangent conic through the node): a point of degree two, a1402rational point of contact two, or two rational points. -/1403private theorem crossing_two_two_law (q : ℚ) (hq : 1 < q) (σ : FactorType) :Example 9.41404 coeffAt q (stateLaw (.crossing 1 1 2 2)) σ = (if σ = {(4,1)} then 1/(q+1) else 0) +1405 (if σ = {(2,2)} then (q^2+q+1)/(2*q*(q+1)) else 0) +1406 (if σ = {(2,1),(2,1)} then (q^2-q-1)/(2*q*(q+1)) else 0) := by1407 have hn : 2 ≤ (State.crossing 1 1 2 2).degree := by decide1408 set D := (State.crossing 1 1 2 2).degree1409 let i0 : Fin D := ⟨0, by omega⟩1410 let i1 : Fin D := ⟨1, by omega⟩1411 let f1 : Fin (D+1) := ⟨1, by omega⟩1412 let f2 : Fin (D+1) := ⟨2, by omega⟩1413 let P1 : TangentPattern D := ⟨f2, 0, 0, spat (i1, i0) f1⟩1414 let P2 : TangentPattern D := ⟨f2, 0, 0, spat (i0, i1) f1⟩1415 let P3 : TangentPattern D := ⟨f2, 0, 0, spat (i0, i0) f2⟩1416 have hA : allowedPatterns (.crossing 1 1 2 2) = {P1, P2, P3} := by1417 ext P1418 simp only [allowedPatterns, Finset.mem_filter, Finset.mem_univ, true_and, Finset.mem_insert,1419 Finset.mem_singleton]1420 constructor1421 · obtain ⟨d, rt, rx, other⟩ := P1422 rintro ⟨h0, hw, h1, h2, h3, h4⟩1423 simp only at h0 hw h1 h2 h3 h41424 have hd : d.val = 2 := by1425 by_contra hd; have := h3.2 (by omega); have := h4.2 (by omega); omega1426 obtain rfl : rt = 0 :=1427 Fin.ext (by rw [Fin.val_zero]; by_contra hc; have := h3.1 (by omega); omega)1428 obtain rfl : rx = 0 :=1429 Fin.ext (by rw [Fin.val_zero]; by_contra hc; have := h4.1 (by omega); omega)1430 obtain rfl : d = f2 := Fin.ext hd1431 rcases pattern_eq_of_weight_two hn other (by simp at hw; omega) with ho | ho | ho <;> rw [ho]1432 · right; right; rfl1433 · right; left; rfl1434 · left; rfl1435 · rintro (rfl | rfl | rfl) <;> refine ⟨by simp [P1, P2, P3, f2], ?_, ?_⟩ <;>1436 simp [P1, P2, P3, patternWeight_spat, f1, f2, i0, i1]1437 have hi01 : i0 ≠ i1 := by simp [i0, i1]1438 have hne : P1 ≠ P2 ∧ P1 ≠ P3 ∧ P2 ≠ P3 := by1439 refine ⟨fun h ↦ ?_, fun h ↦ ?_, fun h ↦ ?_⟩1440 · simpa [P1, P2, spat, hi01, hi01.symm, f1] using congrArg (fun P ↦ (P.other (i1, i0)).val) h1441 · simpa [P1, P3, spat, hi01.symm, f1] using congrArg (fun P ↦ (P.other (i1, i0)).val) h1442 · simpa [P2, P3, spat, hi01.symm, f1] using congrArg (fun P ↦ (P.other (i0, i1)).val) h1443 have hS : ∀ P, ¬ SelfPattern (.crossing 1 1 2 2) P := by rintro P ⟨_, _, h, _⟩; cases h1444 rw [stateLaw_crossing _ _ _ _ ⟨one_pos, one_pos, two_pos, two_pos⟩, coeff_exitLaw, hA,1445 Finset.sum_insert (by simp [hne]), Finset.sum_insert (by simp [hne]), Finset.sum_singleton]1446 simp only [if_neg (hS _)]1447 have hch1 : children (.crossing 1 1 2 2) P1 = [(2, .single 2 1)] := by1448 simp [children, P1, f1, otherChildren_spat, i0, i1]1449 have hch2 : children (.crossing 1 1 2 2) P2 = [(1, .single 2 2)] := by1450 simp [children, P2, f1, otherChildren_spat, i0, i1]1451 have hch3 : children (.crossing 1 1 2 2) P3 = [(1, .single 2 1), (1, .single 2 1)] := by1452 simp [children, P3, f2, otherChildren_spat, i0]1453 rw [hch1, hch2, hch3]1454 simp_children1455 rw [single_two_law 2 two_pos q hq]1456 have hq0 : q ≠ 0 := by positivity1457 have hq1 : q - 1 ≠ 0 := by linarith1458 have hDP : (divisorProbability (.crossing 1 1 2 2) 2).eval q = 1/(q*(q-1)) := by1459 simp [divisorProbability, chooseTwo, Expr.eval, Expr.pow, eminusOne, Expr.sub, Expr.neg]1460 ring1461 simp only [Expr.eval, show P1.d.val = 2 from rfl, show P2.d.val = 2 from rfl,1462 show P3.d.val = 2 from rfl, hDP]1463 simp [tangentCount, divisorCount_spat, P1, P2, P3, f1, f2, falling, Expr.prod, availablePoints,1464 i0, i1, pointCount_two, List.range_succ, Expr.sub, Expr.neg, Expr.eval, Multiset.insert_eq_cons,1465 ite_eq_mul_indicator]1466 have : q + 1 ≠ 0 := by positivity1467 field_simp1468 ring1469 1470/-! ### Degree four: patterns -/1471 1472section DegreeFour1473 1474/-- One rational point of contact four (the self pattern of `S(1;4)`). -/1475private abbrev m4Contact : Pattern 4 := fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 3 then 1 else 01476/-- One point of degree two and contact two. -/1477private abbrev m4QuadraticContact : Pattern 4 := fun ij ↦1478 if ij.1.val = 1 ∧ ij.2.val = 1 then 1 else 01479/-- One point of degree four. -/1480private abbrev m4Inert : Pattern 4 := fun ij ↦ if ij.1.val = 3 ∧ ij.2.val = 0 then 1 else 01481/-- A rational point of contact two and a point of degree two. -/1482private abbrev m4TangentQuadratic : Pattern 4 := fun ij ↦1483 if ij.1.val = 0 ∧ ij.2.val = 1 then 1 else if ij.1.val = 1 ∧ ij.2.val = 0 then 1 else 01484/-- Two rational points of contact two. -/1485private abbrev m4TwoTangent : Pattern 4 := fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 1 then 2 else 01486/-- Two points of degree two. -/1487private abbrev m4TwoQuadratic : Pattern 4 := fun ij ↦1488 if ij.1.val = 1 ∧ ij.2.val = 0 then 2 else 01489/-- A rational point and a rational point of contact three. -/1490private abbrev m4ContactThree : Pattern 4 := fun ij ↦1491 if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else if ij.1.val = 0 ∧ ij.2.val = 2 then 1 else 01492/-- A rational point and a point of degree three. -/1493private abbrev m4Cubic : Pattern 4 := fun ij ↦1494 if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else if ij.1.val = 2 ∧ ij.2.val = 0 then 1 else 01495/-- Two rational points and a rational point of contact two. -/1496private abbrev m4SplitTangent : Pattern 4 := fun ij ↦1497 if ij.1.val = 0 ∧ ij.2.val = 0 then 2 else if ij.1.val = 0 ∧ ij.2.val = 1 then 1 else 01498/-- Two rational points and a point of degree two. -/1499private abbrev m4SplitQuadratic : Pattern 4 := fun ij ↦1500 if ij.1.val = 0 ∧ ij.2.val = 0 then 2 else if ij.1.val = 1 ∧ ij.2.val = 0 then 1 else 01501/-- Four rational points. -/1502private abbrev m4Split : Pattern 4 := fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 4 else 01503 1504open scoped Classical in1505/-- The allowed patterns of `S(1;4)`. -/1506private def allowedFour : Finset (TangentPattern (State.single 1 4).degree) :=1507 {⟨1, 1, 0, fun _ ↦ 0⟩, ⟨2, 2, 0, fun _ ↦ 0⟩,1508 ⟨2, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else 0⟩, ⟨3, 3, 0, fun _ ↦ 0⟩,1509 ⟨3, 2, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else 0⟩,1510 ⟨3, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 2 else 0⟩,1511 ⟨3, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 1 then 1 else 0⟩,1512 ⟨3, 1, 0, fun ij ↦ if ij.1.val = 1 ∧ ij.2.val = 0 then 1 else 0⟩,1513 ⟨4, 0, 0, m4Split⟩, ⟨4, 0, 0, m4SplitTangent⟩, ⟨4, 0, 0, m4SplitQuadratic⟩,1514 ⟨4, 0, 0, m4ContactThree⟩, ⟨4, 0, 0, m4Cubic⟩, ⟨4, 0, 0, m4TwoTangent⟩,1515 ⟨4, 0, 0, m4TangentQuadratic⟩, ⟨4, 0, 0, m4TwoQuadratic⟩, ⟨4, 0, 0, m4QuadraticContact⟩,1516 ⟨4, 0, 0, m4Inert⟩, ⟨4, 0, 0, m4Contact⟩}1517 1518private theorem allowed_single_one_four_iff (d rt rx : Fin 5) (m : Pattern 4) :1519 Allowed (State.single 1 4) (⟨d, rt, rx, m⟩ : TangentPattern 4) ↔1520 (⟨d, rt, rx, m⟩ : TangentPattern 4) ∈ ({⟨1, 1, 0, fun _ ↦ 0⟩, ⟨2, 2, 0, fun _ ↦ 0⟩,1521 ⟨2, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else 0⟩, ⟨3, 3, 0, fun _ ↦ 0⟩,1522 ⟨3, 2, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else 0⟩,1523 ⟨3, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 2 else 0⟩,1524 ⟨3, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 1 then 1 else 0⟩,1525 ⟨3, 1, 0, fun ij ↦ if ij.1.val = 1 ∧ ij.2.val = 0 then 1 else 0⟩,1526 ⟨4, 0, 0, m4Split⟩, ⟨4, 0, 0, m4SplitTangent⟩, ⟨4, 0, 0, m4SplitQuadratic⟩,1527 ⟨4, 0, 0, m4ContactThree⟩, ⟨4, 0, 0, m4Cubic⟩, ⟨4, 0, 0, m4TwoTangent⟩,1528 ⟨4, 0, 0, m4TangentQuadratic⟩, ⟨4, 0, 0, m4TwoQuadratic⟩, ⟨4, 0, 0, m4QuadraticContact⟩,1529 ⟨4, 0, 0, m4Inert⟩, ⟨4, 0, 0, m4Contact⟩} : Finset (TangentPattern 4)) := by1530 have fa4 (p : Fin 4 → Prop) : (∀ i, p i) ↔ p 0 ∧ p 1 ∧ p 2 ∧ p 3 :=1531 ⟨fun h ↦ ⟨h 0, h 1, h 2, h 3⟩, fun ⟨h0, h1, h2, h3⟩ i ↦ by fin_cases i <;> assumption⟩1532 change 0 < d.val ∧ rt.val + rx.val + patternWeight m = d.val ∧ d.val ≤ 4 ∧ rx.val = 0 ∧1533 (0 < rt.val ↔ d.val < 4) ↔ _1534 simp only [patternWeight, Fintype.sum_prod_type, Fin.sum_univ_four,1535 Finset.mem_insert, Finset.mem_singleton, TangentPattern.mk.injEq, funext_iff, Prod.forall, fa4,1536 Fin.ext_iff, m4Contact, m4QuadraticContact, m4Inert, m4TangentQuadratic, m4TwoTangent,1537 m4TwoQuadratic, m4ContactThree, m4Cubic, m4SplitTangent, m4SplitQuadratic, m4Split]1538 simp only [Fin.isValue, Fin.val_zero, Fin.val_one, Fin.val_two, and_self, and_true, and_false,1539 ↓reduceIte, Nat.reduceEqDiff, show ((3 : Fin 5) : ℕ) = 3 from rfl,1540 show ((4 : Fin 5) : ℕ) = 4 from rfl, show ((3 : Fin 4) : ℕ) = 3 from rfl]1541 have := (m (0,0)).isLt; have := (m (0,1)).isLt; have := (m (0,2)).isLt; have := (m (0,3)).isLt1542 have := (m (1,0)).isLt; have := (m (1,1)).isLt; have := (m (1,2)).isLt; have := (m (1,3)).isLt1543 have := (m (2,0)).isLt; have := (m (2,1)).isLt; have := (m (2,2)).isLt; have := (m (2,3)).isLt1544 have := (m (3,0)).isLt; have := (m (3,1)).isLt; have := (m (3,2)).isLt; have := (m (3,3)).isLt1545 have := d.isLt; have := rt.isLt; have := rx.isLt1546 generalize (m (0,0)).val = a00 at *; generalize (m (0,1)).val = a01 at *1547 generalize (m (0,2)).val = a02 at *; generalize (m (0,3)).val = a03 at *1548 generalize (m (1,0)).val = a10 at *; generalize (m (1,1)).val = a11 at *1549 generalize (m (1,2)).val = a12 at *; generalize (m (1,3)).val = a13 at *1550 generalize (m (2,0)).val = a20 at *; generalize (m (2,1)).val = a21 at *1551 generalize (m (2,2)).val = a22 at *; generalize (m (2,3)).val = a23 at *1552 generalize (m (3,0)).val = a30 at *; generalize (m (3,1)).val = a31 at *1553 generalize (m (3,2)).val = a32 at *; generalize (m (3,3)).val = a33 at *1554 generalize d.val = dd at *; generalize rt.val = r at *; generalize rx.val = x at *1555 constructor1556 · rintro ⟨h1, h2, h3, h4, h5⟩1557 obtain ⟨rfl, rfl, rfl, rfl, rfl, rfl, rfl, rfl, rfl⟩ : a12 = 0 ∧ a13 = 0 ∧ a21 = 0 ∧ a22 = 0 ∧1558 a23 = 0 ∧ a31 = 0 ∧ a32 = 0 ∧ a33 = 0 ∧ x = 0 := by omega1559 have : a01 ≤ 2 := by omega1560 have : a02 ≤ 1 := by omega1561 have : a03 ≤ 1 := by omega1562 have : a10 ≤ 2 := by omega1563 have : a11 ≤ 1 := by omega1564 have : a20 ≤ 1 := by omega1565 have : a30 ≤ 1 := by omega1566 have : r ≤ 3 := by omega1567 interval_cases dd <;> interval_cases r <;> (try (exfalso; omega)) <;>1568 interval_cases a00 <;> (try (exfalso; omega)) <;> interval_cases a01 <;>1569 (try (exfalso; omega)) <;> interval_cases a02 <;> (try (exfalso; omega)) <;>1570 interval_cases a03 <;> (try (exfalso; omega)) <;> interval_cases a10 <;>1571 (try (exfalso; omega)) <;> interval_cases a11 <;> (try (exfalso; omega)) <;>1572 interval_cases a20 <;> (try (exfalso; omega)) <;> interval_cases a30 <;>1573 (try (exfalso; omega)) <;> simp1574 · rintro (h|h|h|h|h|h|h|h|h|h|h|h|h|h|h|h|h|h|h) <;> omega1575 1576private theorem allowedPatterns_single_one_four : allowedPatterns (.single 1 4) = allowedFour := by1577 classical1578 ext ⟨d, rt, rx, m⟩1579 exact Finset.mem_filter.trans ((and_iff_right (Finset.mem_univ _)).trans1580 (allowed_single_one_four_iff d rt rx m))1581 1582private theorem residuePatterns_four :1583 residuePatterns 4 = {m4Split, m4SplitTangent, m4SplitQuadratic, m4ContactThree, m4Cubic,1584 m4TwoTangent, m4TangentQuadratic, m4TwoQuadratic, m4QuadraticContact, m4Inert,1585 m4Contact} := by1586 ext m1587 have h := allowed_single_one_four_iff 4 0 0 m1588 change 0 < 4 ∧ 0 + 0 + patternWeight m = 4 ∧ 4 ≤ 4 ∧ 0 = 0 ∧ (0 < 0 ↔ 4 < 4) ↔ _ at h1589 simp only [residuePatterns, Finset.mem_filter, Finset.mem_univ, true_and]1590 simpa using h1591 1592open scoped Classical in1593private theorem sum_allowed_single_one_four (f : TangentPattern (State.single 1 4).degree → ℚ) :1594 ∑ P ∈ allowedPatterns (.single 1 4), (if SelfPattern (.single 1 4) P then 0 else f P) =1595 f ⟨1, 1, 0, fun _ ↦ 0⟩ + f ⟨2, 2, 0, fun _ ↦ 0⟩ +1596 f ⟨2, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else 0⟩ +1597 f ⟨3, 3, 0, fun _ ↦ 0⟩ +1598 f ⟨3, 2, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 1 else 0⟩ +1599 f ⟨3, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 0 then 2 else 0⟩ +1600 f ⟨3, 1, 0, fun ij ↦ if ij.1.val = 0 ∧ ij.2.val = 1 then 1 else 0⟩ +1601 f ⟨3, 1, 0, fun ij ↦ if ij.1.val = 1 ∧ ij.2.val = 0 then 1 else 0⟩ +1602 f ⟨4, 0, 0, m4Split⟩ + f ⟨4, 0, 0, m4SplitTangent⟩ + f ⟨4, 0, 0, m4SplitQuadratic⟩ +1603 f ⟨4, 0, 0, m4ContactThree⟩ + f ⟨4, 0, 0, m4Cubic⟩ + f ⟨4, 0, 0, m4TwoTangent⟩ +1604 f ⟨4, 0, 0, m4TangentQuadratic⟩ + f ⟨4, 0, 0, m4TwoQuadratic⟩ +1605 f ⟨4, 0, 0, m4QuadraticContact⟩ + f ⟨4, 0, 0, m4Inert⟩ := by1606 rw [allowedPatterns_single_one_four, allowedFour]1607 repeat rw [Finset.sum_insert (by decide)]1608 rw [Finset.sum_singleton]1609 simp +decide only [selfPattern_single_iff, if_true, if_false, add_zero, add_assoc]1610 1611/-! ### Degree four: laws at `q = 2` -/1612 1613private theorem single_two_law_at_two (σ : FactorType) : coeffAt 2 (stateLaw (.single 1 2)) σ =1614 (if σ = {(2,1)} then 2/3 else 0) + (if σ = (1,1) ::ₘ {(1,1)} then 1/6 else 0) +1615 (if σ = {(1,2)} then 1/6 else 0) := by1616 rw [single_two_law 1 one_pos 2 (by norm_num)]; norm_num [Multiset.insert_eq_cons]1617 1618private theorem single_two_law_at_four (σ : FactorType) :1619 coeffAt (2^2) (stateLaw (.single 1 2)) σ =1620 (if σ = {(2,1)} then 4/5 else 0) + (if σ = (1,1) ::ₘ {(1,1)} then 1/10 else 0) +1621 (if σ = {(1,2)} then 1/10 else 0) := by1622 rw [single_two_law 1 one_pos (2^2) (by norm_num)]; norm_num [Multiset.insert_eq_cons]1623 1624private theorem single_three_law_at_two (σ : FactorType) : coeffAt 2 (stateLaw (.single 1 3)) σ =1625 (if σ = {(3,1)} then 20/31 else 0) + (if σ = {(1,3)} then 1/31 else 0) +1626 (if σ = (1,1) ::ₘ {(2,1)} then 26/93 else 0) + (if σ = (1,1) ::ₘ {(1,2)} then 7/186 else 0) +1627 (if σ = (1,1) ::ₘ (1,1) ::ₘ {(1,1)} then 1/186 else 0) := by1628 rw [single_three_law 2 (by norm_num)]; norm_num [Multiset.insert_eq_cons]1629 1630private theorem crossing_two_two_law_at_two (σ : FactorType) :Example 9.41631 coeffAt 2 (stateLaw (.crossing 1 1 2 2)) σ = (if σ = {(4,1)} then 1/3 else 0) +1632 (if σ = {(2,2)} then 7/12 else 0) + (if σ = (2,1) ::ₘ {(2,1)} then 1/12 else 0) := by1633 rw [crossing_two_two_law 2 (by norm_num)]; norm_num [Multiset.insert_eq_cons]1634 1635private theorem coeff_m4Inert (q : ℚ) (σ : FactorType) :1636 coeffAt q (childProd (otherChildren 1 m4Inert)) σ = if σ = {(1,4)} then 1 else 0 := by1637 rw [coeff_otherChildren _ [(4, .single 1 1)] (by decide)]; simp_children1638 1639private theorem coeff_m4Cubic (q : ℚ) (σ : FactorType) :1640 coeffAt q (childProd (otherChildren 1 m4Cubic)) σ = if σ = (1,1) ::ₘ {(1,3)} then 1 else 0 := by1641 rw [coeff_otherChildren _ [(1, .single 1 1), (3, .single 1 1)] (by decide)]; simp_children1642 1643private theorem coeff_m4SplitQuadratic (q : ℚ) (σ : FactorType) :1644 coeffAt q (childProd (otherChildren 1 m4SplitQuadratic)) σ =1645 if σ = (1,1) ::ₘ (1,1) ::ₘ {(1,2)} then 1 else 0 := by1646 rw [coeff_otherChildren _ [(1, .single 1 1), (1, .single 1 1), (2, .single 1 1)] (by decide)]1647 simp_children1648 1649private theorem coeff_m4ContactThree (σ : FactorType) :1650 coeffAt 2 (childProd (otherChildren 1 m4ContactThree)) σ =1651 (if σ = (1,1) ::ₘ {(3,1)} then 20/31 else 0) + (if σ = (1,1) ::ₘ {(1,3)} then 1/31 else 0) +1652 (if σ = (1,1) ::ₘ (1,1) ::ₘ {(2,1)} then 26/93 else 0) +1653 (if σ = (1,1) ::ₘ (1,1) ::ₘ {(1,2)} then 7/186 else 0) +1654 (if σ = (1,1) ::ₘ (1,1) ::ₘ (1,1) ::ₘ {(1,1)} then 1/186 else 0) := by1655 rw [coeff_otherChildren _ [(1, .single 1 1), (1, .single 1 3)] (by decide)]1656 simp_children1657 rw [single_three_law_at_two]1658 simp only [ite_add_zero, ite_mem_erase]1659 1660private theorem coeff_m4TangentQuadratic (σ : FactorType) :1661 coeffAt 2 (childProd (otherChildren 1 m4TangentQuadratic)) σ =1662 (if σ = (1,2) ::ₘ {(2,1)} then 2/3 else 0) +1663 (if σ = (1,2) ::ₘ (1,1) ::ₘ {(1,1)} then 1/6 else 0) +1664 (if σ = (1,2) ::ₘ {(1,2)} then 1/6 else 0) := by1665 rw [coeff_otherChildren _ [(2, .single 1 1), (1, .single 1 2)] (by decide)]1666 simp_children1667 rw [single_two_law_at_two]1668 simp only [ite_add_zero, ite_mem_erase]1669 1670private theorem coeff_m4SplitTangent (σ : FactorType) :1671 coeffAt 2 (childProd (otherChildren 1 m4SplitTangent)) σ =1672 (if σ = (1,1) ::ₘ (1,1) ::ₘ {(2,1)} then 2/3 else 0) +1673 (if σ = (1,1) ::ₘ (1,1) ::ₘ (1,1) ::ₘ {(1,1)} then 1/6 else 0) +1674 (if σ = (1,1) ::ₘ (1,1) ::ₘ {(1,2)} then 1/6 else 0) := by1675 rw [coeff_otherChildren _ [(1, .single 1 1), (1, .single 1 1), (1, .single 1 2)] (by decide)]1676 simp_children1677 rw [single_two_law_at_two]1678 simp only [ite_add_zero, ite_mem_erase]1679 1680private theorem coeff_m4QuadraticContact (σ : FactorType) :1681 coeffAt 2 (childProd (otherChildren 1 m4QuadraticContact)) σ =1682 (if σ = {(2,2)} then 4/5 else 0) + (if σ = (1,2) ::ₘ {(1,2)} then 1/10 else 0) +1683 (if σ = {(1,4)} then 1/10 else 0) := by1684 rw [coeff_otherChildren _ [(2, .single 1 2)] (by decide)]1685 simp only [childProd, List.map_cons, List.map_nil, lawProd_cons, lawProd_nil, coeff_mul_lawOne]1686 rw [show ({(2,2)} : FactorType) = scaleType 2 {(2,1)} by decide,1687 show ((1,2) ::ₘ {(1,2)} : FactorType) = scaleType 2 ((1,1) ::ₘ {(1,1)}) by decide,1688 show ({(1,4)} : FactorType) = scaleType 2 {(1,2)} by decide]1689 by_cases h : ∃ τ, σ = scaleType 2 τ1690 · obtain ⟨τ, rfl⟩ := h1691 rw [coeff_descend_scaleType 2 two_pos, single_two_law_at_four]1692 simp only [(scaleType_injective two_pos).eq_iff]1693 · push Not at h1694 rw [coeff_descend_of_ne 2 2 _ σ h, if_neg (h _), if_neg (h _), if_neg (h _)]1695 norm_num1696 1697private theorem coeff_m4TwoTangent (σ : FactorType) :1698 coeffAt 2 (childProd (otherChildren 1 m4TwoTangent)) σ =1699 (if σ = {(2,1)} + {(2,1)} then 2/3 * (2/3) else 0) +1700 (if σ = {(2,1)} + (1,1) ::ₘ {(1,1)} then 2/3 * (1/6) else 0) +1701 (if σ = {(2,1)} + {(1,2)} then 2/3 * (1/6) else 0) +1702 ((if σ = (1,1) ::ₘ {(1,1)} + {(2,1)} then 1/6 * (2/3) else 0) +1703 (if σ = (1,1) ::ₘ {(1,1)} + (1,1) ::ₘ {(1,1)} then 1/6 * (1/6) else 0) +1704 (if σ = (1,1) ::ₘ {(1,1)} + {(1,2)} then 1/6 * (1/6) else 0)) +1705 ((if σ = {(1,2)} + {(2,1)} then 1/6 * (2/3) else 0) +1706 (if σ = {(1,2)} + (1,1) ::ₘ {(1,1)} then 1/6 * (1/6) else 0) +1707 (if σ = {(1,2)} + {(1,2)} then 1/6 * (1/6) else 0)) := by1708 rw [coeff_otherChildren _ [(1, .single 1 2), (1, .single 1 2)] (by decide)]1709 simp only [childProd, List.map_cons, List.map_nil, lawProd_cons]1710 have hS : ∀ τ ∉ ({{(2,1)}, (1,1) ::ₘ {(1,1)}, {(1,2)}} : Finset FactorType),1711 coeffAt 2 (lawDescend 1 (stateLaw (.single 1 2))) τ = 0 := by1712 intro τ h1713 simp only [Finset.mem_insert, Finset.mem_singleton, not_or] at h1714 rw [coeff_descend_one, single_two_law_at_two, if_neg h.1, if_neg h.2.1, if_neg h.2.2]; simp1715 rw [coeff_mul 2 _ _ _ hS, Finset.sum_insert (by decide), Finset.sum_insert (by decide),1716 Finset.sum_singleton]1717 simp only [lawProd_nil, coeff_mul_lawOne, coeff_descend_one, single_two_law_at_two]1718 simp +decide only [if_true, if_false, add_zero, zero_add]1719 simp only [mul_add, ite_add_zero, ite_le_sub]1720 ring1721 1722private theorem children_single_one_four (m : Pattern 4) :1723 children (.single 1 4) ⟨4, 0, 0, m⟩ = otherChildren (n := 4) 1 m := rfl1724 1725private theorem tangentCount_single_one_four (m : Pattern 4) :1726 tangentCount (.single 1 4) ⟨4, 0, 0, m⟩ = divisorCount (n := 4) 0 m := rfl1727 1728private theorem divisorCount_m4_at_two :1729 (divisorCount 0 m4Split).eval 2 = 0 ∧ (divisorCount 0 m4SplitTangent).eval 2 = 0 ∧1730 (divisorCount 0 m4SplitQuadratic).eval 2 = 1 ∧ (divisorCount 0 m4ContactThree).eval 2 = 2 ∧1731 (divisorCount 0 m4Cubic).eval 2 = 4 ∧ (divisorCount 0 m4TwoTangent).eval 2 = 1 ∧1732 (divisorCount 0 m4TangentQuadratic).eval 2 = 2 ∧ (divisorCount 0 m4TwoQuadratic).eval 2 = 0 ∧1733 (divisorCount 0 m4QuadraticContact).eval 2 = 1 ∧ (divisorCount 0 m4Inert).eval 2 = 3 ∧1734 (divisorCount 0 m4Contact).eval 2 = 2 := by1735 refine ⟨?_, ?_, ?_, ?_, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩ <;>1736 simp [divisorCount_eval, Fin.prod_univ_four, Fin.sum_univ_four, falling, eval_prod,1737 availablePoints, Expr.eval, Expr.sub, Expr.neg, List.range_succ, pointCount_two,1738 pointCount_three, pointCount_four, m4Split, m4SplitTangent, m4SplitQuadratic, m4ContactThree,1739 m4Cubic, m4TwoTangent, m4TangentQuadratic, m4TwoQuadratic, m4QuadraticContact, m4Inert,1740 m4Contact] <;> norm_num [Nat.factorial]1741 1742/-- The children `T(1,1;1,1)` and `S(1;2)` (from the tangent pattern of `S(1;4)` with a point of1743contact two). -/1744private theorem coeff_crossing_one_one_single_two_at_two (σ : FactorType) :1745 coeffAt 2 (childProd [(1, .crossing 1 1 1 1), (1, .single 1 2)]) σ =1746 (if σ = {(2,1)} + {(2,1)} then 2/3 else 0) +1747 (if σ = {(2,1)} + (1,1) ::ₘ {(1,1)} then 1/6 else 0) +1748 (if σ = {(2,1)} + {(1,2)} then 1/6 else 0) := by1749 have hS : ∀ τ ∉ ({{(2,1)}} : Finset FactorType),1750 coeffAt 2 (lawDescend 1 (stateLaw (.crossing 1 1 1 1))) τ = 0 := fun τ h ↦ by1751 rw [coeff_descend_one, crossing_one_one_law 1 1 one_pos one_pos 2 (by norm_num),1752 if_neg (Finset.mem_singleton.not.1 h)]1753 simp only [childProd, List.map_cons, List.map_nil, lawProd_cons]1754 rw [coeff_mul 2 _ _ _ hS, Finset.sum_singleton, coeff_descend_one,1755 crossing_one_one_law 1 1 one_pos one_pos 2 (by norm_num), if_pos rfl, lawProd_nil,1756 coeff_mul_lawOne, coeff_descend_one, single_two_law_at_two]1757 simp only [one_mul, ite_add_zero, ite_le_sub_one]1758 1759private theorem single_four_law_at_two (σ : FactorType) :1760 coeffAt 2 (stateLaw (.single 1 4)) σ = (if σ = {(4,1)} then 856/1533 else 0) +1761 (if σ = {(2,2)} then 566/7665 else 0) + (if σ = {(1,4)} then 31/10220 else 0) +1762 (if σ = {(2,1),(2,1)} then 2/63 else 0) + (if σ = {(1,2),(1,2)} then 83/183960 else 0) +1763 (if σ = {(1,2),(2,1)} then 103/4599 else 0) +1764 (if σ = {(1,1),(3,1)} then 4484/15841 else 0) + (if σ = {(1,1),(1,3)} then 9/2263 else 0) +1765 (if σ = {(1,1),(1,1),(2,1)} then 3085/142569 else 0) +1766 (if σ = {(1,1),(1,1),(1,2)} then 817/570276 else 0) +1767 (if σ = {(1,1),(1,1),(1,1),(1,1)} then 43/1140552 else 0) := by1768 obtain ⟨d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, -⟩ := divisorCount_m4_at_two1769 have hR : (Expr.inv (.sub (.const 1) (returnWeight 4))).eval 2 = 512/511 := by1770 rw [returnWeight_eval, show tri 4 = 10 from rfl]; norm_num1771 rw [stateLaw_single 1 4 ⟨one_pos, by norm_num⟩ (by norm_num), coeff_scale, coeff_exitLaw,1772 sum_allowed_single_one_four, hR]1773 simp only [children_single_one_four, coeff_m4Inert, coeff_m4Cubic, coeff_m4SplitQuadratic,1774 coeff_m4ContactThree, coeff_m4TangentQuadratic, coeff_m4TwoTangent, coeff_m4QuadraticContact]1775 rw [coeff_childProd_perm (children_single_perm _ (l := [(1, .crossing 1 1 1 3)]) (by decide)),1776 coeff_childProd_perm (children_single_perm _ (l := [(1, .crossing 1 1 2 2)]) (by decide)),1777 coeff_childProd_perm1778 (children_single_perm _ (l := [(1, .single 1 1), (1, .crossing 1 1 1 2)]) (by decide)),1779 coeff_childProd_perm (children_single_perm _ (l := [(1, .crossing 1 1 3 1)]) (by decide)),1780 coeff_childProd_perm1781 (children_single_perm _ (l := [(1, .single 1 1), (1, .crossing 1 1 2 1)]) (by decide)),1782 coeff_childProd_perm (children_single_perm _1783 (l := [(1, .single 1 1), (1, .single 1 1), (1, .crossing 1 1 1 1)]) (by decide)),1784 coeff_childProd_perm1785 (children_single_perm _ (l := [(1, .crossing 1 1 1 1), (1, .single 1 2)]) (by decide)),1786 coeff_childProd_perm1787 (children_single_perm _ (l := [(2, .single 1 1), (1, .crossing 1 1 1 1)]) (by decide)),1788 coeff_crossing_one_one_single_two_at_two]1789 simp_children1790 simp only [crossing_left_one_law 1 1 3 one_pos one_pos (by norm_num) 2 (by norm_num),1791 crossing_two_two_law_at_two,1792 crossing_left_one_law 1 1 2 one_pos one_pos two_pos 2 (by norm_num),1793 crossing_right_one_law 1 1 3 one_pos one_pos (by norm_num) 2 (by norm_num),1794 crossing_right_one_law 1 1 2 one_pos one_pos two_pos 2 (by norm_num),1795 crossing_one_one_law 1 1 one_pos one_pos 2 (by norm_num)]1796 simp only [Expr.eval, tangentCount_single_one_four, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10,1797 ite_mem_erase, zero_mul]1798 simp only [ite_eq_mul_indicator]1799 simp (disch := decide) only [tangentCount, divisorCount_zero, divisorCount_cell]1800 simp only [divisorProbability, tri, State.degree, Nat.reduceMul, Nat.reduceAdd, Fin.isValue,1801 Fin.coe_ofNat_eq_mod, one_mul, Nat.one_mod, Order.lt_two_iff, zero_le, Nat.div_self, eminusOne,1802 Expr.sub, Expr.neg, Nat.one_lt_ofNat, ↓reduceIte, Expr.eval, eval_pow, pow_one, mul_one,1803 Nat.reduceMod, Nat.reduceDiv, Nat.reduceLT, one_div, falling, availablePoints, zero_add,1804 Int.cast_zero, List.range_succ, List.range_zero, List.nil_append, List.pure_def,1805 List.bind_eq_flatMap, List.flatMap_cons, CharP.cast_eq_zero, List.flatMap_nil, List.append_nil,1806 List.map_cons, List.map_nil, eval_prod, add_zero, mul_zero, List.prod_cons, List.prod_nil,1807 Nat.factorial_one, Nat.cast_one, div_one, Nat.lt_add_one, List.cons_append, Nat.factorial_two,1808 Nat.cast_ofNat, ne_eq, OfNat.ofNat_ne_zero, not_false_eq_true, mul_div_cancel_left₀,1809 Multiset.singleton_add, Multiset.add_cons, OfNat.ofNat_ne_one, pointCount_two, Nat.mod_succ,1810 lt_self_iff_false, pow_zero, Multiset.cons_add, Multiset.insert_eq_cons]1811 sort_types1812 ring1813 1814private theorem divisorCount_m4_projective_at_two :1815 (divisorCount 1 m4Split).eval 2 = 0 ∧ (divisorCount 1 m4SplitTangent).eval 2 = 3 ∧1816 (divisorCount 1 m4SplitQuadratic).eval 2 = 3 ∧ (divisorCount 1 m4ContactThree).eval 2 = 6 ∧1817 (divisorCount 1 m4Cubic).eval 2 = 6 ∧ (divisorCount 1 m4TwoTangent).eval 2 = 3 ∧1818 (divisorCount 1 m4TangentQuadratic).eval 2 = 3 ∧ (divisorCount 1 m4TwoQuadratic).eval 2 = 0 ∧1819 (divisorCount 1 m4QuadraticContact).eval 2 = 1 ∧ (divisorCount 1 m4Inert).eval 2 = 3 ∧1820 (divisorCount 1 m4Contact).eval 2 = 3 := by1821 refine ⟨?_, ?_, ?_, ?_, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩ <;>1822 simp [divisorCount_eval, Fin.prod_univ_four, Fin.sum_univ_four, falling, eval_prod,1823 availablePoints, Expr.eval, Expr.sub, Expr.neg, List.range_succ, pointCount_two,1824 pointCount_three, pointCount_four, m4Split, m4SplitTangent, m4SplitQuadratic, m4ContactThree,1825 m4Cubic, m4TwoTangent, m4TangentQuadratic, m4TwoQuadratic, m4QuadraticContact, m4Inert,1826 m4Contact] <;> norm_num [Nat.factorial]1827 1828private theorem coeff_m4Contact_at_two (σ : FactorType) :1829 coeffAt 2 (childProd (otherChildren 1 m4Contact)) σ = coeffAt 2 (stateLaw (.single 1 4)) σ := by1830 rw [coeff_otherChildren _ [(1, .single 1 4)] (by decide)]1831 simp only [childProd, List.map_cons, List.map_nil, lawProd_cons, lawProd_nil, coeff_mul_lawOne,1832 coeff_descend_one]1833 1834/-- **Quartic monic densities at `q = 2`.** The values at `q = 2` of the universal monic1835expressions of degree `4` on all eleven valid quartic types (and `0` on every other type). -/1836theorem monicExpr_four_eval_two (σ : FactorType) :1837 (monicExpr 4 σ).eval 2 =1838 (if σ = {(4,1)} then 107/1533 else 0) + (if σ = {(2,2)} then 454/7665 else 0) +1839 (if σ = {(1,4)} then 496/2555 else 0) + (if σ = {(2,1), (2,1)} then 2/63 else 0) +1840 (if σ = {(1,2), (1,2)} then 664/22995 else 0) +1841 (if σ = {(1,2), (2,1)} then 460/4599 else 0) +1842 (if σ = {(1,1), (3,1)} then 1838/15841 else 0) +1843 (if σ = {(1,1), (1,3)} then 576/2263 else 0) +1844 (if σ = {(1,1), (1,1), (2,1)} then 7348/142569 else 0) +1845 (if σ = {(1,1), (1,1), (1,2)} then 13072/142569 else 0) +1846 (if σ = {(1,1), (1,1), (1,1), (1,1)} then 344/142569 else 0) := by1847 obtain ⟨d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11⟩ := divisorCount_m4_at_two1848 rw [monicExpr, coeff_globalLaw, residuePatterns_four]1849 repeat rw [Finset.sum_insert (by decide)]1850 rw [Finset.sum_singleton]1851 simp only [Bool.false_eq_true, if_false, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, zero_mul,1852 zero_add, coeff_m4Inert, coeff_m4Cubic, coeff_m4SplitQuadratic, coeff_m4ContactThree,1853 coeff_m4TangentQuadratic, coeff_m4TwoTangent, coeff_m4QuadraticContact, coeff_m4Contact_at_two,1854 single_four_law_at_two]1855 simp only [ite_eq_mul_indicator]1856 simp only [Expr.eval, eval_pow]1857 sort_types1858 ring1859 1860/-- **Quartic projective densities at `q = 2`.** The values at `q = 2` of the universal projective1861expressions of degree `4` on all eleven valid quartic types (and `0` on every other type). -/1862theorem projectiveExpr_four_eval_two (σ : FactorType) :1863 (projectiveExpr 4 σ).eval 2 =1864 (if σ = {(4,1)} then 856/15841 else 0) + (if σ = {(2,2)} then 522/15841 else 0) +1865 (if σ = {(1,4)} then 205/2044 else 0) + (if σ = {(2,1), (2,1)} then 10/217 else 0) +1866 (if σ = {(1,2), (1,2)} then 2799/126728 else 0) +1867 (if σ = {(1,2), (2,1)} then 1397/15841 else 0) +1868 (if σ = {(1,1), (3,1)} then 2412/15841 else 0) +1869 (if σ = {(1,1), (1,3)} then 453/2263 else 0) +1870 (if σ = {(1,1), (1,1), (2,1)} then 2253/15841 else 0) +1871 (if σ = {(1,1), (1,1), (1,2)} then 8987/63364 else 0) +1872 (if σ = {(1,1), (1,1), (1,1), (1,1)} then 2517/126728 else 0) := by1873 obtain ⟨d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11⟩ := divisorCount_m4_projective_at_two1874 rw [projectiveExpr, coeff_globalLaw, residuePatterns_four]1875 repeat rw [Finset.sum_insert (by decide)]1876 rw [Finset.sum_singleton]1877 simp only [if_true, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, zero_mul, zero_add,1878 coeff_m4Inert, coeff_m4Cubic, coeff_m4SplitQuadratic, coeff_m4ContactThree,1879 coeff_m4TangentQuadratic, coeff_m4TwoTangent, coeff_m4QuadraticContact, coeff_m4Contact_at_two,1880 coeff_m4SplitTangent, single_four_law_at_two]1881 simp only [ite_eq_mul_indicator]1882 simp only [Expr.eval, projectiveNormalizer, eval_sum, List.range_succ, List.range_zero,1883 List.map_append, List.map_cons, List.map_nil, eval_pow]1884 sort_types1885 norm_num1886 ring1887 1888end DegreeFour1889 1890/-! ### Regression guards: point values of the universal expressions -/1891 1892/-- The three quadratic monic types are equidistributed at `q = 2`: split. -/1893theorem monicExpr_two_split_eval_two : (monicExpr 2 {(1,1), (1,1)}).eval 2 = 1/3 := by1894 rw [monicExpr_two_eval 2 one_lt_two]; simp +decide; norm_num1895 1896/-- The three quadratic monic types are equidistributed at `q = 2`: inert. -/1897theorem monicExpr_two_inert_eval_two : (monicExpr 2 {(1,2)}).eval 2 = 1/3 := by1898 rw [monicExpr_two_eval 2 one_lt_two]; simp +decide; norm_num1899 1900/-- The three quadratic monic types are equidistributed at `q = 2`: ramified. -/1901theorem monicExpr_two_ramified_eval_two : (monicExpr 2 {(2,1)}).eval 2 = 1/3 := byExample 7.31902 rw [monicExpr_two_eval 2 one_lt_two]; simp +decide; norm_num1903 1904/-- Totally ramified cubics at `q = 3`: `A_{3,(3,1)}(3) = 10/121`. -/1905theorem monicExpr_three_totally_ramified_eval_three : (monicExpr 3 {(3,1)}).eval 3 = 10/121 := by(10.8)1906 rw [monicExpr_three_eval 3 (by norm_num)]; simp +decide; norm_num1907 1908/-- Totally ramified quartics at `q = 2`: `A_{4,(4,1)}(2) = 107/1533`. -/1909theorem monicExpr_four_totally_ramified_eval_two : (monicExpr 4 {(4,1)}).eval 2 = 107/1533 := byExample 10.41910 rw [monicExpr_four_eval_two]; simp +decide1911 1912/-- Totally ramified binary quartic forms at `q = 2`: `B_{4,(4,1)}(2) = 856/15841`. -/1913theorem projectiveExpr_four_totally_ramified_eval_two :Example 10.41914 (projectiveExpr 4 {(4,1)}).eval 2 = 856/15841 := by1915 rw [projectiveExpr_four_eval_two]; simp +decide1916 1917/-- Quartics generating a ramified quadratic extension of a quadratic one (type `(2,2)`) at1918`q = 2`: `454/7665`. -/1919theorem monicExpr_four_ramified_quadratic_eval_two : (monicExpr 4 {(2,2)}).eval 2 = 454/7665 := by1920 rw [monicExpr_four_eval_two]; simp +decide1921 1922/-- Products of two distinct inert quadratics (type `(1,2),(1,2)`) at `q = 2`: `664/22995`. -/1923theorem monicExpr_four_two_inert_quadratics_eval_two :1924 (monicExpr 4 {(1,2), (1,2)}).eval 2 = 664/22995 := by1925 rw [monicExpr_four_eval_two]; simp +decide1926 1927/-! ### Density corollaries of `main_dvr` -/1928 1929section Densities1930 1931open IsLocalRing1932 1933variable (O : Type) [CommRing O] [IsDomain O] [IsDiscreteValuationRing O]1934 [IsAdicComplete (maximalIdeal O) O] [Finite (ResidueField O)] [TopologicalSpace O]1935 [IsTopologicalRing O] [CompactSpace O] [T2Space O] [SecondCountableTopology O]1936 [MeasurableSpace O] [BorelSpace O]1937 1938private theorem densityValue_eq {x : Expr} {q : ℕ} {r : ℚ} (h : x.eval q = r) :1939 densityValue x q = ENNReal.ofReal r := by1940 rw [densityValue, h]1941 1942omit [IsAdicComplete (maximalIdeal O) O] [TopologicalSpace O] [IsTopologicalRing O] [CompactSpace O]1943 [T2Space O] [SecondCountableTopology O] [MeasurableSpace O] [BorelSpace O] in1944private theorem one_lt_card_residueField : 1 < (Nat.card (ResidueField O) : ℚ) := by1945 exact_mod_cast Finite.one_lt_card1946 1947/-- Over any complete DVR with finite residue field of cardinality `q`, a random monic quadratic1948is ramified (type `(2,1)`) with probability `1 / (q + 1)`. -/1949theorem monicDensity_two_ramified (htop : IsAdic (maximalIdeal O)) :(1.3)1950 monicDensity O 2 {(2,1)} = ENNReal.ofReal (1 / (Nat.card (ResidueField O) + 1)) := by1951 rw [(main_dvr O htop 2 {(2,1)}).1, densityValue_eq1952 (monicExpr_two_eval _ (one_lt_card_residueField O) _)]1953 simp +decide1954 1955/-- Over any complete DVR with finite residue field of cardinality `q`, a random primitive binary1956quadratic form is ramified (type `(2,1)`) with probability `q / (q² + q + 1)`. -/1957theorem projectiveDensity_two_ramified (htop : IsAdic (maximalIdeal O)) :Example 7.31958 projectiveDensity O 2 {(2,1)} = ENNReal.ofReal (Nat.card (ResidueField O) /1959 ((Nat.card (ResidueField O)) ^ 2 + Nat.card (ResidueField O) + 1)) := by1960 rw [(main_dvr O htop 2 {(2,1)}).2, densityValue_eq1961 (projectiveExpr_two_eval _ (one_lt_card_residueField O) _)]1962 simp +decide1963 1964/-- Residue field `𝔽₃`: a random monic cubic is totally ramified with probability `10/121`. -/1965theorem monicDensity_three_totally_ramified_of_card_eq_three (htop : IsAdic (maximalIdeal O))(10.8)1966 (hq : Nat.card (ResidueField O) = 3) : monicDensity O 3 {(3,1)} = ENNReal.ofReal (10/121) := by1967 rw [(main_dvr O htop 3 {(3,1)}).1, hq,1968 densityValue_eq monicExpr_three_totally_ramified_eval_three]1969 norm_num1970 1971/-- Residue field `𝔽₂`: a random monic quartic is totally ramified with probability `107/1533`. -/1972theorem monicDensity_four_totally_ramified_of_card_eq_two (htop : IsAdic (maximalIdeal O))Example 10.41973 (hq : Nat.card (ResidueField O) = 2) :1974 monicDensity O 4 {(4,1)} = ENNReal.ofReal (107/1533) := by1975 rw [(main_dvr O htop 4 {(4,1)}).1, hq,1976 densityValue_eq monicExpr_four_totally_ramified_eval_two]1977 norm_num1978 1979/-- Residue field `𝔽₂`: a random primitive binary quartic form is totally ramified with1980probability `856/15841`. -/1981theorem projectiveDensity_four_totally_ramified_of_card_eq_two (htop : IsAdic (maximalIdeal O))1982 (hq : Nat.card (ResidueField O) = 2) :1983 projectiveDensity O 4 {(4,1)} = ENNReal.ofReal (856/15841) := by1984 rw [(main_dvr O htop 4 {(4,1)}).2, hq,1985 densityValue_eq projectiveExpr_four_totally_ramified_eval_two]1986 norm_num1987 1988/-- Residue field `𝔽₂`: a random monic quartic is irreducible of type `(2,2)` with probability1989`454/7665`. -/1990theorem monicDensity_four_ramified_quadratic_of_card_eq_two (htop : IsAdic (maximalIdeal O))1991 (hq : Nat.card (ResidueField O) = 2) :1992 monicDensity O 4 {(2,2)} = ENNReal.ofReal (454/7665) := by1993 rw [(main_dvr O htop 4 {(2,2)}).1, hq,1994 densityValue_eq monicExpr_four_ramified_quadratic_eval_two]1995 norm_num1996 1997/-- Residue field `𝔽₂`: a random monic quartic is a product of two distinct inert quadratics with1998probability `664/22995`. -/1999theorem monicDensity_four_two_inert_quadratics_of_card_eq_two (htop : IsAdic (maximalIdeal O))2000 (hq : Nat.card (ResidueField O) = 2) :2001 monicDensity O 4 {(1,2), (1,2)} = ENNReal.ofReal (664/22995) := by2002 rw [(main_dvr O htop 4 {(1,2), (1,2)}).1, hq,2003 densityValue_eq monicExpr_four_two_inert_quadratics_eval_two]2004 norm_num2005 2006end Densities2007 2008open PowerSeries in2009open scoped PowerSeries.WithPiTopology in2010/-- End-to-end test: over `𝔽₂⟦X⟧`, a random monic quartic is totally ramified with probability2011`107/1533`. -/2012theorem monicDensity_powerSeries_zmod_two_four_totally_ramified :Example 10.42013 monicDensity (ZMod 2)⟦X⟧ 4 {(4,1)} = ENNReal.ofReal (107/1533) := by2014 rw [(main_dvr_zmod 2 4 {(4,1)}).1,2015 densityValue_eq monicExpr_four_totally_ramified_eval_two]2016 norm_num2017 2018end SurfaceBlowup.Tests2019 2020#print axioms SurfaceBlowup.Tests.monicExpr_four_eval_two2021#print axioms SurfaceBlowup.Tests.projectiveExpr_four_eval_two2022#print axioms SurfaceBlowup.Tests.monicExpr_three_eval2023#print axioms SurfaceBlowup.Tests.projectiveExpr_two_eval2024#print axioms SurfaceBlowup.Tests.monicDensity_two_ramified2025#print axioms SurfaceBlowup.Tests.projectiveDensity_two_ramified2026#print axioms SurfaceBlowup.Tests.monicDensity_three_totally_ramified_of_card_eq_three2027#print axioms SurfaceBlowup.Tests.monicDensity_four_totally_ramified_of_card_eq_two2028#print axioms SurfaceBlowup.Tests.projectiveDensity_four_totally_ramified_of_card_eq_two2029#print axioms SurfaceBlowup.Tests.monicDensity_four_ramified_quadratic_of_card_eq_two2030#print axioms SurfaceBlowup.Tests.monicDensity_four_two_inert_quadratics_of_card_eq_two2031#print axioms SurfaceBlowup.Tests.monicDensity_powerSeries_zmod_two_four_totally_ramified