CubicPathwidth.Alg.Proofs2.U2PdTw2NoFallback
Source file CubicPathwidth/Alg/Proofs2/U2PdTw2NoFallback.lean of the Lean project (how it is built).
import CubicPathwidth.Alg.Plan2
import CubicPathwidth.Alg.Proofs.Targets
/-!
# U2: `pd_tw2` never falls back (Stage 2, task U2)
Route. Generalize to `pdTw2Fuel fuel H` with `numNodes ≤ fuel` and `Emptiable H`, and
induct on `fuel`. For `H` with more than 3 nodes: `reduceRecordF H.copy` empties the
copy (`ReduceConfluent` on `H.copy`, which is `Emptiable` by `OpsRecordCongr`), its
flag is `false` (`ReduceRecordNoFallback`), and `BalancedElimBag` gives a bag at which
`find?` succeeds. For a component `c` of the balanced bag, `H.induced c.contains` has at
most `c.length ≤ fuel` nodes and is `Emptiable` (`RecordMono` with the empty graph as
the final graph), so the induction hypothesis applies to it.
The top-level theorem converts `(reduceRecord H.copy).1.numNodes = 0` into `Emptiable H`
using `ReduceRecordMaximal`, `ReduceRecordSpec` (well-formedness of the output) and
`OpsRecordCongr`; the recorded operations are reductions only (`reduceLoop` emits only
`Op.red`).
-/
namespace CubicPathwidth.Alg
open Graph
namespace U2
/-! ## Elementary facts about `SameGraph` and records -/
theorem sameGraph_refl (G : Graph) : SameGraph G G :=
⟨fun _ => Iff.rfl, fun _ _ => Iff.rfl⟩
theorem sameGraph_symm {G H : Graph} (h : SameGraph G H) : SameGraph H G :=
⟨fun v => (h.1 v).symm, fun u v => (h.2 u v).symm⟩
theorem sameGraph_trans {G H K : Graph} (h₁ : SameGraph G H) (h₂ : SameGraph H K) :
SameGraph G K :=
⟨fun v => (h₁.1 v).trans (h₂.1 v), fun u v => (h₁.2 u v).trans (h₂.2 u v)⟩
/-- A record can be re-targeted along `SameGraph` at its end. -/
theorem opsRecord_sameEnd (ops : List Op) :
∀ (F R R' : Graph), OpsRecord F ops R → SameGraph R R' → OpsRecord F ops R' := by
induction ops with
| nil =>
intro F R R' h h'
exact sameGraph_trans h h'
| cons o ops ih =>
intro F R R' h h'
cases o with
| red v nb =>
obtain ⟨h1, h2, h3, h4, h5⟩ := h
exact ⟨h1, h2, h3, h4, ih _ _ _ h5 h'⟩
| del w =>
obtain ⟨h1, h2⟩ := h
exact ⟨h1, ih _ _ _ h2 h'⟩
theorem empty_not_adj (u v : Nat) : ¬ (Graph.empty).Adj u v := by
simp [Graph.Adj, Graph.nbrs, Graph.empty]
/-! ## Operations of `reduce_record` are reductions -/
/-- `reduceLoop` only ever records reductions. -/
theorem reduceLoop_redOnly (fuel : Nat) :
∀ (G : Graph) (stack : List Nat) (opsRev : List Op),
(∀ o ∈ opsRev, ∃ v nb, o = Op.red v nb) →
∀ o ∈ (reduceLoop fuel G stack opsRev).2.1, ∃ v nb, o = Op.red v nb := by
induction fuel with
| zero =>
intro G stack opsRev h o ho
cases stack with
| nil =>
simp only [reduceLoop, List.mem_reverse] at ho
exact h o ho
| cons _ _ =>
simp only [reduceLoop, List.mem_reverse] at ho
exact h o ho
| succ f ih =>
intro G stack opsRev h o ho
cases stack with
| nil =>
simp only [reduceLoop, List.mem_reverse] at ho
exact h o ho
| cons v rest =>
simp only [reduceLoop] at ho
split at ho
· exact ih _ _ _ h o ho
· refine ih _ _ _ ?_ o ho
intro o' ho'
rcases List.mem_cons.mp ho' with rfl | ho'
· exact ⟨_, _, rfl⟩
· exact h o' ho'
theorem reduceRecordF_redOnly (G : Graph) : RedOnly (reduceRecordF G).2.1 := by
intro o ho
exact reduceLoop_redOnly _ _ _ _ (fun o h => by simp at h) o ho
/-! ## Copies -/
theorem copy_wf {H : Graph} (hH : H.WF) : H.copy.WF :=
(inducedSpec H (fun _ => true) hH).1
theorem copy_sameGraph {H : Graph} (hH : H.WF) : SameGraph H H.copy := by
have hI := inducedSpec H (fun _ => true) hH
refine ⟨fun x => ?_, fun u v => ?_⟩
· have := hI.2.1 x
simp only [Graph.copy]
simp only [this, and_true]
· have := hI.2.2 u v
simp only [Graph.copy]
simp only [this, and_true]
/-! ## Induced subgraphs of an emptiable graph are emptiable -/
theorem emptiable_induced (hMono : RecordMono) {H : Graph} (hH : H.WF) (hE : Emptiable H)
(keep : Nat → Bool) : Emptiable (H.induced keep) := by
obtain ⟨ops, hred, hops⟩ := hE
have hI := inducedSpec H keep hH
obtain ⟨ops', R', hr', hops', hN', hA', _⟩ :=
hMono H (H.induced keep) Graph.empty ops hH hI.1
(fun v hv => ((hI.2.1 v).1 hv).1)
(fun u v h => ((hI.2.2 u v).1 h).1)
(fun w hw => by obtain ⟨v, nb, h⟩ := hred _ hw; cases h) hops
refine ⟨ops', hr', ?_⟩
refine opsRecord_sameEnd ops' _ R' Graph.empty hops' ⟨fun v => ?_, fun u v => ?_⟩
· constructor
· intro hv
have := hN' v hv
simp [Graph.empty] at this
· intro hv
simp [Graph.empty] at hv
· constructor
· intro h
exact absurd (hA' u v h) (empty_not_adj u v)
· intro h
exact absurd h (empty_not_adj u v)
/-- The reductions of an emptiable graph empty its copy (`ReduceConfluent`). -/
theorem reduce_copy_empty (hCongr : OpsRecordCongr) (hConf : ReduceConfluent)
{H : Graph} (hH : H.WF) (hE : Emptiable H) :
(reduceRecordF H.copy).1.numNodes = 0 := by
obtain ⟨ops, hr, hops⟩ := hE
have hcE : Emptiable H.copy :=
⟨ops, hr, hCongr H H.copy Graph.empty ops hH (copy_wf hH) (copy_sameGraph hH) hops⟩
exact hConf H.copy (copy_wf hH) hcE
/-- A component's induced graph has at most `c.length` nodes. -/
theorem comp_numNodes_le {H : Graph} (hH : H.WF) (c : List Nat) :
(H.induced c.contains).numNodes ≤ c.length := by
have hI := inducedSpec H c.contains hH
have hsub : (H.induced c.contains).nodes ⊆ c := fun x hx => by
have := (hI.2.1 x).1 hx
simpa using this.2
exact hI.1.nodup.length_le_of_subset hsub
/-! ## Main induction -/
/-- Generalized statement: no fallback for every fuel at least the number of nodes. -/
theorem pdTw2Fuel_noFallback (hR1 : ReduceRecordNoFallback) (hCongr : OpsRecordCongr)
(hMono : RecordMono) (hConf : ReduceConfluent) (hBal : BalancedElimBag) :
∀ (fuel : Nat) (H : Graph), H.WF → H.numNodes ≤ fuel → Emptiable H →
(pdTw2Fuel fuel H).2 = false := by
intro fuel
induction fuel with
| zero =>
intro H _ hN _
have h0 : H.numNodes = 0 := by omega
simp [pdTw2Fuel, h0]
| succ f ih =>
intro H hH hN hE
by_cases h0 : H.numNodes = 0
· simp [pdTw2Fuel, h0]
by_cases h3 : H.numNodes ≤ 3
· simp [pdTw2Fuel, h0, h3]
have hRed0 : (reduceRecordF H.copy).1.numNodes = 0 :=
reduce_copy_empty hCongr hConf hH hE
have hflag : (reduceRecordF H.copy).2.2 = false := hR1 H.copy (copy_wf hH)
obtain ⟨X, hXmem, hXbal⟩ := hBal H hH (by omega) hRed0
simp only [pdTw2Fuel, h0, h3, ite_false, Bool.false_eq_true, hRed0, bne_self_eq_false]
split
· rename_i hnone
exfalso
refine (List.find?_eq_none.mp hnone) X hXmem ?_
simp only [List.all_eq_true, decide_eq_true_eq]
exact fun c hc => hXbal c hc
· rename_i X' hfind
have hX' := List.find?_some hfind
simp only [List.all_eq_true, decide_eq_true_eq] at hX'
simp only [hflag, Bool.false_or]
rw [List.any_eq_false]
intro p hp
obtain ⟨c, hc, rfl⟩ := List.mem_map.mp hp
have hcb : 2 * c.length ≤ H.numNodes := hX' c hc
have hlen : c.length ≤ f := by omega
have hNle : (H.induced c.contains).numNodes ≤ f :=
Nat.le_trans (comp_numNodes_le hH c) hlen
have hEmp : Emptiable (H.induced c.contains) := emptiable_induced hMono hH hE c.contains
have hWF : (H.induced c.contains).WF := (inducedSpec H c.contains hH).1
show ¬ (pdTw2Fuel f (H.induced c.contains)).2 = true
rw [ih _ hWF hNle hEmp]
simp
/-- An emptying run of `reduce_record` on the copy yields `Emptiable H`. -/
theorem emptiable_of_reduce (hMax : ReduceRecordMaximal) (hCongr : OpsRecordCongr)
{H : Graph} (hH : H.WF) (h0 : (reduceRecord H.copy).1.numNodes = 0) : Emptiable H := by
have hc := copy_wf hH
have hM := hMax H.copy hc
have hRS := reduceRecordSpec H.copy hc
dsimp only at hM hRS
obtain ⟨hops, -, -⟩ := hM
have hWF' : (reduceRecord H.copy).1.WF := hRS.1
have hnil : (reduceRecord H.copy).1.nodes = [] := List.length_eq_zero_iff.mp h0
have hsame : SameGraph (reduceRecord H.copy).1 Graph.empty := by
refine ⟨fun v => ?_, fun u v => ?_⟩
· rw [hnil]
simp [Graph.empty]
· constructor
· intro h
have hmem := hWF'.nbrs_sub u v h
rw [hnil] at hmem
simp at hmem
· intro h
exact absurd h (empty_not_adj u v)
have hE' : OpsRecord H.copy (reduceRecord H.copy).2 Graph.empty :=
opsRecord_sameEnd _ _ _ _ hops hsame
exact ⟨((reduceRecord H.copy).2), reduceRecordF_redOnly H.copy, hCongr H.copy H Graph.empty _ hc hH (sameGraph_symm (copy_sameGraph hH)) hE'⟩
end U2
/-- `pd_tw2` never falls back on a graph that reduces to the empty graph (Stage 2 task U2;
`Spec.lean` §7 `PdTw2NoFallback`). -/
theorem pdTw2NoFallback_of (hR1 : ReduceRecordNoFallback) (hMax : ReduceRecordMaximal)
(hCongr : OpsRecordCongr) (hMono : RecordMono) (hConf : ReduceConfluent)
(hBal : BalancedElimBag) : PdTw2NoFallback := by
intro H hH h0
have hE := U2.emptiable_of_reduce hMax hCongr hH h0
exact U2.pdTw2Fuel_noFallback hR1 hCongr hMono hConf hBal H.numNodes H hH le_rfl hE
#print axioms CubicPathwidth.Alg.pdTw2NoFallback_of
end CubicPathwidth.Alg
Back to top