From f2ff8b21e23b3c5080a5b6f4e717d369ed44972a Mon Sep 17 00:00:00 2001 From: Wilf Wilson Date: Fri, 26 Mar 2021 11:09:12 +0000 Subject: [PATCH] Add `OnTuplesDigraphs` and `OnSetsDigraphs` --- doc/oper.xml | 50 +++++++++++++++++++++++++++++++++++++++++++ doc/z-chap6.xml | 1 + gap/digraph.gd | 1 + gap/oper.gd | 2 ++ gap/oper.gi | 15 +++++++++++++ tst/standard/oper.tst | 49 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+) diff --git a/doc/oper.xml b/doc/oper.xml index 54d8d0ed7..324951db2 100644 --- a/doc/oper.xml +++ b/doc/oper.xml @@ -257,6 +257,56 @@ gap> OutNeighbours(D2); <#/GAPDoc> +<#GAPDoc Label="OnTuplesDigraphs"> + + + + A list or set of digraphs. + + If list is a list of digraphs, and perm is a + permutation of the vertices of the digraphs in list, then + + returns a new list constructed by applying perm via + + to a copy (with the same mutability) of each entry of list in turn. +

+ + More precisely, OnTuplesDigraphs(list,perm) is a list + of length Length(list), whose i-th entry is + OnDigraphs(DigraphCopy(list[i]), perm). +

+ + If list is moreover a &GAP; set (i.e. a duplicate-free sorted list), + then + returns the sorted output of + , + which is therefore again a set. + list := [CycleDigraph(IsMutableDigraph, 6), +> DigraphReverse(CycleDigraph(6))]; +[ , + ] +gap> p := (1, 6)(2, 5)(3, 4);; +gap> result_tuples := OnTuplesDigraphs(list, p); +[ , + ] +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); +[ , + ] +gap> result_sets = list; +true]]> + + +<#/GAPDoc> + <#GAPDoc Label="DigraphAddVertex"> diff --git a/doc/z-chap6.xml b/doc/z-chap6.xml index c4aaad204..d9b2369d8 100644 --- a/doc/z-chap6.xml +++ b/doc/z-chap6.xml @@ -11,6 +11,7 @@ from} $E_a$ \emph{to} $E_b$. In this case we say that $E_a$ and $E_b$ are

Acting on digraphs <#Include Label="OnDigraphs"> <#Include Label="OnMultiDigraphs"> + <#Include Label="OnTuplesDigraphs">
diff --git a/gap/digraph.gd b/gap/digraph.gd index 8c3924bc6..d93389b46 100644 --- a/gap/digraph.gd +++ b/gap/digraph.gd @@ -14,6 +14,7 @@ DeclareCategory("IsDigraphWithAdjacencyFunction", IsDigraph); DeclareCategory("IsCayleyDigraph", IsDigraph); DeclareCategory("IsImmutableDigraph", IsDigraph); DeclareSynonym("IsMutableDigraph", IsDigraph and IsMutable); +DeclareCategoryCollections("IsDigraph"); DeclareAttribute("DigraphMutabilityFilter", IsDigraph); diff --git a/gap/oper.gd b/gap/oper.gd index e8fa1f176..45c48ea3c 100644 --- a/gap/oper.gd +++ b/gap/oper.gd @@ -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]); diff --git a/gap/oper.gi b/gap/oper.gi index 4d7e7057c..a8f3f65d9 100644 --- a/gap/oper.gi +++ b/gap/oper.gi @@ -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. diff --git a/tst/standard/oper.tst b/tst/standard/oper.tst index e5549a3e2..4c4aedf0a 100644 --- a/tst/standard/oper.tst +++ b/tst/standard/oper.tst @@ -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); +[ , + , + ] +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);