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;