Logged Rewriting Systems A logged rewrite system is associated with a group presentation. Each logged rewrite rule contains, in addition to the standard rewrite rule, a record or log component which expresses the rule in terms of the original relators of the group. We represent such a rule by a triple [ u, [L1,L2,..,Lk], v], where [u,v] is a rewrite rule and L_i = [n_i,w_i] where n_i is a group relator and w_i is a word. These three components obey the identity u = n_1^{w_1} \ldots n_k^{w_k} v.

Logged Knuth-Bendix Completion The functions in this section are the logged versions of those in the previous chapter. The 12 initial logged rules for mq8 correspond to the 12 initial rules in section . Rules of the form g^{-1} \to G and gG \to id apply to the monoid presentation, but not to the group presentation, so are given an empty logged component. The remaining four rules, which corresppond to the relators r \in [a^4, b^4, abab^{-1}, a^2b^2] are given logged components [r,[\,[n,id]\,], id] for n \in [9..12].
gap> r0 := InitialLoggedRulesOfPresentation( mq8 );; gap> PrintLnUsingLabels( r0, genfmq8, q8labs ); [ [ a^-1, [ ], A ], [ b^-1, [ ], B ], [ A^-1, [ ], a ], [ B^-1, [ ], b ], [ a*A, [ ], id ], [ b*B, [ ], id ], [ A*a, [ ], id ], [ B*b, [ ], id ], [ a^4, [ [ 1, id ] ], id ], [ a^2*b^2, [ [ 4, id ] ], id ], [ a*b*a*B, [ [ 3, id ] ], id ], [ b^4, [ [ 2, id ] ], id ] ]
Given a logged rewrite system for the group grp, this function finds all the rules that would be added to complete the rewrite system of OnePassKB in , and also the logs which relate the new rules to the originals. The result of applying this function to loggedrules is to add new logged rules to the system without changing the monoid it defines.

In the example, we apply one pass of the logged Knuth-Bendix procedure to the initial set of logged rules.

gap> r1 := LoggedOnePassKB( mq8, r0 );; gap> Length( r1 ); 25 gap> PrintLnUsingLabels( r1, genfmq8, q8labs ); [ [ a^-1, [ ], A ], [ b^-1, [ ], B ], [ A^-1, [ ], a ], [ B^-1, [ ], b ], [ a*A, [ ], id ], [ b*B, [ ], id ], [ A*a, [ ], id ], [ B*b, [ ], id ], [ b^2, [ [ -4, id ], [ 2, A^2 ] ], a^2 ], [ b^2, [ [ -1, id ], [ 4, A^2 ] ], a^2 ], [ a^3, [ [ 1, id ] ], A ], [ a^3, [ [ 1, a ] ], A ], [ a^2*b, [ [ 4, id ] ], B ], [ a*b*a, [ [ 3, id ] ], b ], [ a*b^2, [ [ 4, a ] ], A ], [ b*a*B, [ [ 3, a ] ], A ], [ b^3, [ [ 2, id ] ], B ], [ b^3, [ [ 2, b ] ], B ], [ a*b^2, [ [ -1, id ], [ 4, A^3 ] ], a^3 ], [ b*a*B, [ [ -1, id ], [ 3, A^3 ] ], a^3 ], [ b^3, [ [ -4, id ], [ 2, B*A^2 ] ], a^2*b ], [ a^4, [ [ 1, id ] ], id ], [ a^2*b^2, [ [ 4, id ] ], id ], [ a*b*a*B, [ [ 3, id ] ], id ], [ b^4, [ [ 2, id ] ], id ] ]
Note that r1 has length 25, three more than the length 22 of q1 in . This because the three rules b^2 \to a^2;~ a^3 \to A;~ b^3 \to B each appear twice, with alternative logged components.

If we write a,b,A,B for M1,M2,M3,M4 and label the four original relators as q=a^4,\ r=b^4,\ s=abaB,\ t=a^2b^2 then the ninth identity (for example) says that b^2 = (t^{-1}r^{A^2})a^2. To verify this, we may expand the right-hand side as follows: (B^2A^2).a^2(b^4)A^2.a^2 ~=~ B^2(A^2a^2)b^4(A^2a^2) ~=~ B^2b^4 ~=~ b^2. The function LoggedRewriteReduce removes unnecessary rules from a logged rewrite system. It works on the same principle as RewriteReduce in . Note that q2 nd r2 both have length 13.

gap> r2 := LoggedRewriteReduce( mq8, r1 );; gap> Length( r2 ); 13 gap> PrintLnUsingLabels( r2, genfmq8, q8labs ); [ [ a^-1, [ ], A ], [ b^-1, [ ], B ], [ A^-1, [ ], a ], [ B^-1, [ ], b ], [ a*A, [ ], id ], [ b*B, [ ], id ], [ A*a, [ ], id ], [ B*b, [ ], id ], [ b^2, [ [ -4, id ], [ 2, A^2 ] ], a^2 ], [ a^3, [ [ 1, id ] ], A ], [ a^2*b, [ [ 4, id ] ], B ], [ a*b*a, [ [ 3, id ] ], b ], [ b*a*B, [ [ 3, a ] ], A ] ]
The function LoggedKnuthBendix repeatedly applies functions LoggedOnePassKB and LoggedRewriteReduce until no new rules are added and no unnecessary ones are included. The output is a reduced complete logged rewrite system.

As a further example, consider the ninth rule in r3 which shows how ba reduces to aB. For this rule [u,L,v] we will verify that u = n_1^{w_1}n_2^{w_2}n_3^{w_3} v, as in the introduction to this chapter. The rule is: [ ba, [ [-11,id], [12,BA] ], aB ]. The relators are -11 \equiv s^{-1} = bABA and 12 \equiv t = a^2b^2. These are conjugated by the identity and BA respectively. So the second and third parts of the rule expand to: (bABA)(ab(aabb)BA)aB ~=~ bAB(Aa)baab(bB)(Aa)B ~=~ bA(Bb)aa(bB) ~=~ b(Aa)a ~=~ ba, the first part of the rule.

gap> r3 := LoggedKnuthBendix( mq8, r0 );; gap> Length( r3 ); 20 gap> PrintLnUsingLabels( r3, genfmq8, q8labs ); [ [ a^-1, [ ], A ], [ b^-1, [ ], B ], [ A^-1, [ ], a ], [ B^-1, [ ], b ], [ a*A, [ ], id ], [ b*B, [ ], id ], [ A*a, [ ], id ], [ B*b, [ ], id ], [ b*a, [ [ -3, id ], [ 4, B*A ] ], a*B ], [ b^2, [ [ -4, id ], [ 2, A^2 ] ], a^2 ], [ b*A, [ [ -3, id ] ], a*b ], [ A*b, [ [ -1, id ], [ 4, A ] ], a*B ], [ A^2, [ [ -1, id ] ], a^2 ], [ A*B, [ [ -4, a ] ], a*b ], [ B*a, [ [ -4, id ], [ 3, A ] ], a*b ], [ B*A, [ [ -3, a*b ] ], a*B ], [ B^2, [ [ -4, id ] ], a^2 ], [ a^3, [ [ 1, id ] ], A ], [ a^2*b, [ [ 4, id ] ], B ], [ a^2*B, [ [ -4, A^2 ], [ 1, id ] ], b ] ]
Given a group presentation, the function LoggedRewritingSystemFpGroup determines a logged rewrite system based on the relators. The initial logged rewrite system associated with a group presentation consists of two types of rule. These are logged versions of the two types of rule in the monoid presentation. Corresponding to the j-th relator rel of the group there is a logged rule [rel,[[j,id]],id]. For each inverse relator there is a logged rule [ gen*inv, [], id ]. The function then attempts a completion of the logged rewrite system. The rules in the final system are partially ordered by the function ShorterLoggedRule.

gap> lrws := LoggedRewritingSystemFpGroup( q8 );; gap> PrintLnUsingLabels( lrws, genfgmon, q8labs ); [ [ a^-1, [ ], A ], [ b^-1, [ ], B ], [ A^-1, [ ], a ], [ B^-1, [ ], b ], [ a*A, [ ], id ], [ b*B, [ ], id ], [ A*a, [ ], id ], [ B*b, [ ], id ], [ b*a, [ [ -3, id ], [ 4, B*A ] ], a*B ], [ b^2, [ [ -4, id ], [ 2, A^2 ] ], a^2 ], [ b*A, [ [ -3, id ] ], a*b ], [ A*b, [ [ -1, id ], [ 4, A ] ], a*B ], [ A^2, [ [ -1, id ] ], a^2 ], [ A*B, [ [ -4, a ] ], a*b ], [ B*a, [ [ -4, id ], [ 3, A ] ], a*b ], [ B*A, [ [ -3, a*b ] ], a*B ], [ B^2, [ [ -4, id ] ], a^2 ], [ a^3, [ [ 1, id ] ], A ], [ a^2*b, [ [ 4, id ] ], B ], [ a^2*B, [ [ -4, A^2 ], [ 1, id ] ], b ] ] gap> Length( lrws ); 16

Consider now the two-generator abelian group T considered in the previous chapter (). Using the alternative ordering on the monoid generators, [ T_M1=a, T_M2=A, T_M3=b, T_M4=B ], we obtain the following set of 8 logged rules. The last of these may be checked as follows: (ba(BAba)AB)ab ~=~ ba(B(A(b(aA)B)a)b) and is a logged version of the rule ba \to ab.

gap> lrwsT := LoggedRewritingSystemFpGroup( T );; gap> PrintLnUsingLabels( lrwsT, genfgmonT, Tlabs ); [ [ x^-1, [ ], X ], [ X^-1, [ ], x ], [ y^-1, [ ], Y ], [ Y^-1, [ ], y ], [ x*X, [ ], id ], [ X*x, [ ], id ], [ y*Y, [ ], id ], [ Y*y, [ ], id ], [ y*x, [ [ -1, X*Y ] ], x*y ], [ y*X, [ [ 1, Y ] ], X*y ], [ Y*x, [ [ 1, X ] ], x*Y ], [ Y*X, [ [ -1, id ] ], X*Y ] ]
Logged reduction of a word Given a word and a logged rewrite system, the function LoggedOnePassReduceWord makes one reduction pass of the word (possibly involving several reductions) (as does OnePassReduceWord in ) and records this, using the log part of the rule(s) used and the position in the original word of the replaced part.

The function LoggedReduceWordKB repeatedly applies OnePassLoggedReduceWord until the word can no longer be reduced. Each step of the reduction is logged, showing how the original word can be expressed in terms of the original relators and the irreducible word. When loggedrules is complete the reduced word is a unique normal form for that group element. The log of the reduction depends on the order in which the rules are applied.

The function ShorterLoggedrule decides whether one logged rule is better than another, using the same criteria as ShorterRule in . In the example we perform logged reductions of w_0 = a^9b^{-9} corresponding to the ordinary reductions performed in the previous chapter (section ).

In order to clarify the following output, note that, in the log below, b^9a^{-9} reduces to Bb^5aba^{-8} in lw1, just as in section . This may be checked by cancelling terms in: (b^2A^2)(a^2.b^4.A^2)(a^2b^6.bABA.b^6A^2)(a^2b^2)Bb^5aba^{-8} ~=~ b^9a^9. The corresponding expansion of lw2 is too lengthy to include here. (It's hard to believe that the logged part of this identity is the simplest possible. Further investigation is needed to determine whether or not this logged part can be simplified.)

gap> PrintLnUsingLabels( w0, genfmq8, q8labs ); b^9*a^-9 gap> lw1 := LoggedOnePassReduceWord( w0, lrws );; gap> PrintLnUsingLabels( lw1, genfmq8, q8labs ); [ [ [ -4, id ], [ 2, A^2 ], [ -3, b^-6*a^-2 ], [ 4, id ] ], B*b^5*a*b*a^-8 ] gap> lw2 := LoggedReduceWordKB( w0, lrws );; gap> PrintLnUsingLabels( lw2, genfmq8, q8labs ); [ [ [ -4, id ], [ 2, A^2 ], [ -3, b^-6*a^-2 ], [ 4, id ], [ -3, b^-3 ], [ 4, B*A*b^-3 ], [ -4, id ], [ 2, A^2 ], [ -3, B^-1*a^-1*b^-1*a^-2 ], [ -4, a^-1*b^-1*a^-2 ], [ 3, A*a^-1*b^-1*a^-2 ], [ 4, id ], [ -4, a^-2*B^-1 ], [ 2, A^2*a^-2*B^-1 ], [ -4, id ], [ 3, A ], [ 1, b^-1*a^-1 ], [ -3, a^-1 ], [ -1, b^-1*a^-2 ], [ 4, id ], [ -3, a*b ], [ -3, a*b*a^-1 ], [ -4, A^2 ], [ 1, id ], [ -3, id ] ], a*b ]