From 5abe38dbc9cbbb966a5ab8d7e2b011ba0e6f782f Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Mon, 27 Jun 2022 14:50:34 +0200 Subject: [PATCH 1/2] fixed `IsTransitive` ... ... in the case that the group does not act on the given domain --- lib/oprt.gd | 18 +++++++++++++++++- lib/oprt.gi | 10 +++++++--- tst/testinstall/oprt.tst | 7 ++++++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/oprt.gd b/lib/oprt.gd index 36ce5dc148..048ba38ead 100644 --- a/lib/oprt.gd +++ b/lib/oprt.gd @@ -1814,7 +1814,8 @@ OrbitsishOperation( "Earns", OrbitsishReq, false, NewAttribute ); ##

## transitive ## We say that a group G acts transitively on a domain -## D if and only if for every pair of points d, e \in D +## D if and only if G acts on D and for every pair of +## points d, e \in D ## there is an element g in G such that d^g = e. ##

## For a permutation group G, one may also invoke this as @@ -1823,6 +1824,21 @@ OrbitsishOperation( "Earns", OrbitsishReq, false, NewAttribute ); ## moved by it. ## For example the group \langle (2,3,4),(2,3) \rangle ## is transitive on the set \{2, 3, 4\}. +## G:= Group( (2,3,4), (2,3) );; +## gap> IsTransitive( G, [ 2 .. 4 ] ); +## true +## gap> IsTransitive( G, [ 2, 3 ] ); # G does not act on [ 2, 3 ] +## false +## gap> IsTransitive( G, [ 1 .. 4 ] ); # G has two orbits on [ 1 .. 4 ] +## false +## gap> IsTransitive( G ); # G is transitive on [ 2 .. 4 ] +## true +## gap> IsTransitive( SL(2, 3), NormedRowVectors( GF(3)^2 ) ); +## false +## gap> IsTransitive( SL(2, 3), NormedRowVectors( GF(3)^2 ), OnLines ); +## true +## ]]> ## ## ## <#/GAPDoc> diff --git a/lib/oprt.gi b/lib/oprt.gi index 0eb042e7d0..62b3d0c705 100644 --- a/lib/oprt.gi +++ b/lib/oprt.gi @@ -2663,12 +2663,16 @@ end); ## #F IsTransitive( , , , , ) . . . . transitivity test ## +## We cannot assume that acts on . +## Thus it is in general not sufficient to check whether is a subset of +## the -orbit of a point in , or whether and this orbit have the +## same size. +## InstallMethod( IsTransitive, "compare with orbit of element", - true, - OrbitsishReq, 0, + OrbitsishReq, function( G, D, gens, acts, act ) - return Length(D)=0 or IsSubset( OrbitOp( G, D[ 1 ], gens, acts, act ), D ); + return Length(D)=0 or IsEqualSet( OrbitOp( G, D[1], gens, acts, act ), D ); end ); diff --git a/tst/testinstall/oprt.tst b/tst/testinstall/oprt.tst index 9931c061fd..c952d4ffdd 100644 --- a/tst/testinstall/oprt.tst +++ b/tst/testinstall/oprt.tst @@ -38,4 +38,9 @@ gap> IsTransitive(eo); true gap> Blocks(eo); [ [ 1, 5, 9 ], [ 2, 6, 10 ], [ 3, 7, 11 ], [ 4, 8, 12 ] ] -gap> STOP_TEST( "oprt.tst", 1); +gap> G:= Group( (2,3,4), (2,3) );; +gap> IsTransitive( G, [ 2, 3 ] ); +false +gap> Transitivity( G, [ 2, 3 ] ); +0 +gap> STOP_TEST( "oprt.tst" ); From c97041326403e0467dc255e13256f6bbe3e49429 Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Thu, 30 Jun 2022 13:18:47 +0200 Subject: [PATCH 2/2] changed the documentation ... ... in order to state explicitly that the result of several operations is undefined if the arguments do not define a (transitive) group action (I have also added some tests that document certain situations where one does not get an immediate error message but invalid objects are returned, which then lead to error messages later on. The idea is that it might be necessary to adjust the documentation as soon as some of these tests fail due to code improvements.) --- doc/ref/grpoper.xml | 6 +++ lib/oprt.gd | 45 ++++++++++++++++----- tst/testinstall/action.tst | 83 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+), 11 deletions(-) create mode 100644 tst/testinstall/action.tst diff --git a/doc/ref/grpoper.xml b/doc/ref/grpoper.xml index bc459eb665..530e6e0b25 100644 --- a/doc/ref/grpoper.xml +++ b/doc/ref/grpoper.xml @@ -345,6 +345,12 @@ A block system (system of imprimitivity) for the action of a group is a partition of \Omega which –as a partition– remains invariant under the action of G. +For operations concerning block systems, &GAP; assumes that G acts +transitively on \Omega +(see ). +One may get wrong results or error messages (perhaps at a much later stage) +if this condition is not satisfied. + <#Include Label="Blocks"> <#Include Label="MaximalBlocks"> <#Include Label="RepresentativesMinimalBlocks"> diff --git a/lib/oprt.gd b/lib/oprt.gd index 048ba38ead..621d848d41 100644 --- a/lib/oprt.gd +++ b/lib/oprt.gd @@ -897,6 +897,8 @@ end ); ## permutation equivalence, that is the permutation image of a group element ## is given by the positions of points in Omega.) ##

+## The result is undefined if G does not act on Omega. +##

## By default the homomorphism returned by ## ## is not necessarily surjective (its @@ -1213,6 +1215,8 @@ DeclareGlobalFunction( "Action" ); ## described in and , or (to use ## less memory but with a slower performance) an enumerator ## (see ) of this domain. +##

+## The result is undefined if G does not act on Omega. ## g:=Group((1,2,3),(2,3,4));; ## gap> e:=ExternalSet(g,[1..4]); @@ -1252,15 +1256,17 @@ DeclareOperation("RestrictedExternalSet",[IsExternalSet,IsGroup]); ############################################################################# ## -#O ExternalSubset(,,,[,,]) +#O ExternalSubset(,,,[,,]) ## ## <#GAPDoc Label="ExternalSubset"> ## -## +## ## ## -## constructs the external subset of xset on the union of orbits of the -## points in start. +## constructs the external subset of Omega on the union of orbits of +## the points in start. +##

+## The result is undefined if G does not act on Omega. ## ## ## <#/GAPDoc> @@ -1283,6 +1289,8 @@ OrbitishFO( "ExternalSubset", ## ## constructs the external subset on the orbit of pnt. The ## value of this external set is pnt. +##

+## The result is undefined if G does not act on Omega. ## e:=ExternalOrbit(g,g,(1,2,3)); ## (1,2,3)^G @@ -1663,12 +1671,15 @@ OrbitsishOperation( "Transitivity", OrbitsishReq, false, NewAttribute ); ## Label="for an external set"/> ## ## -## computes a block system for the action. +## computes a block system for the transitive (see +## ) +## action of G on Omega. ## If seed is not given and the action is imprimitive, ## a minimal nontrivial block system will be found. ## If seed is given, a block system in which seed ## is the subset of one block is computed. -## The action must be transitive. +##

+## The result is undefined if the action is not transitive. ## g:=TransitiveGroup(8,3); ## E(8)=2[x]2[x]2 @@ -1708,9 +1719,13 @@ OrbitishFO( "Blocks", ## ## ## returns a block system that is maximal (i.e., blocks are maximal with -## respect to inclusion) for the action of G on Omega. +## respect to inclusion) for the transitive (see +## ) +## action of G on Omega. ## If seed is given, a block system is computed in which seed ## is a subset of one block. +##

+## The result is undefined if the action is not transitive. ## MaximalBlocks(g,[1..8]); ## [ [ 1, 2, 3, 8 ], [ 4 .. 7 ] ] @@ -1748,7 +1763,11 @@ OrbitishFO( "MaximalBlocks", ## ## computes a list of block representatives for all minimal (i.e blocks are ## minimal with respect to inclusion) nontrivial block systems for the -## action. +## transitive (see +## ) +## action of G on Omega. +##

+## The result is undefined if the action is not transitive. ## RepresentativesMinimalBlocks(g,[1..8]); ## [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 1, 5 ], [ 1, 6 ], [ 1, 7 ], @@ -1867,7 +1886,9 @@ OrbitsishOperation( "IsTransitive", OrbitsishReq, false, NewProperty ); ## or false otherwise. ##

## primitive -## An action is primitive if it is transitive and the action admits +## An action is primitive if it is transitive (see +## ) +## and the action admits ## no nontrivial block systems. See  for ## the definition of block systems. ##

@@ -2013,8 +2034,10 @@ OrbitsishOperation( "IsRegular", OrbitsishReq, false, NewProperty ); ## Label="for an external set"/> ## ## -## returns the rank of a transitive action, i.e. the number of orbits of -## the point stabilizer. +## returns the rank of the transitive (see +## ) +## action of G on Omega, i. e., the number of orbits of +## any point stabilizer. ## RankAction(g,Combinations([1..4],2),OnSets); ## 4 diff --git a/tst/testinstall/action.tst b/tst/testinstall/action.tst new file mode 100644 index 0000000000..a834415587 --- /dev/null +++ b/tst/testinstall/action.tst @@ -0,0 +1,83 @@ +gap> START_TEST( "action.tst" ); + +# The following session documents what happens currently +# if one specifies "group actions" that are in fact not actions. +# (When some of these tests fail then parts of the documentation +# may have to be changed.) + +# Define an intransitive group. +gap> G:= Group( (1,2), (3,4,5) );; + +# +gap> RankAction( G ); # error, good +Error, RankAction: action must be transitive +gap> RankAction( G, [ 2 .. 5 ] ); # error, good +Error, RankAction: action must be transitive +gap> RankAction( G, [ 1 .. 6 ] ); # error, good +Error, RankAction: action must be transitive +gap> RankAction( G, [ 1 .. 5 ] ); # error, good +Error, RankAction: action must be transitive +gap> RankAction( G, [ 2 .. 6 ] ); # error, good +Error, RankAction: action must be transitive + +# +gap> Blocks( G, [ 2 .. 5 ] ); # error, good +Error, must operate transitively on +gap> Blocks( G, [ 1 .. 6 ] ); # error, good +Error, must operate transitively on +gap> Blocks( G, [ 1 .. 5 ] );; # works although not transitive +gap> bl:= Blocks( G, [ 2 .. 6 ] );; # works although no action +gap> Action( G, bl, OnSets ); # error, good (but late) +Error, List Element: [1] must have an assigned value + +# +gap> MaximalBlocks( G, [ 2 .. 5 ] ); # error, good +Error, must operate transitively on +gap> MaximalBlocks( G, [ 1 .. 6 ] ); # error, good +Error, must operate transitively on +gap> MaximalBlocks( G, [ 1 .. 5 ] );; # works although not transitive +gap> bl:= MaximalBlocks( G, [ 2 .. 6 ] );; # works although no action +gap> Action( G, bl, OnSets ); # error, good (but late) +Error, List Element: [1] must have an assigned value + +# +gap> bl:= RepresentativesMinimalBlocks( G, [ 2 .. 5 ] ); # error, good +Error, must act transitively on +gap> bl:= RepresentativesMinimalBlocks( G, [ 1 .. 6 ] ); # error, good +Error, must act transitively on +gap> RepresentativesMinimalBlocks( G, [ 1 .. 5 ] );; # works although not transitive +gap> bl:= RepresentativesMinimalBlocks( G, [ 2 .. 6 ] );; # works although no action +gap> Action( G, bl, OnSets ); +Error, List Element: [1] must have an assigned value + +# +gap> xset:= ExternalSet( G, [ 2 .. 5 ] );; # works although no action +gap> Elements( xset );; # works +gap> Action( xset );; # error, good (but late) +Error, no method found! For debugging hints type ?Recovery from NoMethodFound +Error, no 1st choice method found for `GroupByGenerators' on 2 arguments + +# +gap> xset:= ExternalOrbit( G, [ 2 .. 5 ], 2 );; # works although no action +gap> Elements( xset ); # error, good (but late) +Error, no method found! For debugging hints type ?Recovery from NoMethodFound +Error, no 1st choice method found for `[]' on 2 arguments +The 2nd argument is 'fail' which might point to an earlier problem + + +# +gap> xset:= ExternalSubset( G, [ 2 .. 5 ], [ 2 ] );; # works (although no action) +gap> Elements( xset );; # error, good (but late) +Error, no method found! For debugging hints type ?Recovery from NoMethodFound +Error, no 1st choice method found for `[]' on 2 arguments +The 2nd argument is 'fail' which might point to an earlier problem + + +# +gap> hom:= ActionHomomorphism( G, [ 2 .. 5 ] );; # works (although no action) +gap> Image( hom ); # error, good (but late) +Error, no method found! For debugging hints type ?Recovery from NoMethodFound +Error, no 1st choice method found for `GroupByGenerators' on 2 arguments + +# +gap> STOP_TEST( "action.tst" );