The machine program fwP computes the Fermat-ring convolution fermatW
ProvedNLogN.FW.fwP_specLet be HvdH parameters with , , , , and let be a multiplication spec that multiplies -bit integers at cost . Let be lists of Gaussian integers () with all coordinates of absolute value , stored as item lists on stacks GU and VI, and let the constant registers hold their prescribed values (, , , , , , , , , and the encoded axis descriptors of the outer axes). Then the program fwP runs from (calling the multiplication procedure for the pointwise products), consumes and , and pushes fermatW q U V — the cyclic convolution of the published reference computed by Kronecker packing into the Fermat ring , forward DIF transforms, pointwise products, DIT transform and unpacking — onto OUT, with cost at most fwCost q kb Φm.
Formalization Note. The machine layer: IState HS is a state with stacks of items (Item = integer or mark), an input position and an output; RM programs (straight-line register code RS, loops rep, conditionals, calls of the multiplication procedure through a MulSpec giving its domain and cost) have a functional semantics p.run s, a definedness predicate p.ok M s and a cost p.cost M s; Spec M p s s' c abbreviates p.ok M s ∧ p.run s = s' ∧ p.cost M s ≤ c. ints L / gints U push an integer list / a list of pairs as items (head = top); zsz z is the bit length of . MulBnd M m Φ says the multiplication procedure accepts all pairs of integers of bit length at cost . Register names (GU, CR, KB, XN, …) are fixed stack indices.
-- Harvey–van der Hoeven multitape-TM development (NLogN), generated by skeleton subtraction. import Definitions.Def_IntMul_HvdH_M_Defs4 set_option autoImplicit false set_option relaxedAutoImplicit false set_option maxHeartbeats 1000000 set_option linter.unusedSimpArgs false set_option linter.unusedVariables false open NLogN open NLogN.FW open IntMul IntMul.HvdH NLogN set_option maxHeartbeats 1000000
theorem NLogN.FW.fwP_spec (M : MulSpec) {Φm : ℕ} (q : Ref.Params) (kb : ℕ) (hMB : MulBnd M (q.fn + 1) Φm)
(hP : 1 ≤ q.P) (hK : q.K ≤ q.fn) (hlo : q.logOuter ≤ q.fn) (hkb : q.logOuter ≤ kb)
(s : IState HS) (U V : List (ℤ × ℤ))
(RU RV Rs LCR LCM LRW LFR LKB LKN LKR LXN LXF LNN LKBR LNAX LSH : List Item)
(hUl : U.length = 2 ^ q.logOuter * q.r) (hVl : V.length = 2 ^ q.logOuter * q.r)
(hUb : ∀ z ∈ U, |z.1| < 2 ^ q.P ∧ |z.2| < 2 ^ q.P)
(hVb : ∀ z ∈ V, |z.1| < 2 ^ q.P ∧ |z.2| < 2 ^ q.P)
(hU : s.G GU = gints U ++ RU) (hV : s.G VI = gints V ++ RV)
(hCR : s.G CR = .int (2 ^ q.P) :: LCR) (hCM : s.G CM = .int (q.r : ℤ) :: LCM)
(hRW : s.G RW = .int (2 ^ (2 * q.r * q.P)) :: LRW) (hFR : s.G FR = .int (2 ^ q.fn + 1) :: LFR)
(hKB : s.G KB = .int (2 ^ q.P) :: LKB) (hKN : s.G KN = .int (2 ^ q.fn) :: LKN)
(hKR : s.G KR = .int (q.r : ℤ) :: LKR)
(hXN : s.G NLogN.FW.XN = .int (2 ^ q.fn) :: LXN) (hXF : s.G XF = .int (2 ^ q.fn + 1) :: LXF)
(hNN : s.G NN = .int ((2 ^ q.logOuter : ℕ) : ℤ) :: LNN) (hKBR : s.G KBR = .int kb :: LKBR)
(hNAX : s.G NAX = .int ((q.K - 1 : ℕ) : ℤ) :: LNAX)
(hAXS : s.G AXS = ints ((descs q.outerAxes 1).flatMap enc8) ++ Rs)
(hSH : s.G SH = .int (2 ^ (q.fn - q.logOuter)) :: LSH) :
Spec M fwP s (((s.upd GU RU).upd VI RV).upd OUT (gints (Ref.fermatW q U V) ++ s.G OUT))
(fwCost q kb Φm) := by sorry