Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  group.gd   Sprache: unbekannt

 
#############################################################################
##
#W group.gd                                                 Laurent Bartholdi
##
##
#Y Copyright (C) 2006, Laurent Bartholdi
##
#############################################################################
##
##  This file declares the (semi)groups of FR and Mealy machines.
##
#############################################################################

#############################################################################
##
#C IsFRGroup . . . . . . . . . . . . . . . . . . . . .all self-similar groups
#C IsFRSemigroup . . . . . . . . . . . . . . . . .all self-similar semigroups
#C IsFRMonoid . . . . . . . . . . . . . . . . . . . .all self-similar monoids
##
## <#GAPDoc Label="IsFRGroup">
## <ManSection>
##   <Filt Name="IsFRGroup" Arg="obj"/>
##   <Filt Name="IsFRMonoid" Arg="obj"/>
##   <Filt Name="IsFRSemigroup" Arg="obj"/>
##   <Returns><K>true</K> if <A>obj</A> is a FR group/monoid/semigroup.</Returns>
##   <Description>
##     These functions accept <E>self-similar groups/monoids/semigroups</E>,
##     i.e. groups/monoids/semigroups whose elements are FR elements.
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareSynonym("IsFRGroup", IsFRElementCollection and IsGroup);
DeclareSynonym("IsFRSemigroup", IsFRElementCollection and IsSemigroup);
DeclareSynonym("IsFRMonoid", IsFRElementCollection and IsMonoid);
#############################################################################

#############################################################################
##
#A AlphabetOfFRSemigroup . . . . . . . . . . . . . . . . alphabet of the tree
##
DeclareAttribute("AlphabetOfFRSemigroup", IsFRSemigroup);
#############################################################################

#############################################################################
##
#F FRGroup
#F FRSemigroup
#F FRMonoid
##
## <#GAPDoc Label="FRGroup">
## <ManSection>
##   <Oper Name="FRGroup" Arg="{definition,}"/>
##   <Oper Name="FRMonoid" Arg="{definition,}"/>
##   <Oper Name="FRSemigroup" Arg="{definition,}"/>
##   <Returns>A new self-similar group/monoid/semigroup.</Returns>
##   <Description>
##     This function constructs a new FR group/monoid/semigroup,
##     generated by group FR elements. It receives as argument any
##     number of strings, each of which represents a generator of
##     the object to be constructed.
##
##     <P/> Each <A>definition</A> is of the form <C>"name=projtrans"</C>,
##     where each of <C>proj</C> and <C>trans</C> is optional.
##     <C>proj</C> is of the form <C><w1,...,wd></C>, where each
##     <C>wi</C> is a (possibly empty) word in the <C>name</C>s or is 1.
##     <C>trans</C> is either a permutation in disjoint cycle notation,
##     or a list, representing the images of a permutation.
##
##     <P/> The last argument may be one of the filters <C>IsMealyElement</C>,
##     <C>IsFRMealyElement</C> or <C>IsFRElement</C>. By default, if each of
##     the states of generators is a generator or 1, the elements of the
##     created object will be Mealy elements; otherwise, they will be
##     FR elements. Specifying such a filter requires them to be in the
##     appropriate category; e.g.,
##     <C>FRGroup("a=(1,2)",IsFRMealyElement)</C> asks for the resulting group
##     to be generated by FR-Mealy elements. The generators must of course be
##     finite-state.
## <Example><![CDATA[
## gap> FRGroup("a=(1,2)","b=(1,2,3,4,5)"); Size(last);
## <self-similar group over [ 1 .. 5 ] with 2 generators>
## 120
## gap> Dinfinity := FRGroup("a=(1,2)","b=<a,b>");
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> AssignGeneratorVariables(Dinfinity);
## #I  Assigned the global variables [ a, b ]
## gap> Order(a); Order(b); Order(a*b);
## 2
## 2
## infinity
## gap> ZZ := FRGroup("t=<,t>[2,1]");
## <self-similar group over [ 1 .. 2 ] with 1 generator>
## tau := FRElement([[[b,1],[1]]],[()],[1]);
## <2|f3>
## gap> IsSubgroup(Dinfinity,ZZ);
## false
## gap> IsSubgroup(Dinfinity^tau,ZZ);
## true
## gap> Index(Dinfinity^tau,ZZ);
## 2
## ]]></Example>
## <Example><![CDATA[
## gap> i4 := FRMonoid("s=(1,2)","f=<s,f>[1,1]");
## <self-similar monoid over [ 1 .. 2 ] with 2 generators>
## gap> f := GeneratorsOfMonoid(i4){[1,2]};;
## gap> for i in [1..10] do Add(f,f[i]*f[i+1]); od;
## gap> f[1]^2=One(m);
## true
## gap> f[2]^3=f[2];
## true
## gap> f[11]*f[10]^2=f[1]*Product(f{[5,7..11]})*f[10];
## true
## gap> f[12]*f[11]^2=f[2]*Product(f{[6,8..12]})*f[11];
## true
## ]]></Example>
## <Example><![CDATA[
## gap> i2 := FRSemigroup("f0=<f0,f0>(1,2)","f1=<f1,f0>[2,2]");
## <self-similar semigroup over [ 1 .. 2 ] with 2 generators>
## gap> AssignGeneratorVariables(i2);
## #I  Assigned the global variables [ "f0", "f1" ]
## gap> f0^2=One(i2);
## true
## gap> ForAll([0..10],p->(f0*f1)^p*(f1*f0)^p*f1=f1^2*(f0*f1)^p*(f1*f0)^p*f1);
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Attr Name="NewSemigroupFRMachine" Arg="..."/>
##   <Attr Name="NewMonoidFRMachine" Arg="..."/>
##   <Attr Name="NewGroupFRMachine" Arg="..."/>
##   <Returns>A new FR machine, based on string descriptions.</Returns>
##   <Description>
##     This command constructs a new FR machine, in a format similar to
##     <Ref Func="FRGroup"/>; namely, the arguments are strings of the form
##     "gen=<word-1,...,word-d>perm"; each <C>word-i</C> is a word in the
##     generators; and <C>perm</C> is a transformation,
##     either written in disjoint cycle or in images notation.
##
##     <P/>Except in the semigroup case, <C>word-i</C> is allowed to be the
##     empty string; and the "<...>" may be skipped altogether.
##     In the group or IMG case, each <C>word-i</C> may also contain inverses.
##         
##     <P/>The following example constructs the "universal Grigorchuk machine".
## <Example><![CDATA[
## gap> m := NewGroupFRMachine("a=(1,2)(3,4)(5,6)","b=<a,b,a,b,,b>",
##      "c=<a,c,,c,a,c>","d=<,d,a,d,a,d>");
## gap> <FR machine with alphabet [ 1, 2, 3, 4, 5, 6 ] on Group( [ a, b, c, d ] )>
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareGlobalFunction("FRGroup");
DeclareGlobalFunction("FRSemigroup");
DeclareGlobalFunction("FRMonoid");
DeclareGlobalFunction("NewSemigroupFRMachine");
DeclareGlobalFunction("NewMonoidFRMachine");
DeclareGlobalFunction("NewGroupFRMachine");
#############################################################################

#############################################################################
##
#O FRGroupByVirtualEndomorphism
##
## <#GAPDoc Label="FRGroupByVirtualEndomorphism">
## <ManSection>
##   <Oper Name="FRGroupByVirtualEndomorphism" Arg="hom[,transversal]"/>
##   <Returns>A new self-similar group.</Returns>
##   <Description>
##     This function constructs a new FR group <C>P</C>, generated by group FR
##     elements. Its first argument is a virtual endomorphism of a group
##     <C>G</C>, i.e. a homomorphism from a subgroup <C>H</C> to <C>G</C>.
##     The constructed FR group acts on a tree with alphabet a transversal
##     of <C>H</C> in <C>G</C> (represented as <C>[1..d]</C>), and is
##     a homomorphic image of <C>G</C>. The stabilizer of the first-level
##     vertex corresponding to the trivial coset is the image of <C>H</C>.
##     This function is loosely speaking an inverse of
##     <Ref Oper="VirtualEndomorphism"/>.
##
##     <P/> The optional second argument is a transversal of <C>H</C> in
##     <C>G</C>, either of type <C>IsRightTransversal</C> or a list.
##
##     <P/> Furthermore, an option "MealyElement" can be passed to the
##     function, as <C>FRGroupByVirtualEndomorphism(f:MealyElement)</C>,
##     to require the resulting group to be generated by Mealy elements
##     and not FR elements. The call will succeed, of course, only if the
##     representation of <C>G</C> is finite-state.
##
##     <P/> The resulting FR group has an attribute <C>Correspondence(P)</C>
##     that records a homomorphism from <C>G</C> to <C>P</C>.
##
##     <P/> The example below constructs the binary adding machine, and a
##     non-standard representation of it.
## <Example><![CDATA[
## gap> G := FreeGroup(1);
## <free group on the generators [ f1 ]>
## gap> f := GroupHomomorphismByImages(Group(G.1^2),G,[G.1^2],[G.1]);
## [ f1^2 ] -> [ f1 ]
## gap> H := FRGroupByVirtualEndomorphism(f);
## <self-similar group over [ 1 .. 2 ] with 1 generator>
## gap> Display(H.1);
##     |     1      2
## ----+--------+------+
##  x1 | <id>,2   x1,1
## ----+--------+------+
## Initial state: x1
## gap> Correspondence(H);
## [ f1 ] -> [ <2|x1> ]
## gap> H := FRGroupByVirtualEndomorphism(f,[G.1^0,G.1^3]);;
## gap> Display(H.1);
##     |      1        2
## ----+---------+--------+
##  x1 | x1^-1,2   x1^2,1
## ----+---------+--------+
## Initial state: x1
## gap> H := FRGroupByVirtualEndomorphism(f:MealyElement);
## <self-similar group over [ 1 .. 2 ] with 1 generator>
## gap> Display(H.1);
##    |  1     2
## ---+-----+-----+
##  a | b,2   a,1
##  b | b,1   b,2
## ---+-----+-----+
## Initial state: a
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareOperation("FRGroupByVirtualEndomorphism",[IsGroupHomomorphism]);
DeclareOperation("FRGroupByVirtualEndomorphism",[IsGroupHomomorphism,IsList]);
#############################################################################

#############################################################################
##
#O VirtualEndomorphism
##
## <#GAPDoc Label="VirtualEndomorphism">
## <ManSection>
##   <Oper Name="VirtualEndomorphism" Arg="g/m,v"/>
##   <Returns>The virtual endomorphism at vertex <A>v</A>.</Returns>
##   <Description>
##     This function returns the homomorphism from <C>Stabilizer(g,v)</C>
##     to <A>g</A>, defined by computing the state at <A>v</A>.
##     It is loosely speaking an inverse of
##     <Ref Oper="FRGroupByVirtualEndomorphism"/>.
##
##     <P/> The first argument <A>m</A> may also be an FR machine.
## <Example><![CDATA[
## gap> A := SCGroup(MealyMachine([[2,1],[2,2]],[(1,2),()]));
## <self-similar group over [ 1 .. 2 ] with 1 generator>
## gap> f := VirtualEndomorphism(A,1);
## MappingByFunction( <self-similar group over [ 1 .. 2 ] with
## 1 generator>, <self-similar group over [ 1 .. 2 ] with
## 1 generator>, function( g ) ... end )
## gap> ((A.1)^2)^f=A.1;
## true
## gap> B := FRGroupByVirtualEndomorphism(f);
## <self-similar group over [ 1 .. 2 ] with 1 generator>
## gap> A=B;
## true
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareOperation("VirtualEndomorphism",[IsFRGroup,IsObject]);
#############################################################################

#############################################################################
##
#O SEARCH@
##
## <#GAPDoc Label="SEARCH@">
## <ManSection>
##   <Var Name="SEARCH@"/>
##   <Description>
##     This variable controls the search mechanism in FR groups. It is
##     a record with in particular entries <C>radius</C> and <C>depth</C>.
##
##     <P/> <C>radius</C> limits the search in FR groups to balls of
##     that radius in the generating set. For example, the command
##     <C>x in G</C> will initiate a search in <C>G</C> to attempt to express
##     <C>x</C> as a reasonably short word in the generators of <C>G</C>.
##
##     <P/> <C>depth</C> limits the level of the tree on which quotients
##     of FR groups should be considered. Again for the command <C>x in G</C>,
##     deeper and deeper quotients will be considered, in the hope of finding
##     a quotient of <C>G</C> to which <C>x</C> does not belong.
##
##     <P/> A primitive mechanism is implemented to search alternatively for
##     a quotient disproving <C>x in G</C> and a word proving <C>x in G</C>.
##
##     <P/> When the limits are reached and the search was unsuccessful, an
##     interactive <C>Error()</C> is raised, to let the user increase their
##     values.
##
##     <P/> Specific limits can be passed to any command via the options
##     <C>FRdepth</C> and <C>FRradius</C>, as for example in
##     <C>Size(G:FRdepth:=3,FRradius:=5)</C>.
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
BindGlobal("SEARCH@", rec(depth := 6, volume := 5000));
#############################################################################

#############################################################################
##
#O SCGroup. . . . . . . . . . . . . . . . . . . . . . . . .state-closed group
#O SCSemigroup. . . . . . . . . . . . . . . . . . . . .state-closed semigroup
#O SCMonoid. . . . . . . . . . . . . . . . . . . . . . . .state-closed monoid
##
## <#GAPDoc Label="SCGroup">
## <ManSection>
##   <Oper Name="SCGroup" Arg="m"/>
##   <Oper Name="SCGroupNC" Arg="m"/>
##   <Oper Name="SCMonoid" Arg="m"/>
##   <Oper Name="SCMonoidNC" Arg="m"/>
##   <Oper Name="SCSemigroup" Arg="m"/>
##   <Oper Name="SCSemigroupNC" Arg="m"/>
##   <Returns>The state-closed group/monoid/semigroup generated by the machine <A>m</A>.</Returns>
##   <Description>
##     This function constructs a new FR group/monoid/semigroup <C>g</C>,
##     generated by all the states of the FR machine <A>m</A>.
##     There is a bijective correspondence between
##     <C>GeneratorsOfFRMachine(m)</C> and the generators of <C>g</C>, which
##     is accessible via <C>Correspondence(g)</C>
##     (See <Ref Attr="Correspondence" Label="FR semigroup"/>); it is a
##     homomorphism from the stateset of <A>m</A> to <C>g</C>, or a list
##     indicating for each state of
##     <A>m</A> a corresponding generator index in the generators of <C>g</C>
##     (with negatives for inverses, and 0 for identity).
##
##     <P/> In the non-<C>NC</C> forms, redundant (equal, trivial
##     or mutually inverse) states are removed from the generating set of
##     <C>g</C>.
## <Example><![CDATA[
## gap> b := MealyMachine([[3,2],[3,1],[3,3]],[(1,2),(),()]);; g := SCGroupNC(b);
## <self-similar group over [ 1 .. 2 ] with 3 generators>
## gap> Size(g);
## infinity
## gap> IsOne(Comm(g.2,g.2^g.1));
## true
## ]]></Example>
## <Example><![CDATA[
## gap> i4machine := MealyMachine([[3,3],[1,2],[3,3]],[(1,2),[1,1],()]);
## <Mealy machine on alphabet [ 1, 2 ] with 3 states>
## gap> IsInvertible(i4machine);
## false
## gap> i4 := SCMonoidNC(i4machine);
## <self-similar monoid over [ 1 .. 2 ] with 3 generators>
## gap> f := GeneratorsOfMonoid(i4){[1,2]};;
## gap> for i in [1..10] do Add(f,f[i]*f[i+1]); od;
## gap> f[1]^2=One(m);
## true
## gap> f[2]^3=f[2];
## true
## gap> f[11]*f[10]^2=f[1]*Product(f{[5,7..11]})*f[10];
## true
## gap> f[12]*f[11]^2=f[2]*Product(f{[6,8..12]})*f[11];
## true
## ]]></Example>
## <Example><![CDATA[
## gap> i2machine := MealyMachine([[1,1],[2,1]],[(1,2),[2,2]]);
## <Mealy machine on alphabet [ 1, 2 ] with 2 states>
## gap> i2 := SCSemigroupNC(i2machine);
## <self-similar semigroup over [ 1 .. 2 ] with 2 generators>
## gap> f0 := GeneratorsOfSemigroup(i2)[1];; f1 := GeneratorsOfSemigroup(i2)[2];;
## gap> f0^2=One(i2);
## true
## gap> ForAll([0..10],p->(f0*f1)^p*(f1*f0)^p*f1=f1^2*(f0*f1)^p*(f1*f0)^p*f1);
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Attr Name="Correspondence" Arg="g" Label="FR semigroup"/>
##   <Returns>A correspondence between the generators of the underlying FR machine of <A>g</A> and <A>g</A>.</Returns>
##   <Description>
##     If <A>g</A> was created as the state closure of an FR machine <C>m</C>,
##     this attribute records the correspondence between <C>m</C> and <A>g</A>.
##
##     <P/> If <C>m</C> is a group/monoid/semigroup/algebra FR machine, then
##     <C>Correspondence(g)</C> is a homomorphism from the stateset of <C>m</C>
##     to <A>g</A>.
##
##     <P/> If <C>m</C> is a Mealy or vector machine, then
##     <C>Correspondence(g)</C> is a list, with in position <M>i</M> the
##     index in the generating set of <A>g</A> of state number <M>i</M>.
##     This index is 0 if there is no corresponding generator because the
##     state is trivial, and is negative if there is no corresponding
##     generator because the inverse of state number <M>i</M> is a
##     generator.
##
##     <P/> See <Ref Oper="SCGroupNC"/>, <Ref Oper="SCGroup"/>,
##     <Ref Oper="SCMonoidNC"/>, <Ref Oper="SCMonoid"/>,
##     <Ref Oper="SCSemigroupNC"/>, <Ref Oper="SCSemigroup"/>,
##     <Ref Oper="SCAlgebraNC"/>, <Ref Oper="SCAlgebra"/>,
##     <Ref Oper="SCAlgebraWithOneNC"/>, and <Ref Oper="SCAlgebraWithOne"/>
##     for examples.
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareOperation("SCGroupNC", [IsFRMachine]);
DeclareOperation("SCMonoidNC", [IsFRMachine]);
DeclareOperation("SCSemigroupNC", [IsFRMachine]);
DeclareOperation("SCGroup", [IsFRMachine]);
DeclareOperation("SCMonoid", [IsFRMachine]);
DeclareOperation("SCSemigroup", [IsFRMachine]);
DeclareAttribute("Correspondence", IsFRSemigroup);
#############################################################################

#############################################################################
##
#O  FullSCGroup. . . . . . . . . . . . . . . . . . maximal state-closed group
#O  FullSCMonoid. . . . . . . . . . . . . . . . . maximal state-closed monoid
#O  FullSCSemigroup. . . . . . . . . . . . . . maximal state-closed semigroup
##
## <#GAPDoc Label="FullSCGroup">
## <ManSection>
##   <Func Name="FullSCGroup" Arg="..."/>
##   <Func Name="FullSCMonoid" Arg="..."/>
##   <Func Name="FullSCSemigroup" Arg="..."/>
##   <Returns>A maximal state-closed group/monoid/semigroup on the alphabet <A>a</A>.</Returns>
##   <Description>
##     This function constructs a new FR group, monoid or semigroup, which
##     contains all transformations with given properties of the tree
##     with given alphabet.
##
##     <P/> The arguments can be, in any order: a semigroup, specifying which
##     vertex actions are allowed; a set or domain, specifying the alphabet
##     of the tree; an integer, specifying the maximal depth of elements;
##     and a filter among <Ref Prop="IsFinitaryFRElement"/>,
##     <Ref Prop="IsBoundedFRElement"/>,
##     <Ref Prop="IsPolynomialGrowthFRElement"/> and
##     <Ref Prop="IsFiniteStateFRElement"/>.
##
##     <P/> This object serves as a container for all
##     FR elements with alphabet <A>a</A>. Random elements can be drawn
##     from it; they are Mealy elements with a random number of states, and
##     with the required properties.
## <Example><![CDATA[
## gap> g := FullSCGroup([1..3]);
## FullSCGroup([ 1 .. 3 ]);
## gap> IsSubgroup(g,GuptaSidkiGroup);
## true
## gap> g := FullSCGroup([1..3],Group((1,2,3)));
## FullSCGroup([ 1 .. 3 ], Group( [ (1,2,3) ] ))
## gap> IsSubgroup(g,GuptaSidkiGroup);
## true
## gap> IsSubgroup(g,GrigorchukGroup);
## false
## gap> Random(g);
## <Mealy element on alphabet [ 1, 2, 3 ] with 2 states, initial state 1>
## gap> Size(FullSCGroup([1,2],3));
## 128
## gap> g := FullSCMonoid([1..2]);
## FullSCMonoid([ 1 .. 2 ])
## gap> IsSubset(g,AsTransformation(FullSCGroup([1..2])));
## true
## gap> IsSubset(g,AsTransformation(GrigorchukGroup));
## true
## gap> g := FullSCSemigroup([1..3]);
## FullSCSemigroup([ 1 .. 3 ])
## gap> h := FullSCSemigroup([1..3],Semigroup(Transformation([1,1,1])));
## FullSCSemigroup([ 1 .. 3 ], Semigroup( [ [ 1, 1, 1 ] ] ))
## gap> Size(h);
## 1
## gap> IsSubset(g,h);
## true
## gap> g=FullSCMonoid([1..3]);
## true
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareGlobalFunction("FullSCGroup");
DeclareGlobalFunction("FullSCSemigroup");
DeclareGlobalFunction("FullSCMonoid");
DeclareAttribute("FullSCFilter", IsFRSemigroup);
DeclareAttribute("FullSCVertex", IsFRSemigroup);
DeclareProperty("HasFullSCData", IsFRSemigroup);
#############################################################################

#############################################################################
##
#O TopVertexTransformations. . the (semi)group acting at the root of the tree
#O VertexTransformations. . . . . . . . . . . . . at all vertices of the tree
##
## <#GAPDoc Label="VertexTransformations">
## <ManSection>
##   <Attr Name="TopVertexTransformations" Arg="g"/>
##   <Returns>The transformations at the root under the action of <A>g</A>.</Returns>
##   <Description>
##     This function returns the permutation group, or the transformation
##     group/semigroup/monoid, of all activities of all elements under the
##     root vertex of the tree on which <A>g</A> acts.
##
##     <P/> It is a synonym for <C>PermGroup(g,1)</C> or
##     <C>TransformationMonoid(g,1)</C> or <C>TransformationSemigroup(g,1)</C>.
## <Example><![CDATA[
## gap> TopVertexTransformations(GrigorchukGroup);
## Group([ (), (1,2) ])
## gap> IsTransitive(last,AlphabetOfFRSemigroup(GrigorchukGroup));
## true
## gap> TopVertexTransformations(FullSCMonoid([1..3]));
## <monoid with 3 generators>
## gap> Size(last);
## 27
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Attr Name="VertexTransformations" Arg="g" Label="FR semigroup"/>
##   <Returns>The transformations at all vertices under the action of <A>g</A>.</Returns>
##   <Description>
##     This function returns the permutation group, or the transformation
##     group/monoid/semigroup, of all activities of all elements under all
##     vertices of the tree on which <A>g</A> acts.
##
##     <P/> This is the smallest group/monoid/semigroup <C>P</C> such that
##     <A>g</A> is a subset of <C>FullSCGroup(AlphabetOfFRSemigroup(g),P)</C>
##     or <C>FullSCMonoid(AlphabetOfFRSemigroup(g),P)</C> or
##     <C>FullSCSemigroup(AlphabetOfFRSemigroup(g),P)</C>.
## <Example><![CDATA[
## gap> VertexTransformations(GuptaSidkiGroup);
## Group([ (), (1,2,3), (1,3,2) ])
## gap> TopVertexTransformations(Group(GuptaSidkiGroup.2));
## Group(())
## gap> VertexTransformations(Group(GuptaSidkiGroup.2));
## Group([ (), (1,2,3), (1,3,2) ])
## ]]></Example>
##   </Description>
## </ManSection>
##
## <#/GAPDoc>
##
DeclareAttribute("TopVertexTransformations", IsFRSemigroup);
DeclareAttribute("VertexTransformations", IsFRSemigroup);
#############################################################################

#############################################################################
##
#O PermGroup. . . . . . . . . . . . . . . . . .group acting on truncated tree
#O [Epimorphism]PermGroup
#O [Epimorphism]PcGroup
#O [Epimorphism]TransformationMonoid
#O [Epimorphism]TransformationSemigroup
##
## <#GAPDoc Label="PermGroup">
## <ManSection>
##   <Oper Name="PermGroup" Arg="g,l"/>
##   <Oper Name="EpimorphismPermGroup" Arg="g,l"/>
##   <Returns>[An epimorphism to] the permutation group of <A>g</A>'s action on level <A>l</A>.</Returns>
##   <Description>
##     The first function returns a permutation group on <M>d^l</M> points, where
##     <M>d</M> is the size of <A>g</A>'s alphabet. It has as many generators
##     as <A>g</A>, and represents the action of <A>g</A> on the <A>l</A>th
##     layer of the tree.
##
##     <P/> The second function returns a homomorphism from <A>g</A> to
##     this permutation group.
## <Example><![CDATA[
## gap> g := FRGroup("a=(1,2)","b=<a,>"); Size(g);
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## 8
## gap> PermGroup(g,2);
## Group([ (1,3)(2,4), (1,2) ])
## gap> PermGroup(g,3);
## Group([ (1,5)(2,6)(3,7)(4,8), (1,3)(2,4) ])
## gap> List([1..6],i->LogInt(Size(PermGroup(GrigorchukGroup,i)),2));
## [ 1, 3, 7, 12, 22, 42 ]
## gap> g := FRGroup("t=<,t>(1,2)"); Size(g);
## <self-similar group over [ 1 .. 2 ] with 1 generator>
## infinity
## gap> pi := EpimorphismPermGroup(g,5);
## MappingByFunction( <self-similar group over [ 1 .. 2 ] with 1 generator,
## of size infinity>, Group([ (1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31,
## 2,18,10,26,6,22,14,30,4,20,12,28,8,24,16,32) ]), function( w ) ... end )
## gap> Order(g.1);
## infinity
## gap> Order(g.1^pi);
## 32
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="PcGroup" Arg="g,l"/>
##   <Oper Name="EpimorphismPcGroup" Arg="g,l"/>
##   <Returns>[An epimorphism to] the pc group of <A>g</A>'s action on level <A>l</A>.</Returns>
##   <Description>
##     The first function returns a polycyclic group representing the action
##     of <A>g</A> on the <A>l</A>th layer of the tree. It converts the
##     permutation group <C>PermGroup(g,l)</C> to a Pc group, in which
##     computations are often faster.
##
##     <P/> The second function returns a homomorphism from <A>g</A> to
##     this pc group.
## <Example><![CDATA[
## gap> g := PcGroup(GrigorchukGroup,7); time;
## <pc group with 5 generators>
## 3370
## gap> NormalClosure(g,Group(g.3)); time;
## <pc group with 79 generators>
## 240
## gap> g := PermGroup(GrigorchukGroup,7); time;
## <permutation group with 5 generators>
## 3
## gap> NormalClosure(g,Group(g.3)); time;
## <permutation group with 5 generators>
## 5344
## gap> g := FRGroup("t=<,t>(1,2)"); Size(g);
## <self-similar group over [ 1 .. 2 ] with 1 generator>
## infinity
## gap> pi := EpimorphismPcGroup(g,5);
## MappingByFunction( <self-similar group over [ 1 .. 2 ] with
## 1 generator, of size infinity>, Group([ f1, f2, f3, f4, f5 ]), function( w ) ... end )
## gap> Order(g.1);
## infinity
## gap> Order(g.1^pi);
## 32
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="TransformationMonoid" Arg="g,l"/>
##   <Oper Name="EpimorphismTransformationMonoid" Arg="g,l"/>
##   <Returns>[An epimorphism to] the transformation monoid of <A>g</A>'s action on level <A>l</A>.</Returns>
##   <Description>
##     The first function returns a transformation monoid on <M>d^l</M> points,
##     where <M>d</M> is the size of <A>g</A>'s alphabet. It has as many
##     generators as <A>g</A>, and represents the action of <A>g</A> on
##     the <A>l</A>th layer of the tree.
##
##     <P/> The second function returns a homomorphism from <A>g</A> to this
##     transformation monoid.
## <Example><![CDATA[
## gap> i4 := SCMonoid(MealyMachine([[3,3],[1,2],[3,3]],[(1,2),[1,1],()]));
## <self-similar monoid over [ 1 .. 2 ] with 3 generators>
## gap> g := TransformationMonoid(i4,6);
## <monoid with 3 generators>
## gap> List([1..6],i->Size(TransformationMonoid(i4,i)));
## [ 4, 14, 50, 170, 570, 1882 ]
## gap> Collected(List(g,RankOfTransformation));
## [ [ 1, 64 ], [ 2, 1280 ], [ 4, 384 ], [ 8, 112 ], [ 16, 32 ], [ 32, 8 ], [ 64, 2 ] ]
## gap> pi := EpimorphismTransformationMonoid(i4,9);
## MappingByFunction( <self-similar monoid over [ 1 .. 2 ] with 3 generators>,
## <monoid with 3 generators>, function( w ) ... end )
## gap> f := GeneratorsOfMonoid(i4){[1,2]};;
## gap> for i in [1..10] do Add(f,f[i]*f[i+1]); od;
## gap> Product(f{[3,5,7,9,11]})=f[11]*f[10];
## false
## gap> Product(f{[3,5,7,9,11]})^pi=(f[11]*f[10])^pi;
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="TransformationSemigroup" Arg="g,l"/>
##   <Oper Name="EpimorphismTransformationSemigroup" Arg="g,l"/>
##   <Returns>[An epimorphism to] the transformation semigroup of <A>g</A>'s action on level <A>l</A>.</Returns>
##   <Description>
##     The first function returns a transformation semigroup on <M>d^l</M>
##     points, where <M>d</M> is the size of <A>g</A>'s alphabet.
##     It has as many generators as <A>g</A>, and represents the action
##     of <A>g</A> on the <A>l</A>th layer of the tree.
##
##     <P/> The second function returns a homomorphism from <A>g</A> to this
##     transformation semigroup.
## <Example><![CDATA[
## gap> i2 := SCSemigroup(MealyMachine([[1,1],[2,1]],[(1,2),[2,2]]));
## <self-similar semigroup over [ 1 .. 2 ] with 2 generators>
## gap> g := TransformationSemigroup(i2,6);
## <semigroup with 2 generators>
## gap> List([1..6],i->Size(TransformationSemigroup(i2,i)));
## [ 4, 14, 42, 114, 290, 706 ]
## gap> Collected(List(g,RankOfTransformation));
## [ [ 1, 64 ], [ 2, 384 ], [ 4, 160 ], [ 8, 64 ], [ 16, 24 ], [ 32, 8 ], [ 64, 2 ] ]
## gap> f0 := GeneratorsOfSemigroup(i2)[1];; f1 := GeneratorsOfSemigroup(i2)[2];;
## gap> pi := EpimorphismTransformationSemigroup(i2,10);
## MappingByFunction( <self-similar semigroup over [ 1 .. 2 ] with
## 2 generators>, <semigroup with 2 generators>, function( w ) ... end )
## gap> (f1*(f1*f0)^10)=((f1*f0)^10);
## false
## gap> (f1*(f1*f0)^10)^pi=((f1*f0)^10)^pi;
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="EpimorphismGermGroup" Arg="g,l"/>
##   <Oper Name="EpimorphismGermGroup" Arg="g" Label="EGG0"/>
##   <Returns>A homomorphism to a polycyclic group.</Returns>
##   <Description>
##     This function returns an epimorphism to a polycyclic group, encoding
##     the action on the first <A>l</A> levels of the tree and on the germs
##     below. If <A>l</A> is omitted, it is assumed to be <M>0</M>.
##
##     <P/> Since the elements of <A>g</A> are finite automata, they map
##     periodic sequences to periodic sequences. The action on the periods,
##     and in the immediate vicinity of them, is called the <E>germ action</E>
##     of <A>g</A>. This function returns the natural homomorphism from
##     <A>g</A> to the wreath product of this germ group with the quotient of
##     <A>g</A> acting on the <A>l</A>th layer of the tree.
##
##     <P/> The germ group, by default, is abelian. If it is finite, this
##     function returns a homomorphism to a Pc group; otherwise, a
##     homomorphism to a polycyclic group.
##
##     <P/> The <Ref Var="GrigorchukTwistedTwin"/> is, for now, the only example
##     with a hand-coded, non-abelian germ group.
## <Example><![CDATA[
## gap> EpimorphismGermGroup(GrigorchukGroup,0);
## MappingByFunction( GrigorchukGroup, <pc group of size 4 with 2 generators>,
##   function( g ) ... end )
## gap> List(GeneratorsOfGroup(GrigorchukGroup),x->x^last);
## [ <identity> of ..., f1, f1*f2, f2 ]
## gap> StructureDescription(Image(last2));
## "C2 x C2"
## gap> g := FRGroup("t=<,t>(1,2)","m=<,m^-1>(1,2)");;
## gap> EpimorphismGermGroup(g,0);
## MappingByFunction( <state-closed, bounded group over [ 1, 2 ] with 2
##   generators>, Pcp-group with orders [ 0, 0 ], function( x ) ... end )
## gap> EpimorphismGermGroup(g,1);; Range(last); Image(last2);
## Pcp-group with orders [ 2, 0, 0, 0, 0 ]
## Pcp-group with orders [ 2, 0, 0, 0 ]
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Attr Name="GermData" Arg="group"/>
##   <Oper Name="GermValue" Arg="element, data"/>
##   <Description>
##     The first command computes some data useful to determine the germ
##     value of a group element; the second command computes these germ
##     values. For more information on germs, see <Ref Oper="Germs"/>.
## <Example><![CDATA[
## gap> data := GermData(GrigorchukGroup);
## rec( endo := [ f1, f2 ] -> [ f1*f2, f1 ], group := <pc group of size 4 with 2 generators>,
##   machines := [  ], map := [ <identity> of ..., f2, f1, f1*f2, <identity> of ... ],
##   nucleus := [ <Trivial Mealy element on alphabet [ 1 .. 2 ]>, d, c, b, a ],
##   nucleusmachine := <Mealy machine on alphabet [ 1 .. 2 ] with 5 states> )
## gap> List(GeneratorsOfGroup(GrigorchukGroup),x->GermValue(x,data));
## [ <identity> of ..., f1*f2, f1, f2 ]
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareAttribute("LevelOfEpimorphismFromFRGroup",IsGroupHomomorphism);
DeclareOperation("PermGroup", [IsFRGroup, IsInt]);
DeclareOperation("EpimorphismPermGroup", [IsFRGroup, IsInt]);
DeclareOperation("PcGroup", [IsFRGroup, IsInt]);
DeclareOperation("EpimorphismPcGroup", [IsFRGroup, IsInt]);
DeclareOperation("TransformationMonoid", [IsFRMonoid, IsInt]);
DeclareOperation("EpimorphismTransformationMonoid", [IsFRMonoid, IsInt]);
DeclareOperation("TransformationSemigroup", [IsFRSemigroup, IsInt]);
DeclareOperation("EpimorphismTransformationSemigroup", [IsFRSemigroup, IsInt]);
DeclareOperation("EpimorphismGermGroup",[IsFRGroup, IsInt]);
DeclareOperation("EpimorphismGermGroup",[IsFRGroup]);
#############################################################################

#############################################################################
##
#P IsStateClosed. . . . . . . . . . . . are all states of elements of G in G?
#O StateClosure. . . . . . . . . the smallest state-closed group containing G
#P IsRecurrent. . . . . . . . .do all elements appear under any fixed vertex?
#P IsLevelTransitive. . . . . . is there one orbit at each level of the tree?
##
## <#GAPDoc Label="IsStateClosed">
## <ManSection>
##   <Prop Name="IsStateClosed" Arg="g"/>
##   <Returns><K>true</K> if all states of elements of <A>g</A> belong to <A>g</A>.</Returns>
##   <Description>
##     This function tests whether <A>g</A> is a <E>state-closed</E> group,
##     i.e. a group such that all states of all elements of <A>g</A> belong
##     to <A>g</A>.
##
##     <P/> The smallest state-closed group containing <A>g</A> is computed
##     with <Ref Oper="StateClosure"/>.
## <Example><![CDATA[
## gap> Dinfinity := FRGroup("a=(1,2)","b=<a,b>");
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> AssignGeneratorVariables(Dinfinity);
## #I  Assigned the global variables [ a, b ]
## gap> IsStateClosed(Group(a));
##      IsStateClosed(Group(b));
##      IsStateClosed(Dinfinity);
## true
## false
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="StateClosure" Arg="g"/>
##   <Returns>The smallest state-closed group containing <A>g</A>.</Returns>
##   <Description>
##     This function computes the smallest group containing all states of
##     all elements of <A>g</A>, i.e. the smallest group containing <A>g</A>
##     and for which <Ref Prop="IsStateClosed"/> returns <K>true</K>.
## <Example><![CDATA[
## gap> Dinfinity := FRGroup("a=(1,2)","b=<a,b>");
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> AssignGeneratorVariables(Dinfinity);
## #I  Assigned the global variables [ a, b ]
## gap> StateStateClosure(Group(a))=Dinfinity; StateClosure(Group(b))=Dinfinity;
## false
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Prop Name="IsRecurrentFRSemigroup" Arg="g"/>
##   <Returns><K>true</K> if <A>g</A> is a recurrent group.</Returns>
##   <Description>
##     This function returns <K>true</K> if <A>g</A> is a <E>recurrent</E>
##     group, i.e. if, for every vertex <C>v</C>, all elements of <A>g</A>
##     appear as states at <C>v</C> of elements fixing <C>v</C>.
## <Example><![CDATA[
## gap> Dinfinity := FRGroup("a=(1,2)","b=<a,b>");
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> AssignGeneratorVariables(Dinfinity);
## #I  Assigned the global variables [ a, b ]
## gap> IsRecurrentFRSemigroup(Group(a)); IsRecurrentFRSemigroup(Group(b));
## false
## false
## gap> IsRecurrentFRSemigroup(Dinfinity);
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Prop Name="IsLevelTransitiveFRGroup" Arg="g"/>
##   <Returns><K>true</K> if <A>g</A> is a level-transitive group.</Returns>
##   <Description>
##     This function returns <K>true</K> if <A>g</A> is a
##     <E>level-transitive</E> group, i.e. if the action of <A>g</A> is
##     transitive at every level of the tree on which it acts.
##
##     <P/> This function can be abbreviated as <C>IsLevelTransitive</C>.
## <Example><![CDATA[
## gap> Dinfinity := FRGroup("a=(1,2)","b=<a,b>");
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> AssignGeneratorVariables(Dinfinity);
## #I  Assigned the global variables [ a, b ]
## gap> IsLevelTransitiveFRGroup(Group(a)); IsLevelTransitiveFRGroup(Group(b));
##      IsLevelTransitiveFRGroup(Dinfinity);
## false
## false
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Prop Name="IsInfinitelyTransitive" Arg="g"/>
##   <Prop Name="IsLevelTransitiveOnPatterns" Arg="g"/>
##   <Returns><K>true</K> if <A>g</A> is infinitely transitive.</Returns>
##   <Description>
##     This function returns <K>true</K> if <A>g</A> is an
##     <E>infinitely transitive</E> group. This means that <A>g</A> is
##     the state-closed group of a bireversible Mealy machine (see <Ref
##     Prop="IsBireversible"/>), and that
##     the action of the set of reduced words of any given length over the
##     alphabet (where "reduced" means no successive letters related by
##     the involution) is transitive.
##
##     <P/> Reduced words are defined as follows: if the underlying Mealy
##     machine of <A>g</A> has an involution on its alphabet
##     (see <Ref Attr="AlphabetInvolution"/>), then reduced words are words
##     in which two consecutive letters are not images of each other under
##     the involution. If no involution is defined, then all words are
##     considered reduced; the command then becomes synonymous to
##     <Ref Prop="IsLevelTransitiveFRGroup"/>.
##
##     <P/> This notion is of fundamental importance for the study of
##     lattices in a product of trees; it implies under appropriate
##     circumstances that the dual group is free.
## <Example><![CDATA[
## gap> IsInfinitelyTransitive(BabyAleshinGroup);
## true
## gap> IsLevelTransitiveFRGroup(BabyAleshinGroup);
## true
## gap> s := DualMachine(BabyAleshinMachine);
## <Mealy machine on alphabet [ 1 .. 3 ] with 2 states>
## gap> AlphabetInvolution(s); # set attribute
## [ 1, 2, 3 ]
## gap> g := SCGroup(s);
## <state-closed group over [ 1 .. 3 ] with 2 generators>
## gap> IsInfinitelyTransitive(g);
## true
## gap> IsLevelTransitiveFRGroup(g);
## false
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareProperty("IsStateClosed", IsFRSemigroup);
DeclareOperation("StateClosure", [IsFRSemigroup]);
DeclareProperty("IsRecurrentFRSemigroup", IsFRSemigroup);
DeclareProperty("IsLevelTransitiveFRGroup", IsFRSemigroup);
DeclareProperty("IsInfinitelyTransitive", IsFRGroup);
DeclareProperty("IsLevelTransitiveOnPatterns", IsFRGroup);
#############################################################################

#############################################################################
##
#P IsContracting
#A NucleusOfFRSemigroup
#A NucleusMachine
##
## <#GAPDoc Label="IsContracting">
## <ManSection>
##   <Prop Name="IsContracting" Arg="g"/>
##   <Returns><K>true</K> if <A>g</A> is a contracting semigroup.</Returns>
##   <Description>
##     This function returns <K>true</K> if <A>g</A> is a <E>contracting</E>
##     semigroup, i.e. if there exists a finite subset <C>N</C> of <A>g</A>
##     such that the <Ref Oper="LimitStates"/> of every element of <A>g</A>
##     belong to <C>N</C>.
##
##     <P/> The minimal such <C>N</C> can be computed with <Ref Attr="NucleusOfFRSemigroup"/>.
## <Example><![CDATA[
## gap> Dinfinity := FRGroup("a=(1,2)","b=<a,b>");
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> IsContracting(Dinfinity);
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Attr Name="NucleusOfFRSemigroup" Arg="g"/>
##   <Oper Name="Nucleus" Arg="g" Label="FR semigroup"/>
##   <Returns>The nucleus of the contracting semigroup <A>g</A>.</Returns>
##   <Description>
##     This function returns the <E>nucleus</E> of the contracting semigroup
##     <A>g</A>, i.e. the smallest subset <C>N</C> of <A>g</A>
##     such that the <Ref Oper="LimitStates"/> of every element of <A>g</A>
##     belong to <C>N</C>.
##
##     <P/> This function returns <K>fail</K> if no such <C>N</C> exists.
##     Usually, it loops forever without being able to decide whether <C>N</C>
##     is finite or infinite. It succeeds precisely when
##     <C>IsContracting(g)</C> succeeds.
## <Example><![CDATA[
## gap> Dinfinity := FRGroup("a=(1,2)","b=<a,b>");
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> NucleusOfFRSemigroup(Dinfinity);
## [ <2|identity ...>, <2|b>, <2|a> ]
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Attr Name="NucleusMachine" Arg="g" Label="FR semigroup"/>
##   <Returns>The nucleus machine of the contracting semigroup <A>g</A>.</Returns>
##   <Description>
##     This function returns the <E>nucleus</E> of the contracting semigroup
##     <A>g</A>, see <Ref Attr="NucleusOfFRSemigroup"/>, in the form of a Mealy machine.
##
##     <P/> Since all states of the nucleus are elements of the nucleus, the
##     transition and output function may be restricted to the nucleus,
##     defining a Mealy machine. Finitely generated recurrent groups are
##     generated by their nucleus machine.
##
##     <P/> This function returns <K>fail</K> if no such <C>n</C> exists.
##     Usually, it loops forever without being able to decide whether <C>n</C>
##     is finite or infinite. It succeeds precisely when
##     <C>IsContracting(g)</C> succeeds.
## <Example><![CDATA[
## gap> Dinfinity := FRGroup("a=(1,2)","b=<a,b>");
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> M := NucleusMachine(Dinfinity);
## <Mealy machine on alphabet [ 1, 2 ] with 3 states>
## gap> Display(M);
##    |  1     2
## ---+-----+-----+
##  a | a,1   a,2
##  b | c,1   b,2
##  c | a,2   a,1
## ---+-----+-----+
## gap> Dinfinity=SCGroup(M);
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Attr Name="AdjacencyBasesWithOne" Arg="g"/>
##   <Attr Name="AdjacencyPoset" Arg="g"/>
##   <Returns>The bases, or the poset, of the simplicial model of <A>g</A>.</Returns>
##   <Description>
##     For these arguments, <A>g</A> can be either the nucleus of an FR
##     semigroup, or that semigroup itself, in which case its nucleus is
##     first computed.
##
##     <P/> The first function computes those maximal (for inclusion)
##     subsets of the nucleus that are recurrent, namely subsets <C>B</C>
##     such that <C>Set(B,x->States(x,v))=B</C> for a string <C>v</C>.
##
##     <P/> The second function then computes the poset of intersections of
##     these bases, and returns it as a binary relation.
##
##     <P/> For more details on these concepts, see <Cite Key="0810.4936"/>.
## <Example><![CDATA[
## gap> n := NucleusOfFRSemigroup(BasilicaGroup);
## [ <Trivial Mealy element on alphabet [ 1 .. 2 ]>, b,
##   <Mealy element on alphabet [ 1 .. 2 ] with 3 states>,
##   <Mealy element on alphabet [ 1 .. 2 ] with 3 states>,
##   <Mealy element on alphabet [ 1 .. 2 ] with 3 states>,
##   <Mealy element on alphabet [ 1 .. 2 ] with 3 states>,
##   <Mealy element on alphabet [ 1 .. 2 ] with 3 states> ]
## gap> AdjacencyBasesWithOne(n);
## [ [ <Trivial Mealy element on alphabet [ 1 .. 2 ]>,
##       <Mealy element on alphabet [ 1 .. 2 ] with 3 states>,
##       <Mealy element on alphabet [ 1 .. 2 ] with 3 states> ],
##   [ <Trivial Mealy element on alphabet [ 1 .. 2 ]>,
##       <Mealy element on alphabet [ 1 .. 2 ] with 3 states>,
##       <Mealy element on alphabet [ 1 .. 2 ] with 3 states> ],
##   [ <Trivial Mealy element on alphabet [ 1 .. 2 ]>,
##       <Mealy element on alphabet [ 1 .. 2 ] with 3 states>,
##       <Mealy element on alphabet [ 1 .. 2 ] with 3 states> ] ]
## gap> AdjacencyPoset(n);
## <general mapping: <object> -> <object> >
## gap> Draw(HasseDiagramBinaryRelation(last));
## ]]></Example>
##     This produces (in a new window) the following picture:
##     <Alt Only="LaTeX"><![CDATA[
##       \includegraphics[height=3cm,keepaspectratio=true]{hasse.jpg}
##     ]]></Alt>
##     <Alt Only="HTML"><![CDATA[
##       <img alt="Hasse Diagram" src="hasse.jpg">
##     ]]></Alt>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareProperty("IsContracting", IsFRSemigroup);
DeclareAttribute("NucleusOfFRSemigroup", IsFRSemigroup);
DeclareAttribute("NucleusMachine", IsFRSemigroup);
DeclareAttribute("AdjacencyBasesWithOne", IsFRElementCollection);
DeclareAttribute("AdjacencyPoset", IsFRElementCollection);
#############################################################################

#############################################################################
##
#P IsFinitary
#P IsBounded
#P IsFiniteState
##
## <#GAPDoc Label="IsFinitary">
## <ManSection>
##   <Prop Name="IsFinitaryFRSemigroup" Arg="g"/>
##   <Prop Name="IsWeaklyFinitaryFRSemigroup" Arg="g"/>
##   <Prop Name="IsBoundedFRSemigroup" Arg="g"/>
##   <Prop Name="IsPolynomialGrowthFRSemigroup" Arg="g"/>
##   <Prop Name="IsFiniteStateFRSemigroup" Arg="g"/>
##   <Returns><K>true</K> if all elements of <A>g</A> have the required property.</Returns>
##   <Description>
##     This function returns <K>true</K> if all elements of <A>g</A>
##     have the required property, as FR elements; see
##     <Ref Prop="IsFinitaryFRElement"/>,
##     <Ref Prop="IsWeaklyFinitaryFRElement"/>,
##     <Ref Prop="IsBoundedFRElement"/>,
##     <Ref Prop="IsPolynomialGrowthFRElement"/> and
##     <Ref Prop="IsFiniteStateFRElement"/>.
## <Example><![CDATA[
## gap> G := FRGroup("a=(1,2)","b=<a,b>","c=<c,b>","d=<d,d>(1,2)");
## <self-similar group over [ 1 .. 2 ] with 4 generators>
## gap> L := [Group(G.1),Group(G.1,G.2),Group(G.1,G.2,G.3),G];;
## gap> List(L,IsFinitaryFRSemigroup);
## [ true, false, false, false ]
## gap> List(L,IsBoundedFRSemigroup);
## [ true, true, false, false ]
## gap> List(L,IsPolynomialGrowthFRSemigroup);
## [ true, true, true, false ]
## gap> List(L,IsFiniteStateFRSemigroup);
## [ true, true, true, true ]
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Attr Name="Degree" Arg="g" Label="FR semigroup"/>
##   <Attr Name="DegreeOfFRSemigroup" Arg="g"/>
##   <Attr Name="Depth" Arg="g" Label="FR semigroup"/>
##   <Attr Name="DepthOfFRSemigroup" Arg="g"/>
##   <Returns>The maximal degree/depth of elements of <A>g</A>.</Returns>
##   <Description>
##     This function returns the maximal degree/depth of elements of <A>g</A>;
##     see <Ref Attr="Degree" Label="FR element"/> and
##     <Ref Attr="Depth" Label="FR element"/>.
## <Example><![CDATA[
## gap> G := FRGroup("a=(1,2)","b=<a,b>","c=<c,b>");
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> Degree(Group(G.1)); Degree(Group(G.1,G.2)); Degree(G);
## 0
## 1
## 2
## gap> Depth(Group(G.1)); Depth(Group(G.1,G.2)); Depth(G);
## 1
## infinity
## infinity
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Prop Name="HasOpenSetConditionFRSemigroup" Arg="g"/>
##   <Returns><K>true</K> if <A>g</A> has the open set condition.</Returns>
##   <Description>
##     This function returns <K>true</K> if all elements of <A>g</A>
##     have the <E>open set condition</E>, see
##     <Ref Prop="HasOpenSetConditionFRElement"/>.
## <Example><![CDATA[
## gap> HasOpenSetConditionFRSemigroup(GrigorchukGroup);
## false
## gap> HasOpenSetConditionFRSemigroup(BinaryAddingGroup);
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Prop Name="HasCongruenceProperty" Arg="G"/>
##   <Returns><K>true</K> if <A>G</A> has the congruence property.</Returns>
##   <Description>
##     This function returns <K>true</K> if the transformation
##     (semi)group <A>G</A> has the <E>congruence property</E>, namely if
##     every homomorphism <M>G\to Q</M> to a finite quotient factors as
##     <M>G\to H\to Q</M> via an action of <M>G</M> on a finite set.
##
##     <P/> This command is not guaranteed to terminate.
## <Example><![CDATA[
## gap> HasCongruenceProperty(GrigorchukGroup);
## true
## gap> HasCongruenceProperty(GrigorchukTwistedTwin);
## ...runs forever...
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareProperty("IsFinitaryFRSemigroup", IsFRSemigroup);
DeclareProperty("IsWeaklyFinitaryFRSemigroup", IsFRSemigroup);
DeclareProperty("IsBoundedFRSemigroup", IsFRSemigroup);
DeclareProperty("IsPolynomialGrowthFRSemigroup", IsFRSemigroup);
DeclareProperty("IsFiniteStateFRSemigroup", IsFRSemigroup);
DeclareAttribute("DegreeOfFRSemigroup", IsFRSemigroup);
DeclareAttribute("DepthOfFRSemigroup", IsFRSemigroup);
DeclareProperty("HasOpenSetConditionFRSemigroup", IsFRSemigroup);
DeclareOperation("Depth", [IsFRSemigroup]);
DeclareAttribute("GermData", IsFRGroup, "mutable");
DeclareOperation("GermValue", [IsFRElement, IsRecord]);
DeclareProperty("HasCongruenceProperty", IsFRGroup);
#############################################################################

#############################################################################
##
#P IsTorsionGroup ...
##
## <#GAPDoc Label="IsTorsionGroup">
## <ManSection>
##   <Prop Name="IsTorsionGroup" Arg="g"/>
##   <Returns><K>true</K> if <A>g</A> is a torsion group.</Returns>
##   <Description>
##     This function returns <K>true</K> if <A>g</A> is a torsion group,
##     i.e. if every element in <A>g</A> has finite order; and <K>false</K>
##     if <A>g</A> contains an element of infinite order.
##
##     <P/> This method is quite rudimentary, and is not guaranteed to
##     terminate. At the minimum, <A>g</A> should be a group in which
##     <C>Order()</C> succeeds in computing element orders; e.g. a
##     bounded group in Mealy machine format.
## <Example><![CDATA[
## gap> Dinfinity := FRGroup("a=(1,2)","b=<a,b>":IsMealyElement);
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> IsTorsionGroup(Dinfinity);
## false
## gap> IsTorsionGroup(GrigorchukGroup); IsTorsionGroup(GuptaSidkiGroup);
## true
## true
## gap> IsTorsionGroup(FabrykowskiGuptaGroup);
## false
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Prop Name="IsTorsionFreeGroup" Arg="g"/>
##   <Returns><K>true</K> if <A>g</A> is a torsion-free group.</Returns>
##   <Description>
##     This function returns <K>true</K> if <A>g</A> is a torsion-free group,
##     i.e. if no element in <A>g</A> has finite order; and <K>false</K>
##     if <A>g</A> contains an element of finite order.
##
##     <P/> This method is quite rudimentary, and is not guaranteed to
##     terminate. At the minimum, <A>g</A> should be a group in which
##     <C>Order()</C> succeeds in computing element orders; e.g. a
##     bounded group in Mealy machine format.
## <Example><![CDATA[
## gap> Dinfinity := FRGroup("a=(1,2)","b=<a,b>":IsMealyElement);
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> IsTorsionFreeGroup(Dinfinity);
## false
## gap> IsTorsionFreeGroup(BasilicaGroup);
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Prop Name="IsAmenableGroup" Arg="g"/>
##   <Returns><K>true</K> if <A>g</A> is an amenable group.</Returns>
##   <Description>
##     Amenable groups, introduced by von Neumann <Cite Key="vneumann"/>,
##     are those groups that admit a finitely additive,
##     translation-invariant measure.
## <Example><![CDATA[
## gap> IsAmenableGroup(FreeGroup(2));
## false
## gap> IsAmenableGroup(BasilicaGroup);
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Prop Name="IsVirtuallySimpleGroup" Arg="g"/>
##   <Attr Name="LambdaElementVHGroup" Arg="g"/>
##   <Returns><K>true</K> if <A>g</A> admits a finite-index simple subgroup.</Returns>
##   <Description>
##     This function attempts to prove that the VH group <A>g</A> admits a finite-index
##     simple subgroup.
##
##     <P/> It is based on the following test: let <C>D</C> be a direction
##     (vertical or horizontal) such that the corresponding action is
##     infinitely transitive (see <Ref Prop="IsInfinitelyTransitive"/>). If the corresponding
##     subgroup of <A>g</A> contains a non-trivial element <M>\lambda</M> that acts
##     trivially in the corresponding action, then every normal subgroup contains
##     <M>\lambda</M>. It then remains to check that the normal closure of <M>\lambda</M>
##     has finite index. This element <M>\lambda</M> is then stored as the
##     attribute <C>LambdaElementVHGroup(g)</C>.
##
##     <P/> The current implementation is based on results in
##     <Cite Key="MR1839488"/> and <Cite Key="MR1839489"/>, and does not
##     work for the Rattaggi examples (see <Ref Var="RattaggiGroup"/>).
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Prop Name="IsResiduallyFinite" Arg="obj"/>
##   <Returns><K>true</K> if <A>obj</A> is residually finite.</Returns>
##   <Description>
##     An object is <E>residually finite</E> if it can be approximated
##     arbitrarily well by finite quotients; i.e. if for every
##     <M>g\neq h\in X</M> there exists a finite quotient <M>\pi:X\to Q</M>
##     such that <M>g^\pi\neq h^\pi</M>.
## <Example><![CDATA[
## gap> IsResiduallyFinite(FreeGroup(2));
## true
## gap> IsResiduallyFinite(BasilicaGroup);
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Prop Name="IsSQUniversal" Arg="obj"/>
##   <Returns><K>true</K> if <A>obj</A> is SQ-universal.</Returns>
##   <Description>
##     An object <A>obj</A> is <E>SQ-universal</E> if every countable
##     object of the same category as <A>obj</A> is a subobject of a
##     quotient of <A>obj</A>.
## <Example><![CDATA[
## gap> IsSQUniversal(FreeGroup(2));
## true
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Prop Name="IsJustInfinite" Arg="obj"/>
##   <Returns><K>true</K> if <A>obj</A> is just-infinite.</Returns>
##   <Description>
##     An object <A>obj</A> is <E>just-infinite</E> if <A>obj</A> is
##     infinite, but every quotient of <A>obj</A> is finite.
## <Example><![CDATA[
## gap> IsJustInfinite(FreeGroup(2));
## false
## gap> IsJustInfinite(FreeGroup(1));
## true
## gap> IsJustInfinite(GrigorchukGroup); time
## true
## 8284
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareProperty("IsTorsionGroup", IsGroup);
DeclareSynonym("IsTorsionFreeGroup", IsTorsionFree);
DeclareProperty("IsAmenableGroup", IsGroup);
DeclareProperty("IsVirtuallySimpleGroup",IsGroup);
DeclareProperty("IsSQUniversal",IsObject);
DeclareProperty("IsJustInfinite",IsObject);
DeclareProperty("IsResiduallyFinite",IsObject);
#############################################################################

#############################################################################
##
#P IsomorphismFRGroup(G)
#P IsomorphismMealyGroup(G)
##
## <#GAPDoc Label="IsomorphismFRGroup">
## <ManSection>
##   <Oper Name="FRMachineFRGroup" Arg="g"/>
##   <Oper Name="FRMachineFRMonoid" Arg="g"/>
##   <Oper Name="FRMachineFRSemigroup" Arg="g"/>
##   <Oper Name="MealyMachineFRGroup" Arg="g"/>
##   <Oper Name="MealyMachineFRMonoid" Arg="g"/>
##   <Oper Name="MealyMachineFRSemigroup" Arg="g"/>
##   <Returns>A machine describing all generators of <A>g</A>.</Returns>
##   <Description>
##     This function constructs a new group/monoid/semigroup/Mealy FR machine,
##     with (at least) one generator per generator of <A>g</A>.
##     This is done by adding all machines of all generators of <A>g</A>,
##     and minimizing.
##
##     <P/> In particular, if <A>g</A> is state-closed, then
##     <C>SCGroup(FRMachineFRGroup(g))</C> gives a group isomorphic to
##     <A>g</A>, and similarly for monoids and semigroups.
## <Example><![CDATA[
## gap> FRMachineFRGroup(GuptaSidkiGroup);
## <FR machine with alphabet [ 1 .. 3 ] on Group( [ f11, f12 ] )>
## gap> Display(last);
##  G   |     1          2        3
## -----+--------+----------+--------+
##  f11 | <id>,2     <id>,3   <id>,1
##  f12 |  f11,1   f11^-1,2    f12,3
## -----+--------+----------+--------+
## ]]></Example>
## <Example><![CDATA[
## gap> FRMachineFRMonoid(I4Monoid);
## <FR machine with alphabet [ 1 .. 2 ] on Monoid( [ m11, m12 ], ... )>
## gap> Display(last);
##  M   |     1        2
## -----+--------+--------+
##  m11 | <id>,2   <id>,1
##  m12 |  m11,1    m12,1
## -----+--------+--------+
## ]]></Example>
## <Example><![CDATA[
## gap> FRMachineFRSemigroup(I2Monoid);
## <FR machine with alphabet [ 1 .. 2 ] on Semigroup( [ s11, s12, s1 ] )>
## gap> Display(last);
##  S   |    1       2
## -----+-------+-------+
##  s11 | s11,1   s11,2
##  s12 | s12,2   s12,1
##   s1 |  s1,2   s12,2
## -----+-------+-------+
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="IsomorphismFRGroup" Arg="g"/>
##   <Oper Name="IsomorphismFRMonoid" Arg="g"/>
##   <Oper Name="IsomorphismFRSemigroup" Arg="g"/>
##   <Returns>An isomorphism towards a group/monoid/semigroup on a single FR machine.</Returns>
##   <Description>
##     This function constructs a new FR group/monoid/semigroup, such that
##     all elements of the resulting object have the same underlying
##     group/monoid/semigroup FR machine.
## <Example><![CDATA[
## gap> phi := IsomorphismFRGroup(GuptaSidkiGroup);
## [ <Mealy element on alphabet [ 1, 2, 3 ] with 2 states, initial state 1>,
##   <Mealy element on alphabet [ 1, 2, 3 ] with 4 states, initial state 1> ] ->
## [ <3|identity ...>, <3|f1>, <3|f1^-1>, <3|f2> ]
## gap> Display(GuptaSidkiGroup.2);
##    |  1     2     3
## ---+-----+-----+-----+
##  a | a,1   a,2   a,3
##  b | a,2   a,3   a,1
##  c | a,3   a,1   a,2
##  d | b,1   c,2   d,3
## ---+-----+-----+-----+
## Initial state: d
## gap> Display(GuptaSidkiGroup.2^phi);
##     |     1         2        3
## ----+--------+---------+--------+
##  f1 | <id>,2    <id>,3   <id>,1
##  f2 |   f1,1   f1^-1,2     f2,3
## ----+--------+---------+--------+
## Initial state: f2
## ]]></Example>
## <Example><![CDATA[
## gap> phi := IsomorphismFRSemigroup(I2Monoid);
## MappingByFunction( I2, <self-similar semigroup over [ 1 .. 2 ] with
## 3 generators>, <Operation "AsSemigroupFRElement"> )
## gap> Display(GeneratorsOfSemigroup(I2Monoid)[3]);
##    |  1     2
## ---+-----+-----+
##  a | a,2   b,2
##  b | b,2   b,1
## ---+-----+-----+
## Initial state: a
## gap> Display(GeneratorsOfSemigroup(I2Monoid)[3]^phi);
##  S  |   1      2
## ----+------+------+
##  s1 | s1,2   s2,2
##  s2 | s2,2   s2,1
## ----+------+------+
## Initial state: s1
## ]]></Example>
## <Example><![CDATA[
## gap> phi := IsomorphismFRMonoid(I4Monoid);
## MappingByFunction( I4, <self-similar monoid over [ 1 .. 2 ] with
## 2 generators>, <Operation "AsMonoidFRElement"> )
## gap> Display(GeneratorsOfMonoid(I4Monoid)[1]);
##    |  1     2
## ---+-----+-----+
##  a | b,2   b,1
##  b | b,1   b,2
## ---+-----+-----+
## Initial state: a
## gap> Display(GeneratorsOfMonoid(I4Monoid)[1]^phi);
##  M  |     1        2
## ----+--------+--------+
##  m1 | <id>,2   <id>,1
## ----+--------+--------+
## Initial state: m1
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="IsomorphismMealyGroup" Arg="g"/>
##   <Oper Name="IsomorphismMealyMonoid" Arg="g"/>
##   <Oper Name="IsomorphismMealySemigroup" Arg="g"/>
##   <Returns>An isomorphism towards a group/monoid/semigroup all of whose elements are Mealy machines.</Returns>
##   <Description>
##     This function constructs a new FR group/monoid/semigroup, such that
##     all elements of the resulting object are Mealy machines.
## <Example><![CDATA[
## gap> G := FRGroup("a=(1,2)","b=<a,b>","c=<c,b>");
## <self-similar group over [ 1 .. 2 ] with 3 generators>
## gap> phi := IsomorphismMealyGroup(G);
## [ <2|a>, <2|b>, <2|c> ] ->
## [ <Mealy element on alphabet [ 1, 2 ] with 2 states, initial state 1>,
##   <Mealy element on alphabet [ 1, 2 ] with 3 states, initial state 1>,
##   <Mealy element on alphabet [ 1, 2 ] with 4 states, initial state 1> ]
## gap> Display(G.3);
##    |     1        2
## ---+--------+--------+
##  a | <id>,2   <id>,1
##  b |    a,1      b,2
##  c |    c,1      b,2
## ---+--------+--------+
## Initial state: c
## gap> Display(G.3^phi);
##    |  1     2
## ---+-----+-----+
##  a | a,1   b,2
##  b | c,1   b,2
##  c | d,2   d,1
##  d | d,1   d,2
## ---+-----+-----+
## Initial state: a
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareOperation("FRMachineFRGroup", [IsFRGroup]);
DeclareOperation("FRMachineFRMonoid", [IsFRMonoid]);
DeclareOperation("FRMachineFRSemigroup", [IsFRSemigroup]);
DeclareOperation("MealyMachineFRGroup", [IsFRGroup]);
DeclareOperation("MealyMachineFRMonoid", [IsFRMonoid]);
DeclareOperation("MealyMachineFRSemigroup", [IsFRSemigroup]);
DeclareOperation("IsomorphismFRGroup", [IsFRGroup]);
DeclareOperation("IsomorphismFRMonoid", [IsFRMonoid]);
DeclareOperation("IsomorphismFRSemigroup", [IsFRSemigroup]);
DeclareOperation("IsomorphismMealyGroup", [IsFRGroup]);
DeclareOperation("IsomorphismMealyMonoid", [IsFRMonoid]);
DeclareOperation("IsomorphismMealySemigroup", [IsFRSemigroup]);
#############################################################################

#############################################################################
##
#O StabilizerImage
##
## <#GAPDoc Label="StabilizerImage">
## <ManSection>
##   <Oper Name="StabilizerImage" Arg="g,v"/>
##   <Returns>The group of all states at <A>v</A> of elements of <A>g</A> fixing <A>v</A>.</Returns>
##   <Description>
##     This function constructs a new FR group, consisting of all states at
##     vertex <A>v</A> (which can be an integer or a list) of the stabilizer
##     of <A>v</A> in <A>g</A>.
##
##     <P/> The result is <A>g</A> itself precisely if <A>g</A> is recurrent
##     (see <Ref Prop="IsRecurrentFRSemigroup"/>).
## <Example><![CDATA[
## gap> G := FRGroup("t=<,t>(1,2)","u=<,u^-1>(1,2)","b=<u,t>");
## <self-similar group over [ 1 .. 2 ] with 3 generators>
## gap> Stabilizer(G,1);
## <self-similar group over [ 1 .. 2 ] with 5 generators>
## gap> GeneratorsOfGroup(last);
## [ <2|u*t^-1>, <2|b>, <2|t^2>, <2|t*u>, <2|t*b*t^-1> ]
## gap> StabilizerImage(G,1);
## <self-similar group over [ 1 .. 2 ] with 5 generators>
## gap> GeneratorsOfGroup(last);
## [ <2|identity ...>, <2|u>, <2|t>, <2|u^-1>, <2|t> ]
## ]]></Example>
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="LevelStabilizer" Arg="g,n"/>
##   <Returns>The fixator of the <A>n</A>th level of the tree.</Returns>
##   <Description>
##     This function constructs the normal subgroup of <A>g</A> that fixes
##     the <A>n</A>th level of the tree.
## <Example><![CDATA[
## gap> G := FRGroup("t=<,t>(1,2)","a=(1,2)");
## <self-similar group over [ 1 .. 2 ] with 2 generators>
## gap> LevelStabilizer(G,2);
## <self-similar group over [ 1 .. 2 ] with 9 generators>
## gap> Index(G,last);
## 8
## gap> IsNormal(G,last2);
## true
## ]]></Example>
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareOperation("StabilizerImage", [IsFRSemigroup, IsObject]);
DeclareOperation("LevelStabilizer", [IsFRSemigroup, IsInt]);
#############################################################################

#############################################################################
##
#O TreeWreathProduct
##
## <#GAPDoc Label="Products">
## <ManSection>
##   <Oper Name="TreeWreathProduct" Arg="g,h,x0,y0" Label="FR group"/>
##   <Returns>The tree-wreath product of groups <A>g,h</A>.</Returns>
##   <Description>
##     The tree-wreath product of two FR groups is a group generated by
##     a copy of <A>g</A> and of <A>h</A>, in such a way that many
##     conjugates of <A>g</A> commute.
##
##     <P/> More formally, assume without loss of generality that all
##     generators of <A>g</A> are states of a machine <C>m</C>, and that
##     all generators of <A>h</A> are states of a machine <C>n</C>. Then
##     the tree-wreath product is generated by the images of generators
##     of <A>g,h</A> in <C>TreeWreathProduct(m,n,x0,y0)</C>.
##
##     <P/> For the operation on FR machines see <Ref
##     Oper="TreeWreathProduct" Label="FR machine"/>). It is described
##     (with small variations, and in lesser generality) in
##     <Cite Key="MR2197828"/>. For example, in
## <Example><![CDATA[
## gap> w := TreeWreathProduct(AddingGroup(2),AddingGroup(2),1,1);
## <recursive group over [ 1 .. 4 ] with 2 generators>
## gap> a := w.1; b := w.2;
## <Mealy element on alphabet [ 1 .. 4 ] with 3 states>
## <Mealy element on alphabet [ 1 .. 4 ] with 2 states>
## gap> Order(a); Order(b);
## infinity
## infinity
## gap> ForAll([-100..100],i->IsOne(Comm(a,a^(b^i))));
## true
## ]]></Example>
##     the group <C>w</C> is the wreath product <M>Z\wr Z</M>.
##   </Description>
## </ManSection>
##
## <ManSection>
##   <Oper Name="WeaklyBranchedEmbedding" Arg="g"/>
##   <Returns>A embedding of <A>g</A> in a weakly branched group.</Returns>
##   <Description>
##     This function constructs a new FR group, on alphabet the square of the
##     alphabet of <A>g</A>. It is generated by the canonical copy of
##     <A>g</A> and by the tree-wreath product of <A>g</A> with an adding
##     machine on the same alphabet as <A>g</A> (see <Ref
##     Oper="TreeWreathProduct" Label="FR group"/>). The function returns a
##     group homomorphism into this new FR group.
##
##     <P/> The main result of <Cite Key="MR1995624"/> is that the
##     resulting group <M>h</M> is weakly branched. More precisely,
##     <M>h'</M> contains <M>|X|^2</M> copies of itself.
## <Code><![CDATA[
## gap> f := WeaklyBranchedEmbedding(BabyAleshinGroup);;
## gap> Range(f);
## <recursive group over [ 1 .. 4 ] with 8 generators>
## ]]></Code>
##     constructs a finitely generated branched group containing a free
##     subgroup.
##   </Description>
## </ManSection>
## <#/GAPDoc>
##
DeclareOperation("TreeWreathProduct", [IsFRSemigroup, IsFRSemigroup, IsObject, IsObject]);
DeclareOperation("WeaklyBranchedEmbedding", [IsFRSemigroup]);
#############################################################################

--> --------------------

--> maximum size reached

--> --------------------

[ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge