#############################################################################
##
##  This file is part of GAP, a system for computational discrete algebra.
##  This file's authors include Alexander Hulpke.
##
##  Copyright of GAP belongs to its developers, whose names are too numerous
##  to list here. Please refer to the COPYRIGHT file for details.
##
##  SPDX-License-Identifier: GPL-2.0-or-later
##
##  This file contains the declarations for finitely presented algebras
##


#############################################################################
##
#C  IsElementOfFpAlgebra
##
DeclareCategory( "IsElementOfFpAlgebra", IsRingElement );


#############################################################################
##
#C  IsElementOfFpAlgebraCollection
##
DeclareCategoryCollections( "IsElementOfFpAlgebra" );


#############################################################################
##
#C  IsElementOfFpAlgebraFamily
##
DeclareCategoryFamily( "IsElementOfFpAlgebra" );


#############################################################################
##
#C  IsSubalgebraFpAlgebra
##
DeclareCategory( "IsSubalgebraFpAlgebra", IsAlgebra );


#############################################################################
##
#M  IsSubalgebraFpAlgebra( <D> )  . for alg. that is coll. of f.p. alg. elms.
##
InstallTrueMethod( IsSubalgebraFpAlgebra,
    IsAlgebra and IsElementOfFpAlgebraCollection );


#############################################################################
##
#P  IsFullFpAlgebra( <A> )
##
##  A f.~p. algebra is given by generators which are arithmetic expressions
##  in terms of a set of generators $X$ of an f.~p. algebra that was
##  constructed as a quotient of a free algebra.
##
##  A *full f.~p. algebra* is a f.~p. algebra that contains $X$.
#T or better postulate ``contains this free algebra''?
##  (So a full f.~p. algebra need *not* contain the whole family of its
##  elements.)
##
DeclareProperty( "IsFullFpAlgebra",
    IsFLMLOR and IsElementOfFpAlgebraCollection );
#T or do we need `IsAlgebraOfFamily', as in the case of f.p. groups?


#############################################################################
##
#O  ElementOfFpAlgebra( <Fam>, <elm> )
##
DeclareOperation( "ElementOfFpAlgebra",
    [ IsElementOfFpAlgebraFamily, IsRingElement ] );


############################################################################
##
#O  MappedExpression( <expr>, <gens1>, <gens2> )
##
##  For an arithmetic expression <expr> in terms of the generators <gens1>,
##  `MappedExpression' returns the corresponding expression in terms of
##  <gens2>.
##
##  Note that it is expected that one can raise elements in <gens2> to the
##  zero-th power.
##
DeclareOperation( "MappedExpression",
    [ IsElementOfFpAlgebra, IsHomogeneousList, IsHomogeneousList ] );


#############################################################################
##
#F  FactorFreeAlgebraByRelators( <F>, <rels> )  . . .  factor of free algebra
##
##  is an f.p.~algebra $A$ isomorphic to the factor of the free (associative)
##  algebra(-with-one) <F> by the two-sided ideasl spanned by the relators
##  in the list <rels>.
##
##  If <F> is an algebra-with-one then the generators in the list
##  `GeneratorsOfAlgebraWithOne( $A$ )' correspond to the generators in the
##  list `GeneratorsOfAlgebraWithOne( <F> )'.
##  Otherwise the generators in the list `GeneratorsOfAlgebra( $A$ )'
##  correspond to the generators in the list `GeneratorsOfAlgebra( <F> )'.
##
DeclareGlobalFunction( "FactorFreeAlgebraByRelators" );


#############################################################################
##
#A  FreeGeneratorsOfFpAlgebra( <A> )
##
##  is the list of underlying free generators corresponding to the generators
##  of the finitely presented algebra <A>.
##
DeclareAttribute( "FreeGeneratorsOfFpAlgebra",
    IsSubalgebraFpAlgebra and IsFullFpAlgebra  );


############################################################################
##
#A  RelatorsOfFpAlgebra( <A> )
##
##  is the list of relators of the finitely presented algebra <A>,
##  each relator being an expression in terms of the free generators
##  provided by `FreeGeneratorsOfFpAlgebra( <A> )'.
##
DeclareAttribute( "RelatorsOfFpAlgebra",
    IsSubalgebraFpAlgebra and IsFullFpAlgebra  );


#############################################################################
##
#A  FreeAlgebraOfFpAlgebra( <A> )
##
##  is the underlying free algebra of the finitely presented algebra <A>.
##  This is the algebra generated by the free generators provided by
##  `FreeGeneratorsOfFpAlgebra( <A> )',
##  with coefficient domain `LeftActingDomain( <A> )'.
##
DeclareAttribute( "FreeAlgebraOfFpAlgebra",
    IsSubalgebraFpAlgebra and IsFullFpAlgebra  );


#############################################################################
##
#P  IsNormalForm( <elm> )
##
DeclareProperty( "IsNormalForm", IsObject );


#############################################################################
##
#A  NiceNormalFormByExtRepFunction( <Fam> )
##
##  `NiceNormalFormByExtRepFunction( <Fam> )' is a function that can be
##  applied to the family <Fam> and the external representation of an element
##  $e$ of <Fam>;
##  This call returns the element of <Fam> that is equal to $e$ and in normal
##  form.
##
##  If the family <Fam> knows a nice normal form for its elements then the
##  elements can be always constructed as normalized elements by
##  `NormalizedObjByExtRep'.
##
##  (Perhaps a normal form that is expensive to compute will not be regarded
##  as a nice normal form.)
##
DeclareAttribute( "NiceNormalFormByExtRepFunction", IsFamily );


#############################################################################
##
#A  NiceAlgebraMonomorphism( <A> )
##
##  <#GAPDoc Label="NiceAlgebraMonomorphism">
##  <ManSection>
##  <Attr Name="NiceAlgebraMonomorphism" Arg='A'/>
##  <Description>
##  If <A>A</A> is an associative algebra with one, returns
##  an isomorphism from <A>A</A> onto a matrix algebra
##  (see <Ref Attr="IsomorphismMatrixAlgebra"/> for an example).
##  If <A>A</A> is a finitely presented Lie algebra, returns an isomorphism
##  from <A>A</A> onto a Lie algebra defined by a structure constants table
##  (see <Ref Sect="Finitely Presented Lie Algebras"/> for an example).
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
##  Let <A> be a subspace or subalgebra of a f.p.~algebra.
##
##  The `NiceAlgebraMonomorphism' value of the algebra stored in
##  the `wholeFamily' component of the elements family of <A>
##  is used to define the `\<' relation of algebra elements.
#T  use it also for a ``nice normal form''!
##
##  If a f.p.~algebra <A> knows the value of `NiceAlgebraMonomorphism'
##  then it can be handled via the mechanism of nice bases
##  (see~"IsFpAlgebraElementsSpace").
##
##  `NiceAlgebraMonomorphism' is inherited to subalgebras and subspaces.
##  (If one knows that <A> contains the source then one should set
##  `GeneratorsOfLeftModule' for <A>,
##  and also one can set `NiceFreeLeftModule' for <A>  to the module
##  of the basis `basisimages'.)
##
DeclareAttribute( "NiceAlgebraMonomorphism", IsSubalgebraFpAlgebra );

InstallSubsetMaintenance( NiceAlgebraMonomorphism,
    IsFreeLeftModule and HasNiceAlgebraMonomorphism, IsFreeLeftModule );


#############################################################################
##
#F  IsFpAlgebraElementsSpace( <V> )
##
##  If an $F$-vector space <V> is in the filter `IsFpAlgebraElementsSpace'
##  then this expresses that <V> consists of elements in a f.p.~algebra,
##  and that <V> is handled via the mechanism of nice bases (see~"...")
##  in the following way.
##  Let $f$ be the `NiceAlgebraMonomorphism' value for <V>
##  (see~"NiceAlgebraMonomorphism").
##  The `NiceVector' value of $v \in <V>$ is defined as
##  $`ImagesRepresentative'( f, v )$;
##  the `NiceFreeLeftModuleInfo' value of <V> is irrelevant.
##
##  So it is assumed that methods for computing the `NiceAlgebraMonomorphism'
##  value are known.
##
DeclareHandlingByNiceBasis( "IsFpAlgebraElementsSpace",
    "for free left modules of f.p. algebra elements" );


#############################################################################
##
#F  FpAlgebraByGeneralizedCartanMatrix( <F>, <A> )
##
##  is a finitely presented associative algebra over the field <F>,
##  defined by the generalized Cartan matrix <A>.
##
DeclareGlobalFunction( "FpAlgebraByGeneralizedCartanMatrix" );
