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

Implement CycleFromList, and fix potential crash in CYCLE_TRANS_INT #2242

Merged
merged 2 commits into from
Mar 20, 2018

Conversation

markusbaumeister
Copy link
Contributor

Add a convenient functionality to generate a cycle from a list of
positive integers.

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 agree that something like this is useful to have in general.

I wonder if instead of just supporting creating cycles, it would be possible / useful to have something which takes a list-of-lists (representing disjoint cycles), and turns those into a permutation. (a simple implementation would just call your function here on each cycle, and then multiply the result together, though of course that would not detect overlaps; which might be considered either a bug or feature ;-)

@codecov
Copy link

codecov bot commented Mar 5, 2018

Codecov Report

Merging #2242 into master will increase coverage by 0.45%.
The diff coverage is 90%.

@@            Coverage Diff             @@
##           master    #2242      +/-   ##
==========================================
+ Coverage   69.88%   70.34%   +0.45%     
==========================================
  Files         481      481              
  Lines      252990   253198     +208     
==========================================
+ Hits       176813   178117    +1304     
+ Misses      76177    75081    -1096
Impacted Files Coverage Δ
src/trans.c 98.71% <100%> (ø) ⬆️
lib/permutat.g 79.54% <88.88%> (+1.47%) ⬆️
lib/csetperm.gi 87.65% <0%> (-3.71%) ⬇️
lib/global.gi 40.14% <0%> (-1.7%) ⬇️
lib/ghompcgs.gi 88.18% <0%> (-1.58%) ⬇️
lib/ghom.gi 72.83% <0%> (-0.82%) ⬇️
lib/grppcint.gi 98.64% <0%> (-0.68%) ⬇️
lib/gpfpiso.gi 60.17% <0%> (-0.39%) ⬇️
lib/stbcrand.gi 90.26% <0%> (-0.2%) ⬇️
lib/gpprmsya.gi 65.25% <0%> (-0.18%) ⬇️
... and 29 more

lib/permutat.g Outdated
fi;

set := Set(list);
if not IsDenseList(list) then
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think you need this check, as the next check will fail if the list is not sense (as the set will be smaller).

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, maybe check Minimum is > 0

## return the <M>n</M>-cycle <M>(a_1,a_2,...,a_n)</M>. For the empty list
## the trivial permutation <M>()</M> is returned.
## <P/>
## If the given <A>list</A> contains duplicates or holes, return <K>fail</K>.
Copy link
Member

Choose a reason for hiding this comment

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

And if there is a something that is not a positive integer in the list? Right now, probably various errors, depending on whether its a negative integer (gives proper error), a string or some such (will run into a method not found at some point), a rational (same, but likely in a different) spot, ...

lib/permutat.g Outdated
min := Minimum( set );
if min <= 0 then
Error("CycleFromList: List must contain only positive integers.");
fi;
Copy link
Member

Choose a reason for hiding this comment

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

Instead of this, perhaps do if not ForAll(list, IsPosInt) then Error(...); fi; even before computing set?

od;
images[ list[Length(list)] ] := list[1];

return PermList(images);
Copy link
Member

Choose a reason for hiding this comment

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

While manual test cases are provided, and exercise the regular parts of the function, not all failure cases are tested, e.g. CycleFromList([0]), CycleFromList([1/2]), CycleFromList([true]) to name a few. Perhaps add some (though perhaps to a .tst file, not the manual example)?

I'll not block the PR over this, but it is needed to maximize the test coverage.

Copy link
Member

Choose a reason for hiding this comment

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

There is also no test for the empty list. All this can be seen on https://codecov.io/gh/gap-system/gap/pull/2242/diff?src=pr&el=tree#diff-bGliL3Blcm11dGF0Lmc= (link comes from the codecov report in the 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 don't know much about the test directory structure of GAP. Where exactly should I put the tests?

Copy link
Member

Choose a reason for hiding this comment

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

Somewhere into tst/testinstall/. In this case, I'd suggest to create tst/testinstall/opers/CyclesFromList.tst. Look at the other files in that directory to get an idea what to put in, in case you are not familiar with .tst files. And feel free to ask more questions.

@fingolfin
Copy link
Member

I suspect the test failure is due to a bug in CYCLE_TRANS_INT, and your PR is just by luck triggering the bug. Try if this patch (added to a new commit helps)

diff --git a/src/trans.c b/src/trans.c
index deb807172..f0ea6c1ea 100644
--- a/src/trans.c
+++ b/src/trans.c
@@ -3102,6 +3102,7 @@ Obj FuncCYCLE_TRANS_INT(Obj self, Obj f, Obj pt)
         i = cpt;
         do {
             AssPlist(out, ++len, INTOBJ_INT(i + 1));
+            ptf2 = CONST_ADDR_TRANS2(f);
             i = ptf2[i];
         } while (i != cpt);
     }
@@ -3116,6 +3117,7 @@ Obj FuncCYCLE_TRANS_INT(Obj self, Obj f, Obj pt)
         i = cpt;
         do {
             AssPlist(out, ++len, INTOBJ_INT(i + 1));
+            ptf4 = CONST_ADDR_TRANS4(f);
             i = ptf4[i];
         } while (i != cpt);
     }

@@ -0,0 +1,33 @@
gap> START_TEST("CyclesFromList")
Copy link
Member

Choose a reason for hiding this comment

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

This is missing a semicolon, hence the test fails.

You can test the .tst file locally using Test(), just do

Test("tst/testinstall/opers/CyclesFromList.tst");

(adjust the path depending on from where you run GAP)

Add a convenient functionality to generate a cycle from a list of
positive integers.
The addition of CycleFromList uncovered a bug in CYCLE_TRANS_INT. This
patch by Max Horn hopefully fixes that.

His failure description (abbreviated) was:
The problem is that `AssPlist` can trigger a GC. The change by chance
happened to fill the heap in such a way that a GC happened at that spot
@fingolfin fingolfin changed the title Implement CyclesFromList Implement CyclesFromList, and fix potential crash in CYCLE_TRANS_INT Mar 10, 2018
@fingolfin fingolfin added the kind: enhancement Label for issues suggesting enhancements; and for pull requests implementing enhancements label Mar 20, 2018
@fingolfin fingolfin added this to the GAP 4.10.0 milestone Mar 20, 2018
@fingolfin fingolfin merged commit db5583e into gap-system:master Mar 20, 2018
@fingolfin fingolfin added release notes: to be added PRs introducing changes that should be (but have not yet been) mentioned in the release notes release notes: added PRs introducing changes that have since been mentioned in the release notes and removed release notes: to be added PRs introducing changes that should be (but have not yet been) mentioned in the release notes labels Jul 31, 2018
@olexandr-konovalov olexandr-konovalov changed the title Implement CyclesFromList, and fix potential crash in CYCLE_TRANS_INT Implement CycleFromList, and fix potential crash in CYCLE_TRANS_INT Nov 1, 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.

3 participants