Skip to content

Commit

Permalink
Replace operation_weights in CategoryConstructor by a better mechanism
Browse files Browse the repository at this point in the history
When using the string "default" for create_func_*, one must now set the
option `underlying_category`, from which the weight is determined. If
create_func_* is a function, one can (optionally) set a weight by returning
a pair of a string and an integer (instead of only a string).
  • Loading branch information
zickgraf committed Oct 8, 2024
1 parent f62f38f commit ac4cf7c
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 43 deletions.
7 changes: 4 additions & 3 deletions CAP/gap/CategoryConstructor.gd
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ DeclareInfoClass( "InfoCategoryConstructor" );
#! * `morphism_constructor` (optional): function added as an installation of <Ref Oper="MorphismConstructor" Label="for IsCapCategoryObject, IsObject, IsCapCategoryObject" /> to the category
#! * `morphism_datum` (optional): function added as an installation of <Ref Oper="MorphismDatum" Label="for IsCapCategoryMorphism" /> to the category
#! * `list_of_operations_to_install` (mandatory): a list of names of &CAP; operations which should be installed for the category
#! * `operation_weights` (optional): a record mapping operations in `list_of_operations_to_install` to their weights
#! * `is_computable` (optional): whether the category can decide `IsCongruentForMorphisms`
#! * `supports_empty_limits` (optional): whether the category supports empty lists in inputs to operations of limits and colimits
#! * `underlying_category_getter_string` (optional): see below
#! * `underlying_category` (optional): see below
#! * `underlying_object_getter_string` (optional): see below
#! * `underlying_morphism_getter_string` (optional): see below
#! * `top_object_getter_string` (optional): see below
Expand All @@ -53,8 +53,9 @@ DeclareInfoClass( "InfoCategoryConstructor" );
#!
#! The values of the keys `create_func_*` should be either the string `"default`" or functions which accept the category and the name of a &CAP; operation
#! of the corresponding `return_type`. Values for return types occuring for operations in `list_of_operations_to_install` are mandatory.
#! The functions must return strings, which (after some replacements described below) will be evaluated and added as an installation of the corresponding operation to the category.
#! The value `"default"` chooses a suitable default string, see the implementation for details.
#! The functions must return either strings or pairs of a string and an integer:
#! The strings (after some replacements described below) will be evaluated and added as installations of the corresponding operations to the category with weights given by the integer (if provided).
#! The value `"default"` chooses a suitable default string (see the implementation for details) and gets the weights from `underlying_category`.
#! The following placeholders may be used in the strings and are replaced automatically:
#! * `operation_name` will be replaced by the name of the operation
#! * `input_arguments...` will be replaced by the `input_arguments_names` specified in the method name record (see <Ref Sect="Section_method_name_record_entries" />)
Expand Down
31 changes: 26 additions & 5 deletions CAP/gap/CategoryConstructor.gi
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ InstallMethod( CategoryConstructor,
[ IsRecord ],

function( options )
local known_options_with_filters, name, object_datum_type, morphism_datum_type, is_computable, filter, CC, default_func_strings, info, unknown_filters, create_func_name, create_func, func_string, underlying_arguments, add, func, option_name, prop;
local known_options_with_filters, name, object_datum_type, morphism_datum_type, is_computable, filter, CC, underlying_category, default_func_strings, info, unknown_filters, create_func_name, create_func, func_string, weight, func_string_and_weight, underlying_arguments, add, func, option_name, prop;

## check given options
known_options_with_filters := rec(
Expand All @@ -27,10 +27,10 @@ InstallMethod( CategoryConstructor,
morphism_constructor := IsFunction,
morphism_datum := IsFunction,
list_of_operations_to_install := IsList,
operation_weights := IsRecord,
is_computable := IsBool,
supports_empty_limits := IsBool,
underlying_category_getter_string := IsString,
underlying_category := IsCapCategory,
underlying_object_getter_string := IsString,
underlying_morphism_getter_string := IsString,
top_object_getter_string := IsString,
Expand Down Expand Up @@ -290,11 +290,32 @@ InstallMethod( CategoryConstructor,

if create_func = "default" then

if not IsBound( options.underlying_category ) then

Error( "when using \"default\" for some `create_func_*`, the option `underlying_category` must be set" );

Check warning on line 295 in CAP/gap/CategoryConstructor.gi

View check run for this annotation

Codecov / codecov/patch

CAP/gap/CategoryConstructor.gi#L295

Added line #L295 was not covered by tests

fi;

func_string := default_func_strings.(info.return_type);

# the default strings simply apply the operation in the underlying category
weight := OperationWeight( options.underlying_category, info.function_name );

elif IsFunction( create_func ) then

func_string := create_func( name, CC );
func_string_and_weight := create_func( name, CC );

if IsList( func_string_and_weight ) and Length( func_string_and_weight ) = 2 and IsInt( func_string_and_weight[2] ) then

func_string := func_string_and_weight[1];
weight := func_string_and_weight[2];

else

func_string := func_string_and_weight;
weight := -1;

Check warning on line 316 in CAP/gap/CategoryConstructor.gi

View check run for this annotation

Codecov / codecov/patch

CAP/gap/CategoryConstructor.gi#L315-L316

Added lines #L315 - L316 were not covered by tests

fi;

else

Expand Down Expand Up @@ -464,9 +485,9 @@ InstallMethod( CategoryConstructor,

func := EvalString( func_string );

if IsBound( options.operation_weights ) and IsBound( options.operation_weights.(name) ) then
if weight <> -1 then

add( CC, func, options.operation_weights.(name) );
add( CC, func, weight );

else

Expand Down
4 changes: 2 additions & 2 deletions CAP/gap/DummyImplementations.gi
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,13 @@ InstallMethod( DummyCategory,

fi;

dummy_function := { operation_name, dummy } -> """
dummy_function := { operation_name, dummy } -> Pair( """
function ( input_arguments... )
Error( "this is a dummy category without actual implementation" );
end
""";
""", 1 );

category_constructor_options.create_func_bool := dummy_function;
category_constructor_options.create_func_object := dummy_function;
Expand Down
9 changes: 1 addition & 8 deletions CAP/gap/ReinterpretationOfCategory.gi
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ InstallMethod( ReinterpretationOfCategory,
# the methods for ModelingObject et al. will be installed later once we have a category instance filter
category_constructor_options := rec(
underlying_category_getter_string := "ModelingCategory",
underlying_category := C,
underlying_object_getter_string := "ModelingObject",
underlying_morphism_getter_string := "ModelingMorphism",
top_object_getter_string := "ReinterpretationOfObject",
Expand Down Expand Up @@ -138,14 +139,6 @@ InstallMethod( ReinterpretationOfCategory,

category_constructor_options.list_of_operations_to_install := list_of_operations_to_install;

category_constructor_options.operation_weights := rec( );

for operation in list_of_operations_to_install do

category_constructor_options.operation_weights.(operation) := OperationWeight( C, operation );

od;

if IsBound( C!.supports_empty_limits ) then

category_constructor_options.supports_empty_limits := C!.supports_empty_limits;
Expand Down
44 changes: 22 additions & 22 deletions CAP/gap/TerminalCategory.gi
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ BindGlobal( "IsCapTerminalCategoryMorphismRep", IsMorphismInCapTerminalCategoryW

InstallGlobalFunction( CAP_INTERNAL_CONSTRUCTOR_FOR_TERMINAL_CATEGORY,
function( input_record )
local completed_record, list_of_operations_to_install, skip, info, properties, excluded_properties, T, operation_name;
local completed_record, list_of_operations_to_install, skip, info, properties, excluded_properties, T, operation_name, operation;

completed_record := ShallowCopy( input_record );

Expand Down Expand Up @@ -104,7 +104,7 @@ InstallGlobalFunction( CAP_INTERNAL_CONSTRUCTOR_FOR_TERMINAL_CATEGORY,
## equality of source and target is part of the specification of the input and checked by the pre-function
return true;

end );
end, 1 );

return T;

Expand Down Expand Up @@ -147,27 +147,27 @@ InstallGlobalFunction( TerminalCategoryWithSingleObject, FunctionWithNamedArgume
create_func_object :=
function( name, T )

return """
return Pair( """
function( input_arguments... )
return ObjectConstructor( cat, fail );
end
""";
""", 1 );

end;

## e.g., IdentityMorphism, PreCompose
create_func_morphism :=
function( name, T )

return """
return Pair( """
function( input_arguments... )
return MorphismConstructor( cat, top_source, fail, top_range );
end
""";
""", 1 );

end;

Expand Down Expand Up @@ -211,39 +211,39 @@ InstallGlobalFunction( TerminalCategoryWithSingleObject, FunctionWithNamedArgume

return true;

end );
end, 1 );

##
AddIsWellDefinedForMorphisms( T,
function( T, morphism )

return true;

end );
end, 1 );

##
AddIsEqualForObjects( T,
function( T, object1, object2 )

return true;

end );
end, 1 );

##
AddIsEqualForMorphisms( T,
function( T, morphism1, morphism2 )

return true;

end );
end, 1 );

##
AddMorphismsOfExternalHom( T,
function( T, object_1, object_2 )

return [ TerminalCategoryWithSingleObjectUniqueMorphism( T ) ];

end );
end, 2 );

if CAP_NAMED_ARGUMENTS.FinalizeCategory then

Expand Down Expand Up @@ -321,27 +321,27 @@ InstallGlobalFunction( TerminalCategoryWithMultipleObjects, FunctionWithNamedArg
create_func_object :=
function( name, T )

return """
return Pair( """
function( input_arguments... )
return ObjectConstructor( cat, "operation_name" );
end
""";
""", 1 );

end;

## e.g., IdentityMorphism, PreCompose
create_func_morphism :=
function( name, T )

return """
return Pair( """
function( input_arguments... )
return MorphismConstructor( cat, top_source, "operation_name", top_range );
end
""";
""", 1 );

end;

Expand Down Expand Up @@ -432,50 +432,50 @@ InstallGlobalFunction( TerminalCategoryWithMultipleObjects, FunctionWithNamedArg

return true;

end );
end, 1 );

##
AddSomeIsomorphismBetweenObjects( T,
function( T, object_1, object_2 )

return MorphismConstructor( T, object_1, "SomeIsomorphismBetweenObjects", object_2 );

end );
end, 1 );

AddDistinguishedObjectOfHomomorphismStructure( T,
function( T )

return TerminalCategoryWithSingleObjectUniqueObject( RangeCategoryOfHomomorphismStructure( T ) );

end );
end, 2 );

AddHomomorphismStructureOnObjects( T,
function( T, source, target )

return TerminalCategoryWithSingleObjectUniqueObject( RangeCategoryOfHomomorphismStructure( T ) );

end );
end, 2 );

AddHomomorphismStructureOnMorphismsWithGivenObjects( T,
function( T, source, morphism_1, morphism_2, target )

return TerminalCategoryWithSingleObjectUniqueMorphism( RangeCategoryOfHomomorphismStructure( T ) );

end );
end, 2 );

AddInterpretMorphismAsMorphismFromDistinguishedObjectToHomomorphismStructureWithGivenObjects( T,
function( T, distinguished_object, morphism, target )

return TerminalCategoryWithSingleObjectUniqueMorphism( RangeCategoryOfHomomorphismStructure( T ) );

end );
end, 2 );

AddInterpretMorphismFromDistinguishedObjectToHomomorphismStructureAsMorphism( T,
function( T, source, target, iota )

return MorphismConstructor( T, source, "InterpretMorphismFromDistinguishedObjectToHomomorphismStructureAsMorphism", target );

end );
end, 1 );

if CAP_NAMED_ARGUMENTS.FinalizeCategory then

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ gap> dummy_range := DummyCategory( rec(
> properties := [
> "IsAdditiveCategory",
> ],
> ) : FinalizeCategory := false );;
gap> AddMorphismBetweenDirectSums( dummy_range, { cat, source_diagram, matrix, target_diagram } -> fail );
gap> Finalize( dummy_range );;
> ) );;

#
gap> dummy := DummyCategory( rec(
Expand Down

0 comments on commit ac4cf7c

Please sign in to comment.