alkahest_cas/poly/
error.rs1use std::fmt;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum ConversionError {
6 UnexpectedSymbol(String),
8 NonIntegerCoefficient,
10 NegativeExponent,
12 ExponentTooLarge,
14 NonConstantExponent,
16 NonPolynomialFunction(String),
18 ZeroDenominator,
20}
21
22impl fmt::Display for ConversionError {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 match self {
25 ConversionError::UnexpectedSymbol(s) => {
26 write!(f, "unexpected free symbol '{s}' in polynomial expression")
27 }
28 ConversionError::NonIntegerCoefficient => {
29 write!(
30 f,
31 "non-integer coefficient (rational or float) in polynomial"
32 )
33 }
34 ConversionError::NegativeExponent => {
35 write!(
36 f,
37 "negative exponent yields a rational function, not a polynomial"
38 )
39 }
40 ConversionError::ExponentTooLarge => {
41 write!(f, "exponent exceeds u32::MAX")
42 }
43 ConversionError::NonConstantExponent => {
44 write!(f, "exponent is not a constant integer")
45 }
46 ConversionError::NonPolynomialFunction(name) => {
47 write!(f, "function '{name}' cannot appear in a polynomial")
48 }
49 ConversionError::ZeroDenominator => {
50 write!(f, "denominator is zero")
51 }
52 }
53 }
54}
55
56impl std::error::Error for ConversionError {}
57
58impl crate::errors::AlkahestError for ConversionError {
59 fn code(&self) -> &'static str {
60 match self {
61 ConversionError::UnexpectedSymbol(_) => "E-POLY-001",
62 ConversionError::NonIntegerCoefficient => "E-POLY-002",
63 ConversionError::NegativeExponent => "E-POLY-003",
64 ConversionError::ExponentTooLarge => "E-POLY-004",
65 ConversionError::NonConstantExponent => "E-POLY-005",
66 ConversionError::NonPolynomialFunction(_) => "E-POLY-006",
67 ConversionError::ZeroDenominator => "E-POLY-007",
68 }
69 }
70
71 fn remediation(&self) -> Option<&'static str> {
72 ConversionError::remediation(self)
73 }
74}
75
76impl ConversionError {
77 pub fn remediation(&self) -> Option<&'static str> {
79 match self {
80 ConversionError::NonPolynomialFunction(_) => Some(
81 "not a polynomial; wrap in the function only after rational reduction",
82 ),
83 ConversionError::NegativeExponent => Some(
84 "negative exponent yields a rational function; use RationalFunction::from_symbolic instead",
85 ),
86 ConversionError::NonConstantExponent => Some(
87 "symbolic exponents are not supported; substitute concrete values first",
88 ),
89 ConversionError::NonIntegerCoefficient => Some(
90 "rational/float coefficients not allowed; multiply through by the denominator",
91 ),
92 ConversionError::UnexpectedSymbol(_) => Some(
93 "pass all free variables in the `vars` argument to poly_normal",
94 ),
95 ConversionError::ExponentTooLarge => Some(
96 "exponent exceeds u32::MAX; consider working with rational functions",
97 ),
98 ConversionError::ZeroDenominator => None,
99 }
100 }
101
102 pub fn span(&self) -> Option<(usize, usize)> {
105 None
106 }
107}
108
109#[derive(Debug, Clone, PartialEq, Eq)]
111pub enum FactorError {
112 ZeroPolynomial,
114 InvalidModulus,
116 FlintFailure,
118}
119
120impl fmt::Display for FactorError {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 match self {
123 FactorError::ZeroPolynomial => write!(f, "cannot factor the zero polynomial"),
124 FactorError::InvalidModulus => write!(f, "modulus must be at least 2"),
125 FactorError::FlintFailure => {
126 write!(f, "polynomial factorization failed internally (FLINT)")
127 }
128 }
129 }
130}
131
132impl std::error::Error for FactorError {}
133
134impl crate::errors::AlkahestError for FactorError {
135 fn code(&self) -> &'static str {
136 match self {
137 FactorError::ZeroPolynomial => "E-POLY-008",
138 FactorError::InvalidModulus => "E-POLY-009",
139 FactorError::FlintFailure => "E-POLY-010",
140 }
141 }
142
143 fn remediation(&self) -> Option<&'static str> {
144 Some(match self {
145 FactorError::ZeroPolynomial => "factorization is only defined for non-zero polynomials",
146 FactorError::InvalidModulus => {
147 "use a modulus ≥ 2 that fits in a machine word (FLINT `nmod`)"
148 }
149 FactorError::FlintFailure => "report the polynomial as a minimal failing example",
150 })
151 }
152}