Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# ## ## CAP package ## ## Copyright 2014, Sebastian Gutsche, TU Kaiserslautern ## Sebastian Posur, RWTH Aachen ## ## ############################################################################# InstallGlobalFunction( InstallMethodWithToDoForIsWellDefined, function( arg ) local orig_func, new_func, name, install_func; orig_func := arg[ Length( arg ) ]; name := NameFunction( arg[ 1 ] ); new_func := function( arg ) local val, entry, i, filtered_arg, list_args; ## ToDo: This can be improved filtered_arg := Filtered( arg, IsCapCategoryCell ); list_args := Flat( Filtered( arg, IsList ) ); list_args := Filtered( list_args, IsCapCategoryCell ); filtered_arg := Concatenation( filtered_arg, list_args ); val := CallFuncList( orig_func, arg ); entry := ToDoListEntry( List( filtered_arg, i -> [ i, "IsWellDefined", true ] ), val, "IsWellDefined", true ); SetDescriptionOfImplication( entry, Concatenation( "Well defined propagation from ", name ) ); AddToToDoList( entry ); for i in filtered_arg do entry := ToDoListEntry( [ [ i, "IsWellDefined", false ] ], val, "IsWellDefined", false ); SetDescriptionOfImplication( entry, Concatenation( "Well defined propagation from ", name ) ); AddToToDoList( entry ); od; return val; end; arg[ Length( arg ) ] := new_func; install_func := ValueOption( "InstallMethod" ); if install_func = fail then install_func := InstallMethod; fi; CallFuncList( install_func, arg : InstallMethod := InstallMethod, InstallSet := InstallSetWithToDoForIsWellDefined ); end ); ## InstallGlobalFunction( "ToDoForIsWellDefinedWrapper", function( orig_func ) local new_func; new_func := function( arg ) local val, entry, i, filtered_arg, list_args; ## ToDo: This can be improved filtered_arg := Filtered( arg, IsCapCategoryCell ); list_args := Flat( Filtered( arg, IsList ) ); list_args := Filtered( list_args, IsCapCategoryCell ); filtered_arg := Concatenation( filtered_arg, list_args ); val := CallFuncList( orig_func, arg ); entry := ToDoListEntry( List( filtered_arg, i -> [ i, "IsWellDefined", true ] ), val, "IsWellDefined", true ); SetDescriptionOfImplication( entry, "Well defined propagation" ); AddToToDoList( entry ); for i in filtered_arg do entry := ToDoListEntry( [ [ i, "IsWellDefined", false ] ], val, "IsWellDefined", false ); SetDescriptionOfImplication( entry, "Well defined propagation" ); AddToToDoList( entry ); od; return val; end; return new_func; end ); ## InstallMethod( InstallSetWithToDoForIsWellDefined, [ IsCachingObject, IsString, IsList ], function( cache, name, filter ) local set_name, install_func; set_name := Concatenation( "Set", name ); if not IsBoundGlobal( set_name ) then DeclareOperation( set_name, Concatenation( filter, [ IsObject ] ) ); fi; InstallOtherMethod( ValueGlobal( set_name ), Concatenation( filter, [ IsObject ] ), function( arg ) local cache_return, cache_key, entry, i, filtered_cache_key, list_cache_key; cache_key := arg{[ 1 .. Length( arg ) - 1 ]}; filtered_cache_key := Filtered( cache_key, IsCapCategoryCell ); list_cache_key := Flat( Filtered( cache_key, IsList ) ); list_cache_key := Filtered( list_cache_key, IsCapCategoryCell ); filtered_cache_key := Concatenation( filtered_cache_key, list_cache_key ); cache_return := CacheValue( cache, cache_key ); if cache_return = [ ] then CallFuncList( SetCacheValue, [ cache, cache_key, arg[ Length( arg ) ] ] ); entry := ToDoListEntry( List( filtered_cache_key, i -> [ i, "IsWellDefined", true ] ), arg[ Length( arg ) ], "IsWellDefined", true ); SetDescriptionOfImplication( entry, Concatenation( "Well defined propagation from ", name ) ); AddToToDoList( entry ); for i in filtered_cache_key do entry := ToDoListEntry( [ [ i, "IsWellDefined", false ] ], arg[ Length( arg ) ], "IsWellDefined", false ); SetDescriptionOfImplication( entry, Concatenation( "Well defined propagation from ", name ) ); AddToToDoList( entry ); od; fi; end ); end ); ## InstallMethod( InstallSetWithToDoForIsWellDefined, [ IsInt, IsString, IsList ], function( cache_number, name, filter ) local set_name; set_name := Concatenation( "Set", name ); if not IsBoundGlobal( set_name ) then DeclareOperation( set_name, Concatenation( filter, [ IsObject ] ) ); fi; InstallOtherMethod( ValueGlobal( set_name ), Concatenation( filter, [ IsObject ] ), function( arg ) local cache, cache_key, cache_return, entry, i, filtered_cache_key, list_cache_key; cache := CachingObject( arg[ cache_number ], name, Length( arg ) - 1 ); cache_key := arg{[ 1 .. Length( arg ) - 1 ]}; filtered_cache_key := Filtered( cache_key, IsCapCategoryCell ); list_cache_key := Flat( Filtered( cache_key, IsList ) ); list_cache_key := Filtered( list_cache_key, IsCapCategoryCell ); filtered_cache_key := Concatenation( filtered_cache_key, list_cache_key ); cache_return := CacheValue( cache, cache_key ); if cache_return = [ ] then CallFuncList( SetCacheValue, [ cache, cache_key, arg[ Length( arg ) ] ] ); entry := ToDoListEntry( List( filtered_cache_key, i -> [ i, "IsWellDefined", true ] ), arg[ Length( arg ) ], "IsWellDefined", true ); SetDescriptionOfImplication( entry, Concatenation( "Well defined propagation from ", name ) ); AddToToDoList( entry ); for i in filtered_cache_key do entry := ToDoListEntry( [ [ i, "IsWellDefined", false ] ], arg[ Length( arg ) ], "IsWellDefined", false ); SetDescriptionOfImplication( entry, Concatenation( "Well defined propagation from ", name ) ); AddToToDoList( entry ); od; fi; end ); end ); ## InstallMethod( InstallSetWithToDoForIsWellDefined, [ IsBool, IsString, IsList ], function( cache, name, filter ) local has_name, set_name; set_name := Concatenation( "Set", name ); if not IsBoundGlobal( set_name ) then DeclareOperation( set_name, Concatenation( filter, [ IsObject ] ) ); fi; InstallOtherMethod( ValueGlobal( set_name ), Concatenation( filter, [ IsObject ] ), function( arg ) return; end ); end ); ## InstallGlobalFunction( DeclareAttributeWithToDoForIsWellDefined, function( arg ) local name; name := arg[ 1 ]; CallFuncList( DeclareAttribute, arg ); name := Concatenation( "Set", name ); InstallMethod( ValueGlobal( name ), [ arg[ 2 ], IsObject ], 10000, #FIXME: Method rank function( obj, value ) local entry; # If you set something wrong, it is your fault. # FIXME: Is this a good idea? entry := ToDoListEntryWithContraposition( obj, "IsWellDefined", true, value, "IsWellDefined", true ); SetDescriptionOfImplication( entry, "Propagation of IsWellDefined" ); AddToToDoList( entry ); TryNextMethod(); end ); end ); ########################################## ## ## Family property ## ########################################## InstallGlobalFunction( DeclareFamilyProperty, function( arg ) local name, filter, family, cell_type, reinstall; if Length( arg ) < 2 or Length( arg ) > 4 then Error( "usage DeclareFamilyProperty( name, filter[, family, type of cell ] )" ); fi; name := arg[ 1 ]; filter := arg[ 2 ]; if not IsBound( arg[ 3 ] ) then family := "general"; elif IsBound( arg[ 3 ] ) and LowercaseString( arg[ 3 ] ) in [ "cell", "object", "morphism", "twocell" ] then arg[ 4 ] := arg[ 3 ]; family := "general"; else family := LowercaseString( arg[ 3 ] ); fi; if Length( arg ) > 3 then cell_type := LowercaseString( arg[ 4 ] ); else cell_type := "cell"; fi; if not cell_type in [ "object", "morphism", "twocell", "cell" ] then Error( "cell must be object, morphism, twocell, or cell" ); fi; if not IsBound( CATEGORIES_FAMILY_PROPERTIES.( family ) ) then CATEGORIES_FAMILY_PROPERTIES.( family ) := rec( ); fi; if not IsBound( CATEGORIES_FAMILY_PROPERTIES.( family ).( cell_type ) ) then CATEGORIES_FAMILY_PROPERTIES.( family ).( cell_type ) := [ ]; fi; reinstall := ValueOption( "reinstall" ); if reinstall <> false then reinstall := true; fi; Add( CATEGORIES_FAMILY_PROPERTIES.( family ).( cell_type ), [ name, reinstall ] ); DeclareProperty( name, filter ); end ); ##################################### ## ## Install add ## ##################################### InstallGlobalFunction( CAP_INTERNAL_REPLACE_STRINGS_WITH_FILTERS, function( list, category ) local i, current_entry, current_filter, j; list := ShallowCopy( list ); for i in [ 1 .. Length( list ) ] do current_entry := list[ i ]; if IsFilter( current_entry ) then continue; elif IsString( current_entry ) then current_entry := LowercaseString( current_entry ); if current_entry = "category" then list[ i ] := CategoryFilter( category ) and IsCapCategory; elif current_entry = "cell" then list[ i ] := CellFilter( category ) and IsCapCategoryCell; elif current_entry = "object" then list[ i ] := ObjectFilter( category ) and IsCapCategoryObject; elif current_entry = "morphism" then list[ i ] := MorphismFilter( category ) and IsCapCategoryMorphism; elif current_entry = "twocell" then list[ i ] := TwoCellFilter( category ) and IsCapCategoryTwoCell; else Error( "filter type is not recognized, must be object, morphism, or twocell" ); fi; elif IsList( current_entry ) then current_entry := CAP_INTERNAL_REPLACE_STRINGS_WITH_FILTERS( current_entry, category ); current_filter := current_entry[ 1 ]; for j in current_entry{[ 2 .. Length( current_entry ) ]} do current_filter := current_filter and j; od; list[ i ] := current_filter; fi; od; return list; end ); InstallGlobalFunction( "CAP_INTERNAL_MERGE_FILTER_LISTS", function( filter_list, additional_filters ) local i; filter_list := ShallowCopy( filter_list ); if not Length( filter_list ) >= Length( additional_filters ) then Error( "too many additional filters" ); fi; for i in [ 1 .. Length( filter_list ) ] do if IsBound( additional_filters[ i ] ) then filter_list[ i ] := filter_list[ i ] and additional_filters[ i ]; fi; od; return filter_list; end ); InstallGlobalFunction( CAP_INTERNAL_RETURN_OPTION_OR_DEFAULT, function( option_name, default ) local value; value := ValueOption( option_name ); if value = fail then return default; fi; return value; end ); ## BindGlobal( "CAP_INTERNAL_MAKE_LOOP_SYMBOL_LOOK_LIKE_LOOP", function( function_string, loop_symbol ) local current_position, current_scan_position, bracket_count; current_position := PositionSublist( function_string, loop_symbol ); while current_position <> fail do current_scan_position := current_position + Length( loop_symbol ) + 1; bracket_count := 1; while bracket_count <> 0 do if function_string[ current_scan_position ] = '(' then bracket_count := bracket_count + 1; elif function_string[ current_scan_position ] = ')' then bracket_count := bracket_count - 1; fi; current_scan_position := current_scan_position + 1; od; function_string := Concatenation( function_string{[ 1 .. current_scan_position - 1 ]}, " od ", function_string{[ current_scan_position .. Length( function_string ) ]} ); current_position := PositionSublist( function_string, loop_symbol, current_position + 1 ); od; return function_string; end ); ## InstallGlobalFunction( "CAP_INTERNAL_FIND_APPEARANCE_OF_SYMBOL_IN_FUNCTION", function( func, symbol_list, loop_multiple ) local func_as_string, func_stream, i, func_as_list, loop_power, symbol_appearance_rec, current_symbol; func_as_string := ""; func_stream := OutputTextString( func_as_string, false ); PrintTo( func_stream, func ); CloseStream( func_stream ); ## Make List, Perform, Apply look like loops ## Beginning space is important here, to avoid scanning things like CallFuncList for i in [ " List(", " Perform(", " Apply(" ] do func_as_string := CAP_INTERNAL_MAKE_LOOP_SYMBOL_LOOK_LIKE_LOOP( func_as_string, i ); od; RemoveCharacters( func_as_string, "()[];," ); NormalizeWhitespace( func_as_string ); func_as_list := SplitString( func_as_string, " " ); loop_power := 0; symbol_appearance_rec := rec( ); for current_symbol in func_as_list do if current_symbol in symbol_list then if not IsBound( symbol_appearance_rec.( current_symbol ) ) then symbol_appearance_rec.( current_symbol ) := 0; fi; symbol_appearance_rec.( current_symbol ) := symbol_appearance_rec.( current_symbol ) + loop_multiple^loop_power; elif current_symbol in [ "for", "while", "List", "Perform", "Apply" ] then loop_power := loop_power + 1; elif current_symbol = "od" then loop_power := loop_power - 1; fi; od; return List( RecNames( symbol_appearance_rec ), i -> [ i, symbol_appearance_rec.(i) ] ); end ); ## InstallGlobalFunction( CAP_INTERNAL_MERGE_PRECONDITIONS_LIST, function( list1, list2 ) local i, j, append; for i in list1 do append := true; for j in [ 1 .. Length( list2 ) ] do if list2[ j ][ 1 ] = i[ 1 ] then list2[ j ][ 2 ] := Maximum( list2[ j ][ 2 ], i[ 2 ] ); append := false; break; fi; od; if append then Add( list2, i ); fi; od; return list2; end ); InstallGlobalFunction( CAP_INTERNAL_GET_CORRESPONDING_OUTPUT_OBJECTS, function( translation_list, function_input ) local input_list, output_list, current_output, return_list, input_position, list_position, i; if not Length( translation_list ) = 2 then Error( "invalid translation list" ); fi; output_list := translation_list[ 2 ]; output_list := List( output_list, i -> SplitString( i, "_" ) ); input_list := translation_list[ 1 ]; return_list := [ ]; for i in [ 1 .. Length( output_list ) ] do current_output := output_list[ i ]; input_position := Position( input_list, current_output[ 1 ] ); if input_position = fail then return_list[ i ] := fail; continue; fi; if Length( current_output ) = 1 then return_list[ i ] := function_input[ input_position ]; elif Length( current_output ) = 2 then if LowercaseString( current_output[ 2 ] ) = "source" then return_list[ i ] := Source( function_input[ input_position ] ); elif LowercaseString( current_output[ 2 ] ) = "range" then return_list[ i ] := Range( function_input[ input_position ] ); elif Position( input_list, current_output[ 2 ] ) <> fail then return_list[ i ] := function_input[ input_position ][ function_input[ Position( input_list, current_output[ 2 ] ) ] ]; else Error( "wrong input type" ); fi; elif Length( current_output ) = 3 then if ForAll( current_output[ 2 ], i -> i in "0123456789" ) then list_position := Int( current_output[ 2 ] ); else list_position := Position( input_list, current_output[ 2 ] ); fi; if list_position = fail then Error( "list index variable not found" ); fi; if LowercaseString( current_output[ 3 ] ) = "source" then return_list[ i ] := Source( function_input[ input_position ][ list_position ] ); elif LowercaseString( current_output[ 3 ] ) = "range" then return_list[ i ] := Range( function_input[ input_position ][ list_position ] ); else Error( "wrong output syntax" ); fi; else Error( "wrong entry length" ); fi; od; return return_list; end ); ## InstallGlobalFunction( ListKnownCategoricalProperties, function( category ) local list, name; if not IsCapCategory( category ) then Error( "the input is not a category" ); fi; list := [ ]; for name in CAP_INTERNAL_CAN_COMPUTE_FILTER_LIST!.MathematicalPropertiesOfCategories do if Tester( ValueGlobal( name ) )( category ) and ValueGlobal( name )( category ) then Add( list, name ); fi; od; return list; end ); InstallGlobalFunction( CAP_MergeRecords, function( dst, src ) local key; for key in RecNames( src ) do if not IsBound( dst.( key ) ) then dst.( key ) := src.( key ); fi; od; end ); InstallGlobalFunction( HelpForCAP, function() local filename, stream, string; filename := DirectoriesPackageLibrary( "CAP", "" ); filename := filename[ 1 ]; filename := Filename( filename, "help_for_CAP.md" ); stream := InputTextFile( filename ); string := ReadAll( stream ); CloseStream( stream ); Print( string ); end );