#############################################################################
##
#W  io.xml
#Y  Copyright (C) 2014-17                               James D. Mitchell
##
##  Licensing information can be found in the README file of this package.
##
#############################################################################
##

<#GAPDoc Label="IteratorFromDigraphFile">
<ManSection>
  <Func Name="IteratorFromDigraphFile" Arg="filename [, decoder]"/>
  <Returns>An iterator.</Returns>
  <Description>
    If <A>filename</A> is a string representing the name of a file containing
    encoded digraphs, then <C>IteratorFromDigraphFile</C> returns an iterator
    for which the value of <Ref Oper="NextIterator" BookName="ref"/> is the
    next digraph encoded in the file.
    <P/>

    If the optional argument <A>decoder</A> is specified and is a function
    which decodes a string into a digraph, then <C>IteratorFromDigraphFile</C>
    will use <A>decoder</A> to decode the digraphs contained in <A>filename</A>.
    <P/>

    The purpose of this function is to easily allow looping over digraphs
    encoded in a file when loading all of the encoded digraphs would require
    too much memory. <P/>

    To see what file types are available, see <Ref Func="WriteDigraphs"/>.

    <Example><![CDATA[
gap> filename := Concatenation(DIGRAPHS_Dir(), "/tst/out/man.d6.gz");;
gap> file := DigraphFile(filename, "w");;
gap> for i in [1 .. 10] do
>   WriteDigraphs(file, Digraph([[1, 3], [2], [1, 2]]));
> od;
gap> IO_Close(file);;
gap> iter := IteratorFromDigraphFile(filename);
<iterator>
gap> for x in iter do od;
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphFile">
<ManSection>
  <Func Name="DigraphFile" Arg="filename [, coder][, mode]"/>
  <Returns>An IO file object.</Returns>
  <Description>
    If <A>filename</A> is a string representing the name of a file, then
    <C>DigraphFile</C> returns an &IO; package file object for that file.
    <P/>

    If the optional argument <A>coder</A> is specified
    and is a function which either encodes a digraph as a string, or decodes a
    string into a digraph, then this function will be used when reading or
    writing to the returned file object. If the optional argument <A>coder</A>
    is not specified, then the encoding of the digraphs in the returned file
    object must be specified in the the file extension. The file extension must
    be one of: <C>.g6</C>, <C>.s6</C>, <C>.d6</C>, <C>.ds6</C>, <C>.txt</C>,
    <C>.p</C>, or <C>.pickle</C>; more details of these file formats is given
    below. <P/>

    If the optional argument <A>mode</A> is specified, then it must be one of:
    <C>"w"</C> (for write), <C>"a"</C> (for append), or <C>"r"</C> (for read).
    If <A>mode</A> is not specified, then <C>"r"</C> is used by default. <P/>

    If <A>filename</A> ends in one of: <C>.gz</C>, <C>.bz2</C>, or
    <C>.xz</C>, then the digraphs which are read from, or written to, the
    returned file object are decompressed, or compressed, appropriately.
    <P/>

    The file object returned by <C>DigraphFile</C> can be given as the first
    argument for either of the functions <Ref Func="ReadDigraphs"/> or <Ref
      Func="WriteDigraphs"/>. The purpose of this is to reduce the overhead of
    recreating the file object inside the functions <Ref Func="ReadDigraphs"/>
    or <Ref Func="WriteDigraphs"/> when, for example, reading or writing many
    digraphs in a loop.
    <P/>

    The currently supported file formats, and associated filename extensions,
    are:
    <List>
      <Mark>graph6 (.g6)</Mark>
      <Item>
	A standard and widely-used format for undirected graphs, with no support
	for loops or multiple edges.  Only symmetric graphs are allowed -- each
	edge is combined with its converse edge to produce a single undirected
	edge.  This format is best used for "dense" graphs -- those with many
	edges per vertex.
      </Item>
      <Mark>sparse6 (.s6)</Mark>
      <Item>
	Unlike graph6, sparse6 has support for loops and multiple edges.
	However, its use is still limited to symmetric graphs.  This format is
	better-suited to "sparse" graphs -- those with few edges per vertex.
      </Item>
      <Mark>digraph6 (.d6)</Mark>
      <Item>
	This format is based on graph6, but stores direction information -
	therefore is not limited to symmetric graphs.  Loops are allowed, but
	multiple edges are not.  Best compression with "dense" graphs.
      </Item>
      <Mark>disparse6 (.ds6)</Mark>
      <Item>
	Any type of digraph can be encoded in disparse6: directions, loops, and
	multiple edges are all allowed.  Similar to sparse6, this has the best
	compression rate with "sparse" graphs.
      </Item>
      <Mark>plain text (.txt)</Mark>
      <Item>
	This is a human-readable format which stores graphs in the form
        <C>0 7  0 8  1 7  2 8  3 8  4 8  5 8  6 8</C> i.e. pairs of vertices
        describing edges in a graph. More specifically, the vertices making up
        one edge must be separated by a single space, and pairs of vertices must
        be separated by two spaces. <P/>

        See <Ref Oper="ReadPlainTextDigraph"/> for a more flexible way to store
        digraphs in a plain text file. <P/>
      </Item>

      <Mark>pickled (<F>.p</F> or <F>.pickle</F>)</Mark>
      <Item>
        Digraphs are pickled using the &IO; package. This is particularly good
        when the <Ref Attr="DigraphGroup"/> is non-trivial.
      </Item>
    </List>

    <Example><![CDATA[
gap> filename := Concatenation(DIGRAPHS_Dir(), "/tst/out/man.d6.gz");;
gap> file := DigraphFile(filename, "w");;
gap> for i in [1 .. 10] do
> WriteDigraphs(file, Digraph([[1, 3], [2], [1, 2]]));
> od;
gap> IO_Close(file);;
gap> file := DigraphFile(filename, "r");;
gap> ReadDigraphs(file, 9);
<immutable digraph with 3 vertices, 5 edges>
gap> IO_Close(file);;
]]></Example>
    </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="PlainTextDecoders">
<ManSection>
  <Func Name="TournamentLineDecoder" Arg="digraph"/>
  <Func Name="AdjacencyMatrixUpperTriangleLineDecoder" Arg="digraph"/>
  <Func Name="TCodeDecoder" Arg="digraph"/>
  <Returns></Returns>
  <Description>
    FIXME: actually write this!
    <Example><![CDATA[
]]></Example>
    </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="String">
<ManSection>
  <Attr Name="String" Arg="digraph"/>
  <Oper Name="PrintString" Arg="digraph"/>
  <Returns>A string.</Returns>
  <Description>
    Returns a string <C>string</C> such that <C>EvalString(string)</C>
    is equal to <A>digraph</A>, and has the same mutability.
    See <Ref Func="EvalString" BookName="ref" />.
    <P/>

    The methods installed for <C>String</C> make some attempts to
    ensure that <C>string</C> has as short a length as possible, but
    there may exist shorter strings that also evaluate to <A>digraph</A>.
    <P/>

    It is possible that <C>string</C> may contain escaped special
    characters. To obtain a representation of <A>digraph</A> that
    can be entered as GAP input, please use
    <Ref Func="Print" BookName="ref" />.
    Note that <C>Print</C> for a digraph  delegates to
    <C>PrintString</C>, which delegates to <C>String</C>.
    <Log><![CDATA[
gap> D := CycleDigraph(3);
<immutable cycle digraph with 3 vertices>
gap> Print(D);
CycleDigraph(3);
gap> G := PetersenGraph(IsMutableDigraph);
<mutable digraph with 10 vertices, 30 edges>
gap> String(G);
"DigraphFromGraph6String(IsMutableDigraph, \"IheA@GUAo\");"
gap> Print(last);
DigraphFromGraph6String(IsMutableDigraph, "IheA@GUAo");
gap> DigraphFromGraph6String(IsMutableDigraph, "IheA@GUAo");
<mutable digraph with 10 vertices, 30 edges>
]]></Log>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphFromGraph6String">
<ManSection>
  <Oper Name="DigraphFromGraph6String"    Arg="[filt, ]str"/>
  <Oper Name="DigraphFromDigraph6String"  Arg="[filt, ]str"/>
  <Oper Name="DigraphFromSparse6String"   Arg="[filt, ]str"/>
  <Oper Name="DigraphFromDiSparse6String" Arg="[filt, ]str"/>
  <Returns>A digraph.</Returns>
  <Description>
    If <A>str</A> is a string encoding a graph in Graph6, Digraph6, Sparse6 or
    DiSparse6 format, then the corresponding function returns a digraph. In the
    case of either Graph6 or Sparse6, formats which do not support directed
    edges, this will be a digraph such that for every edge, the edge going in
    the opposite direction is also present.<P/>

    Each of these functions takes an optional first argument <A>filt</A>,
    which should be either <Ref Filt="IsMutableDigraph"/>
    or <Ref Filt="IsImmutableDigraph"/>,
    and which specifies whether the output digraph shall
    be mutable or immutable.
    If no first argument is provided, then an immutable
    digraph is returned by default.
    <Example><![CDATA[
gap> DigraphFromGraph6String("?");
<immutable empty digraph with 0 vertices>
gap> DigraphFromGraph6String("C]");
<immutable symmetric digraph with 4 vertices, 8 edges>
gap> DigraphFromGraph6String("H?AAEM{");
<immutable symmetric digraph with 9 vertices, 22 edges>
gap> DigraphFromDigraph6String("&?");
<immutable empty digraph with 0 vertices>
gap> DigraphFromDigraph6String(IsMutableDigraph, "&DOOOW?");
<mutable digraph with 5 vertices, 5 edges>
gap> DigraphFromDigraph6String("&CQFG");
<immutable digraph with 4 vertices, 6 edges>
gap> DigraphFromDigraph6String("&IM[SrKLc~lhesbU[F_");
<immutable digraph with 10 vertices, 51 edges>
gap> DigraphFromDiSparse6String(".CaWBGA?b");
<immutable multidigraph with 4 vertices, 9 edges>
]]></Example>
    </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="ReadDigraphs">
<ManSection>
  <Func Name="ReadDigraphs" Arg="filename[, decoder][, n]"/>
  <Returns>A digraph, or a list of digraphs.</Returns>
  <Description>
    If <A>filename</A> is a string containing the name of a file containing
    encoded digraphs or an &IO; file object created using <Ref
      Func="DigraphFile"/>, then <C>ReadDigraphs</C> returns the digraphs
    encoded in the file as a list.  Note that if <A>filename</A> is a
    compressed file, which has been compressed appropriately to give a filename
    extension of <C>.gz</C>, <C>.bz2</C>, or <C>.xz</C>, then
    <C>ReadDigraphs</C> can read <A>filename</A> without it first needing to be
    decompressed.
    <P/>

    If the optional argument <A>decoder</A> is specified
    and is a function which decodes a string into a digraph,
    then <C>ReadDigraphs</C> will use <A>decoder</A> to decode the digraphs
    contained in <A>filename</A>.<P/>

    If the optional argument <A>n</A> is specified, then <C>ReadDigraphs</C>
    returns the <A>n</A>th digraph encoded in the file <A>filename</A>.
    <P/>

    If the optional argument <A>decoder</A> is not specified, then
    <C>ReadDigraphs</C> will deduce which decoder to use based on the filename
    extension of <A>filename</A> (after removing the compression-related
    filename extensions <C>.gz</C>, <C>.bz2</C>, and <C>.xz</C>).  For example,
    if the filename extension is <C>.g6</C>, then <C>ReadDigraphs</C> will use
    the graph6 decoder <Ref Oper="DigraphFromGraph6String"/>.
    <P/>

    The currently supported file formats, and associated filename extensions,
    are:
    <List>
      <Mark>graph6 (.g6)</Mark>
      <Item>
	A standard and widely-used format for undirected graphs, with no support
	for loops or multiple edges.  Only symmetric graphs are allowed -- each
	edge is combined with its converse edge to produce a single undirected
	edge.  This format is best used for "dense" graphs -- those with many
	edges per vertex.
      </Item>
      <Mark>sparse6 (.s6)</Mark>
      <Item>
	Unlike graph6, sparse6 has support for loops and multiple edges.
	However, its use is still limited to symmetric graphs.  This format is
	better-suited to "sparse" graphs -- those with few edges per vertex.
      </Item>
      <Mark>digraph6 (.d6)</Mark>
      <Item>
	This format is based on graph6, but stores direction information -
	therefore is not limited to symmetric graphs.  Loops are allowed, but
	multiple edges are not.  Best compression with "dense" graphs.
      </Item>
      <Mark>disparse6 (.ds6)</Mark>
      <Item>
	Any type of digraph can be encoded in disparse6: directions, loops, and
	multiple edges are all allowed.  Similar to sparse6, this has the best
	compression rate with "sparse" graphs.
      </Item>
      <Mark>plain text (.txt)</Mark>
      <Item>
	This is a human-readable format which stores graphs in the form
        <C>0 7  0 8  1 7  2 8  3 8  4 8  5 8  6 8</C> i.e. pairs of vertices
        describing edges in a graph. More specifically, the vertices making up
        one edge must be separated by a single space, and pairs of vertices must
        be separated by two spaces. <P/>

        See <Ref Oper="ReadPlainTextDigraph"/> for a more flexible way to store
        digraphs in a plain text file. <P/>
<!--
        Just so I remember:
        <C>ReadPlainTextDigraph("data-local/soc-Epinions1.txt.gz", "\t", 1,
        '#');</C>
-->
      </Item>

      <Mark>pickled (<F>.p</F> or <F>.pickle</F>)</Mark>
      <Item>
        Digraphs are pickled using the &IO; package. This is particularly good
        when the <Ref Attr="DigraphGroup"/> is non-trivial.
      </Item>
    </List>

    <Example><![CDATA[
gap> ReadDigraphs(
> Concatenation(DIGRAPHS_Dir(), "/data/graph5.g6.gz"), 10);
<immutable symmetric digraph with 5 vertices, 8 edges>
gap> ReadDigraphs(
> Concatenation(DIGRAPHS_Dir(), "/data/graph5.g6.gz"), 17);
<immutable symmetric digraph with 5 vertices, 12 edges>
gap> ReadDigraphs(
> Concatenation(DIGRAPHS_Dir(), "/data/tree9.4.txt"));
[ <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges>, 
  <immutable digraph with 9 vertices, 8 edges> ]]]></Example>
    </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="WriteDigraphs">
<ManSection>
  <Func Name="WriteDigraphs" Arg="filename, digraphs[, encoder] [, mode]"/>
  <Description>
    If <A>digraphs</A> is a list of digraphs or a digraph and <A>filename</A>
    is a string or an &IO; file object created using <Ref Func="DigraphFile"/>,
    then <C>WriteDigraphs</C> writes the digraphs to the file represented by
    <A>filename</A>.  If the supplied filename ends in one of the extensions
    <C>.gz</C>, <C>.bz2</C>, or <C>.xz</C>, then the file will be compressed
    appropriately.  Excluding these extensions, if the file ends with an
    extension in the list below, the corresponding graph format will be used to
    encode it.  If such an extension is not included, an appropriate format
    will be chosen intelligently, and an extension appended, to minimise file
    size.
    <P/>

    <!-- TODO: encode and mode. -->

    For more verbose information on the progress of the function, set the info
    level of <A>InfoDigraphs</A> to 1 or higher, using <C>SetInfoLevel</C>.<P/>

    The currently supported file formats are:
    <List>
      <Mark>graph6 (.g6)</Mark>
      <Item>
	A standard and widely-used format for undirected graphs, with no support
	for loops or multiple edges.  Only symmetric graphs are allowed -- each
	edge is combined with its converse edge to produce a single undirected
	edge.  This format is best used for "dense" graphs -- those with many
	edges per vertex.
      </Item>
      <Mark>sparse6 (.s6)</Mark>
      <Item>
	Unlike graph6, sparse6 has support for loops and multiple edges.
	However, its use is still limited to symmetric graphs.  This format is
	better-suited to "sparse" graphs -- those with few edges per vertex.
      </Item>
      <Mark>digraph6 (.d6)</Mark>
      <Item>
	This format is based on graph6, but stores direction information -
	therefore is not limited to symmetric graphs.  Loops are allowed, but
	multiple edges are not.  Best compression with "dense" graphs.
      </Item>
      <Mark>disparse6 (.ds6)</Mark>
      <Item>
	Any type of digraph can be encoded in disparse6: directions, loops, and
	multiple edges are all allowed.  Similar to sparse6, this has the best
	compression rate with "sparse" graphs.
      </Item>

      <Mark>plain text (.txt)</Mark>
      <Item>
	This is a human-readable format which stores graphs in the form
        <C>0 7  0 8  1 7  2 8  3 8  4 8  5 8  6 8</C> i.e. pairs of vertices
        describing edges in a graph. More specifically, the vertices making up
        one edge must be separated by a single space, and pairs of vertices must
        be separated by two spaces. <P/>

        See <Ref Oper="ReadPlainTextDigraph"/> for a more flexible way to store
        digraphs in a plain text file. <P/>
<!--
        Just so I remember:
        <C>ReadPlainTextDigraph("data-local/soc-Epinions1.txt.gz", "\t", 1, '#');</C>
-->
      </Item>
      <Mark>pickled (<F>.p</F> or <F>.pickle</F>)</Mark>
      <Item>
        Digraphs are pickled using the &IO; package. This is particularly good
        when the <Ref Attr="DigraphGroup"/> is non-trivial.
      </Item>
    </List>

    <Example><![CDATA[
gap> grs := [];;
gap> grs[1] := Digraph([]);
<immutable empty digraph with 0 vertices>
gap> grs[2] := Digraph([[1, 3], [2], [1, 2]]);
<immutable digraph with 3 vertices, 5 edges>
gap> grs[3] := Digraph([
> [6, 7], [6, 9], [1, 3, 4, 5, 8, 9],
> [1, 2, 3, 4, 5, 6, 7, 10], [1, 5, 6, 7, 10], [2, 4, 5, 9, 10],
> [3, 4, 5, 6, 7, 8, 9, 10], [1, 3, 5, 7, 8, 9], [1, 2, 5],
> [1, 2, 4, 6, 7, 8]]);
<immutable digraph with 10 vertices, 51 edges>
gap> filename := Concatenation(DIGRAPHS_Dir(), "/tst/out/man.d6.gz");;
gap> WriteDigraphs(filename, grs, "w");
IO_OK
gap> ReadDigraphs(filename);
[ <immutable empty digraph with 0 vertices>, 
  <immutable digraph with 3 vertices, 5 edges>, 
  <immutable digraph with 10 vertices, 51 edges> ]]]></Example>
    </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="Graph6String">
<ManSection>
  <Oper Name="Graph6String" Arg="digraph"/>
  <Oper Name="Digraph6String" Arg="digraph"/>
  <Oper Name="Sparse6String" Arg="digraph"/>
  <Oper Name="DiSparse6String" Arg="digraph"/>
  <Returns>A string.</Returns>
  <Description>
    These four functions return a highly compressed string fully describing the
    digraph <A>digraph</A>. <P/>

    Graph6 and Digraph6 are formats best used on small, dense graphs, if
    applicable. For larger, sparse graphs use <E>Sparse6</E> and
    <E>Disparse6</E> (this latter also preserves multiple edges). <P/>

    See <Ref Func="WriteDigraphs"/>.
    <Example><![CDATA[
gap> gr := Digraph([[2, 3], [1], [1]]);
<immutable digraph with 3 vertices, 4 edges>
gap> Sparse6String(gr);
":Bc"
gap> DiSparse6String(gr);
".Bc{f"
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphPlainTextLineEncoder">
<ManSection>
  <Func Name="DigraphPlainTextLineEncoder" Arg="delimiter1, [delimiter2,] offset"/>
  <Oper Name="DigraphPlainTextLineDecoder" Arg="delimiter1, [delimiter2,] offset"/>
  <Returns>A string.</Returns>
  <Description>
    These two functions return a function which encodes or decodes a digraph in
    a plain text format.<P/>

    <A>DigraphPlainTextLineEncoder</A> returns a function which takes a single
    digraph as an argument.  The function returns a string describing the edges
    of that digraph; each edge is written as a pair of integers separated by the
    string <A>delimiter2</A>, and the edges themselves are separated by the
    string <A>delimiter1</A>.  <A>DigraphPlainTextLineDecoder</A> returns the
    corresponding decoder function, which takes a string argument in this format
    and returns a digraph.<P/>

    If only one delimiter is passed as an argument to
    <A>DigraphPlainTextLineDecoder</A>, it will return a function which decodes
    a single edge, returning its contents as a list of integers.<P/>

    The argument <A>offset</A> should be an integer, which will describe a
    number to be added to each vertex before it is encoded, or after it is
    decoded.  This may be used, for example, to label vertices starting at 0
    instead of 1.<P/>

    Note that the number of vertices of a digraph is not stored, and so vertices
    which are not connected to any edge may be lost.

    <Example><![CDATA[
gap> gr := Digraph([[2, 3], [1], [1]]);
<immutable digraph with 3 vertices, 4 edges>
gap> enc := DigraphPlainTextLineEncoder("  ", " ", -1);;
gap> dec := DigraphPlainTextLineDecoder("  ", " ", 1);;
gap> enc(gr);
"0 1  0 2  1 0  2 0"
gap> dec(last);
<immutable digraph with 3 vertices, 4 edges>
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="PlainTextString">
<ManSection>
  <Oper Name="PlainTextString" Arg="digraph"/>
  <Oper Name="DigraphFromPlainTextString" Arg="s"/>
  <Returns>A string.</Returns>
  <Description>
    <A>PlainTextString</A> takes a single digraph, and returns a string
    describing the edges of that digraph.  <A>DigraphFromPlainTextString</A>
    takes such a string and returns the digraph which it describes.  Each edge
    is written as a pair of integers separated by a single space.  The edges
    themselves are separated by a double space.  Vertex numbers are reduced by
    1 when they are encoded, so that vertices in the string are labelled
    starting at 0.<P/>

    Note that the number of vertices of a digraph is not stored, and so vertices
    which are not connected to any edge may be lost.<P/>

    
    The operation <C>DigraphFromPlainTextString</C>
    takes an optional first argument <Ref Filt="IsMutableDigraph"/>
    or <Ref Filt="IsImmutableDigraph"/>, which specifies whether the output digraph shall
    be mutable or immutable. If no first argument is provided, then an immutable
    digraph is returned by default.

    <Example><![CDATA[
gap> gr := Digraph([[2, 3], [1], [1]]);
<immutable digraph with 3 vertices, 4 edges>
gap> PlainTextString(gr);
"0 1  0 2  1 0  2 0"
gap> DigraphFromPlainTextString(last);
<immutable digraph with 3 vertices, 4 edges>
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="WritePlainTextDigraph">
<ManSection>
  <Func Name="WritePlainTextDigraph" Arg="filename, digraph, delimiter, offset"/>
  <Oper Name="ReadPlainTextDigraph" Arg="filename, delimiter, offset, ignore"/>
  <Description>
    These functions write and read a single digraph in a human-readable plain
    text format as follows: each line contains a single edge, and each edge is
    written as a pair of integers separated by the string <A>delimiter</A>.<P/>

    <A>filename</A> should be the name of a file which will be written to or
    read from, and <A>offset</A> should be an integer which is added to each
    vertex number as it is written or read.  For example, if
    <C>WritePlainTextDigraph</C> is called with <A>offset</A> <C>-1</C>, then
    the vertices will be numbered in the file starting from 0 instead of 1 -
    <C>ReadPlainTextDigraph</C> would then need to be called with <A>offset</A>
    <C>1</C> to convert back to the original graph.<P/>

    <A>ignore</A> should be a list of characters which will be ignored when
    reading the graph.
    <Example><![CDATA[
gap> gr := Digraph([[1, 2, 3], [1, 1], [2]]);
<immutable multidigraph with 3 vertices, 6 edges>
gap> filename := Concatenation(DIGRAPHS_Dir(), "/tst/out/plain.txt");;
gap> WritePlainTextDigraph(filename, gr, ",", -1);
gap> ReadPlainTextDigraph(filename, ",", 1, ['/', '%']);
<immutable multidigraph with 3 vertices, 6 edges>
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="WriteDIMACSDigraph">
<ManSection>
  <Oper Name="WriteDIMACSDigraph" Arg="filename, digraph"/>
  <Oper Name="ReadDIMACSDigraph" Arg="filename"/>
  <Description>
    These operations write or read the single symmetric digraph <A>digraph</A>
    to or from a file in DIMACS format, as appropriate. The operation
    <C>WriteDIMACSDigraph</C> records the vertices and edges of <A>digraph</A>.
    The vertex labels of <A>digraph</A> will be recorded only if they are
    integers. See <Ref Prop="IsSymmetricDigraph"/> and <Ref
      Oper="DigraphVertexLabels"/>.<P/>

    The first argument <A>filename</A> should be the name of the file which will
    be written to or read from.  A file can contain one symmetric digraph in
    DIMACS format. If <A>filename</A> ends in one of <C>.gz</C>, <C>.bz2</C>,
    or <C>.xz</C>, then the file is compressed, or decompressed, appropriately.
    <P/>

    The DIMACS format is described as follows.  Each line in the DIMACS file has
    one of four types:
    <List>
      <Item>
        A line beginning with <C>c</C> and followed by any number of characters
        is a comment line, and is ignored.
      </Item>
      <Item>
        A line beginning with <C>p</C> defines the numbers of vertices and edges
        the digraph.  This line has the format <C>p edge &lt;nr_vertices&gt;
          &lt;nr_edges&gt;</C>, where <C>&lt;nr_vertices&gt;</C> and
        <C>&lt;nr_edges&gt;</C> are replaced by the relevant integers. There
        must be exactly one such line in the file, and it must occur before any
        of the following kinds of line.<P/>

        Although it is required to be present, the value of
        <C>&lt;nr_edges&gt;</C> will be ignored. The correct number of edges
        will be deduced from the rest of the information in the file.
      </Item>
      <Item>
        A line of the form <C>e &lt;v&gt; &lt;w&gt;</C>, where <C>&lt;v&gt;</C>
        and <C>&lt;w&gt;</C> are integers in the range <C>[1 ..
          &lt;nr_vertices&gt;]</C>, specifies that there is a (symmetric) edge
        in the digraph between the vertices <C>&lt;v&gt;</C> and
        <C>&lt;w&gt;</C>. A symmetric edge only needs to be defined once; an
        additional line <C>e &lt;v&gt; &lt;w&gt;</C>, or <C>e &lt;w&gt;
          &lt;v&gt;</C>, will be interpreted as an additional, multiple, edge.
        Loops are permitted.
      </Item>
      <Item>
        A line of the form <C>n &lt;v&gt; &lt;label&gt;</C>, where
        <C>&lt;v&gt;</C> is an integer in the range <C>[1 ..
          &lt;nr_vertices&gt;]</C> and <C>&lt;label&gt;</C> is an integer,
        signifies that the vertex <C>&lt;v&gt;</C> has the label
        <C>&lt;label&gt;</C> in the digraph. If a label is not specified for a
        vertex, then <C>ReadDIMACSDigraph</C> will assign the label
        <C>1</C>, according to the DIMACS specification.
      </Item>
    </List>

    A detailed definition of the DIMACS format can be found at
    <URL>http://mat.gsia.cmu.edu/COLOR/general/ccformat.ps</URL>, in Section
    2.1. Note that optional descriptor lines, as described in Section 2.1, will
    be ignored.
    <P/>


    <Example><![CDATA[
gap> gr := Digraph([[2], [1, 3, 4], [2, 4], [2, 3]]);
<immutable digraph with 4 vertices, 8 edges>
gap> filename := Concatenation(DIGRAPHS_Dir(),
>                              "/tst/out/dimacs.dimacs");;
gap> WriteDIMACSDigraph(filename, gr);;
gap> ReadDIMACSDigraph(filename);
<immutable digraph with 4 vertices, 8 edges>]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="TournamentLineDecoder">
<ManSection>
  <Oper Name="TournamentLineDecoder" Arg="str"/>
  <Returns>A digraph.</Returns>
  <Description>
    This function takes a string <A>str</A>, decodes it, and then returns the
    tournament [see <Ref Prop="IsTournament"/>] which it defines, according to
    the following rules. <P/>

    The characters of the string <A>str</A> represent the entries in the upper
    triangle of a tournament's adjacency matrix. The number of vertices
    <C>n</C> will be detected from the length of the string and will be as
    large as possible.  <P/>

    The first character represents the possible edge <C>1 -> 2</C>, the second
    represents <C>1 -> 3</C> and so on until <C>1 -> n</C>; then the following
    character represents <C>2 -> 3</C>, and so on up to the character which
    represents the edge <C>n-1 -> n</C>. <P/>

    If a character of the string with corresponding edge <C>i -> j</C> is equal
    to <C>1</C>, then the edge <C>i -> j</C> is present in the tournament.
    Otherwise, the edge <C>i -> j</C> is present instead.  In this way, all the
    possible edges are encoded one-by-one.

    <Example><![CDATA[
gap> gr := TournamentLineDecoder("100001");
<immutable digraph with 4 vertices, 6 edges>
gap> OutNeighbours(gr);
[ [ 2 ], [  ], [ 1, 2, 4 ], [ 1, 2 ] ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="AdjacencyMatrixUpperTriangleLineDecoder">
<ManSection>
  <Oper Name="AdjacencyMatrixUpperTriangleLineDecoder" Arg="str"/>
  <Returns>A digraph.</Returns>
  <Description>
    This function takes a string <A>str</A>, decodes it, and then returns the
    topologically sorted digraph [see <Ref Attr="DigraphTopologicalSort"/>]
    which it defines, according to the following rules. <P/>

    The characters of the string <A>str</A> represent the entries in the upper
    triangle of a digraph's adjacency matrix. The number of vertices <C>n</C>
    will be detected from the length of the string and will be as large as
    possible.  <P/>

    The first character represents the possible edge <C>1 -> 2</C>, the second
    represents <C>1 -> 3</C> and so on until <C>1 -> n</C>; then the following
    character represents <C>2 -> 3</C>, and so on up to the character which
    represents the edge <C>n-1 -> n</C>.  If a character of the string with
    corresponding edge <C>i -> j</C> is equal to <C>1</C>, then this edge is
    present in the digraph. Otherwise, it is not present.  In this way, all the
    possible edges are encoded one-by-one. <P/>

    In particular, note that there exists no edge <C>[i, j]</C> if <M>j \leq
      i</M>.  In order words, the digraph will be topologically sorted.

    <Example><![CDATA[
gap> gr := AdjacencyMatrixUpperTriangleLineDecoder("100001");
<immutable digraph with 4 vertices, 2 edges>
gap> OutNeighbours(gr);
[ [ 2 ], [  ], [ 4 ], [  ] ]
gap> gr := AdjacencyMatrixUpperTriangleLineDecoder("111111x111");
<immutable digraph with 5 vertices, 9 edges>
gap> OutNeighbours(gr);
[ [ 2, 3, 4, 5 ], [ 3, 4 ], [ 4, 5 ], [ 5 ], [  ] ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="TCodeDecoder">
<ManSection>
  <Oper Name="TCodeDecoder" Arg="str"/>
  <Returns>A digraph.</Returns>
  <Description>
    If <A>str</A> is a string consisting of at least two non-negative integers
    separated by spaces, then this function will attempt to return the digraph
    which it defines as a TCode string. <P/>

    The first integer of the string defines the number of vertices <C>v</C> in
    the digraph, and the second defines the number of edges <C>e</C>.  The
    following <C>2e</C> integers should be vertex numbers in the range <C>[0 ..
      v-1]</C>. These integers are read in pairs and define the digraph's
    edges.  This function will return an error if <A>str</A> has fewer than
    <C>2e+2</C> entries. <P/>

    Note that the vertex numbers will be incremented by 1 in the digraph
    returned.  Hence the string fragment <C>0 6</C> will describe the edge
    <C>[1,7]</C>.
    <Example><![CDATA[
gap> gr := TCodeDecoder("3 2 0 2 2 1");
<immutable digraph with 3 vertices, 2 edges>
gap> OutNeighbours(gr);
[ [ 3 ], [  ], [ 2 ] ]
gap> gr := TCodeDecoder("12 3 0 10 5 2 8 8");
<immutable digraph with 12 vertices, 3 edges>
gap> OutNeighbours(gr);
[ [ 11 ], [  ], [  ], [  ], [  ], [ 3 ], [  ], [  ], [ 9 ], [  ], 
  [  ], [  ] ]
]]></Example>
  </Description>
</ManSection>
<#/GAPDoc>
