Nondeterministic counter programs #
A counter program (Turing.CounterProgram) runs nondeterministically when register 0
receives a fresh nondeterministic bit after every step
(Turing.CounterProgram.toNondeterministicQueryMachine): an instruction branches on the bit by
comparing register 0 with 1. The rest of a step is the deterministic one; in particular the
first instruction sees register 0 at 0. A branch accepts when it halts with the final word
[true].
A program that halts on every branch of every encoded input enc a within time a steps, whose
registers stay at most (n + 1) ^ d on every branch, where n is the length of the input,
decides in logarithmic space the problem of the inputs it accepts
(Turing.CounterProgram.exists_decidesInLogSpace): one finite-state nondeterministic machine
decides it within space c * (Nat.log2 n + 1), every branch halting
(Turing.MultiTapeNTM.DecidesInSpace). This is the classical description of nondeterministic
logarithmic-space algorithms, a constant number of polynomially bounded counters and random
read-only access to the input Sipser, Section 8.4. The machine is compiled through
Turing.NondeterministicQueryMachine.exists_decidesInSpace.
Halting on every branch and the register bounds are established together from an invariant and
a rank that every step from a running configuration satisfying the invariant decreases, whatever
the choice (Turing.CounterProgram.haltsWithin_of_rank,
Turing.CounterProgram.forall_run_of_rank). Accepting branches are built step by step
(Turing.CounterProgram.Branches).
Main definitions #
Turing.CounterProgram.withChoice: overwrite register0by a choice bit.Turing.CounterProgram.toNondeterministicQueryMachine: a counter program as a nondeterministic query machine.Turing.CounterProgram.Branches: some branch leads from one configuration to another.
Main results #
Turing.CounterProgram.step_toNondeterministicQueryMachine: a nondeterministic step is a deterministic step followed by a choice.Turing.CounterProgram.haltsWithin_of_rank,Turing.CounterProgram.forall_run_of_rank: halting on every branch and invariants of every branch, from a decreasing rank.Turing.CounterProgram.accepts_of_branches: a branch to the accepting halt accepts.Turing.CounterProgram.exists_decidesInLogSpace: nondeterministic counter programs with polynomially bounded registers decide in logarithmic space.
References #
Overwrite register 0 by the choice bit, 1 for true and 0 for false.
Instances For
A counter program as a nondeterministic query machine: a step is a deterministic step, after
which register 0 receives the choice. A halted branch accepts when its final word is
[true].
Instances For
A nondeterministic step is a deterministic step followed by a choice; halted configurations stay put.
Every branch #
An invariant preserved by every step from a running configuration holds of every configuration on every branch, halted configurations staying put.
An invariant of every branch, from an invariant of the initial configuration preserved by every step from a running configuration.
Every branch halts within the rank of the initial configuration, when every step from a running configuration satisfying an invariant preserves it and decreases the rank, whatever the choice.
Some branch #
Some branch leads from s to s'.
Instances For
One step from a running configuration, with either choice.
A branch to the accepting halt accepts.
An accepting branch ends at a halt with the final word [true].
Logarithmic space #
Nondeterministic counter programs decide in logarithmic space. Let a counter program, run
nondeterministically, halt on every branch on every encoded input enc a within time a steps,
let its registers stay at most (n + 1) ^ d on every branch, where n is the length of the
input, and let it accept exactly the inputs of the instances in A. Then one finite-state
nondeterministic machine decides A within space c * (Nat.log2 n + 1), halting on every
branch.