Skip to content

Commit 6aa9a8f

Browse files
authored
Format canonical rational results beyond Python's digit limit (#778)
* fix: format canonical rational results safely * refactor: simplify canonical output architecture check
1 parent a8f2924 commit 6aa9a8f

29 files changed

Lines changed: 347 additions & 56 deletions

src/jacobian/domains/arithmetic/operations.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from fractions import Fraction
1717
from typing import Literal
1818

19+
from jacobian.canonical import format_canonical_integer
1920
from jacobian.contracts.arithmetic import (
2021
IntegerBaseDigitsRequest,
2122
IntegerBaseDigitsResult,
@@ -114,8 +115,8 @@ def _fraction(value: CanonicalRational) -> Fraction:
114115

115116
def _wire(value: Fraction) -> CanonicalRational:
116117
return CanonicalRational(
117-
num=str(value.numerator),
118-
den=str(value.denominator),
118+
num=format_canonical_integer(value.numerator),
119+
den=format_canonical_integer(value.denominator),
119120
)
120121

121122

src/jacobian/domains/combinatorics/operations.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from functools import reduce
66
from operator import mul
77

8+
from jacobian.canonical import format_canonical_integer
89
from jacobian.contracts.combinatorics import (
910
FibonacciPairRequest,
1011
FibonacciPairResult,
@@ -168,7 +169,10 @@ def bernoulli(request: NonnegativeIntegerRequest) -> RationalResult:
168169
n = request.n
169170
value = sympy.bernoulli(n)
170171
return RationalResult(
171-
value=CanonicalRational(num=str(value.p), den=str(value.q)),
172+
value=CanonicalRational(
173+
num=format_canonical_integer(int(value.p)),
174+
den=format_canonical_integer(int(value.q)),
175+
),
172176
)
173177

174178

src/jacobian/domains/geometry/operations.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from fractions import Fraction
77
from typing import Any, cast
88

9+
from jacobian.canonical import format_canonical_integer
910
from jacobian.contracts.exact import CanonicalRational
1011
from jacobian.contracts.geometry import (
1112
ClosedSegment2D,
@@ -46,8 +47,8 @@ def _fraction(value: Any) -> Fraction:
4647
def _wire_rational(value: Any) -> CanonicalRational:
4748
fraction = _fraction(value)
4849
return CanonicalRational(
49-
num=str(fraction.numerator),
50-
den=str(fraction.denominator),
50+
num=format_canonical_integer(fraction.numerator),
51+
den=format_canonical_integer(fraction.denominator),
5152
)
5253

5354

src/jacobian/domains/graph_optimization/minimum_spanning_tree.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from fractions import Fraction
66
from typing import TYPE_CHECKING
77

8+
from jacobian.canonical import format_canonical_integer
89
from jacobian.contracts.capabilities import (
910
CapabilityDiagnostic,
1011
CapabilityInvocationExample,
@@ -43,7 +44,10 @@
4344

4445

4546
def _rational(value: Fraction) -> CanonicalRational:
46-
return CanonicalRational(num=str(value.numerator), den=str(value.denominator))
47+
return CanonicalRational(
48+
num=format_canonical_integer(value.numerator),
49+
den=format_canonical_integer(value.denominator),
50+
)
4751

4852

4953
def _canonical_endpoints(left: str, right: str) -> tuple[str, str]:

src/jacobian/domains/matrix_lattice/operations.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from fractions import Fraction
66
from typing import Any
77

8+
from jacobian.canonical import format_canonical_integer
89
from jacobian.contracts.matrix_operations import (
910
CharacteristicPolynomialResult,
1011
IntegerMatrixRequest,
@@ -32,8 +33,8 @@
3233
def _rational(value: Any) -> OutputRational:
3334
fraction = Fraction(value)
3435
return OutputRational(
35-
num=str(fraction.numerator),
36-
den=str(fraction.denominator),
36+
num=format_canonical_integer(fraction.numerator),
37+
den=format_canonical_integer(fraction.denominator),
3738
)
3839

3940

src/jacobian/domains/optimization/worker.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from jacobian.canonical import (
1111
CanonicalizationError,
1212
canonicalize_json,
13+
format_canonical_integer,
1314
loads_strict_json,
1415
)
1516
from jacobian.contracts.exact import CanonicalRational
@@ -26,7 +27,10 @@ def _wire(value: Any) -> dict[str, str]:
2627
import sympy
2728

2829
rational = sympy.Rational(value)
29-
return {"num": str(rational.p), "den": str(rational.q)}
30+
return {
31+
"num": format_canonical_integer(int(rational.p)),
32+
"den": format_canonical_integer(int(rational.q)),
33+
}
3034

3135

3236
def _linear_program(request: RationalLinearProgramRequest) -> dict[str, Any]:

src/jacobian/domains/polynomial/jacobian_syzygy.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from math import gcd
88
from typing import Any, Literal, cast
99

10-
from jacobian.canonical import canonicalize_json
10+
from jacobian.canonical import canonicalize_json, format_canonical_integer
1111
from jacobian.contracts.capabilities import (
1212
CapabilityInvocationExample,
1313
CapabilityMode,
@@ -40,7 +40,10 @@ def _homogeneous_basis(degree: int) -> tuple[tuple[int, int, int], ...]:
4040

4141
def _fraction_text(value: Any) -> str:
4242
fraction = Fraction(value)
43-
return f"{fraction.numerator}/{fraction.denominator}"
43+
return (
44+
f"{format_canonical_integer(fraction.numerator)}/"
45+
f"{format_canonical_integer(fraction.denominator)}"
46+
)
4447

4548

4649
def _matrix_digest(
@@ -97,8 +100,8 @@ def _multiplier_polynomial(
97100
terms=tuple(
98101
RationalPolynomialTerm(
99102
coefficient=CanonicalRational(
100-
num=str(coefficient.numerator),
101-
den=str(coefficient.denominator),
103+
num=format_canonical_integer(coefficient.numerator),
104+
den=format_canonical_integer(coefficient.denominator),
102105
),
103106
exponents=exponents,
104107
)
@@ -269,8 +272,8 @@ def compute_graded_jacobian_syzygy(
269272
multiplier_degree=multiplier_degree,
270273
coefficient_vector=tuple(
271274
CanonicalRational(
272-
num=str(value.numerator),
273-
den=str(value.denominator),
275+
num=format_canonical_integer(value.numerator),
276+
den=format_canonical_integer(value.denominator),
274277
)
275278
for value in vector
276279
),

src/jacobian/domains/polynomial/operations.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from fractions import Fraction
66
from typing import Any
77

8+
from jacobian.canonical import format_canonical_integer
89
from jacobian.contracts.exact import CanonicalRational
910
from jacobian.contracts.polynomial_operations import (
1011
PolynomialBezoutIdentity,
@@ -55,7 +56,10 @@ def _poly(polynomial: RationalPolynomial) -> Any:
5556

5657
def _rational(value: Any) -> CanonicalRational:
5758
fraction = Fraction(value)
58-
return CanonicalRational(num=str(fraction.numerator), den=str(fraction.denominator))
59+
return CanonicalRational(
60+
num=format_canonical_integer(fraction.numerator),
61+
den=format_canonical_integer(fraction.denominator),
62+
)
5963

6064

6165
def _wire(poly: Any, variables: tuple[str, ...]) -> RationalPolynomial:

src/jacobian/domains/polynomial_nullstellensatz/singular.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from pydantic import ValidationError
1212

13-
from jacobian.canonical import canonicalize_json
13+
from jacobian.canonical import canonicalize_json, format_canonical_integer
1414
from jacobian.capability_service import CapabilityInvocationError
1515
from jacobian.contracts.capabilities import (
1616
CapabilityAssurance,
@@ -125,7 +125,10 @@ def _parse_coefficient(value: str) -> CanonicalRational:
125125
if _INTEGER_OR_RATIONAL.fullmatch(value) is None:
126126
raise ValueError("Singular returned a non-rational coefficient")
127127
parsed = Fraction(value)
128-
return CanonicalRational(num=str(parsed.numerator), den=str(parsed.denominator))
128+
return CanonicalRational(
129+
num=format_canonical_integer(parsed.numerator),
130+
den=format_canonical_integer(parsed.denominator),
131+
)
129132

130133

131134
class _TaggedOutputParser:

src/jacobian/domains/polynomial_nullstellensatz/system.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from fractions import Fraction
77
from typing import Literal
88

9+
from jacobian.canonical import format_canonical_integer
910
from jacobian.contracts.exact import CanonicalRational
1011
from jacobian.contracts.nullstellensatz import (
1112
BoundedRationalPolynomial,
@@ -57,8 +58,8 @@ def _polynomial(
5758
terms=tuple(
5859
BoundedRationalPolynomialTerm(
5960
coefficient=CanonicalRational(
60-
num=str(coefficient.numerator),
61-
den=str(coefficient.denominator),
61+
num=format_canonical_integer(coefficient.numerator),
62+
den=format_canonical_integer(coefficient.denominator),
6263
),
6364
exponents=exponent,
6465
)

0 commit comments

Comments
 (0)