Binary addition and comparison inside the polynomial-time algebra #
⚠️ Unreviewed by Bolton
Complexitylib.Classes.Containments.Internal.SavitchBits builds a fixed-width counter in the
algebra — increment and overflow. A search that accumulates counts needs more: to add two numbers
and to compare them. Both are the same shape of computation, a single left-to-right scan over the
two operands, and both are written twice here for the same reason the counter was: as a plain
recursion, where the arithmetic is proved, and as a scan on a packed state, which is the shape
Cobham.iterate_mem_FP iterates.
Numbers are little-endian, least significant bit first, and the two operands are the same width. Addition returns the carry out separately, so nothing is lost to wraparound.
Main definitions #
Complexity.addBitsLE— addition with carry, as a recursionComplexity.addBits,Complexity.addCarry— its two componentsComplexity.ltBitsLE,Complexity.ltFlag— comparisonComplexity.strsOfLen,Complexity.strsLe— the strings of a given length, and up to itComplexity.nextStr,Complexity.strIdx— one counter enumerating every short string
Main results #
Complexity.addBitsLE_binValLE— the adder is correctComplexity.ltFlag_eq_true_iff— the comparator is correctComplexity.addBitsFn_mem_FP,Complexity.ltFlagFn_mem_FP— both are inFPComplexity.strsLe_eq_image— the enumeration hits every short string exactly once
The bit operations #
Exclusive or of two flags.
Equations
Instances For
The carry out, on flags.
Equations
- Complexity.majBit x y z = Complexity.orBit (Complexity.andBit x y) (Complexity.orBit (Complexity.andBit x z) (Complexity.andBit y z))
Instances For
The sum bit, on flags.
Equations
- Complexity.sumBit x y z = Complexity.xorBit (Complexity.xorBit x y) z
Instances For
Addition as a recursion #
Add two little-endian bitstrings with a carry in: the carry out and the sum bits. The
second operand is read through headD/drop, so the two are stepped in lockstep.
Equations
Instances For
Addition as a scan #
One step of the addition scan: the carry, the bits emitted so far, and the two operands still to read.
Equations
Instances For
The scan never has more in hand than it started with.
The packed scan #
The packed scan state.
Equations
- Complexity.addPack c acc ru rv = Complexity.pair c (Complexity.pair acc (Complexity.pair ru rv))
Instances For
The verdicts #
The packed addition run to completion.
Equations
Instances For
The sum bits of u and v.
Equations
Instances For
The carry out of u + v.
Equations
Instances For
Addition is polynomial-time #
Comparison as a recursion #
Scan two little-endian bitstrings from the bottom, keeping the verdict of the highest position at which they have differed so far.
Equations
Instances For
Comparison as a scan #
One step of the comparison scan.
Equations
Instances For
The packed comparison #
The packed comparison state.
Equations
- Complexity.ltPack f ru rv = Complexity.pair f (Complexity.pair ru rv)
Instances For
The packed comparison run to completion.
Equations
Instances For
Is u below v, as a flag.
Equations
- Complexity.ltFlag u v = Complexity.pairFst (Complexity.ltRun u v)
Instances For
Comparison is polynomial-time #
The larger of two numbers #
The larger of two equal-width numbers.
Equations
- Complexity.maxBits u v = Complexity.Cobham.selectHead (Complexity.ltFlag u v) v u
Instances For
Arithmetic without overflow #
Powers of two as bitstrings #
The bitstring of 2 ^ t, one bit wider than t bits so that it can be compared with a
doubled t + 1-bit count.
Equations
Instances For
Selection on a literal flag #
Emptiness and the leading bit #
Is the string empty, as a flag.
Equations
Instances For
The strings of a given length #
The bitstrings of length exactly ℓ.
Equations
- Complexity.strsOfLen ℓ = Finset.image (Complexity.bitsOfLenLE ℓ) (Finset.range (2 ^ ℓ))
Instances For
The bitstrings of length at most m.
Equations
- Complexity.strsLe m = (Finset.range (m + 1)).biUnion Complexity.strsOfLen
Instances For
Enumerating every short string with one counter #
A search that sums over all strings of length at most m must visit each exactly once. One
counter suffices: order the strings by length and then by value, so the successor of the
all-ones string of length ℓ is the all-zeros string of length ℓ + 1. The position of a string
in that order is Complexity.strIdx, and it increases by one at every step, which is what makes
the enumeration a bijection.
The position of a string in the order: by length first, then by value.
Equations
- Complexity.strIdx w = 2 ^ w.length - 1 + Complexity.binValLE w
Instances For
The next string in the order.
Equations
Instances For
The counter enumerates the strings of one length too, starting from the zeros.