Skip to main content

feanor_math/
field.rs

1use crate::divisibility::Domain;
2use crate::ring::*;
3use crate::pid::*;
4
5///
6/// Trait for rings that are fields, i.e. where every
7/// nonzero element has an inverse.
8/// 
9/// Note that fields must be commutative.
10/// 
11pub trait Field: Domain + EuclideanRing {
12
13    ///
14    /// Computes the division `lhs / rhs`, where `rhs != 0`.
15    /// 
16    /// Panics if `rhs = 0`.
17    /// 
18    fn div(&self, lhs: &Self::Element, rhs: &Self::Element) -> Self::Element {
19        assert!(!self.is_zero(rhs));
20        assert!(self.is_commutative());
21        return self.checked_left_div(lhs, rhs).unwrap();
22    }
23}
24
25///
26/// Trait for [`RingStore`]s that store [`Field`]s. Mainly used
27/// to provide a convenient interface to the `Field`-functions.
28/// 
29pub trait FieldStore: RingStore + EuclideanRingStore
30    where Self::Type: Field
31{
32    delegate!{ Field, fn div(&self, lhs: &El<Self>, rhs: &El<Self>) -> El<Self> }
33}
34
35impl<R> FieldStore for R
36    where R: RingStore, R::Type: Field
37{}
38
39///
40/// Field such that every finite degree extension field is separable.
41/// 
42/// This is equivalent to the following:
43///  - Every irreducible polynomial is square-free (over the algebraic closure)
44///  - Every finite-degree field extension is simple, i.e. generated by a single element
45/// 
46/// Note that currently, I sometimes make the assumption that a `PerfectField` is either
47/// finite, or has characteristic 0. This is clearly not the case in general, but all perfect
48/// fields that currently exist are one of those. I would even say that infinite perfect fields
49/// of positive characteristic are quite an exotic case in computer algebra, and I do not expect
50/// to implement them in the forseeable future. The simplest example of such a field would be
51/// the algebraic closure of the function field over a finite field, i.e. `AlgClosure(Fp(X))`.
52/// 
53pub trait PerfectField: Field {}
54
55#[cfg(any(test, feature = "generic_tests"))]
56pub mod generic_tests {
57    use super::*;
58
59    pub fn test_field_axioms<R, I>(R: R, edge_case_elements: I)
60        where R: FieldStore, R::Type: Field, I: Iterator<Item = El<R>>
61    {
62        let edge_case_elements = edge_case_elements.collect::<Vec<_>>();
63        for (i, a) in edge_case_elements.iter().enumerate() {
64            for (j, b) in edge_case_elements.iter().enumerate() {
65                assert!(i == j || !R.eq_el(&a, &b));
66                if !R.is_zero(&b) {
67                    assert_el_eq!(R, a, R.mul_ref_fst(&b, R.div(&a, &b)));
68                }
69            }
70        }
71    }
72}