The method selection is not only used to select methods for attribute
getters but also for arbitrary operations, which can have more than one
argument. In this case, there is a required filter for each argument
(which must yield true for the corresponding arguments).
Additionally, a method with at least two arguments may require a certain
relation between the arguments,
which is expressed in terms of the families of the arguments.
For example, the methods for ConjugateGroup( grp, elm )
require that elm lies in the family of elements from which grp is
made, i.e., that the family of elm equals the ``elements family'' of
grp.
For permutation groups, the situation is quite easy:
all permutations form one family, PermutationsFamily,
and each collection of permutations,
for example each permutation group, each coset of a permutation group,
or each dense list of permutations,
lies in CollectionsFamily( PermutationsFamily ).
For other kinds of group elements, the situation can be different.
Every call of FreeGroup constructs a new family of free group elements.
GAP refuses to compute One( FreeGroup( 1 ) ) * One( FreeGroup( 1 ) )
because the two operands of the multiplication lie in different families
and no method is installed for this case.
For further information on family relations, see Families in the reference manual.
If you want to know which properties are already known for an object
obj, or which properties are known to be true, you can use the
functions KnownPropertiesOfObject(obj) resp.
KnownTruePropertiesOfObject( obj ). This will print a list of names
of properties. These names are also the identifiers of the property
getters, by which you can retrieve the value of the properties (and
confirm that they are really true). Analogously, there is the function
KnownAttributesOfObject which lists the names of the known attributes,
leaving out the properties.
Since GAP lets you know what it already knows about an object, it is
only natural that it also lets you know what methods it considers
applicable for a certain method, and in what order it will try them (in
case TryNextMethod() occurs). ApplicableMethod( opr, [ arg1,
arg2, ... ] ) returns the first applicable method for the call
opr( arg1, arg2, ... ). More generally, ApplicableMethod(
opr, [ ... ], 0, nr ) returns the nrth applicable method (i.e.,
the one that would be chosen after nr -1 TryNextMethods) and if
nr = "all", the sorted list of all applicable methods is returned.
For details, see Applicable Methods and Method Selection in
``Programming in GAP''.
If you want to see which methods are chosen for certain operations while
GAP code is being executed, you can call the function TraceMethods
with a list of these operations as arguments.
gap> TraceMethods( [ Size ] ); gap> g:= Group( (1,2,3), (1,2) );; Size( g ); #I Size: method for a permutation group #I Setter(Size): system setter #I Size: system getter #I Size: system getter 6The system getter is called once to fetch the freshly computed value for returning to the user. The second call is triggered by an immediate method. To find out by which, we can trace the immediate methods by saying
TraceImmediateMethods( true ).
gap> TraceImmediateMethods( true ); gap> g:= Group( (1,2,3), (1,2) );; #I immediate: Size #I immediate: IsCyclic #I immediate: IsCommutative #I immediate: IsTrivial gap> Size( g ); #I Size: for a permutation group #I immediate: IsNonTrivial #I immediate: Size #I immediate: IsNonTrivial #I Setter(Size): system setter #I Size: system getter #I immediate: IsPerfectGroup #I Size: system getter #I immediate: IsEmpty 6 gap> TraceImmediateMethods( false ); gap> UntraceMethods( [ Size ] );The last two lines switch off tracing again. We now see that the system getter was called by the immediate method for
IsPerfectGroup.
Also the above-mentioned immediate method for IsSolvableGroup
was not used because the solvability of g was already found out during
the size calculation
(cf. the example in Section Properties and Filters).
GAP 4 manual