mathhook_core/core/polynomial/
groebner.rs

1//! Groebner Basis Computation
2//!
3//! Provides Groebner basis algorithms for polynomial ideals.
4//! This module re-exports from `algebra::groebner` while providing
5//! a unified interface through the polynomial module.
6//!
7//! # Overview
8//!
9//! Groebner bases are a fundamental tool in computational algebraic geometry
10//! and polynomial system solving. They provide canonical generators for
11//! polynomial ideals, enabling:
12//!
13//! - Ideal membership testing
14//! - Polynomial system solving
15//! - Elimination of variables
16//! - Geometric theorem proving
17//!
18//! # Algorithms
19//!
20//! - **Buchberger's Algorithm**: Classic algorithm for Groebner basis computation
21//! - **Efficient Buchberger**: Optimized variant with pair selection strategies
22//!
23//! # Example
24//!
25//! ```rust
26//! use mathhook_core::core::polynomial::groebner::{GroebnerBasis, MonomialOrder};
27//! use mathhook_core::core::Expression;
28//! use mathhook_core::symbol;
29//!
30//! let x = symbol!(x);
31//! let y = symbol!(y);
32//!
33//! // f1 = x - y
34//! let f1 = Expression::add(vec![
35//!     Expression::symbol(x.clone()),
36//!     Expression::mul(vec![Expression::integer(-1), Expression::symbol(y.clone())]),
37//! ]);
38//! // f2 = y^2 - 1
39//! let f2 = Expression::add(vec![
40//!     Expression::pow(Expression::symbol(y.clone()), Expression::integer(2)),
41//!     Expression::integer(-1),
42//! ]);
43//!
44//! let mut gb = GroebnerBasis::new(
45//!     vec![f1, f2],
46//!     vec![x.clone(), y.clone()],
47//!     MonomialOrder::Lex
48//! );
49//! gb.compute();
50//!
51//! // The basis should have at least 2 polynomials
52//! assert!(gb.basis.len() >= 2);
53//! ```
54
55pub use crate::algebra::groebner::{
56    buchberger_algorithm, efficient_buchberger_algorithm, expression_to_sparse_polynomial,
57    poly_reduce, poly_reduce_completely, s_polynomial, sparse_polynomial_to_expression,
58    GroebnerBasis, Monomial, MonomialOrder, MonomialOrdering, SparsePolynomial,
59};
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64    use crate::core::Expression;
65    use crate::symbol;
66
67    #[test]
68    fn test_monomial_order_export() {
69        let _lex = MonomialOrder::Lex;
70        let _grlex = MonomialOrder::Grlex;
71        let _grevlex = MonomialOrder::Grevlex;
72    }
73
74    #[test]
75    fn test_sparse_polynomial_creation() {
76        let mono = Monomial::new(vec![1, 2]);
77        assert_eq!(mono.degree(), 3);
78    }
79
80    #[test]
81    fn test_groebner_basis_creation() {
82        let x = symbol!(x);
83        let y = symbol!(y);
84
85        let f1 = Expression::add(vec![
86            Expression::pow(Expression::symbol(x.clone()), Expression::integer(2)),
87            Expression::integer(-1),
88        ]);
89
90        let gb = GroebnerBasis::new(vec![f1], vec![x, y], MonomialOrder::Lex);
91
92        assert_eq!(gb.basis.len(), 1);
93        assert_eq!(gb.variables.len(), 2);
94    }
95
96    #[test]
97    fn test_groebner_basis_simple() {
98        let x = symbol!(x);
99        let y = symbol!(y);
100
101        let f1 = Expression::symbol(x.clone()) - Expression::symbol(y.clone());
102        let f2 = Expression::pow(Expression::symbol(y.clone()), Expression::integer(2))
103            - Expression::integer(1);
104
105        let mut gb =
106            GroebnerBasis::new(vec![f1, f2], vec![x.clone(), y.clone()], MonomialOrder::Lex);
107
108        gb.compute();
109
110        assert!(!gb.basis.is_empty());
111        assert!(gb.basis.len() >= 2);
112    }
113
114    #[test]
115    fn test_expression_conversion_exists() {
116        let x = symbol!(x);
117        let y = symbol!(y);
118
119        let poly = Expression::add(vec![
120            Expression::pow(Expression::symbol(x.clone()), Expression::integer(2)),
121            Expression::symbol(y.clone()),
122        ]);
123
124        let vars = vec![x, y];
125        let sparse = expression_to_sparse_polynomial(&poly, &vars);
126
127        assert!(sparse.is_some());
128    }
129}