Stack-machine concatenation a·2^m + b of integer items runs in O(m)
ProvedNLogN.Runs.catRLet be pairwise distinct stacks of a state ( control stack, scratch). Let be an integer, and . Assume stack is followed by , stack is (a "ruler") followed by , stack is followed by ; , and the tops of do not start with a bit symbol. Then catR q i j k t1 t2 runs from to
with cost at most . Here is with the sign of ; for the result is . The ruler on is left in place.
The operation appends the -bit block below the bits of in time linear in only (independent of the size of ), which is what makes the Horner recombination of the -bit output digits linear-time.
Formalization Note. Machine states are St S records: stacks stk : Fin S → List Sym over the 16-letter alphabet Sym = Fin 16 (head = top), input position ip and output out; σ.set i L replaces stack i. An integer item is stored as (Item.int z).enc: a sign header followed by the minimal binary magnitude, least significant bit nearest the header; bitOf detects bit symbols, and the hypotheses bitOf (…).head? = none say that the following stack content does not start with a bit (so item boundaries are recognisable). Runs I prog p σ σ' c means p runs from σ to exactly σ' with some cost ; the procedures prog and input I are arbitrary.
-- Schönhage–Strassen multitape-TM development (NLogN), generated by skeleton subtraction.
import Definitions.Def_IntMul_SS_Defs2
set_option autoImplicit false
set_option relaxedAutoImplicit false
set_option maxHeartbeats 1000000
set_option linter.unusedSimpArgs false
open NLogN
variable {S P : ℕ} {I : List Sym} {prog : Fin P → Stmt S P}
theorem NLogN.Runs.catR {q i j k t1 t2 : Fin S} (hqi : q ≠ i) (hqj : q ≠ j) (hqk : q ≠ k)
(hqt1 : q ≠ t1) (hqt2 : q ≠ t2) (hij : i ≠ j) (hik : i ≠ k) (hit1 : i ≠ t1) (hit2 : i ≠ t2)
(hjk : j ≠ k) (hjt1 : j ≠ t1) (hjt2 : j ≠ t2) (hkt1 : k ≠ t1) (hkt2 : k ≠ t2) (ht12 : t1 ≠ t2)
(σ : St S) (a : ℤ) (b m : ℕ) (ha : a ≠ 0) (hb : b < 2 ^ m) (Ri Rj Rk : List Sym)
(hi : σ.stk i = (Item.int a).enc ++ Ri) (hj : σ.stk j = (Item.int ((2 : ℤ) ^ m)).enc ++ Rj)
(hk : σ.stk k = (Item.int (b : ℤ)).enc ++ Rk)
(hRi : bitOf Ri.head? = none) (hRk : bitOf Rk.head? = none)
(ht1 : bitOf (σ.stk t1).head? = none) (ht2 : bitOf (σ.stk t2).head? = none) :
Runs I prog (NLogN.catR q i j k t1 t2 : Stmt S P) σ
((σ.set i ((Item.int (sg a (a.natAbs * 2 ^ m + b))).enc ++ Ri)).set k Rk) (catCost m) := by sorry