#############################################################################
##
#W  semigrp.gd                  GAP library                     Thomas Breuer
##
#H  @(#)$Id: semigrp.gd,v 4.35 2002/04/15 10:05:21 sal Exp $
##
#Y  Copyright (C)  1997,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
#Y  (C) 1998 School Math and Comp. Sci., University of St.  Andrews, Scotland
#Y  Copyright (C) 2002 The GAP Group
##
##  This file contains the declaration of operations for semigroups.
##
Revision.semigrp_gd :=
    "@(#)$Id: semigrp.gd,v 4.35 2002/04/15 10:05:21 sal Exp $";


#############################################################################
##
#P  IsSemigroup( <D> )
##
##  returns `true' if the object <D> is a semigroup.
##  \index{semigroup}
##  A *semigroup* is a magma (see~"Magmas") with associative multiplication.
##
DeclareSynonymAttr( "IsSemigroup", IsMagma and IsAssociative );



#############################################################################
##
#F  Semigroup( <gen1>, <gen2> ... ) . . . . semigroup generated by collection
#F  Semigroup( <gens> ) . . . . . . . . . . semigroup generated by collection
##
##  In the first form, `Semigroup' returns the semigroup generated by the
##  arguments <gen1>, <gen2>, \dots,
##  that is, the closure of these elements under multiplication.
##  In the second form, `Semigroup' returns the semigroup generated by the
##  elements in the homogeneous list <gens>;
##  a square matrix as only argument is treated as one generator,
##  not as a list of generators.
##
##  It is *not* checked whether the underlying multiplication is associative,
##  use `Magma' (see~"Magma") and `IsAssociative' (see~"IsAssociative")
##  if you want to check whether a magma is in fact a semigroup.
##
DeclareGlobalFunction( "Semigroup" );


#############################################################################
##
#F  Subsemigroup( <S>, <gens> ) . . .  subsemigroup of <S> generated by <gens>
#F  SubsemigroupNC( <S>, <gens> ) . .  subsemigroup of <S> generated by <gens>
##
##  are just synonyms of `Submagma' and `SubmagmaNC', respectively
##  (see~"Submagma").
##
DeclareSynonym( "Subsemigroup", Submagma );

DeclareSynonym( "SubsemigroupNC", SubmagmaNC );


#############################################################################
##
#O  SemigroupByGenerators( <gens> ) . . . . . . semigroup generated by <gens>
##
##  is the underlying operation of `Semigroup' (see~"Semigroup").
##
DeclareOperation( "SemigroupByGenerators", [ IsCollection ] );


#############################################################################
##
#A  AsSemigroup( <C> )  . . . . . . . .  collection <C> regarded as semigroup
##
##  If <C> is a collection whose elements form a semigroup
##  (see~"IsSemigroup") then `AsSemigroup' returns this semigroup.
##  Otherwise `fail' is returned.
##
DeclareAttribute( "AsSemigroup", IsCollection );


#############################################################################
##
#O  AsSubsemigroup( <D>, <C> )
##
##  Let <D> be a domain and <C> a collection.
##  If <C> is a subset of <D> that forms a semigroup then `AsSubsemigroup'
##  returns this semigroup, with parent <D>.
##  Otherwise `fail' is returned.
##
DeclareOperation( "AsSubsemigroup", [ IsDomain, IsCollection ] );


#############################################################################
##
#A  GeneratorsOfSemigroup( <S> ) . . .  semigroup generators of semigroup <S>
##
##  Semigroup generators of a semigroup <D> are the same as magma generators
##  (see~"GeneratorsOfMagma").
##
DeclareSynonymAttr( "GeneratorsOfSemigroup", GeneratorsOfMagma );

#############################################################################
##
#A  CayleyGraphSemigroup( <S> ) 
#A  CayleyGraphDualSemigroup( <S> )
##
##
DeclareAttribute("CayleyGraphSemigroup",IsSemigroup);
DeclareAttribute("CayleyGraphDualSemigroup",IsSemigroup);

#############################################################################
##
#F  FreeSemigroup( [<wfilt>,]<rank> )
#F  FreeSemigroup( [<wfilt>,]<rank>, <name> )
#F  FreeSemigroup( [<wfilt>,]<name1>, <name2>, ... )
#F  FreeSemigroup( [<wfilt>,]<names> )
#F  FreeSemigroup( [<wfilt>,]infinity, <name>, <init> )
##
##  Called in the first form, `FreeSemigroup' returns a free semigroup on
##  <rank> generators.
##  Called in the second form, `FreeSemigroup' returns a free semigroup on
##  <rank> generators, printed as `<name>1', `<name>2' etc.,
##  that is, each name is the concatenation of the string <name> and an
##  integer from `1' to <range>.
##  Called in the third form, `FreeSemigroup' returns a free semigroup on
##  as many generators as arguments, printed as <name1>, <name2> etc.
##  Called in the fourth form, `FreeSemigroup' returns a free semigroup on
##  as many generators as the length of the list <names>, the $i$-th
##  generator being printed as `<names>[$i$]'.
##  Called in the fifth form, `FreeSemigroup' returns a free semigroup on
##  infinitely many generators, where the first generators are printed
##  by the names in the list <init>, and the other generators by <name>
##  and an appended number.
##
##  If the extra argument <wfilt> is given, it must be either
##  `IsSyllableWordsFamily' or `IsLetterWordsFamily' or
##  `IsWLetterWordsFamily' or `IsBLetterWordsFamily'. The filter then
##  specifies the representation used for the elements of the free group
##  (see~"Representations for Associative Words"). If no such filter is
##  given, a letter representation is used.
##
DeclareGlobalFunction( "FreeSemigroup" );

#############################################################################
##
#P  IsZeroGroup( <S> )  
##
##  is `true' if and only if the semigroup is a group with zero
##  adjoined.
##
DeclareProperty( "IsZeroGroup", IsSemigroup );

#############################################################################
##
#P  IsSimpleSemigroup( <S> )  
##
##  is `true' if and only if the semigroup has no proper ideals.
##
DeclareProperty( "IsSimpleSemigroup", IsSemigroup );


#############################################################################
##
#P  IsZeroSimpleSemigroup( <S> )  
##
##  is `true' if and only if the semigroup has no proper ideals except for 0,
##  where <S> is a semigroup with zero. 
##  If the semigroup does not find its zero, then a break-loop is entered.
##
DeclareProperty( "IsZeroSimpleSemigroup", IsSemigroup );


############################################################################
##
#A  ANonReesCongruenceOfSemigroup( <S> )
##
##  for a semigroup <S>, returns a non-Rees congruence if one exists
##  or otherwise returns `fail'.
##
DeclareAttribute("ANonReesCongruenceOfSemigroup",IsSemigroup);


############################################################################
##
#P  IsReesCongruenceSemigroup( <S> )
##
##  returns `true' if <S> is a Rees Congruence semigroup, that is,
##  if all congruences of <S> are Rees Congruences.
##
DeclareProperty( "IsReesCongruenceSemigroup", IsSemigroup );


#############################################################################
##
#O  HomomorphismFactorSemigroup( <S>, <C> )
#O  HomomorphismFactorSemigroupByClosure( <S>, <L> )
#O  FactorSemigroup( <S>, <C> )
#O  FactorSemigroupByClosure( <S>, <L> )
##
##  each find the quotient of <S> by a congruence.
##
##  In the first form <C> is a congruence and HomomorphismFactorSemigroup, 
##  returns a homomorphism $<S> \rightarrow <S>/<C>$.
##
##  In the second form, <L> is a list of pairs of elements of <S>.
##  Returns a homomorphism $<S> \rightarrow <S>/<C>$,
##  where <C> is the congruence generated by <L>.
##
##  `FactorSemigroup(<S>, <C>)' returns 
##    `Range( HomomorphismFactorSemigroup(<S>, <C>) )'.
##
##  `FactorSemigroupByClosure(<S>, <L>)' returns 
##    `Range( HomomorphismFactorSemigroupByClosure(<S>, <L>) )'.
##  
##
DeclareOperation( "HomomorphismFactorSemigroup",  
	[ IsSemigroup, IsSemigroupCongruence ] );

DeclareOperation( "HomomorphismFactorSemigroupByClosure",  
	[ IsSemigroup, IsList ] );

DeclareOperation( "FactorSemigroup",  
	[ IsSemigroup, IsSemigroupCongruence ] );

DeclareOperation( "FactorSemigroupByClosure",  
	[ IsSemigroup, IsList ] );


#############################################################################
##
#O  IsRegularSemigroupElement( <S>, <x> )
##
##  returns `true' if <x> has a general inverse in <S>---i.e. there is an 
##  element $y\in S$ such that $xyx=x$ and $yxy=y$.
##  
DeclareOperation("IsRegularSemigroupElement", [IsSemigroup, 
    IsAssociativeElement]);

#############################################################################
##
#P  IsRegularSemigroup( <S> )
##
##  returns `true' if <S> is regular---i.e. if every D class of <S> is regular.
##
DeclareProperty("IsRegularSemigroup", IsSemigroup);

#############################################################################
##
#E

