use crate::ring::*;
use crate::rings::finite::*;
#[stability::unstable(feature = "enable")]
pub trait FiniteRingOperation<R>
where
R: ?Sized,
{
type Output;
fn execute(self) -> Self::Output
where
R: FiniteRing;
fn fallback(self) -> Self::Output;
}
#[stability::unstable(feature = "enable")]
pub trait FiniteRingSpecializable: RingBase {
fn specialize<O: FiniteRingOperation<Self>>(op: O) -> O::Output;
fn is_finite_ring() -> bool {
struct CheckIsFinite;
impl<R: ?Sized + RingBase> FiniteRingOperation<R> for CheckIsFinite {
type Output = bool;
fn execute(self) -> Self::Output
where
R: FiniteRing,
{
true
}
fn fallback(self) -> Self::Output { false }
}
return Self::specialize(CheckIsFinite);
}
}
#[cfg(test)]
use crate::homomorphism::*;
#[cfg(test)]
use crate::integer::*;
#[cfg(test)]
use crate::rings::extension::extension_impl::*;
#[cfg(test)]
use crate::rings::extension::galois_field::*;
#[cfg(test)]
use crate::rings::extension::*;
#[cfg(test)]
use crate::rings::field::*;
#[cfg(test)]
use crate::rings::rational::*;
#[cfg(test)]
use crate::rings::zn::*;
#[test]
fn test_specialize_finite_field() {
struct Verify<'a, R>(&'a R, i32)
where
R: ?Sized + RingBase;
impl<'a, R: ?Sized> FiniteRingOperation<R> for Verify<'a, R>
where
R: RingBase,
{
type Output = bool;
fn execute(self) -> bool
where
R: FiniteRing,
{
assert_el_eq!(
BigIntRing::RING,
BigIntRing::RING.int_hom().map(self.1),
self.0.size(&BigIntRing::RING).unwrap()
);
return true;
}
fn fallback(self) -> Self::Output { return false; }
}
let ring = zn_64::Zn::new(7).as_field().ok().unwrap();
assert!(<AsFieldBase<zn_64::Zn>>::specialize(Verify(ring.get_ring(), 7)));
let ring = GaloisField::new(3, 2);
assert!(GaloisFieldBase::specialize(Verify(ring.get_ring(), 9)));
let ring = GaloisField::new(3, 2).into().unwrap_self();
assert!(<AsFieldBase<FreeAlgebraImpl<_, _, _, _>>>::specialize(Verify(
ring.get_ring(),
9
)));
let ring = RationalField::new(BigIntRing::RING);
assert!(!<RationalFieldBase<_>>::specialize(Verify(ring.get_ring(), 0)));
let QQ = RationalField::new(BigIntRing::RING);
let ring = FreeAlgebraImpl::new(&QQ, 2, [QQ.neg_one()]).as_field().ok().unwrap();
assert!(!<AsFieldBase<FreeAlgebraImpl<_, _, _, _>>>::specialize(Verify(
ring.get_ring(),
0
)));
let base_ring = GaloisField::new(3, 2).into().unwrap_self();
let ring = FreeAlgebraImpl::new(&base_ring, 3, [base_ring.neg_one(), base_ring.one()])
.as_field()
.ok()
.unwrap();
assert!(<AsFieldBase<FreeAlgebraImpl<_, _, _, _>>>::specialize(Verify(
ring.get_ring(),
729
)));
}