GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#############################################################################
##
## CAP package
##
## Copyright 2015, Sebastian Gutsche, TU Kaiserslautern
## Sebastian Posur, RWTH Aachen
##
#############################################################################
InstallValue( CAP_INTERNAL_FINAL_DERIVATION_LIST,
rec( final_derivation_list := [ ] ) );
InstallMethod( AddFinalDerivation,
[ IsFunction, IsDenseList, IsDenseList, IsFunction ],
function( name, can, cannot, func )
AddFinalDerivation( name, can, cannot, [ [ func, [ ] ] ] );
end );
InstallMethod( AddFinalDerivation,
[ IsFunction, IsDenseList, IsFunction ],
function( name, cannot, func )
AddFinalDerivation( name, [ ], cannot, [ [ func, [ ] ] ] );
end );
BindGlobal( "CAP_INTERNAL_FINAL_DERIVATION_SANITY_CHECK",
function( derivation )
local possible_names, all_operations_names, function_object, function_string,
string_stream, i, all_operations;
possible_names := derivation!.can_compute;
possible_names := List( possible_names, i -> NameFunction( i[ 1 ] ) );
all_operations := Operations( CAP_INTERNAL_DERIVATION_GRAPH );
for function_object in derivation!.function_list do
function_object := function_object[ 1 ];
function_string := "";
string_stream := OutputTextString( function_string, false );
PrintTo( string_stream, function_object );
CloseStream( string_stream );
RemoveCharacters( function_string, "()[];," );
NormalizeWhitespace( function_string );
function_string := SplitString( function_string, " " );
for i in function_string do
if i in all_operations and not i in possible_names then
Error( Concatenation( "final derivation with description\n", derivation.description, "\n uses ", i, ",\n which is not part of its condition" ) );
fi;
od;
od;
end );
InstallMethod( AddFinalDerivation,
[ IsFunction, IsDenseList, IsDenseList ],
function( name, cannot, func_list )
AddFinalDerivation( name, [ ], cannot, func_list );
end );
InstallMethod( AddFinalDerivation,
[ IsFunction, IsDenseList, IsDenseList, IsDenseList ],
function( name, can, cannot, func_list )
local final_derivation, loop_multiplier, collected_list, current_implementation, current_list,
operations_in_graph, used_ops_with_multiples;
final_derivation := rec( );
final_derivation.weight := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "Weight", 1 );
final_derivation.description := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "Description", "" );
final_derivation.category_filter := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "CategoryFilter", IsCapCategory );
final_derivation.option_function := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "CategoryOptionFunction", ReturnTrue );
loop_multiplier := CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT( "WeightLoopMultiple", 2 );
## get used ops
operations_in_graph := Operations( CAP_INTERNAL_DERIVATION_GRAPH );
collected_list := [ ];
for current_implementation in func_list do
current_list := CAP_INTERNAL_FIND_APPEARANCE_OF_SYMBOL_IN_FUNCTION( current_implementation[ 1 ], operations_in_graph, loop_multiplier );
current_list := List( current_list, i -> [ ValueGlobal( i[ 1 ] ), i[ 2 ] ] );
current_list := Concatenation( current_list, CAP_INTERNAL_FIND_APPEARANCE_OF_SYMBOL_IN_FUNCTION_FOR_MONOIDAL_CATEGORIES( current_implementation[ 1 ], loop_multiplier ) );
collected_list := CAP_INTERNAL_MERGE_PRECONDITIONS_LIST( collected_list, current_list );
od;
used_ops_with_multiples := CAP_INTERNAL_MERGE_PRECONDITIONS_LIST( collected_list, can );
final_derivation.name := name;
final_derivation.can_compute := used_ops_with_multiples;
final_derivation.cannot_compute := cannot;
final_derivation.function_list := func_list;
CAP_INTERNAL_FINAL_DERIVATION_SANITY_CHECK( final_derivation );
Add( CAP_INTERNAL_FINAL_DERIVATION_LIST.final_derivation_list, final_derivation );
end );
InstallMethod( Finalize,
[ IsCapCategory ],
IsFinalized );
InstallMethod( IsFinalized,
[ IsCapCategory ],
function( category )
local current_final_derivation, derivation_list, i, n, weight_list, weight, add_name, current_installs;
## Set filters for AbCategory etc to false if not true.
# for i in CAP_INTERNAL_CAN_COMPUTE_FILTER_LIST.MathematicalPropertiesOfCategories do
#
# i := ValueGlobal( i );
#
# if not Tester( i )( category ) then
#
# Setter( i )( category, false );
#
# fi;
#
# od;
derivation_list := ShallowCopy( CAP_INTERNAL_FINAL_DERIVATION_LIST.final_derivation_list );
weight_list := category!.derivations_weight_list;
while true do
current_installs := [ ];
for i in [ 1 .. Length( derivation_list ) ] do
current_final_derivation := derivation_list[ i ];
if ForAll( current_final_derivation.can_compute, j -> CurrentOperationWeight( weight_list, NameFunction( j[ 1 ] ) ) < infinity ) and
ForAll( current_final_derivation.cannot_compute, j -> CurrentOperationWeight( weight_list, NameFunction( j ) ) = infinity ) then
Add( current_installs, i );
fi;
od;
if current_installs = [ ] then
break;
fi;
for i in current_installs do
current_final_derivation := derivation_list[ i ];
## calculate weight
weight := current_final_derivation.weight + Sum( List( current_final_derivation.can_compute, j -> CurrentOperationWeight( weight_list, NameFunction( j[ 1 ] ) ) * j[ 2 ] ) );
Info( DerivationInfo, 1, Concatenation( "install(",
String( weight ),
") ",
NameFunction( current_final_derivation.name ),
": ",
current_final_derivation.description, "\n" ) );
## Add method
add_name := ValueGlobal( Concatenation( [ "Add", NameFunction( current_final_derivation.name ) ] ) );
add_name( category, current_final_derivation.function_list, weight : IsFinalDerivation := true );
current_final_derivation.option_function( category );
od;
## Remove all already installed entries
derivation_list := derivation_list{ Difference( [ 1 .. Length( derivation_list ) ], current_installs ) };
od;
return true;
end );