Concerning the answer to his question, Jacob Hirbawi wrote
This leads me to a somewhat related question about constructing
algebras with a user defined type and a user defined multiplication.
So for example if I defined :A := MyObject(3); B := MyObject(5);
and GAP4 understands how to caclulate A*B; is there a "natural" way
to get GAP4 to understand statements of the form7*A + 12*B + 9*(A*B) or (A+3*B)*A
I have existing GAP3 code that does that; but it is inefficient in the
sense that I have to rewrite a lot of similar code for every new type
I define; hopefully there's something better in GAP4.
If the question is too general; a special case of the above would be
constructing the group algebra of a permutation or finitely presented
group; the construction would invlove the same type of definitions.
The question for a natural way to turn a given multiplicative structure
(which is called a *magma* in GAP 4) into an algebra can be answered
with a clear ``it depends''.
GAP 4 supports the general construction of a *magma ring*
from a given ring R of coefficients and a given magma M,
the result RM being a ring that is a free R-module with basis M.
If M is a group and R is a field then RG is a group algebra.
Note that the objects in M are *not contained* in RM,
the same holds for the objects in R;
one has to use *embeddings* explicitly
whenever one needs for example the magma ring element
corresponding to a given magma element.
Here is an example.
gap> g:= Group( (1,2,3), (1,2) );; f:= Rationals;; gap> fg:= FreeMagmaRing( f, g ); <algebra-with-one over Rationals, with 2 generators> gap> Dimension( fg ); 6 gap> Random( fg ); -4*()+2*(2,3)+-2/3*(1,2)+1/5*(1,2,3)+-2*(1,3,2)+5/3*(1,3) gap> One( fg ); 1*() gap> emb:= Embedding( g, fg );; gap> elm:= (1,2,3)^emb; elm in fg; 1*(1,2,3) true gap> new:= elm + One( fg ); 1*()+1*(1,2,3) gap> new^2; 1*()+2*(1,2,3)+1*(1,3,2)
But one may understand the question in such a way
that an addition for the magma objects *themselves*
shall be defined.
(An obvious but nevertheless important requirement is then
that no addition for the objects is defined before.
For example, consider a matrix group G with matrix entries
in some field F.
If we ask for the group algebra of G over F then the addition
in this group algebra is *not* compatible with the addition
The group algebra construction described above will work,
but it would not be possible to use the original matrices in G
as elements of the group algebra.)
So suppose we are given a multiplicative structure,
and we want to implement an addition for its elements.
Then GAP 4 supports no general mechanism for doing so,
and one has to proceed by installing methods for the
operations `\+', `Zero', and `AdditiveInverse'
--the latter two of course only if zero elements and
additive inverses exist.
(Due to some minor conceptual changes,
it might be that eventually one will have to install methods
not for `Zero' and `AdditiveInverse' but for operations
with different names.)
Finally, a rather technical remark.
It should be noted that it is possible to tell GAP 4
about certain features of objects that are known by construction.
(These features are called *categories* in GAP 4.)
In the case that one has installed multiplication and addition,
one can set the category `IsRingElement' in the objects' type.
This has the advantage that for such an object <obj>,
the operation `7 * <obj>' will work automatically,
by the obvious delegation to the addition for <obj>.
So it is not necessary to install methods for the multiplication
of integers with objects that are known to be ring elements;
but if it turns out that this operations has to be speeded up,
of course one can install a specific method that is more efficient.
This is just an example for the general concept that defaults are
provided where this is reasonable, and that they can be overloaded
(of course in a compatible way) by more efficient methods.
I hope this is of some help.