I myself would probably try to work with the matrix representations, and maybe use lookup to associate products with group elements. Since you seem to want to se a representation in terms of products, and bearing in mind that these do not necessarily commute, we can do as follows. I work with the example shown (where products do in fact commute).
First define the generators and the relations they satisfy.
gens = {e, p, q, r};
rels = {e ** any_ :> any, any_ ** e :> any, any_ ** any_ :> e,
any_ ** p :> p ** any, r ** q -> q ** r};
Next compute products of all pairs.
firstset =
Union[Flatten[Outer[NonCommutativeMultiply, gens, gens] /. rels]]
(* Out[12]= {e, p, q, r, p ** q, p ** r, q ** r} *)
Repeat this in order to determine whether we have all possible group elements. Notice this time I use ReplaceAllRepeated
since there might need to be more than one pass using the relation rules as replacements.
nextset =
Union[Flatten[
Outer[NonCommutativeMultiply, firstset, firstset] //. rels]]
(* Out[16]= {e, p, q, r, p ** q, p ** r, q ** r, p ** q ** r} *)
Maximum length is 3 (rather than 4). I think that means we have all possible group elements. We can rename them along the lines indicated in the question.
elementnames = Array[c, Length[nextset]];
morerels = Reverse[Thread[nextset -> elementnames]]
(* Out[31]= {p ** q ** r -> c[8], q ** r -> c[7], p ** r -> c[6],
p ** q -> c[5], r -> c[4], q -> c[3], p -> c[2], e -> c[1]} *)
We now find all products of these, and use their new names to get the requested product table. Among other things, this will show that we get no new elements from products. Note that I sorted the renamings by length in order to make sure the longest available match is tried first.
multTable =
Outer[NonCommutativeMultiply, nextset, nextset] //. rels /. morerels
(* Out[29]= {{c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8]}, {c[2],
c[1], c[5], c[6], c[3], c[4], c[8], c[7]}, {c[3], c[5], c[1], c[7],
c[2], c[8], c[4], c[6]}, {c[4], c[6], c[7], c[1], c[8], c[2], c[3],
c[5]}, {c[5], c[3], c[2], c[8], c[1], c[7], c[6], c[4]}, {c[6],
c[4], c[8], c[2], c[7], c[1], c[5], c[3]}, {c[7], c[8], c[4], c[3],
c[6], c[5], c[1], c[2]}, {c[8], c[7], c[6], c[5], c[4], c[3], c[2], c[1]}} *)
So this is the product table. I think something like this might work in general, though perhaps there might need to be refinements for more complicated examples.
On a different note, I have received so many edit notifications today that I had to stop following the thread. The responses seem fine, but I've yet to figure out what in the original post has changed during these six or so edits.