FM preprocessing loop: cut M-bit pieces and twist them by powers of 2^Q
ProvedNLogN.prepLoop_runsLet with , , and bit length of at most ; write , and let . Assume XA has on top (over ), W has , CC has , RM has , RQ has , RN has , RF has on top. Then the loop "while CC is nonzero do prepStep" runs from to the state where
replace the tops of XA, W, CC (and the twisted pieces are pushed on QS, last on top), with cost at most .
Here are the first signed -bit pieces of , is the signed quotient left after cuts, and multiplies the -th piece by and reduces mod . Each iteration splits off one piece, shifts it by the current weight , reduces it, and multiplies by . This is the loop inside fmPrep.
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.prepLoop_runs (s : IState NS) (n M Q K : ℕ) (x : ℤ) (LX LW LC LM LQ LN LF : List Item)
(hKQ : K * Q = n) (hM : M ≤ n) (hQ : Q ≤ n) (hK : zsz (K : ℤ) ≤ n)
(hX : s.G XA = .int x :: LX) (hW : s.G W = .int 1 :: LW) (hC : s.G CC = .int K :: LC)
(hRM : s.G RM = .int (2 ^ M) :: LM) (hRQ : s.G RQ = .int (2 ^ Q) :: LQ)
(hN : s.G RN = .int (2 ^ n) :: LN) (hF : s.G RF = .int (2 ^ n + 1) :: LF) :
IRuns I iprog (.loop CC (fun c => c != .zero) prepStep) s
((((s.upd XA (.int (qit M K x) :: LX)).upd QS
((ints (wtZ (2 ^ n + 1) Q 0 (pcs M K x))).reverse ++ s.G QS)).upd W
(.int (2 ^ n) :: LW)).upd CC (.int 0 :: LC))
(K * (30000 * (n + 3) + 30) + 30) := by sorry