Skip to content

Morphisms between diagrammatic instances: data structures and validation#751

Draft
kris-brown wants to merge 4 commits intomainfrom
instancemorphisms
Draft

Morphisms between diagrammatic instances: data structures and validation#751
kris-brown wants to merge 4 commits intomainfrom
instancemorphisms

Conversation

@kris-brown
Copy link
Collaborator

@kris-brown kris-brown commented Oct 6, 2025

This PR introduces a data structure for morphisms of diagrams $D:J \rightarrow C$ to $D': J'\rightarrow C$, i.e. morphisms of instances of double models. We only treat morphisms of discrete double models.

The key features associated with this are checking whether a purported diagram morphism is natural and whether two diagrammatic morphisms are presentations of the same instance morphism.

@kris-brown kris-brown self-assigned this Oct 6, 2025
@kris-brown kris-brown added core Rust core for categorical logic and general computation enhancement New feature or request labels Oct 6, 2025
@epatters epatters changed the title Initial diagrammatic morphisms + validation Morphisms between diagrammatic instances: data structures and validation Oct 6, 2025
@epatters epatters marked this pull request as draft October 6, 2025 21:27
@github-actions
Copy link

github-actions bot commented Oct 8, 2025

@github-actions github-actions bot temporarily deployed to netlify-preview March 2, 2026 20:03 Destroyed
Kris Brown added 2 commits March 3, 2026 11:05
clippy after rustup

some negative tests
using elaborator
WIP on instancemorphisms

fixes
@github-actions github-actions bot temporarily deployed to netlify-preview March 3, 2026 19:41 Destroyed
Copy link
Collaborator

@KevinDCarlson KevinDCarlson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Kris! Looks good in general but I have several little improvements to suggest.

}

/// A morphism between instances (presented as diagrams in some model of a
/// double theory) consists in an assignment, for each representable `j` in the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"representable" doesn't really parse here for me. Is it not just for any object?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally I think this will need to name the instances to be parseable.

///
/// For example, consider the schema for graphs as a model of the trivial double
/// theory. One sends some domain representable vertex `v` to the source of some
/// codomain representable edge, `e`. There may be no outgoing morphism for `e`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really follow this either.

///
///
/// Let `D: J → 𝒞` and `D': J' → 𝒞` be two diagrams. For any `j' ∈ J'`, let
/// `D'j'` be a functor `1 → 𝒞`, picking out `D'(j') ∈ 𝒞`. Consider the comma
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit overwrought to distinguish between D'j' and D'(j') like this.

/// - Its objects are pairs `(j ∈ J, D'j' → Dj ∈ Hom 𝒞)`
/// - Its morphisms are triples `(f: j₁ → j₂, s: D'j → Dj₁, t: D'j → Dj₂)` such
/// that `s;Df = t`
///
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You started out talking about instance morphisms, but now the rest just looks like morphisms of diagrams in categories?

Anyway, this is a bit heavy for a docstring, I think--I need to write it up in the math docs this week and then this can point there, hopefully.

/// This struct borrows its data to perform validation. The domain and codomain
/// are assumed to be valid models of double theories. If that is in question,
/// the models should be validated *before* validating this object.
pub struct InstanceMorphism<'a>(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if this is going to be in Dbl::ModelDiagram, it has to be parametetric, like Dbl::ModelMorphism. If it's going to have Discrete inside of it, then it should be in Discrete::ModelDiagram.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, DblModelMorphism is for some reason in Discrete itself, but then all the moreso this seems like it's in the wrong place.

panic!("Bad input D({j1:?}) = {dj1:?} != src({src:?}")
} else if *dj2 != tgt.src(g) {
panic!("Bad input D({j2:?}) = {dj2:?} != src({tgt:?}")
} else if c != tgt.tgt(g) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we also need to check c != src.tgt?

let mut seen: HashSet<(QualifiedName, QualifiedPath)> = HashSet::new();

let jg = self.1.generating_graph();
let g = model.generating_graph();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

g gets used a bunch to find the src and tgt of a path, but you can just use model.cod(&src) and stuff like that.

let iter: Box<dyn Iterator<Item = usize>> = match ziglen {
None => Box::new(0..),
Some(n) => Box::new(0..n + 1),
};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's much easier to do something like this:

for round in 0.. {
      if ziglen == Some(round) {                                  
          break;                                                              
      }                                                                       
      // ...                                                                  
  }                                                                           

};

for _ in iter {
let mut next_worklist: Vec<(QualifiedName, QualifiedPath)> = vec![];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably shouldn't allocate a fresh worklist every time through the loop. Allocate this next to worklist, and then I hear you can use std::mem::swap to freely put next_worklist into worklist instead of manually rebuilding it below.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Rust core for categorical logic and general computation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants