Canonical Structures

Sometimes the situation is simple and we only want to define one set with structure rather than a family of sets, for example, the set of all rational numbers. Since sets with structure are represented in Algebraeon objects of structure tyes we will need a structure type with exactly once instance. This can be done explicitly like so

#![allow(unused)]
fn main() {
use algebraeon::{nzq::Rational, rings::structure::*, sets::structure::*};

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MyRational {
    value: Rational,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MyRationalCanonicalStructure {}

impl Signature for MyRationalCanonicalStructure {}

impl SetSignature for MyRationalCanonicalStructure {
    type Set = MyRational;

    fn is_element(&self, _x: &Self::Set) -> bool {
        true
    }
}

impl EqSignature for MyRationalCanonicalStructure {
    fn equal(&self, x: &Self::Set, y: &Self::Set) -> bool {
        x == y
    }
}
}

However, Algebraeon provides a derive macro CanonicalStructure which reduces the boilerplate above to

#![allow(unused)]
fn main() {
use algebraeon::{nzq::Rational, rings::structure::*, sets::structure::*};

#[derive(Debug, Clone, PartialEq, Eq, CanonicalStructure)]
pub struct MyRational {
    value: Rational,
}
}

In any case, once we have the structure type MyRationalCanonicalStructure implementing Signature + SetSignature<Set = MyRational> we can go on to implement more structure traits like RingSignature and FieldSignature for MyRationalCanonicalStructure to give the set of instances of MyRational the structure of a ring or a field.