Imports
Paths through one source vertex's incident gadgets
The CLRS construction orders all edge gadgets incident on a source vertex and joins their corresponding six-vertex sides. This file concatenates the local traversals chosen by a source cover and proves that the result follows target edges from the first incidence port to the last one.
namespace CLRS.Chapter34.HamiltonianCycleReductionConcatenate the cover-selected traversals for a list of incidences.
def selectedIncidenceChainPath
(I : CliqueInstance) (cover : Finset Nat)
(refs : List IncidentOccurrence) : List Nat :=
refs.flatMap (selectedGlobalWidgetPath I cover)The complete target path represented by one selected source vertex.
def selectedSourceVertexPath
(I : CliqueInstance) (cover : Finset Nat) (u : Nat) : List Nat :=
selectedIncidenceChainPath I cover (incidentOccurrences I u)theorem selectedIncidenceChainPath_head
(I : CliqueInstance) (cover : Finset Nat)
(first : IncidentOccurrence) (rest : List IncidentOccurrence) :
(selectedIncidenceChainPath I cover (first :: rest)).head? =
some (incidentVertex first 0) := by
simp [selectedIncidenceChainPath, selectedGlobalWidgetPath_head]
theorem selectedIncidenceChainPath_getLast
(I : CliqueInstance) (cover : Finset Nat)
(first : IncidentOccurrence) (rest : List IncidentOccurrence) :
(selectedIncidenceChainPath I cover (first :: rest)).getLast? =
some (incidentVertex ((first :: rest).getLast (by simp)) 5) := by
induction rest generalizing first with
| nil =>
simp [selectedIncidenceChainPath, selectedGlobalWidgetPath_getLast]
| cons second rest ih =>
simp only [selectedIncidenceChainPath, List.flatMap_cons]
rw [List.getLast?_append_of_ne_nil]
· simpa [selectedIncidenceChainPath] using ih second
· change selectedIncidenceChainPath I cover (second :: rest) ≠ []
intro hempty
have hhead := selectedIncidenceChainPath_head I cover second rest
rw [hempty] at hhead
simp at hheadA connector generated for a consecutive suffix also occurs in the full incidence-chain edge list.
theorem mem_incidenceChainEdges_of_cons_cons_suffix
{first second : IncidentOccurrence} {rest refs : List IncidentOccurrence}
(hsuffix : first :: second :: rest <:+ refs) :
normalizeUndirectedEdge (incidentVertex first 5)
(incidentVertex second 0) ∈ incidenceChainEdges refs := by
rcases hsuffix with ⟨pre, rfl⟩
induction pre with
| nil => simp [incidenceChainEdges]
| cons ref pre ih =>
cases pre with
| nil => simp [incidenceChainEdges]
| cons next pre =>
simp only [List.cons_append, incidenceChainEdges, List.mem_cons]
exact Or.inr ihSuccessive incidence paths are joined by an edge of the constructed target graph.
theorem adj_incident_chain_connector
{I : CliqueInstance} {u : Nat}
{first second : IncidentOccurrence} {rest : List IncidentOccurrence}
(hu : u < I.vertexCount)
(hsuffix : first :: second :: rest <:+ incidentOccurrences I u) :
(clrsHamiltonianInstance I).Adj
(incidentVertex first 5) (incidentVertex second 0) := by
have hpairwise : (first :: second :: rest).Pairwise
(fun left right => left.occurrence < right.occurrence) :=
(incidentOccurrences_pairwise I u).sublist hsuffix.sublist
have hoccurrence : first.occurrence < second.occurrence :=
(List.pairwise_cons.mp hpairwise).1 second (by simp)
have hvertices : incidentVertex first 5 < incidentVertex second 0 :=
incidentVertex_lt_of_occurrence_lt hoccurrence (by omega) (by omega)
have hchain : normalizeUndirectedEdge (incidentVertex first 5)
(incidentVertex second 0) ∈ allIncidenceChainEdges I := by
simp only [allIncidenceChainEdges, List.mem_flatMap, List.mem_range]
exact ⟨u, hu, mem_incidenceChainEdges_of_cons_cons_suffix hsuffix⟩
have hchain' : (incidentVertex first 5, incidentVertex second 0) ∈
allIncidenceChainEdges I := by
simpa [normalizeUndirectedEdge, hvertices] using hchain
apply CliqueInstance.adj_of_mem (I := clrsHamiltonianInstance I) hvertices
simp [clrsHamiltonianInstance, clrsReductionEdges, hchain']Concatenating all chosen local traversals along one incidence suffix gives a genuine path of the constructed graph.
theorem selectedIncidenceChainPath_pathAdjacent_of_suffix
{I : CliqueInstance} {u : Nat} {cover : Finset Nat}
{refs : List IncidentOccurrence}
(hu : u < I.vertexCount)
(hsuffix : refs <:+ incidentOccurrences I u) :
(clrsHamiltonianInstance I).PathAdjacent
(selectedIncidenceChainPath I cover refs) := by
rw [CliqueInstance.pathAdjacent_iff_isChain]
induction refs using List.twoStepInduction with
| nil => simp [selectedIncidenceChainPath]
| singleton ref =>
have href : ref ∈ incidentOccurrences I u := by
exact hsuffix.subset (by simp)
simpa [selectedIncidenceChainPath] using
(CliqueInstance.pathAdjacent_iff_isChain _ _).1
(selectedGlobalWidgetPath_pathAdjacent href)
| cons_cons first second rest ihRest ihTail =>
simp only [selectedIncidenceChainPath, List.flatMap_cons]
apply List.IsChain.append
· have hfirst : first ∈ incidentOccurrences I u := by
exact hsuffix.subset (by simp)
exact (CliqueInstance.pathAdjacent_iff_isChain _ _).1
(selectedGlobalWidgetPath_pathAdjacent hfirst)
· apply ihTail second
exact List.IsSuffix.trans (by simp) hsuffix
· intro x hx y hy
rw [selectedGlobalWidgetPath_getLast] at hx
change y ∈ (selectedIncidenceChainPath I cover (second :: rest)).head? at hy
rw [selectedIncidenceChainPath_head] at hy
simp only [Option.mem_some_iff] at hx hy
subst x
subst y
exact adj_incident_chain_connector hu hsuffixtheorem selectedSourceVertexPath_pathAdjacent
{I : CliqueInstance} {cover : Finset Nat} {u : Nat}
(hu : u < I.vertexCount) :
(clrsHamiltonianInstance I).PathAdjacent
(selectedSourceVertexPath I cover u) := by
exact selectedIncidenceChainPath_pathAdjacent_of_suffix hu (by simp)theorem selectedSourceVertexPath_head
{I : CliqueInstance} {cover : Finset Nat} {u : Nat}
{first : IncidentOccurrence} {rest : List IncidentOccurrence}
(hrefs : incidentOccurrences I u = first :: rest) :
(selectedSourceVertexPath I cover u).head? =
some (incidentVertex first 0) := by
simp [selectedSourceVertexPath, hrefs, selectedIncidenceChainPath_head]theorem selectedSourceVertexPath_getLast
{I : CliqueInstance} {cover : Finset Nat} {u : Nat}
{first : IncidentOccurrence} {rest : List IncidentOccurrence}
(hrefs : incidentOccurrences I u = first :: rest) :
(selectedSourceVertexPath I cover u).getLast? =
some (incidentVertex ((first :: rest).getLast (by simp)) 5) := by
simp [selectedSourceVertexPath, hrefs, selectedIncidenceChainPath_getLast]end CLRS.Chapter34.HamiltonianCycleReduction