Stack-machine addition of two integer items is correct in linear time
ProvedNLogN.Runs.addIntLet be a state of the stack machine with stacks, and let be stack indices such that are pairwise distinct and differs from (it may coincide with or ). Here is the control-state stack, hold the operands, receives the result and are scratch stacks. Assume
- stack is the encoding of the integer item followed by , and stack the encoding of followed by , where neither nor starts with a bit symbol;
- the tops of are not bit symbols, and the top of is not the flag symbol
flagB.
Then the statement addInt q i j k t1 t2 runs from to the state obtained by popping both operands and pushing their sum on :
with cost at most , where = zsz z is the bit length of . addIntCost is an explicit affine function of the bit length, so signed addition costs steps. All other stacks, the input position and the output are unchanged.
This is the low-level implementation of the item-language instruction add; it is used (through the compiler correctness theorem) for every addition performed by the Schönhage–Strassen procedures.
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
open NLogN
variable {S P : ℕ} {I : List Sym} {prog : Fin P → Stmt S P}
variable {q i j k t1 t2 : Fin S} (hqi : q ≠ i) (hqj : q ≠ j) (hqt1 : q ≠ t1) (hqt2 : q ≠ t2)
(hij : i ≠ j) (hit1 : i ≠ t1) (hit2 : i ≠ t2) (hjt1 : j ≠ t1) (hjt2 : j ≠ t2) (ht12 : t1 ≠ t2)
(hqk : q ≠ k) (hkt1 : k ≠ t1) (hkt2 : k ≠ t2)
include hqi hqj hqt1 hqt2 hij hit1 hit2 hjt1 hjt2 ht12 hqk hkt1 hkt2
theorem NLogN.Runs.addInt (σ : St S) (z1 z2 : ℤ) (Ri Rj : List Sym)
(hi : σ.stk i = (Item.int z1).enc ++ Ri) (hj : σ.stk j = (Item.int z2).enc ++ Rj)
(hRi : bitOf Ri.head? = none) (hRj : bitOf Rj.head? = none)
(ht1 : bitOf (σ.stk t1).head? = none) (ht1' : (σ.stk t1).head? ≠ some flagB)
(ht2 : bitOf (σ.stk t2).head? = none) :
NLogN.Runs I prog (NLogN.addInt q i j k t1 t2 : Stmt S P) σ
(((σ.set i Ri).set j Rj).set k ((Item.int (z1 + z2)).enc ++ ((σ.set i Ri).set j Rj).stk k))
(addIntCost (max (zsz z1) (zsz z2))) := by sorry