-
Notifications
You must be signed in to change notification settings - Fork 160
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
Fix sparse pperm #2305
Fix sparse pperm #2305
Conversation
230e236
to
7827d86
Compare
Codecov Report
@@ Coverage Diff @@
## master #2305 +/- ##
==========================================
+ Coverage 72.83% 73.07% +0.24%
==========================================
Files 480 480
Lines 246475 246622 +147
==========================================
+ Hits 179508 180213 +705
+ Misses 66967 66409 -558
|
While we are here (this could go into a different PR), PartialPerm([1,2],[2^100,2^1000]) also doesn't work, do you also need to check for IsSmallIntRep? |
@ChrisJefferson good idea, I'll adjust this PR for the sake of simplicity. |
@james-d-mitchell do you still plan to make that adjustment? Or should we merge this, and you'll submit another PR later? |
I am making an adjustment, but it will take a little while. |
Great, thanks! |
354cb5d
to
71f5735
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job, thanks!
Only thing I am not happy with is the commit message of the first commit: "Resolve issue #2301isn't a great commit title, because it require out-of-band information to be intelligible. better would be e.g. "Fix crash in PartialPerm if length of img and domain differ" -- possibly with
Fixes #2301` in the body of the commit message.
Other than that, just some minor remarks, which you can address optionally.
lib/pperm.gi
Outdated
@@ -225,7 +226,8 @@ InstallMethod(AsPartialPerm, "for a transformation and list", | |||
[IsTransformation, IsList], | |||
function(f, list) | |||
|
|||
if not IsSSortedList(list) or not ForAll(list, IsPosInt) then | |||
if not IsSSortedList(list) | |||
or not ForAll(list, x -> IsSmallIntRep(x) and IsPosInt(x)) then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Off-topic: you can actually write ForAll(list, IsSmallIntRep and IsPosInt);
(whether that's a good idea or not is probably a matter of taste; in any case, I am not saying you should change this, just pointing it out ;-)
src/pperm.c
Outdated
SET_CODEG_PPERM2(join, dej); | ||
|
||
if (def > deg) { | ||
return FuncJOIN_IDEM_PPERMS(self, g, f); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice way to simplify the following code a lot! As a minor tweak, you could also do this:
SWAP(Obj, f, g);
SWAP(UInt, def, deg);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I didn't know about SWAP
, I've updated the PR to use this instead.
@@ -2539,7 +2471,7 @@ Obj FuncShortLexLeqPartialPerm(Obj self, Obj f, Obj g) | |||
if (DEG_PPERM4(g) == 0) | |||
return False; | |||
rankg = RANK_PPERM4(g); | |||
domg = DOM_PPERM(f); | |||
domg = DOM_PPERM(g); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, good catch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't get the code to enter one case, which lead me to spot this 👍
src/pperm.c
Outdated
else { /* this case cannot occur since I think POW is not defined | ||
*/ | ||
else { | ||
// This case cannot occur since POW is not defined |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this comment. Best I can come up with is that POW
is a macro, and clearly defined as such... so clearly you mean something else, but what?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an old comment, and I do not know what I meant either, my memory is that I couldn't get the code to enter this case. I will update this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I remember what this means now, after putting the analogous code from permutat.c
in here instead of the error. I have updated the comment.
src/pperm.c
Outdated
@@ -6465,7 +6355,8 @@ Obj FuncOnPosIntSetsPartialPerm(Obj self, Obj set, Obj f) | |||
} | |||
|
|||
PLAIN_LIST(set); | |||
res = NEW_PLIST_WITH_MUTABILITY(IS_MUTABLE_PLIST(set), T_PLIST_CYC_SSORT, LEN_LIST(set)); | |||
res = NEW_PLIST_WITH_MUTABILITY(IS_MUTABLE_PLIST(set), T_PLIST_CYC_SSORT, | |||
LEN_LIST(set)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't really matter, but you could use LEN_PLIST
here, since we just converted set
to a plist in the line before.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
71f5735
to
e0ba3cd
Compare
This also makes the test much faster.
This change is necessary since none of the kernel methods work for non-small int rep integers.
e0ba3cd
to
431881c
Compare
@fingolfin I think I have fixed all the things you requested @fingolfin. |
Tests fail in 32bit builds |
Yup, I’ll fix it in the morning |
src/pperm.c
Outdated
@@ -341,7 +336,7 @@ static Obj PreImagePPermInt(Obj pt, Obj f) | |||
* GAP functions for partial perms | |||
*****************************************************************************/ | |||
|
|||
|
|||
// FIXME why is this a function??? | |||
Obj FuncEmptyPartialPerm(Obj self) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alas, whether there is a good justification or not, this function is documented in the GAP reference manual, so we cannot just remove it. Of course it is also documented as a "short hand for PartialPerm([]);." So one could replace this C function by a GAP function. And then, if you felt strongly about it, also mark it as obsolete.
Not sure that new C comment is going to help anybody, though ;-).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am happy with the first commit now, and only have some quibbles about a new comment -- but we can also resolve those post merge shrug.
src/pperm.c
Outdated
// permutat.c uses the macro POW, which calls PowIntPerm2/4, | ||
// which if called with a non-small positive integer returns | ||
// that integer, since every permutation fixes every positive | ||
// integer (small or not). The methods for PowIntPPerm2/4 give |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh? So (1,2) fixes 1 ?!? Or perhaps you really mean "since every permutation fixes every large positive integer"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, will fix.
src/pperm.c
Outdated
// that integer, since every permutation fixes every positive | ||
// integer (small or not). The methods for PowIntPPerm2/4 give | ||
// an error if the argument is a non-small integer, and so we | ||
// cannot call POW here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, why does it do that? Why not also have a method for (positive) bigint+pperm which returns the bigint unchanged, mirroring the permutation code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we could do that, but for now this is not implemented, and so I opted to fix the comment and make the error message more meaningful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also just to point out that partial perms unlike permutations do not fix all points where they are not defined, they are simply undefined on those points, so PowIntPPerm2/4
should return 0
in those cases.
src/pperm.c
Outdated
// cannot call POW here. | ||
ErrorQuit("the first argument (a set) must consist of " | ||
"integers less than 2 ^ %d but contains %s", | ||
NR_SMALL_INT_BITS, (Int)TNAM_OBJ(*ptset)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The standard way in the kernel to phrase such an error would be this: ErrorQuit("<set> must be a list of small integers", 0,0);
. This uses that this kernel function is called for OnSets
, which is documented as OnSets( set, g )
.
But of course the OnSets
function for permutation does not contain such a message -- because it relies on POW
producing an error, if needed. And that in turn makes it possible for the user resp. packages to install custom methods for \^
-- which then in turn would automatically be useable via OnSets
.
I am not saying that's necessarily a good idea, but it's a possibility there. We could of course make it stricter, but then it would be kinda nice if the pperm and perm code would behave similarly for this.
(That said, I'd accept either approach in this PR, we can work on unification in another PR)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll update this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree it would be better if the pperm code worked in more or less the same way as the permutat code, but didn't want to make further changes in this PR.
src/pperm.c
Outdated
ErrorQuit("not yet implemented!", 0L, 0L); | ||
else { | ||
// This case does not work since PowIntPPerm2/4 only work for | ||
// INTOBJ's (i.e. small integers). The analogous code in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We call them "small integers" or sometimes "immediate integers" elsewhere, and I'd stick to that terminology here, w/o brining it up again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok.
Also: add some further comments, and reformat.
431881c
to
37aee87
Compare
I've updated this according to your comments @fingolfin and the 32-bit tests should also be fixed by these changes. |
Any reason not to merge this? @fingolfin @ChrisJefferson |
Two reasons why @ChrisJefferson and me don't merge: we are both on vacation; and new changes keep being added to this PR, instead of new PRs, i.e. you added changes right after asking why this isn't being merged... So I won't merge this from here, as I can't review the new changes sensibly from here. But of course somebody else who is not on vacation or strike or busy with other things could step up. Otherwise, I'll get to it next week. In the meantime, people shall feel free to review and merge all my open PRs, some of which have been open and waiting for weeks or even months. |
Thanks @fingolfin, and apologies for disturbing your vacation, I didn't know. I added two commits today, but otherwise this is unchanged from when you previously approved it. I'm not sure I have the expertise to review all your open PR's... |
330af54
to
0dbcf48
Compare
I'll amend the second to last commit to avoid OOB access, and drop the last commit altogether since it's not really related. |
This occasionally caused incorrect values to be returned when i == deg and by coincidence ptf2[i] == cpt. When ptf2[deg] is beyond the end of the bag containing f, and so is not valid. For reference, this bug caused errors in: semigroups/Semigroups#296 semigroups/Semigroups#472
0dbcf48
to
aedc32e
Compare
This PR resolves Issue #2301 by checking that the arguments to
PartialPerm
are of equal length, if there are more than two of them.And increases the code coverage of the tests to ~97%, removes unnecessary randomness from the test file, fixes some bugs in the c, and GAP code, and reformats the GAP code.