[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)
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 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]?
[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 %>
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.INSPECT (length/2) %>
#
, 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) %>
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) %> 3<NL> X INSPECT (var) %>
Notice that lists are treated as a structure with arity 2, although the functor ((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) %>
./2
) is not printed.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 ([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) %>
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
.The debugger prints(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) %>
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:
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:b INSPECT (atom) %> 2up 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) %> 5up subterm foo(a, g(b, [1, 2]), 3) INSPECT (foo/3) %>
Moving to the top can also be done by the(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) %>
#
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.
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) %> 2left 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.foo(a, g(b, [1, 2]), 3) INSPECT (foo/3) %> 3<NL> 3 INSPECT (integer) %> 5left subterm a INSPECT (atom) %>
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.
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 (integer) %> 2left subterm a INSPECT (atom) %>
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) %> 3<NL> 3 INSPECT (integer) %> right subterm 3 INSPECT (integer) %>
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.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 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 theINSPECT (atom) %> 0<NL> foo(a, g(b, [1, 2]), 3) INSPECT (foo/3) %> down subterm 1 for 1 levels a INSPECT (atom) %>
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.(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 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.[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) %>
.
' normally prints the source for the predicate.
The fact that a structure has defined field names are indicated by a
“struct” in the summary:
In this example, a structure definition was made for:- 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 %>
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,
The subterm path shows the argument positions taken at each level of the toplevel term to reach the current subterm, starting from the top.(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 %>
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:- 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) %>
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.After selecting the output modeA{[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) %>
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.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 (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) %>
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.