Documentation

Complexitylib.Classes.Containments.Internal.NLSearchAssemble

Running the search to saturation #

⚠️ Unreviewed by Bolton

The search is run for as many steps as there are configurations. Each step advances the counter by one, so after that many steps the counter has passed every record — there are at most as many records as configurations — and the search is complete.

Main definitions #

Main results #

Rulers of polynomial length #

A ruler whose length is a polynomial in the input length.

Equations
Instances For
    theorem Complexity.polyRulerFn_mem_FP (q : Polynomial ) {a : List BoolList Bool} (ha : a FP) :
    (fun (z : List Bool) => polyRuler q (a z)) FP

    The block ruler of a polynomial window.

    The state after n steps #

    noncomputable def Complexity.searchState {k : } (tm : NTM k) (R V₀ : List Bool) (n : ) :

    The unpacked search state after n steps.

    Equations
    Instances For
      theorem Complexity.searchState_counter {k : } (tm : NTM k) (R V₀ : List Bool) (n : ) :
      (searchState tm R V₀ n).1.length = n

      The counter counts the steps.

      theorem Complexity.searchState_ok {k : } (tm : NTM k) {L : Language} {S : } (hdec : tm.DecidesInSpace L S) (x : List Bool) (W : ) (hq : Fintype.card tm.Q Cobham.blockWidth W) (hW : x.length + S x.length + 1 W) (n : ) :

      The invariant holds throughout the run.

      theorem Complexity.searchState_complete {k : } (tm : NTM k) {L : Language} {S : } (hdec : tm.DecidesInSpace L S) (x : List Bool) (W : ) (hq : Fintype.card tm.Q Cobham.blockWidth W) (hW : x.length + S x.length + 1 W) (n : ) (hn : Fintype.card (Code tm.Q k x.length (S x.length)) n) {c : Cfg k tm.Q} (hc : tm.ReachesCfg (tm.initCfg x) c) :

      A long enough run finds every reachable configuration.

      What the accept scan on the finished search decides #

      theorem Complexity.acceptScan_sound {k : } (tm : NTM k) {L : Language} {S : } (hdec : tm.DecidesInSpace L S) (x : List Bool) (W : ) (hq : Fintype.card tm.Q Cobham.blockWidth W) (hW : x.length + S x.length + 1 W) (hW1 : 1 W) (n : ) (ruler : List Bool) (hruler : W ruler.length) (h : acceptScan k (Cobham.stateCode tm.qhalt) (Cobham.blockRuler W) ruler (searchState tm (Cobham.blockRuler W) (Cobham.cfgCode W (tm.initCfg x)) n).2 = [true]) :
      ∃ (c : Cfg k tm.Q), tm.ReachesCfg (tm.initCfg x) c tm.halted c c.output.cells 1 = Γ.one

      The scan fires only on a genuinely accepting configuration.

      theorem Complexity.acceptScan_complete {k : } (tm : NTM k) {L : Language} {S : } (hdec : tm.DecidesInSpace L S) (x : List Bool) (W : ) (hq : Fintype.card tm.Q Cobham.blockWidth W) (hW : x.length + S x.length + 1 W) (hW1 : 1 W) (n : ) (hn : Fintype.card (Code tm.Q k x.length (S x.length)) n) (ruler : List Bool) (hruler : W ruler.length) {c : Cfg k tm.Q} (hc : tm.ReachesCfg (tm.initCfg x) c) (hhalt : tm.halted c) (hout : c.output.cells 1 = Γ.one) :

      The scan fires whenever an accepting configuration is reachable.

      The search as one polynomial-time function #

      noncomputable def Complexity.initRecord {k : } (tm : NTM k) (R x : List Bool) :

      The initial record, built straight from the input.

      Equations
      Instances For
        theorem Complexity.initRecord_eq {k : } (tm : NTM k) (W : ) (x : List Bool) (hx : x.length W) :
        theorem Complexity.initRecordFn_mem_FP {k : } (tm : NTM k) {a b : List BoolList Bool} (ha : a FP) (hb : b FP) :
        (fun (z : List Bool) => initRecord tm (a z) (b z)) FP
        noncomputable def Complexity.searchRun {k : } (tm : NTM k) (R V₀ ruler : List Bool) :

        The packed search, one step per bit of the ruler.

        Equations
        Instances For
          theorem Complexity.searchRun_eq {k : } (tm : NTM k) (R V₀ ruler : List Bool) :
          searchRun tm R V₀ ruler = searchPack R (searchState tm R V₀ ruler.length).1 (searchState tm R V₀ ruler.length).2
          noncomputable def Complexity.searchVisited {k : } (tm : NTM k) (R V₀ ruler : List Bool) :

          The visited string a search leaves behind.

          Equations
          Instances For
            theorem Complexity.searchVisited_eq {k : } (tm : NTM k) (R V₀ ruler : List Bool) :
            searchVisited tm R V₀ ruler = (searchState tm R V₀ ruler.length).2
            theorem Complexity.searchVisitedFn_mem_FP {k : } (tm : NTM k) {Rf V₀f rulerf widthf : List BoolList Bool} (hR : Rf FP) (hV₀ : V₀f FP) (hruler : rulerf FP) (hwidth : widthf FP) (hbound : ∀ (x : List Bool), n(rulerf x).length, ((searchStep tm (codeBlocks k))^[n] (searchPack (Rf x) [] (V₀f x))).length (widthf x).length) :
            (fun (x : List Bool) => searchVisited tm (Rf x) (V₀f x) (rulerf x)) FP

            The search is polynomial-time, given a polynomial bound on its state.

            The verdict #

            noncomputable def Complexity.nlVerdict {k : } (tm : NTM k) (qp np : Polynomial ) (x : List Bool) :

            The whole decision: search the configuration graph, then scan the visited string for an accepting record.

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For
              theorem Complexity.nlVerdict_flag {k : } (tm : NTM k) (qp np : Polynomial ) (x : List Bool) :
              nlVerdict tm qp np x = [true] nlVerdict tm qp np x = [false]

              The verdict is a flag.

              theorem Complexity.nlVerdict_eq_true_iff {k : } (tm : NTM k) {L : Language} {S : } (hdec : tm.DecidesInSpace L S) (qp np : Polynomial ) (hqp : ∀ (n : ), n + S n + 1 Polynomial.eval n qp) (hcardq : ∀ (n : ), Fintype.card tm.Q Cobham.blockWidth (Polynomial.eval n qp)) (hnp : ∀ (n : ), Fintype.card (Code tm.Q k n (S n)) Polynomial.eval n np) (x : List Bool) :
              nlVerdict tm qp np x = [true] x L

              The verdict decides the language.

              theorem Complexity.nlVerdictFn_mem_FP {k : } (tm : NTM k) {L : Language} {S : } (hdec : tm.DecidesInSpace L S) (qp np wp : Polynomial ) (hqp : ∀ (n : ), n + S n + 1 Polynomial.eval n qp) (hcardq : ∀ (n : ), Fintype.card tm.Q Cobham.blockWidth (Polynomial.eval n qp)) (hnp : ∀ (n : ), Fintype.card (Code tm.Q k n (S n)) Polynomial.eval n np) (hwp : ∀ (n : ), 2 * (2 * Polynomial.eval n qp + 2) + 2 * Polynomial.eval n np + Polynomial.eval n np * recordWidth k (Polynomial.eval n qp) + 4 Polynomial.eval n wp) :
              (fun (x : List Bool) => nlVerdict tm qp np x) FP

              The verdict is polynomial-time.

              The containment #

              NL ⊆ P. A log-space nondeterministic machine's configuration graph has polynomially many nodes, and the worklist search above walks all of it in polynomial time.