CubicPathwidth.Alg.Proofs2.R8Attach
Source file CubicPathwidth/Alg/Proofs2/R8Attach.lean of the Lean project (how it is built).
import CubicPathwidth.Alg.Plan2
import CubicPathwidth.Alg.Proofs.Targets
import CubicPathwidth.T4.TorsoDyn
/-!
# R8: attachment invariant (`AttachInvariant`) of a legal record
Depends on the Stage 2 plan interfaces `TorsoSim`, `RecordMono`, `ComponentsConnected`
(taken as hypotheses), and on Stage 1 graph facts and the torso
lemmas `T4.Good.attachment_card_le`, `T4.tgraph_adj_iff`, `T4.mem_components_of_conn`.
`OpsRecordCongr` and `OpsRecordAppend` are part of the signature but not needed.
-/
namespace CubicPathwidth.Alg
open Graph
namespace R8
/-- Subgraph: nodes and adjacency of `H` are among those of `G`. -/
def SubG (H G : Graph) : Prop :=
(∀ x ∈ H.nodes, x ∈ G.nodes) ∧ ∀ u w, H.Adj u w → G.Adj u w
theorem subG_trans {A B C : Graph} (h1 : SubG A B) (h2 : SubG B C) : SubG A C :=
⟨fun x hx => h2.1 x (h1.1 x hx), fun u w h => h2.2 u w (h1.2 u w h)⟩
theorem wf_removeNode {G : Graph} (hG : G.WF) (v : Nat) : (G.removeNode v).WF :=
(removeNodeSpec G v hG).1
theorem wf_addEdge {G : Graph} (hG : G.WF) {u v : Nat} (huv : u ≠ v) :
(G.addEdge u v).WF :=
(addEdgeSpec G u v hG huv).1
theorem mem_of_adj {G : Graph} (hG : G.WF) {u v : Nat} (h : G.Adj u v) :
u ∈ G.nodes ∧ v ∈ G.nodes :=
⟨(wfBasics G hG u v h).1, (wfBasics G hG u v h).2.1⟩
theorem length_le_of_nodup_sub {l₁ l₂ : List Nat} (h1 : l₁.Nodup) (h : ∀ x ∈ l₁, x ∈ l₂) :
l₁.length ≤ l₂.length :=
(List.Nodup.subperm h1 (fun x hx => h x hx)).length_le
theorem ne_of_nbrs_pair {G : Graph} (hG : G.WF) {v a b : Nat} (heq : G.nbrs v = [a, b]) :
a ≠ b := by
have hnd := hG.nbrs_nodup v
rw [heq] at hnd
intro h
subst h
simp at hnd
theorem pair_of_mem_two {l : List Nat} (hl : l.length ≤ 2) {a b : Nat} (ha : a ∈ l)
(hb : b ∈ l) (hab : a ≠ b) : ∃ x y, l = [x, y] := by
match l, hl, ha, hb with
| [], _, ha, _ => simp at ha
| [x], _, ha, hb =>
simp at ha hb
exact absurd (ha.trans hb.symm) hab
| [x, y], _, _, _ => exact ⟨x, y, rfl⟩
| x :: y :: z :: w, hl, _, _ => simp at hl
/-! ## `redStep` -/
theorem redStep_eq_pair {G : Graph} {v a b : Nat} (h : G.nbrs v = [a, b]) :
redStep G v = (G.removeNode v).addEdge a b := by
unfold redStep
rw [h]
theorem redStep_eq_not_pair {G : Graph} {v : Nat} (h : ¬ ∃ a b, G.nbrs v = [a, b]) :
redStep G v = G.removeNode v := by
unfold redStep
split
· rename_i a b heq
exact absurd ⟨a, b, heq⟩ h
· rfl
theorem redStep_wf {G : Graph} (hG : G.WF) (v : Nat) : (redStep G v).WF := by
by_cases h : ∃ a b, G.nbrs v = [a, b]
· obtain ⟨a, b, hab⟩ := h
rw [redStep_eq_pair hab]
exact wf_addEdge (wf_removeNode hG v) (ne_of_nbrs_pair hG hab)
· rw [redStep_eq_not_pair h]
exact wf_removeNode hG v
theorem redStep_nodes_sub {G : Graph} (hG : G.WF) (v x : Nat) (hx : x ∈ (redStep G v).nodes) :
x ∈ G.nodes := by
by_cases h : ∃ a b, G.nbrs v = [a, b]
· obtain ⟨a, b, hab⟩ := h
rw [redStep_eq_pair hab] at hx
have hne := ne_of_nbrs_pair hG hab
rcases (addEdgeSpec (G.removeNode v) a b (wf_removeNode hG v) hne).2.1 x |>.1 hx with hx | hx | hx
· exact ((removeNodeSpec G v hG).2.1 x).1 hx |>.1
· have ha : a ∈ G.nbrs v := by rw [hab]; simp
rw [hx]; exact (mem_of_adj hG ha).2
· have hb : b ∈ G.nbrs v := by rw [hab]; simp
rw [hx]; exact (mem_of_adj hG hb).2
· rw [redStep_eq_not_pair h] at hx
exact ((removeNodeSpec G v hG).2.1 x).1 hx |>.1
theorem redStep_nodes_mem {G : Graph} (hG : G.WF) (v x : Nat) (hx : x ∈ G.nodes) (hxv : x ≠ v) :
x ∈ (redStep G v).nodes := by
have hK : x ∈ (G.removeNode v).nodes := ((removeNodeSpec G v hG).2.1 x).2 ⟨hx, hxv⟩
by_cases h : ∃ a b, G.nbrs v = [a, b]
· obtain ⟨a, b, hab⟩ := h
rw [redStep_eq_pair hab]
exact (addEdgeSpec (G.removeNode v) a b (wf_removeNode hG v) (ne_of_nbrs_pair hG hab)).2.1 x
|>.2 (Or.inl hK)
· rw [redStep_eq_not_pair h]
exact hK
theorem redStep_adj_of {G : Graph} (hG : G.WF) (v u w : Nat) (hu : u ≠ v) (hw : w ≠ v)
(h : G.Adj u w) : (redStep G v).Adj u w := by
have hK : (G.removeNode v).Adj u w := (removeNodeSpec G v hG).2.2 u w |>.2 ⟨h, hu, hw⟩
by_cases hp : ∃ a b, G.nbrs v = [a, b]
· obtain ⟨a, b, hab⟩ := hp
rw [redStep_eq_pair hab]
exact (addEdgeSpec (G.removeNode v) a b (wf_removeNode hG v) (ne_of_nbrs_pair hG hab)).2.2 u w
|>.2 (Or.inl hK)
· rw [redStep_eq_not_pair hp]
exact hK
theorem subG_addEdge {K : Graph} (hK : K.WF) {a b : Nat} (hab : a ≠ b) : SubG K (K.addEdge a b) :=
⟨fun x hx => (addEdgeSpec K a b hK hab).2.1 x |>.2 (Or.inl hx),
fun u w h => (addEdgeSpec K a b hK hab).2.2 u w |>.2 (Or.inl h)⟩
theorem addEdge_sub {H K : Graph} {a b a' b' : Nat} (hH : SubG H K) (hHW : H.WF) (hK : K.WF)
(hab : a ≠ b) (hab' : a' ≠ b') (h1 : (a' = a ∧ b' = b) ∨ (a' = b ∧ b' = a)) :
SubG (H.addEdge a' b') (K.addEdge a b) := by
constructor
· intro x hx
rw [(addEdgeSpec H a' b' hHW hab').2.1 x] at hx
rw [(addEdgeSpec K a b hK hab).2.1 x]
rcases hx with hx | hx | hx
· exact Or.inl (hH.1 x hx)
· rcases h1 with h1 | h1
· exact Or.inr (Or.inl (hx.trans h1.1))
· exact Or.inr (Or.inr (hx.trans h1.1))
· rcases h1 with h1 | h1
· exact Or.inr (Or.inr (hx.trans h1.2))
· exact Or.inr (Or.inl (hx.trans h1.2))
· intro u w h
rw [(addEdgeSpec H a' b' hHW hab').2.2 u w] at h
rw [(addEdgeSpec K a b hK hab).2.2 u w]
rcases h with h | ⟨hu, hw⟩ | ⟨hu, hw⟩
· exact Or.inl (hH.2 u w h)
· rcases h1 with h1 | h1
· exact Or.inr (Or.inl ⟨hu.trans h1.1, hw.trans h1.2⟩)
· exact Or.inr (Or.inr ⟨hu.trans h1.1, hw.trans h1.2⟩)
· rcases h1 with h1 | h1
· exact Or.inr (Or.inr ⟨hu.trans h1.2, hw.trans h1.1⟩)
· exact Or.inr (Or.inl ⟨hu.trans h1.2, hw.trans h1.1⟩)
/-- Pair of neighbours in `G` contained in a list of length at most two. -/
theorem redStep_sub {G G' : Graph} (v : Nat) (hG : G.WF) (hG' : G'.WF) (hS : SubG G' G)
(hl : (G.nbrs v).length ≤ 2) : SubG (redStep G' v) (redStep G v) := by
have hnb : ∀ x ∈ G'.nbrs v, x ∈ G.nbrs v := fun x hx => hS.2 v x hx
have hlen' : (G'.nbrs v).length ≤ 2 :=
le_trans (length_le_of_nodup_sub (hG'.nbrs_nodup v) hnb) hl
have hH : SubG (G'.removeNode v) (G.removeNode v) := by
constructor
· intro x hx
have hx' := ((removeNodeSpec G' v hG').2.1 x).1 hx
exact ((removeNodeSpec G v hG).2.1 x).2 ⟨hS.1 x hx'.1, hx'.2⟩
· intro u w h
have h' := (removeNodeSpec G' v hG').2.2 u w |>.1 h
exact (removeNodeSpec G v hG).2.2 u w |>.2 ⟨hS.2 u w h'.1, h'.2.1, h'.2.2⟩
have hKW : (G.removeNode v).WF := wf_removeNode hG v
by_cases hp : ∃ a b, G.nbrs v = [a, b]
· obtain ⟨a, b, hab⟩ := hp
have hne : a ≠ b := ne_of_nbrs_pair hG hab
rw [redStep_eq_pair hab]
by_cases hp' : ∃ a' b', G'.nbrs v = [a', b']
· obtain ⟨a', b', hab'⟩ := hp'
rw [redStep_eq_pair hab']
have hne' : a' ≠ b' := ne_of_nbrs_pair hG' hab'
have ha' : a' ∈ G.nbrs v := hnb a' (by rw [hab']; simp)
have hb' : b' ∈ G.nbrs v := hnb b' (by rw [hab']; simp)
rw [hab] at ha' hb'
simp only [List.mem_cons, List.not_mem_nil, or_false] at ha' hb'
have h1 : (a' = a ∧ b' = b) ∨ (a' = b ∧ b' = a) := by
rcases ha' with ha' | ha' <;> rcases hb' with hb' | hb'
· exact absurd (ha'.trans hb'.symm) hne'
· exact Or.inl ⟨ha', hb'⟩
· exact Or.inr ⟨ha', hb'⟩
· exact absurd (ha'.trans hb'.symm) hne'
exact addEdge_sub hH (wf_removeNode hG' v) hKW hne hne' h1
· rw [redStep_eq_not_pair hp']
exact subG_trans hH (subG_addEdge hKW hne)
· rw [redStep_eq_not_pair hp]
by_cases hp' : ∃ a' b', G'.nbrs v = [a', b']
· exfalso
obtain ⟨a', b', hab'⟩ := hp'
have hne' : a' ≠ b' := ne_of_nbrs_pair hG' hab'
have ha' : a' ∈ G.nbrs v := hnb a' (by rw [hab']; simp)
have hb' : b' ∈ G.nbrs v := hnb b' (by rw [hab']; simp)
obtain ⟨x, y, hxy⟩ := pair_of_mem_two hl ha' hb' hne'
exact hp ⟨x, y, hxy⟩
· rw [redStep_eq_not_pair hp']
exact hH
/-- Every reached adjacency is between nodes of the final graph. -/
theorem opsRecord_adj_mem (ops : List Op) : ∀ (G R : Graph), G.WF → OpsRecord G ops R →
∀ u v, R.Adj u v → u ∈ R.nodes := by
induction ops with
| nil =>
intro G R hG hrec u v h
have hs : SameGraph G R := hrec
exact (hs.1 u).1 (mem_of_adj hG ((hs.2 u v).2 h)).1
| cons o ops ih =>
intro G R hG hrec u v h
cases o with
| red w nb =>
unfold OpsRecord at hrec
exact ih (redStep G w) R (redStep_wf hG w) hrec.2.2.2.2 u v h
| del w =>
unfold OpsRecord at hrec
exact ih (G.removeNode w) R (wf_removeNode hG w) hrec.2 u v h
/-- Changing the end graph by `SameGraph`. -/
theorem opsRecord_end_congr (ops : List Op) : ∀ (F R R2 : Graph), OpsRecord F ops R →
SameGraph R R2 → OpsRecord F ops R2 := by
induction ops with
| nil =>
intro F R R2 h h2
have hs : SameGraph F R := h
show SameGraph F R2
exact ⟨fun v => (hs.1 v).trans (h2.1 v), fun u v => (hs.2 u v).trans (h2.2 u v)⟩
| cons o ops ih =>
intro F R R2 h h2
cases o with
| red w nb =>
unfold OpsRecord at h ⊢
exact ⟨h.1, h.2.1, h.2.2.1, h.2.2.2.1, ih _ _ _ h.2.2.2.2 h2⟩
| del w =>
unfold OpsRecord at h ⊢
exact ⟨h.1, ih _ _ _ h.2 h2⟩
/-- Replay of a legal record on a subgraph avoiding its deleted vertices. -/
theorem replay (ops : List Op) : ∀ (G G' R : Graph), G.WF → G'.WF → SubG G' G →
(∀ w, Op.del w ∈ ops → w ∉ G'.nodes) → OpsRecord G ops R →
∃ ops' R', RedOnly ops' ∧ OpsRecord G' ops' R' ∧
(∀ v ∈ R'.nodes, v ∈ R.nodes) ∧ (∀ u v, R'.Adj u v → R.Adj u v) ∧
(∀ v ∈ R'.nodes, v ∈ G'.nodes) := by
induction ops with
| nil =>
intro G G' R hG hG' hS _ hrec
have hs : SameGraph G R := hrec
refine ⟨[], G', fun o ho => by simp at ho, ?_, ?_, ?_, fun v hv => hv⟩
· show SameGraph G' G'
exact ⟨fun _ => Iff.rfl, fun _ _ => Iff.rfl⟩
· intro v hv; exact (hs.1 v).1 (hS.1 v hv)
· intro u v h; exact (hs.2 u v).1 (hS.2 u v h)
| cons o ops ih =>
intro G G' R hG hG' hS hdel hrec
cases o with
| red v nb =>
unfold OpsRecord at hrec
obtain ⟨hvG, hnd, hlen, hadj, hrest⟩ := hrec
have hl : (G.nbrs v).length ≤ 2 :=
le_trans (length_le_of_nodup_sub (hG.nbrs_nodup v) (fun x hx => (hadj x).2 hx)) hlen
by_cases hvG' : v ∈ G'.nodes
· have hnb' : (G'.nbrs v).length ≤ 2 :=
le_trans (length_le_of_nodup_sub (hG'.nbrs_nodup v)
(fun x hx => (hadj x).2 (hS.2 v x hx))) hlen
have hdel' : ∀ w, Op.del w ∈ ops → w ∉ (redStep G' v).nodes := by
intro w hw hmem
exact hdel w (List.mem_cons_of_mem _ hw) (redStep_nodes_sub hG' v w hmem)
obtain ⟨ops'', R', hred, hrec2, h1, h2, h3⟩ :=
ih (redStep G v) (redStep G' v) R (redStep_wf hG v) (redStep_wf hG' v)
(redStep_sub v hG hG' hS hl) hdel' hrest
refine ⟨Op.red v (G'.nbrs v) :: ops'', R', ?_, ?_, h1, h2, ?_⟩
· intro o ho
rcases List.mem_cons.1 ho with rfl | ho
· exact ⟨v, G'.nbrs v, rfl⟩
· exact hred o ho
· unfold OpsRecord
exact ⟨hvG', hG'.nbrs_nodup v, hnb', fun x => Iff.rfl, hrec2⟩
· intro x hx
exact redStep_nodes_sub hG' v x (h3 x hx)
· have hS1 : SubG G' (redStep G v) := by
constructor
· intro x hx
have hxv : x ≠ v := by
rintro rfl
exact hvG' hx
exact redStep_nodes_mem hG v x (hS.1 x hx) hxv
· intro u w h
have hu := mem_of_adj hG' h
have huv : u ≠ v := by
rintro rfl
exact hvG' hu.1
have hwv : w ≠ v := by
rintro rfl
exact hvG' hu.2
exact redStep_adj_of hG v u w huv hwv (hS.2 u w h)
exact ih (redStep G v) G' R (redStep_wf hG v) hG' hS1
(fun w hw => hdel w (List.mem_cons_of_mem _ hw)) hrest
| del w =>
unfold OpsRecord at hrec
obtain ⟨_, hrest⟩ := hrec
have hwG' : w ∉ G'.nodes := hdel w (by simp)
have hS1 : SubG G' (G.removeNode w) := by
constructor
· intro x hx
have hxw : x ≠ w := by
rintro rfl
exact hwG' hx
exact ((removeNodeSpec G w hG).2.1 x).2 ⟨hS.1 x hx, hxw⟩
· intro u x h
have hu := mem_of_adj hG' h
have huw : u ≠ w := by
rintro rfl
exact hwG' hu.1
have hxw : x ≠ w := by
rintro rfl
exact hwG' hu.2
exact (removeNodeSpec G w hG).2.2 u x |>.2 ⟨hS.2 u x h, huw, hxw⟩
exact ih (G.removeNode w) G' R (wf_removeNode hG w) hG' hS1
(fun x hx => hdel x (List.mem_cons_of_mem _ hx)) hrest
theorem le_sum_mem : ∀ (l : List ℕ) (x : ℕ), x ∈ l → x ≤ l.sum
| [], x, h => by simp at h
| a :: l, x, h => by
simp only [List.sum_cons]
rcases List.mem_cons.1 h with rfl | h
· omega
· have := le_sum_mem l x h
omega
/-! ## `undoAttach` -/
theorem mem_inner (C D : List Nat) (y : Nat) (l : List Nat) : ∀ acc : List Nat,
y ∈ l.foldl (fun acc x => if C.contains x || D.contains x || acc.contains x then acc
else acc ++ [x]) acc ↔ y ∈ acc ∨ (y ∈ l ∧ y ∉ C ∧ y ∉ D) := by
induction l with
| nil => intro acc; simp
| cons z zs ih =>
intro acc
rw [List.foldl_cons]
rw [ih]
by_cases hc : (C.contains z || D.contains z || acc.contains z) = true
· rw [if_pos hc]
simp only [List.contains, List.elem_eq_mem, decide_eq_true_eq, Bool.or_eq_true] at hc
simp only [List.mem_cons]
constructor
· rintro (h | ⟨h1, h2, h3⟩)
· exact Or.inl h
· exact Or.inr ⟨Or.inr h1, h2, h3⟩
· rintro (h | ⟨h1 | h1, h2, h3⟩)
· exact Or.inl h
· subst h1
rcases hc with (h | h) | h
· exact absurd h h2
· exact absurd h h3
· exact Or.inl h
· exact Or.inr ⟨h1, h2, h3⟩
· rw [if_neg hc]
have hzC : z ∉ C := fun h => hc (by simp [h])
have hzD : z ∉ D := fun h => hc (by simp [h])
by_cases hyz : y = z
· subst hyz
simp [hzC, hzD]
· simp [hyz]
theorem mem_outer (F : Graph) (C D : List Nat) (y : Nat) : ∀ (l : List Nat) (acc : List Nat),
y ∈ l.foldl (fun acc c => (F.nbrs c).foldl (fun acc x =>
if C.contains x || D.contains x || acc.contains x then acc else acc ++ [x]) acc) acc ↔
y ∈ acc ∨ ∃ c ∈ l, y ∈ F.nbrs c ∧ y ∉ C ∧ y ∉ D := by
intro l
induction l with
| nil => intro acc; simp
| cons c cs ih =>
intro acc
rw [List.foldl_cons, ih, mem_inner]
simp only [List.mem_cons, exists_eq_or_imp]
constructor
· rintro ((h | ⟨h1, h2, h3⟩) | h)
· exact Or.inl h
· exact Or.inr (Or.inl ⟨h1, h2, h3⟩)
· exact Or.inr (Or.inr h)
· rintro (h | ⟨h1, h2, h3⟩ | h)
· exact Or.inl (Or.inl h)
· exact Or.inl (Or.inr ⟨h1, h2, h3⟩)
· exact Or.inr h
theorem mem_undoAttach (F : Graph) (D C : List Nat) (x : Nat) :
x ∈ undoAttach F D C ↔ ∃ c ∈ C, x ∈ F.nbrs c ∧ x ∉ C ∧ x ∉ D := by
unfold undoAttach
rw [mem_outer]
simp
theorem nodup_inner (C D : List Nat) (l : List Nat) : ∀ acc : List Nat, acc.Nodup →
(l.foldl (fun acc x => if C.contains x || D.contains x || acc.contains x then acc
else acc ++ [x]) acc).Nodup := by
induction l with
| nil => intro acc h; simpa using h
| cons z zs ih =>
intro acc h
rw [List.foldl_cons]
by_cases hc : (C.contains z || D.contains z || acc.contains z) = true
· rw [if_pos hc]
exact ih acc h
· rw [if_neg hc]
apply ih
apply List.Nodup.append h (List.nodup_singleton z)
rw [List.disjoint_singleton]
intro hz
apply hc
simp only [List.elem_eq_mem, decide_eq_true_eq, Bool.or_eq_true]
exact Or.inr (by simpa using hz)
theorem nodup_undoAttach (F : Graph) (D C : List Nat) : (undoAttach F D C).Nodup := by
unfold undoAttach
have key : ∀ (l : List Nat) (acc : List Nat), acc.Nodup →
(l.foldl (fun acc c => (F.nbrs c).foldl (fun acc x =>
if C.contains x || D.contains x || acc.contains x then acc else acc ++ [x]) acc) acc).Nodup := by
intro l
induction l with
| nil => intro acc h; simpa using h
| cons c cs ih =>
intro acc h
rw [List.foldl_cons]
apply ih
exact nodup_inner C D (F.nbrs c) acc h
exact key C [] List.nodup_nil
/-! ## The rest graph -/
/-- The predicate `v ∉ D ∧ v ∉ V(R)` defining the rest graph of `AttachInvariant`. -/
def restKeep (ops : List Op) (R : Graph) (v : Nat) : Bool :=
!(deletedSet ops).contains v && !R.mem v
theorem restKeep_iff (ops : List Op) (R : Graph) (hR : R.WF) (y : Nat) :
restKeep ops R y = true ↔ (y ∉ deletedSet ops ∧ y ∉ R.nodes) := by
have hm : R.mem y = false ↔ y ∉ R.nodes := by
rw [← hR.mem_iff y]
cases R.mem y <;> simp
unfold restKeep
cases h2 : (deletedSet ops).contains y <;> cases h3 : R.mem y <;> simp_all
/-- Core of `AttachInvariant`, in the torso world of `TorsoSim`. -/
theorem attach_core (n : ℕ) (F R : Graph) (ops : List Op) (F1 B1 : Finset (Fin n))
(hF : F.WF) (hR : R.WF) (hn : ∀ v ∈ F.nodes, v < n) (hOps : OpsRecord F ops R)
(hgood : CubicPathwidth.T4.Good (F.toSimpleGraph n) F1 B1)
(hF1 : ∀ x : Fin n, x ∈ F1 ↔ x.val ∈ F.nodes ∧ x.val ∉ deletedSet ops)
(hB1 : ∀ x : Fin n, x ∈ B1 ↔ x.val ∈ R.nodes)
(hadj : ∀ x y : Fin n,
(CubicPathwidth.T4.tgraph (F.toSimpleGraph n) F1 B1).Adj x y ↔ R.Adj x.val y.val)
(hConn : ComponentsConnected) (hMono : RecordMono) :
∀ C ∈ (F.induced (restKeep ops R)).components,
(∀ x ∈ undoAttach F (deletedSet ops) C, x ∈ R.nodes) ∧
(undoAttach F (deletedSet ops) C).length ≤ 2 ∧
(∀ a b, undoAttach F (deletedSet ops) C = [a, b] → R.Adj a b) ∧
Emptiable (F.induced C.contains) := by
intro C hC
have hHW : (F.induced (restKeep ops R)).WF := (inducedSpec F (restKeep ops R) hF).1
have hHn := (inducedSpec F (restKeep ops R) hF).2.1
have hHadj := (inducedSpec F (restKeep ops R) hF).2.2
have hcomp := componentsSpec (F.induced (restKeep ops R)) hHW
have hCnodes : ∀ y ∈ C, y ∈ F.nodes ∧ restKeep ops R y = true := by
intro y hy
have hmem : y ∈ (F.induced (restKeep ops R)).nodes :=
hcomp.1.mem_iff.1 (List.mem_flatten.2 ⟨C, hC, hy⟩)
exact (hHn y).1 hmem
have hclos : ∀ y ∈ C, ∀ z, (F.induced (restKeep ops R)).Adj y z → z ∈ C :=
fun y hy z h => hcomp.2.2 C hC y hy z h
have hreach : ∀ y ∈ C, ∀ z ∈ C,
Relation.ReflTransGen (F.induced (restKeep ops R)).Adj y z :=
fun y hy z hz => hConn _ hHW C hC y hy z hz
have hCne : C ≠ [] := hcomp.2.1 C hC
-- the torso-side component
obtain ⟨T, hTdef⟩ : ∃ T : Finset (Fin n), T = Finset.univ.filter (fun x => x.val ∈ C) :=
⟨_, rfl⟩
have hTmem : ∀ x : Fin n, x ∈ T ↔ x.val ∈ C := by
intro x; rw [hTdef]; simp
have hSadj : ∀ x y : Fin n, (F.toSimpleGraph n).Adj x y ↔
x ≠ y ∧ (F.Adj x.val y.val ∨ F.Adj y.val x.val) := by
intro x y
simp only [Graph.toSimpleGraph, SimpleGraph.fromRel_adj]
have hSsymm : ∀ x y : Fin n, (F.toSimpleGraph n).Adj x y → F.Adj x.val y.val :=
fun x y h => ((hSadj x y).1 h).2.elim id (fun h' => hF.symm _ _ h')
have hUmem : ∀ x : Fin n, x ∈ F1 \ B1 ↔ (x.val ∈ F.nodes ∧ restKeep ops R x.val = true) := by
intro x
rw [Finset.mem_sdiff, hF1 x, hB1 x, restKeep_iff ops R hR]
constructor
· rintro ⟨⟨h1, h2⟩, h3⟩
exact ⟨h1, h2, h3⟩
· rintro ⟨h1, h2, h3⟩
exact ⟨⟨h1, h2⟩, h3⟩
have hTsub : T ⊆ F1 \ B1 := by
intro x hx
rw [hTmem] at hx
exact (hUmem x).2 ⟨(hCnodes _ hx).1, (hCnodes _ hx).2⟩
have hTcl : CubicPathwidth.ClosedIn (F.toSimpleGraph n) (F1 \ B1) T := by
intro x hx w hw hwx
have hxC := (hTmem x).1 hx
have hFxw := hSsymm x w hwx
have hwk := (hUmem w).1 hw
have hHxw : (F.induced (restKeep ops R)).Adj x.val w.val :=
(hHadj x.val w.val).2 ⟨hFxw, (hCnodes x.val hxC).2, hwk.2⟩
exact (hTmem w).2 (hclos x.val hxC w.val hHxw)
have hTconn : CubicPathwidth.SectionConnected (F.toSimpleGraph n) T := by
refine ⟨?_, ?_⟩
· obtain ⟨y0, hy0⟩ := List.exists_mem_of_ne_nil C hCne
exact ⟨⟨y0, hn y0 (hCnodes y0 hy0).1⟩, (hTmem _).2 hy0⟩
· intro S' hS'T hcl hS'ne
obtain ⟨x0, hx0⟩ := hS'ne
ext x
constructor
· intro hx
exact hS'T hx
· intro hxT
have hx0C : x0.val ∈ C := (hTmem x0).1 (hS'T hx0)
have hxC : x.val ∈ C := (hTmem x).1 hxT
have key : ∀ z, Relation.ReflTransGen (F.induced (restKeep ops R)).Adj x0.val z →
∃ w ∈ S', w.val = z := by
intro z hz
induction hz with
| refl => exact ⟨x0, hx0, rfl⟩
| @tail b c _ hbc ih =>
obtain ⟨w, hwS, hwb⟩ := ih
have hwC : b ∈ C := by
rw [← hwb]
exact (hTmem w).1 (hS'T hwS)
have hcC : c ∈ C := hclos b hwC c hbc
have hcn : c < n := hn c (hCnodes c hcC).1
have hFbc : F.Adj b c := ((hHadj b c).1 hbc).1
have hbne : b ≠ c := by
intro h
subst h
exact hHW.loopless _ hbc
have hc'T : (⟨c, hcn⟩ : Fin n) ∈ T := (hTmem _).2 hcC
have hwc' : w ≠ ⟨c, hcn⟩ := by
intro h
apply hbne
have hv : w.val = c := congrArg Fin.val h
rw [← hwb]
exact hv
have hSwc : (F.toSimpleGraph n).Adj w ⟨c, hcn⟩ :=
(hSadj w ⟨c, hcn⟩).2 ⟨hwc', Or.inl (by rw [hwb]; exact hFbc)⟩
exact ⟨⟨c, hcn⟩, hcl w hwS ⟨c, hcn⟩ hc'T hSwc, rfl⟩
obtain ⟨w, hwS, hwx⟩ := key x.val (hreach x0.val hx0C x.val hxC)
have hwx' : w = x := Fin.ext hwx
rw [← hwx']
exact hwS
have hTcomp : T ∈ CubicPathwidth.components (F.toSimpleGraph n) (F1 \ B1) :=
CubicPathwidth.T4.mem_components_of_conn (F.toSimpleGraph n) hTsub hTcl hTconn
have hatt : (CubicPathwidth.attachment (F.toSimpleGraph n) B1 T).card ≤ 2 :=
CubicPathwidth.T4.Good.attachment_card_le (F.toSimpleGraph n) hgood T hTcomp
-- list facts about `undoAttach`
have hLF : ∀ x ∈ undoAttach F (deletedSet ops) C, x ∈ F.nodes := by
intro x hx
obtain ⟨c, _, hxc, _, _⟩ := (mem_undoAttach F _ C x).1 hx
exact (mem_of_adj hF hxc).2
have hLR : ∀ x ∈ undoAttach F (deletedSet ops) C, x ∈ R.nodes := by
intro x hx
obtain ⟨c, hc, hxc, hxC, hxD⟩ := (mem_undoAttach F _ C x).1 hx
by_contra hxR
have hk : restKeep ops R x = true := (restKeep_iff ops R hR x).2 ⟨hxD, hxR⟩
have hHcx : (F.induced (restKeep ops R)).Adj c x :=
(hHadj c x).2 ⟨hxc, (hCnodes c hc).2, hk⟩
exact hxC (hclos c hc x hHcx)
have hLsub : ∀ x (hx : x ∈ undoAttach F (deletedSet ops) C),
(⟨x, hn x (hLF x hx)⟩ : Fin n) ∈ CubicPathwidth.attachment (F.toSimpleGraph n) B1 T := by
intro x hx
obtain ⟨c, hc, hxc, hxC, _⟩ := (mem_undoAttach F _ C x).1 hx
rw [CubicPathwidth.mem_attachment]
refine ⟨(hB1 _).2 (hLR x hx), ⟨c, hn c (hCnodes c hc).1⟩, (hTmem _).2 hc, ?_⟩
rw [hSadj]
refine ⟨fun h => hxC ?_, Or.inr hxc⟩
have hxc' : x = c := congrArg Fin.val h
rw [hxc']
exact hc
refine ⟨fun x hx => hLR x hx, ?_, ?_, ?_⟩
· have hsub : (undoAttach F (deletedSet ops) C).toFinset ⊆
((CubicPathwidth.attachment (F.toSimpleGraph n) B1 T).image Fin.val) := by
intro x hx
rw [List.mem_toFinset] at hx
rw [Finset.mem_image]
exact ⟨⟨x, hn x (hLF x hx)⟩, hLsub x hx, rfl⟩
rw [← List.toFinset_card_of_nodup (nodup_undoAttach F (deletedSet ops) C)]
exact (Finset.card_le_card hsub).trans ((Finset.card_image_le).trans hatt)
· intro a b hab
have hnd := nodup_undoAttach F (deletedSet ops) C
rw [hab] at hnd
have hne : a ≠ b := by
simp at hnd
exact hnd
have ha : a ∈ undoAttach F (deletedSet ops) C := by rw [hab]; simp
have hb : b ∈ undoAttach F (deletedSet ops) C := by rw [hab]; simp
have hne' : (⟨a, hn a (hLF a ha)⟩ : Fin n) ≠ ⟨b, hn b (hLF b hb)⟩ :=
fun h => hne (congrArg Fin.val h)
have hadjT := (CubicPathwidth.T4.tgraph_adj_iff (F.toSimpleGraph n) F1 B1 _ _).2
⟨hne', (hB1 _).2 (hLR a ha), (hB1 _).2 (hLR b hb),
Or.inr ⟨T, hTcomp, hLsub a ha, hLsub b hb⟩⟩
exact (hadj _ _).1 hadjT
· have hG'W : (F.induced C.contains).WF := (inducedSpec F C.contains hF).1
have hG'n := (inducedSpec F C.contains hF).2.1
have hG'a := (inducedSpec F C.contains hF).2.2
have hsubG : (∀ x ∈ (F.induced C.contains).nodes, x ∈ F.nodes) ∧
∀ u w, (F.induced C.contains).Adj u w → F.Adj u w :=
⟨fun x hx => ((hG'n x).1 hx).1, fun u w h => ((hG'a u w).1 h).1⟩
have hdel : ∀ w, Op.del w ∈ ops → w ∉ (F.induced C.contains).nodes := by
intro w hw hwG
have hwC : w ∈ C := by
have := ((hG'n w).1 hwG).2
simpa using this
have hwD : w ∈ deletedSet ops := List.mem_filterMap.2 ⟨Op.del w, hw, rfl⟩
exact ((restKeep_iff ops R hR w).1 (hCnodes w hwC).2).1 hwD
obtain ⟨ops', R', hred, hrec', h1, _, h3⟩ :=
hMono F (F.induced C.contains) R ops hF hG'W hsubG.1 hsubG.2 hdel hOps
have hempty : ∀ x ∈ R'.nodes, False := by
intro x hx
have hxG := h3 x hx
have hxC : x ∈ C := by
have := ((hG'n x).1 hxG).2
simpa using this
exact ((restKeep_iff ops R hR x).1 (hCnodes x hxC).2).2 (h1 x hx)
have hsame : SameGraph R' Graph.empty := by
constructor
· intro x
constructor
· intro hx
exact absurd hx (hempty x)
· intro hx
simp [Graph.empty] at hx
· intro u v
constructor
· intro h
exact absurd (opsRecord_adj_mem ops' _ R' hG'W hrec' u v h) (hempty u)
· intro h
simp [Graph.Adj, Graph.nbrs, Graph.empty] at h
exact ⟨ops', hred, opsRecord_end_congr ops' _ R' Graph.empty hrec' hsame⟩
end R8
/-- `AttachInvariant` (`(I2)` of Lemma 4.5 (`lem:reduction`)), from the torso simulation, the record
monotonicity and the connectedness of components. -/
theorem attachInvariant_of (hSim : TorsoSim) (hMono : RecordMono) (hConn : ComponentsConnected)
(hCongr : OpsRecordCongr) (hApp : OpsRecordAppend) : AttachInvariant := by
intro F R ops hF hR hOps C hC
have hn : ∀ v ∈ F.nodes, v < F.nodes.sum + 1 :=
fun v hv => Nat.lt_succ_of_le (R8.le_sum_mem _ v hv)
obtain ⟨hG0, hreach, hadj⟩ := hSim (F.nodes.sum + 1) F R ops hF hn hOps
have hgood := CubicPathwidth.T4.Good.reach hG0 hreach
exact R8.attach_core (F.nodes.sum + 1) F R ops _ _ hF hR hn hOps hgood
(fun x => by simp) (fun x => by simp) hadj hConn hMono C hC
end CubicPathwidth.Alg
#print axioms CubicPathwidth.Alg.attachInvariant_of
#print axioms CubicPathwidth.Alg.R8.attach_core
#print axioms CubicPathwidth.Alg.R8.replay
Back to top