use crate::iso::witness::iso::Iso;
use crate::iso::witness::ring_iso::RingIso as WitnessRingIso;
use crate::{Bijective, Hom, Injective, Isomorphism, RingHom, Surjective};
use core::marker::PhantomData;
type Ends<W, S, T> = fn() -> (W, S, T);
pub struct IsoForward<W, S, T>(PhantomData<Ends<W, S, T>>);
pub struct IsoBackward<W, S, T>(PhantomData<Ends<W, S, T>>);
impl<W, S, T> IsoForward<W, S, T> {
pub const fn new() -> Self {
Self(PhantomData)
}
}
impl<W, S, T> IsoBackward<W, S, T> {
pub const fn new() -> Self {
Self(PhantomData)
}
}
impl<W, S, T> Hom for IsoForward<W, S, T>
where
W: Iso<S, T>,
{
type Domain = S;
type Codomain = T;
fn apply(&self, s: S) -> T {
W::to_target(s)
}
}
impl<W, S, T> Hom for IsoBackward<W, S, T>
where
W: Iso<S, T>,
{
type Domain = T;
type Codomain = S;
fn apply(&self, t: T) -> S {
W::to_source(t)
}
}
impl<W, S, T> Injective for IsoForward<W, S, T> where W: Iso<S, T> {}
impl<W, S, T> Surjective for IsoForward<W, S, T> where W: Iso<S, T> {}
impl<W, S, T> Injective for IsoBackward<W, S, T> where W: Iso<S, T> {}
impl<W, S, T> Surjective for IsoBackward<W, S, T> where W: Iso<S, T> {}
impl<W, S, T> Isomorphism for IsoForward<W, S, T>
where
W: Iso<S, T>,
{
type Inverse = IsoBackward<W, S, T>;
fn inverse(&self) -> Self::Inverse {
IsoBackward::new()
}
}
impl<W, S, T> Isomorphism for IsoBackward<W, S, T>
where
W: Iso<S, T>,
{
type Inverse = IsoForward<W, S, T>;
fn inverse(&self) -> Self::Inverse {
IsoForward::new()
}
}
impl<W, S, T> RingHom for IsoForward<W, S, T>
where
W: WitnessRingIso<S, T>,
S: crate::Ring,
T: crate::Ring,
{
}
impl<W, S, T> RingHom for IsoBackward<W, S, T>
where
W: WitnessRingIso<S, T>,
S: crate::Ring,
T: crate::Ring,
{
}
pub fn assert_iso_is_bijective_hom<W, S, T>()
where
IsoForward<W, S, T>: Bijective,
{
}
impl<W, S, T> core::fmt::Debug for IsoForward<W, S, T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("IsoForward")
}
}
impl<W, S, T> core::fmt::Debug for IsoBackward<W, S, T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("IsoBackward")
}
}
impl<W, S, T> Clone for IsoForward<W, S, T> {
fn clone(&self) -> Self {
*self
}
}
impl<W, S, T> Copy for IsoForward<W, S, T> {}
impl<W, S, T> Clone for IsoBackward<W, S, T> {
fn clone(&self) -> Self {
*self
}
}
impl<W, S, T> Copy for IsoBackward<W, S, T> {}
impl<W, S, T> Default for IsoForward<W, S, T> {
fn default() -> Self {
Self::new()
}
}
impl<W, S, T> Default for IsoBackward<W, S, T> {
fn default() -> Self {
Self::new()
}
}
impl<W, S, T> PartialEq for IsoForward<W, S, T> {
fn eq(&self, _: &Self) -> bool {
true
}
}
impl<W, S, T> Eq for IsoForward<W, S, T> {}
impl<W, S, T> PartialEq for IsoBackward<W, S, T> {
fn eq(&self, _: &Self) -> bool {
true
}
}
impl<W, S, T> Eq for IsoBackward<W, S, T> {}