Documentation

Complexity.Computability.Machines.Turing.MultiTape.Counting.Guess

Parsimonious binary guessing #

One fixed machine scans its input, choosing and emitting one bit per symbol, then takes a singleton halting instruction. Its occurrence-labelled terminal traces are in bijection with Boolean words of the input length. The final instruction makes no discarded binary choice.

Main definitions #

Main results #

The scanner is used by the parsimonious guess/verify construction in MultiTape.Counting.Verifier and the #P characterization in Classes.SharpP.Characterization. Balanced signed routing in Classes.SharpP.GapMachine gives the reverse GapP construction and characterization.

References #

The witness-guessing construction is standard in counting complexity [Val79b]. The scanner and its configuration invariant adapt MultiTape.Probabilistic.Sampling, credited there to the cslib crypto branch at 5ff69ca93402e7c947208dc56396d6d86203ccd8. Here the List choice interface and the singleton halt preserve exact branch multiplicity, rather than only the output law.

The ordinary instruction for one guessed bit.

Instances For

    The final instruction emits nothing and halts without moving the input head.

    Instances For

      Emit one independently chosen bit per input symbol, then take a single halting occurrence.

      Instances For

        Every scanner local view has two bit occurrences or one final halt occurrence.

        def Turing.MultiTapeCTM.GuessMachine.config (input : List Bool) (state : Option Unit) (index : ℕ) (output : List Bool) (h : index ≤ input.length) :
        Cfg 0 Bool Unit input

        The scanner at a position in the input, with its current output prefix.

        Instances For

          Each bit selects its occurrence index; the last zero selects the singleton halt.

          Instances For
            @[simp]
            theorem Turing.MultiTapeCTM.GuessMachine.trace_cons (bit : Bool) (word : List Bool) :
            trace (bit :: word) = bit.toNat :: trace word
            theorem Turing.MultiTapeCTM.GuessMachine.step?_inner {input output : List Bool} {index : ℕ} (h : index < input.length) (choice : ℕ) :
            guessMachine.step? (config input (some ()) index output ⋯) choice = if choice < 2 then some (config input (some ()) (index + 1) (output ++ [choice == 1]) h) else none
            theorem Turing.MultiTapeCTM.GuessMachine.step?_boundary (input output : List Bool) (choice : ℕ) :
            guessMachine.step? (config input (some ()) input.length output ⋯) choice = if choice = 0 then some (config input none input.length output ⋯) else none
            theorem Turing.MultiTapeCTM.GuessMachine.runBranch_bits (input output word : List Bool) (index : ℕ) (h : index + word.length ≤ input.length) :
            guessMachine.runBranch (config input (some ()) index output ⋯) (List.map Bool.toNat word) = some (config input (some ()) (index + word.length) (output ++ word) h)

            Replaying the bit choices writes that word, without taking the final halting instruction.

            theorem Turing.MultiTapeCTM.GuessMachine.runBranch_trace (input output word : List Bool) (index : ℕ) (h : index + word.length = input.length) :
            guessMachine.runBranch (config input (some ()) index output ⋯) (trace word) = some (config input none input.length (output ++ word) ⋯)

            A word of the remaining length ends at its output and the right boundary.

            Starting from blank tapes is the zero-position scanner invariant.

            Every branch halts in n + 1 transitions, with a nonempty choice list at every live node.

            theorem Turing.MultiTapeCTM.GuessMachine.runBranch_halted_iff (input : List Bool) (choices : List ℕ) (final : Cfg 0 Bool Unit input) :
            guessMachine.runBranch (Cfg.init guessMachine.initial input) choices = some final ∧ final.Halted ↔ ∃ (word : List Bool), word.length = input.length ∧ choices = trace word ∧ final = config input none input.length word ⋯

            Soundness and completeness of terminal replay, including its exact output.

            theorem Turing.MultiTapeCTM.GuessMachine.length_of_terminal {input : List Bool} {choices : List ℕ} {final : Cfg 0 Bool Unit input} (hrun : guessMachine.runBranch (Cfg.init guessMachine.initial input) choices = some final) (hhalt : final.Halted) :
            choices.length = input.length + 1

            Every terminal branch has exactly one instruction per input symbol and one final halt.

            theorem Turing.MultiTapeCTM.GuessMachine.mem_branches_iff (input : List Bool) (fuel : ℕ) (choices : List ℕ) :
            choices ∈ guessMachine.branches fuel (Cfg.init guessMachine.initial input) ↔ input.length + 1 ≤ fuel ∧ ∃ (word : List Bool), word.length = input.length ∧ choices = trace word

            The bounded terminal traces are exactly the encoded witnesses, with the exact clock exposed.

            Witness words and first-halting occurrence traces are in bijection.

            The same bijection, enumerated by the existing fixed-width bit-string type.

            There are exactly 2 ^ n terminal branches, including one when the input is empty.

            theorem Turing.MultiTapeCTM.GuessMachine.branchCount_eq (input : List Bool) (verdict : List Bool → Bool) :
            guessMachine.branchCount verdict (input.length + 1) (Cfg.init guessMachine.initial input) = {word : Cslib.BitString input.length | verdict (List.ofFn word) = true}.card

            Counting any output predicate is exactly counting witnesses satisfying that predicate.

            List interpretation of the shared program returns each word once, in scanner enumeration order. The existing bit-string enumeration can use a different order, so the result is a permutation.

            The shared FreeM program generates each word of the input length with multiplicity one.