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/PackageInfo.g b/FunctorCategories/PackageInfo.g index fec80c8c0..cf3a9d7b0 100644 --- a/FunctorCategories/PackageInfo.g +++ b/FunctorCategories/PackageInfo.g @@ -89,7 +89,7 @@ Dependencies := rec( NeededOtherPackages := [ [ "GAPDoc", ">= 1.5" ], [ "ToolsForHomalg", ">= 2022.12-01" ], - [ "CAP", ">= 2024.02-01" ], + [ "CAP", ">= 2024.04-02" ], [ "MonoidalCategories", ">= 2024.02-01" ], [ "CartesianCategories", ">= 2024.02-05" ], [ "ToolsForCategoricalTowers", ">= 2024.03-02" ], 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..f2aa5bb3b --- /dev/null +++ b/FunctorCategories/examples/JoinCocone.g @@ -0,0 +1,40 @@ +#! @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 +digraphF := DigraphOfPoset( P );; +digraphF!.vertexlabels := List( SetOfObjects( F ), String ); +#Splash( DotVertexLabelledDigraph( digraphF ) ); +#Splash( DotVertexLabelledDigraph( DigraphOfPoset( P ) ) ); +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 +coproducts := [ [ 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) ] ] ] +PSh_J := ClosedPreSheavesWRTCoproducts( P, coproducts );; +closed := SetOfObjects( PSh_J );; +Assert( 0, Length( closed ) = 10 ); +psh_J := ModelingCategory( ModelingCategory( PSh_J ) );; +Assert( 0, Length( SetOfObjects( psh_J ) ) = Length( SetOfObjects( PSh_J ) ) ); +is_closed := psh_J!.ObjectMembershipFunction; +Assert( 0, ForAll( closed, obj -> is_closed( ObjectDatum( ModelingObject( PSh_J, obj ) ) ) ) ); +#Splash( DotVertexLabelledDigraph( PSh, [ Y, psh_J ], [ "grey", "blue", "red" ] : offset := 0 ) ); +#! @EndExample diff --git a/FunctorCategories/gap/ClosedCoPreSheavesWRTLimitingCones.gd b/FunctorCategories/gap/ClosedCoPreSheavesWRTLimitingCones.gd new file mode 100644 index 000000000..651f96afc --- /dev/null +++ b/FunctorCategories/gap/ClosedCoPreSheavesWRTLimitingCones.gd @@ -0,0 +1,127 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# FunctorCategories: Categories of functors +# +# Declarations +# + +#! @Chapter Category of closed copresheaves with respect to limiting cones + +#################################### +# +#! @Section GAP categories +# +#################################### + +#! @Description +#! The &GAP; category of closed copresheaves with respect to limiting cones. +DeclareCategory( "IsClosedCoPreSheavesWRTLimitingCones", + IsCapCategory ); + +#! @Description +#! The &GAP; category of cells in the category of closed copresheaves with respect to limiting cones. +DeclareCategory( "IsCellInClosedCoPreSheavesWRTLimitingCones", + IsCapCategoryCell ); + +#! @Description +#! The &GAP; category of objects in the category of closed copresheaves with respect to limiting cones. +DeclareCategory( "IsObjectInClosedCoPreSheavesWRTLimitingCones", + IsCellInClosedCoPreSheavesWRTLimitingCones and IsCapCategoryObject ); + +#! @Description +#! The &GAP; category of morphisms in the category of closed copresheaves with respect to limiting cones. +DeclareCategory( "IsMorphismInClosedCoPreSheavesWRTLimitingCones", + IsCellInClosedCoPreSheavesWRTLimitingCones and IsCapCategoryMorphism ); + +#################################### +# +#! @Section Constructors +# +#################################### + +#! @Description +#! The input is category C and a list product_cones of product cones in C. +#! The output is the category of of closed copresheaves with respect to product_cones. +#! @Arguments C, product_cones +DeclareOperation( "ClosedCoPreSheavesWRTProductCones", + [ IsCapCategory, IsList ] ); + +#CapJitAddTypeSignature( "ClosedCoPreSheavesWRTProductCones", [ IsCapCategory, IsList ], function ( input_types ) +# +# return CapJitDataTypeOfCategory( ClosedCoPreSheavesWRTProductCones( input_types[1].category ) ); +# +#end ); + +#! @Description +#! The input is category C and a list lists_of_product_cofactors of lists of product cofactors in C. +#! The output is the category of of closed copresheaves with respect to lists_of_product_cofactors. +#! @Arguments C, lists_of_product_cofactors +DeclareOperation( "ClosedCoPreSheavesWRTProducts", + [ IsCapCategory, IsList ] ); + +#CapJitAddTypeSignature( "ClosedCoPreSheavesWRTProducts", [ IsCapCategory, IsList ], function ( input_types ) +# +# return CapJitDataTypeOfCategory( ClosedCoPreSheavesWRTProducts( input_types[1].category ) ); +# +#end ); + +#! @Description +#! The input is category C and a list lists_of_product_cofactors of lists of product cofactors in C. +#! The output is the category of of closed copresheaves with respect to lists_of_product_cofactors. +#! @Arguments C, lists_of_product_cofactors +DeclareOperation( "ClosedCoPreSheavesWRTProductsByIndices", + [ IsCapCategory, IsList ] ); + +#CapJitAddTypeSignature( "ClosedCoPreSheavesWRTProductsByIndices", [ IsCapCategory, IsList ], function ( input_types ) +# +# return CapJitDataTypeOfCategory( ClosedCoPreSheavesWRTProductsByIndices( input_types[1].category ) ); +# +#end ); + +#################################### +# +#! @Section Attributes +# +#################################### + +#! @Description +#! The input is the category of closed copresheaves on a category $C$ with respect to a list $L$ of limiting cones in $C$. +#! The output is the list $L$. +#! @Arguments coPSh_J +DeclareAttribute( "UnderlyingLimitingCones", + IsClosedCoPreSheavesWRTLimitingCones ); + +#! @Description +#! The input is the category of closed copresheaves on a category $C$ with respect to limiting cones in $C$. +#! The output is the category $C$. +#! @Arguments coPSh_J +DeclareAttribute( "Source", + IsClosedCoPreSheavesWRTLimitingCones ); + +CapJitAddTypeSignature( "Source", [ IsClosedCoPreSheavesWRTLimitingCones ], + function ( input_types ) + + return CapJitDataTypeOfCategory( Source( input_types[1].category ) ); + +end ); + +#! @Description +#! The input is the category of closed copresheaves on a category $C$ with respect to limiting cones in $C$. +#! The output is the target category. +#! @Arguments coPSh_J +DeclareAttribute( "Target", + IsClosedCoPreSheavesWRTLimitingCones ); + +CapJitAddTypeSignature( "Target", [ IsClosedCoPreSheavesWRTLimitingCones ], + function ( input_types ) + + return CapJitDataTypeOfCategory( Target( input_types[1].category ) ); + +end ); + +DeclareAttribute( "CoYonedaEmbeddingDataOfSourceCategory", + IsClosedCoPreSheavesWRTLimitingCones ); + +#! @Arguments coPSh_J +#! @Returns a &CAP; functor +DeclareAttribute( "CoYonedaEmbeddingOfSourceCategory", + IsClosedCoPreSheavesWRTLimitingCones ); diff --git a/FunctorCategories/gap/ClosedCoPreSheavesWRTLimitingCones.gi b/FunctorCategories/gap/ClosedCoPreSheavesWRTLimitingCones.gi new file mode 100644 index 000000000..64d096627 --- /dev/null +++ b/FunctorCategories/gap/ClosedCoPreSheavesWRTLimitingCones.gi @@ -0,0 +1,377 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# FunctorCategories: Categories of functors +# +# Implementations +# + +## +InstallMethod( ClosedCoPreSheavesWRTProductCones, + "for a category and a list of product cones", + [ IsCapCategory, IsList ], + + function ( C, product_cones ) + local H, + object_datum_type, object_constructor, object_datum, + morphism_datum_type, morphism_constructor, morphism_datum, + C_op, coproduct_cocones, PSh_C_op_J, op_PSh_C_op_J, + modeling_tower_object_constructor, modeling_tower_object_datum, + modeling_tower_morphism_constructor, modeling_tower_morphism_datum, + coPSh_J; + + if not ( ForAll( product_cones, IsList ) and + ForAll( product_cones, pair -> IsCapCategoryObject( pair[1] ) and IsIdenticalObj( C, CapCategory( pair[1] ) ) ) and + ForAll( product_cones, pair -> ForAll( pair[2], mor -> IsCapCategoryMorphism( mor ) and IsIdenticalObj( C, CapCategory( mor ) ) ) ) ) then + + Error( "the second argument `product_cones` must be a list of pairs, ", + "where the first entry of the pair is an object in the category `C` and ", + "the second entry a list of morphisms in `C`" ); + + fi; + + H := RangeCategoryOfHomomorphismStructure( C ); + + ## + object_datum_type := + CapJitDataTypeOfNTupleOf( 2, + CapJitDataTypeOfListOf( CapJitDataTypeOfObjectOfCategory( H ) ), + CapJitDataTypeOfListOf( CapJitDataTypeOfMorphismOfCategory( H ) ) ); + + ## + object_constructor := + function( coPSh_J, pair ) + + return CreateCapCategoryObjectWithAttributes( coPSh_J, + Source, Source( coPSh_J ), + Target, Target( coPSh_J ), + AsPrimitiveValue, pair ); + + end; + + ## + object_datum := { coPSh_J, o } -> AsPrimitiveValue( o ); + + ## + morphism_datum_type := + CapJitDataTypeOfListOf( CapJitDataTypeOfMorphismOfCategory( H ) ); + + ## + morphism_constructor := + function( coPSh_J, source, components, target ) + + return CreateCapCategoryMorphismWithAttributes( coPSh_J, + source, + target, + AsPrimitiveValue, components ); + + end; + + ## + morphism_datum := { coPSh_J, m } -> AsPrimitiveValue( m ); + + ## building the categorical tower: + + C_op := Opposite( C : FinalizeCategory := true, only_primitive_operations := true ); + + coproduct_cocones := List( product_cones, pair -> + Pair( ObjectConstructor( C_op, pair[1] ), + List( pair[2], mor -> + MorphismConstructor( C_op, + ObjectConstructor( C_op, Target( mor ) ), + mor, + ObjectConstructor( C_op, Source( mor ) ) ) ) ) ); + + PSh_C_op_J := ClosedPreSheavesWRTCoproductCocones( C_op, coproduct_cocones : FinalizeCategory := true ); + + op_PSh_C_op_J := Opposite( PSh_C_op_J : FinalizeCategory := true, only_primitive_operations := true ); + + ## from the raw object data to the object in the modeling category + modeling_tower_object_constructor := + function( coPSh_J, pair ) + local op_PSh_C_op_J, PSh_C_op_J; + + op_PSh_C_op_J := ModelingCategory( coPSh_J ); + + PSh_C_op_J := OppositeCategory( op_PSh_C_op_J ); + + return ObjectConstructor( op_PSh_C_op_J, + ObjectConstructor( PSh_C_op_J, + pair ) ); + + end; + + ## from the object in the modeling category to the raw object data + modeling_tower_object_datum := + function( coPSh_J, obj ) + local op_PSh_C_op_J, PSh_C_op_J; + + op_PSh_C_op_J := ModelingCategory( coPSh_J ); + + PSh_C_op_J := OppositeCategory( op_PSh_C_op_J ); + + return ObjectDatum( PSh_C_op_J, + ObjectDatum( op_PSh_C_op_J, + obj ) ); + + end; + + ## from the raw morphism data to the morphism in the modeling category + modeling_tower_morphism_constructor := + function( coPSh_J, source, images, target ) + local op_PSh_C_op_J, PSh_C_op_J; + + op_PSh_C_op_J := ModelingCategory( coPSh_J ); + + PSh_C_op_J := OppositeCategory( op_PSh_C_op_J ); + + return MorphismConstructor( op_PSh_C_op_J, + source, + MorphismConstructor( PSh_C_op_J, + ObjectDatum( op_PSh_C_op_J, target ), + images, + ObjectDatum( op_PSh_C_op_J, source ) ), + target ); + + end; + + ## from the morphism in the modeling category to the raw morphism data + modeling_tower_morphism_datum := + function( coPSh_J, mor ) + local op_PSh_C_op_J, PSh_C_op_J; + + op_PSh_C_op_J := ModelingCategory( coPSh_J ); + + PSh_C_op_J := OppositeCategory( op_PSh_C_op_J ); + + return MorphismDatum( PSh_C_op_J, + MorphismDatum( op_PSh_C_op_J, + mor ) ); + + end; + + ## + coPSh_J := + ReinterpretationOfCategory( op_PSh_C_op_J, + rec( name := Concatenation( "ClosedCoPreSheavesWRTProductCones( ", Name( C ), ", product_cones )" ), + category_filter := IsClosedCoPreSheavesWRTLimitingCones, + category_object_filter := IsObjectInClosedCoPreSheavesWRTLimitingCones, + category_morphism_filter := IsMorphismInClosedCoPreSheavesWRTLimitingCones, + object_datum_type := object_datum_type, + morphism_datum_type := morphism_datum_type, + object_constructor := object_constructor, + object_datum := object_datum, + morphism_constructor := morphism_constructor, + morphism_datum := morphism_datum, + modeling_tower_object_constructor := modeling_tower_object_constructor, + modeling_tower_object_datum := modeling_tower_object_datum, + modeling_tower_morphism_constructor := modeling_tower_morphism_constructor, + modeling_tower_morphism_datum := modeling_tower_morphism_datum, + only_primitive_operations := true ) + : FinalizeCategory := false ); + + SetSource( coPSh_J, C ); + SetTarget( coPSh_J, Target( PSh_C_op_J ) ); + SetUnderlyingLimitingCones( coPSh_J, product_cones ); + + Append( coPSh_J!.compiler_hints.category_attribute_names, + [ "Source", + "Target", + "UnderlyingLimitingCones" ] ); + + Finalize( coPSh_J ); + + return coPSh_J; + +end ); + +## +InstallMethod( ClosedCoPreSheavesWRTProducts, + "for a category and a list of product cones", + [ IsCapCategory, IsList ], + + function ( C, lists_of_product_factors ) + + return ClosedCoPreSheavesWRTProductCones( C, ConesOfProducts( C, lists_of_product_factors ) ); + +end ); + +## +InstallMethod( ClosedCoPreSheavesWRTProductsByIndices, + "for a category and a list of product cones", + [ IsCapCategory, IsList ], + + function ( C, lists_of_product_factors_by_indices ) + + return ClosedCoPreSheavesWRTProductCones( C, ConesOfProductsByIndices( C, lists_of_product_factors_by_indices ) ); + +end ); + +## +InstallMethod( \., + "for the category of closed copresheaves with respect to colimiting cocones and a positive integer", + [ IsClosedCoPreSheavesWRTLimitingCones, IsPosInt ], + + function( coPSh_J, string_as_int ) + local name, op_PSh_C_op_J, c; + + name := NameRNam( string_as_int ); + + op_PSh_C_op_J := ModelingCategory( coPSh_J ); + + c := op_PSh_C_op_J.(name); + + if IsCapCategoryObject( c ) and IsIdenticalObj( CapCategory( c ), op_PSh_C_op_J ) then + + return ReinterpretationOfObject( coPSh_J, c ); + + elif IsCapCategoryMorphism( c ) and IsIdenticalObj( CapCategory( c ), op_PSh_C_op_J ) then + + return ReinterpretationOfMorphism( coPSh_J, + ReinterpretationOfObject( coPSh_J, Source( c ) ), + c, + ReinterpretationOfObject( coPSh_J, Target( c ) ) ); + + else + + Error( "`c` is neither an object nor a morphism in the modeling category `op_PSh_C_op_J := ModelingCategory( coPSh_J )`\n" ); + + fi; + +end ); + +## +InstallMethodForCompilerForCAP( SetOfObjects, + "for the category of closed copresheaves with respect to limiting cones", + [ IsClosedCoPreSheavesWRTLimitingCones ], + + function( cat ) + + return SetOfObjectsOfCategory( cat ); + +end ); + +## +InstallMethodForCompilerForCAP( SetOfGeneratingMorphisms, + "for the category of closed copresheaves with respect to limiting cones", + [ IsClosedCoPreSheavesWRTLimitingCones ], + + function( cat ) + + return SetOfGeneratingMorphismsOfCategory( cat ); + +end ); + +## +InstallMethodForCompilerForCAP( CoYonedaEmbeddingDataOfSourceCategory, + "for a category of closed copresheaves w.r.t. limiting cones", + [ IsClosedCoPreSheavesWRTLimitingCones ], + + function ( coPSh_J ) + local C, coyoneda_data, coYoneda_on_objs, coYoneda_on_mors; + + C := Source( coPSh_J ); + + coyoneda_data := CoYonedaEmbeddingData( C ); + + coYoneda_on_objs := + function ( obj ) + + return ObjectConstructor( coPSh_J, + coyoneda_data[1]( obj ) ); + + end; + + coYoneda_on_mors := + function ( source, mor, target ) + local source_on_objs, target_on_objs; + + Error( "not implemented yet" ); + + source_on_objs := ObjectDatum( coPSh_J, source )[1]; + target_on_objs := ObjectDatum( coPSh_J, target )[1]; + + return MorphismConstructor( coPSh_J, + source, + coyoneda_data[2]( source_on_objs, mor, target_on_objs ), + target ); + + end; + + return Pair( coYoneda_on_objs, coYoneda_on_mors ); + +end ); + +## +InstallMethod( CoYonedaEmbeddingOfSourceCategory, + "for a category of closed copresheaves w.r.t. limiting cones", + [ IsClosedCoPreSheavesWRTLimitingCones ], + + function ( coPSh_J ) + local C, coYoneda, coYoneda_data; + + C := Source( coPSh_J ); + + coYoneda := CapFunctor( "co-Yoneda embedding functor", C, coPSh_J ); + + coYoneda_data := CoYonedaEmbeddingDataOfSourceCategory( coPSh_J ); + + AddObjectFunction( coYoneda, coYoneda_data[1] ); + + AddMorphismFunction( coYoneda, coYoneda_data[2] ); + + return coYoneda; + +end ); + +################################## +## +## View & Display +## +################################## + +## +InstallMethod( ViewObj, + [ IsObjectInClosedCoPreSheavesWRTLimitingCones ], + + function( a ) + + Print( "An object in category of closed copresheaves given by: " ); + + ViewObj( ObjectDatum( CapCategory( a ), a ) ); + +end ); + +## +InstallMethod( ViewObj, + [ IsMorphismInClosedCoPreSheavesWRTLimitingCones ], + + function( phi ) + + Print( "A morphism in category of closed copresheaves given by: " ); + + ViewObj( MorphismDatum( CapCategory( phi ), phi ) ); + +end ); + +## +InstallMethod( Display, + [ IsObjectInClosedCoPreSheavesWRTLimitingCones ], + + function( a ) + + Display( ObjectDatum( CapCategory( a ), a ) ); + + Display( "\nAn object in category of closed copresheaves given by the above data" ); + +end ); + +## +InstallMethod( Display, + [ IsMorphismInClosedCoPreSheavesWRTLimitingCones ], + + function( phi ) + + Display( MorphismDatum( CapCategory( phi ), phi ) ); + + Display( "A morphism in category of closed copresheaves given by the above data" ); + +end ); diff --git a/FunctorCategories/gap/ClosedPreSheavesWRTColimitingCocones.gd b/FunctorCategories/gap/ClosedPreSheavesWRTColimitingCocones.gd new file mode 100644 index 000000000..7ebd7e3a1 --- /dev/null +++ b/FunctorCategories/gap/ClosedPreSheavesWRTColimitingCocones.gd @@ -0,0 +1,165 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# FunctorCategories: Categories of functors +# +# Declarations +# + +#! @Chapter Category of closed presheaves with respect to colimiting cocones + +#################################### +# +#! @Section GAP categories +# +#################################### + +#! @Description +#! The &GAP; category of closed presheaves with respect to colimiting cocones. +DeclareCategory( "IsClosedPreSheavesWRTColimitingCocones", + IsCapCategory ); + +#! @Description +#! The &GAP; category of cells in the category of closed presheaves with respect to colimiting cocones. +DeclareCategory( "IsCellInClosedPreSheavesWRTColimitingCocones", + IsCapCategoryCell ); + +#! @Description +#! The &GAP; category of objects in the category of closed presheaves with respect to colimiting cocones. +DeclareCategory( "IsObjectInClosedPreSheavesWRTColimitingCocones", + IsCellInClosedPreSheavesWRTColimitingCocones and IsCapCategoryObject ); + +#! @Description +#! The &GAP; category of morphisms in the category of closed presheaves with respect to colimiting cocones. +DeclareCategory( "IsMorphismInClosedPreSheavesWRTColimitingCocones", + IsCellInClosedPreSheavesWRTColimitingCocones and IsCapCategoryMorphism ); + +#################################### +# +#! @Section Constructors +# +#################################### + +#! @Description +#! The input is category C and a list coproduct_cocones of coproduct cocones in C. +#! The output is the category of of closed presheaves with respect to coproduct_cocones. +#! @Arguments C, coproduct_cocones +DeclareOperation( "ClosedPreSheavesWRTCoproductCocones", + [ IsCapCategory, IsList ] ); + +#CapJitAddTypeSignature( "ClosedPreSheavesWRTCoproductCocones", [ IsCapCategory, IsList ], function ( input_types ) +# +# return CapJitDataTypeOfCategory( ClosedPreSheavesWRTCoproductCocones( input_types[1].category ) ); +# +#end ); + +#! @Description +#! The input is category C and a list lists_of_coproduct_cofactors of lists of coproduct cofactors in C. +#! The output is the category of of closed presheaves with respect to lists_of_coproduct_cofactors. +#! @Arguments C, lists_of_coproduct_cofactors +DeclareOperation( "ClosedPreSheavesWRTCoproducts", + [ IsCapCategory, IsList ] ); + +#CapJitAddTypeSignature( "ClosedPreSheavesWRTCoproducts", [ IsCapCategory, IsList ], function ( input_types ) +# +# return CapJitDataTypeOfCategory( ClosedPreSheavesWRTCoproducts( input_types[1].category ) ); +# +#end ); + +#! @Description +#! The input is category C and a list lists_of_coproduct_cofactors of lists of coproduct cofactors in C. +#! The output is the category of of closed presheaves with respect to lists_of_coproduct_cofactors. +#! @Arguments C, lists_of_coproduct_cofactors +DeclareOperation( "ClosedPreSheavesWRTCoproductsByIndices", + [ IsCapCategory, IsList ] ); + +#CapJitAddTypeSignature( "ClosedPreSheavesWRTCoproductsByIndices", [ IsCapCategory, IsList ], function ( input_types ) +# +# return CapJitDataTypeOfCategory( ClosedPreSheavesWRTCoproductsByIndices( input_types[1].category ) ); +# +#end ); + +#################################### +# +#! @Section Attributes +# +#################################### + +#! @Description +#! The input is the category of closed presheaves on a category $C$ with respect to a list $L$ of colimiting cocones in $C$. +#! The output is the list $L$. +#! @Arguments PSh_J +DeclareAttribute( "UnderlyingColimitingCocones", + IsClosedPreSheavesWRTColimitingCocones ); + +#! @Description +#! The input is the category of closed presheaves on a category $C$ with respect to colimiting cocones in $C$. +#! The output is the category $C$. +#! @Arguments PSh_J +DeclareAttribute( "Source", + IsClosedPreSheavesWRTColimitingCocones ); + +CapJitAddTypeSignature( "Source", [ IsClosedPreSheavesWRTColimitingCocones ], + function ( input_types ) + + return CapJitDataTypeOfCategory( Source( input_types[1].category ) ); + +end ); + +#! @Description +#! The input is the category of closed presheaves on a category $C$ with respect to colimiting cocones in $C$. +#! The output is the target category. +#! @Arguments PSh_J +DeclareAttribute( "Target", + IsClosedPreSheavesWRTColimitingCocones ); + +CapJitAddTypeSignature( "Target", [ IsClosedPreSheavesWRTColimitingCocones ], + function ( input_types ) + + return CapJitDataTypeOfCategory( Target( input_types[1].category ) ); + +end ); + +DeclareAttribute( "YonedaEmbeddingDataOfSourceCategory", + IsClosedPreSheavesWRTColimitingCocones ); + +#! @Arguments PSh_J +#! @Returns a &CAP; functor +DeclareAttribute( "YonedaEmbeddingOfSourceCategory", + IsClosedPreSheavesWRTColimitingCocones ); + +#################################### +# +#! @Section Operations +# +#################################### + +#! @Arguments PSh, presheaf, coproducts_cocones +DeclareOperation( "IsClosedPreSheafWRTCoproductCocones", + [ IsObjectInPreSheafCategory, IsList ] ); + +#! @Arguments PSh, presheaf, lists_of_coproduct_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_coproduct_cofactors +DeclareOperation( "EmbeddingIntoClosureOfPreSheafWRTCoproducts", + [ IsObjectInPreSheafCategory, IsList ] ); + +#! @Arguments PSh, coproducts_cocones +DeclareOperation( "ClosureOfPreSheavesWRTCoproductCocones", + [ IsPreSheafCategoryOfFpEnrichedCategory, IsList ] ); + +#! @Arguments PSh, lists_of_coproduct_cofactors +DeclareOperation( "ClosureOfPreSheavesWRTCoproducts", + [ IsPreSheafCategoryOfFpEnrichedCategory, IsList ] ); diff --git a/FunctorCategories/gap/ClosedPreSheavesWRTColimitingCocones.gi b/FunctorCategories/gap/ClosedPreSheavesWRTColimitingCocones.gi new file mode 100644 index 000000000..ea408337d --- /dev/null +++ b/FunctorCategories/gap/ClosedPreSheavesWRTColimitingCocones.gi @@ -0,0 +1,702 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# FunctorCategories: Categories of functors +# +# Implementations +# + +## +InstallMethod( ClosedPreSheavesWRTCoproductCocones, + "for a category and a list of coproduct cocones", + [ IsCapCategory, IsList ], + + function ( C, coproduct_cocones ) + local H, + object_datum_type, object_constructor, object_datum, + morphism_datum_type, morphism_constructor, morphism_datum, + PSh, eta, Kleisli, + modeling_tower_object_constructor, modeling_tower_object_datum, + modeling_tower_morphism_constructor, modeling_tower_morphism_datum, + PSh_J; + + if not ( ForAll( coproduct_cocones, IsList ) and + ForAll( coproduct_cocones, pair -> IsCapCategoryObject( pair[1] ) and IsIdenticalObj( C, CapCategory( pair[1] ) ) ) and + ForAll( coproduct_cocones, pair -> ForAll( pair[2], mor -> IsCapCategoryMorphism( mor ) and IsIdenticalObj( C, CapCategory( mor ) ) ) ) ) then + + Error( "the second argument `coproduct_cocones` must be a list of pairs, ", + "where the first entry of the pair is an object in the category `C` and ", + "the second entry a list of morphisms in `C`" ); + + fi; + + H := RangeCategoryOfHomomorphismStructure( C ); + + ## + object_datum_type := + CapJitDataTypeOfNTupleOf( 2, + CapJitDataTypeOfListOf( CapJitDataTypeOfObjectOfCategory( H ) ), + CapJitDataTypeOfListOf( CapJitDataTypeOfMorphismOfCategory( H ) ) ); + + ## + object_constructor := + function( PSh_J, pair ) + + return CreateCapCategoryObjectWithAttributes( PSh_J, + Source, Source( PSh_J ), + Target, Target( PSh_J ), + AsPrimitiveValue, pair ); + + end; + + ## + object_datum := { PSh_J, o } -> AsPrimitiveValue( o ); + + ## + morphism_datum_type := + CapJitDataTypeOfListOf( CapJitDataTypeOfMorphismOfCategory( H ) ); + + ## + morphism_constructor := + function( PSh_J, source, components, target ) + + return CreateCapCategoryMorphismWithAttributes( PSh_J, + source, + target, + AsPrimitiveValue, components ); + + end; + + ## + morphism_datum := { PSh_J, m } -> AsPrimitiveValue( m ); + + ## building the categorical tower: + + PSh := PreSheaves( C : FinalizeCategory := true ); + + eta := ClosureOfPreSheavesWRTCoproductCocones( PSh, coproduct_cocones ); + + Kleisli := KleisliReflectiveSubcategoryOfIdempotentMonad( eta : + properties := [ "IsFiniteBicompleteCategory" ], + additional_operations_to_install := CAP_INTERNAL_CONSTRUCTIVE_CATEGORIES_RECORD.IsCartesianCategory, + supports_empty_limits := true, + FinalizeCategory := false ); + + AddCoproduct( Kleisli, + function( Kleisli, list_of_cofactors ) + local PSh, coproduct, closure; + + PSh := AmbientCategory( Kleisli ); + + coproduct := Coproduct( PSh, + List( list_of_cofactors, cofactor -> + ObjectDatum( Kleisli, cofactor ) ) ); + + closure := Target( EmbeddingIntoClosureOfPreSheafWRTCoproductCocones( PSh, coproduct, coproduct_cocones ) ); + + return ObjectConstructor( Kleisli, + closure ); + + end ); + + ## TODO: + ## AddInjectionOfCofactorOfCoproductWithGivenCoproduct + ## AddUniversalMorphismFromCoproductWithGivenCoproduct + + Finalize( Kleisli : FinalizeCategory := true ); + + ## from the raw object data to the object in the modeling category + modeling_tower_object_constructor := + function( PSh_J, pair ) + local Kleisli, PSh; + + Kleisli := ModelingCategory( PSh_J ); + + PSh := AmbientCategory( Kleisli ); + + return ObjectConstructor( Kleisli, + ObjectConstructor( PSh, + pair ) ); + + end; + + ## from the object in the modeling category to the raw object data + modeling_tower_object_datum := + function( PSh_J, obj ) + local Kleisli, PSh; + + Kleisli := ModelingCategory( PSh_J ); + + PSh := AmbientCategory( Kleisli ); + + return ObjectDatum( PSh, + ObjectDatum( Kleisli, + obj ) ); + + end; + + ## from the raw morphism data to the morphism in the modeling category + modeling_tower_morphism_constructor := + function( PSh_J, source, images, target ) + local Kleisli, PSh; + + Kleisli := ModelingCategory( PSh_J ); + + PSh := AmbientCategory( Kleisli ); + + return MorphismConstructor( Kleisli, + source, + MorphismConstructor( PSh, + ObjectDatum( Kleisli, source ), + images, + ObjectDatum( Kleisli, target ) ), + target ); + + end; + + ## from the morphism in the modeling category to the raw morphism data + modeling_tower_morphism_datum := + function( PSh_J, mor ) + local Kleisli, PSh; + + Kleisli := ModelingCategory( PSh_J ); + + PSh := AmbientCategory( Kleisli ); + + return MorphismDatum( PSh, + MorphismDatum( Kleisli, + mor ) ); + + end; + + ## + PSh_J := + ReinterpretationOfCategory( Kleisli, + rec( name := Concatenation( "ClosedPreSheavesWRTCoproductCocones( ", Name( C ), ", coproduct_cocones )" ), + category_filter := IsClosedPreSheavesWRTColimitingCocones, + category_object_filter := IsObjectInClosedPreSheavesWRTColimitingCocones, + category_morphism_filter := IsMorphismInClosedPreSheavesWRTColimitingCocones, + object_datum_type := object_datum_type, + morphism_datum_type := morphism_datum_type, + object_constructor := object_constructor, + object_datum := object_datum, + morphism_constructor := morphism_constructor, + morphism_datum := morphism_datum, + modeling_tower_object_constructor := modeling_tower_object_constructor, + modeling_tower_object_datum := modeling_tower_object_datum, + modeling_tower_morphism_constructor := modeling_tower_morphism_constructor, + modeling_tower_morphism_datum := modeling_tower_morphism_datum, + only_primitive_operations := true ) + : FinalizeCategory := false ); + + SetSource( PSh_J, C ); + SetTarget( PSh_J, Target( PSh ) ); + SetUnderlyingColimitingCocones( PSh_J, coproduct_cocones ); + + #if CanCompute( Kleisli, "SetOfObjectsOfCategory" ) then + # + # ## add a potentially slower method, but that does not need to generate all objects in PSh + # AddSetOfObjectsOfCategory( PSh_J, + # function( PSh_J ) + # local C, Yoneda, representables, joins; + # + # C := Source( PSh_J ); + # + # ## the Yoneda embedding: C ↪ PSh_J( C ) + # Yoneda := YonedaEmbeddingDataOfSourceCategory( PSh_J ); + # + # representables := List( SetOfObjects( C ), Yoneda[1] ); + # + # representables := Filtered( representables, representable -> not IsInitial( PSh_J, representable ) ); + # + # joins := AllCoproducts( PSh_J, representables ); + # + # return List( Concatenation( joins ), entry -> entry[2] ); + # + # end ); + # + #fi; + + Append( PSh_J!.compiler_hints.category_attribute_names, + [ "Source", + "Target", + "UnderlyingColimitingCocones" ] ); + + Finalize( PSh_J ); + + return PSh_J; + +end ); + +## +InstallMethod( ClosedPreSheavesWRTCoproducts, + "for a category and a list of coproduct cocones", + [ IsCapCategory, IsList ], + + function ( C, lists_of_coproduct_cofactors ) + + return ClosedPreSheavesWRTCoproductCocones( C, CoconesOfCoproducts( C, lists_of_coproduct_cofactors ) ); + +end ); + +## +InstallMethod( ClosedPreSheavesWRTCoproductsByIndices, + "for a category and a list of coproduct cocones", + [ IsCapCategory, IsList ], + + function ( C, lists_of_coproduct_cofactors_by_indices ) + + return ClosedPreSheavesWRTCoproductCocones( C, CoconesOfCoproductsByIndices( C, lists_of_coproduct_cofactors_by_indices ) ); + +end ); + +## +InstallMethod( \., + "for the category of closed presheaves with respect to colimiting cocones and a positive integer", + [ IsClosedPreSheavesWRTColimitingCocones, IsPosInt ], + + function( PSh_J, string_as_int ) + local name, Kleisli, c; + + name := NameRNam( string_as_int ); + + Kleisli := ModelingCategory( PSh_J ); + + c := Kleisli.(name); + + if IsCapCategoryObject( c ) and IsIdenticalObj( CapCategory( c ), Kleisli ) then + + return ReinterpretationOfObject( PSh_J, c ); + + elif IsCapCategoryMorphism( c ) and IsIdenticalObj( CapCategory( c ), Kleisli ) then + + return ReinterpretationOfMorphism( PSh_J, + ReinterpretationOfObject( PSh_J, Source( c ) ), + c, + ReinterpretationOfObject( PSh_J, Target( c ) ) ); + + else + + Error( "`c` is neither an object nor a morphism in the Kleisli category `Kleisli`\n" ); + + fi; + +end ); + +## +InstallMethodForCompilerForCAP( SetOfObjects, + "for the category of closed presheaves with respect to colimiting cocones", + [ IsClosedPreSheavesWRTColimitingCocones ], + + function( cat ) + + return SetOfObjectsOfCategory( cat ); + +end ); + +## +InstallMethodForCompilerForCAP( SetOfGeneratingMorphisms, + "for the category of closed presheaves with respect to colimiting cocones", + [ IsClosedPreSheavesWRTColimitingCocones ], + + function( cat ) + + return SetOfGeneratingMorphismsOfCategory( cat ); + +end ); + +## +InstallMethodForCompilerForCAP( YonedaEmbeddingDataOfSourceCategory, + "for a category of closed presheaves w.r.t. colimiting cocones", + [ IsClosedPreSheavesWRTColimitingCocones ], + + function ( PSh_J ) + local C, yoneda_data, Yoneda_on_objs, Yoneda_on_mors; + + C := Source( PSh_J ); + + yoneda_data := YonedaEmbeddingData( C ); + + Yoneda_on_objs := + function ( obj ) + + return ObjectConstructor( PSh_J, + yoneda_data[1]( obj ) ); + + end; + + Yoneda_on_mors := + function ( source, mor, target ) + local source_on_objs, target_on_objs; + + Error( "not implemented yet" ); + + source_on_objs := ObjectDatum( PSh_J, source )[1]; + target_on_objs := ObjectDatum( PSh_J, target )[1]; + + return MorphismConstructor( PSh_J, + source, + yoneda_data[2]( source_on_objs, mor, target_on_objs ), + target ); + + end; + + return Pair( Yoneda_on_objs, Yoneda_on_mors ); + +end ); + +## +InstallMethod( YonedaEmbeddingOfSourceCategory, + "for a category of closed presheaves w.r.t. colimiting cocones", + [ IsClosedPreSheavesWRTColimitingCocones ], + + function ( PSh_J ) + local C, Yoneda, Yoneda_data; + + C := Source( PSh_J ); + + Yoneda := CapFunctor( "Yoneda embedding functor", C, PSh_J ); + + Yoneda_data := YonedaEmbeddingDataOfSourceCategory( PSh_J ); + + AddObjectFunction( Yoneda, Yoneda_data[1] ); + + AddMorphismFunction( Yoneda, Yoneda_data[2] ); + + return Yoneda; + +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, lists_of_coproduct_cofactors ) + local list_of_coproduct_cones; + + list_of_coproduct_cones := CoconesOfCoproducts( Source( PSh ), lists_of_coproduct_cofactors ); + + return IsClosedPreSheafWRTCoproductCocones( PSh, presheaf, list_of_coproduct_cones ); + +end ); + +## +InstallOtherMethodForCompilerForCAP( IsClosedPreSheafWRTCoproductsByIndices, + [ IsPreSheafCategory and IsThinCategory, IsObjectInPreSheafCategory, IsList ], + + function( PSh, presheaf, lists_of_coproduct_cofactors_by_indices ) + local lists_of_coproduct_cofactors; + + lists_of_coproduct_cofactors := CoconesOfCoproductsByIndices( Source( PSh ), lists_of_coproduct_cofactors_by_indices ); + + return IsClosedPreSheafWRTCoproducts( PSh, presheaf, lists_of_coproduct_cofactors ); + +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, emb; + + func := + function( embedding, cocone ) + return PreCompose( PSh, + embedding, + EmbeddingIntoClosureOfPreSheafWRTCoproductCocone( PSh, + Target( embedding ), + cocone ) ); + end; + + emb := Iterated( coproduct_cocones, + func, + IdentityMorphism( PSh, presheaf ) ); + + #% CAP_JIT_DROP_NEXT_STATEMENT + Assert( 0, IsClosedPreSheafWRTCoproductCocones( PSh, Target( emb ), coproduct_cocones ) ); + + return emb; + +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, lists_of_coproduct_cofactors ) + local list_of_coproduct_cones; + + list_of_coproduct_cones := CoconesOfCoproducts( Source( PSh ), lists_of_coproduct_cofactors ); + + return EmbeddingIntoClosureOfPreSheafWRTCoproductCocones( PSh, presheaf, list_of_coproduct_cones ); + +end ); + +## +InstallMethod( EmbeddingIntoClosureOfPreSheafWRTCoproducts, + [ IsObjectInPreSheafCategory, IsList ], + + function( presheaf, lists_of_coproduct_cofactors ) + + return EmbeddingIntoClosureOfPreSheafWRTCoproducts( CapCategory( presheaf ), presheaf, lists_of_coproduct_cofactors ); + +end ); + +## +InstallMethod( ClosureOfPreSheavesWRTCoproductCocones, + [ IsPreSheafCategoryOfFpEnrichedCategory, IsList ], + + function( PSh, coproducts_cocones ) + local Id_PSh, ClosureMonad, UnitOfClosureMonad; + + Id_PSh := IdentityFunctor( PSh ); + + ClosureMonad := CapFunctor( "Closure idempotent monad with respect to coproduct cocones", PSh, PSh ); + + AddObjectFunction( ClosureMonad, + function( object ) + + return Target( EmbeddingIntoClosureOfPreSheafWRTCoproductCocones( PSh, object, coproducts_cocones ) ); + + end ); + + AddMorphismFunction( ClosureMonad, + function( source, morphism, target ) + + Error( "not implemented yet\n" ); + + end ); + + ClosureMonad!.ObjectMembershipFunction := presheaf -> IsClosedPreSheafWRTCoproductCocones( PSh, presheaf, coproducts_cocones ); + + UnitOfClosureMonad := NaturalTransformation( Id_PSh, ClosureMonad ); + + AddNaturalTransformationFunction( UnitOfClosureMonad, + function( source, object, target ) + + return EmbeddingIntoClosureOfPreSheafWRTCoproductCocones( PSh, object, coproducts_cocones ); + + end ); + + return UnitOfClosureMonad; + +end ); + +## +InstallMethod( ClosureOfPreSheavesWRTCoproducts, + [ IsPreSheafCategoryOfFpEnrichedCategory, IsList ], + + function( PSh, lists_of_coproduct_cofactors ) + + return ClosureOfPreSheavesWRTCoproductCocones( PSh, CoconesOfCoproducts( Source( PSh ), lists_of_coproduct_cofactors ) ); + +end ); + +################################## +## +## View & Display +## +################################## + +## +InstallMethod( ViewObj, + [ IsObjectInClosedPreSheavesWRTColimitingCocones ], + + function( a ) + + Print( "An object in category of closed presheaves given by: " ); + + ViewObj( ObjectDatum( CapCategory( a ), a ) ); + +end ); + +## +InstallMethod( ViewObj, + [ IsMorphismInClosedPreSheavesWRTColimitingCocones ], + + function( phi ) + + Print( "A morphism in category of closed presheaves given by: " ); + + ViewObj( MorphismDatum( CapCategory( phi ), phi ) ); + +end ); + +## +InstallMethod( Display, + [ IsObjectInClosedPreSheavesWRTColimitingCocones ], + + function( a ) + + Display( ObjectDatum( CapCategory( a ), a ) ); + + Display( "\nAn object in category of closed presheaves given by the above data" ); + +end ); + +## +InstallMethod( Display, + [ IsMorphismInClosedPreSheavesWRTColimitingCocones ], + + function( phi ) + + Display( MorphismDatum( CapCategory( phi ), phi ) ); + + Display( "A morphism in category of closed presheaves given by the above data" ); + +end ); diff --git a/FunctorCategories/gap/FreeDistributiveCompletion.gd b/FunctorCategories/gap/FreeDistributiveCompletion.gd index 873c68b28..bf66a3dcb 100644 --- a/FunctorCategories/gap/FreeDistributiveCompletion.gd +++ b/FunctorCategories/gap/FreeDistributiveCompletion.gd @@ -4,7 +4,7 @@ # Declarations # -#! @Chapter Free distributive completion of a finitely presented (linear) category +#! @Chapter Free distributive completion of a finitely presented category #################################### # diff --git a/FunctorCategories/gap/PreSheaves.gd b/FunctorCategories/gap/PreSheaves.gd index 7791785ab..a627e42a8 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 ); diff --git a/FunctorCategories/gap/PreSheaves.gi b/FunctorCategories/gap/PreSheaves.gi index fb676bd42..a7e6bc663 100644 --- a/FunctorCategories/gap/PreSheaves.gi +++ b/FunctorCategories/gap/PreSheaves.gi @@ -306,13 +306,24 @@ InstallMethodWithCache( PreSheavesOfFpEnrichedCategory, [ IsCapCategory, IsCapCategory ], function ( B, D ) - local B_op, kq, A, relations, name, list_of_operations, + local object_datum_type, morphism_datum_type, is_computable, + B_op, kq, A, relations, name, list_of_operations, object_constructor, object_datum, morphism_constructor, morphism_datum, create_func_bool, create_func_object, create_func_morphism, list_of_operations_to_install, skip, commutative_ring, properties, supports_empty_limits, prop, option_record, PSh, H, auxiliary_indices; + object_datum_type := + CapJitDataTypeOfNTupleOf( 2, + CapJitDataTypeOfListOf( CapJitDataTypeOfObjectOfCategory( D ) ), + CapJitDataTypeOfListOf( CapJitDataTypeOfMorphismOfCategory( D ) ) ); + + morphism_datum_type := + CapJitDataTypeOfListOf( CapJitDataTypeOfMorphismOfCategory( D ) ); + + is_computable := IsBound( D!.is_computable ) and D!.is_computable; + if IsFpCategory( B ) then B_op := OppositeFpCategory( B : FinalizeCategory := true ); kq := UnderlyingQuiverAlgebra( B_op ); @@ -326,6 +337,8 @@ InstallMethodWithCache( PreSheavesOfFpEnrichedCategory, B_op := OppositeCategoryFromNerveData( B : FinalizeCategory := true ); elif IsCategoryFromDataTables( B ) then B_op := OppositeCategoryFromDataTables( B : FinalizeCategory := true ); + elif WasCreatedAsOppositeCategory( B ) then + B_op := OppositeCategory( B ); elif HasIsFiniteCategory( B ) and IsFiniteCategory( B ) then B_op := OppositeFiniteCategory( B : FinalizeCategory := true ); elif IsAlgebroid( B ) then @@ -776,17 +789,20 @@ InstallMethodWithCache( PreSheavesOfFpEnrichedCategory, category_filter := IsPreSheafCategoryOfFpEnrichedCategory, category_object_filter := IsObjectInPreSheafCategoryOfFpEnrichedCategory, category_morphism_filter := IsMorphismInPreSheafCategoryOfFpEnrichedCategory, - supports_empty_limits := supports_empty_limits, - list_of_operations_to_install := list_of_operations_to_install, + object_datum_type := object_datum_type, + morphism_datum_type := morphism_datum_type, properties := properties, object_constructor := object_constructor, object_datum := object_datum, morphism_constructor := morphism_constructor, morphism_datum := morphism_datum, + list_of_operations_to_install := list_of_operations_to_install, + is_computable := is_computable, + supports_empty_limits := supports_empty_limits, + underlying_category_getter_string := "Target", create_func_bool := create_func_bool, create_func_object := create_func_object, create_func_morphism := create_func_morphism, - underlying_category_getter_string := "Target" ); if not commutative_ring = fail then @@ -2741,6 +2757,13 @@ InstallMethodForCompilerForCAP( ApplyObjectInPreSheafCategoryOfFpEnrichedCategor OppositeAlgebraElement( UnderlyingQuiverAlgebraElement( morB ) ), SetOfObjects( B_op )[VertexIndex( UnderlyingVertex( Source( morB ) ) )] ); + elif WasCreatedAsOppositeCategory( B ) then + + morB_op := MorphismConstructor( B_op, + SetOfObjects( B_op )[SafeUniquePositionProperty( SetOfObjects( B ), obj -> IsEqualForObjects( B, obj, Target( morB ) ) )], + MorphismDatum( B_op, MorphismDatum( B, morB ) ), + SetOfObjects( B_op )[SafeUniquePositionProperty( SetOfObjects( B ), obj -> IsEqualForObjects( B, obj, Source( morB ) ) )] ); + else morB_op := MorphismConstructor( B_op, @@ -3239,6 +3262,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", diff --git a/FunctorCategories/gap/Tools.gd b/FunctorCategories/gap/Tools.gd index 510b1c0ce..479573fc5 100644 --- a/FunctorCategories/gap/Tools.gd +++ b/FunctorCategories/gap/Tools.gd @@ -72,3 +72,25 @@ end ); #! @Arguments F DeclareProperty( "IsReflexive", IsCapCategoryObject ); + +################################### +## +#! @Section Operations +## +################################### + +#! @Arguments PSh, lists_of_cofactors +DeclareOperation( "CoconesOfCoproducts", + [ IsCapCategory, IsList ] ); + +#! @Arguments PSh, lists_of_cofactors_by_indices +DeclareOperation( "CoconesOfCoproductsByIndices", + [ IsCapCategory, IsList ] ); + +#! @Arguments PSh, lists_of_factors +DeclareOperation( "ConesOfProducts", + [ IsCapCategory, IsList ] ); + +#! @Arguments PSh, lists_of_factors_by_indices +DeclareOperation( "ConesOfProductsByIndices", + [ IsCapCategory, IsList ] ); diff --git a/FunctorCategories/gap/Tools.gi b/FunctorCategories/gap/Tools.gi index f6afe3f24..13d4e616d 100644 --- a/FunctorCategories/gap/Tools.gi +++ b/FunctorCategories/gap/Tools.gi @@ -13,3 +13,79 @@ InstallOtherMethod( QUO, return HomalgMatrix( mat, CommutativeRingOfLinearCategory( A ) ) / A; end ); + +## +InstallOtherMethodForCompilerForCAP( CoconesOfCoproducts, + [ IsCapCategory and IsThinCategory, IsList ], + + function( P, list_of_coproducts ) + local coproducts, cocones; + + if not CanCompute( P, "UniqueMorphism" ) then + Error( "the poset `P` 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] ) ) ); + + return ListN( coproducts, cocones, { coproduct, cocone } -> [ coproduct, cocone ] ); + +end ); + +## +InstallOtherMethodForCompilerForCAP( CoconesOfCoproductsByIndices, + [ IsCapCategory and IsThinCategory, IsList ], + + function( P, list_of_coproducts_by_indices ) + local offset, objects, coproducts, cofactors, list_of_coproducts; + + offset := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "offset", 0 ); + + 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 CoconesOfCoproducts( P, list_of_coproducts ); + +end ); + +## +InstallOtherMethodForCompilerForCAP( ConesOfProducts, + [ IsCapCategory and IsThinCategory, IsList ], + + function( P, list_of_products ) + local products, cones; + + if not CanCompute( P, "UniqueMorphism" ) then + Error( "the poset `P` cannot compute the categorical operation `UniqueMorphism`\n" ); + fi; + + products := List( list_of_products, cone -> cone[1] ); + cones := List( list_of_products, cone -> List( cone[2], factor -> UniqueMorphism( P, cone[1], factor ) ) ); + + return ListN( products, cones, { product, cone } -> [ product, cone ] ); + +end ); + +## +InstallOtherMethodForCompilerForCAP( ConesOfProductsByIndices, + [ IsCapCategory and IsThinCategory, IsList ], + + function( P, list_of_products_by_indices ) + local offset, objects, products, factors, list_of_products; + + offset := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "offset", 0 ); + + objects := SetOfObjects( P ); + + products := List( list_of_products_by_indices, cone -> objects[offset + cone[1]] ); + factors := List( list_of_products_by_indices, cone -> List( cone[2], i -> objects[offset + i] ) ); + + list_of_products := ListN( products, factors, { product, factor } -> [ product, factor ] ); + + return ConesOfProducts( P, list_of_products ); + +end ); diff --git a/FunctorCategories/init.g b/FunctorCategories/init.g index cf162c1c5..ab7f92c13 100644 --- a/FunctorCategories/init.g +++ b/FunctorCategories/init.g @@ -16,6 +16,8 @@ ReadPackage( "FunctorCategories", "gap/CategoryOfReflexiveQuivers.gd"); ReadPackage( "FunctorCategories", "gap/FiniteCompletion.gd"); ReadPackage( "FunctorCategories", "gap/FreeDistributiveCompletion.gd"); ReadPackage( "FunctorCategories", "gap/AbelianClosure.gd"); +ReadPackage( "FunctorCategories", "gap/ClosedPreSheavesWRTColimitingCocones.gd"); +ReadPackage( "FunctorCategories", "gap/ClosedCoPreSheavesWRTLimitingCones.gd"); ReadPackage( "FunctorCategories", "gap/Functors.gd"); ReadPackage( "FunctorCategories", "gap/DirectSumDecomposition.gd"); ReadPackage( "FunctorCategories", "gap/HomologicalMethods.gd"); diff --git a/FunctorCategories/read.g b/FunctorCategories/read.g index 38c2ad3cd..7d7622d18 100644 --- a/FunctorCategories/read.g +++ b/FunctorCategories/read.g @@ -34,6 +34,8 @@ ReadPackage( "FunctorCategories", "gap/CategoryOfReflexiveQuivers.gi"); ReadPackage( "FunctorCategories", "gap/FiniteCompletion.gi"); ReadPackage( "FunctorCategories", "gap/FreeDistributiveCompletion.gi"); ReadPackage( "FunctorCategories", "gap/AbelianClosure.gi"); +ReadPackage( "FunctorCategories", "gap/ClosedPreSheavesWRTColimitingCocones.gi"); +ReadPackage( "FunctorCategories", "gap/ClosedCoPreSheavesWRTLimitingCones.gi"); ReadPackage( "FunctorCategories", "gap/Functors.gi"); ReadPackage( "FunctorCategories", "gap/DirectSumDecomposition.gi"); ReadPackage( "FunctorCategories", "gap/HomologicalMethods.gi"); diff --git a/Locales/examples/DifferenceCSL.g b/Locales/examples/DifferenceCSL.g new file mode 100644 index 000000000..ace3b94ee --- /dev/null +++ b/Locales/examples/DifferenceCSL.g @@ -0,0 +1,93 @@ +#! @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 ) ); +coPSh := CoPreSheaves( P );; +Length( SetOfObjects( coPSh ) ); +#! 41 +products := [ [ P.m1_x_s2, [ P.m1, P.s2 ] ], + [ P.m0_x_s1, [ P.m0, P.s1 ] ] ];; ## the order is important +coPSh_J := ClosedCoPreSheavesWRTProducts( P, products );; +coY := CoYonedaEmbeddingOfSourceCategory( coPSh_J ); +#! co-Yoneda embedding functor +objs_coPSh_J := SetOfObjects( coPSh_J ); +Assert( 0, Length( objs_coPSh_J ) = 28 ); +#Splash( DotVertexLabelledDigraph( coPSh_J, [ coY ], [ "darkgreen", "blue" ] : offset := 0 ) ); +coproducts := [ [ coPSh_J.s1_u_m2, [ coPSh_J.s1, coPSh_J.m2 ] ], + [ coPSh_J.s0_u_m1, [ coPSh_J.s0, coPSh_J.m1 ] ] ];; ## the order is important +PSh_J := ClosedPreSheavesWRTCoproducts( coPSh_J, coproducts );; +Y := YonedaEmbeddingOfSourceCategory( PSh_J ); +Assert( 0, IsHomSetInhabited( PSh_J.m0, PSh_J.s0_u_m1 ) ); +Assert( 0, IsHomSetInhabited( PSh_J.m1, PSh_J.s1_u_m2 ) ); +Assert( 0, IsHomSetInhabited( PSh_J.m0_x_s1, PSh_J.s0 ) ); +Assert( 0, IsHomSetInhabited( PSh_J.m1_x_s2, PSh_J.s1 ) ); +Assert( 0, DirectProduct( PSh_J.m0, PSh_J.s1 ) = PSh_J.m0_x_s1 ); +Assert( 0, DirectProduct( PSh_J.m1, PSh_J.s2 ) = PSh_J.m1_x_s2 ); +Assert( 0, Coproduct( PSh_J.s0, PSh_J.m1 ) = PSh_J.s0_u_m1 ); +Assert( 0, Coproduct( PSh_J.s1, PSh_J.m2 ) = PSh_J.s1_u_m2 ); +#objs := SetOfObjects( PSh_J ); + +#PSh := PreSheaves( coPSh_J ); +#objs := SetOfObjects( PSh ); ## took 122h 15m to compute +#Length( objs ); ## 728 +#Splash( DotVertexLabelledDigraph( PSh_J, [ PreCompose( coY, Y ), Y ], [ "red", "blue", "darkgreen" ] ) ); +#! @EndExample diff --git a/Locales/examples/FreeBooleanAlgebra.g b/Locales/examples/FreeBooleanAlgebra.g new file mode 100644 index 000000000..9e38251d7 --- /dev/null +++ b/Locales/examples/FreeBooleanAlgebra.g @@ -0,0 +1,65 @@ +#! @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 +#Splash( DotVertexLabelledDigraph( Dist, [ [ Dist.p, Dist.q ] ], [ "magenta", "blue" ] ) ); +DiffbCSL := MeetSemilatticeOfSingleDifferences( Dist ); +#! MeetSemilatticeOfSingleDifferences( FreeDistributiveCompletion( +#! PosetOfCategory( PathCategory( FinQuiver( "quiver(p,q)[]" ) ) ) ) ) +Length( SetOfObjects( DiffbCSL ) ); +#! 13 +#Splash( DotVertexLabelledDigraph( DiffbCSL, [ [ DiffbCSL.p, DiffbCSL.q ], SetOfGeneratingObjects( DiffbCSL ) ], [ "orange", "blue", "magenta" ] ) ); +PSh := PreSheaves( DiffbCSL ); +#! PreSheaves( MeetSemilatticeOfSingleDifferences( FreeDistributiveCompletion( +#! PosetOfCategory( PathCategory( FinQuiver( "quiver(p,q)[]" ) ) ) ) ), +#! IntervalCategory ) +Y := YonedaEmbeddingOfSourceCategory( PSh );; +Length( SetOfObjects( PSh ) ); +#! 85 +coproducts := [ [ 1, [ ] ], + [ 3, [ 5, 11 ] ], + [ 4, [ 5, 12 ] ], + [ 7, [ 10, 12 ] ], + [ 8, [ 10, 11 ] ], + [ 13, [ 11, 12 ] ], + [ 6, [ 3, 4, 13 ] ], + [ 9, [ 7, 8, 13 ] ], + [ 2, [ 6, 9 ] ] ];; +PSh_J := ClosedPreSheavesWRTCoproductsByIndices( DiffbCSL, coproducts );; +psh_J := ModelingCategory( ModelingCategory( PSh_J ) );; +Assert( 0, Length( SetOfObjects( psh_J ) ) = 16 ); +is_closed := psh_J!.ObjectMembershipFunction; +closed := SetOfObjects( PSh_J );; +Assert( 0, Length( closed ) = 16 ); +Assert( 0, ForAll( closed, obj -> is_closed( ObjectDatum( ModelingObject( PSh_J, obj ) ) ) ) ); +#Splash( DotVertexLabelledDigraph( PSh, [ [ PSh.p, PSh.q ], List( SetOfGeneratingObjects( DiffbCSL ), Y ), Y, psh_J ], [ "gray", "blue", "magenta", "orange", "red" ] ) ); +#Splash( DotVertexLabelledDigraph( psh_J, [ [ PSh.p, PSh.q ], List( SetOfGeneratingObjects( DiffbCSL ), Y ), Y ], [ "red", "blue", "magenta", "orange" ] : offset := 0 ) ); +#! @EndExample diff --git a/Locales/examples/PSh_J_coPSh_J.g b/Locales/examples/PSh_J_coPSh_J.g new file mode 100644 index 000000000..4fd316ee8 --- /dev/null +++ b/Locales/examples/PSh_J_coPSh_J.g @@ -0,0 +1,73 @@ +#! @Chunk DifferenceCSL + +# the assumption si <= mi leads to fewer meets and joins: + +#! @Example +LoadPackage( "FunctorCategories", false ); +#! true +q := "q(m0,s0,m1,s1,m0_x_s1,s0_u_m1)\ +[sm0:s0->m0,sm1:s1->m1,\ +p011:m0_x_s1->s1,\ +i101:m1->s0_u_m1,\ +mc0:m0_x_s1->s0,jc0:m0->s0_u_m1]";; +q := FinQuiver( q ); +#! FinQuiver( "q(m0,s0,m1,s1,m0_x_s1,s0_u_m1) +#! [sm0:s0-≻m0,sm1:s1-≻m1,p011:m0_x_s1-≻s1, +#! i101:m1-≻s0_u_m1,mc0:m0_x_s1-≻s0,jc0:m0-≻s0_u_m1]" ) +F := PathCategory( q ); +#! PathCategory( FinQuiver( "q(m0,s0,m1,s1,m0_x_s1,s0_u_m1) +#! [sm0:s0-≻m0,sm1:s1-≻m1,p011:m0_x_s1-≻s1, +#! i101:m1-≻s0_u_m1,mc0:m0_x_s1-≻s0,jc0:m0-≻s0_u_m1]" ) ) +Size( F ); +#! 18 +HomStructure( F.s0, F.s0_u_m1 ); +#! |1| +HomStructure( F.m0_x_s1, F.m0 ); +#! |1| +C := F / + [ [ F.p011 * F.sm1 * F.i101, F.mc0 * F.sm0 * F.jc0 ] ]; +#! 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 ); +#! 17 +P := PosetOfCategory( F );; +Size( P ); +#! 17 +digraphF := DigraphOfPoset( P );; +digraphF!.vertexlabels := List( SetOfObjects( F ), String ); +#Splash( DotVertexLabelledDigraph( digraphF ) ); +#Splash( DotVertexLabelledDigraph( DigraphOfPoset( P ) ) ); +coPSh := CoPreSheaves( P );; +Length( SetOfObjects( coPSh ) ); +#! 11 +products := [ [ P.m0_x_s1, [ P.m0, P.s1 ] ] ];; +coPSh_J := ClosedCoPreSheavesWRTProducts( P, products );; +coY := CoYonedaEmbeddingOfSourceCategory( coPSh_J ); +#! co-Yoneda embedding functor +objs_coPSh_J := SetOfObjects( coPSh_J ); +Assert( 0, Length( objs_coPSh_J ) = 9 ); +#Splash( DotVertexLabelledDigraph( coPSh_J, [ coY ], [ "darkgreen", "blue" ] ) ); +#coproducts := [ [ coPSh_J.s0_u_m1, [ coPSh_J.s0, coPSh_J.m1 ] ] ];; +coproducts := [ [ coPSh_J.s0_u_m1, [ coPSh_J.s0, coPSh_J.m1 ] ], + [ objs_coPSh_J[1 + 1], [ objs_coPSh_J[1 + 2], objs_coPSh_J[1 + 7] ] ] ];; +PSh_J := ClosedPreSheavesWRTCoproducts( coPSh_J, coproducts );; +Y := YonedaEmbeddingOfSourceCategory( PSh_J ); +#! Yoneda embedding functor +Assert( 0, IsHomSetInhabited( PSh_J.m0, PSh_J.s0_u_m1 ) ); +Assert( 0, IsHomSetInhabited( PSh_J.m0_x_s1, PSh_J.s0 ) ); +Assert( 0, DirectProduct( PSh_J.m0, PSh_J.s1 ) = PSh_J.m0_x_s1 ); +Assert( 0, Coproduct( PSh_J.s0, PSh_J.m1 ) = PSh_J.s0_u_m1 ); +objs := SetOfObjects( PSh_J ); +Assert( 0, Length( objs ) = 14 ); +#Splash( DotVertexLabelledDigraph( PSh_J, [ PreCompose( coY, Y ), Y ], [ "red", "blue", "darkgreen" ] : offset := 0 ) ); +#PSh := PreSheaves( coPSh_J ); +#objs := SetOfObjects( PSh ); ## took 122h 15m to compute +#Length( objs ); ## 728 +#! @EndExample diff --git a/Locales/gap/ProsetDerivedMethods.gi b/Locales/gap/ProsetDerivedMethods.gi index febe99fca..152803cf4 100644 --- a/Locales/gap/ProsetDerivedMethods.gi +++ b/Locales/gap/ProsetDerivedMethods.gi @@ -99,9 +99,9 @@ AddDerivationToCAP( UniversalMorphismIntoTerminalObject, [ [ TerminalObject, 1 ], [ UniqueMorphism, 1 ] ], - function( cat, A ) + function( cat, source ) - return UniqueMorphism( cat, A, TerminalObject( cat ) ); + return UniqueMorphism( cat, source, TerminalObject( cat ) ); end : CategoryFilter := IsThinCategory ); @@ -123,9 +123,9 @@ AddDerivationToCAP( UniversalMorphismFromInitialObject, [ [ InitialObject, 1 ], [ UniqueMorphism, 1 ] ], - function( cat, A ) + function( cat, target ) - return UniqueMorphism( cat, InitialObject( cat ), A ); + return UniqueMorphism( cat, InitialObject( cat ), target ); end : CategoryFilter := IsThinCategory ); 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..6efb74e14 100644 --- a/Locales/gap/ToolsUsingDigraphs.gi +++ b/Locales/gap/ToolsUsingDigraphs.gi @@ -208,14 +208,16 @@ InstallMethod( DigraphOfPoset, [ IsThinCategory and IsFiniteCategory ], function( P ) - local objects, D; + local objects, offset, D; objects := SetOfObjectsOfCategory( P ); + offset := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "offset", 1 ); + if ValueOption( "use_vertex_labels" ) = true then D := Digraph( objects, IsHomSetInhabited ); else - D := Digraph( [ 0 .. Length( objects ) - 1 ], { i, j } -> IsHomSetInhabited( objects[1+i], objects[1+j] ) ); + D := Digraph( [ offset .. offset + Length( objects ) - 1 ], { i, j } -> IsHomSetInhabited( objects[1-offset+i], objects[1-offset+j] ) ); fi; D := DigraphReflexiveTransitiveReduction( D ); @@ -226,6 +228,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/PackageInfo.g b/SubcategoriesForCAP/PackageInfo.g index bea524bab..58b558820 100644 --- a/SubcategoriesForCAP/PackageInfo.g +++ b/SubcategoriesForCAP/PackageInfo.g @@ -10,7 +10,7 @@ SetPackageInfo( rec( PackageName := "SubcategoriesForCAP", Subtitle := "Subcategory and other related constructors for CAP categories", -Version := "2024.03-03", +Version := "2024.03-04", Date := (function ( ) if IsBound( GAPInfo.SystemEnvironment.GAP_PKG_RELEASE_DATE ) then return GAPInfo.SystemEnvironment.GAP_PKG_RELEASE_DATE; else return Concatenation( ~.Version{[ 1 .. 4 ]}, "-", ~.Version{[ 6, 7 ]}, "-01" ); fi; end)( ), License := "GPL-2.0-or-later", diff --git a/SubcategoriesForCAP/gap/FullSubcategory.gi b/SubcategoriesForCAP/gap/FullSubcategory.gi index 75da0cadb..539de3a89 100644 --- a/SubcategoriesForCAP/gap/FullSubcategory.gi +++ b/SubcategoriesForCAP/gap/FullSubcategory.gi @@ -362,10 +362,10 @@ InstallMethod( Display, [ IsObjectInAFullSubcategory ], function( a ) - Print( "An object in full subcategory given by: " ); - Display( UnderlyingCell( a ) ); + Display( "\nAn object in full subcategory given by the above data" ); + end ); ## @@ -373,8 +373,8 @@ InstallMethod( Display, [ IsMorphismInAFullSubcategory ], function( phi ) - Print( "A morphism in full subcategory given by: " ); - Display( UnderlyingCell( phi ) ); + Display( "\nA morphism in full subcategory given by the above data" ); + end ); diff --git a/SubcategoriesForCAP/gap/KleisliReflectiveSubcategoryOfIdempotentMonad.gd b/SubcategoriesForCAP/gap/KleisliReflectiveSubcategoryOfIdempotentMonad.gd new file mode 100644 index 000000000..7c34551d0 --- /dev/null +++ b/SubcategoriesForCAP/gap/KleisliReflectiveSubcategoryOfIdempotentMonad.gd @@ -0,0 +1,86 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# SubcategoriesForCAP: Subcategory and other related constructors for CAP categories +# +# Declarations +# + +#! @Chapter Kleisli reflective subcategory of an idempotent monad + +#################################### +# +#! @Section GAP categories +# +#################################### + +#! @Description +#! The &GAP; category of Kleisli reflective subcategories of idempotent monads. +DeclareCategory( "IsKleisliReflectiveSubcategoryOfIdempotentMonad", + IsCapCategory ); + +#! @Description +#! The &GAP; category of cells in the Kleisli reflective subcategory of an idempotent monad. +DeclareCategory( "IsCellInKleisliReflectiveSubcategoryOfIdempotentMonad", + IsCapCategoryCell ); + +#! @Description +#! The &GAP; category of objects in the Kleisli reflective subcategory of an idempotent monad. +DeclareCategory( "IsObjectInKleisliReflectiveSubcategoryOfIdempotentMonad", + IsCellInKleisliReflectiveSubcategoryOfIdempotentMonad and IsCapCategoryObject ); + +#! @Description +#! The &GAP; category of morphisms in the Kleisli reflective subcategory of an idempotent monad. +DeclareCategory( "IsMorphismInKleisliReflectiveSubcategoryOfIdempotentMonad", + IsCellInKleisliReflectiveSubcategoryOfIdempotentMonad and IsCapCategoryMorphism ); + +#################################### +# +#! @Section Constructors +# +#################################### + +#! @Description +#! Return the Kleisli reflective subcategory of the idempotent monad $T:C \to C$ +#! with unit eta:$\mathrm{Id}_C \to T$. +#! @Arguments T +DeclareAttribute( "KleisliReflectiveSubcategoryOfIdempotentMonad", + IsCapNaturalTransformation ); + +#CapJitAddTypeSignature( "KleisliReflectiveSubcategoryOfIdempotentMonad", [ IsCapFunctor ], function ( input_types ) +# +# return CapJitDataTypeOfCategory( KleisliReflectiveSubcategoryOfIdempotentMonad( input_types[1].category ) ); +# +#end ); + +#################################### +# +#! @Section Attributes +# +#################################### + +#! @Description +#! The input is the Kleisli reflective subcategory C_T of an idempotent monad $T:C \to C$. +#! The output is the monad $T$. +#! @Arguments C_T +DeclareAttribute( "UnderlyingMonadUnit", + IsKleisliReflectiveSubcategoryOfIdempotentMonad ); + +#! @Description +#! The input is the Kleisli reflective subcategory of an idempotent monad $T:C \to C$. +#! The output is the monad $T$. +#! @Arguments C_T +DeclareAttribute( "UnderlyingMonad", + IsKleisliReflectiveSubcategoryOfIdempotentMonad ); + +#! @Description +#! The input is the Kleisli reflective subcategory of an idempotent monad $T:C \to C$. +#! The output is the underlying category $C$. +#! @Arguments C_T +DeclareAttribute( "AmbientCategory", + IsKleisliReflectiveSubcategoryOfIdempotentMonad ); + +CapJitAddTypeSignature( "AmbientCategory", [ IsKleisliReflectiveSubcategoryOfIdempotentMonad ], + function ( input_types ) + + return CapJitDataTypeOfCategory( AmbientCategory( input_types[1].category ) ); + +end ); diff --git a/SubcategoriesForCAP/gap/KleisliReflectiveSubcategoryOfIdempotentMonad.gi b/SubcategoriesForCAP/gap/KleisliReflectiveSubcategoryOfIdempotentMonad.gi new file mode 100644 index 000000000..f8b3f654f --- /dev/null +++ b/SubcategoriesForCAP/gap/KleisliReflectiveSubcategoryOfIdempotentMonad.gi @@ -0,0 +1,266 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# SubcategoriesForCAP: Subcategory and other related constructors for CAP categories +# +# Implementations +# + +## +InstallMethod( KleisliReflectiveSubcategoryOfIdempotentMonad, + "for a CAP natural transformation", + [ IsCapNaturalTransformation ], + + function ( eta ) + local T, C, + object_datum_type, object_constructor, object_datum, + morphism_datum_type, morphism_constructor, morphism_datum, + object_membership_func, reflective_subcategory, + modeling_tower_object_constructor, modeling_tower_object_datum, + modeling_tower_morphism_constructor, modeling_tower_morphism_datum, + Kleisli; + + T := Target( eta ); + C := SourceOfFunctor( T ); + + #% CAP_JIT_DROP_NEXT_STATEMENT + Assert( 0, IsIdenticalObj( C, RangeOfFunctor( T ) ) ); + + ## + object_datum_type := + CapJitDataTypeOfObjectOfCategory( C ); + + ## + object_constructor := + function( Kleisli, obj ) + + return CreateCapCategoryObjectWithAttributes( Kleisli, + AsPrimitiveValue, obj ); + + end; + + ## + object_datum := { Kleisli, o } -> AsPrimitiveValue( o ); + + ## + morphism_datum_type := + CapJitDataTypeOfMorphismOfCategory( C ); + + ## + morphism_constructor := + function( Kleisli, source, mor, target ) + + return CreateCapCategoryMorphismWithAttributes( Kleisli, + source, + target, + AsPrimitiveValue, mor ); + + end; + + ## + morphism_datum := { Kleisli, m } -> AsPrimitiveValue( m ); + + ## building the categorical tower: + + if IsBound( T!.ObjectMembershipFunction ) then + object_membership_func := T!.ObjectMembershipFunction; + else + object_membership_func := + function( object ) + + return IsIsomorphism( C, eta( object ) ); + + end; + fi; + + reflective_subcategory := FullSubcategoryByObjectMembershipFunction( C, object_membership_func : FinalizeCategory := true ); + + ## from the raw object data to the object in the modeling category + modeling_tower_object_constructor := + function( Kleisli, obj ) + local reflective_subcategory; + + reflective_subcategory := ModelingCategory( Kleisli ); + + return ObjectConstructor( reflective_subcategory, + obj ); + + end; + + ## from the object in the modeling category to the raw object data + modeling_tower_object_datum := + function( Kleisli, obj ) + local reflective_subcategory; + + reflective_subcategory := ModelingCategory( Kleisli ); + + return ObjectDatum( reflective_subcategory, + obj ); + + end; + + ## from the raw morphism data to the morphism in the modeling category + modeling_tower_morphism_constructor := + function( Kleisli, source, mor, target ) + local reflective_subcategory; + + reflective_subcategory := ModelingCategory( Kleisli ); + + return MorphismConstructor( reflective_subcategory, + source, + mor, + target ); + + end; + + ## from the morphism in the modeling category to the raw morphism data + modeling_tower_morphism_datum := + function( Kleisli, mor ) + local reflective_subcategory; + + reflective_subcategory := ModelingCategory( Kleisli ); + + return MorphismDatum( reflective_subcategory, + mor ); + + end; + + ## + Kleisli := + ReinterpretationOfCategory( reflective_subcategory, + rec( name := Concatenation( "KleisliReflectiveSubcategoryOfIdempotentMonad( ", Name( eta ), " )" ), + category_filter := IsKleisliReflectiveSubcategoryOfIdempotentMonad, + category_object_filter := IsObjectInKleisliReflectiveSubcategoryOfIdempotentMonad, + category_morphism_filter := IsMorphismInKleisliReflectiveSubcategoryOfIdempotentMonad, + object_datum_type := object_datum_type, + morphism_datum_type := morphism_datum_type, + object_constructor := object_constructor, + object_datum := object_datum, + morphism_constructor := morphism_constructor, + morphism_datum := morphism_datum, + modeling_tower_object_constructor := modeling_tower_object_constructor, + modeling_tower_object_datum := modeling_tower_object_datum, + modeling_tower_morphism_constructor := modeling_tower_morphism_constructor, + modeling_tower_morphism_datum := modeling_tower_morphism_datum, + only_primitive_operations := true ) + : FinalizeCategory := false ); + + SetUnderlyingMonad( Kleisli, T ); + SetAmbientCategory( Kleisli, C ); + + Append( Kleisli!.compiler_hints.category_attribute_names, + [ "UnderlyingMonad", + "AmbientCategory" ] ); + + Finalize( Kleisli ); + + return Kleisli; + +end ); + +## +InstallMethod( \., + "for the Kleisli reflective subcategory of an idempotent monad and a positive integer", + [ IsKleisliReflectiveSubcategoryOfIdempotentMonad, IsPosInt ], + + function( Kleisli, string_as_int ) + local name, reflective_subcategory, c; + + name := NameRNam( string_as_int ); + + reflective_subcategory := ModelingCategory( Kleisli ); + + c := reflective_subcategory.(name); + + if IsCapCategoryObject( c ) and IsIdenticalObj( CapCategory( c ), reflective_subcategory ) then + + return ReinterpretationOfObject( Kleisli, c ); + + elif IsCapCategoryMorphism( c ) and IsIdenticalObj( CapCategory( c ), reflective_subcategory ) then + + return ReinterpretationOfMorphism( Kleisli, + ReinterpretationOfObject( Kleisli, Source( c ) ), + c, + ReinterpretationOfObject( Kleisli, Target( c ) ) ); + + else + + Error( "`c` is neither an object nor a morphism in the ambient category `C`\n" ); + + fi; + +end ); + +## +InstallMethodForCompilerForCAP( SetOfObjects, + "for the Kleisli reflective subcategory of an idempotent monad", + [ IsKleisliReflectiveSubcategoryOfIdempotentMonad ], + + function( cat ) + + return SetOfObjectsOfCategory( cat ); + +end ); + +## +InstallMethodForCompilerForCAP( SetOfGeneratingMorphisms, + "for the Kleisli reflective subcategory of an idempotent monad", + [ IsKleisliReflectiveSubcategoryOfIdempotentMonad ], + + function( cat ) + + return SetOfGeneratingMorphismsOfCategory( cat ); + +end ); + +################################## +## +## View & Display +## +################################## + +## +InstallMethod( ViewObj, + [ IsObjectInKleisliReflectiveSubcategoryOfIdempotentMonad ], + + function( a ) + + Print( "An object in the Kleisli category of an idempotent monad given by: " ); + + ViewObj( ObjectDatum( a ) ); + +end ); + +## +InstallMethod( ViewObj, + [ IsMorphismInASubcategory ], + + function( phi ) + + Print( "A morphism in the Kleisli category of an idempotent monad given by: " ); + + ViewObj( MorphismDatum( phi ) ); + +end ); + +## +InstallMethod( Display, + [ IsObjectInKleisliReflectiveSubcategoryOfIdempotentMonad ], + + function( a ) + + Display( ObjectDatum( a ) ); + + Display( "\nAn object in the Kleisli category of an idempotent monad given by the above data" ); + +end ); + +## +InstallMethod( Display, + [ IsMorphismInASubcategory ], + + function( phi ) + + Display( MorphismDatum( phi ) ); + + Display( "\nA morphism in the Kleisli category of an idempotent monad given by the above data" ); + +end ); diff --git a/SubcategoriesForCAP/gap/Subcategory.gi b/SubcategoriesForCAP/gap/Subcategory.gi index bea7d87fd..fcf97b427 100644 --- a/SubcategoriesForCAP/gap/Subcategory.gi +++ b/SubcategoriesForCAP/gap/Subcategory.gi @@ -90,7 +90,8 @@ InstallMethod( Subcategory, [ IsCapCategory, IsString ], function( C, name ) - local category_constructor_options, list_of_operations_to_install, is_full, is_additive, skip, func, pos, properties, D; + local category_constructor_options, list_of_operations_to_install, is_full, is_additive, additional_operations_to_install, + skip, func, pos, properties, additional_properties, D; category_constructor_options := rec( name := name, @@ -116,6 +117,10 @@ InstallMethod( Subcategory, is_additive := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "is_additive", false ); + additional_operations_to_install := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "additional_operations_to_install", [ ] ); + + list_of_operations_to_install := DuplicateFreeList( Concatenation( list_of_operations_to_install, additional_operations_to_install ) ); + if IsIdenticalObj( is_full, true ) then Append( list_of_operations_to_install, CAP_INTERNAL_METHOD_NAME_LIST_FOR_FULL_SUBCATEGORY ); fi; @@ -180,7 +185,11 @@ InstallMethod( Subcategory, Add( properties, "IsAdditiveCategory" ); fi; - category_constructor_options.properties := properties; + additional_properties := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "properties", [ ] ); + + category_constructor_options.properties := Concatenation( properties, additional_properties ); + + category_constructor_options.supports_empty_limits := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "supports_empty_limits", false ); D := CategoryConstructor( category_constructor_options ); @@ -288,6 +297,33 @@ InstallGlobalFunction( SubcategoryGeneratedByListOfMorphisms, end ); +## +InstallMethod( \., + "for a subcategory and a positive integer", + [ IsCapSubcategory, IsPosInt ], + + function( subcategory, string_as_int ) + local name, C, c; + + name := NameRNam( string_as_int ); + + C := AmbientCategory( subcategory ); + + c := C.(name); + + if ( IsCapCategoryObject( c ) or IsCapCategoryMorphism( c ) ) and + IsIdenticalObj( CapCategory( c ), C ) then + + return c / subcategory; + + else + + Error( "`c` is neither an object nor a morphism in the ambient category `C`\n" ); + + fi; + +end ); + ## InstallMethodForCompilerForCAP( SetOfObjects, "for a subcategory", @@ -318,7 +354,8 @@ end ); ## InstallMethod( ViewObj, - [ IsObjectInASubcategory ], + [ IsObjectInASubcategory ], + function( a ) Print( "An object in subcategory given by: " ); @@ -329,7 +366,8 @@ end ); ## InstallMethod( ViewObj, - [ IsMorphismInASubcategory ], + [ IsMorphismInASubcategory ], + function( phi ) Print( "A morphism in subcategory given by: " ); @@ -340,7 +378,8 @@ end ); ## InstallMethod( Display, - [ IsObjectInASubcategory ], + [ IsObjectInASubcategory ], + function( a ) Print( "An object in subcategory given by: " ); @@ -351,7 +390,8 @@ end ); ## InstallMethod( Display, - [ IsMorphismInASubcategory ], + [ IsMorphismInASubcategory ], + function( phi ) Print( "A morphism in subcategory given by: " ); @@ -359,4 +399,3 @@ InstallMethod( Display, Display( UnderlyingCell( phi ) ); end ); - 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/init.g b/SubcategoriesForCAP/init.g index f2be236d6..d0ac90610 100644 --- a/SubcategoriesForCAP/init.g +++ b/SubcategoriesForCAP/init.g @@ -7,6 +7,7 @@ ReadPackage( "SubcategoriesForCAP", "gap/Subcategory.gd"); ReadPackage( "SubcategoriesForCAP", "gap/FullSubcategory.gd"); ReadPackage( "SubcategoriesForCAP", "gap/FunctorsForFullSubcategories.gd"); +ReadPackage( "SubcategoriesForCAP", "gap/KleisliReflectiveSubcategoryOfIdempotentMonad.gd"); if IsPackageMarkedForLoading( "Toposes", ">= 2020.02.19" ) and IsPackageMarkedForLoading( "FreydCategoriesForCAP", ">= 2019.11.02" ) then diff --git a/SubcategoriesForCAP/read.g b/SubcategoriesForCAP/read.g index 5389bf890..043519945 100644 --- a/SubcategoriesForCAP/read.g +++ b/SubcategoriesForCAP/read.g @@ -7,6 +7,7 @@ ReadPackage( "SubcategoriesForCAP", "gap/Subcategory.gi"); ReadPackage( "SubcategoriesForCAP", "gap/FullSubcategory.gi"); ReadPackage( "SubcategoriesForCAP", "gap/FunctorsForFullSubcategories.gi"); +ReadPackage( "SubcategoriesForCAP", "gap/KleisliReflectiveSubcategoryOfIdempotentMonad.gi"); if IsPackageMarkedForLoading( "Toposes", ">= 2020.02.19" ) and IsPackageMarkedForLoading( "FreydCategoriesForCAP", ">= 2019.11.02" ) then @@ -16,3 +17,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; diff --git a/ToolsForCategoricalTowers/gap/Tools.gi b/ToolsForCategoricalTowers/gap/Tools.gi index f3193c34c..18ea5f5c1 100644 --- a/ToolsForCategoricalTowers/gap/Tools.gi +++ b/ToolsForCategoricalTowers/gap/Tools.gi @@ -961,6 +961,39 @@ InstallGlobalFunction( PositionsOfSublist, end ); +## +InstallMethod( \., + "for an opposite category and a positive integer", + [ IsCapCategory and WasCreatedAsOppositeCategory, IsPosInt ], + + function( C_op, string_as_int ) + local name, C, c; + + name := NameRNam( string_as_int ); + + C := OppositeCategory( C_op ); + + c := C.(name); + + if IsCapCategoryObject( c ) and IsIdenticalObj( CapCategory( c ), C ) then + + return ObjectConstructor( C_op, c ); + + elif IsCapCategoryMorphism( c ) and IsIdenticalObj( CapCategory( c ), C ) then + + return MorphismConstructor( C_op, + ObjectConstructor( C_op, Target( c ) ), + c, + ObjectConstructor( C_op, Source( c ) ) ); + + else + + Error( "`c` is neither an object nor a morphism in the category `C := OppositeCategory( C_op )`\n" ); + + fi; + +end ); + ## InstallMethod( AllCoproducts, "for a CAP category and list of objects",