Skip to content

Commit

Permalink
don't expose generating graph
Browse files Browse the repository at this point in the history
The domain and codomain of a morphism generator should be objects, not
object generators.
  • Loading branch information
olynch committed Aug 30, 2024
1 parent cb234f2 commit 61a8e2c
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 50 deletions.
8 changes: 4 additions & 4 deletions packages/catlog-wasm/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ use tsify_next::Tsify;
use wasm_bindgen::prelude::*;

use super::theory::*;
use catlog::dbl::model::{self as dbl_model, FgDblModel, InvalidDiscreteDblModel};
use catlog::dbl::model::{self as dbl_model, InvalidDiscreteDblModel};
use catlog::one::fin_category::UstrFinCategory;
use catlog::one::Category as _;
use catlog::one::Path;
use catlog::one::{Category as _, FgCategory};
use catlog::validate::{self, Validate};

/// An object in a model of a double theory.
Expand Down Expand Up @@ -213,15 +213,15 @@ impl DblModel {
#[wasm_bindgen]
pub fn objects(&self) -> Vec<Ob> {
all_the_same!(match &self.0 {
DblModelBox::[Discrete](model) => model.objects().map(|x| x.into()).collect()
DblModelBox::[Discrete](model) => model.object_generators().map(|x| x.into()).collect()
})
}

/// Returns array of all basic morphisms in the model.
#[wasm_bindgen]
pub fn morphisms(&self) -> Vec<Mor> {
all_the_same!(match &self.0 {
DblModelBox::[Discrete](model) => model.morphisms().map( Mor::Basic).collect()
DblModelBox::[Discrete](model) => model.morphism_generators().map(Mor::Basic).collect()
})
}

Expand Down
5 changes: 3 additions & 2 deletions packages/catlog-wasm/src/model_morphism.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use std::hash::Hash;

use super::model::DblModel;
use catlog::dbl::model::{self, FgDblModel};
use catlog::dbl::model;
use catlog::dbl::model_morphism::DiscreteDblModelMapping;
use catlog::one::fin_category::UstrFinCategory;
use catlog::one::FgCategory;

/// Find motifs in a model of a discrete double theory.
pub fn motifs<Id>(
Expand All @@ -22,7 +23,7 @@ where
.collect();

// Order motifs from small to large.
images.sort_by_key(|im| (im.objects().count(), im.morphisms().count()));
images.sort_by_key(|im| (im.object_generators().count(), im.morphism_generators().count()));

// Remove duplicates: different morphisms can have the same image.
retain_unique(&mut images);
Expand Down
56 changes: 36 additions & 20 deletions packages/catlog/src/dbl/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,24 +125,20 @@ pub trait FgDblModel: DblModel + FgCategory {
/// Type of a morphism generator.
fn mor_gen_type(&self, mor: &Self::MorGen) -> Self::MorType;

/// Iterates over object generators in the model.
fn objects(&self) -> impl Iterator<Item = Self::ObGen> {
self.generating_graph().vertices()
}

/// Iterates over object generators in the model of a given object type.
fn objects_with_type(&self, obtype: &Self::ObType) -> impl Iterator<Item = Self::ObGen> {
self.objects().filter(move |ob| self.ob_gen_type(ob) == *obtype)
}

/// Iterates over morphism generators in the model.
fn morphisms(&self) -> impl Iterator<Item = Self::MorGen> {
self.generating_graph().edges()
fn object_generators_with_type(
&self,
obtype: &Self::ObType,
) -> impl Iterator<Item = Self::ObGen> {
self.object_generators().filter(move |ob| self.ob_gen_type(ob) == *obtype)
}

/// Iterates over morphism generators in the model of a given morphism type.
fn morphisms_with_type(&self, mortype: &Self::MorType) -> impl Iterator<Item = Self::MorGen> {
self.morphisms().filter(move |mor| self.mor_gen_type(mor) == *mortype)
fn morphism_generators_with_type(
&self,
mortype: &Self::MorType,
) -> impl Iterator<Item = Self::MorGen> {
self.morphism_generators().filter(move |mor| self.mor_gen_type(mor) == *mortype)
}
}

Expand Down Expand Up @@ -193,6 +189,11 @@ where
self.theory.clone()
}

/// Returns the underlying graph of the model
pub fn generating_graph(&self) -> &impl FinGraph<V = Id, E = Id> {
self.category.generators()
}

/// Is the model freely generated?
pub fn is_free(&self) -> bool {
self.category.is_free()
Expand Down Expand Up @@ -237,14 +238,14 @@ where
InvalidFpCategory::EqSrc(eq) => Invalid::EqSrc(eq),
InvalidFpCategory::EqTgt(eq) => Invalid::EqTgt(eq),
});
let ob_type_errors = self.category.generating_graph().vertices().filter_map(|x| {
let ob_type_errors = self.category.object_generators().filter_map(|x| {
if self.theory.has_ob_type(&self.ob_type(&x)) {
None
} else {
Some(Invalid::ObType(x))
}
});
let mor_type_errors = self.category.generating_graph().edges().flat_map(|f| {
let mor_type_errors = self.category.morphism_generators().flat_map(|f| {
let mut errs = Vec::new();
let e = f.clone();
let mor_type = self.mor_type(&f.into());
Expand Down Expand Up @@ -309,8 +310,20 @@ where
type ObGen = Id;
type MorGen = Id;

fn generating_graph(&self) -> &impl FinGraph<V = Id, E = Id> {
self.category.generating_graph()
fn object_generators(&self) -> impl Iterator<Item = Self::ObGen> {
self.category.object_generators()
}

fn morphism_generators(&self) -> impl Iterator<Item = Self::MorGen> {
self.category.morphism_generators()
}

fn morphism_generator_dom(&self, f: &Self::MorGen) -> Self::Ob {
self.category.morphism_generator_dom(f)
}

fn morphism_generator_cod(&self, f: &Self::MorGen) -> Self::Ob {
self.category.morphism_generator_cod(f)
}
}

Expand Down Expand Up @@ -368,11 +381,14 @@ where
self.mor_types.apply(mor).unwrap().clone()
}

fn objects_with_type(&self, typ: &Self::ObType) -> impl Iterator<Item = Self::ObGen> {
fn object_generators_with_type(&self, typ: &Self::ObType) -> impl Iterator<Item = Self::ObGen> {
self.ob_types.preimage(typ)
}

fn morphisms_with_type(&self, typ: &Self::MorType) -> impl Iterator<Item = Self::MorGen> {
fn morphism_generators_with_type(
&self,
typ: &Self::MorType,
) -> impl Iterator<Item = Self::MorGen> {
self.mor_types.preimage(typ)
}
}
Expand Down
7 changes: 3 additions & 4 deletions packages/catlog/src/dbl/model_morphism.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ where
let var = &self.var_order[depth];
match var.clone() {
GraphElem::Vertex(x) => {
for y in self.cod.objects_with_type(&self.dom.ob_type(&x)) {
for y in self.cod.object_generators_with_type(&self.dom.ob_type(&x)) {
self.map.assign_ob(x.clone(), y);
self.search(depth + 1);
}
Expand Down Expand Up @@ -309,7 +309,6 @@ mod tests {
use ustr::ustr;

use super::*;
use crate::dbl::model::FgDblModel;
use crate::stdlib::*;
use crate::validate::Validate;

Expand All @@ -330,7 +329,7 @@ mod tests {
fn find_positive_loops() {
let th = Arc::new(th_signed_category());
let positive_loop = positive_loop(th.clone());
let pos = positive_loop.morphisms().next().unwrap().into();
let pos = positive_loop.morphism_generators().next().unwrap().into();

let maps = DiscreteDblModelMapping::morphisms(&positive_loop, &positive_loop).find_all();
assert_eq!(maps.len(), 2);
Expand All @@ -349,7 +348,7 @@ mod tests {
fn find_negative_loops() {
let th = Arc::new(th_signed_category());
let negative_loop = negative_loop(th.clone());
let base_pt = negative_loop.objects().next().unwrap();
let base_pt = negative_loop.object_generators().next().unwrap();

let negative_feedback = negative_feedback(th);
let maps =
Expand Down
54 changes: 42 additions & 12 deletions packages/catlog/src/one/category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,20 @@ pub trait FgCategory: Category {
/// The type of object generators.
type ObGen: Eq + Into<Self::Ob>;

/// The type of morphism generators. Often Mor = Path<Ob, MorGen>
/// The type of morphism generators. Often Mor = Path<Ob, MorGen>.
type MorGen: Eq + Into<Self::Mor>;

/// The graph of generating morphisms and objects
fn generating_graph(&self) -> &impl FinGraph<V = Self::ObGen, E = Self::MorGen>;
/// An iterator over object generators.
fn object_generators(&self) -> impl Iterator<Item = Self::ObGen>;

/// An iterator over morphism generators.
fn morphism_generators(&self) -> impl Iterator<Item = Self::MorGen>;

/// The domain of a morphism generator
fn morphism_generator_dom(&self, f: &Self::MorGen) -> Self::Ob;

/// The codomain of a morphism generator
fn morphism_generator_cod(&self, f: &Self::MorGen) -> Self::Ob;
}

impl<S: FinSet> Graph for DiscreteCategory<S>
Expand Down Expand Up @@ -252,8 +261,20 @@ where
type ObGen = S::Elem;
type MorGen = S::Elem;

fn generating_graph(&self) -> &impl FinGraph<V = Self::Ob, E = Self::MorGen> {
self
fn object_generators(&self) -> impl Iterator<Item = Self::ObGen> {
self.0.iter()
}

fn morphism_generators(&self) -> impl Iterator<Item = Self::MorGen> {
self.0.iter()
}

fn morphism_generator_dom(&self, f: &Self::MorGen) -> Self::Ob {
f.clone()
}

fn morphism_generator_cod(&self, f: &Self::MorGen) -> Self::Ob {
f.clone()
}
}

Expand All @@ -264,8 +285,20 @@ where
type ObGen = G::V;
type MorGen = G::E;

fn generating_graph(&self) -> &impl FinGraph<V = Self::ObGen, E = Self::MorGen> {
&self.0
fn object_generators(&self) -> impl Iterator<Item = Self::ObGen> {
self.0.vertices()
}

fn morphism_generators(&self) -> impl Iterator<Item = Self::MorGen> {
self.0.edges()
}

fn morphism_generator_dom(&self, f: &Self::MorGen) -> Self::Ob {
self.0.src(f)
}

fn morphism_generator_cod(&self, f: &Self::MorGen) -> Self::Ob {
self.0.tgt(f)
}
}

Expand All @@ -292,11 +325,8 @@ mod tests {
fn free_category() {
let cat = FreeCategory::from(SkelGraph::triangle());
assert!(cat.has_ob(&2));
assert!(cat.generating_graph().has_vertex(&2));
assert_eq!(cat.generating_graph().vertices().count(), 3);
assert_eq!(cat.generating_graph().edges().count(), 3);
assert_eq!(cat.generating_graph().out_edges(&0).count(), 2);
assert_eq!(cat.generating_graph().in_edges(&2).count(), 2);
assert_eq!(cat.object_generators().count(), 3);
assert_eq!(cat.morphism_generators().count(), 3);

let id = Path::Id(1);
assert!(cat.has_mor(&id));
Expand Down
40 changes: 32 additions & 8 deletions packages/catlog/src/one/fin_category.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,20 @@ where
type ObGen = V;
type MorGen = E;

fn generating_graph(&self) -> &impl FinGraph<V = Self::Ob, E = Self::MorGen> {
&self.generators
fn object_generators(&self) -> impl Iterator<Item = Self::ObGen> {
self.generators.vertices()
}

fn morphism_generators(&self) -> impl Iterator<Item = Self::MorGen> {
self.generators.edges()
}

fn morphism_generator_dom(&self, f: &Self::MorGen) -> Self::Ob {
self.generators.src(f)
}

fn morphism_generator_cod(&self, f: &Self::MorGen) -> Self::Ob {
self.generators.tgt(f)
}
}

Expand Down Expand Up @@ -399,8 +411,20 @@ where
type ObGen = V;
type MorGen = E;

fn generating_graph(&self) -> &impl FinGraph<V = Self::Ob, E = Self::MorGen> {
&self.generators
fn object_generators(&self) -> impl Iterator<Item = Self::ObGen> {
self.generators.vertices()
}

fn morphism_generators(&self) -> impl Iterator<Item = Self::MorGen> {
self.generators.edges()
}

fn morphism_generator_dom(&self, f: &Self::MorGen) -> Self::Ob {
self.generators.src(f)
}

fn morphism_generator_cod(&self, f: &Self::MorGen) -> Self::Ob {
self.generators.tgt(f)
}
}

Expand Down Expand Up @@ -446,8 +470,8 @@ mod tests {
sch_sgraph.add_mor_generator('s', 'E', 'V');
sch_sgraph.add_mor_generator('t', 'E', 'V');
sch_sgraph.add_mor_generator('i', 'E', 'E');
assert_eq!(sch_sgraph.generating_graph().vertices().count(), 2);
assert_eq!(sch_sgraph.generating_graph().edges().count(), 3);
assert_eq!(sch_sgraph.object_generators().count(), 2);
assert_eq!(sch_sgraph.morphism_generators().count(), 3);
assert_eq!(sch_sgraph.dom(&Mor::Generator('t')), 'E');
assert_eq!(sch_sgraph.cod(&Mor::Generator('t')), 'V');
assert_eq!(sch_sgraph.validate().unwrap_err().len(), 3);
Expand Down Expand Up @@ -475,8 +499,8 @@ mod tests {
sch_sgraph.add_mor_generator('t', 'E', 'V');
sch_sgraph.add_mor_generator('i', 'E', 'E');
assert!(sch_sgraph.is_free());
assert_eq!(sch_sgraph.generating_graph().vertices().count(), 2);
assert_eq!(sch_sgraph.generating_graph().edges().count(), 3);
assert_eq!(sch_sgraph.object_generators().count(), 2);
assert_eq!(sch_sgraph.morphism_generators().count(), 3);
assert_eq!(sch_sgraph.dom(&Path::single('t')), 'E');
assert_eq!(sch_sgraph.cod(&Path::single('t')), 'V');
assert!(sch_sgraph.validate().is_ok());
Expand Down

0 comments on commit 61a8e2c

Please sign in to comment.