#############################################################################
##
#W  grahom.xml
#Y  Copyright (C) 2014-18
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

<#GAPDoc Label="HomomorphismDigraphsFinder">
<ManSection>
  <Func Name="HomomorphismDigraphsFinder" Arg="D1, D2, hook, user_param, max_results, hint, injective, image, partial_map, colors1, colors2[, order, aut_grp]"/>
  <Returns>The argument <A>user_param</A>.</Returns>
  <Description>
    This function finds homomorphisms from the digraph <A>D1</A> to the digraph
    <A>D2</A> subject to the conditions imposed by the other arguments as
    described below.<P/>

    If <C>f</C> and <C>g</C> are homomorphisms found by
    <C>HomomorphismDigraphsFinder</C>, then <C>f</C> cannot be obtained from
    <C>g</C> by right multiplying by an automorphism of <A>D2</A> in
    <A>aut_grp</A>.

    <List>
      <Mark><A>hook</A></Mark>
      <Item>
        This argument should be a function or <K>fail</K>.<P/>

        If <A>hook</A> is a function, then it must have two arguments
        <A>user_param</A> (see below) and a transformation <C>t</C>. The
        function <C><A>hook</A>(<A>user_param</A>, t)</C> is called every time
        a new homomorphism <C>t</C> is found by
        <C>HomomorphismDigraphsFinder</C>. If the function returns <K>true</K>,
        then <C>HomomorphismDigraphsFinder</C> stops and does not find any
        further homomorphisms. This feature might be useful if you are
        searching for a homomorphism that satisfies some condition that you
        cannot specify via the other arguments to
        <C>HomomorphismDigraphsFinder</C>.
        <P/>

        If <A>hook</A> is <K>fail</K>, then a default function is used which
        simply adds every new homomorphism found by
        <C>HomomorphismDigraphsFinder</C> to <A>user_param</A>, which must be a
        mutable list in this case.
      </Item>

      <Mark><A>user_param</A></Mark>
      <Item>
        If <A>hook</A> is a function, then <A>user_param</A> can be any &GAP;
        object. The object <A>user_param</A> is used as the first argument of
        the function <A>hook</A>. For example, <A>user_param</A> might be a
        transformation semigroup, and <C><A>hook</A>(<A>user_param</A>, t)</C>
        might set <A>user_param</A> to be the closure of <A>user_param</A> and
        <C>t</C>. <P/>

        If the value of <A>hook</A> is <K>fail</K>, then the value of
        <A>user_param</A> must be a mutable list.
      </Item>

      <Mark><A>max_results</A></Mark>
      <Item>
        This argument should be a positive integer or <K>infinity</K>.
        <C>HomomorphismDigraphsFinder</C> will return after it has found
        <A>max_results</A> homomorphisms or the search is complete, whichever
        happens first.
      </Item>

      <Mark><A>hint</A></Mark>
      <Item>
        This argument should be a positive integer or <K>fail</K>. <P/>

        If <A>hint</A> is a positive integer, then only homorphisms of rank
        <A>hint</A> are found.<P/>

        If <A>hint</A> is <K>fail</K>, then no restriction is put on the rank
        of homomorphisms found.
      </Item>

      <Mark><A>injective</A></Mark>
      <Item>
        This argument should be <C>0</C>, <C>1</C>, or <C>2</C>.  If it is
        <C>2</C>, then only embeddings are found, if it is <C>1</C>, then only
        injective homomorphisms are found, and if it is <C>0</C> there are no
        restrictions imposed by this argument.
        <P/>

        For backwards compatibility, <A>injective</A> can also be <K>false</K>
        or <K>true</K> which correspond to the values <C>0</C> and <C>1</C>
        described in the previous paragraph, respectively.
      </Item>

      <Mark><A>image</A></Mark>
      <Item>
        This argument should be a subset of the vertices of the graph <A>D2</A>.
        <C>HomomorphismDigraphsFinder</C> only finds homomorphisms from
        <A>D1</A> to the subgraph of <A>D2</A> induced by the vertices
        <A>image</A>.<P/>

        The returned homomorphisms (if any) are still "up to the action" of the
        group specified by <A>aut_grp</A> (which is the entire automorphism
        group by default). This might generate unexpected results. For example,
        if <A>D1</A> has automorphism group where one orbit consists of, say,
        <C>1</C> and <C>2</C>, then <C>HomomorphismDigraphsFinder</C> will only
        attempt to find homomorphisms mapping <C>1</C> to <C>1</C>, and if
        there are no such homomorphisms with image set equal to <A>image</A>,
        then no homomorphisms will be returned (even if there is a homomorphism
        from <A>D1</A> to <A>D2</A> mapping <C>1</C> to <C>2</C>). To ensure that
        that <B>all</B> homomorphisms with image set equal to <A>image</A> are
        considered it is necessary for the last argument <A>aut_grp</A> to be
        the trivial permutation group.
      </Item>

      <Mark><A>partial_map</A></Mark>
      <Item>
        This argument should be a partial map from <A>D1</A> to <A>D2</A>,
        that is, a (not necessarily dense) list of vertices of the digraph
        <A>D2</A> of length no greater than the number vertices in the digraph
        <A>D1</A>. <C>HomomorphismDigraphsFinder</C> only finds homomorphisms
        extending <A>partial_map</A> (if any).
      </Item>

      <Mark><A>colors1</A></Mark>
      <Item>
        This should be a list representing possible colours of vertices in the
        digraph <A>D1</A>; see
        <Ref Oper="AutomorphismGroup"
          Label="for a digraph and a homogeneous list"/>
        for details of the permissible values for this argument.
      </Item>

      <Mark><A>colors2</A></Mark>
      <Item>
        This should be a list representing possible colours of vertices in the
        digraph <A>D2</A>; see
        <Ref Oper="AutomorphismGroup"
          Label="for a digraph and a homogeneous list"/>
        for details of the permissible values for this argument.
      </Item>
      <Mark><A>order</A></Mark>
      <Item>
        The optional argument <A>order</A> specifies the order the
        vertices in <A>D1</A> appear in the search for homomorphisms.
        The value of this parameter can have a large impact
        on the runtime of the function. It seems in many cases to be a good
        idea for this to be the <Ref Attr="DigraphWelshPowellOrder"/>, i.e.
        vertices ordered from highest to lowest degree.
      </Item>
      <Mark><A>aut_grp</A></Mark>
      <Item>
        The optional argument <A>aut_grp</A> should be a subgroup of the
        automorphism group of <A>D2</A>. This function returns unique
        representatives of the homomorphisms found up to right multiplication
        by <A>aut_grp</A>. If this argument is not specific, it defaults to the
        full automorphism group of <A>D2</A>, which may be costly to calculate.
      </Item>
    </List>

    <Example><![CDATA[
gap> D := ChainDigraph(10);
<immutable chain digraph with 10 vertices>
gap> D := DigraphSymmetricClosure(D);
<immutable symmetric digraph with 10 vertices, 18 edges>
gap> HomomorphismDigraphsFinder(D, D, fail, [], infinity, 2, 0,
> [3, 4], [], fail, fail);
#I  WARNING you are trying to find homomorphisms by specifying a subset
of the vertices of the target digraph. This might lead to unexpected
results! If this happens, try passing Group(()) as the last argument.
Please see the documentation of HomomorphismDigraphsFinder for details.
[ Transformation( [ 3, 4, 3, 4, 3, 4, 3, 4, 3, 4 ] ),
  Transformation( [ 4, 3, 4, 3, 4, 3, 4, 3, 4, 3 ] ) ]
gap> D2 := CompleteDigraph(6);;
gap> HomomorphismDigraphsFinder(D, D2, fail, [], 1, fail, 0,
> [1 .. 6], [1, 2, 1], fail, fail);
[ Transformation( [ 1, 2, 1, 3, 4, 5, 6, 1, 2, 1 ] ) ]
gap> func := function(user_param, t)
> Add(user_param, t * user_param[1]);
> end;;
gap> HomomorphismDigraphsFinder(D, D2, func, [Transformation([2, 2])],
> 3, fail, 0, [1 .. 6], [1, 2, 1], fail, fail);
[ Transformation( [ 2, 2 ] ),
  Transformation( [ 2, 2, 2, 3, 4, 5, 6, 2, 2, 2 ] ),
  Transformation( [ 2, 2, 2, 3, 4, 5, 6, 2, 2, 3 ] ),
  Transformation( [ 2, 2, 2, 3, 4, 5, 6, 2, 2, 4 ] ) ]
gap> HomomorphismDigraphsFinder(NullDigraph(2), NullDigraph(3), fail,
> [], infinity, fail, 1, [1, 2, 3], fail, fail, fail, fail,
> Group(()));
[ IdentityTransformation, Transformation( [ 1, 3, 3 ] ),
  Transformation( [ 2, 1 ] ), Transformation( [ 2, 3, 3 ] ),
  Transformation( [ 3, 1, 3 ] ), Transformation( [ 3, 2, 3 ] ) ]
gap> HomomorphismDigraphsFinder(NullDigraph(2), NullDigraph(3), fail,
> [], infinity, fail, 1, [1, 2, 3], fail, fail, fail, fail,
> Group((1, 2)));
[ IdentityTransformation, Transformation( [ 1, 3, 3 ] ),
  Transformation( [ 3, 1, 3 ] ) ]]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphHomomorphism">
<ManSection>
  <Oper Name="DigraphHomomorphism" Arg="digraph1, digraph2"/>
  <Returns> A transformation, or <K>fail</K>.</Returns>
  <Description>
    A homomorphism from <A>digraph1</A> to <A>digraph2</A> is a mapping from
    the vertex set of <A>digraph1</A> to a subset of the vertices of
    <A>digraph2</A>, such that every pair of vertices <C>[i,j]</C> which has
    an edge <C>i->j</C> is mapped to a pair of vertices <C>[a,b]</C> which
    has an edge <C>a->b</C>.  Note that non-adjacent vertices can still be
    mapped to adjacent vertices. <P/>

    <C>DigraphHomomorphism</C> returns a single homomorphism between
    <A>digraph1</A> and <A>digraph2</A> if it exists, otherwise it returns
    <K>fail</K>.
<Example><![CDATA[
gap> gr1 := ChainDigraph(3);;
gap> gr2 := Digraph([[3, 5], [2], [3, 1], [], [4]]);
<immutable digraph with 5 vertices, 6 edges>
gap> DigraphHomomorphism(gr1, gr1);
IdentityTransformation
gap> map := DigraphHomomorphism(gr1, gr2);
Transformation( [ 3, 1, 5, 4, 5 ] )
gap> IsDigraphHomomorphism(gr1, gr2, map);
true
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="HomomorphismsDigraphs">
<ManSection>
  <Oper Name="HomomorphismsDigraphs" Arg="digraph1, digraph2"/>
  <Oper Name="HomomorphismsDigraphsRepresentatives" Arg="digraph1, digraph2"/>
  <Returns> A list of transformations.</Returns>
  <Description>
    <C>HomomorphismsDigraphsRepresentatives</C> finds every
    <Ref Oper="DigraphHomomorphism"/> between <A>digraph1</A> and
    <A>digraph2</A>, up to right multiplication by an element of the
    <Ref Attr="AutomorphismGroup" Label="for a digraph"/> of <A>digraph2</A>.
    In other words, every homomorphism <C>f</C> between <A>digraph1</A> and
    <A>digraph2</A> can be written as the composition <C>f = g * x</C>,
    where <C>g</C> is one of the <C>HomomorphismsDigraphsRepresentatives</C>
    and <C>x</C> is an automorphism of <A>digraph2</A>.
    <P/>

    <C>HomomorphismsDigraphs</C> returns all homomorphisms between
    <A>digraph1</A> and <A>digraph2</A>.
    <Example><![CDATA[
gap> gr1 := ChainDigraph(3);;
gap> gr2 := Digraph([[3, 5], [2], [3, 1], [], [4]]);
<immutable digraph with 5 vertices, 6 edges>
gap> HomomorphismsDigraphs(gr1, gr2);
[ Transformation( [ 1, 3, 1 ] ), Transformation( [ 1, 3, 3 ] ),
  Transformation( [ 1, 5, 4, 4, 5 ] ), Transformation( [ 2, 2, 2 ] ),
  Transformation( [ 3, 1, 3 ] ), Transformation( [ 3, 1, 5, 4, 5 ] ),
  Transformation( [ 3, 3, 1 ] ), Transformation( [ 3, 3, 3 ] ) ]
gap> HomomorphismsDigraphsRepresentatives(gr1, CompleteDigraph(3));
[ Transformation( [ 2, 1 ] ), Transformation( [ 2, 1, 2 ] ) ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphMonomorphism">
<ManSection>
  <Oper Name="DigraphMonomorphism" Arg="digraph1, digraph2"/>
  <Returns>A transformation, or <K>fail</K>.</Returns>
  <Description>
    <C>DigraphMonomorphism</C> returns a single <E>injective</E> <Ref
      Oper="DigraphHomomorphism"/> between <A>digraph1</A> and <A>digraph2</A>
    if one exists, otherwise it returns <K>fail</K>.
    <Example><![CDATA[
gap> gr1 := ChainDigraph(3);;
gap> gr2 := Digraph([[3, 5], [2], [3, 1], [], [4]]);
<immutable digraph with 5 vertices, 6 edges>
gap> DigraphMonomorphism(gr1, gr1);
IdentityTransformation
gap> DigraphMonomorphism(gr1, gr2);
Transformation( [ 3, 1, 5, 4, 5 ] )
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="MonomorphismsDigraphs">
<ManSection>
  <Oper Name="MonomorphismsDigraphs" Arg="digraph1, digraph2"/>
  <Oper Name="MonomorphismsDigraphsRepresentatives" Arg="digraph1, digraph2"/>
  <Returns>A list of transformations.</Returns>
  <Description>
    These operations behave the same as <Ref Oper="HomomorphismsDigraphs"/> and
    <Ref Oper="HomomorphismsDigraphsRepresentatives"/>, except they only return
    <E>injective</E> homomorphisms.
    <Example><![CDATA[
gap> gr1 := ChainDigraph(3);;
gap> gr2 := Digraph([[3, 5], [2], [3, 1], [], [4]]);
<immutable digraph with 5 vertices, 6 edges>
gap> MonomorphismsDigraphs(gr1, gr2);
[ Transformation( [ 1, 5, 4, 4, 5 ] ),
  Transformation( [ 3, 1, 5, 4, 5 ] ) ]
gap> MonomorphismsDigraphsRepresentatives(gr1, CompleteDigraph(3));
[ Transformation( [ 2, 1 ] ) ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="SubdigraphsMonomorphisms">
<ManSection>
  <Oper Name="SubdigraphsMonomorphisms" Arg="digraph1, digraph2"/>
  <Oper Name="SubdigraphsMonomorphismsRepresentatives" Arg="digraph1, digraph2"/>
  <Returns>A list of transformations.</Returns>
  <Description>
    These operations behave the same as <Ref Oper="HomomorphismsDigraphs"/> and
    <Ref Oper="HomomorphismsDigraphsRepresentatives"/>, except they only return
    <E>injective</E> homomorphisms with the following property: the (not
    necessarily induced) subdigraphs defined by the images of these
    monomorphisms are all of the subdigraphs of <A>digraph2</A> that are
    isomorphic to <A>digraph1</A>. Note that the subdigraphs of the previous
    sentence are those obtained by applying the corresponding monomorphism to
    the vertices and the edges of <A>digraph1</A>, and are therefore possibly
    strictly contained in the induced subdigraph on the same vertex set.
    <Example><![CDATA[
gap> SubdigraphsMonomorphisms(CompleteBipartiteDigraph(2, 2),
> CompleteDigraph(4));
[ Transformation( [ 1, 3, 2 ] ), Transformation( [ 2, 3, 1 ] ),
  Transformation( [ 3, 4, 2, 1 ] ) ]
gap> SubdigraphsMonomorphismsRepresentatives(
> CompleteBipartiteDigraph(2, 2), CompleteDigraph(4));
[ Transformation( [ 1, 3, 2 ] ) ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphEpimorphism">
<ManSection>
  <Oper Name="DigraphEpimorphism" Arg="digraph1, digraph2"/>
  <Returns>A transformation, or <K>fail</K>.</Returns>
  <Description>
    <C>DigraphEpimorphism</C> returns a single <E>surjective</E> <Ref
      Oper="DigraphHomomorphism"/> between <A>digraph1</A> and <A>digraph2</A>
    if one exists, otherwise it returns <K>fail</K>.
    <Example><![CDATA[
gap> gr1 := DigraphReverse(ChainDigraph(4));
<immutable digraph with 4 vertices, 3 edges>
gap> gr2 := DigraphRemoveEdge(CompleteDigraph(3), [1, 2]);
<immutable digraph with 3 vertices, 5 edges>
gap> DigraphEpimorphism(gr2, gr1);
fail
gap> DigraphEpimorphism(gr1, gr2);
Transformation( [ 3, 1, 2, 3 ] )
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="EpimorphismsDigraphs">
<ManSection>
  <Oper Name="EpimorphismsDigraphs" Arg="digraph1, digraph2"/>
  <Oper Name="EpimorphismsDigraphsRepresentatives" Arg="digraph1, digraph2"/>
  <Returns>A list of transformations.</Returns>
  <Description>
    These operations behave the same as <Ref Oper="HomomorphismsDigraphs"/> and
    <Ref Oper="HomomorphismsDigraphsRepresentatives"/>, except they only return
    <E>surjective</E> homomorphisms.
    <Example><![CDATA[
gap> gr1 := DigraphReverse(ChainDigraph(4));
<immutable digraph with 4 vertices, 3 edges>
gap> gr2 := DigraphSymmetricClosure(CycleDigraph(3));
<immutable symmetric digraph with 3 vertices, 6 edges>
gap> EpimorphismsDigraphsRepresentatives(gr1, gr2);
[ Transformation( [ 3, 1, 2, 1 ] ), Transformation( [ 3, 1, 2, 3 ] ),
  Transformation( [ 2, 1, 2, 3 ] ) ]
gap> EpimorphismsDigraphs(gr1, gr2);
[ Transformation( [ 1, 2, 1, 3 ] ), Transformation( [ 1, 2, 3, 1 ] ),
  Transformation( [ 1, 2, 3, 2 ] ), Transformation( [ 1, 3, 1, 2 ] ),
  Transformation( [ 1, 3, 2, 1 ] ), Transformation( [ 1, 3, 2, 3 ] ),
  Transformation( [ 2, 1, 2, 3 ] ), Transformation( [ 2, 1, 3, 1 ] ),
  Transformation( [ 2, 1, 3, 2 ] ), Transformation( [ 2, 3, 1, 2 ] ),
  Transformation( [ 2, 3, 1, 3 ] ), Transformation( [ 2, 3, 2, 1 ] ),
  Transformation( [ 3, 1, 2, 1 ] ), Transformation( [ 3, 1, 2, 3 ] ),
  Transformation( [ 3, 1, 3, 2 ] ), Transformation( [ 3, 2, 1, 2 ] ),
  Transformation( [ 3, 2, 1, 3 ] ), Transformation( [ 3, 2, 3, 1 ] ) ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="GeneratorsOfEndomorphismMonoid">
<ManSection>
  <Func Name="GeneratorsOfEndomorphismMonoid" Arg="digraph[, colors][, limit]"/>
  <Attr Name="GeneratorsOfEndomorphismMonoidAttr" Arg="digraph"/>
  <Returns> A list of transformations.</Returns>
  <Description>
    An endomorphism of <A>digraph</A> is a homomorphism
    <Ref Oper="DigraphHomomorphism"/> from <A>digraph</A> back to itself.

    <C>GeneratorsOfEndomorphismMonoid</C>, called with a single argument,
    returns a generating set for the monoid of all endomorphisms of
    <A>digraph</A>. If <A>digraph</A>  belongs to <Ref
      Filt="IsImmutableDigraph"/>, then the value of
    <C>GeneratorsOfEndomorphismMonoid</C> will not be recomputed on future
    calls.<P/>

    If the <A>colors</A> argument is specified, then
    <C>GeneratorsOfEndomorphismMonoid</C> will return a generating
    set for the monoid of endomorphisms which respect the given colouring.
    The colouring <A>colors</A> can be in one of two forms: <P/>

    <List>
      <Item>
        A list of positive integers of size the number of vertices of
        <A>digraph</A>, where <A>colors</A><C>[i]</C> is the colour of vertex
        <C>i</C>.
      </Item>
      <Item>
        A list of lists, such that <A>colors</A><C>[i]</C> is a list of all
        vertices with colour <C>i</C>.
      </Item>
    </List>

    If the <A>limit</A> argument is specified, then it will return only the
    first <A>limit</A> homomorphisms, where <A>limit</A> must be a positive
    integer or <C>infinity</C>. <P/>

    <Example><![CDATA[
gap> gr := Digraph(List([1 .. 3], x -> [1 .. 3]));;
gap> GeneratorsOfEndomorphismMonoid(gr);
[ Transformation( [ 1, 3, 2 ] ), Transformation( [ 2, 1 ] ),
  IdentityTransformation, Transformation( [ 1, 2, 1 ] ),
  Transformation( [ 1, 2, 2 ] ), Transformation( [ 1, 1, 2 ] ),
  Transformation( [ 1, 1, 1 ] ) ]
gap> GeneratorsOfEndomorphismMonoid(gr, 3);
[ Transformation( [ 1, 3, 2 ] ), Transformation( [ 2, 1 ] ),
  IdentityTransformation ]
gap> gr := CompleteDigraph(3);;
gap> GeneratorsOfEndomorphismMonoid(gr);
[ Transformation( [ 2, 3, 1 ] ), Transformation( [ 2, 1 ] ),
  IdentityTransformation ]
gap> GeneratorsOfEndomorphismMonoid(gr, [1, 2, 2]);
[ Transformation( [ 1, 3, 2 ] ), IdentityTransformation ]
gap> GeneratorsOfEndomorphismMonoid(gr, [[1], [2, 3]]);
[ Transformation( [ 1, 3, 2 ] ), IdentityTransformation ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphColouring">
<ManSection>
  <Oper Name="DigraphColouring" Arg="digraph, n"
    Label="for a digraph and a number of colours"/>
  <Returns> A transformation, or <K>fail</K>.</Returns>
  <Description>
    A <E>proper colouring</E> of a digraph is a labelling of its vertices in
    such a way that adjacent vertices have different labels. A <E>proper
      <C>n</C>-colouring</E> is a proper colouring that uses exactly <C>n</C>
    colours.  Equivalently, a proper (<C>n</C>-)colouring of a digraph can be
    defined to be a <Ref Oper="DigraphEpimorphism"/> from a digraph onto the
    complete digraph (with <C>n</C> vertices); see <Ref
      Oper="CompleteDigraph"/>.  Note that a digraph with loops (<Ref
      Prop="DigraphHasLoops"/>) does not have a proper <C>n</C>-colouring for
    any value <C>n</C>.
    <P/>

    If <A>digraph</A> is a digraph and <A>n</A> is a non-negative integer, then
    <C>DigraphColouring(<A>digraph</A>, <A>n</A>)</C> returns an epimorphism
    from <A>digraph</A> onto the complete digraph with <A>n</A> vertices if one
    exists, else it returns <K>fail</K>. <P/>

    See also <Ref Attr="DigraphGreedyColouring" Label="for a digraph"/> and
    <P/>

    Note that a digraph with at least two vertices has a 2-colouring if and only
    if it is bipartite, see <Ref Prop="IsBipartiteDigraph"/>.

    <Example><![CDATA[
gap> DigraphColouring(CompleteDigraph(5), 4);
fail
gap> DigraphColouring(ChainDigraph(10), 1);
fail
gap> D := ChainDigraph(10);;
gap> t := DigraphColouring(D, 2);
Transformation( [ 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 ] )
gap> IsDigraphColouring(D, t);
true
gap> DigraphGreedyColouring(D);
Transformation( [ 2, 1, 2, 1, 2, 1, 2, 1, 2, 1 ] )
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphGreedyColouring">
<ManSection>
  <Oper Name="DigraphGreedyColouring"
        Arg="digraph, order"
        Label="for a digraph and vertex order"/>
  <Oper Name="DigraphGreedyColouring"
        Arg="digraph, func"
        Label="for a digraph and vertex order function"/>
  <Attr Name="DigraphGreedyColouring"
        Arg="digraph"
        Label="for a digraph"/>
  <Returns> A transformation, or <K>fail</K>.</Returns>
  <Description>
    A <E>proper colouring</E> of a digraph is a labelling of its vertices in
    such a way that adjacent vertices have different labels. Note that a digraph
    with loops (<Ref Prop="DigraphHasLoops"/>) does not have any proper
    colouring.
    <P/>

    If <A>digraph</A> is a digraph and <A>order</A> is a dense list consisting
    of all of the vertices of <A>digraph</A> (in any order), then
    <C>DigraphGreedyColouring</C>
    uses a greedy algorithm with the specified order to obtain some proper
    colouring of <A>digraph</A>, which may not use the minimal number of
    colours. <P/>

    If <A>digraph</A> is a digraph and <A>func</A> is a function whose argument
    is a digraph, and that returns a dense list <A>order</A>, then
    <C>DigraphGreedyColouring(<A>digraph</A>, <A>func</A>)</C> returns
    <C>DigraphGreedyColouring(<A>digraph</A>, <A>func</A>(<A>digraph</A>))</C>.
    <P/>

    If the optional second argument (either a list or a function), is not
    specified, then <Ref Attr="DigraphWelshPowellOrder"/> is used by default.
    <P/>

    See also
    <Ref Oper="DigraphColouring"
         Label="for a digraph and a number of colours"/>.
    <P/>

    <Example><![CDATA[
gap> DigraphGreedyColouring(ChainDigraph(10));
Transformation( [ 2, 1, 2, 1, 2, 1, 2, 1, 2, 1 ] )
gap> DigraphGreedyColouring(ChainDigraph(10), [1 .. 10]);
Transformation( [ 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 ] )
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphWelshPowellOrder">
<ManSection>
  <Attr Name="DigraphWelshPowellOrder" Arg="digraph"/>
  <Returns> A list of the vertices.</Returns>
  <Description>
    <C>DigraphWelshPowellOrder</C> returns a list of all of the vertices of
    the digraph <A>digraph</A> ordered according to the sum of the number of
    out- and in-neighbours, from highest to lowest.
    <P/>

    <Example><![CDATA[
gap> DigraphWelshPowellOrder(Digraph([[4], [9], [9], [],
>                                     [4, 6, 9], [1], [], [],
>                                     [4, 5], [4, 5]]));
[ 5, 9, 4, 1, 6, 10, 2, 3, 7, 8 ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphEmbedding">
<ManSection>
  <Oper Name="DigraphEmbedding" Arg="digraph1, digraph2"/>
  <Returns> A transformation, or <K>fail</K>.</Returns>
  <Description>
    An embedding of a digraph <A>digraph1</A> into another digraph
    <A>digraph2</A> is a <Ref Oper="DigraphMonomorphism"/> from <A>digraph1</A>
    to <A>digraph2</A> which has the additional property that a pair of
    vertices <C>[i, j]</C> which have no edge <C>i -> j</C> in <A>digraph1</A> are

    mapped to a pair of vertices <C>[a, b]</C> which have no edge <C>a->b</C> in
    <A>digraph2</A>.<P/>

    In other words, an embedding <C>t</C> is an isomorphism from
    <A>digraph1</A> to the <Ref Oper="InducedSubdigraph"/> of <A>digraph2</A>
    on the image of <C>t</C>. <P/>

    <C>DigraphEmbedding</C> returns a single embedding if one exists, otherwise
    it returns <K>fail</K>.
    <Example><![CDATA[
gap> gr := ChainDigraph(3);
<immutable chain digraph with 3 vertices>
gap> DigraphEmbedding(gr, CompleteDigraph(4));
fail
gap> DigraphEmbedding(gr, Digraph([[3], [1, 4], [1], [3]]));
Transformation( [ 2, 4, 3, 4 ] )
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="EmbeddingsDigraphs">
<ManSection>
  <Oper Name="EmbeddingsDigraphs" Arg="D1, D2"/>
  <Oper Name="EmbeddingsDigraphsRepresentatives" Arg="D1, D2"/>
  <Returns>A list of transformations.</Returns>
  <Description>
    These operations behave the same as <Ref Oper="HomomorphismsDigraphs"/> and
    <Ref Oper="HomomorphismsDigraphsRepresentatives"/>, except they only return
    embeddings of <A>D1</A> into <A>D2</A>.<P/>

    See also <Ref Oper="IsDigraphEmbedding"/>.
    <Example><![CDATA[
gap> D1 := NullDigraph(2);
<immutable empty digraph with 2 vertices>
gap> D2 := CycleDigraph(5);
<immutable cycle digraph with 5 vertices>
gap> EmbeddingsDigraphsRepresentatives(D1, D2);
[ Transformation( [ 1, 3, 3 ] ), Transformation( [ 1, 4, 3, 4 ] ) ]
gap> EmbeddingsDigraphs(D1, D2);
[ Transformation( [ 1, 3, 3 ] ), Transformation( [ 1, 4, 3, 4 ] ),
  Transformation( [ 2, 4, 4, 5, 1 ] ),
  Transformation( [ 2, 5, 4, 5, 1 ] ),
  Transformation( [ 3, 1, 5, 1, 2 ] ),
  Transformation( [ 3, 5, 5, 1, 2 ] ),
  Transformation( [ 4, 1, 1, 2, 3 ] ),
  Transformation( [ 4, 2, 1, 2, 3 ] ),
  Transformation( [ 5, 2, 2, 3, 4 ] ),
  Transformation( [ 5, 3, 2, 3, 4 ] ) ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsDigraphHomomorphism">
<ManSection>
  <Oper Name="IsDigraphHomomorphism" Arg="src, ran, x"
        Label="for digraphs and a permutation or transformation"/>
  <Oper Name="IsDigraphHomomorphism" Arg="src, ran, x, col1, col2"/>
  <Oper Name="IsDigraphEpimorphism" Arg="src, ran, x"
        Label="for digraphs and a permutation or transformation"/>
  <Oper Name="IsDigraphEpimorphism" Arg="src, ran, x, col1, col2"/>
  <Oper Name="IsDigraphMonomorphism" Arg="src, ran, x"
        Label="for digraphs and a permutation or transformation"/>
  <Oper Name="IsDigraphMonomorphism" Arg="src, ran, x, col1, col2"/>
  <Oper Name="IsDigraphEndomorphism" Arg="digraph, x"
        Label="for digraphs and a permutation or transformation"/>
  <Oper Name="IsDigraphEndomorphism" Arg="digraph, x, col"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    <C>IsDigraphHomomorphism</C> returns <K>true</K> if the permutation
    or transformation <A>x</A> is a homomorphism from the digraph
    <A>src</A> to the digraph <A>ran</A>.
    <P/>

    <C>IsDigraphEpimorphism</C> returns <K>true</K> if the permutation
    or transformation <A>x</A> is a surjective homomorphism from the digraph
    <A>src</A> to the digraph <A>ran</A>.
    <P/>

    <C>IsDigraphMonomorphism</C> returns <K>true</K> if the permutation
    or transformation <A>x</A> is an injective homomorphism from the digraph
    <A>src</A> to the digraph <A>ran</A>.
    <P/>

    <C>IsDigraphEndomorphism</C> returns <K>true</K> if the permutation
    or transformation <A>x</A> is an endomorphism of the digraph
    <A>digraph</A>.
    <P/>

    A permutation or transformation <A>x</A> is a <E>homomorphism</E> from a
    digraph <A>src</A> to a digraph <A>ran</A> if the following hold:
    <List>
    <Item>
    <C>[u ^ <A>x</A>, v ^
    <A>x</A>]</C> is an edge of <A>ran</A> whenever <C>[u, v]</C> is an edge of
    <A>src</A>; and
    </Item>
    <Item>
    <A>x</A> maps the vertices of <A>src</A> to a subset of the vertices of
    <A>ran</A>, i.e. <C>IsSubset(DigraphVertices(<A>ran</A>),
    OnSets(DigraphVertices(<A>src</A>), <A>x</A>))</C> is <K>true</K>.
    </Item>
    </List>

    Note that if <C>i</C> is any integer greater than
    <C>DigraphNrVertice(<A>src</A>)</C>, then the action of <A>x</A> on
    <C>i</C> is ignored by this function. One consequence of this is that
    distinct transformations or permutations might represent the same
    homomorphism. For example, if <A>src</A> and <A>ran</A> are
    <C>CycleDigraph(2)</C>, then both the permutations <C>(1, 2)</C> and <C>(1,
    2)(3, 4)</C> represent the same automorphism of <A>src</A>.
    <P/>

    See also <Ref Func="GeneratorsOfEndomorphismMonoid"/>.<P/>


    If <A>col1</A> and <A>col2</A>, or <A>col</A>, are given, then they must
    represent vertex colourings; see
    <Ref Oper="AutomorphismGroup" Label="for a digraph and a homogeneous list"/>
    for details of the permissible values for these argument. The
    homomorphism must then also have the property:

    <List>
      <Item>
        <C>col[i] = col[i ^ x]</C> for all vertices <C>i</C> of <A>digraph</A>,
        in the case of <C>IsDigraphEndomorphism</C>.</Item>
      <Item>
        <C>col1[i] = col2[i ^ x]</C> for all vertices <C>i</C> of <A>src</A>,
        in the cases of the other operations.</Item>
    </List>

    See also <Ref Oper="DigraphsRespectsColouring"/>.

    <Example><![CDATA[
gap> src := Digraph([[1], [1, 2], [1, 3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> ran := Digraph([[1], [1, 2]]);
<immutable digraph with 2 vertices, 3 edges>
gap> IsDigraphHomomorphism(src, ran, Transformation([1, 2, 2]));
true
gap> IsDigraphHomomorphism(src, ran, Transformation([2, 1, 2]));
false
gap> IsDigraphHomomorphism(src, ran, Transformation([3, 3, 3]));
false
gap> IsDigraphHomomorphism(src, src, Transformation([3, 3, 3]));
true
gap> IsDigraphHomomorphism(src, ran, Transformation([1, 2, 2]),
>                          [1, 2, 2], [1, 2]);
true
gap> IsDigraphHomomorphism(src, ran, Transformation([1, 2, 2]),
>                          [2, 1, 1], [1, 2]);
false
gap> IsDigraphEndomorphism(src, Transformation([3, 3, 3]));
true
gap> IsDigraphEndomorphism(src, Transformation([3, 3, 3]), [1, 1, 1]);
true
gap> IsDigraphEndomorphism(src, Transformation([3, 3, 3]), [1, 1, 2]);
false
gap> IsDigraphEpimorphism(src, ran, Transformation([3, 3, 3]));
false
gap> IsDigraphMonomorphism(src, ran, Transformation([1, 2, 2]));
false
gap> IsDigraphEpimorphism(src, ran, Transformation([1, 2, 2]));
true
gap> IsDigraphMonomorphism(ran, src, ());
true]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsDigraphEmbedding">
<ManSection>
  <Oper Name="IsDigraphEmbedding" Arg="src, ran, x"
        Label="for digraphs and a permutation or transformation"/>
  <Oper Name="IsDigraphEmbedding" Arg="src, ran, x, col1, col2"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>
  <Description>
    <C>IsDigraphEmbedding</C> returns <K>true</K> if the permutation
    or transformation <A>x</A> is a embedding of the digraph
    <A>src</A> into the digraph <A>ran</A>, while respecting the colourings
    <A>col1</A> and <A>col2</A> if given.
    <P/>

    A permutation or transformation <A>x</A> is a <E>embedding</E> of a digraph
    <A>src</A> into a digraph <A>ran</A> if <A>x</A> is a monomorphism from
    <A>src</A> to <A>ran</A> and the inverse of <A>x</A> is a monomorphism from
    the subdigraph of <A>ran</A> induced by the image of <A>x</A> to
    <A>src</A>.

    See also <Ref Oper="IsDigraphHomomorphism"/>.<P/>

    <Example><![CDATA[
gap> src := Digraph([[1], [1, 2]]);
<immutable digraph with 2 vertices, 3 edges>
gap> ran := Digraph([[1], [1, 2], [1, 3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> IsDigraphMonomorphism(src, ran, ());
true
gap> IsDigraphEmbedding(src, ran, ());
true
gap> IsDigraphEmbedding(src, ran, (), [2, 1], [2, 1, 1]);
true
gap> IsDigraphEmbedding(src, ran, (), [2, 1], [1, 2, 1]);
false
gap> ran := Digraph([[1, 2], [1, 2], [1, 3]]);
<immutable digraph with 3 vertices, 6 edges>
gap> IsDigraphMonomorphism(src, ran, IdentityTransformation);
true
gap> IsDigraphEmbedding(src, ran, IdentityTransformation);
false]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsDigraphColouring">
  <ManSection>
    <Oper Name="IsDigraphColouring" Arg="digraph, list"/>
    <Oper Name="IsDigraphColouring" Arg="digraph, t"
      Label="for a transformation"/>
    <Returns> <K>true</K> or <K>false</K>. </Returns>
    <Description>
      The operation <C>IsDigraphColouring</C> verifies whether or not
      the list <A>list</A> describes a proper colouring of the digraph
      <A>digraph</A>.
      <P/>

      A list <A>list</A> describes a <E>proper colouring</E> of a digraph
      <A>digraph</A> if <A>list</A> consists of positive integers, the length of
      <A>list</A> equals the number of vertices in <A>digraph</A>, and for any
      vertices <C>u, v</C> of <A>digraph</A> if <C>u</C> and <C>v</C> are adjacent,
      then <C><A>list</A>[u] &gt;&lt; <A>list</A>[v]</C>.
      <P/>

      A transformation <A>t</A> describes a proper colouring of a digraph
      <A>digraph</A>, if <C>ImageListOfTransformation(<A>t</A>,
      DigraphNrVertices(<A>digraph</A>))</C> is a proper colouring of
      <A>digraph</A>. <P/>

      See also <Ref Oper="IsDigraphHomomorphism"/>.

      <Example><![CDATA[
gap> D := JohnsonDigraph(5, 3);
<immutable symmetric digraph with 10 vertices, 60 edges>
gap> IsDigraphColouring(D, [1, 2, 3, 3, 2, 1, 4, 5, 6, 7]);
true
gap> IsDigraphColouring(D, [1, 2, 3, 3, 2, 1, 2, 5, 6, 7]);
false
gap> IsDigraphColouring(D, [1, 2, 3, 3, 2, 1, 2, 5, 6, -1]);
false
gap> IsDigraphColouring(D, [1, 2, 3]);
false
gap> IsDigraphColouring(D, IdentityTransformation);
true
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphsRespectsColouring">
  <ManSection>
    <Oper Name="DigraphsRespectsColouring" Arg="src, ran, x, col1, col2"/>
    <Returns> <K>true</K> or <K>false</K>. </Returns>
    <Description>
      The operation <C>DigraphsRespectsColouring</C> verifies whether or not
      the permutation or transformation <A>x</A> respects the vertex colourings
      <A>col1</A> and <A>col2</A> of the digraphs <A>src</A> and <A>range</A>.
      That is, <C>DigraphsRespectsColouring</C> returns <K>true</K> if and only if for
      all vertices <C>i</C> of <A>src</A>, <C>col1[i] = col2[i ^ x]</C>.
      <P/>

      <Example><![CDATA[
gap> src := Digraph([[1], [1, 2]]);
<immutable digraph with 2 vertices, 3 edges>
gap> ran := Digraph([[1], [1, 2], [1, 3]]);
<immutable digraph with 3 vertices, 5 edges>
gap> DigraphsRespectsColouring(src, ran, (1, 2), [2, 1], [1, 2, 1]);
true
gap> DigraphsRespectsColouring(src, ran, (1, 2), [2, 1], [2, 1, 1]);
false
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="MaximalCommonSubdigraph">
  <ManSection>
    <Oper Name="MaximalCommonSubdigraph" Arg="D1, D2"/>
    <Returns>A list containing a digraph and two transformations.</Returns>
    <Description>
  If <A>D1</A> and <A>D2</A> are digraphs without multiple edges, then
  <C>MaximalCommonSubdigraph</C> returns a maximal common subgraph <C>M</C> of
  <A>D1</A> and <A>D2</A> with the maximum number of vertices. So <C>M</C> is a
  digraph which embeds into both <A>D1</A> and <A>D2</A> and has the largest
  number of vertices among such digraphs.

  It returns a list <C>[M, t1, t2]</C> where <C>M</C> is the maximal common
  subdigraph and <C>t1, t2</C> are transformations embedding <C>M</C> into
  <A>D1</A> and <A>D2</A> respectively.

<Example><![CDATA[
gap> MaximalCommonSubdigraph(PetersenGraph(), CompleteDigraph(10));
[ <immutable digraph with 2 vertices, 2 edges>,
  IdentityTransformation, IdentityTransformation ]
gap> MaximalCommonSubdigraph(PetersenGraph(),
> DigraphSymmetricClosure(CycleDigraph(5)));
[ <immutable digraph with 5 vertices, 10 edges>,
  IdentityTransformation, IdentityTransformation ]
gap> MaximalCommonSubdigraph(NullDigraph(0), CompleteDigraph(10));
[ <immutable empty digraph with 0 vertices>, IdentityTransformation,
  IdentityTransformation ]
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="MinimalCommonSuperdigraph">
  <ManSection>
    <Oper Name="MinimalCommonSuperdigraph" Arg="D1, D2"/>
    <Returns>A list containing a digraph and two transformations.</Returns>
    <Description>
  If <A>D1</A> and <A>D2</A> are digraphs without multiple edges, then
  <C>MinimalCommonSuperdigraph</C> returns a minimal common superdigraph
  <C>M</C> of <A>D1</A> and <A>D2</A> with the minimum number of vertices.
  So <C>M</C> is a digraph into which both <A>D1</A> and <A>D2</A> embed and
  has the smallest number of vertices among such digraphs.

  It returns a list <C>[M, t1, t2]</C> where <C>M</C> is the minimal common
  superdigraph and <C>t1, t2</C> are transformations embedding <A>D1</A> and
  <A>D2</A> respectively into <C>M</C>.
<Example><![CDATA[
gap> MinimalCommonSuperdigraph(PetersenGraph(), CompleteDigraph(10));
[ <immutable digraph with 18 vertices, 118 edges>,
  IdentityTransformation,
  Transformation( [ 1, 2, 11, 12, 13, 14, 15, 16, 17, 18, 11, 12, 13,
      14, 15, 16, 17, 18 ] ) ]
gap> MinimalCommonSuperdigraph(PetersenGraph(),
> DigraphSymmetricClosure(CycleDigraph(5)));
[ <immutable digraph with 10 vertices, 30 edges>,
  IdentityTransformation, IdentityTransformation ]
gap> MinimalCommonSuperdigraph(NullDigraph(0), CompleteDigraph(10));
[ <immutable digraph with 10 vertices, 90 edges>,
  IdentityTransformation, IdentityTransformation ]
]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="LatticeDigraphEmbedding">
<ManSection>
  <Oper Name="LatticeDigraphEmbedding" Arg="L1, L2"/>
  <Returns>A transformation, or <K>fail</K>.</Returns>
  <Description>
    If <A>L1</A> and <A>L2</A> are lattice digraphs (<Ref
      Prop="IsLatticeDigraph"/> returns <K>true</K>, then
    <C>LatticeDigraphEmbedding</C> returns a single <E>injective</E> <Ref
      Oper="DigraphHomomorphism"/> between <A>L1</A> and <A>L2</A>, with
      the property that it is a <E>lattice homomorphism</E>. If no such
      homomorphism exists, <K>fail</K> is returned.<P/>

      A <E>lattice homomorphism</E> is a digraph homomorphism which respects
      meets and joins of every pair of vertices. Note that every injective
      lattice homomorphism <C>map</C> is an embedding, in the sense that
      the inverse of <C>map</C> is a lattice homomorphism also.

    <Example><![CDATA[
gap> D := DigraphReflexiveTransitiveClosure(ChainDigraph(5));
<immutable preorder digraph with 5 vertices, 15 edges>
gap> L1 := DigraphReflexiveTransitiveClosure(ChainDigraph(5));
<immutable preorder digraph with 5 vertices, 15 edges>
gap> L2 := DigraphReflexiveTransitiveClosure(ChainDigraph(6));
<immutable preorder digraph with 6 vertices, 21 edges>
gap> LatticeDigraphEmbedding(L1, L2);
IdentityTransformation
gap> LatticeDigraphEmbedding(L2, L1);
fail
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsLatticeHomomorphism">
<ManSection>
  <Oper Name="IsLatticeHomomorphism" Arg="L1, L2, map"
        Label="for digraphs and a permutation or transformation"/>
  <Oper Name="IsLatticeEpimorphism" Arg="L1, L2, map"
        Label="for digraphs and a permutation or transformation"/>
  <Oper Name="IsLatticeEmbedding" Arg="L1, L2, map"
        Label="for digraphs and a permutation or transformation"/>
  <Oper Name="IsLatticeMonomorphism" Arg="L1, L2, map"
        Label="for digraphs and a permutation or transformation"/>
  <Oper Name="IsLatticeEndomorphism" Arg="L, map"
        Label="for digraphs and a permutation or transformation"/>
  <Returns><K>true</K> or <K>false</K>.</Returns>

  <Description>
    Each of the function described in this section (except
    <C>IsLatticeEndomorphism</C>) takes a pair of digraphs <A>L1</A> and
    <A>L2</A>, and a transformation <A>map</A>, returning <K>true</K> if
    <A>map</A> is a <E>lattice homomorphism</E> from <A>L1</A> to <A>L2</A>,
      and <K>false</K> otherwise. If <A>L1</A> or <A>L2</A> is not a lattice,
      then <K>false</K> is returned.<P/>

    A transformation or permutation <A>map</A> is a <E>lattice homomorphism</E>
    if <A>map</A> respects meets and joins of every pair of vertices, and
    <A>map</A> fixes every <C>i</C> which is not a vertex of <A>L1</A>.
    <P/>

    <C>IsLatticeHomomorphism</C> returns <K>true</K> if the permutation
    or transformation <A>map</A> is a lattice homomorphism from the lattice digraph
    <A>L1</A> to the lattice digraph <A>L2</A>.
    <P/>

    <C>IsLatticeEpimorphism</C> returns <K>true</K> if the permutation
    or transformation <A>map</A> is a surjective lattice homomorphism from
    the lattice digraph <A>L1</A> to the lattice digraph <A>L2</A>.
    <P/>

    <C>IsLatticeEmbedding</C> returns <K>true</K> if the permutation
    or transformation <A>map</A> is an injective lattice homomorphism from
    the lattice digraph <A>L1</A> to the lattice digraph <A>L2</A>.
    The function <C>IsLatticeMonomorphism</C> is a synonym of
    <C>IsLatticeEmbedding</C>.
    <P/>

    <C>IsLatticeEndomorphism</C> returns <K>true</K> if the permutation
    or transformation <A>map</A> is an lattice endomorphism of the
    lattice digraph <A>L</A>.

    <Example><![CDATA[
gap> G := Digraph([[2, 4], [3, 7], [6], [5, 7], [6], [], [6]]);
<immutable digraph with 7 vertices, 9 edges>
gap> D := DigraphRemoveVertex(G, 7);
<immutable digraph with 6 vertices, 6 edges>
gap> G := DigraphReflexiveTransitiveClosure(G);
<immutable preorder digraph with 7 vertices, 22 edges>
gap> D := DigraphReflexiveTransitiveClosure(D);
<immutable preorder digraph with 6 vertices, 17 edges>
gap> IsDigraphEmbedding(D, G, IdentityTransformation);
true
gap> IsLatticeHomomorphism(D, G, IdentityTransformation);
false
gap> D := Digraph([[2, 3], [4], [4], []]);
<immutable digraph with 4 vertices, 4 edges>
gap> G := Digraph([[2, 3], [4], [4], [5], []]);
<immutable digraph with 5 vertices, 5 edges>
gap> D := DigraphReflexiveTransitiveClosure(D);
<immutable preorder digraph with 4 vertices, 9 edges>
gap> G := DigraphReflexiveTransitiveClosure(G);
<immutable preorder digraph with 5 vertices, 14 edges>
gap> IsLatticeEmbedding(D, G, IdentityTransformation);
true
gap> IsLatticeMonomorphism(D, G, IdentityTransformation);
true
gap> f := Transformation([1, 2, 3, 4, 4]);
Transformation( [ 1, 2, 3, 4, 4 ] )
gap> IsLatticeEpimorphism(G, D, f);
true
gap> IsLatticeEndomorphism(D, (2, 3));
true
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>
