  
  [1X9 Iterated monodromy groups[0X
  
  Iterated  monodromy  machines  are a special class of group FR machines (see
  Section  [14X3[0m)  with  attribute  [2XIMGRelator[0m  ([14X9.1-2[0m).  This attribute records a
  cyclic ordering of the generators of the machine whose product is trivial.
  
  The  interpretation  is  the  following: the machine encodes a [13XThurston map[0m,
  i.e.  a  post-critically  finite  topological  branched self-covering of the
  sphere S^2. Generators of the machine correspond to loops in the fundamental
  group  of  the  sphere (punctured at post-critical points), that circle once
  counter-clockwise  around  a  post-critical  point.  For more details on the
  connection between self-similar groups and Thurston maps, see [Nek05].
  
  IMG  elements  are  a  bit different from group FR elements: while we said a
  group  FR  element  is  trivial  if  and  only if its action on sequences is
  trivial,  we say that an IMG element g is trivial if there exists an integer
  N such that unfolding N times the recursion for g yields only trivial states
  (as elements of the underlying free group).
  
  
  [1X9.1 Creators and operations for IMG machines[0X
  
  [1X9.1-1 AsIMGMachine[0m
  
  [2X> AsIMGMachine( [0X[3Xm[, w][0X[2X ) __________________________________________[0Xoperation
  [6XReturns:[0X  An IMG FR machine.
  
  This function creates a new IMG FR machine, starting from a group FR machine
  [3Xm[0m. If a state [10Xw[0m is specified, and that state defines the trivial FR element,
  then it is used as [2XIMGRelator[0m ([14X9.1-2[0m); if the state [10Xw[0m is non-trivial, then a
  new  generator  [10Xf[0m  is  added  to  [3Xm[0m,  equal to the inverse of [10Xw[0m; and the IMG
  relator  is  chosen  to be [10Xw*f[0m. Finally, if no relator is specified, and the
  product  (in  some ordering) of the generators is trivial, then that product
  is used as IMG relator. In other cases, the method returns [9Xfail[0m.
  
  Note  that  IMG  elements  and FR elements are compared differently (see the
  example  below);  namely,  an  FR  element is trivial precisely when it acts
  trivially  on  sequences.  An IMG element is trivial precisely when a finite
  number  of  applications  of  free  cancellation,  the  IMG relator, and the
  decomposition map, result in trivial elements of the underlying free group.
  
  A  standard  FR  machine  can  be  recovered  from  an  IMG  FR  machine  by
  [2XAsGroupFRMachine[0m      ([14X3.3-4[0m),      [2XAsMonoidFRMachine[0m      ([14X3.3-4[0m),      and
  [2XAsSemigroupFRMachine[0m ([14X3.3-4[0m).
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> m := UnderlyingFRMachine(BasilicaGroup);[0X
    [4X<Mealy machine on alphabet [ 1 .. 2 ] with 3 states>[0X
    [4Xgap> g := AsGroupFRMachine(m);[0X
    [4X<FR machine with alphabet [ 1 .. 2 ] on Group( [ f1, f2 ] )>[0X
    [4Xgap> AsIMGMachine(g,Product(GeneratorsOfFRMachine(g)));[0X
    [4X<FR machine with alphabet [ 1 .. 2 ] on Group( [ f1, f2, t ] )/[ f1*f2*t ]>[0X
    [4Xgap> Display(last);[0X
    [4X G  |              1         2[0X
    [4X----+-----------------+---------+[0X
    [4X f1 |          <id>,2      f2,1[0X
    [4X f2 |          <id>,1      f1,2[0X
    [4X  t | f2^-1*f1*f2*t,2   f1^-1,1[0X
    [4X----+-----------------+---------+[0X
    [4XRelator: f1*f2*t[0X
    [4Xgap> g := AsGroupFRMachine(GuptaSidkiMachine);[0X
    [4X<FR machine with alphabet [ 1 .. 3 ] on Group( [ f1, f2 ] )>[0X
    [4Xgap> m := AsIMGMachine(g,GeneratorsOfFRMachine(g)[1]);[0X
    [4X<FR machine with alphabet [ 1 .. 3 ] on Group( [ f1, f2, t ] )/[ f1*t ]>[0X
    [4Xgap> x := FRElement(g,2)^3; IsOne(x);[0X
    [4X<3|identity ...>[0X
    [4Xtrue[0X
    [4Xgap> x := FRElement(m,2)^3; IsOne(x);[0X
    [4X<3#f2^3>[0X
    [4Xfalse[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.1-2 IMGRelator[0m
  
  [2X> IMGRelator( [0X[3Xm[0X[2X ) _________________________________________________[0Xattribute
  [6XReturns:[0X  The relator of the IMG FR machine.
  
  This attribute stores the product of generators that is trivial. In essence,
  it  records  an  ordering  of the generators whose product is trivial in the
  punctured sphere's fundamental group.
  
  [1X9.1-3 IsKneadingMachine[0m
  
  [2X> IsKneadingMachine( [0X[3Xm[0X[2X ) ___________________________________________[0Xproperty
  [2X> IsPlanarKneadingMachine( [0X[3Xm[0X[2X ) _____________________________________[0Xproperty
  [6XReturns:[0X  Whether [3Xm[0m is a (planar) kneading machine.
  
  A  [13Xkneading  machine[0m  is  a  special kind of Mealy machine, used to describe
  postcritically finite complex polynomials. It is a machine such that its set
  of  permutations  is  "treelike"  (see  [Nek05,  Â§6.7])  and such that each
  non-trivial state occurs exactly once among the outputs.
  
  Furthermore,  this  set  of  permutations  is  [13Xtreelike[0m  if  there exists an
  ordering  of  the  states  that  their  product in that order t is an adding
  machine; i.e. such that t's activity is a full cycle, and the product of its
  states  along  that  cycle  is conjugate to t. This element t represents the
  CarathÃ©odory loop around infinity.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> M := BinaryKneadingMachine("0");[0X
    [4XBinaryKneadingMachine("0*")[0X
    [4Xgap> Display(M);[0X
    [4X   |  1     2[0X
    [4X---+-----+-----+[0X
    [4X a | c,2   b,1[0X
    [4X b | a,1   c,2[0X
    [4X c | c,1   c,2[0X
    [4X---+-----+-----+[0X
    [4Xgap> IsPlanarKneadingMachine(M);[0X
    [4Xtrue[0X
    [4Xgap> IsPlanarKneadingMachine(GrigorchukMachine);[0X
    [4Xfalse[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.1-4 AsPolynomialFRMachine[0m
  
  [2X> AsPolynomialFRMachine( [0X[3Xm[, adder][0X[2X ) _____________________________[0Xoperation
  [2X> AsPolynomialIMGMachine( [0X[3Xm[, adder[, relator]][0X[2X ) _________________[0Xoperation
  [6XReturns:[0X  A polynomial FR machine.
  
  The  first  function  creates  a  new polynomial FR machine, starting from a
  group or Mealy machine. A [13Xpolynomial[0m machine is one that has a distinguished
  adding element, [2XAddingElement[0m ([14X10.1-5[0m).
  
  If   the   argument   is   a   Mealy   machine,   it  must  be  planar  (see
  [2XIsPlanarKneadingMachine[0m  ([14X9.1-3[0m)).  If  the argument is a group machine, its
  permutations  must  be  treelike,  and  its outputs must be such that, up to
  conjugation,  each  non-trivial  state  appears  exactly once as the product
  along all cycles of all states.
  
  If a second argument [3Xadder[0m is supplied, it is checked to represent an adding
  element, and is used as such.
  
  The  second function creates a new polynomial IMG machine, i.e. a polynomial
  FR  machine with an extra relation among the generators. the optional second
  argument  may  be  an adder (if [3Xm[0m is an IMG machine) or a relator (if [3Xm[0m is a
  polynomial  FR machine). Finally, if [3Xm[0m is a group FR machine, two arguments,
  an adder and a relator, may be specified.
  
  A  machine  without  the extra polynomial / IMG information may be recovered
  using [2XAsGroupFRMachine[0m ([14X3.3-4[0m).
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> M := PolynomialIMGMachine(2,[1/7],[]);; SetName(StateSet(M),"F"); M;[0X
    [4X<FR machine with alphabet [ 1, 2 ] and adder f4 on F/[ f4*f3*f2*f1 ]>[0X
    [4Xgap> Mi := AsIMGMachine(M);[0X
    [4X<FR machine with alphabet [ 1, 2 ] on F/[ f4*f3*f2*f1 ]>[0X
    [4Xgap> Mp := AsPolynomialFRMachine(M);[0X
    [4X<FR machine with alphabet [ 1, 2 ] and adder f4 on F>[0X
    [4Xgap> Mg := AsGroupFRMachine(M);[0X
    [4X<FR machine with alphabet [ 1, 2 ] on F>[0X
    [4Xgap>[0X
    [4Xgap> AsPolynomialIMGMachine(Mg);[0X
    [4X<FR machine with alphabet [ 1, 2 ] and adder f4 on F/[ f4*f3*f2*f1 ]>[0X
    [4Xgap> AsPolynomialIMGMachine(Mi);[0X
    [4X<FR machine with alphabet [ 1, 2 ] and adder f4 on F/[ f4*f3*f2*f1 ]>[0X
    [4Xgap> AsPolynomialIMGMachine(Mp);[0X
    [4X<FR machine with alphabet [ 1, 2 ] and adder f4 on F/[ f4*f3*f2*f1 ]>[0X
    [4Xgap> AsIMGMachine(Mg);[0X
    [4X<FR machine with alphabet [ 1, 2 ] on F4/[ f1*f4*f3*f2 ]>[0X
    [4Xgap> AsPolynomialFRMachine(Mg);[0X
    [4X<FR machine with alphabet [ 1, 2 ] and adder f4 on F4>[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.1-5 AddingElement[0m
  
  [2X> AddingElement( [0X[3Xm[0X[2X ) ______________________________________________[0Xattribute
  [6XReturns:[0X  The relator of the IMG FR machine.
  
  This  attribute  stores the product of generators that is an adding machine.
  In  essence,  it  records  an  ordering  of  the  generators  whose  product
  corresponds to the CarathÃ©odory loop around infinity.
  
  [1X9.1-6 PolynomialFRMachine[0m
  
  [2X> PolynomialFRMachine( [0X[3Xd, per, pre[0X[2X ) ______________________________[0Xoperation
  [2X> PolynomialIMGMachine( [0X[3Xd, per, pre[, formal][0X[2X ) ___________________[0Xoperation
  [2X> PolynomialMealyMachine( [0X[3Xd, per, pre[0X[2X ) ___________________________[0Xoperation
  [6XReturns:[0X  An IMG FR machine.
  
  This  function  creates  a  group,  IMG  or  Mealy  machine that describes a
  topological  polynomial.  The  polynomial  is  described symbolically in the
  language of [13Xexternal angles[0m. For more details, see [DH84] and [DH85] (in the
  quadratic  case),  [BFH92]  (in  the  preperiodic  case),  and [Poi] (in the
  general case).
  
  [3Xd[0m  is  the  degree  of  the  polynomial.  [3Xper[0m and [3Xpre[0m are lists of angles or
  preangles.  In  what follows, angles are rational numbers, considered modulo
  1.  Each entry in [3Xper[0m or [3Xpre[0m is either a rational (interpreted as an angle),
  or a list of angles [a_1,...,a_i] such that da_1=...=da_i. The angles in [3Xper[0m
  are  angles  landing at the root of a Fatou component, and the angles in [3Xpre[0m
  land on the Julia set.
  
  Note  that,  for IMG machines, the last generator of the machine produced is
  an  adding  machine,  representing  a  loop  going  counterclockwise  around
  infinity  (in  the compactification of C by a disk, this loop goes [13Xclockwise[0m
  around that disk).
  
  In  constructing  a  polynomial  IMG machine, one may specify a boolean flag
  [3Xformal[0m,  which defaults to [9Xtrue[0m. In a [13Xformal[0m recursion, distinct angles give
  distinct generators; while in a non-formal recursion, distinct angles, which
  land  at  the  same  point  in  the  Julia set, give a single generator. The
  simplest example where this occurs is angle 5/12 in the quadratic family, in
  which angles 1/3 and 2/3 land at the same point -- see the example below.
  
  The   attribute   [10XCorrespondence(m)[0m   records  the  angles  landing  on  the
  generators: [10XCorrespondence(m)[i][0m is a list [10X[a,s][0m where a is an angle landing
  on generator [10Xi[0m and s is [9X"Julia"[0m or [9X"Fatou"[0m.
  
  The  inverse  operation,  reconstructing the angles from the IMG machine, is
  [2XExternalAngles[0m ([14X9.1-7[0m).
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> PolynomialIMGMachine(2,[0],[]); # the adding machine[0X
    [4X<FR machine with alphabet [ 1 .. 2 ] on Group( [ f1, f2 ] )/[ f2*f1 ]>[0X
    [4Xgap> Display(last);[0X
    [4X G  |     1        2[0X
    [4X----+--------+--------+[0X
    [4X f1 | <id>,2     f1,1[0X
    [4X f2 |   f2,2   <id>,1[0X
    [4X----+--------+--------+[0X
    [4XRelator: f2*f1[0X
    [4Xgap> Display(PolynomialIMGMachine(2,[1/3],[])); # the Basilica[0X
    [4X G  |      1         2[0X
    [4X----+---------+---------+[0X
    [4X f1 | f1^-1,2   f2*f1,1[0X
    [4X f2 |    f1,1    <id>,2[0X
    [4X f3 |    f3,2    <id>,1[0X
    [4X----+---------+---------+[0X
    [4XRelator: f3*f2*f1[0X
    [4Xgap> Display(PolynomialIMGMachine(2,[],[1/6])); # z^2+I[0X
    [4X G  |            1         2[0X
    [4X----+---------------+---------+[0X
    [4X f1 | f1^-1*f2^-1,2   f2*f1,1[0X
    [4X f2 |          f1,1      f3,2[0X
    [4X f3 |          f2,1    <id>,2[0X
    [4X f4 |          f4,2    <id>,1[0X
    [4X----+---------------+---------+[0X
    [4XRelator: f4*f3*f2*f1[0X
    [4Xgap> PolynomialIMGMachine(2,[],[5/12]);[0X
    [4Xgap> PolynomialIMGMachine(2,[],[5/12]);[0X
    [4X<FR machine with alphabet [ 1, 2 ] and adder f5 on Group( [ f1, f2, f3, f4, f5 ] )/[ f5*f4*f3*f2*f1 ]>[0X
    [4Xgap> Correspondence(last);[0X
    [4X[ [ 1/3, "Julia" ], [ 5/12, "Julia" ], [ 2/3, "Julia" ], [ 5/6, "Julia" ] ][0X
    [4Xgap> PolynomialIMGMachine(2,[],[5/12],false);[0X
    [4X<FR machine with alphabet [ 1, 2 ] and adder f4 on Group( [ f1, f2, f3, f4 ] )/[ f4*f3*f2*f1 ]>[0X
    [4Xgap> Correspondence(last);[0X
    [4X[ [ [ 1/3, 2/3 ], "Julia" ], [ [ 5/12 ], "Julia" ], [ [ 5/6 ], "Julia" ] ][0X
  [4X------------------------------------------------------------------[0X
  
  The following construct the examples in Poirier's paper:
  
  [4X------------------------------------------------------------------[0X
    [4XPoirierExamples := function(arg)[0X
    [4X    if arg=[1] then[0X
    [4X        return PolynomialIMGMachine(2,[1/7],[]);[0X
    [4X    elif arg=[2] then[0X
    [4X        return PolynomialIMGMachine(2,[],[1/2]);[0X
    [4X    elif arg=[3,1] then[0X
    [4X        return PolynomialIMGMachine(2,[],[5/12]);[0X
    [4X    elif arg=[3,2] then[0X
    [4X        return PolynomialIMGMachine(2,[],[7/12]);[0X
    [4X    elif arg=[4,1] then[0X
    [4X        return PolynomialIMGMachine(3,[[3/4,1/12],[1/4,7/12]],[]);[0X
    [4X    elif arg=[4,2] then[0X
    [4X        return PolynomialIMGMachine(3,[[7/8,5/24],[5/8,7/24]],[]);[0X
    [4X    elif arg=[4,3] then[0X
    [4X        return PolynomialIMGMachine(3,[[1/8,19/24],[3/8,17/24]],[]);[0X
    [4X    elif arg=[5] then[0X
    [4X        return PolynomialIMGMachine(3,[[3/4,1/12],[3/8,17/24]],[]);[0X
    [4X    elif arg=[6,1] then[0X
    [4X        return PolynomialIMGMachine(4,[],[[1/4,3/4],[1/16,13/16],[5/16,9/16]]);[0X
    [4X    elif arg=[6,2] then[0X
    [4X        return PolynomialIMGMachine(4,[],[[1/4,3/4],[3/16,15/16],[7/16,11/16]]);[0X
    [4X    elif arg=[7] then[0X
    [4X        return PolynomialIMGMachine(5,[[0,4/5],[1/5,2/5,3/5]],[[1/5,4/5]]);[0X
    [4X    elif arg=[9,1] then[0X
    [4X        return PolynomialIMGMachine(3,[[0,1/3],[5/9,8/9]],[]);[0X
    [4X    elif arg=[9,2] then[0X
    [4X        return PolynomialIMGMachine(3,[[0,1/3]],[[5/9,8/9]]);[0X
    [4X    else[0X
    [4X        Error("Unknown Poirier example ",arg);[0X
    [4X    fi;[0X
    [4Xend;[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.1-7 ExternalAngles[0m
  
  [2X> ExternalAngles( [0X[3Xm[, full][0X[2X ) _____________________________________[0Xattribute
  [6XReturns:[0X  A [10X[degree,fatou,julia][0m description of [3Xm[0m.
  
  This operation is the inverse of [2XPolynomialIMGMachine[0m ([14X9.1-6[0m): it computes a
  choice of angles, describing landing rays on Fatou/Julia critical points.
  
  If the second argument [3Xfull[0m is present and equals [9Xtrue[0m, the function returns
  a  record  with fields [10Xdegree,fatou,julia,angle,twist[0m. The last two are: for
  each generator of [3Xm[0m the angle of a ray landing on it; and an automorphism of
  [3Xm[0m's stateset that puts the machine into a reasonably simple form.
  
  If  there  does  not  exist  a complex realization, namely if the machine is
  obstructed, then this command returns an obstruction, as a record. The field
  [10Xobstruction[0m  is  a  string, describing the obstruction: either "Dehn twist",
  with  fields  [10Xtwist[0m  a  free  group automorphism turning about the twist and
  [10Xmachine[0m  a  simplified machine on which this twist acts; or "Topological" if
  there  does  not  even  exist  a topological polynomial satisfying the given
  recursion;  or  "Collisions",  with  a field [10Xpairs[0m indicating which pairs of
  generators land at the same external ray.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> r := PolynomialIMGMachine(2,[1/7],[]);[0X
    [4X<FR machine with alphabet [ 1, 2 ] and adder f4 on Group( [ f1, f2, f3, f4 ] )/[ f4*f3*f2*f1 ]>[0X
    [4Xgap> F := StateSet(r);; SetName(F,"F");[0X
    [4Xgap> ExternalAngles(r);[0X
    [4X[ 2, [ [ 1/7, 9/14 ] ], [  ] ] # actually returns the angle 2/7[0X
    [4Xgap> ExternalAngles(r,true);[0X
    [4Xrec( degree := 2, twist := IdentityMapping( F ), fatou := [ [ 1/7, 9/14 ] ],[0X
    [4X     julia := [  ], angle := [ 4/7, 1/7, 2/7, 0 ] )[0X
    [4Xgap> twist := GroupHomomorphismByImages(F,F,GeneratorsOfGroup(F),[F.1^(F.2*F.1),F.2^F.1,F.3,F.4]);[0X
    [4X[ f1, f2, f3, f4 ] -> [ f1^-1*f2^-1*f1*f2*f1, f1^-1*f2*f1, f3, f4 ][0X
    [4Xgap> List([-10..10],i->2*ExternalAngles(r*twist^i)[2][1][1]);[0X
    [4X[ 4/7, 4/7, 4/7, 4/7, 4/7, 4/7, 4/7, 2/7, 4/7, 4/7,[0X
    [4X  2/7, 5/7, 4/7, 4/7, 5/7, 4/7, 4/7, 4/7, 4/7, 4/7, 4/7 ][0X
    [4Xgap> r := PolynomialIMGMachine(2,[],[1/6]);;[0X
    [4Xgap> F := StateSet(r);;[0X
    [4Xgap> twist := GroupHomomorphismByImages(F,F,GeneratorsOfGroup(F),[F.1,F.2^(F.3*F.2),F.3^F.2,F.4]);;[0X
    [4Xgap> ExternalAngles(r);[0X
    [4X[ 2, [  ], [ [ 1/12, 7/12 ] ] ][0X
    [4Xgap> ExternalAngles(r*twist);[0X
    [4X[ 2, [  ], [ [ 5/12, 11/12 ] ] ][0X
    [4Xgap> ExternalAngles(r*twist^2);[0X
    [4Xrec( machine := <FR machine with alphabet [ 1, 2 ] on F/[ f4*f1*f2*f3 ]>,[0X
    [4X     twist := [ f1, f2, f3, f4 ] -> [ f1, f3*f2*f3^-1, f3*f2*f3*f2^-1*f3^-1, f4 ],[0X
    [4X     obstruction := "Dehn twist" )[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.1-8 Lift[0m
  
  [2X> Lift( [0X[3Xm[, shift][0X[2X ) ______________________________________________[0Xattribute
  [6XReturns:[0X  The lift of a polynomial FR machine.
  
  This  operation constructs, for a polynomial FR machine representing a point
  in TeichmÃ¼ller space, the image of this point under Thurston's sigma map.
  
  Iteration  of  this  method is at the basis of [2XExternalAngles[0m ([14X9.1-7[0m). It is
  currently only implemented for polynomial maps.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> r := PolynomialIMGMachine(2,[],[1/6]);;[0X
    [4Xgap> F := StateSet(r);;[0X
    [4Xgap> twist := GroupHomomorphismByImages(F,F,GeneratorsOfGroup(F),[F.1,F.2^(F.3*F.2),F.3^F.2,F.4]);[0X
    [4X[ f1, f2, f3, f4 ] -> [ f1, f2^-1*f3^-1*f2*f3*f2, f2^-1*f3*f2, f4 ][0X
    [4Xgap> r=Lift(r);[0X
    [4Xtrue[0X
    [4Xgap> r2 := [r*twist^2];; # an obstructed map[0X
    [4Xgap> for i in [1..5] do Add(r2,Lift(r2[i])); od;[0X
    [4Xgap> r2[4]=r2[6];[0X
    [4Xtrue[0X
    [4Xgap> Display(r2[4]);[0X
    [4X G  |      1               2[0X
    [4X----+---------+---------------+[0X
    [4X f1 | f1^-1,2            f1,1[0X
    [4X f2 |    f1,1            f3,2[0X
    [4X f3 |  <id>,1   f3*f2*f3^-1,2[0X
    [4X f4 |    f4,2          <id>,1[0X
    [4X----+---------+---------------+[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.1-9 AsGroupFRMachine[0m
  
  [2X> AsGroupFRMachine( [0X[3Xf[0X[2X ) ___________________________________________[0Xattribute
  [2X> AsMonoidFRMachine( [0X[3Xf[0X[2X ) __________________________________________[0Xattribute
  [2X> AsSemigroupFRMachine( [0X[3Xf[0X[2X ) _______________________________________[0Xattribute
  [6XReturns:[0X  An FR machine.
  
  This  function creates an FR machine on a 1-letter alphabet, that represents
  the  endomorphism  [3Xf[0m.  It is specially useful when combined with products of
  machines; indeed the usual product of machines corresponds to composition of
  endomorphisms.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> f := FreeGroup(2);;[0X
    [4Xgap> h := GroupHomomorphismByImages(f,f,[f.1,f.2],[f.2,f.1*f.2]);[0X
    [4X[ f1, f2 ] -> [ f2, f1*f2 ][0X
    [4Xgap> m := AsGroupFRMachine(h);[0X
    [4X<FR machine with alphabet [ 1 ] on Group( [ f1, f2 ] )>[0X
    [4Xgap> mm := TensorProduct(m,m);[0X
    [4X<FR machine with alphabet [ 1 ] on Group( [ f1, f2 ] )>[0X
    [4Xgap> Display(mm);[0X
    [4X G  |         1[0X
    [4X----+------------+[0X
    [4X f1 |    f1*f2,1[0X
    [4X f2 | f2*f1*f2,1[0X
    [4X----+------------+[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.1-10 NormalizedPolynomialFRMachine[0m
  
  [2X> NormalizedPolynomialFRMachine( [0X[3Xm[0X[2X ) ______________________________[0Xattribute
  [2X> NormalizedPolynomialIMGMachine( [0X[3Xm[0X[2X ) _____________________________[0Xattribute
  [6XReturns:[0X  A polynomial FR machine.
  
  This function returns a new FR machine, in which the adding element has been
  put into a standard form t=[t,1,dots,1]s, where s is the long cycle i-> i-1.
  
  For  the  first  command,  the  machine  returned  is an FR machine; for the
  second, it is an IMG machine.
  
  [1X9.1-11 Mating[0m
  
  [2X> Mating( [0X[3Xm1, m2[, formal][0X[2X ) ______________________________________[0Xoperation
  [6XReturns:[0X  An IMG FR machine.
  
  This function "mates" two polynomial IMG machines.
  
  The  mating  is  defined  as  follows:  one removes a disc around the adding
  machine  in  [3Xm1[0m and [3Xm2[0m; one applies complex conjugation to [3Xm2[0m; and one glues
  the hollowed spheres along their boundary circle.
  
  The  optional  argument  [3Xformal[0m, which defaults to [9Xtrue[0m, specifies whether a
  [13Xformal[0m  mating  should be done; in a non-formal mating, generators of [3Xm1[0m and
  [3Xm2[0m  which  have  identical  angle should be treated as a single generator. A
  non-formal  mating is of course possible only if the machines are realizable
  -- see [2XExternalAngles[0m ([14X9.1-7[0m).
  
  The  attribute [10XCorrespondence[0m is a pair of homomorphisms, from the statesets
  of [3Xm1,m2[0m respectively to the stateset of the mating.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> # the Tan-Shishikura examples[0X
    [4Xgap> z := Indeterminate(COMPLEX_FIELD);;[0X
    [4Xgap> a := ComplexRootsOfUnivariatePolynomial((z-1)*(3*z^2-2*z^3)+1);;[0X
    [4Xgap> c := ComplexRootsOfUnivariatePolynomial((z^3+z)^3+z);;[0X
    [4Xgap> am := List(a,a->IMGMachine((a-1)*(3*z^2-2*z^3)+1));;[0X
    [4Xgap> cm := List(c,c->IMGMachine(z^3+c));;[0X
    [4Xgap> m := ListX(am,cm,Mating);;[0X
    [4Xgap> # m[2] is realizable[0X
    [4Xgap> RationalFunction(m[2]);[0X
    [4X((1.66408+I*0.668485)*z^3+(-2.59772+I*0.627498)*z^2+(-1.80694-I*0.833718)*z[0X
    [4X  +(1.14397-I*1.38991))/((-1.52357-I*1.27895)*z^3+(2.95502+I*0.234926)*z^2[0X
    [4X  +(1.61715+I*1.50244)*z+1)[0X
    [4Xgap> # m[6] is obstructed[0X
    [4Xgap> RationalFunction(m[6]);[0X
    [4Xrec( matrix := [ [ 1/2, 1 ], [ 1/2, 0 ] ], machine := <FR machine with alphabet[0X
    [4X    [ 1, 2, 3 ] on Group( [ f1, f2, f3, g1, g2, g3 ] )/[ f2*f3*f1*g1*g3*g2 ]>,[0X
    [4X  obstruction := [ f1^-1*f3^-1*f2^-1*f1*f2*f3*f1*g2^-1*g3^-1*f1^-1*f3^-1*f2^-1,[0X
    [4X      f2*f3*f1*f2*f3*f1*g2*f1^-1*f3^-1*f2^-1*f1^-1*f3^-1 ],[0X
    [4X  spider := <spider on <triangulation with 8 vertices, 36 edges and[0X
    [4X    12 faces> marked by GroupHomomorphismByImages( Group( [ f1, f2, f3, g1, g2, g3[0X
    [4X     ] ), Group( [ f1, f2, f3, f4, f5 ] ), [ f1, f2, f3, g1, g2, g3 ],[0X
    [4X    [ f1*f4*f2^-1*f1*f4^-1*f1^-1, f1*f4*f2^-1*f1*f4*f5^-1*f1^-1*f2*f4^-1*f1^-1,[0X
    [4X      f1*f4*f2^-1*f1*f5*f1^-1*f2*f4^-1*f1^-1, f2*f4^-1*f1^-1*f2*f1*f4*f2^-1,[0X
    [4X      f2*f4^-1*f3*f2^-1, f2*f4^-1*f1^-1*f3^-1*f4*f2^-1 ] )> )[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.1-12 DBRationalIMGGroup[0m
  
  [2X> DBRationalIMGGroup( [0X[3Xsequence/map[0X[2X ) _______________________________[0Xfunction
  [6XReturns:[0X  An IMG group from Dau's database.
  
  This function returns the iterated monodromy group from a database of groups
  associated  to  quadratic  rational maps. This database has been compiled by
  Dau Truong Tan [Tan02].
  
  When called with no arguments, this command returns the database contents in
  raw form.
  
  The  argments  can  be  a  sequence;  the  first  integer is the size of the
  postcritical  set,  the  second  argument  is  an index for the postcritical
  graph,  and  sometimes a third argument distinguishes between maps with same
  post-critical graph.
  
  If the argument is a rational map, the command returns the IMG group of that
  map,  assuming  its  canonical  quadratic  rational  form form exists in the
  database.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> DBRationalIMGGroup(z^2-1);[0X
    [4XIMG((z-1)^2)[0X
    [4Xgap> DBRationalIMGGroup(z^2+1); # not post-critically finite[0X
    [4Xfail[0X
    [4Xgap> DBRationalIMGGroup(4,1,1);[0X
    [4XIMG((z/h+1)^2|2h^3+2h^2+2h+1=0,h~-0.64)[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.1-13 PostCriticalMachine[0m
  
  [2X> PostCriticalMachine( [0X[3Xf[0X[2X ) _________________________________________[0Xfunction
  [6XReturns:[0X  The Mealy machine of [3Xf[0m's post-critical orbit.
  
  This  function  constructs  a  Mealy  machine  [10XP[0m  on the alphabet [10X[1][0m, which
  describes  the  post-critical set of [3Xf[0m. It is in fact an oriented graph with
  constant out-degree 1. It is most conveniently passed to [2XDraw[0m ([14X5.2-1[0m).
  
  The  attribute  [10XCorrespondence(P)[0m  is the list of values associated with the
  stateset of [10XP[0m.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> z := Indeterminate(Rationals,"z");;[0X
    [4Xgap> m := PostCriticalMachine(z^2);[0X
    [4X<Mealy machine on alphabet [ 1 ] with 2 states>[0X
    [4Xgap> Display(m);[0X
    [4X   |  1[0X
    [4X---+-----+[0X
    [4X a | a,1[0X
    [4X b | b,1[0X
    [4X---+-----+[0X
    [4Xgap> Correspondence(m);[0X
    [4X[ 0, infinity ][0X
    [4Xgap> m := PostCriticalMachine(z^2-1);; Display(m); Correspondence(m);[0X
    [4X   |  1[0X
    [4X---+-----+[0X
    [4X a | c,1[0X
    [4X b | b,1[0X
    [4X c | a,1[0X
    [4X---+-----+[0X
    [4X[ -1, infinity, 0 ][0X
  [4X------------------------------------------------------------------[0X
  
  
  [1X9.2 Spiders[0X
  
  [5XFR[0m  contains  an  implementation  of the Thurston-Hubbard-Schleicher "spider
  algorithm" [HS94] that constructs a rational map from an IMG recursion. This
  implementation does not give rigourous results, but relies of floating-point
  approximation.  In particular, various floating-point parameters control the
  proper  functioning  of  the algorithm. They are stored in a record, [10XEPS@fr[0m.
  Their meaning and default values are:
  
  [8X[10XEPS@fr.mesh := 10^-1[0m[8X[0m
        If  points  on  the unit sphere are that close, the triangulation mesh
        should be refined.
  
  [8X[10XEPS@fr.prec := 10^-6[0m[8X[0m
        If  points  on  the  unit  sphere  are that close, they are considered
        equal.
  
  [8X[10XEPS@fr.obst := 10^-1[0m[8X[0m
        If  points  on  the  unit sphere are that close, they are suspected to
        form a Thurston obstruction.
  
  [8X[10XEPS@fr.juliaiter := 10^3[0m[8X[0m
        In computing images of the Julia set, never recur deeper than that.
  
  [8X[10XEPS@fr.fast := 10^-1[0m[8X[0m
        If  the  spider moved less than that amount in the last iteration, try
        speeding  up  by  only wiggling the spider's legs, without recomputing
        it.
  
  [8X[10XEPS@fr.ratprec := 10^-10[0m[8X[0m
        The desired precision on the coefficients of the rational function.
  
  [1X9.2-1 DelaunayTriangulation[0m
  
  [2X> DelaunayTriangulation( [0X[3Xpoints[0X[2X ) _________________________________[0Xoperation
  [6XReturns:[0X  A Delaunay triangulation of the sphere.
  
  If  [3Xpoints[0m  is  a list of points on the unit sphere, represented by their 3D
  coordinates,  this function creates a triangulation of the sphere with these
  points  as  vertices.  This  triangulation  is  such  that the angles are as
  equilateral as possible.
  
  This  triangulation  is  a  recursive  collection  of  records, one for each
  vertex,  oriented  edge or face. Each such object has a [10Xpos[0m component giving
  its   coordinates;   and   an   [10Xindex[0m  component  identifying  it  uniquely.
  Additionally,  vertices  and  faces  have  a  [10Xn[0m  component which lists their
  neighbours   in   CCW   order,  and  edges  have  [10Xfrom,to,left,right,reverse[0m
  components.
  
  If  all  points  are  aligned  on  a great circle, or if all points are in a
  hemisphere, some points are added so as to make the triangulation simplicial
  with  all  edges  of  length  <pi.  These  vertices additionally have a [10Xfake[0m
  component set to [9Xtrue[0m.
  
  A  triangulation  may be plotted with [10XDraw[0m; this requires [5Xappletviewer[0m to be
  installed.  The  command  [10XDraw(t:detach)[0m detaches the subprocess after it is
  started.
  
  This  command  makes  essential  use  of  Renka's  package  "Algorithm  772"
  ([Ren97]), which must have been compiled before [5XGAP[0m was run.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> octagon := Concatenation(IdentityMat(3),-IdentityMat(3))*MACFLOAT_1;[0X
    [4Xgap> dt := DelaunayTriangulation(octagon);[0X
    [4X<triangulation with 6 vertices, 24 edges and 8 faces>[0X
    [4Xgap> dt!.v;[0X
    [4X[ <vertex 1>, <vertex 2>, <vertex 3>, <vertex 4>, <vertex 5>, <vertex 6> ][0X
    [4Xgap> last[1].n;[0X
    [4X[ <edge 17>, <edge 1>, <edge 2>, <edge 11> ][0X
    [4Xgap> last[1].from;[0X
    [4X<vertex 1>[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.2-2 LocateInTriangulation[0m
  
  [2X> LocateInTriangulation( [0X[3Xt[, seed], point[0X[2X ) _______________________[0Xoperation
  [6XReturns:[0X  The face in [3Xt[0m containing [3Xpoint[0m.
  
  This command locates the face in [3Xt[0m that contains [3Xpoint[0m; or, if [3Xpoint[0m lies on
  an edge or a vertex, it returns that edge or vertex.
  
  The  optional  second  argument  specifies a starting vertex, edge, face, or
  vertex  index from which to start the search. Its only effect is to speed up
  the algorithm.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> cube := Tuples([-1,1],3)/Sqrt(Float(3));;[0X
    [4Xgap> dt := DelaunayTriangulation(cube);[0X
    [4X<triangulation with 8 vertices, 36 edges and 12 faces>[0X
    [4Xgap> LocateInTriangulation(dt,dt!.v[1].pos);[0X
    [4X<vertex 1>[0X
    [4Xgap> LocateInTriangulation(dt,[3/5,0,4/5]*MACFLOAT_1);[0X
    [4X<face 9>[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.2-3 RationalFunction[0m
  
  [2X> RationalFunction( [0X[3X[z, ]m[0X[2X ) ______________________________________[0Xoperation
  [6XReturns:[0X  A rational function.
  
  This  command  runs  a  modification  of  Hubbard  and  Schleicher's "spider
  algorithm"  [HS94]  on  the  IMG  FR machine [3Xm[0m. It either returns a rational
  function  [10Xf[0m  whose  associated  machine  is  [3Xm[0m;  or  a record describing the
  Thurston obstruction to realizability of [10Xf[0m.
  
  This  obstruction record [10Xr[0m contains a list [10Xr.multicurve[0m of conjugacy classes
  in  [10XStateSet(m)[0m,  which  represent  short multicurves; a matrix [10Xr.mat[0m, and a
  spider [10Xr.spider[0m on which the obstruction was discovered.
  
  If  a  rational function is returned, it has preset attributes [10XSpider(f)[0m and
  [10XIMGMachine(f)[0m  which is a simplified version of [3Xm[0m. This rational function is
  also  normalized  so that its post-critical points have barycenter=0 and has
  two  post-critical  points  at  infinity  and  on  the  positive  real axis.
  Furthermore, if [3Xm[0m is polynomial-like, then the returned map is a polynomial.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> m := PolynomialIMGMachine(2,[1/3],[]);[0X
    [4X<FR machine with alphabet [ 1, 2 ] on Group( [ f1, f2, f3 ] )/[ f3*f2*f1 ]>[0X
    [4Xgap> RationalFunction(m);[0X
    [4X0.866025*z^2+(-1)*z+(-0.288675)[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.2-4 FRMachine[0m
  
  [2X> FRMachine( [0X[3Xf[0X[2X ) __________________________________________________[0Xoperation
  [2X> IMGMachine( [0X[3Xf[0X[2X ) _________________________________________________[0Xoperation
  [6XReturns:[0X  An IMG FR machine.
  
  This  function  computes a triangulation of the sphere, on the post-critical
  set  of  [3Xf[0m,  and  lifts  it through the map [3Xf[0m. the action of the fundamental
  group  of  the punctured sphere is then read into an IMG fr machine [10Xm[0m, which
  is returned.
  
  This machine has a preset attribute [10XSpider(m)[0m.
  
  An  approximation  of the Julia set of [3Xf[0m can be computed, and plotted on the
  spider, with the form [10XIMGMachine(f:julia)[0m or [10XIMGMachine(f:julia:=gridsize)[0m.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> z := Indeterminate(COMPLEX_FIELD);;[0X
    [4Xgap> IMGMachine(z^2-1);[0X
    [4X<FR machine with alphabet [ 1, 2 ] on Group( [ f1, f2, f3 ] )/[ f2*f1*f3 ]>[0X
    [4Xgap> Display(last);[0X
    [4X G  |            1        2[0X
    [4X----+---------------+--------+[0X
    [4X f1 |          f2,2   <id>,1[0X
    [4X f2 | f3^-1*f1*f3,1   <id>,2[0X
    [4X f3 |        <id>,2     f3,1[0X
    [4X----+---------------+--------+[0X
    [4XRelator: f2*f1*f3[0X
  [4X------------------------------------------------------------------[0X
  
  [1X9.2-5 FindThurstonObstruction[0m
  
  [2X> FindThurstonObstruction( [0X[3Xlist[0X[2X ) _________________________________[0Xoperation
  [6XReturns:[0X  A description of the obstruction corresponding to [3Xlist[0m, or [9Xfail[0m.
  
  This  method  accepts a list of IMG elements on the same underlying machine,
  and  treats these as representatives of conjugacy classes defining (part of)
  a multicurve. It computes whether these curves, when supplemented with their
  lifts  under  the recursion, constitute a Thurston obstruction, by computing
  its transition matrix.
  
  The method either returns [9Xfail[0m, if there is no obstruction, or a record with
  as  fields  [10Xmatrix,machine,obstruction[0m  giving  respectively  the transition
  matrix,  a  simplified  machine,  and  the  curves that constitute a minimal
  obstruction.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4Xgap> r := PolynomialIMGMachine(2,[],[1/6]);;[0X
    [4Xgap> F := StateSet(r);;[0X
    [4Xgap> twist := GroupHomomorphismByImages(F,F,GeneratorsOfGroup(F),[F.1,F.2^(F.3*F.2),F.3^F.2,F.4]);;[0X
    [4Xgap> ExternalAngles(r*twist^-1);[0X
    [4Xrec( machine := <FR machine with alphabet [ 1, 2 ] on F/[ f4*f1*f2*f3 ]>,[0X
    [4X     twist := [ f1, f2, f3, f4 ] -> [ f1, f3^-1*f2*f3, f3^-1*f2^-1*f3*f2*f3, f4 ],[0X
    [4X     obstruction := "Dehn twist" )[0X
    [4Xgap> FindThurstonObstruction([FRElement(last.machine,[2,3])]);[0X
    [4Xrec( matrix := [ [ 1 ] ], machine := <FR machine with alphabet [ 1, 2 ] on F/[ f4*f1*f2*f3 ]>, obstruction := [ f1^-1*f4^-1 ] )[0X
  [4X------------------------------------------------------------------[0X
  
