feanor_math/
specialization.rs1use crate::ring::*;
2use crate::rings::finite::*;
3
4#[stability::unstable(feature = "enable")]
11pub trait FiniteRingOperation<R>
12 where R: ?Sized
13{
14 type Output;
15
16 fn execute(self) -> Self::Output
20 where R: FiniteRing;
21
22 fn fallback(self) -> Self::Output;
26}
27
28#[stability::unstable(feature = "enable")]
35pub trait FiniteRingSpecializable: RingBase {
36
37 fn specialize<O: FiniteRingOperation<Self>>(op: O) -> O::Output;
38
39 fn is_finite_ring() -> bool {
40 struct CheckIsFinite;
41 impl<R: ?Sized + RingBase> FiniteRingOperation<R> for CheckIsFinite {
42 type Output = bool;
43 fn execute(self) -> Self::Output
44 where R: FiniteRing { true }
45 fn fallback(self) -> Self::Output { false }
46 }
47 return Self::specialize(CheckIsFinite);
48 }
49}
50
51#[cfg(test)]
52use crate::homomorphism::*;
53#[cfg(test)]
54use crate::rings::field::*;
55#[cfg(test)]
56use crate::rings::extension::galois_field::*;
57#[cfg(test)]
58use crate::rings::rational::*;
59#[cfg(test)]
60use crate::rings::zn::*;
61#[cfg(test)]
62use crate::integer::*;
63#[cfg(test)]
64use crate::rings::extension::extension_impl::*;
65#[cfg(test)]
66use crate::rings::extension::*;
67
68#[test]
69fn test_specialize_finite_field() {
70
71 struct Verify<'a, R>(&'a R, i32)
72 where R: ?Sized + RingBase;
73
74 impl<'a, R: ?Sized> FiniteRingOperation<R> for Verify<'a, R>
75 where R: RingBase
76 {
77 type Output = bool;
78
79 fn execute(self) -> bool
80 where R: FiniteRing
81 {
82 assert_el_eq!(BigIntRing::RING, BigIntRing::RING.int_hom().map(self.1), self.0.size(&BigIntRing::RING).unwrap());
83 return true;
84 }
85
86 fn fallback(self) -> Self::Output {
87 return false;
88 }
89 }
90
91 let ring = zn_64::Zn::new(7).as_field().ok().unwrap();
92 assert!(<AsFieldBase<zn_64::Zn>>::specialize(Verify(ring.get_ring(), 7)));
93
94 let ring = GaloisField::new(3, 2);
95 assert!(GaloisFieldBase::specialize(Verify(ring.get_ring(), 9)));
96
97 let ring = GaloisField::new(3, 2).into().unwrap_self();
98 assert!(<AsFieldBase<FreeAlgebraImpl<_, _, _, _>>>::specialize(Verify(ring.get_ring(), 9)));
99
100 let ring = RationalField::new(BigIntRing::RING);
101 assert!(!<RationalFieldBase<_>>::specialize(Verify(ring.get_ring(), 0)));
102
103 let QQ = RationalField::new(BigIntRing::RING);
104 let ring = FreeAlgebraImpl::new(&QQ, 2, [QQ.neg_one()]).as_field().ok().unwrap();
105 assert!(!<AsFieldBase<FreeAlgebraImpl<_, _, _, _>>>::specialize(Verify(ring.get_ring(), 0)));
106
107 let base_ring = GaloisField::new(3, 2).into().unwrap_self();
108 let ring = FreeAlgebraImpl::new(&base_ring, 3, [base_ring.neg_one(), base_ring.one()]).as_field().ok().unwrap();
109 assert!(<AsFieldBase<FreeAlgebraImpl<_, _, _, _>>>::specialize(Verify(ring.get_ring(), 729)));
110}