#[cfg(feature = "groebner-cuda")]
pub mod cuda;
pub mod f4;
pub mod f5;
pub mod ideal;
pub mod monomial_order;
pub mod reduce;
#[cfg(feature = "groebner-cuda")]
pub use cuda::{compute_groebner_basis_gpu, GpuGroebnerError, MacaulayMatrix};
pub use f4::compute_groebner_basis;
pub use f5::compute_groebner_basis_f5;
pub use ideal::GbPoly;
pub use monomial_order::MonomialOrder;
pub use reduce::reduce;
#[derive(Clone, Debug)]
pub struct GroebnerBasis {
generators: Vec<GbPoly>,
order: MonomialOrder,
}
impl GroebnerBasis {
pub fn compute(gens: Vec<GbPoly>, order: MonomialOrder) -> Self {
let generators = compute_groebner_basis(gens, order);
GroebnerBasis { generators, order }
}
pub fn compute_f5(gens: Vec<GbPoly>, order: MonomialOrder) -> Self {
let generators = compute_groebner_basis_f5(gens, order);
GroebnerBasis { generators, order }
}
pub fn generators(&self) -> &[GbPoly] {
&self.generators
}
pub fn reduce(&self, p: &GbPoly) -> GbPoly {
reduce(p, &self.generators, self.order)
}
pub fn contains(&self, p: &GbPoly) -> bool {
self.reduce(p).is_zero()
}
pub fn len(&self) -> usize {
self.generators.len()
}
pub fn is_empty(&self) -> bool {
self.generators.is_empty()
}
pub fn eliminate(&self, vars: &[usize]) -> GroebnerBasis {
let generators: Vec<GbPoly> = self
.generators
.iter()
.filter(|g| {
!g.terms
.keys()
.any(|e| vars.iter().any(|&i| e.get(i).copied().unwrap_or(0) > 0))
})
.cloned()
.collect();
GroebnerBasis {
generators,
order: self.order,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn eliminate_drops_generators() {
let xm_y = GbPoly {
terms: [
(vec![1u32, 0], rug::Rational::from(1)),
(vec![0, 1], rug::Rational::from(-1)),
]
.into_iter()
.collect(),
n_vars: 2,
};
let two_y2_m1 = GbPoly {
terms: [
(vec![0, 2], rug::Rational::from(2)),
(vec![0, 0], rug::Rational::from(-1)),
]
.into_iter()
.collect(),
n_vars: 2,
};
let gb = GroebnerBasis::compute(vec![xm_y, two_y2_m1], MonomialOrder::Lex);
let elim = gb.eliminate(&[0]);
assert_eq!(elim.generators().len(), 1);
for term in elim.generators()[0].terms.keys() {
assert_eq!(term[0], 0, "eliminated variable x must not appear");
}
}
}