[m-rev.] for review: improvements to subterm dependency tracking

Ian MacLarty maclarty at cs.mu.OZ.AU
Sun Oct 30 15:33:37 AEDT 2005


This change is based on an idea of Zoltan's where the subterm tracking
algorithm can avoid generating subtrees if the subterm it is tracking is in an
output argument and the same subterm appears in the same position in one of the
input arguments.  The algorithm only checks input arguments that have the
same name as the output argument, except for a numerical suffix, because
dereferencing the subterm can be expensive.

After implementing this idea I wrote a test case and did a few benchmarks.
Below are the results.  I tested the old and new algorithms on a program where
the proposed optimisation could be used and one where it couldn't.
(The program where the optimisation could be applied is the new test case given
in the diff at the end of this email, while the program where the optimisation
could not be applied is the same program very slightly modified, so the
subterm is different in the input argument).

old version with optimisation opportunity:
real    0m1.731s
user    0m1.422s
sys     0m0.298s

new version with optimisation opportunity:
real    0m0.712s
user    0m0.473s
sys     0m0.237s

old version with no optimisation opportunity:
real    0m0.761s
user    0m0.502s
sys     0m0.251s

new version with no optimisation opportunity:
real    0m48.037s
user    0m47.687s
sys     0m0.296s

The new version is certainly better when the heuristic is applicable, however
when the heuristic is not applicable there is a big slowdown.  This is
because looking up the value of a subterm in a larger term is expensive.

To fix this I implemented a further heuristic where the algorithm will only
try to bypass a given procedure once during a given run (since if the subterm
doesn't appear in the same position in one call, it is unlikely to
appear in the same position in recursive calls to the same procedure).

This change yielded the following results:

old version with optimisation opportunity:
real    0m1.724s
user    0m1.413s
sys     0m0.293s

new version with optimisation opportunity:
real    0m0.700s
user    0m0.459s
sys     0m0.237s

old version with no optimisation opportunity:
real    0m0.757s
user    0m0.494s
sys     0m0.257s

new version with no optimisation opportunity:
real    0m0.939s
user    0m0.630s
sys     0m0.297s

Ian.

For review by Zoltan.

Estimated hours taken: 20
Branches: main

Implement a second version of the subterm dependency tracking algorithm
that uses the following heuristic to speed things up: If the subterm is being
tracked through an output argument, and there is an input argument with the
same name as the output argumnet, except for a numerical suffix, then the new
algorithm will check if the subterm appears in the same position in the input
argument.  If it does then it will continue tracking the subterm in the input
argument, thus bypassing the subtree rooted at the call.  Since dereferencing a
subterm in a large structure can be expensive, the new algorithm will only try
to bypass calls to procedures it has not tried to bypass before.  The set of
procedures it has tried is reset each time a new explicit subtree or supertree
is generated.

Change the `mark' command to `track' and add an optional `--accurate'
argument which tells the declarative debugger to use the original
tracking algorithm.  We still allow the old algorithm to be used, because there
are situations where the new algorithm could find the wrong call (i.e.
when a subterm appears in the same position in an input argument,
but the subterm in the output argument is actually bound by a descendent call
-- it just happens to be bound to the same value as the input subterm).

If the user tracks a subterm, do not interpret this as an assertion that the
atom is erroneous or inadmissible.  Experience has should that this behaviour
is not all that useful and requires much more thought from the user before they
track a subterm, because the user must be sure the atom is in fact erroneous or
inadmissible before tracking the subterm.  The user may just be suspicious of
the subterm and may not be willing or able to assert that the atom is
erroneous or inadmissible.  The new approach also doesn't require the user to
have information about the modes of the arguments.

doc/user_guide.texi:
	Change the documentation accordingly.

browser/browse.m:
browser/browser_info.m:
browser/parse.m:
browser/declarative_user.m:
	Change the `mark' command to `track' and allow an `--accurate' or `-a'
	argument.
	Pass information about tracked subterms to the declarative debugger.

browser/declarative_analyser.m:
browser/declarative_debugger.m:
browser/declarative_edt.m:
browser/declarative_oracle.m:
	Implement the new tracking algorithm.

browser/term_rep.m:
	Add a predicate to dereference a subterm in another term.

mdbcomp/rtti_access.m:
	Add a predicate to find a candidate input argument on which to
	apply the new heuristic.

runtime/Mmakefile:
runtime/mercury_layout_util.h:
runtime/mercury_stack_layout.h:
trace/mercury_trace_vars.c:
trace/mercury_trace_vars.h:
	Move the function for finding the name of a variable to the runtime,
	so that it can be called from the declarative debugger.

tests/debugger/declarative/Mmakefile:
tests/debugger/declarative/nodescend_tracking.exp:
tests/debugger/declarative/nodescend_tracking.inp:
tests/debugger/declarative/nodescend_tracking.m:
	Test the new heuristic.

tests/debugger/declarative/*
	Update expected output to expect `track' instead of `mark' and
	adjust tests that relied on `mark' implying that the atom was
	erroneous or inadmissible.

Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.456
diff -u -b -r1.456 user_guide.texi
--- doc/user_guide.texi	25 Oct 2005 04:00:47 -0000	1.456
+++ doc/user_guide.texi	30 Oct 2005 02:28:59 -0000
@@ -1663,9 +1663,9 @@
 at every execution point that represents a potential trace event,
 which is very convenient.

-The ``decldebug'' grades improve declarative debugging by tracking
-the source of marked subterms (see @ref{Improving the search}).
-Doing this substantially increases the size of executables so these
+The ``decldebug'' grades improve declarative debugging by allowing the user
+to track the source of subterms (see @ref{Improving the search}).
+Doing this increases the size of executables so these
 grades should only be used when the subterm dependency tracking feature
 of the declarative debugger is required.
 Note that declarative debugging, with the exception of the subterm dependency
@@ -4227,8 +4227,8 @@
 Start the interactive term browser and browse the @var{n}th argument
 before answering.  If the argument number
 is omitted then browse the whole call as if it were a data term.
-While browsing a @samp{mark} command may be issued to assert that
-the current subterm is incorrect (see @ref{Improving the search}).
+While browsing a @samp{track} command may be issued to find the point at
+which the current subterm was bound (see @ref{Improving the search}).
 To return to the declarative debugger question issue a @samp{quit}
 command from within the interactive term browser.  For more information
 on the use of the interactive term browser see the @samp{browse} command
@@ -4257,13 +4257,27 @@
 @samp{list_path}, @samp{list_context_lines}, @samp{format}, @samp{depth},
 @samp{size}, @samp{width} and @samp{lines}.
 @sp 1
- at item mark [@var{term-path}]
-The @samp{mark} command can only be given from within the interactive
-term browser and asserts that the marked subterm is incorrect.  The
-declarative debugger uses this information to better direct the bug search.
+ at item track [-a] [@var{term-path}]
+The @samp{track} command can only be given from within the interactive
+term browser and tells the declarative debugger to find the point at which
+the current subterm was bound.
 If no argument is given the current subterm is taken to be incorrect.
 If a @var{term-path} is given then the subterm at @var{term-path} relative to
 the current subterm will be considered incorrect.
+The declarative debugger will ask about the call that bound the given subterm
+next.
+To find out the location of the unification that bound the subterm,
+issue an @samp{info} command when asked about the call that bound the subterm.
+The declarative debugger can use one of two algorithms to find the
+point at which the subterm was bound.
+The first algorithm uses some heuristics
+to find the subterm more quickly than the second algorithm.
+It is possible, though unlikely,
+for the first algorithm to find the wrong call.
+The first algorithm is the default.
+To tell the declarative debugger to
+use the second, more accurate but slower algorithm,
+give the @samp{-a} or @samp{--accurate} option to the @samp{track} command.
 @sp 1
 @item pd
 Commence procedural debugging from the current point.
@@ -4421,25 +4435,16 @@
 of extra information that can be given and how to convey this information are
 explained in this section.

- at subsubsection Marking incorrect subterms
+ at subsubsection Tracking incorrect subterms

-An incorrect subterm can be @emph{marked} by the user from within the
-interactive term browser (see @ref{Declarative debugging commands}).
-The effect of marking a subterm depends on the whether the subterm was part
-of an input or an output argument.
-
-If the subterm was an input then by marking the subterm the user is asserting
-that the call was inadmissible and that the marked input subterm is the
-reason for inadmissibility (i.e. the subterm's value violates a precondition
-of the call).
-
-If the subterm was an output then the user is saying the exit atom is false
-in the intended interpretation and the marked subterm is the reason for the
-atom being false (i.e. if it were some other value then the atom would be
-true).
-
-In either case the next question asked by the declarative debugger will
-be about the call that bound the incorrect subterm, unless that call was
+An incorrect subterm can be tracked to the call that bound the subterm
+from within the interactive term browser
+(see @ref{Declarative debugging commands}).
+
+After issuing a @samp{track} command,
+the next question asked by the declarative debugger will
+be about the call that bound the incorrect subterm,
+unless that call was
 eliminated as a possible bug because of an answer to a previous
 question or the call that bound the subterm was not traced.

@@ -4473,7 +4478,7 @@
 @end example

 Then if we know that this is the right payment amount for the given loan,
-but the date is incorrect, we can mark the date(...) subterm and the
+but the date is incorrect, we can track the date(...) subterm and the
 debugger will then ask us about @code{get_payment_date}:

 @noindent
@@ -4483,8 +4488,8 @@
 browser> cd 3/1
 browser> ls
 date(9, 10, 1977)
-browser> mark
-get_payment_date(loan(...), 10, dat(9, 10, 1977)).
+browser> track
+get_payment_date(loan(...), 10, date(9, 10, 1977)).
 Valid?
 @end example

@@ -4492,15 +4497,15 @@

 @noindent
 If, say, the date was only wrong in the year part, then we could also have
-marked the year subterm in which case the next question would have been about
+tracked the year subterm in which case the next question would have been about
 the call that constructed the year part of the date.

 This feature is also useful when using the procedural debugger.  For example,
 suppose that you come across a @samp{CALL} event and you would like to know the
 source of a particular input to the call.  To find out you could first go to
 the final event by issuing a @samp{finish} command.  Invoke the declarative
-debugger with a @samp{dd} command and then mark the input term you are
-interested in.  The next question should be about the call that bound the term.
+debugger with a @samp{dd} command and then track the input term you are
+interested in.  The next question will be about the call that bound the term.
 Issue a @samp{pd} command at this point to return to the procedural debugger.
 It will now show the final event of the call that bound the term.

@@ -4539,9 +4544,8 @@
 @subsubsection When different search modes are used

 If a search mode is given when invoking the declarative debugger then that
-search mode will be used, unless (a) a subterm is marked during the session,
-in which case the subterm is tracked to its origin, or (b) the user
-has not answered @samp{no} to any questions yet,
+search mode will be used, unless (a) a subterm is tracked during the session,
+or (b) the user has not answered @samp{no} to any questions yet,
 in which case top-down search is used until @samp{no} is answered to at least
 one question.

@@ -4553,6 +4557,8 @@

 You can check the search mode used to find a particular question by issuing
 an @samp{info} command at the question prompt in the declarative debugger.
+You can also change the search mode from within the declarative debugger
+with the @samp{mode} command.

 @c ----------------------------------------------------------------------------

Index: browser/browse.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/browse.m,v
retrieving revision 1.53
diff -u -b -r1.53 browse.m
--- browser/browse.m	19 Oct 2005 05:38:55 -0000	1.53
+++ browser/browse.m	29 Oct 2005 09:08:15 -0000
@@ -26,7 +26,6 @@
 :- import_module mdb.browser_term.

 :- import_module io.
-:- import_module list.
 :- import_module std_util.

     % The interactive term browser. The caller type will be `browse', and
@@ -35,7 +34,8 @@
     % mode function can be supplied.
     %
 :- pred browse_browser_term_no_modes(browser_term::in,
-    io__input_stream::in, io__output_stream::in, maybe(list(dir))::out,
+    io__input_stream::in, io__output_stream::in,
+    maybe_track_subterm_browser::out,
     browser_persistent_state::in, browser_persistent_state::out,
     io::di, io::uo) is cc_multi.

@@ -44,7 +44,7 @@
     %
 :- pred browse_browser_term(browser_term::in,
     io__input_stream::in, io__output_stream::in,
-    maybe(browser_mode_func)::in, maybe(list(dir))::out,
+    maybe(browser_mode_func)::in, maybe_track_subterm_browser::out,
     browser_persistent_state::in, browser_persistent_state::out,
     io::di, io::uo) is cc_multi.

@@ -158,6 +158,7 @@
 :- import_module deconstruct.
 :- import_module getopt.
 :- import_module int.
+:- import_module list.
 :- import_module map.
 :- import_module parser.
 :- import_module pprint.
@@ -484,14 +485,14 @@
 %

 browse_browser_term_no_modes(Term, InputStream, OutputStream,
-        MaybeMark, !State, !IO) :-
+        MaybeTrack, !State, !IO) :-
     browse_common(internal, Term, InputStream, OutputStream, no, no,
-        MaybeMark, !State, !IO).
+        MaybeTrack, !State, !IO).

 browse_browser_term(Term, InputStream, OutputStream, MaybeModeFunc,
-        MaybeMark, !State, !IO) :-
+        MaybeTrack, !State, !IO) :-
     browse_common(internal, Term, InputStream, OutputStream, no,
-        MaybeModeFunc, MaybeMark, !State, !IO).
+        MaybeModeFunc, MaybeTrack, !State, !IO).

 browse_browser_term_format_no_modes(Term, InputStream, OutputStream,
         Format, !State, !IO) :-
@@ -513,12 +514,12 @@

 :- pred browse_common(debugger::in, browser_term::in, io__input_stream::in,
     io__output_stream::in, maybe(portray_format)::in,
-    maybe(browser_mode_func)::in, maybe(list(dir))::out,
+    maybe(browser_mode_func)::in, maybe_track_subterm_browser::out,
     browser_persistent_state::in, browser_persistent_state::out,
     io::di, io::uo) is cc_multi.

 browse_common(Debugger, Object, InputStream, OutputStream, MaybeFormat,
-        MaybeModeFunc, MaybeMark, !State, !IO) :-
+        MaybeModeFunc, MaybeTrack, !State, !IO) :-
     Info0 = browser_info__init(Object, browse, MaybeFormat, MaybeModeFunc,
         !.State),
     io__set_input_stream(InputStream, OldInputStream, !IO),
@@ -527,7 +528,7 @@
     browse_main_loop(Debugger, Info0, Info, !IO),
     io__set_input_stream(OldInputStream, _, !IO),
     io__set_output_stream(OldOutputStream, _, !IO),
-    MaybeMark = Info ^ maybe_mark,
+    MaybeTrack = Info ^ maybe_track,
     !:State = Info ^ state.

 :- pred browse_main_loop(debugger::in, browser_info::in, browser_info::out,
@@ -626,20 +627,38 @@
         nl_debugger(Debugger, !IO),
         Quit = no
     ;
-        Command = mark,
-        !:Info = !.Info ^ maybe_mark := yes(!.Info ^ dirs),
+        Command = track_accurate,
+        !:Info = !.Info ^ maybe_track := track_accurate(!.Info ^ dirs),
+        Quit = yes
+    ;
+        Command = track_accurate(Path),
+        change_dir(!.Info ^ dirs, Path, NewPwd),
+        deref_subterm(!.Info ^ term, NewPwd, [], SubResult),
+        (
+            SubResult = deref_result(_),
+            !:Info = !.Info ^ maybe_track := track_accurate(NewPwd),
+            Quit = yes
+        ;
+            SubResult = deref_error(_, _),
+            write_string_debugger(Debugger, "error: cannot track subterm\n",
+                !IO),
+            Quit = no
+        )
+    ;
+        Command = track_fast,
+        !:Info = !.Info ^ maybe_track := track_fast(!.Info ^ dirs),
         Quit = yes
     ;
-        Command = mark(Path),
+        Command = track_fast(Path),
         change_dir(!.Info ^ dirs, Path, NewPwd),
         deref_subterm(!.Info ^ term, NewPwd, [], SubResult),
         (
             SubResult = deref_result(_),
-            !:Info = !.Info ^ maybe_mark := yes(NewPwd),
+            !:Info = !.Info ^ maybe_track := track_fast(NewPwd),
             Quit = yes
         ;
             SubResult = deref_error(_, _),
-            write_string_debugger(Debugger, "error: cannot mark subterm\n",
+            write_string_debugger(Debugger, "error: cannot track subterm\n",
                 !IO),
             Quit = no
         )
Index: browser/browser_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/browser_info.m,v
retrieving revision 1.20
diff -u -b -r1.20 browser_info.m
--- browser/browser_info.m	11 Jul 2005 07:30:19 -0000	1.20
+++ browser/browser_info.m	30 Oct 2005 02:17:09 -0000
@@ -43,16 +43,22 @@
 					% mdb command.
 			state		:: browser_persistent_state,
 					% Persistent settings.
-			maybe_mark	:: maybe(list(dir)),
-					% Location of the marked term
-					% relative to the root, or `no'
-					% if there is no mark.
+			maybe_track	:: maybe_track_subterm_browser,
+					% Location of subterm for which the
+					% `track' command was given,
+					% or `no_track' if the `track' command
+					% was not given.
 			maybe_mode_func	:: maybe(browser_mode_func)
 					% An optional function to determine the
 					% mode of a particular sub-term should
 					% the user issue a `mode' query.
 		).

+:- type maybe_track_subterm_browser
+	--->	no_track
+	;	track_accurate(list(dir))
+	;	track_fast(list(dir)).
+
 	% A signature for functions that can be used by the browser to work
 	% out the mode of a sub-term.
 	%
@@ -331,7 +337,7 @@

 browser_info__init(BrowserTerm, CallerType, MaybeFormat, MaybeModeFunc,
 		State) =
-	browser_info(BrowserTerm, [], CallerType, MaybeFormat, State, no,
+	browser_info(BrowserTerm, [], CallerType, MaybeFormat, State, no_track,
 		MaybeModeFunc).

 browser_info__get_format(Info, Caller, MaybeFormat, Format) :-
Index: browser/parse.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/parse.m,v
retrieving revision 1.25
diff -u -b -r1.25 parse.m
--- browser/parse.m	11 Jul 2005 07:30:21 -0000	1.25
+++ browser/parse.m	29 Oct 2005 09:39:32 -0000
@@ -34,7 +34,7 @@
 %		"display"
 %		"write"
 %		"set" [[setoptions] varvalue]
-%		"mark" [path]
+%		"track" [--accurate] [path]
 %		"mode" [path]
 %		"quit"
 %
@@ -120,8 +120,10 @@
 		)
 	;	cd(path)
 	;	cd
-	;	mark(path)
-	;	mark
+	;	track_accurate(path)
+	;	track_fast(path)
+	;	track_accurate
+	;	track_fast
 	;	mode_query(path)
 	;	mode_query
 	;	pwd
@@ -187,6 +189,7 @@
 	;	(<)
 	;	num(int)
 	;	name(string)
+	;	arg(string)
 	;	unknown(char).

 parse__read_command(Prompt, Command, !IO) :-
@@ -248,6 +251,8 @@
 	; C = ('<') ->
 		Toks = [(<) | Toks2],
 		lexer_word_chars(Cs, Toks2)
+	; C = ('-'), Cs = [H | T] ->
+		lexer_arg([H | T], Toks)
 	; char__is_digit(C) ->
 		dig_to_int(C, N),
 		lexer_num(N, Cs, Toks)
@@ -281,6 +286,16 @@
 	char__to_int(C, CN),
 	N = CN - Zero.

+:- pred lexer_arg(list(char)::in(non_empty_list), list(token)::out) is det.
+
+lexer_arg([Head | Tail], Toks) :-
+	( Head = ('-') ->
+		string__from_char_list(Tail, ArgName)
+	;
+		string__from_char_list([Head | Tail], ArgName)
+	),
+	Toks = [arg(ArgName)].
+
 :- pred lexer_num(int::in, list(char)::in, list(token)::out) is det.

 lexer_num(N, Cs, Toks) :-
@@ -373,13 +388,26 @@
 		ArgTokens = [],
 		Command = pwd
 	;
-		CmdToken = name("mark")
+		CmdToken = name("track")
 	->
 		( ArgTokens = [] ->
-			Command = mark
+			Command = track_fast
+		;
+			( ArgTokens = [arg("accurate")]
+			; ArgTokens = [arg("a")]
+			)
+		->
+			Command = track_accurate
+		;
+			( ArgTokens = [arg("accurate") | Rest]
+			; ArgTokens = [arg("a") | Rest]
+			)
+		->
+			parse_path(Rest, Path),
+			Command = track_accurate(Path)
 		;
 			parse_path(ArgTokens, Path),
-			Command = mark(Path)
+			Command = track_fast(Path)
 		)
 	;
 		CmdToken = name("mode")
@@ -611,12 +639,12 @@
 % 	io__nl.
 % show_command(cd) -->
 % 	io__write_string("cd\n").
-% show_command(mark(Path)) -->
-% 	io__write_string("mark "),
+% show_command(track(Path)) -->
+% 	io__write_string("track "),
 % 	show_path(Path),
 % 	io__nl.
-% show_command(mark) -->
-% 	io__write_string("mark\n").
+% show_command(track) -->
+% 	io__write_string("track\n").
 % show_command(pwd) -->
 % 	io__write_string("pwd\n").
 % show_command(help) -->
Index: browser/declarative_user.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_user.m,v
retrieving revision 1.53
diff -u -b -r1.53 declarative_user.m
--- browser/declarative_user.m	24 Aug 2005 09:07:08 -0000	1.53
+++ browser/declarative_user.m	29 Oct 2005 09:18:21 -0000
@@ -190,47 +190,65 @@
 	Node = get_decl_question_node(Question),
 	Response = user_answer(Question, skip(Node)).

-handle_command(browse_arg(MaybeArgNum), UserQuestion, Response,
-		!User, !IO) :-
+handle_command(browse_arg(MaybeArgNum), UserQuestion, Response, !User, !IO) :-
 	Question = get_decl_question(UserQuestion),
 	edt_node_trace_atoms(Question, InitAtom, FinalAtom),
 	(
 		MaybeArgNum = yes(ArgNum),
-		browse_atom_argument(InitAtom, FinalAtom, ArgNum, MaybeMark,
+		browse_atom_argument(InitAtom, FinalAtom, ArgNum, MaybeTrack,
 			!User, !IO),
 		(
-			MaybeMark = no,
+			MaybeTrack = no_track,
 			query_user(UserQuestion, Response,
 				!User, !IO)
 		;
-			MaybeMark = yes(Mark),
+			MaybeTrack = track_fast(TermPath),
+			ArgPos = arg_num_to_arg_pos(ArgNum),
+			Node = get_decl_question_node(Question),
+			Answer = suspicious_subterm(Node, ArgPos, TermPath,
+				track_fast),
+			Response = user_answer(Question, Answer)
+		;
+			MaybeTrack = track_accurate(TermPath),
 			ArgPos = arg_num_to_arg_pos(ArgNum),
 			Node = get_decl_question_node(Question),
-			Answer = suspicious_subterm(Node, ArgPos, Mark),
+			Answer = suspicious_subterm(Node, ArgPos, TermPath,
+				track_accurate),
 			Response = user_answer(Question, Answer)
 		)
 	;
 		MaybeArgNum = no,
-		browse_atom(InitAtom, FinalAtom, MaybeMark, !User, !IO),
+		browse_atom(InitAtom, FinalAtom, MaybeTrack, !User, !IO),
 		(
-			MaybeMark = no,
+			MaybeTrack = no_track,
 			query_user(UserQuestion, Response,
 				!User, !IO)
 		;
-			%
-			% If the user marks the predicate or function,
-			% we make the atom erroneous.
-			%
-			MaybeMark = yes([]),
+			MaybeTrack = track_fast([ArgNum | TermPath]),
+			ArgPos = arg_num_to_arg_pos(ArgNum),
 			Node = get_decl_question_node(Question),
-			Answer = truth_value(Node, erroneous),
+			Answer = suspicious_subterm(Node, ArgPos, TermPath,
+				track_fast),
 			Response = user_answer(Question, Answer)
 		;
-			MaybeMark = yes([ArgNum | Mark]),
+			MaybeTrack = track_accurate([ArgNum | TermPath]),
 			ArgPos = arg_num_to_arg_pos(ArgNum),
 			Node = get_decl_question_node(Question),
-			Answer = suspicious_subterm(Node, ArgPos, Mark),
+			Answer = suspicious_subterm(Node, ArgPos, TermPath,
+				track_accurate),
 			Response = user_answer(Question, Answer)
+		;
+			%
+			% Tracking the entire atom doesn't make sense.
+			%
+			( MaybeTrack = track_fast([])
+			; MaybeTrack = track_accurate([])
+			),
+			io.write_string(!.User ^ outstr,
+				"Cannot track the entire atom. " ++
+				"Please select a subterm to track.\n",
+				!IO),
+			query_user(UserQuestion, Response, !User, !IO)
 		)
 	).

@@ -284,7 +302,7 @@
 	Question = get_decl_question(UserQuestion),
 	edt_node_io_actions(Question, MaybeIoActions),
 	% We don't have code yet to trace a marked I/O action.
-	browse_chosen_io_action(MaybeIoActions, ActionNum, _MaybeMark,
+	browse_chosen_io_action(MaybeIoActions, ActionNum, _MaybeTrack,
 		!User, !IO),
 	query_user(UserQuestion, Response, !User, !IO).

@@ -434,25 +452,25 @@
 decl_bug_io_actions(i_bug(inadmissible_call(_, _, _, _)), no).

 :- pred browse_chosen_io_action(maybe(io_action_range)::in, int::in,
-	maybe(term_path)::out, user_state::in, user_state::out,
+	maybe_track_subterm_user::out, user_state::in, user_state::out,
 	io::di, io::uo) is cc_multi.

-browse_chosen_io_action(MaybeIoActions, ActionNum, MaybeMark, !User, !IO) :-
+browse_chosen_io_action(MaybeIoActions, ActionNum, MaybeTrack, !User, !IO) :-
 	(
 		MaybeIoActions = yes(IoActions),
 		find_tabled_io_action(IoActions, ActionNum, MaybeIoAction,
 			!IO),
 		(
 			MaybeIoAction = yes(IoAction),
-			browse_io_action(IoAction, MaybeMark, !User, !IO)
+			browse_io_action(IoAction, MaybeTrack, !User, !IO)
 		;
 			MaybeIoAction = no,
-			MaybeMark = no
+			MaybeTrack = no_track
 		)
 	;
 		MaybeIoActions = no,
 		io.write_string("No such IO action.\n", !IO),
-		MaybeMark = no
+		MaybeTrack = no_track
 	).

 :- pred find_tabled_io_action(io_action_range::in, int::in,
@@ -519,14 +537,15 @@
 		OK = no
 	).

-:- pred browse_io_action(io_action::in, maybe(term_path)::out,
+:- pred browse_io_action(io_action::in, maybe_track_subterm_user::out,
 	user_state::in, user_state::out, io::di, io::uo) is cc_multi.

-browse_io_action(IoAction, MaybeMark, !User, !IO) :-
+browse_io_action(IoAction, MaybeTrack, !User, !IO) :-
 	Term = io_action_to_browser_term(IoAction),
 	browse_browser_term(Term, !.User ^ instr, !.User ^ outstr, no,
-		MaybeDirs, !.User ^ browser, Browser, !IO),
-	maybe_convert_dirs_to_path(MaybeDirs, MaybeMark),
+		MaybeTrackBrowser, !.User ^ browser, Browser, !IO),
+	convert_maybe_track_browser_to_maybe_track_user(MaybeTrackBrowser,
+		MaybeTrack),
 	!:User = !.User ^ browser := Browser.

 :- pred browse_decl_bug(decl_bug::in, maybe(int)::in, user_state::in,
@@ -556,11 +575,16 @@
 		browse_xml_atom(FinalAtom, User, !IO)
 	).

+:- type maybe_track_subterm_user
+	--->	no_track
+	;	track_accurate(term_path)
+	;	track_fast(term_path).
+
 :- pred browse_atom_argument(trace_atom::in, trace_atom::in, int::in,
-	maybe(term_path)::out, user_state::in, user_state::out,
+	maybe_track_subterm_user::out, user_state::in, user_state::out,
 	io::di, io::uo) is cc_multi.

-browse_atom_argument(InitAtom, FinalAtom, ArgNum, MaybeMark, !User, !IO) :-
+browse_atom_argument(InitAtom, FinalAtom, ArgNum, MaybeTrack, !User, !IO) :-
 	FinalAtom = atom(_, Args0),
 	maybe_filter_headvars(chosen_head_vars_presentation, Args0, Args),
 	(
@@ -573,13 +597,14 @@
 			!.User ^ instr, !.User ^ outstr,
 			yes(get_subterm_mode_from_atoms_for_arg(ArgNum,
 				InitAtom, FinalAtom)),
-			MaybeDirs, !.User ^ browser, Browser, !IO),
-		maybe_convert_dirs_to_path(MaybeDirs, MaybeMark),
+			MaybeTrackBrowser, !.User ^ browser, Browser, !IO),
+		convert_maybe_track_browser_to_maybe_track_user(
+			MaybeTrackBrowser, MaybeTrack),
 		!:User = !.User ^ browser := Browser
 	;
 		io.write_string(!.User ^ outstr, "Invalid argument number\n",
 			!IO),
-		MaybeMark = no
+		MaybeTrack = no_track
 	).

 :- pred browse_xml_atom_argument(trace_atom::in, int::in, user_state::in,
@@ -601,10 +626,11 @@
 			!IO)
 	).

-:- pred browse_atom(trace_atom::in, trace_atom::in, maybe(term_path)::out,
+:- pred browse_atom(trace_atom::in, trace_atom::in,
+	maybe_track_subterm_user::out,
 	user_state::in, user_state::out, io::di, io::uo) is cc_multi.

-browse_atom(InitAtom, FinalAtom, MaybeMark, !User, !IO) :-
+browse_atom(InitAtom, FinalAtom, MaybeTrack, !User, !IO) :-
 	FinalAtom = atom(ProcLayout, Args),
 	ProcLabel = get_proc_label_from_layout(ProcLayout),
 	get_user_arg_values(Args, ArgValues),
@@ -615,8 +641,9 @@
 		ArgValues, IsFunction),
 	browse_browser_term(BrowserTerm, !.User ^ instr, !.User ^ outstr,
 		yes(get_subterm_mode_from_atoms(InitAtom, FinalAtom)),
-		MaybeDirs, !.User ^ browser, Browser, !IO),
-	maybe_convert_dirs_to_path(MaybeDirs, MaybeMark),
+		MaybeTrackBrowser, !.User ^ browser, Browser, !IO),
+	convert_maybe_track_browser_to_maybe_track_user(
+		MaybeTrackBrowser, MaybeTrack),
 	!:User = !.User ^ browser := Browser.

 :- pred browse_xml_atom(trace_atom::in, user_state::in, io::di, io::uo)
@@ -727,11 +754,15 @@
 		OK = no
 	).

-:- pred maybe_convert_dirs_to_path(maybe(list(dir))::in,
-	maybe(term_path)::out) is det.
+:- pred convert_maybe_track_browser_to_maybe_track_user(
+	maybe_track_subterm_browser::in, maybe_track_subterm_user::out) is det.

-maybe_convert_dirs_to_path(no, no).
-maybe_convert_dirs_to_path(yes(Dirs), yes(TermPath)) :-
+convert_maybe_track_browser_to_maybe_track_user(no_track, no_track).
+convert_maybe_track_browser_to_maybe_track_user(track_fast(Dirs),
+		track_fast(TermPath)) :-
+	convert_dirs_to_term_path(Dirs, TermPath).
+convert_maybe_track_browser_to_maybe_track_user(track_accurate(Dirs),
+		track_accurate(TermPath)) :-
 	convert_dirs_to_term_path(Dirs, TermPath).

 	% Reverse the first argument and append the second to it.
@@ -1019,7 +1050,7 @@
 		->
 			decl_bug_io_actions(Bug, MaybeIoActions),
 			browse_chosen_io_action(MaybeIoActions, ActionNum,
-				_MaybeMark, !User, !IO),
+				_MaybeTrack, !User, !IO),
 			user_confirm_bug(Bug, Response, !User, !IO)
 		;
 			user_confirm_bug_help(!.User, !IO),
Index: browser/declarative_analyser.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_analyser.m,v
retrieving revision 1.30
diff -u -b -r1.30 declarative_analyser.m
--- browser/declarative_analyser.m	24 Aug 2005 09:07:07 -0000	1.30
+++ browser/declarative_analyser.m	29 Oct 2005 10:08:41 -0000
@@ -145,6 +145,7 @@
 :- import_module mdb.declarative_execution.
 :- import_module mdbcomp.prim_data.
 :- import_module mdbcomp.program_representation.
+:- import_module mdbcomp.rtti_access.

 :- import_module array.
 :- import_module bool.
@@ -200,7 +201,11 @@
 				% This is then used as the next question if the
 				% node that bound the sub-term is trusted or in
 				% an excluded part of the search tree.
-			maybe(suspect_id)
+			maybe(suspect_id),
+
+				% This field specifies the algorithm to use
+				% when tracking the subterm.
+			how_track_subterm
 		)
 			%
 			% Perform a binary search on a path in the search space
@@ -416,7 +421,7 @@
 	yes(Weighting).
 get_maybe_weighting_from_search_mode(top_down) = no.
 get_maybe_weighting_from_search_mode(binary(_, _, _)) = no.
-get_maybe_weighting_from_search_mode(follow_subterm_end(_, _, _, _)) = no.
+get_maybe_weighting_from_search_mode(follow_subterm_end(_, _, _, _, _)) = no.

 reask_last_question(Store, Analyser, Response) :-
 	MaybeLastQuestion = Analyser ^ last_search_question,
@@ -494,8 +499,8 @@
 		SearchSpace),
 	!:Analyser = !.Analyser ^ search_space := SearchSpace.

-process_answer(Store, suspicious_subterm(Node, ArgPos, TermPath), SuspectId,
-		!Analyser) :-
+process_answer(Store, suspicious_subterm(Node, ArgPos, TermPath, HowTrack),
+	SuspectId, !Analyser) :-
 	%
 	% XXX The following 2 lines just done so that debugging info can be
 	% printed for tests run when declarative_analyser.m not compiled with
@@ -505,19 +510,8 @@
 	edt_dependency(Store, Node, ArgPos, TermPath, _, DebugOrigin),
 	!:Analyser = !.Analyser ^ debug_origin := yes(DebugOrigin),

-	edt_subterm_mode(Store, Node, ArgPos, TermPath, Mode),
-	(
-		Mode = subterm_in,
-		assert_suspect_is_inadmissible(SuspectId,
-			!.Analyser ^ search_space, SearchSpace)
-	;
-		Mode = subterm_out,
-		assert_suspect_is_erroneous(SuspectId,
-			!.Analyser ^ search_space, SearchSpace)
-	),
-	!:Analyser = !.Analyser ^ search_space := SearchSpace,
 	!:Analyser = !.Analyser ^ search_mode := follow_subterm_end(SuspectId,
-		ArgPos, TermPath, no).
+		ArgPos, TermPath, no, HowTrack).

 revise_analysis(Store, Response, !Analyser) :-
 	SearchSpace = !.Analyser ^ search_space,
@@ -667,8 +661,8 @@
 search(Store, Oracle, !SearchSpace, SearchMode, FallBackSearchMode,
 		NewMode, Response) :-
 	SearchMode = follow_subterm_end(SuspectId, ArgPos, TermPath,
-		LastUnknown),
-	follow_subterm_end_search(Store, Oracle, !SearchSpace,
+		LastUnknown, HowTrack),
+	follow_subterm_end_search(Store, Oracle, !SearchSpace, HowTrack,
 		LastUnknown, SuspectId, ArgPos, TermPath, FallBackSearchMode,
 		NewMode, Response).

@@ -778,16 +772,31 @@
 	).

 :- pred follow_subterm_end_search(S::in, oracle_state::in,
-	search_space(T)::in, search_space(T)::out,
+	search_space(T)::in, search_space(T)::out, how_track_subterm::in,
 	maybe(suspect_id)::in, suspect_id::in,
 	arg_pos::in, term_path::in, search_mode::in, search_mode::out,
 	search_response::out) is det <= mercury_edt(S, T).

-follow_subterm_end_search(Store, Oracle, !SearchSpace,
+follow_subterm_end_search(Store, Oracle, !SearchSpace, HowTrack,
 		LastUnknown, SuspectId, ArgPos, TermPath, FallBackSearchMode,
 		NewMode, SearchResponse) :-
+	follow_subterm_end_search_2(Store, Oracle, !SearchSpace, HowTrack,
+		map.init, _, LastUnknown, SuspectId, ArgPos, TermPath,
+		FallBackSearchMode, NewMode, SearchResponse).
+
+:- pred follow_subterm_end_search_2(S::in, oracle_state::in,
+	search_space(T)::in, search_space(T)::out, how_track_subterm::in,
+	map(proc_layout, unit)::in, map(proc_layout, unit)::out,
+	maybe(suspect_id)::in, suspect_id::in,
+	arg_pos::in, term_path::in, search_mode::in, search_mode::out,
+	search_response::out) is det <= mercury_edt(S, T).
+
+follow_subterm_end_search_2(Store, Oracle, !SearchSpace, HowTrack,
+		!TriedShortcutProcs, LastUnknown, SuspectId, ArgPos, TermPath,
+		FallBackSearchMode, NewMode, SearchResponse) :-
 	find_subterm_origin(Store, Oracle, SuspectId, ArgPos,
-		TermPath, !SearchSpace, FindOriginResponse),
+		TermPath, HowTrack, !TriedShortcutProcs, !SearchSpace,
+		FindOriginResponse),
 	(
 		FindOriginResponse = primitive_op(BindingSuspectId, FileName,
 			LineNo, PrimOpType, Output),
@@ -863,12 +872,12 @@
 		% subtree has been generated.
 		%
 		NewMode = follow_subterm_end(SuspectId, ArgPos, TermPath,
-			LastUnknown)
+			LastUnknown, HowTrack)
 	;
 		FindOriginResponse = require_explicit_supertree,
 		SearchResponse = require_explicit_supertree,
 		NewMode = follow_subterm_end(SuspectId, ArgPos, TermPath,
-			LastUnknown)
+			LastUnknown, HowTrack)
 	;
 		FindOriginResponse = origin(OriginId, OriginArgPos,
 			OriginTermPath, SubtermMode),
@@ -912,8 +921,9 @@
 			% information to continue (and find_subterm_origin will
 			% respond with not_found).
 			%
-			follow_subterm_end_search(Store, Oracle,
-				!SearchSpace, NewLastUnknown, OriginId,
+			follow_subterm_end_search_2(Store, Oracle,
+				!SearchSpace, HowTrack, !TriedShortcutProcs,
+				NewLastUnknown, OriginId,
 				OriginArgPos, OriginTermPath,
 				FallBackSearchMode, NewMode, SearchResponse)
 		)
@@ -1422,8 +1432,10 @@
 :- func search_mode_to_string(search_mode) = string.

 search_mode_to_string(top_down) = "top down".
-search_mode_to_string(follow_subterm_end(_, _, _, _)) =
-	"tracking marked sub-term".
+search_mode_to_string(follow_subterm_end(_, _, _, _, track_accurate)) =
+	"tracking marked sub-term (using accurate algorithm)".
+search_mode_to_string(follow_subterm_end(_, _, _, _, track_fast)) =
+	"tracking marked sub-term (using fast algorithm)".
 search_mode_to_string(binary(_, _, _)) = "binary search on path".
 search_mode_to_string(divide_and_query(number_of_events)) =
 	"divide and query".
Index: browser/declarative_debugger.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_debugger.m,v
retrieving revision 1.64
diff -u -b -r1.64 declarative_debugger.m
--- browser/declarative_debugger.m	24 Aug 2005 09:07:07 -0000	1.64
+++ browser/declarative_debugger.m	29 Oct 2005 08:53:28 -0000
@@ -183,7 +183,7 @@
 			% value, but is suspicious of the subterm at the
 			% given term_path and arg_pos.
 			%
-	;	suspicious_subterm(T, arg_pos, term_path)
+	;	suspicious_subterm(T, arg_pos, term_path, how_track_subterm)

 			% This node should be ignored.  It cannot contain a bug
 			% but its children may or may not contain a bug.
@@ -193,6 +193,10 @@
 			% The oracle has deferred answering this question.
 	;	skip(T).

+:- type how_track_subterm
+	--->	track_fast
+	;	track_accurate.
+
 	% Answers that are known by the oracle without having to consult the
 	% user, such as answers stored in the knowledge base or answers about
 	% trusted predicates.  mdb.declarative_oracle.answer_known/3 returns
Index: browser/declarative_edt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_edt.m,v
retrieving revision 1.13
diff -u -b -r1.13 declarative_edt.m
--- browser/declarative_edt.m	24 Aug 2005 09:07:07 -0000	1.13
+++ browser/declarative_edt.m	30 Oct 2005 02:20:59 -0000
@@ -62,9 +62,11 @@
 :- import_module mdb.declarative_oracle.
 :- import_module mdbcomp.prim_data.
 :- import_module mdbcomp.program_representation.
+:- import_module mdbcomp.rtti_access.

 :- import_module bool.
 :- import_module list.
+:- import_module map.
 :- import_module std_util.

 	% This typeclass defines how EDTs may be accessed by this module.
@@ -327,20 +329,48 @@
 :- pred skip_suspect(suspect_id::in, search_space(T)::in, search_space(T)::out)
 	is det.

+	% lookup_subterm_node(Store, SuspectId, ArgPos,
+	%	TermPath, SearchSpace, Suspect, Mode, Node):
+	%
+	% Finds the node of the subterm given by SuspectId, ArgPos and
+	% TermPath in its immediate neighbours.
+	%
+:- pred lookup_subterm_node(S::in, suspect_id::in, arg_pos::in, term_path::in,
+	search_space(T)::in, suspect(T)::out, subterm_mode::out, T::out)
+	is det <= mercury_edt(S, T).
+
 	% find_subterm_origin(Store, Oracle, SuspectId, ArgPos,
-	%	TermPath, !SearchSpace, Response).
+	%	TermPath, HowTrack, !TriedShortcutProcs, !SearchSpace,
+	%	Response):
+	%
 	% Finds the origin of the subterm given by SuspectId, ArgPos and
 	% TermPath in its immediate neighbours.  If the children of a suspect
 	% are required then they'll be added to the search space, unless an
 	% explicit subtree is required in which case the appropriate response
 	% is returned (see definition of find_origin_response type below).
 	%
+	% find_subterm_origin can use heuristics to avoid materialising
+	% subtrees unnecessarily.  If the subterm is being tracked through an
+	% output argument, and there is an input argument with the same
+	% name as the output argumnet, except for a numerical suffix, then
+	% find_subterm_origin will check if the subterm appears in the same
+	% position in the input argument.  If it does then it will continue
+	% tracking the subterm in the input argument, thus bypassing the
+	% subtree rooted at the call.  Since dereferencing a subterm in a
+	% large structure can be expensive, find_subterm_origin will only
+	% try to bypass calls to procedures it has not tried to bypass
+	% before.  The HowTrack argument specfies whether to use the bypassing
+	% heuristics and !TriedShortcutProcs keeps track of which procedures'
+	% calls it has already tried to bypass.
+	%
 :- pred find_subterm_origin(S::in, oracle_state::in,
-	suspect_id::in, arg_pos::in, term_path::in, search_space(T)::in,
-	search_space(T)::out, find_origin_response::out)
+	suspect_id::in, arg_pos::in, term_path::in, how_track_subterm::in,
+	map(proc_layout, unit)::in, map(proc_layout, unit)::out,
+	search_space(T)::in, search_space(T)::out, find_origin_response::out)
 	is det <= mercury_edt(S, T).

 :- type find_origin_response
+
 			% The origin couldn't be found because of insufficient
 			% tracing information.
 	--->	not_found
@@ -540,14 +570,18 @@
 :- implementation.

 :- import_module bimap.
+:- import_module char.
 :- import_module counter.
 :- import_module exception.
 :- import_module float.
 :- import_module int.
-:- import_module map.
+:- import_module svmap.
 :- import_module std_util.
 :- import_module string.

+:- import_module mdb.declarative_execution.
+:- import_module mdb.term_rep.
+
 	% A suspect is an edt node with some additional information relevant
 	% to the bug search.
 	%
@@ -931,11 +965,9 @@
 		FinishId = StartId
 	).

-find_subterm_origin(Store, Oracle, SuspectId, ArgPos, TermPath,
-		!SearchSpace, Response) :-
-	lookup_suspect(!.SearchSpace, SuspectId, Suspect),
-	ImplicitToExplicit = !.SearchSpace ^
-		implicit_roots_to_explicit_roots,
+lookup_subterm_node(Store, SuspectId, ArgPos, TermPath, SearchSpace, Suspect,
+		Mode, Node) :-
+	lookup_suspect(SearchSpace, SuspectId, Suspect),
 	% The node in the search space will be the explicit version.
 	ExplicitNode = Suspect ^ edt_node,
 	edt_subterm_mode(Store, ExplicitNode, ArgPos, TermPath, Mode),
@@ -948,19 +980,25 @@
 	%
 	(
 		Mode = subterm_in,
+		ImplicitToExplicit = SearchSpace ^
+			implicit_roots_to_explicit_roots,
 		bimap.search(ImplicitToExplicit, ImplicitNode, ExplicitNode)
 	->
 		Node = ImplicitNode
 	;
 		Node = ExplicitNode
-	),
+	).
+
+find_subterm_origin(Store, Oracle, SuspectId, ArgPos, TermPath, HowTrack,
+		!TriedShortcutProcs, !SearchSpace, Response) :-
+	lookup_subterm_node(Store, SuspectId, ArgPos, TermPath,
+		!.SearchSpace, Suspect, Mode, Node),
 	(
 		Mode = subterm_in,
 		(
 			Suspect ^ parent = yes(ParentId),
-			resolve_origin(Store, Oracle, Node,
-				ArgPos, TermPath, ParentId, no, !SearchSpace,
-				Response)
+			resolve_origin(Store, Oracle, Node, ArgPos, TermPath,
+				ParentId, no, !SearchSpace, Response)
 		;
 			Suspect ^ parent = no,
 			(
@@ -977,9 +1015,27 @@
 		)
 	;
 		Mode = subterm_out,
+		(
+			HowTrack = track_accurate,
 		resolve_origin(Store, Oracle, Node, ArgPos,
 			TermPath, SuspectId, yes, !SearchSpace,
 			Response)
+		;
+			HowTrack = track_fast,
+			subterm_is_in_input_with_same_prefix(Store, Node,
+				ArgPos, TermPath, !TriedShortcutProcs,
+				MaybeInputArgPos),
+			(
+				MaybeInputArgPos = yes(InputArgPos),
+				Response = origin(SuspectId, InputArgPos,
+					TermPath, subterm_in)
+			;
+				MaybeInputArgPos = no,
+				resolve_origin(Store, Oracle, Node, ArgPos,
+					TermPath, SuspectId, yes, !SearchSpace,
+					Response)
+			)
+		)
 	).

 	% resolve_origin(Store, Oracle, Node, ArgPos, TermPath,
@@ -994,7 +1050,8 @@
 	%
 :- pred resolve_origin(S::in, oracle_state::in, T::in,
 	arg_pos::in, term_path::in, suspect_id::in, bool::in,
-	search_space(T)::in, search_space(T)::out, find_origin_response::out)
+	search_space(T)::in, search_space(T)::out,
+	find_origin_response::out)
 	is det <= mercury_edt(S, T).

 resolve_origin(Store, Oracle, Node, ArgPos, TermPath, SuspectId,
@@ -1046,6 +1103,46 @@
 		Response = require_explicit_subtree
 	).

+:- pred subterm_is_in_input_with_same_prefix(S::in, T::in, arg_pos::in,
+	term_path::in, map(proc_layout, unit)::in, map(proc_layout, unit)::out,
+	maybe(arg_pos)::out) is det <= mercury_edt(S, T).
+
+subterm_is_in_input_with_same_prefix(Store, Node, OutputArgPos, TermPath,
+		!TriedProcs, MaybeInitialVersionArgPos) :-
+	edt_question(Store, Node, Question),
+	(
+		Question = wrong_answer(_, _, FinalDeclAtom),
+		FinalDeclAtom = final_decl_atom(FinalAtom, _),
+		FinalAtom = atom(ProcLayout, FinalArgs),
+		not map.search(!.TriedProcs, ProcLayout, _)
+	->
+		svmap.det_insert(ProcLayout, unit, !TriedProcs),
+		(
+			absolute_arg_num(OutputArgPos, FinalAtom,
+				OutputArgNum),
+			select_arg_at_pos(OutputArgPos, FinalArgs, OutputArg),
+			OutputArg = arg_info(_, _, yes(OutputTermRep)),
+			find_initial_version_arg_num(ProcLayout, OutputArgNum,
+				InitialVersionArgNum),
+			deref_path(OutputTermRep, TermPath, OutputSubtermRep),
+			InitialVersionArgPos = any_head_var(
+				InitialVersionArgNum),
+			select_arg_at_pos(InitialVersionArgPos, FinalArgs,
+				InitialVersionArg),
+			InitialVersionArg = arg_info(_, _,
+				yes(InitialVersionTermRep)),
+			deref_path(InitialVersionTermRep, TermPath,
+				InitialVersionSubtermRep),
+			InitialVersionSubtermRep = OutputSubtermRep
+		->
+			MaybeInitialVersionArgPos = yes(InitialVersionArgPos)
+		;
+			MaybeInitialVersionArgPos = no
+		)
+	;
+		MaybeInitialVersionArgPos = no
+	).
+
 	% Returns the suspect id in the given list that refers to the given edt
 	% node or fails if it can't find such a suspect in the list.
 	%
Index: browser/declarative_oracle.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_oracle.m,v
retrieving revision 1.47
diff -u -b -r1.47 declarative_oracle.m
--- browser/declarative_oracle.m	24 Aug 2005 09:07:07 -0000	1.47
+++ browser/declarative_oracle.m	29 Oct 2005 08:55:56 -0000
@@ -613,7 +613,7 @@
 		oracle_kb).
 :- mode assert_oracle_kb(in, in, in, out) is det.

-assert_oracle_kb(_, suspicious_subterm(_, _, _), KB, KB).
+assert_oracle_kb(_, suspicious_subterm(_, _, _, _), KB, KB).

 assert_oracle_kb(_, ignore(_), KB, KB).

Index: browser/term_rep.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/term_rep.m,v
retrieving revision 1.4
diff -u -b -r1.4 term_rep.m
--- browser/term_rep.m	11 Jul 2005 07:30:21 -0000	1.4
+++ browser/term_rep.m	30 Oct 2005 02:26:33 -0000
@@ -19,6 +19,9 @@

 :- interface.

+:- import_module mdbcomp.
+:- import_module mdbcomp.program_representation.
+
 :- import_module std_util.

 :- type term_rep.
@@ -27,10 +30,15 @@

 :- pred rep_to_univ(term_rep::in, univ::out) is det.

+:- pred deref_path(term_rep::in, term_path::in, term_rep::out) is semidet.
+
 %-----------------------------------------------------------------------------%

 :- implementation.

+:- import_module int.
+:- import_module list.
+
 :- type term_rep
 	---> term_rep(univ)
 	where
@@ -60,3 +68,24 @@
 	Univ = promise_only_solution(
 		pred(U::out) is cc_multi :- Rep = term_rep(U)
 	).
+
+deref_path(Term, Path, SubTerm):-
+	(
+		Path = [],
+		SubTerm = Term
+	;
+		Path = [Head | Tail],
+		%
+		% There is only one representation of a subterm, given
+		% the representation of the containing term and a term path.
+		%
+		promise_equivalent_solutions [NextSubTerm] (
+			rep_to_univ(Term, Univ),
+			% Argument indexes in the term path start from one, but
+			% the argument function wants argument indexes to
+			% start from zero.
+			SubUniv = argument(univ_value(Univ), Head - 1),
+			univ_to_rep(SubUniv, NextSubTerm)
+		),
+		deref_path(NextSubTerm, Tail, SubTerm)
+	).
Index: mdbcomp/rtti_access.m
===================================================================
RCS file: /home/mercury1/repository/mercury/mdbcomp/rtti_access.m,v
retrieving revision 1.3
diff -u -b -r1.3 rtti_access.m
--- mdbcomp/rtti_access.m	5 Oct 2005 06:34:17 -0000	1.3
+++ mdbcomp/rtti_access.m	30 Oct 2005 02:29:49 -0000
@@ -44,6 +44,24 @@

 :- func get_proc_name(proc_label) = string.

+    % find_initial_version_arg_num(Proc, OutputArgNum, InputArgNum).
+    % Given a procedure and an output argument number of that procedure,
+    % find an input argument which has the same name as the output argument,
+    % expect for a numerical suffix and possibly an underscore.  The output
+    % argument name needn't have a numerical suffix, but if it does, then the
+    % input argument's numerical suffix should be less that the numerical
+    % suffix of the output argument.  This procedure is used as a heuristic to
+    % determine when it is worth checking if a subterm appearing in the output
+    % argument also appears in the same position in the input argument.  The
+    % heuristic is used by the subterm dependency tracking algorithm to help
+    % speed up the search.
+    % Argument numbers start at one.
+    % This procedure is implemented in C to avoid having to allocate
+    % memory to import non word-aligned strings into Mercury code.
+    %
+:- pred find_initial_version_arg_num(proc_layout::in, int::in, int::out)
+    is semidet.
+
 :- func get_all_modes_for_layout(proc_layout) = list(proc_layout).

 %-----------------------------------------------------------------------------%
@@ -194,6 +212,140 @@
 ").

 :- pragma foreign_proc("C",
+    find_initial_version_arg_num(Layout::in, OutArgNum::in, InArgNum::out),
+    [will_not_call_mercury, thread_safe, promise_pure],
+"
+    const MR_Proc_Layout    *proc;
+    int         out_hlds_num;
+    const char      *out_name;
+
+    proc = Layout;
+
+    if (! MR_PROC_LAYOUT_HAS_EXEC_TRACE(proc)) {
+        MR_fatal_error(""find_initial_version_arg_num: proc"");
+    }
+
+    out_hlds_num = proc->MR_sle_head_var_nums[OutArgNum - 1];
+    out_name = MR_hlds_var_name(proc, out_hlds_num);
+    if (out_name == NULL || MR_streq(out_name, """")) {
+        /* out_hlds_num was not named by the user */
+        SUCCESS_INDICATOR = MR_FALSE;
+    } else {
+        int                     out_base_name_len;
+        int                     out_numerical_suffix;
+        int                     num_matches;
+        int                     in_hlds_num;
+        int                     in_arg_num;
+        const char              *in_name;
+        int                     start_of_num;
+        int                     in_numerical_suffix;
+        int                     head_var_num;
+        int                     call_var_num;
+        int                     call_num_vars;
+        const MR_Label_Layout   *call_label;
+        MR_bool                 found;
+
+        start_of_num = MR_find_start_of_num_suffix(out_name);
+        if (start_of_num < 0) {
+            out_base_name_len = strlen(out_name);
+            out_numerical_suffix = -1;
+        } else {
+            out_base_name_len = start_of_num;
+            out_numerical_suffix = atoi(out_name + start_of_num);
+        }
+
+        num_matches = 0;
+        in_arg_num = -1;
+
+        for (head_var_num = 0; head_var_num < proc->MR_sle_num_head_vars;
+            head_var_num++)
+        {
+            in_hlds_num = proc->MR_sle_head_var_nums[head_var_num];
+            in_name = MR_hlds_var_name(proc, in_hlds_num);
+            if (in_name == NULL || MR_streq(in_name, """")) {
+                continue;
+            }
+
+            start_of_num = MR_find_start_of_num_suffix(in_name);
+            if (start_of_num < 0) {
+                continue;
+            }
+
+            if (! (
+                    (
+                        /*
+                        ** The names are exactly the same except
+                        ** for the numerical suffix.
+                        */
+                        start_of_num == out_base_name_len &&
+                        strneq(out_name, in_name, start_of_num)
+                    )
+                ||
+                    (
+                        /*
+                        ** The names are exactly the same except
+                        ** for an underscore and the numerical suffix
+                        ** (as is the case with state variable notation).
+                        */
+                        start_of_num == out_base_name_len + 1 &&
+                        start_of_num > 0 &&
+                        in_name[start_of_num - 1] == '_' &&
+                        strneq(out_name, in_name, start_of_num - 1)
+                    )
+                ))
+            {
+                continue;
+            }
+
+            in_numerical_suffix = atoi(in_name + start_of_num);
+            if (! ((in_numerical_suffix >= out_numerical_suffix)
+                || (out_numerical_suffix < 0)))
+            {
+                continue;
+            }
+
+            call_label = proc->MR_sle_call_label;
+            if (! MR_has_valid_var_count(call_label)) {
+                    continue;
+            }
+
+            if (! MR_has_valid_var_info(call_label)) {
+                continue;
+            }
+
+            /*
+            ** The in_hlds_num has the same prefix as the output variable.
+            ** Check if in_hlds_num is an input argument.
+            */
+            call_num_vars = MR_all_desc_var_count(call_label);
+            found = MR_FALSE;
+            for (call_var_num = 0 ; call_var_num < call_num_vars;
+                    call_var_num++)
+            {
+                if (call_label->MR_sll_var_nums[call_var_num] == in_hlds_num) {
+                    found = MR_TRUE;
+                    break;
+                }
+            }
+
+            if (! found) {
+                continue;
+            }
+
+            num_matches++;
+            in_arg_num = head_var_num;
+        }
+
+        if (num_matches == 1) {
+            InArgNum = in_arg_num + 1;
+            SUCCESS_INDICATOR = MR_TRUE;
+        } else {
+            SUCCESS_INDICATOR = MR_FALSE;
+        }
+    }
+").
+
+:- pragma foreign_proc("C",
     get_all_modes_for_layout(Layout::in) = (Layouts::out),
     [will_not_call_mercury, thread_safe, promise_pure],
 "
Index: runtime/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/Mmakefile,v
retrieving revision 1.126
diff -u -b -r1.126 Mmakefile
--- runtime/Mmakefile	12 Sep 2005 03:03:04 -0000	1.126
+++ runtime/Mmakefile	29 Oct 2005 03:53:48 -0000
@@ -179,6 +179,7 @@
 			mercury_runtime_util.c	\
 			mercury_signal.c	\
 			mercury_stacks.c	\
+			mercury_stack_layout.c	\
 			mercury_stack_trace.c	\
 			mercury_string.c	\
 			mercury_tabling.c	\
Index: runtime/mercury_layout_util.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_layout_util.h,v
retrieving revision 1.23
diff -u -b -r1.23 mercury_layout_util.h
--- runtime/mercury_layout_util.h	21 Jun 2005 03:12:02 -0000	1.23
+++ runtime/mercury_layout_util.h	29 Oct 2005 03:53:48 -0000
@@ -1,4 +1,7 @@
 /*
+** vim:sw=4 ts=4 expandtab
+*/
+/*
 ** Copyright (C) 1998-2003, 2005 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
@@ -75,7 +78,6 @@
 					const MR_Type_Param_Locns *tvar_locns,
 					MR_Word *answer_block, int block_size);

-
 /*
 ** If the given encoded location refers to a register, return its number.
 ** If it does not, return -1.
@@ -150,8 +152,7 @@
 			MR_TypeInfo *type_info);

 /*
-** MR_write_variable:
-**	Write a variable to stdout.
+** MR_write_variable: write a variable to stdout.
 **	This uses the fake_reg copies of the registers,
 **	and it may also clobber the real registers.
 */
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.95
diff -u -b -r1.95 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h	5 Oct 2005 06:34:20 -0000	1.95
+++ runtime/mercury_stack_layout.h	29 Oct 2005 03:53:48 -0000
@@ -955,6 +955,23 @@
 		? 1 : 0))

 /*
+** Return the name (if any) of the variable with the given HLDS variable number
+** in the procedure indicated by the first argument.
+*/
+
+extern	MR_ConstString	MR_hlds_var_name(const MR_Proc_Layout *entry,
+				int hlds_var_num);
+
+/*
+** Given a string, see whether its end consists a sequence of digits.
+** If yes, return the offset of the first digit in this sequence relative
+** to the start of the string. Otherwise, return a negative number.
+*/
+
+extern	int		MR_find_start_of_num_suffix(const char *str);
+
+
+/*
 ** Define a layout structure for a procedure, containing information
 ** for stack traversal and procedure identification.
 **
Index: trace/mercury_trace_vars.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_vars.c,v
retrieving revision 1.67
diff -u -b -r1.67 mercury_trace_vars.c
--- trace/mercury_trace_vars.c	27 Sep 2005 06:20:54 -0000	1.67
+++ trace/mercury_trace_vars.c	29 Oct 2005 06:29:23 -0000
@@ -335,12 +335,8 @@
     int                     i;
     int                     slot;
     int                     slot_max;
-    int                     copylen;
     char                    *copy;
-    char                    *s;
     const char              *name;
-    const char              *string_table;
-    MR_Integer              string_table_size;
     const char              *filename;
     int                     linenumber;

@@ -415,39 +411,20 @@
         MR_free(MR_point.MR_point_vars[slot].MR_var_basename);
     }

-    string_table = entry->MR_sle_module_layout->MR_ml_string_table;
-    string_table_size = entry->MR_sle_module_layout->MR_ml_string_table_size;
-
     MR_proc_id_arity_addedargs_predfunc(entry, &arity, &num_added_args,
         &pred_or_func);

     slot = 0;
     for (i = 0; i < var_count; i++) {
-        int var_num;
+        int     hlds_var_num;
         int head_var_num;
-        int offset;
-
-        var_num = level_layout->MR_sll_var_nums[i];
-
-        if (var_num == 0) {
-            /* this value is not a variable */
-            continue;
-        }
-
-        if (var_num > entry->MR_sle_max_named_var_num) {
-            /* this value is a compiler-generated variable */
-            continue;
-        }
-
-        /* the offset of variable number 1 is stored at index 0 */
-        offset = entry->MR_sle_used_var_names[var_num - 1];
-        if (offset > string_table_size) {
-            MR_fatal_error("array bounds error on string table");
-        }
+        int     start_of_num;
+        char    *num_addr;

-        name = string_table + offset;
+        hlds_var_num = level_layout->MR_sll_var_nums[i];
+        name = MR_hlds_var_name(entry, hlds_var_num);
         if (name == NULL || MR_streq(name, "")) {
-            /* this value is a compiler-generated variable */
+            /* this value is not a variable or is not named by the user */
             continue;
         }

@@ -463,7 +440,7 @@
             continue;
         }

-        MR_point.MR_point_vars[slot].MR_var_hlds_number = var_num;
+        MR_point.MR_point_vars[slot].MR_var_hlds_number = hlds_var_num;
         MR_point.MR_point_vars[slot].MR_var_seq_num_in_label = i;

         copy = MR_copy_string(name);
@@ -473,25 +450,22 @@

         /* we need another copy we can cut apart */
         copy = MR_copy_string(name);
-        copylen = strlen(copy);
-        s = copy + copylen - 1;
-        while (s > copy && MR_isdigit(*s)) {
-            s--;
-        }
+        start_of_num = MR_find_start_of_num_suffix(copy);

-        if (s == copy + copylen - 1) {
+        if (start_of_num < 0) {
             MR_point.MR_point_vars[slot].MR_var_has_suffix = MR_FALSE;
             /* num_suffix should not be used */
             MR_point.MR_point_vars[slot].MR_var_num_suffix = -1;
             MR_point.MR_point_vars[slot].MR_var_basename = copy;
         } else {
-            if (MR_isdigit(*s)) {
+            if (start_of_num == 0) {
                 MR_fatal_error("variable name starts with digit");
             }

+            num_addr = copy + start_of_num;
             MR_point.MR_point_vars[slot].MR_var_has_suffix = MR_TRUE;
-            MR_point.MR_point_vars[slot].MR_var_num_suffix = atoi(s + 1);
-            *(s + 1) = '\0';
+            MR_point.MR_point_vars[slot].MR_var_num_suffix = atoi(num_addr);
+            *num_addr = '\0';
             MR_point.MR_point_vars[slot].MR_var_basename = copy;
         }

@@ -500,7 +474,7 @@
             head_var_num < entry->MR_sle_num_head_vars;
             head_var_num++)
         {
-            if (entry->MR_sle_head_var_nums[head_var_num] == var_num) {
+            if (entry->MR_sle_head_var_nums[head_var_num] == hlds_var_num) {
                 MR_point.MR_point_vars[slot].MR_var_is_headvar =
                     head_var_num - num_added_args + 1;
                 break;
@@ -1473,30 +1447,6 @@
     return NULL;
 }

-MR_ConstString
-MR_hlds_var_name(const MR_Proc_Layout *entry, int hlds_var_num)
-{
-    const char  *string_table;
-    MR_Integer  string_table_size;
-    int         offset;
-
-    string_table = entry->MR_sle_module_layout->MR_ml_string_table;
-    string_table_size = entry->MR_sle_module_layout->MR_ml_string_table_size;
-
-    if (hlds_var_num > entry->MR_sle_max_named_var_num) {
-        /* this value is a compiler-generated variable */
-        return NULL;
-    }
-
-    /* variable number 1 is stored at offset 0 */
-    offset = entry->MR_sle_used_var_names[hlds_var_num - 1];
-    if (offset > string_table_size) {
-        MR_fatal_error("array bounds error on string table");
-    }
-
-    return string_table + offset;
-}
-
 MR_Completer_List *
 MR_trace_var_completer(const char *word, size_t word_len)
 {
Index: trace/mercury_trace_vars.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_vars.h,v
retrieving revision 1.28
diff -u -b -r1.28 mercury_trace_vars.h
--- trace/mercury_trace_vars.h	11 Jul 2005 07:30:31 -0000	1.28
+++ trace/mercury_trace_vars.h	29 Oct 2005 06:26:46 -0000
@@ -128,7 +128,7 @@
 extern	const char 	*MR_trace_list_var_details(FILE *out);

 /*
-** Return as a side effect the type and value of the variable with the
+** Return as a side effect the name, type and value of the variable with the
 ** specified HLDS number, in the specified locations, all of which must be
 ** non-NULL. If the variable isn't live or isn't known, return a non-null
 ** string giving the problem.
@@ -326,15 +326,6 @@
 				const char **functor_ptr,
 				MR_Word *arg_list_ptr, MR_bool *is_func_ptr);

-
-/*
-** Return the name (if any) of the variable with the given HLDS variable number
-** in the procedure indicated by the first argument.
-*/
-
-extern	MR_ConstString	MR_hlds_var_name(const MR_Proc_Layout *entry,
-				int hlds_var_num);
-
 /*
 ** A Readline completer for variable names.
 */
Index: tests/debugger/declarative/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/Mmakefile,v
retrieving revision 1.83
diff -u -b -r1.83 Mmakefile
--- tests/debugger/declarative/Mmakefile	10 Oct 2005 12:00:16 -0000	1.83
+++ tests/debugger/declarative/Mmakefile	27 Oct 2005 13:30:24 -0000
@@ -50,6 +50,7 @@
 	mismatch_on_call	\
 	negation		\
 	neg_conj		\
+	nodescend_tracking	\
 	oracle_db		\
 	output_term_dep		\
 	partial			\
@@ -387,6 +388,11 @@
 	$(MDB) ./neg_conj < neg_conj.inp > neg_conj.out 2>&1 \
 	|| { grep . $@ /dev/null; exit 1; }

+nodescend_tracking.out: nodescend_tracking nodescend_tracking.inp
+	$(MDB_STD) ./nodescend_tracking < nodescend_tracking.inp \
+		> nodescend_tracking.out 2>&1 \
+	|| { grep . $@ /dev/null; exit 1; }
+
 negation.out: negation negation.inp
 	$(MDB) ./negation < negation.inp > negation.out 2>&1 \
 	|| { grep . $@ /dev/null; exit 1; }
Index: tests/debugger/declarative/nodescend_tracking.exp
===================================================================
RCS file: tests/debugger/declarative/nodescend_tracking.exp
diff -N tests/debugger/declarative/nodescend_tracking.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/declarative/nodescend_tracking.exp	29 Oct 2005 09:40:59 -0000
@@ -0,0 +1,39 @@
+      E1:     C1 CALL pred nodescend_tracking.main/2-0 (det) nodescend_tracking.m:24
+mdb> mdb> echo on
+Command echo enabled.
+mdb> table_io allow
+mdb> table_io start
+I/O tabling started.
+mdb> break run_test
+ 0: + stop  interface pred nodescend_tracking.run_test/3-0 (det)
+mdb> continue
+      E2:     C2 CALL pred nodescend_tracking.run_test/3-0 (det) nodescend_tracking.m:31 (nodescend_tracking.m:25)
+mdb> delete *
+ 0: E stop  interface pred nodescend_tracking.run_test/3-0 (det)
+mdb> finish
+
+*** called untabled_print ***
+      E3:     C2 EXIT pred nodescend_tracking.run_test/3-0 (det) nodescend_tracking.m:31 (nodescend_tracking.m:25)
+mdb> dd -d 1 -n 1000 -a
+
+*** called untabled_print ***
+run_test([reverse(2, 1), reverse(2, 1), reverse(2, 1), reverse(2, 1), reverse(2, 1), reverse(2, 1), reverse(2, 1), reverse(2, 1), ...], _, _)
+Valid? browse 1
+browser> cdr 9999 2
+browser> cd 1
+browser> ls
+leave(1, 2)
+browser> track
+make_test_list(1) = [leave(1, 2)]
+Valid? info
+Context of current question : nodescend_tracking.m:64 (nodescend_tracking.m:65)
+Search mode                 : top down
+The current question was chosen because the marked subterm was bound by
+the unification inside the function nodescend_tracking.make_test_list/2
+(nodescend_tracking.m:63). The path to the subterm in the atom is 2/1.
+dd> quit
+Diagnosis aborted.
+
+*** called untabled_print ***
+      E3:     C2 EXIT pred nodescend_tracking.run_test/3-0 (det) nodescend_tracking.m:31 (nodescend_tracking.m:25)
+mdb> quit -y
Index: tests/debugger/declarative/nodescend_tracking.inp
===================================================================
RCS file: tests/debugger/declarative/nodescend_tracking.inp
diff -N tests/debugger/declarative/nodescend_tracking.inp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/declarative/nodescend_tracking.inp	29 Oct 2005 09:36:11 -0000
@@ -0,0 +1,17 @@
+register --quiet
+echo on
+table_io allow
+table_io start
+break run_test
+continue
+delete *
+finish
+dd -d 1 -n 1000 -a
+browse 1
+cdr 9999 2
+cd 1
+ls
+track
+info
+quit
+quit -y
Index: tests/debugger/declarative/nodescend_tracking.m
===================================================================
RCS file: tests/debugger/declarative/nodescend_tracking.m
diff -N tests/debugger/declarative/nodescend_tracking.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/declarative/nodescend_tracking.m	29 Oct 2005 09:36:50 -0000
@@ -0,0 +1,79 @@
+% Test an optimisation to the subterm dependency tracking where
+% the tracking algorithm checks to see if the subterm it is tracking in
+% an output argument appears in the same position in an input argument.  If
+% it doesm then the algorithm can continue tracking the subterm in the
+% input and needn't generated any descendent nodes.
+% The algorithm checks only input variables that differ from the output
+% variable by a numerical suffix.
+%
+
+:- module nodescend_tracking.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module list, int.
+
+:- type t ---> reverse(int, int) ; leave(int, int).
+
+main(!IO) :-
+	run_test(List, !IO),
+	io.write_int(list.length(List), !IO),
+	nl(!IO).
+
+:- pred run_test(list(t)::out, io::di, io::uo) is det.
+
+run_test(List, !IO) :-
+	make_test_list(10000) = List0,
+	change(List0, List, !IO).
+
+:- pred change(list(t)::in, list(t)::out, io::di, io::uo) is det.
+
+change(!List, !IO) :-
+	(
+		!.List = []
+	;
+		!.List = [Head | Tail],
+		change(Tail, Rest, !IO),
+		(
+			Head = reverse(X, Y),
+			!:List = [reverse(Y, X) | Rest]
+		;
+			Head = leave(_, _),
+			%
+			% The test case will track the leave/2 term, so
+			% if the optimisation works then this code should
+			% not be reexecuted by the debugger when tracking
+			% the term.
+			%
+			untabled_print(!IO),
+			!:List = [Head | Rest]
+		)
+	).
+
+:- func make_test_list(int) = list(t).
+
+make_test_list(NumElements) = List :-
+	( NumElements =< 1 ->
+		List = [leave(1, 2)]
+	;
+		List = [reverse(1, 2) | make_test_list(NumElements - 1)]
+	).
+
+:- pred untabled_print(io::di, io::uo) is det.
+
+	% untabled_print is intentionally not tabled.
+	% We use it to check when a piece of code is reexecuted by the
+	% debugger.
+:- pragma foreign_proc("C",
+	untabled_print(IO0::di, IO::uo),
+	[will_not_call_mercury, promise_pure, thread_safe],
+"
+	printf(\"\\n*** called untabled_print ***\\n\");
+	IO = IO0;
+").
Index: tests/debugger/mdb_command_test.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/mdb_command_test.inp,v
retrieving revision 1.47
diff -u -b -r1.47 mdb_command_test.inp
--- tests/debugger/mdb_command_test.inp	25 Oct 2005 04:00:53 -0000	1.47
+++ tests/debugger/mdb_command_test.inp	30 Oct 2005 01:39:43 -0000
@@ -8,7 +8,7 @@
 browse               xyzzy xyzzy xyzzy xyzzy xyzzy
 print                xyzzy xyzzy xyzzy xyzzy xyzzy
 set                  xyzzy xyzzy xyzzy xyzzy xyzzy
-mark                 xyzzy xyzzy xyzzy xyzzy xyzzy
+track                xyzzy xyzzy xyzzy xyzzy xyzzy
 pd                   xyzzy xyzzy xyzzy xyzzy xyzzy
 quit                 xyzzy xyzzy xyzzy xyzzy xyzzy
 info                 xyzzy xyzzy xyzzy xyzzy xyzzy
Index: tests/debugger/declarative/Mercury.options
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/Mercury.options,v
retrieving revision 1.11
diff -u -b -r1.11 Mercury.options
--- tests/debugger/declarative/Mercury.options	28 Sep 2005 12:20:03 -0000	1.11
+++ tests/debugger/declarative/Mercury.options	29 Oct 2005 14:54:50 -0000
@@ -1,5 +1,7 @@
 MCFLAGS-deep_sub=--trace rep --suppress-trace context
+MCFLAGS-nodescend_tracking=--trace rep --trace-table-io-all
 MCFLAGS-shallow_2=--trace shallow
+MCFLAGS-special_term_dep=--trace rep --trace-table-io-all
 MCFLAGS-tabled_read_decl=--trace rep --trace-table-io-all
 MCFLAGS-tabled_read_decl_goto=--trace rep --trace-table-io-all
 MCFLAGS-untraced_subgoal_sub=--trace minimum
Index: tests/debugger/declarative/binary_search.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/binary_search.exp,v
retrieving revision 1.5
diff -u -b -r1.5 binary_search.exp
--- tests/debugger/declarative/binary_search.exp	19 Aug 2005 16:08:29 -0000	1.5
+++ tests/debugger/declarative/binary_search.exp	29 Oct 2005 09:33:28 -0000
@@ -11,7 +11,7 @@
 mdb> dd -d 3 -n 7
 a(yes)
 Valid? b 1
-browser> mark
+browser> track --accurate
 silly_even(0, yes)
 Valid? mode binary
 sillier_even(502, yes)
@@ -52,7 +52,7 @@
 mdb> dd -d 3 -n 7
 b(yes)
 Valid? b 1
-browser> mark
+browser> track --accurate
 Found incorrect contour:
 silly_even(618, yes)
 silly_even(619, yes)
@@ -77,7 +77,7 @@
 browser> ls
 [11]
 browser> cd 1
-browser> mark
+browser> track --accurate
 add1s([10], [11])
 Valid? mode binary
 add1s([5, 6, 7, 8, 9, 10], [6, ...])
Index: tests/debugger/declarative/binary_search.exp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/binary_search.exp2,v
retrieving revision 1.5
diff -u -b -r1.5 binary_search.exp2
--- tests/debugger/declarative/binary_search.exp2	19 Aug 2005 16:08:30 -0000	1.5
+++ tests/debugger/declarative/binary_search.exp2	29 Oct 2005 09:33:28 -0000
@@ -11,7 +11,7 @@
 mdb> dd -d 3 -n 7
 a(yes)
 Valid? b 1
-browser> mark
+browser> track --accurate
 silly_even(0, yes)
 Valid? mode binary
 sillier_even(502, yes)
@@ -54,7 +54,7 @@
 mdb> dd -d 3 -n 7
 b(yes)
 Valid? b 1
-browser> mark
+browser> track --accurate
 Found incorrect contour:
 >(619, 0)
 -(619, 1) = 618
@@ -81,7 +81,7 @@
 browser> ls
 [11]
 browser> cd 1
-browser> mark
+browser> track --accurate
 add1s([10], [11])
 Valid? mode binary
 add1s([5, 6, 7, 8, 9, 10], [6, ...])
Index: tests/debugger/declarative/binary_search.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/binary_search.inp,v
retrieving revision 1.4
diff -u -b -r1.4 binary_search.inp
--- tests/debugger/declarative/binary_search.inp	19 Aug 2005 16:08:30 -0000	1.4
+++ tests/debugger/declarative/binary_search.inp	29 Oct 2005 09:32:40 -0000
@@ -6,7 +6,7 @@
 f
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
 mode binary
 y
 n
@@ -26,7 +26,7 @@
 f
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
 y
 delete 1
 break add1s
@@ -39,7 +39,7 @@
 cdr 9 2
 ls
 cd 1
-mark
+track --accurate
 mode binary
 n
 y
Index: tests/debugger/declarative/binary_search.inp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/binary_search.inp2,v
retrieving revision 1.4
diff -u -b -r1.4 binary_search.inp2
--- tests/debugger/declarative/binary_search.inp2	19 Aug 2005 16:08:30 -0000	1.4
+++ tests/debugger/declarative/binary_search.inp2	29 Oct 2005 09:32:40 -0000
@@ -6,7 +6,7 @@
 f
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
 mode binary
 y
 n
@@ -26,7 +26,7 @@
 f
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
 y
 delete 1
 break add1s
@@ -39,7 +39,7 @@
 cdr 9 2
 ls
 cd 1
-mark
+track --accurate
 mode binary
 y
 n
Index: tests/debugger/declarative/builtin_call_rep.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/builtin_call_rep.exp,v
retrieving revision 1.3
diff -u -b -r1.3 builtin_call_rep.exp
--- tests/debugger/declarative/builtin_call_rep.exp	20 May 2005 05:40:21 -0000	1.3
+++ tests/debugger/declarative/builtin_call_rep.exp	29 Oct 2005 14:32:15 -0000
@@ -16,7 +16,9 @@
 mdb> dd -d 3 -n 7
 +(1, 2) = 3
 Valid? b 3
-browser> mark
+browser> track --accurate
++(1, 2) = 3
+Valid? n
 Found incorrect contour:
 +(1, 2) = 3
 Is this a bug? y
Index: tests/debugger/declarative/builtin_call_rep.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/builtin_call_rep.inp,v
retrieving revision 1.2
diff -u -b -r1.2 builtin_call_rep.inp
--- tests/debugger/declarative/builtin_call_rep.inp	20 May 2005 05:40:21 -0000	1.2
+++ tests/debugger/declarative/builtin_call_rep.inp	29 Oct 2005 14:29:33 -0000
@@ -11,6 +11,7 @@
 f
 dd -d 3 -n 7
 b 3
-mark
+track --accurate
+n
 y
 c
Index: tests/debugger/declarative/change_search.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/change_search.exp,v
retrieving revision 1.2
diff -u -b -r1.2 change_search.exp
--- tests/debugger/declarative/change_search.exp	24 Aug 2005 09:07:12 -0000	1.2
+++ tests/debugger/declarative/change_search.exp	29 Oct 2005 15:56:21 -0000
@@ -54,13 +54,13 @@
 mdb> dd -r
 mylast([751, 752, 753, 754, 755, 756, 757, 758, ...], no)
 Valid? browse 2
-browser> mark
+browser> track --accurate
 mylast([1000], no)
 Valid? info
 Context of current question   : change_search.m:20 (change_search.m:22)
 Search mode                   : divide and query
-Estimated questions remaining : 10
-Number of suspect events      : 1,000
+Estimated questions remaining : 11
+Number of suspect events      : 2,000
 The current question was chosen because the marked subterm was bound by
 the unification inside the predicate change_search.mylast/2
 (change_search.m:21). The path to the subterm in the atom is 2.
@@ -71,22 +71,22 @@
 Valid? info
 Context of current question   : change_search.m:20 (change_search.m:22)
 Search mode                   : divide and query
-Estimated questions remaining : 10
-Number of suspect events      : 1,000
+Estimated questions remaining : 11
+Number of suspect events      : 2,000
 The current question was chosen because the marked subterm was bound by
 the unification inside the predicate change_search.mylast/2
 (change_search.m:21). The path to the subterm in the atom is 2.
 dd> mode binary
-mylast([875, 876, 877, 878, 879, 880, 881, 882, ...], no)
+mylast([750, 751, 752, 753, 754, 755, 756, 757, ...], no)
 Valid? mode top_down
-mylast([752, 753, 754, 755, 756, 757, 758, 759, ...], no)
+mylast([502, 503, 504, 505, 506, 507, 508, 509, ...], no)
 Valid? undo
-mylast([875, 876, 877, 878, 879, 880, 881, 882, ...], no)
+mylast([750, 751, 752, 753, 754, 755, 756, 757, ...], no)
 Valid? undo
 dd> mode divide_and_query
-mylast([876, 877, 878, 879, 880, 881, 882, 883, ...], no)
+mylast([751, 752, 753, 754, 755, 756, 757, 758, ...], no)
 Valid? n
-mylast([939, 940, 941, 942, 943, 944, 945, 946, ...], no)
+mylast([876, 877, 878, 879, 880, 881, 882, 883, ...], no)
 Valid? q
 Diagnosis aborted.
       E5:     C4 EXIT pred change_search.mylast/2-0 (det)
Index: tests/debugger/declarative/change_search.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/change_search.inp,v
retrieving revision 1.1
diff -u -b -r1.1 change_search.inp
--- tests/debugger/declarative/change_search.inp	19 Aug 2005 16:08:31 -0000	1.1
+++ tests/debugger/declarative/change_search.inp	29 Oct 2005 09:32:40 -0000
@@ -20,7 +20,7 @@
 p
 dd -r
 browse 2
-mark
+track --accurate
 info
 pd
 dd -r
Index: tests/debugger/declarative/closure_dependency.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/closure_dependency.exp,v
retrieving revision 1.2
diff -u -b -r1.2 closure_dependency.exp
--- tests/debugger/declarative/closure_dependency.exp	20 May 2005 05:40:21 -0000	1.2
+++ tests/debugger/declarative/closure_dependency.exp	30 Oct 2005 01:48:16 -0000
@@ -9,12 +9,14 @@
 mdb> dd -d 3 -n 7
 a(0, [100, 0], t(p([0])))
 Valid? b 2
-browser> mark
+browser> track --accurate
 c(t(p([0])), 100, [100, 0])
 Valid? n
 p([0], 100, [100, 0])
 Valid? b 1
-browser> mark
+browser> track --accurate
+p([0], 100, [100, 0])
+Valid? i
 Found inadmissible call:
 Parent c(t(p([0])), 100, _)
 Call p([0], 100, _)
@@ -31,12 +33,14 @@
 mdb> dd -d 3 -n 7
 a(1, [100, 1], t(p([1])))
 Valid? b 2
-browser> mark
+browser> track --accurate
 c(t(p([1])), 100, [100, 1])
 Valid? n
 p([1], 100, [100, 1])
 Valid? b 2
-browser> mark
+browser> track --accurate
+p([1], 100, [100, 1])
+Valid? i
 Found inadmissible call:
 Parent c(t(p([1])), 100, _)
 Call p([1], 100, _)
@@ -51,12 +55,14 @@
 mdb> dd -d 3 -n 7
 a(2, [100, 2], t(p([2])))
 Valid? b 2
-browser> mark
+browser> track --accurate
 c(t(p([2])), 100, [100, 2])
 Valid? n
 p([2], 100, [100, 2])
 Valid? b 3
-browser> mark
+browser> track --accurate
+p([2], 100, [100, 2])
+Valid? n
 Found incorrect contour:
 p([2], 100, [100, 2])
 Is this a bug? y
@@ -72,7 +78,7 @@
 Valid? b 3
 browser> ls
 t(p([3]))
-browser> mark
+browser> track --accurate
 d([3], t(p([3])))
 Valid? n
 Found incorrect contour:
Index: tests/debugger/declarative/closure_dependency.exp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/closure_dependency.exp2,v
retrieving revision 1.2
diff -u -b -r1.2 closure_dependency.exp2
--- tests/debugger/declarative/closure_dependency.exp2	20 May 2005 05:40:21 -0000	1.2
+++ tests/debugger/declarative/closure_dependency.exp2	29 Oct 2005 14:24:56 -0000
@@ -14,10 +14,12 @@
 browser> cd 3/1
 browser> ls
 p([0])
-browser> mark
+browser> track --accurate
 d([0], t(p([0])))
 Valid? browse
-browser> mark
+browser> track
+Cannot track the entire atom. Please select a subterm to track.
+dd> n
 Found incorrect contour:
 d([0], t(p([0])))
 Is this a bug? y
@@ -31,11 +33,11 @@
 mdb> dd -d 3 -n 7
 a(1, [100, 1], t(p([1])))
 Valid? b 2
-browser> mark
+browser> track --accurate
 p([1], 100, [100, 1])
 Valid? b
 browser> cd 1
-browser> mark
+browser> track --accurate
 b(1, [1])
 Valid? n
 Found incorrect contour:
@@ -51,10 +53,10 @@
 mdb> dd -d 3 -n 7
 a(2, [100, 2], t(p([2])))
 Valid? b 2
-browser> mark
+browser> track --accurate
 p([2], 100, [100, 2])
 Valid? b 2
-browser> mark
+browser> track --accurate
 e(2, 100)
 Valid? n
 Found incorrect contour:
@@ -70,14 +72,26 @@
 mdb> dd -d 3 -n 7
 a(3, [100, 3], t(p([3])))
 Valid? b 2
-browser> mark
+browser> track --accurate
 p([3], 100, [100, 3])
 Valid? b
 browser> cd 3
 browser> cd 2
 browser> ls
 [3]
-browser> mark
+browser> track --accurate
+b(3, [3])
+Valid? y
+a(3, [100, 3], t(p([3])))
+Valid? n
+e(3, 100)
+Valid? y
+d([3], t(p([3])))
+Valid? y
+c(t(p([3])), 100, [100, 3])
+Valid? n
+p([3], 100, [100, 3])
+Valid? n
 Found incorrect contour:
 p([3], 100, [100, 3])
 Is this a bug? y
Index: tests/debugger/declarative/closure_dependency.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/closure_dependency.inp,v
retrieving revision 1.2
diff -u -b -r1.2 closure_dependency.inp
--- tests/debugger/declarative/closure_dependency.inp	20 May 2005 05:40:22 -0000	1.2
+++ tests/debugger/declarative/closure_dependency.inp	30 Oct 2005 01:17:37 -0000
@@ -5,10 +5,11 @@
 f
 dd -d 3 -n 7
 b 2
-mark
+track --accurate
 n
 b 1
-mark
+track --accurate
+i
 y
 break a
 c
@@ -16,20 +17,22 @@
 f
 dd -d 3 -n 7
 b 2
-mark
+track --accurate
 n
 b 2
-mark
+track --accurate
+i
 y
 c
 c
 f
 dd -d 3 -n 7
 b 2
-mark
+track --accurate
 n
 b 3
-mark
+track --accurate
+n
 y
 c
 c
@@ -37,7 +40,7 @@
 dd -d 3 -n 7
 b 3
 ls
-mark
+track --accurate
 n
 y
 quit -y
Index: tests/debugger/declarative/closure_dependency.inp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/closure_dependency.inp2,v
retrieving revision 1.2
diff -u -b -r1.2 closure_dependency.inp2
--- tests/debugger/declarative/closure_dependency.inp2	20 May 2005 05:40:22 -0000	1.2
+++ tests/debugger/declarative/closure_dependency.inp2	29 Oct 2005 14:23:50 -0000
@@ -8,19 +8,20 @@
 browse
 cd 3/1
 ls
-mark
+track --accurate
 browse
-mark
+track
+n
 y
 c
 c
 f
 dd -d 3 -n 7
 b 2
-mark
+track --accurate
 b
 cd 1
-mark
+track --accurate
 n
 y
 c
@@ -28,9 +29,9 @@
 f
 dd -d 3 -n 7
 b 2
-mark
+track --accurate
 b 2
-mark
+track --accurate
 n
 y
 c
@@ -38,11 +39,17 @@
 f
 dd -d 3 -n 7
 b 2
-mark
+track --accurate
 b
 cd 3
 cd 2
 ls
-mark
+track --accurate
+y
+n
+y
+y
+n
+n
 y
 quit -y
Index: tests/debugger/declarative/dependency.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/dependency.exp,v
retrieving revision 1.11
diff -u -b -r1.11 dependency.exp
--- tests/debugger/declarative/dependency.exp	20 May 2005 05:40:22 -0000	1.11
+++ tests/debugger/declarative/dependency.exp	29 Oct 2005 15:36:44 -0000
@@ -37,9 +37,9 @@
 test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
 Valid? browse 1
 browser> ^1
-browser> mark
+browser> track --accurate
 Origin: primitive_op("dependency.m", 22, unification)
-p(1)
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
 Valid? quit
 Diagnosis aborted.
       18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
@@ -47,25 +47,34 @@
 test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
 Valid? browse 1
 browser> ^2^1
-browser> mark
+browser> track --accurate
+Origin: output(r, any_head_var_from_back(1), [1])
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
+Valid? no
+Origin: output(r, any_head_var_from_back(1), [1])
+p(1)
+Valid? y
+Origin: output(r, any_head_var_from_back(1), [1])
+q(no)
+Valid? y
 Origin: output(r, any_head_var_from_back(1), [1])
 r(1, [|](3, [|](4, [])), -(3, 4))
 Valid? browse 2
 browser> print
 [|](3, [|](4, []))
-browser> mark
+browser> track --accurate
 Origin: primitive_op("dependency.m", 29, unification)
-p(1)
+r(1, [|](3, [|](4, [])), -(3, 4))
 Valid? quit
 Diagnosis aborted.
       18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
 mdb> dd -d 3 -n 7
 test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
-Valid? browse 1
+Valid? [no] browse 1
 browser> ^2^2^1
-browser> mark
+browser> track --accurate
 Origin: primitive_op("dependency.m", 41, unification)
-p(1)
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
 Valid? quit
 Diagnosis aborted.
       18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
@@ -73,9 +82,9 @@
 test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
 Valid? browse 1
 browser> ^2^2^2^1
-browser> mark
+browser> track --accurate
 Origin: primitive_op("dependency.m", 22, unification)
-p(1)
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
 Valid? quit
 Diagnosis aborted.
       18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
@@ -83,9 +92,9 @@
 test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
 Valid? browse 1
 browser> ^2^2^2^2^1
-browser> mark
+browser> track --accurate
 Origin: output(r, any_head_var_from_back(1), [1])
-r(1, [|](3, [|](4, [])), -(3, 4))
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
 Valid? quit
 Diagnosis aborted.
       18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
@@ -93,9 +102,9 @@
 test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
 Valid? browse 1
 browser> ^2^2^2^2^2
-browser> mark
+browser> track --accurate
 Origin: primitive_op("dependency.m", 43, unification)
-p(1)
+test([|](1, [|](3, [|](6, [|](1, [|](3, []))))))
 Valid? quit
 Diagnosis aborted.
       18:      3  2 EXIT pred dependency.test/1-0 (cc_multi) dependency.m:19 (dependency.m:13)
Index: tests/debugger/declarative/dependency.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/dependency.inp,v
retrieving revision 1.5
diff -u -b -r1.5 dependency.inp
--- tests/debugger/declarative/dependency.inp	20 May 2005 05:40:22 -0000	1.5
+++ tests/debugger/declarative/dependency.inp	29 Oct 2005 15:33:20 -0000
@@ -13,34 +13,37 @@
 dd -d 3 -n 7
 browse 1
 ^1
-mark
+track --accurate
 quit
 dd -d 3 -n 7
 browse 1
 ^2^1
-mark
+track --accurate
+no
+y
+y
 browse 2
 print
-mark
+track --accurate
 quit
 dd -d 3 -n 7
 browse 1
 ^2^2^1
-mark
+track --accurate
 quit
 dd -d 3 -n 7
 browse 1
 ^2^2^2^1
-mark
+track --accurate
 quit
 dd -d 3 -n 7
 browse 1
 ^2^2^2^2^1
-mark
+track --accurate
 quit
 dd -d 3 -n 7
 browse 1
 ^2^2^2^2^2
-mark
+track --accurate
 quit
 continue
Index: tests/debugger/declarative/dependency2.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/dependency2.exp,v
retrieving revision 1.7
diff -u -b -r1.7 dependency2.exp
--- tests/debugger/declarative/dependency2.exp	20 May 2005 05:40:22 -0000	1.7
+++ tests/debugger/declarative/dependency2.exp	29 Oct 2005 15:12:55 -0000
@@ -12,19 +12,32 @@
 test([1, 3, 6, 1, 3])
 Valid? browse 1
 browser> ^2^1
-browser> mark
+browser> track --accurate
+Origin: output(r, any_head_var_from_back(1), [1])
+test([1, 3, 6, 1, 3])
+Valid? info
+Context of current question : dependency2.m:19 (dependency2.m:13)
+Search mode                 : top down
+The current question was chosen because the marked subterm was bound by
+the unification inside the predicate dependency2.test/1
+(dependency2.m:29).
+Origin: output(r, any_head_var_from_back(1), [1])
+dd> n
+Origin: output(r, any_head_var_from_back(1), [1])
+p(1)
+Valid? y
+Origin: output(r, any_head_var_from_back(1), [1])
+q(no)
+Valid? y
 Origin: output(r, any_head_var_from_back(1), [1])
 r(1, [3, 4], 3 - 4)
 Valid? browse 2
 browser> print
 [3, 4]
-browser> mark
-Origin: primitive_op("dependency2.m", 29, unification)
-p(1)
-Valid? yes
+browser> track --accurate
 Origin: primitive_op("dependency2.m", 29, unification)
-q(no)
-Valid? yes
+r(1, [3, 4], 3 - 4)
+Valid? inadmissible
 Found inadmissible call:
 Parent test(_)
 Call r(1, [3, 4], _)
Index: tests/debugger/declarative/dependency2.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/dependency2.inp,v
retrieving revision 1.3
diff -u -b -r1.3 dependency2.inp
--- tests/debugger/declarative/dependency2.inp	20 May 2005 05:40:22 -0000	1.3
+++ tests/debugger/declarative/dependency2.inp	29 Oct 2005 15:11:59 -0000
@@ -6,11 +6,14 @@
 dd -d 3 -n 7
 browse 1
 ^2^1
-mark
+track --accurate
+info
+n
+y
+y
 browse 2
 print
-mark
-yes
-yes
+track --accurate
+inadmissible
 yes
 continue
Index: tests/debugger/declarative/divide_and_query1.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/divide_and_query1.exp,v
retrieving revision 1.3
diff -u -b -r1.3 divide_and_query1.exp
--- tests/debugger/declarative/divide_and_query1.exp	20 May 2005 05:40:22 -0000	1.3
+++ tests/debugger/declarative/divide_and_query1.exp	29 Oct 2005 09:33:28 -0000
@@ -144,7 +144,7 @@
 to_b2([c, c, c, c, c, c, c], [b, b, b, b, b, b, b])
 Valid? b 2
 browser> cd 2/2
-browser> mark
+browser> track --accurate
 to_b([c, c, c, c, c], [b, b, b, b, b])
 Valid? n
 to_b([c, c], [b, b])
Index: tests/debugger/declarative/divide_and_query1.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/divide_and_query1.inp,v
retrieving revision 1.2
diff -u -b -r1.2 divide_and_query1.inp
--- tests/debugger/declarative/divide_and_query1.inp	20 May 2005 05:40:23 -0000	1.2
+++ tests/debugger/declarative/divide_and_query1.inp	29 Oct 2005 09:32:40 -0000
@@ -53,7 +53,7 @@
 dd -d 3 -n 7 -s divide_and_query
 b 2
 cd 2/2
-mark
+track --accurate
 n
 y
 n
Index: tests/debugger/declarative/explicit_subtree.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/explicit_subtree.exp,v
retrieving revision 1.4
diff -u -b -r1.4 explicit_subtree.exp
--- tests/debugger/declarative/explicit_subtree.exp	20 May 2005 05:40:23 -0000	1.4
+++ tests/debugger/declarative/explicit_subtree.exp	30 Oct 2005 01:26:14 -0000
@@ -15,14 +15,14 @@
 Call divide2(10, 0, _)
 Throws "zero denominator"
 Expected? browse 2
-browser> mark
+browser> track --accurate
 a(0)
 Valid? n
 q(49, 0, 49)
 Valid? y
 q(51, 0, 51)
 Valid? b 3
-browser> mark
+browser> track --accurate
 q(1, 50, 51)
 Valid? n
 q(0, 51, 51)
@@ -33,6 +33,8 @@
 Is this a bug? n
 q(1, 50, 51)
 Valid? [no] y
+q(51, 0, 51)
+Valid? n
 q(50, 1, 51)
 Valid? y
 Found incorrect contour:
@@ -40,7 +42,7 @@
 q(51, 0, 51)
 Is this a bug? n
 q(51, 0, 51)
-Valid? y
+Valid? [no] y
 Found incorrect contour:
 q(49, 0, 49)
 q(51, 0, 51)
@@ -50,7 +52,7 @@
 Valid? [no]
 q(49, 0, 49)
 Valid? [yes] b 3
-browser> mark
+browser> track --accurate
 q(1, 48, 49)
 Valid? n
 q(0, 49, 49)
@@ -66,6 +68,8 @@
 Is this a bug? n
 q(1, 48, 49)
 Valid? [no] y
+q(49, 0, 49)
+Valid? n
 q(48, 1, 49)
 Valid? y
 Found incorrect contour:
@@ -73,7 +77,7 @@
 q(49, 0, 49)
 Is this a bug? n
 q(49, 0, 49)
-Valid? y
+Valid? [no] y
 q(51, 0, 51)
 Valid? [yes]
 Found incorrect contour:
@@ -92,7 +96,7 @@
 Call p2(10, _)
 Throws "zero denominator"
 Expected? b 1
-browser> mark
+browser> track --accurate
 Call main(_, _)
 Throws "zero denominator"
 Expected? y
Index: tests/debugger/declarative/explicit_subtree.exp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/explicit_subtree.exp2,v
retrieving revision 1.6
diff -u -b -r1.6 explicit_subtree.exp2
--- tests/debugger/declarative/explicit_subtree.exp2	20 May 2005 05:40:23 -0000	1.6
+++ tests/debugger/declarative/explicit_subtree.exp2	29 Oct 2005 16:00:14 -0000
@@ -16,7 +16,7 @@
 Call divide2(10, 0, _)
 Throws "zero denominator"
 Expected? browse 2
-browser> mark
+browser> track --accurate
 -(100, 100) = 0
 Valid? n
 Found incorrect contour:
@@ -35,7 +35,7 @@
 Valid? y
 q(51, 0, 51)
 Valid? b 3
-browser> mark
+browser> track --accurate
 +(50, 1) = 51
 Valid? n
 Found incorrect contour:
@@ -43,6 +43,8 @@
 Is this a bug? n
 +(50, 1) = 51
 Valid? [no] y
+q(51, 0, 51)
+Valid? n
 Call =<(51, 0)
 Unsatisfiable? y
 -(51, 1) = 50
@@ -58,7 +60,7 @@
 q(51, 0, 51)
 Is this a bug? n
 q(51, 0, 51)
-Valid? y
+Valid? [no] y
 +(49, 51) = 100
 Valid? y
 Found incorrect contour:
@@ -72,7 +74,7 @@
 Valid? [no] n
 q(49, 0, 49)
 Valid? [yes] b 3
-browser> mark
+browser> track --accurate
 +(48, 1) = 49
 Valid? n
 Found incorrect contour:
@@ -80,6 +82,8 @@
 Is this a bug? n
 +(48, 1) = 49
 Valid? [no] y
+q(49, 0, 49)
+Valid? n
 Call =<(49, 0)
 Unsatisfiable? y
 -(49, 1) = 48
@@ -95,7 +99,7 @@
 q(49, 0, 49)
 Is this a bug? n
 q(49, 0, 49)
-Valid? y
+Valid? [no] y
 q(51, 0, 51)
 Valid? [yes] y
 +(49, 51) = 100
@@ -111,6 +115,9 @@
 Is this a bug? n
 a(0)
 Valid? [no] y
+Call divide2(10, 0, _)
+Throws "zero denominator"
+Expected? i
 Found inadmissible call:
 Parent calc(10, _)
 Call divide2(10, 0, _)
Index: tests/debugger/declarative/explicit_subtree.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/explicit_subtree.inp,v
retrieving revision 1.3
diff -u -b -r1.3 explicit_subtree.inp
--- tests/debugger/declarative/explicit_subtree.inp	20 May 2005 05:40:23 -0000	1.3
+++ tests/debugger/declarative/explicit_subtree.inp	30 Oct 2005 01:25:44 -0000
@@ -8,28 +8,30 @@
 finish
 dd -d 3 -n 7 -ad3
 browse 2
-mark
+track --accurate
 n
 y
 b 3
-mark
+track --accurate
 n
 y
 n
 y
+n
 y
 n
 y
 n

 b 3
-mark
+track --accurate
 n
 n
 n
 y
 n
 y
+n
 y
 n
 y
@@ -39,6 +41,6 @@
 y
 y
 b 1
-mark
+track --accurate
 y
 quit -y
Index: tests/debugger/declarative/explicit_subtree.inp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/explicit_subtree.inp2,v
retrieving revision 1.4
diff -u -b -r1.4 explicit_subtree.inp2
--- tests/debugger/declarative/explicit_subtree.inp2	20 May 2005 05:40:23 -0000	1.4
+++ tests/debugger/declarative/explicit_subtree.inp2	29 Oct 2005 15:58:33 -0000
@@ -9,7 +9,7 @@
 finish
 dd -d 3 -n 7 -ad3
 browse 2
-mark
+track --accurate
 n
 n
 y
@@ -18,10 +18,11 @@
 n
 y
 b 3
-mark
+track --accurate
 n
 n
 y
+n
 y
 y
 y
@@ -32,10 +33,11 @@
 n
 n
 b 3
-mark
+track --accurate
 n
 n
 y
+n
 y
 y
 y
@@ -47,6 +49,7 @@
 y
 n
 y
+i
 n
 y
 y
Index: tests/debugger/declarative/failed_cond.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/failed_cond.exp,v
retrieving revision 1.4
diff -u -b -r1.4 failed_cond.exp
--- tests/debugger/declarative/failed_cond.exp	20 May 2005 05:40:23 -0000	1.4
+++ tests/debugger/declarative/failed_cond.exp	29 Oct 2005 14:51:49 -0000
@@ -13,7 +13,9 @@
 Valid? no
 Call r(c)
 Unsatisfiable? browse 1
-browser> mark
+browser> track --accurate
+Call r(c)
+Unsatisfiable? inadmissible
 Found inadmissible call:
 Parent q(c, _)
 Call r(c)
Index: tests/debugger/declarative/failed_cond.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/failed_cond.inp,v
retrieving revision 1.2
diff -u -b -r1.2 failed_cond.inp
--- tests/debugger/declarative/failed_cond.inp	20 May 2005 05:40:23 -0000	1.2
+++ tests/debugger/declarative/failed_cond.inp	29 Oct 2005 14:51:10 -0000
@@ -7,6 +7,7 @@
 no
 no
 browse 1
-mark
+track --accurate
+inadmissible
 yes
 quit -y
Index: tests/debugger/declarative/find_origin.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/find_origin.exp,v
retrieving revision 1.7
diff -u -b -r1.7 find_origin.exp
--- tests/debugger/declarative/find_origin.exp	26 May 2005 00:17:05 -0000	1.7
+++ tests/debugger/declarative/find_origin.exp	29 Oct 2005 09:33:28 -0000
@@ -9,7 +9,7 @@
 mdb> dd -d 3 -n 7
 monotest(t(101), 1)
 Valid? b 1
-browser> mark
+browser> track --accurate
 monotest4(t(101), t(101))
 Valid? n
 Call lambda_find_origin_m_86(t(101), t(3))
@@ -34,7 +34,7 @@
 mdb> dd -d 3 -n 7
 polytest("hello", u("hello"), 5)
 Valid? b 2
-browser> mark
+browser> track --accurate
 polytest4(u("hello"), u("hello"))
 Valid? browse
 browser> set format pretty
@@ -62,7 +62,7 @@
 mdb> dd -d 3 -n 7
 tracetest(t(101), -2)
 Valid? b 1
-browser> mark
+browser> track --accurate
 tracetest1(t(101))
 Valid? n
 Found incorrect contour:
Index: tests/debugger/declarative/find_origin.exp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/find_origin.exp2,v
retrieving revision 1.7
diff -u -b -r1.7 find_origin.exp2
--- tests/debugger/declarative/find_origin.exp2	26 May 2005 00:17:05 -0000	1.7
+++ tests/debugger/declarative/find_origin.exp2	29 Oct 2005 09:33:28 -0000
@@ -9,7 +9,7 @@
 mdb> dd -d 3 -n 7
 monotest(t(101), 1)
 Valid? b 1
-browser> mark
+browser> track --accurate
 monotest4(t(101), t(101))
 Valid? n
 Call lambda_find_origin_m_86(t(101), t(3))
@@ -34,7 +34,7 @@
 mdb> dd -d 3 -n 7
 polytest("hello", u("hello"), 5)
 Valid? b 2
-browser> mark
+browser> track --accurate
 polytest4(u("hello"), u("hello"))
 Valid? browse
 browser> set format pretty
@@ -62,7 +62,7 @@
 mdb> dd -d 3 -n 7
 tracetest(t(101), -2)
 Valid? b 1
-browser> mark
+browser> track --accurate
 tracetest1(t(101))
 Valid? n
 Found incorrect contour:
Index: tests/debugger/declarative/find_origin.exp3
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/find_origin.exp3,v
retrieving revision 1.2
diff -u -b -r1.2 find_origin.exp3
--- tests/debugger/declarative/find_origin.exp3	20 May 2005 05:40:24 -0000	1.2
+++ tests/debugger/declarative/find_origin.exp3	29 Oct 2005 09:33:28 -0000
@@ -9,7 +9,7 @@
 mdb> dd -d 3 -n 7
 monotest(t(101), 1)
 Valid? b 1
-browser> mark
+browser> track --accurate
 monotest1(t(101))
 Valid? n
 Found incorrect contour:
@@ -25,7 +25,7 @@
 mdb> dd -d 3 -n 7
 polytest("hello", u("hello"), 5)
 Valid? b 2
-browser> mark
+browser> track --accurate
 polytest1("hello", u("hello"))
 Valid? n
 Found incorrect contour:
@@ -45,7 +45,7 @@
 mdb> dd -d 3 -n 7
 tracetest(t(101), -2)
 Valid? b 1
-browser> mark
+browser> track --accurate
 tracetest1(t(101))
 Valid? n
 Found incorrect contour:
Index: tests/debugger/declarative/find_origin.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/find_origin.inp,v
retrieving revision 1.2
diff -u -b -r1.2 find_origin.inp
--- tests/debugger/declarative/find_origin.inp	20 May 2005 05:40:24 -0000	1.2
+++ tests/debugger/declarative/find_origin.inp	29 Oct 2005 09:32:40 -0000
@@ -5,7 +5,7 @@
 f
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
 n
 y
 y
@@ -17,7 +17,7 @@
 f
 dd -d 3 -n 7
 b 2
-mark
+track --accurate
 browse
 set format pretty
 p
@@ -32,7 +32,7 @@
 f
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
 n
 y
 quit -y
Index: tests/debugger/declarative/find_origin.inp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/find_origin.inp2,v
retrieving revision 1.2
diff -u -b -r1.2 find_origin.inp2
--- tests/debugger/declarative/find_origin.inp2	20 May 2005 05:40:24 -0000	1.2
+++ tests/debugger/declarative/find_origin.inp2	29 Oct 2005 09:32:40 -0000
@@ -5,7 +5,7 @@
 f
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
 n
 y
 y
@@ -17,7 +17,7 @@
 f
 dd -d 3 -n 7
 b 2
-mark
+track --accurate
 browse
 set format pretty
 p
@@ -32,7 +32,7 @@
 f
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
 n
 y
 quit -y
Index: tests/debugger/declarative/find_origin.inp3
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/find_origin.inp3,v
retrieving revision 1.2
diff -u -b -r1.2 find_origin.inp3
--- tests/debugger/declarative/find_origin.inp3	20 May 2005 05:40:24 -0000	1.2
+++ tests/debugger/declarative/find_origin.inp3	29 Oct 2005 09:32:40 -0000
@@ -5,7 +5,7 @@
 finish
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
 n
 y
 break polytest
@@ -13,7 +13,7 @@
 f
 dd -d 3 -n 7
 b 2
-mark
+track --accurate
 n
 y
 c
@@ -23,7 +23,7 @@
 f
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
 n
 y
 quit -y
Index: tests/debugger/declarative/ignore.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/ignore.exp,v
retrieving revision 1.3
diff -u -b -r1.3 ignore.exp
--- tests/debugger/declarative/ignore.exp	20 May 2005 05:40:26 -0000	1.3
+++ tests/debugger/declarative/ignore.exp	30 Oct 2005 01:29:11 -0000
@@ -11,7 +11,9 @@
 mdb> dd -d 3 -n 7
 p(15)
 Valid? b 1
-browser> mark
+browser> track --accurate
+p(15)
+Valid? n
 q(1, 0) = 1
 Valid? n
 Found incorrect contour:
@@ -26,7 +28,7 @@
       E6:     C4 EXIT pred ignore.p/1-0 (det)
 mdb> dd -d 3 -n 7
 p(15)
-Valid? n
+Valid? [no] n
 Found incorrect contour:
 q(1, 0) = 1
 Is this a bug? n
Index: tests/debugger/declarative/ignore.exp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/ignore.exp2,v
retrieving revision 1.3
diff -u -b -r1.3 ignore.exp2
--- tests/debugger/declarative/ignore.exp2	20 May 2005 05:40:26 -0000	1.3
+++ tests/debugger/declarative/ignore.exp2	29 Oct 2005 09:33:29 -0000
@@ -13,7 +13,7 @@
 mdb> dd -d 3 -n 7
 p(15)
 Valid? b 1
-browser> mark
+browser> track --accurate
 q(5, 10) = 15
 Valid? n
 Found incorrect contour:
Index: tests/debugger/declarative/ignore.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/ignore.inp,v
retrieving revision 1.2
diff -u -b -r1.2 ignore.inp
--- tests/debugger/declarative/ignore.inp	20 May 2005 05:40:26 -0000	1.2
+++ tests/debugger/declarative/ignore.inp	30 Oct 2005 01:28:22 -0000
@@ -6,7 +6,8 @@
 finish
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
+n
 n
 y
 break 15
Index: tests/debugger/declarative/ignore.inp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/ignore.inp2,v
retrieving revision 1.2
diff -u -b -r1.2 ignore.inp2
--- tests/debugger/declarative/ignore.inp2	20 May 2005 05:40:26 -0000	1.2
+++ tests/debugger/declarative/ignore.inp2	29 Oct 2005 09:32:40 -0000
@@ -7,7 +7,7 @@
 finish
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
 n
 y
 break 15
Index: tests/debugger/declarative/info.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/info.exp,v
retrieving revision 1.6
diff -u -b -r1.6 info.exp
--- tests/debugger/declarative/info.exp	24 Aug 2005 09:07:13 -0000	1.6
+++ tests/debugger/declarative/info.exp	29 Oct 2005 15:02:33 -0000
@@ -54,7 +54,7 @@
 The current question was chosen because this is the next node in the
 top-down search.
 dd> b 2
-browser> mark
+browser> track --accurate
 last([108], t(108))
 Valid? info
 Context of current question : info.m:43 (info.m:45)
@@ -63,23 +63,23 @@
 the unification inside the predicate info.last/2 (info.m:43). The path
 to the subterm in the atom is 2.
 dd> mode binary
-last([105, 106, 107, 108], t(108))
+last([104, 105, 106, 107, 108], t(108))
 Valid? info
 Context of current question : info.m:43 (info.m:45)
 Search mode                 : binary search on path
 The current question was chosen because this node divides a path of
-length 7 into two paths of length 3 and 4.
+length 8 into two paths of length 4 and 4.
 dd> n
-last([107, 108], t(108))
+last([106, 107, 108], t(108))
 Valid? info
 Context of current question : info.m:43 (info.m:45)
 Search mode                 : binary search on path
 The current question was chosen because this node divides a path of
-length 3 into two paths of length 1 and 2.
+length 4 into two paths of length 2 and 2.
 dd> b 1
 browser> cd 1
-browser> mark
-last([106, 107, 108], t(108))
+browser> track --accurate
+last([105, 106, 107, 108], t(108))
 Valid? info
 Context of current question : info.m:43 (info.m:45)
 Search mode                 : top down
@@ -101,7 +101,7 @@
 q(0, "lala", t(t(t("lala"))), 2)
 Valid? b 3
 browser> cd 1/1
-browser> mark
+browser> track --accurate
 f(0, "lala") = t(t(t("lala")))
 Valid? info
 Context of current question : info.m:51 (info.m:34)
@@ -119,7 +119,7 @@
 mdb> dd -d 3 -n 7
 q(1, "lala", t(t(t("lala"))), 2)
 Valid? b 4
-browser> mark
+browser> track --accurate
 fproc(1) = 2
 Valid? info
 Context of current question : info.m:57 (info.m:37)
Index: tests/debugger/declarative/info.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/info.inp,v
retrieving revision 1.5
diff -u -b -r1.5 info.inp
--- tests/debugger/declarative/info.inp	19 Aug 2005 16:08:31 -0000	1.5
+++ tests/debugger/declarative/info.inp	29 Oct 2005 09:32:40 -0000
@@ -18,7 +18,7 @@
 n
 info
 b 2
-mark
+track --accurate
 info
 mode binary
 info
@@ -26,7 +26,7 @@
 info
 b 1
 cd 1
-mark
+track --accurate
 info
 q
 break q
@@ -36,14 +36,14 @@
 dd -d 3 -n 7
 b 3
 cd 1/1
-mark
+track --accurate
 info
 q

 f
 dd -d 3 -n 7
 b 4
-mark
+track --accurate
 info
 n
 n
Index: tests/debugger/declarative/input_term_dep.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/input_term_dep.exp,v
retrieving revision 1.10
diff -u -b -r1.10 input_term_dep.exp
--- tests/debugger/declarative/input_term_dep.exp	8 Jul 2005 16:45:20 -0000	1.10
+++ tests/debugger/declarative/input_term_dep.exp	29 Oct 2005 15:29:06 -0000
@@ -17,14 +17,18 @@
 mdb> dd -d 3 -n 7
 p(5, 8, 13)
 Valid? browse 3
-browser> mark
+browser> track --accurate
 pc(5, 13)
 Valid? browse 1
-browser> mark
+browser> track --accurate
 pa(5)
 Valid? yes
+p(5, 8, 13)
+Valid? no
 pb(8)
 Valid? yes
+pc(5, 13)
+Valid? i
 Found inadmissible call:
 Parent p(_, _, _)
 Call pc(5, _)
@@ -40,9 +44,11 @@
 mdb> dd -d 3 -n 7
 q([[2, 3], [], [1]])
 Valid? browse 1
-browser> mark 1/2
+browser> track -a 1/2
 qa([[1], [2, 3]])
 Valid? yes
+q([[2, 3], [], [1]])
+Valid? no
 qb([])
 Valid? yes
 qc([[2, ...], [], [1]], [[2, ...], [], [1]])
@@ -62,14 +68,18 @@
 mdb> dd -d 3 -n 7
 r(1, 33)
 Valid? browse 2
-browser> mark
+browser> track --accurate
 rc(3, 33)
 Valid? browse 1
-browser> mark
+browser> track --accurate
 ra(1, 3)
 Valid? yes
+r(1, 33)
+Valid? no
 rb(3)
 Valid? yes
+rc(3, 33)
+Valid? i
 Found inadmissible call:
 Parent r(1, _)
 Call rc(3, _)
@@ -87,9 +97,11 @@
 Valid? skip
 sc(7)
 Valid? browse 1
-browser> mark
+browser> track --accurate
 sa(1, 7)
 Valid? yes
+sc(7)
+Valid? i
 Found inadmissible call:
 Parent s(1)
 Call sc(7)
Index: tests/debugger/declarative/input_term_dep.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/input_term_dep.inp,v
retrieving revision 1.4
diff -u -b -r1.4 input_term_dep.inp
--- tests/debugger/declarative/input_term_dep.inp	8 Jul 2005 16:45:21 -0000	1.4
+++ tests/debugger/declarative/input_term_dep.inp	29 Oct 2005 15:28:37 -0000
@@ -8,18 +8,21 @@
 finish
 dd -d 3 -n 7
 browse 3
-mark
+track --accurate
 browse 1
-mark
+track --accurate
 yes
+no
 yes
+i
 yes
 continue
 finish
 dd -d 3 -n 7
 browse 1
-mark 1/2
+track -a 1/2
 yes
+no
 yes
 yes
 yes
@@ -27,11 +30,13 @@
 finish
 dd -d 3 -n 7
 browse 2
-mark
+track --accurate
 browse 1
-mark
+track --accurate
 yes
+no
 yes
+i
 yes
 continue
 finish
@@ -39,7 +44,8 @@
 no
 skip
 browse 1
-mark
+track --accurate
 yes
+i
 yes
 continue
Index: tests/debugger/declarative/mismatch_on_call.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/mismatch_on_call.exp,v
retrieving revision 1.2
diff -u -b -r1.2 mismatch_on_call.exp
--- tests/debugger/declarative/mismatch_on_call.exp	20 May 2005 05:40:27 -0000	1.2
+++ tests/debugger/declarative/mismatch_on_call.exp	29 Oct 2005 09:33:29 -0000
@@ -9,7 +9,7 @@
 mdb> dd -d 3 -n 7
 p(1, 2, 204, 202)
 Valid? b 4
-browser> mark
+browser> track --accurate
 q(102, 202)
 Valid? n
 Found incorrect contour:
Index: tests/debugger/declarative/mismatch_on_call.exp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/mismatch_on_call.exp2,v
retrieving revision 1.2
diff -u -b -r1.2 mismatch_on_call.exp2
--- tests/debugger/declarative/mismatch_on_call.exp2	20 May 2005 05:40:27 -0000	1.2
+++ tests/debugger/declarative/mismatch_on_call.exp2	29 Oct 2005 09:33:29 -0000
@@ -9,7 +9,7 @@
 mdb> dd -d 3 -n 7
 p(1, 2, 204, 202)
 Valid? b 4
-browser> mark
+browser> track --accurate
 +(102, 100) = 202
 Valid? n
 Found incorrect contour:
Index: tests/debugger/declarative/mismatch_on_call.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/mismatch_on_call.inp,v
retrieving revision 1.2
diff -u -b -r1.2 mismatch_on_call.inp
--- tests/debugger/declarative/mismatch_on_call.inp	20 May 2005 05:40:27 -0000	1.2
+++ tests/debugger/declarative/mismatch_on_call.inp	29 Oct 2005 09:32:40 -0000
@@ -5,7 +5,7 @@
 f
 dd -d 3 -n 7
 b 4
-mark
+track --accurate
 n
 y
 quit -y
Index: tests/debugger/declarative/mismatch_on_call.inp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/mismatch_on_call.inp2,v
retrieving revision 1.2
diff -u -b -r1.2 mismatch_on_call.inp2
--- tests/debugger/declarative/mismatch_on_call.inp2	20 May 2005 05:40:27 -0000	1.2
+++ tests/debugger/declarative/mismatch_on_call.inp2	29 Oct 2005 09:32:40 -0000
@@ -6,7 +6,7 @@
 f
 dd -d 3 -n 7
 b 4
-mark
+track --accurate
 n
 y
 quit -y
Index: tests/debugger/declarative/output_term_dep.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/output_term_dep.exp,v
retrieving revision 1.12
diff -u -b -r1.12 output_term_dep.exp
--- tests/debugger/declarative/output_term_dep.exp	20 May 2005 05:40:28 -0000	1.12
+++ tests/debugger/declarative/output_term_dep.exp	29 Oct 2005 15:44:43 -0000
@@ -21,9 +21,11 @@
 mdb> dd -d 3 -n 7
 p(5, 8, 13)
 Valid? browse 2
-browser> mark
+browser> track --accurate
 pb(8)
 Valid? yes
+p(5, 8, 13)
+Valid? no
 pa(5)
 Valid? yes
 pc(13)
@@ -45,9 +47,11 @@
 mdb> dd -d 3 -n 7
 q([[1, ...], [], [99]])
 Valid? browse 1
-browser> mark 2/1
+browser> track --accurate 2/1
 qb([])
 Valid? yes
+q([[1, ...], [], [99]])
+Valid? no
 qa([1, 2, 3])
 Valid? yes
 qc([99])
@@ -67,7 +71,9 @@
 mdb> dd -d 3 -n 7
 r(1, 999)
 Valid? browse 2
-browser> mark
+browser> track --accurate
+r(1, 999)
+Valid? no
 Found incorrect contour:
 r(1, 999)
 Is this a bug? yes
@@ -80,7 +86,9 @@
 mdb> dd -d 3 -n 7
 r(2, 43)
 Valid? browse 2
-browser> mark
+browser> track --accurate
+r(2, 43)
+Valid? no
 ra(2)
 Valid? yes
 Call rb(2)
@@ -98,9 +106,11 @@
 mdb> dd -d 3 -n 7
 r(3, 57)
 Valid? browse 2
-browser> mark
+browser> track --accurate
 rc(57)
 Valid? yes
+r(3, 57)
+Valid? no
 ra(3)
 Valid? yes
 rb(3)
@@ -120,9 +130,11 @@
 mdb> dd -d 3 -n 7
 r(4, -1)
 Valid? browse 2
-browser> mark
+browser> track --accurate
 rd(-1)
 Valid? yes
+r(4, -1)
+Valid? no
 Call ra(4)
 Unsatisfiable? yes
 Found incorrect contour:
@@ -138,7 +150,7 @@
 mdb> dd -d 3 -n 7
 s(1, 7, 7)
 Valid? browse 2
-browser> mark
+browser> track --accurate
 sa(7)
 Valid? quit
 Diagnosis aborted.
@@ -150,7 +162,7 @@
 mdb> dd -d 3 -n 7
 s(1, 7, 155)
 Valid? browse 3
-browser> mark
+browser> track --accurate
 sc(155)
 Valid? quit
 Diagnosis aborted.
@@ -162,7 +174,7 @@
 mdb> dd -d 3 -n 7
 s(1, 38, 7)
 Valid? browse 3
-browser> mark
+browser> track --accurate
 sa(7)
 Valid? quit
 Diagnosis aborted.
@@ -174,7 +186,7 @@
 mdb> dd -d 3 -n 7
 s(1, 38, 155)
 Valid? browse 3
-browser> mark
+browser> track --accurate
 sc(155)
 Valid? quit
 Diagnosis aborted.
@@ -191,7 +203,7 @@
 mdb> dd -d 3 -n 7
 s(2, 7, 38)
 Valid? browse 3
-browser> mark
+browser> track --accurate
 sb(38)
 Valid? no
 Found incorrect contour:
@@ -207,7 +219,7 @@
 mdb> dd -d 3 -n 7
 s(2, 38, 155)
 Valid? browse 2
-browser> mark
+browser> track --accurate
 Found incorrect contour:
 sb(38)
 Is this a bug? yes
@@ -226,9 +238,11 @@
 mdb> dd -d 3 -n 7
 t(1, 77)
 Valid? browse 2
-browser> mark
+browser> track --accurate
 tb(77)
 Valid? yes
+t(1, 77)
+Valid? no
 Call ta(1)
 Unsatisfiable? yes
 Call tc(77)
Index: tests/debugger/declarative/output_term_dep.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/output_term_dep.inp,v
retrieving revision 1.5
diff -u -b -r1.5 output_term_dep.inp
--- tests/debugger/declarative/output_term_dep.inp	20 May 2005 05:40:28 -0000	1.5
+++ tests/debugger/declarative/output_term_dep.inp	29 Oct 2005 15:44:11 -0000
@@ -10,8 +10,9 @@
 finish
 dd -d 3 -n 7
 browse 2
-mark
+track --accurate
 yes
+no
 yes
 yes
 yes
@@ -19,8 +20,9 @@
 finish
 dd -d 3 -n 7
 browse 1
-mark 2/1
+track --accurate 2/1
 yes
+no
 yes
 yes
 yes
@@ -28,13 +30,15 @@
 finish
 dd -d 3 -n 7
 browse 2
-mark
+track --accurate
+no
 yes
 continue
 finish
 dd -d 3 -n 7
 browse 2
-mark
+track --accurate
+no
 yes
 yes
 yes
@@ -42,8 +46,9 @@
 finish
 dd -d 3 -n 7
 browse 2
-mark
+track --accurate
 yes
+no
 yes
 yes
 yes
@@ -51,33 +56,34 @@
 finish
 dd -d 3 -n 7
 browse 2
-mark
+track --accurate
 yes
+no
 yes
 yes
 continue
 finish
 dd -d 3 -n 7
 browse 2
-mark
+track --accurate
 quit
 continue
 finish
 dd -d 3 -n 7
 browse 3
-mark
+track --accurate
 quit
 continue
 finish
 dd -d 3 -n 7
 browse 3
-mark
+track --accurate
 quit
 continue
 finish
 dd -d 3 -n 7
 browse 3
-mark
+track --accurate
 quit
 continue
 finish
@@ -85,7 +91,7 @@
 finish
 dd -d 3 -n 7
 browse 3
-mark
+track --accurate
 no
 yes
 continue
@@ -93,7 +99,7 @@
 finish
 dd -d 3 -n 7
 browse 2
-mark
+track --accurate
 yes
 continue
 continue
@@ -102,8 +108,9 @@
 finish
 dd -d 3 -n 7
 browse 2
-mark
+track --accurate
 yes
+no
 yes
 yes
 yes
Index: tests/debugger/declarative/partial.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/partial.exp,v
retrieving revision 1.1
diff -u -b -r1.1 partial.exp
--- tests/debugger/declarative/partial.exp	13 Sep 2005 04:04:07 -0000	1.1
+++ tests/debugger/declarative/partial.exp	29 Oct 2005 09:34:17 -0000
@@ -10,7 +10,7 @@
 p(t(1, 2))
 Valid? browse 1
 browser> cd 1
-browser> mark
+browser> track -a
 a(1)
 Valid? info
 Context of current question : partial.m:32 (partial.m:25)
@@ -22,7 +22,7 @@
 p(t(1, 2))
 Valid? browse 1
 browser> cd 2
-browser> mark
+browser> track --accurate
 b(2)
 Valid? info
 Context of current question : partial.m:36 (partial.m:26)
Index: tests/debugger/declarative/partial.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/partial.inp,v
retrieving revision 1.1
diff -u -b -r1.1 partial.inp
--- tests/debugger/declarative/partial.inp	13 Sep 2005 04:04:07 -0000	1.1
+++ tests/debugger/declarative/partial.inp	29 Oct 2005 09:34:10 -0000
@@ -6,12 +6,12 @@
 dd
 browse 1
 cd 1
-mark
+track -a
 info
 undo
 browse 1
 cd 2
-mark
+track --accurate
 info
 quit
 quit -y
Index: tests/debugger/declarative/priv_builtin_bug.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/priv_builtin_bug.exp,v
retrieving revision 1.1
diff -u -b -r1.1 priv_builtin_bug.exp
--- tests/debugger/declarative/priv_builtin_bug.exp	14 Jun 2005 08:15:06 -0000	1.1
+++ tests/debugger/declarative/priv_builtin_bug.exp	29 Oct 2005 14:49:54 -0000
@@ -11,10 +11,12 @@
 mdb> dd
 p(2, 2)
 Valid? b 1
-browser> mark
+browser> track --accurate
 2
 q(1, 2)
 Valid? n
+p(2, 2)
+Valid? i
 Found inadmissible call:
 Parent q(1, _)
 Call p(2, _)
Index: tests/debugger/declarative/priv_builtin_bug.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/priv_builtin_bug.inp,v
retrieving revision 1.1
diff -u -b -r1.1 priv_builtin_bug.inp
--- tests/debugger/declarative/priv_builtin_bug.inp	14 Jun 2005 08:15:07 -0000	1.1
+++ tests/debugger/declarative/priv_builtin_bug.inp	29 Oct 2005 14:49:37 -0000
@@ -6,7 +6,8 @@
 f
 dd
 b 1
-mark
+track --accurate
 n
+i
 y
 quit -y
Index: tests/debugger/declarative/special_term_dep.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/special_term_dep.exp,v
retrieving revision 1.7
diff -u -b -r1.7 special_term_dep.exp
--- tests/debugger/declarative/special_term_dep.exp	20 May 2005 05:40:30 -0000	1.7
+++ tests/debugger/declarative/special_term_dep.exp	30 Oct 2005 01:31:18 -0000
@@ -2,6 +2,9 @@
 mdb> echo on
 Command echo enabled.
 mdb> register --quiet
+mdb> table_io allow
+mdb> table_io start
+I/O tabling started.
 mdb> break p
  0: + stop  interface pred special_term_dep.p/1-0 (det)
 mdb> break q
@@ -10,12 +13,14 @@
       E2:     C2 CALL pred special_term_dep.p/1-0 (det) special_term_dep.m:29 (special_term_dep.m:22)
 mdb> finish
       E3:     C2 EXIT pred special_term_dep.p/1-0 (det) special_term_dep.m:29 (special_term_dep.m:22)
-mdb> dd -d 3 -n 7
+mdb> dd -d 3 -n 7 -a
 p([2, 3])
 Valid? browse 1
-browser> mark
+browser> track --accurate
 pa([2, 3])
 Valid? yes
+p([2, 3])
+Valid? no
 Found incorrect contour:
 pa([2, 3])
 p([2, 3])
@@ -26,19 +31,24 @@
       E4:     C3 CALL pred special_term_dep.q/2-0 (semidet) special_term_dep.m:61 (special_term_dep.m:50)
 mdb> finish
       E5:     C3 EXIT pred special_term_dep.q/2-0 (semidet) special_term_dep.m:61 (special_term_dep.m:50)
-mdb> dd -d 3 -n 7
+mdb> dd -d 3 -n 7 -a
 q([1, 2], [3])
 Valid? browse 2
-browser> mark
+browser> track --accurate
 qb([1, 2], [3])
 Valid? browse 1
-browser> mark
+browser> track --accurate
+[2, 3]
+[3]
+test2(_, _)
+Valid? no
+q([1, 2], [3])
+Valid? no
+qa([1, 2])
+Valid? no
+Found incorrect contour:
 qa([1, 2])
-Valid? yes
-Found inadmissible call:
-Parent q([1, 2], _)
-Call qb([1, 2], _)
 Is this a bug? yes
-      E5:     C3 EXIT pred special_term_dep.q/2-0 (semidet) special_term_dep.m:61 (special_term_dep.m:50)
-mdb> continue
-[3]
+[2, 3]
+      E6:     C4 EXIT pred special_term_dep.qa/1-0 (det) special_term_dep.m:68 (special_term_dep.m:62)
+mdb> quit -y
Index: tests/debugger/declarative/special_term_dep.exp2
===================================================================
RCS file: tests/debugger/declarative/special_term_dep.exp2
diff -N tests/debugger/declarative/special_term_dep.exp2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/declarative/special_term_dep.exp2	29 Oct 2005 15:01:16 -0000
@@ -0,0 +1,57 @@
+      E1:     C1 CALL pred special_term_dep.main/2-0 (det) special_term_dep.m:13
+mdb> echo on
+Command echo enabled.
+mdb> register --quiet
+mdb> table_io allow
+mdb> table_io start
+I/O tabling started.
+mdb> break p
+ 0: + stop  interface pred special_term_dep.p/1-0 (det)
+mdb> break q
+ 1: + stop  interface pred special_term_dep.q/2-0 (semidet)
+mdb> continue
+      E2:     C2 CALL pred special_term_dep.p/1-0 (det) special_term_dep.m:29 (special_term_dep.m:22)
+mdb> finish
+      E3:     C2 EXIT pred special_term_dep.p/1-0 (det) special_term_dep.m:29 (special_term_dep.m:22)
+mdb> dd -d 3 -n 7 -a
+p([2, 3])
+Valid? browse 1
+browser> track --accurate
+pa([2, 3])
+Valid? yes
+p([2, 3])
+Valid? no
+Found incorrect contour:
+pa([2, 3])
+p([2, 3])
+Is this a bug? yes
+      E3:     C2 EXIT pred special_term_dep.p/1-0 (det) special_term_dep.m:29 (special_term_dep.m:22)
+mdb> continue
+[2, 3]
+      E4:     C3 CALL pred special_term_dep.q/2-0 (semidet) special_term_dep.m:61 (special_term_dep.m:50)
+mdb> finish
+      E5:     C3 EXIT pred special_term_dep.q/2-0 (semidet) special_term_dep.m:61 (special_term_dep.m:50)
+mdb> dd -d 3 -n 7 -a
+q([1, 2], [3])
+Valid? browse 2
+browser> track --accurate
+qb([1, 2], [3])
+Valid? browse 1
+browser> track --accurate
+[3]
+test2(_, _)
+4 tabled IO actions:
+write_char('[')
+write_int(3)
+write_char(']')
+write_char('\n')
+Valid? no
+q([1, 2], [3])
+Valid? no
+qa([1, 2])
+Valid? no
+Found incorrect contour:
+qa([1, 2])
+Is this a bug? yes
+      E6:     C4 EXIT pred special_term_dep.qa/1-0 (det) special_term_dep.m:68 (special_term_dep.m:62)
+mdb> quit -y
Index: tests/debugger/declarative/special_term_dep.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/special_term_dep.inp,v
retrieving revision 1.2
diff -u -b -r1.2 special_term_dep.inp
--- tests/debugger/declarative/special_term_dep.inp	20 May 2005 05:40:30 -0000	1.2
+++ tests/debugger/declarative/special_term_dep.inp	29 Oct 2005 14:59:23 -0000
@@ -1,21 +1,26 @@
 echo on
 register --quiet
+table_io allow
+table_io start
 break p
 break q
 continue
 finish
-dd -d 3 -n 7
+dd -d 3 -n 7 -a
 browse 1
-mark
+track --accurate
 yes
+no
 yes
 continue
 finish
-dd -d 3 -n 7
+dd -d 3 -n 7 -a
 browse 2
-mark
+track --accurate
 browse 1
-mark
+track --accurate
+no
+no
+no
 yes
-yes
-continue
+quit -y
Index: tests/debugger/declarative/unsafe_cast.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/unsafe_cast.exp,v
retrieving revision 1.2
diff -u -b -r1.2 unsafe_cast.exp
--- tests/debugger/declarative/unsafe_cast.exp	20 May 2005 05:40:30 -0000	1.2
+++ tests/debugger/declarative/unsafe_cast.exp	29 Oct 2005 15:31:17 -0000
@@ -10,7 +10,9 @@
 mdb> dd -d 3 -n 7
 p(42)
 Valid? b 1
-browser> mark
+browser> track --accurate
+p(42)
+Valid? no
 Found incorrect contour:
 p(42)
 Is this a bug? yes
Index: tests/debugger/declarative/unsafe_cast.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/unsafe_cast.inp,v
retrieving revision 1.2
diff -u -b -r1.2 unsafe_cast.inp
--- tests/debugger/declarative/unsafe_cast.inp	20 May 2005 05:40:31 -0000	1.2
+++ tests/debugger/declarative/unsafe_cast.inp	29 Oct 2005 15:30:17 -0000
@@ -4,6 +4,7 @@
 f
 dd -d 3 -n 7
 b 1
-mark
+track --accurate
+no
 yes
 c

--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list