Domain is GAP's name for structured sets. The ring of Gaussian integers Z[i] is an example of a domain, the group D12 of symmetries of a regular hexahedron is another.
The GAP library predefines some domains.
For example the ring of Gaussian integers is predefined as
GaussianIntegers
(see Gaussians) and the field of rationals
is predefined as Rationals
(see Rational Numbers).
Most domains are constructed by functions,
which are called domain constructors (see Constructing Domains).
For example the group D12 is constructed by the construction
Group( (1,2,3,4,5,6), (2,6)(3,5) )
(see Group)
and the finite field with 16 elements is constructed by
GaloisField( 16 )
(see GaloisField).
The first place where you need domains in GAP is the obvious one.
Sometimes you simply want to deal with a domain.
For example if you want to compute the size of the group D12,
you had better be able to represent this group in a way that the
Size
function can understand.
The second place where you need domains in GAP is when you want to
be able to specify that an operation or computation takes place in a
certain domain.
For example suppose you want to factor 10 in the ring of Gaussian
integers.
Saying Factors( 10 )
will not do, because this will return the
factorization [ 2, 5 ]
in the ring of integers.
To allow operations and computations to happen in a specific domain,
Factors
, and many other functions as well, accept this domain as
optional first argument.
Thus Factors( GaussianIntegers, 10 )
yields the desired result
[ 1+E(4), 1-E(4), 2+E(4), 2-E(4) ]
.
(The imaginary unit exp( 2 πi/4 ) is written as E(4)
in GAP.)
The most important facts about domains are stated in Chapter Domains of the GAP Tutorial.
There are only few operations especially for domains
(see Operations for Domains),
operations such as Intersection
and Random
are defined for the more
general situation of collections (see Chapter Collections).
Domains have an operational structure, that is, a collection of operations under which the domain is closed. For example, a group is closed under multiplication, taking the zeroth power of elements, and taking inverses of elements. The operational structure may be empty, examples of domains without additional structure are the underlying relations of general mappings (see Properties and Attributes of (General) Mappings).
The operations under which a domain is closed are a subset of the operations that the elements of a domain admit. It is possible that the elements admit more operations. For example, matrices can be multiplied and added. But addition plays no role in a group of matrices, and multiplication plays no role in a vector space of matrices. In particular, a matrix group is not closed under addition.
Note that the elements of a domain exist independently of this domain, usually they existed already before the domain was created. So it makes sense to say that a domain is generated by some elements with respect to certain operations.
Of course, different sets of operations yield different notions of generation. For example, the group generated by some matrices is different from the ring generated by these matrices, and these two will in general be different from the vector space generated by the same matrices, over a suitable field.
The other way round, the same set of elements may be obtained by generation w.r.t. different notions of generation. For example, one can get the group generated by two elements g and h also as the monoid generated by the elements g, g−1, h, h−1; if both g and h have finite order then of course the group generated by g and h coincides with the monoid generated by g and h.
Additionally to the operational structure, a domain can have properties. For example, the multiplication of a group is associative, and the multiplication in a field is commutative.
Note that associativity and commutativity depend on the set of elements for which one considers the multiplication, i.e., it depends on the domain. For example, the multiplication in a full matrix ring over a field is not commutative, whereas its restriction to the set of diagonal matrices is commutative.
One important difference between the operational structure and the properties of a domain is that the operational structure is fixed when the domain is constructed, whereas properties can be discovered later. For example, take a domain whose operational structure is given by closure under multiplication. If it is discovered that the inverses of all its elements also do (by chance) lie in this domain, being closed under taking inverses is not added to the operational structure. But a domain with operational structure of multiplication, taking the identity, and taking inverses will be treated as a group as soon as the multiplication is found out to be associative for this domain.
The operational structures available in GAP form a hierarchy, which is explicitly formulated in terms of domain categories, see Domain Categories.
Equality and comparison of domains are defined as follows.
Two domains are considered equal if and only if the sets of their
elements as computed by AsSSortedList
(see AsSSortedList) are equal.
Thus, in general =
behaves as if each domain operand were replaced by
its set of elements.
Except that =
will also sometimes, but not always,
work for infinite domains, for which of course GAP cannot compute
the set of elements.
Note that this implies that domains with different algebraic structure
may well be equal.
As a special case of this, either operand of =
may also be a proper set
(see Sorted Lists and Sets),
i.e., a sorted list without holes or duplicates (see AsSSortedList),
and =
will return true
if and only if this proper set is equal to
the set of elements of the argument that is a domain.
No general ordering of arbitrary domains via <
is defined in
GAP 4.
This is because a well-defined <
for domains or, more general, for
collections, would have to be compatible with =
and would need to be
transitive and antisymmetric in order to be used to form ordered sets.
In particular, <
would have to be independent of the algebraic
structure of its arguments because this holds for =
,
and thus there would be hardly a situation where one could implement
an efficient comparison method.
(Note that in the case that two domains are comparable with <
,
the result is in general not compatible with the set theoretical
subset relation, which can be decided with IsSubset
.)
For several operational structures (see Operational Structure of Domains),
GAP provides functions to construct domains with this structure.
For example, Group
returns groups, VectorSpace
returns vector spaces etc.
Struct(
arg1,
arg2, ... ) F
The syntax of these functions may vary, dependent on the structure in question. Usually a domain is constructed as the closure of some elements under the given operations, that is, the domain is given by its generators. For example, a group can be constructed from a list of generating permutations or matrices or whatever is admissible as group elements, and a vector space over a given field F can be constructed from F and a list of appropriate vectors.
The idea of generation and generators in GAP is that the domain
returned by a function such as Group
, Algebra
, or FreeLeftModule
contains the given generators.
This implies that the generators of a group must know how they are
multiplied and inverted,
the generators of a module must know how they are added and how scalar
multiplication works, and so on.
Thus one cannot use for example permutations as generators of a vector
space.
The function Struct first checks whether the arguments admit the construction of a domain with the desired structure. This is done by calling the operation
IsGeneratorsOf
Struct( [
info, ]
gens) O
where arglist is the list of given generators and info an argument
of Struct, for example the field of scalars in the case that a
vector space shall be constructed.
If the check failed then Struct returns fail
,
otherwise it returns the result of Struct
ByGenerators
(see below).
(So if one wants to omit the check then one should call
Struct
ByGenerators
directly.)
GeneratorsOf
Struct(
D) A
For a domain D with operational structure corresponding to Struct,
the attribute GeneratorsOf
Struct returns a list of corresponding
generators of D.
If these generators were not yet stored in D then D must know some
generators if
GeneratorsOf
Struct shall have a chance to compute the
desired result;
for example, monoid generators of a group can be computed from known
group generators (and vice versa).
Note that several notions of generation may be meaningful for a given
domain, so it makes no sense to ask for ``the generators of a domain''.
Further note that the generators may depend on other information about D.
For example the generators of a vector space depend on the underlying field
of scalars; the vector space generators of a vector space over the field
with four elements need not generate the same vector space when this is
viewed as a space over the field with two elements.
StructByGenerators( [
info, ]
gens ) O
Domain construction from generators gens is implemented by operations
Struct
ByGenerators
,
which are called by the simple functions Struct;
methods can be installed only for the operations.
Note that additional information info may be necessary
to construct the domain;
for example, a vector space needs the underlying field of scalars
in addition to the list of vector space generators.
The GeneratorsOf
Struct value of the returned domain need not
be equal to gens.
But if a domain D is printed as
Struct
([
a,
b, ...])
and if
there is an attribute GeneratorsOf
Struct then the list
GeneratorsOf
Struct(
D )
is guaranteed to be equal to
[
a,
b, ... ]
.
StructWithGenerators( [
info, ]
gens ) O
The only difference between Struct
ByGenerators
and
Struct
WithGenerators
is that the latter guarantees that the
GeneratorsOf
Struct value of the result is equal to the given
generators gens.
Closure
Struct(
D,
obj ) O
For constructing a domain as the closure of a given domain with an
element or another domain, one can use the operation Closure
Struct.
It returns the smallest domain with operational structure corresponding to
Struct that contains D as a subset and obj as an element.
The same set of elements can have different operational structures. For example, it may happen that a monoid M does in fact contain the inverses of all of its elements; if M has not been constructed as a group (see Domain Categories) then it is reasonable to ask for the group that is equal to M.
As
Struct( [
info, ]
D ) O
If D is a domain that is closed under the operational structure
given by Struct then As
Struct returns a domain E that consists
of the same elements (that is,
D
=
E) and that has this
operational structure (that is,
Is
Struct(
E )
is true
);
if D is not closed under the structure given by Struct then
As
Struct returns
fail
.
If additional information besides generators are necessary to define D
then the argument info describes the value of this information for the
desired domain.
For example, if we want to view D as a vector space over the field
with two elements then we may call AsVectorSpace( GF(2),
D )
;
this allows us to change the underlying field of scalars,
for example if D is a vector space over the field with four elements.
Again, if D is not equal to a domain with the desired structure and
additional information then fail
is returned.
In the case that no additional information info is related to the
structure given by Struct,
the operation As
Struct is in fact an attribute (see Attributes).
See the index of the GAP Reference Manual for an overview of the available
As
Struct functions.
Often it is useful to answer questions about a domain via computations in a different but isomorphic domain. In the sense that this approach keeps the structure and changes the underlying set of elements, it can be viewed as a counterpart of keeping the set of elements and changing its structure (see Changing the Structure).
One reason for doing so can be that computations with the elements in the given domain are not very efficient. For example, if one is given a solvable matrix group (see Chapter Matrix Groups) then one can compute an isomorphism to a polycyclicly presented group G, say (see Chapter Polycyclic Groups); the multiplication of two matrices --which is essentially determined by the dimension of the matrices-- is much more expensive than the multiplication of two elements in G --which is essentially determined by the composition length of G.
Isomorphism
Rep
Struct(
D ) A
If D is a domain that is closed under the operational structure
given by Struct then Isomorphism
RepStruct
returns a mapping hom
from D to a domain E having structure given by Struct,
such that hom respects the structure Struct
and Rep describes the representation of the elements in E.
If no domain E with the required properties exists then
fail
is
returned.
For example, IsomorphismPermGroup
(see IsomorphismPermGroup) takes a
group as its argument and returns a group homomorphism
(see Group Homomorphisms) onto an isomorphic permutation group
(see Chapter Permutation Groups) provided the original
group is finite; for infinite groups, IsomorphismPermGroup
returns fail
.
Similarly, IsomorphismPcGroup
(see IsomorphismPcGroup) returns a group
homomorphism from its argument to a polycyclicly presented group
(see Pc Groups) if the argument is polycyclic, and fail
otherwise.
See the index of the GAP Reference Manual for an overview of the available
Isomorphism
RepStruct
functions.
As mentioned in Operational Structure of Domains,
the operational structure of a domain is fixed when the domain is
constructed.
For example, if D was constructed by Monoid
then D is in general not
regarded as a group in GAP,
even if D is in fact closed under taking inverses.
In this case, IsGroup
returns false
for D.
The operational structure determines which operations are applicable for
a domain, so for example SylowSubgroup
is not defined for D
and therefore will signal an error.
Is
Struct(
D )
The functions Is
Struct implement the tests whether a domain D has the
respective operational structure (upon construction).
Is
Struct is a filter (see Types of Objects) that involves certain
categories (see Categories)
and usually also certain properties (see Properties).
For example,
IsGroup
is equivalent to
IsMagmaWithInverses and IsAssociative
,
the first being a category and the second being a property.
Implications between domain categories describe the hierarchy of operational structures available in GAP. Here are some typical examples.
IsDomain
is implied by each domain category,
IsMagma
is implied by each category that describes the closure under
multiplication *
,
IsAdditiveMagma
is implied by each category that describes the closure
under addition +
,
IsMagmaWithOne
implies IsMagma
;
a magma-with-one is a magma such that each element
(and thus also the magma itself) can be asked for its zeroth power,
IsMagmaWithInverses
implies IsMagmaWithOne
;
a magma-with-inverses is a magma such that each element
can be asked for its inverse;
important special cases are groups,
which in addition are associative,
Each operational structure Struct has associated with it
a domain category Is
Struct,
and operations
Struct
ByGenerators
for constructing a domain from
generators,
GeneratorsOf
Struct for storing and accessing generators w.r.t. this
structure,
Closure
Struct for forming the closure,
and
As
Struct for getting a domain with the desired structure from one
with weaker operational structure and for testing whether a given domain
can be regarded as a domain with Struct.
The functions applicable to domains with the various structures are described in the corresponding chapters of the Reference Manual. For example, functions for rings, fields, groups, and vector spaces are described in Chapters Rings, Fields and Division Rings, Groups, and Vector Spaces, respectively. More general functions for arbitrary collections can be found in Chapter Collections.
Parent(
D ) F
SetParent(
D,
P ) O
HasParent(
D ) F
It is possible to assign to a domain D one other domain P containing D as a subset, in order to exploit this subset relation between D and P. Note that P need not have the same operational structure as D, for example P may be a magma and D a field.
The assignment is done by calling SetParent
,
and P is called the parent of D.
If D has already a parent, calls to SetParent
will be ignored.
If D has a parent P --this can be checked with HasParent
--
then P can be used to gain information about D.
First, the call of SetParent
causes UseSubsetRelation
(see UseSubsetRelation) to be called.
Second, for a domain D with parent, information relative to the parent
can be stored in D;
for example, there is an attribute NormalizerInParent
for storing
Normalizer(
P,
D )
in the case that D is a group.
(More about such parent dependent attributes can be found in
In Parent Attributes in ``Extending GAP''.)
Note that because of this relative information,
one cannot change the parent;
that is, one can set the parent only once,
subsequent calls to SetParent
for the same domain D are ignored.
Further note that contrary to UseSubsetRelation
(see UseSubsetRelation),
also knowledge about the parent P might be used
that is discovered after the SetParent
call.
A stored parent can be accessed using Parent
.
If D has no parent then Parent
returns D itself,
and HasParent
will return false
also after a call to Parent
.
So Parent
is not an attribute,
the underlying attribute to store the parent is ParentAttr
.
Certain functions that return domains with parent already set,
for example Subgroup
,
are described in Section Constructing Subdomains.
Whenever a function has this property,
the Reference Manual states this explicitly.
Note that these functions do not guarantee a certain parent,
for example DerivedSubgroup
(see DerivedSubgroup) for a perfect
group G may return G itself, and if G had already a parent
then this is not replaced by G.
As a rule of thumb, GAP avoids to set a domain as its own parent,
which is consistent with the behaviour of Parent
,
at least until a parent is set explicitly with SetParent
.
gap> g:= Group( (1,2,3), (1,2) );; h:= Group( (1,2) );; gap> HasParent( g ); HasParent( h ); false false gap> SetParent( h, g ); gap> Parent( g ); Parent( h ); Group([ (1,2,3), (1,2) ]) Group([ (1,2,3), (1,2) ]) gap> HasParent( g ); HasParent( h ); false true
For many domains D, there are functions that construct certain subsets S
of D as domains with parent (see Parents) already set to D.
For example, if G is a group that contains the elements in the list gens
then Subgroup(
G,
gens )
returns a group S that is generated by the
elements in gens and with Parent(
S ) =
G.
Sub
struct(
D,
gens ) F
More general, if D is a domain whose algebraic structure is given by the
function Struct (for example Group
, Algebra
, Field
)
then the function Sub
struct (for example
Subgroup
, Subalgebra
,
Subfield
) returns domains with structure Struct and parent set to
the first argument.
Sub
structNC(
D,
gens ) F
Each function Sub
struct checks that the Struct generated by
gens is in fact a subset of D.
If one wants to omit this check then one can call
Sub
structNC
instead;
the suffix NC
stands for ``no check''.
AsSub
struct(
D,
S ) F
first constructs As
struct( [
info, ]
S )
,
where info depends on D and S,
and then sets the parent (see Parents) of this new domain to D.
IsSub
struct(
D,
S ) F
There is no real need for functions that check whether a domain S is a
Sub
struct of a domain D,
since this is equivalent to the checks whether S is a Struct and S
is a subset of D.
Note that in many cases, only the subset relation is what one really wants
to check, and that appropriate methods for the operation
IsSubset
(see IsSubset) are available for many special situations,
such as the test whether a group is contained in another group,
where only generators need to be checked.
If a function IsSub
struct is available in GAP then it is implemented
as first a call to
Is
Struct for the second argument and then a call to
IsSubset
for the two arguments.
For the meaning of the attributes Characteristic
, One
, Zero
in the case of a domain argument,
see Attributes and Properties of Elements.
IsGeneralizedDomain(
D ) C
IsDomain(
D ) C
For some purposes, it is useful to deal with objects that are similar to domains but that are not collections in the sense of GAP because their elements may lie in different families; such objects are called generalized domains. An instance of generalized domains are ``operation domains'', for example any G-set for a permutation group G consisting of some union of points, sets of points, sets of sets of points etc., under a suitable action.
IsDomain
is a synonym for IsGeneralizedDomain and IsCollection
.
GeneratorsOfDomain(
D ) A
For a domain D, GeneratorsOfDomain
returns a list containing all
elements of D, perhaps with repetitions.
Note that if the domain D shall be generated by a list of some elements
w.r.t. the empty operational structure
(see Operational Structure of Domains),
the only possible choice of elements is to take all elements of D.
See Constructing Domains and Changing the Structure for the concepts
of other notions of generation.
Domain( [
Fam, ]
generators ) F
DomainByGenerators(
Fam,
generators ) O
Domain
returns the domain consisting of the elements
in the homogeneous list generators.
If generators is empty then a family Fam must be entered as first
argument, and the returned (empty) domain lies in the collections
family of Fam.
DomainByGenerators
is the operation called by Domain
.
The following attributes and properties for elements and domains correspond to the operational structure.
Characteristic(
obj ) A
Characteristic
returns the characteristic of obj,
where obj must either be an additive element, a domain or a family.
For a domain D, the characteristic is defined if D is closed under
addition and has a zero element z
= Zero(
D )
(see Zero);
in this case, Characteristic(
D )
is the smallest positive integer
p such that p
*
x =
z for all elements x in D,
if such an integer exists, and the integer zero
0
otherwise.
If a family has a characteristic then this means that all domains of elements in this family have this characteristic. In this case, also each element in the family has this characteristic. (Note that also the zero element z of a finite field in characteristic p has characteristic p, although n * z = z for any integer n.)
OneImmutable(
obj ) A
OneAttr(
obj ) AM
One(
obj ) AM
Identity(
obj ) AM
OneMutable(
obj ) O
OneOp(
obj ) O
OneSameMutability(
obj ) O
OneSM(
obj ) O
OneImmutable
, OneMutable
, and OneSameMutability
return the
multiplicative neutral element of the multiplicative element obj.
They differ only w.r.t. the mutability of the result.
OneImmutable
is an attribute and hence returns an immutable result.
OneMutable
is guaranteed to return a new mutable object whenever
a mutable version of the required element exists in GAP
(see IsCopyable).
OneSameMutability
returns a result that is mutable if obj is mutable
and if a mutable version of the required element exists in GAP;
for lists, it returns a result of the same immutability level as
the argument. For instance, if the argument is a mutable matrix
with immutable rows, it returns a similar object.
If obj is a multiplicative element then OneSameMutability(
obj )
is equivalent to obj
^0
.
OneAttr
, One
and Identity
are synonyms of OneImmutable
.
OneSM
is a synonym of OneSameMutability
.
OneOp
is a synonym of OneMutable
.
If obj is a domain or a family then One
is defined as the identity
element of all elements in obj,
provided that all these elements have the same identity.
For example, the family of all cyclotomics has the identity element 1
,
but a collections family (see CollectionsFamily) may contain
matrices of all dimensions and then it cannot have a unique identity
element.
Note that One
is applicable to a domain only if it is a
magma-with-one (see IsMagmaWithOne);
use MultiplicativeNeutralElement
(see MultiplicativeNeutralElement)
otherwise.
The identity of an object need not be distinct from its zero, so for example a ring consisting of a single element can be regarded as a ring-with-one (see Rings). This is particularly useful in the case of finitely presented algebras, where any factor of a free algebra-with-one is again an algebra-with-one, no matter whether or not it is a zero algebra.
The default method of One
for multiplicative elements calls
OneMutable
(note that methods for OneMutable
must not delegate to
One
);
so other methods to compute identity elements need to be installed only
for OneOp
and (in the case of copyable objects) OneSameMutability
.
For domains, One
may call Representative
(see Representative),
but Representative
is allowed to fetch the identity of a domain D
only if HasOne(
D )
is true
.
ZeroImmutable(
obj ) A
ZeroAttr(
obj ) AM
Zero(
obj ) AM
ZeroMutable(
obj ) O
ZeroOp(
obj ) O
ZeroSameMutability(
obj ) O
ZeroSM(
obj ) O
ZeroImmutable
, ZeroMutable
, and ZeroSameMutability
all
return the additive neutral element of the additive element obj.
They differ only w.r.t. the mutability of the result.
ZeroImmutable
is an attribute and hence returns an immutable result.
ZeroMutable
is guaranteed to return a new mutable object whenever
a mutable version of the required element exists in GAP
(see IsCopyable).
ZeroSameMutability
returns a result that is mutable if obj is mutable
and if a mutable version of the required element exists in GAP;
for lists, it returns a result of the same immutability level as
the argument. For instance, if the argument is a mutable matrix
with immutable rows, it returns a similar object.
ZeroSameMutability(
obj )
is equivalent to 0 *
obj.
ZeroAttr
and Zero
are synonyms of ZeroImmutable
.
ZeroSM
is a synonym of ZeroSameMutability
.
ZeroOp
is a synonym of ZeroMutable
.
If obj is a domain or a family then Zero
is defined as the zero
element of all elements in obj,
provided that all these elements have the same zero.
For example, the family of all cyclotomics has the zero element 0
,
but a collections family (see CollectionsFamily) may contain
matrices of all dimensions and then it cannot have a unique zero element.
Note that Zero
is applicable to a domain only if it is an
additive magma-with-zero (see IsAdditiveMagmaWithZero);
use AdditiveNeutralElement
(see AdditiveNeutralElement) otherwise.
The default method of Zero
for additive elements calls ZeroMutable
(note that methods for ZeroMutable
must not delegate to Zero
);
so other methods to compute zero elements need to be installed only for
ZeroMutable
and (in the case of copyable objects) ZeroSameMutability
.
For domains, Zero
may call Representative
(see Representative),
but Representative
is allowed to fetch the zero of a domain D
only if HasZero(
D )
is true
.
MultiplicativeZeroOp(
elt ) O
returns the element z in the family F of elt with the property that z * m = z = m * z holds for all m ∈ F, if such an element is known.
Families of elements in the category IsMultiplicativeElementWithZero often arise from adjoining a new zero to an existing magma. See InjectionZeroMagma for details.
IsOne(
elm ) P
is true
if elm
= One(
elm )
, and false
otherwise.
IsZero(
elm ) P
is true
if elm
= Zero(
elm )
, and false
otherwise.
IsIdempotent(
elt ) P
true iff elt is its own square. (Even if IsZero(elt) is also true.)
InverseImmutable(
elm ) A
InverseAttr(
elm ) AM
Inverse(
elm ) AM
InverseMutable(
elm ) O
InverseOp(
elm ) O
InverseSameMutability(
elm ) O
InverseSM(
elm ) O
InverseImmutable
, InverseMutable
, and InverseSameMutability
all return the multiplicative inverse of an element elm,
that is, an element inv such that
elm
*
inv =
inv *
elm = One(
elm )
holds;
if elm is not invertible then fail
(see Fail) is returned.
Note that the above definition implies that a (general) mapping
is invertible in the sense of Inverse
only if its source equals its
range (see Technical Matters Concerning General Mappings).
For a bijective mapping f whose source and range differ,
InverseGeneralMapping
(see InverseGeneralMapping) can be used
to construct a mapping g with the property
that f * g is the identity mapping on the source of f
and g * f is the identity mapping on the range of f.
The operations differ only w.r.t. the mutability of the result.
InverseImmutable
is an attribute and hence returns an immutable result.
InverseMutable
is guaranteed to return a new mutable object whenever
a mutable version of the required element exists in GAP.
InverseSameMutability
returns a result that is mutable if elm is
mutable and if a mutable version of the required element exists in
GAP; for lists, it returns a result of the same immutability level as
the argument. For instance, if the argument is a mutable matrix
with immutable rows, it returns a similar object.
InverseSameMutability(
elm )
is equivalent to elm
^-1
.
InverseAttr
and Inverse
are synonyms of InverseImmutable
.
InverseSM
is a synonym of InverseSameMutability
.
InverseOp
is a synonym of InverseMutable
.
The default method of InverseImmutable
calls InverseMutable
(note that methods
for InverseMutable
must not delegate to InverseImmutable
);
other methods to compute inverses need to be installed only for
InverseMutable
and (in the case of copyable objects)
InverseSameMutability
.
AdditiveInverseImmutable(
elm ) A
AdditiveInverseAttr(
elm ) AM
AdditiveInverse(
elm ) AM
AdditiveInverseMutable(
elm ) O
AdditiveInverseOp(
elm ) O
AdditiveInverseSameMutability(
elm ) O
AdditiveInverseSM(
elm ) O
AdditiveInverseImmutable
, AdditiveInverseMutable
, and
AdditiveInverseSameMutability
all return the
additive inverse of elm.
They differ only w.r.t. the mutability of the result.
AdditiveInverseImmutable
is an attribute and hence returns an
immutable result. AdditiveInverseMutable
is guaranteed to
return a new mutable object whenever a mutable version of the
required element exists in GAP (see IsCopyable).
AdditiveInverseSameMutability
returns a result that is mutable
if elm is mutable and if a mutable version of the required
element exists in GAP;
for lists, it returns a result of the same immutability level as
the argument. For instance, if the argument is a mutable matrix
with immutable rows, it returns a similar object.
AdditiveInverseSameMutability(
elm )
is equivalent to -
elm.
AdditiveInverseAttr
and AdditiveInverse
are synonyms of AdditiveInverseImmutable
.
AdditiveInverseSM
is a synonym of AdditiveInverseSameMutability
.
AdditiveInverseOp
is a synonym of AdditiveInverseMutable
.
The default method of AdditiveInverse
calls AdditiveInverseMutable
(note that methods for AdditiveInverseMutable
must not delegate to
AdditiveInverse
);
so other methods to compute additive inverses need to be installed only
for AdditiveInverseMutable
and (in the case of copyable objects)
AdditiveInverseSameMutability
.
Order(
elm ) A
is the multiplicative order of elm.
This is the smallest positive integer n such that
elm
^
n = One(
elm )
if such an integer exists. If the order is
infinite, Order
may return the value infinity
, but it also might run
into an infinite loop trying to test the order.
Binary comparison operations have been introduced already in Comparisons. The underlying operations for which methods can be installed are the following.
\=(
left-expr,
right-expr ) O
\<(
left-expr,
right-expr ) O
Note that the comparisons via <>
, <=
, >
, and >=
are delegated to
the operations \=
and \<
.
In general, objects in different families cannot be compared with <
.
For the reason and for exceptions from this rule, see Comparisons.
For some objects a ``normal form'' is hard to compute and thus equality of elements of a domain might be expensive to test. Therefore GAP provides a (slightly technical) property with which an algorithm can test whether an efficient equality test is available for elements of a certain kind.
CanEasilyCompareElements(
obj ) P
CanEasilyCompareElementsFamily(
fam ) F
CanEasilySortElements(
obj ) P
CanEasilySortElementsFamily(
fam ) F
CanEasilyCompareElements
indicates whether the elements in the family
fam of obj can be easily compared with =
.
(In some cases element comparisons are very hard, for example in cases
where no normal forms for the elements exist.)
The default method for this property is to ask the family of obj,
the default method for the family is to return false
.
The ability to compare elements may depend on the successful computation
of certain information. (For example for finitely presented groups it
might depend on the knowledge of a faithful permutation representation.)
This information might change over time and thus it might not be a good
idea to store a value false
too early in a family. Instead the
function CanEasilyCompareElementsFamily
should be called for the
family of obj which returns false
if the value of
CanEasilyCompareElements
is not known for the family without computing
it. (This is in fact what the above mentioned family dispatch does.)
If a family knows ab initio that it can compare elements this property
should be set as implied filter and filter for the family (the 3rd and
4th argument of NewFamily
respectively). This guarantees that code
which directly asks the family gets a right answer.
The property CanEasilySortElements
and the function
CanEasilySortElementsFamily
behave exactly in the same way, except
that they indicate that objects can be compared via <
. This property
implies CanEasilyCompareElements
, as the ordering must be total.
Binary arithmetic operations have been introduced already in Arithmetic Operators. The underlying operations for which methods can be installed are the following.
\+(
left-expr,
right-expr ) O
\*(
left-expr,
right-expr ) O
\/(
left-expr,
right-expr ) O
\^(
left-expr,
right-expr ) O
\mod(
left-expr,
right-expr ) O
For details about special methods for \mod
, consult the index entries
for ``mod''.
LeftQuotient(
elm1,
elm2 ) O
returns the product elm1
^(-1) *
elm2.
For some types of objects (for example permutations) this product can be
evaluated more efficiently than by first inverting elm1
and then forming the product with elm2.
Comm(
elm1,
elm2 ) O
returns the commutator of elm1 and elm2. The commutator is defined as the product elm1 −1 * elm2 −1 * elm1 * elm2 .
gap> a:= (1,3)(4,6);; b:= (1,6,5,4,3,2);; gap> Comm( a, b ); (1,5,3)(2,6,4) gap> LeftQuotient( a, b ); (1,2)(3,6)(4,5)
LieBracket(
elm1,
elm2 ) O
returns the element elm1
*
elm2 -
elm2 *
elm1.
The addition \+
is assumed to be associative but not assumed to be
commutative (see IsAdditivelyCommutative).
The multiplication \*
is not assumed to be commutative or associative
(see IsCommutative, IsAssociative).
Sqrt(
obj ) O
Sqrt
returns a square root of obj, that is, an object x with the
property that x ·x = obj holds.
If such an x is not unique then the choice of x depends on the type
of obj.
For example, ER
(see ER) is the Sqrt
method for rationals
(see IsRat).
Domains are often constructed relative to other domains. The probably most usual case is to form a subset of a domain, for example the intersection (see Intersection) of two domains, or a Sylow subgroup of a given group (see SylowSubgroup).
In such a situation, the new domain can gain knowledge by exploiting that several attributes are maintained under taking subsets. For example, the intersection of an arbitrary domain with a finite domain is clearly finite, a Sylow subgroup of an abelian group is abelian, too, and so on.
Since usually the new domain has access to the knowledge of the old domain(s) only when it is created (see Constructing Subdomains for the exception), this is the right moment to take advantage of the subset relation.
Analogous relations occur when a factor structure is created from a domain and a subset, and when a domain isomorphic to a given one is created.
UseSubsetRelation(
super,
sub ) O
Methods for this operation transfer possibly useful information from the domain super to its subset sub, and vice versa.
UseSubsetRelation
is designed to be called automatically
whenever substructures of domains are constructed.
So the methods must be cheap, and the requirements should be as
sharp as possible!
To achieve that all applicable methods are executed, all methods for
this operation except the default method must end with TryNextMethod()
.
This default method deals with the information that is available by
the calls of InstallSubsetMaintenance
in the GAP library.
gap> g:= Group( (1,2), (3,4), (5,6) );; h:= Group( (1,2), (3,4) );; gap> IsAbelian( g ); HasIsAbelian( h ); true false gap> UseSubsetRelation( g, h );; HasIsAbelian( h ); IsAbelian( h ); true true
UseIsomorphismRelation(
old,
new ) O
Methods for this operation transfer possibly useful information from the domain old to the isomorphic domain new.
UseIsomorphismRelation
is designed to be called automatically
whenever isomorphic structures of domains are constructed.
So the methods must be cheap, and the requirements should be as
sharp as possible!
To achieve that all applicable methods are executed, all methods for
this operation except the default method must end with TryNextMethod()
.
This default method deals with the information that is available by
the calls of InstallIsomorphismMaintenance
in the GAP library.
gap> g:= Group( (1,2) );; h:= Group( [ [ -1 ] ] );; gap> Size( g ); HasSize( h ); 2 false gap> UseIsomorphismRelation( g, h );; HasSize( h ); Size( h ); true 2
UseFactorRelation(
numer,
denom,
factor ) O
Methods for this operation transfer possibly useful information from the
domain numer or its subset denom to the domain factor that
is isomorphic to the factor of numer by denom, and vice versa.
denom may be fail
, for example if factor is just known to be a
factor of numer but denom is not available as a GAP object;
in this case those factor relations are used that are installed without
special requirements for denom.
UseFactorRelation
is designed to be called automatically
whenever factor structures of domains are constructed.
So the methods must be cheap, and the requirements should be as
sharp as possible!
To achieve that all applicable methods are executed, all methods for
this operation except the default method must end with TryNextMethod()
.
This default method deals with the information that is available by
the calls of InstallFactorMaintenance
in the GAP library.
gap> g:= Group( (1,2,3,4), (1,2) );; h:= Group( (1,2,3), (1,2) );; gap> IsSolvableGroup( g ); HasIsSolvableGroup( h ); true false gap> UseFactorRelation( g, Subgroup( g, [ (1,2)(3,4), (1,3)(2,4) ] ), h );; gap> HasIsSolvableGroup( h ); IsSolvableGroup( h ); true true
The following functions are used to tell GAP under what conditions
an attribute is maintained under taking subsets,
or forming factor structures or isomorphic domains.
This is used only when a new attribute is created,
see Creating Attributes and Properties in ``Programming in GAP''.
For the attributes already available, such as IsFinite
and IsCommutative
,
the maintenances are already notified.
InstallSubsetMaintenance(
opr,
super_req,
sub_req ) F
opr must be a property or an attribute.
The call of InstallSubsetMaintenance
has the effect that
for a domain D in the filter super_req, and a domain S in the
filter sub_req,
the call UseSubsetRelation(
D,
S )
(see UseSubsetRelation)
sets a known value of opr for D as value of opr also for S.
A typical example for which InstallSubsetMaintenance
is applied
is given by opr
= IsFinite
,
super_req
= IsCollection and IsFinite
,
and sub_req
= IsCollection
.
If opr is a property and the filter super_req lies in the filter
opr then we can use also the following inverse implication.
If D is in the filter whose intersection with opr is super_req
and if S is in the filter sub_req, S is a subset of D, and
the value of opr for S is false
then the value of opr for D is also false
.
InstallIsomorphismMaintenance(
opr,
old_req,
new_req ) F
opr must be a property or an attribute.
The call of InstallIsomorphismMaintenance
has the effect that
for a domain D in the filter old_req, and a domain E in the
filter new_req,
the call UseIsomorphismRelation(
D,
E )
(see UseIsomorphismRelation)
sets a known value of opr for D as value of opr also for E.
A typical example for which InstallIsomorphismMaintenance
is
applied is given by opr
= Size
,
old_req
= IsCollection
, and new_req
= IsCollection
.
InstallFactorMaintenance(
opr,
numer_req,
denom_req,
factor_req ) F
opr must be a property or an attribute.
The call of InstallFactorMaintenance
has the effect that
for collections N, D, F in the filters numer_req, denom_req,
and factor_req, respectively,
the call UseFactorRelation(
N,
D,
F )
(see UseFactorRelation)
sets a known value of opr for N as value of opr also for F.
A typical example for which InstallFactorMaintenance
is
applied is given by opr
= IsFinite
,
numer_req
= IsCollection and IsFinite
, denom_req
= IsCollection
,
and factor_req
= IsCollection
.
For the other direction, if numer_req involves the filter opr
then a known false
value of opr for F implies a false
value for D provided that D lies in the filter obtained from
numer_req by removing opr.
Note that an implication of a factor relation holds in particular for the
case of isomorphisms.
So one need not install an isomorphism maintained method when
a factor maintained method is already installed.
For example, UseIsomorphismRelation
(see UseIsomorphismRelation)
will transfer a known IsFinite
value because of the installed factor
maintained method.
This section and the following one are rather technical, and may be interesting only for those GAP users who want to implement new kinds of elements.
It deals with certain categories of elements that are useful mainly for the
design of elements, from the viewpoint that one wants to form certain domains
of these elements.
For example, a domain closed under multiplication *
(a so-called magma,
see Chapter Magmas) makes sense only if its elements can be multiplied,
and the latter is indicated by the category IsMultiplicativeElement
for each element.
Again note that the underlying idea is that a domain is regarded as
generated by given elements, and that these elements carry information
about the desired domain.
For general information on categories and their hierarchies,
see Categories.
IsExtAElement(
obj ) C
An external additive element is an object that can be added via +
with other elements (not necessarily in the same family, see Families).
IsNearAdditiveElement(
obj ) C
A near-additive element is an object that can be added via +
with elements in its family (see Families);
this addition is not necessarily commutative.
IsAdditiveElement(
obj ) C
An additive element is an object that can be added via +
with elements in its family (see Families);
this addition is commutative.
IsNearAdditiveElementWithZero(
obj ) C
A near-additive element-with-zero is an object that can be added
via +
with elements in its family (see Families),
and that is an admissible argument for the operation Zero
(see Zero);
this addition is not necessarily commutative.
IsAdditiveElementWithZero(
obj ) C
An additive element-with-zero is an object that can be added
via +
with elements in its family (see Families),
and that is an admissible argument for the operation Zero
(see Zero);
this addition is commutative.
IsNearAdditiveElementWithInverse(
obj ) C
A near-additive element-with-inverse is an object that can be
added via +
with elements in its family (see Families),
and that is an admissible argument for the operations Zero
(see Zero)
and AdditiveInverse
(see AdditiveInverse);
this addition is not necessarily commutative.
IsAdditiveElementWithInverse(
obj ) C
An additive element-with-inverse is an object that can be
added via +
with elements in its family (see Families),
and that is an admissible argument for the operations Zero
(see Zero)
and AdditiveInverse
(see AdditiveInverse);
this addition is commutative.
IsExtLElement(
obj ) C
An external left element is an object that can be multiplied from the
left, via *
, with other elements (not necessarily in the same family,
see Families).
IsExtRElement(
obj ) C
An external right element is an object that can be multiplied from the
right, via *
, with other elements (not necessarily in the same family,
see Families).
IsMultiplicativeElement(
obj ) C
A multiplicative element is an object that can be multiplied via *
with elements in its family (see Families).
IsMultiplicativeElementWithOne(
obj ) C
A multiplicative element-with-one is an object that can be multiplied
via *
with elements in its family (see Families),
and that is an admissible argument for the operation One
(see One).
IsMultiplicativeElementWithZero(
elt ) C
Elements in a family which can be the operands of the
*
and the operation MultiplicativeZero.
IsMultiplicativeElementWithInverse(
obj ) C
A multiplicative element-with-inverse is an object that can be
multiplied via *
with elements in its family (see Families),
and that is an admissible argument for the operations One
(see One)
and Inverse
(see Inverse). (Note the word ``admissible'': an
object in this category does not necessarily have an inverse, Inverse
may return fail
.)
IsVector(
obj ) C
A vector is an additive-element-with-inverse that can be multiplied from the left and right with other objects (not necessarily of the same type). Examples are cyclotomics, finite field elements, and of course row vectors (see below).
Note that not all lists of ring elements are regarded as vectors,
for example lists of matrices are not vectors.
This is because although the category IsAdditiveElementWithInverse
is
implied by the join of its collections category and IsList
,
the family of a list entry may not imply IsAdditiveElementWithInverse
for all its elements.
IsNearRingElement(
obj ) C
IsNearRingElement
is just a synonym for the join of
IsNearAdditiveElementWithInverse
and IsMultiplicativeElement
.
IsRingElement(
obj ) C
IsRingElement
is just a synonym for the join of
IsAdditiveElementWithInverse
and IsMultiplicativeElement
.
IsNearRingElementWithOne(
obj ) C
IsNearRingElementWithOne
is just a synonym for the join of
IsNearAdditiveElementWithInverse
and IsMultiplicativeElementWithOne
.
IsRingElementWithOne(
obj ) C
IsRingElementWithOne
is just a synonym for the join of
IsAdditiveElementWithInverse
and IsMultiplicativeElementWithOne
.
IsNearRingElementWithInverse(
obj ) C
IsRingElementWithInverse(
obj ) C
IsScalar(
obj ) C
IsRingElementWithInverse
and IsScalar
are just synonyms for the join
of
IsAdditiveElementWithInverse
and IsMultiplicativeElementWithInverse
.
More special categories of this kind are described in the contexts where
they arise,
they are IsRowVector
(see IsRowVector),
IsMatrix
(see IsMatrix),
IsOrdinaryMatrix
(see IsOrdinaryMatrix),
and IsLieMatrix
(see IsLieMatrix).
The following categories of elements are to be understood mainly as
categories for all objects in a family,
they are usually used as third argument of NewFamily
(see Creating Families in ``Programming in GAP'').
The purpose of each of the following categories is then to guarantee that
each collection of its elements automatically lies in its collections
category (see CategoryCollections).
For example, the multiplication of permutations is associative,
and it is stored in the family of permutations that each permutation lies
in IsAssociativeElement
.
As a consequence, each magma consisting of permutations
(more precisely: each collection that lies in the family
CollectionsFamily( PermutationsFamily )
, see CollectionsFamily)
automatically lies in CategoryCollections( IsAssociativeElement )
.
A magma in this category is always known to be associative, via a logical
implication (see Logical Implications in ``Programming in GAP'').
Similarly, if a family knows that all its elements are in the categories
IsJacobianElement
and IsZeroSquaredElement
,
then each algebra of these elements is automatically known to be a
Lie algebra (see Algebras).
IsAssociativeElement(
obj ) C
IsAssociativeElementCollection(
obj ) C
IsAssociativeElementCollColl(
obj ) C
An element obj in the category IsAssociativeElement
knows
that the multiplication of any elements in the family of obj
is associative.
For example, all permutations lie in this category, as well as those
ordinary matrices (see IsOrdinaryMatrix) whose entries are also in
IsAssociativeElement
.
IsAdditivelyCommutativeElement(
obj ) C
IsAdditivelyCommutativeElementCollection(
obj ) C
IsAdditivelyCommutativeElementCollColl(
obj ) C
IsAdditivelyCommutativeElementFamily(
obj ) C
An element obj in the category IsAdditivelyCommutativeElement
knows
that the addition of any elements in the family of obj
is commutative.
For example, each finite field element and each rational number lies in
this category.
IsCommutativeElement(
obj ) C
IsCommutativeElementCollection(
obj ) C
IsCommutativeElementCollColl(
obj ) C
An element obj in the category IsCommutativeElement
knows
that the multiplication of any elements in the family of obj
is commutative.
For example, each finite field element and each rational number lies in
this category.
IsFiniteOrderElement(
obj ) C
IsFiniteOrderElementCollection(
obj ) C
IsFiniteOrderElementCollColl(
obj ) C
An element obj in the category IsFiniteOrderElement
knows
that it has finite multiplicative order.
For example, each finite field element and each permutation lies in
this category.
However the value may be false
even if obj has finite order,
but if this was not known when obj was constructed.
Although it is legal to set this filter for any object with finite order, this is really useful only in the case that all elements of a family are known to have finite order.
IsJacobianElement(
obj ) C
IsJacobianElementCollection(
obj ) C
IsJacobianElementCollColl(
obj ) C
An element obj in the category IsJacobianElement
knows
that the multiplication of any elements in the family F of obj
satisfies the Jacobi identity, that is,
x * y * z + z * x * y + y * z * x is zero
for all x, y, z in F.
For example, each Lie matrix (see IsLieMatrix) lies in this category.
IsZeroSquaredElement(
obj ) C
IsZeroSquaredElementCollection(
obj ) C
IsZeroSquaredElementCollColl(
obj ) C
An element obj in the category IsZeroSquaredElement
knows
that obj
^2 = Zero(
obj )
.
For example, each Lie matrix (see IsLieMatrix) lies in this category.
Although it is legal to set this filter for any zero squared object, this is really useful only in the case that all elements of a family are known to have square zero.
[Top] [Up] [Previous] [Next] [Index]
GAP 4 manual
March 2006