Hamiltonian paths to Witness encoding of a nonempty list
DefinitionHamiltonian paths#✓fully proved
Let \(E\) be a list of pairs of natural numbers, viewed as the digraph on \(0, \dots, n - 1\) whose arcs are the pairs in \(E\) with both ends below \(n\). A list \(p\) is a Hamiltonian path from \(s\) to \(t\) when it lists each of the vertices \(0, \dots, n - 1\) exactly once, starts at \(s\), ends at \(t\), and each two consecutive entries of \(p\) form an arc.
def IsHamPath (n : ℕ) (es : List (ℕ × ℕ)) (s t : ℕ) (p : List ℕ) : Prop :=
p.Nodup ∧ p.length = n ∧ (∀ v ∈ p, v < n) ∧ p.head? = some s ∧ p.getLast? = some t ∧
p.IsChain (Path.arc n es)
def arc (n : ℕ) (es : List (ℕ × ℕ)) (u v : ℕ) : Prop := (u, v) ∈ es ∧ u < n ∧ v < n
CSLibExt/Computability/Complexity/Path.lean:53
Uses 1 · Used by 23
DefinitionThe HAMPATH problem#✓fully proved
The decision problem that accepts a bit string \(x\) exactly when, for some \(s\), \(t\), \(n\) and list of pairs \(E\), \(x\) is the PATH encoding of \(s\), \(t\) and the digraph on \(0, \dots, n - 1\) with edge list \(E\), and this digraph has a Hamiltonian path from \(s\) to \(t\).
noncomputable def hamPathDec : MetaMathlibExt.ComplexityTheory.DecisionProblem := fun x =>
decide (∃ s t n es, Path.encodeP s t n es = x ∧ ∃ p, IsHamPath n es s t p)
abbrev DecisionProblem := List Bool → Bool
MathlibExt/Computability/Complexity.lean:170
def encodeP (s t n : ℕ) (es : List (ℕ × ℕ)) : List Bool :=
List.replicate s true ++ false :: (List.replicate t true ++ false :: Karp.encodeE n es)
CSLibExt/Computability/Complexity/Path.lean:40
def IsHamPath (n : ℕ) (es : List (ℕ × ℕ)) (s t : ℕ) (p : List ℕ) : Prop :=
p.Nodup ∧ p.length = n ∧ (∀ v ∈ p, v < n) ∧ p.head? = some s ∧ p.getLast? = some t ∧
p.IsChain (Path.arc n es)
CSLibExt/Computability/Complexity/Karp/HamPath.lean:53
Uses 3 · Used by 7
DefinitionDistinct variables of a formula#✓fully proved
The list of the distinct variables of a CNF formula \(\varphi\), in order of occurrence in \(\varphi\), with each variable kept at its last occurrence.
def hamVars (φ : CNF) : List ℕ := (varsOf φ).dedup
abbrev CNF := List CNFClause
CSLibExt/Logics/Propositional/CNF/Basic.lean:33
def varsOf (φ : CNF) : List Nat := φ.flatMap fun C => C.map Prod.fst
CSLibExt/Computability/SatTimeM.lean:70
Uses 2 · Used by 33
DefinitionTops of the diamonds#✓fully proved
In the HAMPATH construction with \(m\) clauses, the top of diamond \(i\) is the vertex \(m + i(3m + 2)\); it is also the bottom of diamond \(i - 1\).
def hpT (m i : ℕ) : ℕ := m + i * (3 * m + 2)
Used by 56
DefinitionRow vertices of a diamond#✓fully proved
In the HAMPATH construction with \(m\) clauses, write \(T(i)\) for the top of diamond \(i\). Row vertex \(l\) of diamond \(i\) is the number \(T(i) + 1 + l\); the row of diamond \(i\) consists of the vertices with \(l \le 3m\).
def hpR (m i l : ℕ) : ℕ := hpT m i + 1 + l
def hpT (m i : ℕ) : ℕ := m + i * (3 * m + 2)
CSLibExt/Computability/Complexity/Karp/HamPath.lean:66
Uses 1 · Used by 48
DefinitionArcs of a variable diamond#✓fully proved
Let \(\varphi\) be a CNF formula with \(m\) clauses, and write \(T(i)\) for the top of diamond \(i\) and \(R(i, l)\) for its row vertex \(l\). The arcs of diamond \(i\) for variable \(x\) are \(T(i) \to R(i, 0)\), \(T(i) \to R(i, 3m)\), \(R(i, 0) \to T(i + 1)\) and \(R(i, 3m) \to T(i + 1)\); for every \(l < 3m\), both \(R(i, l) \to R(i, l + 1)\) and \(R(i, l + 1) \to R(i, l)\); and for every clause \(j < m\), the arcs \(R(i, 3j + 1) \to j\) and \(j \to R(i, 3j + 2)\) if \(x\) occurs positively in clause \(j\), and the arcs \(R(i, 3j + 2) \to j\) and \(j \to R(i, 3j + 1)\) if \(x\) occurs negatively in clause \(j\). Here \(j\) is the vertex of clause \(j\).
def diamondEdges (φ : CNF) (i x : ℕ) : List (ℕ × ℕ) :=
let m := φ.length
[(hpT m i, hpR m i 0), (hpT m i, hpR m i (3 * m)), (hpR m i 0, hpT m (i + 1)),
(hpR m i (3 * m), hpT m (i + 1))] ++
(List.range (3 * m)).flatMap (fun l => [(hpR m i l, hpR m i (l + 1)),
(hpR m i (l + 1), hpR m i l)]) ++
(List.range m).flatMap fun j =>
(if (x, true) ∈ φ.getD j [] then [(hpR m i (3 * j + 1), j), (j, hpR m i (3 * j + 2))]
else []) ++
(if (x, false) ∈ φ.getD j [] then [(hpR m i (3 * j + 2), j), (j, hpR m i (3 * j + 1))]
else [])
abbrev CNF := List CNFClause
CSLibExt/Logics/Propositional/CNF/Basic.lean:33
def hpT (m i : ℕ) : ℕ := m + i * (3 * m + 2)
CSLibExt/Computability/Complexity/Karp/HamPath.lean:66
def hpR (m i l : ℕ) : ℕ := hpT m i + 1 + l
CSLibExt/Computability/Complexity/Karp/HamPath.lean:69
Uses 4 · Used by 10
DefinitionArcs of the HAMPATH construction#✓fully proved
Let \(\varphi\) be a CNF formula and let \(x_0, \dots, x_{k-1}\) be its distinct variables, in the order of the distinct-variable list of \(\varphi\). The arcs of the construction for \(\varphi\) are the arcs of diamond \(i\) for variable \(x_i\), for \(i = 0, \dots, k - 1\), concatenated in this order.
def hamEdges (φ : CNF) : List (ℕ × ℕ) :=
(List.range (hamVars φ).length).flatMap fun i => diamondEdges φ i ((hamVars φ).getD i 0)
abbrev CNF := List CNFClause
CSLibExt/Logics/Propositional/CNF/Basic.lean:33
def hamVars (φ : CNF) : List ℕ := (varsOf φ).dedup
CSLibExt/Computability/Complexity/Karp/HamPath.lean:63
def diamondEdges (φ : CNF) (i x : ℕ) : List (ℕ × ℕ) :=
let m := φ.length
[(hpT m i, hpR m i 0), (hpT m i, hpR m i (3 * m)), (hpR m i 0, hpT m (i + 1)),
(hpR m i (3 * m), hpT m (i + 1))] ++
(List.range (3 * m)).flatMap (fun l => [(hpR m i l, hpR m i (l + 1)),
(hpR m i (l + 1), hpR m i l)]) ++
(List.range m).flatMap fun j =>
(if (x, true) ∈ φ.getD j [] then [(hpR m i (3 * j + 1), j), (j, hpR m i (3 * j + 2))]
else []) ++
(if (x, false) ∈ φ.getD j [] then [(hpR m i (3 * j + 2), j), (j, hpR m i (3 * j + 1))]
else [])
CSLibExt/Computability/Complexity/Karp/HamPath.lean:72
Uses 3 · Used by 30
DefinitionSipser's HAMPATH instance of a CNF formula#✓fully proved
Let \(\varphi\) be a CNF formula with \(m\) clauses, numbered \(0, \dots, m - 1\), and let \(x_0, \dots, x_{k-1}\) be its distinct variables, in the order of their last occurrences in \(\varphi\) (clauses read in order, and the literals of each clause in order). Put \(T_i = m + i(3m + 2)\) and \(R_{i,l} = T_i + 1 + l\). The result is the encoded PATH instance with vertices \(0, \dots, T_k\), source \(T_0\), target \(T_k\), and, for each \(i < k\), the following arcs: the frame arcs \(T_i \to R_{i,0}\), \(T_i \to R_{i,3m}\), \(R_{i,0} \to T_{i+1}\) and \(R_{i,3m} \to T_{i+1}\); the row arcs \(R_{i,l} \to R_{i,l+1}\) and \(R_{i,l+1} \to R_{i,l}\) for every \(l < 3m\); and, for every clause \(j < m\), the arcs \(R_{i,3j+1} \to j\) and \(j \to R_{i,3j+2}\) if the literal \(x_i\) occurs in clause \(j\), and the arcs \(R_{i,3j+2} \to j\) and \(j \to R_{i,3j+1}\) if the literal \(\neg x_i\) occurs in clause \(j\).
def toHam (φ : CNF) : List Bool :=
Path.encodeP (hpT φ.length 0) (hpT φ.length (hamVars φ).length)
(hpT φ.length (hamVars φ).length + 1) (hamEdges φ)
abbrev CNF := List CNFClause
CSLibExt/Logics/Propositional/CNF/Basic.lean:33
def encodeP (s t n : ℕ) (es : List (ℕ × ℕ)) : List Bool :=
List.replicate s true ++ false :: (List.replicate t true ++ false :: Karp.encodeE n es)
CSLibExt/Computability/Complexity/Path.lean:40
def hpT (m i : ℕ) : ℕ := m + i * (3 * m + 2)
CSLibExt/Computability/Complexity/Karp/HamPath.lean:66
def hamVars (φ : CNF) : List ℕ := (varsOf φ).dedup
CSLibExt/Computability/Complexity/Karp/HamPath.lean:63
def hamEdges (φ : CNF) : List (ℕ × ℕ) :=
(List.range (hamVars φ).length).flatMap fun i => diamondEdges φ i ((hamVars φ).getD i 0)
CSLibExt/Computability/Complexity/Karp/HamPath.lean:85
Uses 6 · Used by 6
DefinitionA fixed HAMPATH no-instance#✓fully proved
The encoded PATH instance on the two vertices \(0\) and \(1\), with no arcs, whose source and target are both \(0\).
It is a no-instance of HAMPATH: a Hamiltonian path would visit both vertices and start and end at \(0\), so it would visit \(0\) twice.
def noHam : List Bool := Path.encodeP 0 0 2 []
def encodeP (s t n : ℕ) (es : List (ℕ × ℕ)) : List Bool :=
List.replicate s true ++ false :: (List.replicate t true ++ false :: Karp.encodeE n es)
CSLibExt/Computability/Complexity/Path.lean:40
Uses 1 · Used by 5
DefinitionThe SAT-to-HAMPATH reduction map#✓fully proved
A bit string \(x\) that decodes to a CNF formula \(\varphi\) is sent to Sipser's HAMPATH instance of \(\varphi\), and a bit string that does not decode to a CNF formula is sent to the fixed HAMPATH no-instance (two vertices, no arcs, source and target \(0\)).
def reduceHam (x : List Bool) : List Bool :=
match decodeCNF x with
| some φ => toHam φ
| none => noHam
def decodeCNF (input : List Bool) : Option CNF := do
let (φ, rest) ← decodeCNFAux input
if rest.isEmpty then some φ else none
CSLibExt/Computability/CookLevin.lean:108
def toHam (φ : CNF) : List Bool :=
Path.encodeP (hpT φ.length 0) (hpT φ.length (hamVars φ).length)
(hpT φ.length (hamVars φ).length + 1) (hamEdges φ)
CSLibExt/Computability/Complexity/Karp/HamPath.lean:89
def noHam : List Bool := Path.encodeP 0 0 2 []
CSLibExt/Computability/Complexity/Karp/HamPath.lean:94
Uses 4 · Used by 3
DefinitionNormal clause detours#✓fully proved
Let \(\varphi\) be a CNF formula with \(m\) clauses and \(k\) distinct variables, and write \(R(i, l)\) for row vertex \(l\) of diamond \(i\) in the HAMPATH construction for \(\varphi\). A list of vertices \(p\) has normal detours when for every clause \(j < m\) there is a diamond \(i < k\) such that \(p\) contains \(R(i, 3j + 1), j, R(i, 3j + 2)\) or \(R(i, 3j + 2), j, R(i, 3j + 1)\) as consecutive entries.
def DetoursNormal (φ : CNF) (p : List ℕ) : Prop :=
∀ j < φ.length, ∃ i < (hamVars φ).length,
[hpR φ.length i (3 * j + 1), j, hpR φ.length i (3 * j + 2)] <:+: p ∨
[hpR φ.length i (3 * j + 2), j, hpR φ.length i (3 * j + 1)] <:+: p
abbrev CNF := List CNFClause
CSLibExt/Logics/Propositional/CNF/Basic.lean:33
def hamVars (φ : CNF) : List ℕ := (varsOf φ).dedup
CSLibExt/Computability/Complexity/Karp/HamPath.lean:63
def hpR (m i l : ℕ) : ℕ := hpT m i + 1 + l
CSLibExt/Computability/Complexity/Karp/HamPath.lean:69
Uses 4 · Used by 6
TheoremTops are monotone in the diamond index#✓fully proved
In the HAMPATH construction with \(m\) clauses, if \(i \le i'\) then the top of diamond \(i\) is at most the top of diamond \(i'\).
theorem hpT_mono {m i i' : ℕ} (h : i ≤ i') : hpT m i ≤ hpT m i'
def hpT (m i : ℕ) : ℕ := m + i * (3 * m + 2)
CSLibExt/Computability/Complexity/Karp/HamPath.lean:66
Uses 1 · Used by 6
TheoremRow vertices lie below the next top#✓fully proved
In the HAMPATH construction with \(m\) clauses, for every diamond \(i\) and every \(l \le 3m\), row vertex \(l\) of diamond \(i\) is a smaller number than the top of diamond \(i + 1\).
theorem hpR_lt_hpT_succ {m i l : ℕ} (hl : l ≤ 3 * m) : hpR m i l < hpT m (i + 1)
def hpR (m i l : ℕ) : ℕ := hpT m i + 1 + l
CSLibExt/Computability/Complexity/Karp/HamPath.lean:69
def hpT (m i : ℕ) : ℕ := m + i * (3 * m + 2)
CSLibExt/Computability/Complexity/Karp/HamPath.lean:66
Uses 2 · Used by 3
TheoremBits of an edge list, first edge first#✓fully proved
For natural numbers \(u, v\) and a list \(E\) of pairs of natural numbers, the bit encoding of the edge list whose first edge is \((u, v)\) and whose remaining edges are \(E\) is: \(u\) copies of true, then false, then \(v\) copies of true, then false, then the bit encoding of \(E\).
theorem edgeBits_cons (u v : ℕ) (es : List (ℕ × ℕ)) : Karp.edgeBits ((u, v) :: es) =
List.replicate u true ++ false :: (List.replicate v true ++ false :: Karp.edgeBits es)
def edgeBits (es : List (ℕ × ℕ)) : List Bool :=
es.flatMap fun e => List.replicate e.1 true ++ false :: (List.replicate e.2 true ++ [false])
CSLibExt/Computability/Complexity/Karp/Color.lean:160
Uses 1 · Used by 2
TheoremEdge bits of the empty edge list#✓fully proved
The edge-list bit encoding of the empty list of edges is the empty bit string.
@[simp] theorem edgeBits_nil : Karp.edgeBits [] = []
def edgeBits (es : List (ℕ × ℕ)) : List Bool :=
es.flatMap fun e => List.replicate e.1 true ++ false :: (List.replicate e.2 true ++ [false])
CSLibExt/Computability/Complexity/Karp/Color.lean:160
Uses 1
TheoremBits of concatenated edge lists#✓fully proved
For all lists \(E\) and \(E'\) of pairs of natural numbers, the bit encoding of the concatenation of \(E\) and \(E'\) is the bit encoding of \(E\) followed by the bit encoding of \(E'\).
theorem edgeBits_append (es es' : List (ℕ × ℕ)) :
Karp.edgeBits (es ++ es') = Karp.edgeBits es ++ Karp.edgeBits es'
def edgeBits (es : List (ℕ × ℕ)) : List Bool :=
es.flatMap fun e => List.replicate e.1 true ++ false :: (List.replicate e.2 true ++ [false])
CSLibExt/Computability/Complexity/Karp/Color.lean:160
DefinitionWitness encoding#✓fully proved
The witness encoding of a list \(p\) of natural numbers (the vertices of a candidate path) is the bit string obtained by writing each entry \(v\) of \(p\), in order, as \(v\) copies of true followed by one false, and concatenating the results.
Used by 19
DefinitionWitness decoder#✓fully proved
The witness decoder reads a list \(w\) of bits as a list of natural numbers. On the empty list it returns the empty list. Otherwise it reads a unary number \(v\) from the front of \(w\), a run of \(v\) copies of true ended by false, and if decoding the remaining bits gives a list \(p\), it returns \(v\) followed by \(p\). It fails if no unary number can be read from a nonempty list, or if decoding the remaining bits fails.
def decodeW (w : List Bool) : Option (List ℕ) :=
if w = [] then some [] else
match h : readUnaryLength w with
| none => none
| some (v, r) =>
have : r.length < w.length := Karp.length_lt_of_readUnaryLength h
(decodeW r).map (v :: ·)
termination_by w.length
def readUnaryLength : List Bool → Option (Nat × List Bool)
| [] => none
| false :: rest => some (0, rest)
| true :: rest => (readUnaryLength rest).map fun result => (result.1 + 1, result.2)
CSLibExt/Computability/CookLevin.lean:46
theorem length_lt_of_readUnaryLength {x r : List Bool} {u : ℕ}
(h : readUnaryLength x = some (u, r)) : r.length < x.length
CSLibExt/Computability/Complexity/Karp/Color.lean:132
Uses 2 · Used by 13
TheoremWitness encoding of the empty list#✓fully proved
The witness encoding of the empty list of vertices is the empty bit string.
@[simp] theorem encW_nil : encW [] = []
def encW (p : List ℕ) : List Bool := p.flatMap fun v => List.replicate v true ++ [false]
CSLibExt/Computability/Complexity/Karp/HamPathCheck.lean:53
Uses 1
TheoremWitness encoding of a nonempty list#✓fully proved
For a natural number \(v\) and a list \(p\) of natural numbers, the witness encoding of the list with first entry \(v\) followed by \(p\) is the bit string made of \(v\) copies of true, then one false, then the witness encoding of \(p\).
theorem encW_cons (v : ℕ) (p : List ℕ) :
encW (v :: p) = List.replicate v true ++ false :: encW p
def encW (p : List ℕ) : List Bool := p.flatMap fun v => List.replicate v true ++ [false]
CSLibExt/Computability/Complexity/Karp/HamPathCheck.lean:53
Uses 1 · Used by 7
Loading dependency explorer…
The dependency explorer needs JavaScript and its graph data.