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

Enhance some nilpotent and p-group attributes #442

Merged
merged 5 commits into from
Jan 18, 2016

Conversation

hungaborhorvath
Copy link
Contributor

This pull request enhances IsNilpotentGroup, IsPGroup, PrimePGroup:

- Added method for groups where the size can be computed. The method uses
  the fast IsPrimePowerInt, and needs no factorization of integers.
- Increased rank when the group is known to be a direct product.

- RedispathcOnCondition if group is not yet known to be a p-group.
- Added method if p-group has generators.
- For a p-group Set(Factors(Size(G)))[1]=Factors(Size(G))[1], thus no need
  to call for Set.

- Replaced Factors by first checking for IsPrimePowerInt, and then calling
  Factors.

The rank numbers are chosen so that these will be higher ranked than the currently highest method for permgroups in lib/grpperm.gi:1259. However, these ranks should be open to discussion.

I personally do not like the code for IsPGroup. First, it contains almost 100% the same code twice, one for the nilpotent groups and one for without. Currently it works like the following: if size is known, then it is checked to be a prime power. Otherwise, if the group is nilpotent, then the orders of the generators are checked to be all prime powers for the same prime. If neither the size, nor nilpotency is known, then IsAbelian check is forced and if successful, then used the same way as for the nilpotent case. Finally, a Size computation is forced. I am sure that this can be written much better by using the filters and RedispatchOnCondition, so the whole code would actually be readable. I did not write it that way in order to make reviewing easier, but I am happy to do it if people agree.

Finally, the cases where the group is a direct product are not handled well, because knowing that the group is a direct product is a low ranked filter. It would be nice to increase these ranks in a uniform manner, rather than setting them one by one for IsNilpotentGroup, IsPGroup, etc.

@fingolfin
Copy link
Member

You write:

I am sure that this can be written much better by using the filters and RedispatchOnCondition, so the whole code would actually be readable.

I actually think that code becomes less readable, and harder to understand, when RedispatchOnCondition, is used a lot. It makes behavior of code non-local, i.e. to really understand what goes on, one has to combine code which possible sits in completely different files.

So, not writing it that way actually does more than making reviewing easier; it also later on makes maintanance easier.

@@ -176,9 +176,13 @@ InstallMethod( IsPGroup,
if ord = infinity then
return false;
elif 1 < ord then
UniteSet( s, Factors( ord ) );
if 1 < Length( s ) then
if not IsPrimePowerInt( s ) then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you mean ord here instead of s (which is a list)?

Did you check your changes at all? I would recommend adding tests cass (in the form of a new .tst file, e.g. tst/testinstall/pgroups.tst, which exercises this code path. (You can temporarily insert a Print statement here to make sure you triggered the code path).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sorry. I made this typo at two places, and found only one before....

I will try to look at the structure of these tst files and add one for p-groups.

@hungaborhorvath
Copy link
Contributor Author

Added a test file for pgroups. I specifically checked (by hand) that all situations are triggered at least once, but I feel that the number of examples is rather limited. As this is my very first test file, any advice would be welcome.

Note that there is one particular code that I could not trigger. This is grp.gi:267. The reason is that I do not know how to give an example of a group in GAP so that GAP would not know its generators....

@fingolfin
Copy link
Member

Here is an example of a group without known generators:

gap> G:=CyclicGroup(IsFpGroup, 4); H:=CyclicGroup(2);
<fp group of size 4 on the generators [ a ]>
<pc group of size 2 with 1 generators>
gap> hom:=GroupHomomorphismByImages(G,H);
[ a ] -> [ f1 ]
gap> K:=Kernel(hom);
Group(<fp, no generators known>)
gap> # But GAP can compute some generators if we ask it to do so
gap> GeneratorsOfGroup(K);
[ a^-2 ]
gap> HasGeneratorsOfGroup(K);
true

@hungaborhorvath
Copy link
Contributor Author

The two methods are: one checks if the size is a p-power. The other checks if all the generators are of p-power order. The second works if we know the group is nilpotent.

The original algorithm did the following (in a very convoluted way): if we know the size, then it factors it. If we do not know the size but know that the group is nilpotent, then it checks for the orders of the generators. If we do not know any of these, then it checks if the group is Abelian and if yes, then goes for the generator method, if not, then computes the size and then follows from there.

I am happy to rewrite this, because I do not like it as it is. But I did not want to make too much of a change, so that is why I made it this way.

@hungaborhorvath
Copy link
Contributor Author

About the nilpotent test examples: those are for testing the new nilpotent code: if the order of the group is a prime power then it is nilpotent (as it is a p-group). Maybe such checks should rather go to another test file (say nilpotent.tst), but then a lot of other test cases should be added (for direct products, for permutation groups, etc), and I really did not want to do that....

@fingolfin
Copy link
Member

It's perfectly fine to keep this to just one test file -- and this test file could certainly also contain some computations with non-pgroups and non-nilpotent groups. Think of the tests focused on the specific functions, not on the class of objects they are dealing with. And of course a user may invoke IsPGroup on a group which is not a p-group, perhaps not even a nilpotent group (after all, they do not know the answer yet, and want GAP to find out for them). And of course we we want IsPGroup to return a correct answe in all of these cases.

Also note that is is also perfectly fine to add a test file that is (for the time being) "incomplete" (i.e. if you were to add a nilpotent.tst, I wouldn't expect you to test everything in it in one go. Actually, I am not even sure what would go into such a file, it probably would have to be split up anyway, as there are so may things related to nilpotent groups in GAP and that could be potentially be tested

But anyway, I am not asking you to add one, no worries :-).

BTW, in the future, I expect we will have many more test files; perhaps even one for each function / operation / atribute, with a filename reflecting the name of the function be tested.

@fingolfin
Copy link
Member

OK, if IsPGroupNilpotent is only called for nilpotent groups, then it is of course correct. Then perhaps rename it to IsPGroup_forNilpotent or so? (That's not strictly following our usual naming conventions, but since this is an internal function, not to be used by the user, I'd consider this a bonus, as it kind of warns the user not to use it. Come to think, perhaps IS_PGROUP_FOR_NILPOTENT would be even better, so that it does not show up in tab completion (then also IsPGroupSize could become IS_PGROUP_SIZE).

@hungaborhorvath
Copy link
Contributor Author

Ok, I have renamed the functions. I kept the size method to depend on the group rather than on the size, because it sets the PrimePGroup attribute, as well, and that belongs to the group.

I will add some more examples into the tst file, and then come back with it.

@fingolfin
Copy link
Member

This looks very good now. I'll wait for your new tests, and also for Travis to run those tests, but I am hopeful we can merge this today (or whenever you get around to do the extra work on the tests).

@hungaborhorvath
Copy link
Contributor Author

Ok, I added some more examples into the test. Computed some SylowSubgroups, as well, to check if they automatically get the IsPGroup property.

@hungaborhorvath
Copy link
Contributor Author

I have one more question. According to the manual (and also the code) IsPGroup returns false for all infinite groups. Could then maybe the IsPGroup filter contain the IsFinite filter? So if somebody wants to write a code checking for IsPGroup, then it would get the proper rank.

One example is Socle in lib/grppc.gi:2560. This has only filter 43, but IsFinite and IsPGroup would have filter 56, which would move it above IsFinite and IsSolvableGroup (having rank 48).

@fingolfin
Copy link
Member

Regarding IsPGroup and IsFinite: I see your point, but we should not do that in this PR. I suggest writing an email to the gap mailing list with that idea -- it seems logical to me, but maybe somebody else will spot an issue with it... But if it turns out ok, you could open a separate PR for it (or somebody else could).

@hungaborhorvath
Copy link
Contributor Author

@fingolfin Sure. Should I do anything else here?

@fingolfin
Copy link
Member

I think this is basically ready to be merged, thank you!

Though perhaps you'd be willing to run one last "interactive rebase": The typo fixes could be squashed suitably; "Add more examples into tst" could be squashed into "Add test file for p-groups"; and "Rename functions" into "Remove code duplication" (and perhaps more, your choice)

@hungaborhorvath
Copy link
Contributor Author

@fingolfin Ok, I will try to do it, and if I fail, then I will just let you know. :-)

@hungaborhorvath
Copy link
Contributor Author

Ok, I think I have managed to rebase the commits and squash them a bit. Force pushed (SW pun intended) them just now.

@fingolfin
Copy link
Member

Any reason you did not squash "Correct small typos" into "Enhance IsPGroup"?

@fingolfin fingolfin added the kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements label Jan 18, 2016
@fingolfin
Copy link
Member

Anyway, I think this is good to go. Great work! I'll wait a bit longer to see whether you want to do that last squash, but I'll just merge it soon (tomorrow at the latest)

Replaced Factors by first checking for IsPrimePowerInt, and then calling
Factors.
- RedispathcOnCondition if group is not yet known to be a p-group.
- Added method if p-group has generators.
- For a p-group Set(Factors(Size(G)))[1]=Factors(Size(G))[1], thus no need
  to call for Set.
- Added method for groups where the size can be computed. The method uses
the fast IsPrimePowerInt, and needs no factorization of integers.
- Increased rank when the group is known to be a direct product.
- Set IsPGroup during IsNilpotent check
@hungaborhorvath
Copy link
Contributor Author

No particular reason, apart from keeping the history of things, as it was commented in this PR. Anyway, I rebased it, force pushed it, checks are running now. Thank you.

fingolfin added a commit that referenced this pull request Jan 18, 2016
Enhance some nilpotent and p-group attributes
@fingolfin fingolfin merged commit a0eb0f1 into gap-system:master Jan 18, 2016
@fingolfin
Copy link
Member

Thanks a lot for your patience and hard work.

I'll try to get to your other PRs this week, too (of course if somebody else beats me to, I am also fine with that)

@hungaborhorvath hungaborhorvath deleted the NilpotentandPGroups branch January 18, 2016 18:02
@olexandr-konovalov olexandr-konovalov added the release notes: added PRs introducing changes that have since been mentioned in the release notes label Jan 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements release notes: added PRs introducing changes that have since been mentioned in the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants