Spend any amount of time in GAP, and eventually you will hit the break loop. This is the message GAP prints when code breaks. This can happen for many reasons, but the most common reason is giving a function invalid arguments. Here is an example:
gap> Intersection(1,2); Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for Intersection2(1, 2) called from Intersection2( I, D ) at /Users/caj/reps/gap/gap/lib/coll.gi:2479 called from <function "Intersection">( <arguments> ) called from read-eval loop at line 1 of *stdin* you can 'quit;' to quit to outer loop, or you can 'return;' to continue
The break loop acts like the debugger in most other languages. So, what can we do once we are here?
If you just want to get out of the break loop, either type
quit; or press ctrl+d.
Break loops will often say you can
'return;' to continue, or sometimes tell you that you can return a new value, to fix up the broken computation. My advice is to ignore these choices. They are rarely useful, and a good way to end up with further break loops, incorrect answers, or even crashing GAP! Here is an example of returning a replacement value.
gap> Print(10/0); Error, Rational operations: <divisor> must not be zero not in any function at *stdin*:1 you can replace <divisor> via 'return <divisor>;' brk> return 2; 5
and here is an example of crashing GAP
gap> STRING_SINTLIST(42); Error, <val> must be a plain list or range, not a integer) not in any function at *stdin*:2 you can replace <val> via 'return <val>;' brk> return 42; fish: 'gap' terminated by signal SIGSEGV (Address boundary error)
Let's use the break loop to understand what went wrong. We will begin with the general break loop, and also the extra methods when provided when the break loop is caused by
NoMethodFound (the most common type of break loop).
Let's start with some silly code. If you want to follow along, save this to a file
test.g and use
Read("test.g") to read it in (so line numbers will be set correctly).
mult := function(x,y) local i; i := x * y; return i; end; f := function(a,b) local i,j; i := mult(a,b); j := mult(a,-1); return i * j; end;
Now, let's call our function.
gap> f((1,2),(3,4)); Error, no method found! For debugging hints type ?Recovery from NoMethodFound Error, no 1st choice method found for `*' on 2 arguments called from x * y at test.g:3 called from mult( a, -1 ) at test.g:10 called from <function "f">( <arguments> ) called from read-eval loop at line 16 of *stdin* you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk>
From this, we can already see what went wrong:
(1,2) * -1
x * y.
mult(a,-1)on line 10.
f, which we run from
*stdin*, which represents the user typing into GAP.
From the break loop we can execute any normal GAP code. We can see the value of variables in the function
mult. If we try to read a variable without a value, we get a slightly scary message, which tells us that
i has not got a value yet.
brk> x; (1,2) brk> y; -1 brk> i; Error, Variable: <debug-variable-0-3> must have a value in <compiled or corrupted statement> called from x * y at /Users/caj/temp/t.g:3 called from mult( a, -1 ) at /Users/caj/temp/t.g:10 called from <function "f">( <arguments> ) called from read-eval loop at line 3 of *errin*
We can also get the value of variables from functions higher up the stack:
brk> a; (1,2) brk> b; (3,4)
However, how can we get access to the
f? To do this, we use
DownEnv. These allow us to step up and down through the functions which have been called, and read their variables.
brk> DownEnv(); brk> DownEnv(); brk> i; (1,2)(3,4)
The first line of our error loop is
No Method Found. There is extra support in GAP to help understand why GAP failed to find a method call. We will describe them each, then give an example.
ShowArgumentsshows the arguments to the function
ShowDetailsgives some general information about the function call
ShowMethodsshows all methods which were considered, and why they were rejected. This can often be a very long list! The argument to this function sets how verbose the function is (5 displays the most information).
brk> ShowArguments(); [ (1,2), -1 ] brk> ShowDetails(); -------------------------------------------- Information about a `No method found'-error: -------------------------------------------- Operation : * Number of Arguments : 2 Operation traced : false IsConstructor : false Choice : 1st brk> ShowMethods(5); #I Searching Method for * with 2 arguments: #I Total: 246 entries #I Method 1: ``*: additive element with zero * zero integer'', value: 1*SUM_FLAGS+24 #I - 1st argument needs [ "IsNearAdditiveElementWithZero" ] #I - 2nd argument needs [ "IsZeroCyc" ] #I Method 2: ``*: zero integer * additive element with zero'', value: 1*SUM_FLAGS+24 #I - 1st argument needs [ "IsInt", "IsZeroCyc" ] ....
Finally, we should exit the loop. The best idea is to press ctrl+d, or type
quit;. If we try typing
return;, we get the following, which shows GAP trying to recover, but finding is has no idea what to do with
x * y (that's what the
no method returned is referring to).
Error, no method returned in i := x * y; at test.g:3 called from mult( a, -1 ) at test.g:10 called from <function "f">( <arguments> ) called from read-eval loop at *stdin*:2