Every branch of a nondeterministic counter program #
A nondeterministic counter program (Turing.CounterProgram.toNondeterministicQueryMachine)
writes a fresh choice bit into register 0 after every step. Its correctness is proved branch
by branch with the inductive predicate Turing.CounterProgram.AllBranches: every branch from a
configuration reaches a configuration satisfying Q, or halts in one satisfying Post, and
passes only through configurations whose registers are at most B. These predicates compose
(Turing.CounterProgram.AllBranches.bind), and every branch of a program satisfying one from
its initial configuration with Q empty halts within a common number of steps, keeps its
registers bounded and halts only in configurations satisfying Post
(Turing.CounterProgram.AllBranches.exists_haltsWithin,
Turing.CounterProgram.AllBranches.replay).
Most of a program is deterministic: its instructions do not mention register 0
(Turing.CounterProgram.Instr.readsChoice). On such code every branch follows the
deterministic run up to register 0, so the deterministic reachability of counter programs
(Turing.CounterProgram.Reaches) gives both every branch
(Turing.CounterProgram.allBranches_of_reaches) and one branch
(Turing.CounterProgram.branches_of_reaches).
Main definitions #
Turing.CounterProgram.Expr.readsChoice,Turing.CounterProgram.Instr.readsChoice: whether an expression or an instruction mentions register0.Turing.CounterProgram.AllBranches: every branch reaches a target or halts.
Main results #
Turing.CounterProgram.AllBranches.bind: sequential composition.Turing.CounterProgram.AllBranches.exists_haltsWithin,Turing.CounterProgram.AllBranches.replay: the consequences for every branch from the initial configuration.Turing.CounterProgram.allBranches_of_reaches,Turing.CounterProgram.branches_of_reaches: deterministic code that does not read register0.Turing.CounterProgram.exists_decidesInLogSpace_of_allBranches: deciding in logarithmic space from every branch and one accepting branch.
Code that does not read the choice #
Whether an expression mentions register 0, the choice.
Instances For
Whether an instruction reads or writes register 0, the choice.
Instances For
A step that does not read the choice commutes with it: overwriting register 0 before
the step overwrites it after the step.
Every branch #
P.AllBranches w B Post Q s: every branch from s reaches a configuration satisfying Q, or
halts in a configuration satisfying Post, and the configurations before are running ones with
registers at most B.
- exit {P : CounterProgram} {w : List Bool} {B : ℕ} {Post Q : Config → Prop} {s : Config} : Q s → P.AllBranches w B Post Q s
A target is reached.
- halt {P : CounterProgram} {w : List Bool} {B : ℕ} {Post Q : Config → Prop} {s : Config} : P.halted s = true → Post s → (∀ r ∈ s.2, r ≤ B) → P.AllBranches w B Post Q s
A halt satisfying
Post. - step {P : CounterProgram} {w : List Bool} {B : ℕ} {Post Q : Config → Prop} {s : Config} : P.halted s = false →
(∀ r ∈ s.2, r ≤ B) →
(∀ (choice : Bool), P.AllBranches w B Post Q (withChoice (P.step w s) choice)) → P.AllBranches w B Post Q s
A step from a running configuration, with either choice.
Instances For
Sequential composition: continuing from every target.
One step from a running configuration, whatever the choice.
Every branch halts within a common number of steps, for a program with no target.
Every branch keeps its registers bounded and halts only where Post holds, for a program
with no target.
Deterministic code #
Every branch through deterministic code that does not read register 0 follows the
deterministic run, whatever the choice before it.
One branch through deterministic code that does not read register 0: the
deterministic run from s to s', ending with any choice c' when s ≠ s' and with the
initial choice c when s = s'.
Steps of code that does not read the choice #
Running configurations, with registers at most B, at instructions that do not read the
choice.
Instances For
Every branch through oblivious deterministic code.
One branch through oblivious deterministic code.
Deciding in logarithmic space #
A nondeterministic counter program decides in logarithmic space a problem when, on every
encoded instance, every branch from the initial configuration halts with registers at most
(n + 1) ^ d and accepts only instances of the problem, and some branch reaches the accepting
halt on every instance of the problem.