CubicPathwidth.Alg.Proofs2.TorsoLocal
Source file CubicPathwidth/Alg/Proofs2/TorsoLocal.lean of the Lean project (how it is built).
import CubicPathwidth.Alg.Plan2Deletion
import CubicPathwidth.T4.TorsoDyn
/-!
# Task D6: locality of torsos (`torsoLocal : TorsoLocal`)
Route (from `CubicPathwidth/Alg/Plan2Deletion.lean`): `components G U` and
`attachment G B T` only read `G` on `U` and on `B ∪ T`. Here `B ⊆ F ⊆ F₀`, so the
torso `T4.tgraph S F B` only reads `S` on `F₀`. Reachability is preserved step by step:
the invariant `B ⊆ F ⊆ F₀` is kept by all steps, and each step's torso condition
(`tdeg ≤ 2`) transfers by the torso equality.
-/
noncomputable section
namespace CubicPathwidth.Alg.D6
variable {n : ℕ}
/-- `ClosedIn` on a subset of `U` only reads the graph on `U`. -/
theorem closedIn_congr {S S' : SimpleGraph (Fin n)} {U T : Finset (Fin n)} (hT : T ⊆ U)
(h : ∀ u ∈ U, ∀ v ∈ U, S.Adj u v ↔ S'.Adj u v) :
CubicPathwidth.ClosedIn S U T ↔ CubicPathwidth.ClosedIn S' U T := by
unfold CubicPathwidth.ClosedIn
constructor
· intro hc v hv w hw hadj
exact hc v hv w hw ((h v (hT hv) w hw).mpr hadj)
· intro hc v hv w hw hadj
exact hc v hv w hw ((h v (hT hv) w hw).mp hadj)
/-- `component U v` only reads the graph on `U`. -/
theorem component_congr {S S' : SimpleGraph (Fin n)} {U : Finset (Fin n)}
(h : ∀ u ∈ U, ∀ v ∈ U, S.Adj u v ↔ S'.Adj u v) (v : Fin n) :
CubicPathwidth.component S U v = CubicPathwidth.component S' U v := by
ext w
unfold CubicPathwidth.component
simp only [Finset.mem_filter]
constructor
· rintro ⟨hw, hv, hmin⟩
exact ⟨hw, hv, fun T hT hc hvT => hmin T hT ((closedIn_congr hT h).mpr hc) hvT⟩
· rintro ⟨hw, hv, hmin⟩
exact ⟨hw, hv, fun T hT hc hvT => hmin T hT ((closedIn_congr hT h).mp hc) hvT⟩
/-- `components U` only reads the graph on `U`. -/
theorem components_congr {S S' : SimpleGraph (Fin n)} {U : Finset (Fin n)}
(h : ∀ u ∈ U, ∀ v ∈ U, S.Adj u v ↔ S'.Adj u v) :
CubicPathwidth.components S U = CubicPathwidth.components S' U := by
ext T
unfold CubicPathwidth.components
simp only [Finset.mem_image, component_congr h]
/-- `attachment B T` only reads the graph between `B` and `T`. -/
theorem attachment_congr {S S' : SimpleGraph (Fin n)} {B T : Finset (Fin n)}
(h : ∀ u ∈ B, ∀ v ∈ T, S.Adj u v ↔ S'.Adj u v) :
CubicPathwidth.attachment S B T = CubicPathwidth.attachment S' B T := by
ext x
rw [CubicPathwidth.mem_attachment S, CubicPathwidth.mem_attachment S']
constructor
· rintro ⟨hx, u, hu, hxu⟩
exact ⟨hx, u, hu, (h x hx u hu).mp hxu⟩
· rintro ⟨hx, u, hu, hxu⟩
exact ⟨hx, u, hu, (h x hx u hu).mpr hxu⟩
/-- The torso of `(F, B)` only depends on the graph on `F₀`, when `B ⊆ F ⊆ F₀`. -/
theorem tgraph_congr_of {S S' : SimpleGraph (Fin n)} {F₀ : Finset (Fin n)}
(h : ∀ u ∈ F₀, ∀ v ∈ F₀, S.Adj u v ↔ S'.Adj u v) {F B : Finset (Fin n)}
(hB : B ⊆ F) (hF : F ⊆ F₀) : CubicPathwidth.T4.tgraph S F B = CubicPathwidth.T4.tgraph S' F B := by
have hU : F \ B ⊆ F₀ := Finset.sdiff_subset.trans hF
have hBF₀ : B ⊆ F₀ := hB.trans hF
have hcomp : CubicPathwidth.components S (F \ B) = CubicPathwidth.components S' (F \ B) :=
components_congr (fun a ha b hb => h a (hU ha) b (hU hb))
have hatt : ∀ T ∈ CubicPathwidth.components S (F \ B),
CubicPathwidth.attachment S B T = CubicPathwidth.attachment S' B T :=
fun T hT => attachment_congr
(fun a ha b hb => h a (hBF₀ ha) b (hU ((CubicPathwidth.mem_components S hT).1 hb)))
ext x y
rw [CubicPathwidth.T4.tgraph_adj_iff S F B x y, CubicPathwidth.T4.tgraph_adj_iff S' F B x y]
constructor
· rintro ⟨hne, hx, hy, hxy | ⟨T, hT, hxT, hyT⟩⟩
· exact ⟨hne, hx, hy, Or.inl ((h x (hBF₀ hx) y (hBF₀ hy)).mp hxy)⟩
· have hT' : T ∈ CubicPathwidth.components S' (F \ B) := by rw [← hcomp]; exact hT
rw [hatt T hT] at hxT hyT
exact ⟨hne, hx, hy, Or.inr ⟨T, hT', hxT, hyT⟩⟩
· rintro ⟨hne, hx, hy, hxy | ⟨T, hT, hxT, hyT⟩⟩
· exact ⟨hne, hx, hy, Or.inl ((h x (hBF₀ hx) y (hBF₀ hy)).mpr hxy)⟩
· have hT' : T ∈ CubicPathwidth.components S (F \ B) := by rw [hcomp]; exact hT
rw [← hatt T hT'] at hxT hyT
exact ⟨hne, hx, hy, Or.inr ⟨T, hT', hxT, hyT⟩⟩
/-- Torso degrees agree when the torsos agree. -/
theorem tdeg_congr_of {S S' : SimpleGraph (Fin n)} {F B : Finset (Fin n)}
(hg : CubicPathwidth.T4.tgraph S F B = CubicPathwidth.T4.tgraph S' F B) (v : Fin n) :
CubicPathwidth.T4.tdeg S F B v = CubicPathwidth.T4.tdeg S' F B v := by
rw [CubicPathwidth.T4.tdeg_eq_card S F B v, CubicPathwidth.T4.tdeg_eq_card S' F B v, hg]
/-- The core stays inside the undeleted set along a reachability. -/
theorem inv_reach {G : SimpleGraph (Fin n)} {s t : Finset (Fin n) × Finset (Fin n)}
(h : CubicPathwidth.T4.Reach G s t) (hs : s.2 ⊆ s.1) : t.2 ⊆ t.1 := by
induction h with
| refl => exact hs
| tail _ hst ih =>
cases hst with
| reduce _ _ => exact (Finset.erase_subset _ _).trans ih
| delete _ => exact Finset.erase_subset_erase _ ih
/-- Reachability in `S'` from a state inside `F₀` is reachability in `S`. -/
theorem reach_transfer {S S' : SimpleGraph (Fin n)} {F₀ : Finset (Fin n)}
(h : ∀ u ∈ F₀, ∀ v ∈ F₀, S.Adj u v ↔ S'.Adj u v) {s t : Finset (Fin n) × Finset (Fin n)}
(hr : CubicPathwidth.T4.Reach S' s t) (hs : s.2 ⊆ s.1) (hF : s.1 ⊆ F₀) :
CubicPathwidth.T4.Reach S s t := by
induction hr with
| refl => exact CubicPathwidth.T4.Reach.refl S _
| @tail b c hb hst ih =>
have hbF : b.1 ⊆ F₀ := (CubicPathwidth.T4.Reach.subset hb).1.trans hF
have hbinv : b.2 ⊆ b.1 := inv_reach hb hs
cases hst with
| @reduce F B v hv hdeg =>
have hBF : B ⊆ F := hbinv
have hFF₀ : F ⊆ F₀ := hbF
have hg := tgraph_congr_of h hBF hFF₀
have hdeg' : CubicPathwidth.T4.tdeg S F B v ≤ 2 := by
rw [tdeg_congr_of hg v]; exact hdeg
exact ih.tail (CubicPathwidth.T4.Step.reduce hv hdeg')
| @delete F B w hw =>
exact ih.tail (CubicPathwidth.T4.Step.delete hw)
end CubicPathwidth.Alg.D6
namespace CubicPathwidth.Alg
/-- (D6) Locality of torsos: the torso of a state `B ⊆ F ⊆ F₀` and reachability from it
only depend on the graph on `F₀`. -/
theorem torsoLocal : TorsoLocal := by
unfold TorsoLocal
intro n S S' F₀ h
exact ⟨fun F B hB hF => D6.tgraph_congr_of h hB hF,
fun F B F' B' hB hF hr => D6.reach_transfer h hr hB hF⟩
end CubicPathwidth.Alg
#print axioms CubicPathwidth.Alg.torsoLocal
Back to top