Skip to content

Commit 2c0dcdd

Browse files
Implement diagrams in models of a discrete double theory. (#248)
1 parent 839c8e8 commit 2c0dcdd

File tree

4 files changed

+168
-2
lines changed

4 files changed

+168
-2
lines changed

packages/catlog/src/dbl/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ pub mod diagram;
55
pub mod pasting;
66

77
pub mod model;
8+
pub mod model_diagram;
89
pub mod model_morphism;
910
pub mod theory;
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*! Diagrams in models of a double theory.
2+
3+
A diagram in a [model](super::model) consists of a [morphism](super::model_morphism)
4+
of models together with its domain, which is a free mode.
5+
6+
Diagrams are currently used primarily to represent instances of models from
7+
a fibered perspective.
8+
9+
# References
10+
11+
- TODO dev-docs
12+
*/
13+
14+
use std::hash::Hash;
15+
16+
use nonempty::NonEmpty;
17+
use thiserror::Error;
18+
19+
use super::model::DiscreteDblModel;
20+
use super::model_morphism::{DblModelMapping, DiscreteDblModelMapping};
21+
use crate::one::*;
22+
use crate::validate::{self, Validate};
23+
24+
/** A diagram in a model of a double theory defined by a [mapping](DblModelMapping).
25+
26+
This struct owns its data, namely, the domain model and the model
27+
mapping. The domain is assumed to
28+
be a valid model of a double theory. If that is in question, the
29+
model should be validated *before* validating this object.
30+
*/
31+
pub struct DblModelDiagram<Map, Dom>(pub Map, pub Dom);
32+
33+
/// A diagram in a model of a discrete double theory.
34+
pub type DiscreteDblModelDiagram<DomId, CodId, Cat> =
35+
DblModelDiagram<DiscreteDblModelMapping<DomId, CodId>, DiscreteDblModel<DomId, Cat>>;
36+
37+
impl<DomId, CodId, Cat> DiscreteDblModelDiagram<DomId, CodId, Cat>
38+
where
39+
DomId: Eq + Clone + Hash,
40+
CodId: Eq + Clone + Hash,
41+
Cat: FgCategory,
42+
Cat::Ob: Hash,
43+
Cat::Mor: Hash,
44+
{
45+
/// The domain of the diagram.
46+
pub fn domain(&self) -> &DiscreteDblModel<DomId, Cat> {
47+
&self.1
48+
}
49+
50+
/// The mapping of the diagram.
51+
pub fn mapping(&self) -> &DiscreteDblModelMapping<DomId, CodId> {
52+
&self.0
53+
}
54+
}
55+
56+
/** An invalid assignment in a double model diagram defined explicitly by data.
57+
*
58+
* Note that, by specifying a model morphism via its action on generators, we
59+
* obtain for free that identities are sent to identities and composites of
60+
* generators are sent to their composites in the codomain.
61+
*/
62+
#[derive(Debug, Error, PartialEq, Clone)]
63+
pub enum InvalidDblModelDiagram<Ob, Mor> {
64+
/// Missing data
65+
#[error("Object `{0}` is not mapped to anything in the codomain")]
66+
MissingOb(Ob),
67+
68+
/// Missing data
69+
#[error("Morphism `{0}` is not mapped to anything in the codomain")]
70+
MissingMor(Mor),
71+
}
72+
73+
impl<DomId, CodId, Cat> Validate for DiscreteDblModelDiagram<DomId, CodId, Cat>
74+
where
75+
DomId: Eq + Clone + Hash,
76+
CodId: Eq + Clone + Hash,
77+
Cat: FgCategory,
78+
Cat::Ob: Hash,
79+
Cat::Mor: Hash,
80+
{
81+
type ValidationError = InvalidDblModelDiagram<DomId, DomId>;
82+
83+
fn validate(&self) -> Result<(), NonEmpty<Self::ValidationError>> {
84+
validate::wrap_errors(self.iter_invalid())
85+
}
86+
}
87+
88+
impl<DomId, CodId, Cat> DiscreteDblModelDiagram<DomId, CodId, Cat>
89+
where
90+
DomId: Eq + Clone + Hash,
91+
CodId: Eq + Clone + Hash,
92+
Cat: FgCategory,
93+
Cat::Ob: Hash,
94+
Cat::Mor: Hash,
95+
{
96+
/// An iterator over invalid objects and morphisms in the diagram.
97+
pub fn iter_invalid(&self) -> impl Iterator<Item = InvalidDblModelDiagram<DomId, DomId>> + '_ {
98+
let DblModelDiagram(mapping, dom) = self;
99+
100+
// Diagrams can always be indexed by free models.
101+
assert!(dom.is_free(), "Domain model should be free");
102+
let ob_errors = dom.object_generators().filter_map(|v| {
103+
if mapping.apply_ob(&v).is_some() {
104+
None
105+
} else {
106+
Some(InvalidDblModelDiagram::MissingOb(v))
107+
}
108+
});
109+
110+
let mor_errors = dom.morphism_generators().flat_map(|f| {
111+
if mapping.apply_basic_mor(&f).is_some() {
112+
vec![] // No errors
113+
} else {
114+
[InvalidDblModelDiagram::MissingMor(f)].to_vec()
115+
}
116+
});
117+
118+
ob_errors.chain(mor_errors)
119+
}
120+
}
121+
122+
#[cfg(test)]
123+
mod tests {
124+
use super::*;
125+
126+
use std::sync::Arc;
127+
use ustr::ustr;
128+
129+
use crate::one::fin_category::FinMor;
130+
use crate::stdlib::*;
131+
132+
#[test]
133+
fn discrete_model_diagram() {
134+
let th = Arc::new(th_schema());
135+
let mut model = DiscreteDblModel::new(th.clone());
136+
let entity = ustr("entity");
137+
model.add_ob(entity, ustr("Entity"));
138+
model.add_ob(ustr("type"), ustr("AttrType"));
139+
model.add_mor(ustr("a"), entity, ustr("type"), FinMor::Generator(ustr("Attr")));
140+
141+
let mut f: DiscreteDblModelMapping<_, _> = Default::default();
142+
f.assign_ob(entity, 'x');
143+
f.assign_ob(ustr("type"), 'y');
144+
f.assign_basic_mor(ustr("a"), Path::pair('p', 'q'));
145+
146+
let diagram = DblModelDiagram(f.clone(), model.clone());
147+
assert_eq!(diagram.domain(), &model);
148+
assert_eq!(diagram.mapping(), &f);
149+
}
150+
151+
#[test]
152+
fn validate_model_diagram() {
153+
let theory = Arc::new(th_signed_category());
154+
let negloop = negative_loop(theory.clone());
155+
156+
let mut f: DiscreteDblModelMapping<_, _> = Default::default();
157+
f.assign_ob(ustr("x"), ustr("x"));
158+
f.assign_basic_mor(ustr(""), Path::Id(ustr("negative")));
159+
let dmd = DblModelDiagram(f, negloop);
160+
assert!(dmd.validate().is_err());
161+
// A bad map from h to itself that is wrong for the ob (it is in the map
162+
// but sent to something that doesn't exist) and for the hom generator
163+
// (not in the map)
164+
}
165+
}

packages/catlog/src/dbl/model_morphism.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ where
349349
}
350350
}
351351

352-
impl<'a, DomId, CodId, Cat> Validate for DiscreteDblModelMorphism<'a, DomId, CodId, Cat>
352+
impl<DomId, CodId, Cat> Validate for DiscreteDblModelMorphism<'_, DomId, CodId, Cat>
353353
where
354354
DomId: Eq + Clone + Hash,
355355
CodId: Eq + Clone + Hash,

packages/catlog/src/simulate/mathexpr/pprint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ impl<'a, 'b, T: DisplayWithSource> WithSource<'a, 'b, T> {
1818
}
1919
}
2020

21-
impl<'a, 'b, T> fmt::Display for WithSource<'a, 'b, T>
21+
impl<T> fmt::Display for WithSource<'_, '_, T>
2222
where
2323
T: DisplayWithSource,
2424
{

0 commit comments

Comments
 (0)