  
  [1X3 Logged Rewriting Systems[0X
  
  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  express the rule in terms of the original relators of
  the  group.  Here  a  logged  rewrite  rule  is represented by a triple [10X[ u,
  [L1,L2,..,Lk],  v][0m,  where [10X[u,v][0m 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 ... n_k^w_k v.
  
  Rules of the form g^+g^- are relevant to the monoid presentation, but not to
  the group presentation, so are not included in the logging.
  
  
  [1X3.1 Logged Knuth-Bendix Completion[0X
  
  The  functions  in  this  section  are  the  logged versions of those in the
  previous chapter.
  
  [1X3.1-1 LoggedOnePassKB[0m
  
  [2X> LoggedOnePassKB( [0X[3Xloggedrules[0X[2X ) __________________________________[0Xoperation
  
  Given  a logged rewrite system, this function finds all the rules that would
  be  added  to  complete  the  rewrite system in [10XOnePassKB[0m, 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 first convert the presentation for [10Xq8[0m into an initial set
  of logged rules, and then apply one pass of Knuth-Bendix.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> l0 := ListWithIdenticalEntries( 8, 0 );;[0X
    [4Xgap> for j in [1..8] do [0X
    [4X         r := r0[j];[0X
    [4X         if ( j<5 ) then[0X
    [4X            l0[j] := [ r[1], [ [j,id] ], r[2] ];[0X
    [4X         else[0X
    [4X            l0[j] := [ r[1], [ ], r[2] ];[0X
    [4X         fi;[0X
    [4X     od;[0X
    [4Xgap> l0;[0X
    [4X[ [ q8_M1^4, [ [ 1, <identity ...>] ], <identity. ..> ], [0X
    [4X  [ q8_M2^4, [ [ 2, <identity ...>] ], <identity ...> ], [0X
    [4X  [ q8_M1*q8_M2*q8_M1*q8_M4, [ [ 3, <identity ...> ] ], <identity ...> ],   [0X
    [4X  [ q8_M1^2*q8_M2^2, [ [ 4, <identity ...> ] ], <identity ...> ], [0X
    [4X  [ q8_M1*q8_M3, [ ], <identity ...> ], [ q8_M2*q8_M4, [ ], <identity ...> ], [0X
    [4X  [ q8_M3*q8_M1, [ ], <identity ...> ], [ q8_M4*q8_M2, [ ], <identity ...> ] ] [0X
    [4Xgap> l1 := LoggedOnePassKB( l0 );;[0X
    [4Xgap> Length( l1 ); [0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  [1X3.1-2 LoggedKnuthBendix[0m
  
  [2X> LoggedKnuthBendix( [0X[3Xloggedrules[0X[2X ) ________________________________[0Xoperation
  [2X> LoggedRewriteReduce( [0X[3Xloggedrules[0X[2X ) ______________________________[0Xoperation
  
  The  function  [10XLoggedRewriteReduce[0m  removes  unnecessary rules from a logged
  rewrite system. It works on the same principle as [10XRewriteReduce[0m.
  
  The   function  [10XLoggedKnuthBendix[0m  repeatedly  applies  [10XLoggedOnePassKB[0m  and
  [10XLoggedRewriteReduce[0m until no new rules are added and no unnecessary ones are
  included. The output is a reduced complete logged rewrite system.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> l1 := LoggedRewriteReduce( l1 );[0X
    [4X[ [ q8_M1*q8_M3, [ ], <identity ...> ], [0X
    [4X  [ q8_M2^2, [ [ -4, <identity ...> ], [ 2, q8_M1^-2 ] ], q8_M1^2 ], [0X
    [4X  [ q8_M2*q8_M4, [ ], <identity ...> ], [ q8_M3*q8_M1, [ ], <identity ...> ], [0X
    [4X      [ q8_M4*q8_M2, [ ], <identity ...> ], [0X
    [4X  [ q8_M1^3, [ [ 1, <identity. ..> ] ], q8_M3 ], [0X
    [4X  [ q8_M1^2*q8_M2, [ [ 4, <identity. ..> ] ], q8_M4 ], [0X
    [4X  [ q8_M1*q8_M2*q8_M1, [ [ 3, <identity ...> ] ], q8_M2 ], [0X
    [4X  [ q8_M2*q8_M1*q8_M4, [ [ 3, q8_M3^-1 ] ], q8_M3] ][0X
    [4Xgap> l2 := LoggedKnuthBendix( l1 );[0X
    [4X[ [ q8_M1*q8_M3, [ ], <identity ...> ], [0X
    [4X  [ q8_M2*q8_M1, [ [ 3, q8_M3^-1 ], [-1, <identity. ..> ], [ 4, q8_M1^-1 ] ], [0X
    [4X      q8_M1*q8_M4 ], [0X
    [4X  [ q8_M2^2, [ [ -4, <identity ...> ], [2, q8_M1^-2] ], q8_M1^2 ], [0X
    [4X  [ q8_M2*q8_M3, [ [ -3, <identity ...> ] ], q8_M1*q8_M2 ], [0X
    [4X  [ q8_M2*q8_M4, [ ], <identity ...> ], [ q8_M3*q8_M1, [ ], <identity ...> ], [0X
    [4X  [ q8_M3*q8_M2, [ [ -1, <identity ...>], [4, q8_M1^-1 ] ], q8_M1*q8_M4 ],[0X
    [4X  [ q8_M3^2, [ [ -1, <identity ...>] ], q8_M1^2 ], [0X
    [4X  [ q8_M3*q8_M4, [ [ -1, <identity ...>], [ -2, q8_M1^-2], [0X
    [4X        [ 4, <identity ...> ], [ 3, q8_M3^-1*q8_M2^-1 ], [0X
    [4X        [ -3, <identity. ..> ] ], q8_M1*q8_M2 ], [0X
    [4X  [ q8_M4*q8_M1, [ [ -4, <identity ...> ], [ 3, q8_M1^-1 ] ], q8_M1*q8_M2 ], [0X
    [4X  [ q8_M4*q8_M2, [ ], <identity ...> ], [0X
    [4X  [ q8_M4*q8_M3, [ [ -3, q8_M3^-1*q8_M4^-1] ], q8_M1*q8_M4 ], [0X
    [4X  [ q8_M4^2, [ [ -4, <identity. ..> ] ], q8_M1^2 ], [0X
    [4X  [ q8_M1^3, [ [ 1, <identity ...> ] ], q8_M3 ], [0X
    [4X  [ q8_M1^2*q8_M2, [ [4, <identity. ..> ] ], q8_M4 ], [0X
    [4X  [ q8_M1^2*q8_M4, [ [ -4, q8_M1^-2], [ 1, <identity ...> ] ], q8_M2 ] ] [0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  
  [1X3.2 Logged reduction of a word[0X
  
  [1X3.2-1 LoggedReduceWordKB[0m
  
  [2X> LoggedReduceWordKB( [0X[3Xword, loggedrules[0X[2X ) _________________________[0Xoperation
  [2X> LoggedOnePassReduceWord( [0X[3Xword, loggedrules[0X[2X ) ____________________[0Xoperation
  [2X> ShorterLoggedRule( [0X[3Xlogrule1, logrule2[0X[2X ) _________________________[0Xoperation
  
  Given    a    word    and    a   logged   rewrite   system,   the   function
  [10XLoggedOnePassReduceWord[0m   makes   one   reduction   of   the   word  (as  in
  [10XOnePassReduceWord[0m) and records this, using the log part of the rule used and
  the position in the original word of the replaced part.
  
  The  function  [10XLoggedReduceWordKB[0m repeatedly applies [10XOnePassLoggedReduceWord[0m
  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 [10Xloggedrules[0m 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  [10XShorterLoggedrule[0m  decides  whether one logged rule is better
  than  another,  using  the  same  criteria as [10XShorterRule[0m. In the example we
  perform  logged  reductions  of  [10Xw0[0m corresponding to the ordinary reductions
  performed in the previous chapter.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> w0; [0X
    [4Xq8_M2^9*q8_M1^9[0X
    [4Xgap> lw1 := LoggedOnePassReduceWord( w0, l0 );[0X
    [4X[ [ [ 1, q8_M2^-9 ], [ 2, <identity ...> ] ], q8_M2^5*q8_M1^5 ][0X
    [4Xgap> lw2 := LoggedReduceWordKB( w0, l0 ); [0X
    [4X[ [ [ 1, q8_M2^-9 ], [ 2, <identity ...> ], [ 1, q8_M2^-5 ],[0X
    [4X      [ 2, <identity ...> ] ], q8_M2*q8_M1 ][0X
    [4Xgap> lw2 := LoggedReduceWordKB( w0, l2 ); [0X
    [4X[ [ [ 3, q8_M3^-1*q8_M2^-8 ], [ -1, q8_M2^-8 ], [ 4, q8_M1^-1*q8_M2^-8 ],[0X
    [4X      [ -4, <identity ...> ], [ 2, q8_M1^-2 ],[0X
    [4X      [ -4, q8_M1^-1*q8_M2^-6*q8_M1^-2 ], [ 3, q8_M1^-2*q8_M2^-6*q8_M1^-2 ],[0X
    [4X      [ 1, q8_M2^-1*q8_M1^-2*q8_M2^-6*q8_M1^-2 ], [ 4, <identity ...> ],[0X
    [4X      [ 3, q8_M3^-1*q8_M2^-4*q8_M4^-1 ], [ -1, q8_M2^-4*q8_M4^-1 ],[0X
    [4X      [ 4, q8_M1^-1*q8_M2^-4*q8_M4^-1 ], [ -4, q8_M4^-1 ],[0X
    [4X      [ 2, q8_M1^-2*q8_M4^-1 ],[0X
    [4X      [ -3, q8_M1^-1*q8_M4^-1*q8_M1^-1*q8_M2^-2*q8_M1^-2*q8_M4^-1 ],[0X
    [4X      [ -4, <identity ...> ], [ 3, q8_M1^-1 ],[0X
    [4X      [ 1, q8_M2^-1*q8_M1^-2*q8_M4^-1*q8_M1^-1*q8_M2^-2*q8_M1^-1*q8_M2^[0X
    [4X            -1*q8_M1^-1 ],[0X
    [4X      [ 4, q8_M4^-1*q8_M1^-1*q8_M2^-2*q8_M1^-1*q8_M2^-1*q8_M1^-1 ],[0X
    [4X      [ 3, q8_M3^-1*q8_M1^-1 ], [ -1, q8_M1^-1 ], [ 4, q8_M1^-2 ],[0X
    [4X      [ -4, q8_M4^-1*q8_M1^-2 ], [ 2, q8_M1^-2*q8_M4^-1*q8_M1^-2 ],[0X
    [4X      [ -4, q8_M1^-2 ], [ 3, q8_M1^-3 ], [ -4, q8_M1^-2*q8_M2^-1*q8_M1^-3 ],[0X
    [4X      [ 1, <identity ...> ], [ 3, q8_M3^-2 ], [ -1, q8_M3^-1 ],[0X
    [4X      [ 4, q8_M1^-1*q8_M3^-1 ], [ -4, <identity ...> ], [ 3, q8_M1^-1 ],[0X
    [4X      [ 3, q8_M3^-1*q8_M1^-1 ], [ -1, q8_M1^-1 ], [ 4, q8_M1^-2 ],[0X
    [4X      [ -4, q8_M1^-2 ], [ 3, q8_M1^-3 ], [ 1, <identity ...> ],[0X
    [4X      [ -1, <identity ...> ], [ 4, q8_M1^-1 ] ], q8_M1*q8_M4 ][0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  [1X3.2-2 LoggedRewritingSystemFpGroup[0m
  
  [2X> LoggedRewritingSystemFpGroup( [0X[3Xloggedrules[0X[2X ) _____________________[0Xattribute
  
  Given   a  group  presentation,  the  function  [10XLoggedRewritingSystemFpGroup[0m
  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.  For  each  relator  [10Xrel[0m of the group there is a logged rule [10X[
  rel,  [  [  1,  rel] ], id][0m. For each inverse relator there is a logged rule
  [10X[gen*inv,  [],  id  ][0m.  It  then attempts a completion of the logged rewrite
  system.  The rules in the final system are partially ordered by the function
  [10XShorterLoggedRule[0m.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> LoggedRewritingSystemFpGroup( q8 );[0X
    [4X[ [ q8_M4*q8_M2, [ ], <identity ...> ], [ q8_M3*q8_Ml, [ ], <identity ...> ], [0X
    [4X    [ q8_M2*q8_M4, [ ], <identity ...> ], [0X
    [4X  [ q8_Ml*q8_M3, [ ], <identity ...> ], [0X
    [4X  [ q8_Ml^2*q8_M4, [ [ -8, q8_Ml^-2 ], [ 5, <identity ...> ] ], q8_M2 ], [0X
    [4X  [ q8_Ml^2*q8_M2, [ [ 8, <identity ...> ] ], q8_M4 ], [0X
    [4X  [ q8_Ml^3, [ [ 5, <identity ...> ] ], q8_M3 ], [0X
    [4X  [ q8_M4^2, [ [ -8, <identity ...> ] ], q8_Ml^2 ], [0X
    [4X  [ q8_M4*q8_M3, [ [ -7, q8_M3^-1*q8_M4^-1 ] ], q8_Ml*q8_M4 ], [0X
    [4X  [ q8_M4*q8_Ml, [ [ -8, <identity. ..> ], [ 7, q8_Ml^-1 ] ], q8_Ml*q8_M2 ], [0X
    [4X  [ q8_M3*q8_M4, [0X
    [4X      [ [ -5, <identity ...>], [ -6, q8_Ml^-2 ], [ 8, <identity ...> ], [0X
    [4X          [ 7, q8_M3^-1*q8_M2^-1 ], [ -7, <identity. ..> ] ], q8_Ml*q8_M2 ], [0X
    [4X  [ q8_M3^2, [ [ -5, <identity ...>] ], q8_Ml^2 ], [0X
    [4X  [ q8_M3*q8_M2, [ [ -5, <identity. ..> ], [ 8, q8_Ml^-1 ] ], q8_Ml*q8_M4 ], [0X
    [4X  [ q8_M2*q8_M3, [ [ -7, <identity ...> ] ], q8_M1*q8_M2 ], [0X
    [4X  [ q8_M2^2, [ [ -a, <identity ...> ], [ 6, q8_M1^-2 ] ], q8_M1^2 ], [0X
    [4X  [ q8_M2*q8_M1, [ [ 7, q8_M3^-1 ], [ -5, <identity ...> ], [ a, q8_M1^-1 ] ], [0X
    [4X      q8_M1*q8_M4 ] ] [0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
