use crate::{
coords::Coords,
traits::{
CField, Field, Manifold, Nat, NatCompare, NatZero, Real, Succ, Tensor, Topological, Vector,
},
};
use core::{
convert::Infallible,
fmt::Debug,
marker::PhantomData,
ops::{Deref, DerefMut},
};
#[derive(Debug, Copy, Clone)]
pub struct Ø;
#[derive(Debug, Copy, Clone)]
pub struct ː<Head, Tail>(PhantomData<(Head, Tail)>);
mod sealed {
pub trait Category {}
pub trait AssocList {}
pub trait PropertyList {}
pub trait PropertyEntry {}
pub trait EquationList {}
pub trait AssocEntry {}
}
pub trait Category: sealed::Category + Sized {
type Structure: AssocList;
type Properties: PropertyList;
type Equations: EquationList;
}
#[derive(Debug, Copy, Clone)]
pub struct 𝒯<Structure: AssocList, Properties: PropertyList, Equations: EquationList = Ø>(
PhantomData<(Structure, Properties, Equations)>,
);
impl<S: AssocList, P: PropertyList, E: EquationList> sealed::Category for 𝒯<S, P, E> {}
impl<S: AssocList, P: PropertyList, E: EquationList> Category for 𝒯<S, P, E> {
type Structure = S;
type Properties = P;
type Equations = E;
}
#[derive(Debug, Copy, Clone)]
pub struct Rooted<𝒞: Cat, X, C: Category>(PhantomData<fn() -> (𝒞, X, C)>);
impl<𝒞: Cat, X, C: Category> sealed::Category for Rooted<𝒞, X, C> {}
impl<𝒞: Cat, X, C: Category> Category for Rooted<𝒞, X, C> {
type Structure = C::Structure;
type Properties = C::Properties;
type Equations = C::Equations;
}
#[doc(hidden)]
#[derive(Debug, Copy, Clone)]
pub struct ReflectedContext<𝒞: Cat, X>(PhantomData<fn() -> (𝒞, X)>);
impl<𝒞: Cat, X: Reflect<𝒞>> sealed::Category for ReflectedContext<𝒞, X> {}
impl<𝒞: Cat, X: Reflect<𝒞>> Category for ReflectedContext<𝒞, X> {
type Structure = <<X as Reflect<𝒞>>::Body as Category>::Structure;
type Properties = <<X as Reflect<𝒞>>::Body as Category>::Properties;
type Equations = <<X as Reflect<𝒞>>::Body as Category>::Equations;
}
pub trait Cat: Copy + Clone + Debug + Send + Sync + 'static {
type C: Category;
}
#[allow(non_camel_case_types)]
pub trait ι: Sized {
type C: RootContext<X = Self>;
}
#[allow(type_alias_bounds)]
pub type Model<𝒞: Cat, X: ι<C: Ⱶ<𝒞>>> = <<X as ι>::C as Ⱶ<𝒞>>::C;
pub trait Ob<C: Category + 'static>: ι {
type Context: RootContext<X = Self> + Ⱶ<𝐈𝐝<C>>;
}
impl<X, C> Ob<C> for X
where
X: ι,
C: Category + 'static,
X::C: RootContext<X = X> + Ⱶ<𝐈𝐝<C>>,
{
type Context = X::C;
}
pub trait AssocName: Copy + Clone + Debug + Send + Sync + 'static {}
#[derive(Debug, Copy, Clone)]
pub struct Requires<Name: AssocName, 𝒞: Cat>(PhantomData<(Name, 𝒞)>);
#[derive(Debug, Copy, Clone)]
pub struct Binds<Name: AssocName, 𝒞: Cat, Value, Context: Category>(
PhantomData<(Name, 𝒞, Value, Context)>,
);
#[allow(type_alias_bounds)]
pub type BindsReflected<Name: AssocName, 𝒞: Cat, Value: Reflect<𝒞>> =
Binds<Name, 𝒞, Value, ReflectedContext<𝒞, Value>>;
#[allow(type_alias_bounds)]
pub type BindsIncluded<Name: AssocName, Value: ι> =
Binds<Name, <<Value as ι>::C as RootContext>::𝒞, Value, <Value as ι>::C>;
#[derive(Debug, Copy, Clone)]
pub struct BindsAs<Name: AssocName, 𝒞: Cat, Value, Context: Category>(
PhantomData<(Name, 𝒞, Value, Context)>,
);
#[derive(Debug, Copy, Clone)]
pub struct ArrowSignature<C: Category, D, E>(PhantomData<fn() -> (C, D, E)>);
pub trait Signature {
type Domain;
type Codomain;
}
impl<C: Category, D, E> Signature for ArrowSignature<C, D, E> {
type Domain = D;
type Codomain = E;
}
#[derive(Debug, Copy, Clone)]
pub struct BindsTyping<C: Category + 'static, D, DContext: Category, E, EContext: Category>(
PhantomData<fn() -> (C, D, DContext, E, EContext)>,
);
#[derive(Debug, Copy, Clone)]
pub struct Unspecified;
#[doc(hidden)]
pub trait AssocEntry: sealed::AssocEntry {
type Name: AssocName;
type Role: Cat;
type C: Category;
type Value;
}
impl<𝒞: Cat, N: AssocName> sealed::AssocEntry for Requires<N, 𝒞> {}
impl<𝒞: Cat, N: AssocName> AssocEntry for Requires<N, 𝒞> {
type Name = N;
type Role = 𝒞;
type C = 𝒞::C;
type Value = Unspecified;
}
impl<𝒞: Cat, N: AssocName, V, C: Category> sealed::AssocEntry for Binds<N, 𝒞, V, C> {}
impl<𝒞: Cat, N: AssocName, V, C: Category> AssocEntry for Binds<N, 𝒞, V, C> {
type Name = N;
type Role = 𝒞;
type C = C;
type Value = V;
}
impl<𝒞: Cat, N: AssocName, V, C: Category> sealed::AssocEntry for BindsAs<N, 𝒞, V, C> {}
impl<𝒞: Cat, N: AssocName, V, C: Category> AssocEntry for BindsAs<N, 𝒞, V, C> {
type Name = N;
type Role = 𝒞;
type C = C;
type Value = V;
}
impl<C, D, DContext, E, EContext> sealed::AssocEntry for BindsTyping<C, D, DContext, E, EContext>
where
C: Category + 'static,
DContext: RootContext<X = D> + Ⱶ<𝐈𝐝<C>>,
EContext: RootContext<X = E> + Ⱶ<𝐈𝐝<C>>,
{
}
impl<C, D, DContext, E, EContext> AssocEntry for BindsTyping<C, D, DContext, E, EContext>
where
C: Category + 'static,
DContext: RootContext<X = D> + Ⱶ<𝐈𝐝<C>>,
EContext: RootContext<X = E> + Ⱶ<𝐈𝐝<C>>,
{
type Name = arrow::Typing;
type Role = 𝐓𝐲𝐩𝐢𝐧𝐠<C>;
type C = Rooted<
𝐓𝐲𝐩𝐢𝐧𝐠<C>,
ArrowSignature<C, D, E>,
𝒯<
ː<
BindsAs<signature::Domain, 𝐈𝐝<C>, D, DContext>,
ː<BindsAs<signature::Codomain, 𝐈𝐝<C>, E, EContext>, Ø>,
>,
Ø,
>,
>;
type Value = ArrowSignature<C, D, E>;
}
#[doc(hidden)]
pub trait AssocList: sealed::AssocList {}
impl sealed::AssocList for Ø {}
impl AssocList for Ø {}
impl<H: AssocEntry, T: AssocList> sealed::AssocList for ː<H, T> {}
impl<H: AssocEntry, T: AssocList> AssocList for ː<H, T> {}
#[doc(hidden)]
pub trait CompareAssoc<Rhs: AssocName>: AssocName {
type Relation;
}
macro_rules! assoc_namespace {
($namespace:ident { $($name:ident),+ $(,)? }) => {
pub mod $namespace {
$(
#[derive(Debug, Copy, Clone)]
pub struct $name;
)+
}
};
}
/// Declare constructive equality for the finite universe of associated labels.
macro_rules! assoc_relations {
() => {};
($head:path $(, $tail:path)* $(,)?) => {
impl AssocName for $head {}
impl CompareAssoc<$head> for $head {
type Relation = Same;
}
$(
impl CompareAssoc<$tail> for $head {
type Relation = Different;
}
impl CompareAssoc<$head> for $tail {
type Relation = Different;
}
)*
assoc_relations!($($tail),*);
};
}
#[derive(Debug, Copy, Clone)]
pub struct This;
assoc_namespace!(tensor { F });
assoc_namespace!(field {
Fixed,
Characteristic
});
assoc_namespace!(manifold { Tangent });
assoc_namespace!(arrow { Typing });
assoc_namespace!(signature { Domain, Codomain });
assoc_namespace!(homotopy { From, To });
assoc_namespace!(jet { Payload });
assoc_namespace!(tensor_of { Payload });
assoc_relations!(
This,
tensor::F,
field::Fixed,
field::Characteristic,
manifold::Tangent,
arrow::Typing,
signature::Domain,
signature::Codomain,
homotopy::From,
homotopy::To,
jet::Payload,
tensor_of::Payload,
);
#[doc(hidden)]
pub trait FindAssoc<Name: AssocName>: AssocList {
type Found: AssocEntry<Name = Name>;
}
#[doc(hidden)]
pub trait FindAssocWith<Name: AssocName, Relation>: AssocList {
type Found: AssocEntry<Name = Name>;
}
impl<Name: AssocName, Head: AssocEntry<Name = Name>, Tail: AssocList> FindAssocWith<Name, Same>
for ː<Head, Tail>
{
type Found = Head;
}
impl<Name: AssocName, Head: AssocEntry, Tail: AssocList + FindAssoc<Name>>
FindAssocWith<Name, Different> for ː<Head, Tail>
{
type Found = <Tail as FindAssoc<Name>>::Found;
}
impl<Name: AssocName, Head: AssocEntry<Name: CompareAssoc<Name>>, Tail: AssocList> FindAssoc<Name>
for ː<Head, Tail>
where
ː<Head, Tail>: FindAssocWith<Name, <Head::Name as CompareAssoc<Name>>::Relation>,
{
type Found = <ː<Head, Tail> as FindAssocWith<
Name,
<Head::Name as CompareAssoc<Name>>::Relation,
>>::Found;
}
#[doc(hidden)]
pub trait RootContext: Category {
type 𝒞: Cat;
type X;
}
impl<𝒞: Cat, X, C: Category> RootContext for Rooted<𝒞, X, C> {
type 𝒞 = 𝒞;
type X = X;
}
impl<𝒞: Cat, X: Reflect<𝒞>> RootContext for ReflectedContext<𝒞, X> {
type 𝒞 = 𝒞;
type X = X;
}
#[doc(hidden)]
pub trait ProjectAssoc<Name: AssocName, Relation>: Category {
type 𝒞: Cat;
type C: Category;
type X;
}
impl<C: RootContext> ProjectAssoc<This, Same> for C {
type 𝒞 = C::𝒞;
type C = C;
type X = C::X;
}
impl<Name: AssocName, C: Category<Structure: FindAssoc<Name>>> ProjectAssoc<Name, Different> for C
where
<C::Structure as FindAssoc<Name>>::Found: AssocEntry,
{
type 𝒞 = <<C::Structure as FindAssoc<Name>>::Found as AssocEntry>::Role;
type C = <<C::Structure as FindAssoc<Name>>::Found as AssocEntry>::C;
type X = <<C::Structure as FindAssoc<Name>>::Found as AssocEntry>::Value;
}
#[allow(non_camel_case_types)]
pub trait π<Name: AssocName = This>: Category {
type 𝒞: Cat;
type C: Category;
type X;
}
impl<Name: AssocName + CompareAssoc<This>, C: Category> π<Name> for C
where
C: ProjectAssoc<Name, <Name as CompareAssoc<This>>::Relation>,
{
type 𝒞 = <C as ProjectAssoc<Name, <Name as CompareAssoc<This>>::Relation>>::𝒞;
type C = <C as ProjectAssoc<Name, <Name as CompareAssoc<This>>::Relation>>::C;
type X = <C as ProjectAssoc<Name, <Name as CompareAssoc<This>>::Relation>>::X;
}
#[derive(Debug, Copy, Clone)]
pub struct BindsProperty<𝒞: Cat, Context: Category>(PhantomData<(𝒞, Context)>);
#[doc(hidden)]
pub trait PropertyEntry: sealed::PropertyEntry {
type Role: Cat;
}
impl<𝒞: Cat> sealed::PropertyEntry for 𝒞 {}
impl<𝒞: Cat> PropertyEntry for 𝒞 {
type Role = 𝒞;
}
impl<𝒞: Cat, C: Category> sealed::PropertyEntry for BindsProperty<𝒞, C> {}
impl<𝒞: Cat, C: Category> PropertyEntry for BindsProperty<𝒞, C> {
type Role = 𝒞;
}
#[doc(hidden)]
pub trait PropertyList: sealed::PropertyList {}
impl sealed::PropertyList for Ø {}
impl PropertyList for Ø {}
impl<H: PropertyEntry, T: PropertyList> sealed::PropertyList for ː<H, T> {}
impl<H: PropertyEntry, T: PropertyList> PropertyList for ː<H, T> {}
#[doc(hidden)]
pub trait AppendProperties<Rhs: PropertyList>: PropertyList {
type Output: PropertyList;
}
impl<Rhs: PropertyList> AppendProperties<Rhs> for Ø {
type Output = Rhs;
}
impl<Rhs: PropertyList, Head: PropertyEntry, Tail: PropertyList + AppendProperties<Rhs>>
AppendProperties<Rhs> for ː<Head, Tail>
{
type Output = ː<Head, <Tail as AppendProperties<Rhs>>::Output>;
}
#[doc(hidden)]
pub trait ExpandProperty: PropertyEntry {
type Expansion: PropertyList;
}
impl<𝒞: Cat<C: Category<Properties: ExpandProperties>>> ExpandProperty for 𝒞 {
type Expansion = <<𝒞::C as Category>::Properties as ExpandProperties>::Expansion;
}
impl<𝒞: Cat, Context: Category<Properties: ExpandProperties>> ExpandProperty
for BindsProperty<𝒞, Context>
{
type Expansion = <<Context as Category>::Properties as ExpandProperties>::Expansion;
}
#[doc(hidden)]
pub trait ExpandProperties: PropertyList {
type Expansion: PropertyList;
}
impl ExpandProperties for Ø {
type Expansion = Ø;
}
impl<
Head: PropertyEntry + ExpandProperty<Expansion: AppendProperties<Tail::Expansion>>,
Tail: PropertyList + ExpandProperties,
> ExpandProperties for ː<Head, Tail>
{
type Expansion = ː<
Head,
<<Head as ExpandProperty>::Expansion as AppendProperties<
<Tail as ExpandProperties>::Expansion,
>>::Output,
>;
}
#[derive(Debug, Copy, Clone)]
pub struct Present;
#[derive(Debug, Copy, Clone)]
pub struct Absent;
#[doc(hidden)]
pub trait PropertyPresence<𝒞: Cat>: PropertyList {
type Relation;
}
#[doc(hidden)]
pub trait PropertyPresenceWith<𝒞: Cat, Relation>: PropertyList {
type Output;
}
impl<𝒞: Cat> PropertyPresence<𝒞> for Ø {
type Relation = Absent;
}
impl<𝒞: Cat, Head: PropertyEntry<Role: Compare<𝒞, Relation = Same>>, Tail: PropertyList>
PropertyPresenceWith<𝒞, Same> for ː<Head, Tail>
{
type Output = Present;
}
impl<
𝒞: Cat,
Head: PropertyEntry<Role: Compare<𝒞, Relation = Different>>,
Tail: PropertyList + PropertyPresence<𝒞>,
> PropertyPresenceWith<𝒞, Different> for ː<Head, Tail>
{
type Output = <Tail as PropertyPresence<𝒞>>::Relation;
}
impl<𝒞: Cat, Head: PropertyEntry<Role: Compare<𝒞>>, Tail: PropertyList> PropertyPresence<𝒞>
for ː<Head, Tail>
where
ː<Head, Tail>: PropertyPresenceWith<𝒞, <Head::Role as Compare<𝒞>>::Relation>,
{
type Relation = <ː<Head, Tail> as PropertyPresenceWith<
𝒞,
<Head::Role as Compare<𝒞>>::Relation,
>>::Output;
}
#[doc(hidden)]
pub trait CoversProperties<Target: PropertyList>: PropertyList {
type Relation;
}
#[doc(hidden)]
pub trait CoversPropertiesWith<Target: PropertyList, Relation>: PropertyList {
type Output;
}
impl<S: PropertyList> CoversProperties<Ø> for S {
type Relation = Present;
}
impl<S: PropertyList, Tail: PropertyList> CoversPropertiesWith<Tail, Absent> for S {
type Output = Absent;
}
impl<Tail: PropertyList, S: PropertyList + CoversProperties<Tail>>
CoversPropertiesWith<Tail, Present> for S
{
type Output = <S as CoversProperties<Tail>>::Relation;
}
impl<
Head: PropertyEntry,
Tail: PropertyList,
S: PropertyList + PropertyPresence<<Head as PropertyEntry>::Role>,
> CoversProperties<ː<Head, Tail>> for S
where
S: CoversPropertiesWith<Tail, <S as PropertyPresence<<Head as PropertyEntry>::Role>>::Relation>,
{
type Relation = <S as CoversPropertiesWith<
Tail,
<S as PropertyPresence<<Head as PropertyEntry>::Role>>::Relation,
>>::Output;
}
#[doc(hidden)]
pub trait FindProperty<𝒞: Cat>: PropertyList {
type Found: PropertyEntry;
}
#[doc(hidden)]
pub trait FindPropertyWith<𝒞: Cat, Relation>: PropertyList {
type Found: PropertyEntry;
}
impl<𝒞: Cat, Head: PropertyEntry<Role: Compare<𝒞, Relation = Same>>, Tail: PropertyList>
FindPropertyWith<𝒞, Same> for ː<Head, Tail>
{
type Found = Head;
}
impl<
𝒞: Cat,
Head: PropertyEntry<Role: Compare<𝒞, Relation = Different>>,
Tail: PropertyList + FindProperty<𝒞>,
> FindPropertyWith<𝒞, Different> for ː<Head, Tail>
{
type Found = <Tail as FindProperty<𝒞>>::Found;
}
impl<𝒞: Cat, Head: PropertyEntry<Role: Compare<𝒞>>, Tail: PropertyList> FindProperty<𝒞>
for ː<Head, Tail>
where
ː<Head, Tail>: FindPropertyWith<𝒞, <Head::Role as Compare<𝒞>>::Relation>,
{
type Found =
<ː<Head, Tail> as FindPropertyWith<𝒞, <Head::Role as Compare<𝒞>>::Relation>>::Found;
}
#[doc(hidden)]
pub trait SelectProperty<𝒞: Cat>: Category {
type C: Category;
}
#[doc(hidden)]
pub trait ResolvedProperty<𝒞: Cat>: PropertyEntry {
type Refinement: Category;
}
impl<𝒞: Cat, 𝒟: Cat + Compare<𝒞, Relation = Same>, Context: Ⱶ<𝒞>> ResolvedProperty<𝒞>
for BindsProperty<𝒟, Context>
{
type Refinement = Context;
}
impl<𝒞: Cat, 𝒟: Cat<C: Ⱶ<𝒞>> + Compare<𝒞, Relation = Same>> ResolvedProperty<𝒞> for 𝒟 {
type Refinement = <𝒟::C as Ⱶ<𝒞>>::C;
}
impl<𝒞: Cat, C: Category<Properties: ExpandProperties>> SelectProperty<𝒞> for C
where
<C::Properties as ExpandProperties>::Expansion: FindProperty<𝒞, Found: ResolvedProperty<𝒞>>,
{
type C = <<<C::Properties as ExpandProperties>::Expansion as FindProperty<
𝒞,
>>::Found as ResolvedProperty<𝒞>>::Refinement;
}
#[derive(Debug, Copy, Clone)]
pub struct At<Name: AssocName>(PhantomData<Name>);
#[derive(Debug, Copy, Clone)]
pub struct Follow<Path, Name: AssocName>(PhantomData<(Path, Name)>);
#[derive(Debug, Copy, Clone)]
pub struct Equal<Left, Right>(PhantomData<(Left, Right)>);
#[doc(hidden)]
pub trait EquationList: sealed::EquationList {}
impl sealed::EquationList for Ø {}
impl EquationList for Ø {}
impl<L, R, T: EquationList> sealed::EquationList for ː<Equal<L, R>, T> {}
impl<L, R, T: EquationList> EquationList for ː<Equal<L, R>, T> {}
#[doc(hidden)]
pub trait ResolvePath<Path>: Category {
type 𝒞: Cat;
type C: Category;
type Output;
}
impl<Name: AssocName, C: Category + π<Name>> ResolvePath<At<Name>> for C {
type 𝒞 = <C as π<Name>>::𝒞;
type C = <C as π<Name>>::C;
type Output = <C as π<Name>>::X;
}
impl<Path, Name: AssocName, C: Category + ResolvePath<Path>> ResolvePath<Follow<Path, Name>> for C
where
<C as ResolvePath<Path>>::C: π<Name>,
{
type 𝒞 = <<C as ResolvePath<Path>>::C as π<Name>>::𝒞;
type C = <<C as ResolvePath<Path>>::C as π<Name>>::C;
type Output = <<C as ResolvePath<Path>>::C as π<Name>>::X;
}
#[doc(hidden)]
pub trait SameType<Rhs> {}
impl<T> SameType<T> for T {}
trait SatisfiesEquation<Eq>: Category {}
impl<
Left,
Right,
C: Category
+ ResolvePath<Right>
+ ResolvePath<Left, Output: SameType<<C as ResolvePath<Right>>::Output>>,
> SatisfiesEquation<Equal<Left, Right>> for C
{
}
trait SatisfiesEquations<Equations: EquationList>: Category {}
impl<C: Category> SatisfiesEquations<Ø> for C {}
impl<
Left,
Right,
Tail: EquationList,
C: Category + SatisfiesEquation<Equal<Left, Right>> + SatisfiesEquations<Tail>,
> SatisfiesEquations<ː<Equal<Left, Right>, Tail>> for C
{
}
pub struct Same;
pub struct Different;
#[doc(hidden)]
pub trait Compare<𝒟: Cat>: Cat {
type Relation;
}
#[doc(hidden)]
pub trait Atom: Cat {}
impl<𝒞: Atom> Compare<𝒞> for 𝒞 {
type Relation = Same;
}
macro_rules! atoms {
() => {};
($head:ty $(, $tail:ty)* $(,)?) => {
impl Atom for $head {}
$(
impl Compare<$tail> for $head {
type Relation = Different;
}
impl Compare<$head> for $tail {
type Relation = Different;
}
)*
atoms!($($tail),*);
};
}
macro_rules! compare_atoms_to_family {
($family:ident; $($cat:ty),* $(,)?) => {
$(
impl<N: Nat> Compare<$family<N>> for $cat
where
$family<N>: Cat,
{
type Relation = Different;
}
impl<N: Nat> Compare<$cat> for $family<N>
where
$family<N>: Cat,
{
type Relation = Different;
}
)*
};
}
macro_rules! compare_atoms_to_families {
([$($cat:ty),* $(,)?];) => {};
(
[$($cat:ty),* $(,)?];
$family:ident $(, $rest:ident)* $(,)?
) => {
compare_atoms_to_family!($family; $($cat),*);
compare_atoms_to_families!(
[$($cat),*];
$($rest),*
);
};
}
macro_rules! assoc_requirements {
() => {
Ø
};
($name:path : $role:ty $(, $rest_name:path : $rest_role:ty)* $(,)?) => {
ː<
Requires<$name, $role>,
assoc_requirements!($($rest_name : $rest_role),*)
>
};
}
macro_rules! properties {
() => {
Ø
};
($head:ty $(, $tail:ty)* $(,)?) => {
ː<$head, properties!($($tail),*)>
};
}
macro_rules! equations {
() => {
Ø
};
($head:ty $(, $tail:ty)* $(,)?) => {
ː<$head, equations!($($tail),*)>
};
}
macro_rules! cat {
(
($($name:path : $role:ty),* $(,)?),
{$($property:ty),* $(,)?},
{$($equation:ty),* $(,)?}
) => {
𝒯<
assoc_requirements!($($name : $role),*),
properties!($($property),*),
equations!($($equation),*)
>
};
(
($($name:path : $role:ty),* $(,)?),
{$($property:ty),* $(,)?}
) => {
𝒯<
assoc_requirements!($($name : $role),*),
properties!($($property),*),
Ø
>
};
(
$($name:path : $role:ty),* $(,)?
) => {
cat![
($($name : $role),*),
{}
]
};
(
$($property:ty),* $(,)?
) => {
cat![
(),
{$($property),*}
]
};
}
pub struct 𝐈𝐝<C: Category + 'static>(PhantomData<fn() -> C>);
impl<C: Category + 'static> Copy for 𝐈𝐝<C> {}
impl<C: Category + 'static> Clone for 𝐈𝐝<C> {
fn clone(&self) -> Self {
*self
}
}
impl<C: Category + 'static> Debug for 𝐈𝐝<C> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("𝐈𝐝")
}
}
impl<C: Category + 'static> Cat for 𝐈𝐝<C> {
type C = C;
}
impl<C: Category + 'static> Compare<𝐈𝐝<C>> for 𝐈𝐝<C> {
type Relation = Same;
}
impl<𝒞: Atom, C: Category + 'static> Compare<𝐈𝐝<C>> for 𝒞 {
type Relation = Different;
}
pub struct WithPayload<𝒞: Cat, Name: AssocName>(PhantomData<fn() -> (𝒞, Name)>);
impl<𝒞: Cat, Name: AssocName> Copy for WithPayload<𝒞, Name> {}
impl<𝒞: Cat, Name: AssocName> Clone for WithPayload<𝒞, Name> {
fn clone(&self) -> Self {
*self
}
}
impl<𝒞: Cat, Name: AssocName> Debug for WithPayload<𝒞, Name> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("WithPayload")
}
}
impl<𝒞: Cat, Name: AssocName> Cat for WithPayload<𝒞, Name> {
type C = 𝒯<
ː<Requires<Name, 𝒞>, <𝒞::C as Category>::Structure>,
<𝒞::C as Category>::Properties,
<𝒞::C as Category>::Equations,
>;
}
impl<𝒞: Cat, Name: AssocName, C: Category + 'static> Compare<𝐈𝐝<C>> for WithPayload<𝒞, Name> {
type Relation = Different;
}
impl<𝒞: Atom, Base: Cat, Name: AssocName> Compare<WithPayload<Base, Name>> for 𝒞 {
type Relation = Different;
}
#[allow(type_alias_bounds)]
pub type Jetted<𝒞: Cat> = WithPayload<𝒞, jet::Payload>;
#[allow(type_alias_bounds)]
pub type TensorOf<𝒞: Cat> = WithPayload<𝒞, tensor_of::Payload>;
pub struct 𝐀𝐫𝐫<C: Category + 'static>(PhantomData<fn() -> C>);
impl<C: Category + 'static> Copy for 𝐀𝐫𝐫<C> {}
impl<C: Category + 'static> Clone for 𝐀𝐫𝐫<C> {
fn clone(&self) -> Self {
*self
}
}
impl<C: Category + 'static> Debug for 𝐀𝐫𝐫<C> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("𝐀𝐫𝐫")
}
}
pub struct 𝐓𝐲𝐩𝐢𝐧𝐠<C: Category + 'static>(PhantomData<fn() -> C>);
impl<C: Category + 'static> Copy for 𝐓𝐲𝐩𝐢𝐧𝐠<C> {}
impl<C: Category + 'static> Clone for 𝐓𝐲𝐩𝐢𝐧𝐠<C> {
fn clone(&self) -> Self {
*self
}
}
impl<C: Category + 'static> Debug for 𝐓𝐲𝐩𝐢𝐧𝐠<C> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("𝐓𝐲𝐩𝐢𝐧𝐠")
}
}
impl<C: Category + 'static> Cat for 𝐓𝐲𝐩𝐢𝐧𝐠<C> {
type C = cat![(signature::Domain: 𝐈𝐝<C>, signature::Codomain: 𝐈𝐝<C>), {}];
}
impl<A: Category + 'static, C: Category + 'static> Compare<𝐈𝐝<C>> for 𝐓𝐲𝐩𝐢𝐧𝐠<A> {
type Relation = Different;
}
impl<C: Category + 'static> Cat for 𝐀𝐫𝐫<C> {
type C = cat![(arrow::Typing: 𝐓𝐲𝐩𝐢𝐧𝐠<C>), {}];
}
impl<A: Category + 'static, C: Category + 'static> Compare<𝐈𝐝<C>> for 𝐀𝐫𝐫<A> {
type Relation = Different;
}
pub struct 𝐇𝐨𝐦𝐨𝐭𝐨𝐩𝐲<C: Category + 'static>(PhantomData<fn() -> C>);
impl<C: Category + 'static> Copy for 𝐇𝐨𝐦𝐨𝐭𝐨𝐩𝐲<C> {}
impl<C: Category + 'static> Clone for 𝐇𝐨𝐦𝐨𝐭𝐨𝐩𝐲<C> {
fn clone(&self) -> Self {
*self
}
}
impl<C: Category + 'static> Debug for 𝐇𝐨𝐦𝐨𝐭𝐨𝐩𝐲<C> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str("𝐇𝐨𝐦𝐨𝐭𝐨𝐩𝐲")
}
}
impl<C: Category + 'static> Cat for 𝐇𝐨𝐦𝐨𝐭𝐨𝐩𝐲<C> {
type C = cat![(homotopy::From: 𝐀𝐫𝐫<C>, homotopy::To: 𝐀𝐫𝐫<C>), {}];
}
impl<A: Category + 'static, C: Category + 'static> Compare<𝐈𝐝<C>>
for 𝐇𝐨𝐦𝐨𝐭𝐨𝐩𝐲<A>
{
type Relation = Different;
}
#[macro_export]
macro_rules! C {
[$𝒞:ty] => {
<$𝒞 as Cat>::C
};
}
macro_rules! category_context {
(@root {}) => {
cat!{}
};
(@root {$($property:ident),+ $(,)?}) => {
cat!{$($property::𝒞),+}
};
(@root [($($name:path : $role:ident),* $(,)?), {$($property:ident),* $(,)?}, {$($equation:ty),* $(,)?} $(,)?]) => {
cat![
($($name: $role::𝒞),*),
{$($property::𝒞),*},
{$($equation),*}
]
};
(@root [($($name:path : $role:ident),* $(,)?), {$($property:ident),* $(,)?} $(,)?]) => {
cat![
($($name: $role::𝒞),*),
{$($property::𝒞),*}
]
};
(@module {}) => {
cat!{}
};
(@module {$($property:ident),+ $(,)?}) => {
cat!{$(super::$property::𝒞),+}
};
(@module [($($name:path : $role:ident),* $(,)?), {$($property:ident),* $(,)?}, {$($equation:ty),* $(,)?} $(,)?]) => {
cat![
($($name: super::$role::𝒞),*),
{$(super::$property::𝒞),*},
{$($equation),*}
]
};
(@module [($($name:path : $role:ident),* $(,)?), {$($property:ident),* $(,)?} $(,)?]) => {
cat![
($($name: super::$role::𝒞),*),
{$(super::$property::𝒞),*}
]
};
}
macro_rules! category_module_impl {
($cat:ident => $context:tt; $($property:ident),* $(,)?) => {
#[allow(non_snake_case)]
pub mod $cat {
use super::*;
#[derive(Copy, Clone, Debug)]
pub struct 𝒞;
impl super::Cat for 𝒞 {
type C = category_context!(@module $context);
}
pub type C = <𝒞 as super::Cat>::C;
#[allow(non_camel_case_types)]
pub trait Ⱶ: super::Ⱶ<𝒞> $(+ super::$property::Ⱶ)* {}
impl<Context> Ⱶ for Context
where
Context: super::Ⱶ<𝒞> $(+ super::$property::Ⱶ)*,
{
}
}
};
}
macro_rules! category_module {
($cat:ident => {}) => {
category_module_impl!($cat => {};);
};
($cat:ident => {$($property:ident),+ $(,)?}) => {
category_module_impl!($cat => {$($property),+}; $($property),+);
};
($cat:ident => [($($structure:tt)*), {$($property:ident),* $(,)?}, {$($equation:tt)*} $(,)?]) => {
category_module_impl!(
$cat => [($($structure)*), {$($property),*}, {$($equation)*}];
$($property),*
);
};
($cat:ident => [($($structure:tt)*), {$($property:ident),* $(,)?} $(,)?]) => {
category_module_impl!(
$cat => [($($structure)*), {$($property),*}];
$($property),*
);
};
}
macro_rules! categories {
(
$(
$cat:ident => cat!$context:tt;
)*
$(
@$family:ident<$n:ident> => cat!$base:tt;
)*
) => {
$(
category_module!($cat => $context);
)*
$(
#[derive(Copy, Clone, Debug)]
pub struct $family<$n: Nat>(PhantomData<$n>);
impl Cat for $family<NatZero> {
type C = category_context!(@root $base);
}
impl<$n: Nat> Cat for $family<Succ<$n>>
where
$family<$n>: Cat,
{
type C = cat![(), {$family<$n>}];
}
)*
#[derive(Copy, Clone, Debug)]
pub struct 𝐂𝐚𝐭<N: Nat>(PhantomData<N>);
impl<N: Nat> Cat for 𝐂𝐚𝐭<N>
where
$(
$family<N>: Cat,
)*
{
type C = cat![
(),
{
$($cat::𝒞,)*
$($family<N>,)*
}
];
}
atoms![$($cat::𝒞),*];
impl<𝒞: Atom, N: Nat> Compare<𝐂𝐚𝐭<N>> for 𝒞
where
𝐂𝐚𝐭<N>: Cat,
{
type Relation = Different;
}
impl<𝒞: Atom, N: Nat> Compare<𝒞> for 𝐂𝐚𝐭<N>
where
𝐂𝐚𝐭<N>: Cat,
{
type Relation = Different;
}
compare_atoms_to_families!(
[$($cat::𝒞),*];
$($family),*
);
$(
impl<N: Nat, C: Category + 'static> Compare<𝐈𝐝<C>> for $family<N>
where
$family<N>: Cat,
{
type Relation = Different;
}
)*
impl<N: Nat, C: Category + 'static> Compare<𝐈𝐝<C>> for 𝐂𝐚𝐭<N>
where
𝐂𝐚𝐭<N>: Cat,
{
type Relation = Different;
}
$(
impl<N: Nat, Base: Cat, Name: AssocName> Compare<WithPayload<Base, Name>>
for $family<N>
where
$family<N>: Cat,
{
type Relation = Different;
}
)*
impl<N: Nat, Base: Cat, Name: AssocName> Compare<WithPayload<Base, Name>>
for 𝐂𝐚𝐭<N>
where
𝐂𝐚𝐭<N>: Cat,
{
type Relation = Different;
}
$(
impl<N: Nat + NatCompare<M>, M: Nat> Compare<$family<M>> for $family<N>
where
$family<N>: Cat,
$family<M>: Cat,
{
type Relation = <N as NatCompare<M>>::Relation;
}
impl<N: Nat, M: Nat> Compare<𝐂𝐚𝐭<M>> for $family<N>
where
$family<N>: Cat,
𝐂𝐚𝐭<M>: Cat,
{
type Relation = Different;
}
impl<N: Nat, M: Nat> Compare<$family<M>> for 𝐂𝐚𝐭<N>
where
𝐂𝐚𝐭<N>: Cat,
$family<M>: Cat,
{
type Relation = Different;
}
)*
impl<N: Nat + NatCompare<M>, M: Nat> Compare<𝐂𝐚𝐭<M>> for 𝐂𝐚𝐭<N>
where
𝐂𝐚𝐭<N>: Cat,
𝐂𝐚𝐭<M>: Cat,
{
type Relation = <N as NatCompare<M>>::Relation;
}
};
}
categories! {
𝐒𝐞𝐭 => cat!{};
𝐓𝐨𝐩 => cat!{𝐒𝐞𝐭};
𝐌𝐨𝐧 => cat!{𝐓𝐨𝐩};
𝐂𝐌𝐨𝐧 => cat!{𝐌𝐨𝐧};
𝐆𝐫𝐩 => cat!{𝐌𝐨𝐧};
𝐀𝐛 => cat!{𝐆𝐫𝐩, 𝐂𝐌𝐨𝐧};
𝐑𝐢𝐧𝐠 => cat!{𝐂𝐌𝐨𝐧, 𝐆𝐫𝐩};
𝐍𝐚𝐭 => cat!{};
𝐂𝐅𝐥𝐝 => cat!{𝐅𝐥𝐝, 𝐀𝐛};
𝐎𝐫𝐝 => cat!{𝐒𝐞𝐭};
𝐎𝐫𝐝𝐅𝐥𝐝 => cat!{𝐂𝐅𝐥𝐝, 𝐎𝐫𝐝};
𝐃𝐞𝐝𝐞𝐤𝐢𝐧𝐝 => cat!{𝐎𝐫𝐝};
𝐑𝐞𝐚𝐥 => cat!{𝐎𝐫𝐝𝐅𝐥𝐝, 𝐃𝐞𝐝𝐞𝐤𝐢𝐧𝐝};
𝐅𝐥𝐝 => cat![
(field::Fixed: 𝐂𝐅𝐥𝐝, field::Characteristic: 𝐍𝐚𝐭),
{𝐑𝐢𝐧𝐠, 𝐆𝐫𝐩},
{Equal<Follow<At<field::Fixed>, field::Fixed>, At<field::Fixed>>}
];
𝐓𝐞𝐧𝐬 => cat![(tensor::F: 𝐅𝐥𝐝), {𝐂𝐌𝐨𝐧}];
𝐕𝐞𝐜𝐭 => cat!{𝐓𝐞𝐧𝐬, 𝐆𝐫𝐩};
𝐌𝐚𝐧 => cat![(manifold::Tangent: 𝐓𝐞𝐧𝐬), {𝐓𝐨𝐩}];
@𝐇𝐨𝐦<N> => cat!{𝐌𝐚𝐧};
}
pub type 𝐃𝐢𝐟𝐟 = 𝐇𝐨𝐦<NatZero>;
pub trait Reflect<𝒞: Cat> {
type Body: Ⱶ<𝒞>;
}
impl<N: Nat> Reflect<𝐍𝐚𝐭::𝒞> for N {
type Body = 𝐍𝐚𝐭::C;
}
impl<T: Field> Reflect<𝐅𝐥𝐝::𝒞> for T {
type Body = 𝒯<
ː<
BindsReflected<field::Fixed, 𝐂𝐅𝐥𝐝::𝒞, T::Fixed>,
ː<BindsReflected<field::Characteristic, 𝐍𝐚𝐭::𝒞, T::Characteristic>, Ø>,
>,
properties![𝐑𝐢𝐧𝐠::𝒞, 𝐆𝐫𝐩::𝒞],
ː<Equal<Follow<At<field::Fixed>, field::Fixed>, At<field::Fixed>>, Ø>,
>;
}
impl<T: CField> Reflect<𝐂𝐅𝐥𝐝::𝒞> for T {
type Body = 𝒯<
ː<
BindsReflected<field::Fixed, 𝐂𝐅𝐥𝐝::𝒞, T::Fixed>,
ː<BindsReflected<field::Characteristic, 𝐍𝐚𝐭::𝒞, T::Characteristic>, Ø>,
>,
ː<BindsProperty<𝐅𝐥𝐝::𝒞, ReflectedContext<𝐅𝐥𝐝::𝒞, T>>, ː<𝐀𝐛::𝒞, Ø>>,
ː<Equal<Follow<At<field::Fixed>, field::Fixed>, At<field::Fixed>>, Ø>,
>;
}
impl<R: Real> Reflect<𝐎𝐫𝐝::𝒞> for R {
type Body = 𝒯<Ø, ː<BindsProperty<𝐒𝐞𝐭::𝒞, 𝐒𝐞𝐭::C>, Ø>>;
}
impl<R: Real> Reflect<𝐎𝐫𝐝𝐅𝐥𝐝::𝒞> for R {
type Body = 𝒯<
Ø,
ː<
BindsProperty<𝐂𝐅𝐥𝐝::𝒞, ReflectedContext<𝐂𝐅𝐥𝐝::𝒞, R>>,
ː<BindsProperty<𝐎𝐫𝐝::𝒞, ReflectedContext<𝐎𝐫𝐝::𝒞, R>>, Ø>,
>,
>;
}
impl<R: Real> Reflect<𝐃𝐞𝐝𝐞𝐤𝐢𝐧𝐝::𝒞> for R {
type Body = 𝒯<Ø, ː<BindsProperty<𝐎𝐫𝐝::𝒞, ReflectedContext<𝐎𝐫𝐝::𝒞, R>>, Ø>>;
}
impl<R: Real> Reflect<𝐑𝐞𝐚𝐥::𝒞> for R {
type Body = 𝒯<
Ø,
ː<
BindsProperty<𝐎𝐫𝐝𝐅𝐥𝐝::𝒞, ReflectedContext<𝐎𝐫𝐝𝐅𝐥𝐝::𝒞, R>>,
ː<BindsProperty<𝐃𝐞𝐝𝐞𝐤𝐢𝐧𝐝::𝒞, ReflectedContext<𝐃𝐞𝐝𝐞𝐤𝐢𝐧𝐝::𝒞, R>>, Ø>,
>,
>;
}
impl<T: Tensor> Reflect<𝐓𝐞𝐧𝐬::𝒞> for T {
type Body = 𝒯<ː<BindsReflected<tensor::F, 𝐅𝐥𝐝::𝒞, T::F>, Ø>, properties![𝐂𝐌𝐨𝐧::𝒞]>;
}
impl<V: Vector> Reflect<𝐕𝐞𝐜𝐭::𝒞> for V {
type Body = 𝒯<Ø, ː<BindsProperty<𝐓𝐞𝐧𝐬::𝒞, ReflectedContext<𝐓𝐞𝐧𝐬::𝒞, V>>, ː<𝐆𝐫𝐩::𝒞, Ø>>>;
}
impl<T: Topological> Reflect<𝐓𝐨𝐩::𝒞> for T {
type Body = 𝒯<Ø, ː<BindsProperty<𝐒𝐞𝐭::𝒞, 𝐒𝐞𝐭::C>, Ø>>;
}
impl<M: Manifold> Reflect<𝐌𝐚𝐧::𝒞> for M {
type Body = 𝒯<
ː<BindsReflected<manifold::Tangent, 𝐓𝐞𝐧𝐬::𝒞, M::Tangent>, Ø>,
ː<BindsProperty<𝐓𝐨𝐩::𝒞, ReflectedContext<𝐓𝐨𝐩::𝒞, M>>, Ø>,
>;
}
#[allow(type_alias_bounds)]
pub type DomainOf<C: π<arrow::Typing, X: Signature>> =
<<C as π<arrow::Typing>>::X as Signature>::Domain;
#[allow(type_alias_bounds)]
pub type CodomainOf<C: π<arrow::Typing, X: Signature>> =
<<C as π<arrow::Typing>>::X as Signature>::Codomain;
#[allow(type_alias_bounds)]
pub type ArrowCategory<C: Category + 'static, D: Ob<C>, E: Ob<C>> =
𝒯<ː<BindsTyping<C, D, <D as Ob<C>>::Context, E, <E as Ob<C>>::Context>, Ø>, Ø>;
pub struct Arrow<C: Category, F = Infallible> {
f: F,
ctx: PhantomData<fn() -> C>,
}
impl<C: Category, F> Deref for Arrow<C, F> {
type Target = F;
#[inline]
fn deref(&self) -> &Self::Target {
&self.f
}
}
impl<C: Category, F> DerefMut for Arrow<C, F> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.f
}
}
impl<C: π<arrow::Typing, X: Signature>> Arrow<C, Infallible> {
#[inline]
pub fn new<F>(f: F) -> Arrow<C, F> {
Arrow::<C, F> {
f,
ctx: PhantomData,
}
}
}
impl<C: π<arrow::Typing, X: Signature>, F: Fn(&DomainOf<C>) -> CodomainOf<C>> Arrow<C, F> {
#[inline]
pub fn into_inner(self) -> F {
self.f
}
}
impl<C: Category, F: Clone> Clone for Arrow<C, F> {
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
ctx: PhantomData,
}
}
}
#[doc(hidden)]
pub trait RefineProperty<𝒞: Cat>: PropertyEntry {
type Refinement: Category;
}
impl<𝒞: Cat, 𝒟: Compare<𝒞, Relation = Same>, C: Ⱶ<𝒞>> RefineProperty<𝒞> for BindsProperty<𝒟, C> {
type Refinement = C;
}
impl<𝒞: Cat, 𝒟: Cat<C: Ⱶ<𝒞>> + Compare<𝒞, Relation = Same>> RefineProperty<𝒞> for 𝒟 {
type Refinement = <𝒟::C as Ⱶ<𝒞>>::C;
}
#[doc(hidden)]
pub trait RefinesProperties<Target: PropertyList>: PropertyList {
type Refinement: PropertyList;
}
impl<S: PropertyList> RefinesProperties<Ø> for S {
type Refinement = Ø;
}
impl<
𝒞: Cat,
Tail: PropertyList,
S: PropertyList
+ ExpandProperties<Expansion: FindProperty<𝒞, Found: RefineProperty<𝒞>>>
+ RefinesProperties<Tail>,
> RefinesProperties<ː<𝒞, Tail>> for S
{
type Refinement = ː<
BindsProperty<
𝒞,
<<<S as ExpandProperties>::Expansion as FindProperty<𝒞>>::Found as RefineProperty<
𝒞,
>>::Refinement,
>,
<S as RefinesProperties<Tail>>::Refinement,
>;
}
trait SatisfiesAssoc<𝒞: Cat>: AssocEntry {}
trait ChildContext<𝒞: Cat, X>: Category {}
impl<𝒞: Cat, X: Reflect<𝒞>> ChildContext<𝒞, X> for ReflectedContext<𝒞, X> {}
impl<𝒞: Cat, X, C: Category> ChildContext<𝒞, X> for Rooted<𝒞, X, C> where
Rooted<𝒞, X, C>: Ⱶ<𝒞>
{
}
trait RoleSatisfies<Required: Cat, Relation>: Cat {}
impl<Required: Cat, Actual: Cat> RoleSatisfies<Required, Same> for Actual {}
impl<Required: Cat, Actual: Cat<C: Category<Properties: ExpandProperties>>>
RoleSatisfies<Required, Different> for Actual
where
<<Actual::C as Category>::Properties as ExpandProperties>::Expansion:
PropertyPresence<Required, Relation = Present>,
{
}
impl<
Required: Cat,
Actual: Cat + Compare<Required>,
Name: AssocName,
Value,
Context: ChildContext<Actual, Value>,
> SatisfiesAssoc<Required> for Binds<Name, Actual, Value, Context>
where
Actual: RoleSatisfies<Required, <Actual as Compare<Required>>::Relation>,
{
}
impl<
Name: AssocName,
Required: Category + 'static,
Actual: Ⱶ<𝐈𝐝<Required>> + 'static,
Context: RootContext<X = Value> + Ⱶ<𝐈𝐝<Actual>>,
Value,
> SatisfiesAssoc<𝐈𝐝<Required>> for BindsAs<Name, 𝐈𝐝<Actual>, Value, Context>
{
}
impl<Required, Actual, D, DContext, E, EContext> SatisfiesAssoc<𝐓𝐲𝐩𝐢𝐧𝐠<Required>>
for BindsTyping<Actual, D, DContext, E, EContext>
where
Required: Category + 'static,
Actual: Ⱶ<𝐈𝐝<Required>> + 'static,
DContext: RootContext<X = D> + Ⱶ<𝐈𝐝<Actual>>,
EContext: RootContext<X = E> + Ⱶ<𝐈𝐝<Actual>>,
{
}
#[doc(hidden)]
pub trait RefinesStructure<Target: AssocList>: AssocList {
type Refinement: AssocList;
}
impl<S: AssocList> RefinesStructure<Ø> for S {
type Refinement = Ø;
}
impl<
𝒞: Cat,
Name: AssocName,
Tail: AssocList,
S: AssocList + FindAssoc<Name, Found: SatisfiesAssoc<𝒞>> + RefinesStructure<Tail>,
> RefinesStructure<ː<Requires<Name, 𝒞>, Tail>> for S
{
type Refinement = ː<<S as FindAssoc<Name>>::Found, <S as RefinesStructure<Tail>>::Refinement>;
}
#[doc(hidden)]
pub trait StructuralRefinement<Target: Category>: Category {
type C: Category;
}
impl<
TS: AssocList,
TP: PropertyList,
TE: EquationList,
SS: AssocList + RefinesStructure<TS>,
SP: PropertyList + RefinesProperties<TP>,
SE: EquationList,
> StructuralRefinement<𝒯<TS, TP, TE>> for 𝒯<SS, SP, SE>
where
𝒯<SS, SP, SE>: SatisfiesEquations<TE>,
{
type C = 𝒯<
<SS as RefinesStructure<TS>>::Refinement,
<SP as RefinesProperties<TP>>::Refinement,
TE,
>;
}
impl<𝒞: Cat, X, C: Category + StructuralRefinement<Target>, Target: Category>
StructuralRefinement<Target> for Rooted<𝒞, X, C>
{
type C = <C as StructuralRefinement<Target>>::C;
}
impl<𝒞: Cat, X: Reflect<𝒞>, Target: Category> StructuralRefinement<Target>
for ReflectedContext<𝒞, X>
where
<X as Reflect<𝒞>>::Body: StructuralRefinement<Target>,
{
type C = <<X as Reflect<𝒞>>::Body as StructuralRefinement<Target>>::C;
}
pub trait Ⱶ<𝒞: Cat, Relation = Present>: Category {
type C: Category;
}
#[doc(hidden)]
pub trait RefinementRoute<𝒞: Cat, Presence>: Category {
type C: Category;
}
impl<Required: Cat, C: Category + SelectProperty<Required>> RefinementRoute<Required, Present>
for C
{
type C = <C as SelectProperty<Required>>::C;
}
impl<Required: Cat, C: Category + StructuralRefinement<Required::C>>
RefinementRoute<Required, Absent> for C
{
type C = <C as StructuralRefinement<Required::C>>::C;
}
impl<Required: Cat, C, P> Ⱶ<Required> for C
where
C: Category<Properties = P>,
P: ExpandProperties,
P::Expansion: PropertyPresence<Required>,
C: RefinementRoute<Required, <P::Expansion as PropertyPresence<Required>>::Relation>,
{
type C =
<C as RefinementRoute<Required, <P::Expansion as PropertyPresence<Required>>::Relation>>::C;
}
impl<Required: Cat, C, P> Ⱶ<Required, Absent> for C
where
C: Category<Properties = P>,
P: ExpandProperties,
<Required as Cat>::C: Category<Structure = Ø, Equations = Ø>,
P::Expansion:
CoversProperties<<<Required as Cat>::C as Category>::Properties, Relation = Absent>,
{
type C = C;
}
pub trait Equivalent<𝒞: Cat, X> {
fn project(self) -> X;
fn lift(x: X) -> Self;
}
impl<𝒞: Cat, X> Equivalent<𝒞, X> for X {
fn project(self) -> X {
self
}
fn lift(x: X) -> Self {
x
}
}
#[allow(unused)]
fn test_this_whole_thing_baby() {
type ReflectedV = <Coords<f64, 2> as ι>::C;
type RootRole = <ReflectedV as π>::𝒞;
type RootC = <ReflectedV as π>::C;
type V = <Coords<f64, 2> as ι>::C;
type T = <V as Ⱶ<𝐓𝐞𝐧𝐬::𝒞>>::C;
type Scalar = <T as π<tensor::F>>::X;
type ScalarC = <T as π<tensor::F>>::C;
fn assert_same_type<T>(_: T, _: T) {}
fn assert_different_names<A, B>()
where
A: AssocName + CompareAssoc<B, Relation = Different>,
B: AssocName,
{
}
assert_different_names::<jet::Payload, tensor_of::Payload>();
assert_same_type(PhantomData::<RootRole>, PhantomData::<𝐕𝐞𝐜𝐭::𝒞>);
assert_same_type(PhantomData::<RootC>, PhantomData::<ReflectedV>);
assert_same_type(PhantomData::<Scalar>, PhantomData::<f64>);
fn scalar_context_is_field<C: Ⱶ<𝐅𝐥𝐝::𝒞>>() {}
scalar_context_is_field::<ScalarC>();
type DirectFieldC = Model<𝐅𝐥𝐝::𝒞, f64>;
assert_same_type(PhantomData::<ScalarC>, PhantomData::<DirectFieldC>);
fn refines_concrete_field_theory<C: Ⱶ<𝐈𝐝<𝐅𝐥𝐝::C>>>() {}
refines_concrete_field_theory::<DirectFieldC>();
type FieldC = Model<𝐅𝐥𝐝::𝒞, f64>;
type FixedC = <FieldC as π<field::Fixed>>::C;
type FixedFixedC = <FixedC as π<field::Fixed>>::C;
assert_same_type(PhantomData::<FixedC>, PhantomData::<FixedFixedC>);
type RealC = <f64 as ι>::C;
type OrderedFieldViaReal = <RealC as Ⱶ<𝐎𝐫𝐝𝐅𝐥𝐝::𝒞>>::C;
type DedekindViaReal = <RealC as Ⱶ<𝐃𝐞𝐝𝐞𝐤𝐢𝐧𝐝::𝒞>>::C;
assert_same_type(
PhantomData::<OrderedFieldViaReal>,
PhantomData::<Model<𝐎𝐫𝐝𝐅𝐥𝐝::𝒞, f64>>,
);
assert_same_type(
PhantomData::<DedekindViaReal>,
PhantomData::<Model<𝐃𝐞𝐝𝐞𝐤𝐢𝐧𝐝::𝒞, f64>>,
);
type CFieldViaReal = <RealC as Ⱶ<𝐂𝐅𝐥𝐝::𝒞>>::C;
assert_same_type(
PhantomData::<CFieldViaReal>,
PhantomData::<Model<𝐂𝐅𝐥𝐝::𝒞, f64>>,
);
fn cfield_is_abelian<C: Ⱶ<𝐀𝐛::𝒞>>() {}
cfield_is_abelian::<CFieldViaReal>();
type FieldViaReal = <RealC as Ⱶ<𝐅𝐥𝐝::𝒞>>::C;
assert_same_type(
PhantomData::<FieldViaReal>,
PhantomData::<Model<𝐅𝐥𝐝::𝒞, f64>>,
);
type Parent = 𝒯<ː<Binds<tensor::F, 𝐑𝐞𝐚𝐥::𝒞, f64, RealC>, Ø>, Ø>;
type ChildRole = <Parent as π<tensor::F>>::𝒞;
type ChildC = <Parent as π<tensor::F>>::C;
type ChildRootRole = <ChildC as π>::𝒞;
assert_same_type(PhantomData::<ChildRole>, PhantomData::<𝐑𝐞𝐚𝐥::𝒞>);
assert_same_type(PhantomData::<ChildC>, PhantomData::<RealC>);
assert_same_type(PhantomData::<ChildRootRole>, PhantomData::<𝐑𝐞𝐚𝐥::𝒞>);
type RequiresFieldChild = 𝒯<ː<Requires<tensor::F, 𝐅𝐥𝐝::𝒞>, Ø>, Ø>;
fn richer_edge_satisfies_weaker_requirement<C: Ⱶ<𝐈𝐝<RequiresFieldChild>>>() {}
richer_edge_satisfies_weaker_requirement::<Parent>();
fn child_keeps_real_information<C: Ⱶ<𝐅𝐥𝐝::𝒞> + Ⱶ<𝐑𝐞𝐚𝐥::𝒞>>() {}
child_keeps_real_information::<ChildC>();
type IncludedParent = 𝒯<ː<BindsIncluded<tensor::F, f64>, Ø>, Ø>;
type IncludedChildRole = <IncludedParent as π<tensor::F>>::𝒞;
type IncludedChildC = <IncludedParent as π<tensor::F>>::C;
assert_same_type(PhantomData::<IncludedParent>, PhantomData::<Parent>);
assert_same_type(PhantomData::<IncludedChildRole>, PhantomData::<𝐑𝐞𝐚𝐥::𝒞>);
assert_same_type(PhantomData::<IncludedChildC>, PhantomData::<RealC>);
richer_edge_satisfies_weaker_requirement::<IncludedParent>();
child_keeps_real_information::<IncludedChildC>();
fn is_constructively_not_real<C: Ⱶ<𝐑𝐞𝐚𝐥::𝒞, Absent>>() {}
is_constructively_not_real::<Model<𝐂𝐅𝐥𝐝::𝒞, f64>>();
}