Lean sources / SurfaceBlowup / Formula / StateCombinatorics.lean
Combinatorics of states, ranks and safety of the laws
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.Formula.LawAlgebra7 8/-!9# Combinatorics of states, ranks and safety of the laws10 11Combinatorial facts about states and their children under one blowup step: positivity of12degrees, the unique self pattern of a single-branch state, strict decrease of the rank along13non-self children (which makes the fuel-based recursion `stateLawFuel` stable), and the14resulting safety (no division by zero at integers `q ≥ 2`) of the local and global laws, hence15regularity of the global formula. Also small arithmetic facts on `tri`, return weights,16divisor probabilities and scaled types.17 18## Main results19 20* `SurfaceBlowup.self_patterns_of_single_state`: `S(a; c)` has a unique self pattern.21* `SurfaceBlowup.nonself_child_rank_lt`: non-self children have strictly smaller rank.22* `SurfaceBlowup.state_fuel_stable`: `stateLawFuel k s = stateLaw s` once `rank s < k`.23* `SurfaceBlowup.state_law_unfold`: the law of a non-terminal state in terms of its exit law24 `exitLaw` (the non-self part of the recursion).25* `SurfaceBlowup.local_law_safe`, `SurfaceBlowup.global_law_safe`: safety of the laws.26* `SurfaceBlowup.global_formula_regular`: the global formula is regular at prime powers.27* `SurfaceBlowup.scale_type_valid_degree_iff`: scaling types by `δ` preserves validity and28 multiplies degrees by `δ`.29 30Provenance: `Thm_SurfaceBlowupV2_*` for self_patterns_of_single_state, state_degree_pos,31equal_degree_child_is_unique, state_weight_le_degree, rank_lt_of_weight_gt, nonself_child_rank_lt,32state_fuel_stable, exitLaw, state_law_unfold, tangent_weight_safe, terminal_law, tri_chooseTwo,33tri_ge_three, return_weight_bounds, divisor_probability_pos, local_law_safe, global_law_safe,34global_coefficients_safe, global_formula_regular, type_degree_scale,35scale_type_valid_degree_iff.36-/37 38open scoped BigOperators ENNReal39 40namespace SurfaceBlowup41 42/-! ### The self pattern of a single-branch state -/43 44/-- Multiplicity of a given "other" child in `otherChildren a m`. -/45private theorem count_otherChildren {n : ℕ} (a : ℕ) (m : Pattern n) (i j : Fin n) :46 (otherChildren a m).count (i.val + 1, State.single a (j.val + 1)) = (m (i, j)).val := by47 unfold otherChildren48 rw [List.count_flatMap, Finset.sum_map_toList]49 simp only [Function.comp, List.count_replicate]50 rw [Finset.sum_eq_single (i,j)]51 · simp52 · intro b _ hb53 refine if_neg fun h ↦ hb ?_54 simp only [beq_iff_eq, Prod.mk.injEq, State.single.injEq, add_left_inj, true_and] at h55 exact Prod.ext (Fin.ext h.1) (Fin.ext h.2)56 · simp57 58/-- The indicator pattern of the cell `(0, c - 1)`. -/59private abbrev IsSelfOther {n : ℕ} (c : ℕ) (m : Pattern n) : Prop :=60 ∀ ij, (m ij).val = if ij.1.val = 0 ∧ ij.2.val + 1 = c then 1 else 061 62/-- Sums over `Fin n × Fin n` of the indicator of the cell `(0, c - 1)`. -/63private theorem sum_selfOther {n : ℕ} (c : ℕ) (hc : 0 < c) (hcn : c ≤ n) (f : Fin n × Fin n → ℕ)64 (hf : ∀ ij, ¬ (ij.1.val = 0 ∧ ij.2.val + 1 = c) → f ij = 0) :65 ∑ ij, f ij = f (⟨0, by omega⟩, ⟨c-1, by omega⟩) := by66 refine Finset.sum_eq_single _ (fun b _ hb ↦ hf b fun ⟨h1, h2⟩ ↦ hb ?_) (by simp)67 exact Prod.ext (Fin.ext h1) (Fin.ext (by simp; omega))68 69private theorem weight_selfOther {n : ℕ} (c : ℕ) (hc : 0 < c) (hcn : c ≤ n) (m : Pattern n)70 (hm : IsSelfOther c m) : patternWeight m = c := by71 unfold patternWeight72 rw [sum_selfOther c hc hcn _ fun ij h ↦ by rw [hm, if_neg h, mul_zero], hm,73 if_pos ⟨rfl, show c - 1 + 1 = c by omega⟩]74 change (0+1)*((c-1)+1)*1 = c; omega75 76private theorem otherChildren_selfOther {n : ℕ} (a c : ℕ) (hc : 0 < c) (hcn : c ≤ n)77 (m : Pattern n) (hm : IsSelfOther c m) :78 otherChildren a m = [(1, State.single a c)] := by79 have h1 : (otherChildren a m).length = 1 := by80 rw [otherChildren, List.length_flatMap, Finset.sum_map_toList]81 simp only [List.length_replicate]82 rw [sum_selfOther c hc hcn _ fun ij h ↦ by rw [hm, if_neg h], hm,83 if_pos ⟨rfl, show c - 1 + 1 = c by omega⟩]84 have h2 := count_otherChildren a m ⟨0, by omega⟩ ⟨c-1, by omega⟩85 rw [hm, if_pos ⟨rfl, show c - 1 + 1 = c by omega⟩] at h286 simp only [show c - 1 + 1 = c by omega] at h287 obtain ⟨y, hy⟩ := List.length_eq_one_iff.1 h188 rw [hy] at h2 ⊢89 by_cases e : y = (1, State.single a c)90 · rw [e]91 · simp [e] at h292 93/-- The unique self pattern of `S(a; c)`. -/94private def selfPattern (a c : ℕ) (hc : 0 < c) (hca : c ≤ a * c) :95 TangentPattern (State.single a c).degree where96 d := ⟨c, by change c < a*c+1; omega⟩97 rt := ⟨0, by change 0 < a*c+1; omega⟩98 rx := ⟨0, by change 0 < a*c+1; omega⟩99 other := fun ij ↦ if ij.1.val = 0 ∧ ij.2.val + 1 = c then ⟨1, by change 1 < a*c+1; omega⟩100 else ⟨0, by change 0 < a*c+1; omega⟩101 102private theorem selfPattern_other (a c : ℕ) (hc : 0 < c) (hca : c ≤ a * c) :103 IsSelfOther c (selfPattern a c hc hca).other := fun ij ↦ by104 simp only [selfPattern]; split_ifs <;> rfl105 106/-- Every allowed self pattern of `S(a; c)` is `selfPattern a c`. -/107private theorem eq_selfPattern (a c : ℕ) (hc : 0 < c) (hca : c ≤ a * c)108 (P : TangentPattern (State.single a c).degree) (hA : Allowed (.single a c) P)109 (hS : SelfPattern (.single a c) P) : P = selfPattern a c hc hca := by110 obtain ⟨a', c', hs, hch⟩ := hS111 cases hs112 have hrt : P.rt.val = 0 := by113 by_contra h114 simp [children, h] at hch115 simp only [children, hrt, if_true, List.nil_append] at hch116 have hm : IsSelfOther c P.other := by117 intro ij118 rw [← count_otherChildren a P.other ij.1 ij.2, hch]119 simp [List.count_cons]120 split_ifs <;> omega121 have hw := weight_selfOther (n := (State.single a c).degree) c hc hca _ hm122 obtain ⟨hd0, hsum, hdc, hrx, hiff⟩ := hA123 obtain ⟨d, rt, rx, other⟩ := P124 simp only at hrt hrx hsum hm hw hd0 hdc hiff125 unfold selfPattern126 congr 1127 · ext; change d.val = c; omega128 · ext; change rt.val = 0; omega129 · ext; change rx.val = 0; omega130 · funext ij; ext; rw [hm]; split_ifs <;> rfl131 132open scoped Classical in133/-- The self patterns among the allowed patterns of `S(a; c)` are exactly `[selfPattern a c]`. -/134private theorem filter_selfPattern_eq (a c : ℕ) (hc : 0 < c) (hca : c ≤ a * c) :135 (allowedPatterns (.single a c)).toList.filter (SelfPattern (.single a c)) =136 [selfPattern a c hc hca] := by137 have hmem : selfPattern a c hc hca ∈138 (allowedPatterns (.single a c)).toList.filter (SelfPattern (.single a c)) := by139 simp only [List.mem_filter, Finset.mem_toList, allowedPatterns, Finset.mem_filter,140 Finset.mem_univ, true_and, decide_eq_true_eq]141 have hw := weight_selfOther (n := (State.single a c).degree) c hc hca _142 (selfPattern_other a c hc hca)143 have ho := otherChildren_selfOther (n := (State.single a c).degree) a c hc hca _144 (selfPattern_other a c hc hca)145 refine ⟨⟨hc, ?_, ?_⟩, a, c, rfl, by simp only [children, ho]; rfl⟩146 · rw [hw]; change 0 + 0 + c = c; omega147 · change c ≤ c ∧ 0 = 0 ∧ (0 < 0 ↔ c < c); omega148 refine ((List.perm_ext_iff_of_nodup ((Finset.nodup_toList _).filter _)149 (List.nodup_singleton _)).2 fun b ↦ ⟨fun hb ↦ ?_, fun hb ↦ ?_⟩).eq_singleton150 · simp only [List.mem_filter, Finset.mem_toList, allowedPatterns, Finset.mem_filter,151 decide_eq_true_eq] at hb152 exact List.mem_singleton.2 (eq_selfPattern a c hc hca b hb.1.2 hb.2)153 · exact List.mem_singleton.1 hb ▸ hmem154 155/-- The tangent count of `selfPattern a c` evaluates to `q`. -/156private theorem tangentCount_selfPattern_eval (a c q : ℕ) (hc : 0 < c) (hca : c ≤ a * c) :157 (tangentCount (.single a c) (selfPattern a c hc hca)).eval (q:ℚ) = q := by158 simp only [tangentCount, divisorCount]159 rw [expression_prod_eval, List.map_map, Finset.prod_map_toList,160 Finset.prod_eq_single (⟨0, by change 0 < a*c; omega⟩ : Fin (State.single a c).degree)]161 · simp only [Function.comp, Expr.eval, selfPattern_other, true_and]162 have hs : (∑ x : Fin (State.single a c).degree, if x.val + 1 = c then 1 else 0) = 1 := by163 rw [Finset.sum_eq_single (⟨c-1, by change c-1 < a*c; omega⟩ :164 Fin (State.single a c).degree)]165 · simp; omega166 · exact fun b _ hb ↦ if_neg fun h ↦ hb (Fin.ext (by simp; omega))167 · simp168 have hp : (∏ x : Fin (State.single a c).degree,169 (((if x.val + 1 = c then 1 else 0 : ℕ)).factorial : ℚ)) = 1 :=170 Finset.prod_eq_one fun j _ ↦ by split_ifs <;> simp171 rw [hs, hp]172 simp [falling, expression_prod_eval, availablePoints, Expr.sub, Expr.neg, Expr.eval]173 · intro b _ hb174 simp [selfPattern_other, Fin.val_ne_iff.2 hb, falling, expression_prod_eval, Expr.eval]175 · simp176 177open scoped Classical in178/-- A single-branch state `S(a; c)` with `c ≥ 2` has exactly one self pattern (of179multiplicity `d = c`, with the state itself as only child), whose tangent count at `q` is180`q`. -/181theorem self_patterns_of_single_state (a c q : ℕ) (ha : 0 < a) (hc : 2 ≤ c) :(6.6)182 (∀ P : TangentPattern (State.single a c).degree, Allowed (State.single a c) P →183 SelfPattern (State.single a c) P →184 P.d.val = c ∧ children (State.single a c) P = [(1, State.single a c)]) ∧185 (((allowedPatterns (State.single a c)).toList.filter (SelfPattern (State.single a c))).map186 fun P ↦ (tangentCount (State.single a c) P).eval q).sum = q := by187 have hc : 0 < c := by omega188 have hca : c ≤ a*c := Nat.le_mul_of_pos_left c ha189 refine ⟨fun P hA hS ↦ ⟨by rw [eq_selfPattern a c hc hca P hA hS]; rfl,190 hS.choose_spec.choose_spec.2⟩, ?_⟩191 simpa [filter_selfPattern_eq a c hc hca] using tangentCount_selfPattern_eval a c q hc hca192 193/-! ### Degrees, weights and ranks -/194 195/-- A valid state has positive degree. -/196private theorem state_degree_pos (s : State) (hs : s.Valid) :197 0 < s.degree := by198 cases s with199 | single a c => exact Nat.mul_pos hs.1 hs.2200 | crossing a b c h =>201 have := Nat.mul_pos hs.1 hs.2.2.1202 change 0 < a*c+b*h203 omega204 205/-- If a child has the same degree as its parent, it is the only child and has residue206degree `1`. -/207private theorem equal_degree_child_is_unique (s : State) (hs : s.Valid)208 (P : TangentPattern s.degree)209 (hP : Allowed s P) (z : ℕ × State) (hz : z ∈ children s P) (heq : z.2.degree = s.degree) :210 children s P = [z] ∧ z.1 = 1 := by211 have hsum := children_degree_identity s hs P hP212 have hD := state_degree_pos s hs213 have hpos : ∀ w ∈ children s P, 0 < w.1 * w.2.degree := fun w hw ↦214 Nat.mul_pos (children_residue_degree_pos s P w hw)215 (state_degree_pos _ (children_valid s hs P hP w hw))216 have hz1 := children_residue_degree_pos s P z hz217 obtain ⟨l1, l2, hL⟩ := List.append_of_mem hz218 have empty : ∀ l : List (ℕ × State), (∀ w ∈ l, w ∈ children s P) →219 (l.map fun z ↦ z.1*z.2.degree).sum = 0 → l = [] := by220 rintro (_ | ⟨a, t⟩) hl h0221 · rfl222 · have := hpos a (hl a (by simp))223 simp only [List.map_cons, List.sum_cons] at h0224 omega225 rw [hL] at hsum226 simp only [List.map_append, List.map_cons, List.sum_append, List.sum_cons, heq] at hsum227 have hge : s.degree ≤ z.1 * s.degree := Nat.le_mul_of_pos_left _ hz1228 obtain rfl := empty l1 (fun w hw ↦ by rw [hL]; simp [hw]) (by omega)229 obtain rfl := empty l2 (fun w hw ↦ by rw [hL]; simp [hw]) (by omega)230 refine ⟨by simpa using hL, Nat.eq_of_mul_eq_mul_right hD ?_⟩231 simp at hsum232 omega233 234/-- The weight of a valid state is at most its degree. -/235private theorem state_weight_le_degree (s : State) (hs : s.Valid) :236 s.weight ≤ s.degree := by237 cases s with238 | single a c => exact Nat.le_mul_of_pos_right a hs.2239 | crossing a b c h =>240 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)241 242/-- Among valid states of equal degree, larger weight forces smaller rank. -/243private theorem rank_lt_of_weight_gt (s u : State) (hs : s.Valid) (hu : u.Valid)244 (hN : u.degree = s.degree)245 (hw : s.weight < u.weight) :246 u.rank < s.rank := by247 have h1 := state_weight_le_degree s hs248 have h2 := state_weight_le_degree u hu249 have ht : u.tag ≤ 1 := by cases u <;> simp [State.tag]250 unfold State.rank251 rw [hN] at h2 ⊢252 omega253 254/-- Every child of a non-self allowed pattern has strictly smaller rank than its parent. -/255theorem nonself_child_rank_lt (s : State) (hs : s.Valid) (P : TangentPattern s.degree)Contact-size order(6.6)256 (hP : Allowed s P) (hself : ¬ SelfPattern s P) (z : ℕ × State) (hz : z ∈ children s P) :257 z.2.rank < s.rank := by258 have hv := children_valid s hs P hP z hz259 rcases Nat.lt_or_eq_of_le (child_degree_le s hs P hP z hz) with hlt | heq260 · exact rank_lt_of_degree_lt s z.2 hv hlt261 obtain ⟨hch, hz1⟩ := equal_degree_child_is_unique s hs P hP z hz heq262 have hw : s.weight < z.2.weight → z.2.rank < s.rank :=263 rank_lt_of_weight_gt s z.2 hs hv heq264 cases s with265 | single a c =>266 obtain ⟨ha, hc⟩ := hs267 simp only [children, otherChildren, List.mem_append, List.mem_flatMap,268 List.mem_replicate] at hz269 rcases hz with hz | ⟨ij, -, -, rfl⟩270 · split_ifs at hz271 · simp at hz272 · obtain rfl := List.mem_singleton.1 hz273 exact hw (by simp [State.weight]; omega)274 · refine absurd ⟨a, c, rfl, ?_⟩ hself275 have hj : ij.2.val + 1 = c :=276 Nat.eq_of_mul_eq_mul_left ha (by simpa [State.degree] using heq)277 rw [hch]278 simp only at hz1279 rw [hz1, hj]280 | crossing a b c h =>281 obtain ⟨ha, hb, hc, hh⟩ := hs282 simp only [children, otherChildren, List.mem_append, List.mem_flatMap,283 List.mem_replicate] at hz284 rcases hz with (hz | hz) | ⟨ij, -, -, rfl⟩285 pick_goal 3286 · simp only [State.rank, State.weight, State.tag] at heq ⊢287 rw [heq]288 omega289 all_goals290 split_ifs at hz291 · simp at hz292 · obtain rfl := List.mem_singleton.1 hz293 exact hw (by simp [State.weight]; omega)294 295/-- Two fuel values above the rank give the same law (strong induction on a rank bound). -/296private theorem stateLawFuel_stable (n : ℕ) : ∀ (s : State), s.Valid → s.rank < n →297 ∀ k1 k2 : ℕ, s.rank < k1 → s.rank < k2 → stateLawFuel k1 s = stateLawFuel k2 s := by298 classical299 induction n with300 | zero => intro s _ h; omega301 | succ n ih =>302 intro s hs hn k1 k2 h1 h2303 obtain ⟨j1, rfl⟩ : ∃ j, k1 = j + 1 := ⟨k1 - 1, by omega⟩304 obtain ⟨j2, rfl⟩ : ∃ j, k2 = j + 1 := ⟨k2 - 1, by omega⟩305 have hterms : ((allowedPatterns s).toList.flatMap fun P ↦306 if SelfPattern s P then [] else307 lawScale (.mul (tangentCount s P) (divisorProbability s P.d.val))308 (lawProd ((children s P).map fun z ↦ lawDescend z.1 (stateLawFuel j1 z.2)))) =309 ((allowedPatterns s).toList.flatMap fun P ↦310 if SelfPattern s P then [] else311 lawScale (.mul (tangentCount s P) (divisorProbability s P.d.val))312 (lawProd ((children s P).map fun z ↦ lawDescend z.1 (stateLawFuel j2 z.2)))) := by313 simp only [List.flatMap]314 congr 1315 refine List.map_congr_left fun P hP ↦ ?_316 have hA : Allowed s P := by simpa [allowedPatterns] using hP317 split_ifs with hself318 · rfl319 · congr 2320 refine List.map_congr_left fun z hz ↦ ?_321 have hlt := nonself_child_rank_lt s hs P hA hself z hz322 rw [ih z.2 (children_valid s hs P hA z hz) (by omega) j1 j2 (by omega) (by omega)]323 cases s with324 | single a c =>325 rcases c with _ | _ | c326 · simp only [stateLawFuel]; rw [hterms]327 · simp only [stateLawFuel]328 · simp only [stateLawFuel]; rw [hterms]329 | crossing a b c h =>330 simp only [stateLawFuel]; rw [hterms]331 332/-- The fuel-based recursion is stable: any fuel `k > rank s` computes `stateLaw s`. -/333theorem state_fuel_stable (s : State) (hs : s.Valid) (k : ℕ) (hk : s.rank < k) :334 stateLawFuel k s = stateLaw s :=335 stateLawFuel_stable (s.rank + 1) s hs (by omega) k (s.rank + 1) hk (by omega)336 337/-! ### Unfolding the state law -/338 339open scoped Classical in340/-- The non-self part of the recursion of a state `s`: over the allowed tangent patterns `P` that341are not self patterns, the weight `tangentCount · divisorProbability` times the product of the342descended laws of the children of `P`. -/343noncomputable def exitLaw (s : State) : Law :=(6.6)344 (allowedPatterns s).toList.flatMap fun P ↦345 if SelfPattern s P then [] else346 lawScale (.mul (tangentCount s P) (divisorProbability s P.d.val))347 (lawProd ((children s P).map fun z ↦ lawDescend z.1 (stateLaw z.2)))348 349open scoped Classical in350private theorem flatMap_terms_eq_exitLaw (s : State) (hs : s.Valid) :351 ((allowedPatterns s).toList.flatMap fun P ↦352 if SelfPattern s P then [] else353 lawScale (.mul (tangentCount s P) (divisorProbability s P.d.val))354 (lawProd ((children s P).map fun z ↦ lawDescend z.1 (stateLawFuel s.rank z.2))))355 = exitLaw s := by356 unfold exitLaw357 refine List.flatMap_congr fun P hP ↦ ?_358 have hA : Allowed s P := by simpa [allowedPatterns] using hP359 split_ifs with hself360 · rfl361 · congr 2362 refine List.map_congr_left fun z hz ↦ ?_363 rw [state_fuel_stable z.2 (children_valid s hs P hA z hz) s.rank364 (nonself_child_rank_lt s hs P hA hself z hz)]365 366/-- Unfolding of the state law: for a single state it is the exit law rescaled by367`1 / (1 - returnWeight c)`, and for a crossing state it is the exit law itself. -/368theorem state_law_unfold (s : State) (hs : s.Valid) (hnt : s.terminal = false) :(6.7)Theorem 6.2369 (∀ a c : ℕ, s = State.single a c → stateLaw s =370 lawScale (.inv (.sub (.const 1) (returnWeight c))) (exitLaw s)) ∧371 (∀ a b c h : ℕ, s = State.crossing a b c h → stateLaw s = exitLaw s) := by372 refine ⟨?_, ?_⟩373 · rintro a c rfl374 obtain ⟨_, hc⟩ := id hs375 obtain _ | _ | c := c376 · omega377 · simp [State.terminal] at hnt378 · rw [← flatMap_terms_eq_exitLaw _ hs]379 rfl380 · rintro a b c h rfl381 rw [← flatMap_terms_eq_exitLaw _ hs]382 rfl383 384/-! ### Arithmetic of weights and probabilities -/385 386/-- The weight `tangentCount · divisorProbability` of a pattern is safe at all `q ≥ 2`. -/387private theorem tangent_weight_safe (s : State) (P : TangentPattern s.degree) :388 (Expr.mul (tangentCount s P) (divisorProbability s P.d.val)).allSafe := fun q hq ↦389 ⟨divisor_count_safe s.degree _ P.other q hq, divisor_probability_safe s P.d.val q hq⟩390 391/-- The law of the terminal state `S(a; 1)` is the atom `[(a, 1)]`. -/392theorem terminal_law (a : ℕ) :Lemma 2.2393 stateLaw (State.single a 1) = lawAtom a 1 := by394 rw [stateLaw, State.rank, stateLawFuel]395 396/-- `tri d = chooseTwo d + d`. -/397theorem tri_chooseTwo (d : ℕ) :398 tri d = chooseTwo d + d := by399 cases d with400 | zero => simp [tri, chooseTwo]401 | succ n =>402 unfold tri chooseTwo403 have h : (n+1)*(n+1+1) = (n+1)*(n+1-1) + 2*(n+1) := by404 simp only [Nat.add_sub_cancel]; ring405 rw [h, Nat.add_mul_div_left _ _ (by norm_num : 0 < 2)]406 407/-- `tri c ≥ 3` for `c ≥ 2`. -/408private theorem tri_ge_three (c : ℕ) (hc : 2 ≤ c) :409 3 ≤ tri c := by410 unfold tri411 have : 6 ≤ c*(c+1) := by nlinarith412 omega413 414/-- For `q, c ≥ 2`, the return weight `q · q^(-tri c)` lies in `(0, q⁻²]`, in particular415below `1`. -/416theorem return_weight_bounds (q c : ℕ) (hq : 2 ≤ q) (hc : 2 ≤ c) :417 0 < (returnWeight c).eval q ∧ (returnWeight c).eval q ≤ (q : ℚ)⁻¹^2 ∧418 (returnWeight c).eval q < 1 := by419 have hev : (returnWeight c).eval (q:ℚ) = (q:ℚ) * ((q:ℚ)^(tri c))⁻¹ := by420 simp [returnWeight, Expr.eval, expression_pow_eval]421 rw [hev]422 have hq2 : (2:ℚ) ≤ q := by exact_mod_cast hq423 have hqpos : (0:ℚ) < q := by linarith424 have hp3 : (q:ℚ)^3 ≤ (q:ℚ)^(tri c) := pow_le_pow_right₀ (by linarith) (tri_ge_three c hc)425 have hle : (q:ℚ) * ((q:ℚ)^(tri c))⁻¹ ≤ (q:ℚ)⁻¹^2 := by426 calc (q:ℚ) * ((q:ℚ)^(tri c))⁻¹ ≤ (q:ℚ) * ((q:ℚ)^3)⁻¹ :=427 mul_le_mul_of_nonneg_left (inv_anti₀ (by positivity) hp3) hqpos.le428 _ = (q:ℚ)⁻¹^2 := by field_simp429 refine ⟨by positivity, hle, lt_of_le_of_lt hle ?_⟩430 have : (q:ℚ)⁻¹ ≤ 1/2 := by431 rw [one_div]; exact inv_anti₀ (by norm_num) hq2432 have h0 : (0:ℚ) ≤ (q:ℚ)⁻¹ := by positivity433 nlinarith434 435/-- Divisor probabilities and the inverse `1 / (1 - returnWeight c)` are positive at `q ≥ 2`. -/436theorem divisor_probability_pos (q : ℕ) (hq : 2 ≤ q) (s : State) (d c : ℕ) (hc : 2 ≤ c) :437 0 < (divisorProbability s d).eval q ∧438 0 < (Expr.inv (.sub (.const 1) (returnWeight c))).eval q := by439 have hQ : (2:ℚ) ≤ (q:ℚ) := by exact_mod_cast hq440 have hE : (eminusOne).eval q = (q:ℚ) - 1 := by441 simp [eminusOne, Expr.sub, Expr.neg, Expr.eval]; ring442 have hE0 : 0 < (q:ℚ) - 1 := by linarith443 have hP : ∀ n : ℕ, 0 < ((Expr.pow .var n).eval q) := fun n ↦ by444 rw [expression_pow_eval]; simp only [Expr.eval]; positivity445 have hEp : ∀ n : ℕ, 0 < ((Expr.pow eminusOne n).eval q) := fun n ↦ by446 rw [expression_pow_eval, hE]; exact pow_pos hE0 _447 refine ⟨?_, ?_⟩448 · cases s with449 | single a c' => exact mul_pos (inv_pos.mpr (hP _)) (hEp _)450 | crossing a b c' h =>451 simp only [divisorProbability, Expr.eval]452 refine mul_pos (inv_pos.mpr (hP _)) ?_453 split_ifs454 all_goals first455 | exact hEp _456 | (simp only [Expr.eval]; rw [hE]; exact inv_pos.mpr hE0)457 · have := (return_weight_bounds q c hq hc).2.2458 simp only [Expr.sub, Expr.neg, Expr.eval]459 exact inv_pos.mpr (by linarith)460 461/-! ### Safety of the laws -/462 463/-- Products of safe laws are safe. -/464private theorem lawProd_safe (Ls : List Law) (h : ∀ L ∈ Ls, LawSafe L) :465 LawSafe (lawProd Ls) := by466 induction Ls with467 | nil =>468 intro z hz q _469 simp only [lawProd, lawOne, List.foldr_nil, List.mem_singleton] at hz470 subst hz471 trivial472 | cons L Ls ih =>473 exact law_safe_mul _ _ (h L (by simp)) (ih fun M hM ↦ h M (by simp [hM]))474 475open scoped Classical in476/-- The non-self part of the recursion for `stateLaw s` is safe, given safety for states of477smaller rank. -/478private theorem stateLaw_terms_safe (s : State) (hs : s.Valid)479 (ih : ∀ t : State, t.rank < s.rank → t.Valid → LawSafe (stateLaw t)) :480 LawSafe ((allowedPatterns s).toList.flatMap fun P ↦481 if SelfPattern s P then [] else482 lawScale (.mul (tangentCount s P) (divisorProbability s P.d.val))483 (lawProd ((children s P).map fun z ↦ lawDescend z.1 (stateLawFuel s.rank z.2)))) := by484 intro z hz485 rw [List.mem_flatMap] at hz486 obtain ⟨P, hP, hz⟩ := hz487 have hA : Allowed s P := by simpa [allowedPatterns] using hP488 by_cases hself : SelfPattern s P489 · simp [hself] at hz490 · rw [if_neg hself] at hz491 refine law_safe_scale _ _ (tangent_weight_safe s P) (lawProd_safe _ ?_) z hz492 simp only [List.mem_map]493 rintro _ ⟨w, hw, rfl⟩494 have hv := children_valid s hs P hA w hw495 have hr := nonself_child_rank_lt s hs P hA hself w hw496 rw [state_fuel_stable w.2 hv _ hr]497 exact law_safe_descend _ (children_residue_degree_pos s P w hw) _ (ih _ hr hv)498 499/-- The local law of every valid state is safe. -/500theorem local_law_safe (s : State) (hs : s.Valid) :Theorem 6.2501 LawSafe (stateLaw s) := by502 classical503 induction hn : s.rank using Nat.strong_induction_on generalizing s with504 | _ n IH =>505 have hT := stateLaw_terms_safe s hs fun t ht htv ↦ IH t.rank (hn ▸ ht) t htv rfl506 unfold stateLaw507 cases s with508 | single a c =>509 by_cases hc : c = 1510 · subst hc511 intro z hz q _512 simp only [stateLawFuel, lawAtom, List.mem_singleton] at hz513 subst hz514 trivial515 · have hc2 : 2 ≤ c := by have := hs.2; omega516 have hfuel : stateLawFuel ((State.single a c).rank + 1) (State.single a c) =517 lawScale (.inv (.sub (.const 1) (returnWeight c)))518 ((allowedPatterns (State.single a c)).toList.flatMap fun P ↦519 if SelfPattern (State.single a c) P then [] else520 lawScale (.mul (tangentCount (State.single a c) P)521 (divisorProbability (State.single a c) P.d.val))522 (lawProd ((children (State.single a c) P).map fun z ↦523 lawDescend z.1 (stateLawFuel (State.single a c).rank z.2)))) := by524 rw [stateLawFuel]525 all_goals first | rfl | (intro a1 h; cases h; exact hc rfl)526 rw [hfuel]527 refine law_safe_scale _ _ (fun q hq ↦ ?_) hT528 obtain ⟨hpos, -, hlt⟩ := return_weight_bounds q c hq hc2529 have hne : (Expr.pow .var (tri c)).eval (q : ℚ) ≠ 0 := fun h0 ↦ by530 simp [returnWeight, Expr.eval, h0] at hpos531 refine ⟨⟨trivial, trivial, ⟨trivial, expression_pow_safe _ _ _ trivial, hne⟩⟩, ?_⟩532 simp only [Expr.sub, Expr.neg, Expr.eval]533 intro h0534 linarith535 | crossing a b c h =>536 rw [stateLawFuel]537 exact hT538 539/-- The global law (monic for `ε = false`, projective for `ε = true`) of degree `n` is safe. -/540theorem global_law_safe (n : ℕ) (ε : Bool) :541 LawSafe (globalLaw ε n) := by542 have normSafe : (Expr.inv (if ε then projectiveNormalizer n else .pow .var n)).allSafe := by543 intro q hq544 cases ε with545 | true =>546 refine ⟨?_, ne_of_gt (projective_normalizer_positive n q (by positivity))⟩547 refine expression_sum_safe _ _ ?_548 simp only [List.mem_map]549 rintro _ ⟨i, _, rfl⟩550 exact expression_pow_safe _ _ _ trivial551 | false =>552 refine ⟨expression_pow_safe _ _ _ trivial, ?_⟩553 have : (2:ℚ) ≤ q := by exact_mod_cast hq554 simpa [expression_pow_eval, Expr.eval] using pow_ne_zero n (by linarith : (q:ℚ) ≠ 0)555 refine law_safe_scale _ _ normSafe fun z hz ↦ ?_556 simp only [List.mem_flatMap] at hz557 obtain ⟨m, _, hz⟩ := hz558 refine law_safe_scale _ _ (divisor_count_safe _ _ m) (lawProd_safe _ ?_) z hz559 simp only [List.mem_map, otherChildren, List.mem_flatMap, List.mem_replicate]560 rintro _ ⟨w, ⟨ij, _, _, rfl⟩, rfl⟩561 exact law_safe_descend _ (Nat.succ_pos _) _ (local_law_safe _ ⟨Nat.one_pos, Nat.succ_pos _⟩)562 563/-- The coefficients of the monic and projective global laws are safe. -/564theorem global_coefficients_safe (n : ℕ) (σ : FactorType) :565 (monicExpr n σ).allSafe ∧ (projectiveExpr n σ).allSafe := by566 have hsafe : ∀ L : Law, LawSafe L → (lawCoeff L σ).allSafe := by567 intro L hL q hq568 refine expression_sum_safe _ _ fun x hx ↦ ?_569 obtain ⟨z, hz, rfl⟩ := List.mem_map.mp hx570 by_cases h : z.1 = σ571 · simp only [h, if_true]; exact hL z hz q hq572 · simp [h, Expr.safe]573 exact ⟨hsafe _ (global_law_safe n false), hsafe _ (global_law_safe n true)⟩574 575/-- The global formula is regular at every prime power. -/576theorem global_formula_regular (n : ℕ) (σ : FactorType) :Theorem 1.1Theorem 6.2577 FormulaRegular n σ := by578 intro q hq579 have h2 := prime_power_ge_two q hq580 obtain ⟨h1, h3⟩ := global_coefficients_safe n σ581 exact ⟨expression_regular _ _ (h1 q h2), expression_regular _ _ (h3 q h2)⟩582 583/-! ### Scaled types -/584 585/-- `typeDegree (scaleType δ σ) = δ · typeDegree σ`. -/586private theorem type_degree_scale (δ : ℕ) (σ : FactorType) :587 typeDegree (scaleType δ σ) = δ * typeDegree σ := by588 unfold typeDegree scaleType589 rw [Multiset.map_map, ← Multiset.sum_map_mul_left]590 congr 1591 refine Multiset.map_congr rfl fun z _ ↦ ?_592 simp only [Function.comp]593 ring594 595/-- Scaling by `δ > 0` is injective on types, preserves validity, and multiplies the degree596by `δ`. -/597theorem scale_type_valid_degree_iff (δ r : ℕ) (hδ : 0 < δ) (τ : FactorType) :598 ((ValidType (scaleType δ τ) ∧ typeDegree (scaleType δ τ) = δ * r) ↔599 (ValidType τ ∧ typeDegree τ = r)) ∧ Function.Injective (scaleType δ) := by600 refine ⟨?_, ?_⟩601 · have hv : ValidType (scaleType δ τ) ↔ ValidType τ := by602 unfold ValidType scaleType603 simp only [Multiset.mem_map, forall_exists_index, and_imp, forall_apply_eq_imp_iff₂]604 exact forall₂_congr fun z _ ↦ by simp [hδ]605 rw [hv, type_degree_scale, Nat.mul_left_cancel_iff hδ]606 · apply Multiset.map_injective607 intro a b h608 simp only [Prod.mk.injEq] at h609 exact Prod.ext h.1 (Nat.eq_of_mul_eq_mul_left hδ h.2)610 611end SurfaceBlowup