use crate::op::{Additive, Multiplicative, Operator};
use super::{AbelianGroup, Monoid, VectorSpace};
pub trait Semiring<Oa: Operator = Additive, Om: Operator = Multiplicative>:
Monoid<Oa> + Monoid<Om>
{
}
pub trait Ring<Oa: Operator = Additive, Om: Operator = Multiplicative>:
Semiring<Oa, Om> + AbelianGroup<Oa>
{
}
pub trait CommutativeRing<Oa: Operator = Additive, Om: Operator = Multiplicative>:
Ring<Oa, Om>
{
}
pub trait DivisionRing<Oa: Operator = Additive, Om: Operator = Multiplicative>:
Ring<Oa, Om>
{
fn inv(&self) -> Self;
}
pub trait Field<Oa: Operator = Additive, Om: Operator = Multiplicative>:
DivisionRing<Oa, Om> + CommutativeRing<Oa, Om>
{
}
pub trait IntegralDomain<Oa: Operator = Additive, Om: Operator = Multiplicative>:
CommutativeRing<Oa, Om>
{
}
pub trait UniqueFactorizationDomain<Oa: Operator = Additive, Om: Operator = Multiplicative>:
IntegralDomain<Oa, Om>
{
}
pub trait PrincipalIdealDomain<Oa: Operator = Additive, Om: Operator = Multiplicative>:
UniqueFactorizationDomain<Oa, Om>
{
}
pub trait OrderedField<Oa: Operator = Additive, Om: Operator = Multiplicative>:
Field<Oa, Om> + PartialOrd
{
}
pub trait FiniteField<Oa: Operator = Additive, Om: Operator = Multiplicative>:
Field<Oa, Om>
{
fn characteristic() -> u64;
fn order() -> u64;
}
pub trait FieldExtension<Oa: Operator = Additive, Om: Operator = Multiplicative>:
Field<Oa, Om> + VectorSpace<Oa, Om, Scalar = <Self as FieldExtension<Oa, Om>>::BaseField>
{
type BaseField: Field<Oa, Om>;
fn degree() -> usize;
fn trace(&self) -> Self::BaseField;
fn norm(&self) -> Self::BaseField;
}
pub trait FieldExtensionTower<Oa: Operator = Additive, Om: Operator = Multiplicative>:
FieldExtension<Oa, Om>
{
fn tower_height() -> usize;
fn extension_degree(i: usize) -> usize;
}