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

Fix sparse pperm #2305

Merged
merged 9 commits into from
Apr 6, 2018
Merged

Conversation

james-d-mitchell
Copy link
Contributor

@james-d-mitchell james-d-mitchell commented Mar 26, 2018

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.

@codecov
Copy link

codecov bot commented Mar 26, 2018

Codecov Report

Merging #2305 into master will increase coverage by 0.24%.
The diff coverage is 99.54%.

@@            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
Impacted Files Coverage Δ
lib/pperm.gd 0% <0%> (ø) ⬆️
lib/pperm.gi 100% <100%> (+31.64%) ⬆️
src/pperm.c 97.89% <100%> (+11.87%) ⬆️
src/exprs.c 93.6% <0%> (+0.17%) ⬆️

@ChrisJefferson
Copy link
Contributor

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?

@james-d-mitchell
Copy link
Contributor Author

@ChrisJefferson good idea, I'll adjust this PR for the sake of simplicity.

@fingolfin
Copy link
Member

@james-d-mitchell do you still plan to make that adjustment? Or should we merge this, and you'll submit another PR later?

@james-d-mitchell
Copy link
Contributor Author

I am making an adjustment, but it will take a little while.

@fingolfin
Copy link
Member

Great, thanks!

@james-d-mitchell james-d-mitchell force-pushed the fix-sparse-pperm branch 2 times, most recently from 354cb5d to 71f5735 Compare March 29, 2018 19:20
Copy link
Member

@fingolfin fingolfin left a 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 withFixes #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
Copy link
Member

@fingolfin fingolfin Mar 29, 2018

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);
Copy link
Member

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);

Copy link
Contributor Author

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);
Copy link
Member

Choose a reason for hiding this comment

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

Oops, good catch!

Copy link
Contributor Author

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
Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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));
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

James Mitchell added 5 commits April 2, 2018 17:51
@james-d-mitchell
Copy link
Contributor Author

@fingolfin I think I have fixed all the things you requested @fingolfin.

@fingolfin
Copy link
Member

Tests fail in 32bit builds

@james-d-mitchell
Copy link
Contributor Author

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)
Copy link
Member

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 ;-).

Copy link
Member

@fingolfin fingolfin left a 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
Copy link
Member

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"?

Copy link
Contributor Author

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.
Copy link
Member

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?

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, 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.

Copy link
Contributor Author

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));
Copy link
Member

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)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll update this.

Copy link
Contributor Author

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
Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok.

@james-d-mitchell
Copy link
Contributor Author

I've updated this according to your comments @fingolfin and the 32-bit tests should also be fixed by these changes.

@james-d-mitchell
Copy link
Contributor Author

james-d-mitchell commented Apr 5, 2018

Any reason not to merge this? @fingolfin @ChrisJefferson

@fingolfin
Copy link
Member

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.

@james-d-mitchell
Copy link
Contributor Author

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...

@james-d-mitchell
Copy link
Contributor Author

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
@fingolfin fingolfin merged commit dd60f28 into gap-system:master Apr 6, 2018
@fingolfin fingolfin mentioned this pull request Apr 22, 2018
@fingolfin fingolfin added kind: bug Issues describing general bugs, and PRs fixing them kind: bug: crash Issues describing bugs that cause GAP to crash, and PRs fixing them (used for release notes) labels May 2, 2018
@fingolfin fingolfin added the release notes: added PRs introducing changes that have since been mentioned in the release notes label Jul 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: bug: crash Issues describing bugs that cause GAP to crash, and PRs fixing them (used for release notes) kind: bug Issues describing general bugs, and PRs fixing them 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.

3 participants