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}