Documentation

Complexitylib.Classes.Containments.Internal.CodeSearch

The reachability search as a finite computation on codes #

⚠️ Unreviewed by Bolton

Complexitylib.Classes.Containments.Internal.BoundedReach reduces membership to a bounded breadth-first search in the configuration graph, but the rounds there are Set (Cfg k tm.Q) — a specification, not a computation. This file replays the same search on the codes of Complexitylib.Classes.Containments.Internal.ConfigCount: a round is a Finset operation on a finite type, so the whole search is a finite, decidable iteration.

The bridge is a decoder. cfgCode forgets nothing about a configuration that respects the space window, so it has a left inverse there, and the successor of a code is simply the code of the successor of the configuration it denotes.

For a log-space machine the code type has polynomially many elements, so a round set is a polynomially sized object and the search runs for polynomially many rounds — this is the data structure a polynomial-time implementation manipulates.

Main definitions #

Main results #

def Complexity.decodeCfg {k : } {Q : Type} (x : List Bool) (S : ) (a : Code Q k x.length S) :
Cfg k Q

Rebuild a configuration from its code. The input tape is restored from the input itself — it is read-only — and each work and output cell beyond the window is restored to the blank that the window invariant guarantees is there.

Equations
  • One or more equations did not get rendered due to their size.
Instances For
    theorem Complexity.decodeCfg_cfgCode {k : } {Q : Type} {x : List Bool} {S : } {c : Cfg k Q} (hw : Windowed x S c) (hs : c.WithinDecisionSpace x.length S) :
    decodeCfg x S (cfgCode x.length S c) = c

    Decoding inverts coding on the configurations the search meets. Inside the space window the clamps in cfgCode are inert and the cells it drops are the ones Windowed pins down, so nothing is lost.

    def Complexity.NTM.codeSucc {k : } (tm : NTM k) (x : List Bool) (S : ) (a : Code tm.Q k x.length S) :
    Finset (Code tm.Q k x.length S)

    The codes of the successors of the configuration a code denotes.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      def Complexity.NTM.codeRound {k : } (tm : NTM k) (x : List Bool) (S : ) (F : Finset (Code tm.Q k x.length S)) :
      Finset (Code tm.Q k x.length S)

      One round of the search: keep what is known and add every successor code.

      Equations
      Instances For
        def Complexity.NTM.reachCodes {k : } (tm : NTM k) (x : List Bool) (S : ) (a₀ : Code tm.Q k x.length S) :
        Finset (Code tm.Q k x.length S)

        The search: t rounds of successor-closure starting from a single code.

        Equations
        Instances For
          theorem Complexity.NTM.mem_reachCodes_iff {k : } {tm : NTM k} {x : List Bool} {S : } {c₀ : Cfg k tm.Q} (hs : ∀ (c : Cfg k tm.Q), tm.ReachesCfg c₀ cc.WithinDecisionSpace x.length S) (hw : ∀ (c : Cfg k tm.Q), tm.ReachesCfg c₀ cWindowed x S c) (t : ) (a : Code tm.Q k x.length S) :
          a tm.reachCodes x S (cfgCode x.length S c₀) t ctm.reachSet c₀ t, cfgCode x.length S c = a

          The code search computes exactly the specified rounds. Every code in round t is the code of a configuration in round t, and conversely.

          theorem Complexity.NTM.mem_iff_exists_mem_reachCodes {k : } {tm : NTM k} {L : Language} {S : } (hdec : tm.DecidesInSpace L S) (x : List Bool) {N : } (hN : Fintype.card (Code tm.Q k x.length (S x.length)) N) :
          x L atm.reachCodes x (S x.length) (cfgCode x.length (S x.length) (tm.initCfg x)) N, (decodeCfg x (S x.length) a).state = tm.qhalt (decodeCfg x (S x.length) a).output.cells 1 = Γ.one

          Membership is a finite search over codes. Every quantifier is over a finite type and every operation is a Finset operation, so this is an algorithm — what remains for NL ⊆ P is to bound its cost.

          theorem Complexity.logWindow_bigO (C D : ) :
          BigO (logWindow C D) fun (n : ) => Nat.log 2 n

          The concrete window is still a logarithmic bound, so the code count over it stays polynomial.