#[macro_export]
macro_rules! define_category {
(
$(#[$cat_meta:meta])*
pub $cat_name:ident {
entity: $entity:ident,
relation: $relation:ident,
kind: $kind:ident,
kinds: [$($(#[$kind_meta:meta])* $domain_kind:ident),* $(,)?],
edges: [$(($e_from:ident, $e_to:ident, $e_kind:ident)),* $(,)?],
composed: [$(($c_from:ident, $c_to:ident)),* $(,)?],
}
) => {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[allow(dead_code)]
pub enum $kind {
Identity,
$($(#[$kind_meta])* $domain_kind,)*
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct $relation {
pub from: $entity,
pub to: $entity,
pub kind: $kind,
}
impl $crate::category::Arrow for $relation {
type Object = $entity;
type Kind = $kind;
fn source(&self) -> $entity { self.from }
fn target(&self) -> $entity { self.to }
fn kind(&self) -> $kind { self.kind }
fn meta(&self) -> $crate::ontology::meta::Provenance {
$crate::ontology::meta::Provenance {
name: $crate::ontology::meta::OntologyName::new(
format!("{:?}-[{:?}]-{:?}", self.from, self.kind, self.to)
),
description: $crate::ontology::meta::Label::new(
format!("{:?} -[{:?}]-> {:?}", self.from, self.kind, self.to)
),
citation: $crate::ontology::meta::Citation::EMPTY,
module_path: $crate::ontology::meta::ModulePath::new_static(module_path!()),
}
}
}
$(#[$cat_meta])*
pub struct $cat_name;
impl $crate::category::Category for $cat_name {
type Object = $entity;
type Morphism = $relation;
fn identity(obj: &$entity) -> $relation {
$relation { from: *obj, to: *obj, kind: $kind::Identity }
}
fn compose(f: &$relation, g: &$relation) -> Option<$relation> {
if f.to != g.from { return None; }
if f.kind == $kind::Identity { return Some(g.clone()); }
if g.kind == $kind::Identity { return Some(f.clone()); }
None
}
fn morphisms() -> Vec<$relation> {
use $crate::category::FinitelyGenerated;
let mut m = Vec::new();
for c in $entity::variants() {
m.push($relation { from: c, to: c, kind: $kind::Identity });
}
$(m.push($relation { from: $entity::$e_from, to: $entity::$e_to, kind: $kind::$e_kind });)*
m
}
}
};
}