use super::classification::PolynomialClassification;
use crate::core::{Expression, Symbol};
mod content;
mod degree;
#[cfg(test)]
mod tests;
pub(crate) use content::{compute_content_impl, divide_by_integer};
pub(crate) use degree::{
compute_leading_coefficient_impl, compute_total_degree_impl, degree_cached,
};
pub trait PolynomialProperties: PolynomialClassification {
fn degree(&self, var: &Symbol) -> Option<i64>;
fn total_degree(&self) -> Option<i64>;
fn leading_coefficient(&self, var: &Symbol) -> Expression;
fn content(&self) -> Expression;
fn primitive_part(&self) -> Expression;
}
impl PolynomialProperties for Expression {
fn degree(&self, var: &Symbol) -> Option<i64> {
degree_cached(self, var)
}
fn total_degree(&self) -> Option<i64> {
let vars = self.polynomial_variables();
if vars.is_empty() {
return Some(0);
}
compute_total_degree_impl(self, &vars)
}
fn leading_coefficient(&self, var: &Symbol) -> Expression {
compute_leading_coefficient_impl(self, var)
}
fn content(&self) -> Expression {
compute_content_impl(self)
}
fn primitive_part(&self) -> Expression {
let content = self.content();
if content.is_zero() || content == Expression::integer(1) {
self.clone()
} else {
divide_by_integer(self, &content)
}
}
}