Documentation

Complexitylib.Models.TuringMachine.Registers.Horner

Horner layers: polynomial register evaluation #

The reduction emitter's variable indices are mixed-radix numerals (flatVar), and its time budget is p.eval n — both are computed by iterating the single Horner layer tmp := tmp · X + c over unary registers. This file builds that layer from the Arith register calculus and folds it into polyEvalTM.

To keep the time accounting sane across long seqTM chains, every stage bound is rounded up to the single monotone budget opBudget M, where M bounds every register value in play. Only the polynomial shape of the final bound matters (FP quantifies the degree existentially), so all budgets are deliberately loose.

Main definitions #

Main results #

One budget bounds every register operation whose values are at most M: increments, clears, copies, additions, multiply-accumulates, and literal emissions. Cubic in M because mulAddIntoTM's bound is (product value) × (per-mark sweep length).

Equations
Instances For
    theorem Complexity.TM.le_opBudget_of_le {a M : } (h : a 6 * (M + 2) * (M + 2)) :

    Anything at most quadratic in M + 2 (with constant 6) fits in opBudget M.

    theorem Complexity.TM.incRegTM_le_opBudget {d M : } (h : d M) :
    2 * d + 4 opBudget M

    incRegTM fits the budget.

    theorem Complexity.TM.clearRegTM_le_opBudget {d M : } (h : d M) :
    2 * d + 4 opBudget M

    clearRegTM fits the budget.

    skipTM fits the budget.

    theorem Complexity.TM.addIntoTM_le_opBudget {a b M : } (ha : a M) (hab : b + a M) :
    a * (2 * (b + a) + 4 + 2) + (a + 2) opBudget M

    addIntoTM fits the budget.

    theorem Complexity.TM.iterTM_incRegTM_le_opBudget {c d M : } (h : d + c M) :
    c * (2 * (d + c) + 5) + 1 opBudget M

    iterTM (incRegTM q) c fits the budget.

    theorem Complexity.TM.copyIntoTM_le_opBudget {a b M : } (ha : a M) (hb : b M) :
    2 * b + 4 + 1 + (a * (2 * (0 + a) + 4 + 2) + (a + 2)) opBudget M

    copyIntoTM fits the budget.

    theorem Complexity.TM.setConstTM_le_opBudget {c d M : } (hc : c M) (hd : d M) :
    2 * d + 4 + 1 + (c * (2 * c + 5) + 1) opBudget M

    setConstTM fits the budget.

    theorem Complexity.TM.emitLitTM_le_opBudget {v M : } (h : v M) :
    3 * v + 9 opBudget M

    emitLitTM fits the budget.

    theorem Complexity.TM.mulAddIntoTM_le_opBudget {a b d M : } (ha : a M) (hb : b M) (hd : d + a * b M) :
    a * (mulAddBound a b d + 2) + (a + 2) opBudget M

    mulAddIntoTM fits the budget, provided the accumulated product stays below M.

    def Complexity.TM.setConstTM {n : } (q : Fin n) (c : ) :
    TM n

    q := c (clear, then increment c times).

    Equations
    Instances For
      theorem Complexity.TM.setConstTM_hoareTime {n : } (q : Fin n) (c d : ) (inp₀ : Tape) (work₀ : Fin nTape) (ys : List Bool) (hinp₀ : Parked inp₀) (hwork₀ : ∀ (i : Fin n), Parked (work₀ i)) (hq : work₀ q = regTape d) :
      (setConstTM q c).HoareTime (EmitPred inp₀ work₀ ys) (EmitPred inp₀ (Function.update work₀ q (regTape c)) ys) (2 * d + 4 + 1 + (c * (2 * c + 5) + 1))

      setConstTM Hoare specification.

      def Complexity.TM.hornerLayerRegTM {n : } (X comp tmp tmp2 : Fin n) :
      TM n

      One Horner layer with a register addend: tmp := tmp · X + comp (scratch tmp2 ends holding the same value).

      Equations
      • One or more equations did not get rendered due to their size.
      Instances For
        def Complexity.TM.hornerLayerConstTM {n : } (X tmp tmp2 : Fin n) (c : ) :
        TM n

        One Horner layer with a constant addend: tmp := tmp · X + c (scratch tmp2 ends holding the same value).

        Equations
        • One or more equations did not get rendered due to their size.
        Instances For

          The (uniform) time budget of one Horner layer.

          Equations
          Instances For
            theorem Complexity.TM.hornerLayerRegTM_hoareTime {n : } {X comp tmp tmp2 : Fin n} (hXt : X tmp) (hXt2 : X tmp2) (htt2 : tmp tmp2) (hct2 : comp tmp2) (M x v w u : ) (hx : x M) (hv : v M) (hu : u M) (hres : v * x + w M) (inp₀ : Tape) (work₀ : Fin nTape) (ys : List Bool) (hinp₀ : Parked inp₀) (hwork₀ : ∀ (i : Fin n), Parked (work₀ i)) (hX : work₀ X = regTape x) (hc : work₀ comp = regTape w) (ht : work₀ tmp = regTape v) (ht2 : work₀ tmp2 = regTape u) :
            (hornerLayerRegTM X comp tmp tmp2).HoareTime (EmitPred inp₀ work₀ ys) (EmitPred inp₀ (Function.update (Function.update work₀ tmp2 (regTape (v * x + w))) tmp (regTape (v * x + w))) ys) (layerBudget M)

            hornerLayerRegTM Hoare specification. From tmp = v, X = x, comp = w (and any tmp2 = u), reach tmp = tmp2 = v·x + w with all other tapes untouched, within layerBudget M steps, provided every value in play is at most M.

            theorem Complexity.TM.hornerLayerConstTM_hoareTime {n : } {X tmp tmp2 : Fin n} (hXt : X tmp) (hXt2 : X tmp2) (htt2 : tmp tmp2) (M x v c u : ) (hx : x M) (hv : v M) (hu : u M) (hres : v * x + c M) (inp₀ : Tape) (work₀ : Fin nTape) (ys : List Bool) (hinp₀ : Parked inp₀) (hwork₀ : ∀ (i : Fin n), Parked (work₀ i)) (hX : work₀ X = regTape x) (ht : work₀ tmp = regTape v) (ht2 : work₀ tmp2 = regTape u) :
            (hornerLayerConstTM X tmp tmp2 c).HoareTime (EmitPred inp₀ work₀ ys) (EmitPred inp₀ (Function.update (Function.update work₀ tmp2 (regTape (v * x + c))) tmp (regTape (v * x + c))) ys) (layerBudget M)

            hornerLayerConstTM Hoare specification. From tmp = v, X = x (and any tmp2 = u), reach tmp = tmp2 = v·x + c.

            Horner accumulator over a coefficient list (highest degree first).

            Equations
            Instances For
              @[simp]

              hornerFold over the empty coefficient list returns the accumulator.

              theorem Complexity.TM.hornerFold_cons (x c a : ) (cs : List ) :
              hornerFold x (c :: cs) a = hornerFold x cs (a * x + c)

              Unfolding lemma: one Horner layer replaces the accumulator a by a * x + c.

              theorem Complexity.TM.hornerFold_reverse_range (f : ) (x k a : ) :
              hornerFold x (List.map f (List.range k)).reverse a = a * x ^ k + iFinset.range k, f i * x ^ i

              The Horner fold of a reversed coefficient window is the polynomial sum.

              theorem Complexity.TM.hornerFold_le (x : ) (cs : List ) (a : ) :
              hornerFold x cs a (a + cs.sum) * (x + 1) ^ cs.length

              Crude but monotone bound on the Horner accumulator.

              theorem Complexity.TM.hornerFold_take_le (x : ) (cs : List ) (k : ) :
              hornerFold x (List.take k cs) 0 (cs.sum + 1) * (x + 1) ^ cs.length

              Every prefix of the Horner fold is bounded by the full coefficient sum times the dominating power — the hypothesis-discharger for hornerLayersTM_hoareTime's value cap.

              def Complexity.TM.hornerLayersTM {n : } (X tmp tmp2 : Fin n) (cs : List ) :
              TM n

              Fold Horner layers (constant addends, highest first) over a register.

              Equations
              Instances For
                theorem Complexity.TM.hornerLayersTM_hoareTime {n : } (X tmp tmp2 : Fin n) (hXt : X tmp) (hXt2 : X tmp2) (htt2 : tmp tmp2) (M x : ) (hx : x M) (inp₀ : Tape) (hinp₀ : Parked inp₀) (c : ) (cs : List ) (v u : ) (work₀ : Fin nTape) (ys : List Bool) :
                (∀ k(c :: cs).length, hornerFold x (List.take k (c :: cs)) v M)u M(∀ (i : Fin n), Parked (work₀ i))work₀ X = regTape xwork₀ tmp = regTape vwork₀ tmp2 = regTape u(hornerLayersTM X tmp tmp2 (c :: cs)).HoareTime (EmitPred inp₀ work₀ ys) (EmitPred inp₀ (Function.update (Function.update work₀ tmp2 (regTape (hornerFold x (c :: cs) v))) tmp (regTape (hornerFold x (c :: cs) v))) ys) ((c :: cs).length * (layerBudget M + 1) + 1)

                hornerLayersTM Hoare specification (nonempty coefficient list). From tmp = v, reach tmp = tmp2 = hornerFold x (c :: cs) v, provided every intermediate accumulator value is at most M.

                The coefficient list of p, highest degree first.

                Equations
                Instances For

                  The coefficient list of a polynomial is never empty (it has natDegree + 1 entries).

                  @[simp]

                  polyCoeffs p has exactly p.natDegree + 1 entries.

                  The Horner fold computes p.eval.

                  def Complexity.TM.polyEvalTM {n : } (X tmp tmp2 : Fin n) (p : Polynomial ) :
                  TM n

                  tmp := p.eval x, reading x from register X (Horner's rule over the hardwired coefficient list; tmp2 is scratch and ends equal to tmp).

                  Equations
                  Instances For
                    theorem Complexity.TM.polyEvalTM_hoareTime {n : } (X tmp tmp2 : Fin n) (hXt : X tmp) (hXt2 : X tmp2) (htt2 : tmp tmp2) (p : Polynomial ) (M x v u : ) (hx : x M) (hv : v M) (hu : u M) (hpre : kp.natDegree + 1, hornerFold x (List.take k (polyCoeffs p)) 0 M) (inp₀ : Tape) (work₀ : Fin nTape) (ys : List Bool) (hinp₀ : Parked inp₀) (hwork₀ : ∀ (i : Fin n), Parked (work₀ i)) (hX : work₀ X = regTape x) (ht : work₀ tmp = regTape v) (ht2 : work₀ tmp2 = regTape u) :
                    (polyEvalTM X tmp tmp2 p).HoareTime (EmitPred inp₀ work₀ ys) (EmitPred inp₀ (Function.update (Function.update work₀ tmp2 (regTape (Polynomial.eval x p))) tmp (regTape (Polynomial.eval x p))) ys) (opBudget M + 1 + ((p.natDegree + 1) * (layerBudget M + 1) + 1))

                    polyEvalTM Hoare specification. From X = x (and any tmp = v, tmp2 = u), reach tmp = tmp2 = p.eval x, provided M caps x, the starting scratch values, and every Horner prefix value.