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