Section Operation functions!for groups of the Reference Manual
explains that certain operations such as Orbits,
besides their usual usage with arguments G, D, and opr,
can also be applied to an external set,
in which case they can be interpreted as attributes.
Moreover, they can also be interpreted as attributes for permutation
group, meansing the natural action on the set of its moved points.
The definition of Orbits says that a method should be a function
with arguments G, D, gens, oprs, and opr,
as in the case of the operation ExternalSet when specified via gens
and oprs (see External Sets in the Reference Manual).
All other syntax variants allowed for Orbits (e.g., leaving
out gens and oprs) are handled by default methods.
The default methods for Orbits support the following behaviour.
HasOrbits( xset ) returns true,
the stored value of that attribute is returned.
Pcgs( G ) if CanEasilyComputePcgs( G )
is true, and to GeneratorsOfGroup( G ) otherwise;
oprs is set to gens.
OnPoints.
MovedPoints( G ) via OnPoints,
if the attribute tester HasOrbits( G ) returns true,
the stored attribute value is returned.
result:= Orbits( G, D, gens,
oprs, opr ).
The declaration of operations that match the above pattern is done as follows.
OrbitsishOperation( name, reqs, usetype, NewAttribute ) F
OrbitsishOperation( name, reqs, usetype, NewProperty ) F
declares an attribute op as described above, with name name. The second argument reqs specifies the list of required filters for the usual (five-argument) methods that do the real work.
If the third argument usetype is true,
the function call op( xset ) will
--- if the value of op for xset is not yet known ---
delegate to the five-argument call of op with second argument xset
rather than with D (cf. step 6 above).
This allows certain methods for op to make use of the type of xset,
in which the types of the external subsets of xset
and of the external orbits in xset are stored.
(This is used to avoid repeated calls of NewType in functions like
ExternalOrbits( xset ),
which call ExternalOrbit( xset, pnt ) for several values of pnt.)
For property testing functions such as IsTransitive,
the fourth argument is NewProperty,
otherwise it is NewAttribute.
For example, to set up the operation Orbits,
the declaration file ``lib/oprt.gd'' contains the following line of code:
OrbitsishOperation( "Orbits", OrbitsishReq, false, NewAttribute );The variable
OrbitsishReq contains the standard requirements
OrbitsishReq := [ IsGroup, IsList, IsList, IsList, IsFunction ];which are usually entered in calls to
OrbitsishOperation.
A similar mechanism is provided for operations such as Orbit that do
not have an associated attribute but still need a wrapper function to
standardize the arguments for the associated operation.
OrbitishFO( name, reqs, famrel, usetype ) F
declares a wrapper function and its operation,
with names name and nameOp.
The second argument reqs specifies the list of required filters for the
operation nameOp.
The third argument famrel is used to test the family relation between
the second and third argument of name( G, D, elm ).
For example, in the call Orbit( G, D, pnt ),
pnt must be an element of D, so famrel = IsCollsElms is
appropriate, and in the call Blocks( G, D, seed ),
seed must be a subset of D,
and the family relation is IsIdenticalObj.
The fourth argument usetype serves the same purpose as in the case of
OrbitsishOperation.
For example, to setup the function Orbit and its operation OrbitOp,
the declaration file ``lib/oprt.gd'' contains the following line of code:
OrbitishFO( "Orbit", OrbitishReq, IsCollsElms, false );The variable
OrbitishReq contains the standard requirements
OrbitishReq := [ IsGroup, IsList, IsObject, IsList, IsList, IsFunction ];which are usually entered in calls to
OrbitishFO.
The relation test via famrel is used to provide a uniform construction
of the wrapper functions created by OrbitishFO,
in spite of the different syntax of the specific functions.
For example, Orbit admits the calls Orbit( G, D, pnt, opr )
and Orbit( G, pnt, opr ), i.e., the second argument D may be
omitted;
Blocks admits the calls Blocks( G, D, seed, opr ) and
Blocks( G, D, opr ), i.e., the third argument may be omitted.
The translation to the appropriate call of OrbitOp or BlocksOp,
for either operation with five or six arguments,
is handled via famrel.
As a consequence, there must not only be methods for OrbitOp with
the six arguments corresponding to OrbitishReq,
but also methods for only five arguments (i.e., without D).
Plenty of examples are contained in the implementation file ``lib/oprt.gi''.
In order to handle a few special cases
(currently Blocks and MaximalBlocks),
also the following form is supported.
OrbitishFO( name, reqs, famrel, attr ) F
The functions in question depend upon an argument seed,
so they cannot be regarded as attributes.
However, they are most often called without giving seed,
meaning ``choose any minimal resp. maximal block system''.
In this case, the result can be stored as the value of the attribute
attr that was entered as fourth argument of OrbitishFO.
This attribute is considered by a call Blocks( G, D, opr )
(i.e., without seed) in the same way as Orbits considers OrbitsAttr.
To set this up, the declaration file ``lib/oprt.gd'' contains the following lines:
DeclareAttribute( "BlocksAttr", IsExternalSet );
OrbitishFO( "Blocks",
[ IsGroup, IsList, IsList,
IsList,
IsList,
IsFunction ], IsIdenticalObj, BlocksAttr );
And this extraordinary FOA triple works as follows:
gap> s4 := Group((1,2,3,4),(1,2));; Blocks( s4, MovedPoints(s4), [1,2] ); [ [ 1, 2, 3, 4 ] ] gap> Tester( BlocksAttr )( s4 ); false
gap> Blocks( s4, MovedPoints(s4) ); [ [ 1, 2, 3, 4 ] ] gap> Tester( BlocksAttr )( s4 ); BlocksAttr( s4 ); true [ [ 1, 2, 3, 4 ] ]
GAP 4 manual