lean/SpectreKnot/ProofB.lean
550 lines · 38 declarations, each with its own page · on GitHub ·
Theorem B (theoremB, theoremB_sharp): the nest has no boundary, no closed strand, and any two ports of a block lie on one strand of the block three levels up (b even) or four (b odd).
← SpectreKnot/ProofA.leanSpectreKnot/ProofStrand.lean →
All 39 files, and the declarations of this one
1/-
2**Theorem B** (`theoremB`, `theoremB_sharp`): the nest has no boundary, no closed strand, and any two ports of a
3block lie on one strand of the block three levels up (`b` even) or four (`b` odd).
5The merging (the paper's proof of Thm 9.1): a strand of `N_m` leaves it at a rim port; in `N_{m+1}` it runs on to the
6parent hook at the junction that the junction map names (`step_tile`, `NestStep.lean`), or, on child 1's side 2, the
7rim port is itself a parent hook (`stretch_eq`) (Lemma 9.3). The junctions lie inside the parent's sides 2–5
8(Lemma 9.4), and inside side `J` the map depends only on `J` (`adv_some`, `adv_none`). Following the sides level by
9level, every strand of `N_b` reaches the hook at junction 12 of `N_{b+3}` (even `b`) or `N_{b+4}` (odd `b`).
10-/
11import SpectreKnot.NestStep
13namespace SpectreKnot.Statement
15open Pattern Compose Gluing
17/-! ### Child 1's side 2: its rim ports are parent hooks -/
19/-- The parent vertex at child 1's vertex `u` on its side 2 (piece 16 of the parent's rim, traversed backwards). -/
22/-- Piece 16 of the Δ-supertile's rim is child 1's side 2. -/
25/-- Piece 17 starts where piece 16, child 1's side 2, ends. -/
27 -- piece 17 starts where piece 16 does, plus its length
30 exact next_start
32/-- Rim position `jpos 16 + i` of the Δ-supertile is child 1's edge `pos 2 + L 1 2 - 1 - i`, on its side 2. -/
35 -- the `i`-th edge of piece 16
36 have on_piece := ownGo_jpos L (q := 16) (by omega) (by rw [piece16]; exact hi)
38 exact on_piece
40/-- The gluing's port `(1, u, s)` of `N_{m+1}` is port `(u, s)` of `N_m`, taken one level up. -/
44/-- **On child 1's side 2, rim ports of `N_m` are rim ports of `N_{m+1}`**: for `u` strictly inside side 2, port
45`(u, s)` of `N_m`, one level up, is port `(stp u, !s)` of `N_{m+1}` (the hand swaps with the orientation). -/
46theorem stretch_eq {m : Nat} (m_pos : 1 ≤ m) {u : Nat} (after_two : pos (Lk m .Delta 1) 2 < u)
48 upPort m 1 ((N m).bport (ori m) (u, s)) = (N (m + 1)).bport (ori (m + 1)) (stp (Lk m .Delta) u, !s) := by
49 -- the children of `N_{m+1}`
51 -- child 1's side 2 ends `L 1 2` edges after it starts
52 have side_two_len : pos (Lk m .Delta 1) 3 = pos (Lk m .Delta 1) 2 + Lk m .Delta 1 2 := pos_succ _ 2
53 -- and no later than the rim
55 -- piece 17 starts where piece 16 ends
57 -- and the rim ends at least 25 edges later
59 -- so the parent vertex is on the parent's rim
62 -- piece 16 starts at least 5 edges along
65 cases s
66 · rw [Bool.not_false, kids.bport_R stp_lt]
67 -- the parent's rim edge at `stp u` is child 1's edge `u - 1`
69 -- so the gluing's port there is `L` at child 1's vertex `u`
70 have gR_eq : gR .Delta (Lk m .Delta) (dOff m) (ori m) (stp (Lk m .Delta) u) = (1, u, false) := by
71 -- the end of edge `u - 1` is vertex `u`
77 · rw [Bool.not_true, kids.bport_L stp_lt]
78 -- the rim position before `stp u`
81 -- `stp u` is not rim position 0
84 -- the parent's rim edge there is child 1's edge `u`
86 -- so the gluing's port there is `R` at child 1's vertex `u`
88 -- the edge's number is `u`
89 have edge_u : pos (Lk m .Delta 1) 2 + Lk m .Delta 1 2 - 1 - (pos (Lk m .Delta 1) 3 - u - 1) = u := by omega
93/-! ### Sides -/
95/-- `v` lies inside side `J` of `N_n`, at least two vertices from either end. -/
96def Inside (n J v : Nat) : Prop := pos (Lk n .Delta 1) J + 2 ≤ v ∧ v + 2 ≤ pos (Lk n .Delta 1) (J + 1)
98/-- Side `J` of `N_{n+1}` starts where piece `sJ J` of its rim starts (with the level-`n` lengths). -/
101 rw [show pos (Lk (n + 1) .Delta 1) J = vpos (n + 1) .Delta J from rfl, vpos_eq n_pos .Delta hJ, vpos_jpos _ hJ]
103/-- The sides start at pieces `0 … 22`. -/
106/-- A junction `q` at least one piece after the start of side `J` and one piece before its end lies inside side `J`
107of `N_{n+1}`. -/
111 -- the side ends within the rim's 22 pieces
113 -- `k₁` pieces from the side's start to `q`, each of at least 5 edges
114 have from_start := jpos_le_add (Lk n .Delta) (len5 n_pos) (sJ J) k₁ (by omega)
115 -- and `k₂` pieces from `q` to the side's end
116 have to_end := jpos_le_add (Lk n .Delta) (len5 n_pos) q k₂ (by omega)
117 rw [after_start] at from_start
118 rw [before_end] at to_end
119 refine ⟨?_, ?_⟩
123/-- Junction 9 lies inside side 2 of `N_{n+1}`. -/
126/-- Junction 12 lies inside side 3 of `N_{n+1}`. -/
129/-- Junction 16 lies inside side 4 of `N_{n+1}`. -/
132/-- Junction 17 lies inside side 4 of `N_{n+1}`. -/
135/-- Junction 21 lies inside side 5 of `N_{n+1}`. -/
139/-- The parent vertex at a vertex strictly inside child 1's side 2 lies inside side 4 of `N_{n+1}`. -/
140theorem inside_stp {n : Nat} (n_pos : 1 ≤ n) {u : Nat} (after_two : pos (Lk n .Delta 1) 2 < u)
142 -- child 1's side 2 ends `L 1 2` edges after it starts
143 have side_two_len : pos (Lk n .Delta 1) 3 = pos (Lk n .Delta 1) 2 + Lk n .Delta 1 2 := pos_succ _ 2
144 -- piece 17 starts where piece 16 ends
146 -- side 4 starts (at piece 14) at least 10 edges before piece 16
147 have side4_start := jpos_le (Lk n .Delta) (len5 n_pos) (q := 14) (q' := 16) (by omega) (by omega)
148 -- and ends (at piece 19) at least 10 edges after piece 17
150 refine ⟨?_, ?_⟩
153 omega
156 omega
158/-- A vertex inside a side is at least two vertices from both ends of the rim. -/
159theorem inside_bounds {n J v : Nat} (hJ : J < 6) (inside : Inside n J v) :
161 -- `v` is at least two vertices after the start of side `J`
162 have after_start := inside.1
165/-! ### The map read side by side -/
167/-- From a vertex inside side `J` of `N_n` where the map names junction `q`, the strand runs on, one level up, to
168the hook at junction `q` of `N_{n+1}`. -/
173 -- `v` is a rim vertex of `N_n`, away from the corners
174 have v_bounds := inside_bounds hJ inside
177/-- From a vertex inside side 2 of `N_n` (on the parent's rim), the strand is, one level up, on the hook at the same
178vertex of `N_{n+1}`. -/
182 -- `v` lies at least two vertices after the start of side 2
183 have after_start := inside.1
184 -- and two before its end, vertex `pos 3`
186 rw [stretch_eq n_pos (by omega) (by omega), Bool.not_true]
187 -- the parent vertex lies inside side 4 of `N_{n+1}`, so it is a hook
188 have stp_inside := inside_stp n_pos (show pos (Lk n .Delta 1) 2 < v by omega) (by omega)
189 exact hook (by omega) (inside_bounds (by omega) stp_inside).1 (inside_bounds (by omega) stp_inside).2
191/-- `x` is on the strand of the hook at a vertex inside side `J` of `N_n`. -/
195/-- A strand that reaches a hook inside side `J` of `N_n` reaches, one level up, the hook at the junction the map
196names for side `J`. -/
197theorem reach_some {n : Nat} (n_pos : 1 ≤ n) {J q : Nat} (hJ : J < 6) {x : Port} (reach : Reach n J x)
199 (N (n + 1)).Linked (upPort n 1 x) ((N (n + 1)).bport (ori (n + 1)) (jpos (Lk n .Delta) q, true)) := by
200 obtain ⟨x_port, v, inside, linked⟩ := reach
203/-- A strand that reaches a hook inside side 2 of `N_n` (on the parent's rim) reaches, one level up, a hook inside
204side 4 of `N_{n+1}`. -/
205theorem reach_none {n : Nat} (n_pos : 1 ≤ n) {x : Port} (reach : Reach n 2 x) : Reach (n + 1) 4 (upPort n 1 x) := by
206 obtain ⟨x_port, v, inside, linked⟩ := reach
207 -- `v` lies at least two vertices after the start of side 2
208 have after_start := inside.1
209 -- and two before its end, vertex `pos 3`
211 exact ⟨isPort_up n_pos x_port, _, inside_stp n_pos (by omega) (by omega),
214/-- A port of `N_{n+1}` on the strand of the hook at a junction inside side `J` reaches side `J`. -/
217 (linked : (N (n + 1)).Linked y ((N (n + 1)).bport (ori (n + 1)) (jpos (Lk n .Delta) q, true))) :
219 ⟨y_port, _, inside, linked⟩
221/-! ### The first step: from a port of `N_b` -/
223/-- The map names no junction only strictly inside side 2. -/
227 revert tgt_eq
228 cases ω <;> simp only [Bool.false_eq_true, ite_false, ite_true] <;> (repeat' split) <;> intro tgt_eq <;>
229 first | omega | (exfalso; simp at tgt_eq)
231/-- For `ω = true` the map names only junctions 17, 9, 16 and 12. -/
232theorem tgt_vals_t {f : Nat → Nat} {u : Nat} {s : Bool} {q : Nat} (tgt_eq : tgt true f u s = some q) :
233 q = 17 ∨ q = 9 ∨ q = 16 ∨ q = 12 := by
235 revert tgt_eq
236 cases s <;> simp only [ite_true] <;> (repeat' split) <;> intro tgt_eq <;>
237 simp only [Option.some.injEq, reduceCtorEq] at tgt_eq <;> omega
239/-- For `ω = false` the map names only junctions 21, 16 and 17. -/
240theorem tgt_vals_f {f : Nat → Nat} {u : Nat} {s : Bool} {q : Nat} (tgt_eq : tgt false f u s = some q) :
241 q = 21 ∨ q = 16 ∨ q = 17 := by
243 revert tgt_eq
244 cases s <;> simp only [Bool.false_eq_true, ite_false] <;> (repeat' split) <;> intro tgt_eq <;>
245 simp only [Option.some.injEq, reduceCtorEq] at tgt_eq <;> omega
247/-- **The first step**: one level up, every port of `N_b` reaches a hook inside side 2, 3 or 4 of `N_{b+1}` (if
248`ω_b = true`, that is `b` even) or inside side 4 or 5 (if `ω_b = false`). Inside side 2, the hook is the one at
249junction 9. -/
253 (J = 2 → (N (b + 1)).Linked (upPort b 1 x) ((N (b + 1)).bport (ori (b + 1)) (jpos (Lk b .Delta) 9, true))) := by
254 -- `N_b` has the signature
256 -- following the ribbon from `x` leaves `N_b` at a port `r`
257 obtain ⟨r, follows⟩ := good_b.sig.noClosed x x_port
258 obtain ⟨nothing_across, r_tile, r_vertex⟩ := Patch.Follow.end_ good_b.sig follows x_port.1 x_port.2
259 -- `r` is port `s` at a rim vertex `u`
260 obtain ⟨u, s, hu, rfl⟩ := Patch.rim_port good_b.sig r_tile r_vertex nothing_across
261 -- the rim of `N_b`
264 rw [rim_len] at hu
265 -- one level up, `x` is on the strand of that rim port
267 -- and is a port of `N_{b+1}`
270 | none =>
271 -- strictly inside child 1's side 2: the rim port is a hook of `N_{b+1}`, inside its side 4
273 refine ⟨4, ⟨x_up_port, _, inside_stp b_pos after_two before_three, lifted.trans ?_⟩, fun _ => by omega,
274 fun _ => by omega, fun wrong => absurd wrong (by decide)⟩
275 -- the rim port of `N_b`, one level up, is a rim port of `N_{b+1}`
276 have same_port := stretch_eq b_pos after_two before_three s
278 rw [same_port]
279 -- inside side 4 of `N_{b+1}`
280 have stp_inside := inside_stp b_pos after_two before_three
281 cases s
282 · exact .refl
283 · exact hook (by omega) (inside_bounds (by omega) stp_inside).1 (inside_bounds (by omega) stp_inside).2
284 | some q =>
285 -- one level up, the strand runs on to the hook at junction `q`
288 · rw [orient] at tgt_eq
289 rcases tgt_vals_f tgt_eq with rfl | rfl | rfl
290 · exact ⟨5, reach_of x_up_port (inside_21 b_pos) to_junction, fun wrong => by simp at wrong, fun _ => by omega,
291 fun wrong => absurd wrong (by decide)⟩
292 · exact ⟨4, reach_of x_up_port (inside_16 b_pos) to_junction, fun wrong => by simp at wrong, fun _ => by omega,
293 fun wrong => absurd wrong (by decide)⟩
294 · exact ⟨4, reach_of x_up_port (inside_17 b_pos) to_junction, fun wrong => by simp at wrong, fun _ => by omega,
295 fun wrong => absurd wrong (by decide)⟩
296 · rw [orient] at tgt_eq
297 rcases tgt_vals_t tgt_eq with rfl | rfl | rfl | rfl
298 · exact ⟨4, reach_of x_up_port (inside_17 b_pos) to_junction, fun _ => by omega, fun wrong => by simp at wrong,
299 fun wrong => absurd wrong (by decide)⟩
300 · exact ⟨2, reach_of x_up_port (inside_9 b_pos) to_junction, fun _ => by omega, fun wrong => by simp at wrong,
301 fun _ => to_junction⟩
302 · exact ⟨4, reach_of x_up_port (inside_16 b_pos) to_junction, fun _ => by omega, fun wrong => by simp at wrong,
303 fun wrong => absurd wrong (by decide)⟩
304 · exact ⟨3, reach_of x_up_port (inside_12 b_pos) to_junction, fun _ => by omega, fun wrong => by simp at wrong,
305 fun wrong => absurd wrong (by decide)⟩
307/-! ### The chain -/
309/-- The hook at junction 12 of `N_{n+1}`, where every strand of the block three or four levels down ends up. -/
312/-- Even levels have `ω = true`. -/
314/-- Odd levels have `ω = false`. -/
317/-- **Even `b`**: every port of `N_b` lies, in `N_{b+3}`, on the strand of the hook at junction 12. -/
318theorem chain_even {b : Nat} (b_pos : 1 ≤ b) (even : b % 2 = 0) {x : Port} (x_port : (N b).IsPort x) :
320 -- level `b` is even
322 -- level `b + 1` odd
324 -- and level `b + 2` even
326 -- one level up: inside side 2, 3 or 4
327 obtain ⟨J, reach_J, sides_even, _, _⟩ := first b_pos x_port
328 -- two levels up: inside side 4
330 -- the port, one level up, is a port of `N_{b+1}`
332 rcases sides_even ori_b with rfl | rfl | rfl
333 · exact reach_none (by omega) reach_J
334 · exact reach_of up_port (inside_16 (by omega)) (reach_some (by omega) (by omega) reach_J (by rw [ori_b1]; rfl))
335 · exact reach_of up_port (inside_16 (by omega)) (reach_some (by omega) (by omega) reach_J (by rw [ori_b1]; rfl))
336 -- three levels up: the hook at junction 12
337 exact reach_some (n := b + 2) (by omega) (by omega) reach_four (by rw [ori_b2]; rfl)
339/-- **Odd `b`**: every port of `N_b` lies, in `N_{b+4}`, on the strand of the hook at junction 12. -/
340theorem chain_odd {b : Nat} (b_pos : 1 ≤ b) (odd : b % 2 = 1) {x : Port} (x_port : (N b).IsPort x) :
342 -- level `b` is odd
344 -- level `b + 1` even
346 -- level `b + 2` odd
348 -- and level `b + 3` even
350 -- one level up: inside side 4 or 5
351 obtain ⟨J, reach_J, _, sides_odd, _⟩ := first b_pos x_port
352 -- the port, one level up, is a port of `N_{b+1}`
354 -- three levels up: inside side 4
356 -- the port, two levels up, is a port of `N_{b+2}`
358 rcases sides_odd ori_b with rfl | rfl
359 · -- from side 4
360 -- two levels up, inside side 3
362 reach_of up_port (inside_12 (by omega)) (reach_some (by omega) (by omega) reach_J (by rw [ori_b1]; rfl))
364 (reach_some (by omega) (by omega) reach_three (by rw [ori_b2]; rfl))
365 · -- from side 5
366 -- two levels up, inside side 2
368 reach_of up_port (inside_9 (by omega)) (reach_some (by omega) (by omega) reach_J (by rw [ori_b1]; rfl))
369 exact reach_none (by omega) reach_two
370 -- four levels up: the hook at junction 12
371 exact reach_some (n := b + 3) (by omega) (by omega) reach_four (by rw [ori_b3]; rfl)
373/-- Any number of levels up, a port of `N_b` is still a port. -/
374theorem isPort_upk {b : Nat} (b_pos : 1 ≤ b) {x : Port} (x_port : (N b).IsPort x) :
376 | 0 => x_port
377 | k + 1 => by rw [upPort_succ]; exact isPort_up (m := b + k) (by omega) (isPort_upk b_pos x_port k)
379/-- **Theorem B with the paper's bound.** -/
380theorem theoremB_sharp : TheoremB_sharp := by
381 intro b p q b_pos hp hq
382 rcases Nat.mod_two_eq_zero_or_one b with even | odd
383 · -- even `b`
384 -- both ports reach the hook at junction 12 of `N_{b+3}`, so they lie on one strand there
386 (chain_even b_pos even hp).trans
387 (linked_symm (m := b + 3) (by omega) (chain_even b_pos even hq) (isPort_upk b_pos hq 3))
388 refine ⟨?_, fun _ => linked3⟩
389 -- and one level further up, in `N_{b+4}`
390 have linked4 := lift_nest (m := b + 3) (by omega) linked3 (isPort_upk b_pos hp 3)
391 rw [← upPort_succ, ← upPort_succ] at linked4
392 exact linked4
393 · -- odd `b`: both ports reach the hook at junction 12 of `N_{b+4}`
395 (linked_symm (m := b + 4) (by omega) (chain_odd b_pos odd hq) (isPort_upk b_pos hq 4)),
396 fun is_even => absurd is_even (by omega)⟩
398/-! ### No boundary -/
400/-- An edge glued in `N_m` stays glued in `N_{m+1}`. -/
404 -- the children of `N_{m+1}`
406 -- the same gluing, in child 1
409 rw [kids.glue_shift (c := 1) (by decide) ht]
411 rw [glued_child]
412 exact ⟨_, rfl⟩
414/-- Child 1's sides other than side 2 are glued to siblings. -/
417 ∃ e, (Comp.ofLens .Delta (Lk n .Delta) (dOff n) (ori n)).toGluing.mate 1 p = some e := by
418 -- side `j` has `L 1 j` edges
421 show ∃ e, (Comp.ofLens .Delta (Lk n .Delta) (dOff n) (ori n)).mate 1 (pos (Lk n .Delta 1) j + o) = some e
422 rw [ofLens_mate (fun c _ j _ => by
423 -- every side has an edge
425 omega) (by decide) hj (by omega)]
427 | none => exact absurd (adj_one_none j hj adj) not_two
428 | some _ => exact ⟨_, rfl⟩
430/-- **No boundary** (Lemma 8.3(b)): every edge of `N_b` is glued in `N_{b+2}`. -/
431theorem no_boundary {b : Nat} (b_pos : 1 ≤ b) {t i : Nat} (ht : t < (N b).tiles) (hi : i < 14) :
433 -- `N_b` has the signature
435 -- so does `N_{b+1}`, of level at least 1
436 have b1_pos : 1 ≤ b + 1 := by omega
437 -- the tile, one level up, is a tile of `N_{b+1}`
439 -- an edge glued in `N_{b+1}` is glued in `N_{b+2}`
440 have glued_up : ∀ e, (N (b + 1)).glue (up b 1 t) i = some e → ((N (b + 2)).glue (up b 2 t) i).isSome := by
441 intro e glued
445 | some e =>
446 -- glued in `N_b`, so in `N_{b+1}`
448 exact glued_up e' glued'
449 | none =>
450 -- a rim edge of `N_b`, at rim position `k`
451 obtain ⟨k, hk, at_k⟩ := good_b.sig.rim_all t i ht hi glued_b
452 -- the children of `N_{b+1}`
454 -- the rim of `N_b`
457 -- so `k` is a rim position of child 1
459 -- `N_{b+1}` glues the edge as the gluing's `mate` says
460 have formula := kids.glue_rimEdge (c := 1) (by decide) hk
461 -- the edge, as rim edge `k` of child 1
463 rw [at_k'] at formula
464 -- its side `j` and offset `o`
466 -- side `j` has `L 1 j` edges
468 by_cases side_two : j = 2
469 · -- on child 1's side 2: a rim edge of `N_{b+1}`, on its side 4
470 subst side_two
471 -- side 2 of child 1 lies on the parent's rim
472 have on_rim : (Comp.ofLens .Delta (Lk b .Delta) (dOff b) (ori b)).toGluing.mate 1 k = none := by
473 rw [k_eq]
474 exact ofLens_mate_none (fun c j => by
475 -- every side has an edge
477 omega) (by decide) (by omega) ho rfl
478 -- so the edge is the parent's rim edge at some position `p`
479 obtain ⟨p, hp, own_p⟩ := own_surj (d := dOff b) (ω := ori b) kids.len_pos (by decide) k_lt on_rim
480 -- piece 17 starts where piece 16 ends
482 -- and the rim ends at least 25 edges later
484 -- where the pieces end
486 -- `p` is on piece 16, child 1's side 2
490 -- the same edge of child 1
493 rw [edge_eq]
494 -- the edge at rim position `p` of `N_{b+1}` is `(up b 1 t, i)`
497 rw [N_succ b_pos, rim_edgeAt kids.shape hp, own_p, at_k']
498 rfl
499 -- the children of `N_{b+2}`
501 -- `p` is a rim position of `N_{b+1}`, child 1 of `N_{b+2}`
505 -- `N_{b+2}` glues it as `mate` says
506 have formula' := kids'.glue_rimEdge (c := 1) (by decide) p_lt
507 rw [edge_p] at formula'
508 -- side 4 of `N_{b+1}` starts at piece 14
510 -- and side 5 at piece 19
512 -- piece 16 starts at least 10 edges after piece 14
514 -- and piece 19 at least 10 edges after piece 17
516 -- side 4 of child 1 of `N_{b+2}` is glued to a sibling
520 rw [mated] at formula'
523 rw [formula']; rfl
524 · -- on another side: glued to a sibling in `N_{b+1}`
526 rw [mated, Option.map_some] at formula
529/-! ### Theorem B -/
531/-- **Theorem B** (as stated in `Statement.lean`). -/
533 refine ⟨fun b b_pos t i ht hi => no_boundary b_pos ht hi, fun b => theoremA b .Delta, ?_⟩
534 intro b p q hp hq
535 rcases Nat.eq_zero_or_pos b with rfl | b_pos
536 · -- `N_0` is one tile, tile 1 of `N_1`
537 -- `N_1` has nine tiles
539 -- `p` is on the one tile of `N_0`
540 have p_tile : p.1 < 1 := hp.1
541 -- and so is `q`
542 have q_tile : q.1 < 1 := hq.1
543 -- one level up, `p` is a port of `N_1`
545 -- and so is `q`
547 exact ⟨5, (theoremB_sharp 1 _ _ (Nat.le_refl _) p_up q_up).1⟩
548 · exact ⟨4, (theoremB_sharp b p q b_pos hp hq).1⟩
550end SpectreKnot.Statement