Arithmetic in the ambient model: increment, unary conversion, multiplication, polynomials #
The arithmetic the wrapper decider (Halting/Wrapper.lean) and the compressor's decider
(Halting/Compressor.lean) need, each with its cost:
Prog.incProg: the successor of a canonical binary numeral (Data.inc, withData.inc_bits : inc n.bits = (n + 1).bits), used to enumerate the bit queries;Prog.toUnaryProg: a binary numeral to unary (encode n ↦ ofNat n), by the foldk ↦ 2k + bover the bits from the most significant one, doubling the unary accumulator withrevOntoProg;Prog.mulProg: multiplication of unary numerals, by repeatedaddProg;Prog.polyProg cs: the Horner evaluationc₀ + m (c₁ + m (…))of a polynomial given by its coefficient list, on a unary input;hornerCoeffsandData.polyEval_hornerCoeffsconnect it toPolynomial.eval, so that the wrapper can compute the paper'spoly(n, λ)bounds.
Costs are polynomial in the values (the unary numerals are as long as the values); the
polynomial evaluation is bounded by an explicit Polynomial ℕ in the argument
(Prog.polyProg_runs), which is what the time accounting downstream composes.
The successor of a binary numeral #
The successor of a binary numeral, least significant bit first.
Equations
Instances For
The first phase of the increment: (rest, acc) ↦ (acc', rest') with
acc'.reverse ++ rest' = acc.reverse ++ inc rest.
Equations
Instances For
Binary to unary #
The fold k ↦ 2k + b over bits, most significant first.
Equations
- MIPRE.Cost.Data.msbFold [] x✝ = x✝
- MIPRE.Cost.Data.msbFold (b :: r) x✝ = MIPRE.Cost.Data.msbFold r (2 * x✝ + b.toNat)
Instances For
Polynomials by their coefficients #
Horner evaluation of a coefficient list: polyEval [c₀, c₁, …] m = c₀ + m (c₁ + m (…)).
Equations
- MIPRE.Cost.Data.polyEval [] x✝ = 0
- MIPRE.Cost.Data.polyEval (c :: cs) x✝ = c + x✝ * MIPRE.Cost.Data.polyEval cs x✝
Instances For
The coefficient list of a polynomial over ℕ, least significant first and padded to
natDegree + 1 entries: the form Horner evaluation consumes (Data.polyEval). Mathlib's
Polynomial.coeffList is the big-endian list without the padding.
Equations
- MIPRE.Cost.hornerCoeffs p = List.map (⇑p.coeff) (List.range (p.natDegree + 1))
Instances For
Close a cost bound after the run has been built: unfold the sizes of the small constants
and of unary numerals, and let omega finish.
Equations
- MIPRE.Cost.Prog.tacticCost_omega' = Lean.ParserDescr.node `MIPRE.Cost.Prog.tacticCost_omega' 1024 (Lean.ParserDescr.nonReservedSymbol "cost_omega'" false)
Instances For
The increment program #
Body of the first phase of incProg, on the state cons rest acc: at the end or at a
false bit, stop with (true :: acc, rest); at a true bit, move a false onto acc.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Binary to unary #
Body of toUnaryProg, on the state cons rest acc (rest the remaining bits, most
significant first; acc a unary numeral): double acc and add the next bit.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The doubling of a unary numeral by revOntoProg.
The unary fold over the bits, most significant first: from (rest, ofNat k) to
ofNat (msbFold rest k), in time (|rest| + 1) · B for B a bound depending on the final
value N = msbFold rest k.
Multiplication of unary numerals #
Body of the multiplication loop, on the state cons bRest acc, with the first factor a
one variable further out: at the end stop with acc, otherwise add a to acc.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Polynomials, by Horner's rule #
Horner evaluation of the coefficient list cs on a unary input m:
polyProg (c :: cs) computes c + m · polyProg cs.
Equations
- One or more equations did not get rendered due to their size.
- MIPRE.Cost.Prog.polyProg [] = MIPRE.Cost.Prog.nil
Instances For
polyProg cs evaluates the polynomial, within a cost polynomial in the argument.
Evaluating a fixed polynomial, primitively recursively #
The answer-length budget of the tabulation is bound.eval (n + λ) for the fixed polynomial
bound of MIPRE.GapCompression, so MIPRE.Halting.tab_computable needs a polynomial's
evaluation to be primitive recursive in its argument. It goes through this file's own
Data.polyEval and hornerCoeffs rather than Mathlib's Polynomial API: the coefficient
list is fixed data, and Horner's rule on a fixed list is a fixed composition of + and *.