<Chapter Label="PathAlgebras">
<Heading>Path Algebras</Heading>

<Section>
<Heading>Introduction</Heading> 

A path algebra is an algebra constructed from a field <Math>F</Math>
(see Chapter 56 and 57 in the &GAP; manual for information about
fields) and a quiver <Math>Q</Math>.  The path algebra <Math>FQ</Math>
contains all finite linear combinations of paths of <Math>Q</Math>.
This chapter describes the functions in <Package>QPA</Package> that
deal with path algebras and quotients of path algebras.  Path algebras
are algebras, so see Chapter 60: Algebras in the &GAP; manual for
functionality such as generators, basis functions, and mappings.<P/>

The only supported ordering of elements in a path algebra is length
left lexicographic ordering. See <Ref Sect="qpa:Orderings"/> for
more information.<P/> 
<!-- removed the following, as it does not exist. -->
<!-- <ManSection> -->
<!--    <InfoClass Name="InfoPathAlgebra" Comm=""/> -->
<!--    <Description> -->
<!--       is the info class for functions dealing with path algebras. -->
<!--    </Description> -->
<!-- </ManSection> -->

</Section>

<Section Label="Constructing Paths">
<Heading>Constructing Path Algebras</Heading> 
  <ManSection>
   <Func Name="PathAlgebra" Arg="F, Q" Comm=""/>
   <Description>Arguments: <Arg>F</Arg> -- a field, <Arg>Q</Arg> -- a quiver.<Br /></Description>
   <Returns>the path algebra <Arg>FQ</Arg> of <Arg>Q</Arg> over the
   field <Arg>F</Arg>.</Returns>
   <Description>For construction of fields, see the &GAP; documentation.
   The elements of the path algebra <Arg>FQ</Arg> will be ordered by
   left length-lexicographic ordering.
   </Description>
  </ManSection>

<Example><![CDATA[
gap> Q := Quiver( ["u","v"] , [ ["u","u","a"], ["u","v","b"], 
> ["v","u","c"], ["v","v","d"] ] );
<quiver with 2 vertices and 4 arrows>
gap> F := Rationals;
Rationals
gap> FQ := PathAlgebra(F,Q);
<Rationals[<quiver with 2 vertices and 4 arrows>]>]]>
</Example>

<!-- \* NO: the FOLLOWING is not true: -->
<!--   <ManSection> -->
<!--    <Func Name="OrderedBy" Arg="path algebra, ordering" Comm="Path Algebras:OrderedBy"/> -->
<!--    <Returns> a copy of <Arg>path algebra</Arg> whose elements are -->
<!--       ordered by <Arg>ordering</Arg>.  See Section -->
<!--       <Ref Sect="qpa:Orderings"/> for more information on -->
<!--       orderings.</Returns> -->
<!--    <Description> -->
<!--    </Description> -->
<!--   </ManSection> -->
<!-- </Section> -->

</Section>

<Section>
<Heading>Categories and Properties of Path Algebras</Heading>

  <ManSection>
   <Prop Name="IsPathAlgebra" Arg="object" Comm="checks if object is a path algebra"/>
   <Description>
     Arguments: <Arg>object</Arg> -- any object in &GAP;. <Br />
   </Description>
   <Returns>true whenever <Arg>object</Arg> is a path algebra.
   </Returns>
  </ManSection>

<Example><![CDATA[
gap> IsPathAlgebra(FQ);
true
]]></Example>
  
</Section>

<Section><Heading>Attributes and Operations for Path Algebras</Heading>

<ManSection>
  <Attr Name="AssociatedMonomialAlgebra" Arg="A" />
  <Description>
    Arguments: <Arg>A</Arg> -- a quiver algebra.<Br />
  </Description>
  <Returns>
    the associated monomial algebra of  <Arg>A</Arg> with respect to
    the Groebner basis the path algebra is endoved with.
  </Returns>
</ManSection>

  <ManSection>
   <Attr Name="QuiverOfPathAlgebra" Arg="FQ" Comm=""/>
   <Description>
    Arguments: <Arg>FQ</Arg> -- a path algebra. <Br />
   </Description>
   <Returns> the quiver from which <Arg>FQ</Arg> was
    constructed.
   </Returns>
  </ManSection>

<Example><![CDATA[
gap> QuiverOfPathAlgebra(FQ);
<quiver with 2 vertices and 4 arrows> ]]>
</Example>

<ManSection>
  <Attr Name="OrderingOfAlgebra" Arg="FQ" />
  <Description>
    Arguments: <Arg>FQ</Arg> -- a path algebra.<Br />
  </Description>
  <Returns>
    the ordering of the quiver of the path algebra.
  </Returns>
  <Description><Emph>Note:</Emph> As of the current version
  of <Package>QPA</Package>, only left length lexicographic ordering
  is supported.
  </Description>
</ManSection>

  <ManSection>
   <Oper Name="." Label="for a path algebra" Arg="FQ, generator" Comm="path algebra record access"/>
   <Description>
    Arguments: <Arg>FQ</Arg> -- a path algebra, <Arg>generator</Arg> --
    a vertex or an arrow in the quiver <Arg>Q</Arg>. <Br />
   </Description>
   <Returns> the <Arg>generator</Arg> as an element of the path algebra.
   </Returns>
   <Description>Other elements of the path algebra can be constructed
   as linear combinations of the generators.  For further operations
   on elements, see below.
   </Description>
  </ManSection>

<Example><![CDATA[
gap> FQ.a;
(1)*a
gap> FQ.v;
(1)*v
gap> elem := 2*FQ.a - 3*FQ.v;
(-3)*v+(2)*a
]]></Example>

</Section>

<Section><Heading>Operations on Path Algebra Elements</Heading>

  <ManSection>
   <Oper Name="ElementOfPathAlgebra" Arg="PA, path" Comm=""/>
   <Description>
     Arguments: <Arg>PA</Arg> -- a path algebra, <Arg>path</Arg> -- a path in the quiver from which <A>PA</A> was constructed.<Br />
   </Description>
   <Returns>The embedding of <Arg>path</Arg> into the path algebra <Arg>PA</Arg>, or
it returns false if  <Arg>path</Arg> is not an element of the quiver from which <A>PA</A> was constructed.  
   </Returns>
</ManSection>
  
  
  <ManSection>
   <Oper Name="&lt;" Label="for two elements in a path algebra" Arg="a, b" Comm="PathAlgebra:lessthan"/>
   <Description>
    Arguments: <Arg>a</Arg> and <Arg>b</Arg> -- two elements of the
    same path algebra.<Br />
   </Description>
   <Returns>
     True whenever <Arg>a</Arg> is smaller than <Arg>b</Arg>,
  according to the ordering of the path algebra.
   </Returns>
  </ManSection>

  <ManSection>
   <Oper Name="IsLeftUniform" Arg="element" Comm=""/>
   <Description>
     Arguments: <Arg>element</Arg> -- an element of the path
     algebra.<Br />
   </Description>
   <Returns> true if each monomial in <Arg>element</Arg> has the same
   source vertex, false otherwise.
   </Returns>
  </ManSection>

  <ManSection>
   <Oper Name="IsRightUniform" Arg="element" Comm=""/>
   <Description>
     Arguments: <Arg>element</Arg> -- an element of the path
     algebra.<Br />
   </Description>
   <Returns> true if each monomial in <Arg>element</Arg> has the same
   target vertex, false otherwise.
   </Returns>
  </ManSection>

  <ManSection>
   <Oper Name="IsUniform" Arg="element" Comm=""/>
   <Description>
     Arguments: <Arg>element</Arg> -- an element of the path
     algebra. <Br />
   </Description>
   <Returns> true whenever <Arg>element</Arg> is both left and right
   uniform.
   </Returns>
  </ManSection>

<Example><![CDATA[
gap> IsLeftUniform(elem);
false
gap> IsRightUniform(elem);
false
gap> IsUniform(elem);
false
gap> another := FQ.a*FQ.b + FQ.b*FQ.d*FQ.c*FQ.b*FQ.d;
(1)*a*b+(1)*b*d*c*b*d
gap> IsLeftUniform(another);
true
gap> IsRightUniform(another);
true
gap> IsUniform(another);
true ]]>
</Example>

  <ManSection>
   <Oper Name="LeadingTerm" Arg="element" Comm=""/>
   <Oper Name="Tip" Arg="element" Comm=""/>
   <Description>
     Arguments: <Arg>element</Arg> -- an element of the path
     algebra. <Br />
   </Description>
   <Returns>
    the term in <Arg>element</Arg> whose monomial is
    largest among those monomials that have nonzero coefficients
    (known as the "tip" of <Arg>element</Arg>).
   </Returns>
   <Description>
     <Emph>Note: </Emph> The two operations are equivalent.
   </Description>
  </ManSection>

  <ManSection>
   <Oper Name="LeadingCoefficient" Arg="element" Comm=""/>
   <Oper Name="TipCoefficient" Arg="element" Comm=""/>
   <Description>
     Arguments: <Arg>element</Arg> -- an element of the path
     algebra. <Br />
   </Description>
   <Returns>
    the coefficient of the tip of <Arg>element</Arg> (which is an
    element of the field).
   </Returns>
   <Description>
     <Emph>Note: </Emph> The two operations are equivalent.
   </Description>
  </ManSection>

  <ManSection>
   <Oper Name="LeadingMonomial" Arg="element" Comm=""/>
   <Oper Name="TipMonomial" Arg="element" Comm=""/>
   <Description>
     Arguments: <Arg>element</Arg> -- an element of the path
     algebra. <Br />
   </Description>
   <Returns>
    the monomial of the tip of <Arg>element</Arg> (which is an
    element of the underlying quiver, not of the path algebra).
   </Returns>
   <Description>
     <Emph>Note: </Emph> The two operations are equivalent.
   </Description>
  </ManSection>

<Example><![CDATA[
gap> elem := FQ.a*FQ.b*FQ.c + FQ.b*FQ.d*FQ.c+FQ.d*FQ.d;
(1)*d^2+(1)*a*b*c+(1)*b*d*c
gap> LeadingTerm(elem);
(1)*b*d*c
gap> LeadingCoefficient(elem);
1
gap> mon := LeadingMonomial(elem);
b*d*c
gap> mon in FQ;
false
gap> mon in Q;
true ]]>
</Example>


<ManSection>
   <Oper Name="MakeUniformOnRight" Arg="elems" Comm=""/>
   <Description>
     Arguments: <Arg>elems</Arg> -- a list of elements in a path
    algebra.<Br /> 
   </Description>
   <Returns> a list of right uniform elements generated by each
    element of <Arg>elems</Arg>.
   </Returns>
</ManSection>


<ManSection>
   <Oper Name="MappedExpression" Arg="expr, gens1, gens2"  Comm=""/>
   <Description>
     Arguments: <Arg>expr</Arg> -- element of a path
     algebra, <Arg>gens1</Arg> and <Arg>gens2</Arg> -- equal-length
     lists of generators for subalgebras.<Br />
   </Description>
   <Returns>
     <Arg>expr</Arg> as an element of the subalgebra generated
     by <Arg>gens2</Arg>.
   </Returns>
   <Description>
     The element <Arg>expr</Arg> must be in the subalgebra generated
    by <Arg>gens1</Arg>.  The lists define a mapping of each generator
    in <Arg>gens1</Arg> to the corresponding generator
    in <Arg>gens2</Arg>.  The value returned is the evaluation of the
    mapping at <Arg>expr</Arg>.
   </Description>
</ManSection>

<ManSection>
   <Oper Name="VertexPosition" Arg="element" Comm=""/>
   <Description>
     Arguments: <Arg>element</Arg> -- an element of the path algebra
     on the form <Math>k*v</Math>, where <Math>v</Math> is a vertex of
     the underlying quiver and <Math>k</Math> is an element of the
     field.<Br />
   </Description>
   <Returns> the position of the vertex <Arg>v</Arg> in the list of
   vertices of the quiver.
   </Returns>  
</ManSection>

<ManSection>
   <Attr Name="RelationsOfAlgebra" Arg="A" Comm=""/>
   <Description>
    Arguments: <Arg>A</Arg> -- a quiver algebra. <Br />
   </Description>
   <Returns>a set of generators for the ideal in the path algebra
   <M>kQ</M> from which the algebra <Arg>FQ</Arg> was
    constructed.  If <Arg>A</Arg> is a path algebra, then an empty
    list is returned.
   </Returns>
  </ManSection>

</Section>


<Section Label="qpa:Quotients_of_path_algebras">
<Heading>Constructing Quotients of Path Algebras</Heading> 

In the introduction we saw already one way of constructing a quotient of a 
path algebra. In addition to this there are at least two other ways of constructing
a quotient of a path algebra; one with factoring out an ideal and one where a Groebner
basis is attached to the quotient. We discuss these two next.<P/>

For several functions in <Package>QPA</Package> to function properly
one needs to have a Groebner basis attached to the quotient one wants
to construct, or equivalently a Groebner basis for the ideal one is
factoring out. For this to work the ideal must admit a finite Groebner
basis. However, to our knowlegde there is no algorithm for determining
if an ideal has a finite Groebner basis. On the other hand, it is
known that if the factor algebra is finite dimensional, then the ideal
has a finite Groebner basis (independent of the ordering of the
elements, see <Cite Key="Green"/> ). In addition to having a finite
Groebner basis, several functions also need that the factoring ideal
is admissible. A quotient of a path algebra by an admissible ideal
belongs to the category <Ref
Filt="IsAdmissibleQuotientOfPathAlgebra"/>. The method used in the
introduction constructs a quotient in this category. However, there
are situations where it is interesting to analyze quotients of path
algebras by a non-admissible ideal, so we provide also additional
methods.<P/>

In the example below, we construct a factor of a path algebra purely
with commands in &GAP; (cf. also Chapter 60: Algebras in the &GAP;
manual on how to construct an ideal and a quotient of an
algebra). Functions which use Groebner bases like <Ref
Prop="IsFiniteDimensional"/>, <Ref Attr="Dimension"/>, <Ref
Prop="IsSpecialBiserialAlgebra"/> or a membership test <Ref Oper="\in"
Label="elt. in path alg. and ideal"/> will work properly (they simply
compute the Groebner basis if it is necessary). But some "older"
functions (like <Ref Prop="IndecProjectiveModules"/>) can fail or give
an incorrect answer! This way of constructing a quotient of a path
algebra can be useful e.g. if we know that computing a Groebner basis
will take a long time and we do not need this because we want to deal
only with modules.<P/>

<Example><![CDATA[
gap> Q := Quiver( 1, [ [1,1,"a"], [1,1,"b"] ] );
<quiver with 1 vertices and 2 arrows>
gap> kQ := PathAlgebra(Rationals, Q);
<Rationals[<quiver with 1 vertices and 2 arrows>]>
gap> gens := GeneratorsOfAlgebra(kQ);
[ (1)*v1, (1)*a, (1)*b ]
gap> a := gens[2];
(1)*a
gap> b := gens[3];
(1)*b
gap> relations := [a^2,a*b-b*a, b*b];
[ (1)*a^2, (1)*a*b+(-1)*b*a, (1)*b^2 ]
gap> I := Ideal(kQ,relations);
<two-sided ideal in <Rationals[<quiver with 1 vertices and 2 arrows>]>
    , (3 generators)>
gap> A := kQ/I;
<Rationals[<quiver with 1 vertices and 2 arrows>]/
<two-sided ideal in <Rationals[<quiver with 1 vertices and 2 arrows>]>
    , (3 generators)>>
gap> IndecProjectiveModules(A);
Compute a Groebner basis of the ideal you are factoring out with befor\
e you form the quotient algebra, or you have entered an algebra which \
is not finite dimensional.
fail]]>
</Example> 
To resolve this matter, we need to compute the Gröbner basis of the
ideal generated by the relations in <Math>kQ</Math>  (yes, it seems
like we are going in circles here. Remember, then, that an ideal in
the "mathematical sense" may exist independently of the a
corresponding <C>Ideal</C> object in &GAP;. Also,
Gröbner bases in <Package>QPA</Package> are handled by the
<Package>GBNP</Package> package, with constructor methods not
dependent on <C>Ideal</C> objects. After creating the ideal
<Math>I</Math>, we need to perform yet another Gröbner basis operation
which just set a respective attribute for <Math>I</Math>, see <Ref
Oper="GroebnerBasis"/>.  

<Example><![CDATA[
gap> gb := GBNPGroebnerBasis(relations,kQ);
[ (1)*a^2, (-1)*a*b+(1)*b*a, (1)*b^2 ]
gap> I := Ideal(kQ,gb);                    
<two-sided ideal in <Rationals[<quiver with 1 vertices and 2 arrows>]>, 
  (3 generators)>
gap> GroebnerBasis(I,gb);                  
<complete two-sided Groebner basis containing 3 elements>
gap> IndecProjectiveModules(A);                                                
fail
gap> A := kQ/I;                                                                
<Rationals[<quiver with 1 vertices and 2 arrows>]/
<two-sided ideal in <Rationals[<quiver with 1 vertices and 2 arrows>]>, 
  (3 generators)>>
gap> IndecProjectiveModules(A);
[ <[ 4 ]> ]]]>
</Example>

Note that the instruction <C>A := kQ/relations;</C> used in Introduction
is exactly an abbreviation for a sequence of instructions with Groebner basis as in above example.<P/>

Most <Package>QPA</Package> operations working on algebras handle
path algebras and quotients of path algebras in the same way (when
this makes sense). However, there are still a few operations which
does not work properly when given a quotient of a path algebra. 

When constructing a quotient of a path algebra one needs define the 
ideal one is factoring out.  Above this has been done with the commands

<Example><![CDATA[ 
gap> gens := GeneratorsOfAlgebra(kQ);
[ (1)*v1, (1)*a, (1)*b ]
gap> a := gens[2];
(1)*a
gap> b := gens[3];
(1)*b
]]></Example>

The following command makes this process easier.
<ManSection>
  <Oper Name="AssignGeneratorVariables" Arg="A" Comm="for a quiver algebra"/>
  <Description>
    Arguments: <Arg>A</Arg> -- a quiver algebra.<Br />
  </Description>
  <Returns>
Takes a quiver algebra <Arg>A</Arg> as an argument and creates
variables, say <M>v_1,...,v_n</M> for the vertices, and
<M>a_1,...,a_t</M> for the arrows for the corresponding elements in
<Arg>A</Arg>, whenever the quiver for the quiver algebra <Arg>A</Arg>
is was constructed with the vertices being named <M>v_1,...,v_n</M>
and the arrows being named <M>a_1,...,a_t</M>.
</Returns>
</ManSection>
Here is an example of its use.
<Example><![CDATA[ 
gap> AssignGeneratorVariables(kQ);
#I  Assigned the global variables [ v1, a, b ]
gap> v1; a; b;
(1)*v1
(1)*a
(1)*b
]]></Example>

</Section>

<Section Label="IdealsAndOperations"><Heading>Ideals and operations
    on ideals</Heading>

  <ManSection>
   <Func Name="Ideal" Arg="FQ, elems" Comm=""/>
   <Description>Arguments: <Arg>FQ</Arg> -- a path
    algebra, <Arg>elems</Arg> -- a list of elements
    in <Arg>FQ</Arg>.<Br />
   </Description>
   <Returns>the ideal of <Arg>FQ</Arg> generated by <Arg>elems</Arg> with the property 
   <Ref Prop="IsIdealInPathAlgebra"/>.
   </Returns>
   <Description>For more on ideals, see the &GAP; reference manual
   (Chapter 60.6). <Br />
   <Emph>Technical info:</Emph> Ideal is a synonym for a global GAP function TwoSidedIdeal
   which calls an operation TwoSidedIdealByGenerators (synonym IdealByGenerators) for an algebra (FLMLOR).
   </Description>
  </ManSection>

<Example><![CDATA[
gap> gb := GBNPGroebnerBasis(relations,kQ);
[ (1)*a^2, (-1)*a*b+(1)*b*a, (1)*b^2 ]
gap> I := Ideal(kQ,gb);
<two-sided ideal in <Rationals[<quiver with 1 vertices and 2 arrows>]>
    , (3 generators)>
gap> GroebnerBasis(I,gb);
<complete two-sided Groebner basis containing 3 elements>
gap> IndecProjectiveModules(A);
[ <[ 4 ]> ]
gap> A := kQ/I;
<Rationals[<quiver with 1 vertices and 2 arrows>]/
<two-sided ideal in <Rationals[<quiver with 1 vertices and 2 arrows>]>
    , (3 generators)>>
gap> IndecProjectiveModules(A);
[ <[ 4 ]> ]
true]]>
</Example>

<ManSection>
   <Attr Name="IdealOfQuotient" Arg="A" Comm=""/>
   <Description>
    Arguments: <Arg>A</Arg> -- a quiver algebra. <Br />
   </Description>
   <Returns>the ideal in the path algebra <M>kQ</M> from which
   <Arg>A</Arg> was constructed.
   </Returns>
  </ManSection>

<ManSection>
  <Oper Name="PathsOfLengthTwo" Arg="Q" Comm="for a quiver"/>
  <Description>
    Arguments: <Arg>Q</Arg> -- a quiver.<Br />
  </Description>
  <Returns>
    a list of all paths of length two in <Arg>Q</Arg>, sorted by <C>&lt;</C>.
    Fails with error message if <Arg>Q</Arg> is not a Quiver object.
  </Returns>
</ManSection>
  
  
<ManSection>
  <Oper Name="NthPowerOfArrowIdeal" Arg="FQ, n" Comm=""/>
  <Description>
    Arguments: <Arg>FQ</Arg> -- a path algebra, <Arg>n</Arg> -- a
    positive integer.<Br />
  </Description>
  <Returns>
    the ideal generated all the paths of length <Arg>n</Arg> in <Arg>FQ</Arg>.
  </Returns>
</ManSection>

<ManSection>
  <Oper Name="AddNthPowerToRelations" Arg="FQ, rels, n" Comm=""/>
  <Description>
    Arguments: <Arg>FQ</Arg> -- a path algebra, <Arg>rels</Arg> -- a
    (possibly empty) list of elements in <Arg>FQ</Arg>, <Arg>n</Arg>
    -- a positive integer.<Br />
  </Description>
  <Returns>
    the list <Arg>rels</Arg> with the paths of length <Arg>n</Arg>
    of <Arg>FQ</Arg> appended (will change the list <Arg>rels</Arg>).
  </Returns>
</ManSection>

<ManSection>
   <Oper Name="\in" Label="elt. in path alg. and ideal" Arg="elt, I " Comm="membership test for an ideal in path algebra"/>
   <Description>
     Arguments: <Arg>elt</Arg> - an element in a path algebra, <Arg>I</Arg> 
     - an ideal in the same path algebra (i.e. with <Ref Prop="IsIdealInPathAlgebra"/> property).<Br />
   </Description>
   <Returns>true, if <Arg>elt</Arg> belongs to <Arg>I</Arg>.</Returns>
   <Description>It performs the membership test for an ideal in path algebra using 
   completely reduced Groebner
   bases machinery. 
   <Br /> <Emph>Technical info:</Emph> For the efficiency reasons, it computes Groebner basis
  for <Arg>I</Arg> only if it has not been computed yet. Similarly, it performs
  CompletelyReduceGroebnerBasis only if it has not been reduced yet.
  The method can change the existing Groebner basis.<Br />
  <Emph>Remark:</Emph> It works only in case <Arg>I</Arg> is in the arrow 
   ideal.
   </Description>
</ManSection>

</Section>

<Section Label="PropertiesOfIdeals"><Heading>Categories and properties of ideals</Heading>
  
<ManSection>
  <Prop Name="IsAdmissibleIdeal" Arg="I" Comm="checks if I is an admissible ideal in a path algebra"/>
  <Description>
    Arguments: <Arg>I</Arg> -- an IsIdealInPathAlgebra object. <Br />
  </Description>
  <Returns>true whenever <Arg>I</Arg> is an <Emph>admissible</Emph>
  ideal in a path algebra, i.e. <Arg>I</Arg> is a subset of <M>J^2</M>
  and <Arg>I</Arg> contains <M>J^n</M> for some <M>n</M>, where
  <M>J</M> is the arrow ideal.
  </Returns>
  <Description>
    <Emph>Technical note:</Emph> The second condition is checked by
    the nilpotency index of the radical and checking if the ideal
    generated by the arrows to one plus this index is in the ideal of
    the relations (this uses Groebner bases machinery).
  </Description>
</ManSection>

<ManSection>
  <Prop Name="IsIdealInPathAlgebra" Arg="I" Comm="checks if I is an ideal in a path algebra"/>
  <Description>
    Arguments: <Arg>I</Arg> -- an IsFLMLOR object. <Br />
  </Description>
  <Returns>true whenever <Arg>I</Arg> is an ideal in a path algebra.
  </Returns>
</ManSection> 

<ManSection>
  <Prop Name="IsMonomialIdeal" Arg="I" Comm="checks if I is a monomial ideal in a path algebra"/>
  <Description>
    Arguments: <Arg>I</Arg> -- an IsIdealInPathAlgebra object. <Br />
  </Description>
  <Returns>true whenever <Arg>I</Arg> is a <Emph>monomial</Emph> ideal in a path algebra, 
  i.e. <Arg>I</Arg> is generated by a set of monomials (= "zero-relations").
  </Returns>
  <Description>
    <Emph>Technical note:</Emph> It uses the
    observation: <Arg>I</Arg> is a monomial ideal iff Groebner basis
    of <Arg>I</Arg> is a set of monomials. It computes Groebner basis
    for <Arg>I</Arg> only in case it has not been computed yet and a
    usual set of generators (GeneratorsOfIdeal) is not a set of
    monomials.
  </Description>
</ManSection>

<ManSection>
  <Oper Name="IsQuadraticIdeal" Arg="rels" Comm="for an ideal in a
						 path algebra"/> 
  <Description>
    Arguments: <Arg>rels</Arg> -- a list of elements in a path algebra.<Br />
  </Description>
  <Returns>true whenever <Arg>rels</Arg> is a list of elements in the
  linear span of degree two elements of a path algebra. It returns
  false whenever <Arg>rels</Arg> is a list of elements in a path
  algebra, but not in the linear span of degree two of a path
  algebra. Otherwise it returns fail.
  </Returns>
</ManSection>
</Section>

<Section Label="OperationsOnIdeals"><Heading>Operations on ideals</Heading>

  <ManSection>
   <Oper Name="ProductOfIdeals" Arg="I, J" Comm="for
   two ideals in a path algebra"/>
   <Description>
     Arguments: <Arg>I, J</Arg> -- two ideals in a path
     algebra <Arg>KQ</Arg>.<Br />
   </Description>
   <Returns>the ideal formed by the product of the ideals <Arg>I</Arg>
   and <Arg>J</Arg>, whenever the ideal <Arg>J</Arg> admits finitely
   many nontips in <Arg>KQ</Arg>.    
   </Returns>
   <Description>
     The function checks if the two ideals are ideals in the same path
     algebra and that <Arg>J</Arg> admits finitely many nontips
     in <Arg>KQ</Arg>.
   </Description>
  </ManSection>


  <ManSection>
   <Oper Name="QuadraticPerpOfPathAlgebraIdeal" Arg="rels" Comm="for
   an ideal in a path algebra"/>
   <Description>
     Arguments: <Arg>rels</Arg> -- a list of elements in a path algebra.<Br />
   </Description>
   <Returns>fail if <Arg>rels</Arg> is not a list of elements in the
   linear span of degree two elements of a path
   algebra <Arg>KQ</Arg>. Otherwise it returns a list of length two,
   where the first element is a set of generators
   for the ideal <Math><Arg>rels</Arg>^\perp</Math> in opposite
   algebra of <Arg>KQ</Arg> and the second element is the opposite
   algebra of <Arg>KQ</Arg>. 
   </Returns>
  </ManSection>

  
</Section>

<Section Label="AttributesOfIdeals"><Heading>Attributes of ideals</Heading>

For many of the functions related to quotients, you will need to
compute a Groebner basis of the ideal.  This is done with the GBNP
package. The following example shows how to set a Groebner basis for
an ideal (note that this must be done before the quotient is
constructed). See the next two chapters for more on Groebner bases.


<Example><![CDATA[
gap> rels := [FQ.a - FQ.b*FQ.c, FQ.d*FQ.d];
[ (1)*a+(-1)*b*c, (1)*d^2 ]
gap> gb := GBNPGroebnerBasis(rels, FQ); 
[ (-1)*a+(1)*b*c, (1)*d^2 ]
gap> I := Ideal(FQ, gb);
<two-sided ideal in <Rationals[<quiver with 2 vertices and 4 arrows>]>
    , (2 generators)>
gap> GroebnerBasis(I, gb);
<complete two-sided Groebner basis containing 2 elements>
gap> quot := FQ/I;
<Rationals[<quiver with 2 vertices and 4 arrows>]/
<two-sided ideal in <Rationals[<quiver with 2 vertices and 4 arrows>]>
    , (2 generators)>>]]>
</Example>

<ManSection>
   <Attr Name="GroebnerBasisOfIdeal" Arg="I" Comm=""/>
   <Description>
     Arguments: <Arg>I</Arg> -- an ideal in path algebra.<Br />
   </Description>
   <Returns>a Groebner basis of ideal <Arg>I</Arg> (if it has been already computed!).
   </Returns>
   <Description>
    This attribute is set only by an operation <Ref Oper="GroebnerBasis"/>.
   </Description>
</ManSection>

</Section>

<Section>
<Heading>Categories and Properties of Quotients of Path Algebras</Heading>

<ManSection>
  <Filt Name="IsAdmissibleQuotientOfPathAlgebra" Arg="A" Comm="category"/>
  <Description>
    Arguments: <Arg>A</Arg> -- any object.<Br />
  </Description>
  <Returns>true whenever <Arg>A</Arg> is a quotient of a path algebra
  by an admissible ideal constructed by the command <C>\/</C> with
  arguments a path algebra and a list of relations, <C>KQ/rels</C>,
  where <C>rels</C> is a list of relations. Otherewise it returns an error message. 
  </Returns>
</ManSection>

<ManSection>
   <Prop Name="IsQuotientOfPathAlgebra" Arg="object" Comm="checks if
   object is a quotient of a path algebra"/>
   <Description>
     Argument: <Arg>object</Arg> -- any object in &GAP;.<Br />
   </Description>
   <Returns> true whenever <Arg>object</Arg> is a quotient of a path algebra.
   </Returns>
</ManSection>

<Example><![CDATA[
gap> quot := FQ/I;
<Rationals[<quiver with 2 vertices and 4 arrows>]/
<two-sided ideal in <Rationals[<quiver with 2 vertices and 4 arrows>]>
    , (2 generators)>>
gap> IsQuotientOfPathAlgebra(quot);
true
gap> IsQuotientOfPathAlgebra(FQ);
false]]>
</Example>

  <ManSection>
   <Prop Name="IsFiniteDimensional" Arg="A" Comm="checks if A is a finite dimensional quotient of path algebra"/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path algebra. <Br />
   </Description>
   <Returns>true whenever <Arg>A</Arg> is a finite dimensional  algebra.
   </Returns>
   <Description><Emph>Technical note:</Emph> For a path algebra it uses a standard &GAP; method.
   For a quotient of a path algebra it uses Groebner bases machinery 
   (it computes Groebner basis for the ideal only in case it has not been computed yet).
   </Description>
  </ManSection>
  
  <ManSection>
   <Prop Name="IsCanonicalAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>
     true if <Arg>A</Arg> has been constructed by the operation 
     <Ref Oper="CanonicalAlgebra"/>, otherwise "Error, no method found".
   </Returns>
</ManSection>

<ManSection>
   <Prop Name="IsDistributiveAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>
     true if <Arg>A</Arg> is an admissible quotient of a path algebra and distributive. Otherwise it 
     returns false if <Arg>A</Arg> is an admissible quotient of a path
     algebra and distributive.  If <Arg>A</Arg> is a quotient of a
     path algebra, but not an admissible quotient, then it looks for
     other methods.  There are not further methods implemented in QPA
     as of now. 
   </Returns>
</ManSection>

<ManSection>
    <Prop Name="IsFiniteGlobalDimensionAlgebra" Arg="A"/>
    <Description>
      Arguments: <Arg>A</Arg> - an algebra over a field.<Br />
    </Description>
    <Returns> true if it is known that the entered algebra
    <Arg>A</Arg> has finite global dimension.
    </Returns> 
    <Description>
      There is no method associated to this, so if it is not known that 
      the algebra has finite global dimension, then an error message saying 
      "no method found!" is return. 
    </Description>
</ManSection>

<ManSection>
   <Prop Name="IsGentleAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>
     true if the algebra <Arg>A</Arg> is a gentle algebra. Otherwise false.
   </Returns>
</ManSection>

<ManSection>
   <Prop Name="IsGorensteinAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- an algebra.<Br />
   </Description>
   <Returns>
     true if it is known that <Arg>A</Arg> is a Gorenstein algebra. If
     unknown it returns an error message saying "no method found!".
   </Returns>
   <Description>
     There is no method installed for this yet. 
   </Description>
</ManSection>

<ManSection>
   <Prop Name="IsHereditaryAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- an admissible quotient of a path algebra.<Br />
   </Description>
   <Returns>
     true if  <Arg>A</Arg> is a hereditary algebra and false otherwise. 
   </Returns>
</ManSection>

<ManSection>
   <Prop Name="IsKroneckerAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>
     true if <Arg>A</Arg> has been constructed by the operation 
     <Ref Oper="KroneckerAlgebra"/>, otherwise "Error, no method found".
   </Returns>
</ManSection>

<ManSection>
   <Prop Name="IsMonomialAlgebra" Arg="A" Comm="for a quiver algebra"/>
   <Description>
     Arguments: <Arg>A</Arg> -- a quiver algebra.<Br />
   </Description>
   <Returns>
     true when <Arg>A</Arg> is given as <C>kQ/I</C> and <C>I</C> is a
     monomial ideal in <C>kQ</C>, otherwise it returns false.
   </Returns>
</ManSection>

<ManSection>
   <Prop Name="IsNakayamaAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>
     true if <Arg>A</Arg> has been constructed by the operation 
     <Ref Oper="NakayamaAlgebra"/>, otherwise "Error, no method found".
   </Returns>
</ManSection>

<ManSection>
   <Filt Name="IsQuiverAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- an algebra.<Br />
   </Description>
   <Returns>
     true if <Arg>A</Arg> is a path algebra or a quotient of a path
     algebra algebra, otherwise false. 
   </Returns>
</ManSection>

<ManSection>
   <Prop Name="IsRadicalSquareZeroAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- an algebra.<Br />
   </Description>
   <Returns>
     true if <Arg>A</Arg> is a radical square zero algebra, otherwise false. 
   </Returns>
</ManSection>

<ManSection>
   <Prop Name="IsSchurianAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>true if <Arg>A</Arg> is a schurian algebra. By definition it means that:
   for all <Math>x,y\in Q_0</Math> we have <Math>\dim A(x,y)\leq 1 </Math>.
   </Returns>
  <Description>
    <Emph>Note:</Emph> This method fail when a Groebner basis
  for ideal has not been computed before creating a quotient!
   </Description>
</ManSection>

<ManSection>
   <Prop Name="IsSelfinjectiveAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>fail if <Arg>A</Arg> is not finite dimensional. Otherwise
     it returns true or false according to whether <Arg>A</Arg> is
     selfinjective or not.
   </Returns>
</ManSection>

<ManSection>
   <Prop Name="IsSemicommutativeAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>true if <Arg>A</Arg> is a semicommutative algebra. By definition it means that:<Br />
     1. <Arg>A</Arg> is schurian (cf. <Ref Prop="IsSchurianAlgebra"/>).<Br />
    2. Quiver <Math>Q</Math> of <Arg>A</Arg> is acyclic (cf. <Ref Prop="IsAcyclicQuiver"/>).<Br />
    3. For all pairs of vertices <Math>(x,y)</Math> the following condition is satisfied:
     for every two paths <Math>P,P'</Math> from <Math>x</Math> to <Math>y</Math>:
     <Math>P\in I \Leftrightarrow P'\in I</Math>.
   </Returns>
  <Description>
    <Emph>Note:</Emph> This method fail when a Groebner basis
  for ideal has not been computed before creating a quotient!
   </Description>
</ManSection>

<ManSection>
    <Prop Name="IsSemisimpleAlgebra" Arg="A"/>
    <Description>
      Arguments: <Arg>A</Arg> - an algebra over a field.<Br />
    </Description>
    <Returns> true if the entered algebra
    <Arg>A</Arg> is semisimple, false otherwise.
    </Returns> 
    <Description>
      Checks if the algebra is finite dimensional.  If it is an
      admissible quotients of a path algebra, it only checks if the
      underlying quiver has any arrows or not.  Otherwise, it computes
      the radical of the algebra and checks if it is zero.
    </Description>
  </ManSection>

<ManSection>
  <Prop Name="IsSpecialBiserialAlgebra" Arg="A" Comm="checks if A is a special biserial algebra"/>
  <Description>
    Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path algebra. <Br />
  </Description>
  <Returns>true whenever <Arg>A</Arg> is a <Emph>special biserial algebra</Emph>, i.e. <Arg>A=KQ/I</Arg>,
  where <A>Q</A> is <Ref Prop="IsSpecialBiserialQuiver"/>, <A>I</A> is an admissible ideal
  (<Ref Prop="IsAdmissibleIdeal"/>) and <A>I</A> satisfies 
  the "special biserial" conditions, i.e.:
  <List> 
    <Item>for any arrow <M>a</M> there exists at most one arrow <M>b</M> 
    such that <M>ab</M> does not belong to <A>I</A></Item>
    <Item>there exists at most one arrow <M>c</M> such that <M>ca</M> does not belong to <M>I</M>.</Item> 
  </List>
  </Returns>
  <Description>
    <Emph>Note:</Emph>  e.g. a path algebra of one loop IS NOT special biserial,
    but one loop IS special biserial quiver (see <Ref Prop="IsSpecialBiserialQuiver"/> for examples).
  </Description>
</ManSection>
  
<ManSection>
  <Prop Name="IsStringAlgebra" Arg="A" Comm="checks if A is a string (special biserial) algebra"/>
  <Description>
    Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path algebra. <Br />
  </Description>
  <Returns>true whenever <Arg>A</Arg> is a <Emph>string</Emph> (special biserial) algebra, 
  i.e. <Arg>A=KQ/I</Arg> is a special biserial algebra (<Ref Prop="IsSpecialBiserialAlgebra"/>
  and <A>I</A> is generated by monomials (= "zero-relations")
  (cf. <Ref Prop="IsMonomialIdeal"/>). See <Ref Prop="IsSpecialBiserialQuiver"/> for examples.
  </Returns>
</ManSection>

<ManSection>
   <Prop Name="IsSymmetricAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>fail if <Arg>A</Arg> is not finite dimensional or does not
     have a Groebner basis. Otherwise it returns true or false
     according to whether <Arg>A</Arg> is symmetric or not.
   </Returns>
</ManSection>

<ManSection>
    <Prop Name="IsTriangularReduced" Arg="A"/>
    <Description>
      Arguments: <Arg>A</Arg> - a finite dimensional QuiverAlgebra.<Br />
    </Description>
    <Returns><C>false</C> if the algebra <Arg>A</Arg> is triangular
    reducable, that is, there is a sum over vertices <M>e</M> such
    that <M>eA(1 - e) = (0)</M> for <M>e\neq 0,1</M>.  Otherwise, it
    returns <C>true</C>.
    </Returns> 
    <Description>
    The function checks if the algebra <Arg>A</Arg> is finite dimensional and
    gives an error message otherwise.  
    </Description>
 </ManSection>

<ManSection>
   <Prop Name="IsWeaklySymmetricAlgebra" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>fail if <Arg>A</Arg> is not finite dimensional or does not
     have a Groebner basis. Otherwise it returns true or false
     according to whether <Arg>A</Arg> is weakly symmetric or not.
   </Returns>
</ManSection>

<ManSection>
   <Prop Name="BongartzTest" Arg="A, bound" Comm="test for infinite type"/>
   <Description>
     Arguments: <Arg>A, bound</Arg> -- a path algebra or a quotient of a path
     algebra and an integer.<Br />
   </Description>
   <Returns>false if there exists a <M>\tau</M>-translate of a simple,
   injective or projective <Arg>A</Arg>-module up to the power
   <Arg>bound</Arg> has dimension greater or equal to <M>\max\{2\dim
   A, 30\}</M>.  Then <Arg>A</Arg> is of infinite representation type.
  Returns fail otherwise. 
   </Returns>
</ManSection>

<ManSection>
   <Prop Name="IsFiniteTypeAlgebra" Arg="A" Comm="test for finite type"/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>Returns true if <Arg>A</Arg> is of finite representation type.
  Returns false if <Arg>A</Arg> is of infinite representation type.
  Returns fail if we can not determine the representation type
  (i.e. it impossible from theoretical/algorithmic point of view
  or a suitable criterion has not been implemented yet; the implementation is in progress).
  Note: in case <Arg>A</Arg> is a path algebra the function is completely 
  implemented.
   </Returns>
</ManSection>

<Example><![CDATA[
gap> Q := Quiver(5, [ [1,2,"a"], [2,4,"b"], [3,2,"c"], [2,5,"d"] ]);
<quiver with 5 vertices and 4 arrows>
gap> A := PathAlgebra(Rationals, Q);
<Rationals[<quiver with 5 vertices and 4 arrows>]>
gap> IsFiniteTypeAlgebra(A);
Infinite type!
Quiver is not a (union of) Dynkin quiver(s).
false
gap> quo := A/[A.a*A.b, A.c*A.d];;
gap> IsFiniteTypeAlgebra(quo);
Finite type!
Special biserial algebra with no unoriented cycles in Q.
true ]]>
</Example>
  
</Section>
	
<Section><Heading> Operations on String Algebras</Heading>
A quiver is a quadruple <Math>Q = (Q_0, Q_1, s, t)</Math> where <Math>Q_0</Math>
is the set of vertices, <Math>Q_1</Math> is the set of arrows and <Math>s, t :
Q_1 \rightarrow Q_0</Math> are source and target functions where for each <Math>
\alpha \in Q_1</Math>, <Math>s(\alpha)</Math> and <Math>t(\alpha)</Math> denotes
starting and ending vertex of <Math>\alpha</Math> respectively. For the functions
defined in this section the quiver has to be constructed using first construction
of <Ref Sect="Basic Construction"/>. The arrows in <Math>Q_1</Math> should be
small Roman letters defined in alphabetical order as in the example below. These
operations can handle string algebras with number of arrows less than or equal
to 26. Say that a finite sequence <M>\alpha_n\alpha_{n-1}...\alpha_1</M> is a
path in <M>Q</M> if <M>s(\alpha_{i+1}) = t(\alpha_i)</M> for all <M>1 \leq i \leq n-1</M>
The source and target of the path are <M>s(\alpha_1)</M> and <M>t(\alpha_n)</M>
respectively. We denote by <Math>\rho</Math> a set of monomial relations on
<Math>Q</Math>. Every relation in <M>\rho</M> is a finite sequence <M>\alpha_1
\alpha_{2}...\alpha_n</M> of elements of <M>Q_1</M> with <M>n \geq 2</M> such
that <M>\alpha_n \alpha_{n-1}...\alpha_1</M> is a path.
<M>\newline</M>

For a quiver <Math>Q</Math>, we define two functions <M>\sigma, \epsilon : Q_1
\rightarrow \{-1, 1\}</M> such that
<List>
    <Item> if <M>b_1 \neq b_2</M> such that <M>s(b_1) = s(b_2)</M>,
    then <M>\sigma(b_1) = -\sigma(b_2)</M>;</Item>
    <Item> if <M>b_1 \neq b_2</M> such that <M>t(b_1) = t(b_2)</M>,
    then <M>\epsilon(b_1) = -\epsilon(b_2)</M>;</Item>
    <Item> if <M>s(b_1) = t(b_2)</M> and <M>b_1b_2 \notin \rho</M>,
    then <M>\sigma(b_1) = -\epsilon(b_2)</M>.</Item>
</List>
Let us denote the inverse of the set of arrows in <M>Q_1</M> by the
corresponding capital letters. For example if <M>b</M> is an arrow in <M>Q_1</M>
the its inverse is denoted by <M>B</M>. The set of the inverse arrows is denoted
by <M>Q_1^{-1}</M>. We extend the definition of <M>\sigma</M> and
<M>\epsilon</M> to <M>Q_1 \cup Q_1^{-1}</M> so that <M>\sigma(B) =
\epsilon(b)</M> and <M>\epsilon(B) = \sigma(b)</M> for all <M>b \in Q_1</M>.
Note that a <Emph>string</Emph> of positive length is a walk along the arrows of
<M>Q</M> and their inverses such that it does not contain paths obtained by
reversing relations in <M>\rho</M> and their inverses as substrings. We also
extend the definition of <M>\sigma</M> and <M>\epsilon</M> to all strings; if
<M>\alpha = \alpha_n ...\alpha_2 \alpha_1</M>, then <M>\sigma(\alpha) =
\sigma(\alpha_1)</M> and <M>\epsilon(\alpha) = \epsilon(\alpha_n)</M>.
<M>\newline</M>

For each vertex <M>v\in Q_0</M>, we have a zero length lazy string starting and
ending at vertex <M>v</M>, denoted by <M>1_v</M>. The inverse of this string is
<M>1_v</M> itself. The main purpose of defining <M>\sigma</M> and <M>\epsilon</M>
is to distinguish <M>1_v</M> with its inverse. We denote this zero length string
as <M>(v,1)</M> and <M>(v,-1)</M> and set <M>\sigma((v,i)) := -i</M> and
<M>\epsilon((v,i)) := i</M>. The concatenation <M>(v,i)u</M> of strings is
defined if and only if <M>\epsilon(u) = i</M> and the concatenation <M>u(v,i)</M>
is defined if and only if <M>\sigma(u) = -i</M>. Moreover if <M>\alpha = \alpha_n
\alpha_{n-1} ... \alpha_2 \alpha_1</M> and <M>\beta = \beta_m \beta_{m-1} ...
\beta_2 \beta_1</M> are two strings such that <M>s(\alpha) = t(\beta)</M>, their
concatenation is the string <M>\alpha\beta = \alpha_n ... \alpha_1 \beta_m ...
\beta_1</M>. Note that, for a given quiver <M>Q</M>, the functions <M>\sigma,
\epsilon</M> are not unique. A choice of <M>\sigma</M> and <M>\epsilon</M>
functions is computed within our codes and utilized in other functions.

<ManSection>
  <Oper Name="IsValidString" Arg="Q,rho,input_str" Comm="A quiver, a list of
    monomial relations and an input collection of characters"/>
  <Description>
    Arguments: <Arg>Q</Arg> -- a quiver,
    <Arg>rho</Arg> -- a list of monomial relations,
    <Arg>input_str</Arg> -- an input collection of characters.<Br />
  </Description>
  <Returns>
    "Not a String Algebra" if the algebra presented by <Arg>(Q,rho)</Arg>
    is not a string algebra, "Valid Positive Length String" if <Arg>input_str</Arg>
    is a string of positive length in the corresponding string algebra,
    "Valid Zero Length String", if <Arg>input_str</Arg> is a zero length string
    in the corresponding string algebra, "Invalid String" if <Arg>input_str</Arg>
    is not a string in the corresponding string algebra
  </Returns>
</ManSection>

<ManSection>
  <Oper Name="StringsLessThan" Arg="Q,rho,level" Comm="A quiver, a list of monomial
    relations and an integer"/>
  <Description>
    Arguments: <Arg>Q</Arg> -- a quiver,
    <Arg>rho</Arg> -- a list of monomial relations,
    <Arg>level</Arg> -- an integer.<Br />
  </Description>
  <Returns>
    "Not a String Algebra" if the algebra presented by <Arg>(Q,rho)</Arg>
    is not a string algebra, an empty list if <Arg>level</Arg>
    is a negative integer, a list of all strings of length less than or
    equal to <Arg>level</Arg> if <Arg>level</Arg> is a non-negative integer.
  </Returns>
</ManSection>

A string <M>u</M> is called <M>\textbf{cyclic}</M> if <M>s(u) = t(u)</M>. A cyclic
string is called <M>\textbf{primitive}</M> if it can not be written as an n-fold
concatenation <M>\mathfrak{v}^n</M> for any string <M>\mathfrak{v}</M> and any
<M>n \in \mathbb{N}</M>. If <M>\mathfrak{b}</M> is a primitive cyclic string such
that <M>\mathfrak{b}^m</M> exists, for all <M>m \in \mathbb{N}</M>, then
<M>\mathfrak{b} </M> is called a <M>\textbf{band}</M>.

<ManSection>
  <Oper Name="IsABand" Arg="Q,rho,input_str" Comm="A quiver, a list of monomial
    relations and an input collection of characters"/>
  <Description>
    Arguments: <Arg>Q</Arg> -- a quiver,
    <Arg>rho</Arg> -- a list of monomial relations,
    <Arg>input_str</Arg> -- an input collection of characters.<Br />
  </Description>
  <Returns>
    "Not a String Algebra" if the algebra presented by <Arg>(Q,rho)</Arg> is not
    a string algebra, "Invalid String" if <Arg>input_str</Arg> is not a string
    in the corresponding string algebra, <M>0</M> if <Arg>input_str</Arg> is a
    valid string but not a band, <M>1</M> if <Arg>input_str</Arg> is a band in
    the corresponding string algebra.
  </Returns>
</ManSection>

<ManSection>
  <Oper Name="BandsLessThan" Arg="Q,rho,level" Comm="A quiver, a list of monomial
    relations and an integer"/>
  <Description>
    Arguments: <Arg>Q</Arg> -- a quiver,
    <Arg>rho</Arg> -- a list of monomial relations,
    <Arg>level</Arg> -- an integer.<Br />
  </Description>
  <Returns>
    "Not a String Algebra" if the algebra presented by <Arg>(Q,rho)</Arg> is not
    a string algebra, an empty list if <Arg>level</Arg> is a negative integer,
    a list of all bands of length less than or equal to <Arg>level</Arg>
    if <Arg>level</Arg> is a non-negative integer.
  </Returns>
</ManSection>

Two bands <M>\mathfrak{b}_1</M> and <M>\mathfrak{b}_2</M> of a string algebra are
said to be equivalent if they are cyclic permutations of each other. For any band
<M>\mathfrak{b}</M>, output of <M>\texttt{BandsLessThan}</M> function contains
all bands equivalent to <M>\mathfrak{b}</M>. A representative of each equivalence
class is chosen such that the first syllable from right is an inverse syllable
and the last syllable from right is a direct syllable. This new list is returned
as the output of the following function.

<ManSection>
  <Oper Name="BandRepresentativesLessThan" Arg="Q,rho,level" Comm="A quiver, a list of monomial
    relations and an integer"/>
  <Description>
    Arguments: <Arg>Q</Arg> -- a quiver,
    <Arg>rho</Arg> -- a list of monomial relations,
    <Arg>level</Arg> -- an integer.<Br />
  </Description>
  <Returns>
    "Not a String Algebra" if the algebra presented by <Arg>(Q,rho)</Arg> is not
    a string algebra, an empty list if <Arg>level</Arg> is negative integer,
    a list of all band representatives of length less than or equal to
    <Arg>level</Arg> if <Arg>level</Arg> is a non-negative integer.
  </Returns>
</ManSection>


A string algebra with finite number of bands is called a domestic string algebra.


<ManSection>
  <Oper Name="IsDomesticStringAlgebra" Arg="Q,rho" Comm="A quiver, a list of monomial
    relations"/>
  <Description>
    Arguments: <Arg>Q</Arg> -- a quiver,
    <Arg>rho</Arg> -- a list of monomial relations. <Br />
  </Description>
  <Returns>
    "Not a String Algebra" if the algebra presented by <Arg>(Q,rho)</Arg> is not
    a string algebra, <M>0</M> if the corresponding string algebra is non-domestic,
    <M>1</M> if the corresponding string algebra is domestic.
  </Returns>
</ManSection>


A string is <M>\textbf{band-free}</M> if it does not contain any cyclic permutation of
a band as a substring. Let <M>Ba(\Lambda)</M> denote the collection of all bands
up to cyclic permutation and <M>Q_0^{Ba}</M> denote a fixed set of representatives
of bands in <M>Ba(\Lambda)</M>. For <M>\mathfrak{b}_1, \mathfrak{b}_2 \in Q_0^{Ba}</M>,
we say that a finite string <M>u</M> is a weak bridge <M>\mathfrak{b}_1 \xrightarrow{u}
\mathfrak{b}_2</M> if it is band-free and if <M>\mathfrak{b}_2 u \mathfrak{b}_1</M>
is a string.<M>\newline</M>
We say that a weak bridge
<M>\mathfrak{b}_1 \xrightarrow{u} \mathfrak{b}_2</M> is a bridge if there is
<M>\textbf{no}</M> <M>\mathfrak{b}\in Q_0^{Ba}</M> and weak bridges
<M>\mathfrak{b}_1 \xrightarrow{u_1} \mathfrak{b}</M> and
<M>\mathfrak{b} \xrightarrow{u_2} \mathfrak{b}_2</M> such that one of the following holds :
<List>
    <Item>
      <M>\mathfrak{u} = \mathfrak{u_2}\mathfrak{u_1}</M>, where <M>\mathfrak{u_1}</M>
      and <M>\mathfrak{u_2}</M> are positive length strings,
    </Item>
    <Item>
      <M>\mathfrak{u} = \mathfrak{u_2'}\mathfrak{u_1'}</M>, for some positive
      length strings <M>\mathfrak{u_1'}, \mathfrak{u_2'}</M> such that <M>\mathfrak{u_2}
      = \mathfrak{u_2'} \mathfrak{u_2''}</M>, <M>\mathfrak{u_1} = \mathfrak{u_1''}
      \mathfrak{u_1'}</M> and <M>\mathfrak{b} = \mathfrak{u_1''} \mathfrak{u_2''}</M>.
    </Item>
</List>

<ManSection>
  <Oper Name="BridgeQuiver" Arg="Q,rho" Comm="A quiver, a list of monomial relations"/>
  <Description>
    Arguments: <Arg>Q</Arg>  a quiver,
    <Arg>rho</Arg>  a list of monomial relations.<Br />
  </Description>
  <Returns>
    "Not a String Algebra" if the algebra presented by <Arg>(Q,rho)</Arg>
    is not a string algebra, <M>0</M> if the corresponding string algebra is
    non-domestic, the bridge quiver of the corresponding string algebra
    if it is domestic.
  </Returns>
</ManSection>



<ManSection>
  <Oper Name="LocalARQuiver" Arg="Q,rho,input_str" Comm="A quiver, a list of monomial relations
    and an input collection of characters"/>
  <Description>
    Arguments: <Arg>Q</Arg> -- a quiver,
    <Arg>rho</Arg> -- a list of monomial relations,
    <Arg>input_str</Arg> -- an input collection of characters.<Br />
  </Description>
  <Returns>
    "Not a String Algebra" if the algebra presented by <Arg>(Q,rho)</Arg>
    is not a string algebra, the list of (equivalence classes of)
    irreducible maps, i.e., the arrows of the Auslander-Reiten quiver, whose
    source or target is the string module corresponding to <Arg>input_str</Arg>.
  </Returns>
</ManSection>

<Example><![CDATA[
gap> Q := Quiver(4, [[1,2,"a"], [1,2,"b"], [2,3,"c"], [3,4,"d"], [3,4,"e"]]);
<quiver with 4 vertices and 5 arrows>
gap> rho := ["bc", "cd"];
[ "bc", "cd" ]
gap> IsValidString(Q,rho,"eca");
"Valid Positive Length String"
gap> StringsLessThan(Q,rho,2);
[ "(1,1)", "b", "Ab", "(1,-1)", "a", "ca", "Ba", "(2,1)", "c", "B", "ec", "aB",
 "(2,-1)", "A", "bA", "(3,1)", "e", "De", "(3,-1)", "d", "C", "Ed", "AC",
 "(4,1)", "E", "dE", "CE", "(4,-1)", "D", "eD" ]
gap> IsABand(Q,rho,"eca");
0
gap> IsABand(Q,rho,"Ab");
1
gap> BandsLessThan(Q,rho,3);
[ "Ab", "Ba", "aB", "bA", "De", "Ed", "dE", "eD" ]
gap> BandRepresentativesLessThan(Q,rho,3);
[ "aB", "bA", "dE", "eD" ]
gap> IsDomesticStringAlgebra(Q,rho);
true
gap> Q1 := BridgeQuiver(Q,rho);
<quiver with 4 vertices and 2 arrows>
gap> Display(Q1);
Quiver( ["v1","v2","v3","v4"], [["v3","v2","CE"],["v1","v4","ec"]] )
gap> LocalARQuiver(Q,rho,"eca");
[ "The cannonical embedding StringModule(eca) to StringModule(eDeca)",
  "The cannonical projection StringModule(ecaBa) to StringModule(eca)" ] ]]>
</Example>

</Section>

<Section><Heading>Attributes and Operations (for Quotients) of Path
    Algebras</Heading> 

<!-- Is never used -->
  <!-- <ManSection> -->
  <!--  <Attr Name="NormalFormFunction" Arg="object" Comm=""/> -->
  <!--  <Description> -->
  <!--   is a function that can compute normal forms for elements -->
  <!--   of <Arg>object</Arg>. It may be supplied by the user.<Br /> -->
  <!--   <Emph>Note: no documentation on this. Remove??</Emph> -->
  <!--  </Description> -->
  <!-- </ManSection> -->

<ManSection>
   <Oper Name="CartanMatrix" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>the Cartan matrix of the algebra <Arg>A</Arg>, after
     having checked that <Arg>A</Arg> is a finite dimensional quotient
     of a path algebra.
   </Returns>
</ManSection>

<ManSection> 
    <Oper Name="Centre/Center" Arg="A" Comm=""/> 
    <Description> 
      Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path 
      algebra.<Br /> 
    </Description> 
    <Returns> 
      the centre of the algebra <Arg>A</Arg> as a subalgebra. 
    </Returns> 
    <Description>
      The function computes the center of <Arg>A</Arg> if
      <Arg>A</Arg> is a finite dimensional quotient of a path algebra
      or  <Arg>A</Arg> is a path algebra with on restriction on the
      underlying quiver. 
    </Description>
 </ManSection> 

<ManSection> 
    <Oper Name="ComplexityOfAlgebra" Arg="A, n" Comm="for an algebra and a positive integer"/> 
    <Description> 
      Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path 
      algebra, <Arg>n</Arg> -- a positive integer.<Br /> 
    </Description> 
    <Returns>an estimate of the complexity of the algebra <Arg>A</Arg>. 
    </Returns>
    <Description>
      The function checks if the algebra <Arg>A</Arg> is known to have
      finite global dimension. If so, it returns complexity
      zero. Otherwise it tries to estimate the complexity in the
      following way. Recall that if a function <M>f(x)</M> is a
      polynomial in <M>x</M>, the degree of <M>f(x)</M> is given by
      <M>\lim_{n\to\infty} \frac{\log |f(n)|}{\log n}</M>. So then
      this function computes an estimate of the maximal complexity of
      the simple modules over <Arg>A</Arg> by approximating the
      complexity of each simple module <M>S</M> by considering the
      limit <M>\lim_{m\to \infty} \log \frac{\dim(P(S)(m))}{\log
      m}</M> where <M>P(S)(m)</M> is the <M>m</M>-th projective in a
      minimal projective resolution of <Arg>S</Arg> at stage <M>m</M>.
      This limit is estimated by <M>\frac{\log \dim(P(S)(n))}{\log
      n}</M>.
    </Description>
 </ManSection> 

<ManSection>
   <Attr Name="CoxeterMatrix" Arg="A" Comm=""/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>
     the Coxeter matrix of the algebra <Arg>A</Arg>, after having
     checked that <Arg>A</Arg> is a finite dimensional quotient of a
     path algebra.
   </Returns>
</ManSection>

 <ManSection> 
    <Attr Name="CoxeterPolynomial" Arg="A" Comm=""/> 
    <Description> 
      Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path 
      algebra.<Br /> 
    </Description> 
    <Returns> 
      the Coxeter polynomial of the algebra <Arg>A</Arg>, after having 
      checked that <Arg>A</Arg> is a finite dimensional quotient of a 
      path algebra. 
    </Returns> 
 </ManSection>

<ManSection>
  <Attr Name="Dimension"  Arg="A" Comm="computes the dimension of A"/>
  <Description>
    Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path algebra.<Br />
  </Description>
  <Returns>
    the dimension of the algebra <Arg>A</Arg> or <Emph>infinity</Emph> in case <Arg>A</Arg> is an infinite dimensional algebra.
  </Returns>
  <Description> 
For a quotient of a path algebra it uses Groebner bases machinery (it
computes Groebner basis for the ideal only in case it has not been
computed yet).
  </Description>
</ManSection>

<ManSection>
   <Attr Name="FrobeniusForm" Arg="A" Comm="for a quotient of a path algebra"/>
   <Description>
     Arguments: <Arg>A</Arg> -- a quotient of a path algebra.<Br />
   </Description>
   <Returns>
     false if <Arg>A</Arg> is not selfinjective algebra. Otherwise it
     returns the Frobenius form of <Arg>A</Arg>. 
   </Returns>
</ManSection>

<ManSection>
   <Attr Name="FrobeniusLinearFunctional" Arg="A" Comm="for a quotient of a path algebra"/>
   <Description>
     Arguments: <Arg>A</Arg> -- a quotient of a path algebra.<Br />
   </Description>
   <Returns>
     false if <Arg>A</Arg> is not selfinjective algebra. Otherwise it
     returns the Frobenius linear functional of <Arg>A</Arg>, which is
     used to construct the Frobenius form. 
   </Returns>
</ManSection> 

<ManSection>
  <Attr Name="GlobalDimension"  Arg="A" Comm="computes the dimension of A"/>
  <Description>
    Arguments: <Arg>A</Arg> -- an algebra.<Br />
  </Description>
  <Returns>
    the global dimension of the algebra <Arg>A</Arg> if it is
    known. Otherwise it returns an error message saying "no method found!". 
  </Returns>
  <Description>
    There is no method installed for this yet. 
  </Description>
</ManSection>

<ManSection>
   <Attr Name="LoewyLength" Arg="A" Comm="for a (quotient of a) path algebra"/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>
     fail if <Arg>A</Arg> is not finite dimensional. Otherwise it
     returns the Loewy length of the algebra <Arg>A</Arg>.
   </Returns>
</ManSection>

<ManSection>
   <Attr Name="NakayamaAutomorphism" Arg="A" Comm="for a (quotient of a) path algebra"/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>
     false if <Arg>A</Arg> is not selfinjective algebra. Otherwise it
     returns the Nakayama automorphism of <Arg>A</Arg>. 
   </Returns>
</ManSection> 

<ManSection>
   <Attr Name="NakayamaPermutation" Arg="A" Comm="for a (quotient of a) path algebra"/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>
     false if <Arg>A</Arg> is not selfinjective algebra. Otherwise it
     returns a list of two elements where the first is the Nakayama permutation on the 
     simple modules and the second is the Nakayama permutation on the index set of the 
     simple modules of <Arg>A</Arg>.
   </Returns>
</ManSection> 

<ManSection>
   <Attr Name="OrderOfNakayamaAutomorphism" Arg="A" Comm="for a (quotient of a) path algebra"/>
   <Description>
     Arguments: <Arg>A</Arg> -- a path algebra or a quotient of a path
     algebra.<Br />
   </Description>
   <Returns>
     false if <Arg>A</Arg> is not selfinjective algebra. Otherwise it
     returns the order of the Nakayama autormorphism of <Arg>A</Arg>
     AS AN ELEMENT OF <M>\operatorname{Aut}(A)</M>. 
   </Returns>
</ManSection>
 
<ManSection> 
    <Attr Name="RadicalSeriesOfAlgebra" Arg="A" Comm=""/> 
    <Description> 
      Arguments: <Arg>A</Arg> -- an algebra.<Br /> 
    </Description> 
    <Returns> 
      the radical series of the algebra  <Arg>A</Arg> in a 
      list, where the first element is the algebra  <Arg>A</Arg> itself, then 
      radical of <Arg>A</Arg>, radical square of <Arg>A</Arg>, and so on.
    </Returns> 
 </ManSection> 
</Section>


<Section><Heading>Attributes and Operations on Elements
 of Quotients of Path Algebra</Heading>

 <ManSection>
   <Prop Name="IsElementOfQuotientOfPathAlgebra" Arg="object" Comm=""/>
   <Description>
     Arguments: <Arg>object</Arg> -- any object in &GAP;.<Br />
   </Description>
   <Returns>
     true whenever <Arg>object</Arg> is an element of some quotient of a
     path algebra.
   </Returns>
  </ManSection>

<Example><![CDATA[
gap> elem := quot.a*quot.b;
[(1)*a*b]
gap> IsElementOfQuotientOfPathAlgebra(elem);
true
gap> IsElementOfQuotientOfPathAlgebra(FQ.a*FQ.b);    
false ]]>
</Example>

  <ManSection>
   <Oper Name="Coefficients" Arg="B, element" Comm=""/>
   <Description>
     Arguments: <Arg>B, element</Arg> -- a basis for a quotient of a
     path algebra and element thereof.<Br />
   </Description>
   <Returns>
     the coefficients of the <Arg>element</Arg> in terms of the
    canonical basis <Arg>B</Arg> of the quotient of a path algebra in
    which <Arg>element</Arg> is an element.
   </Returns>
  </ManSection>

   <ManSection> 
    <Oper Name="IsNormalForm" Arg="element" Comm=""/> 
    <Description> 
      Arguments: <Arg>element</Arg> -- an element of a path algebra.<Br /> 
    </Description> 
    <Returns>true if <Arg>element</Arg> is known to be in normal form. 
    </Returns> 
   </ManSection> 

 <Example><![CDATA[ 
 gap> IsNormalForm(elem);  
 true  ]]>
</Example> 

   <ManSection> 
    <Oper Name="&lt;" Label="for two elements of a path algebra" Arg="a, b" Comm=""/> 
    <Description> 
      Arguments: <Arg>a</Arg> and <Arg>b</Arg> -- elements from a path 
     algebra.<Br /> 
    </Description> 
    <Returns>true whenever <Arg>a</Arg> &lt; <Arg>b</Arg>. 
    </Returns> 
   </ManSection> 

<!-- Note: This function is to be rewritten. -->
  <ManSection>
   <Oper Name="ElementOfQuotientOfPathAlgebra" Arg="family, element,
   computenormal" Comm=""/>
   <Description>
     Arguments: <Arg>family</Arg> -- a family of
     elements, <Arg>element</Arg> -- an element of a path
     algebra, <Arg>computenormal</Arg> -- true or false.<Br />
   </Description>
   <Returns>The projection of <Arg>element</Arg> into the quotient given
    by <Arg>family</Arg>.  If <Arg>computenormal</Arg> is false, then
    the normal form of the projection of <Arg>element</Arg> is
    returned.
   </Returns>
   <Description><Arg>family</Arg> is the ElementsFamily of the family
   of the algebra <Arg>element</Arg> is projected into.
   </Description>
  </ManSection>

  <ManSection>
   <Attr Name="OriginalPathAlgebra" Arg="algebra" Comm="for a quotient
   of a path algebra"/>
   <Description>
     Arguments: <Arg>algebra</Arg> -- an algebra.<Br />
   </Description>
   <Returns>a path algebra.</Returns>
   <Description>If <Arg>algebra</Arg> is a quotient of a path algebra
    or just a path algebra itself, the returned algebra is the path
    algebra it was constructed from. Otherwise it returns an error
    saying that the algebra entered was not given as a quotient of a path
    algebra.
   </Description>
  </ManSection>
</Section>

<Section Label="qpa:predefinedalgebras"><Heading>Predefined classes and classes 
  of (quotients of) path algebras</Heading>

<ManSection>
  <Func Name="BrauerConfigurationAlgebra" Arg="field, brauer_configuration" 
  Comm="creates a Brauer configuration algebra"/>
  <Description>
    Arguments: <Arg>field</Arg> -- a field, <Arg>brauer_configuration</Arg> -- a list of the form [[vertices], [edges/polygons], [orientations]].<Br />
  </Description>
  <Returns>
    the Brauer configuration algebra corresponding to the brauer configuration
    <Arg>brauer_configuration</Arg> over the field <Arg>field</Arg>. If the brauer configuration entered is not valid, fail is returned.
  </Returns>
  <Description>The <Arg>brauer_configuration</Arg> consists of vertices, polygons/edges, and orientations corrresponding to a Brauer Configuration or Brauer Tree. Each vertex must have the form ["vertexname", multiplicity]. Each edge/polygon must have the form ["edgename", "vertex1name", "vertex2name", ...]. There must be an orientation corresponding to each vertex. Orientations must have the form ["edge1name/polygon1name", "edge2name/polygon2name", ...].</Description>
</ManSection>

<Example><![CDATA[ 
gap> alg := BrauerConfigurationAlgebra(Rationals, [ [ [ "v1", 1 ], [ "v2", 1 ], [ "v3", 2 ] ], [ [ "e1", "v1", "v2" ], [ "e2", "v2", "v3" ] ], [ [ "e1" ], [ "e1", "e2" ], ["e2" ] ]]);
<A quotient of the path algebra <Rationals[<quiver with 2 vertices and 
3 arrows>]> modulo the ideal 
<two-sided ideal in <Rationals[<quiver with 2 vertices and 3 arrows>]>, 
  (5 generators)>>]]>
</Example>

<ManSection>
  <Oper Name="CanonicalAlgebra" Arg="field, weights [, relcoeff]" 
	Comm="creates a canonical algebra"/>
  <Description>
    Arguments: <Arg>field</Arg> -- a field, <Arg>weights</Arg> -- a
    list of positive integers, [, <A>relcoeff</A> -- a list of non-zero
    elements in the field.<Br />
  </Description>
  <Returns>the canonical algebra over the <Arg>field</Arg> with the
  quiver given by the weight sequence <Arg>weights</Arg> and the
  relations given by the coefficients <Arg>relcoeff</Arg>.
  </Returns>
  <Description>It function checks if all the <Arg>weights</Arg> are
  greater or equal to two, the number of weights is at least two, the
  number of coefficients is the number of <Arg>weights</Arg> - 2, the
  coefficients for the relations are in field and non-zero. If only
  the two first arguments are given, then the number of weights must
  be two.
  </Description>
</ManSection>



<ManSection>
  <Oper Name="KroneckerAlgebra" Arg="field, n" 
	Comm="creates a Kronecker algebra"/>
  <Description>
    Arguments: <Arg>field</Arg> -- a field, <Arg>n</Arg> -- a
    positive integer.<Br />
  </Description>
  <Returns>the <Arg>n</Arg>-Kronecker algebra over the field 
  <Arg>field</Arg>.
  </Returns>
  <Description>It function checks if the number <Arg>n</Arg> of
  arrows is greater or equal to two and returns an error message
  if not. 
  </Description>
</ManSection>

<ManSection>
  <Func Name="NakayamaAlgebra" Arg="admiss-seq,field" 
	Comm="creates a Nakayama algebra"/>
  <Description>
    Arguments: <Arg>field</Arg> -- a field, <Arg>admiss-seq</Arg> -- a list of positive
    integers.<Br />
  </Description>
  <Returns>
    the Nakayama algebra corresponding to the admissible sequence
    <Arg>admiss-seq</Arg> over the field <Arg>field</Arg>. If the
    entered sequence is not an admissible sequence, the sequence is
    returned.
  </Returns>
  <Description>The <Arg>admiss-seq</Arg> consists of the dimensions
  of the projective representations.</Description>
</ManSection>

<ManSection>
  <Oper Name="AdmissibleSequenceGenerator" Arg="num_vert, height " 
	Comm="creates a Kronecker algebra"/>
  <Description>
    Arguments: <Arg>num_vert</Arg>, <Arg>height</Arg> -- two
    positive integers.<Br />
  </Description>
  <Returns>all admissible sequences of Nakayama algebras with
  <Arg>num_vert</Arg> number of vertices, and indecomposable
  projective modules of length at most
  <Arg>height</Arg>.
  </Returns>
</ManSection>

<Example><![CDATA[ 
gap> alg := NakayamaAlgebra([2,1], Rationals);
<Rationals[<quiver with 2 vertices and 1 arrows>]>
gap> QuiverOfPathAlgebra(alg);
<quiver with 2 vertices and 1 arrows>]]>
</Example> 

<ManSection>
  <Oper Name="PosetAlgebra" Arg="F, P" 
	Comm="creates a poset algebra"/>
  <Description>
    Arguments: <Arg>F</Arg> -- a field, <Arg>P</Arg> -- a poset.<Br />
  </Description>
  <Returns>the poset algebra associated to the poset <Arg>P</Arg> over
  the field <Arg>K</Arg>. 
  </Returns>
</ManSection>

  <ManSection>
    <Attr Name="PosetOfPosetAlgebra" Arg="A"/>
    <Description>
      Arguments: <Arg>A</Arg> -- a poset algebra.<Br />
    </Description>
    <Returns>
      the poset from which that poset algebra <Arg>A</Arg> is
      constructed. 
    </Returns>
  </ManSection>

<ManSection>
  <Oper Name="TruncatedPathAlgebra" Arg="F, Q, n" 
	Comm="creates a truncated path algebra"/>
  <Description>
    Arguments: <Arg>F</Arg> -- a field, <Arg>Q</Arg> -- a
    quiver, <Arg>n</Arg> -- a positive integer.<Br />
  </Description>
  <Returns>the truncated path algebra <Arg>KQ/I</Arg>,
  where <Arg>I</Arg> is the ideal generated by all paths of
  length <Arg>n</Arg> in <Arg>KQ</Arg>.
  </Returns>
</ManSection>

<ManSection>
  <Prop Name="IsSpecialBiserialQuiver" Arg="Q" Comm="checks if Q is a special biserial quiver"/>
  <Description>
    Arguments: <Arg>Q</Arg> -- a quiver. <Br />
  </Description>
  <Returns>true whenever <Arg>Q</Arg> is a <Emph>"special biserial"</Emph> quiver, i.e. 
  every vertex in <Arg>Q</Arg> is a source (resp. target) 
  of at most 2 arrows.
  </Returns>
  <Description>
    <Emph>Note:</Emph> e.g. a path algebra of one loop IS NOT special biserial,
    but one loop IS special biserial quiver (cf. <Ref Prop="IsSpecialBiserialAlgebra"/>
    and also an Example below).
  </Description>
</ManSection>



<Example><![CDATA[
gap> Q := Quiver(1, [ [1,1,"a"], [1,1,"b"] ]);;  
gap> A := PathAlgebra(Rationals, Q);;
gap> IsSpecialBiserialAlgebra(A); IsStringAlgebra(A);
false
false
gap> rel1 := [A.a*A.b, A.a^2, A.b^2];  
[ (1)*a*b, (1)*a^2, (1)*b^2 ]
gap> quo1 := A/rel1;;
gap> IsSpecialBiserialAlgebra(quo1); IsStringAlgebra(quo1);
true
true
gap> rel2 := [A.a*A.b-A.b*A.a, A.a^2, A.b^2];  
[ (1)*a*b+(-1)*b*a, (1)*a^2, (1)*b^2 ]
gap> quo2 := A/rel2;;
gap> IsSpecialBiserialAlgebra(quo2); IsStringAlgebra(quo2);
true
false
gap> rel3 := [A.a*A.b+A.b*A.a, A.a^2, A.b^2, A.b*A.a];   
[ (1)*a*b+(1)*b*a, (1)*a^2, (1)*b^2, (1)*b*a ]
gap> quo3 := A/rel3;;
gap> IsSpecialBiserialAlgebra(quo3); IsStringAlgebra(quo3);
true
true
gap> rel4 := [A.a*A.b, A.a^2, A.b^3]; 
[ (1)*a*b, (1)*a^2, (1)*b^3 ]
gap> quo4 := A/rel4;;
gap> IsSpecialBiserialAlgebra(quo4); IsStringAlgebra(quo4);
false
false ]]>
</Example>
</Section>

<Section Label="qpa:opposite">
  <Heading>Opposite algebras</Heading>

<ManSection>
  <Oper Name="OppositePath" Arg="p"/>
  <Description>
    Arguments: <Arg>p</Arg> -- a path.<Br />
  </Description>
  <Returns>
    the path corresponding to <Arg>p</Arg> in the opposite quiver.
  </Returns>
</ManSection>

The following example illustrates the use of
<Ref Attr="OppositeQuiver"/> and <Ref Oper="OppositePath"/>.

<Example><![CDATA[
gap> Q := Quiver( [ "u", "v" ], [ [ "u", "u", "a" ], 
>              [ "u", "v", "b" ] ] );
<quiver with 2 vertices and 2 arrows>
gap> Qop := OppositeQuiver(Q);
<quiver with 2 vertices and 2 arrows>
gap> VerticesOfQuiver( Qop );
[ u_op, v_op ]
gap> ArrowsOfQuiver( Qop );
[ a_op, b_op ]
gap> OppositePath( Q.a * Q.b );
b_op*a_op
gap> IsIdenticalObj( Q, OppositeQuiver( Qop ) );
true
gap> OppositePath( Qop.b_op * Qop.a_op );
a*b]]>
</Example>

  
<ManSection>
  <Attr Name="OppositePathAlgebra" Arg="A"/>
  <Description>
    Arguments: <Arg>A</Arg> -- a path algebra or quotient of path algebra.<Br />
  </Description>
  <Returns>
    the opposite algebra <M><Arg>A</Arg>^\text{op}</M>.
  </Returns>
  <Description>
    This attribute contains the opposite algebra of an algebra.<P/>
    
    The opposite algebra of a path algebra is the path algebra
    over the opposite quiver (as given by
    <Ref Attr="OppositeQuiver"/>).  The opposite algebra of a
    quotient of a path algebra has the opposite quiver and the
    opposite relations of the original algebra.<P/>
    
    The function <Ref Oper="OppositePathAlgebraElement"/> takes an
    algebra element to the corresponding element in the opposite
    algebra.<P/>
    
    The opposite of the opposite of an algebra <M>A</M> is
    isomorphic to <M>A</M>.  In QPA, we regard these two algebras to
    be the same, so the
    call <Code>OppositePathAlgebra(OppositePathAlgebra(A))</Code>
    returns the object <Code>A</Code>.
  </Description>
</ManSection>
  
  <ManSection>
    <Func Name="OppositePathAlgebraElement" Arg="x"/>
    <Description>
      Arguments: <Arg>x</Arg> -- a path.<Br />
    </Description>
    <Returns>
      the element corresponding to <Arg>x</Arg> in the opposite algebra.
    </Returns>
  </ManSection>

  <ManSection>
  <Attr Name="OppositeAlgebraHomomorphism" Arg="A"/>
  <Description>
    Arguments: <Arg>A</Arg> -- an algebra homomorphism of two (quotients) of path algebras.<Br />
  </Description>
  <Returns>
  algebra homomorphism between the corresponding opposite algebras.
  </Returns>
</ManSection>
  

  The following example illustrates the use of
  <Ref Attr="OppositePathAlgebra"/> and
  <Ref Oper="OppositePathAlgebraElement"/>.

  <Example><![CDATA[
gap> Q := Quiver( [ "u", "v" ], [ [ "u", "u", "a" ], 
>              [ "u", "v", "b" ] ] );
<quiver with 2 vertices and 2 arrows>
gap> A := PathAlgebra( Rationals, Q );
<Rationals[<quiver with 2 vertices and 2 arrows>]>
gap> OppositePathAlgebra( A );
<Rationals[<quiver with 2 vertices and 2 arrows>]>
gap> OppositePathAlgebraElement( A.u + 2*A.a + 5*A.a*A.b );
(1)*u_op+(2)*a_op+(5)*b_op*a_op
gap> IsIdenticalObj( A, 
>         OppositePathAlgebra( OppositePathAlgebra( A ) ) );
true]]>
</Example>
</Section>

<Section Label="qpa:patensor">
  <Heading>Tensor products of path algebras</Heading>

  If <M>\Lambda</M> and <M>\Gamma</M> are quotients of path algebras
  over the same field <M>F</M>, then their tensor product <M>\Lambda
  \tensor_F \Gamma</M> is also a quotient of a path algebra
  over <M>F</M>.<P/>

  The quiver for the tensor product path algebra is the
  <Ref Oper="QuiverProduct"/> of the quivers of the original
  algebras.<P/>

  The operation <Ref Oper="TensorProductOfAlgebras"/> computes the
  tensor products of two quotients of path algebras as a quotient of a
  path algebra.

  <ManSection>
    <Oper Name="QuiverProduct" Arg="Q1, Q2"/>
    <Description>
      Arguments: <Arg>Q1</Arg> and <Arg>Q2</Arg> -- quivers.<Br />
    </Description>
    <Returns>
      the product quiver <M><Arg>Q1</Arg>
      \quiverproduct <Arg>Q2</Arg></M>.  
    </Returns>
    <Description>
      A vertex in <M><Arg>Q1</Arg> \quiverproduct <Arg>Q2</Arg></M>
      which is made by combining a vertex named <C>u</C>
      in <Arg>Q1</Arg> with a vertex <C>v</C> in <Arg>Q2</Arg> is
      named <C>u_v</C>.  Arrows are named similarly (they are made by
      combining an arrow from one quiver with a vertex from the
      other).
    </Description>
  </ManSection>

  <ManSection>
    <Attr Name="QuiverProductDecomposition" Arg="Q"/>
    <Description>
      Arguments: <Arg>Q</Arg> -- a quiver.<Br />
    </Description>
    <Returns>
      the original quivers <Arg>Q</Arg> is a product of,
      if <Arg>Q</Arg> was created by the <Ref Oper="QuiverProduct"/>
      operation.  
    </Returns>
    <Description>
      The value of this attribute is an object in the category
      <Ref Filt="IsQuiverProductDecomposition"/>.
    </Description>
  </ManSection>

  <ManSection>
    <Filt Name="IsQuiverProductDecomposition" Arg="object" Type="category" />
    <Description>
      Arguments: <Arg>object</Arg> -- any object in &GAP;.
    </Description>
    <Description>
      Category for objects containing information about the relation
      between a product quiver and the quivers it is a product of.
      The quiver factors can be extracted from the decomposition
      object by using the [] notation (like accessing elements of a
      list).  The decomposition object is also used by the operations
      <Ref Oper="IncludeInProductQuiver"/> and
      <Ref Oper="ProjectFromProductQuiver"/>.
    </Description>
  </ManSection>

  <ManSection>
    <Oper Name="IncludeInProductQuiver" Arg="L, Q"/>
    <Description>
      Arguments: <Arg>L</Arg> -- a list containing the
      paths <M>q_1</M> and <M>q_2</M>, <M>Q</M> -- a
      product quiver.<Br />
    </Description>
    <Returns>a path in <Arg>Q</Arg>.
    </Returns>
    <Description>
      Includes paths <M>q_1</M> and <M>q_2</M> from two quivers into
      the product of these quivers, <Arg>Q</Arg>.  If at least one
      of <M>q_1</M> and <M>q_2</M> is a vertex, there is exactly one
      possible inclusion.  If they are both non-trivial paths, there
      are several possibilities.  This operation constructs the path
      which is the inclusion of <M>q_1</M> at the source of <M>q_2</M>
      multiplied with the inclusion of <M>q_2</M> at the target
      of <M>q_1</M>.
    </Description>
  </ManSection>

  <ManSection>
    <Oper Name="ProjectFromProductQuiver" Arg="i, p"/>
    <Description>
      Arguments: <Arg>i</Arg> -- a positive integer, <Arg>p</Arg> -- a
      path in the product quiver.<Br />
    </Description>
    <Returns>the projection of the product quiver path <Arg>p</Arg>
      to one of the factors.  Which factor it should be projected to
      is specified by the argument <Arg>i</Arg>.
    </Returns>
  </ManSection>

  The following example shows how the operations related to quiver
  products are used.

  <Example><![CDATA[
gap> q1 := Quiver( [ "u1", "u2" ], [ [ "u1", "u2", "a" ] ] );
<quiver with 2 vertices and 1 arrows>
gap> q2 := Quiver( [ "v1", "v2", "v3" ],
                      [ [ "v1", "v2", "b" ],
                        [ "v2", "v3", "c" ] ] );
<quiver with 3 vertices and 2 arrows>
gap> q1_q2 := QuiverProduct( q1, q2 );
<quiver with 6 vertices and 7 arrows>
gap> q1_q2.u1_b * q1_q2.a_v2;
u1_b*a_v2
gap> IncludeInProductQuiver( [ q1.a, q2.b * q2.c ], q1_q2 );
a_v1*u2_b*u2_c
gap> ProjectFromProductQuiver( 2, q1_q2.a_v1 * q1_q2.u2_b * q1_q2.u2_c );
b*c
gap> q1_q2_dec := QuiverProductDecomposition( q1_q2 );
<object>
gap> q1_q2_dec[ 1 ];
<quiver with 2 vertices and 1 arrows>
gap> q1_q2_dec[ 1 ] = q1;
true  ]]>
</Example>

  <ManSection>
   <Oper Name="TensorProductOfAlgebras" Arg="FQ1, FQ2"/>
   <Description>
     Arguments: <Arg>FQ1</Arg> and <Arg>FQ2</Arg> -- (quotients of)
     path algebras.<Br />
   </Description>
   <Returns>
     The tensor product of <Arg>FQ1</Arg> and <Arg>FQ2</Arg>.
   </Returns>
   <Description>
     The result is a quotient of a path algebra, whose quiver is the
     <Ref Oper="QuiverProduct"/> of the quivers of the operands.
   </Description>
  </ManSection>

    <ManSection>
   <Oper Name="TensorAlgebrasInclusion" Arg="T, n"/>
   <Description>
     Arguments: <Arg>T</Arg> -- quiver algebra, <Arg>n</Arg> -- 1 or 2.<Br />
   </Description>
   <Returns>
     Returns the inclusion  <M>A \hookrightarrow A \otimes B</M> or the
     inclusion <M>B \hookrightarrow A \otimes B</M> if <M>n = 1</M> or
     <M>n = 2</M>, respectively.  
   </Returns>
  </ManSection>
  
  <ManSection>
    <Oper Name="SimpleTensor" Arg="L, T"/>
    <Description>
      Arguments: <Arg>L</Arg> -- a list containing two
			      elements <M>x</M> and <M>y</M> of two
			      (quotients of) path
			      algebras, <Arg>T</Arg> -- the tensor
			      product of these algebras.<Br />
    </Description>
    <Returns>
      the simple tensor <M>x \tensor y</M>.
    </Returns>
    <Description>
      <M>x \tensor y</M> is in the tensor product <Arg>T</Arg>
      (produced by <Ref Oper="TensorProductOfAlgebras"/>).
    </Description>
  </ManSection>

  <ManSection>
    <Attr Name="TensorProductDecomposition" Arg="T"/>
    <Description>
      Arguments: <Arg>T</Arg> -- a tensor product of path
      algebras.<Br />
    </Description>
    <Returns>a list of the factors in the tensor product.
    </Returns>
    <Description><Arg>T</Arg> should be produced by
      <Ref Oper="TensorProductOfAlgebras"/>).
    </Description>
  </ManSection>

The following example shows how the operations for tensor products
of quotients of path algebras are used.

  <Example><![CDATA[
gap> q1 := Quiver( [ "u1", "u2" ], [ [ "u1", "u2", "a" ] ] );
<quiver with 2 vertices and 1 arrows>
gap> q2 := Quiver( [ "v1", "v2", "v3", "v4" ],
>                       [ [ "v1", "v2", "b" ],
>                         [ "v1", "v3", "c" ],
>                         [ "v2", "v4", "d" ],
>                         [ "v3", "v4", "e" ] ] );
<quiver with 4 vertices and 4 arrows>
gap> fq1 := PathAlgebra( Rationals, q1 );
<Rationals[<quiver with 2 vertices and 1 arrows>]>
gap> fq2 := PathAlgebra( Rationals, q2 );
<Rationals[<quiver with 4 vertices and 4 arrows>]>
gap> I := Ideal( fq2, [ fq2.b * fq2.d - fq2.c * fq2.e ] );
<two-sided ideal in <Rationals[<quiver with 4 vertices and 4 arrows>]>
    , (1 generators)>
gap> quot := fq2 / I;
<Rationals[<quiver with 4 vertices and 4 arrows>]/
<two-sided ideal in <Rationals[<quiver with 4 vertices and 4 arrows>]>
    , (1 generators)>>
gap> t := TensorProductOfAlgebras( fq1, quot );
<Rationals[<quiver with 8 vertices and 12 arrows>]/
<two-sided ideal in <Rationals[<quiver with 8 vertices and 
    12 arrows>]>, (6 generators)>>
gap> SimpleTensor( [ fq1.a, quot.b ], t );
[(1)*u1_b*a_v2]
gap> t_dec := TensorProductDecomposition( t );
[ <Rationals[<quiver with 2 vertices and 1 arrows>]>, 
  <Rationals[<quiver with 4 vertices and 4 arrows>]/
    <two-sided ideal in <Rationals[<quiver with 4 vertices and 
        4 arrows>]>, (1 generators)>> ]
gap> t_dec[ 1 ] = fq1;
true]]>
</Example>



  <ManSection>
    <Attr Name="EnvelopingAlgebra" Arg="A"/>
    <Description>
      Arguments: <Arg>A</Arg> -- a (quotient of) a path
      algebra. <Br /> 
    </Description>
    <Returns>the enveloping algebra <M><Arg>A</Arg>^\text{e}
      = <Arg>A</Arg>^\text{op} \tensor <Arg>A</Arg></M>
      of <Arg>A</Arg>.
    </Returns>
  </ManSection>

    <ManSection>
    <Attr Name="EnvelopingAlgebraHomomorphism" Arg="f"/>
    <Description>
      Arguments: <Arg>f</Arg> -- an algebra homomorphism of two (quotients of) a path
      algebras. <Br /> 
    </Description>
    <Returns>the algebra homomorphism between the corresponding
    enveloping algebras the source of <Arg>f</Arg> and the range of
    <Arg>f</Arg>. 
    </Returns>
  </ManSection>

  <ManSection>
    <Prop Name="IsEnvelopingAlgebra" Arg="A"/>
    <Description>
      Arguments: <Arg>A</Arg> -- an algebra.<Br />
    </Description>
    <Returns>true if and only if <Arg>A</Arg> is the result of a call to
      <Ref Oper="EnvelopingAlgebra"/>.
    </Returns>
  </ManSection>

  <ManSection>
    <Attr Name="AlgebraAsModuleOverEnvelopingAlgebra" Arg=" A "/>
    <Description>
      Arguments: <Arg>A</Arg> -- a
      (quotient of a) path algebra <Arg>A</Arg>. <Br />
    </Description>
    <Returns>the algebra <Arg>A</Arg> as a right module over the
      enveloping algebra of <Arg>A</Arg>. 
    </Returns>
  </ManSection>

  <ManSection>
    <Attr Name="DualOfAlgebraAsModuleOverEnvelopingAlgebra" Arg=" A "/>
    <Description>
      Arguments: <Arg>A</Arg> -- a finite dimensional (admissible quotient of) a path algebra <Arg>A</Arg>. <Br />
    </Description>
    <Returns>the algebra <Arg>A</Arg> as a right module over the
      enveloping algebra of <Arg>A</Arg>. 
    </Returns>
  </ManSection>

  <ManSection>
    <Attr Name="TrivialExtensionOfQuiverAlgebra" Arg=" A "/>
    <Description>
      Arguments: <Arg>A</Arg> -- a finite dimensional (admissible quotient of) a path algebra <Arg>A</Arg>. <Br />
    </Description>
    <Returns>the trivial extension algebra <M>T(A)=A\oplus D(A)</M> of the entered algebra <Arg>A</Arg>. 
    </Returns>
  </ManSection>

   <ManSection>
    <Attr Name="TrivialExtensionOfQuiverAlgebraProjection" Arg=" A "/>
    <Description>
      Arguments: <Arg>A</Arg> -- a finite dimensional (admissible quotient of) a path algebra <Arg>A</Arg>. <Br />
    </Description>
    <Returns>the natural algebra projection form trivial extension  <M>T(A)</M>  to  <Arg>A</Arg>.
    </Returns>
  </ManSection>

</Section>

<Section Label="qpa:operationsonquiveralgebras">
  <Heading>Operations on quiver algebras</Heading>

<ManSection>
    <Oper Name="QuiverAlgebraOfAmodAeA" Arg="A, elist"/>
    <Description>
      Arguments: <Arg>A</Arg>, <Arg>elist</Arg> - a finite dimensional
      quiver algebra and a list of integers.<Br />
    </Description>
    <Returns>a quiver algebra isomorphic <Arg>A</Arg> modulo the ideal
    generated by a sum of vertices in <Arg>A</Arg>.
    </Returns> 
    <Description>
      Given a quiver algebra <A>A</A> and a sum of vertices  <M>e</M>,
      this function computes the quiver algebra <M>A/AeA</M>. The list
      <A>elist</A>  is a list of integers, where each integer occurring in
      the list corresponds to the position of the vertex in the
      vertices defining the idempotent <M>e</M>. 
    </Description>
</ManSection>

<ManSection>
    <Oper Name="QuiverAlgebraOfeAe" Arg="A, elist"/>
    <Description>
      Arguments: <Arg>A</Arg>, <Arg>e</Arg> - a finite dimensional
      quiver algebra and an idempotent.<Br />
    </Description>
    <Returns>a quiver algebra isomorphic <M>eAe</M>, where
    <Arg>A</Arg> is the entered algebra and <Arg>e</Arg> is the
    entered idempotent.
    </Returns> 
    <Description>
      Given a quiver algebra <A>A</A> and an idempotent <A>e</A>,
      this function computes the quiver algebra isomorphic to
      <M>eAe</M>. The function checks if the entered element <A>e</A>
      is an idempotent in <A>A</A>. 
    </Description>
  </ManSection>  

</Section>

<Section Label="qpa:moregeneralalgebrastuff">
  <Heading>Finite dimensional algebras over finite fields</Heading>

<ManSection>
    <Oper Name="AlgebraAsQuiverAlgebra" Arg="A"/>
    <Description>
      Arguments: <Arg>A</Arg> - a finite dimensional algebra over a
      finite field.<Br />
    </Description>
    <Returns>a (quotient of a) path algebra isomorphic to the entered
    algebra <Arg>A</Arg> whenever possible and a list of the images of
    the vertices and the arrows in this path algebra in <Arg>A</Arg>. 
    </Returns> 
    <Description>
     The operation only applies when <Arg>A</Arg> is a finite
     dimensional indecomposable algebra over a finite field, otherwise
     it returns an error message.  It checks the algebra <Arg>A</Arg>
     is basic and elementary over some field and otherwise it returns
     an error message.  In the list of images the images of the
     vertices are listed first and then the images of the arrows. 
    </Description>
  </ManSection>

<ManSection>
    <Oper Name="BlocksOfAlgebra" Arg="A"/>
    <Description>
      Arguments: <Arg>A</Arg> - a finite dimensional algebra.<Br />
    </Description>
    <Returns>a block decomposition of the entered algebra <A>A</A>
    as a list of indecomposable algebras.
    </Returns> 
  </ManSection>
  
<ManSection>
    <Prop Name="IsBasicAlgebra" Arg="A"/>
    <Description>
      Arguments: <Arg>A</Arg> - a finite dimensional algebra over a finite field.<Br />
    </Description>
    <Returns> true if the entered algebra <Arg>A</Arg> is a (finite
    dimensional) basic algebra and false otherwise. This method only 
    applies to algebras over finite fields. 
    </Returns> 
  </ManSection>

<ManSection>
    <Prop Name="IsElementaryAlgebra" Arg="A"/>
    <Description>
      Arguments: <Arg>A</Arg> - a finite dimensional algebra over a finite field.<Br />
    </Description>
    <Returns> true if the entered algebra <Arg>A</Arg> is a (finite
    dimensional) elementary algebra and false otherwise. This method only 
    applies to algebras over finite fields. 
    </Returns> 
    <Description>
      The algebra <Arg>A</Arg> need not to be an elementary algebra
      over the field which it is defined, but be an elementary algebra
      over a field extension.
    </Description>
</ManSection>

<ManSection>
  <Oper Name="PreprojectiveAlgebra" Arg="M, n"/>
  <Oper Name="PreprojectiveAlgebra" Arg="A"/>  
    <Description>
      Arguments (first version): <Arg>M</Arg> - a path algebra module over finite
      dimensional hereditary algebra over a
      finite field, <Arg>n</Arg> - an integer.<Br />
      Arguments (second version): <Arg>A</Arg> - a path algebra.<Br />
    </Description>
    <Returns>in the first version the preprojective algebra of the
    module <Arg>M</Arg> if it only has support up to degree
    <Arg>n</Arg>.  In the second version it returns the preprojective
    algebra of a hereditary algebra given by a path algebra over a
    field. 
    </Returns> 
  </ManSection>
 
<ManSection>
    <Attr Name="PrimitiveIdempotents" Arg="A"/>
    <Description>
      Arguments: <Arg>A</Arg> - a finite dimensional simple algebra over a finite field.<Br />
    </Description>
    <Returns> a complete set of primitive idempotents <Math>\{ e_i
    \}</Math> such that <Math>A \simeq Ae_1 + ... + Ae_n</Math>.
    </Returns> 
    <Description>
      TODO: Understand what this function actually does.
    </Description>
  </ManSection>

</Section>

<Section Label="qpa:idempotentalgebrastuff">
  <Heading>Algebras</Heading>

<ManSection>
    <Oper Name="LiftingCompleteSetOfOrthogonalIdempotents" Arg="f, e"/>
    <Description>
      Arguments: <Arg>map</Arg> - an algebra homomorphism, <Arg>idempotents</Arg>
      elements in the range of <Arg>map</Arg>.<Br />
    </Description>
    <Returns>a complete set of orthogonal idempotents in
    <C>Source(f)</C> which are liftings of the entered
    <Arg>idempotents</Arg> whenever possible. 
    </Returns> 
    <Description>
     The operation only applies when the domain of <Arg>f</Arg> is
     finite dimensional.  It checks if the list of elements
     <Arg>idempotents</Arg> is a set complete set of orthogonal
     idempotents.  If some idempotent in <Arg>idempotents</Arg> is not
     in the image of <Arg>map</Arg>, then an error message is
     returned.  If all idempotents in <Arg>idempotents</Arg> has a
     preimage, then this operation returns a complete set of
     orthogonal of idempotents which is a lifting of the idempotents
     in <Arg>idempotents</Arg> to the source
     of <Arg>f</Arg> whenever possible or it returns fail.  
    </Description>
  </ManSection>

<ManSection>
    <Oper Name="LiftingIdempotent" Arg="f, e"/>
    <Description>
      Arguments: <Arg>f</Arg> - an algebra homomorphism, <Arg>e</Arg>
      an element in the range of <Arg>f</Arg>.<Br />
    </Description>
    <Returns>an idempotent  <M>a</M> in <C>Source(f)</C> such that
    <C>ImageElm(f, a) = e</C> whenever possible.  If <Arg>e</Arg> is
    not in the image of <Arg>f</Arg>, an error message is given, and if
    <Arg>e</Arg> does not have a preimage by <Arg>f</Arg> <C>fail</C>
    is returned. 
    </Returns> 
    <Description>
     The operation only applies when the domain of <Arg>f</Arg> is
     finite dimensional.  It checks if the element <Arg>e</Arg> is an
     idempotent.  If <Arg>e</Arg> is not in the image of <Arg>f</Arg>,
     then an error message is returned.  If <Arg>e</Arg> has a
     preimage, then this operation returns a lifting of <Arg>e</Arg> to the
     source of <Arg>f</Arg> whenever possible or it returns fail. 
     Using the algorithm described in the proof of Proposition 27.1 in
     Anderson and Fuller, Rings and categories of modules, second
     edition, GMT, Springer-Verlag.
    </Description>
  </ManSection>
</Section>

<Section Label="qpa:read-save">
  <Heading>Saving and reading quotients of path algebras to and from a
  file</Heading>
  
<ManSection>
  <Oper Name="ReadAlgebra" Arg="string"/>
  <Description>
    Arguments: <Arg>string</Arg> - a name of a file.<Br />
  </Description>
  <Returns> a finite dimension quotient <M>A</M> of a path algebra saved
  by command <C>SaveAlgebra</C> to the file <Arg>string</Arg>.  This
  function creates the algebra <M>A</M> again, which can be saved to a
  file again with the function <C>SaveAlgebra</C>.
  </Returns>
</ManSection>

<ManSection>
  <Oper Name="SaveAlgebra" Arg="A, string, action"/>
  <Description>
    Arguments: <Arg>A</Arg> - an algebra, <Arg>string</Arg> - a name
    of a file, <Arg>action</Arg> - a string.<Br />
  </Description>
  <Returns> or creates a file with name <Arg>string</Arg>, storing the
  algebra <Arg>A</Arg>, which can be opened again with the function
  <C>ReadAlgebra</C> and reconstructed.  The last argument
  <A>action</A> decides if the file <A>string</A>, if it exists
  already, should be overwritten, not overwritten or the user should
  be prompted for an answer to this question.  The corresponding
  user inputs are: "delete", "keep" or "query".
  </Returns>
</ManSection>
</Section>
</Chapter>
