diff --git a/FiniteCocompletions/gap/CategoryOfColimitQuivers.gd b/FiniteCocompletions/gap/CategoryOfColimitQuivers.gd
index 7ca7c8596..6826a2db0 100644
--- a/FiniteCocompletions/gap/CategoryOfColimitQuivers.gd
+++ b/FiniteCocompletions/gap/CategoryOfColimitQuivers.gd
@@ -118,6 +118,15 @@ CapJitAddTypeSignature( "FiniteColimitCompletionWithStrictCoproductsOfUnderlying
end );
+#! @Description
+#! The inputs are a colimit quiver colim_quiver in the category $C$
+#! and a list vertices of objects in $C$.
+#! The output is the full colimit subquiver on these objects.
+#! @Returns a monomorphism of colimit quivers
+#! @Arguments colim_quiver, vertices
+DeclareOperation( "EmbeddingOfFullColimitSubquiver",
+ [ IsObjectInCategoryOfColimitQuivers, IsList ] );
+
####################################
#
#! @Section Constructors
diff --git a/FiniteCocompletions/gap/CategoryOfColimitQuivers.gi b/FiniteCocompletions/gap/CategoryOfColimitQuivers.gi
index d52bae014..b20b72889 100644
--- a/FiniteCocompletions/gap/CategoryOfColimitQuivers.gi
+++ b/FiniteCocompletions/gap/CategoryOfColimitQuivers.gi
@@ -349,6 +349,65 @@ InstallMethod( CategoryOfPreSheavesOfUnderlyingCategory,
end );
+##
+InstallMethod( CategoryOfPreSheavesOfUnderlyingCategory,
+ [ IsCategoryOfColimitQuivers ],
+
+ function( ColimitQuiversC )
+
+ return PreSheaves( UnderlyingCategory( ColimitQuiversC ) );
+
+end );
+
+##
+InstallOtherMethodForCompilerForCAP( EmbeddingOfFullColimitSubquiver,
+ [ IsCategoryOfColimitQuivers, IsObjectInCategoryOfColimitQuivers, IsList ],
+
+ function( ColimitQuiversC, colim_quiver, list_of_objects )
+ local C, vertices_arrows, vertices, arrows, positions, V, id, A, colim_subquiver, embedding;
+
+ C := UnderlyingCategory( ColimitQuiversC );
+
+ vertices_arrows := ObjectDatum( ColimitQuiversC, colim_quiver );
+
+ vertices := vertices_arrows[1];
+ arrows := vertices_arrows[2];
+
+ positions := List( vertices, vertex ->
+ PositionProperty( list_of_objects, obj -> IsEqualForObjects( C, obj, vertex ) ) );
+
+ V := Filtered( [ 0 .. Length( vertices ) - 1 ], i -> IsInt( positions[1 + i] ) );
+
+ id := List( list_of_objects, obj -> IdentityMorphism( C, obj ) );
+
+ A := Filtered( [ 0 .. Length( arrows ) - 1 ], j ->
+ ( arrows[1 + j][1] in V ) and ( arrows[1 + j][3] in V ) );
+
+ colim_subquiver := CreateColimitQuiver( ColimitQuiversC,
+ Pair( vertices{1 + V}, arrows{1 + A} ) );
+
+ embedding := CreateMorphismOfColimitQuivers( ColimitQuiversC,
+ colim_subquiver,
+ Pair( Pair( V, id{positions{1 + V}} ),
+ A ),
+ colim_quiver );
+ #% CAP_JIT_DROP_NEXT_STATEMENT
+ SetIsMonomorphism( embedding, true );
+
+ return embedding;
+
+end );
+
+##
+InstallMethod( EmbeddingOfFullColimitSubquiver,
+ [ IsObjectInCategoryOfColimitQuivers, IsList ],
+
+ function( colim_quiver, list_of_objects )
+
+ return EmbeddingOfFullColimitSubquiver( CapCategory( colim_quiver ), colim_quiver, list_of_objects );
+
+end );
+
####################################
#
# View, Print, Display and LaTeX methods:
diff --git a/FpCategories/gap/PathCategories.gd b/FpCategories/gap/PathCategories.gd
index cbddd65c3..b666b68fe 100644
--- a/FpCategories/gap/PathCategories.gd
+++ b/FpCategories/gap/PathCategories.gd
@@ -173,5 +173,11 @@ DeclareAttribute( "ExternalHoms", IsPathCategory );
#
####################################
+DeclareAttribute( "DecompositionIndicesOfMorphism",
+ IsPathCategoryMorphism );
+
+DeclareAttribute( "DecompositionOfMorphismInCategory",
+ IsPathCategoryMorphism );
+
DeclareOperation( "ExtendFunctorToFpCategoryData",
[ IsPathCategory, IsList, IsCapCategory ] );
diff --git a/FpCategories/gap/PathCategories.gi b/FpCategories/gap/PathCategories.gi
index 8c25ed9c0..6281e7098 100644
--- a/FpCategories/gap/PathCategories.gi
+++ b/FpCategories/gap/PathCategories.gi
@@ -1066,6 +1066,42 @@ InstallOtherMethod( ExternalHoms,
end );
+##
+InstallOtherMethodForCompilerForCAP( DecompositionIndicesOfMorphism,
+ "for a path category and a morphism therein",
+ [ IsPathCategory, IsPathCategoryMorphism ],
+
+ function( C, mor )
+
+ return List( MorphismIndices( mor ), i -> -1 + i );
+
+end );
+
+##
+InstallMethod( DecompositionIndicesOfMorphism,
+ "for a morphism in a path category",
+ [ IsPathCategoryMorphism ],
+
+ function( mor )
+
+ return DecompositionIndicesOfMorphism( CapCategory( mor ), mor );
+
+end );
+
+##
+InstallMethod( DecompositionOfMorphismInCategory,
+ "for a morphism in a path category",
+ [ IsPathCategoryMorphism ],
+
+ function( mor )
+ local C;
+
+ C := CapCategory( mor );
+
+ return SetOfGeneratingMorphisms( C ){1 + DecompositionIndicesOfMorphism( mor )};
+
+end );
+
##
InstallMethod( DatumOfCellAsEvaluatableString,
[ IsPathCategoryMorphism, IsList ],
diff --git a/FunctorCategories/examples/ColimitingCocone.g b/FunctorCategories/examples/ColimitingCocone.g
new file mode 100644
index 000000000..66efa0602
--- /dev/null
+++ b/FunctorCategories/examples/ColimitingCocone.g
@@ -0,0 +1,35 @@
+#! @Chunk ColimitingCocone
+
+#! @Example
+LoadPackage( "FunctorCategories", false );
+#! true
+q := "q(a,l,m,r,i,i1,i2,c,b)[ac:a->c,lc:l->c,mi:m->i,ic:i->c,ri1:r->i1,i1i2:i1->i2,i2c:i2->c,cb:c->b]";;
+q := RightQuiver( q );
+#! RightQuiver( "" );
+F := FreeCategory( q );
+#F := PathCategory( q );
+#! FreeCategory(
+#! RightQuiver( "" ) );
+Size( F );
+#! 7
+PSh := PreSheaves( F );
+#! PreSheaves( FreeCategory(
+#! RightQuiver( "" ) ) );
+#! SkeletalFinSets )
+Y := YonedaEmbeddingOfSourceCategory( PSh );
+#! Yoneda embedding functor
+coprd_cocone := [ F.c, [ F.lc, F.mi * F.ic, F.ri1 * F.i1i2 * F.i2c ] ];
+#coprd_cocone := [ F.c, [ F.ac, F.lc ] ];
+is_closed := G -> IsClosedPreSheafWRTCoproductCocones( PSh, G, [ coprd_cocone ] );
+#! function( G ) ... end
+G := Coproduct( [ PSh.a, PSh.a, PSh.l, PSh.m, PSh.r, PSh.r, PSh.c, PSh.b ] );
+#G := Coproduct( [ PSh.a, PSh.l, PSh.l ] );
+#!
+emb := EmbeddingIntoClosureOfPreSheafWRTCoproductCocones( G, [ coprd_cocone ] );
+Assert( 0, IsWellDefined( emb ) );
+Assert( 0, IsMonomorphism( emb ) );
+Assert( 0, Source( emb ) = G );
+Assert( 0, is_closed( Target( emb ) ) );
+#! @EndExample
diff --git a/FunctorCategories/examples/JoinCocone.g b/FunctorCategories/examples/JoinCocone.g
new file mode 100644
index 000000000..f95c65d51
--- /dev/null
+++ b/FunctorCategories/examples/JoinCocone.g
@@ -0,0 +1,41 @@
+#! @Chunk JoinCocone
+
+#! @Example
+LoadPackage( "FunctorCategories", false );
+#! true
+q := FinQuiver( "q(a,l,r,i,c,b)[ac:a->c,lc:l->c,ri:r->i,ic:i->c,cb:c->b]" );
+#! FinQuiver( "q(a,l,r,i,c,b)[ac:a-≻c,lc:l-≻c,ri:r-≻i,ic:i-≻c,cb:c-≻b]" )
+F := PathCategory( q );
+#! PathCategory(
+#! FinQuiver( "q(a,l,r,i,c,b)[ac:a-≻c,lc:l-≻c,ri:r-≻i,ic:i-≻c,cb:c-≻b]" ) )
+Size( F );
+#! 16
+P := PosetOfCategory( F );
+#! PosetOfCategory( PathCategory(
+#! FinQuiver( "q(a,l,r,i,c,b)[ac:a-≻c,lc:l-≻c,ri:r-≻i,ic:i-≻c,cb:c-≻b]" ) ) )
+Size( P );
+#! 16
+PSh := PreSheaves( P );
+#! PreSheaves( PosetOfCategory( PathCategory(
+#! FinQuiver( "q(a,l,r,i,c,b)[ac:a-≻c,lc:l-≻c,ri:r-≻i,ic:i-≻c,cb:c-≻b]" ) ) ),
+#! IntervalCategory )
+Y := YonedaEmbeddingOfSourceCategory( PSh );
+#! Yoneda embedding functor
+coprd_cocone := [ P.c, [ P.l, P.r ] ];;
+#! [ [ An object in the poset given by: (c),
+#! [ An object in the poset given by: (l),
+#! An object in the poset given by: (r) ] ] ]
+is_closed := G -> IsClosedPreSheafWRTCoproducts( PSh, G, [ coprd_cocone ] );
+#! function( G ) ... end
+PShJ := FullSubcategoryByObjectMembershipFunction( PSh, is_closed );
+#Splash( DotVertexLabelledDigraph( PSh, [ Y, PShJ ], [ "grey", "blue", "red" ] ) );
+G := Coproduct( [ PSh.l, PSh.r ] );
+emb := EmbeddingIntoClosureOfPreSheafWRTCoproducts( G, [ coprd_cocone ] );
+#Assert( 0, IsWellDefined( emb ) );
+Assert( 0, IsMonomorphism( emb ) );
+Assert( 0, Source( emb ) = G );
+Assert( 0, is_closed( Target( emb ) ) );
+closed := List( SetOfObjects( PSh ), G -> Target( EmbeddingIntoClosureOfPreSheafWRTCoproducts( G, [ coprd_cocone ] ) ) );
+Assert( 0, ForAll( closed, is_closed ) );
+Assert( 0, Length( SetOfObjects( PShJ ) ) = Length( DuplicateFreeList( closed ) ) );
+#! @EndExample
diff --git a/FunctorCategories/gap/PreSheaves.gd b/FunctorCategories/gap/PreSheaves.gd
index 7791785ab..0506d57da 100644
--- a/FunctorCategories/gap/PreSheaves.gd
+++ b/FunctorCategories/gap/PreSheaves.gd
@@ -393,6 +393,10 @@ DeclareAttribute( "CoequalizerDataOfPreSheafUsingOptimizedCoYonedaLemma",
DeclareAttribute( "AssociatedCoequalizerPairInPreSheaves",
IsObjectInCategoryOfColimitQuivers );
+#! @Arguments F
+DeclareAttribute( "AssociatedCellInPreSheaves",
+ IsCellInCategoryOfColimitQuivers );
+
#! @Arguments F
DeclareAttribute( "AssociatedCoequalizerPairInPreSheaves",
IsObjectInFiniteColimitCompletionWithStrictCoproducts );
@@ -417,3 +421,27 @@ DeclareOperation( "ApplyPreSheafToMorphismInFiniteStrictCoproductCompletion",
#! @Arguments C
DeclareAttribute( "CategoryOfInternalCategories",
IsCapCategory );
+
+#! @Arguments PSh, presheaf, coproducts_cocones
+DeclareOperation( "IsClosedPreSheafWRTCoproductCocones",
+ [ IsObjectInPreSheafCategory, IsList ] );
+
+#! @Arguments PSh, presheaf, lists_of_cofactors
+DeclareOperation( "IsClosedPreSheafWRTCoproducts",
+ [ IsObjectInPreSheafCategory, IsList ] );
+
+#! @Arguments presheaf, lists_of_indices
+DeclareOperation( "IsClosedPreSheafWRTCoproductsByIndices",
+ [ IsObjectInPreSheafCategory, IsList ] );
+
+#! @Arguments presheaf, coproduct_cocone
+DeclareOperation( "EmbeddingIntoClosureOfPreSheafWRTCoproductCocone",
+ [ IsObjectInPreSheafCategory, IsList ] );
+
+#! @Arguments presheaf, coproducts_cocones
+DeclareOperation( "EmbeddingIntoClosureOfPreSheafWRTCoproductCocones",
+ [ IsObjectInPreSheafCategory, IsList ] );
+
+#! @Arguments presheaf, lists_of_cofactors
+DeclareOperation( "EmbeddingIntoClosureOfPreSheafWRTCoproducts",
+ [ IsObjectInPreSheafCategory, IsList ] );
diff --git a/FunctorCategories/gap/PreSheaves.gi b/FunctorCategories/gap/PreSheaves.gi
index fb676bd42..3193c5565 100644
--- a/FunctorCategories/gap/PreSheaves.gi
+++ b/FunctorCategories/gap/PreSheaves.gi
@@ -3239,6 +3239,80 @@ InstallMethod( AssociatedCoequalizerPairInPreSheaves,
end );
+##
+InstallOtherMethodForCompilerForCAP( AssociatedCellInPreSheaves,
+ "for a category of colimit quivers and an object therein",
+ [ IsCategoryOfColimitQuivers, IsObjectInCategoryOfColimitQuivers ],
+
+ function( ColimitQuiversC, colimit_quiver )
+ local PSh, coequalizer_pair;
+
+ PSh := CategoryOfPreSheavesOfUnderlyingCategory( ColimitQuiversC );
+
+ coequalizer_pair := AssociatedCoequalizerPairInPreSheaves( ColimitQuiversC, colimit_quiver );
+
+ return Coequalizer( PSh, coequalizer_pair[1], coequalizer_pair[2] );
+
+end );
+
+##
+InstallOtherMethodForCompilerForCAP( AssociatedCellInPreSheaves,
+ "for a category of colimit quivers, two objects and a morphism therein",
+ [ IsCategoryOfColimitQuivers, IsObjectInPreSheafCategoryOfFpEnrichedCategory, IsMorphismInCategoryOfColimitQuivers, IsObjectInPreSheafCategoryOfFpEnrichedCategory ],
+
+ function( ColimitQuiversC, source, colimit_quiver_morphism, target )
+ local ParallelPairs, PSh_VA, mor_VA, S, T, V, A, PSh, Yoneda, Y_V, Y_A;
+
+ ParallelPairs := ModelingCategory( ColimitQuiversC );
+
+ PSh_VA := ModelingCategory( ParallelPairs );
+
+ mor_VA := MorphismDatum( PSh_VA,
+ ModelingMorphism( ParallelPairs,
+ ModelingMorphism( ColimitQuiversC, colimit_quiver_morphism ) ) );
+
+ V := mor_VA[1];
+
+ PSh := CategoryOfPreSheavesOfUnderlyingCategory( ColimitQuiversC );
+
+ Yoneda := EmbeddingFunctorOfFiniteStrictCoproductCompletionIntoPreSheavesData( PSh )[2];
+
+ Y_V := Yoneda[2]( Yoneda[1]( Source( V ) ), V, Yoneda[1]( Target( V ) ) );
+
+ return CoequalizerFunctorialWithGivenCoequalizers( PSh,
+ source,
+ AssociatedCoequalizerPairInPreSheaves( ColimitQuiversC, Source( colimit_quiver_morphism ) )[2],
+ Y_V,
+ AssociatedCoequalizerPairInPreSheaves( ColimitQuiversC, Target( colimit_quiver_morphism ) )[2],
+ target );
+
+end );
+
+##
+InstallOtherMethod( AssociatedCellInPreSheaves,
+ "for a category of colimit quivers and an morphism therein",
+ [ IsCategoryOfColimitQuivers, IsMorphismInCategoryOfColimitQuivers ],
+
+ function( ColimitQuiversC, colimit_quiver_morphism )
+
+ return AssociatedCellInPreSheaves( ColimitQuiversC,
+ AssociatedCellInPreSheaves( Source( colimit_quiver_morphism ) ),
+ colimit_quiver_morphism,
+ AssociatedCellInPreSheaves( Target( colimit_quiver_morphism ) ) );
+
+end );
+
+##
+InstallOtherMethod( AssociatedCellInPreSheaves,
+ "for a category of colimit quivers and a cell therein",
+ [ IsCellInCategoryOfColimitQuivers ],
+
+ function( colimit_quiver_cell )
+
+ return AssociatedCellInPreSheaves( CapCategory( colimit_quiver_cell ), colimit_quiver_cell );
+
+end );
+
##
InstallOtherMethodForCompilerForCAP( AssociatedCoequalizerPairInPreSheaves,
"for the finite colimit completion of a category and an object therein",
@@ -4570,6 +4644,260 @@ InstallMethod( SimpleObjects,
end );
+####################################
+#
+# Methods for operations
+#
+####################################
+
+##
+InstallOtherMethodForCompilerForCAP( IsClosedPreSheafWRTCoproductCocones,
+ [ IsPreSheafCategory, IsObjectInPreSheafCategory, IsList ],
+
+ function( PSh, presheaf, list_of_coproduct_cones )
+ local H, coproducts, cocones;
+
+ H := Target( PSh );
+
+ coproducts := List( list_of_coproduct_cones, cocone -> cocone[1] );
+ cocones := List( list_of_coproduct_cones, cocone -> cocone[2] );
+
+ return ForAll( [ 1 .. Length( coproducts ) ], i ->
+ IsIsomorphism( H,
+ UniversalMorphismIntoDirectProduct( H,
+ List( cocones[i], morphism ->
+ ApplyObjectInPreSheafCategoryOfFpEnrichedCategoryToObject( PSh, presheaf, Source( morphism ) ) ),
+ ApplyObjectInPreSheafCategoryOfFpEnrichedCategoryToObject( PSh, presheaf, coproducts[i] ),
+ List( cocones[i], morphism ->
+ ApplyObjectInPreSheafCategoryOfFpEnrichedCategoryToMorphism( PSh, presheaf, morphism ) ) ) ) );
+
+end );
+
+##
+InstallOtherMethodForCompilerForCAP( IsClosedPreSheafWRTCoproducts,
+ [ IsPreSheafCategory and IsThinCategory, IsObjectInPreSheafCategory, IsList ],
+
+ function( PSh, presheaf, list_of_coproducts )
+ local P, coproducts, cocones, list_of_coproduct_cones;
+
+ P := Source( PSh );
+
+ if not CanCompute( P, "UniqueMorphism" ) then
+ Error( "the poset `P := Source( PSh )` cannot compute the categorical operation `UniqueMorphism`\n" );
+ fi;
+
+ coproducts := List( list_of_coproducts, cocone -> cocone[1] );
+ cocones := List( list_of_coproducts, cocone -> List( cocone[2], cofactor -> UniqueMorphism( P, cofactor, cocone[1] ) ) );
+
+ list_of_coproduct_cones := ListN( coproducts, cocones, { coproduct, cocone } -> [ coproduct, cocone ] );
+
+ return IsClosedPreSheafWRTCoproductCocones( PSh, presheaf, list_of_coproduct_cones );
+
+end );
+
+##
+InstallOtherMethodForCompilerForCAP( IsClosedPreSheafWRTCoproductsByIndices,
+ [ IsPreSheafCategory and IsThinCategory, IsObjectInPreSheafCategory, IsList ],
+
+ function( PSh, presheaf, list_of_coproducts_by_indices )
+ local offset, P, objects, coproducts, cofactors, list_of_coproducts;
+
+ offset := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "offset", 0 );
+
+ P := Source( PSh );
+
+ objects := SetOfObjects( P );
+
+ coproducts := List( list_of_coproducts_by_indices, cocone -> objects[offset + cocone[1]] );
+ cofactors := List( list_of_coproducts_by_indices, cocone -> List( cocone[2], i -> objects[offset + i] ) );
+
+ list_of_coproducts := ListN( coproducts, cofactors, { coproduct, cofactor } -> [ coproduct, cofactor ] );
+
+ return IsClosedPreSheafWRTCoproducts( PSh, presheaf, list_of_coproducts );
+
+end );
+
+##
+InstallOtherMethodForCompilerForCAP( EmbeddingIntoClosureOfPreSheafWRTCoproductCocone,
+ [ IsPreSheafCategory, IsObjectInPreSheafCategory, IsList ],
+
+ function( PSh, presheaf, coproduct_cocone )
+ local C, H, C_hat, ColimitQuiversC, objects, id_objects,
+ colim_quiver_of_presheaf, vertices_arrows, vertices, arrows, v, vertices_indices,
+ coproduct, id_coproduct, c, coproduct_index, coproduct_indices_in_vertices,
+ cocone, l, diagram, diagram_indices, diagram_indices_in_vertices,
+ direct_product_diagram, direct_product, universal_morphism, universal_map, projection_morphisms, projection_maps,
+ d, additional_vertices, additional_arrows_in, additional_arrows_out, closure_of_colim_quiver_of_presheaf, embedding;
+
+ ## categories
+ C := Source( PSh );
+ H := Target( PSh );
+
+ C_hat := FiniteColimitCompletionWithStrictCoproductsOfSourceCategory( PSh );
+
+ ColimitQuiversC := CategoryOfColimitQuiversOfSourceCategory( PSh );
+
+ objects := SetOfObjects( C );
+
+ id_objects := List( objects, o -> IdentityMorphism( C, o ) );
+
+ ## presheaf
+ colim_quiver_of_presheaf := AssociatedColimitQuiver( C_hat, CoYonedaLemmaOnObjects( presheaf ) );
+
+ vertices_arrows := ObjectDatum( ColimitQuiversC, colim_quiver_of_presheaf );
+
+ vertices := vertices_arrows[1];
+ arrows := vertices_arrows[2];
+
+ v := Length( vertices );
+
+ vertices_indices := List( vertices, vertex -> -1 + SafeUniquePositionProperty( objects, o -> IsEqualForObjects( C, vertex, o ) ) );
+
+ ## coproduct
+ coproduct := coproduct_cocone[1];
+
+ id_coproduct := IdentityMorphism( C, coproduct );
+
+ c := presheaf( coproduct );
+
+ coproduct_index := -1 + SafeUniquePositionProperty( objects, o -> IsEqualForObjects( C, coproduct_cocone[1], o ) );
+
+ coproduct_indices_in_vertices := Positions( vertices_indices, coproduct_index );
+
+ ## cocone
+ cocone := coproduct_cocone[2];
+
+ l := Length( cocone );
+
+ ## diagram
+ diagram := List( cocone, Source );
+
+ diagram_indices := List( diagram, obj ->
+ -1 + SafeUniquePositionProperty( objects, o -> IsEqualForObjects( C, obj, o ) ) );
+
+ diagram_indices_in_vertices := List( diagram_indices, i -> Positions( vertices_indices, i ) );
+
+ ## direct product
+ direct_product_diagram := List( diagram, presheaf );
+
+ direct_product := DirectProduct( H, direct_product_diagram );
+
+ universal_morphism := UniversalMorphismIntoDirectProductWithGivenDirectProduct( H,
+ direct_product_diagram,
+ c,
+ List( cocone, presheaf ),
+ direct_product );
+
+ universal_map := MorphismDatum( H, universal_morphism );
+
+ projection_morphisms := List( [ 1 .. l ], p ->
+ ProjectionInFactorOfDirectProductWithGivenDirectProduct( H,
+ direct_product_diagram,
+ p,
+ direct_product ) );
+
+ projection_maps := List( [ 1 .. l ], p -> AsList( projection_morphisms[p] ) );
+
+ d := Length( direct_product );
+
+ ## closure of colimit quiver of presheaf
+ additional_vertices := ListWithIdenticalEntries( d, coproduct );
+
+ additional_arrows_in := List( [ 0 .. Length( c ) - 1 ], i ->
+ Triple( v + universal_map[1 + i], id_coproduct, -1 + coproduct_indices_in_vertices[1 + i] ) );
+
+ additional_arrows_out := List( [ 1 .. l ], p ->
+ List( [ 0 .. d - 1 ], i ->
+ Triple( -1 + diagram_indices_in_vertices[p][1 + projection_maps[p][1 + i]], cocone[p], v + i ) ) );
+
+ closure_of_colim_quiver_of_presheaf := CreateColimitQuiver( ColimitQuiversC,
+ Pair( Concatenation( vertices, additional_vertices ),
+ Concatenation( arrows, additional_arrows_in, Concatenation( additional_arrows_out ) ) ) );
+
+ embedding := CreateMorphismOfColimitQuivers( ColimitQuiversC,
+ colim_quiver_of_presheaf,
+ Pair( Pair( [ 0 .. v - 1 ], id_objects{1 + vertices_indices} ),
+ [ 0 .. Length( arrows ) - 1 ] ),
+ closure_of_colim_quiver_of_presheaf );
+
+ return AssociatedCellInPreSheaves( ColimitQuiversC, embedding );
+
+end );
+
+##
+InstallMethod( EmbeddingIntoClosureOfPreSheafWRTCoproductCocone,
+ [ IsObjectInPreSheafCategory, IsList ],
+
+ function( presheaf, coproduct_cocone )
+
+ return EmbeddingIntoClosureOfPreSheafWRTCoproductCocone( CapCategory( presheaf ), presheaf, coproduct_cocone );
+
+end );
+
+##
+InstallOtherMethodForCompilerForCAP( EmbeddingIntoClosureOfPreSheafWRTCoproductCocones,
+ [ IsPreSheafCategory, IsObjectInPreSheafCategory, IsList ],
+
+ function( PSh, presheaf, coproduct_cocones )
+ local func;
+
+ func :=
+ function( embedding, cocone )
+ return PreCompose( PSh,
+ embedding,
+ EmbeddingIntoClosureOfPreSheafWRTCoproductCocone( PSh,
+ Target( embedding ),
+ cocone ) );
+ end;
+
+ return Iterated( coproduct_cocones,
+ func,
+ IdentityMorphism( PSh, presheaf ) );
+
+end );
+
+##
+InstallMethod( EmbeddingIntoClosureOfPreSheafWRTCoproductCocones,
+ [ IsObjectInPreSheafCategory, IsList ],
+
+ function( presheaf, coproduct_cocones )
+
+ return EmbeddingIntoClosureOfPreSheafWRTCoproductCocones( CapCategory( presheaf ), presheaf, coproduct_cocones );
+
+end );
+
+##
+InstallOtherMethodForCompilerForCAP( EmbeddingIntoClosureOfPreSheafWRTCoproducts,
+ [ IsPreSheafCategory and IsThinCategory, IsObjectInPreSheafCategory, IsList ],
+
+ function( PSh, presheaf, list_of_coproducts )
+ local P, coproducts, cocones, list_of_coproduct_cones;
+
+ P := Source( PSh );
+
+ if not CanCompute( P, "UniqueMorphism" ) then
+ Error( "the poset `P := Source( PSh )` cannot compute the categorical operation `UniqueMorphism`\n" );
+ fi;
+
+ coproducts := List( list_of_coproducts, cocone -> cocone[1] );
+ cocones := List( list_of_coproducts, cocone -> List( cocone[2], cofactor -> UniqueMorphism( P, cofactor, cocone[1] ) ) );
+
+ list_of_coproduct_cones := ListN( coproducts, cocones, { coproduct, cocone } -> [ coproduct, cocone ] );
+
+ return EmbeddingIntoClosureOfPreSheafWRTCoproductCocones( PSh, presheaf, list_of_coproduct_cones );
+
+end );
+
+##
+InstallMethod( EmbeddingIntoClosureOfPreSheafWRTCoproducts,
+ [ IsObjectInPreSheafCategory, IsList ],
+
+ function( presheaf, list_of_coproducts )
+
+ return EmbeddingIntoClosureOfPreSheafWRTCoproducts( CapCategory( presheaf ), presheaf, list_of_coproducts );
+
+end );
+
####################################
#
# View, Print, Display and LaTeX methods:
diff --git a/Locales/examples/DifferenceCSL.g b/Locales/examples/DifferenceCSL.g
new file mode 100644
index 000000000..138a65c95
--- /dev/null
+++ b/Locales/examples/DifferenceCSL.g
@@ -0,0 +1,85 @@
+#! @Chunk DifferenceCSL
+
+# the assumption si <= mi leads to fewer meets and joins:
+
+#! @Example
+LoadPackage( "FunctorCategories", false );
+#! true
+q := "q(m0,s0,m1,s1,m2,s2,m0_x_s1,s0_u_m1,m1_x_s2,s1_u_m2)\
+[sm0:s0->m0,sm1:s1->m1,sm2:s2->m2,\
+p011:m0_x_s1->s1,\
+i101:m1->s0_u_m1,\
+p122:m1_x_s2->s2,\
+i212:m2->s1_u_m2,\
+mc0:m0_x_s1->s0,jc0:m0->s0_u_m1,\
+mc1:m1_x_s2->s1,jc1:m1->s1_u_m2]";;
+q := FinQuiver( q );
+#! FinQuiver( "q(m0,s0,m1,s1,m2,s2,m0_x_s1,s0_u_m1,m1_x_s2,s1_u_m2)
+#! [sm0:s0-≻m0,sm1:s1-≻m1,sm2:s2-≻m2,
+#! p011:m0_x_s1-≻s1,
+#! i101:m1-≻s0_u_m1,
+#! p122:m1_x_s2-≻s2,
+#! i212:m2-≻s1_u_m2,
+#! mc0:m0_x_s1-≻s0,jc0:m0-≻s0_u_m1,
+#! mc1:m1_x_s2-≻s1,jc1:m1-≻s1_u_m2]" )
+F := PathCategory( q );
+#! PathCategory( FinQuiver( "q(m0,s0,m1,s1,m2,s2,m0_x_s1,s0_u_m1,m1_x_s2,s1_u_m2)
+#! [sm0:s0-≻m0,sm1:s1-≻m1,sm2:s2-≻m2,
+#! p011:m0_x_s1-≻s1,
+#! i101:m1-≻s0_u_m1,
+#! p122:m1_x_s2-≻s2,
+#! i212:m2-≻s1_u_m2,
+#! mc0:m0_x_s1-≻s0,jc0:m0-≻s0_u_m1,
+#! mc1:m1_x_s2-≻s1,jc1:m1-≻s1_u_m2]" ) )
+Size( F );
+#! 35
+HomStructure( F.s0, F.s0_u_m1 );
+#! |1|
+HomStructure( F.s1, F.s1_u_m2 );
+#! |1|
+HomStructure( F.m0_x_s1, F.m0 );
+#! |1|
+HomStructure( F.m1_x_s2, F.m1 );
+#! |1|
+C := F /
+ [ [ F.p011 * F.sm1 * F.i101, F.mc0 * F.sm0 * F.jc0 ],
+ [ F.p122 * F.sm2 * F.i212, F.mc1 * F.sm1 * F.jc1 ] ];
+#! PathCategory( FinQuiver( "q(m0,s0,m1,s1,m2,s2,m0_x_s1,s0_u_m1,m1_x_s2,s1_u_m2)
+#! [sm0:s0-≻m0,sm1:s1-≻m1,sm2:s2-≻m2,
+#! p011:m0_x_s1-≻s1,
+#! i101:m1-≻s0_u_m1,
+#! p122:m1_x_s2-≻s2,
+#! i212:m2-≻s1_u_m2,
+#! mc0:m0_x_s1-≻s0,jc0:m0-≻s0_u_m1,
+#! mc1:m1_x_s2-≻s1,jc1:m1-≻s1_u_m2]" ) )
+#! / [ p011⋅sm1⋅i101 = mc0⋅sm0⋅jc0, p122⋅sm2⋅i212 = mc1⋅sm1⋅jc1 ]
+Size( C );
+#! 33
+P := PosetOfCategory( F );;
+Size( P );
+#! 33
+digraphF := DigraphOfPoset( P );;
+digraphF!.vertexlabels := List( SetOfObjects( F ), String );
+#Splash( DotVertexLabelledDigraph( digraphF ) );
+PSh := PreSheaves( P );;
+Y := YonedaEmbeddingOfSourceCategory( PSh );
+#! Yoneda embedding functor
+
+coprd_cocones := [ [ P.s1_u_m2, [ P.s1, P.m2 ] ],
+ [ P.s0_u_m1, [ P.s0, P.m1 ] ] ];; ## the order is important
+
+is_closed := G -> IsClosedPreSheafWRTCoproducts( PSh, G, coprd_cocones );;
+PShJ := FullSubcategoryByObjectMembershipFunction( PSh, is_closed );;
+Length( SetOfObjects( PSh ) );
+#! 41
+Length( SetOfObjects( PShJ ) );
+#! 28
+#Splash( DotVertexLabelledDigraph( PSh, [ Y, PShJ ], [ "grey", "blue", "red" ] ) );
+closed := List( SetOfObjects( PSh ), G -> Target( EmbeddingIntoClosureOfPreSheafWRTCoproducts( G, coprd_cocones ) ) );
+Assert( 0, ForAll( closed, is_closed ) );
+Assert( 0, Length( SetOfObjects( PShJ ) ) = Length( DuplicateFreeList( closed ) ) );
+
+#coPSh := CoPreSheaves( PShJ );
+#objs := SetOfObjects( coPSh ); ## took 122h 15m to compute
+#Length( objs ); ## 728
+#! @EndExample
diff --git a/Locales/examples/FreeBooleanAlgebra.g b/Locales/examples/FreeBooleanAlgebra.g
new file mode 100644
index 000000000..ea32f8b92
--- /dev/null
+++ b/Locales/examples/FreeBooleanAlgebra.g
@@ -0,0 +1,64 @@
+#! @Chunk FreeBooleanAlgebra
+
+#! Construct the free boolean algebra on two generators with its $2^(2^2)$ elements
+#! in two steps.
+
+#! @Example
+LoadPackage( "FunctorCategories", false );
+#! true
+pq := FinQuiver( "quiver(p,q)" );
+#! FinQuiver( "quiver(p,q)[]" )
+F := PathCategory( pq );
+#! PathCategory( FinQuiver( "quiver(p,q)[]" ) )
+P := PosetOfCategory( F );
+#! PosetOfCategory( PathCategory( FinQuiver( "quiver(p,q)[]" ) ) )
+Length( SetOfObjects( P ) );
+#! 2
+Dist := FreeDistributiveCompletion( P );
+#! FreeDistributiveCompletion(
+#! PosetOfCategory( PathCategory( FinQuiver( "quiver(p,q)[]" ) ) ) )
+Display( Dist );
+#! A CAP category with name FreeDistributiveCompletion(
+#! PosetOfCategory( PathCategory( FinQuiver( "quiver(p,q)[]" ) ) ) ):
+#!
+#! 54 primitive operations were used to derive 250 operations for this category
+#! which algorithmically
+#! * IsFiniteCategory
+#! * IsEquippedWithHomomorphismStructure
+#! * IsHeytingAlgebra
+#! and not yet algorithmically
+#! * IsBiHeytingAlgebra
+Length( SetOfObjects( Dist ) );
+#! 6
+DiffbCSL := MeetSemilatticeOfSingleDifferences( Dist );
+#! MeetSemilatticeOfSingleDifferences( FreeDistributiveCompletion(
+#! PosetOfCategory( PathCategory( FinQuiver( "quiver(p,q)[]" ) ) ) ) )
+Length( SetOfObjects( DiffbCSL ) );
+#! 13
+PSh := PreSheaves( DiffbCSL );
+#! PreSheaves( MeetSemilatticeOfSingleDifferences( FreeDistributiveCompletion(
+#! PosetOfCategory( PathCategory( FinQuiver( "quiver(p,q)[]" ) ) ) ) ),
+#! IntervalCategory )
+Y := YonedaEmbeddingOfSourceCategory( PSh );;
+Length( SetOfObjects( PSh ) );
+#! 85
+cocones := [ [ 0, [ ] ],
+ [ 2, [ 4, 10 ] ],
+ [ 3, [ 4, 11 ] ],
+ [ 6, [ 9, 11 ] ],
+ [ 7, [ 9, 10 ] ],
+ [ 12, [ 10, 11 ] ],
+ [ 5, [ 2, 3, 12 ] ],
+ [ 8, [ 6, 7, 12 ] ],
+ [ 1, [ 5, 8 ] ] ];;
+is_closed := G -> IsClosedPreSheafWRTCoproductsByIndices( PSh, G, cocones : offset := 1 );
+PShJ := FullSubcategoryByObjectMembershipFunction( PSh, is_closed );
+#! FullSubcategoryByObjectMembershipFunction( PreSheaves(
+#! MeetSemilatticeOfSingleDifferences( FreeDistributiveCompletion(
+#! PosetOfCategory( PathCategory( FinQuiver( "quiver(p,q)[]" ) ) ) ) ),
+#! IntervalCategory ), ObjectMembershipFunction )
+Length( SetOfObjects( PShJ ) );
+#! 16
+#Splash( DotVertexLabelledDigraph( PSh, [ [ PSh.p, PSh.q ], List( SetOfGeneratingObjects( DiffbCSL ), Y ), Y, PShJ ], [ "gray", "blue", "magenta", "orange", "red" ] ) );
+#Splash( DotVertexLabelledDigraph( PShJ, [ [ PSh.p, PSh.q ], List( SetOfGeneratingObjects( DiffbCSL ), Y ), Y ], [ "red", "blue", "magenta", "orange" ] ) );
+#! @EndExample
diff --git a/Locales/gap/SingleDifferences.gd b/Locales/gap/SingleDifferences.gd
index 85e536f35..175750909 100644
--- a/Locales/gap/SingleDifferences.gd
+++ b/Locales/gap/SingleDifferences.gd
@@ -94,6 +94,9 @@ DeclareAttribute( "MeetSemilatticeOfSingleDifferences",
DeclareOperation( "SingleDifference",
[ IsList ] );
+DeclareAttribute( "SetOfGeneratingObjects",
+ IsMeetSemilatticeOfSingleDifferences );
+
#! @Description
#! Form the formal single difference object A - B.
#! The expression A - 0 := A - InitialObject( CapCategory( A ) ).
diff --git a/Locales/gap/SingleDifferences.gi b/Locales/gap/SingleDifferences.gi
index fffdc4a38..38e260358 100644
--- a/Locales/gap/SingleDifferences.gi
+++ b/Locales/gap/SingleDifferences.gi
@@ -227,6 +227,21 @@ InstallMethodForCompilerForCAP( SetOfGeneratingMorphisms,
end );
+##
+InstallMethod( SetOfGeneratingObjects,
+ "for a meet-semilattice of single differences",
+ [ IsMeetSemilatticeOfSingleDifferences ],
+
+ function( D )
+ local Dist;
+
+ Dist := UnderlyingCategory( D );
+
+ return List( SetOfObjects( Dist ), minued ->
+ SingleDifference( D, Pair( minued, InitialObject( Dist ) ) ) );
+
+end );
+
##
InstallMethod( \-,
"for two objects in a thin category",
@@ -316,7 +331,7 @@ end );
##
InstallOtherMethodForCompilerForCAP( NormalizedMinuendAndSubtrahendInUnderlyingHeytingOrCoHeytingAlgebroid,
"for a Heyting algebroid and two objects in it",
- [ IsCapCategory and IsHeytingAlgebroid, IsObjectInThinCategory, IsObjectInThinCategory ],
+ [ IsCapCategory and IsHeytingAlgebroid, IsCapCategoryObject, IsCapCategoryObject ],
function( L, minuend, subtrahend )
local H;
@@ -332,7 +347,7 @@ end );
##
InstallOtherMethodForCompilerForCAP( NormalizedMinuendAndSubtrahendInUnderlyingHeytingOrCoHeytingAlgebroid,
"for a co-Heyting algebroid and two objects in it",
- [ IsCapCategory and IsCoHeytingAlgebroid, IsObjectInThinCategory, IsObjectInThinCategory ],
+ [ IsCapCategory and IsCoHeytingAlgebroid, IsCapCategoryObject, IsCapCategoryObject ],
function( L, minuend, subtrahend )
local H;
@@ -582,6 +597,22 @@ InstallMethod( \.,
end );
+##
+InstallMethod( \.,
+ "for a meet-semilattice of formal single differences and a positive integer",
+ [ IsMeetSemilatticeOfSingleDifferences, IsPosInt ],
+
+ function( D, string_as_int )
+ local Dist, name;
+
+ Dist := UnderlyingCategory( D );
+
+ name := NameRNam( string_as_int );
+
+ return SingleDifference( D, Pair( Dist.(name), InitialObject( Dist ) ) );
+
+end );
+
##
InstallMethod( ViewString,
"for an object in a meet-semilattice of formal single differences",
diff --git a/Locales/gap/ToolsUsingDigraphs.gi b/Locales/gap/ToolsUsingDigraphs.gi
index 47808be31..4e1d4610e 100644
--- a/Locales/gap/ToolsUsingDigraphs.gi
+++ b/Locales/gap/ToolsUsingDigraphs.gi
@@ -226,6 +226,87 @@ InstallMethod( DigraphOfPoset,
end );
+##
+InstallOtherMethod( DotVertexLabelledDigraph,
+ [ IsDigraphByOutNeighboursRep and IsDigraphOfSubobjects, IsList ],
+
+ function( D, list_of_colorings )
+ local out, str, i, pos, j;
+
+ # Copied from DotVertexLabeledDigraph() at Digraphs/gap/display.gi
+ out := OutNeighbours( D );
+ str := "//dot\n";
+
+ Append( str, "digraph subobject_lattice{\n" );
+ Append( str, "rankdir=\"BT\"\n" );
+ Append( str, "minlen=0\n" );
+ Append( str, "node [shape=circle width=0 height=0]\n" );
+
+ for i in DigraphVertices( D ) do
+ Append( str, String( i ) );
+ Append( str, " [label=\"" );
+ Append( str, String( DigraphVertexLabel( D, i ) ) );
+ pos := PositionProperty( list_of_colorings, pair -> pair[1] = i );
+ Append( str, "\"" );
+ if IsInt( pos ) then
+ Append( str, Concatenation( " color=", list_of_colorings[pos][2], " fontcolor=", list_of_colorings[pos][2] ) );
+ fi;
+ Append( str, " fontsize=12 margin=0.01 fontname=\"DejaVu Serif,serif\"]\n" );
+ od;
+
+ for i in DigraphVertices( D ) do
+ for j in out[i] do
+ Append( str, Concatenation( String( i ), " -> ", String( j ), " [arrowsize=0.5]\n" ) );
+ od;
+ od;
+
+ Append( str, "}\n" );
+
+ return str;
+
+end );
+
+##
+InstallOtherMethod( DotVertexLabelledDigraph,
+ [ IsPosetCategory and IsFiniteCategory, IsList, IsList ],
+
+ function( P, lists_of_subobjects, list_of_colors )
+ local c, objects, l, func, list_of_colorings;
+
+ c := Length( list_of_colors );
+
+ Assert( 0, Length( lists_of_subobjects ) + 1 = c );
+
+ objects := SetOfObjects( P );
+
+ l := Length( objects );
+
+ func :=
+ function( emb )
+ if IsCapFunctor( emb ) then
+ return List( SetOfObjects( SourceOfFunctor( emb ) ), emb );
+ elif IsBoundGlobal( "IsCapSubcategory" ) and ValueGlobal( "IsCapSubcategory" )( emb ) then
+ return List( SetOfObjects( emb ), UnderlyingCell );
+ else
+ return emb;
+ fi;
+
+ end;
+
+ lists_of_subobjects := List( lists_of_subobjects, func );
+
+ list_of_colorings := List( lists_of_subobjects, list_of_subobjects ->
+ List( list_of_subobjects, object ->
+ SafeUniquePositionProperty( objects, obj -> IsEqualForObjects( P, obj, object ) ) ) );
+
+ list_of_colorings := Concatenation( [ Difference( [ 1 .. l ], Concatenation( list_of_colorings ) ) ], list_of_colorings );
+
+ list_of_colorings := List( [ 1 .. c ], i -> List( list_of_colorings[i], o -> [ o, list_of_colors[i] ] ) );
+
+ return DotVertexLabelledDigraph( DigraphOfPoset( P ), Concatenation( list_of_colorings ) );
+
+end );
+
##
InstallMethod( Visualize,
"for a datastructure of a constructible object",
diff --git a/SubcategoriesForCAP/gap/ToolsUsingDigraphs.gi b/SubcategoriesForCAP/gap/ToolsUsingDigraphs.gi
new file mode 100644
index 000000000..865b8cd13
--- /dev/null
+++ b/SubcategoriesForCAP/gap/ToolsUsingDigraphs.gi
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# SubcategoriesForCAP: Subcategory and other related constructors for CAP categories
+#
+# Implementations
+#
+
+##
+InstallOtherMethod( DotVertexLabelledDigraph,
+ [ IsCapSubcategory and IsPosetCategory and IsFiniteCategory, IsList, IsList ],
+
+ function( subposet, lists_of_subobjects, list_of_colors )
+ local P, c, objects, l, func, list_of_colorings, digraph, ambient_objects;
+
+ P := AmbientCategory( subposet );
+
+ c := Length( list_of_colors );
+
+ Assert( 0, Length( lists_of_subobjects ) + 1 = c );
+
+ objects := List( SetOfObjects( subposet ), UnderlyingCell );
+
+ l := Length( objects );
+
+ func :=
+ function( emb )
+ if IsCapFunctor( emb ) then
+ return List( SetOfObjects( SourceOfFunctor( emb ) ), emb );
+ elif IsCapSubcategory( emb ) then
+ return List( SetOfObjects( emb ), UnderlyingCell );
+ else
+ return emb;
+ fi;
+
+ end;
+
+ lists_of_subobjects := List( lists_of_subobjects, func );
+
+ list_of_colorings := List( lists_of_subobjects, list_of_subobjects ->
+ List( list_of_subobjects, object ->
+ SafeUniquePositionProperty( objects, obj -> IsEqualForObjects( P, obj, object ) ) ) );
+
+ list_of_colorings := Concatenation( [ Difference( [ 1 .. l ], Concatenation( list_of_colorings ) ) ], list_of_colorings );
+
+ list_of_colorings := List( [ 1 .. c ], i -> List( list_of_colorings[i], o -> [ o, list_of_colors[i] ] ) );
+
+ digraph := DigraphOfPoset( subposet );
+
+ ambient_objects := SetOfObjects( P );
+
+ digraph!.vertexlabels := List( objects, object -> String( -1 + SafeUniquePositionProperty( ambient_objects, obj -> IsEqualForObjects( P, obj, object ) ) ) );
+
+ return DotVertexLabelledDigraph( digraph, Concatenation( list_of_colorings ) );
+
+end );
diff --git a/SubcategoriesForCAP/read.g b/SubcategoriesForCAP/read.g
index 5389bf890..25ebead63 100644
--- a/SubcategoriesForCAP/read.g
+++ b/SubcategoriesForCAP/read.g
@@ -16,3 +16,7 @@ if IsPackageMarkedForLoading( "Toposes", ">= 2020.02.19" ) and
ReadPackage( "SubcategoriesForCAP", "gap/LazySliceCategory.gi");
fi;
+
+if IsPackageMarkedForLoading( "Digraphs", ">= 1.3.1" ) then
+ ReadPackage( "SubcategoriesForCAP", "gap/ToolsUsingDigraphs.gi");
+fi;