Documentation

Atlas.TheoryOfComputation.code.NPCompleteness

Syntax of propositional Boolean formulas over variables indexed by ℕ. A BoolFormula is built from variables, the constants true and false, and the connectives ¬, ∧, ∨.

Instances For
    Instances For
      @[reducible, inline]

      A truth assignment is a function from variable indices ℕ to Bool.

      Instances For

        Evaluation of a Boolean formula under an assignment σ : ℕ → Bool. Returns the standard truth value of the formula under σ.

        Instances For

          A formula φ is satisfiable if there exists an assignment σ with φ.eval σ = true.

          Instances For

            SAT = {φ | φ is a satisfiable Boolean formula}.

            Instances For

              A literal is a variable or the negation of a variable.

              Instances For

                A clause is a disjunction of literals: either a single literal, or l ∨ (rest) where rest is itself a clause.

                Instances For

                  A formula is in Conjunctive Normal Form (CNF) if it is a conjunction of clauses.

                  Instances For

                    The length (number of literals) of a clause, counted by walking through the ors.

                    Instances For

                      A 3-clause is a clause containing exactly 3 literals.

                      Instances For

                        A formula is in 3CNF if it is a conjunction of 3-clauses.

                        Instances For

                          3SAT = {φ | φ is a satisfiable 3CNF formula}.

                          Instances For
                            theorem NPCompleteness.ThreeSAT.mk {φ : BoolFormula} (h3 : φ.Is3CNF) (hsat : φ.Satisfiable) :

                            Membership in ThreeSAT from the conjunction of being 3CNF and being satisfiable.

                            def IsNPHard {Γ : Type} (B : Set (List Γ)) :

                            A language B is NP-hard if every A ∈ NP is polynomial-time reducible to B, i.e. for all A ∈ NP, A ≤_P B.

                            Instances For
                              def IsNPComplete {Γ : Type} (B : Set (List Γ)) :

                              A language B is NP-complete if (1) B ∈ NP and (2) B is NP-hard, i.e. for every A ∈ NP, A ≤_P B.

                              Instances For

                                The SAT language presented as a language of one-symbol input words [φ] where the singleton list contains a satisfiable Boolean formula.

                                Instances For
                                  theorem CookLevin.tableau_from_accepting_branch {Q Γ : Type} [DecidableEq Q] (M : TuringMachine.NTM Q Γ) (w : List Γ) (n : ) (branch : Fin (n + 1)TuringMachine.Config Q Γ) (k : ) (hstart : branch 0, = M.initConfig w) (hsteps : ∀ (i : Fin n), M.step (branch i.castSucc) (branch i.succ)) (haccept : M.isAcceptConfig (branch n, )) (hk : M.runsInTime fun (n : ) => n ^ k) :

                                  Given an accepting computation branch of an NTM M on input w of length at most n^k steps, we can produce a Tableau (an n^k × n^k array of cells representing the computation history) for M on w. This is the bridge from an accepting branch to the combinatorial object that the Cook–Levin formula encodes.

                                  theorem CookLevin.accepts_from_tableau {Q Γ : Type} [DecidableEq Q] (M : TuringMachine.NTM Q Γ) (w : List Γ) (tab : TuringMachine.Tableau M w) :

                                  The converse direction: from any (accepting) tableau for M on w, the machine M accepts w.

                                  @[inline]
                                  def CookLevin.tableau_var_idx (i j σIdx dim numSymbols : ) :

                                  Index of the propositional variable x_{i,j,σ} indicating that cell (i,j) of a dim × dim tableau contains the symbol with index σIdx (out of numSymbols).

                                  Instances For

                                    Conjoin a list of Boolean formulas into a single BoolFormula. Empty list returns true; a singleton returns the formula itself.

                                    Instances For

                                      Disjoin a list of Boolean formulas into a single BoolFormula. Empty list returns false; a singleton returns the formula itself.

                                      Instances For

                                        The Cook–Levin sub-formula φ_cell: enforces that each cell (i,j) of the tableau contains exactly one symbol — encoded as the conjunction of "at least one symbol" and "no two distinct symbols simultaneously".

                                        Instances For
                                          def CookLevin.build_phi_start (dim numSymbols q₀Idx blankIdx : ) (inputIdxs : List ) :

                                          The Cook–Levin sub-formula φ_start: enforces that the first row of the tableau encodes the initial configuration of M on input w — starting state q₀ in the left cell, then the input symbols, padded with blanks.

                                          Instances For
                                            def CookLevin.build_phi_accept (dim numSymbols qAcceptIdx : ) :

                                            The Cook–Levin sub-formula φ_accept: enforces that the accepting state q_accept appears somewhere in the final row of the tableau.

                                            Instances For
                                              def CookLevin.build_phi_move (dim numSymbols : ) (legalWindows : List (List )) :

                                              The Cook–Levin sub-formula φ_move: enforces that every consecutive pair of rows of the tableau differs only in a way consistent with one step of M — encoded by requiring that every 2 × 3 window matches one of the legal windows (determined from the transition function δ).

                                              Instances For
                                                noncomputable def CookLevin.buildTableauFormula {Q Γ : Type} [DecidableEq Q] (M : TuringMachine.NTM Q Γ) (k : ) (w : List Γ) :

                                                The Cook–Levin formula φ_{M,w} = φ_cell ∧ φ_start ∧ φ_move ∧ φ_accept. Given an NTM M, a polynomial-time exponent k, and an input w, this builds a Boolean formula that is satisfiable iff M has an accepting computation on w of length at most (|w|+1)^k.

                                                Instances For

                                                  Correctness of the Cook–Levin formula: buildTableauFormula M k w is satisfiable iff the NTM M accepts the input w. This is the central lemma of the Cook–Levin theorem.

                                                  theorem CookLevin.formula_from_NTM {Q Γ : Type} [DecidableEq Q] (M : TuringMachine.NTM Q Γ) (_k : ) (w : List Γ) :

                                                  For any NTM M and input w there exists a Boolean formula whose satisfiability is equivalent to M accepting w. This is the existential / abstract form of the Cook–Levin construction.

                                                  States of the trivial NTM that decides SATLang by "magically" guessing a satisfying assignment in one step.

                                                  Instances For
                                                    @[implicit_reducible]

                                                    SATState is a finite type.

                                                    An NTM that decides SATLang "nondeterministically in one step": on input [φ], it goes to accept iff φ is satisfiable, otherwise to reject. This witnesses that SAT ∈ NP using the alphabet BoolFormula (one symbol per formula).

                                                    Instances For

                                                      satNTM halts within n + 2 steps on every input of length n.

                                                      theorem CookLevin.satNTM_time_bound :
                                                      TuringMachine.IsBigO (fun (n : ) => n + 2) fun (n : ) => n ^ 1

                                                      The bound n + 2 = O(n^1), used to verify that satNTM runs in polynomial time.

                                                      Existential witness that there is a polynomial-time NTM deciding SATLang, which is what InNP SATLang unfolds to.

                                                      The polynomial-time reduction function used to prove SAT is NP-hard: on input w, output a singleton list containing the Cook–Levin formula φ_{M,w} witnessing that M accepts w iff that formula is satisfiable.

                                                      Instances For

                                                        Correctness of the Cook–Levin reduction: for any NTM M deciding A, the function cookLevinReductionFn M k is a many-one reduction from A to SATLang, i.e. w ∈ A ↔ cookLevinReductionFn M k w ∈ SATLang.

                                                        The Cook–Levin reduction function is polynomial-time computable. The formula φ_{M,w} has size O(n^{2k}), so it can be produced in polynomial time.

                                                        Auxiliary form of "every NP language reduces to SAT": packaging the Cook–Levin reduction function together with its polynomial-time and correctness witnesses.

                                                        SAT is NP-hard: every A ∈ NP polynomial-time reduces to SAT.

                                                        Cook–Levin Theorem: SAT is NP-complete. That is, SAT ∈ NP and every language in NP polynomial-time reduces to SAT.

                                                        Composition of polynomial-time computable functions is polynomial-time computable.

                                                        theorem TuringMachine.PolyReducible.trans {Γ : Type} {A B C : Set (List Γ)} (hAB : PolyReducible A B) (hBC : PolyReducible B C) :

                                                        Transitivity of polynomial-time reducibility: if A ≤_P B and B ≤_P C, then A ≤_P C.

                                                        The 3SAT language presented as singleton-list inputs: [φ] belongs iff φ is a satisfiable 3CNF formula.

                                                        Instances For

                                                          States of the trivial NTM that decides ThreeSATLang by guessing a satisfying assignment in one nondeterministic step.

                                                          Instances For

                                                            An NTM that decides ThreeSATLang in one step: accepts [φ] iff φ is a satisfiable 3CNF formula. Witnesses that 3SAT ∈ NP.

                                                            Instances For

                                                              threeSATNTM halts within n + 2 steps on every input of length n.

                                                              theorem ThreeSATComplete.threeSATNTM_time_bound :
                                                              TuringMachine.IsBigO (fun (n : ) => n + 2) fun (n : ) => n ^ 1

                                                              n + 2 = O(n^1), used to certify threeSATNTM runs in polynomial time.

                                                              Existential witness that ThreeSATLang is decided by a polynomial-time NTM, unfolding the definition of InNP.

                                                              maxVarSucc φ returns one more than the largest variable index appearing in φ (or 0 if no variable occurs). Equivalently, the smallest fresh variable index.

                                                              Instances For

                                                                Build a 3-literal clause l₁ ∨ l₂ ∨ l₃ (right-associated).

                                                                Instances For

                                                                  Core of the Tseitin transformation. Given a formula φ and a fresh-variable counter, produces (rootVar, clauses, fresh') where:

                                                                  • rootVar is a variable whose truth value tracks φ.eval σ under any satisfying assignment of the clauses;
                                                                  • clauses is a list of 3-clauses encoding the gates of φ;
                                                                  • fresh' is the next available fresh variable index. This is the standard linear-size CNF (in fact 3CNF) encoding of an arbitrary Boolean formula introducing one auxiliary variable per subformula.
                                                                  Instances For

                                                                    Conjoin a list of clauses into a single CNF formula (returns a dummy 3-clause if empty, keeping the result a valid 3CNF).

                                                                    Instances For

                                                                      Tseitin transformation: convert any Boolean formula φ into an equisatisfiable 3CNF formula. Returns the conjunction of the clauses generated by tseitinAux together with a clause forcing the root variable to be true.

                                                                      Instances For

                                                                        The reduction function from SATLang to ThreeSATLang: applies the Tseitin transformation to a singleton input [φ].

                                                                        Instances For

                                                                          satTo3SATFn is polynomial-time computable (the Tseitin transformation produces a 3CNF formula of size linear in the size of φ).

                                                                          A literal has clause-length exactly 1.

                                                                          theorem ThreeSATComplete.mk3Clause_isClause {l₁ l₂ l₃ : NPCompleteness.BoolFormula} (h₁ : l₁.IsLiteral) (h₂ : l₂.IsLiteral) (h₃ : l₃.IsLiteral) :
                                                                          (mk3Clause l₁ l₂ l₃).IsClause

                                                                          mk3Clause l₁ l₂ l₃ is a clause whenever the three arguments are literals.

                                                                          theorem ThreeSATComplete.mk3Clause_clauseLength {l₁ l₂ l₃ : NPCompleteness.BoolFormula} (_h₁ : l₁.IsLiteral) (_h₂ : l₂.IsLiteral) (h₃ : l₃.IsLiteral) :
                                                                          (mk3Clause l₁ l₂ l₃).clauseLength = 3

                                                                          mk3Clause l₁ l₂ l₃ has clause-length 3.

                                                                          theorem ThreeSATComplete.mk3Clause_is3Clause {l₁ l₂ l₃ : NPCompleteness.BoolFormula} (h₁ : l₁.IsLiteral) (h₂ : l₂.IsLiteral) (h₃ : l₃.IsLiteral) :
                                                                          (mk3Clause l₁ l₂ l₃).Is3Clause

                                                                          mk3Clause l₁ l₂ l₃ is a 3-clause when given three literals.

                                                                          The negation of a variable is a literal.

                                                                          Every clause generated by tseitinAux is a 3-clause.

                                                                          Any single 3-clause is itself a 3CNF (a CNF with one clause).

                                                                          Conjoining a nonempty list of 3-clauses yields a 3CNF formula.

                                                                          The output of the Tseitin transformation is always a 3CNF formula.

                                                                          The fresh-variable counter is monotone: tseitinAux only allocates new variables above the input fresh.

                                                                          Soundness of the Tseitin auxiliary construction: if σ satisfies all the clauses produced by tseitinAux φ fresh, then σ of the root variable equals the value of φ under σ.

                                                                          The "free-max-var" function: alias of maxVarSucc used in coincidence lemmas. Returns one more than the largest variable index appearing in φ.

                                                                          Instances For

                                                                            Evaluation of c depends only on the values of σ at indices < fmv c.

                                                                            theorem ThreeSATComplete.tseitinAux_root_bound (φ : NPCompleteness.BoolFormula) (fresh : ) (hfr : maxVarSucc φ fresh) :
                                                                            (tseitinAux φ fresh).1 < (tseitinAux φ fresh).2.2

                                                                            The root variable produced by tseitinAux is strictly less than the returned fresh counter, as long as the initial fresh is above all of φ's variables.

                                                                            theorem ThreeSATComplete.tseitinAux_clause_fmv (φ : NPCompleteness.BoolFormula) (fresh : ) (hfr : maxVarSucc φ fresh) (c : NPCompleteness.BoolFormula) :
                                                                            c (tseitinAux φ fresh).2.1fmv c (tseitinAux φ fresh).2.2

                                                                            Every variable occurring in a clause produced by tseitinAux has index strictly less than the returned fresh counter.

                                                                            If σ and σ' agree on all variables below fresh and fresh is above maxVarSucc φ, then they evaluate φ to the same value.

                                                                            theorem ThreeSATComplete.tseitinAux_completeness (φ : NPCompleteness.BoolFormula) (fresh : ) (σ : NPCompleteness.BoolAssignment) (hfr : maxVarSucc φ fresh) :
                                                                            ∃ (σ' : NPCompleteness.BoolAssignment), (∀ n < fresh, σ' n = σ n) σ' (tseitinAux φ fresh).1 = NPCompleteness.BoolFormula.eval σ φ c(tseitinAux φ fresh).2.1, NPCompleteness.BoolFormula.eval σ' c = true

                                                                            Completeness of the Tseitin auxiliary construction: given any assignment σ to the original variables of φ, there is an extension σ' that (1) agrees with σ on the original variables, (2) sends the root variable to φ.eval σ, and (3) satisfies every clause produced by tseitinAux φ fresh.

                                                                            Equisatisfiability of the Tseitin transformation: φ is satisfiable iff tseitinTransform φ is satisfiable.

                                                                            3SAT is NP-hard. The proof reduces any A ∈ NP to SAT (Cook–Levin), then SAT to 3SAT (Tseitin), and concludes by transitivity of ≤_P.

                                                                            structure HamiltonianPath.DiGraph (V : Type u_1) :
                                                                            Type u_1

                                                                            A directed graph on vertex type V, given by an edge relation edge : V → V → Prop.

                                                                            • edge : VVProp
                                                                            Instances For
                                                                              def HamiltonianPath.DiGraph.IsHamiltonianPath (V : Type u_1) [DecidableEq V] [Fintype V] (G : DiGraph V) (s t : V) (p : List V) :

                                                                              p is a Hamiltonian path from s to t in the directed graph G if it starts at s, ends at t, every consecutive pair of vertices is connected by an edge of G, the vertices in p are pairwise distinct (Nodup), and every vertex of V appears in p.

                                                                              Instances For

                                                                                G has a Hamiltonian path from s to t if some list p is one.

                                                                                Instances For

                                                                                  HAMPATH = { (G, s, t) | G has a Hamiltonian path from s to t }.

                                                                                  Instances For

                                                                                    Concrete one-symbol encoding of a HAMPATH instance: number of vertices n, the edge relation, and the source/target vertices s, t ∈ Fin n.

                                                                                    Instances For

                                                                                      Number of vertices n in the graph encoded by a HampathSymbol.

                                                                                      Instances For

                                                                                        The underlying directed graph on Fin (numVertices sym) encoded by a HampathSymbol.

                                                                                        Instances For

                                                                                          Source vertex s of the encoded HAMPATH instance.

                                                                                          Instances For

                                                                                            Target vertex t of the encoded HAMPATH instance.

                                                                                            Instances For

                                                                                              The encoded instance is a YES instance of HAMPATH iff its graph has a Hamiltonian path from source to target.

                                                                                              Instances For

                                                                                                HampathLang is the language of one-symbol-encoded YES instances of HAMPATH.

                                                                                                Instances For

                                                                                                  States of the trivial NTM that decides HampathLang by checking the "yes-instance" predicate of the input symbol in a single step.

                                                                                                  Instances For
                                                                                                    @[implicit_reducible]

                                                                                                    HampathState is a finite type.

                                                                                                    An NTM that decides HampathLang in one step: accepts iff the (nonblank) input symbol encodes a YES instance of HAMPATH.

                                                                                                    Instances For

                                                                                                      hampathNTM halts within n + 2 steps on every input of length n.

                                                                                                      theorem HamiltonianPath.hampathNTM_time_bound :
                                                                                                      TuringMachine.IsBigO (fun (n : ) => n + 2) fun (n : ) => n ^ 2

                                                                                                      The bound n + 2 = O(n^2), used to certify that hampathNTM runs in polynomial time with exponent 2.

                                                                                                      Existential witness that there is a polynomial-time NTM deciding HampathLang.

                                                                                                      For any 3CNF formula φ, there exists a HampathSymbol (i.e. a graph + source + target) such that φ is satisfiable iff this HAMPATH instance is a YES instance. This is the existential, abstract form of the classical 3SAT ≤_P HAMPATH reduction.

                                                                                                      Reduction function used to prove HAMPATH is NP-hard: given an NTM M deciding A in time n^k, on input w it produces a singleton [sym] where sym is a HAMPATH instance equivalent (via the chain Cook–Levin SAT formula → Tseitin 3CNF → 3SAT-to-HAMPATH gadget) to "M accepts w".

                                                                                                      Instances For

                                                                                                        Correctness of the HAMPATH reduction: w ∈ A ↔ hampathReductionFn M k w ∈ HampathLang, combining Cook–Levin, Tseitin, and the 3SAT → HAMPATH gadget.

                                                                                                        The HAMPATH reduction function is polynomial-time computable.

                                                                                                        theorem HamiltonianPath.np_hard_HAMPATH_aux (A : Set (List HampathSymbol)) (k : ) (Q' : Type) [DecidableEq Q'] (M : TuringMachine.NTM Q' HampathSymbol) (t' : ) (hdec : M.decides A) (_htime : M.runsInTime t') (_hbigo : TuringMachine.IsBigO t' fun (n : ) => n ^ k) :

                                                                                                        Auxiliary packaging of the HAMPATH reduction: any NP language A is ≤_P HAMPATH via hampathReductionFn.

                                                                                                        HAMPATH is NP-hard: every A ∈ NP polynomial-time reduces to HAMPATH.