The closure library, part IV: folds over lists #
The generic iteration combinator of the library, PolyTimeFun.foldl: a fold of a
polynomial-time body over a list is polynomial-time provided the accumulator grows by at
most an additive polynomial in the element at each step (the Cobham condition
esize (F (s, a)) ≤ esize s + B (esize a)), and from it cons, casesList, map, zip,
append, replicate and reverse (planning/succinct-cook-levin.md, S3). Every
combinator's toFun is the corresponding List function, so that a program assembled
from them is defined by its mathematical meaning and only its time bound is inherited.
Lists of an arbitrary encodable type encode as cons-chains of the encodings
(instSizedEncodingList, at low priority so that the existing instances for bit strings
and gate lists are still found first; they agree definitionally).
Lists of encodable values #
Lists encode elementwise, as cons-chains.
Equations
- MIPRE.Cost.instSizedEncodingList = { encode := MIPRE.Cost.Data.ofList MIPRE.Cost.encode, decode := MIPRE.Cost.Data.toList? MIPRE.Cost.decode, decode_encode := ⋯ }
Program layer: the fold loop #
Function layer #
The step function of a fold, as a binary function.
Instances For
The size bound along a fold under the additive Cobham condition: after consuming pre,
the accumulator has size at most esize s₀ + |pre| · B (esize l) whenever the elements of
pre are elements of l.
The Cobham condition for folding F over a list: along the fold of any list l from
any s₀, the accumulator has size at most B (esize (l, s₀)).
Equations
- F.FoldBounded B = ∀ (l : List α) (s₀ : σ) (pre xs : List α), l = pre ++ xs → MIPRE.Cost.esize (List.foldl F.step s₀ pre) ≤ Polynomial.eval (MIPRE.Cost.esize (l, s₀)) B
Instances For
The additive condition — each step grows the accumulator by at most B (esize a) — is a
Cobham condition with the bound X + X · B.
The per-iteration cost bound of the fold loop, as a polynomial in esize (l, s₀).
Equations
- F.foldStepBound B = F.timeBound.comp (B + Polynomial.X + 1) + 2 * B + 3 * Polynomial.X + Polynomial.C 14
Instances For
Folding a polynomial-time body over a list, under the Cobham condition FoldBounded F B:
foldl F B hB (l, s₀) = l.foldl (fun s a => F (s, a)) s₀. The loop state is the input pair
itself.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Folding under the additive condition.
Equations
- F.foldlAdd B hB = F.foldl (Polynomial.X + Polynomial.X * B) ⋯
Instances For
Derived combinators #
Replacing the function of a PolyTimeFun by an extensionally equal one.
Equations
Instances For
A function whose output encodes exactly as its input is computed by var 0.
Equations
- MIPRE.Cost.PolyTimeFun.ofEncodeEq f h = { toFun := f, code := MIPRE.Cost.Prog.var 0, closed := Nat.zero_lt_one, timeBound := Polynomial.X + 1, computes := ⋯ }
Instances For
Retyping the output: a function whose values encode as the values of F is computed by
the program of F.
Equations
Instances For
Consing.
Equations
Instances For
Reversal.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Case analysis on a list component: casesList N K (a, []) is N a and
casesList N K (a, h :: t) is K (a, (h, t)).
Equations
- One or more equations did not get rendered due to their size.
Instances For
The list functions underlying the combinators #
Mapping a polynomial-time function over a list.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Appending.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The zip step as a polynomial-time function.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Zipping two lists.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Unary numerals as lists of units #
The unit encodes as the atom, so that a list of n units is the unary numeral
Data.ofNat n.
Equations
- One or more equations did not get rendered due to their size.
Unary numerals: lists of units.
Equations
Instances For
The unary numeral of n.
Equations
Instances For
The length of a list, in unary.
Equations
- MIPRE.Cost.PolyTimeFun.length = (MIPRE.Cost.PolyTimeFun.const ()).map.congr (fun (l : List α) => MIPRE.Cost.unary l.length) ⋯
Instances For
replicate (u, b) = List.replicate |u| b, by a fold over the unary numeral u whose state
carries b.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Mapping with a parameter: mapWith F (l, c) = l.map (fun a => F (a, c)), by zipping l
with copies of c.
Equations
- One or more equations did not get rendered due to their size.