Pair bits are read off by position to The row-by-row check of the clique verifier

TheoremPair bits are read off by position#✓fully proved

Let \(n\) be a natural number, and let the pair list of \(n\) be the list of pairs \((i, j)\) with \(i < j < n\) in encoding order. Let \(b\) be a list of bits whose length equals the length of the pair list of \(n\). For all \(i < j < n\), the bit of the pair \((i, j)\) in \(b\) is the entry of \(b\) at the position of \((i, j)\) in the pair list of \(n\).

theorem adjBits_eq_getElem {n : ℕ} {bits : List Bool} {i j : ℕ}
    (h : bits.length = (pairs n).length) (hij : i < j) (hj : j < n) :
    adjBits n bits i j = bits[(pairs n).idxOf (i, j)]'(by
      rw [h]; exact List.idxOf_lt_length_of_mem (mem_pairs.2 ⟨hij, hj⟩))
Uses 3 · Used by 3

TheoremPair bits computed by a function#✓fully proved

Let \(n\) be a natural number, let \(f\) be a function from pairs of natural numbers to bits, and let \(b\) be the list obtained by applying \(f\) to each entry of the pair list of \(n\) (the pairs \((i, j)\) with \(i < j < n\) in encoding order). Then for all \(i < j < n\), the bit of the pair \((i, j)\) in \(b\) is \(f(i, j)\).

theorem adjBits_map_pairs {n i j : ℕ} (f : ℕ × ℕ → Bool) (hij : i < j) (hj : j < n) :
    adjBits n ((pairs n).map f) i j = f (i, j)
Uses 4 · Used by 1

TheoremComplementing the pair bits complements the graph#✓fully proved

Let \(n \in \mathbb{N}\) and let \(b\) be a list of bits whose length is the number of pairs \((i, j)\) with \(i < j < n\). Then the graph on \(\{0, \dots, n-1\}\) read off the list obtained by negating every bit of \(b\) is the complement of the graph on \(\{0, \dots, n-1\}\) read off \(b\).

theorem toGraph_map_not {n : ℕ} {bits : List Bool} (h : bits.length = (pairs n).length) :
    toGraph n (bits.map not) = (toGraph n bits)ᶜ
Uses 5 · Used by 1

TheoremCorrectness of the complementing map from CLIQUE to INDEPENDENT-SET#✓fully proved

For every bit string \(x\), CLIQUE accepts \(x\) if and only if INDEPENDENT-SET accepts the image of \(x\) under the complementing map from CLIQUE to INDEPENDENT-SET instances.

theorem cliqueDec_eq_indSetDec_flipKG (x : List Bool) : cliqueDec x = indSetDec (flipKG x)
Uses 13 · Used by 1

TheoremIndependent sets and vertex covers of complementary sizes#✓fully proved

Let \(G\) be a simple graph whose vertices are \(0, 1, \dots, n - 1\), and let \(k \le n\). Then \(G\) has an independent set of exactly \(k\) vertices if and only if \(G\) has a vertex cover of exactly \(n - k\) vertices.

theorem exists_isNIndepSet_iff_exists_isVertexCover {n k : ℕ} (G : SimpleGraph (Fin n))
    (hk : k ≤ n) : (∃ s, G.IsNIndepSet k s) ↔
      ∃ s : Finset (Fin n), s.card = n - k ∧ G.IsVertexCover (s : Set (Fin n))
Used by 1

TheoremMembership in the literal occurrences of a CNF formula#✓fully proved

Let \(\varphi\) be a CNF formula with clauses \(C_0, \dots, C_{m-1}\), let \(i\) and \(x\) be natural numbers and let \(b\) be a Boolean. The triple \((i, x, b)\) belongs to the list of literal occurrences of \(\varphi\) if and only if \(i < m\) and the literal \((x, b)\) belongs to \(C_i\).

theorem mem_occs {p : ℕ × ℕ × Bool} {φ : CNF} :
    p ∈ occs φ ↔ ∃ h : p.1 < φ.length, p.2 ∈ φ[p.1]
Uses 3 · Used by 1

TheoremAdjacency in Karp's clique graph#✓fully proved

Let \(\varphi\) be a CNF formula and let \(o_0, \dots, o_{m-1}\) be its literal occurrences (clause index, variable, polarity) in formula order. In Karp's graph of \(\varphi\), the graph on \(\{0, \dots, m-1\}\) read off the clique pair bits of \(\varphi\), vertices \(i\) and \(j\) are adjacent if and only if \(i \ne j\) and the occurrences \(o_i\) and \(o_j\) are adjacent, that is, they lie in different clauses and are not complementary (they are not the same variable with opposite polarities).

theorem toGraph_cliqueBits_adj {φ : CNF} {i j : Fin (occs φ).length} :
    (toGraph _ (cliqueBits φ)).Adj i j ↔ i ≠ j ∧ occAdj (occs φ)[i] (occs φ)[j] = true
Uses 8 · Used by 1

TheoremKarp's reduction from SAT to CLIQUE is correct#✓fully proved

A CNF formula \(\varphi\) with \(m\) clauses is satisfiable if and only if Karp's graph of \(\varphi\) has a clique of exactly \(m\) vertices. Karp's graph has one vertex for each literal occurrence of \(\varphi\), and two occurrences are adjacent when they lie in different clauses and are not complementary.

theorem cnfSat_iff_exists_isNClique (φ : CNF) :
    CNFSat φ ↔ ∃ s, (toGraph (occs φ).length (cliqueBits φ)).IsNClique φ.length s
Uses 9 · Used by 1

TheoremSAT decision on undecodable input (moved alias)#✓fully proved

Moved to DenseSAT.ToBinary.satDec_of_decodeCNF_eq_none (DenseToBinary).

@[deprecated DenseSAT.ToBinary.satDec_of_decodeCNF_eq_none (since := "2026-10-15")]
theorem satDec_of_decodeCNF_eq_none {x : List Bool} (h : decodeCNF x = none) :
    satDec x = false
Uses 4

InductiveModes of the clique verifier#✓fully proved

A mode is one of three values, clique, independent set and vertex cover, naming the three graph problems CLIQUE, INDEPENDENT-SET and VERTEX-COVER that share one NP verifier.

inductive Mode | clique | indep | cover
  deriving DecidableEq
Used by 34
Used byVertices that settle their pairs alone · The verifier for CLIQUE, INDEPENDENT-SET and VERTEX-COVER · Pair condition of the clique verifier · The pair condition splits by vertex · The row-by-row check of the clique verifier · The pair condition left to the later vertex · CLIQUE is verified with witnesses no longer than the input · Cliques of the graph given by pair bits · Vertex covers of the graph given by pair bits · An accepted input encodes an instance with a good vertex set · INDEPENDENT-SET is verified with witnesses no longer than the input · Independent sets of the graph given by pair bits · The verifier as a row-by-row check · Characterization of the CLIQUE verifier · The characteristic vector of a good vertex set is accepted · Verifying a graph language defined by a vertex-set condition · The row-by-row check is the pairwise check · Vertex sets meeting a mode's pair condition · VERTEX-COVER is verified by the clique verifier in cover mode · Run of the load phase · Program of the clique verifier · Reading an unterminated unary number rejects · The clique verifier's unary reader succeeds · One row of the clique verifier's walk · All rows of the clique verifier's walk · The verifier machine for clique, independent set and vertex cover · Walking the pairs of one row of the clique verifier · Walk step of the clique verifier · Rest of a walk step of the clique verifier · CLIQUE is in NP · INDEPENDENT-SET is in NP · The CLIQUE, INDEPENDENT-SET and VERTEX-COVER verifier as a host component · NP membership from the CLIQUE, INDEPENDENT-SET and VERTEX-COVER verifier · VERTEX-COVER (exact size k) is in NP

DefinitionPair condition of the clique verifier#✓fully proved

For a mode \(m\), the adjacency bit \(b\) of a vertex pair \(\{i, j\}\), and flags \(s_i\), \(s_j\) saying whether \(i\) and \(j\) are chosen, the pair condition \(\mathrm{ok}_m(b, s_i, s_j)\) is \(\lnot(s_i \land s_j) \lor b\) for clique, \(\lnot(s_i \land s_j) \lor \lnot b\) for independent set, and \(\lnot b \lor s_i \lor s_j\) for vertex cover.

def Mode.ok : Mode → Bool → Bool → Bool → Bool
  | .clique, b, si, sj => !(si && sj) || b
  | .indep, b, si, sj => !(si && sj) || !b
  | .cover, b, si, sj => !b || si || sj
Uses 1 · Used by 12

DefinitionThe verifier for CLIQUE, INDEPENDENT-SET and VERTEX-COVER#✓fully proved

For a mode \(m\), an input \(x\) and a witness \(w\) (bit lists), the verifier rejects if \(x\) does not decode to a triple \((k, n, \mathit{bits})\). Otherwise it accepts if and only if \(\mathit{bits}\) has one bit per pair \((i, j)\) with \(i < j < n\), \(w\) has at least \(n\) bits, exactly \(k\) of the first \(n\) bits of \(w\) are set, and for every pair \((i, j)\), matched with its bit \(b\) in the encoding order of the pairs, the pair condition of \(m\) holds for \(b\), \(w_i\) and \(w_j\). So the first \(n\) bits of \(w\) choose the vertices.

def kgCheck (m : Mode) (x w : List Bool) : Bool :=
  match decodeKG x with
  | none => false
  | some (k, n, bits) => bits.length == (pairs n).length && n ≤ w.length &&
      (w.take n).count true == k &&
      ((pairs n).zip bits).all fun pb => m.ok pb.2 (w.getD pb.1.1 false) (w.getD pb.1.2 false)
Uses 4 · Used by 10

DefinitionVertices that settle their pairs alone#✓fully proved

For a mode and the Boolean saying whether a vertex \(i\) is chosen, the result is true when \(i\) alone settles the condition on every pair \(\{i, j\}\): in the clique and independent-set modes it is true exactly when \(i\) is not chosen, and in the vertex-cover mode exactly when \(i\) is chosen.

def Mode.free : Mode → Bool → Bool
  | .cover, si => si
  | _, si => !si
Uses 1 · Used by 7

DefinitionThe pair condition left to the later vertex#✓fully proved

For a mode \(m\), a pair bit \(b\) and a flag \(s_j\) saying whether vertex \(j\) is chosen, \(\mathrm{sat}_m(b, s_j)\) is \(\lnot s_j \lor b\) for clique, \(\lnot s_j \lor \lnot b\) for independent set, and \(\lnot b \lor s_j\) for vertex cover.

It is the pair condition on \(\{i, j\}\) when vertex \(i\) does not settle it.

def Mode.sat : Mode → Bool → Bool → Bool
  | .clique, b, sj => !sj || b
  | .indep, b, sj => !sj || !b
  | .cover, b, sj => !b || sj
Uses 1 · Used by 7

TheoremThe pair condition splits by vertex#✓fully proved

For a mode \(m\) and Booleans \(b\), \(s_i\), \(s_j\), let \(\mathrm{ok}_m(b, s_i, s_j)\) be the pair condition of \(m\): \(\lnot(s_i \land s_j) \lor b\) for clique, \(\lnot(s_i \land s_j) \lor \lnot b\) for independent set and \(\lnot b \lor s_i \lor s_j\) for vertex cover. Let \(\mathrm{free}_m(s_i)\), the part that vertex \(i\) alone settles, be \(\lnot s_i\) for clique and independent set and \(s_i\) for vertex cover, and let \(\mathrm{sat}_m(b, s_j)\), the part left to \(j\), be \(\lnot s_j \lor b\) for clique, \(\lnot s_j \lor \lnot b\) for independent set and \(\lnot b \lor s_j\) for vertex cover. Then for every mode \(m\) and all Booleans \(b\), \(s_i\), \(s_j\), we have \(\mathrm{ok}_m(b, s_i, s_j) = \mathrm{free}_m(s_i) \lor \mathrm{sat}_m(b, s_j)\).

theorem Mode.ok_eq (m : Mode) (b si sj : Bool) : m.ok b si sj = (m.free si || m.sat b sj)
Uses 4 · Used by 1

TheoremVertex pairs in encoding order for one more vertex#✓fully proved

For a natural number \(m\), write \(P(m)\) for the list of pairs \((i, j)\) of natural numbers with \(i < j < m\), ordered by \(i\) ascending and, for each \(i\), by \(j\) descending. Then for every natural number \(n\), \(P(n + 1)\) is the list \((0, n), (0, n - 1), \dots, (0, 1)\) (empty when \(n = 0\)) followed by the pairs \((i + 1, j + 1)\) for the pairs \((i, j)\) of \(P(n)\), in the order of \(P(n)\).

theorem pairs_succ (n : ℕ) : pairs (n + 1) = (List.range n).reverse.map (fun j => (0, j + 1)) ++
    (pairs n).map fun p => (p.1 + 1, p.2 + 1)
Uses 1 · Used by 2

DefinitionChosen-flag pairs#✓fully proved

For a list \(s = (s_0, \dots, s_{\ell - 1})\) of Booleans, the chosen-flag pairs of \(s\) are the pairs \((s_i, s_j)\), one for each vertex pair \((i, j)\) with \(i < j < \ell\), listed in the encoding order of the vertex pairs of \(\ell\) vertices (rows \(i\) ascending, within a row \(j\) descending).

def pairVals (s : List Bool) : List (Bool × Bool) :=
  (pairs s.length).map fun p => (s.getD p.1 false, s.getD p.2 false)
Uses 1 · Used by 3

TheoremReading a list at every index#✓fully proved

For every list \(s\) of Booleans of length \(\ell\), reading \(s\) at the indices \(0, 1, \dots, \ell - 1\) in turn (with default value false) gives back \(s\).

theorem map_getD_range (s : List Bool) : (List.range s.length).map (s.getD · false) = s
Used by 1

TheoremChosen-flag pairs of a list with a new head#✓fully proved

For a Boolean \(a\) and a list \(s = (s_0, \dots, s_{\ell - 1})\) of Booleans, the chosen-flag pairs of the list \((a, s_0, \dots, s_{\ell - 1})\) are \((a, s_{\ell - 1}), (a, s_{\ell - 2}), \dots, (a, s_0)\), followed by the chosen-flag pairs of \(s\).

theorem pairVals_cons (a : Bool) (s : List Bool) :
    pairVals (a :: s) = s.reverse.map (a, ·) ++ pairVals s
Uses 4 · Used by 1

DefinitionThe row-by-row check of the clique verifier#✓fully proved

For a mode \(m\), the row-by-row check of a list of chosen-flags against a list \(b\) of pair bits is defined by recursion on the flags. For the empty list it holds iff \(b\) is empty. For a flag \(a\) followed by the flags \(r\) of the later vertices, write \(\rho\) for the reverse of \(r\): the check holds iff \(|r| \le |b|\), either \(a\) is free for \(m\) or \(\mathrm{sat}_m(b_t, \rho_t)\) holds for every \(t < |r|\) (indices from \(0\)), and the check of \(r\) against \(b\) with its first \(|r|\) bits dropped holds.

This is what the machine checks, vertex by vertex; at the end no bit may be left.

def rowsOk (m : Mode) : List Bool → List Bool → Bool
  | [], bs => bs.isEmpty
  | s :: rest, bs => decide (rest.length ≤ bs.length) &&
      (m.free s || (rest.reverse.zip bs).all fun p => m.sat p.2 p.1) &&
      rowsOk m rest (bs.drop rest.length)
Uses 3 · Used by 4
20 fully proved

The dependency explorer needs JavaScript and its graph data.

Download the complete graph data.