Skip to content

feat(math): add integer multiplicative normal-form operations (#1893) - #2009

Open
morluto wants to merge 1 commit into
mainfrom
agent/integer-multiplicative-normal-forms-1893
Open

feat(math): add integer multiplicative normal-form operations (#1893)#2009
morluto wants to merge 1 commit into
mainfrom
agent/integer-multiplicative-normal-forms-1893

Conversation

@morluto

@morluto morluto commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Summary

Add five exact bounded operations for integer multiplicative normalization, closing #1893.

Operations

  • **** — Maximal perfect-power profile with signed base/exponent. For negative integers, the maximal exponent is the largest odd divisor of the gcd of prime exponents (negative integers can only be odd powers). Zero, +1, and -1 use closed structural variants.
  • **** — Unique decomposition n = a^k * c with |c| k-th-power-free, per-prime exponent rows, and exact reconstruction.
  • **** — k=2 specialization with signed squarefree part and per-prime parity rows.
  • **** — Compact projection returning the signed squarefree part and extracted square factor.
  • **** — Canonical sqrt(n) = s*sqrt(d) normalization with squarefree d, classifying as ZERO, RATIONAL_INTEGER, or IRRATIONAL_QUADRATIC.

Design

All operations use SymPy's for complete prime factorization, then pure-Python arithmetic for the normal-form computation (gcd, divmod, reconstruction). Every result carries an exact reconstruction witness (b^e = n, a^k * c = n, s^2 * d = n, etc.).

Key semantics

  • Zero and units use structural variants, not arbitrary exponent assignments
  • Negative integers restrict to odd maximal exponents
  • k-free cofactor preserves the sign of n under the public convention
  • Squarefree part ≠ prime-support radical (e.g., 72 → squarefree part = 2, radical = 6)
  • Normalized radical is the positive real branch only

Tests

34 known-answer, boundary, and adversarial tests covering:

  • Zero, ±1, primes, perfect powers, negative perfect powers
  • k-free decomposition for k=2,3,4
  • Already k-free inputs
  • Squarefree decomposition for squarefree, nonsquarefree, positive, negative
  • Normalized radicals: sqrt(0), sqrt(1), sqrt(12), sqrt(72), sqrt(144), large perfect square
  • Reconstruction invariants for all operations

Continue this on Linzumi

Add five exact bounded operations for integer multiplicative normalization:

- integer.perfect_power.profile.compute: maximal perfect-power profile
  with signed base/exponent and exact reconstruction, handling zero,
  units, positive, and negative integers correctly (negative integers
  use largest odd divisor of the exponent gcd).
- integer.k_free_decomposition.compute: unique n = a^k * c decomposition
  with k-th-power-free cofactor, per-prime exponent rows, and exact
  reconstruction.
- integer.squarefree_decomposition.compute: k=2 specialization with
  signed squarefree part and per-prime parity rows.
- integer.squarefree_part.compute: compact projection returning the
  signed squarefree part and extracted square factor.
- quadratic_radical.positive_integer.normalize.compute: canonical
  sqrt(n) = s*sqrt(d) normalization with squarefree d, classifying
  results as ZERO, RATIONAL_INTEGER, or IRRATIONAL_QUADRATIC.

All operations use SymPy factorint for complete prime factorization
and pure-Python arithmetic for the normal-form computation. Every
result carries an exact reconstruction witness.

Closes #1893.
@morluto morluto added feature epic: execute Execute: math.run honesty, results, verify path domain: algebra Algebra and algebraic operations domain: number-theory Number theory, arithmetic, and arithmetic functions request: math-operation Request to add or extend a user-facing mathematical operation labels Aug 18, 2026
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@morluto morluto left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review verdict: core formulas are correct, but the public contract is blocked and this overlaps #2038

I checked the arithmetic kernels across positive, negative, zero, and unit cases. The gcd-of-prime-exponents perfect-power rule (with the 2-adic part removed for negative inputs), e = qk+r k-free split, parity squarefree split, and positive quadratic-radical normalization are mathematically correct.

The blockers are in the value/catalog design:

1. Units are falsely classified as NONUNIT

Both k-free and squarefree operations send 1 and -1 through the nonzero branch, but the only nonzero result tag is "NONUNIT". The returned decompositions are numerically correct, yet the structural classification is false. Use NONZERO, or explicit unit variants.

2. The advertised closed variants are not closed

The validators only require fields when kind == "NONUNIT"; they do not forbid them otherwise and do not replay any equations. For example, a ZERO perfect-power result can carry an arbitrary base, exponent, factors, and reconstruction; a nonunit can carry a reconstruction unrelated to base**exponent; NormalizedQuadraticRadicalResult has no invariant validator at all. The in-kernel assert statements are not a wire invariant and disappear under optimized Python.

Bind at least:

  • base**exponent == source/reconstruction and maximality;
  • base**k * cofactor == source plus all cofactor exponents < k;
  • s**2*d == source plus squarefreeness/sign/canonical s >= 1;
  • radical classification, reconstruction, and squarefree radicand;
  • absence of non-applicable fields on zero/unit variants.

3. integer.squarefree_part.compute is not the compact projection it claims to be

It has the same request, result schema, and implementation as integer.squarefree_decomposition.compute, including factor rows and reconstruction. This is a duplicate catalog alias, not a distinct atomic operation. Remove it or give it an actually smaller result value.

4. The operation is not computationally bounded

CanonicalInteger supplies no factorization-work budget here, while every operation calls complete factorint(abs(n)). An accepted adversarial semiprime can make the supposedly routine exact operation run without a defensible bound. Bound derived work/bit length to an empirically justified envelope or expose a bounded/incomplete factorization contract rather than calling arbitrary complete factorization bounded.

5. Overlap

#2038 implements the same four substantive operation IDs with stronger reconstruction validators and avoids the duplicate squarefree-part catalog entry. These branches cannot both merge. Prefer one domain owner and one schema; after its unrelated stacked changes are removed, #2038 is the better structural starting point, while this PR's reuse of the repository canonical-integer type is worth retaining.

So: no formula-level arithmetic error found, but I would not merge this head as a second implementation with false variants and unenforced normal-form invariants.

morluto commented Aug 18, 2026

Copy link
Copy Markdown
Owner Author

Deep review summary

Verdict: REQUEST CHANGES — the arithmetic formulas are correct, but the public variants/invariants are false or unenforced, the factorization work is unbounded, and this overlaps #2038.

I checked positive, negative, zero, and unit cases. The gcd-of-prime-exponents perfect-power rule, odd-exponent restriction for negative inputs, e=qk+r k-free split, parity squarefree split, and positive quadratic-radical normalization are mathematically correct.

The blockers are structural:

1. Units are falsely labelled NONUNIT

The k-free and squarefree operations route 1 and -1 through a result variant named NONUNIT. The numerical decompositions are valid, but the type-level classification is false. Use NONZERO or explicit unit variants.

2. The result variants are not actually closed

Validators require some fields on NONUNIT, but do not forbid inapplicable fields on zero/unit variants and do not replay the defining equations. Kernel assert statements are not wire invariants and disappear under optimized Python.

Bind at least:

  • base**exponent == source plus maximality;
  • base**k * cofactor == source and every cofactor prime exponent <k;
  • s²d == source, squarefreeness, sign, and canonical positive s;
  • radical classification and squarefree radicand;
  • absence of nonapplicable fields on zero/unit variants.

3. squarefree_part.compute is a duplicate alias

It uses the same request, result, factor rows, reconstruction, and implementation as the full squarefree decomposition. That is not the compact projection described by the operation. Remove it or return a genuinely smaller value.

4. Complete factorization has no defensible input/work bound

Every operation calls factorint(abs(n)) on an unrestricted canonical integer. A hard semiprime can make an accepted request run indefinitely. Reuse a conservative factorization-bound type or expose an explicitly bounded/incomplete outcome.

5. This cannot merge alongside #2038

Both PRs publish the same substantive operation IDs with conflicting schemas. Keep one owner and one contract. #2038 has stronger reconstruction models after its unrelated stacked changes are removed; this PR's reuse of the repository canonical-integer type is worth preserving in the consolidated version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

domain: algebra Algebra and algebraic operations domain: number-theory Number theory, arithmetic, and arithmetic functions epic: execute Execute: math.run honesty, results, verify path feature request: math-operation Request to add or extend a user-facing mathematical operation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant