-
Notifications
You must be signed in to change notification settings - Fork 179
Implement CycleFromList, and fix potential crash in CYCLE_TRANS_INT #2242
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -479,6 +479,64 @@ BIND_GLOBAL( "ListPerm", function( arg ) | |
| end ); | ||
|
|
||
|
|
||
| ############################################################################# | ||
| ## | ||
| #F CycleFromList( <list> ) . . . . . . . . . . . cycle defined from a list | ||
| ## | ||
| ## <#GAPDoc Label="CycleFromList"> | ||
| ## <ManSection> | ||
| ## <Func Name="CycleFromList" Arg='list'/> | ||
| ## | ||
| ## <Description> | ||
| ## For the given dense, duplicate-free list of positive integers | ||
| ## <M>[a_1, a_2, ..., a_n]</M> | ||
| ## 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>. | ||
| ## <P/> | ||
| ## <Example><![CDATA[ | ||
| ## gap> CycleFromList( [1,2,3,4] ); | ||
| ## (1,2,3,4) | ||
| ## gap> CycleFromList( [3,2,6,4,5] ); | ||
| ## (2,6,4,5,3) | ||
| ## gap> CycleFromList( [2,3,2] ); | ||
| ## fail | ||
| ## gap> CycleFromList( [1,,3] ); | ||
| ## fail | ||
| ## ]]></Example> | ||
| ## </Description> | ||
| ## </ManSection> | ||
| ## <#/GAPDoc> | ||
| ## | ||
| BIND_GLOBAL( "CycleFromList", function( list ) | ||
| local max, images, set, i; | ||
|
|
||
| # Trivial case | ||
| if Length(list) = 0 then | ||
| return (); | ||
| fi; | ||
|
|
||
| if ForAny( list, i -> not IsPosInt(i) ) then | ||
| Error("CycleFromList: List must only contain positive integers."); | ||
| fi; | ||
|
|
||
| set := Set(list); | ||
| if Length(set) <> Length(list) then | ||
| # we found duplicates (or list was not dense) | ||
| return fail; | ||
| fi; | ||
| max := Maximum( set ); | ||
| images := [1..max]; | ||
| for i in [1..Length(list)-1] do | ||
| images[ list[i] ] := list[i+1]; | ||
| od; | ||
| images[ list[Length(list)] ] := list[1]; | ||
|
|
||
| return PermList(images); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. I'll not block the PR over this, but it is needed to maximize the test coverage.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Somewhere into |
||
| end ); | ||
|
|
||
|
|
||
| ############################################################################# | ||
| ## | ||
| #O RestrictedPerm(<perm>,<list>) restriction of a perm. to an invariant set | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| gap> START_TEST("CyclesFromList"); | ||
|
|
||
| # | ||
| gap> CycleFromList( [1..10] ); | ||
| (1,2,3,4,5,6,7,8,9,10) | ||
| gap> CycleFromList( [1,5,4,8] ); | ||
| (1,5,4,8) | ||
| gap> CycleFromList( [9,10,3,5]); | ||
| (3,5,9,10) | ||
| gap> CycleFromList( [1,3,,9] ); | ||
| fail | ||
| gap> CycleFromList( [1,3,3,8] ); | ||
| fail | ||
|
|
||
| # Errors | ||
| gap> CycleFromList( [7,2,0,3] ); | ||
| Error, CycleFromList: List must only contain positive integers. | ||
| gap> CycleFromList( [9,3,-7,8,9] ); | ||
| Error, CycleFromList: List must only contain positive integers. | ||
| gap> CycleFromList( [2,2,1/2,6] ); | ||
| Error, CycleFromList: List must only contain positive integers. | ||
|
|
||
| # | ||
| gap> CycleFromList( [] ); | ||
| () | ||
| gap> CycleFromList( [7] ); | ||
| () | ||
| gap> CycleFromList( [0] ); | ||
| Error, CycleFromList: List must only contain positive integers. | ||
| gap> CycleFromList( [true] ); | ||
| Error, CycleFromList: List must only contain positive integers. | ||
| gap> STOP_TEST("CyclesFromList", 1); |
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.
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, ...