|
# N — Number Theory Four Views
A single `(a, N)` pair projects through four classical number-theoretic surfaces, all reading the same prime-atom vector `v⃗(N)`:
- **N1** prime factorisation ≡ `v⃗(N)` (LFTA, Lean-backed)
- **N2** polynomial root finding ≡ roots of `P_N(x) = ∏_p (x−p)^{v_p(N)}` (constructive over EGPTReal)
- **N3** order finding ≡ min divisor of φ(N) with `a^r ≡ 1` (LFTA + Lagrange)
- **N4** signal period ≡ direct orbit period of `a^k mod N` (classical Shor, definitional)
The four projections agree on r and on the prime set every time — not by tuning, but because they are the same operation under four labels.
*(Ported from `theorems/N_NumberTheoryFourViews.js`. `EGPTReal/EGPTPolynomial/PrimeAtomPolynomial/OrderFinder` come from `caps.math` — no imports. The runner + helpers are inlined.)*
|
## Setup — the four-view runner
Builds the atom-root polynomial, checks each prime is a root (N1≡N2), finds the order via `OrderFinder` (N3), and the direct orbit period (N4), asserting N3≡N4 and N1≡N2. Produced as a binding the case cells call.
|
const { math, display } = caps;
const { EGPTReal, EGPTPolynomial, PrimeAtomPolynomial, OrderFinder } = math;
const ZERO = EGPTReal.fromBigInt(0n);
const ONE = EGPTReal.fromBigInt(1n);
const intN = (n) => EGPTReal.fromBigInt(BigInt(n));
function buildAtomRootPolynomial(N) {
const factors = PrimeAtomPolynomial.factorize(N);
let poly = [ONE];
for (const { prime, exponent } of factors) {
const linear = [intN(-prime), ONE];
for (let k = 0n; k < exponent; k++) poly = EGPTPolynomial.multiply(poly, linear);
}
return poly;
}
function directPeriodOfOrbit(a, N) {
const aBi = BigInt(a), NBi = BigInt(N);
let current = 1n;
for (let r = 1; r <= Number(NBi); r++) { current = (current * aBi) % NBi; if (current === 1n) return r; }
return null;
}
function check(label, cond) { display((cond ? ' ✓ ' : ' ✗ ') + label); if (!cond) throw new Error('N FAILED: ' + label); }
function runFourViews(a, N, expectedOrder) {
const aBi = BigInt(a), NBi = BigInt(N);
display(`── a = ${aBi}, N = ${NBi}`);
// N1
const factors = PrimeAtomPolynomial.factorize(NBi);
const primeSet = factors.map(f => f.prime);
display(` N1 factorize(${NBi}) = ${factors.map(f => `(${f.prime}^${f.exponent})`).join(' · ') || '1'} Ω=${PrimeAtomPolynomial.bigOmega(NBi)} bitLen=${PrimeAtomPolynomial.bitLength(NBi)}`);
// N2
const P = buildAtomRootPolynomial(NBi);
for (const p of primeSet) check(`N2 P_${NBi}(${p}) = 0`, EGPTPolynomial.evaluateAt(P, intN(p)).equals(ZERO));
check(`deg(P) = Ω(N) = ${Number(PrimeAtomPolynomial.bigOmega(NBi))}`, EGPTPolynomial.degree(P) === Number(PrimeAtomPolynomial.bigOmega(NBi)));
// N3
const phi = PrimeAtomPolynomial.totient(NBi);
const orderR = OrderFinder.findOrder(aBi, NBi);
display(` N3 φ(${NBi})=${phi} order(${aBi} mod ${NBi})=${orderR}`);
check(`order(${aBi} mod ${NBi}) = ${expectedOrder}`, orderR === expectedOrder);
check(`verify: ${aBi}^${orderR} ≡ 1 (mod ${NBi})`, OrderFinder.verifyOrder(aBi, NBi, orderR));
// N4
const directPeriod = directPeriodOfOrbit(aBi, NBi);
display(` N4 direct orbit period = ${directPeriod}`);
check(`direct orbit period = ${expectedOrder}`, directPeriod === expectedOrder);
check('N3 order ≡ N4 period', orderR === directPeriod);
}
return { nrun: runFourViews };
|
## Cases — eight (a, N) pairs
Each pair runs all four projections and asserts they agree on the order/period and the prime set.
|
const { display } = caps;
const run = inputs.nrun;
run(3n, 8n, 2);
run(7n, 15n, 4);
run(2n, 7n, 3);
run(2n, 15n, 4);
run(4n, 15n, 2);
run(2n, 21n, 6);
run(5n, 21n, 6);
run(3n, 35n, 12);
display('All eight cases agree across N1/N2/N3/N4.');
|
const { display } = caps;
display('QED — factoring, polynomial roots, order finding, and signal period are four labels for one object: v⃗(N).');
|