diff --git a/CAP/PackageInfo.g b/CAP/PackageInfo.g index aba72b5bd0..f5926a257c 100644 --- a/CAP/PackageInfo.g +++ b/CAP/PackageInfo.g @@ -10,7 +10,7 @@ SetPackageInfo( rec( PackageName := "CAP", Subtitle := "Categories, Algorithms, Programming", -Version := "2023.11-01", +Version := "2023.11-02", 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/CAP/doc/Doc.autodoc b/CAP/doc/Doc.autodoc index a24d7da0cb..9433864e9f 100644 --- a/CAP/doc/Doc.autodoc +++ b/CAP/doc/Doc.autodoc @@ -24,6 +24,6 @@ @Chapter Create wrapper hulls of a category -@Chapter Dummy categories +@Chapter Dummy implementations @Chapter Examples and Tests diff --git a/CAP/examples/DummyCategory.g b/CAP/examples/DummyCategory.g index 6888e0b097..b9bef43ee6 100644 --- a/CAP/examples/DummyCategory.g +++ b/CAP/examples/DummyCategory.g @@ -1,6 +1,8 @@ #! @Chapter Examples and Tests -#! @Section Dummy category +#! @Section Dummy implementations + +#! @Subsection Dummy categories #! @Example diff --git a/CAP/examples/dummy_rings.g b/CAP/examples/dummy_rings.g new file mode 100644 index 0000000000..57fbdeeb1c --- /dev/null +++ b/CAP/examples/dummy_rings.g @@ -0,0 +1,37 @@ +#! @Chapter Examples and Tests + +#! @Section Dummy implementations + +#! @Subsection Dummy rings + +#! @Example + +LoadPackage( "CAP", false ); +#! true + +DummyRing( ); +#! Dummy ring 1 +DummyRing( ); +#! Dummy ring 2 +IsRing( DummyRing( ) ); +#! true + +DummyCommutativeRing( ); +#! Dummy commutative ring 1 +DummyCommutativeRing( ); +#! Dummy commutative ring 2 +IsRing( DummyCommutativeRing( ) ); +#! true +IsCommutative( DummyCommutativeRing( ) ); +#! true + +DummyField( ); +#! Dummy field 1 +DummyField( ); +#! Dummy field 2 +IsRing( DummyField( ) ); +#! true +IsField( DummyField( ) ); +#! true + +#! @EndExample diff --git a/CAP/gap/DummyCategory.gd b/CAP/gap/DummyCategory.gd deleted file mode 100644 index 45ee1c51ea..0000000000 --- a/CAP/gap/DummyCategory.gd +++ /dev/null @@ -1,47 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# CAP: Categories, Algorithms, Programming -# -# Declarations -# - -#! @Chapter Dummy categories -#! -#! A dummy category pretends to support certain CAP operations but has not actual implementation. -#! This is useful for testing or compiling against a certain set of CAP operations. - -#################################### -# -#! @Section GAP categories -# -#################################### - -#! @Description -#! The ⪆ category of a dummy CAP category. -DeclareCategory( "IsDummyCategory", - IsCapCategory ); - -#! @Description -#! The ⪆ category of objects in a dummy CAP category. -DeclareCategory( "IsDummyCategoryObject", - IsCapCategoryObject ); - -#! @Description -#! The ⪆ category of morphisms in a dummy CAP category. -DeclareCategory( "IsDummyCategoryMorphism", - IsCapCategoryMorphism ); - -#################################### -# -#! @Section Constructors -# -#################################### - -#! @Description -#! Creates a dummy category subject to the options given via options, which is a record passed on to . -#! Note that the options `{category,object,morphism}_filter` will be set to `IsDummyCategory{,Object,Morphism}` and the options `{object,morphism}_{constructor,datum}` and -#! `create_func_*` will be set to dummy implementations (throwing errors when actually called). -#! The dummy category will pretend to support empty limits by default. -#! @Arguments options -#! @Returns a category -DeclareOperation( "DummyCategory", - [ IsRecord ] ); diff --git a/CAP/gap/DummyCategory.gi b/CAP/gap/DummyCategory.gi deleted file mode 100644 index d108f1d1bf..0000000000 --- a/CAP/gap/DummyCategory.gi +++ /dev/null @@ -1,93 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later -# CAP: Categories, Algorithms, Programming -# -# Implementations -# - -## -InstallMethod( DummyCategory, - "for a record of options", - [ IsRecord ], - - function( options ) - local category_constructor_options, dummy_function, C, operation_name; - - category_constructor_options := ShallowCopy( options ); - category_constructor_options.category_filter := IsDummyCategory; - category_constructor_options.category_object_filter := IsDummyCategoryObject; - category_constructor_options.category_morphism_filter := IsDummyCategoryMorphism; - category_constructor_options.is_computable := "IsCongruentForMorphisms" in options.list_of_operations_to_install; - category_constructor_options.supports_empty_limits := true; - - if "ObjectConstructor" in options.list_of_operations_to_install then - - category_constructor_options.object_constructor := function ( cat, object_datum ) - - Error( "this is a dummy category without actual implementation" ); - - end; - - fi; - - if "MorphismConstructor" in options.list_of_operations_to_install then - - category_constructor_options.morphism_constructor := function ( cat, source, morphism_datum, range ) - - Error( "this is a dummy category without actual implementation" ); - - end; - - fi; - - if "ObjectDatum" in options.list_of_operations_to_install then - - category_constructor_options.object_datum := function ( cat, object ) - - Error( "this is a dummy category without actual implementation" ); - - end; - - fi; - - if "MorphismDatum" in options.list_of_operations_to_install then - - category_constructor_options.morphism_datum := function ( cat, morphism ) - - Error( "this is a dummy category without actual implementation" ); - - end; - - fi; - - dummy_function := { operation_name, dummy } -> """ - function ( input_arguments... ) - - Error( "this is a dummy category without actual implementation" ); - - end - """; - - category_constructor_options.create_func_bool := dummy_function; - category_constructor_options.create_func_object := dummy_function; - category_constructor_options.create_func_object_or_fail := dummy_function; - category_constructor_options.create_func_morphism := dummy_function; - category_constructor_options.create_func_morphism_or_fail := dummy_function; - category_constructor_options.create_func_list_of_objects := dummy_function; - - C := CategoryConstructor( category_constructor_options ); - - Finalize( C ); - - for operation_name in options.list_of_operations_to_install do - - if not CanCompute( C, operation_name ) then - - Print( "WARNING: The dummy category cannot compute ", operation_name, ", probably because the operation is not supported by CategoryConstructor yet.\n" ); - - fi; - - od; - - return C; - -end ); diff --git a/CAP/gap/DummyImplementations.gd b/CAP/gap/DummyImplementations.gd new file mode 100644 index 0000000000..1d1ea02d51 --- /dev/null +++ b/CAP/gap/DummyImplementations.gd @@ -0,0 +1,115 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# CAP: Categories, Algorithms, Programming +# +# Declarations +# + +#! @Chapter Dummy implementations +#! +#! A dummy implementation of a concept seems to provide an interface for the concept, but calling any operation in this interface will simply signal an error. +#! Hence, when using a dummy implementation, we can be sure that we only rely on the abstract interface but not on any implementation details, +#! for the simple reason that there is no actual implementation. +#! This is useful for testing or compilation against a generic implementation of a concept. + +#################################### +# +#! @Section Dummy rings +# +#################################### + +#################################### +# +# GAP filters +# +#################################### + +#! @Description +#! The ⪆ filter of dummy rings. +DeclareFilter( "IsDummyRing", + IsRingWithOne ); + +#! @Description +#! The ⪆ filter of elements of a dummy ring. +DeclareFilter( "IsDummyRingElement", + IsRingElementWithOne ); + +#! @Description +#! The ⪆ filter of dummy commutative rings. +DeclareFilter( "IsDummyCommutativeRing", + IsDummyRing ); + +#! @Description +#! The ⪆ filter of elements of a dummy commutative ring. +DeclareFilter( "IsDummyCommutativeRingElement", + IsDummyRingElement ); + +#! @Description +#! The ⪆ filter of dummy fields. +DeclareFilter( "IsDummyField", + IsDummyCommutativeRing ); + +#! @Description +#! The ⪆ filter of elements of a dummy commutative ring. +DeclareFilter( "IsDummyFieldElement", + IsDummyCommutativeRingElement ); + +#################################### +# +# Constructors +# +#################################### + +#! @Description +#! @Returns a dummy ring +DeclareGlobalFunction( "DummyRing" ); + +#! @Description +#! @Returns a dummy commutative ring +DeclareGlobalFunction( "DummyCommutativeRing" ); + +#! @Description +#! @Returns a dummy field +DeclareGlobalFunction( "DummyField" ); + +#################################### +# +#! @Section Dummy categories +# +#################################### + +#################################### +# +# GAP categories +# +#################################### + +#! @Description +#! The ⪆ category of a dummy CAP category. +DeclareCategory( "IsDummyCategory", + IsCapCategory ); + +#! @Description +#! The ⪆ category of objects in a dummy CAP category. +DeclareCategory( "IsDummyCategoryObject", + IsCapCategoryObject ); + +#! @Description +#! The ⪆ category of morphisms in a dummy CAP category. +DeclareCategory( "IsDummyCategoryMorphism", + IsCapCategoryMorphism ); + +#################################### +# +# Constructors +# +#################################### + +#! @Description +#! Creates a dummy category subject to the options given via options, which is a record passed on to . +#! Note that the options `{category,object,morphism}_filter` will be set to `IsDummyCategory{,Object,Morphism}` and the options `{object,morphism}_{constructor,datum}` and +#! `create_func_*` will be set to dummy implementations (throwing errors when actually called). +#! The dummy category will pretend to support empty limits by default. +#! @Arguments options +#! @Returns a category +DeclareOperation( "DummyCategory", + [ IsRecord ] ); diff --git a/CAP/gap/DummyImplementations.gi b/CAP/gap/DummyImplementations.gi new file mode 100644 index 0000000000..1528859728 --- /dev/null +++ b/CAP/gap/DummyImplementations.gi @@ -0,0 +1,196 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# CAP: Categories, Algorithms, Programming +# +# Implementations +# + +## dummy rings + +BindGlobal( "TheFamilyOfDummyRings", + NewFamily( "TheFamilyOfDummyRings" ) ); + +CAP_INTERNAL_DUMMY_RING_COUNTER := 1; + +InstallGlobalFunction( DummyRing, function( ) + local ring_filter, ring_element_filter, name, ring; + + ring_filter := NewFilter( "DummyRingFilter", IsDummyRing ); + ring_element_filter := NewFilter( "DummyRingElementFilter", IsDummyRingElement ); + + name := Concatenation( "Dummy ring ", String( CAP_INTERNAL_DUMMY_RING_COUNTER ) ); + CAP_INTERNAL_DUMMY_RING_COUNTER := CAP_INTERNAL_DUMMY_RING_COUNTER + 1; + + ring := ObjectifyWithAttributes( rec( ), + NewType( TheFamilyOfDummyRings, IsAttributeStoringRep and ring_filter ), + Name, name, + String, name, + RingFilter, ring_filter, + RingElementFilter, ring_element_filter + ); + + CapJitAddTypeSignature( "+", [ ring_element_filter, ring_element_filter ], ring_element_filter ); + CapJitAddTypeSignature( "ZeroImmutable", [ ring_filter ], ring_element_filter ); + CapJitAddTypeSignature( "AdditiveInverseSameMutability", [ ring_element_filter ], ring_element_filter ); + CapJitAddTypeSignature( "*", [ ring_element_filter, ring_element_filter ], ring_element_filter ); + + return ring; + +end ); + +## dummy commutative rings + +BindGlobal( "TheFamilyOfDummyCommutativeRings", + NewFamily( "TheFamilyOfDummyCommutativeRings" ) ); + +CAP_INTERNAL_DUMMY_COMMUTATIVE_RING_COUNTER := 1; + +InstallGlobalFunction( DummyCommutativeRing, function( ) + local ring_filter, ring_element_filter, name, ring; + + ring_filter := NewFilter( "DummyCommutativeRingFilter", IsDummyCommutativeRing ); + ring_element_filter := NewFilter( "DummyCommutativeRingElementFilter", IsDummyCommutativeRingElement ); + + name := Concatenation( "Dummy commutative ring ", String( CAP_INTERNAL_DUMMY_COMMUTATIVE_RING_COUNTER ) ); + CAP_INTERNAL_DUMMY_COMMUTATIVE_RING_COUNTER := CAP_INTERNAL_DUMMY_COMMUTATIVE_RING_COUNTER + 1; + + ring := ObjectifyWithAttributes( rec( ), + NewType( TheFamilyOfDummyCommutativeRings, IsAttributeStoringRep and ring_filter ), + Name, name, + String, name, + RingFilter, ring_filter, + RingElementFilter, ring_element_filter, + IsCommutative, true + ); + + CapJitAddTypeSignature( "+", [ ring_element_filter, ring_element_filter ], ring_element_filter ); + CapJitAddTypeSignature( "ZeroImmutable", [ ring_filter ], ring_element_filter ); + CapJitAddTypeSignature( "AdditiveInverseSameMutability", [ ring_element_filter ], ring_element_filter ); + CapJitAddTypeSignature( "*", [ ring_element_filter, ring_element_filter ], ring_element_filter ); + + return ring; + +end ); + +## dummy fields + +BindGlobal( "TheFamilyOfDummyFields", + NewFamily( "TheFamilyOfDummyFields" ) ); + +CAP_INTERNAL_DUMMY_FIELD_COUNTER := 1; + +InstallGlobalFunction( DummyField, function( ) + local ring_filter, ring_element_filter, name, ring; + + ring_filter := NewFilter( "DummyFieldFilter", IsDummyField ); + ring_element_filter := NewFilter( "DummyFieldElementFilter", IsDummyFieldElement ); + + name := Concatenation( "Dummy field ", String( CAP_INTERNAL_DUMMY_FIELD_COUNTER ) ); + CAP_INTERNAL_DUMMY_FIELD_COUNTER := CAP_INTERNAL_DUMMY_FIELD_COUNTER + 1; + + ring := ObjectifyWithAttributes( rec( ), + NewType( TheFamilyOfDummyFields, IsAttributeStoringRep and ring_filter ), + Name, name, + String, name, + RingFilter, ring_filter, + RingElementFilter, ring_element_filter, + IsField, true + ); + + CapJitAddTypeSignature( "+", [ ring_element_filter, ring_element_filter ], ring_element_filter ); + CapJitAddTypeSignature( "ZeroImmutable", [ ring_filter ], ring_element_filter ); + CapJitAddTypeSignature( "AdditiveInverseSameMutability", [ ring_element_filter ], ring_element_filter ); + CapJitAddTypeSignature( "*", [ ring_element_filter, ring_element_filter ], ring_element_filter ); + + return ring; + +end ); + +## dummy categories + +## +InstallMethod( DummyCategory, + "for a record of options", + [ IsRecord ], + + function( options ) + local category_constructor_options, dummy_function, C, operation_name; + + category_constructor_options := ShallowCopy( options ); + category_constructor_options.category_filter := IsDummyCategory; + category_constructor_options.category_object_filter := IsDummyCategoryObject; + category_constructor_options.category_morphism_filter := IsDummyCategoryMorphism; + category_constructor_options.is_computable := "IsCongruentForMorphisms" in options.list_of_operations_to_install; + category_constructor_options.supports_empty_limits := true; + + if "ObjectConstructor" in options.list_of_operations_to_install then + + category_constructor_options.object_constructor := function ( cat, object_datum ) + + Error( "this is a dummy category without actual implementation" ); + + end; + + fi; + + if "MorphismConstructor" in options.list_of_operations_to_install then + + category_constructor_options.morphism_constructor := function ( cat, source, morphism_datum, range ) + + Error( "this is a dummy category without actual implementation" ); + + end; + + fi; + + if "ObjectDatum" in options.list_of_operations_to_install then + + category_constructor_options.object_datum := function ( cat, object ) + + Error( "this is a dummy category without actual implementation" ); + + end; + + fi; + + if "MorphismDatum" in options.list_of_operations_to_install then + + category_constructor_options.morphism_datum := function ( cat, morphism ) + + Error( "this is a dummy category without actual implementation" ); + + end; + + fi; + + dummy_function := { operation_name, dummy } -> """ + function ( input_arguments... ) + + Error( "this is a dummy category without actual implementation" ); + + end + """; + + category_constructor_options.create_func_bool := dummy_function; + category_constructor_options.create_func_object := dummy_function; + category_constructor_options.create_func_object_or_fail := dummy_function; + category_constructor_options.create_func_morphism := dummy_function; + category_constructor_options.create_func_morphism_or_fail := dummy_function; + category_constructor_options.create_func_list_of_objects := dummy_function; + + C := CategoryConstructor( category_constructor_options ); + + Finalize( C ); + + for operation_name in options.list_of_operations_to_install do + + if not CanCompute( C, operation_name ) then + + Print( "WARNING: The dummy category cannot compute ", operation_name, ", probably because the operation is not supported by CategoryConstructor yet.\n" ); + + fi; + + od; + + return C; + +end ); diff --git a/CAP/init.g b/CAP/init.g index 9ebfb6a1ea..f708642b9b 100644 --- a/CAP/init.g +++ b/CAP/init.g @@ -56,4 +56,4 @@ ReadPackage( "CAP", "gap/ReinterpretationOfCategory.gd" ); ReadPackage( "CAP", "gap/WrapperCategory.gd" ); -ReadPackage( "CAP", "gap/DummyCategory.gd" ); +ReadPackage( "CAP", "gap/DummyImplementations.gd" ); diff --git a/CAP/read.g b/CAP/read.g index 20133b0dfa..c097c68b4d 100644 --- a/CAP/read.g +++ b/CAP/read.g @@ -56,7 +56,7 @@ ReadPackage( "CAP", "gap/ReinterpretationOfCategory.gi" ); ReadPackage( "CAP", "gap/WrapperCategory.gi" ); -ReadPackage( "CAP", "gap/DummyCategory.gi" ); +ReadPackage( "CAP", "gap/DummyImplementations.gi" ); ReadPackage( "CAP", "gap/ToolsForCategories_AfterLoading.gi" );