Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/cap/gap/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 22.8.2025 mit Größe 148 kB image not shown  

SSL MethodRecord.gi   Interaktion und
Portierbarkeitunbekannt

 
Spracherkennung für: .gi vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

# SPDX-License-Identifier: GPL-2.0-or-later
# CAP: Categories, Algorithms, Programming
#
# Implementations
#
BindGlobal( "CAP_INTERNAL_CORE_METHOD_NAME_RECORD", rec(
ObjectConstructor := rec(
  filter_list := [ "category", "object_datum" ],
  return_type := "object",
  compatible_with_congruence_of_morphisms := false,
),

ObjectDatum := rec(
  filter_list := [ "category", "object" ],
  return_type := "object_datum",
),

MorphismConstructor := rec(
  filter_list := [ "category", "object", "morphism_datum", "object" ],
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

MorphismDatum := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "morphism_datum",
  compatible_with_congruence_of_morphisms := false,
),

SetOfObjectsOfCategory := rec(
  filter_list := [ "category" ],
  return_type := "list_of_objects",
  dual_operation := "SetOfObjectsOfCategory",
),

SetOfMorphismsOfFiniteCategory := rec(
  filter_list := [ "category" ],
  return_type := "list_of_morphisms",
  dual_operation := "SetOfMorphismsOfFiniteCategory",
),

LiftAlongMonomorphism := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "iota", "tau" ],
  output_source_getter_string := "Source( tau )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Source( iota )",
  output_range_getter_preconditions := [ ],
  pre_function := function( cat, iota, tau )
    
    if not IsEqualForObjects( cat, Range( iota ), Range( tau ) ) then
        
        return [ false, "the two morphisms must have equal ranges" ];
        
    fi;
    
    return [ true ];
  end,
  return_type := "morphism",
  dual_operation := "ColiftAlongEpimorphism",
  compatible_with_congruence_of_morphisms := true,
),

IsLiftableAlongMonomorphism := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  pre_function := function( cat, iota, tau )
    
    if not IsEqualForObjects( cat, Range( iota ), Range( tau ) ) then
        
        return [ false, "the two morphisms must have equal ranges" ];
        
    fi;
    
    return [ true ];
  end,
  return_type := "bool",
  dual_operation := "IsColiftableAlongEpimorphism",
  compatible_with_congruence_of_morphisms := true,
),

ColiftAlongEpimorphism := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "epsilon", "tau" ],
  output_source_getter_string := "Range( epsilon )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( tau )",
  output_range_getter_preconditions := [ ],
  pre_function := function( cat, epsilon, tau )
    
    if not IsEqualForObjects( cat, Source( epsilon ), Source( tau ) ) then
        
        return [ false, "the two morphisms must have equal sources" ];
        
    fi;
    
    return [ true ];
  end,
  return_type := "morphism",
  dual_operation := "LiftAlongMonomorphism",
  compatible_with_congruence_of_morphisms := true,
),

IsColiftableAlongEpimorphism := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  pre_function := function( cat, epsilon, tau )
    
    if not IsEqualForObjects( cat, Source( epsilon ), Source( tau ) ) then
        
        return [ false, "the two morphisms must have equal sources" ];
        
    fi;
    
    return [ true ];
  end,
  return_type := "bool",
  dual_operation := "IsLiftableAlongMonomorphism",
  compatible_with_congruence_of_morphisms := true,
),

Lift := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "beta" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Source( beta )",
  output_range_getter_preconditions := [ ],
  pre_function := function( cat, iota, tau )
    
    if not IsEqualForObjects( cat, Range( iota ), Range( tau ) ) then
        
        return [ false, "the two morphisms must have equal ranges" ];
        
    fi;
    
    return [ true ];
  end,
  return_type := "morphism",
  dual_operation := "Colift",
  dual_arguments_reversed := true,
  is_merely_set_theoretic := true,
  compatible_with_congruence_of_morphisms := false,
),

IsLiftable := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  pre_function := "Lift",
  return_type := "bool",
  dual_operation := "IsColiftable",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

Colift := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "beta" ],
  output_source_getter_string := "Range( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( beta )",
  output_range_getter_preconditions := [ ],
  pre_function := function( cat, epsilon, tau )
    
    if not IsEqualForObjects( cat, Source( epsilon ), Source( tau ) ) then
        
        return [ false, "the two morphisms must have equal sources" ];
        
    fi;
    
    return [ true ];
  end,
  return_type := "morphism",
  dual_operation := "Lift",
  dual_arguments_reversed := true,
  is_merely_set_theoretic := true,
  compatible_with_congruence_of_morphisms := false,
),

IsColiftable := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  pre_function := "Colift",
  return_type := "bool",
  dual_operation := "IsLiftable",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

ProjectiveLift := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "beta" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Source( beta )",
  output_range_getter_preconditions := [ ],
  pre_function := function( cat, iota, tau )
    
    if not IsEqualForObjects( cat, Range( iota ), Range( tau ) ) then
        
        return [ false, "the two morphisms must have equal ranges" ];
        
    fi;
    
    return [ true ];
  end,
  return_type := "morphism",
  dual_arguments_reversed := true,
  dual_operation := "InjectiveColift",
  compatible_with_congruence_of_morphisms := false,
),

InjectiveColift := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "beta" ],
  output_source_getter_string := "Range( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( beta )",
  output_range_getter_preconditions := [ ],
  pre_function := function( cat, epsilon, tau )
    
    if not IsEqualForObjects( cat, Source( epsilon ), Source( tau ) ) then
        
        return [ false, "the two morphisms must have equal sources" ];
        
    fi;
    
    return [ true ];
  end,
  return_type := "morphism",
  dual_arguments_reversed := true,
  dual_operation := "ProjectiveLift",
  compatible_with_congruence_of_morphisms := false,
),

IdentityMorphism := rec(
  filter_list := [ "category", "object" ],
  input_arguments_names := [ "cat", "a" ],
  output_source_getter_string := "a",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "a",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "IdentityMorphism" ),

InverseForMorphisms := rec(
# Type check for IsIsomorphism
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_source_getter_string := "Range( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Source( alpha )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "InverseForMorphisms",
  compatible_with_congruence_of_morphisms := true,
),

PreInverseForMorphisms := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_source_getter_string := "Range( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Source( alpha )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "PostInverseForMorphisms",
  is_merely_set_theoretic := true
),

PostInverseForMorphisms := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_source_getter_string := "Range( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Source( alpha )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "PreInverseForMorphisms",
  is_merely_set_theoretic := true
),

KernelObject := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  return_type := "object",
  dual_operation := "CokernelObject",
  compatible_with_congruence_of_morphisms := false,
  functorial := "KernelObjectFunctorial",
),

KernelEmbedding := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_range_getter_string := "Source( alpha )",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  return_type := "morphism",
  dual_operation := "CokernelProjection",
  compatible_with_congruence_of_morphisms := false,
),

KernelEmbeddingWithGivenKernelObject := rec(
  filter_list := [ "category", "morphism", "object" ],
  input_arguments_names := [ "cat", "alpha", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Source( alpha )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "CokernelProjectionWithGivenCokernelObject",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromKernelObjectToSink := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  dual_operation := "MorphismFromSourceToCokernelObject",
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromKernelObjectToSinkWithGivenKernelObject := rec(
  filter_list := [ "category", "morphism", "object" ],
  input_arguments_names := [ "cat", "alpha", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  dual_operation := "MorphismFromSourceToCokernelObjectWithGivenCokernelObject",
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

KernelLift := rec(
  filter_list := [ "category", "morphism", "object", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "T", "tau" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  return_type := "morphism",
  dual_operation := "CokernelColift",
  compatible_with_congruence_of_morphisms := false,
),

KernelLiftWithGivenKernelObject := rec(
  filter_list := [ "category", "morphism", "object", "morphism", "object" ],
  input_arguments_names := [ "cat", "alpha", "T", "tau", "P" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "CokernelColiftWithGivenCokernelObject",
  compatible_with_congruence_of_morphisms := false,
),

CokernelObject := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  return_type := "object",
  dual_operation := "KernelObject",
  compatible_with_congruence_of_morphisms := false,
  functorial := "CokernelObjectFunctorial",
),

CokernelProjection := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_source_getter_string := "Range( alpha )",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  return_type := "morphism",
  dual_operation := "KernelEmbedding",
  compatible_with_congruence_of_morphisms := false,
),

CokernelProjectionWithGivenCokernelObject := rec(
  filter_list := [ "category", "morphism", "object" ],
  input_arguments_names := [ "cat", "alpha", "P" ],
  output_source_getter_string := "Range( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "KernelEmbeddingWithGivenKernelObject",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromSourceToCokernelObject := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  dual_operation := "MorphismFromKernelObjectToSink",
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromSourceToCokernelObjectWithGivenCokernelObject := rec(
  filter_list := [ "category", "morphism", "object" ],
  input_arguments_names := [ "cat", "alpha", "P" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  dual_operation := "MorphismFromKernelObjectToSinkWithGivenKernelObject",
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

CokernelColift := rec(
  filter_list := [ "category", "morphism", "object", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "T", "tau" ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  return_type := "morphism",
  dual_operation := "KernelLift",
  compatible_with_congruence_of_morphisms := false,
),

CokernelColiftWithGivenCokernelObject := rec(
  filter_list := [ "category", "morphism", "object", "morphism", "object" ],
  input_arguments_names := [ "cat", "alpha", "T", "tau", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "KernelLiftWithGivenKernelObject",
  compatible_with_congruence_of_morphisms := false,
),

PreCompose := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "beta" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( beta )",
  output_range_getter_preconditions := [ ],
  
  pre_function := function( cat, mor_left, mor_right )
    
    if not IsEqualForObjects( cat, Range( mor_left ), Source( mor_right ) ) then
        
        return [ false, "morphisms not composable" ];
        
    fi;
    
    return [ true ];
  end,
  return_type := "morphism",
  dual_operation := "PostCompose",
  compatible_with_congruence_of_morphisms := true,
),

SumOfMorphisms := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "source", "list_of_morphisms", "range" ],
  pre_function := function( cat, source, list_of_morphisms, range )
    local m;
    
    for m in list_of_morphisms do
        
        if not IsEqualForObjects( cat, source, Source( m ) ) or not IsEqualForObjects( cat, range, Range( m ) ) then
            
            return [ false, "some of the morphisms are not compatible with the provided source and range objects" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  output_source_getter_string := "source",
  output_range_getter_string := "range",
  dual_operation := "SumOfMorphisms",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := true,
),

LinearCombinationOfMorphisms := rec(
  filter_list := [ "category", "object", "list_of_elements_of_commutative_ring_of_linear_structure", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "source", "list_of_ring_elements", "list_of_morphisms", "range" ],
  pre_function := function( cat, source, list_of_ring_elements, list_of_morphisms, range )
    local m;
    
    if not Length( list_of_ring_elements ) = Length( list_of_morphisms ) then
        
        return [ false, "the length of the lists of coefficients and morphisms must be the same" ];
        
    fi;
    
    for m in list_of_morphisms do
        
        if not IsEqualForObjects( cat, source, Source( m ) ) or not IsEqualForObjects( cat, range, Range( m ) ) then
            
            return [ false, "some of the morphisms are not compatible with the provided source and range objects" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  output_source_getter_string := "source",
  output_range_getter_string := "range",
  dual_operation := "LinearCombinationOfMorphisms",
  dual_preprocessor_func := function( arg )
      local list;
      list := CAP_INTERNAL_OPPOSITE_RECURSIVE( arg );
      return NTuple( 5, list[1], list[5], list[3], list[4], list[2] );
  end,
  compatible_with_congruence_of_morphisms := true,
),

PreComposeList := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "source", "list_of_morphisms", "range" ],
  pre_function := function( cat, source, list_of_morphisms, range )
    local i;
    
    if IsEmpty( list_of_morphisms ) then
        
        if not IsEqualForObjects( cat, source, range ) then
            
            return [ false, "the given source and range are not equal while the given list of morphisms to compose is empty" ];
            
        fi;
        
    else
        
        if not IsEqualForObjects( cat, source, Source( First( list_of_morphisms ) ) ) then
            
            return [ false, "the given source is not equal to the source of the first morphism" ];
            
        elif not IsEqualForObjects( cat, range, Range( Last( list_of_morphisms ) ) ) then
            
            return [ false, "the given range is not equal to the range of the last morphism" ];
            
        fi;
        
    fi;
    
    for i in [ 1 .. Length( list_of_morphisms ) - 1 ] do
        
        if not IsEqualForObjects( cat, Range( list_of_morphisms[i] ), Source( list_of_morphisms[i + 1] ) ) then
            
            return [ false, "morphisms not composable" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  output_source_getter_string := "source",
  output_range_getter_string := "range",
  dual_operation := "PostComposeList",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := true,
),

PostCompose := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "beta", "alpha" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( beta )",
  output_range_getter_preconditions := [ ],
  
  pre_function := function( cat, mor_right, mor_left )
    
    if not IsEqualForObjects( cat, Range( mor_left ), Source( mor_right ) ) then
        
        return [ false, "morphisms not composable" ];
        
    fi;
    
    return [ true ];
  end,
  
  return_type := "morphism",
  dual_operation := "PreCompose",
  compatible_with_congruence_of_morphisms := true,
),

PostComposeList := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "source", "list_of_morphisms", "range" ],
  pre_function := function( cat, source, list_of_morphisms, range )
    local i;
    
    if IsEmpty( list_of_morphisms ) then
        
        if not IsEqualForObjects( cat, source, range ) then
            
            return [ false, "the given source and range are not equal while the given list of morphisms to compose is empty" ];
            
        fi;
        
    else
        
        if not IsEqualForObjects( cat, source, Source( Last( list_of_morphisms ) ) ) then
            
            return [ false, "the given source is not equal to the source of the last morphism" ];
            
        elif not IsEqualForObjects( cat, range, Range( First( list_of_morphisms ) ) ) then
            
            return [ false, "the given range is not equal to the range of the first morphism" ];
            
        fi;
        
    fi;
    
    for i in [ 1 .. Length( list_of_morphisms ) - 1 ] do
        
        if not IsEqualForObjects( cat, Range( list_of_morphisms[i + 1] ), Source( list_of_morphisms[i] ) ) then
            
            return [ false, "morphisms not composable" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  output_source_getter_string := "source",
  output_range_getter_string := "range",
  dual_operation := "PreComposeList",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := true,
),

ZeroObject := rec(
  filter_list := [ "category" ],
  input_arguments_names := [ "cat" ],
  return_type := "object",
  dual_operation := "ZeroObject",
  functorial := "ZeroObjectFunctorial",
),

ZeroObjectFunctorial := rec(
  filter_list := [ "category" ],
  input_arguments_names := [ "cat" ],
  return_type := "morphism",
  output_source_getter_string := "ZeroObject( cat )",
  output_source_getter_preconditions := [ [ "ZeroObject", 1 ] ],
  output_range_getter_string := "ZeroObject( cat )",
  output_range_getter_preconditions := [ [ "ZeroObject", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "ZeroObjectFunctorial",
  dual_arguments_reversed := true
),

ZeroObjectFunctorialWithGivenZeroObjects := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "P", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "ZeroObjectFunctorialWithGivenZeroObjects",
  dual_arguments_reversed := true
),

UniversalMorphismFromZeroObject := rec(
  filter_list := [ "category", "object" ],
  input_arguments_names := [ "cat", "T" ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  return_type := "morphism",
  dual_operation := "UniversalMorphismIntoZeroObject" ),
  
UniversalMorphismFromZeroObjectWithGivenZeroObject := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "T", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "UniversalMorphismIntoZeroObjectWithGivenZeroObject" ),

UniversalMorphismIntoZeroObject := rec(
  filter_list := [ "category", "object" ],
  input_arguments_names := [ "cat", "T" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  return_type := "morphism",
  dual_operation := "UniversalMorphismFromZeroObject" ),

UniversalMorphismIntoZeroObjectWithGivenZeroObject := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "T", "P" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "UniversalMorphismFromZeroObjectWithGivenZeroObject" ),

IsomorphismFromZeroObjectToInitialObject := rec(
  filter_list := [ "category" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromTerminalObjectToZeroObject",
),

IsomorphismFromInitialObjectToZeroObject := rec(
  filter_list := [ "category" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromZeroObjectToTerminalObject",
),

IsomorphismFromZeroObjectToTerminalObject := rec(
  filter_list := [ "category" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromInitialObjectToZeroObject",
),

IsomorphismFromTerminalObjectToZeroObject := rec(
  filter_list := [ "category" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromZeroObjectToInitialObject",
),

ZeroMorphism := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "a", "b" ],
  output_source_getter_string := "a",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "b",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_arguments_reversed := true,
  dual_operation := "ZeroMorphism" ),

DirectSum := rec(
  filter_list := [ "category", "list_of_objects" ],
  input_arguments_names := [ "cat", "objects" ],
  return_type := "object",
  dual_operation := "DirectSum",
  functorial := "DirectSumFunctorial",
),

ProjectionInFactorOfDirectSum := rec(
  filter_list := [ "category", "list_of_objects", "integer" ],
  input_arguments_names := [ "cat", "objects", "k" ],
  output_range_getter_string := "objects[k]",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  return_type := "morphism",
  dual_operation := "InjectionOfCofactorOfDirectSum" ),

ProjectionInFactorOfDirectSumWithGivenDirectSum := rec(
  filter_list := [ "category", "list_of_objects", "integer", "object" ],
  input_arguments_names := [ "cat", "objects", "k", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "objects[k]",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "InjectionOfCofactorOfDirectSumWithGivenDirectSum" ),

UniversalMorphismIntoDirectSum := rec(
  filter_list := [ "category", "list_of_objects", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "objects", "T", "tau" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  dual_operation := "UniversalMorphismFromDirectSum",
  
  pre_function := function( cat, diagram, test_object, source )
    local current_morphism;
    
    for current_morphism in source do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), test_object ) then
            
            return [ false, "sources of morphisms must be equal to the test object in given source diagram" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

UniversalMorphismIntoDirectSumWithGivenDirectSum := rec(
  filter_list := [ "category", "list_of_objects", "object", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "objects", "T", "tau", "P" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  dual_operation := "UniversalMorphismFromDirectSumWithGivenDirectSum",
  
  pre_function := function( cat, diagram, test_object, source, direct_sum )
    local current_morphism;
    
    for current_morphism in source do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), test_object ) then
            
            return [ false, "sources of morphisms must be equal to the test object in given source diagram" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

InjectionOfCofactorOfDirectSum := rec(
  filter_list := [ "category", "list_of_objects", "integer" ],
  input_arguments_names := [ "cat", "objects", "k" ],
  output_source_getter_string := "objects[k]",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  return_type := "morphism",
  dual_operation := "ProjectionInFactorOfDirectSum" ),

InjectionOfCofactorOfDirectSumWithGivenDirectSum := rec(
  filter_list := [ "category", "list_of_objects", "integer", "object" ],
  input_arguments_names := [ "cat", "objects", "k", "P" ],
  output_source_getter_string := "objects[k]",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "ProjectionInFactorOfDirectSumWithGivenDirectSum" ),

UniversalMorphismFromDirectSum := rec(
  filter_list := [ "category", "list_of_objects", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "objects", "T", "tau" ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  dual_operation := "UniversalMorphismIntoDirectSum",
  
  pre_function := function( cat, diagram, test_object, sink )
    local current_morphism;
    
    for current_morphism in sink do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), test_object ) then
            
            return [ false, "ranges of morphisms must be equal to the test object in given sink diagram" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

UniversalMorphismFromDirectSumWithGivenDirectSum := rec(
  filter_list := [ "category", "list_of_objects", "object", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "objects", "T", "tau", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  dual_operation := "UniversalMorphismIntoDirectSumWithGivenDirectSum",
  
  pre_function := function( cat, diagram, test_object, sink, direct_sum )
    local current_morphism;
    
    for current_morphism in sink do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), test_object ) then
            
            return [ false, "ranges of morphisms must be equal to the test object in given sink diagram" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

TerminalObject := rec(
  filter_list := [ "category" ],
  input_arguments_names := [ "cat" ],
  return_type := "object",
  dual_operation := "InitialObject",
  functorial := "TerminalObjectFunctorial",
),

UniversalMorphismIntoTerminalObject := rec(
  filter_list := [ "category", "object" ],
  input_arguments_names := [ "cat", "T" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  return_type := "morphism",
  dual_operation := "UniversalMorphismFromInitialObject" ),

UniversalMorphismIntoTerminalObjectWithGivenTerminalObject := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "T", "P" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "UniversalMorphismFromInitialObjectWithGivenInitialObject" ),

InitialObject := rec(
  filter_list := [ "category" ],
  input_arguments_names := [ "cat" ],
  return_type := "object",
  dual_operation := "TerminalObject",
  functorial := "InitialObjectFunctorial",
),

UniversalMorphismFromInitialObject := rec(
  filter_list := [ "category", "object" ],
  input_arguments_names := [ "cat", "T" ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  return_type := "morphism",
  dual_operation := "UniversalMorphismIntoTerminalObject" ),

UniversalMorphismFromInitialObjectWithGivenInitialObject := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "T", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "UniversalMorphismIntoTerminalObjectWithGivenTerminalObject" ),

DirectProduct := rec(
  filter_list := [ "category", "list_of_objects" ],
  input_arguments_names := [ "cat", "objects" ],
  return_type := "object",
  dual_operation := "Coproduct",
  functorial := "DirectProductFunctorial",
),

ProjectionInFactorOfDirectProduct := rec(
  filter_list := [ "category", "list_of_objects", "integer" ],
  input_arguments_names := [ "cat", "objects", "k" ],
  output_range_getter_string := "objects[k]",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  return_type := "morphism",
  dual_operation := "InjectionOfCofactorOfCoproduct" ),

ProjectionInFactorOfDirectProductWithGivenDirectProduct := rec(
  filter_list := [ "category", "list_of_objects", "integer", "object" ],
  input_arguments_names := [ "cat", "objects", "k", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "objects[k]",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "InjectionOfCofactorOfCoproductWithGivenCoproduct" ),

UniversalMorphismIntoDirectProduct := rec(
  filter_list := [ "category", "list_of_objects", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "objects", "T", "tau" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  dual_operation := "UniversalMorphismFromCoproduct",
  
  pre_function := function( cat, diagram, test_object, source )
    local current_morphism;
    
    for current_morphism in source do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), test_object ) then
            
            return [ false, "sources of morphisms must be equal to the test object in given source diagram" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

UniversalMorphismIntoDirectProductWithGivenDirectProduct := rec(
  filter_list := [ "category", "list_of_objects", "object", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "objects", "T", "tau", "P" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  dual_operation := "UniversalMorphismFromCoproductWithGivenCoproduct",
  
  pre_function := function( cat, diagram, test_object, source, direct_product )
    local current_morphism;
    
    for current_morphism in source do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), test_object ) then
            
            return [ false, "sources of morphisms must be equal to the test object in given source diagram" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

ComponentOfMorphismIntoDirectProduct := rec(
  filter_list := [ "category", "morphism", "list_of_objects", "integer" ],
  input_arguments_names := [ "cat", "alpha", "P", "i" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P[i]",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "ComponentOfMorphismFromCoproduct" ),

IsCongruentForMorphisms := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  dual_operation := "IsCongruentForMorphisms",
  
  pre_function := function( cat, morphism_1, morphism_2 )
    
    if not IsEqualForObjects( cat, Source( morphism_1 ), Source( morphism_2 ) ) then
        
        return [ false, "sources are not equal" ];
        
    fi;
        
    if not IsEqualForObjects( cat, Range( morphism_1 ), Range( morphism_2 ) ) then
        
        return [ false, "ranges are not equal" ];
        
    fi;
    
    return [ true ];
    
  end,
  
  redirect_function := function( cat, morphism_1, morphism_2 )
    
    if IsIdenticalObj( morphism_1, morphism_2 ) then
      
      return [ true, true ];
      
    else
      
      return [ false ];
      
    fi;
    
  end,
  
  post_function := function( cat, morphism_1, morphism_2, return_value )
    
    if cat!.predicate_logic_propagation_for_morphisms and
       cat!.predicate_logic and return_value = true then
          
          INSTALL_TODO_LIST_FOR_EQUAL_MORPHISMS( morphism_1, morphism_2 );
          
    fi;
    
  end,
  
  return_type := "bool",
  compatible_with_congruence_of_morphisms := true,
),

IsEqualForMorphisms := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  dual_operation := "IsEqualForMorphisms",
  
  pre_function := function( cat, morphism_1, morphism_2 )
    
    if not IsEqualForObjects( cat, Source( morphism_1 ), Source( morphism_2 ) ) then
        
        return [ false, "sources are not equal" ];
        
    fi;
        
    if not IsEqualForObjects( cat, Range( morphism_1 ), Range( morphism_2 ) ) then
        
        return [ false, "ranges are not equal" ];
        
    fi;
    
    return [ true ];
    
  end,
  
  redirect_function := function( cat, morphism_1, morphism_2 )
    
    if IsIdenticalObj( morphism_1, morphism_2 ) then
      
      return [ true, true ];
      
    else
      
      return [ false ];
      
    fi;
    
  end,
  
  return_type := "bool",
  compatible_with_congruence_of_morphisms := false,
),

IsEqualForMorphismsOnMor := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  dual_operation := "IsEqualForMorphismsOnMor",
  
  redirect_function := function( cat, morphism_1, morphism_2 )
    
    if IsIdenticalObj( morphism_1, morphism_2 ) then
      
      return [ true, true ];
      
    else
      
      return [ false ];
      
    fi;
    
  end,
  
  return_type := "bool",
  compatible_with_congruence_of_morphisms := false,
),

IsEqualForObjects := rec(
  filter_list := [ "category", "object", "object" ],
  dual_operation := "IsEqualForObjects",
  
  redirect_function := function( cat, object_1, object_2 )
    
    if IsIdenticalObj( object_1, object_2 ) then
      
      return [ true, true ];
      
    else
      
      return [ false ];
      
    fi;
    
  end,
  
  post_function := function( cat, object_1, object_2, return_value )
    
    if cat!.predicate_logic_propagation_for_objects and
       cat!.predicate_logic and return_value = true and not IsIdenticalObj( object_1, object_2 ) then
        
        INSTALL_TODO_LIST_FOR_EQUAL_OBJECTS( object_1, object_2 );
        
    fi;
    
  end,
  
  return_type := "bool" ),
  
IsEqualForCacheForObjects := rec(
  filter_list := [ "category", "object", "object" ],
  dual_operation := "IsEqualForCacheForObjects",
  return_type := "bool" ),

IsEqualForCacheForMorphisms := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  dual_operation := "IsEqualForCacheForMorphisms",
  return_type := "bool",
  compatible_with_congruence_of_morphisms := false,
),

IsIsomorphicForObjects := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "object_1", "object_2" ],
  return_type := "bool",
  dual_operation := "IsIsomorphicForObjects",
  # The witness SomeIsomorphismBetweenObjects needs reversed arguments.
  # This shows that reversing the arguments is the correct dualization,
  # even if the relation is symmetric.
  dual_arguments_reversed := true,
  redirect_function := function( cat, object_1, object_2 )
    
    # As any CAP operation, IsIsomorphicForObjects must be compatible with IsEqualForObjects.
    # This implies that IsIsomorphicForObjects must be coarser than IsEqualForObjects:
    # One can see this by first choosing object_2 := object_1 and the varying one argument with regard to IsEqualForObjects.
    if IsEqualForObjects( object_1, object_2 ) then
        
        return [ true, true ];
        
    else
        
        return [ false ];
        
    fi;
    
  end,
),

SomeIsomorphismBetweenObjects := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "object_1", "object_2" ],
  return_type := "morphism",
  output_source_getter_string := "object_1",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "object_2",
  output_range_getter_preconditions := [ ],
  dual_operation := "SomeIsomorphismBetweenObjects",
  dual_arguments_reversed := true,
),

IsZeroForMorphisms := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "bool",
  dual_operation := "IsZeroForMorphisms",
  is_reflected_by_faithful_functor := true,
  compatible_with_congruence_of_morphisms := true,
),

AdditionForMorphisms := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "beta" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  dual_operation := "AdditionForMorphisms",
  
  pre_function := function( cat, morphism_1, morphism_2 )
    
    if not IsEqualForObjects( cat, Source( morphism_1 ), Source( morphism_2 ) ) then
        
        return [ false, "sources are not equal" ];
        
    fi;
        
    if not IsEqualForObjects( cat, Range( morphism_1 ), Range( morphism_2 ) ) then
        
        return [ false, "ranges are not equal" ];
        
    fi;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

SubtractionForMorphisms := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "beta" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  dual_operation := "SubtractionForMorphisms",
  
  pre_function := function( cat, morphism_1, morphism_2 )
    
    if not IsEqualForObjects( cat, Source( morphism_1 ), Source( morphism_2 ) ) then
        
        return [ false, "sources are not equal" ];
        
    fi;
        
    if not IsEqualForObjects( cat, Range( morphism_1 ), Range( morphism_2 ) ) then
        
        return [ false, "ranges are not equal" ];
        
    fi;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

MultiplyWithElementOfCommutativeRingForMorphisms := rec(
  filter_list := [ "category", "element_of_commutative_ring_of_linear_structure", "morphism" ],
  input_arguments_names := [ "cat", "r", "alpha" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  
  pre_function := function( cat, r, morphism )
    
    if not r in CommutativeRingOfLinearCategory( cat ) then
      
      return [ false, "the first argument is not an element of the ring of the category of the morphism" ];
      
    fi;
    
    return [ true ];
  end,
  dual_operation := "MultiplyWithElementOfCommutativeRingForMorphisms",
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

AdditiveInverseForMorphisms := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  dual_operation := "AdditiveInverseForMorphisms",
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

Coproduct := rec(
  filter_list := [ "category", "list_of_objects" ],
  input_arguments_names := [ "cat", "objects" ],
  return_type := "object",
  dual_operation := "DirectProduct",
  functorial := "CoproductFunctorial",
),

InjectionOfCofactorOfCoproduct := rec(
  filter_list := [ "category", "list_of_objects", "integer" ],
  input_arguments_names := [ "cat", "objects", "k" ],
  output_source_getter_string := "objects[k]",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  return_type := "morphism",
  dual_operation := "ProjectionInFactorOfDirectProduct" ),

InjectionOfCofactorOfCoproductWithGivenCoproduct := rec(
  filter_list := [ "category", "list_of_objects", "integer", "object" ],
  input_arguments_names := [ "cat", "objects", "k", "P" ],
  output_source_getter_string := "objects[k]",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "ProjectionInFactorOfDirectProductWithGivenDirectProduct" ),

UniversalMorphismFromCoproduct := rec(
  filter_list := [ "category", "list_of_objects", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "objects", "T", "tau" ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  dual_operation := "UniversalMorphismIntoDirectProduct",
  
  pre_function := function( cat, diagram, test_object, sink )
    local current_morphism;
    
    for current_morphism in sink do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), test_object ) then
            
            return [ false, "ranges of morphisms must be equal to the test object in given sink diagram" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

UniversalMorphismFromCoproductWithGivenCoproduct := rec(
  filter_list := [ "category", "list_of_objects", "object", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "objects", "T", "tau", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  dual_operation := "UniversalMorphismIntoDirectProductWithGivenDirectProduct",
  
  pre_function := function( cat, diagram, test_object, sink, coproduct )
    local current_morphism;
    
    for current_morphism in sink do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), test_object ) then
            
            return [ false, "ranges of morphisms must be equal to the test object in given sink diagram" ];
            
        fi;
        
    od;
    
    return [ true ];
    
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := true,
),

ComponentOfMorphismFromCoproduct := rec(
  filter_list := [ "category", "morphism", "list_of_objects", "integer" ],
  input_arguments_names := [ "cat", "alpha", "I", "i" ],
  output_source_getter_string := "I[i]",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "ComponentOfMorphismIntoDirectProduct" ),

IsEqualAsSubobjects := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  return_type := "bool",
  dual_operation := "IsEqualAsFactorobjects",
  compatible_with_congruence_of_morphisms := true,
),

IsEqualAsFactorobjects := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  return_type := "bool",
  dual_operation := "IsEqualAsSubobjects",
  compatible_with_congruence_of_morphisms := true,
),

IsDominating := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  dual_operation := "IsCodominating",
  
  pre_function := function( cat, sub1, sub2 )
    
    if not IsEqualForObjects( cat, Range( sub1 ), Range( sub2 ) ) then
        
        return [ false, "subobjects of different objects are not comparable by dominates" ];
        
    fi;
    
    return [ true ];
  end,
  return_type := "bool",
  compatible_with_congruence_of_morphisms := true,
),

IsCodominating := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  dual_operation := "IsDominating",
  
  pre_function := function( cat, factor1, factor2 )
    
    if not IsEqualForObjects( cat, Source( factor1 ), Source( factor2 ) ) then
        
        return [ false, "factors of different objects are not comparable by codominates" ];
        
    fi;
    
    return [ true ];
  end,
  return_type := "bool",
  compatible_with_congruence_of_morphisms := true,
),

Equalizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "Y", "morphisms" ],
  return_type := "object",
  dual_operation := "Coequalizer",
  
  pre_function := function( cat, cobase, diagram )
    local base, current_morphism;
    
    if IsEmpty( diagram ) then
        
        return [ true ];
        
    fi;
    
    for current_morphism in diagram{[ 1 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), cobase ) then
            return [ false, "the given morphisms of the equalizer diagram must have equal sources" ];
        fi;
        
    od;
    
    base := Range( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), base ) then
            return [ false, "the given morphisms of the equalizer diagram must have equal ranges" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  compatible_with_congruence_of_morphisms := false,
  functorial := "EqualizerFunctorial",
),

EmbeddingOfEqualizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  return_type := "morphism",
  input_arguments_names := [ "cat", "Y", "morphisms" ],
  output_range_getter_string := "Y",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  dual_operation := "ProjectionOntoCoequalizer",
  
  pre_function := "Equalizer",
  compatible_with_congruence_of_morphisms := false,
),

EmbeddingOfEqualizerWithGivenEqualizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "object" ],
  return_type := "morphism",
  input_arguments_names := [ "cat", "Y", "morphisms", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Y",
  output_range_getter_preconditions := [ ],
  dual_operation := "ProjectionOntoCoequalizerWithGivenCoequalizer",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromEqualizerToSink := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "Y", "morphisms" ],
  output_range_getter_string := "Range( morphisms[1] )",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  dual_operation := "MorphismFromSourceToCoequalizer",
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromEqualizerToSinkWithGivenEqualizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "Y", "morphisms", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( morphisms[1] )",
  output_range_getter_preconditions := [ ],
  dual_operation := "MorphismFromSourceToCoequalizerWithGivenCoequalizer",
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

UniversalMorphismIntoEqualizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "object", "morphism" ],
  input_arguments_names := [ "cat", "Y", "morphisms", "T", "tau" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  return_type := "morphism",
  dual_operation := "UniversalMorphismFromCoequalizer",
  
  pre_function := function( cat, cobase, diagram, test_object, tau )
    local base, current_morphism, current_morphism_position;
    
    if IsEmpty( diagram ) then
        
        return [ true ];
        
    fi;
    
    for current_morphism in diagram{[ 1 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), cobase ) then
            return [ false, "the given morphisms of the equalizer diagram must have equal sources" ];
        fi;
        
    od;
    
    base := Range( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), base ) then
            return [ false, "the given morphisms of the equalizer diagram must have equal ranges" ];
        fi;
        
    od;
    
    for current_morphism_position in [ 1 .. Length( diagram ) ] do
        
        if not IsEqualForObjects( cat, Source( diagram[ current_morphism_position ] ), Range( tau ) ) then
            return [ false, Concatenation( "in diagram position ", String( current_morphism_position ), ": source and range are not equal" ) ];
        fi;
        
    od;
    
    return [ true ];
  end,
  compatible_with_congruence_of_morphisms := false,
),

UniversalMorphismIntoEqualizerWithGivenEqualizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "object", "morphism", "object" ],
  input_arguments_names := [ "cat", "Y", "morphisms", "T", "tau", "P" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "UniversalMorphismFromCoequalizerWithGivenCoequalizer",
  compatible_with_congruence_of_morphisms := false,
),

IsomorphismFromEqualizerToKernelOfJointPairwiseDifferencesOfMorphismsIntoDirectProduct := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "A", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromCokernelOfJointPairwiseDifferencesOfMorphismsFromCoproductToCoequalizer",
),

IsomorphismFromKernelOfJointPairwiseDifferencesOfMorphismsIntoDirectProductToEqualizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "A", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromCoequalizerToCokernelOfJointPairwiseDifferencesOfMorphismsFromCoproduct",
),

FiberProduct := rec(
  filter_list := [ "category", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "morphisms" ],
  dual_operation := "Pushout",
  
  pre_function := function( cat, diagram )
    local base, current_morphism;
    
    if IsEmpty( diagram ) then
        
        return [ true ];
        
    fi;
    
    base := Range( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), base ) then
            return [ false, "the given morphisms of the fiber product diagram must have equal ranges" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "object",
  compatible_with_congruence_of_morphisms := false,
  functorial := "FiberProductFunctorial",
),

ProjectionInFactorOfFiberProduct := rec(
  filter_list := [ "category", "list_of_morphisms", "integer" ],
  input_arguments_names := [ "cat", "morphisms", "k" ],
  output_range_getter_string := "Source( morphisms[k] )",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  dual_operation := "InjectionOfCofactorOfPushout",
  
  pre_function := function( cat, diagram, projection_number )
    local base, current_morphism;
    
    if projection_number < 1 or projection_number > Length( diagram ) then
        return[ false, Concatenation( "there does not exist a ", String( projection_number ), "th projection" ) ];
    fi;
    
    base := Range( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), base ) then
            return [ false, "the given morphisms of the fiber product diagram must have equal ranges" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

ProjectionInFactorOfFiberProductWithGivenFiberProduct := rec(
  filter_list := [ "category", "list_of_morphisms", "integer", "object" ],
  input_arguments_names := [ "cat", "morphisms", "k", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Source( morphisms[k] )",
  output_range_getter_preconditions := [ ],
  dual_operation := "InjectionOfCofactorOfPushoutWithGivenPushout",
  
  pre_function := function( cat, diagram, projection_number, pullback )
    local base, current_morphism;
    
    if projection_number < 1 or projection_number > Length( diagram ) then
        return[ false, Concatenation( "there does not exist a ", String( projection_number ), "th projection" ) ];
    fi;
    
    base := Range( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), base ) then
            return [ false, "the given morphisms of the fiber product diagram must have equal ranges" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromFiberProductToSink := rec(
  filter_list := [ "category", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "morphisms" ],
  output_range_getter_string := "Range( morphisms[1] )",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  dual_operation := "MorphismFromSourceToPushout",
  
  pre_function := function( cat, diagram )
    local base, current_morphism;
    
    base := Range( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), base ) then
            return [ false, "the given morphisms of the fiber product diagram must have equal ranges" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromFiberProductToSinkWithGivenFiberProduct := rec(
  filter_list := [ "category", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "morphisms", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( morphisms[1] )",
  output_range_getter_preconditions := [ ],
  dual_operation := "MorphismFromSourceToPushoutWithGivenPushout",
  
  pre_function := function( cat, diagram, pullback )
    local base, current_morphism;
    
    base := Range( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), base ) then
            return [ false, "the given morphisms of the fiber product diagram must have equal ranges" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

UniversalMorphismIntoFiberProduct := rec(
  filter_list := [ "category", "list_of_morphisms", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "morphisms", "T", "tau" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  dual_operation := "UniversalMorphismFromPushout",
  
  pre_function := function( cat, diagram, test_object, source )
    local base, current_morphism, current_morphism_position;
    
    if Length( diagram ) <> Length( source ) then
        return [ false, "fiber product diagram and test diagram must have equal length" ];
    fi;
    
    if IsEmpty( diagram ) then
        
        return [ true ];
        
    fi;
    
    base := Range( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), base ) then
            return [ false, "the given morphisms of the fiber product diagram must have equal ranges" ];
        fi;
        
    od;
    
    for current_morphism in source do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), test_object ) then
            return [ false, "the given morphisms of the test source do not have sources equal to the test object" ];
        fi;
        
    od;
    
    for current_morphism_position in [ 1 .. Length( diagram ) ] do
        
        if not IsEqualForObjects( cat, Source( diagram[ current_morphism_position ] ), Range( source[ current_morphism_position ] ) ) then
            return [ false, Concatenation( "in diagram position ", String( current_morphism_position ), ": source and range are not equal" ) ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

UniversalMorphismIntoFiberProductWithGivenFiberProduct := rec(
  filter_list := [ "category", "list_of_morphisms", "object", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "morphisms", "T", "tau", "P" ],
  output_source_getter_string := "T",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  dual_operation := "UniversalMorphismFromPushoutWithGivenPushout",
  
  pre_function := function( cat, diagram, test_object, source, pullback )
    local base, current_morphism, current_morphism_position;
    
    if Length( diagram ) <> Length( source ) then
        return [ false, "fiber product diagram and test diagram must have equal length" ];
    fi;
    
    if IsEmpty( diagram ) then
        
        return [ true ];
        
    fi;
    
    base := Range( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), base ) then
            return [ false, "the given morphisms of the fiber product diagram must have equal ranges" ];
        fi;
        
    od;
    
    for current_morphism in source do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), test_object ) then
            return [ false, "the given morphisms of the test source do not have sources equal to the test object" ];
        fi;
        
    od;
    
    for current_morphism_position in [ 1 .. Length( diagram ) ] do
        
        if not IsEqualForObjects( cat, Source( diagram[ current_morphism_position ] ), Range( source[ current_morphism_position ] ) ) then
            return [ false, Concatenation( "in diagram position ", String( current_morphism_position ), ": source and range are not equal" ) ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

Coequalizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "Y", "morphisms" ],
  return_type := "object",
  dual_operation := "Equalizer",
  
  pre_function := function( cat, cobase, diagram )
    local base, current_morphism;
    
    if IsEmpty( diagram ) then
        
        return [ true ];
        
    fi;
    
    base := Source( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), base ) then
            return [ false, "the given morphisms of the coequalizer diagram must have equal sources" ];
        fi;
        
    od;
    
    for current_morphism in diagram{[ 1 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), cobase ) then
            return [ false, "the given morphisms of the coequalizer diagram must have equal ranges" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  compatible_with_congruence_of_morphisms := false,
  functorial := "CoequalizerFunctorial",
),

ProjectionOntoCoequalizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  return_type := "morphism",
  input_arguments_names := [ "cat", "Y", "morphisms" ],
  output_source_getter_string := "Y",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  dual_operation := "EmbeddingOfEqualizer",
  
  pre_function := "Coequalizer",
  compatible_with_congruence_of_morphisms := false,
),

ProjectionOntoCoequalizerWithGivenCoequalizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "object" ],
  return_type := "morphism",
  input_arguments_names := [ "cat", "Y", "morphisms", "P" ],
  output_source_getter_string := "Y",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  dual_operation := "EmbeddingOfEqualizerWithGivenEqualizer",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromSourceToCoequalizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "Y", "morphisms" ],
  output_source_getter_string := "Source( morphisms[1] )",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  dual_operation := "MorphismFromEqualizerToSink",
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromSourceToCoequalizerWithGivenCoequalizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "Y", "morphisms", "P" ],
  output_source_getter_string := "Source( morphisms[1] )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  dual_operation := "MorphismFromEqualizerToSinkWithGivenEqualizer",
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

UniversalMorphismFromCoequalizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "object", "morphism" ],
  input_arguments_names := [ "cat", "Y", "morphisms", "T", "tau" ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  return_type := "morphism",
  dual_operation := "UniversalMorphismIntoEqualizer",
  
  pre_function := function( cat, cobase, diagram, test_object, tau )
    local base, current_morphism, current_morphism_position;
    
    if IsEmpty( diagram ) then
        
        return [ true ];
        
    fi;
    
    base := Source( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), base ) then
            return [ false, "the given morphisms of the coequalizer diagram must have equal sources" ];
        fi;
        
    od;
    
    for current_morphism in diagram{[ 1 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), cobase ) then
            return [ false, "the given morphisms of the coequalizer diagram must have equal ranges" ];
        fi;
        
    od;
    
    for current_morphism_position in [ 1 .. Length( diagram ) ] do
        
        if not IsEqualForObjects( cat, Range( diagram[ current_morphism_position ] ), Source( tau ) ) then
            return [ false, Concatenation( "in diagram position ", String( current_morphism_position ), ": range and source are not equal" ) ];
        fi;
        
    od;
    
    return [ true ];
  end,
  compatible_with_congruence_of_morphisms := false,
),

UniversalMorphismFromCoequalizerWithGivenCoequalizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "object", "morphism", "object" ],
  input_arguments_names := [ "cat", "Y", "morphisms", "T", "tau", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "UniversalMorphismIntoEqualizerWithGivenEqualizer",
  compatible_with_congruence_of_morphisms := false,
),

IsomorphismFromCoequalizerToCokernelOfJointPairwiseDifferencesOfMorphismsFromCoproduct := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "A", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromKernelOfJointPairwiseDifferencesOfMorphismsIntoDirectProductToEqualizer",
),

IsomorphismFromCokernelOfJointPairwiseDifferencesOfMorphismsFromCoproductToCoequalizer := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "A", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromEqualizerToKernelOfJointPairwiseDifferencesOfMorphismsIntoDirectProduct",
),

Pushout := rec(
  filter_list := [ "category", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "morphisms" ],
  dual_operation := "FiberProduct",
  
  pre_function := function( cat, diagram )
    local cobase, current_morphism;
    
    if IsEmpty( diagram ) then
        
        return [ true ];
        
    fi;
    
    cobase := Source( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), cobase ) then
            return [ false, "the given morphisms of the pushout diagram must have equal sources" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "object",
  compatible_with_congruence_of_morphisms := false,
  functorial := "PushoutFunctorial",
),

InjectionOfCofactorOfPushout := rec(
  filter_list := [ "category", "list_of_morphisms", "integer" ],
  input_arguments_names := [ "cat", "morphisms", "k" ],
  output_source_getter_string := "Range( morphisms[k] )",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  dual_operation := "ProjectionInFactorOfFiberProduct",
  
  pre_function := function( cat, diagram, injection_number )
    local cobase, current_morphism;
    
    if injection_number < 1 or injection_number > Length( diagram ) then
        return[ false, Concatenation( "there does not exist a ", String( injection_number ), "th injection" ) ];
    fi;
    
    cobase := Source( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), cobase ) then
            return [ false, "the given morphisms of the pushout diagram must have equal sources" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

InjectionOfCofactorOfPushoutWithGivenPushout := rec(
  filter_list := [ "category", "list_of_morphisms", "integer", "object" ],
  input_arguments_names := [ "cat", "morphisms", "k", "P" ],
  output_source_getter_string := "Range( morphisms[k] )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  dual_operation := "ProjectionInFactorOfFiberProductWithGivenFiberProduct",
  
  pre_function := function( cat, diagram, injection_number, pushout )
    local cobase, current_morphism;
    
    if injection_number < 1 or injection_number > Length( diagram ) then
        return[ false, Concatenation( "there does not exist a ", String( injection_number ), "th injection" ) ];
    fi;
    
    cobase := Source( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), cobase ) then
            return [ false, "the given morphisms of the pushout diagram must have equal sources" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromSourceToPushout := rec(
  filter_list := [ "category", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "morphisms" ],
  output_source_getter_string := "Source( morphisms[1] )",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  dual_operation := "MorphismFromFiberProductToSink",
  
  pre_function := function( cat, diagram )
    local cobase, current_morphism;
    
    cobase := Source( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), cobase ) then
            return [ false, "the given morphisms of the pushout diagram must have equal sources" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

MorphismFromSourceToPushoutWithGivenPushout := rec(
  filter_list := [ "category", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "morphisms", "P" ],
  output_source_getter_string := "Source( morphisms[1] )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "P",
  output_range_getter_preconditions := [ ],
  dual_operation := "MorphismFromFiberProductToSinkWithGivenFiberProduct",
  
  pre_function := function( cat, diagram, pushout )
    local cobase, current_morphism;
    
    cobase := Source( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), cobase ) then
            return [ false, "the given morphisms of the pushout diagram must have equal sources" ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

UniversalMorphismFromPushout := rec(
  filter_list := [ "category", "list_of_morphisms", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "morphisms", "T", "tau" ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  dual_operation := "UniversalMorphismIntoFiberProduct",
  
  pre_function := function( cat, diagram, test_object, sink )
    local cobase, current_morphism, current_morphism_position;
    
    if Length( diagram ) <> Length( sink ) then
        return [ false, "pushout diagram and test diagram must have equal length" ];
    fi;
    
    if IsEmpty( diagram ) then
        
        return [ true ];
        
    fi;
    
    cobase := Source( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), cobase ) then
            return [ false, "the given morphisms of the fiber pushout must have equal sources" ];
        fi;
        
    od;
    
    for current_morphism in sink do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), test_object ) then
            return [ false, "the given morphisms of the test sink do not have ranges equal to the test object" ];
        fi;
        
    od;
    
    for current_morphism_position in [ 1 .. Length( diagram ) ] do
        
        if not IsEqualForObjects( cat, Range( diagram[ current_morphism_position ] ), Source( sink[ current_morphism_position ] ) ) then
            return [ false, Concatenation( "in diagram position ", String( current_morphism_position ), ": source and range are not equal" ) ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

UniversalMorphismFromPushoutWithGivenPushout := rec(
  filter_list := [ "category", "list_of_morphisms", "object", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "morphisms", "T", "tau", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  dual_operation := "UniversalMorphismIntoFiberProductWithGivenFiberProduct",
  
  pre_function := function( cat, diagram, test_object, sink, pushout )
    local cobase, current_morphism, current_morphism_position;
    
    if Length( diagram ) <> Length( sink ) then
        return [ false, "pushout diagram and test diagram must have equal length" ];
    fi;
    
    if IsEmpty( diagram ) then
        
        return [ true ];
        
    fi;
    
    cobase := Source( diagram[1] );
    
    for current_morphism in diagram{[ 2 .. Length( diagram ) ]} do
        
        if not IsEqualForObjects( cat, Source( current_morphism ), cobase ) then
            return [ false, "the given morphisms of the fiber pushout must have equal sources" ];
        fi;
        
    od;
    
    for current_morphism in sink do
        
        if not IsEqualForObjects( cat, Range( current_morphism ), test_object ) then
            return [ false, "the given morphisms of the test sink do not have ranges equal to the test object" ];
        fi;
        
    od;
    
    for current_morphism_position in [ 1 .. Length( diagram ) ] do
        
        if not IsEqualForObjects( cat, Range( diagram[ current_morphism_position ] ), Source( sink[ current_morphism_position ] ) ) then
            return [ false, Concatenation( "in diagram position ", String( current_morphism_position ), ": source and range are not equal" ) ];
        fi;
        
    od;
    
    return [ true ];
  end,
  return_type := "morphism",
  compatible_with_congruence_of_morphisms := false,
),

ImageObject := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "object",
  dual_operation := "CoimageObject",
  functorial := "ImageObjectFunctorial",
),

ImageEmbedding := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  return_type := "morphism",
  dual_operation := "CoimageProjection" ),

ImageEmbeddingWithGivenImageObject := rec(
  filter_list := [ "category", "morphism", "object" ],
  input_arguments_names := [ "cat", "alpha", "I" ],
  output_source_getter_string := "I",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "CoimageProjectionWithGivenCoimageObject" ),

CoimageObject := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "object",
  dual_operation := "ImageObject",
  functorial := "CoimageObjectFunctorial",
),

CoimageProjection := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  return_type := "morphism",
  dual_operation := "ImageEmbedding" ),

CoimageProjectionWithGivenCoimageObject := rec(
  filter_list := [ "category", "morphism", "object" ],
  input_arguments_names := [ "cat", "alpha", "C" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "C",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "ImageEmbeddingWithGivenImageObject" ),

AstrictionToCoimage := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  return_type := "morphism",
  dual_operation := "CoastrictionToImage" ),

AstrictionToCoimageWithGivenCoimageObject := rec(
  filter_list := [ "category", "morphism", "object" ],
  input_arguments_names := [ "cat", "alpha", "C" ],
  output_source_getter_string := "C",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "CoastrictionToImageWithGivenImageObject" ),

UniversalMorphismIntoCoimage := rec(
  filter_list := [ "category", "morphism", "pair_of_morphisms" ],
  input_arguments_names := [ "cat", "alpha", "tau" ],
  output_source_getter_string := "Range( tau[1] )",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  dual_preprocessor_func := function( cat, alpha, tau )
    return Triple( OppositeCategory( cat ), Opposite( alpha ), Pair( Opposite( tau[2] ), Opposite( tau[1] ) ) );
  end,
  pre_function := function( cat, morphism, test_factorization )
    
    if not IsEqualForObjects( cat, Source( morphism ), Source( test_factorization[ 1 ] ) ) then
        return [ false, "source of morphism and test factorization are not equal" ];
    fi;
    
    if not IsEqualForObjects( cat, Range( morphism ), Range( test_factorization[ 2 ] ) ) then
        return [ false, "range of morphism and test factorization are not equal" ];
    fi;
    
    if not IsEqualForObjects( cat, Range( test_factorization[ 1 ] ), Source( test_factorization[ 2 ] ) ) then
        return [ false, "source and range of test factorization are not equal" ];
    fi;
    
    return [ true ];
  end,
  return_type := "morphism",
  dual_operation := "UniversalMorphismFromImage" ),

UniversalMorphismIntoCoimageWithGivenCoimageObject := rec(
  filter_list := [ "category", "morphism", "pair_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "alpha", "tau", "C" ],
  output_source_getter_string := "Range( tau[1] )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "C",
  output_range_getter_preconditions := [ ],
  dual_preprocessor_func := function( cat, alpha, tau, C )
    return NTuple( 4, OppositeCategory( cat ), Opposite( alpha ), Pair( Opposite( tau[2] ), Opposite( tau[1] ) ), Opposite( C ) );
  end,
  pre_function := function( cat, morphism, test_factorization, image )
    
    if not IsEqualForObjects( cat, Source( morphism ), Source( test_factorization[ 1 ] ) ) then
        return [ false, "source of morphism and test factorization are not equal" ];
    fi;
    
    if not IsEqualForObjects( cat, Range( morphism ), Range( test_factorization[ 2 ] ) ) then
        return [ false, "range of morphism and test factorization are not equal" ];
    fi;
    
    if not IsEqualForObjects( cat, Range( test_factorization[ 1 ] ), Source( test_factorization[ 2 ] ) ) then
        return [ false, "source and range of test factorization are not equal" ];
    fi;
    
    return [ true ];
  end,
  return_type := "morphism",
  dual_operation := "UniversalMorphismFromImageWithGivenImageObject" ),

MorphismFromCoimageToImage := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_source_getter_string := "CoimageObject( cat, alpha )",
  output_source_getter_preconditions := [ [ "CoimageObject", 1 ] ],
  output_range_getter_string := "ImageObject( cat, alpha )",
  output_range_getter_preconditions := [ [ "ImageObject", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "MorphismFromCoimageToImage",
  return_type := "morphism" ),

MorphismFromCoimageToImageWithGivenObjects := rec(
  filter_list := [ "category", "object", "morphism", "object" ],
  input_arguments_names := [ "cat", "C", "alpha", "I" ],
  output_source_getter_string := "C",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "I",
  output_range_getter_preconditions := [ ],
  dual_operation := "MorphismFromCoimageToImageWithGivenObjects",
  dual_arguments_reversed := true,
  return_type := "morphism" ),

InverseOfMorphismFromCoimageToImage := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_source_getter_string := "ImageObject( cat, alpha )",
  output_source_getter_preconditions := [ [ "ImageObject", 1 ] ],
  output_range_getter_string := "CoimageObject( cat, alpha )",
  output_range_getter_preconditions := [ [ "CoimageObject", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "InverseOfMorphismFromCoimageToImage",
  return_type := "morphism" ),

InverseOfMorphismFromCoimageToImageWithGivenObjects := rec(
  filter_list := [ "category", "object", "morphism", "object" ],
  input_arguments_names := [ "cat", "I", "alpha", "C" ],
  output_source_getter_string := "I",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "C",
  output_range_getter_preconditions := [ ],
  dual_operation := "InverseOfMorphismFromCoimageToImageWithGivenObjects",
  dual_arguments_reversed := true,
  return_type := "morphism" ),

IsWellDefinedForMorphisms := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  dual_operation := "IsWellDefinedForMorphisms",
  
  redirect_function := function( cat, morphism )
    local source, range;
    
    source := Source( morphism );
    
    range := Range( morphism );
    
    if not ( IsWellDefinedForObjects( cat, source ) and IsWellDefinedForObjects( cat, range ) ) then
      
      return [ true, false ];
      
      
    else
      
      return [ false ];
      
    fi;
    
  end,
  
  return_type := "bool" ),

IsWellDefinedForMorphismsWithGivenSourceAndRange := rec(
  filter_list := [ "category", "object", "morphism", "object" ],
  input_arguments_names := [ "cat", "source", "alpha", "range" ],
  return_type := "bool",
  dual_operation := "IsWellDefinedForMorphismsWithGivenSourceAndRange",
  dual_arguments_reversed := true,
),

IsWellDefinedForObjects := rec(
  filter_list := [ "category", "object" ],
  dual_operation := "IsWellDefinedForObjects",
  return_type := "bool" ),

IsZeroForObjects := rec(
  filter_list := [ "category", "object" ],
  return_type := "bool",
  dual_operation := "IsZeroForObjects",
),

IsMonomorphism := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "bool",
  dual_operation := "IsEpimorphism",
  is_reflected_by_faithful_functor := true,
),

IsEpimorphism := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "bool",
  dual_operation := "IsMonomorphism",
  is_reflected_by_faithful_functor := true,
),

IsIsomorphism := rec(
  filter_list := [ "category", "morphism" ],
  dual_operation := "IsIsomorphism",
  return_type := "bool",
),

IsEndomorphism := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "bool",
  dual_operation := "IsEndomorphism",
),

IsAutomorphism := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "bool",
  dual_operation := "IsAutomorphism",
),

IsOne := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "bool",
  dual_operation := "IsOne",
  pre_function := function( cat, morphism )
    
    if not IsEqualForObjects( cat, Source( morphism ), Range( morphism ) ) then
        
        return [ false, "source and range of the given morphism are not equal" ];
        
    fi;
    
    return [ true ];
  end,
),

IsSplitMonomorphism := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "bool",
  dual_operation := "IsSplitEpimorphism",
),

IsSplitEpimorphism := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "bool",
  dual_operation := "IsSplitMonomorphism",
),

IsIdempotent := rec(
   pre_function := function( cat, morphism )
    
    # do not use IsEndomorphism( morphism ) here because you don't know if
    # the user has given an own IsEndomorphism function
    if not IsEqualForObjects( cat, Source( morphism ), Range( morphism ) ) then
      
      return [ false, "the given morphism has to be an endomorphism" ];
      
    fi;
    
    return [ true ];
  end,
  filter_list := [ "category", "morphism" ],
  return_type := "bool",
  dual_operation := "IsIdempotent",
),

IsBijectiveObject := rec(
  filter_list := [ "category", "object" ],
  return_type := "bool",
  dual_operation := "IsBijectiveObject",
),

IsProjective := rec(
  filter_list := [ "category", "object" ],
  return_type := "bool",
  dual_operation := "IsInjective",
),

IsInjective := rec(
  filter_list := [ "category", "object" ],
  return_type := "bool",
  dual_operation := "IsProjective",
),

IsTerminal := rec(
  filter_list := [ "category", "object" ],
  return_type := "bool",
  dual_operation := "IsInitial",
),

IsInitial := rec(
  filter_list := [ "category", "object" ],
  return_type := "bool",
  dual_operation := "IsTerminal",
),

IsEqualToIdentityMorphism := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "bool",
  dual_operation := "IsEqualToIdentityMorphism",
),

IsEqualToZeroMorphism := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "bool",
  dual_operation := "IsEqualToZeroMorphism",
),

CoastrictionToImage := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  return_type := "morphism",
  dual_operation := "AstrictionToCoimage" ),

CoastrictionToImageWithGivenImageObject := rec(
  filter_list := [ "category", "morphism", "object" ],
  input_arguments_names := [ "cat", "alpha", "I" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "I",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "AstrictionToCoimageWithGivenCoimageObject" ),

UniversalMorphismFromImage := rec(
  filter_list := [ "category", "morphism", "pair_of_morphisms" ],
  input_arguments_names := [ "cat", "alpha", "tau" ],
  output_range_getter_string := "Range( tau[1] )",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  dual_operation := "UniversalMorphismIntoCoimage",
  dual_preprocessor_func := function( cat, alpha, tau )
    return Triple( OppositeCategory( cat ), Opposite( alpha ), Pair( Opposite( tau[2] ), Opposite( tau[1] ) ) );
  end,
  pre_function := function( cat, morphism, test_factorization )
    
    if not IsEqualForObjects( cat, Source( morphism ), Source( test_factorization[ 1 ] ) ) then
        return [ false, "source of morphism and test factorization are not equal" ];
    fi;
    
    if not IsEqualForObjects( cat, Range( morphism ), Range( test_factorization[ 2 ] ) ) then
        return [ false, "range of morphism and test factorization are not equal" ];
    fi;
    
    if not IsEqualForObjects( cat, Range( test_factorization[ 1 ] ), Source( test_factorization[ 2 ] ) ) then
        return [ false, "source and range of test factorization are not equal" ];
    fi;
    
    return [ true ];
  end,
  return_type := "morphism" ),

UniversalMorphismFromImageWithGivenImageObject := rec(
  filter_list := [ "category", "morphism", "pair_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "alpha", "tau", "I" ],
  output_source_getter_string := "I",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( tau[1] )",
  output_range_getter_preconditions := [ ],
  dual_operation := "UniversalMorphismIntoCoimageWithGivenCoimageObject",
  dual_preprocessor_func := function( cat, alpha, tau, I )
    return NTuple( 4, OppositeCategory( cat ), Opposite( alpha ), Pair( Opposite( tau[2] ), Opposite( tau[1] ) ), Opposite( I ) );
  end,
  pre_function := function( cat, morphism, test_factorization, image )
    
    if not IsEqualForObjects( cat, Source( morphism ), Source( test_factorization[ 1 ] ) ) then
        return [ false, "source of morphism and test factorization are not equal" ];
    fi;
    
    if not IsEqualForObjects( cat, Range( morphism ), Range( test_factorization[ 2 ] ) ) then
        return [ false, "range of morphism and test factorization are not equal" ];
    fi;
    
    if not IsEqualForObjects( cat, Range( test_factorization[ 1 ] ), Source( test_factorization[ 2 ] ) ) then
        return [ false, "source and range of test factorization are not equal" ];
    fi;
    
    return [ true ];
  end,
  return_type := "morphism" ),

KernelObjectFunctorial := rec(
  filter_list := [ "category", "morphism", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "mu", "alphap" ],
  return_type := "morphism",
  output_source_getter_string := "KernelObject( cat, alpha )",
  output_source_getter_preconditions := [ [ "KernelObject", 1 ] ],
  output_range_getter_string := "KernelObject( cat, alphap )",
  output_range_getter_preconditions := [ [ "KernelObject", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "CokernelObjectFunctorial",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

KernelObjectFunctorialWithGivenKernelObjects := rec(
  filter_list := [ "category", "object", "morphism", "morphism", "morphism", "object" ],
  input_arguments_names := [ "cat", "P", "alpha", "mu", "alphap", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "CokernelObjectFunctorialWithGivenCokernelObjects",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

CokernelObjectFunctorial := rec(
  filter_list := [ "category", "morphism", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "mu", "alphap" ],
  return_type := "morphism",
  output_source_getter_string := "CokernelObject( cat, alpha )",
  output_source_getter_preconditions := [ [ "CokernelObject", 1 ] ],
  output_range_getter_string := "CokernelObject( cat, alphap )",
  output_range_getter_preconditions := [ [ "CokernelObject", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "KernelObjectFunctorial",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

CokernelObjectFunctorialWithGivenCokernelObjects := rec(
  filter_list := [ "category", "object", "morphism", "morphism", "morphism", "object" ],
  input_arguments_names := [ "cat", "P", "alpha", "mu", "alphap", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "KernelObjectFunctorialWithGivenKernelObjects",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

TerminalObjectFunctorial := rec(
  filter_list := [ "category" ],
  input_arguments_names := [ "cat" ],
  return_type := "morphism",
  output_source_getter_string := "TerminalObject( cat )",
  output_source_getter_preconditions := [ [ "TerminalObject", 1 ] ],
  output_range_getter_string := "TerminalObject( cat )",
  output_range_getter_preconditions := [ [ "TerminalObject", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "InitialObjectFunctorial",
  dual_arguments_reversed := true,
),

TerminalObjectFunctorialWithGivenTerminalObjects := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "P", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "InitialObjectFunctorialWithGivenInitialObjects",
  dual_arguments_reversed := true,
),

InitialObjectFunctorial := rec(
  filter_list := [ "category" ],
  input_arguments_names := [ "cat" ],
  return_type := "morphism",
  output_source_getter_string := "InitialObject( cat )",
  output_source_getter_preconditions := [ [ "InitialObject", 1 ] ],
  output_range_getter_string := "InitialObject( cat )",
  output_range_getter_preconditions := [ [ "InitialObject", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "TerminalObjectFunctorial",
  dual_arguments_reversed := true,
),

InitialObjectFunctorialWithGivenInitialObjects := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "P", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "TerminalObjectFunctorialWithGivenTerminalObjects",
  dual_arguments_reversed := true,
),

DirectProductFunctorial := rec(
  filter_list := [ "category", "list_of_objects", "list_of_morphisms", "list_of_objects" ],
  input_arguments_names := [ "cat", "objects", "L", "objectsp" ],
  return_type := "morphism",
  output_source_getter_string := "DirectProduct( cat, objects )",
  output_source_getter_preconditions := [ [ "DirectProduct", 1 ] ],
  output_range_getter_string := "DirectProduct( cat, objectsp )",
  output_range_getter_preconditions := [ [ "DirectProduct", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "CoproductFunctorial",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := true,
),

DirectProductFunctorialWithGivenDirectProducts := rec(
  filter_list := [ "category", "object", "list_of_objects", "list_of_morphisms", "list_of_objects", "object" ],
  input_arguments_names := [ "cat", "P", "objects", "L", "objectsp", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "CoproductFunctorialWithGivenCoproducts",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := true,
),

CoproductFunctorial := rec(
  filter_list := [ "category", "list_of_objects", "list_of_morphisms", "list_of_objects" ],
  input_arguments_names := [ "cat", "objects", "L", "objectsp" ],
  return_type := "morphism",
  output_source_getter_string := "Coproduct( cat, objects )",
  output_source_getter_preconditions := [ [ "Coproduct", 1 ] ],
  output_range_getter_string := "Coproduct( cat, objectsp )",
  output_range_getter_preconditions := [ [ "Coproduct", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "DirectProductFunctorial",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := true,
),

CoproductFunctorialWithGivenCoproducts := rec(
  filter_list := [ "category", "object", "list_of_objects", "list_of_morphisms", "list_of_objects", "object" ],
  input_arguments_names := [ "cat", "P", "objects", "L", "objectsp", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "DirectProductFunctorialWithGivenDirectProducts",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := true,
),

DirectSumFunctorial := rec(
  filter_list := [ "category", "list_of_objects", "list_of_morphisms", "list_of_objects" ],
  input_arguments_names := [ "cat", "objects", "L", "objectsp" ],
  return_type := "morphism",
  output_source_getter_string := "DirectSum( cat, objects )",
  output_source_getter_preconditions := [ [ "DirectSum", 1 ] ],
  output_range_getter_string := "DirectSum( cat, objectsp )",
  output_range_getter_preconditions := [ [ "DirectSum", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "DirectSumFunctorial",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := true,
),

DirectSumFunctorialWithGivenDirectSums := rec(
  filter_list := [ "category", "object", "list_of_objects", "list_of_morphisms", "list_of_objects", "object" ],
  input_arguments_names := [ "cat", "P", "objects", "L", "objectsp", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "DirectSumFunctorialWithGivenDirectSums",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := true,
),

EqualizerFunctorial := rec(
  filter_list := [ "category", "list_of_morphisms", "morphism", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "morphisms", "mu", "morphismsp" ],
  return_type := "morphism",
  output_source_getter_string := "Equalizer( cat, Source( mu ), morphisms )",
  output_source_getter_preconditions := [ [ "Equalizer", 1 ] ],
  output_range_getter_string := "Equalizer( cat, Range( mu ), morphismsp )",
  output_range_getter_preconditions := [ [ "Equalizer", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "CoequalizerFunctorial",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

EqualizerFunctorialWithGivenEqualizers := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "morphism", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "P", "morphisms", "mu", "morphismsp", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "CoequalizerFunctorialWithGivenCoequalizers",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

CoequalizerFunctorial := rec(
  filter_list := [ "category", "list_of_morphisms", "morphism", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "morphisms", "mu", "morphismsp" ],
  return_type := "morphism",
  output_source_getter_string := "Coequalizer( cat, Source( mu ), morphisms )",
  output_source_getter_preconditions := [ [ "Coequalizer", 1 ] ],
  output_range_getter_string := "Coequalizer( cat, Range( mu ), morphismsp )",
  output_range_getter_preconditions := [ [ "Coequalizer", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "EqualizerFunctorial",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

CoequalizerFunctorialWithGivenCoequalizers := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "morphism", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "P", "morphisms", "mu", "morphismsp", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "EqualizerFunctorialWithGivenEqualizers",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

FiberProductFunctorial := rec(
  filter_list := [ "category", "list_of_morphisms", "list_of_morphisms", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "morphisms", "L", "morphismsp" ],
  return_type := "morphism",
  output_source_getter_string := "FiberProduct( cat, morphisms )",
  output_source_getter_preconditions := [ [ "FiberProduct", 1 ] ],
  output_range_getter_string := "FiberProduct( cat, morphismsp )",
  output_range_getter_preconditions := [ [ "FiberProduct", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "PushoutFunctorial",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

FiberProductFunctorialWithGivenFiberProducts := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "list_of_morphisms", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "P", "morphisms", "L", "morphismsp", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "PushoutFunctorialWithGivenPushouts",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

PushoutFunctorial := rec(
  filter_list := [ "category", "list_of_morphisms", "list_of_morphisms", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "morphisms", "L", "morphismsp" ],
  return_type := "morphism",
  output_source_getter_string := "Pushout( cat, morphisms )",
  output_source_getter_preconditions := [ [ "Pushout", 1 ] ],
  output_range_getter_string := "Pushout( cat, morphismsp )",
  output_range_getter_preconditions := [ [ "Pushout", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "FiberProductFunctorial",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

PushoutFunctorialWithGivenPushouts := rec(
  filter_list := [ "category", "object", "list_of_morphisms", "list_of_morphisms", "list_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "P", "morphisms", "L", "morphismsp", "Pp" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Pp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "FiberProductFunctorialWithGivenFiberProducts",
  dual_arguments_reversed := true,
  compatible_with_congruence_of_morphisms := false,
),

ImageObjectFunctorial := rec(
  filter_list := [ "category", "morphism", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "nu", "alphap" ],
  return_type := "morphism",
  output_source_getter_string := "ImageObject( cat, alpha )",
  output_source_getter_preconditions := [ [ "ImageObject", 1 ] ],
  output_range_getter_string := "ImageObject( cat, alphap )",
  output_range_getter_preconditions := [ [ "ImageObject", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "CoimageObjectFunctorial",
  dual_arguments_reversed := true,
),

ImageObjectFunctorialWithGivenImageObjects := rec(
  filter_list := [ "category", "object", "morphism", "morphism", "morphism", "object" ],
  input_arguments_names := [ "cat", "I", "alpha", "nu", "alphap", "Ip" ],
  output_source_getter_string := "I",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Ip",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "CoimageObjectFunctorialWithGivenCoimageObjects",
  dual_arguments_reversed := true,
),

CoimageObjectFunctorial := rec(
  filter_list := [ "category", "morphism", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "mu", "alphap" ],
  return_type := "morphism",
  output_source_getter_string := "CoimageObject( cat, alpha )",
  output_source_getter_preconditions := [ [ "CoimageObject", 1 ] ],
  output_range_getter_string := "CoimageObject( cat, alphap )",
  output_range_getter_preconditions := [ [ "CoimageObject", 1 ] ],
  with_given_object_position := "both",
  dual_operation := "ImageObjectFunctorial",
  dual_arguments_reversed := true,
),

CoimageObjectFunctorialWithGivenCoimageObjects := rec(
  filter_list := [ "category", "object", "morphism", "morphism", "morphism", "object" ],
  input_arguments_names := [ "cat", "C", "alpha", "mu", "alphap", "Cp" ],
  output_source_getter_string := "C",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Cp",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "ImageObjectFunctorialWithGivenImageObjects",
  dual_arguments_reversed := true,
),

HorizontalPreCompose := rec(
  filter_list := [ "category", "twocell", "twocell" ],
  dual_operation := "HorizontalPostCompose",
  
  pre_function := function( cat, twocell_1, twocell_2 )
    
    if not IsEqualForObjects( cat, Range( Source( twocell_1 ) ), Source( Source( twocell_2 ) ) ) then
        return [ false, "2-cells are not horizontally composable" ];
    fi;
    
    return [ true ];
  end,
  return_type := "twocell" ),

HorizontalPostCompose := rec(
  filter_list := [ "category", "twocell", "twocell" ],
  dual_operation := "HorizontalPreCompose",
  
  pre_function := function( cat, twocell_2, twocell_1 )
    
    if not IsEqualForObjects( cat, Range( Source( twocell_1 ) ), Source( Source( twocell_2 ) ) ) then
        return [ false, "2-cells are not horizontally composable" ];
    fi;
    
    return [ true ];
  end,
  return_type := "twocell" ),

VerticalPreCompose := rec(
  filter_list := [ "category", "twocell", "twocell" ],
  dual_operation := "VerticalPostCompose",
  
  pre_function := function( cat, twocell_1, twocell_2 )
    
    if not IsEqualForMorphisms( Range( twocell_1 ), Source( twocell_2 ) ) then
        return [ false, "2-cells are not vertically composable" ];
    fi;
    
    return [ true ];
  end,
  return_type := "twocell" ),

VerticalPostCompose := rec(
  filter_list := [ "category", "twocell", "twocell" ],
  dual_operation := "VerticalPreCompose",
  
  pre_function := function( cat, twocell_2, twocell_1 )
    
    if not IsEqualForMorphisms( Range( twocell_1 ), Source( twocell_2 ) ) then
        return [ false, "2-cells are not vertically composable" ];
    fi;
    
    return [ true ];
  end,
  return_type := "twocell" ),

IdentityTwoCell := rec(
  filter_list := [ "category", "morphism" ],
  dual_operation := "IdentityTwoCell",
  return_type := "twocell" ),

IsWellDefinedForTwoCells := rec(
  filter_list := [ "category", "twocell" ],
  dual_operation := "IsWellDefinedForTwoCells",
  
  redirect_function := function( cat, twocell )
    
    if not( IsWellDefined( Source( twocell ) ) and IsWellDefined( Range( twocell ) ) ) then
      
      return [ true, false ];
      
    fi;
    
    return [ false ];
    
  end,
  
  return_type := "bool" ),
  
JointPairwiseDifferencesOfMorphismsIntoDirectProduct := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "A", "D" ],
  output_source_getter_string := "A",
  output_source_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "JointPairwiseDifferencesOfMorphismsFromCoproduct",
),

IsomorphismFromFiberProductToEqualizerOfDirectProductDiagram := rec(
  filter_list := [ "category", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromCoequalizerOfCoproductDiagramToPushout",
),
  
IsomorphismFromEqualizerOfDirectProductDiagramToFiberProduct := rec(
  filter_list := [ "category", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromPushoutToCoequalizerOfCoproductDiagram",
),
  
IsomorphismFromPushoutToCoequalizerOfCoproductDiagram := rec(
  filter_list := [ "category", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromEqualizerOfDirectProductDiagramToFiberProduct",
),
  
IsomorphismFromCoequalizerOfCoproductDiagramToPushout := rec(
  filter_list := [ "category", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromFiberProductToEqualizerOfDirectProductDiagram",
),

IsomorphismFromImageObjectToKernelOfCokernel := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromCokernelOfKernelToCoimage",
),

IsomorphismFromKernelOfCokernelToImageObject := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromCoimageToCokernelOfKernel",
),

IsomorphismFromCoimageToCokernelOfKernel := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromKernelOfCokernelToImageObject",
),

IsomorphismFromCokernelOfKernelToCoimage := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromImageObjectToKernelOfCokernel",
),

IsomorphismFromDirectSumToDirectProduct := rec(
  filter_list := [ "category", "list_of_objects" ],
  input_arguments_names := [ "cat", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromCoproductToDirectSum",
),

IsomorphismFromDirectSumToCoproduct := rec(
  filter_list := [ "category", "list_of_objects" ],
  input_arguments_names := [ "cat", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromDirectProductToDirectSum",
),

IsomorphismFromDirectProductToDirectSum := rec(
  filter_list := [ "category", "list_of_objects" ],
  input_arguments_names := [ "cat", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromDirectSumToCoproduct",
),

IsomorphismFromCoproductToDirectSum := rec(
  filter_list := [ "category", "list_of_objects" ],
  input_arguments_names := [ "cat", "D" ],
  return_type := "morphism",
  dual_operation := "IsomorphismFromDirectSumToDirectProduct",
),

JointPairwiseDifferencesOfMorphismsFromCoproduct := rec(
  filter_list := [ "category", "object", "list_of_morphisms" ],
  input_arguments_names := [ "cat", "A", "D" ],
  output_range_getter_string := "A",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "JointPairwiseDifferencesOfMorphismsIntoDirectProduct",
),

SomeProjectiveObject := rec(
  filter_list := [ "category", "object" ],
  return_type := "object",
  dual_operation := "SomeInjectiveObject",
  is_merely_set_theoretic := true ),

EpimorphismFromSomeProjectiveObject := rec(
  filter_list := [ "category", "object" ],
  input_arguments_names := [ "cat", "A" ],
  output_range_getter_string := "A",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  return_type := "morphism",
  dual_operation := "MonomorphismIntoSomeInjectiveObject",
  is_merely_set_theoretic := true ),

EpimorphismFromSomeProjectiveObjectWithGivenSomeProjectiveObject := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "A", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "A",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "MonomorphismIntoSomeInjectiveObjectWithGivenSomeInjectiveObject",
  is_merely_set_theoretic := true ),

SomeInjectiveObject := rec(
  filter_list := [ "category", "object" ],
  return_type := "object",
  dual_operation := "SomeProjectiveObject",
  is_merely_set_theoretic := true ),

MonomorphismIntoSomeInjectiveObject := rec(
  filter_list := [ "category", "object" ],
  input_arguments_names := [ "cat", "A" ],
  output_source_getter_string := "A",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  return_type := "morphism",
  dual_operation := "EpimorphismFromSomeProjectiveObject",
  is_merely_set_theoretic := true ),

MonomorphismIntoSomeInjectiveObjectWithGivenSomeInjectiveObject := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "A", "I" ],
  output_source_getter_string := "A",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "I",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "EpimorphismFromSomeProjectiveObjectWithGivenSomeProjectiveObject",
  is_merely_set_theoretic := true ),

ComponentOfMorphismIntoDirectSum := rec(
  filter_list := [ "category", "morphism", "list_of_objects", "integer" ],
  input_arguments_names := [ "cat", "alpha", "S", "i" ],
  output_source_getter_string := "Source( alpha )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "S[i]",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "ComponentOfMorphismFromDirectSum" ),

ComponentOfMorphismFromDirectSum := rec(
  filter_list := [ "category", "morphism", "list_of_objects", "integer" ],
  input_arguments_names := [ "cat", "alpha", "S", "i" ],
  output_source_getter_string := "S[i]",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( alpha )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "ComponentOfMorphismIntoDirectSum" ),

MorphismBetweenDirectSums := rec(
  filter_list := [ "category", "list_of_objects", "list_of_lists_of_morphisms", "list_of_objects" ],
  input_arguments_names := [ "cat", "source_diagram", "mat", "range_diagram" ],
  return_type := "morphism",
  output_source_getter_string := "DirectSum( cat, source_diagram )",
  output_source_getter_preconditions := [ [ "DirectSum", 1 ] ],
  output_range_getter_string := "DirectSum( cat, range_diagram )",
  output_range_getter_preconditions := [ [ "DirectSum", 1 ] ],
  with_given_object_position := "both",
  pre_function := function( cat, source_diagram, listlist, range_diagram )
    local i, j;
      
      if Length( listlist ) <> Length( source_diagram ) then
          
          return [ false, "the number of rows does not match the length of the source diagram" ];
          
      fi;
      
      for i in [ 1 .. Length( listlist ) ] do
          
          if Length( listlist[i] ) <> Length( range_diagram ) then
              
              return [ false, Concatenation( "the ", String(i), ". row has not the same length as the range diagram" ) ];
              
          fi;
          
          for j in [ 1 .. Length( range_diagram ) ] do
              
              if not IsEqualForObjects( cat, source_diagram[i], Source( listlist[i][j] ) ) then
                  
                  return [ false, Concatenation( "the sources of the morphisms in the ", String(i), ". row must be equal to the ", String(i), ". entry of the source diagram" ) ];
                  
              fi;
              
              if not IsEqualForObjects( cat, range_diagram[j], Range( listlist[i][j] ) ) then
                  
                  return [ false, Concatenation( "the ranges of the morphisms in the ", String(j), ". column must be equal to the ", String(j), ". entry of the range diagram" ) ];
                  
              fi;
              
          od;
          
      od;
      
      return [ true ];
      
  end,
  dual_operation := "MorphismBetweenDirectSums",
  dual_preprocessor_func := function( arg )
      local list;
      list := CAP_INTERNAL_OPPOSITE_RECURSIVE( arg );
      
      return NTuple( 4, list[1], list[4], TransposedMatWithGivenDimensions( Length( list[2] ), Length( list[4] ), list[3] ), list[2] );
  end
),

MorphismBetweenDirectSumsWithGivenDirectSums := rec(
  filter_list := [ "category", "object", "list_of_objects", "list_of_lists_of_morphisms", "list_of_objects", "object" ],
  input_arguments_names := [ "cat", "S", "source_diagram", "mat", "range_diagram", "T" ],
  output_source_getter_string := "S",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "T",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "MorphismBetweenDirectSumsWithGivenDirectSums",
  dual_preprocessor_func := function( arg )
      local list;
      list := CAP_INTERNAL_OPPOSITE_RECURSIVE( arg );
      return NTuple( 6, list[1], list[6], list[5], TransposedMatWithGivenDimensions( Length( list[3] ), Length( list[5] ), list[4] ), list[3], list[2] );
  end
),

IsHomSetInhabited := rec(
  filter_list := [ "category", "object", "object" ],
  return_type := "bool",
  dual_operation := "IsHomSetInhabited",
  dual_arguments_reversed := true,
),

HomomorphismStructureOnObjects := rec(
  filter_list := [ "category", "object", "object" ],
  return_type := "object_in_range_category_of_homomorphism_structure",
  dual_operation := "HomomorphismStructureOnObjects",
  dual_arguments_reversed := true,
  dual_postprocessor_func := IdFunc
),

HomomorphismStructureOnMorphisms := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "beta" ],
  output_source_getter_string := "HomomorphismStructureOnObjects( cat, Range( alpha ), Source( beta ) )",
  output_source_getter_preconditions := [ [ "HomomorphismStructureOnObjects", 1 ] ],
  output_range_getter_string := "HomomorphismStructureOnObjects( cat, Source( alpha ), Range( beta ) )",
  output_range_getter_preconditions := [ [ "HomomorphismStructureOnObjects", 1 ] ],
  with_given_object_position := "both",
  return_type := "morphism_in_range_category_of_homomorphism_structure",
  dual_operation := "HomomorphismStructureOnMorphisms",
  dual_preprocessor_func := function( cat, alpha, beta )
    return Triple( OppositeCategory( cat ), Opposite( beta ), Opposite( alpha ) );
  end,
  dual_postprocessor_func := IdFunc,
),

HomomorphismStructureOnMorphismsWithGivenObjects := rec(
  filter_list := [ "category", "object_in_range_category_of_homomorphism_structure", "morphism", "morphism", "object_in_range_category_of_homomorphism_structure" ],
  input_arguments_names := [ "cat", "source", "alpha", "beta", "range" ],
  output_source_getter_string := "source",
  output_range_getter_string := "range",
  return_type := "morphism_in_range_category_of_homomorphism_structure",
  dual_operation := "HomomorphismStructureOnMorphismsWithGivenObjects",
  dual_preprocessor_func := function( cat, source, alpha, beta, range )
    return NTuple( 5, OppositeCategory( cat ), source, Opposite( beta ), Opposite( alpha ), range );
  end,
  dual_postprocessor_func := IdFunc,
),

DistinguishedObjectOfHomomorphismStructure := rec(
  filter_list := [ "category" ],
  return_type := "object_in_range_category_of_homomorphism_structure",
  dual_operation := "DistinguishedObjectOfHomomorphismStructure",
  dual_postprocessor_func := IdFunc ),

InterpretMorphismAsMorphismFromDistinguishedObjectToHomomorphismStructure := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  output_source_getter_string := "DistinguishedObjectOfHomomorphismStructure( cat )",
  output_source_getter_preconditions := [ [ "DistinguishedObjectOfHomomorphismStructure", 1 ] ],
  output_range_getter_string := "HomomorphismStructureOnObjects( cat, Source( alpha ), Range( alpha ) )",
  output_range_getter_preconditions := [ [ "HomomorphismStructureOnObjects", 1 ] ],
  with_given_object_position := "both",
  return_type := "morphism_in_range_category_of_homomorphism_structure",
  dual_operation := "InterpretMorphismAsMorphismFromDistinguishedObjectToHomomorphismStructure",
  dual_postprocessor_func := IdFunc
),

InterpretMorphismAsMorphismFromDistinguishedObjectToHomomorphismStructureWithGivenObjects := rec(
  filter_list := [ "category", "object_in_range_category_of_homomorphism_structure", "morphism", "object_in_range_category_of_homomorphism_structure" ],
  input_arguments_names := [ "cat", "source", "alpha", "range" ],
  return_type := "morphism_in_range_category_of_homomorphism_structure",
  output_source_getter_string := "source",
  output_range_getter_string := "range",
  dual_operation := "InterpretMorphismAsMorphismFromDistinguishedObjectToHomomorphismStructureWithGivenObjects",
  dual_preprocessor_func := function( cat, distinguished_object, alpha, hom_source_range )
    return NTuple( 4, OppositeCategory( cat ), distinguished_object, Opposite( alpha ), hom_source_range );
  end,
  dual_postprocessor_func := IdFunc
),

InterpretMorphismFromDistinguishedObjectToHomomorphismStructureAsMorphism := rec(
  filter_list := [ "category", "object", "object", "morphism_in_range_category_of_homomorphism_structure" ],
  input_arguments_names := [ "cat", "source", "range", "alpha" ],
  return_type := "morphism",
  output_source_getter_string := "source",
  output_range_getter_string := "range",
  dual_operation := "InterpretMorphismFromDistinguishedObjectToHomomorphismStructureAsMorphism",
  dual_preprocessor_func := function( cat, A, B, morphism )
    return NTuple( 4, OppositeCategory( cat ), Opposite( B ), Opposite( A ), morphism );
  end
),

SolveLinearSystemInAbCategory := rec(
  filter_list := [ "category", "list_of_lists_of_morphisms", "list_of_lists_of_morphisms", "list_of_morphisms" ],
  return_type := "list_of_morphisms",
  pre_function := function( cat, left_coeffs, right_coeffs, rhs )
    
    if not Length( left_coeffs ) > 0 then
        return [ false, "the list of left coefficients is empty" ];
    fi;
    
    if not Length( left_coeffs ) = Length( right_coeffs ) then
        return [ false, "the list of left coefficients and the list of right coefficients do not have the same length" ];
    fi;
    
    if not Length( left_coeffs ) = Length( rhs ) then
        return [ false, "the list of left coefficients does not have the same length as the right hand side" ];
    fi;
    
    if not ForAll( Concatenation( left_coeffs, right_coeffs ), x -> IsList( x ) and Length( x ) = Length( left_coeffs[1] ) ) then
        return [ false, "the left coefficients and the right coefficients must be given by lists of lists of the same length containing morphisms in the current category" ];
    fi;
    
    return [ true ];
    
  end,
  pre_function_full := function( cat, left_coeffs, right_coeffs, rhs )
    local nr_columns_left, nr_columns_right;
    
    if not ForAll( [ 1 .. Length( left_coeffs ) ], i -> ForAll( left_coeffs[i], coeff -> IsEqualForObjects( cat, Source( coeff ), Source( rhs[i] ) ) <> false ) ) then
        return [ false, "the sources of the left coefficients must correspond to the sources of the right hand side" ];
    fi;
    
    if not ForAll( [ 1 .. Length( right_coeffs ) ], i -> ForAll( right_coeffs[i], coeff -> IsEqualForObjects( cat, Range( coeff ), Range( rhs[i] ) ) <> false ) ) then
        return [ false, "the ranges of the right coefficients must correspond to the ranges of the right hand side" ];
    fi;
    
    nr_columns_left := Length( left_coeffs[1] );
    
    if not ForAll( [ 1 .. nr_columns_left ], j -> ForAll( left_coeffs, x -> IsEqualForObjects( cat, Range( x[j] ), Range( left_coeffs[1][j] ) ) <> false ) ) then
        return [ false, "all ranges in a column of the left coefficients must be equal" ];
    fi;
    
    nr_columns_right := Length( right_coeffs[1] );
    
    if not ForAll( [ 1 .. nr_columns_right ], j -> ForAll( right_coeffs, x -> IsEqualForObjects( cat, Source( x[j] ), Source( right_coeffs[1][j] ) ) <> false ) ) then
        return [ false, "all sources in a column of the right coefficients must be equal" ];
    fi;
    
    return [ true ];
    
  end,
),

MereExistenceOfSolutionOfLinearSystemInAbCategory := rec(
  filter_list := [ "category", "list_of_lists_of_morphisms", "list_of_lists_of_morphisms", "list_of_morphisms" ],
  return_type := "bool",
  pre_function := "SolveLinearSystemInAbCategory",
  pre_function_full := "SolveLinearSystemInAbCategory"
),

MereExistenceOfUniqueSolutionOfLinearSystemInAbCategory := rec(
  filter_list := [ "category", "list_of_lists_of_morphisms", "list_of_lists_of_morphisms", "list_of_morphisms" ],
  return_type := "bool",
  pre_function := "SolveLinearSystemInAbCategory",
  pre_function_full := "SolveLinearSystemInAbCategory"
),

MereExistenceOfUniqueSolutionOfHomogeneousLinearSystemInAbCategory := rec(
  filter_list := [ "category", "list_of_lists_of_morphisms", "list_of_lists_of_morphisms" ],
  return_type := "bool",
  pre_function := "BasisOfSolutionsOfHomogeneousLinearSystemInLinearCategory",
  pre_function_full := "BasisOfSolutionsOfHomogeneousLinearSystemInLinearCategory"
),

BasisOfSolutionsOfHomogeneousLinearSystemInLinearCategory := rec(
  filter_list := [ "category", "list_of_lists_of_morphisms", "list_of_lists_of_morphisms" ],
  return_type := "list_of_lists_of_morphisms",
  pre_function := function( cat, left_coeffs, right_coeffs )

    if not Length( left_coeffs ) > 0 then
        return [ false, "the list of left coefficients is empty" ];
    fi;

    if not Length( left_coeffs ) = Length( right_coeffs ) then
        return [ false, "the list of left coefficients and the list of right coefficients do not have the same length" ];
    fi;

    if not ForAll( Concatenation( left_coeffs, right_coeffs ), x -> IsList( x ) and Length( x ) = Length( left_coeffs[1] ) ) then
        return [ false, "the left coefficients and the right coefficients must be given by lists of lists of morphisms of the same length" ];
    fi;

    return [ true ];

  end,
  pre_function_full := function( cat, left_coeffs, right_coeffs )
    local nr_columns_left, nr_columns_right;

    nr_columns_left := Length( left_coeffs[1] );

    if not ForAll( [ 1 .. nr_columns_left ],
            j -> ForAll( left_coeffs, x -> IsEqualForObjects( cat, Target( x[j] ), Target( left_coeffs[1][j] ) ) <> false ) ) then
        return [ false, "all targets in any column of the left coefficients must be equal" ];
    fi;

    nr_columns_right := Length( right_coeffs[1] );

    if not ForAll( [ 1 .. nr_columns_right ],
            j -> ForAll( right_coeffs, x -> IsEqualForObjects( cat, Source( x[j] ), Source( right_coeffs[1][j] ) ) <> false ) ) then
        return [ false, "all sources in any column of the right coefficients must be equal" ];
    fi;

    return [ true ];

  end,
),

BasisOfSolutionsOfHomogeneousDoubleLinearSystemInLinearCategory := rec(
  filter_list := [ "category", "list_of_lists_of_morphisms", "list_of_lists_of_morphisms", "list_of_lists_of_morphisms", "list_of_lists_of_morphisms" ],
  return_type := "list_of_lists_of_morphisms",
),

MorphismsOfExternalHom := rec(
  filter_list := [ "category", "object", "object" ],
  return_type := "list_of_morphisms",
  dual_operation := "MorphismsOfExternalHom",
  dual_arguments_reversed := true
),

BasisOfExternalHom := rec(
  filter_list := [ "category", "object", "object" ],
  return_type := "list_of_morphisms",
  dual_operation := "BasisOfExternalHom",
  dual_arguments_reversed := true
),

CoefficientsOfMorphism := rec(
  filter_list := [ "category", "morphism" ],
  return_type := "list_of_elements_of_commutative_ring_of_linear_structure",
  dual_operation := "CoefficientsOfMorphism",
  dual_postprocessor_func := IdFunc
),

RandomObjectByInteger := rec(
  filter_list := [ "category", "integer" ],
  input_arguments_names := [ "cat", "n" ],
  return_type := "object",
  dual_operation := "RandomObjectByInteger",
),

RandomMorphismByInteger := rec(
  filter_list := [ "category", "integer" ],
  input_arguments_names := [ "cat", "n" ],
  return_type := "morphism",
  dual_operation := "RandomMorphismByInteger",
),

RandomMorphismWithFixedSourceByInteger := rec(
  filter_list := [ "category", "object", "integer" ],
  input_arguments_names := [ "cat", "A", "n" ],
  output_source_getter_string := "A",
  output_source_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "RandomMorphismWithFixedRangeByInteger",
),

RandomMorphismWithFixedRangeByInteger := rec(
  filter_list := [ "category", "object", "integer" ],
  input_arguments_names := [ "cat", "B", "n" ],
  output_range_getter_string := "B",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "RandomMorphismWithFixedSourceByInteger",
),

RandomMorphismWithFixedSourceAndRangeByInteger := rec(
  filter_list := [ "category", "object", "object", "integer" ],
  input_arguments_names := [ "cat", "A", "B", "n" ],
  output_source_getter_string := "A",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "B",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "RandomMorphismWithFixedSourceAndRangeByInteger",
  dual_preprocessor_func := function( cat, A, B, n )
      return NTuple( 4, OppositeCategory( cat ), Opposite( B ), Opposite( A ), n );
  end
),

RandomObjectByList := rec(
  filter_list := [ "category", "arbitrary_list" ],
  input_arguments_names := [ "cat", "L" ],
  return_type := "object"
),

RandomMorphismByList := rec(
  filter_list := [ "category", "arbitrary_list" ],
  input_arguments_names := [ "cat", "L" ],
  return_type := "morphism"
),

RandomMorphismWithFixedSourceByList := rec(
  filter_list := [ "category", "object", "arbitrary_list" ],
  input_arguments_names := [ "cat", "A", "L" ],
  output_source_getter_string := "A",
  output_source_getter_preconditions := [ ],
  return_type := "morphism",
),

RandomMorphismWithFixedRangeByList := rec(
  filter_list := [ "category", "object", "arbitrary_list" ],
  input_arguments_names := [ "cat", "B", "L" ],
  output_range_getter_string := "B",
  output_range_getter_preconditions := [ ],
  return_type := "morphism"
),

RandomMorphismWithFixedSourceAndRangeByList := rec(
  filter_list := [ "category", "object", "object", "arbitrary_list" ],
  input_arguments_names := [ "cat", "A", "B", "L" ],
  output_source_getter_string := "A",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "B",
  output_range_getter_preconditions := [ ],
  return_type := "morphism"
),

HomologyObject := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "beta" ],
  return_type := "object",
  pre_function := function( cat, alpha, beta )
      if not IsEqualForObjects( cat, Range( alpha ), Source( beta ) ) then
            
            return [ false, "the range of the first morphism has to be equal to the source of the second morphism" ];
            
      fi;
      
      return [ true ];
      
  end,
  dual_operation := "HomologyObject",
  dual_arguments_reversed := true
),

HomologyObjectFunctorialWithGivenHomologyObjects := rec(
  filter_list := [ "category", "object", "5_tuple_of_morphisms", "object" ],
  input_arguments_names := [ "cat", "H_1", "L", "H_2" ],
  return_type := "morphism",
  pre_function := function( cat, H_1, L, H2 )
      local alpha, beta, epsilon, gamma, delta;
      
      alpha := L[1];
      
      beta := L[2];
      
      epsilon := L[3];
      
      gamma := L[4];
      
      delta := L[5];
      
      if not IsEqualForObjects( cat, Range( alpha ), Source( beta ) ) then
            
            return [ false, "the range of the first morphism has to be equal to the source of the second morphism" ];
            
      fi;
      
      if not IsEqualForObjects( cat, Range( gamma ), Source( delta ) ) then
            
            return [ false, "the range of the fourth morphism has to be equal to the source of the fifth morphism" ];
            
      fi;
      
      if not IsEqualForObjects( cat, Source( epsilon ), Source( beta ) ) then
            
            return [ false, "the source of the third morphism has to be equal to the source of the second morphism" ];
            
      fi;
      
      if not IsEqualForObjects( cat, Range( epsilon ), Range( gamma ) ) then
            
            return [ false, "the range of the third morphism has to be equal to the range of the fourth morphism" ];
            
      fi;
      
      return [ true ];
      
  end,
  dual_operation := "HomologyObjectFunctorialWithGivenHomologyObjects",
  dual_preprocessor_func := function( arg )
      local list;
      list := CAP_INTERNAL_OPPOSITE_RECURSIVE( arg );
      return NTuple( 4, list[1], list[4], Reversed( list[3] ), list[2] );
  end
),

IsomorphismFromHomologyObjectToItsConstructionAsAnImageObject := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "beta" ],
  return_type := "morphism" ),

IsomorphismFromItsConstructionAsAnImageObjectToHomologyObject := rec(
  filter_list := [ "category", "morphism", "morphism" ],
  input_arguments_names := [ "cat", "alpha", "beta" ],
  return_type := "morphism" ),
  
## SimplifyObject*
SimplifyObject := rec(
  filter_list := [ "category", "object", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "A", "n" ],
  return_type := "object",
  dual_operation := "SimplifyObject",
  redirect_function := function( cat, A, n )
    
    if n = 0 then
        return [ true, A ];
    fi;
    
    return [ false ];
    
  end,
  pre_function := function( cat, A, n )
    
    if not ( IsPosInt( n ) or IsInfinity( n ) ) then
        return [ false, "the second argument must be a non-negative integer or infinity" ];
    fi;
    
    return [ true ];
    
  end 
  ),

SimplifyObject_IsoFromInputObject := rec(
  filter_list := [ "category", "object", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "A", "n" ],
  output_source_getter_string := "A",
  output_source_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifyObject_IsoToInputObject",
  redirect_function := function( cat, A, n )
    
    if n = 0 then
        return [ true, IdentityMorphism( A ) ];
    fi;
    
    return [ false ];
    
  end,
  pre_function := "SimplifyObject"
  ),

SimplifyObject_IsoToInputObject := rec(
  filter_list := [ "category", "object", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "A", "n" ],
  output_range_getter_string := "A",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifyObject_IsoFromInputObject",
  redirect_function := "SimplifyObject_IsoFromInputObject",
  pre_function := "SimplifyObject"
  ),

## SimplifyMorphism
SimplifyMorphism := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_source_getter_string := "Source( mor )",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "Range( mor )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifyMorphism",
  redirect_function := "SimplifyObject",
  pre_function := "SimplifyObject"
  ),

## SimplifySource*
SimplifySource := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_range_getter_string := "Range( mor )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifyRange",
  redirect_function := "SimplifyObject",
  pre_function := "SimplifyObject"
  ),

SimplifySource_IsoToInputObject := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_range_getter_string := "Source( mor )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifyRange_IsoFromInputObject",
  redirect_function := function( cat, alpha, n )
    
    if n = 0 then
        return [ true, IdentityMorphism( Source( alpha ) ) ];
    fi;
    
    return [ false ];
    
  end,
  pre_function := "SimplifyObject"
  ),
  
SimplifySource_IsoFromInputObject := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_source_getter_string := "Source( mor )",
  output_source_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifyRange_IsoToInputObject",
  redirect_function := "SimplifySource_IsoToInputObject",
  pre_function := "SimplifyObject"
  ),

## SimplifyRange*
SimplifyRange := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_source_getter_string := "Source( mor )",
  output_source_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifySource",
  redirect_function := "SimplifyObject",
  pre_function := "SimplifyObject"
  ),

SimplifyRange_IsoToInputObject := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_range_getter_string := "Range( mor )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifySource_IsoFromInputObject",
  redirect_function := function( cat, alpha, n )
    
    if n = 0 then
        return [ true, IdentityMorphism( Range( alpha ) ) ];
    fi;
    
    return [ false ];
    
  end,
  pre_function := "SimplifyObject"
  ),
  
SimplifyRange_IsoFromInputObject := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_source_getter_string := "Range( mor )",
  output_source_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifySource_IsoToInputObject",
  redirect_function := "SimplifySource_IsoToInputObject",
  pre_function := "SimplifyObject"
  ),

## SimplifySourceAndRange*
SimplifySourceAndRange := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  return_type := "morphism",
  dual_operation := "SimplifySourceAndRange",
  redirect_function := "SimplifyObject",
  pre_function := "SimplifyObject"
  ),

SimplifySourceAndRange_IsoToInputSource := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_range_getter_string := "Source( mor )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifySourceAndRange_IsoFromInputRange",
  redirect_function := "SimplifySource_IsoToInputObject",
  pre_function := "SimplifyObject"
  ),
  
SimplifySourceAndRange_IsoFromInputSource := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_source_getter_string := "Source( mor )",
  output_source_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifySourceAndRange_IsoToInputRange",
  redirect_function := "SimplifySource_IsoToInputObject",
  pre_function := "SimplifyObject"
  ),

SimplifySourceAndRange_IsoToInputRange := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_range_getter_string := "Range( mor )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifySourceAndRange_IsoFromInputSource",
  redirect_function := "SimplifySource_IsoToInputObject",
  pre_function := "SimplifyObject"
  ),
  
SimplifySourceAndRange_IsoFromInputRange := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_source_getter_string := "Range( mor )",
  output_source_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifySourceAndRange_IsoToInputSource",
  redirect_function := "SimplifySource_IsoToInputObject",
  pre_function := "SimplifyObject"
  ),

## SimplifyEndo*
SimplifyEndo := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  return_type := "morphism",
  dual_operation := "SimplifyEndo",
  redirect_function := "SimplifyObject",
  pre_function := function( cat, endo, n )
    
    if not ( IsPosInt( n ) or IsInfinity( n ) ) then
        return [ false, "the second argument must be a non-negative integer or infinity" ];
    fi;
    
    if not IsEndomorphism( endo ) then
        return [ false, "the first argument must be an endomorphism" ];
    fi;
    
    return [ true ];
    
  end 
  ),

SimplifyEndo_IsoFromInputObject := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_source_getter_string := "Source( mor )",
  output_source_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifyEndo_IsoToInputObject",
  redirect_function := "SimplifySource_IsoToInputObject",
  pre_function := "SimplifyEndo"
  ),

SimplifyEndo_IsoToInputObject := rec(
  filter_list := [ "category", "morphism", "nonneg_integer_or_infinity" ],
  input_arguments_names := [ "cat", "mor", "n" ],
  output_range_getter_string := "Range( mor )",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "SimplifyEndo_IsoFromInputObject",
  redirect_function := "SimplifySource_IsoToInputObject",
  pre_function := "SimplifyEndo"
  ),

SomeReductionBySplitEpiSummand := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  return_type := "morphism",
  ),

SomeReductionBySplitEpiSummand_MorphismToInputRange := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  return_type := "morphism",
  ),

SomeReductionBySplitEpiSummand_MorphismFromInputRange := rec(
  filter_list := [ "category", "morphism" ],
  input_arguments_names := [ "cat", "alpha" ],
  return_type := "morphism",
  ),

ProjectiveDimension := rec(
  filter_list := [ "category", "object" ],
  return_type := "nonneg_integer_or_infinity",
  dual_operation := "InjectiveDimension",
  ),

InjectiveDimension := rec(
  filter_list := [ "category", "object" ],
  return_type := "nonneg_integer_or_infinity",
  dual_operation := "ProjectiveDimension",
  ),

AdditiveGenerators := rec(
  filter_list := [ "category" ],
  return_type := "list_of_objects",
  dual_operation := "AdditiveGenerators",
),

IndecomposableProjectiveObjects := rec(
  filter_list := [ "category" ],
  return_type := "list_of_objects",
  dual_operation := "IndecomposableInjectiveObjects",
),

IndecomposableInjectiveObjects := rec(
  filter_list := [ "category" ],
  return_type := "list_of_objects",
  dual_operation := "IndecomposableProjectiveObjects",
),

ProjectiveCoverObject := rec(
  filter_list := [ "category", "object" ],
  return_type := "object",
  dual_operation := "InjectiveEnvelopeObject",
  is_merely_set_theoretic := true ),

EpimorphismFromProjectiveCoverObject := rec(
  filter_list := [ "category", "object" ],
  input_arguments_names := [ "cat", "A" ],
  output_range_getter_string := "A",
  output_range_getter_preconditions := [ ],
  with_given_object_position := "Source",
  return_type := "morphism",
  dual_operation := "MonomorphismIntoInjectiveEnvelopeObject",
  is_merely_set_theoretic := true ),

EpimorphismFromProjectiveCoverObjectWithGivenProjectiveCoverObject := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "A", "P" ],
  output_source_getter_string := "P",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "A",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "MonomorphismIntoInjectiveEnvelopeObjectWithGivenInjectiveEnvelopeObject",
  is_merely_set_theoretic := true ),

InjectiveEnvelopeObject := rec(
  filter_list := [ "category", "object" ],
  return_type := "object",
  dual_operation := "ProjectiveCoverObject",
  is_merely_set_theoretic := true ),

MonomorphismIntoInjectiveEnvelopeObject := rec(
  filter_list := [ "category", "object" ],
  input_arguments_names := [ "cat", "A" ],
  output_source_getter_string := "A",
  output_source_getter_preconditions := [ ],
  with_given_object_position := "Range",
  return_type := "morphism",
  dual_operation := "EpimorphismFromProjectiveCoverObject",
  is_merely_set_theoretic := true ),

MonomorphismIntoInjectiveEnvelopeObjectWithGivenInjectiveEnvelopeObject := rec(
  filter_list := [ "category", "object", "object" ],
  input_arguments_names := [ "cat", "A", "I" ],
  output_source_getter_string := "A",
  output_source_getter_preconditions := [ ],
  output_range_getter_string := "I",
  output_range_getter_preconditions := [ ],
  return_type := "morphism",
  dual_operation := "EpimorphismFromProjectiveCoverObjectWithGivenProjectiveCoverObject",
  is_merely_set_theoretic := true ),

) );

BindGlobal( "CAP_INTERNAL_METHOD_NAME_RECORD_LIMITS", [
rec(
  object_specification := [ "varobject" ],
  morphism_specification := [  ],
  limit_object_name := "DirectProduct",
  colimit_object_name := "Coproduct",
),

rec(
  object_specification := [ "varobject" ],
  morphism_specification := [  ],
  limit_object_name := "DirectSum",
  colimit_object_name := "DirectSum",
),

rec(
  object_specification := [ "fixedobject", "varobject" ],
  morphism_specification := [ [ 2, "varmorphism", 1 ] ],
  limit_object_name := "FiberProduct",
  colimit_object_name := "Pushout",
),

rec(
  object_specification := [ "fixedobject", "fixedobject" ],
  morphism_specification := [ [ 1, "varmorphism", 2 ] ],
  limit_object_name := "Equalizer",
  limit_projection_name := "EmbeddingOfEqualizer",
  colimit_object_name := "Coequalizer",
  colimit_injection_name := "ProjectionOntoCoequalizer",
),

rec(
  object_specification := [ "fixedobject", "fixedobject" ],
  morphism_specification := [ [ 1, "fixedmorphism", 2 ], [ 1, "zeromorphism", 2 ] ],
  limit_object_name := "KernelObject",
  limit_projection_name := "KernelEmbedding",
  limit_universal_morphism_name := "KernelLift",
  colimit_object_name := "CokernelObject",
  colimit_injection_name := "CokernelProjection",
  colimit_universal_morphism_name := "CokernelColift",
),

rec(
  object_specification := [ ],
  morphism_specification := [ ],
  limit_object_name := "TerminalObject",
  colimit_object_name := "InitialObject",
),

rec(
  object_specification := [ ],
  morphism_specification := [ ],
  limit_object_name := "ZeroObject",
  colimit_object_name := "ZeroObject",
)

] );

CAP_INTERNAL_ENHANCE_NAME_RECORD_LIMITS( CAP_INTERNAL_METHOD_NAME_RECORD_LIMITS );

CAP_INTERNAL_VALIDATE_LIMITS_IN_NAME_RECORD( CAP_INTERNAL_CORE_METHOD_NAME_RECORD, CAP_INTERNAL_METHOD_NAME_RECORD_LIMITS );

CAP_INTERNAL_ENHANCE_NAME_RECORD( CAP_INTERNAL_CORE_METHOD_NAME_RECORD );

CAP_INTERNAL_GENERATE_DECLARATIONS_AND_INSTALLATIONS_FROM_METHOD_NAME_RECORD(
    CAP_INTERNAL_CORE_METHOD_NAME_RECORD,
    "CAP",
    "MethodRecord",
    "Add Functions",
    "Available Add functions"
);

CAP_INTERNAL_REGISTER_METHOD_NAME_RECORD_OF_PACKAGE( CAP_INTERNAL_CORE_METHOD_NAME_RECORD, "CAP" );

#= comment for Julia
CAP_INTERNAL_GENERATE_CONVENIENCE_METHODS_FOR_LIMITS( "CAP", CAP_INTERNAL_CORE_METHOD_NAME_RECORD, CAP_INTERNAL_METHOD_NAME_RECORD_LIMITS );
# =#

CAP_INTERNAL_INSTALL_ADDS_FROM_RECORD( CAP_INTERNAL_CORE_METHOD_NAME_RECORD );

[Verzeichnis aufwärts0.66unsichere VerbindungÜbersetzung europäischer Sprachen durch Browser2026-04-26]