diff --git a/packages/catlog-wasm/src/model.rs b/packages/catlog-wasm/src/model.rs index d81d97c7..7fdd5121 100644 --- a/packages/catlog-wasm/src/model.rs +++ b/packages/catlog-wasm/src/model.rs @@ -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. @@ -213,7 +213,7 @@ impl DblModel { #[wasm_bindgen] pub fn objects(&self) -> Vec { 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() }) } @@ -221,7 +221,7 @@ impl DblModel { #[wasm_bindgen] pub fn morphisms(&self) -> Vec { 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() }) } diff --git a/packages/catlog-wasm/src/model_morphism.rs b/packages/catlog-wasm/src/model_morphism.rs index b6a3466b..e2fd2507 100644 --- a/packages/catlog-wasm/src/model_morphism.rs +++ b/packages/catlog-wasm/src/model_morphism.rs @@ -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( @@ -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); diff --git a/packages/catlog/src/dbl/model.rs b/packages/catlog/src/dbl/model.rs index 31f70ef4..3a631d72 100644 --- a/packages/catlog/src/dbl/model.rs +++ b/packages/catlog/src/dbl/model.rs @@ -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 { - 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 { - self.objects().filter(move |ob| self.ob_gen_type(ob) == *obtype) - } - - /// Iterates over morphism generators in the model. - fn morphisms(&self) -> impl Iterator { - self.generating_graph().edges() + fn object_generators_with_type( + &self, + obtype: &Self::ObType, + ) -> impl Iterator { + 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 { - self.morphisms().filter(move |mor| self.mor_gen_type(mor) == *mortype) + fn morphism_generators_with_type( + &self, + mortype: &Self::MorType, + ) -> impl Iterator { + self.morphism_generators().filter(move |mor| self.mor_gen_type(mor) == *mortype) } } @@ -193,6 +189,11 @@ where self.theory.clone() } + /// Returns the underlying graph of the model + pub fn generating_graph(&self) -> &impl FinGraph { + self.category.generators() + } + /// Is the model freely generated? pub fn is_free(&self) -> bool { self.category.is_free() @@ -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()); @@ -309,8 +310,20 @@ where type ObGen = Id; type MorGen = Id; - fn generating_graph(&self) -> &impl FinGraph { - self.category.generating_graph() + fn object_generators(&self) -> impl Iterator { + self.category.object_generators() + } + + fn morphism_generators(&self) -> impl Iterator { + 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) } } @@ -368,11 +381,14 @@ where self.mor_types.apply(mor).unwrap().clone() } - fn objects_with_type(&self, typ: &Self::ObType) -> impl Iterator { + fn object_generators_with_type(&self, typ: &Self::ObType) -> impl Iterator { self.ob_types.preimage(typ) } - fn morphisms_with_type(&self, typ: &Self::MorType) -> impl Iterator { + fn morphism_generators_with_type( + &self, + typ: &Self::MorType, + ) -> impl Iterator { self.mor_types.preimage(typ) } } diff --git a/packages/catlog/src/dbl/model_morphism.rs b/packages/catlog/src/dbl/model_morphism.rs index e8c082c3..df5f40ba 100644 --- a/packages/catlog/src/dbl/model_morphism.rs +++ b/packages/catlog/src/dbl/model_morphism.rs @@ -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); } @@ -309,7 +309,6 @@ mod tests { use ustr::ustr; use super::*; - use crate::dbl::model::FgDblModel; use crate::stdlib::*; use crate::validate::Validate; @@ -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); @@ -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 = diff --git a/packages/catlog/src/one/category.rs b/packages/catlog/src/one/category.rs index 7d3d88ed..ceea3629 100644 --- a/packages/catlog/src/one/category.rs +++ b/packages/catlog/src/one/category.rs @@ -181,11 +181,20 @@ pub trait FgCategory: Category { /// The type of object generators. type ObGen: Eq + Into; - /// The type of morphism generators. Often Mor = Path + /// The type of morphism generators. Often Mor = Path. type MorGen: Eq + Into; - /// The graph of generating morphisms and objects - fn generating_graph(&self) -> &impl FinGraph; + /// An iterator over object generators. + fn object_generators(&self) -> impl Iterator; + + /// An iterator over morphism generators. + fn morphism_generators(&self) -> impl Iterator; + + /// 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 Graph for DiscreteCategory @@ -252,8 +261,20 @@ where type ObGen = S::Elem; type MorGen = S::Elem; - fn generating_graph(&self) -> &impl FinGraph { - self + fn object_generators(&self) -> impl Iterator { + self.0.iter() + } + + fn morphism_generators(&self) -> impl Iterator { + 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() } } @@ -264,8 +285,20 @@ where type ObGen = G::V; type MorGen = G::E; - fn generating_graph(&self) -> &impl FinGraph { - &self.0 + fn object_generators(&self) -> impl Iterator { + self.0.vertices() + } + + fn morphism_generators(&self) -> impl Iterator { + 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) } } @@ -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)); diff --git a/packages/catlog/src/one/fin_category.rs b/packages/catlog/src/one/fin_category.rs index 32cf738d..c4a48fb8 100644 --- a/packages/catlog/src/one/fin_category.rs +++ b/packages/catlog/src/one/fin_category.rs @@ -192,8 +192,20 @@ where type ObGen = V; type MorGen = E; - fn generating_graph(&self) -> &impl FinGraph { - &self.generators + fn object_generators(&self) -> impl Iterator { + self.generators.vertices() + } + + fn morphism_generators(&self) -> impl Iterator { + 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) } } @@ -399,8 +411,20 @@ where type ObGen = V; type MorGen = E; - fn generating_graph(&self) -> &impl FinGraph { - &self.generators + fn object_generators(&self) -> impl Iterator { + self.generators.vertices() + } + + fn morphism_generators(&self) -> impl Iterator { + 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) } } @@ -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); @@ -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());