#############################################################################
##
#W  homomorph.xml
#Y  Copyright (C) 2022                               Artemis Konstantinidi
##                                                         Chinmaya Nagpal
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

<#GAPDoc Label="SemigroupHomomorphismByImages">
  <ManSection>
    <Oper Name = "SemigroupHomomorphismByImages" 
          Arg = "S, T, gens, imgs" 
          Label = "for two semigroups and two lists"/>
    <Oper Name = "SemigroupHomomorphismByImages" 
          Arg = "S, T, imgs" 
          Label = "for two semigroups and a list"/>
    <Oper Name = "SemigroupHomomorphismByImages" 
          Arg = "S, T" 
          Label = "for two semigroups"/>
    <Oper Name = "SemigroupHomomorphismByImages" 
          Arg = "S, gens, imgs" 
          Label = "for a semigroup and two lists"/>
    <Returns>
      A semigroup homomorphism, or <K>fail</K>.
    </Returns>
    <Description>
      <C>SemigroupHomomorphismByImages</C> attempts to construct a homomorphism
      from the semigroup <A>S</A> to the semigroup <A>T</A> by mapping the
      <C>i</C>-th element of <A>gens</A> to the <C>i</C>-th element of
      <A>imgs</A>. If this mapping corresponds to a homomorphism, the
      homomorphism is returned, and if not, then <K>fail</K> is returned.
      Similarly, if <A>gens</A> does not generate <A>S</A>, <K>fail</K> is
      returned.<P/>

      If omitted, the arguments <A>gens</A> and <A>imgs</A> default to the
      generators of <A>S</A> and <A>T</A> respectively. See <Ref Attr =
      "GeneratorsOfSemigroup" BookName = "ref"/>.<P/>

      If <A>T</A> is not given, then it defaults to the semigroup generated by
      <A>imgs</A>, resulting in the mapping being surjective.
      <Example><![CDATA[
gap> S := FullTransformationMonoid(3);;
gap> gens := GeneratorsOfSemigroup(S);;
gap> J := FullTransformationMonoid(4);;
gap> imgs := ListWithIdenticalEntries(4,
> ConstantTransformation(3, 1));;
gap> hom := SemigroupHomomorphismByImages(S, J, gens, imgs);
<full transformation monoid of degree 3> -> 
<full transformation monoid of degree 4>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="SemigroupIsomorphismByImages">
  <ManSection>
    <Oper Name = "SemigroupIsomorphismByImages" 
          Arg = "S, T, gens, imgs" 
          Label = "for two semigroups and two lists"/>
    <Oper Name = "SemigroupIsomorphismByImages" 
          Arg = "S, T, imgs" 
          Label = "for two semigroups and a list"/>
    <Oper Name = "SemigroupIsomorphismByImages" 
          Arg = "S, T" 
          Label = "for two semigroups"/>
    <Oper Name = "SemigroupIsomorphismByImages" 
          Arg = "S, gens, imgs" 
          Label = "for a semigroup and two list"/>
    <Returns>
      A semigroup isomorphism, or <K>fail</K>.
    </Returns>
    <Description>
      <C>SemigroupIsomorphismByImages</C> attempts to construct a
      isomorphism from the semigroup <A>S</A> to the semigroup <A>T</A>,
      by mapping the <C>i</C>-th element of <A>gens</A> to the <C>i</C>-th
      element of <A>imgs</A>. If this mapping corresponds to an isomorphism,
      the isomorphism is returned, and if not, then <K>fail</K> is returned. An
      isomorphism is a bijective homomorphism. See also
      <Ref Oper = "SemigroupHomomorphismByImages" 
        Label = "for two semigroups and two lists"/>.
      <Example><![CDATA[
gap> S := Semigroup([
>  Matrix(IsNTPMatrix, [[0, 1, 2], [4, 3, 0], [0, 2, 0]], 9, 4),
>  Matrix(IsNTPMatrix, [[1, 1, 0], [4, 1, 1], [0, 0, 0]], 9, 4)]);;
gap> T := AsSemigroup(IsTransformationSemigroup, S);;
gap> iso := SemigroupIsomorphismByImages(S, T);
<semigroup of size 46, 3x3 ntp matrices with 2 generators> -> 
<transformation semigroup of size 46, degree 47 with 2 generators>
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="SemigroupHomomorphismByFunction">
  <ManSection>
    <Oper Name = "SemigroupHomomorphismByFunctionNC" Arg = "S, T, fun"/>
    <Oper Name = "SemigroupHomomorphismByFunction" Arg = "S, T, fun"/>
    <Returns>
      A semigroup homomorphism or <K>fail</K>.
    </Returns>
    <Description>
      <C>SemigroupHomomorphismByFunctionNC</C> returns a semigroup homomorphism
      with source <A>S</A> and range <A>T</A>, such that each element <C>s</C>
      in <A>S</A> is mapped to the element <A>fun</A><C>(s)</C>, where
      <A>fun</A> is a &GAP; function.<P/>

      The function <C>SemigroupHomomorphismByFunctionNC</C> performs no checks
      on whether the function actually gives a homomorphism, and so it is
      possible for this operation to return a mapping from <A>S</A> to <A>T</A>
      that is not a homomorphism.<P/>

      The function <C>SemigroupHomomorphismByFunction</C> checks that the
      mapping from <A>S</A> to <A>T</A> defined by <A>fun</A> satisfies <Ref
        Prop="RespectsMultiplication" BookName= "ref"/>, which can be expensive.
      If <Ref Prop="RespectsMultiplication" BookName= "ref"/> does not hold,
      then <K>fail</K> is returned.

      <Example><![CDATA[
gap> g := Semigroup([(1, 2, 3, 4), (1, 2)]);;
gap> h := Semigroup([(1, 2, 3), (1, 2)]);;
gap> hom := SemigroupHomomorphismByFunction(g, h,
> function(x) 
> if SignPerm(x) = -1 then return (1, 2);
> else return ();
> fi; end);
<semigroup of size 24, with 2 generators> -> 
<semigroup of size 6, with 2 generators>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="SemigroupIsomorphismByFunction">
  <ManSection>
    <Oper Name = "SemigroupIsomorphismByFunctionNC"
          Arg = "S, T, fun, invFun"/>
    <Oper Name = "SemigroupIsomorphismByFunction"
          Arg = "S, T, fun, invFun"/>
    <Returns>
      A semigroup isomorphism or <K>fail</K>.
    </Returns>
    <Description>
      <C>SemigroupIsomorphismByFunctionNC</C> returns a semigroup isomorphism
      with source <A>S</A> and range <A>T</A>, such that each element
      <C>s</C> in <A>S</A> is mapped to the element <A>fun</A><C>(s)</C>,
      where <A>fun</A> is a &GAP; function, and <A>invFun</A> its inverse,
      mapping <A>fun</A><C>(s)</C> back to <C>s</C>. <P/>

      The function <C>SemigroupIsomorphismByFunctionNC</C> performs no checks
      on whether the function actually gives an isomorphism, and so it is
      possible for this operation to return a mapping from <A>S</A> to <A>T</A>
      that is not a homomorphism, or not a bijection, or where the return value
      of <Ref Attr="InverseGeneralMapping" BookName="ref"/> is not the inverse
      of the returned function.<P/>

      The function <C>SemigroupIsomorphismByFunction</C> checks that: the
      mapping from <A>S</A> to <A>T</A> defined by <A>fun</A> satisfies <Ref
      Prop="RespectsMultiplication" BookName= "ref"/>; that the function from
      <A>T</A> to <A>S</A> defined by <A>invFun</A> satisfies <Ref
      Prop="RespectsMultiplication" BookName= "ref"/>; and that these functions
      are mutual inverses. This can be expensive. If any of these checks fails,
      then <K>fail</K> is returned.

      <Example><![CDATA[
gap> S := MonogenicSemigroup(IsTransformationSemigroup, 3, 2);;
gap> T := MonogenicSemigroup(IsBipartitionSemigroup, 3, 2);;
gap> map := x -> T.1 ^ Length(Factorization(S, x));;
gap> inv := x -> S.1 ^ Length(Factorization(T, x));;
gap> iso := SemigroupIsomorphismByFunction(S, T, map, inv);
<commutative non-regular transformation semigroup of size 4, degree 5 
  with 1 generator> -> <commutative non-regular block bijection 
  semigroup of size 4, degree 6 with 1 generator>
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsSemigroupHomomorphismByImages">
  <ManSection>
    <Filt Name = "IsSemigroupHomomorphismByImages" Arg = "hom"/>
    <Returns>
      <K>true</K> or <K>false</K>.
    </Returns>
    <Description>
      <C>IsSemigroupHomomorphismByImages</C> returns <K>true</K> if <A>hom</A>
      is a semigroup homomorphism by images and <K>false</K> if it is not. A
      semigroup homomorphism is a mapping from a semigroup <C>S</C> to a
      semigroup <C>T</C> that respects multiplication. This representation
      describes semigroup homomorphisms internally by the generators of
      <C>S</C> and their images in <C>T</C>. See 
      <Ref Oper="SemigroupHomomorphismByImages" 
        Label = "for two semigroups and two lists"/>.
      <Example><![CDATA[
gap> S := FullTransformationMonoid(3);;
gap> gens := GeneratorsOfSemigroup(S);;
gap> T := FullTransformationMonoid(4);;
gap> imgs := ListWithIdenticalEntries(4, ConstantTransformation(3, 1));;
gap> hom := SemigroupHomomorphismByImages(S, T, gens, imgs);
<full transformation monoid of degree 3> -> 
<full transformation monoid of degree 4>
gap> IsSemigroupHomomorphismByImages(hom);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsSemigroupHomomorphismByFunction">
  <ManSection>
    <Filt Name = "IsSemigroupHomomorphismByFunction" Arg = "hom"/>
    <Returns>
      <K>true</K> or <K>false</K>.
    </Returns>
    <Description>
      <C>IsSemigroupHomomorphismByFunction</C> returns <K>true</K> if <A>hom</A>
      was created using <Ref Oper="SemigroupHomomorphismByFunction"/> and 
      <K>false</K> if it was not. Note that this filter may return <K>true</K> 
      even if the underlying &GAP; function does not define a homomorphism.
      A semigroup homomorphism is a mapping from a semigroup <C>S</C> to a 
      semigroup <C>T</C> that respects multiplication. This representation 
      describes semigroup homomorphisms internally using a &GAP;  function 
      mapping elements of <C>S</C> to their images in <C>T</C>.
      <Example><![CDATA[
gap> S := Semigroup([(1, 2, 3, 4), (1, 2)]);;
gap> T := Semigroup([(1, 2, 3), (1, 2)]);;
gap> hom := SemigroupHomomorphismByFunction(S, T,
> function(x) if SignPerm(x) = -1 then return (1, 2); 
> else return ();fi; end);
<semigroup of size 24, with 2 generators> -> 
<semigroup of size 6, with 2 generators>
gap> IsSemigroupHomomorphismByFunction(hom);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsSemigroupIsomorphismByFunction">
  <ManSection>
    <Filt Name = "IsSemigroupIsomorphismByFunction" Arg = "iso"/>
    <Returns>
      <K>true</K> or <K>false</K>.
    </Returns>
    <Description>
      <C>IsSemigroupIsomorphismByFunction</C> returns <K>true</K> if <A>hom</A>
      satisfies <Ref Oper="IsSemigroupHomomorphismByFunction"/> and <Ref
      Oper="IsBijective" BookName="ref"/>, and <K>false</K> if does not. Note
      that this filter may return <K>true</K> even if the underlying &GAP;
      function does not define a homomorphism. A semigroup isomorphism is a
      mapping from a semigroup <C>S</C> to a semigroup <C>T</C> that respects
      multiplication. This representation describes semigroup isomorphisms
      internally by using a  &GAP; function mapping elements of <C>S</C> to
      their images in <C>T</C>. See
      <Ref Oper="SemigroupIsomorphismByFunction"/>.<P/>
      <Example><![CDATA[
gap> S := MonogenicSemigroup(IsTransformationSemigroup, 3, 2);;
gap> T := MonogenicSemigroup(IsBipartitionSemigroup, 3, 2);;
gap> map := x -> T.1 ^ Length(Factorization(S, x));;
gap> inv := x -> S.1 ^ Length(Factorization(T, x));;
gap> iso := SemigroupIsomorphismByFunction(S, T, map, inv);
<commutative non-regular transformation semigroup of size 4, degree 5 
  with 1 generator> -> <commutative non-regular block bijection 
  semigroup of size 4, degree 6 with 1 generator>
gap> IsSemigroupIsomorphismByFunction(iso);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsSemigroupHomomorphismByImages">
  <ManSection>
    <Oper Name = "AsSemigroupHomomorphismByImages" 
          Arg = "hom" 
          Label = "for a semigroup homomorphism by function"/>
    <Returns>
      A semigroup homomorphism, or <K>fail</K>.
    </Returns>
    <Description>
      <C>AsSemigroupHomomorphismByImages</C> takes <A>hom</A>, a semigroup 
      homomorphism, and returns the same mapping but represented internally 
      using the generators of <C>Source(<A>hom</A>)</C> and their images in 
      <C>Range(<A>hom</A>)</C>. If <A>hom</A> not a semigroup homomorphism, 
      then <K>fail</K> is returned. For example, this could happen if 
      <A>hom</A> was created using <Ref Oper="SemigroupIsomorphismByFunction"/> 
      and a function which does not give a homomorphism.<P/>
      <Example><![CDATA[
gap> S := Semigroup([(1, 2, 3, 4), (1, 2)]);;
gap> T := Semigroup([(1, 2, 3), (1, 2)]);;
gap> hom := SemigroupHomomorphismByFunction(S, T,
> function(x) if SignPerm(x) = -1 then return (1, 2); 
> else return (); fi; end);
<semigroup of size 24, with 2 generators> -> 
<semigroup of size 6, with 2 generators>
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsSemigroupHomomorphismByFunction">
  <ManSection>
    <Oper Name = "AsSemigroupHomomorphismByFunction" 
          Arg = "hom" 
          Label = "for a semigroup homomorphism by images"/>
    <Returns>
      A semigroup homomorphism.
    </Returns>
    <Description>
      <C>AsSemigroupHomomorphismByFunction</C> takes <A>hom</A>, a semigroup 
      homomorphism, and returns the same mapping but described by a &GAP; 
      function mapping elements of <C>Source(<A>hom</A>)</C> to their images 
      in <C>Range(<A>hom</A>)</C>.<P/>
      <Example><![CDATA[
gap> T := TrivialSemigroup();;
gap> S := GLM(2, 2);;
gap> gens := GeneratorsOfSemigroup(S);;
gap> imgs := ListX(gens, x -> IdentityTransformation);;
gap> hom := SemigroupHomomorphismByImages(S, T, gens, imgs);;
gap> hom := AsSemigroupHomomorphismByFunction(hom);
<general linear monoid 2x2 over GF(2)> -> 
<trivial transformation group of degree 0 with 1 generator>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsSemigroupIsomorphismByFunction">
  <ManSection>
    <Oper Name = "AsSemigroupIsomorphismByFunction" 
          Arg = "hom" 
          Label = "for a semigroup homomorphism by images"/>
    <Returns>
      A semigroup isomorphism, or <K>fail</K>.
    </Returns>
    <Description>
      <C>AsSemigroupIsomorphismByFunction</C> takes a semigroup homomorphism
      <A>hom</A> and returns a semigroup isomorphism represented using &GAP;
      functions for the isomorphism and its inverse. If <A>hom</A> is not
      bijective, then <K>fail</K> is returned.
      <Example><![CDATA[
gap> S := FullTransformationMonoid(3);;
gap> gens := GeneratorsOfSemigroup(S);;
gap> imgs := ListWithIdenticalEntries(4, ConstantTransformation(3, 1));;
gap> hom := SemigroupHomomorphismByImages(S, S, gens, gens);;
gap> AsSemigroupIsomorphismByFunction(hom);
<full transformation monoid of degree 3> -> 
<full transformation monoid of degree 3>]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="KernelOfSemigroupHomomorphism">
  <ManSection>
    <Attr Name = "KernelOfSemigroupHomomorphism" Arg = "hom"/>
    <Returns>
        A semigroup congruence.
    </Returns>
    <Description>
      <C>KernelOfSemigroupHomomorphism</C> returns the kernel of the 
      semigroup homomorphism <A>hom</A>. The kernel of a semigroup 
      homomorphism <A>hom</A> is a semigroup congruence relating 
      pairs of elements in <C>Source(<A>hom</A>)</C> mapping to the 
      same element under <A>hom</A>.
      <Example><![CDATA[
gap> S := Semigroup([Transformation([2, 1, 5, 1, 5]),
>       Transformation([1, 1, 1, 5, 3]),
>       Transformation([2, 5, 3, 5, 3])]);;
gap> congs := CongruencesOfSemigroup(S);;
gap> cong := congs[3];;
gap> T := S / cong;;
gap> gens := GeneratorsOfSemigroup(S);;
gap> images := List(gens, gen -> EquivalenceClassOfElement(cong, gen));;
gap> hom1 := SemigroupHomomorphismByImages(S, T, gens, images);;
gap> cong = KernelOfSemigroupHomomorphism(hom1);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>
