Polynomial-time numbers and tests #
Rules for showing that a function to the natural numbers is polynomial-time
(UnaryFn: its value can be written in unary in polynomial time) and that a test
is (FPPred: a polynomial-time function outputs its verdict as one bit), stated
on numbers and propositions rather than on strings.
The rules cover
- the length of a polynomial-time output, constants, and the two halves of a pair, which is how a loop's body reads the loop's input and index;
- addition, multiplication, truncated subtraction, minimum and maximum;
- comparisons, the Boolean connectives, and case distinction on a test;
- loops over the indices below a polynomial-time bound: a sum, a count, the first index at which a test passes, a maximum, and iterating an update whose values stay below a polynomial-time bound;
- division and remainder, capped powers, binary length and logarithms, which are derived from the loops.
A loop's body reads the loop's input z and the index i from the string
pair z (1^i), as in Complexitylib.Classes.P.Range: UnaryFn.lift and
FPPred.lift read a rule on z there, and UnaryFn.index reads i. For
example, z ↦ |z| / 3 is polynomial-time by
(UnaryFn.length id_mem_FP).div (UnaryFn.const 3).
Main results #
UnaryFn.mem_FP,UnaryFn.of_eq,FPPred.of_iff— moving between the rules andFPUnaryFn.length,UnaryFn.const,UnaryFn.lift,UnaryFn.indexUnaryFn.add,UnaryFn.mul,UnaryFn.sub,UnaryFn.min,UnaryFn.maxFPPred.le,FPPred.lt,FPPred.eq,FPPred.and,FPPred.or,FPPred.notFPPred.ite_mem_FP,UnaryFn.ite— case distinctionUnaryFn.sum,UnaryFn.count,UnaryFn.find,UnaryFn.bmax,UnaryFn.iterate— loopsUnaryFn.div,UnaryFn.mod,UnaryFn.powMin,UnaryFn.pow_of_le,UnaryFn.size,UnaryFn.log,UnaryFn.clog
Between numbers and strings #
Lengths, constants and pairs #
Arithmetic #
Comparisons and connectives #
Case distinction #
Loops over a range of indices #
A sum over a range is polynomial-time. If n and the body f are
polynomial-time, then so is the sum of f (pair z (1^i)) over i < n z.
A count over a range is polynomial-time. If n and the test p are
polynomial-time, then so is the number of i < n z such that p holds of
pair z (1^i).
A search over a range is polynomial-time. If n and the test p are
polynomial-time, then so is the least i < n z such that p holds of
pair z (1^i), or n z if there is none.
A maximum over a range is polynomial-time. If n and the body f are
polynomial-time, then so is the largest value of f (pair z (1^i)) over
i < n z, or 0 if n z = 0.
A loop on a number is polynomial-time while its values stay below a
polynomial-time bound. Starting from a z, the loop applies the update
x ↦ s z x k z times; the update reads pair z (1^x), and every value along
the way is at most B z.
Division, powers and logarithms #
A capped power is polynomial-time: min (b z ^ k z) (c z), when b, k
and c are polynomial-time. The cap keeps the value polynomially bounded. (Inside
the UnaryFn namespace a bare min means UnaryFn.min, hence Min.min.)