CubicPathwidth.Alg.Proofs2.R6Confluent

Source file CubicPathwidth/Alg/Proofs2/R6Confluent.lean of the Lean project (how it is built).

import CubicPathwidth.Alg.Plan2
import CubicPathwidth.Alg.Proofs.Targets
import CubicPathwidth.T4.TorsoDyn

/-!
# R6: confluence of `reduce_record` (`ReduceConfluent`)

Route (torso world, fixed core vertex set). Let `F = V₀` be the vertices of `G`
(as `Fin n`). Reduction-only states `(F, B)` form the relation `RR F B B'`: a single
step removes some `v ∈ B` of torso degree at most two in `(F, B)`.

* `RR_erase`: if `RR B B'` and `v ∈ B` has torso degree at most two in `(F, B)`, then
  `RR (B.erase v) (B'.erase v)` (degrees never increase along reductions).
* `RR_of_empty`: if `RR B ∅` and `RR B B'`, then `RR B' ∅` (greedy runs cannot be
  stuck, by `RR_erase`).
* `RR_nonempty_contra`: `RR X ∅` with `X ≠ ∅` needs a vertex of torso degree `≤ 2`.

The two records of `G` (an emptying one from `Emptiable`, and the output of
`reduce_record`) are simulated by `TorsoSim`; `ReduceRecordSpec` (Stage 1) gives that
`reduce_record` is red-only, well formed, and has nodes among those of `G`.
`ReduceRecordMaximal` gives minimum degree at least `3` on the output.
-/

noncomputable section

namespace CubicPathwidth.Alg.R6

open Graph

variable {n : ℕ} (S : SimpleGraph (Fin n))

/-- One reduction in the fixed core `F`: remove `v ∈ B` of torso degree at most two. -/
def RRstep (F B B' : Finset (Fin n)) : Prop :=
  ∃ v ∈ B, CubicPathwidth.T4.tdeg S F B v ≤ 2 ∧ B' = B.erase v

/-- Reduction-only reachability in the fixed core `F`. -/
abbrev RR (F : Finset (Fin n)) : Finset (Fin n) → Finset (Fin n) → Prop :=
  Relation.ReflTransGen (RRstep S F)

variable {S}

theorem RR_sub {F B B' : Finset (Fin n)} (h : RR S F B B') : B' ⊆ B := by
  induction h with
  | refl => exact Finset.Subset.rfl
  | @tail b c _ hs ih =>
    obtain ⟨v, _, _, rfl⟩ := hs
    exact (Finset.erase_subset _ _).trans ih

theorem RR_tdeg_le {F B B' : Finset (Fin n)} (hBF : B ⊆ F) (h : RR S F B B') :
    ∀ v ∈ B', CubicPathwidth.T4.tdeg S F B' v ≤ CubicPathwidth.T4.tdeg S F B v := by
  induction h with
  | refl => intro v _; exact le_rfl
  | @tail b c hab hs ih =>
    obtain ⟨u, hu, hdeg, rfl⟩ := hs
    intro v hv
    have hbF : b ⊆ F := (RR_sub hab).trans hBF
    have hvb : v ∈ b := Finset.mem_of_mem_erase hv
    exact (CubicPathwidth.T4.tdeg_erase_le S hbF hu hdeg hv).trans (ih v hvb)

theorem RR_erase {F B B' : Finset (Fin n)} (hBF : B ⊆ F) (h : RR S F B B') :
    ∀ v ∈ B, CubicPathwidth.T4.tdeg S F B v ≤ 2 → RR S F (B.erase v) (B'.erase v) := by
  induction h with
  | refl => intro v _ _; exact Relation.ReflTransGen.refl
  | @tail b c hab hs ih =>
    intro v hvB hvdeg
    obtain ⟨u, hu, hdeg, rfl⟩ := hs
    have hbF : b ⊆ F := (RR_sub hab).trans hBF
    have ih' := ih v hvB hvdeg
    by_cases hvb : v ∈ b
    · have hvdeg' : CubicPathwidth.T4.tdeg S F b v ≤ 2 :=
        (RR_tdeg_le hBF hab v hvb).trans hvdeg
      by_cases huv : u = v
      · subst huv
        rw [Finset.erase_idem]
        exact ih'
      · have hu' : u ∈ b.erase v := Finset.mem_erase.mpr ⟨huv, hu⟩
        have hdeg' : CubicPathwidth.T4.tdeg S F (b.erase v) u ≤ 2 :=
          (CubicPathwidth.T4.tdeg_erase_le S hbF hvb hvdeg' hu').trans hdeg
        rw [Finset.erase_right_comm]
        exact ih'.tail ⟨u, hu', hdeg', rfl⟩
    · rw [Finset.erase_eq_of_notMem hvb] at ih'
      rw [Finset.erase_eq_of_notMem (fun h => hvb (Finset.mem_of_mem_erase h))]
      exact ih'.tail ⟨u, hu, hdeg, rfl⟩

theorem RR_of_empty {F B B' : Finset (Fin n)} (hBF : B ⊆ F) (h : RR S F B B')
    (h0 : RR S F B ∅) : RR S F B' ∅ := by
  induction h with
  | refl => exact h0
  | @tail b c hab hs ih =>
    obtain ⟨u, hu, hdeg, rfl⟩ := hs
    have hbF : b ⊆ F := (RR_sub hab).trans hBF
    have := RR_erase hbF ih u hu hdeg
    simpa using this

theorem RR_nonempty_contra {F X : Finset (Fin n)} (h : RR S F X ∅) (hX : X.Nonempty)
    (hmin : ∀ v ∈ X, 3 ≤ CubicPathwidth.T4.tdeg S F X v) : False := by
  rcases Relation.ReflTransGen.cases_head h with heq | ⟨c, ⟨u, hu, hdeg, _⟩, _⟩
  · rw [heq] at hX
    exact Finset.not_nonempty_empty hX
  · have := hmin u hu
    omega

/-! ## Reachability with the core-set fixed -/

theorem reach_inv {F B : Finset (Fin n)} {p : Finset (Fin n) × Finset (Fin n)}
    (h : Relation.ReflTransGen (CubicPathwidth.T4.Step S) (F, B) p) (hBF : B ⊆ F) :
    p.2 ⊆ p.1 ∧ p.1 ⊆ F := by
  induction h with
  | refl => exact ⟨hBF, Finset.Subset.rfl⟩
  | @tail p1 p2 _ hs ih =>
    obtain ⟨ih1, ih2⟩ := ih
    cases hs with
    | reduce hv _ =>
      exact ⟨(Finset.erase_subset _ _).trans ih1, ih2⟩
    | delete hw =>
      exact ⟨Finset.erase_subset_erase _ ih1, (Finset.erase_subset _ _).trans ih2⟩

theorem RR_of_reach' {F B : Finset (Fin n)} {p : Finset (Fin n) × Finset (Fin n)}
    (h : Relation.ReflTransGen (CubicPathwidth.T4.Step S) (F, B) p) (hBF : B ⊆ F) :
    p.1 = F → RR S F B p.2 := by
  induction h with
  | refl => intro _; exact Relation.ReflTransGen.refl
  | @tail p1 p2 hp hs ih =>
    intro h2
    have hinv := reach_inv hp hBF
    cases hs with
    | reduce hv hdeg =>
      dsimp only at h2 ih
      subst h2
      exact (ih rfl).tail ⟨_, hv, hdeg, rfl⟩
    | delete hw =>
      exfalso
      have hwF : _ ∈ F := hinv.2 (hinv.1 hw)
      rw [← h2] at hwF
      simp at hwF

theorem RR_of_reach {F B B' : Finset (Fin n)} (hBF : B ⊆ F)
    (h : Relation.ReflTransGen (CubicPathwidth.T4.Step S) (F, B) (F, B')) :
    RR S F B B' :=
  RR_of_reach' h hBF rfl

/-! ## Counting torso neighbours -/

open Classical in

theorem card_adj_eq_degree (R : Graph) (hRWF : R.WF) (hn : ∀ w ∈ R.nodes, w < n)
    (x : Fin n) :
    (Finset.univ.filter fun y : Fin n => R.Adj x.val y.val).card = R.degree x.val := by
  have hmap : (Finset.univ.filter fun y : Fin n => R.Adj x.val y.val).map Fin.valEmbedding
      = (R.nbrs x.val).toFinset := by
    ext w
    simp only [Finset.mem_map, Finset.mem_filter, Finset.mem_univ, true_and,
      List.mem_toFinset, Fin.valEmbedding_apply]
    constructor
    · rintro ⟨y, hy, rfl⟩
      exact hy
    · intro hw
      have hwn : w ∈ R.nodes := hRWF.nbrs_sub _ _ hw
      exact ⟨⟨w, hn w hwn⟩, hw, rfl⟩
  rw [← Finset.card_map Fin.valEmbedding, hmap, List.toFinset_card_of_nodup (hRWF.nbrs_nodup _)]
  rfl

theorem deletedSet_nil {ops : List Op} (h : ∀ o ∈ ops, ∃ v nb, o = Op.red v nb) :
    deletedSet ops = [] := by
  unfold deletedSet
  rw [List.filterMap_eq_nil_iff]
  intro o ho
  obtain ⟨v, nb, rfl⟩ := h o ho
  rfl

/-! ## Main theorem -/

theorem reduceConfluent_of (hSim : TorsoSim) (hMax : ReduceRecordMaximal) (hMono : RecordMono)
    (hCongr : OpsRecordCongr) (hApp : OpsRecordAppend) : ReduceConfluent := by
  classical
  intro G hG hEm
  obtain ⟨opsE, hredE, hrecE⟩ := hEm
  have hRS := reduceRecordSpec G hG
  dsimp only at hRS
  obtain ⟨hRWF, hRnodes, -, hRops, -⟩ := hRS
  have hMx := hMax G hG
  dsimp only at hMx
  obtain ⟨hOps, hmin, -⟩ := hMx
  set R := (reduceRecord G).1 with hRdef
  set ops := (reduceRecord G).2 with hopsdef
  obtain ⟨n, hn⟩ : ∃ n : ℕ, ∀ v ∈ G.nodes, v < n :=
    ⟨G.nodes.sum + 1, fun v hv => Nat.lt_succ_of_le (List.le_sum_of_mem hv)⟩
  have hRn : ∀ w ∈ R.nodes, w < n := fun w hw => hn w (hRnodes w hw)
  obtain ⟨-, hReachE, -⟩ := hSim n G Graph.empty opsE hG hn hrecE
  obtain ⟨-, hReachR, hAdjR⟩ := hSim n G R ops hG hn hOps
  have hdelE : deletedSet opsE = [] := deletedSet_nil hredE
  have hdelR : deletedSet ops = [] := by
    apply deletedSet_nil
    intro o ho
    obtain ⟨v, nb, h, -⟩ := hRops o ho
    exact ⟨v, nb, h⟩
  have hF1 : ∀ ops' : List Op, deletedSet ops' = [] →
      (Finset.univ.filter fun x : Fin n => x.val ∈ G.nodes).filter
          (fun x : Fin n => x.val ∉ deletedSet ops') =
        Finset.univ.filter fun x : Fin n => x.val ∈ G.nodes := by
    intro ops' h
    apply Finset.filter_true_of_mem
    intro x _
    rw [h]
    simp
  rw [hF1 opsE hdelE] at hReachE
  rw [hF1 ops hdelR] at hReachR hAdjR
  have hB1E : (Finset.univ.filter fun x : Fin n => x.val ∈ (Graph.empty).nodes) = ∅ := by
    simp [Graph.empty]
  have hRE := RR_of_reach (Finset.Subset.refl _) hReachE
  rw [hB1E] at hRE
  have hRV := RR_of_reach (Finset.Subset.refl _) hReachR
  have hcore := RR_of_empty (Finset.Subset.refl _) hRV hRE
  have hminR : ∀ x ∈ Finset.univ.filter (fun x : Fin n => x.val ∈ R.nodes),
      3 ≤ CubicPathwidth.T4.tdeg (G.toSimpleGraph n)
        (Finset.univ.filter fun x : Fin n => x.val ∈ G.nodes)
        (Finset.univ.filter (fun x : Fin n => x.val ∈ R.nodes)) x := by
    intro x hx
    have hxR : x.val ∈ R.nodes := (Finset.mem_filter.mp hx).2
    rw [CubicPathwidth.T4.tdeg_eq_card, Finset.filter_congr (fun y _ => hAdjR x y),
      card_adj_eq_degree R hRWF hRn x]
    exact hmin x.val hxR
  have hB1empty : Finset.univ.filter (fun x : Fin n => x.val ∈ R.nodes) = ∅ := by
    by_contra hne
    exact RR_nonempty_contra hcore (Finset.nonempty_iff_ne_empty.mpr hne) hminR
  have hRnil : R.nodes = [] := by
    rw [List.eq_nil_iff_forall_not_mem]
    intro v hv
    have hvlt := hn v (hRnodes v hv)
    have hmem : (⟨v, hvlt⟩ : Fin n) ∈ Finset.univ.filter (fun x : Fin n => x.val ∈ R.nodes) := by
      simp [hv]
    rw [hB1empty] at hmem
    simp at hmem
  show R.nodes.length = 0
  rw [hRnil]
  rfl

end CubicPathwidth.Alg.R6

#print axioms CubicPathwidth.Alg.R6.reduceConfluent_of
Back to top