Bounds on the number of reachable configurations in bounded space #
A multi-tape Turing machine that uses at most s cells of work-tape space can only reach a number
of configurations that differ in their storage content (state and work tapes) that is bounded
exponentially in s. Together with the n + 2 possible positions of the input head this bounds
the number of configurations the machine can be in, disregarding the write-only output tape.
Important Definitions #
The results are layered, from the purely combinatorial to the machine-specific:
MultiTapeTM.encard_fitsIn_leis a counting statement about the typeStoragealone and does not mention Turing machines: a memory whose non-blank cells and heads stay within per-tape windows of total sizescan hold at moststorageBound Symbol State k sdifferent values.MultiTapeTM.storage_fitsInis the geometric input: the storage reached aftertsteps stays within the windows given by the space used up to stept.MultiTapeTM.encard_storages_lecombines the two: a machine bounded by spacespasses through at moststorageBound Symbol State k sstorages during its whole run, no matter how long it runs and how long its input is. This is the form needed for arguments below logarithmic space, where the number of storages is much smaller than the number of input head positions.MultiTapeTM.encard_cores_leadds the input head position, giving the bound(n + 2) * storageBound Symbol State k son the number of reachable cores (Cfg.core, a configuration without its output tape) for an input of lengthn.MultiTapeTM.storageBound_le_base_mul_powrestatesstorageBound Symbol State k sasstorageBoundBase Symbol State k * 2 ^ (storageBoundExp Symbol k * s), so that the bounds can be used to time-bound space-bounded machines.
Design #
The write-only output tape is never read by step, so it can be dropped: what a machine can still
react to is its Cfg.core, the pair of the input head position and the Storage. The input head
position, in contrast, is read, so it cannot be dropped and has to be counted, which is where
the factor n + 2 comes from (the input head may move one step off the input in either direction).
Starting from the all-blank tapes with every head at 0 and moving by at most one cell per step,
a computation in which tape i has visited at most sᵢ cells keeps that tape's head position and
every non-blank cell within the per-tape window [-sᵢ, sᵢ].
Hence a storage is determined by finite data over these windows, and counting it gives the
per-tape product ∏ᵢ (2 sᵢ + 1) · (|Symbol| + 1)^(2 sᵢ + 1). Since the tapes share the total space
budget (∑ᵢ sᵢ ≤ s), this collapses to an expression with the total space (2s + k) as the
alphabet exponent.
We lose a factor of 2 * k by simplifying the windows to [-sᵢ, sᵢ] instead of the actually used
area, but this is absorbed by the O(s) exponent in the final bound.
The windows for a whole run are available because a machine that is space-bounded at every point in
time attains its per-tape space usage at a single step (MultiTapeTM.exists_spaceUsedByTape_max).
Storage #
Defines the core data structure for this file, Storage, which contains the state and the work
tapes of a multi-tape Turing machine, with the work tape cells indexed over all of ℤ. It is
thus equivalent to a projection of Cfg.
Then BoundedStorage is introduced, which restricts the cells and the head position of each tape
to a window [-s, s] (with a different s for each tape) and is therefore a finite type. It is
proven that the restriction map is injective on those Storages whose non-blank cells and head
positions all lie inside the [-s, s] windows, so that counting BoundedStorage bounds the
number of such Storages.
The state and work-tape data of a machine.
- state : Option State
the state of the TM (cf.
Cfg.state) the contents of work tape
i(cf.Cfg.workTapes)the position of the head on work tape
i(cf.Cfg.workTapePos)
Instances For
The window [-s, s] of tape positions allotted to a tape that uses s cells.
Equations
- Turing.window s = Finset.Icc (-↑s) ↑s
Instances For
A bounded storage: the state and work-tape data of a machine, but with the cells and the head
position of tape i restricted to the finite window [-(w i), w i].
Equations
- Turing.BoundedStorage Symbol State w = (Option State × ((i : Fin k) → ↥(Turing.window (w i)) → Option Symbol) × ((i : Fin k) → ↥(Turing.window (w i))))
Instances For
A storage fits in the per-tape windows w: on each tape j, the head position and every
non-blank cell have absolute value ≤ w j.
the head position on every tape lies within its window
every non-blank cell on every tape lies within its window
Instances For
Restriction of a storage to the finite windows w (with heads outside their window
clamped to 0).
Equations
- One or more equations did not get rendered due to their size.
Instances For
Counting storages #
This section is purely combinatorial: it counts how many values a Storage restricted to given
windows can take, without reference to a machine or a run.
An upper bound on the number of storages a k-tape machine can be in while using
at most s cells of total work-tape space, over the given alphabet and state set. The (2s + 1)^k
factor counts the possible head positions; the dominant factor (|Symbol| + 1)^(2s + k) uses the
total space s in the exponent (the k tapes share the space budget).
Equations
- Turing.storageBound Symbol State k s = (Fintype.card State + 1) * ((2 * s + 1) ^ k * (Fintype.card Symbol + 1) ^ (2 * s + k))
Instances For
The number of bounded storages is at most storageBound. Counting the tapes separately gives
the per-tape product ∏ᵢ (2 wᵢ + 1) · (|Symbol| + 1) ^ (2 wᵢ + 1); each tape uses at most the
total space s, and the tapes together use at most s, which collapses the alphabet exponent
to 2s + k.
The counting result at the heart of this file: a Storage whose non-blank cells and head
positions stay within per-tape windows of total size at most s can take at most
storageBound Symbol State k s different values.
The exponential form of storageBound #
This proves that storageBound is exponential in the space s.
The base factor in the resulting exponential form of storageBound.
Equations
- Turing.storageBoundBase Symbol State k = (Fintype.card State + 1) * 2 ^ ((Fintype.card Symbol + 1) * k + k)
Instances For
The factor in the exponent of the exponential form of storageBound.
Equations
- Turing.storageBoundExp Symbol k = 2 * (Fintype.card Symbol + 1) + k
Instances For
storageBound grows at most exponentially in the space s, with a constant factor and a
factor in the exponent that only depend on the machine's alphabet, state set and tape count.
storageBound grows at most exponentially in the space s: there exist constants a and c
(depending on the machine's alphabet, state set and tape count) with
storageBound Symbol State k s ≤ a * 2 ^ (c * s) for all s.
The storage and the core of a configuration #
Now we relate Cfg and Storage by giving the projection.
The part of a configuration that the machine can still read: the input head position together
with the Storage, i.e. the configuration without the write-only output tape.
Instances For
step never reads the output tape, so the core of the next configuration is determined by the
core of the current one.
The storages and cores of a space-bounded run #
These are the main results giving upper bounds on the number of storages and configuration cores reachable in bounded space.
The storage reached after t steps fits in the windows given by the per-tape space usage up
to step t.
A machine that uses at most s cells of work-tape space at every point in time passes through
at most storageBound Symbol State k s different storages during its whole run — independently of
the length of the input and of how long it runs.
The number of configuration cores that a machine bounded by space s can reach is at most
(n + 2) * storageBound Symbol State k s, where n is the length of the input.
The storage bound in exponential form: the number of storages a space-s-bounded machine
passes through is at most 2 ^ (O(s)), with constants depending only on the machine.
The core bound in exponential form: the number of cores a space-s-bounded machine can reach
is at most (n + 2) * 2 ^ (O(s)), with constants depending only on the machine and not on the
input.