Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OnTuplesDigraphs and OnSetsDigraphs #449

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions doc/oper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,56 @@ gap> OutNeighbours(D2);
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="OnTuplesDigraphs">
<ManSection>
<Oper Name="OnTuplesDigraphs" Arg="list, perm"
Label="for a list of digraphs and a perm"/>
<Oper Name="OnSetsDigraphs" Arg="list, perm"
Label="for a set of digraphs and a perm"/>
<Returns>A list or set of digraphs.</Returns>
<Description>
If <A>list</A> is a list of digraphs, and <A>perm</A> is a
<E>permutation</E> of the vertices of the digraphs in <A>list</A>, then
<Ref Oper="OnTuplesDigraphs" Label="for a list of digraphs and a perm"/>
returns a new list constructed by applying <A>perm</A> via
<Ref Oper="OnDigraphs" Label="for a digraph and a perm"/>
to a copy (with the same mutability) of each entry of <A>list</A> in turn.
<P/>

More precisely, <C>OnTuplesDigraphs(<A>list</A>,<A>perm</A>)</C> is a list
of length <C>Length(<A>list</A>)</C>, whose <C>i</C>-th entry is
<C>OnDigraphs(DigraphCopy(<A>list</A>[i]), <A>perm</A>)</C>.
<P/>

If <A>list</A> is moreover a &GAP; set (i.e. a duplicate-free sorted list),
then <Ref Oper="OnSetsDigraphs" Label="for a set of digraphs and a perm"/>
returns the sorted output of
<Ref Oper="OnTuplesDigraphs" Label="for a list of digraphs and a perm"/>,
which is therefore again a set.
<Example><![CDATA[
gap> list := [CycleDigraph(IsMutableDigraph, 6),
> DigraphReverse(CycleDigraph(6))];
[ <mutable digraph with 6 vertices, 6 edges>,
<immutable digraph with 6 vertices, 6 edges> ]
gap> p := (1, 6)(2, 5)(3, 4);;
gap> result_tuples := OnTuplesDigraphs(list, p);
[ <mutable digraph with 6 vertices, 6 edges>,
<immutable digraph with 6 vertices, 6 edges> ]
gap> result_tuples[2] = OnDigraphs(list[2], p);
true
gap> result_tuples = list;
false
gap> result_tuples = Reversed(list);
true
gap> result_sets := OnSetsDigraphs(list, p);
[ <immutable digraph with 6 vertices, 6 edges>,
<mutable digraph with 6 vertices, 6 edges> ]
gap> result_sets = list;
true]]></Example>
</Description>
</ManSection>
<#/GAPDoc>

<#GAPDoc Label="DigraphAddVertex">
<ManSection>
<Oper Name="DigraphAddVertex" Arg="digraph[, label ]"/>
Expand Down
1 change: 1 addition & 0 deletions doc/z-chap6.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ from} $E_a$ \emph{to} $E_b$. In this case we say that $E_a$ and $E_b$ are
<Section><Heading>Acting on digraphs</Heading>
<#Include Label="OnDigraphs">
<#Include Label="OnMultiDigraphs">
<#Include Label="OnTuplesDigraphs">
</Section>

<Section Label="Isomorphisms and canonical labellings">
Expand Down
1 change: 1 addition & 0 deletions gap/digraph.gd
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ DeclareCategory("IsDigraphWithAdjacencyFunction", IsDigraph);
DeclareCategory("IsCayleyDigraph", IsDigraph);
DeclareCategory("IsImmutableDigraph", IsDigraph);
DeclareSynonym("IsMutableDigraph", IsDigraph and IsMutable);
DeclareCategoryCollections("IsDigraph");

DeclareAttribute("DigraphMutabilityFilter", IsDigraph);

Expand Down
2 changes: 2 additions & 0 deletions gap/oper.gd
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ DeclareOperation("DIGRAPHS_GraphProduct", [IsDigraph, IsDigraph, IsFunction]);
# 4. Actions . . .
DeclareOperation("OnDigraphs", [IsDigraph, IsPerm]);
DeclareOperation("OnDigraphs", [IsDigraph, IsTransformation]);
DeclareOperation("OnTuplesDigraphs", [IsDigraphCollection, IsPerm]);
DeclareOperation("OnSetsDigraphs", [IsDigraphCollection, IsPerm]);
DeclareOperation("OnMultiDigraphs", [IsDigraph, IsPermCollection]);
DeclareOperation("OnMultiDigraphs", [IsDigraph, IsPerm, IsPerm]);

Expand Down
15 changes: 15 additions & 0 deletions gap/oper.gi
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,21 @@ function(D, t)
return MakeImmutable(OnDigraphs(DigraphMutableCopy(D), t));
end);

InstallMethod(OnTuplesDigraphs,
"for list of digraphs and a perm",
[IsDigraphCollection and IsHomogeneousList, IsPerm],
{L, p} -> List(L, D -> OnDigraphs(DigraphMutableCopyIfMutable(D), p)));

InstallMethod(OnSetsDigraphs,
"for a list of digraphs and a perm",
[IsDigraphCollection and IsHomogeneousList, IsPerm],
function(S, p)
if not IsSet(S) then
ErrorNoReturn("the first argument must be a set (a strictly sorted list),");
fi;
return Set(S, D -> OnDigraphs(DigraphMutableCopyIfMutable(D), p));
end);

# Not revising the following because multi-digraphs are being withdrawn in the
# near future.

Expand Down
49 changes: 49 additions & 0 deletions tst/standard/oper.tst
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,55 @@ gap> gr := OnDigraphs(gr, t);
gap> OutNeighbours(gr);
[ [ 2 ], [ 1, 1 ], [ ] ]

# OnTuplesDigraphs: for a digraph and a permutation
gap> D := [ChainDigraph(3), CycleDigraph(4)];;
gap> List(D, OutNeighbours);
[ [ [ 2 ], [ 3 ], [ ] ], [ [ 2 ], [ 3 ], [ 4 ], [ 1 ] ] ]
gap> List(OnTuplesDigraphs(D, (1, 3)), OutNeighbours);
[ [ [ ], [ 1 ], [ 2 ] ], [ [ 4 ], [ 1 ], [ 2 ], [ 3 ] ] ]
gap> D := [ChainDigraph(3), DigraphReverse(ChainDigraph(3))];;
gap> List(D, OutNeighbours);
[ [ [ 2 ], [ 3 ], [ ] ], [ [ ], [ 1 ], [ 2 ] ] ]
gap> List(OnTuplesDigraphs(D, (1, 3)), OutNeighbours);
[ [ [ ], [ 1 ], [ 2 ] ], [ [ 2 ], [ 3 ], [ ] ] ]
gap> OnTuplesDigraphs(D, (1, 3)) = Permuted(D, (1, 2));
true
gap> D := EmptyDigraph(IsMutableDigraph, 3);;
gap> DigraphAddEdge(D, 1, 1);;
gap> out := OnTuplesDigraphs([D, D], (1, 2, 3));;
gap> List(out, DigraphEdges);
[ [ [ 2, 2 ] ], [ [ 2, 2 ] ] ]

# OnSetsDigraphs: for a digraph and a permutation
gap> D := [DigraphReverse(ChainDigraph(3)), ChainDigraph(3)];;
gap> IsSet(D);
false
gap> OnSetsDigraphs(D, (1, 2));
Error, the first argument must be a set (a strictly sorted list),
gap> D := Reversed(D);;
gap> OnSetsDigraphs(D, (1, 3)) = D;
true
gap> OnSetsDigraphs(D, (1, 3)) = OnTuplesDigraphs(D, (1, 3));
false
gap> MinimalGeneratingSet(Stabilizer(SymmetricGroup(3), D, OnSetsDigraphs));
[ (1,3) ]

# Set of orbital graphs of G := TransitiveGroup(6, 4)
# The stabiliser of this set is the normaliser of G in S_6
gap> x := Set(["&ECA@_OG", "&EQHcQHc", "&EHcQHcQ"], DigraphFromDigraph6String);
[ <immutable digraph with 6 vertices, 6 edges>,
<immutable digraph with 6 vertices, 12 edges>,
<immutable digraph with 6 vertices, 12 edges> ]
gap> Stabiliser(SymmetricGroup(6), x, OnSetsDigraphs)
> = Group([(1, 2, 3, 4, 5, 6), (1, 5)(2, 4)(3, 6)]);
true
gap> OnTuplesDigraphs(x, (2, 3)(5, 6)) = x;
false
gap> OnTuplesDigraphs(x, (2, 3)(5, 6)) = [x[1], x[3], x[2]];
true
gap> OnSetsDigraphs(x, (2, 3)(5, 6)) = x;
true

# OnMultiDigraphs: for a pair of permutations
gap> gr1 := CompleteDigraph(3);
<immutable complete digraph with 3 vertices>
Expand Down