lean/SpectreKnot/Parity.lean
632 lines · 38 declarations, each with its own page · on GitHub ·
The parity lemma (the paper's Prop 7.4, by Lemmas 7.1 and 7.2). For every level m ≥ 1, every kind and both signs, the composition with the level-m lengths (ℓ_m, d_m), its children carrying the signature, has the signature itself (parity_lemma; prop_7_4 reads it at Table 3's rim positions).
← SpectreKnot/CompSig.leanSpectreKnot/PatchSig.lean →
All 39 files, and the declarations of this one
1/-
2**The parity lemma** (the paper's Prop 7.4, by Lemmas 7.1 and 7.2). For every level `m ≥ 1`, every kind and both
3signs, the composition with the level-`m` lengths `(ℓ_m, d_m)`, its children carrying the signature, has the signature
4itself (`parity_lemma`; `prop_7_4` reads it at Table 3's rim positions).
6Proof, as in the paper. The pairs `(L, d)` reached from `(ℓ₁, d₁)` by moves are the admissible ones (`Adm`): a move adds
7two edges to a pair of glued sides (or to one side on the parent's rim), and two to `d` if it adds them before the Σ
8corner. The level-`m` lengths are admissible (`adm_level`, Lemma 7.2(a)), and a property that holds at `(ℓ₁, d₁)` and is
9kept by the moves holds at every admissible pair (`adm_induct`, Lemma 7.2(b)). The signature holds at `(ℓ₁, d₁)` by
10Computation 7.3 (`sig_base`), and a move keeps it (Lemma 7.1, `Move.OK.keep`): a move is the same as cutting one edge
11into three (`Move.OK.equiv`), and cutting keeps the signature (`Cut.OK.sig`). So every admissible pair has it
12(`adm_sig`). The junction map (`StepMap.lean`, Lemma 9.3) is carried to every level by `adm_induct` too.
13-/
14import SpectreKnot.Move
15import SpectreKnot.CompSig
17namespace SpectreKnot.Compose
19open Gluing Pattern
21/-! ### Facts from the tables -/
23/-- The Σ child of each kind. -/
25 | .Gamma => 3
26 | _ => 4
28/-- `sigIdx T` is a child of kind `T`, and it is the Σ child (checked by `decide`). -/
30 intro T; cases T <;> decide
32/-- Each kind has only one Σ child. -/
33theorem sigma_unique : ∀ T : Kind, ∀ c, c < nk T → ∀ c', c' < nk T → kidAt T c = .Sigma → kidAt T c' = .Sigma →
34 c = c' := by
35 intro T; cases T <;> decide
37/-- Table 2 glues sides with the same letter. -/
40 | none => true
43/-- Table 2 glues sides with the same letter, at every side of every child of every kind (checked by `decide`). -/
45 intro T; cases T <;> decide
47/-- Sides glued by Table 2 carry the same letter. -/
48theorem pair_letter {T : Kind} {c j c' j' : Nat} (c_lt : c < nk T) (j_lt : j < 6)
50 -- the table check at `(c, j)`
53 exact table
55/-! ### Sums -/
57/-- `tot n f = f 0 + … + f (n-1)`. -/
59 | 0, _ => 0
62/-- Sums are monotone: if `f ≤ g` term by term, then `tot n f ≤ tot n g`. -/
63theorem tot_le {n : Nat} {f g : Nat → Nat} (le_termwise : ∀ i, i < n → f i ≤ g i) : tot n f ≤ tot n g := by
64 induction n with
65 | zero => exact Nat.le_refl _
66 | succ n ih =>
68 -- the first `n` terms
69 have := ih (fun i i_lt => le_termwise i (by omega))
70 -- the last term
71 have := le_termwise n (by omega)
72 omega
74/-- If `f ≤ g` term by term, and strictly at one term, then `tot n f < tot n g`. -/
75theorem tot_lt {n : Nat} {f g : Nat → Nat} (le_termwise : ∀ i, i < n → f i ≤ g i) {i : Nat} (i_lt : i < n)
77 induction n with
78 | zero => omega
79 | succ n ih =>
81 by_cases is_last : i = n
82 · subst is_last
83 -- the terms before the strict one
85 omega
86 -- the strict term is among the first `n`
87 · have := ih (fun k k_lt => le_termwise k (by omega)) (by omega)
88 -- the last term
89 have := le_termwise n (by omega)
90 omega
92/-- A sum that is not zero has a term that is not zero. -/
93theorem tot_ne_zero {n : Nat} {f : Nat → Nat} (ne_zero : tot n f ≠ 0) : ∃ i, i < n ∧ f i ≠ 0 := by
94 induction n with
95 | zero => exact absurd rfl ne_zero
96 | succ n ih =>
98 by_cases last_zero : f n = 0
99 · obtain ⟨i, i_lt, term_ne⟩ := ih (by omega)
100 exact ⟨i, by omega, term_ne⟩
101 · exact ⟨n, by omega, last_zero⟩
103/-- A sum that is zero has only zero terms. -/
104theorem tot_eq_zero {n : Nat} {f : Nat → Nat} (eq_zero : tot n f = 0) : ∀ i, i < n → f i = 0 := by
105 induction n with
106 | zero => intro i i_lt; omega
107 | succ n ih =>
109 intro i i_lt
110 by_cases is_last : i = n
111 · subst is_last; omega
112 · exact ih (by omega) i (by omega)
114/-! ### Admissible lengths -/
116/-- The level-1 side lengths ℓ₁. -/
119/-- Side lengths `L` and Σ offset `d` reachable from `(ℓ₁, d₁)` by moves: every side at least as long as at level 1
120and of the same parity, glued sides equally long, `d ≥ d₁` of the same parity, and the rest of the Σ child's side 5
121past its corner at least as long as at level 1. -/
129/-- How far `L` is from `ℓ₁`. -/
130def excess (T : Kind) (L : Nat → Nat → Nat) : Nat := tot (nk T) fun c => tot 6 fun j => L c j - L₁ T c j
132/-- Every level-1 side has at least 5 edges (Lemma 6.5). -/
135/-- At level 1, side 5 of the Σ child has 10 edges. -/
139/-- The level-1 Σ offset is `d₁ = 6`. -/
142/-- A composition depends only on the lengths of actual sides (and on `d` only through its Σ child). -/
143theorem ofLens_congr {T : Kind} {L L' : Nat → Nat → Nat} {d d' : Nat} {ω : Bool}
146 Comp.ofLens T L d ω = Comp.ofLens T L' d' ω := by
147 unfold Comp.ofLens
148 congr 1
149 apply List.map_congr_left
150 intro c c_lt
151 rw [List.mem_range] at c_lt
152 -- the six side lengths of child `c` agree
153 have same_sides : (List.range 6).map (L c) = (List.range 6).map (L' c) :=
154 List.map_congr_left (fun j j_mem => same_len c c_lt j (List.mem_range.mp j_mem))
155 rw [same_sides]
157 · rw [same_d c c_lt is_sigma]
160/-! ### Undoing a move -/
162namespace Move
166/-- The side lengths before the move. -/
167def shorten (T : Kind) (μ : Move) (L : Nat → Nat → Nat) (c j : Nat) : Nat := L c j - if μ.Hit T c j then 2 else 0
169/-- If a side is lengthened, so is the side glued to it. -/
170theorem hit_partner_mp (c₀_lt : μ.c₀ < nk T) (j₀_lt : μ.j₀ < 6) {c j c' j' : Nat}
172 rcases hit with ⟨rfl, rfl⟩ | ⟨side_glued, rfl, rfl⟩
173 -- (c, j) = (c₀, j₀): Table 2 glues it to the sibling's side, which is hit
175 rw [glued] at partner
176 by_cases side_glued : μ.two T = true
177 · rw [ite_eq_left side_glued] at partner
178 simp only [Option.some.injEq, Prod.mk.injEq] at partner
179 exact Or.inr ⟨side_glued, partner.1, partner.2⟩
180 · rw [ite_eq_right side_glued] at partner; contradiction
181 -- (c, j) = (c₁, j₁): Table 2 glues side `j₀` of `c₀` to it
183 rw [ite_eq_left side_glued] at sib_glued
184 -- so the sibling's side is glued back to side `j₀` of `c₀`
186 rw [glued] at glued_back
187 simp only [Option.some.injEq, Prod.mk.injEq] at glued_back
188 exact Or.inl ⟨glued_back.1, glued_back.2⟩
190/-- Glued sides are both lengthened or both not. -/
191theorem hit_partner (c₀_lt : μ.c₀ < nk T) (j₀_lt : μ.j₀ < 6) {c j c' j' : Nat} (c_lt : c < nk T) (j_lt : j < 6)
193 ⟨hit_partner_mp c₀_lt j₀_lt glued, hit_partner_mp c₀_lt j₀_lt (adj_valid c_lt j_lt glued).2.2.2⟩
195variable {L : Nat → Nat → Nat} {d : Nat}
197/-- The sides lengthened are at least two edges longer than at level 1. -/
198theorem hit_big (adm : Adm T L d) (c₀_lt : μ.c₀ < nk T) (j₀_lt : μ.j₀ < 6) (long₀ : L₁ T μ.c₀ μ.j₀ + 2 ≤ L μ.c₀ μ.j₀)
200 rcases hit with ⟨rfl, rfl⟩ | ⟨side_glued, rfl, rfl⟩
201 · exact long₀
202 -- the sibling's side: Table 2 glues side `j₀` of `c₀` to it
204 rw [ite_eq_left side_glued] at glued
205 rw [adm.pair _ c₀_lt _ j₀_lt _ _ glued]
207 rw [pair_letter c₀_lt j₀_lt glued]
208 exact long₀
210/-- Undoing a move and then making it gives back `L`. -/
211theorem lens_shorten (adm : Adm T L d) (c₀_lt : μ.c₀ < nk T) (j₀_lt : μ.j₀ < 6)
213 funext c j
215 by_cases hit : μ.Hit T c j
216 -- a side lengthened has at least two edges to spare
218 rw [ite_eq_left hit]; omega
219 · rw [ite_eq_right hit]; omega
221/-- Undoing a move from admissible lengths gives admissible lengths, with any Σ offset `d₀` that suits them. -/
222theorem adm_shorten (adm : Adm T L d) (c₀_lt : μ.c₀ < nk T) (j₀_lt : μ.j₀ < 6)
223 (long₀ : L₁ T μ.c₀ μ.j₀ + 2 ≤ L μ.c₀ μ.j₀) {d₀ : Nat} (d₀_ge : dOff 1 ≤ d₀) (d₀_par : (d₀ - dOff 1) % 2 = 0)
226 len c c_lt j j_lt := by
227 -- the side is as long as at level 1 or longer, by an even number of edges
228 have := adm.len c c_lt j j_lt
230 by_cases hit : μ.Hit T c j
231 -- a side lengthened is at least two edges longer than at level 1
233 rw [ite_eq_left hit]; omega
234 · rw [ite_eq_right hit]; omega
235 pair c c_lt j j_lt c' j' glued := by
237 rw [adm.pair c c_lt j j_lt c' j' glued]
238 by_cases hit : μ.Hit T c j
239 · rw [ite_eq_left hit, ite_eq_left ((hit_partner c₀_lt j₀_lt c_lt j_lt glued).mp hit)]
240 · rw [ite_eq_right hit,
241 ite_eq_right (fun partner_hit => hit ((hit_partner c₀_lt j₀_lt c_lt j_lt glued).mpr partner_hit))]
242 d_ge := d₀_ge
243 d_par := d₀_par
244 sig := sig_room
246/-- Undoing a move lowers the excess over the level-1 lengths. -/
247theorem excess_shorten (adm : Adm T L d) (c₀_lt : μ.c₀ < nk T) (j₀_lt : μ.j₀ < 6)
250 -- no side's excess grows
253 refine tot_lt (fun c _ => tot_le (fun j _ => no_growth c j)) c₀_lt (tot_lt (fun j _ => no_growth _ j) j₀_lt ?_)
255 rw [ite_eq_left (show μ.Hit T μ.c₀ μ.j₀ from Or.inl ⟨rfl, rfl⟩)]
256 omega
258/-- **Lemma 7.1**: a move keeps the signature. -/
259theorem OK.keep {ω : Bool} (move_ok : μ.OK T L d ω) (has_sig : Sig (Comp.ofLens T L d ω).toGluing (nk T - 1)) :
260 Sig (Comp.ofLens T (μ.lens T L) (μ.d' T L d) ω).toGluing (nk T - 1) :=
261 move_ok.equiv.symm.sig (move_ok.cutOK.sig has_sig)
263/-- The conditions of a move from the shortened lengths: a move cutting side `j₀` of child `c₀` at offset `r₀`, at
264least one edge from its start and three from its end (with the lengths after the move), can be made at admissible
265shortened lengths whose composition is well formed, if it is clear of the Σ corner. -/
267 (r₀_pos : 1 ≤ μ.r₀) (r₀_room : μ.r₀ + 4 ≤ L μ.c₀ μ.j₀) {d₀ : Nat} (adm₀ : Adm T (μ.shorten T L) d₀)
270 (wf₀ : (Comp.ofLens T (μ.shorten T L) d₀ ω).toGluing.WF) : μ.OK T (μ.shorten T L) d₀ ω :=
271 { wf := wf₀
272 pos_len := fun c hc j hj => by
273 -- each side is at least as long as at level 1
274 have := (adm₀.len c hc j hj).1
275 -- where it has at least 5 edges
277 omega
278 pair := adm₀.pair
279 c₀ := hc₀
280 j₀ := hj₀
281 r₀ := r₀_pos
282 r₀' := by simp only [shorten]; rw [ite_eq_left (show μ.Hit T μ.c₀ μ.j₀ from Or.inl ⟨rfl, rfl⟩)]; omega
283 sig := fun c hc is_sigma => by
284 -- room for the Σ corner on side 5, as at level 1
285 have := adm₀.sig c hc is_sigma
286 -- and `d₀ ≥ d₁`
287 have := adm₀.d_ge
289 omega
290 sig1 := fun c c' hc hc' is_sigma is_sigma' => sigma_unique T c hc c' hc' is_sigma is_sigma'
291 cut₀ := cut₀
292 cut₁ := fun shared is_sigma side_five => by
293 rcases cut₁ shared with not_sigma | not_five <;> contradiction }
295end Move
297/-! ### The induction (Lemma 7.2) -/
299/-- **Lemma 7.2(b), as an induction principle** (with `adm_level`, Lemma 7.2(a), below). A property of `(L, d)` that
300holds at `(ℓ₁, d₁)`, depends only on the lengths of actual sides (and on `d` only through the Σ child), and is kept by
301every move whose cut is two edges clear of both ends of its side or lies on the Σ child's side 5, holds at every
302admissible `(L, d)`.
304By induction on the excess over `ℓ₁` (the paper's induction on `∑ L`): from an admissible `(L, d) ≠ (ℓ₁, d₁)`, undo a
305move, chosen as in the paper: the third edge of a long side; on the Σ child's side 5, the second edge before the corner
306if `d ≥ d₁ + 2`, the second after it if `d = d₁`. The induction also carries that the composition is well formed
307(`Gluing.WF`), which a move needs (`Move.OK`): at `(ℓ₁, d₁)` by Computation 7.3 (`sig_base`), and after a move because
308the composition is then the old one with an edge cut (`Move.OK.equiv`). -/
309theorem adm_induct (T : Kind) (ω : Bool) (P : (Nat → Nat → Nat) → Nat → Prop)
315 P (μ.lens T L) (μ.d' T L d)) :
317 -- by induction on the excess, carrying along that the composition is well formed
318 suffices carried : ∀ N L d, excess T L < N → Adm T L d → P L d ∧ (Comp.ofLens T L d ω).toGluing.WF from
319 fun L d adm => (carried _ L d (Nat.lt_succ_self _) adm).1
320 intro N
321 induction N with
322 | zero => intro L d below_zero; omega
323 | succ N ih =>
324 intro L d excess_lt adm
325 -- the Σ child is an actual child, of kind Σ
326 obtain ⟨sig_lt, sig_kind⟩ := sigIdx_spec T
327 -- `d₁ = 6`
330 · -- the base case: `(L, d) = (ℓ₁, d₁)`
331 -- every side is as long as at level 1
333 -- no excess on side `j` of child `c`
334 have := tot_eq_zero (tot_eq_zero at_base c hc) j hj
335 -- and the side is at least as long as at level 1
336 have := (adm.len c hc j hj).1
337 omega
338 -- and the Σ offset is `d₁`
340 -- room for the Σ corner on side 5
341 have := adm.sig _ sig_lt sig_kind
342 -- which is as long as at level 1
343 have := is_L₁ _ sig_lt 5 (by omega)
344 -- and `d ≥ d₁`
345 have := adm.d_ge
346 omega
347 -- so the property holds, and the composition is that of Computation 7.3, which is well formed
349 rw [ofLens_congr is_L₁ (fun _ _ _ => is_d₁)]
351 · -- a side longer than at level 1
352 obtain ⟨c, hc, child_excess⟩ := tot_ne_zero at_base
353 obtain ⟨j, hj, side_excess⟩ := tot_ne_zero child_excess
354 -- side `j` of child `c` is at least two edges longer than at level 1
356 -- it is at least as long, with the same parity
357 have := adm.len c hc j hj
358 omega
359 -- one step back
365 P L d ∧ (Comp.ofLens T L d ω).toGluing.WF := by
366 intro μ hc₀ hj₀ big r₀_pos r₀_room d₀ adm₀ cut₀ cut₁ d_after clear
367 -- the induction hypothesis: at the shortened lengths, which have less excess, the property holds and the
368 -- composition is well formed
369 obtain ⟨holds₀, wf₀⟩ := ih _ _ (by
370 -- shortening lowers the excess
371 have := Move.excess_shorten adm hc₀ hj₀ big
372 omega) adm₀
373 -- so the move can be made from the shortened lengths
374 have move_ok : μ.OK T (μ.shorten T L) d₀ ω := Move.mkOK hc₀ hj₀ r₀_pos r₀_room adm₀ cut₀ cut₁ wf₀
375 -- side `j₀` of `c₀` is two edges shorter before the move
376 have shortened : μ.shorten T L μ.c₀ μ.j₀ = L μ.c₀ μ.j₀ - 2 := by
377 simp only [Move.shorten]; rw [ite_eq_left (show μ.Hit T μ.c₀ μ.j₀ from Or.inl ⟨rfl, rfl⟩)]
378 -- the property survives the move
379 have after := step μ _ _ move_ok (by
380 rw [shortened]
381 rcases clear with clear_ends | on_sigma_five
382 · exact Or.inl ⟨clear_ends.1, by omega⟩
383 · exact Or.inr on_sigma_five) holds₀
384 -- and the composition after it is the old one with an edge cut, so it is well formed
385 have wf_after := move_ok.equiv.symm.wf move_ok.cutOK.wf_subdiv
386 rw [Move.lens_shorten adm hc₀ hj₀ big, d_after] at after wf_after
387 exact ⟨after, wf_after⟩
388 -- the sibling glued to side 5 of the Σ child is not the Σ child
389 have sib_not_sig : ∀ μ : Move, μ.c₀ = sigIdx T → μ.j₀ = 5 → μ.two T = true → kidAt T (μ.c₁ T) ≠ .Sigma := by
390 intro μ on_sigma side_five shared sib_sigma
391 -- Table 2 glues side `j₀` of `c₀` to side `j₁` of `c₁`
393 rw [ite_eq_left shared] at sib
394 -- the sibling is an actual child, other than `c₀`
396 exact sib_valid.2.2.1 (sigma_unique T _ sib_valid.1 _ (on_sigma ▸ sig_lt) sib_sigma (on_sigma ▸ sig_kind))
398 · -- a move on the Σ child's side 5
399 -- that side is at least two edges longer than at level 1
401 rcases on_sig_five with ⟨rfl, rfl⟩ | glued_to
402 · exact longer
403 · rw [adm.pair c hc j hj _ _ glued_to]
405 rw [pair_letter hc hj glued_to]; exact longer
406 -- side 5 of the Σ child has 10 edges at level 1
408 -- room for the Σ corner on side 5
409 have corner_room := adm.sig _ sig_lt sig_kind
410 -- `d ≥ d₁`
411 have d_ge := adm.d_ge
412 -- and `d` has the parity of `d₁`
413 have d_par := adm.d_par
415 · -- cut the edge at offset 1, before the Σ corner, which moves back by 2
417 ⟨⟨_, 5, 1⟩, rfl, rfl, rfl⟩
419 have hj₀ : μ.j₀ < 6 := by omega -- and side 5 is a side
420 -- the side cut is at least two edges longer than at level 1
422 -- before the move it is two edges shorter
424 simp only [Move.shorten]; rw [ite_eq_left (show μ.Hit T (sigIdx T) 5 from Or.inl ⟨μ_c₀.symm, μ_j₀.symm⟩)]
425 -- the shortened lengths, with `d - 2`, are admissible
427 Move.adm_shorten adm hc₀ hj₀ big' (by omega) (by omega) (fun c' hc' is_sigma => by
428 rw [sigma_unique T _ hc' _ sig_lt is_sigma sig_kind, shortened, sig_five]; omega)
429 refine back μ hc₀ hj₀ big' (by omega) (by rw [μ_c₀, μ_j₀, μ_r₀]; omega) _ adm₀
430 (fun _ _ => Or.inr (by omega)) (fun shared => Or.inl (sib_not_sig μ μ_c₀ μ_j₀ shared)) ?_
431 (Or.inr ⟨by rw [μ_c₀]; exact sig_kind, μ_j₀⟩)
432 -- the move puts the Σ corner back at `d`
433 have new_d := Move.d'_c₀ (L := μ.shorten T L) (d := d - 2) (by rw [μ_c₀]; exact sig_kind) μ_j₀
434 (fun ⟨shared, is_sigma, _⟩ => sib_not_sig μ μ_c₀ μ_j₀ shared is_sigma)
435 rw [ite_eq_left (by omega)] at new_d; omega
436 · -- `d = d₁`: cut the edge just after the Σ corner, which stays put
439 ⟨⟨_, 5, d + 1⟩, rfl, rfl, rfl⟩
441 have hj₀ : μ.j₀ < 6 := by omega -- and side 5 is a side
442 -- the side cut is at least two edges longer than at level 1
444 -- before the move it is two edges shorter
446 simp only [Move.shorten]; rw [ite_eq_left (show μ.Hit T (sigIdx T) 5 from Or.inl ⟨μ_c₀.symm, μ_j₀.symm⟩)]
447 -- the shortened lengths, with the same `d`, are admissible
449 Move.adm_shorten adm hc₀ hj₀ big' d_ge d_par (fun c' hc' is_sigma => by
450 rw [sigma_unique T _ hc' _ sig_lt is_sigma sig_kind, shortened, sig_five]; omega)
451 refine back μ hc₀ hj₀ big' (by omega) (by rw [μ_c₀, μ_j₀, μ_r₀]; omega) _ adm₀
452 (fun _ _ => Or.inl (by omega)) (fun shared => Or.inl (sib_not_sig μ μ_c₀ μ_j₀ shared)) ?_
453 (Or.inr ⟨by rw [μ_c₀]; exact sig_kind, μ_j₀⟩)
454 -- the move leaves the Σ corner at `d`
455 have new_d := Move.d'_c₀ (L := μ.shorten T L) (d := d) (by rw [μ_c₀]; exact sig_kind) μ_j₀
456 (fun ⟨shared, is_sigma, _⟩ => sib_not_sig μ μ_c₀ μ_j₀ shared is_sigma)
457 rw [ite_eq_right (by omega)] at new_d; omega
458 · -- a move elsewhere, cutting the third edge of the side
459 obtain ⟨μ, μ_c₀, μ_j₀, μ_r₀⟩ : ∃ μ : Move, μ.c₀ = c ∧ μ.j₀ = j ∧ μ.r₀ = 2 := ⟨⟨c, j, 2⟩, rfl, rfl, rfl⟩
460 subst μ_c₀ μ_j₀
461 -- every side has at least 5 edges at level 1
463 -- the side cut is not the Σ child's side 5
465 on_sig_five (Or.inl ⟨sigma_unique T _ hc _ sig_lt is_sigma sig_kind, side_five⟩)
466 -- nor is the sibling's side glued to it
468 rintro ⟨shared, is_sigma, side_five⟩
469 -- Table 2 glues side `j₀` of `c₀` to side `j₁` of `c₁`
471 rw [ite_eq_left shared] at sib
472 -- the sibling is an actual child
474 rw [sigma_unique T _ sib_valid.1 _ sig_lt is_sigma sig_kind, side_five] at sib
475 exact on_sig_five (Or.inr sib)
476 -- so the move leaves the Σ child's side 5 alone
478 rintro (⟨is_c₀, is_j₀⟩ | ⟨shared, is_c₁, is_j₁⟩)
479 · exact not_sig_five₀ ⟨is_c₀ ▸ sig_kind, is_j₀.symm⟩
480 · exact not_sig_five₁ ⟨shared, is_c₁ ▸ sig_kind, is_j₁.symm⟩
481 -- the Σ child's side 5 is as long before the move as after
483 simp only [Move.shorten]; rw [ite_eq_right sig_not_hit]; omega
484 -- the shortened lengths, with the same `d`, are admissible
486 Move.adm_shorten adm hc hj longer adm.d_ge adm.d_par (fun c' hc' is_sigma => by
487 rw [sigma_unique T _ hc' _ sig_lt is_sigma sig_kind, unchanged]; exact adm.sig _ sig_lt sig_kind)
488 refine back μ hc hj longer (by omega) (by omega) _ adm₀
489 (fun is_sigma side_five => absurd ⟨is_sigma, side_five⟩ not_sig_five₀) (fun shared => ?_)
490 (Move.d'_eq not_sig_five₀ not_sig_five₁) (Or.inl ⟨by omega, by omega⟩)
492 · exact Or.inr (fun side_five => not_sig_five₁ ⟨shared, is_sigma, side_five⟩)
493 · exact Or.inl is_sigma
495/-- **Every admissible `(L, d)` has the signature**: it holds at `(ℓ₁, d₁)` by Computation 7.3 (`sig_base`), and a
496move keeps it by Lemma 7.1 (`Move.OK.keep`). -/
497theorem adm_sig (T : Kind) (ω : Bool) : ∀ L d, Adm T L d → Sig (Comp.ofLens T L d ω).toGluing (nk T - 1) :=
498 adm_induct T ω (fun L d => Sig (Comp.ofLens T L d ω).toGluing (nk T - 1))
499 (fun _ _ _ _ same_len same_d has_sig => by rw [ofLens_congr same_len same_d]; exact has_sig)
502/-! ### The level-`m` lengths are admissible -/
504/-- Each Fibonacci number is at most the next. -/
505theorem fib_le_succ (n : Nat) : fib n ≤ fib (n + 1) := by
506 cases n with
507 | zero => decide
508 | succ n => rw [fib_add_two]; omega
510/-- The Fibonacci numbers are monotone. -/
512 induction b with
513 | zero =>
514 -- only `a = 0` is at most 0
515 have a_zero : a = 0 := by omega
516 subst a_zero; exact Nat.le_refl _
517 | succ b ih =>
518 by_cases a_eq : a = b + 1
519 · subst a_eq; exact Nat.le_refl _
520 · exact Nat.le_trans (ih (by omega)) (fib_le_succ b)
522/-- Letter lengths only grow, and keep their parities. -/
523theorem letterLen_ge (m : Nat) (m_pos : 1 ≤ m) (x : Letter) :
525 -- the closed forms of the eight letter lengths (Prop 6.2)
526 obtain ⟨len_a, len_b, len_g, len_d, len_e, len_z, len_h, len_t⟩ := letterLen_fib m m_pos
527 -- and their parities (Cor 6.3)
528 obtain ⟨par_a, par_b, par_g, par_d, par_e, par_z, par_h, par_t⟩ := letterLen_parity m m_pos
529 -- `F(3m+1) ≥ F(4)`
531 -- `F(3m+2) ≥ F(5)`
533 -- `F(3m+3) ≥ F(6)`
535 -- `F(3m+4) ≥ F(7)`
537 -- `F(4) = 3`
539 -- `F(5) = 5`
541 -- `F(6) = 8`
543 -- `F(7) = 13`
545 cases x <;> simp only [letterLen, letterLen1] <;> omega
547/-- The level-`m` lengths `(ℓ_m, d_m)` are admissible. -/
550 len c _ j _ := letterLen_ge m m_pos _
551 pair c c_lt j j_lt c' j' glued := by simp only [pair_letter c_lt j_lt glued]
552 d_ge := by
554 -- `F(3m+1) ≥ F(4)`
556 -- `F(4) = 3`
558 omega
560 sig c _ is_sigma := by
562 rw [L₁_sig is_sigma, is_sigma, dOff_one, show letterOf .Sigma 5 = .delta from rfl, (dOff_fib m m_pos).2]
563 -- `F(3m) ≥ F(3)`
565 -- `F(3) = 2`
567 omega
569/-! ### The parity lemma -/
571/-- **The parity lemma** (the paper's Prop 7.4: Computation 7.3 at every level). For every level `m ≥ 1`, every kind
572`T` and both signs `ω`: the composition of §7.1 with the level-`m` lengths `(ℓ_m, d_m)`, its children carrying the
573signature, has the signature (`Sig`): it is well formed, no strand closes up, every parent rim vertex is a hook except
574the Γ child's corners `A` and `B`, which lie on the parent's rim and carry the crossover. -/
575theorem parity_lemma (m : Nat) (m_pos : 1 ≤ m) (T : Kind) (ω : Bool) :
579/-- **Prop 7.4, as the paper words it**: for every level `m ≥ 1`, every kind `T` and both signs `ω`, the composition
580`C_T(ℓ_m, d_m, ω)` has the signature (`CompSig`): the parity lemma's `Sig`, read at Table 3's rim positions. -/
584 (fun c j => by
585 -- every side has at least 5 edges (Lemma 6.5)
587 omega)
588 (by
589 -- so does side 0 of the Γ child
591 omega)
592 (parity_lemma m m_pos T ω)
594/-- The corner `B` of child `c`, in terms of the composition's own rim length and corner `A`: the vertex after `A` if
595`ω`, the vertex before it otherwise. -/
596theorem ofLens_B' {T : Kind} {L : Nat → Nat → Nat} {d : Nat} {ω : Bool} {c : Nat} (c_lt : c < nk T) :
597 (Comp.ofLens T L d ω).toGluing.B c =
598 if ω then nxt ((Comp.ofLens T L d ω).toGluing.E c) ((Comp.ofLens T L d ω).toGluing.A c)
599 else prv ((Comp.ofLens T L d ω).toGluing.E c) ((Comp.ofLens T L d ω).toGluing.A c) := by
602/-- In a composition with the signature, `A` and `B` are adjacent parent rim vertices: `B` comes right after `A`
603along the parent's rim (in the children's sense) if `ω`, right before it otherwise. -/
605 (G_eq : G = (Comp.ofLens T L d ω).toGluing) (has_sig : Sig G (nk T - 1)) :
608 -- the crossover child is a child of the composition
610 -- the signature says it is a child of `G`
611 have g_lt_G := has_sig.g_lt
613 -- `B` is the vertex after `A` if `ω`, the vertex before it otherwise
616 cases ω with
617 | true =>
618 rw [ite_eq_left rfl] at B_eq ⊢
619 rw [← B_eq]; exact .stop has_sig.rimB
620 | false =>
621 rw [ite_eq_right (by decide)] at B_eq ⊢
624/-- **The parity lemma, adjacency**: `A` and `B` are adjacent parent rim vertices, `B` right after `A` along the
625parent's rim (in the children's sense) if `ω`, right before it otherwise. -/
626theorem parity_lemma_adj (m : Nat) (m_pos : 1 ≤ m) (T : Kind) (ω : Bool) :
627 let G := (Comp.ofPattern T (letterLen m) (dOff m) ω).toGluing
629 if ω then G.Rot (g, nxt (G.E g) (G.A g)) (g, G.B g) else G.Rot (g, nxt (G.E g) (G.B g)) (g, G.A g) :=
630 sig_adj rfl (parity_lemma m m_pos T ω)
632end SpectreKnot.Compose