Cost measures for random-access machines #
A cost measure charges each instruction, executed on given register contents, an amount of time, and the time of a run is the total charge of the instructions it executes. Two measures are standard Cook and Reckhow, Section 1:
- the unit cost measure charges every instruction
1, so that time counts steps; - the logarithmic cost measure charges every instruction the lengths of the numbers it reads, so that time accounts for the size of the numbers in the registers.
Within logarithmic time T a RAM never holds a number longer than T or than the longest number
it starts with (Cslib.RAM.bitLength_read_run_le), whereas within unit time 4 k + 5 a fixed
program builds from k a number with 2 ^ k + 1 binary digits
(Cslib.RAM.computesInTime_unitCost_repeatedSquaring), so that logarithmic time is not bounded by
any polynomial in unit time (Cslib.RAM.exists_mul_pow_lt_of_computesInTime_logCost).
A program computes a function within time T (Cslib.RAM.ComputesInTime) when on every input it
halts with the value of the function in the output register 0 (Cslib.RAM.HaltsWithResult)
after a run of time at most T. The time bound is a function of the input tuple, with no chosen
string encoding or input-length measure. Input loading and output extraction are free. For
example, the empty program returns its first preloaded input in time 0 under either measure.
The bit-length bound above therefore retains the initial-size term: it cannot in general be
replaced by a bound in execution time alone. These costs adapt Cook and Reckhow's conventions;
no Turing-machine simulation or equality of polynomial-time language classes is proved here.
The length of a number is Cslib.RAM.bitLength n = ⌊log₂ n⌋ + 1, its number of binary digits with
0 written as one digit: it is max n.size 1, Mathlib's Nat.size n except at 0
(Cslib.RAM.bitLength_eq_max_size). It is defined through Nat.log, which the kernel evaluates,
so that decide computes costs, and it is the ⌊log₂ n⌋ + 1 of the bounds of
Cslib.polynomiallyBounded_two_pow_mul_log. Cook and Reckhow's logarithmic function l(n) is
⌈log₂ n⌉ for n ≥ 2 and 1 below, so that l(n) ≤ bitLength n ≤ 2 * l(n).
Main definitions #
Cslib.RAM.bitLength: the length of a natural number.Cslib.RAM.unitCost,Cslib.RAM.logCost: the unit and the logarithmic cost measures.Cslib.RAM.stepCost: the cost of the next step of a program.Cslib.RAM.time: the time of a run of a given number of steps.Cslib.RAM.HaltsWithResultInTime,Cslib.RAM.ComputesInTime: halting with a given output, and computing a function, within a time bound.
Main results #
Cslib.RAM.time_add: time is additive along a run.Cslib.RAM.bitLength_eq_max_size: the length of a number ismax n.size 1.Cslib.RAM.time_le_time_of_le,Cslib.RAM.time_mono_cost,Cslib.RAM.time_eq_of_le: time is monotone in the number of steps and in the cost measure, and stationary once halted.Cslib.RAM.time_unitCost: unit time counts the steps taken.Cslib.RAM.time_unitCost_le_time_logCost: unit time is at most logarithmic time.Cslib.RAM.bitLength_read_run_le: the numbers held after a run of logarithmic timeTare no longer thanTor the longest number held at the start.
References #
The length of a number #
The length ⌊log₂ n⌋ + 1 of a natural number n: its number of binary digits, where 0 is
written with one digit. This is the logarithmic cost of storing n
Cook and Reckhow, Section 1. It is max n.size 1
(Cslib.RAM.bitLength_eq_max_size), and is defined through Nat.log so that the kernel
evaluates it.
Instances For
A nonzero number has as many binary digits as its length.
Cost measures and time #
The unit cost measure charges every instruction one unit of time, whatever the size of the numbers it manipulates.
Instances For
The logarithmic cost measure charges every instruction the lengths of the numbers it reads:
its constant, the contents of its operand registers, and, for an indirect operand, both the
address and the contents of the register at that address. This is Cook and Reckhow's measure
Cook and Reckhow, Table I with bitLength for their l, multiplication charged
like addition, and a constant charged its length rather than 1, so that the bound
Cslib.RAM.bitLength_read_run_le does not depend on the program. Register indices written in the
instruction are not charged, since they are bounded by the program. Neither is the number written:
it is never longer than the charge (Cslib.RAM.bitLength_read_exec_le).
Instances For
Unit cost #
Logarithmic cost #
An instruction writes no number longer than its logarithmic cost: if the registers of s hold
numbers of length at most b, then after executing i they hold numbers of length at most the
larger of b and the logarithmic cost of i.
Logarithmic cost bounds the numbers a RAM holds. If the registers of s hold numbers of
length at most b, then after a run of logarithmic time T they hold numbers of length at most
the larger of b and T. This is the fact on which Cook and Reckhow's simulation of RAMs by
Turing machines rests Cook and Reckhow, Section 4, Lemma.
Computing within a time bound #
p halts on inputs with result in the output register 0 within time T under cost:
its run from the initial state is halted after some number of steps, with result in register
0, and takes time at most T until then.
Instances For
p computes the function f of k arguments within time T under cost: on every input
x it halts with f x in the output register 0 within time T x. As for URMs
(Cslib.URM.Computes), the arguments are the inputs in registers 0, …, k - 1.
Initialization and output extraction are uncharged; T is indexed by the input tuple, not by a
specified string-encoding length.
Instances For
A program halting with a result within a time bound halts with that result.
A time bound can be increased.
A cost measure can be decreased.
A time bound can be increased.
A cost measure can be decreased.