CubicPathwidth.Alg.Proofs2.R5RecordMono
Source file CubicPathwidth/Alg/Proofs2/R5RecordMono.lean of the Lean project (how it is built).
import CubicPathwidth.Alg.Plan2
import CubicPathwidth.Alg.Proofs.Targets
/-!
# R5: a legal record restricted to a subgraph is a legal record of the subgraph
Proves `RecordMono` (`Plan2.lean` §6.2). Induction on the operations. A reduction at `v`
is replayed on the subgraph `G'` when `v` is a node of `G'` (its `G'`-neighbours are
among its `G`-neighbours, so there are at most two of them); otherwise it is skipped.
The graph helpers `redStep_facts` and its lemmas are copied from `Proofs2/R4TorsoSim.lean`.
-/
noncomputable section
namespace CubicPathwidth.Alg.R5
/-! ## Graph facts about `redStep` -/
theorem mem_of_len_le_one {L : List Nat} (h : L.length ≤ 1) {x y : Nat}
(hx : x ∈ L) (hy : y ∈ L) : x = y := by
rcases L with _ | ⟨a, _ | ⟨b, t⟩⟩
· simp at hx
· simp at hx hy
omega
· simp at h
theorem redStep_cases (G : Graph) (v : Nat) :
(∃ a b, G.nbrs v = [a, b] ∧ redStep G v = (G.removeNode v).addEdge a b) ∨
((G.nbrs v).length ≤ 1 ∧ redStep G v = G.removeNode v) ∨
(3 ≤ (G.nbrs v).length ∧ redStep G v = G.removeNode v) := by
unfold redStep
rcases h : G.nbrs v with _ | ⟨a, _ | ⟨b, _ | ⟨c, t⟩⟩⟩
· right; left; simp
· right; left; simp
· left; exact ⟨a, b, rfl, rfl⟩
· right; right; simp
theorem nbrs_len_eq (G : Graph) (hG : G.WF) (v : Nat) (nb : List Nat) (hnb : nb.Nodup)
(hmem : ∀ x, x ∈ nb ↔ G.Adj v x) : (G.nbrs v).length = nb.length := by
have hperm : (G.nbrs v).Perm nb :=
(List.perm_ext_iff_of_nodup (hG.nbrs_nodup v) hnb).2 (fun x => (hmem x).symm)
exact hperm.length_eq
/-- The graph after one reduction at `v` (with neighbour list `nb`, as in `OpsRecord`):
nodes are the old nodes except `v`, and the adjacency is the torso adjacency of
`(F, B.erase v)` (joining the two neighbours of `v`). -/
theorem redStep_facts (G : Graph) (hG : G.WF) (v : Nat) (nb : List Nat)
(hnb : nb.Nodup) (hlen : nb.length ≤ 2)
(hmem : ∀ x, x ∈ nb ↔ G.Adj v x) :
(redStep G v).WF ∧
(∀ x, x ∈ (redStep G v).nodes ↔ x ∈ G.nodes ∧ x ≠ v) ∧
(∀ x y, (redStep G v).Adj x y ↔
x ≠ v ∧ y ≠ v ∧ (G.Adj x y ∨ (x ≠ y ∧ G.Adj x v ∧ G.Adj y v))) := by
have hL : (G.nbrs v).length ≤ 2 := by
rw [nbrs_len_eq G hG v nb hnb hmem]; exact hlen
have hRem := removeNodeSpec G v hG
have hsymm : ∀ x, G.Adj x v ↔ G.Adj v x :=
fun x => ⟨fun h => hG.symm x v h, fun h => hG.symm v x h⟩
rcases redStep_cases G v with ⟨a, b, hab, hred⟩ | ⟨hlen1, hred⟩ | ⟨hlen3, _⟩
· -- two neighbours `a ≠ b`
have hnodup := hG.nbrs_nodup v
rw [hab] at hnodup
have hab' : a ≠ b := by simpa using hnodup
have haN : a ∈ G.nbrs v := by rw [hab]; simp
have hbN : b ∈ G.nbrs v := by rw [hab]; simp
have hav : a ≠ v := fun h => hG.loopless v (h ▸ haN)
have hbv : b ≠ v := fun h => hG.loopless v (h ▸ hbN)
have haV : a ∈ G.nodes := hG.nbrs_sub v a haN
have hbV : b ∈ G.nodes := hG.nbrs_sub v b hbN
have hxa : ∀ x, G.Adj x v ↔ (x = a ∨ x = b) := by
intro x
rw [hsymm x]
show x ∈ G.nbrs v ↔ _
rw [hab]; simp
have hA := addEdgeSpec (G.removeNode v) a b hRem.1 hab'
rw [hred]
refine ⟨hA.1, fun x => ?_, fun x y => ?_⟩
· rw [hA.2.1 x, hRem.2.1 x]
constructor
· rintro (h | rfl | rfl)
· exact h
· exact ⟨haV, hav⟩
· exact ⟨hbV, hbv⟩
· intro h
exact Or.inl h
· rw [hA.2.2 x y, hRem.2.2 x y, hxa x, hxa y]
constructor
· rintro ((⟨h, h1, h2⟩) | ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩)
· exact ⟨h1, h2, Or.inl h⟩
· exact ⟨hav, hbv, Or.inr ⟨hab', Or.inl rfl, Or.inr rfl⟩⟩
· exact ⟨hbv, hav, Or.inr ⟨fun e => hab' e.symm, Or.inr rfl, Or.inl rfl⟩⟩
· rintro ⟨h1, h2, h | ⟨hne, hx, hy⟩⟩
· exact Or.inl ⟨h, h1, h2⟩
· rcases hx with rfl | rfl <;> rcases hy with rfl | rfl
· exact absurd rfl hne
· exact Or.inr (Or.inl ⟨rfl, rfl⟩)
· exact Or.inr (Or.inr ⟨rfl, rfl⟩)
· exact absurd rfl hne
· -- at most one neighbour
rw [hred]
refine ⟨hRem.1, fun x => hRem.2.1 x, fun x y => ?_⟩
rw [hRem.2.2 x y]
constructor
· rintro ⟨h, h1, h2⟩
exact ⟨h1, h2, Or.inl h⟩
· rintro ⟨h1, h2, h | ⟨hne, hx, hy⟩⟩
· exact ⟨h, h1, h2⟩
· exact absurd (mem_of_len_le_one hlen1 ((hsymm x).mp hx) ((hsymm y).mp hy)) hne
· omega
end CubicPathwidth.Alg.R5
namespace CubicPathwidth.Alg
open Graph
theorem recordMono_aux (ops : List Op) :
∀ (G G' R : Graph), G.WF → G'.WF →
(∀ v ∈ G'.nodes, v ∈ G.nodes) → (∀ u v, G'.Adj u v → G.Adj u v) →
(∀ 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' hn ha _ hops
simp only [OpsRecord] at hops
obtain ⟨hV, hA⟩ := hops
refine ⟨[], G', ?_, ?_, ?_, ?_, ?_⟩
· intro o ho
simp at ho
· simp only [OpsRecord]
exact ⟨fun _ => Iff.rfl, fun _ _ => Iff.rfl⟩
· intro v hv
exact (hV v).1 (hn v hv)
· intro u v h
exact (hA u v).1 (ha u v h)
· intro v hv
exact hv
| cons o ops ih =>
intro G G' R hG hG' hn ha hdel hops
cases o with
| del w =>
simp only [OpsRecord] at hops
obtain ⟨hwN, hrest⟩ := hops
have hwG' : w ∉ G'.nodes := hdel w (by simp)
have hRem := removeNodeSpec G w hG
obtain ⟨ops', R', h1, h2, h3, h4, h5⟩ :=
ih (G.removeNode w) G' R hRem.1 hG'
(fun x hx => (hRem.2.1 x).2 ⟨hn x hx, fun e => hwG' (by rw [← e]; exact hx)⟩)
(fun u v h => by
obtain ⟨hu, hv, _, _⟩ := wfBasics G' hG' u v h
exact (hRem.2.2 u v).2 ⟨ha u v h,
fun e => hwG' (by rw [← e]; exact hu),
fun e => hwG' (by rw [← e]; exact hv)⟩)
(fun w' hw => hdel w' (List.mem_cons_of_mem _ hw))
hrest
exact ⟨ops', R', h1, h2, h3, h4, h5⟩
| red v nb =>
simp only [OpsRecord] at hops
obtain ⟨hvN, hnb, hlen, hmem, hrest⟩ := hops
obtain ⟨hW1, hN1, hA1⟩ := R5.redStep_facts G hG v nb hnb hlen hmem
by_cases hvG' : v ∈ G'.nodes
· -- replay the reduction on `G'` with its own neighbour list
have hnb' : (G'.nbrs v).Nodup := hG'.nbrs_nodup v
have hsub : G'.nbrs v ⊆ nb := fun x hx => (hmem x).2 (ha v x hx)
have hlen' : (G'.nbrs v).length ≤ 2 :=
le_trans (hnb'.length_le_of_subset hsub) hlen
have hmem' : ∀ x, x ∈ G'.nbrs v ↔ G'.Adj v x := fun x => Iff.rfl
obtain ⟨hW1', hN1', hA1'⟩ := R5.redStep_facts G' hG' v (G'.nbrs v) hnb' hlen' hmem'
obtain ⟨ops', R', h1, h2, h3, h4, h5⟩ :=
ih (redStep G v) (redStep G' v) R hW1 hW1'
(fun x hx =>
(hN1 x).2 ⟨hn x ((hN1' x).1 hx).1, ((hN1' x).1 hx).2⟩)
(fun a b hab => by
obtain ⟨h1, h2, h3⟩ := (hA1' a b).1 hab
refine (hA1 a b).2 ⟨h1, h2, ?_⟩
rcases h3 with h | ⟨hne, h4, h5⟩
· exact Or.inl (ha a b h)
· exact Or.inr ⟨hne, ha a v h4, ha b v h5⟩)
(fun w' hw hw'mem => hdel w' (List.mem_cons_of_mem _ hw) ((hN1' w').1 hw'mem).1)
hrest
refine ⟨Op.red v (G'.nbrs v) :: ops', R', ?_, ?_, h3, h4,
fun x hx => ((hN1' x).1 (h5 x hx)).1⟩
· intro o ho
rcases List.mem_cons.1 ho with rfl | ho
· exact ⟨v, _, rfl⟩
· exact h1 o ho
· exact ⟨hvG', hnb', hlen', hmem', h2⟩
· -- `G'` avoids `v`: skip the reduction
obtain ⟨ops', R', h1, h2, h3, h4, h5⟩ :=
ih (redStep G v) G' R hW1 hG'
(fun x hx =>
(hN1 x).2 ⟨hn x hx, fun e => hvG' (by rw [← e]; exact hx)⟩)
(fun a b hab => by
obtain ⟨ha', hb', _, _⟩ := wfBasics G' hG' a b hab
refine (hA1 a b).2 ⟨fun e => hvG' (by rw [← e]; exact ha'),
fun e => hvG' (by rw [← e]; exact hb'), Or.inl (ha a b hab)⟩)
(fun w' hw => hdel w' (List.mem_cons_of_mem _ hw))
hrest
exact ⟨ops', R', h1, h2, h3, h4, h5⟩
/-- `RecordMono` (`Plan2.lean` §6.2): replaying a legal record on a subgraph. -/
theorem recordMono : RecordMono := by
intro G G' R ops hG hG' hn ha hdel hops
exact recordMono_aux ops G G' R hG hG' hn ha hdel hops
end CubicPathwidth.Alg
#print axioms CubicPathwidth.Alg.recordMono
Back to top