Reduction of an integer modulo 2^n+1 in linear time
ProvedNLogN.fred_runsLet be a stack different from RN, RF, T1, T2, and let and with . Assume has on top (over ), RN has and RF has on top. Then fred X runs from to
with cost at most ; the result is the canonical residue in .
The procedure splits twice by , uses to fold the pieces with additions and a negation, and then applies at most two additions and two subtractions of the modulus. It is the reduction step after every butterfly, twist and untwist in the Fermat ring.
Formalization Note. States are IState NS records with item stacks G : Fin NS → List Item (head = top), input pointer ip and output out; s.upd X L replaces stack X by L; ints A is the list of integer items of A. The named stacks (ARG, PRM, RN, RF, DX, DL, …) are fixed indices in Fin 32. IRuns I iprog p s s' c means that p executes from s to exactly s' with some cost , so costs are upper bounds; the program text iprog and input I are arbitrary unless constrained.
-- 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
open IntMul
variable {P : ℕ} {I : List Sym} {iprog : Fin P → IStmt NS P}
theorem NLogN.fred_runs {X : Fin NS} (h1 : X ≠ RN) (h2 : X ≠ RF) (h3 : X ≠ T1) (h4 : X ≠ T2)
(s : IState NS) (z : ℤ) (n : ℕ) (L LN LF : List Item) (hX : s.G X = .int z :: L)
(hN : s.G RN = .int (2 ^ n) :: LN) (hF : s.G RF = .int (2 ^ n + 1) :: LF)
(hz : z.natAbs < 2 ^ (2 * n + 1)) :
IRuns I iprog (fred X) s (s.upd X (.int (z % (2 ^ n + 1)) :: L)) (20000 * (n + 3)) := by sorry