[eclipse 3]: p. (1) 1 CALL p %> skip (1) 1 FAIL p %> query culprit failure culprit was (3) - rerun and type q to jump there %> nodebug? [y] No (0.00s cpu) [eclipse 4]: p. (1) 1 CALL p %> query culprit failure culprit was (3) - jump to invoc: [3]? (3) 3 CALL r(1) %> creep (3) 3 FAIL r(...) %> creep (2) 2 FAIL q %> creep (1) 1 FAIL p %> creep No (0.01s cpu)
[eclipse 4]: [X, Y] :: 1..9, X #>= Y, Y#>1.
(1) 1 CALL [X, Y] :: 1..9 %> var/term spy? [y]
Var/term spy set up with invocation number (2) %> jump to invoc: [1]? 2
(2) 3 MODIFY [X{[1..9]}, Y{[2..9]}] :: 1..9 %> jump to invoc: [2]?
(2) 4 MODIFY [X{[2..9]}, Y{[2..9]}] :: 1..9 %> jump to invoc: [2]?
Note that these monitors can also be set
up from within the program code using one of the built-ins
spy_var/1 or
spy_term/2.
[eclipse 5]: [X, Y] :: 1..9, X #>= Y, Y #>= X.
(1) 1 CALL [X, Y] :: 1..9 %> creep
(1) 1 EXIT [X{[1..9]}, Y{[1..9]}] :: 1..9 %> creep
(2) 1 CALL X{[1..9]} - Y{[1..9]}#>=0 %> creep
(3) 2 DELAY X{[1..9]} - Y{[1..9]}#>=0 %> creep
(2) 1 EXIT X{[1..9]} - Y{[1..9]}#>=0 %> creep
(4) 1 CALL Y{[1..9]} - X{[1..9]}#>=0 %> creep
(5) 2 DELAY Y{[1..9]} - X{[1..9]}#>=0 %> delayed goals
with prio: [all]?
------- delayed goals -------
(3) <2> X{[1..9]} - Y{[1..9]}#>=0
(5) <2> Y{[1..9]} - X{[1..9]}#>=0
------------ end ------------
(5) 2 DELAY Y{[1..9]} - X{[1..9]}#>=0 %>
[eclipse 13]: [X,Y,Z]::1..9, X#>Z, Y#>Z, Z#>1.
(1) 1 CALL [X, Y, Z] :: 1..9 %> creep
(1) 1 EXIT [X{[1..9]}, Y{[1..9]}, Z{[1..9]}] :: 1..9 %> creep
(2) 1 CALL X{[1..9]} - Z{[1..9]}+-1#>=0 %> creep
(3) 2 DELAY X{[2..9]} - Z{[1..8]}#>=1 %> creep
(2) 1 EXIT X{[2..9]} - Z{[1..8]}+-1#>=0 %> creep
(4) 1 CALL Y{[1..9]} - Z{[1..8]}+-1#>=0 %> creep
(5) 2 DELAY Y{[2..9]} - Z{[1..8]}#>=1 %> creep
(4) 1 EXIT Y{[2..9]} - Z{[1..8]}+-1#>=0 %> creep
(6) 1 CALL 0 + Z{[1..8]}+-2#>=0 %> creep
(3) 2 RESUME X{[2..9]} - Z{[2..8]}#>=1 %> scheduled goals
with prio: [all]?
------ scheduled goals ------
(5) <2> Y{[2..9]} - Z{[2..8]}#>=1
------------ end ------------
(3) 2 RESUME X{[2..9]} - Z{[2..8]}#>=1 %>
INSPECT (length/2) %>
Instead of showing the goal, a summary of the current subterm – generally its
functor and arity if the subterm is a structure – is shown in brackets.
#, which causes the
debugger to prompt for a number. In both cases, the number specifies the
argument number to move down to.
In the following example, the # style of the command is used to move
to the first argument, and the number style of the command to move to the
third argument:
(1) 1 CALL foo(a, g(b, [1, 2]), X) %> inspect arg #: 1<NL>
a
INSPECT (atom) %>
(1) 1 CALL foo(a, g(b, [1, 2]), X) %> 3<NL>
X
INSPECT (var) %>
The new current subterm is printed, followed by the INSPECT
trace line. Notice that the summary shows the type of the current
subterm, instead of Name/Arity, since in both cases the subterms are not
structures.
(1) 1 CALL foo(a, g(b, [1, 2]), X) %> 2<NL>
g(b, [1, 2])
INSPECT (g/2) %> 2<NL>
[1, 2]
INSPECT (list 1-head 2-tail) %> 2<NL>
[2]
INSPECT (list 1-head 2-tail) %>
Notice that lists are treated as a structure with arity 2, although the
functor (./2) is not printed.
[eclipse 21]: suspend(foo(X), 3, X->inst), foo(X).<NL>
(1) 1 DELAY foo(X) %> <NL>
creep
(2) 1 CALL foo(X) %> 1<NL>
X
INSPECT (attributes 1-suspend 2-fd ) %>1<NL>
suspend(['SUSP-1-susp'|_218] - _218, [], [])
INSPECT (struct suspend/3) %>
The variable X is an attributed variable in this case, and when it is the
current subterm, this is indicated in the trace line. The debugger also
shows the user the currently available attributes, and the user can then
select one to navigate into (fd is available in
this case because the finite domain library was loaded earlier in the
session. Otherwise, it would not be available as a choice here). suspend/3 summary contains a struct before
it. This is because the suspend/3 is a predefined structure with
field names (see section 5.1). It is possible to view the
field names of such structures using the . command in inspect mode.
foo(a, g(b, [1, 2]), 3)
INSPECT (foo/3) %> 4<NL>
Out of range.....
foo(a, g(b, [1, 2]), 3)
INSPECT (foo/3) %>
A by the debugger, so one can also type
A. Typing A may be necessary for some configurations
(combination of keyboards and operating systems) because the uparrow key is
not correctly mapped to A.
(1) 1 CALL foo(a, g(b, [1, 2]), 3) %> 2<NL>
g(b, [1, 2])
INSPECT (g/2) %> 1<NL>
b
INSPECT (atom) %> up subterm
g(b, [1, 2])
INSPECT (g/2) %> 1up subterm
foo(a, g(b, [1, 2]), 3)
INSPECT (foo/3) %>
The debugger prints up subterm when the uparrow key is typed. The
current subterm moves back up the structure to its parent for each level it
moves up, and the above move can be done directly by specifying 2 as the
levels to move up:
b
INSPECT (atom) %> 2up subterm
foo(a, g(b, [1, 2]), 3)
INSPECT (foo/3) %>
If the number of levels specified is more than the number of levels that
can be traversed up, the current subterm stops at the toplevel:
(1) 1 CALL foo(a, g(b, [1, 2]), 3) %> 2<NL>
g(b, [1, 2])
INSPECT (g/2) %> 2<NL>
[1, 2]
INSPECT (list 1-head 2-tail) %> 5up subterm
foo(a, g(b, [1, 2]), 3)
INSPECT (foo/3) %>
(1) 1 CALL foo(a, g(b, [1, 2]), 3) %> 2<NL>
g(b, [1, 2])
INSPECT (g/2) %> 2<NL>
[1, 2]
INSPECT (list 1-head 2-tail) %> 2<NL>
[2]
INSPECT (list 1-head 2-tail) %> 2<NL>
[]
INSPECT (atom) %> 0<NL>
foo(a, g(b, [1, 2]), 3)
INSPECT (foo/3) %>
Moving to the top can also be done by the # command, and not giving
any argument (or 0) when prompted for the argument.D) moves the current subterm to
a sibling subterm (i.e. fellow argument of the parent structure) that is to
the left of it. Consider the structure foo(a, g(b, [1, 2]), 3), then
for the second argument, g(b, [1, 2]), a is its (only) left
sibling, and 3 its (only) right sibling. For the third argument,
3, both a (distance of 2) and
g(b, [1, 2]) (distance of 1) are its left siblings. The optional
numeric argument for the command specifies the distance to the left that
the current subterm should be moved. It defaults to 1.
foo(a, g(b, [1, 2]), 3)
INSPECT (foo/3) %> 3<NL>
3
INSPECT (integer) %> 2left subterm
a
INSPECT (atom) %>
If the leftward movement specified would move the argument position before the
first argument of the parent term, then the movement will stop at the first
argument:
foo(a, g(b, [1, 2]), 3)
INSPECT (foo/3) %> 3<NL>
3
INSPECT (integer) %> 5left subterm
a
INSPECT (atom) %>
In the above example, the current subterm was at the third argument, thus
trying to move left by 5 argument positions is not possible, and
the current subterm stopped at leftmost position – the first argument.C) moves the current subterm
to a sibling subterm (i.e. fellow argument of the parent structure) that is
to the right of it. Consider the structure foo(a, g(b, [1, 2]), 3),
then for the first argument, a, g(b, [1, 2]) is a right
sibling with distance of 1, and 3 is a right sibling with distance
of 2. The optional numeric argument for the command specifies the distance
to the left that the current subterm should be moved. It defaults to 1.
foo(a, g(b, [1, 2]), 3)
INSPECT (integer) %> 2left subterm
a
INSPECT (atom) %>
If the rightward movement specified would move the argument position beyond
the last argument of the parent term, then the movement will stop at the
last argument:
foo(a, g(b, [1, 2]), 3)
INSPECT (foo/3) %> 3<NL>
3
INSPECT (integer) %> right subterm
3
INSPECT (integer) %>
In the above example, the current subterm was at the third (and last)
argument, thus trying to move to the right (by the default 1 position in
this case) is not possible, and the current subterm remains at the third
argument.
foo(a, g(b, [1, 2]), 3)
INSPECT (foo/3) %> 2<NL>
g(b, [1, 2])
INSPECT (list 1-head 2-tail) %> 3down subterm 2 for 3 levels
[]
INSPECT (atom) %>
In the above example, the user moves down into the second argument, and
then use the down-arrow key to move down into the second argument for 2
levels – the numeric argument typed before the arrow key specified the
number of levels that the current subterm was moved down by.
The command moves into the second argument because it was at the
second argument position when the command was issue.
INSPECT (atom) %> 0<NL>
foo(a, g(b, [1, 2]), 3)
INSPECT (foo/3) %> down subterm 1 for 1 levels
a
INSPECT (atom) %>
In the above example, the down-arrow key is typed at the top-level, and
thus the argument position chosen for moving down is first argument, with
the default numeric argument for the
(1) 1 CALL foo(a, b, c(d, e)) %> 3<NL>
c(d, e)
INSPECT (c/2) %> Out of range after traversing down arg...
c(d, e)
INSPECT (c/2) %>
In this case, the down-arrow key was typed in the second trace line, which
had the current subterm at the third argument of its parent term, and thus
the command tries to move the new current subterm to the third argument of
the current sub-term, but the structure does not have a third argument and
so no move was made. In the case of moving down multiple levels, then the
movement will stop as soon as the argument position to move down to goes
out of range.
[eclipse 30]: foo([1,2,3,4,5,6,7,8,9]).
(1) 1 CALL foo([1, 2, 3, ...]) %> 1<NL>
[1, 2, 3, 4, ...]
INSPECT (list 1-head 2-tail) %> 2<NL>
[2, 3, 4, 5, ...]
INSPECT (list 1-head 2-tail) %> 6down subterm 2 for 6 levels
[8, 9]
INSPECT (list 1-head 2-tail) %>
In order to move down a list, we repeatedly move into the tail of the list
– the second argument position. In order to do this with the down-arrow
command, we need to be at the second argument position first, and this is
done in the second trace line. Once this is done, then it is possible to
move arbitrarily far down the list in one go, as is shown in the example..' normally prints the source for the predicate.
The fact that a structure has defined field names are indicated by a
“struct” in the summary:
:- local struct(capital(city,country)).
.....
(1) 1 CALL f(capital(london, C)) %> 1<NL>
capital(london, C)
INSPECT (struct capital/2) %> structure definition:
1=city 2=country
%>
In this example, a structure definition was made for captial/2. When
this structure is the current subterm in the inspect mode, the
struct in the summary for the structure indicates that it has
a structure definition. For such structures, the field names are printed by
the structure definition command.
INSPECT (f/1) %> structure definition:
No struct definition for term f/1@eclipse.
%>
p command. For example,
(1) 1 CALL foo(a, g(b, [1, 2]), 3) %> 2<NL>
g(b, [1, 2])
INSPECT (g/2) %> 2<NL>
[1, 2]
INSPECT (list 1-head 2-tail) %> 1<NL>
1
INSPECT (integer) %> p
Subterm path: 2, 2, 1
%>
The subterm path shows the argument positions taken at each level of the
toplevel term to reach the current subterm, starting from the top.
:- local struct(capital(city,country)).
.....
[eclipse 8]: suspend(capital(london, C), 3, C -> inst), f(capital(london, C)).
....
(2) 1 CALL f(capital(london, C)) %> 1<NL>
capital(london, C)
INSPECT (struct capital/2) %> 2<NL>
C
INSPECT (attributes 1-suspend ) %> 1<NL>
suspend(['SUSP-1-susp'|_244] - _244, [], [])
INSPECT (struct suspend/3) %> 1<NL>
['SUSP-1-susp'|_244] - _244
INSPECT (-/2) %>
Subterm path: 1, country of capital (2), attr: suspend, inst of suspend (1)
%>
In this example, except for the toplevel argument, all the other positions are
either have field names or are attributes. This is reflected in the path,
for example, country of capital (2) shows that the field name for
the selected argument position (2, shown in brackets) is country,
and the structure name is capital. For the `position' of the
selected attribute (suspend) of the attributed variable C,
the path position is shown as attr: suspend.
A{[4..10000000]}
INSPECT (attributes 1-suspend 2-fd ) %> 2<NL>
[4..10000000]
INSPECT (list 1-head 2-tail) %> 1<NL>
4..10000000
INSPECT (../2) %> 2up subterm
A{[4..10000000]}
INSPECT (attributes 1-suspend 2-fd ) %> <o>
current output mode is "QPm", toggle char: T
new output mode is "TQPm".
A{[4..10000000]}
INSPECT (attributes 1-suspend 2-fd ) %> 2<NL>
fd(dom([4..10000000], 9999997), [], [], [])
INSPECT (struct fd/4) %> 1<NL>
dom([4..10000000], 9999997)
INSPECT (dom/2) %>
After selecting the output mode T, which turns off any output
macros, the internal form of the attribute is shown. This allows previously
hidden fields of the attribute to be examined by the subterm navigation.
Note that if the current subterm is inside a structure which will be
changed by a changed output mode (such as inside the fd attribute), and the
output mode is changed, then until the current subterm is moved out of the
structure, the existing subterm path is still applicable.
4..10000000
INSPECT (../2) %> up subterm
[4..10000000] ***** printed structure 1
INSPECT (list 1-head 2-tail) %> <o>
current output mode is "QPm", toggle char: T
new output mode is "TQPm".
[4..10000000]
INSPECT (list 1-head 2-tail) %> up subterm
A{[4..10000000]}
INSPECT (attributes 1-suspend 2-fd ) %> 2
fd(dom([4..10000000], 9999997), [], [], [])
INSPECT (struct fd/4) %> <o>
current output mode is "QPmT", toggle char: T
new output mode is "QPm".
fd(4..10000000, [], [], []) ***** printed structure 2
INSPECT (struct fd/4) %>
Printed structures 1 and 2 in the above example are at the same position
(toplevel of the finite domain structure), and printed with the same output
mode (QPm), but are different because the structure obtained from
the parent subterm is different – in printed structure 2, the output mode
was not changed until after the fd/4 structure was the current
subterm. ....
Note that the debugger has a private print_depth setting with
default 5, which is different from the global setting obtained from
get_flag/2.(1) 1 CALL true %> show module (1) 1 CALL eclipse : true %>
(1) 1 CALL X is length([1, 2, ...]) %> current output mode
is "QPm", toggle char: V
new output mode is "VQPm".
(1) 1 CALL X_72 is length([1, 2, ...]) %> current output mode
is "QVPm", toggle char: O
new output mode is "OQVPm".
(1) 1 CALL is(X_72, length([1, 2, ...])) %> current output mode
is "OQVPm", toggle char: .
new output mode is ".OQVPm".
(1) 1 CALL is(X_72, length(.(1, .(2, .(...))))) %>
^D, or end_of_file
the execution returns to the debugger and the last trace line is redisplayed.