the answer to your first question is easy:
First query: Can one make a trivial PcGroup, and if so, are all PcGroup
operations applicable to it? My problem is that an algorithm of mine
may produce as an answer a PcGroup which happens to be trivial.
Yes, you can construct the trivial pc-group and pc-group operations
gap> G := TrivialGroup(); <pc group of size 1 with 0 generators> gap> Size(G); 1 gap> DerivedSubgroup( G ); Group([ ]) gap> Center( G ); <pc group of size 1 with 0 generators> gap>
Second query: Is there any way of asserting that the type of an object
(say a vector over a given finite field F) will *never* change, in
order that checks do not have to be made if, say, an element of F is
appended to that vector?
It is not possible to fix the type of an object once and for all.
Making this possible would (probably) open a can of worms. However,
careful programming avoids type changes and there is a GAP function
which allows you to determine the exact (internal) type of an object.
Let me demonstrate this in an example.
If you have a vector v of elements in a finite field F, then appending
an element of F should not change the type of v.
gap> v := [1..5] * Z(3); [ Z(3), Z(3)^0, 0*Z(3), Z(3), Z(3)^0 ] gap> TNUM_OBJ(v); # get the internal type [ 30, "list (plain,hom)" ] # still a plain (homogeneous) list gap> v+v; [ Z(3)^0, Z(3), 0*Z(3), Z(3)^0, Z(3) ] gap> TNUM_OBJ(v); # now GAP knows it's a vector [ 54, "list (sml fin fld elms)" ] gap> v := Z(3); Z(3) gap> TNUM_OBJ(v); # still a vector [ 54, "list (sml fin fld elms)" ] gap> v := Z(3); # if we leave a whole, Z(3) gap> TNUM_OBJ(v); # then it's not a vector any more [ 18, "list (plain,ndense)" ]
The first statement creates a list v of elements in GF(3). At this
stage GAP has not recognized yet that this can be viewed as a vector.
Doing arithmetic forces GAP to check what type of object we have and
afterwards it knows that v is a finite field vector. Assigning
elements from GF(3) does not change this unless the result is not a
In composing this answer, I realized that there is a problem with the
Add() function as it does not follow that rule. I consider this a bug
and we'll look into it:
gap> v := [1..5] * Z(3);; v + v;; # produce a vector gap> Add( v, Z(3) ); gap> TNUM_OBJ(v); [ 16, "list (plain)" ] # darn!
Replacing Add() by an assignment to index 'Length(v)+1' works:
gap> v := [1..5] * Z(3);; v + v;; # produce a vector gap> v[ Length(v)+1 ] := Z(3);; gap> TNUM_OBJ(v); [ 54, "list (sml fin fld elms)" ] gap>
Does this answer your questions?
All the best,