[m-dev.] for review: term dependencies in the declarative debugger

Mark Anthony BROWN dougl at cs.mu.OZ.AU
Tue Jan 30 04:29:30 AEDT 2001


Estimated hours taken: 40

This is the second part of a change to support term dependency analysis
in the declarative debugger.  A `mark' command is implemented for the
term browser, which allows a particular subterm to be selected and
returned from the browser.  The declarative debugger interprets this as
a suspicious subterm, and tries to find a child or sibling node from which
this subterm comes.  This is used to determine the next question to be
asked of the oracle.

browser/browse.m:
	Update the browser interface to allow for marked subterms being
	returned from the browser.

	Implement and document the mark command.

	Rewrite run_command as a switch instead of a chain of if-then-elses.
	This forces all unimplemented commands to be explicitly listed,
	and gives better error checking.

browser/browser_info.m:
	Add a maybe_mark field to the browser_info.  It is initially `no',
	but is updated when the mark command is given.

browser/declarative_analyser.m:
	Select which child or sibling node to ask about next by searching
	for the origin of the suspicious subterm.  If the subterm has mode
	`out' we act as if the oracle had answered no, and if the subterm
	has mode `in' we act as if the oracle had answered yes.  In future
	we may not wish to presume this -- we do so now mainly to keep the
	analysis algorithm simpler.

browser/declarative_debugger.m:
	Add a functor for suspicious subterms to the decl_answer type.

browser/declarative_oracle.m:
	Accommodate the changed answer type.  The oracle does not try to
	store information about suspicious subterms in the knowledge base,
	because in principle this could lead to infinite loops (although
	currently this wouldn't be a problem since we don't ever use the
	information to move upward in the tree, so no cycle could be
	formed).

browser/declarative_user.m:
	Accommodate the changed answer type, and interpret marked terms
	from the browser as suspicious subterms.

browser/parse.m:
	Add the new command.

browser/program_representation.m:
	Add a procedure to convert the browser's list(dir) to a term_path.

	Change atomic_goal_rep_is_call/2 so it fails for special predicates,
	which was originally intended.

trace/mercury_trace_browse.c:
	Ignore the extra argument -- marked terms are not currently used in
	the main debugger.

tests/debugger/declarative/Mmakefile:
tests/debugger/declarative/input_term_dep.*:
tests/debugger/declarative/output_term_dep.*:
tests/debugger/declarative/special_term_dep.*:
	New test cases.

Index: browser/browse.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/browse.m,v
retrieving revision 1.17
diff -u -r1.17 browse.m
--- browser/browse.m	2001/01/09 23:30:13	1.17
+++ browser/browse.m	2001/01/29 14:08:17
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 1998-2000 The University of Melbourne.
+% Copyright (C) 1998-2001 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.
 %---------------------------------------------------------------------------%
@@ -20,16 +20,16 @@
 
 :- interface.
 
-:- import_module io, std_util.
+:- import_module io, std_util, list.
 :- import_module mdb__browser_info.
 
 	% The interactive term browser.  The caller type will be `browse', and
 	% the default format for the `browse' caller type will be used.
 	%
 :- pred browse__browse(T, io__input_stream, io__output_stream,
-			browser_persistent_state, browser_persistent_state,
-			io__state, io__state).
-:- mode browse__browse(in, in, in, in, out, di, uo) is det.
+			maybe(list(dir)), browser_persistent_state,
+			browser_persistent_state, io__state, io__state).
+:- mode browse__browse(in, in, in, out, in, out, di, uo) is det.
 
 	% As above, except that the supplied format will override the default.
 	%
@@ -83,7 +83,7 @@
 :- implementation.
 
 :- import_module mdb__parse, mdb__util, mdb__frame.
-:- import_module string, list, parser, require, std_util, int, char, pprint.
+:- import_module string, parser, require, std_util, int, char, pprint.
 :- import_module bool.
 
 %---------------------------------------------------------------------------%
@@ -92,7 +92,7 @@
 % they are used in trace/mercury_trace_browser.c.
 %
 
-:- pragma export(browse__browse(in, in, in, in, out, di, uo),
+:- pragma export(browse__browse(in, in, in, out, in, out, di, uo),
 	"ML_BROWSE_browse").
 :- pragma export(browse__browse_format(in, in, in, in, in, out, di, uo),
 	"ML_BROWSE_browse_format").
@@ -163,27 +163,28 @@
 % Interactive display
 %
 
-browse__browse(Object, InputStream, OutputStream, State0, State) -->
+browse__browse(Object, InputStream, OutputStream, MaybeMark, State0, State) -->
 	browse_common(internal, Object, InputStream, OutputStream, 
-		no, State0, State).
+		no, MaybeMark, State0, State).
 
 browse__browse_format(Object, InputStream, OutputStream, Format,
 		State0, State) -->
 
 	browse_common(internal, Object, InputStream, OutputStream,
-		yes(Format), State0, State).
+		yes(Format), _, State0, State).
 
 browse__browse_external(Object, InputStream, OutputStream, State0, State) -->
 	browse_common(external, Object, InputStream, OutputStream, 
-		no, State0, State).
+		no, _, State0, State).
 
-:- pred browse_common(debugger, T, io__input_stream, io__output_stream,
-		maybe(portray_format), browser_persistent_state,
-		browser_persistent_state, io__state, io__state).
-:- mode browse_common(in, in, in, in, in, in, out, di, uo) is det.
+:- pred browse_common(debugger::in, T::in, io__input_stream::in,
+		io__output_stream::in, maybe(portray_format)::in,
+		maybe(list(dir))::out, browser_persistent_state::in,
+		browser_persistent_state::out, io__state::di, io__state::uo)
+		is det.
 
 browse_common(Debugger, Object, InputStream, OutputStream, MaybeFormat,
-		State0, State) -->
+		MaybeMark, State0, State) -->
 	
 	{ browser_info__init(Object, MaybeFormat, State0, Info0) },
 	io__set_input_stream(InputStream, OldInputStream),
@@ -192,6 +193,7 @@
 	browse_main_loop(Debugger, Info0, Info),
 	io__set_input_stream(OldInputStream, _),
 	io__set_output_stream(OldOutputStream, _),
+	{ MaybeMark = Info ^ maybe_mark },
 	{ State = Info ^ state }.
 
 :- pred browse_main_loop(debugger, browser_info, browser_info, 
@@ -207,7 +209,9 @@
 		{ Debugger = external },
 		parse__read_command_external(Command)
 	),
-	( { Command = quit } ->
+	run_command(Debugger, Command, Quit, Info0, Info1),
+	(
+		{ Quit = yes },
 		% write_string_debugger(Debugger, "quitting...\n")
 		(
 			{ Debugger = external },
@@ -215,9 +219,9 @@
 		;
 			{ Debugger = internal }
 		),
-		{ Info = Info0 }
+		{ Info = Info1 }
 	;
-		run_command(Debugger, Command, Info0, Info1),
+		{ Quit = no },
 		browse_main_loop(Debugger, Info1, Info)
 	).
 
@@ -230,36 +234,42 @@
 prompt("browser> ").
 
 
-:- pred run_command(debugger, command, browser_info, browser_info,
-		io__state, io__state).
-:- mode run_command(in, in, in, out, di, uo) is det.
+:- pred run_command(debugger::in, command::in, bool::out, browser_info::in,
+		browser_info::out, io__state::di, io__state::uo) is det.
 
-run_command(Debugger, Command, Info0, Info) -->
+run_command(Debugger, Command, Quit, Info0, Info) -->
 	% XXX The commands `set', `ls' and `print' should allow the format
 	% to be specified by an option.  In each case we instead pass `no' to
 	% the respective handler.
-	( { Command = unknown } ->
+	( { Command = unknown },
 		write_string_debugger(Debugger, 
 			"Error: unknown command or syntax error.\n"),
 		write_string_debugger(Debugger, "Type \"help\" for help.\n"),
+		{ Quit = no },
 		{ Info = Info0 }
-	; { Command = help } ->
+	; { Command = help },
 		help(Debugger),
+		{ Quit = no },
 		{ Info = Info0 }
-	; { Command = set } ->
+	; { Command = set },
 		show_settings(Debugger, Info0, no),
+		{ Quit = no },
 		{ Info = Info0 }
-	; { Command = set(Setting) } ->
-		{ set_browse_param(Setting, Info0, Info) }
-	; { Command = ls } ->
+	; { Command = set(Setting) },
+		{ set_browse_param(Setting, Info0, Info) },
+		{ Quit = no }
+	; { Command = ls },
 		portray(Debugger, browse, no, Info0),
+		{ Quit = no },
 		{ Info = Info0 }
-	; { Command = ls(Path) } ->
+	; { Command = ls(Path) },
 		portray_path(Debugger, browse, no, Info0, Path),
+		{ Quit = no },
 		{ Info = Info0 }
-	; { Command = cd } ->
-		{ set_path(root_rel([]), Info0, Info) }
-	; { Command = cd(Path) } ->
+	; { Command = cd },
+		{ set_path(root_rel([]), Info0, Info) },
+		{ Quit = no }
+	; { Command = cd(Path) },
 		{ change_dir(Info0 ^ dirs, Path, NewPwd) },
 		( { deref_subterm(Info0 ^ term, NewPwd, _SubUniv) } ->
 			{ Info = Info0 ^ dirs := NewPwd }
@@ -267,17 +277,43 @@
 			write_string_debugger(Debugger, 
 				"error: cannot change to subterm\n"),
 			{ Info = Info0 }
-		)
-	; { Command = print } ->
+		),
+		{ Quit = no }
+	; { Command = print },
 		portray(Debugger, print, no, Info0),
+		{ Quit = no },
 		{ Info = Info0 }
-	; { Command = pwd } ->
+	; { Command = pwd },
 		write_path(Debugger, Info0 ^ dirs),
 		nl_debugger(Debugger),
+		{ Quit = no },
+		{ Info = Info0 }
+	; { Command = mark },
+		{ Quit = yes },
+		{ Info = Info0 ^ maybe_mark := yes(Info0 ^ dirs) }
+	; { Command = mark(Path) },
+		{ change_dir(Info0 ^ dirs, Path, NewPwd) },
+		( { deref_subterm(Info0 ^ term, NewPwd, _SubUniv) } ->
+			{ Quit = yes },
+			{ Info = Info0 ^ maybe_mark := yes(NewPwd) }
+		;
+			write_string_debugger(Debugger, 
+				"error: cannot mark subterm\n"),
+			{ Quit = no },
+			{ Info = Info0 }
+		)
+	; { Command = quit },
+		{ Quit = yes },
+		{ Info = Info0 }
+	; { Command = display },
+		write_string_debugger(Debugger,
+				"command not yet implemented\n"),
+		{ Quit = no },
 		{ Info = Info0 }
-	;	
+	; { Command = write },
 		write_string_debugger(Debugger,
 				"command not yet implemented\n"),
+		{ Quit = no },
 		{ Info = Info0 }
 	),
 	( { Debugger = external } ->
@@ -309,6 +345,7 @@
 "\tset            -- show settings\n",
 "\tprint          -- show single line representation of current term\n",
 "\tquit           -- quit browser\n",
+"\tmark [path]    -- mark the given subterm (default is current) and quit\n",
 "SICStus Prolog style commands are:\n",
 "\tp              -- print\n",
 "\t< n            -- set depth\n",
Index: browser/browser_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/browser_info.m,v
retrieving revision 1.1
diff -u -r1.1 browser_info.m
--- browser/browser_info.m	2000/10/27 08:38:49	1.1
+++ browser/browser_info.m	2001/01/29 14:08:19
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 2000 The University of Melbourne.
+% Copyright (C) 2000-2001 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.
 %---------------------------------------------------------------------------%
@@ -29,8 +29,12 @@
 						% Format specified as
 						% an option to the mdb
 						% command.
-			state	:: browser_persistent_state
+			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.
 		).
 
 :- type dir
@@ -177,7 +181,7 @@
 %---------------------------------------------------------------------------%
 
 browser_info__init(Term, MaybeFormat, State, Info) :-
-	Info = browser_info(univ(Term), [], MaybeFormat, State).
+	Info = browser_info(univ(Term), [], MaybeFormat, State, no).
 
 browser_info__get_format(Info, Caller, MaybeFormat, Format) :-
 	(
Index: browser/declarative_analyser.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_analyser.m,v
retrieving revision 1.6
diff -u -r1.6 declarative_analyser.m
--- browser/declarative_analyser.m	2001/01/16 15:44:16	1.6
+++ browser/declarative_analyser.m	2001/01/29 14:08:21
@@ -149,32 +149,107 @@
 	Response = oracle_queries(Queries).
 
 continue_analysis(Store, Answers, Response, Analyser0, Analyser) :-
+	%
+	% Check for suspicious subterms before anything else.  The oracle
+	% is unlikely to answer with one of these unless it thinks it is
+	% particularly significant, which is why we check these first.
+	%
+	% After that check for incorrect suspects.  Leave the correct
+	% suspects until last, since these generally prune the search space
+	% by the least amount.
+	%
+	Analyser0 = analyser(_, Suspects, _),
 	(
-		find_incorrect_suspect(Answers, Analyser0, Suspect)
+		find_suspicious_subterm(Answers, Suspects, Suspect, ArgPos,
+				TermPath)
 	->
+		follow_suspicious_subterm(Store, Suspect, ArgPos, TermPath,
+				Response, Analyser0, Analyser)
+	;
+		find_incorrect_suspect(Answers, Suspects, Suspect)
+	->
 		make_new_prime_suspect(Store, Suspect, Response, Analyser0,
 				Analyser)
 	;
 		remove_suspects(Store, Answers, Response, Analyser0, Analyser)
 	).
 
+	% Find an answer which is a suspicious subterm, and find the
+	% suspect that corresponds to it, or else fail.
+	%
+:- pred find_suspicious_subterm(list(decl_answer), list(suspect(T)),
+		suspect(T), arg_pos, term_path).
+:- mode find_suspicious_subterm(in, in, out, out, out) is semidet.
+
+find_suspicious_subterm([Answer | Answers], Suspects, Suspect, ArgPos,
+		TermPath) :-
+	
+	(
+		Answer = suspicious_subterm(Question, ArgPos0, TermPath0),
+		find_matching_suspects(Question, Suspects, [Match | _], _)
+	->
+		Suspect = Match,
+		ArgPos = ArgPos0,
+		TermPath = TermPath0
+	;
+		find_suspicious_subterm(Answers, Suspects, Suspect, ArgPos,
+				TermPath)
+	).
+
+:- pred follow_suspicious_subterm(S, suspect(T), arg_pos, term_path,
+		analyser_response(T), analyser_state(T), analyser_state(T))
+			<= mercury_edt(S, T).
+:- mode follow_suspicious_subterm(in, in, in, in, out, in, out) is det.
+
+follow_suspicious_subterm(Store, Suspect, ArgPos, TermPath, Response,
+		Analyser0, Analyser) :-
+
+	Suspect = suspect(Tree, Query),
+	edt_dependency(Store, Tree, ArgPos, TermPath, SubtermMode, Origin),
+	%
+	% If the selected subterm has mode `in' then we infer that the node
+	% is correct, otherwise we infer that it is wrong.
+	%
+	(
+		SubtermMode = subterm_in,
+		remove_suspects(Store, [truth_value(Query, yes)], Response0,
+				Analyser0, Analyser)
+	;
+		SubtermMode = subterm_out,
+		make_new_prime_suspect(Store, Suspect, Response0, Analyser0,
+				Analyser)
+	),
+	(
+		Origin = output(Node, _, _),
+		Response0 = oracle_queries(_)
+	->
+		%
+		% Replace all of the queries with just the one which output
+		% the subterm.  We may wind up asking the full list later,
+		% including this query, but the oracle should have the
+		% previous answer available.
+		%
+		create_suspect(Store, Node, suspect(_, NodeQuery)),
+		Response = oracle_queries([NodeQuery])
+	;
+		Response = Response0
+	).
 
 	% Find an answer which is `no' and find the suspect that
-	% corresponds to it, or else fail.
+	% corresponds to it from the given list, or else fail.
 	%
-:- pred find_incorrect_suspect(list(decl_answer), analyser_state(T),
+:- pred find_incorrect_suspect(list(decl_answer), list(suspect(T)),
 		suspect(T)).
 :- mode find_incorrect_suspect(in, in, out) is semidet.
 
-find_incorrect_suspect([Answer | Answers], Analyser, Child) :-
-	Analyser = analyser(_, Suspects, _),
+find_incorrect_suspect([Answer | Answers], Suspects, Child) :-
 	(
-		Answer = _ - no,
-		find_matching_suspects(Answer, Suspects, [Match | _], _)
+		Answer = truth_value(Question, no),
+		find_matching_suspects(Question, Suspects, [Match | _], _)
 	->
 		Match = Child
 	;
-		find_incorrect_suspect(Answers, Analyser, Child)
+		find_incorrect_suspect(Answers, Suspects, Child)
 	).
 
 	% Create a new prime suspect from the given suspect, which is
@@ -267,16 +342,22 @@
 		Analyser) :-
 
 	(
-		Answer = _ - yes
+		Answer = truth_value(_, yes)
 	->
 		Analyser0 = analyser(MaybePrime, Suspects0, OldPrimes),
-		find_matching_suspects(Answer, Suspects0, _, Suspects),
+		find_matching_suspects(get_decl_question(Answer), Suspects0,
+				_, Suspects),
 		Analyser1 = analyser(MaybePrime, Suspects, OldPrimes),
 		remove_suspects(Store, Answers, Response, Analyser1, Analyser)
 	;
 		error("remove_suspects: unexpected incorrect node")
 	).
 
+:- func get_decl_question(decl_answer) = decl_question.
+
+get_decl_question(truth_value(Q, _)) = Q.
+get_decl_question(suspicious_subterm(Q, _, _)) = Q.
+
 %-----------------------------------------------------------------------------%
 
 :- type suspect(T)
@@ -299,17 +380,14 @@
 
 suspect_get_question(suspect(_, Question), Question).
 
-:- pred suspect_answer_match(suspect(T), decl_answer, decl_truth).
-:- mode suspect_answer_match(in, in, out) is semidet.
-
-suspect_answer_match(suspect(_, Question), Question - Truth, Truth).
-
-:- pred find_matching_suspects(decl_answer, list(suspect(T)),
+:- pred find_matching_suspects(decl_question, list(suspect(T)),
 		list(suspect(T)), list(suspect(T))).
 :- mode find_matching_suspects(in, in, out, out) is det.
 
-find_matching_suspects(Answer, Suspects, Matches, NoMatches) :-
-	P = (pred(S::in) is semidet :- suspect_answer_match(S, Answer, _)),
+find_matching_suspects(Question, Suspects, Matches, NoMatches) :-
+	P = (pred(S::in) is semidet :-
+		suspect_get_question(S, Question)
+	),
 	list__filter(P, Suspects, Matches, NoMatches).
 
 %-----------------------------------------------------------------------------%
Index: browser/declarative_debugger.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_debugger.m,v
retrieving revision 1.20
diff -u -r1.20 declarative_debugger.m
--- browser/declarative_debugger.m	2001/01/24 05:18:02	1.20
+++ browser/declarative_debugger.m	2001/01/29 14:08:27
@@ -22,7 +22,7 @@
 :- module mdb__declarative_debugger.
 :- interface.
 :- import_module io, list, bool, std_util.
-:- import_module mdb__declarative_execution.
+:- import_module mdb__declarative_execution, mdb__program_representation.
 
 	% This type represents the possible truth values for nodes
 	% in the EDT.
@@ -112,7 +112,18 @@
 			%
 	;	unexpected_exception(decl_atom, decl_exception).
 
-:- type decl_answer == pair(decl_question, decl_truth).
+	% These are the possible answers that the oracle can give.
+	%
+:- type decl_answer
+			% The oracle knows the truth value of this node.
+			%
+	--->	truth_value(decl_question, decl_truth)
+
+			% The oracle does not say anything about the truth
+			% value, but is suspicious of the subterm at the
+			% given term_path and arg_pos.
+			%
+	;	suspicious_subterm(decl_question, arg_pos, term_path).
 
 :- type decl_atom == trace_atom.
 
@@ -160,7 +171,6 @@
 :- implementation.
 :- import_module require, int, char, string.
 :- import_module mdb__declarative_analyser, mdb__declarative_oracle.
-:- import_module mdb__program_representation.
 
 :- type diagnoser_state(R)
 	--->	diagnoser(
Index: browser/declarative_oracle.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_oracle.m,v
retrieving revision 1.9
diff -u -r1.9 declarative_oracle.m
--- browser/declarative_oracle.m	2000/08/10 05:50:57	1.9
+++ browser/declarative_oracle.m	2001/01/29 14:08:29
@@ -1,5 +1,5 @@
 %-----------------------------------------------------------------------------%
-% Copyright (C) 1999-2000 The University of Melbourne.
+% Copyright (C) 1999-2001 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.
 %-----------------------------------------------------------------------------%
@@ -237,12 +237,12 @@
 :- pred query_oracle_kb(oracle_kb, decl_question, decl_answer).
 :- mode query_oracle_kb(in, in, out) is semidet.
 
-query_oracle_kb(KB, Node, Node - Truth) :-
+query_oracle_kb(KB, Node, truth_value(Node, Truth)) :-
 	Node = wrong_answer(Atom),
 	get_kb_ground_map(KB, Map),
 	map__search(Map, Atom, Truth).
 
-query_oracle_kb(KB, Node, Node - Truth) :-
+query_oracle_kb(KB, Node, truth_value(Node, Truth)) :-
 	Node = missing_answer(Call, Solns),
 	set__list_to_set(Solns, Ss),
 	get_kb_complete_map(KB, CMap),
@@ -258,7 +258,7 @@
 		Truth = no
 	).
 
-query_oracle_kb(KB, Node, Node - Truth) :-
+query_oracle_kb(KB, Node, truth_value(Node, Truth)) :-
 	Node = unexpected_exception(Call, Exception),
 	get_kb_exceptions_map(KB, XMap),
 	map__search(XMap, Call, known_excp(Possible, Impossible)),
@@ -279,12 +279,14 @@
 :- pred assert_oracle_kb(decl_answer, oracle_kb, oracle_kb).
 :- mode assert_oracle_kb(in, in, out) is det.
 
-assert_oracle_kb(wrong_answer(Atom) - Truth, KB0, KB) :-
+assert_oracle_kb(suspicious_subterm(_, _, _), KB, KB).
+
+assert_oracle_kb(truth_value(wrong_answer(Atom), Truth), KB0, KB) :-
 	get_kb_ground_map(KB0, Map0),
 	map__det_insert(Map0, Atom, Truth, Map),
 	set_kb_ground_map(KB0, Map, KB).
 
-assert_oracle_kb(missing_answer(Call, Solns) - yes, KB0, KB) :-
+assert_oracle_kb(truth_value(missing_answer(Call, Solns), yes), KB0, KB) :-
 	get_kb_complete_map(KB0, Map0),
 	set__list_to_set(Solns, Ss0),
 	(
@@ -300,7 +302,7 @@
 	),
 	set_kb_complete_map(KB0, Map, KB).
 
-assert_oracle_kb(missing_answer(Call, Solns) - no, KB0, KB) :-
+assert_oracle_kb(truth_value(missing_answer(Call, Solns), no), KB0, KB) :-
 	get_kb_incomplete_map(KB0, Map0),
 	set__list_to_set(Solns, Ss),
 		%
@@ -309,8 +311,10 @@
 		%
 	map__set(Map0, Call, Ss, Map),
 	set_kb_incomplete_map(KB0, Map, KB).
+
+assert_oracle_kb(truth_value(unexpected_exception(Call, Exception), Truth),
+		KB0, KB) :-
 
-assert_oracle_kb(unexpected_exception(Call, Exception) - Truth, KB0, KB) :-
 	get_kb_exceptions_map(KB0, Map0),
 	(
 		map__search(Map0, Call, known_excp(Possible0, Impossible0))
Index: browser/declarative_user.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_user.m,v
retrieving revision 1.13
diff -u -r1.13 declarative_user.m
--- browser/declarative_user.m	2001/01/17 18:53:43	1.13
+++ browser/declarative_user.m	2001/01/29 14:08:31
@@ -46,7 +46,7 @@
 
 :- implementation.
 :- import_module mdb__browser_info, mdb__browse, mdb__util.
-:- import_module mdb__declarative_execution.
+:- import_module mdb__declarative_execution, mdb__program_representation.
 :- import_module std_util, char, string, bool, int.
 
 :- type user_state
@@ -77,11 +77,11 @@
 	get_command(Question, Command, User0, User1),
 	(
 		{ Command = yes },
-		{ Response = user_answer(Node - yes) },
+		{ Response = user_answer(truth_value(Node, yes)) },
 		{ User = User1 }
 	;
 		{ Command = no },
-		{ Response = user_answer(Node - no) },
+		{ Response = user_answer(truth_value(Node, no)) },
 		{ User = User1 }
 	;
 		{ Command = inadmissible },
@@ -96,8 +96,17 @@
 		query_user_2(Questions, [], Response, User1, User)
 	;
 		{ Command = browse(Arg) },
-		browse_edt_node(Node, Arg, User1, User2),
-		query_user_2([Node | Nodes], Skipped, Response, User2, User)
+		browse_edt_node(Node, Arg, MaybeMark, User1, User2),
+		(
+			{ MaybeMark = no },
+			query_user_2([Node | Nodes], Skipped, Response, User2,
+					User)
+		;
+			{ MaybeMark = yes(Mark) },
+			{ Answer = suspicious_subterm(Node, Arg, Mark) },
+			{ Response = user_answer(Answer) },
+			{ User = User2 }
+		)
 	;
 		{ Command = abort },
 		{ Response = abort_diagnosis },
@@ -119,11 +128,11 @@
 decl_question_prompt(missing_answer(_, _), "Complete? ").
 decl_question_prompt(unexpected_exception(_, _), "Expected? ").
 
-:- pred browse_edt_node(decl_question, int, user_state, user_state,
-		io__state, io__state).
-:- mode browse_edt_node(in, in, in, out, di, uo) is det.
+:- pred browse_edt_node(decl_question::in, int::in, maybe(term_path)::out,
+		user_state::in, user_state::out, io__state::di,
+		io__state::uo) is det.
 
-browse_edt_node(Node, ArgNum, User0, User) -->
+browse_edt_node(Node, ArgNum, MaybeMark, User0, User) -->
 	{
 		Node = wrong_answer(Atom)
 	;
@@ -131,7 +140,7 @@
 	;
 		Node = unexpected_exception(Atom, _)
 	},
-	browse_atom_argument(Atom, ArgNum, User0, User).
+	browse_atom_argument(Atom, ArgNum, MaybeMark, User0, User).
 
 :- pred browse_decl_bug(decl_bug, int, user_state, user_state,
 		io__state, io__state).
@@ -150,25 +159,34 @@
 	;
 		Bug = i_bug(inadmissible_call(_, _, Atom, _))
 	},
-	browse_atom_argument(Atom, ArgNum, User0, User).
+	browse_atom_argument(Atom, ArgNum, _, User0, User).
 
-:- pred browse_atom_argument(decl_atom, int, user_state, user_state,
-		io__state, io__state).
-:- mode browse_atom_argument(in, in, in, out, di, uo) is det.
+:- pred browse_atom_argument(decl_atom::in, int::in, maybe(term_path)::out,
+		user_state::in, user_state::out, io__state::di,
+		io__state::uo) is det.
 
-browse_atom_argument(Atom, ArgNum, User0, User) -->
+browse_atom_argument(Atom, ArgNum, MaybeMark, User0, User) -->
 	{ Atom = atom(_, _, Args) },
 	(
 		{ list__index1(Args, ArgNum, MaybeArg) },
 		{ MaybeArg = yes(Arg) }
 	->
-		browse(univ_value(Arg), User0^instr, User0^outstr,
+		browse(univ_value(Arg), User0^instr, User0^outstr, MaybeDirs,
 			User0^browser, Browser),
+		{ maybe_convert_dirs_to_path(MaybeDirs, MaybeMark) },
 		{ User = User0^browser := Browser }
 	;
 		io__write_string(User^outstr, "Invalid argument number\n"),
+		{ MaybeMark = no },
 		{ User = User0 }
 	).
+
+:- pred maybe_convert_dirs_to_path(maybe(list(dir)), maybe(term_path)).
+:- mode maybe_convert_dirs_to_path(in, out) is det.
+
+maybe_convert_dirs_to_path(no, no).
+maybe_convert_dirs_to_path(yes(Dirs), yes(TermPath)) :-
+	convert_dirs_to_term_path(Dirs, TermPath).
 
 	% Reverse the first argument and append the second to it.
 	%
Index: browser/parse.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/parse.m,v
retrieving revision 1.9
diff -u -r1.9 parse.m
--- browser/parse.m	2000/10/27 08:38:50	1.9
+++ browser/parse.m	2001/01/29 14:08:33
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 1998-2000 The University of Melbourne.
+% Copyright (C) 1998-2001 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.
 %---------------------------------------------------------------------------%
@@ -30,6 +30,7 @@
 %		"display"
 %		"write"
 %		"set" [varvalue]
+%		"mark" [path]
 %		"quit"
 %
 %	varvalue:
@@ -71,6 +72,8 @@
 	;	ls
 	;	cd(path)
 	;	cd
+	;	mark(path)
+	;	mark
 	;	pwd
 	;	help
 	;	set(setting)
@@ -251,6 +254,13 @@
 			parse_path(Toks, Path),
 			Comm = ls(Path)
 		)
+	; Tok = name("mark") ->
+		( Toks = [] ->
+			Comm = mark
+		;
+			parse_path(Toks, Path),
+			Comm = mark(Path)
+		)
 	; Tok = name("set") ->
 		( Toks = [] ->
 			Comm = set
@@ -358,6 +368,12 @@
 	io__nl.
 show_command(cd) -->
 	io__write_string("cd\n").
+show_command(mark(Path)) -->
+	io__write_string("mark "),
+	show_path(Path),
+	io__nl.
+show_command(mark) -->
+	io__write_string("mark\n").
 show_command(pwd) -->
 	io__write_string("pwd\n").
 show_command(help) -->
Index: browser/program_representation.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/program_representation.m,v
retrieving revision 1.4
diff -u -r1.4 program_representation.m
--- browser/program_representation.m	2001/01/16 15:44:17	1.4
+++ browser/program_representation.m	2001/01/29 14:08:34
@@ -34,6 +34,7 @@
 :- interface.
 
 :- import_module list, std_util.
+:- import_module mdb__browser_info.
 
 	% A representation of the goal we execute.  These need to be
 	% generated statically and stored inside the executable.
@@ -125,6 +126,10 @@
 	;	erroneous_rep
 	;	failure_rep.
 
+	% If the given atomic goal is a call to a predicate or function
+	% (not including the special predicates `unify' and `compare'),
+	% then return the list of variables that are passed as arguments.
+	%
 :- pred atomic_goal_rep_is_call(atomic_goal_rep, list(var_rep)).
 :- mode atomic_goal_rep_is_call(in, out) is semidet.
 
@@ -162,18 +167,23 @@
 
 :- type term_path ==	list(arg_pos).
 
+:- pred convert_dirs_to_term_path(list(dir), term_path).
+:- mode convert_dirs_to_term_path(in, out) is det.
+
 	% Returns type_of(_ `with_type` goal_rep), for use in C code.
 :- func goal_rep_type = type_desc.
 
 %-----------------------------------------------------------------------------%
 
 :- implementation.
-:- import_module string, char.
+:- import_module string, char, require.
 
 atomic_goal_rep_is_call(pragma_foreign_code_rep(Args), Args).
 atomic_goal_rep_is_call(higher_order_call_rep(_, Args), Args).
 atomic_goal_rep_is_call(method_call_rep(_, _, Args), Args).
-atomic_goal_rep_is_call(plain_call_rep(_, Args), Args).
+atomic_goal_rep_is_call(plain_call_rep(Name, Args), Args) :-
+	Name \= "unify",
+	Name \= "compare".
 
 path_step_from_string(String, Step) :-
 	string__first_char(String, First, Rest),
@@ -196,6 +206,12 @@
 path_step_from_string_2('q', "", exist(no_cut)).
 path_step_from_string_2('f', "", first).
 path_step_from_string_2('l', "", later).
+
+convert_dirs_to_term_path([], []).
+convert_dirs_to_term_path([child(N) | Dirs], [N | TermPath]) :-
+	convert_dirs_to_term_path(Dirs, TermPath).
+convert_dirs_to_term_path([parent | _], _) :-
+	error("convert_dirs_to_term_path: not in canonical form").
 
 :- pragma export(goal_rep_type = out, "ML_goal_rep_type").
 goal_rep_type = type_of(_ `with_type` goal_rep).
Index: tests/debugger/declarative/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/Mmakefile,v
retrieving revision 1.25
diff -u -r1.25 Mmakefile
--- tests/debugger/declarative/Mmakefile	2001/01/17 18:55:18	1.25
+++ tests/debugger/declarative/Mmakefile	2001/01/29 14:08:58
@@ -31,13 +31,16 @@
 	func_call		\
 	gcf			\
 	if_then_else		\
+	input_term_dep		\
 	lpe_example		\
 	neg_conj		\
 	negation		\
 	oracle_db		\
+	output_term_dep		\
 	propositional		\
 	queens			\
 	small			\
+	special_term_dep	\
 	throw
 
 # The following should not be run in `debug' grades.
@@ -54,6 +57,9 @@
 C2INITFLAGS = --trace
 
 MCFLAGS-deep_sub=--trace deep
+MCFLAGS-input_term_dep=--trace rep
+MCFLAGS-output_term_dep=--trace rep
+MCFLAGS-special_term_dep=--trace rep
 MCFLAGS-untraced_subgoal_sub=--trace minimum
 
 ifneq "$(findstring .debug,$(GRADE))" ""
@@ -133,6 +139,9 @@
 if_then_else.out: if_then_else if_then_else.inp
 	$(MDB) ./if_then_else < if_then_else.inp > if_then_else.out 2>&1
 
+input_term_dep.out: input_term_dep input_term_dep.inp
+	$(MDB) ./input_term_dep < input_term_dep.inp > input_term_dep.out 2>&1
+
 ite_2.out: ite_2 ite_2.inp
 	$(MDB) ./ite_2 < ite_2.inp > ite_2.out 2>&1
 
@@ -148,6 +157,10 @@
 oracle_db.out: oracle_db oracle_db.inp
 	$(MDB) ./oracle_db < oracle_db.inp > oracle_db.out 2>&1
 
+output_term_dep.out: output_term_dep output_term_dep.inp
+	$(MDB) ./output_term_dep < output_term_dep.inp	\
+			> output_term_dep.out 2>&1
+
 propositional.out: propositional propositional.inp
 	$(MDB) ./propositional < propositional.inp > propositional.out 2>&1
 
@@ -159,6 +172,10 @@
 
 solutions.out: solutions solutions.inp
 	$(MDB) ./solutions < solutions.inp > solutions.out 2>&1
+
+special_term_dep.out: special_term_dep special_term_dep.inp
+	$(MDB) ./special_term_dep < special_term_dep.inp \
+			> special_term_dep.out 2>&1
 
 # We need to pipe the output through sed to avoid hard-coding dependencies on
 # particular line numbers in the standard library source code.
Index: tests/debugger/declarative/input_term_dep.exp
===================================================================
RCS file: input_term_dep.exp
diff -N input_term_dep.exp
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ input_term_dep.exp	Tue Jan 30 01:08:59 2001
@@ -0,0 +1,100 @@
+       1:      1  1 CALL pred input_term_dep:main/2-0 (det) input_term_dep.m:9
+mdb> echo on
+Command echo enabled.
+mdb> register --quiet
+mdb> break p
+ 0: + stop  interface pred input_term_dep:p/3-0 (det)
+mdb> break q
+ 1: + stop  interface pred input_term_dep:q/1-0 (semidet)
+mdb> break r
+ 2: + stop  interface pred input_term_dep:r/2-0 (det)
+mdb> break s
+ 3: + stop  interface pred input_term_dep:s/1-0 (semidet)
+mdb> continue
+       3:      3  3 CALL pred input_term_dep:p/3-0 (det) input_term_dep.m:33 (input_term_dep.m:22)
+mdb> finish
+      10:      3  3 EXIT pred input_term_dep:p/3-0 (det) input_term_dep.m:33 (input_term_dep.m:22)
+mdb> dd
+p(5, 8, 13)
+Valid? browse 3
+browser> mark
+pc(5, 13)
+Valid? browse 1
+browser> mark
+pa(5)
+Valid? yes
+pb(8)
+Valid? yes
+Found incorrect contour:
+p(5, 8, 13)
+Is this a bug? yes
+      10:      3  3 EXIT pred input_term_dep:p/3-0 (det) input_term_dep.m:33 (input_term_dep.m:22)
+mdb> continue
+5
+8
+13
+      14:      8  3 CALL pred input_term_dep:q/1-0 (semidet) input_term_dep.m:69 (input_term_dep.m:58)
+mdb> finish
+      21:      8  3 EXIT pred input_term_dep:q/1-0 (semidet) input_term_dep.m:69 (input_term_dep.m:58)
+mdb> dd
+q([[2, 3], [], [1]])
+Valid? browse 1
+browser> mark 1/2
+pred qc
+	[[2, 3], [], [1]]
+	[[2, 3], [], [1]]
+Valid? browse 1
+browser> mark 1/2
+qa([[1], [2, 3]])
+Valid? yes
+qb([])
+Valid? yes
+Found incorrect contour:
+q([[2, 3], [], [1]])
+Is this a bug? yes
+      21:      8  3 EXIT pred input_term_dep:q/1-0 (semidet) input_term_dep.m:69 (input_term_dep.m:58)
+mdb> continue
+[[2, 3], [], [1]]
+      25:     13  3 CALL pred input_term_dep:r/2-0 (det) input_term_dep.m:111 (input_term_dep.m:93)
+mdb> finish
+      36:     13  3 EXIT pred input_term_dep:r/2-0 (det) input_term_dep.m:111 (input_term_dep.m:93)
+mdb> dd
+r(1, 33)
+Valid? browse 2
+browser> mark
+rc(3, 33)
+Valid? browse 1
+browser> mark
+ra(1, 3)
+Valid? yes
+rb(3)
+Valid? yes
+Found incorrect contour:
+r(1, 33)
+Is this a bug? yes
+      36:     13  3 EXIT pred input_term_dep:r/2-0 (det) input_term_dep.m:111 (input_term_dep.m:93)
+mdb> continue
+33
+      40:     18  3 CALL pred input_term_dep:s/1-0 (semidet) input_term_dep.m:146 (input_term_dep.m:135)
+mdb> finish
+      51:     18  3 EXIT pred input_term_dep:s/1-0 (semidet) input_term_dep.m:146 (input_term_dep.m:135)
+mdb> dd
+s(1)
+Valid? no
+sa(1, 7)
+Valid? skip
+sb(7)
+Valid? skip
+sc(7)
+Valid? browse 1
+browser> mark
+sa(1, 7)
+Valid? yes
+sb(7)
+Valid? yes
+Found incorrect contour:
+s(1)
+Is this a bug? yes
+      51:     18  3 EXIT pred input_term_dep:s/1-0 (semidet) input_term_dep.m:146 (input_term_dep.m:135)
+mdb> continue
+yes
Index: tests/debugger/declarative/input_term_dep.exp2
===================================================================
RCS file: input_term_dep.exp2
diff -N input_term_dep.exp2
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ input_term_dep.exp2	Tue Jan 30 01:08:59 2001
@@ -0,0 +1,100 @@
+       1:      1  1 CALL pred input_term_dep:main/2-0 (det) input_term_dep.m:9
+mdb> echo on
+Command echo enabled.
+mdb> register --quiet
+mdb> break p
+ 0: + stop  interface pred input_term_dep:p/3-0 (det)
+mdb> break q
+ 1: + stop  interface pred input_term_dep:q/1-0 (semidet)
+mdb> break r
+ 2: + stop  interface pred input_term_dep:r/2-0 (det)
+mdb> break s
+ 3: + stop  interface pred input_term_dep:s/1-0 (semidet)
+mdb> continue
+       3:      3  3 CALL pred input_term_dep:p/3-0 (det) input_term_dep.m:33 (input_term_dep.m:22)
+mdb> finish
+      10:      3  3 EXIT pred input_term_dep:p/3-0 (det) input_term_dep.m:33 (input_term_dep.m:22)
+mdb> dd
+p(5, 8, 13)
+Valid? browse 3
+browser> mark
+pc(5, 13)
+Valid? browse 1
+browser> mark
+pa(5)
+Valid? yes
+pb(8)
+Valid? yes
+Found incorrect contour:
+p(5, 8, 13)
+Is this a bug? yes
+      10:      3  3 EXIT pred input_term_dep:p/3-0 (det) input_term_dep.m:33 (input_term_dep.m:22)
+mdb> continue
+5
+8
+13
+      26:     14  3 CALL pred input_term_dep:q/1-0 (semidet) input_term_dep.m:69 (input_term_dep.m:58)
+mdb> finish
+      35:     14  3 EXIT pred input_term_dep:q/1-0 (semidet) input_term_dep.m:69 (input_term_dep.m:58)
+mdb> dd
+q([[2, 3], [], [1]])
+Valid? browse 1
+browser> mark 1/2
+pred qc
+	[[2, 3], [], [1]]
+	[[2, 3], [], [1]]
+Valid? browse 1
+browser> mark 1/2
+qa([[1], [2, 3]])
+Valid? yes
+qb([])
+Valid? yes
+Found incorrect contour:
+q([[2, 3], [], [1]])
+Is this a bug? yes
+      35:     14  3 EXIT pred input_term_dep:q/1-0 (semidet) input_term_dep.m:69 (input_term_dep.m:58)
+mdb> continue
+[[2, 3], [], [1]]
+      43:     22  3 CALL pred input_term_dep:r/2-0 (det) input_term_dep.m:111 (input_term_dep.m:93)
+mdb> finish
+      54:     22  3 EXIT pred input_term_dep:r/2-0 (det) input_term_dep.m:111 (input_term_dep.m:93)
+mdb> dd
+r(1, 33)
+Valid? browse 2
+browser> mark
+rc(3, 33)
+Valid? browse 1
+browser> mark
+ra(1, 3)
+Valid? yes
+rb(3)
+Valid? yes
+Found incorrect contour:
+r(1, 33)
+Is this a bug? yes
+      54:     22  3 EXIT pred input_term_dep:r/2-0 (det) input_term_dep.m:111 (input_term_dep.m:93)
+mdb> continue
+33
+      62:     29  3 CALL pred input_term_dep:s/1-0 (semidet) input_term_dep.m:146 (input_term_dep.m:135)
+mdb> finish
+      73:     29  3 EXIT pred input_term_dep:s/1-0 (semidet) input_term_dep.m:146 (input_term_dep.m:135)
+mdb> dd
+s(1)
+Valid? no
+sa(1, 7)
+Valid? skip
+sb(7)
+Valid? skip
+sc(7)
+Valid? browse 1
+browser> mark
+sa(1, 7)
+Valid? yes
+sb(7)
+Valid? yes
+Found incorrect contour:
+s(1)
+Is this a bug? yes
+      73:     29  3 EXIT pred input_term_dep:s/1-0 (semidet) input_term_dep.m:146 (input_term_dep.m:135)
+mdb> continue
+yes
Index: tests/debugger/declarative/input_term_dep.inp
===================================================================
RCS file: input_term_dep.inp
diff -N input_term_dep.inp
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ input_term_dep.inp	Tue Jan 30 01:08:59 2001
@@ -0,0 +1,48 @@
+echo on
+register --quiet
+break p
+break q
+break r
+break s
+continue
+finish
+dd
+browse 3
+mark
+browse 1
+mark
+yes
+yes
+yes
+continue
+finish
+dd
+browse 1
+mark 1/2
+browse 1
+mark 1/2
+yes
+yes
+yes
+continue
+finish
+dd
+browse 2
+mark
+browse 1
+mark
+yes
+yes
+yes
+continue
+finish
+dd
+no
+skip
+skip
+browse 1
+mark
+yes
+yes
+yes
+continue
Index: tests/debugger/declarative/input_term_dep.m
===================================================================
RCS file: input_term_dep.m
diff -N input_term_dep.m
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ input_term_dep.m	Tue Jan 30 01:08:59 2001
@@ -0,0 +1,167 @@
+:- module input_term_dep.
+:- interface.
+:- import_module io.
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+:- import_module list.
+
+main -->
+	%
+	% Test cases which track an input subterm.
+	%
+	test1,		% basic det conjunction
+	test2,		% construction unification
+	test3,		% if-then-else
+	test4.		% negation
+
+%-----------------------------------------------------------------------------%
+
+:- pred test1(io__state::di, io__state::uo) is det.
+test1 -->
+	{ p(A, B, C) },
+	io__write_int(A),
+	io__nl,
+	io__write_int(B),
+	io__nl,
+	io__write_int(C),
+	io__nl.
+
+:- pred p(int, int, int).
+:- mode p(out, out, out) is det.
+
+p(A, B, C) :-
+	pa(A),
+	pb(B),
+	pc(A, C).
+
+:- pred pa(int).
+:- mode pa(out) is det.
+
+pa(5).
+
+:- pred pb(int).
+:- mode pb(out) is det.
+
+pb(8).
+
+:- pred pc(int, int).
+:- mode pc(in, out) is det.
+
+pc(_, 13).
+
+%-----------------------------------------------------------------------------%
+
+:- pred test2(io__state::di, io__state::uo) is det.
+test2 -->
+	(
+		{ q(X) }
+	->
+		io__write(X),
+		io__nl
+	;
+		io__write_string("no\n")
+	).
+
+:- pred q(list(list(int))).
+:- mode q(out) is semidet.
+
+q(L) :-
+	qa([C, A]),
+	qb(B),
+	qc([A, B, C], L).
+
+:- pred qa(list(list(int))).
+:- mode qa(out) is det.
+
+qa([[1], [2, 3]]).
+
+:- pred qb(list(int)).
+:- mode qb(out) is det.
+
+qb([]).
+
+:- pred qc(list(list(int)), list(list(int))).
+:- mode qc(in, out) is det.
+
+qc(L, L).
+
+%-----------------------------------------------------------------------------%
+
+:- pred test3(io__state::di, io__state::uo) is det.
+test3 -->
+	{ r(1, Z) },
+	io__write(Z),
+	io__nl.
+
+:- pred r(int, int).
+:- mode r(in, out) is det.
+
+r(N, P) :-
+	(
+		ra(N, A)
+	->
+		(
+			rb(A)
+		->
+			rc(A, P)
+		;
+			P = 1
+		)
+	;
+		P = 99
+	).
+
+:- pred ra(int, int).
+:- mode ra(in, out) is semidet.
+
+ra(1, 3).
+
+:- pred rb(int).
+:- mode rb(in) is semidet.
+
+rb(3).
+
+:- pred rc(int, int).
+:- mode rc(in, out) is det.
+
+rc(_, 33).
+
+%-----------------------------------------------------------------------------%
+
+:- pred test4(io__state::di, io__state::uo) is det.
+test4 -->
+	(
+		{ s(1) }
+	->
+		io__write_string("yes\n")
+	;
+		io__write_string("no\n")
+	).
+
+:- pred s(int).
+:- mode s(in) is semidet.
+
+s(N) :-
+	\+ (
+		sa(N, A),
+		sb(A),
+		\+ sc(A)
+	).
+
+:- pred sa(int, int).
+:- mode sa(in, out) is semidet.
+
+sa(1, 7).
+
+:- pred sb(int).
+:- mode sb(in) is semidet.
+
+sb(7).
+
+:- pred sc(int).
+:- mode sc(in) is semidet.
+
+sc(7).
+
+%-----------------------------------------------------------------------------%
Index: tests/debugger/declarative/output_term_dep.exp
===================================================================
RCS file: output_term_dep.exp
diff -N output_term_dep.exp
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ output_term_dep.exp	Tue Jan 30 01:09:01 2001
@@ -0,0 +1,244 @@
+       1:      1  1 CALL pred output_term_dep:main/2-0 (det) output_term_dep.m:9
+mdb> echo on
+Command echo enabled.
+mdb> register --quiet
+mdb> break p
+ 0: + stop  interface pred output_term_dep:p/3-0 (det)
+mdb> break q
+ 1: + stop  interface pred output_term_dep:q/1-0 (det)
+mdb> break r
+ 2: + stop  interface pred output_term_dep:r/2-0 (det)
+mdb> break s
+ 3: + stop  interface pred output_term_dep:s/3-0 (nondet)
+mdb> break t
+ 4: + stop  interface pred output_term_dep:t/2-0 (semidet)
+mdb> continue
+       3:      3  3 CALL pred output_term_dep:p/3-0 (det) output_term_dep.m:34 (output_term_dep.m:23)
+mdb> finish
+      10:      3  3 EXIT pred output_term_dep:p/3-0 (det) output_term_dep.m:34 (output_term_dep.m:23)
+mdb> dd
+p(5, 8, 13)
+Valid? browse 2
+browser> mark
+pb(8)
+Valid? yes
+pa(5)
+Valid? yes
+pc(13)
+Valid? yes
+Found incorrect contour:
+p(5, 8, 13)
+Is this a bug? yes
+      10:      3  3 EXIT pred output_term_dep:p/3-0 (det) output_term_dep.m:34 (output_term_dep.m:23)
+mdb> continue
+5
+8
+13
+      13:      8  3 CALL pred output_term_dep:q/1-0 (det) output_term_dep.m:65 (output_term_dep.m:58)
+mdb> finish
+      20:      8  3 EXIT pred output_term_dep:q/1-0 (det) output_term_dep.m:65 (output_term_dep.m:58)
+mdb> dd
+q([[1, 2, 3], [], [99]])
+Valid? browse 1
+browser> mark 2/1
+qb([])
+Valid? yes
+qa([1, 2, 3])
+Valid? yes
+qc([99])
+Valid? yes
+Found incorrect contour:
+q([[1, 2, 3], [], [99]])
+Is this a bug? yes
+      20:      8  3 EXIT pred output_term_dep:q/1-0 (det) output_term_dep.m:65 (output_term_dep.m:58)
+mdb> continue
+[[1, 2, 3], [], [99]]
+      23:     13  3 CALL pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:89)
+mdb> finish
+      26:     13  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:89)
+mdb> dd
+r(1, 999)
+Valid? browse 2
+browser> mark
+Found incorrect contour:
+r(1, 999)
+Is this a bug? yes
+      26:     13  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:89)
+mdb> continue
+999
+      27:     14  3 CALL pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:92)
+mdb> finish
+      39:     14  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:92)
+mdb> dd
+r(2, 43)
+Valid? browse 2
+browser> mark
+ra(2)
+Valid? yes
+Call rb(2)
+No solutions.
+Complete? yes
+Found incorrect contour:
+r(2, 43)
+Is this a bug? yes
+      39:     14  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:92)
+mdb> continue
+43
+      40:     17  3 CALL pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:95)
+mdb> finish
+      54:     17  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:95)
+mdb> dd
+r(3, 57)
+Valid? browse 2
+browser> mark
+rc(57)
+Valid? yes
+ra(3)
+Valid? yes
+rb(3)
+Valid? yes
+Found incorrect contour:
+r(3, 57)
+Is this a bug? yes
+      54:     17  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:95)
+mdb> continue
+57
+      55:     21  3 CALL pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:98)
+mdb> finish
+      64:     21  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:98)
+mdb> dd
+r(4, -1)
+Valid? browse 2
+browser> mark
+rd(-1)
+Valid? yes
+Call ra(4)
+No solutions.
+Complete? yes
+Found incorrect contour:
+r(4, -1)
+Is this a bug? yes
+      64:     21  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:98)
+mdb> continue
+-1
+      68:     25  3 CALL pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> finish
+      76:     25  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> dd
+s(1, 7, 7)
+Valid? browse 2
+browser> mark
+sa(7)
+Valid? no
+Found incorrect contour:
+sa(7)
+Is this a bug? yes
+      72:     26  4 EXIT pred output_term_dep:sa/1-0 (det) output_term_dep.m:192 (output_term_dep.m:171)
+mdb> continue
+      76:     25  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> continue
+      79:     25  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> finish
+      83:     25  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> dd
+s(1, 7, 155)
+Valid? browse 3
+browser> mark
+sc(155)
+Valid? no
+Found incorrect contour:
+sc(155)
+Is this a bug? yes
+      82:     29  4 EXIT pred output_term_dep:sc/1-0 (det) output_term_dep.m:202 (output_term_dep.m:178)
+mdb> continue
+      83:     25  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> continue
+      86:     25  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> finish
+      93:     25  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> dd
+s(1, 38, 7)
+Valid? browse 3
+browser> mark
+Found incorrect contour:
+sa(7)
+Is this a bug? yes
+      92:     32  4 EXIT pred output_term_dep:sa/1-0 (det) output_term_dep.m:192 (output_term_dep.m:176)
+mdb> continue
+      93:     25  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> continue
+      96:     25  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> finish
+     100:     25  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> dd
+s(1, 38, 155)
+Valid? browse 3
+browser> mark
+Found incorrect contour:
+sc(155)
+Is this a bug? yes
+      99:     34  4 EXIT pred output_term_dep:sc/1-0 (det) output_term_dep.m:202 (output_term_dep.m:178)
+mdb> continue
+     100:     25  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> continue
+     103:     25  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> finish
+     104:     25  3 FAIL pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> continue
+no
+     107:     36  3 CALL pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> finish
+     114:     36  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> dd
+s(2, 7, 38)
+Valid? browse 3
+browser> mark
+sb(38)
+Valid? no
+Found incorrect contour:
+sb(38)
+Is this a bug? yes
+     113:     38  4 EXIT pred output_term_dep:sb/1-0 (det) output_term_dep.m:197 (output_term_dep.m:183)
+mdb> continue
+     114:     36  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> continue
+     117:     36  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> finish
+     123:     36  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> dd
+s(2, 38, 155)
+Valid? browse 2
+browser> mark
+Found incorrect contour:
+sb(38)
+Is this a bug? yes
+     120:     40  4 EXIT pred output_term_dep:sb/1-0 (det) output_term_dep.m:197 (output_term_dep.m:185)
+mdb> continue
+     123:     36  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> continue
+     126:     36  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> continue
+     127:     36  3 FAIL pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> continue
+no
+     132:     44  3 CALL pred output_term_dep:t/2-0 (semidet) output_term_dep.m:225 (output_term_dep.m:214)
+mdb> finish
+     143:     44  3 EXIT pred output_term_dep:t/2-0 (semidet) output_term_dep.m:225 (output_term_dep.m:214)
+mdb> dd
+t(1, 77)
+Valid? browse 2
+browser> mark
+tb(77)
+Valid? yes
+Call ta(1)
+No solutions.
+Complete? yes
+Call tc(77)
+No solutions.
+Complete? yes
+Found incorrect contour:
+t(1, 77)
+Is this a bug? yes
+     143:     44  3 EXIT pred output_term_dep:t/2-0 (semidet) output_term_dep.m:225 (output_term_dep.m:214)
+mdb> continue
+77
Index: tests/debugger/declarative/output_term_dep.exp2
===================================================================
RCS file: output_term_dep.exp2
diff -N output_term_dep.exp2
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ output_term_dep.exp2	Tue Jan 30 01:09:02 2001
@@ -0,0 +1,244 @@
+       1:      1  1 CALL pred output_term_dep:main/2-0 (det) output_term_dep.m:9
+mdb> echo on
+Command echo enabled.
+mdb> register --quiet
+mdb> break p
+ 0: + stop  interface pred output_term_dep:p/3-0 (det)
+mdb> break q
+ 1: + stop  interface pred output_term_dep:q/1-0 (det)
+mdb> break r
+ 2: + stop  interface pred output_term_dep:r/2-0 (det)
+mdb> break s
+ 3: + stop  interface pred output_term_dep:s/3-0 (nondet)
+mdb> break t
+ 4: + stop  interface pred output_term_dep:t/2-0 (semidet)
+mdb> continue
+       3:      3  3 CALL pred output_term_dep:p/3-0 (det) output_term_dep.m:34 (output_term_dep.m:23)
+mdb> finish
+      10:      3  3 EXIT pred output_term_dep:p/3-0 (det) output_term_dep.m:34 (output_term_dep.m:23)
+mdb> dd
+p(5, 8, 13)
+Valid? browse 2
+browser> mark
+pb(8)
+Valid? yes
+pa(5)
+Valid? yes
+pc(13)
+Valid? yes
+Found incorrect contour:
+p(5, 8, 13)
+Is this a bug? yes
+      10:      3  3 EXIT pred output_term_dep:p/3-0 (det) output_term_dep.m:34 (output_term_dep.m:23)
+mdb> continue
+5
+8
+13
+      25:     14  3 CALL pred output_term_dep:q/1-0 (det) output_term_dep.m:65 (output_term_dep.m:58)
+mdb> finish
+      32:     14  3 EXIT pred output_term_dep:q/1-0 (det) output_term_dep.m:65 (output_term_dep.m:58)
+mdb> dd
+q([[1, 2, 3], [], [99]])
+Valid? browse 1
+browser> mark 2/1
+qb([])
+Valid? yes
+qa([1, 2, 3])
+Valid? yes
+qc([99])
+Valid? yes
+Found incorrect contour:
+q([[1, 2, 3], [], [99]])
+Is this a bug? yes
+      32:     14  3 EXIT pred output_term_dep:q/1-0 (det) output_term_dep.m:65 (output_term_dep.m:58)
+mdb> continue
+[[1, 2, 3], [], [99]]
+      39:     21  3 CALL pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:89)
+mdb> finish
+      42:     21  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:89)
+mdb> dd
+r(1, 999)
+Valid? browse 2
+browser> mark
+Found incorrect contour:
+r(1, 999)
+Is this a bug? yes
+      42:     21  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:89)
+mdb> continue
+999
+      47:     24  3 CALL pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:92)
+mdb> finish
+      59:     24  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:92)
+mdb> dd
+r(2, 43)
+Valid? browse 2
+browser> mark
+ra(2)
+Valid? yes
+Call rb(2)
+No solutions.
+Complete? yes
+Found incorrect contour:
+r(2, 43)
+Is this a bug? yes
+      59:     24  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:92)
+mdb> continue
+43
+      64:     29  3 CALL pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:95)
+mdb> finish
+      78:     29  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:95)
+mdb> dd
+r(3, 57)
+Valid? browse 2
+browser> mark
+rc(57)
+Valid? yes
+ra(3)
+Valid? yes
+rb(3)
+Valid? yes
+Found incorrect contour:
+r(3, 57)
+Is this a bug? yes
+      78:     29  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:95)
+mdb> continue
+57
+      83:     35  3 CALL pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:98)
+mdb> finish
+      92:     35  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:98)
+mdb> dd
+r(4, -1)
+Valid? browse 2
+browser> mark
+rd(-1)
+Valid? yes
+Call ra(4)
+No solutions.
+Complete? yes
+Found incorrect contour:
+r(4, -1)
+Is this a bug? yes
+      92:     35  3 EXIT pred output_term_dep:r/2-0 (det) output_term_dep.m:110 (output_term_dep.m:98)
+mdb> continue
+-1
+     100:     41  3 CALL pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> finish
+     108:     41  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> dd
+s(1, 7, 7)
+Valid? browse 2
+browser> mark
+sa(7)
+Valid? no
+Found incorrect contour:
+sa(7)
+Is this a bug? yes
+     104:     42  4 EXIT pred output_term_dep:sa/1-0 (det) output_term_dep.m:192 (output_term_dep.m:171)
+mdb> continue
+     108:     41  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> continue
+     111:     41  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> finish
+     115:     41  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> dd
+s(1, 7, 155)
+Valid? browse 3
+browser> mark
+sc(155)
+Valid? no
+Found incorrect contour:
+sc(155)
+Is this a bug? yes
+     114:     45  4 EXIT pred output_term_dep:sc/1-0 (det) output_term_dep.m:202 (output_term_dep.m:178)
+mdb> continue
+     115:     41  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> continue
+     118:     41  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> finish
+     125:     41  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> dd
+s(1, 38, 7)
+Valid? browse 3
+browser> mark
+Found incorrect contour:
+sa(7)
+Is this a bug? yes
+     124:     48  4 EXIT pred output_term_dep:sa/1-0 (det) output_term_dep.m:192 (output_term_dep.m:176)
+mdb> continue
+     125:     41  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> continue
+     128:     41  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> finish
+     132:     41  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> dd
+s(1, 38, 155)
+Valid? browse 3
+browser> mark
+Found incorrect contour:
+sc(155)
+Is this a bug? yes
+     131:     50  4 EXIT pred output_term_dep:sc/1-0 (det) output_term_dep.m:202 (output_term_dep.m:178)
+mdb> continue
+     132:     41  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> continue
+     135:     41  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> finish
+     136:     41  3 FAIL pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:150)
+mdb> continue
+no
+     141:     53  3 CALL pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> finish
+     148:     53  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> dd
+s(2, 7, 38)
+Valid? browse 3
+browser> mark
+sb(38)
+Valid? no
+Found incorrect contour:
+sb(38)
+Is this a bug? yes
+     147:     55  4 EXIT pred output_term_dep:sb/1-0 (det) output_term_dep.m:197 (output_term_dep.m:183)
+mdb> continue
+     148:     53  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> continue
+     151:     53  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> finish
+     157:     53  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> dd
+s(2, 38, 155)
+Valid? browse 2
+browser> mark
+Found incorrect contour:
+sb(38)
+Is this a bug? yes
+     154:     57  4 EXIT pred output_term_dep:sb/1-0 (det) output_term_dep.m:197 (output_term_dep.m:185)
+mdb> continue
+     157:     53  3 EXIT pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> continue
+     160:     53  3 REDO pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> continue
+     161:     53  3 FAIL pred output_term_dep:s/3-0 (nondet) output_term_dep.m:169 (output_term_dep.m:158)
+mdb> continue
+no
+     168:     62  3 CALL pred output_term_dep:t/2-0 (semidet) output_term_dep.m:225 (output_term_dep.m:214)
+mdb> finish
+     179:     62  3 EXIT pred output_term_dep:t/2-0 (semidet) output_term_dep.m:225 (output_term_dep.m:214)
+mdb> dd
+t(1, 77)
+Valid? browse 2
+browser> mark
+tb(77)
+Valid? yes
+Call ta(1)
+No solutions.
+Complete? yes
+Call tc(77)
+No solutions.
+Complete? yes
+Found incorrect contour:
+t(1, 77)
+Is this a bug? yes
+     179:     62  3 EXIT pred output_term_dep:t/2-0 (semidet) output_term_dep.m:225 (output_term_dep.m:214)
+mdb> continue
+77
Index: tests/debugger/declarative/output_term_dep.inp
===================================================================
RCS file: output_term_dep.inp
diff -N output_term_dep.inp
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ output_term_dep.inp	Tue Jan 30 01:09:02 2001
@@ -0,0 +1,115 @@
+echo on
+register --quiet
+break p
+break q
+break r
+break s
+break t
+continue
+finish
+dd
+browse 2
+mark
+yes
+yes
+yes
+yes
+continue
+finish
+dd
+browse 1
+mark 2/1
+yes
+yes
+yes
+yes
+continue
+finish
+dd
+browse 2
+mark
+yes
+continue
+finish
+dd
+browse 2
+mark
+yes
+yes
+yes
+continue
+finish
+dd
+browse 2
+mark
+yes
+yes
+yes
+yes
+continue
+finish
+dd
+browse 2
+mark
+yes
+yes
+yes
+continue
+finish
+dd
+browse 2
+mark
+no
+yes
+continue
+continue
+finish
+dd
+browse 3
+mark
+no
+yes
+continue
+continue
+finish
+dd
+browse 3
+mark
+yes
+continue
+continue
+finish
+dd
+browse 3
+mark
+yes
+continue
+continue
+finish
+continue
+finish
+dd
+browse 3
+mark
+no
+yes
+continue
+continue
+finish
+dd
+browse 2
+mark
+yes
+continue
+continue
+continue
+continue
+finish
+dd
+browse 2
+mark
+yes
+yes
+yes
+yes
+continue
Index: tests/debugger/declarative/output_term_dep.m
===================================================================
RCS file: output_term_dep.m
diff -N output_term_dep.m
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ output_term_dep.m	Tue Jan 30 01:09:02 2001
@@ -0,0 +1,246 @@
+:- module output_term_dep.
+:- interface.
+:- import_module io.
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+:- import_module list.
+
+main -->
+	%
+	% Test cases which track an output subterm.
+	%
+	test1,		% basic det conjunction
+	test2,		% construction unification
+	test3,		% if-then-else
+	test4,		% switch and disjunction
+	test5.		% negation
+
+%-----------------------------------------------------------------------------%
+
+:- pred test1(io__state::di, io__state::uo) is det.
+test1 -->
+	{ p(A, B, C) },
+	io__write_int(A),
+	io__nl,
+	io__write_int(B),
+	io__nl,
+	io__write_int(C),
+	io__nl.
+
+:- pred p(int, int, int).
+:- mode p(out, out, out) is det.
+
+p(A, B, C) :-		% tracking subterm B
+	pa(A),
+	pb(B),
+	pc(C).
+
+:- pred pa(int).
+:- mode pa(out) is det.
+
+pa(5).
+
+:- pred pb(int).
+:- mode pb(out) is det.
+
+pb(8).
+
+:- pred pc(int).
+:- mode pc(out) is det.
+
+pc(13).
+
+%-----------------------------------------------------------------------------%
+
+:- pred test2(io__state::di, io__state::uo) is det.
+test2 -->
+	{ q(X) },
+	io__write(X),
+	io__nl.
+
+:- pred q(list(list(int))).
+:- mode q(out) is det.
+
+q([A, B, C]) :-		% tracking subterm B
+	qa(A),
+	qb(B),
+	qc(C).
+
+:- pred qa(list(int)).
+:- mode qa(out) is det.
+
+qa([1, 2, 3]).
+
+:- pred qb(list(int)).
+:- mode qb(out) is det.
+
+qb([]).
+
+:- pred qc(list(int)).
+:- mode qc(out) is det.
+
+qc([99]).
+
+%-----------------------------------------------------------------------------%
+
+:- pred test3(io__state::di, io__state::uo) is det.
+test3 -->
+	{ r(1, W) },
+	io__write(W),
+	io__nl,
+	{ r(2, X) },
+	io__write(X),
+	io__nl,
+	{ r(3, Y) },
+	io__write(Y),
+	io__nl,
+	{ r(4, Z) },
+	io__write(Z),
+	io__nl.
+
+:- pred r(int, int).
+:- mode r(in, out) is det.
+
+r(N, P) :-
+	(
+		N = 1
+	->
+		P = 999
+	;
+		ra(N)
+	->
+		(
+			rb(N)
+		->
+			rc(P)
+		;
+			P = 43
+		)
+	;
+		rd(P)
+	).
+
+:- pred ra(int).
+:- mode ra(in) is semidet.
+
+ra(2).
+ra(3).
+
+:- pred rb(int).
+:- mode rb(in) is semidet.
+
+rb(3).
+
+:- pred rc(int).
+:- mode rc(out) is det.
+
+rc(57).
+
+:- pred rd(int).
+:- mode rd(out) is det.
+
+rd(-1).
+
+%-----------------------------------------------------------------------------%
+
+:- pred test4(io__state::di, io__state::uo) is det.
+test4 -->
+	(
+		{ s(1, _, X) },
+		{ sd(X) }
+	->
+		io__write_string("yes\n")
+	;
+		io__write_string("no\n")
+	),
+	(
+		{ s(2, _, Y) },
+		{ sd(Y) }
+	->
+		io__write_string("yes\n")
+	;
+		io__write_string("no\n")
+	).
+
+:- pred s(int, int, int).
+:- mode s(in, out, out) is nondet.
+
+s(1, J, K) :-
+	(
+		sa(J)
+	;
+		sb(J)
+	),
+	(
+		sa(K)
+	;
+		sc(K)
+	).
+s(2, J, K) :-
+	(
+		sa(J),
+		sb(K)
+	;
+		sb(J),
+		sc(K)
+	).
+
+:- pred sa(int).
+:- mode sa(out) is det.
+
+sa(7).
+
+:- pred sb(int).
+:- mode sb(out) is det.
+
+sb(38).
+
+:- pred sc(int).
+:- mode sc(out) is det.
+
+sc(155).
+
+:- pred sd(int).
+:- mode sd(in) is semidet.
+
+sd(-3).
+
+%-----------------------------------------------------------------------------%
+
+:- pred test5(io__state::di, io__state::uo) is det.
+test5 -->
+	(
+		{ t(1, K) }
+	->
+		io__write_int(K),
+		io__nl
+	;
+		io__write_string("no\n")
+	).
+
+:- pred t(int, int).
+:- mode t(in, out) is semidet.
+
+t(J, K) :-
+	\+ ta(J),
+	tb(K),
+	\+ tc(K).
+
+:- pred ta(int).
+:- mode ta(in) is semidet.
+
+ta(0).
+
+:- pred tb(int).
+:- mode tb(out) is det.
+
+tb(77).
+
+:- pred tc(int).
+:- mode tc(in) is semidet.
+
+tc(-654).
+
+%-----------------------------------------------------------------------------%
+
Index: tests/debugger/declarative/special_term_dep.exp
===================================================================
RCS file: special_term_dep.exp
diff -N special_term_dep.exp
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ special_term_dep.exp	Tue Jan 30 01:09:03 2001
@@ -0,0 +1,42 @@
+       1:      1  1 CALL pred special_term_dep:main/2-0 (det) special_term_dep.m:13
+mdb> echo on
+Command echo enabled.
+mdb> register --quiet
+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
+       3:      3  3 CALL pred special_term_dep:p/1-0 (det) special_term_dep.m:29 (special_term_dep.m:22)
+mdb> finish
+       8:      3  3 EXIT pred special_term_dep:p/1-0 (det) special_term_dep.m:29 (special_term_dep.m:22)
+mdb> dd
+p([2, 3])
+Valid? browse 1
+browser> mark
+pa([2, 3])
+Valid? yes
+Found incorrect contour:
+p([2, 3])
+Is this a bug? yes
+       8:      3  3 EXIT pred special_term_dep:p/1-0 (det) special_term_dep.m:29 (special_term_dep.m:22)
+mdb> continue
+[2, 3]
+      12:      6  3 CALL pred special_term_dep:q/2-0 (semidet) special_term_dep.m:61 (special_term_dep.m:50)
+mdb> finish
+      17:      6  3 EXIT pred special_term_dep:q/2-0 (semidet) special_term_dep.m:61 (special_term_dep.m:50)
+mdb> dd
+q([1, 2], [3])
+Valid? browse 2
+browser> mark
+qb([1, 2], [3])
+Valid? browse 1
+browser> mark
+qa([1, 2])
+Valid? yes
+Found incorrect contour:
+q([1, 2], [3])
+Is this a bug? yes
+      17:      6  3 EXIT pred special_term_dep:q/2-0 (semidet) special_term_dep.m:61 (special_term_dep.m:50)
+mdb> continue
+[3]
Index: tests/debugger/declarative/special_term_dep.exp2
===================================================================
RCS file: special_term_dep.exp2
diff -N special_term_dep.exp2
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ special_term_dep.exp2	Tue Jan 30 01:09:03 2001
@@ -0,0 +1,42 @@
+       1:      1  1 CALL pred special_term_dep:main/2-0 (det) special_term_dep.m:13
+mdb> echo on
+Command echo enabled.
+mdb> register --quiet
+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
+       3:      3  3 CALL pred special_term_dep:p/1-0 (det) special_term_dep.m:29 (special_term_dep.m:22)
+mdb> finish
+      10:      3  3 EXIT pred special_term_dep:p/1-0 (det) special_term_dep.m:29 (special_term_dep.m:22)
+mdb> dd
+p([2, 3])
+Valid? browse 1
+browser> mark
+pa([2, 3])
+Valid? yes
+Found incorrect contour:
+p([2, 3])
+Is this a bug? yes
+      10:      3  3 EXIT pred special_term_dep:p/1-0 (det) special_term_dep.m:29 (special_term_dep.m:22)
+mdb> continue
+[2, 3]
+      18:      9  3 CALL pred special_term_dep:q/2-0 (semidet) special_term_dep.m:61 (special_term_dep.m:50)
+mdb> finish
+      25:      9  3 EXIT pred special_term_dep:q/2-0 (semidet) special_term_dep.m:61 (special_term_dep.m:50)
+mdb> dd
+q([1, 2], [3])
+Valid? browse 2
+browser> mark
+qb([1, 2], [3])
+Valid? browse 1
+browser> mark
+qa([1, 2])
+Valid? yes
+Found incorrect contour:
+q([1, 2], [3])
+Is this a bug? yes
+      25:      9  3 EXIT pred special_term_dep:q/2-0 (semidet) special_term_dep.m:61 (special_term_dep.m:50)
+mdb> continue
+[3]
Index: tests/debugger/declarative/special_term_dep.inp
===================================================================
RCS file: special_term_dep.inp
diff -N special_term_dep.inp
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ special_term_dep.inp	Tue Jan 30 01:09:03 2001
@@ -0,0 +1,21 @@
+echo on
+register --quiet
+break p
+break q
+continue
+finish
+dd
+browse 1
+mark
+yes
+yes
+continue
+finish
+dd
+browse 2
+mark
+browse 1
+mark
+yes
+yes
+continue
Index: tests/debugger/declarative/special_term_dep.m
===================================================================
RCS file: special_term_dep.m
diff -N special_term_dep.m
--- /dev/null	Wed Nov 15 09:24:47 2000
+++ special_term_dep.m	Tue Jan 30 01:09:03 2001
@@ -0,0 +1,76 @@
+:- module special_term_dep.
+:- interface.
+:- import_module io.
+:- pred main(io__state::di, io__state::uo) is det.
+
+%
+% Term dependencies in the presence of calls to special predicates.
+%
+
+:- implementation.
+:- import_module list.
+
+main -->
+	test1,			% compare
+	test2.			% unify
+
+%-----------------------------------------------------------------------------%
+
+:- pred test1(io__state::di, io__state::uo) is det.
+
+test1 -->
+	{ p(L) },
+	io__write(L),
+	io__nl.
+
+:- pred p(list(int)).
+:- mode p(out) is det.
+
+p(L) :-
+	pa(L0),
+	(
+		compare('>', L0, [1])
+	->
+		L = L0
+	;
+		L = []
+	).
+
+:- pred pa(list(int)).
+:- mode pa(out) is det.
+
+pa([2, 3]).
+
+%-----------------------------------------------------------------------------%
+
+:- pred test2(io__state::di, io__state::uo) is det.
+
+test2 -->
+	(
+		{ q([1, 2], L) }
+	->
+		io__write(L),
+		io__nl
+	;
+		io__write_string("no\n")
+	).
+
+:- pred q(list(int), list(int)).
+:- mode q(in, out) is semidet.
+
+q(A, B) :-
+	qa(A),
+	qb(A, B).
+
+:- pred qa(list(int)).
+:- mode qa(out) is det.
+
+qa([1, 2]).
+
+:- pred qb(list(int), list(int)).
+:- mode qb(in, out) is det.
+
+qb(_, [3]).
+
+%-----------------------------------------------------------------------------%
+
Index: trace/mercury_trace_browse.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_browse.c,v
retrieving revision 1.18
diff -u -r1.18 mercury_trace_browse.c
--- trace/mercury_trace_browse.c	2000/11/23 02:01:07	1.18
+++ trace/mercury_trace_browse.c	2001/01/29 14:09:13
@@ -57,7 +57,8 @@
 void
 MR_trace_browse(MR_Word type_info, MR_Word value, MR_Browse_Format format)
 {
-	MercuryFile mdb_in, mdb_out;
+	MercuryFile	mdb_in, mdb_out;
+	MR_Word		maybe_mark;
 
 	MR_trace_browse_ensure_init();
 
@@ -76,7 +77,7 @@
 		MR_TRACE_CALL_MERCURY(
 			ML_BROWSE_browse(type_info, value,
 				(MR_Word) &mdb_in, (MR_Word) &mdb_out,
-				MR_trace_browser_persistent_state,
+				&maybe_mark, MR_trace_browser_persistent_state,
 				&MR_trace_browser_persistent_state);
 		);
 	}
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list