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

<#GAPDoc Label="BooleanMat">
  <ManSection>
    <Func Name = "BooleanMat" Arg = "arg"/>
    <Returns>A boolean matrix.</Returns>
    <Description>
      <C>BooleanMat</C> returns the boolean matrix <C>mat</C> defined by its
      argument. The argument can be any of the following:
      <List>

        <Mark>a matrix with entries <C>0</C> and/or <C>1</C></Mark>
        <Item>
          the argument <A>arg</A> is list of <C>n</C> lists of length <C>n</C>
          consisting of the values <C>0</C> and <C>1</C>;
        </Item>

        <Mark>a matrix with entries <K>true</K> and/or <K>false</K></Mark>
        <Item>
          the argument <A>arg</A> is list of <C>n</C> lists of length <C>n</C>
          consisting of the values <K>true</K> and <K>false</K>;
        </Item>

        <Mark>successors</Mark>
        <Item>
          the argument <A>arg</A> is list of <C>n</C> sublists of consisting of
          positive integers not greater than <C>n</C>. In this case, the entry
          <C>j</C> in the sublist in position <C>i</C> of <A>arg</A> indicates
          that the entry in position <C>(i, j)</C> of the created boolean matrix is
          <K>true</K>.
        </Item>

      </List>
      <C>BooleanMat</C> returns an error if the argument is not one of the
      above types.
      <Example><![CDATA[
gap> x := BooleanMat([[true, false], [true, true]]);
Matrix(IsBooleanMat, [[1, 0], [1, 1]])
gap> y := BooleanMat([[1, 0], [1, 1]]);
Matrix(IsBooleanMat, [[1, 0], [1, 1]])
gap> z := BooleanMat([[1], [1, 2]]);
Matrix(IsBooleanMat, [[1, 0], [1, 1]])
gap> x = y;
true
gap> y = z;
true
gap> Display(x);
1 0
1 1]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="ContainmentBooleanMats">
  <ManSection>
    <Oper Name = "\in" Arg = "mat1, mat2"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      If <A>mat1</A> and <A>mat2</A> are boolean matrices, then <C><A>mat1</A>
        in <A>mat2</A></C> returns <K>true</K> if the binary relation defined
      by <A>mat1</A> is a subset of that defined by <A>mat2</A>.

      <Example><![CDATA[
gap> x := BooleanMat([[1, 0, 0, 1], [0, 0, 0, 0],
>                     [1, 0, 1, 1], [0, 1, 1, 1]]);;
gap> y := BooleanMat([[1, 0, 1, 0], [1, 1, 1, 0],
>                     [0, 1, 1, 0], [1, 1, 1, 1]]);;
gap> x in y;
false
gap> y in y;
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="OnBlist">
  <ManSection>
    <Func Name = "OnBlist" Arg = "blist, mat"/>
    <Returns>A boolean list.</Returns>
    <Description>
      If <A>blist</A> is a boolean list of length <C>n</C> and <A>mat</A> is
      boolean matrices of dimension <C>n</C>, then <C>OnBlist</C> returns the
      product of <A>blist</A> (thought of as a row vector over the boolean
      semiring) and <A>mat</A>.

      <Example><![CDATA[
gap> mat := BooleanMat([[1, 0, 0, 1],
>                       [0, 0, 0, 0],
>                       [1, 0, 1, 1],
>                       [0, 1, 1, 1]]);;
gap> blist := BlistList([1 .. 4], [1, 2]);
[ true, true, false, false ]
gap> OnBlist(blist, mat);
[ true, false, false, true ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="Successors">
  <ManSection>
    <Attr Name = "Successors" Arg = "mat"/>
    <Returns>A list of lists of positive integers.</Returns>
    <Description>
      A row of a boolean matrix of dimension <C>n</C> can be thought of of as
      the characteristic function of a subset <C>S</C> of <C>[1 .. n]</C>, i.e.
      <C>i in S</C> if and only if the <C>i</C>th component of the row equals
      <M>1</M>.  We refer to the subset <C>S</C> as the <B>successors</B> of
      the row.
      <P/>

      If <A>mat</A> is a boolean matrix, then <C>Successors</C> returns the
      list of successors of the rows of <A>mat</A>.

      <Example><![CDATA[
gap> mat := BooleanMat([[1, 0, 1, 1],
>                       [1, 0, 0, 0],
>                       [0, 0, 1, 0],
>                       [1, 1, 0, 0]]);;
gap> Successors(mat);
[ [ 1, 3, 4 ], [ 1 ], [ 3 ], [ 1, 2 ] ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsRowTrimBooleanMat">
  <ManSection>
    <Prop Name = "IsRowTrimBooleanMat" Arg = "mat"/>
    <Prop Name = "IsColTrimBooleanMat" Arg = "mat"/>
    <Prop Name = "IsTrimBooleanMat"    Arg = "mat"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      A row or column of a boolean matrix of dimension <C>n</C> can be thought of
      of as the characteristic function of a subset <C>S</C> of <C>[1 .. n]</C>,
      i.e. <C>i in S</C> if and only if the <C>i</C>th component of
      the row or column equals <C>1</C>. <P/>

      A boolean matrix is <B>row trim</B> if no subset induced by a
      row of <A>mat</A> is contained in the subset induced by any other row of
      <A>mat</A>. <B>Column trim</B> is defined analogously. A boolean matrix
      is <B>trim</B> if it is both row and column trim.

      <Example><![CDATA[
gap> mat := BooleanMat([[0, 0, 1, 1],
>                       [1, 0, 1, 0],
>                       [1, 1, 0, 0],
>                       [0, 1, 0, 1]]);;
gap> IsTrimBooleanMat(mat);
true
gap> mat := BooleanMat([[0, 1, 1, 0],
>                       [0, 0, 1, 0],
>                       [1, 0, 0, 1],
>                       [1, 0, 1, 0]]);;
gap> IsRowTrimBooleanMat(mat);
false
gap> IsColTrimBooleanMat(mat);
false]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="NumberBooleanMat">
  <ManSection>
    <Oper Name = "BooleanMatNumber" Arg = "m, n"/>
    <Oper Name = "NumberBooleanMat" Arg = "mat"/>
    <Returns>A boolean matrix, or a positive integer.</Returns>
    <Description>
      These functions implement a bijection from the set of all boolean
      matrices of dimension <A>n</A> and the numbers
      <C>[1 .. 2 ^ (<A>n</A> ^ 2)]</C>.
      <P/>

      More precisely, if <A>m</A> and <A>n</A> are positive integers such that
      <A>m</A> is at most <C>2 ^ (<A>n</A> ^ 2)</C>, then
      <C>BooleanMatNumber</C> returns the <A>m</A>th <A>n</A> by <A>n</A>
      boolean matrix.
      <P/>

      If <A>mat</A> is an <A>n</A> by <A>n</A> boolean matrix, then
      <C>NumberBooleanMat</C> returns the number in
      <C>[1 .. 2 ^ (<A>n</A> ^ 2)]</C> that corresponds to <A>mat</A>.

      <Example><![CDATA[
gap> mat := BooleanMat([[0, 1, 1, 0],
>                       [1, 0, 1, 1],
>                       [1, 1, 0, 1],
>                       [0, 1, 0, 1]]);;
gap> NumberBooleanMat(mat);
27606
gap> Display(BooleanMatNumber(27606, 4));
0 1 1 0
1 0 1 1
1 1 0 1
0 1 0 1]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="NumberBlist">
  <ManSection>
    <Func Name = "BlistNumber" Arg = "m, n"/>
    <Func Name = "NumberBlist" Arg = "blist"/>
    <Returns>A boolean list, or a positive integer.</Returns>
    <Description>
      These functions implement a bijection from the set of all boolean
      lists of length <A>n</A> and the numbers <C>[1 .. 2 ^ <A>n</A>]</C>.
      <P/>

      More precisely, if <A>m</A> and <A>n</A> are positive integers such that
      <A>m</A> is at most <C>2 ^ <A>n</A></C>, then <C>BlistNumber</C>
      returns the <A>m</A>th boolean list of length <A>n</A>.
      <P/>

      If <A>blist</A> is a boolean list of length <A>n</A>, then
      <C>NumberBlist</C> returns the number in  <C>[1 .. 2 ^ <A>n</A>]</C>
      that corresponds to <A>blist</A>.

      <Example><![CDATA[
gap> blist := BlistList([1 .. 10], []);
[ false, false, false, false, false, false, false, false, false,
  false ]
gap> NumberBlist(blist);
1
gap> blist := BlistList([1 .. 10], [10]);
[ false, false, false, false, false, false, false, false, false, true
 ]
gap> NumberBlist(blist);
2
gap> BlistNumber(1, 10);
[ false, false, false, false, false, false, false, false, false,
  false ]
gap> BlistNumber(2, 10);
[ false, false, false, false, false, false, false, false, false, true
 ]]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="AsBooleanMat">
  <ManSection>
    <Oper Name = "AsBooleanMat" Arg = "x[, n]"/>
    <Returns>A boolean matrix.</Returns>
    <Description>
      <C>AsBooleanMat</C> returns the pbr, bipartition, permutation,
      transformation, or partial permutation <A>x</A>, as a boolean matrix of
      dimension <A>n</A>.
      <P/>

      There are several possible arguments for <C>AsBooleanMat</C>:
      <List>
        <Mark>permutations</Mark>
        <Item>
          If <A>x</A> is a permutation and <A>n</A> is a positive integer, then
          <C>AsBooleanMat(<A>x</A>, <A>n</A>)</C> returns the boolean matrix
          <C>mat</C> of dimension <A>n</A> such that <C>mat[i][j] = true</C> if
          and only if <C>j = i ^ x</C>. <P/>

          If no positive integer <A>n</A> is specified, then the largest moved
          point of <A>x</A> is used as the value for <A>n</A>; see <Ref
            Func="LargestMovedPoint" Label="for a permutation"
            BookName="ref"/>.
        </Item>

        <Mark>transformations</Mark>
        <Item>
          If <A>x</A> is a transformation and <A>n</A> is a positive integer
          such that <A>x</A> is a transformation of <C>[1 .. <A>n</A>]</C>, then
          <C>AsTransformation</C> returns the boolean matrix
          <C>mat</C> of dimension <A>n</A> such that <C>mat[i][j] = true</C> if
          and only if <C>j = i ^ x</C>. <P/>

          If the positive integer <A>n</A> is not specified, then the
          degree of <A>f</A> is used as the value for <A>n</A>.
        </Item>

        <Mark>partial permutations</Mark>
        <Item>
          If <A>x</A> is a partial permutation and <A>n</A> is a positive
          integer such that <C>i ^ <A>x</A> &lt;= n</C> for all <C>i</C> in
          <C>[1 .. <A>n</A>]</C>, then <C>AsBooleanMat</C> returns the boolean
          matrix <C>mat</C> of dimension <A>n</A> such that <C>mat[i][j] =
            true</C> if and only if <C>j = i ^ x</C>.
          <P/>

          If the optional argument <A>n</A> is not present, then the default
          value of the maximum of degree and the codegree of <A>x</A>
          is used.
        </Item>

        <Mark>bipartitions</Mark>
        <Item>
          If <A>x</A> is a bipartition and <A>n</A> is any non-negative
          integer, then <C>AsBooleanMat</C> returns the boolean matrix
          <C>mat</C> of dimension <A>n</A> such that <C>mat[i][j] = true</C> if
          and only if <C>i</C> and <C>j</C> belong to the same block of
          <A>x</A>.
          <P/>

          If the optional argument <A>n</A> is not present, then twice the
          degree of <A>x</A> is used by default.
        </Item>

        <Mark>pbrs</Mark>
        <Item>
          If <A>x</A> is a pbr and <A>n</A> is any non-negative
          integer, then <C>AsBooleanMat</C> returns the boolean matrix
          <C>mat</C> of dimension <A>n</A> such that <C>mat[i][j] = true</C> if
          and only if <C>i</C> and <C>j</C> are related in <A>x</A>.
          <P/>

          If the optional argument <A>n</A> is not present, then twice the
          degree of <A>x</A> is used by default.
        </Item>
      </List>

  <Example><![CDATA[
gap> Display(AsBooleanMat((1, 2), 5));
0 1 0 0 0
1 0 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
gap> Display(AsBooleanMat((1, 2)));
0 1
1 0
gap> x := Transformation([1, 3, 4, 1, 3]);;
gap> Display(AsBooleanMat(x));
1 0 0 0 0
0 0 1 0 0
0 0 0 1 0
1 0 0 0 0
0 0 1 0 0
gap> Display(AsBooleanMat(x, 4));
1 0 0 0
0 0 1 0
0 0 0 1
1 0 0 0
gap> x := PartialPerm([1, 2, 3, 6, 8, 10],
>                     [2, 6, 7, 9, 1, 5]);
[3,7][8,1,2,6,9][10,5]
gap> Display(AsBooleanMat(x));
0 1 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 0 0
gap> x := Bipartition([[1, 4, -2, -3], [2, 3, 5, -5], [-1, -4]]);
<bipartition: [ 1, 4, -2, -3 ], [ 2, 3, 5, -5 ], [ -1, -4 ]>
gap> y := AsBooleanMat(x);
<10x10 boolean matrix>
gap> Display(y);
1 0 0 1 0 0 1 1 0 0
0 1 1 0 1 0 0 0 0 1
0 1 1 0 1 0 0 0 0 1
1 0 0 1 0 0 1 1 0 0
0 1 1 0 1 0 0 0 0 1
0 0 0 0 0 1 0 0 1 0
1 0 0 1 0 0 1 1 0 0
1 0 0 1 0 0 1 1 0 0
0 0 0 0 0 1 0 0 1 0
0 1 1 0 1 0 0 0 0 1
gap> IsEquivalenceBooleanMat(y);
true
gap> AsBooleanMat(x, 1);
Matrix(IsBooleanMat, [[1]])
gap> Display(AsBooleanMat(x, 1));
1
gap> Display(AsBooleanMat(x, 2));
1 0
0 1
gap> Display(AsBooleanMat(x, 3));
1 0 0
0 1 1
0 1 1
gap> Display(AsBooleanMat(x, 11));
1 0 0 1 0 0 1 1 0 0 0
0 1 1 0 1 0 0 0 0 1 0
0 1 1 0 1 0 0 0 0 1 0
1 0 0 1 0 0 1 1 0 0 0
0 1 1 0 1 0 0 0 0 1 0
0 0 0 0 0 1 0 0 1 0 0
1 0 0 1 0 0 1 1 0 0 0
1 0 0 1 0 0 1 1 0 0 0
0 0 0 0 0 1 0 0 1 0 0
0 1 1 0 1 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0
gap> x := PBR(
> [[-1, 1], [2, 3], [-3, 2, 3]],
> [[-1, 1, 2], [-3, -1, 1, 3], [-3, -1, 1, 2, 3]]);;
gap> AsBooleanMat(x);
Matrix(IsBooleanMat, [[1, 0, 0, 1, 0, 0], [0, 1, 1, 0, 0, 0],
  [0, 1, 1, 0, 0, 1], [1, 1, 0, 1, 0, 0], [1, 0, 1, 1, 0, 1],
  [1, 1, 1, 1, 0, 1]])
gap> Display(AsBooleanMat(x));
1 0 0 1 0 0
0 1 1 0 0 0
0 1 1 0 0 1
1 1 0 1 0 0
1 0 1 1 0 1
1 1 1 1 0 1]]></Example>
  </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="CanonicalBooleanMat">
  <ManSection>
    <Oper Name = "CanonicalBooleanMat" Arg = "G, H, mat"
      Label = "for a perm group, perm group and boolean matrix"/>
    <Oper Name = "CanonicalBooleanMat" Arg = "G, mat"
      Label = "for a perm group and boolean matrix"/>
    <Attr Name = "CanonicalBooleanMat" Arg = "mat"/>
    <Returns>A boolean matrix.</Returns>
    <Description>
      This operation returns a fixed representative of the orbit of the boolean
      matrix <A>mat</A> under the action of the permutation group <A>G</A> on
      its rows and the permutation group <A>H</A> on its columns.
      <P/>

      In its second form, when only a single permutation group <A>G</A> is
      specified, <A>G</A> acts on the rows and columns of <A>mat</A> independently.
      <P/>

      In its third form, when only a boolean matrix is specified,
      <C>CanonicalBooleanMat</C> returns a fixed representative of the orbit of
      <A>mat</A> under the action of the symmetric group on its rows, and,
      independently, on its columns. In other words, <C>CanonicalBooleanMat</C>
      returns a canonical boolean matrix equivalent to <A>mat</A> up to
      rearranging rows and columns. This version of <C>CanonicalBooleanMat</C>
      uses &DIGRAPHS; and its interface with the &BLISS; library for computing
      automorphism groups and canonical forms of graphs <Cite
        Key="JunttilaKaski"/>. As a consequence, <C>CanonicalBooleanMat</C>
      with a single argument is significantly faster than the versions with 2
      or 3 arguments.

      <Example><![CDATA[
gap> mat := BooleanMat([[1, 1, 1, 0, 0, 0],
>                       [0, 0, 0, 1, 0, 1],
>                       [1, 0, 0, 1, 0, 1],
>                       [0, 0, 0, 0, 0, 0],
>                       [0, 1, 1, 1, 1, 1],
>                       [0, 1, 1, 0, 1, 0]]);
Matrix(IsBooleanMat, [[1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 0, 1],
  [1, 0, 0, 1, 0, 1], [0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1],
  [0, 1, 1, 0, 1, 0]])
gap> CanonicalBooleanMat(mat);
Matrix(IsBooleanMat, [[0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0],
  [0, 0, 1, 1, 1, 0], [1, 1, 0, 0, 1, 0], [0, 0, 1, 1, 0, 1],
  [1, 1, 1, 1, 0, 1]])
gap> Display(CanonicalBooleanMat(mat));
0 0 0 0 0 0
1 1 0 0 0 0
0 0 1 1 1 0
1 1 0 0 1 0
0 0 1 1 0 1
1 1 1 1 0 1
gap> Display(CanonicalBooleanMat(Group((1, 3)), mat));
0 1 1 0 0 1
0 0 1 0 0 1
1 1 0 1 0 0
0 0 0 0 0 0
1 0 1 1 1 1
1 0 0 1 1 0
gap> Display(CanonicalBooleanMat(Group((1, 3)), Group(()), mat));
1 1 1 0 0 0
0 0 0 1 0 1
0 1 0 1 0 1
0 0 0 0 0 0
1 0 1 1 1 1
1 0 1 0 1 0]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsSymmetricBooleanMat">
  <ManSection>
    <Prop Name = "IsSymmetricBooleanMat" Arg = "mat"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      A boolean matrix is <B>symmetric</B> if it is symmetric about the main
      diagonal, i.e. <C><A>mat</A>[i][j] = <A>mat</A>[j][i]</C> for all <C>i,
        j</C> in the range <C>[1 .. n]</C> where <C>n</C> is the dimension of
      <A>mat</A>.

  <Example><![CDATA[
gap> mat := BooleanMat([[0, 1, 1, 0],
>                       [1, 0, 1, 1],
>                       [1, 1, 0, 1],
>                       [0, 1, 0, 1]]);
Matrix(IsBooleanMat, [[0, 1, 1, 0], [1, 0, 1, 1], [1, 1, 0, 1],
  [0, 1, 0, 1]])
gap> IsSymmetricBooleanMat(mat);
false
gap> mat := BooleanMat([[0, 1, 1, 0],
>                       [1, 0, 1, 1],
>                       [1, 1, 0, 1],
>                       [0, 1, 1, 1]]);
Matrix(IsBooleanMat, [[0, 1, 1, 0], [1, 0, 1, 1], [1, 1, 0, 1],
  [0, 1, 1, 1]])
gap> IsSymmetricBooleanMat(mat);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsReflexiveBooleanMat">
  <ManSection>
    <Prop Name = "IsReflexiveBooleanMat" Arg = "mat"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      A boolean matrix is <B>reflexive</B> if every entry in the main diagonal
      is <K>true</K>, i.e. <C><A>mat</A>[i][i] = true</C> for all <C>i</C> in
      the range <C>[1 .. n]</C> where <C>n</C> is the dimension of
      <A>mat</A>.

  <Example><![CDATA[
gap> mat := BooleanMat([[1, 0, 0, 0],
>                       [1, 1, 0, 0],
>                       [0, 1, 0, 1],
>                       [1, 1, 1, 1]]);
Matrix(IsBooleanMat, [[1, 0, 0, 0], [1, 1, 0, 0], [0, 1, 0, 1],
  [1, 1, 1, 1]])
gap> IsReflexiveBooleanMat(mat);
false
gap> mat := BooleanMat([[1, 1, 1, 0],
>                       [1, 1, 1, 1],
>                       [1, 1, 1, 1],
>                       [0, 1, 1, 1]]);
Matrix(IsBooleanMat, [[1, 1, 1, 0], [1, 1, 1, 1], [1, 1, 1, 1],
  [0, 1, 1, 1]])
gap> IsReflexiveBooleanMat(mat);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsTransitiveBooleanMat">
  <ManSection>
    <Prop Name = "IsTransitiveBooleanMat" Arg = "mat"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      A boolean matrix is <B>transitive</B> if whenever
      <C><A>mat</A>[i][j] = true</C> and
      <C><A>mat</A>[j][k] = true</C> then
      <C><A>mat</A>[i][k] = true</C>.

      <Example><![CDATA[
gap> x := BooleanMat([[1, 0, 0, 1],
>                     [1, 0, 1, 1],
>                     [1, 1, 1, 0],
>                     [0, 1, 1, 0]]);
Matrix(IsBooleanMat, [[1, 0, 0, 1], [1, 0, 1, 1], [1, 1, 1, 0],
  [0, 1, 1, 0]])
gap> IsTransitiveBooleanMat(x);
false
gap> x := BooleanMat([[1, 1, 1, 1],
>                     [1, 1, 1, 1],
>                     [1, 1, 1, 1],
>                     [1, 1, 1, 1]]);
Matrix(IsBooleanMat, [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1],
  [1, 1, 1, 1]])
gap> IsTransitiveBooleanMat(x);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsAntiSymmetricBooleanMat">
  <ManSection>
    <Prop Name = "IsAntiSymmetricBooleanMat" Arg = "mat"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      A boolean matrix is <B>anti-symmetric</B> if whenever
      <C><A>mat</A>[i][j] = true</C> and
      <C><A>mat</A>[j][i] = true</C> then
      <C>i = j</C>.

      <Example><![CDATA[
gap> x := BooleanMat([[1, 0, 0, 1],
>                     [1, 0, 1, 1],
>                     [1, 1, 1, 0],
>                     [0, 1, 1, 0]]);
Matrix(IsBooleanMat, [[1, 0, 0, 1], [1, 0, 1, 1], [1, 1, 1, 0],
  [0, 1, 1, 0]])
gap> IsAntiSymmetricBooleanMat(x);
false
gap> x := BooleanMat([[1, 0, 0, 1],
>                     [1, 0, 1, 0],
>                     [1, 0, 1, 0],
>                     [0, 1, 1, 0]]);
Matrix(IsBooleanMat, [[1, 0, 0, 1], [1, 0, 1, 0], [1, 0, 1, 0],
  [0, 1, 1, 0]])
gap> IsAntiSymmetricBooleanMat(x);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsTotalBooleanMat">
  <ManSection>
    <Prop Name = "IsTotalBooleanMat" Arg = "mat"/>
    <Prop Name = "IsOntoBooleanMat" Arg = "mat"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      A boolean matrix is <B>total</B> if there is at least one entry in every
      row is <K>true</K>. Similarly, a boolean matrix is <B>onto</B> if at
      least one entry in every column is <K>true</K>.

      <Example><![CDATA[
gap> x := BooleanMat([[1, 0, 0, 1],
>                     [1, 0, 1, 1],
>                     [1, 1, 1, 0],
>                     [0, 1, 1, 0]]);
Matrix(IsBooleanMat, [[1, 0, 0, 1], [1, 0, 1, 1], [1, 1, 1, 0],
  [0, 1, 1, 0]])
gap> IsTotalBooleanMat(x);
true
gap> IsOntoBooleanMat(x);
true
gap> x := BooleanMat([[1, 0, 0, 1],
>                     [1, 0, 1, 0],
>                     [0, 0, 0, 0],
>                     [0, 1, 1, 0]]);
Matrix(IsBooleanMat, [[1, 0, 0, 1], [1, 0, 1, 0], [0, 0, 0, 0],
  [0, 1, 1, 0]])
gap> IsTotalBooleanMat(x);
false
gap> IsOntoBooleanMat(x);
true]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsPartialOrderBooleanMat">
  <ManSection>
    <Prop Name = "IsPartialOrderBooleanMat" Arg = "mat"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      A boolean matrix is a <B>partial order</B> if it is reflexive,
      transitive, and anti-symmetric.

      <Example><![CDATA[
gap> Number(FullBooleanMatMonoid(3), IsPartialOrderBooleanMat);
19]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsEquivalenceBooleanMat">
  <ManSection>
    <Prop Name = "IsEquivalenceBooleanMat" Arg = "mat"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      A boolean matrix is an <B>equivalence</B> if it is reflexive,
      transitive, and symmetric.

      <Example><![CDATA[
gap> Number(FullBooleanMatMonoid(3), IsEquivalenceBooleanMat);
5
gap> Bell(3);
5]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>

<#GAPDoc Label="IsTransformationBooleanMat">
  <ManSection>
    <Prop Name = "IsTransformationBooleanMat" Arg = "mat"/>
    <Returns><K>true</K> or <K>false</K>.</Returns>
    <Description>
      A boolean matrix is a <B>transformation</B> if every row contains
      precisely one <K>true</K> value.

      <Example><![CDATA[
gap> Number(FullBooleanMatMonoid(3), IsTransformationBooleanMat);
27]]></Example>
    </Description>
  </ManSection>
<#/GAPDoc>


