[m-rev.] for review: consult knowledge base when adding suspects to the search space

Ian MacLarty maclarty at cs.mu.OZ.AU
Thu May 5 17:04:46 AEST 2005


For review by anyone.

Estimated hours taken: 10
Branches: main

Look up atoms in the knowledge base as soon as the are added to the search
space.

This generalises a feature of the debugger which I earlier removed
for simplicity, where the analyser would pass a list of questions to the
oracle.  If the oracle had any of the questions in its knowledge base it
would return those answers to the analyser, otherwise it would ask the user.
This was changed so that only one question was asked of the oracle at a time.
Now the analyser still asks only one question of the oracle at a time (through
an analyser response), but the oracle's knowledge base is consulted everytime a
new suspect is added to the search space i.e. as it is being searched.

The main benefit of this is that search algorithms can immediately avoid
generating queries about trusted nodes.  This fixes some slightly annoying
behaviour with subterm dependency tracking.  Previously if a subterm was
bound by a trusted predicate, then this would cause a binary search to be
performed between the trusted predicate and the root of the search space.
It would be better for the dependency tracking algorithm to first ask about the
closest untrusted call to the call that bound the subterm, since often subterms
are bound by internal library predicates.  The subterm dependency algorithm
was unable to do this, however, because it didn't know which calls were
trusted while it was tracking the subterm.  Now it does.

browser/declarative_analyser.m:
	Pass the oracle state and the io action map to any predicates
	that add suspects to the search space, so that the oracle's
	knowledge base can be consulted.

	Move the code that checks if a bug has been found from
	decide_analyser_response to the top-down search routine.  This is okay
	since all the other search algorithms will eventually call top-down
	search if they can't find any unknown suspects to ask questions about.

	When keeping track of the last unknown suspect, double check that the
	suspect is still unknown before asking a question about it, since
	it's status may have been changed because, for example, an erroneous
	child was added to the search space.

	Pass the mode of the subterm to give_up_subterm_tracking/3, since
	tracking of the subterm should only be stopped if it's the input to
	an erroneous node.

browser/declarative_debugger.m:
	Add a subtype of decl_answer/1 that specifies those answers which
	can be obtained from places other than the user.

	Pass the oracle state to the analyser.

browser/declarative_edt.m:
	Make first_unknown_descendent return a new type which captures
	whether an unknown suspect was found, an unknown suspect was not
	found, or an explicit_subtree was requested.  Previously this predicate
	would fail if an explicit subtree was required, which meant that any
	suspects added to the search space during the call to
	first_unknown_descendent would have to be added again once the
	subtree had been generated.  This also removes the need for
	pick_implicit_root.

	Pass the oracle state and the io action map to any predicates
	that add suspects to the search space, so that the oracle's
	knowledge base can be consulted.

	Remove the suspect_is_bug predicate, since this is now done by top-down
	search in the anaylser.  Export non_ignored_descendents so the
	analyser can use it.

	Return the mode of a subterm in its origin.  Make
	give_up_subterm_tracking consider the mode of the subterm.

	Check if the oracle knows the answer to a question when adding
	children to the search space, or adding a new suspect at the top
	of the search space.  Also give better names to some variables in these
	predicates.

browser/declarative_oracle.m:
	Export answer_known/3 so that declarative_edt can call it.

tests/debugger/declarative/binary_search.exp:
tests/debugger/declarative/binary_search.exp2:
tests/debugger/declarative/binary_search.inp:
tests/debugger/declarative/binary_search.inp2:
tests/debugger/declarative/family.exp:
tests/debugger/declarative/family.inp:
	These test cases now ask fewer questions, except for one dd session
	in the binary_search test case. This, however, is a fix for the quirk
	mentioned above where a binary search would be started if the
	binding node is trusted.  The new behaviour is more predictable
	and preferable even if an extra question is asked.

trace/mercury_trace_declarative.c:
	Fix a bug where the dd_dd command didn't work.  This was introduced
	by an earlier diff in which I cleaned up mercury_trace_declarative.c.

Index: browser/declarative_analyser.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_analyser.m,v
retrieving revision 1.24
diff -u -r1.24 declarative_analyser.m
--- browser/declarative_analyser.m	2 May 2005 04:21:13 -0000	1.24
+++ browser/declarative_analyser.m	5 May 2005 05:25:00 -0000
@@ -19,8 +19,9 @@
 :- interface.

 :- import_module mdb.declarative_debugger.
-:- import_module mdb.io_action.
 :- import_module mdb.declarative_edt.
+:- import_module mdb.declarative_oracle.
+:- import_module mdb.io_action.

 :- import_module std_util, io.

@@ -92,14 +93,14 @@
 	% to diagnose, or a sub-tree that was required to be made
 	% explicit.
 	%
-:- pred start_or_resume_analysis(S::in, analysis_type(T)::in,
+:- pred start_or_resume_analysis(S::in, oracle_state::in, analysis_type(T)::in,
 	analyser_response(T)::out, analyser_state(T)::in,
 	analyser_state(T)::out) is det <= mercury_edt(S, T).

 	% Continue analysis after the oracle has responded with an
 	% answer.
 	%
-:- pred continue_analysis(S::in, decl_answer(T)::in,
+:- pred continue_analysis(S::in, oracle_state::in, decl_answer(T)::in,
 	analyser_response(T)::out, analyser_state(T)::in,
 	analyser_state(T)::out) is det <= mercury_edt(S, T).

@@ -220,7 +221,8 @@
 	--->	question(suspect_id, reason_for_question)
 	;	require_explicit_subtree(suspect_id)
 	;	require_explicit_supertree
-	;	no_suspects.
+	;	no_suspects
+	;	found_bug(suspect_id, list(suspect_id), list(suspect_id)).

 	% The reason the declarative debugger asked a question.
 	%
@@ -327,7 +329,7 @@

 debug_analyser_state(Analyser, Analyser ^ debug_origin).

-start_or_resume_analysis(Store, AnalysisType, Response, !Analyser) :-
+start_or_resume_analysis(Store, Oracle, AnalysisType, Response, !Analyser) :-
 	(
 		AnalysisType = new_tree(Node),
 		MaybeRequireExplicit = !.Analyser ^ require_explicit,
@@ -336,8 +338,10 @@
 			SearchSpace0 = !.Analyser ^ search_space,
 			(
 				TreeType = explicit_supertree,
-				incorporate_explicit_supertree(Store, Node,
-					SearchSpace0, SearchSpace)
+				incorporate_explicit_supertree(
+					!.Analyser ^ io_action_map, Store,
+					Oracle, Node, SearchSpace0,
+					SearchSpace)
 			;
 				TreeType = explicit_subtree(SuspectId),
 				incorporate_explicit_subtree(SuspectId, Node,
@@ -345,7 +349,8 @@
 			),
 			!:Analyser = !.Analyser ^ search_space := SearchSpace,
 			!:Analyser = !.Analyser ^ require_explicit := no,
-			decide_analyser_response(Store, Response, !Analyser)
+			decide_analyser_response(Store, Oracle, Response,
+				!Analyser)
 		;
 			MaybeRequireExplicit = no,
 			%
@@ -364,10 +369,10 @@
 		)
 	;
 		AnalysisType = resume_previous,
-		decide_analyser_response(Store, Response, !Analyser)
+		decide_analyser_response(Store, Oracle, Response, !Analyser)
 	).

-continue_analysis(Store, Answer, Response, !Analyser) :-
+continue_analysis(Store, Oracle, Answer, Response, !Analyser) :-
 	(
 		!.Analyser ^ last_search_question = yes(
 			suspect_and_reason(SuspectId, _)),
@@ -378,7 +383,7 @@
 			"received answer to unasked question"))
 	),
 	!:Analyser = !.Analyser ^ last_search_question := no,
-	decide_analyser_response(Store, Response, !Analyser).
+	decide_analyser_response(Store, Oracle, Response, !Analyser).

 :- pred process_answer(S::in, decl_answer(T)::in, suspect_id::in,
 	analyser_state(T)::in, analyser_state(T)::out)
@@ -460,36 +465,23 @@
 		throw(internal_error("revise_analysis", "no root"))
 	).

-:- pred decide_analyser_response(S::in, analyser_response(T)::out,
-	analyser_state(T)::in, analyser_state(T)::out)
-	is det <= mercury_edt(S, T).
+:- pred decide_analyser_response(S::in, oracle_state::in,
+	analyser_response(T)::out, analyser_state(T)::in,
+	analyser_state(T)::out) is det <= mercury_edt(S, T).

-decide_analyser_response(Store, Response, !Analyser) :-
+decide_analyser_response(Store, Oracle, Response, !Analyser) :-
 	maybe_check_search_space_consistency(Store, !.Analyser ^ search_space,
 		"Start of decide_analyser_response"),
 	some [!SearchSpace] (
 		!:SearchSpace = !.Analyser ^ search_space,
-		(
-			root(!.SearchSpace, RootId),
-			suspect_is_bug(Store, RootId, !SearchSpace,
-				CorrectDescendents, InadmissibleChildren)
-		->
-			!:Analyser = !.Analyser ^ search_space :=
-				!.SearchSpace,
-			bug_response(Store, !.Analyser ^ io_action_map,
-				!.SearchSpace, RootId,
-				[RootId | CorrectDescendents],
-				InadmissibleChildren, Response)
-		;
-			search(Store, !SearchSpace, !.Analyser ^ search_mode,
-				!.Analyser ^ fallback_search_mode, NewMode,
-				SearchResponse),
-			!:Analyser = !.Analyser ^ search_space :=
-				!.SearchSpace,
-			!:Analyser = !.Analyser ^ search_mode := NewMode,
-			handle_search_response(Store, SearchResponse,
-				!Analyser, Response)
-		)
+		search(!.Analyser ^ io_action_map, Store, Oracle, !SearchSpace,
+			!.Analyser ^ search_mode,
+			!.Analyser ^ fallback_search_mode, NewMode,
+			SearchResponse),
+		!:Analyser = !.Analyser ^ search_space := !.SearchSpace,
+		!:Analyser = !.Analyser ^ search_mode := NewMode,
+		handle_search_response(Store, SearchResponse,
+			!Analyser, Response)
 	),
 	maybe_check_search_space_consistency(Store, !.Analyser ^ search_space,
 		"End of decide_analyser_response").
@@ -545,6 +537,12 @@

 handle_search_response(_, no_suspects, !Analyser, no_suspects).

+handle_search_response(Store, found_bug(BugId, CorrectDescendents,
+		InadmissibleChildren), !Analyser, Response) :-
+	bug_response(Store, !.Analyser ^ io_action_map,
+		!.Analyser ^ search_space, BugId, [BugId | CorrectDescendents],
+		InadmissibleChildren, Response).
+
 	% bug_response(Store, IoActionMap, SearchSpace, BugId, Evidence,
 	%	InadmissibleChildren, Response)
 	% Create a bug analyser-response using the given Evidence.  If
@@ -581,35 +579,44 @@
 	% that the search algorithm being used can remember its current state
 	% next time round.
 	%
-:- pred search(S::in, search_space(T)::in, search_space(T)::out,
+:- pred search(io_action_map::in, S::in, oracle_state::in,
+	search_space(T)::in, search_space(T)::out,
 	search_mode::in, search_mode::in,
 	search_mode::out, search_response::out) is det <= mercury_edt(S, T).

-search(Store, !SearchSpace, top_down, FallBackSearchMode, NewMode, Response) :-
-	top_down_search(Store, !SearchSpace, Response),
+search(IoActionMap, Store, Oracle, !SearchSpace, top_down, FallBackSearchMode,
+		NewMode, Response) :-
+	top_down_search(IoActionMap, Store, Oracle, !SearchSpace, Response),
 	% We always go back to the fallback search mode after a top-down
 	% search, because some fallback searches (such as divide and query)
 	% use top-down as a fail safe and we want the fallback search to
 	% resume after the top-down search.
 	NewMode = FallBackSearchMode.

-search(Store, !SearchSpace, follow_subterm_end(SuspectId, ArgPos, TermPath,
-		LastUnknown), FallBackSearchMode, NewMode, Response) :-
-	follow_subterm_end_search(Store, !SearchSpace, LastUnknown, SuspectId,
-		ArgPos, TermPath, FallBackSearchMode, NewMode, Response).
+search(IoActionMap, Store, Oracle, !SearchSpace, follow_subterm_end(SuspectId,
+		ArgPos, TermPath, LastUnknown), FallBackSearchMode,
+		NewMode, Response) :-
+	follow_subterm_end_search(IoActionMap, Store, Oracle, !SearchSpace,
+		LastUnknown, SuspectId, ArgPos, TermPath, FallBackSearchMode,
+		NewMode, Response).

-search(Store, !SearchSpace, binary(PathArray, Top - Bottom, LastTested),
+search(IoActionMap, Store, Oracle, !SearchSpace,
+		binary(PathArray, Top - Bottom, LastTested),
 		FallBackSearchMode, NewMode, Response) :-
-	binary_search(Store, PathArray, Top, Bottom, LastTested, !SearchSpace,
-		FallBackSearchMode, NewMode, Response).
+	binary_search(IoActionMap, Store, Oracle, PathArray, Top, Bottom,
+		LastTested, !SearchSpace, FallBackSearchMode, NewMode,
+		Response).

-search(Store, !SearchSpace, divide_and_query, _, NewMode, Response) :-
-	divide_and_query_search(Store, !SearchSpace, Response, NewMode).
+search(IoActionMap, Store, Oracle, !SearchSpace, divide_and_query, _, NewMode,
+		Response) :-
+	divide_and_query_search(IoActionMap, Store, Oracle, !SearchSpace,
+		Response, NewMode).

-:- pred top_down_search(S::in, search_space(T)::in, search_space(T)::out,
+:- pred top_down_search(io_action_map::in, S::in, oracle_state::in,
+	search_space(T)::in, search_space(T)::out,
 	search_response::out) is det <= mercury_edt(S, T).

-top_down_search(Store, !SearchSpace, Response) :-
+top_down_search(IoActionMap, Store, Oracle, !SearchSpace, Response) :-
 	%
 	% If there's no root yet (because the oracle hasn't asserted any nodes
 	% are erroneous yet) then use the topmost suspect as a starting point.
@@ -621,89 +628,93 @@
 	;
 		topmost_det(!.SearchSpace, Start)
 	),
+	first_unknown_descendent(IoActionMap, Store, Oracle, Start,
+		!SearchSpace, MaybeUnknownDescendent),
 	(
-		first_unknown_descendent(Store, Start,
-			!.SearchSpace, SearchSpace1, MaybeDescendent)
-	->
-		SearchSpace1 = !:SearchSpace,
+		MaybeUnknownDescendent = found(Unknown),
+		Response = question(Unknown, top_down)
+	;
+		MaybeUnknownDescendent = not_found,
 		(
-			MaybeDescendent = yes(Unknown),
-			Response = question(Unknown, top_down)
+			choose_skipped_suspect(!.SearchSpace,
+				SkippedSuspect)
+		->
+			Response = question(SkippedSuspect, skipped)
 		;
-			MaybeDescendent = no,
+			% Since the are no skipped suspects and no
+			% unknown suspects in the search space, if there
+			% is a root (i.e. an erroneous suspect), then
+			% it must be a bug.
+			root(!.SearchSpace, BugId)
+		->
 			(
-				choose_skipped_suspect(!.SearchSpace,
-					SkippedSuspect)
+				children(IoActionMap, Store, Oracle, BugId,
+					!SearchSpace, BugChildren),
+				non_ignored_descendents(IoActionMap,
+					Store, Oracle, BugChildren,
+					!SearchSpace, NonIgnoredDescendents),
+				list.filter(suspect_correct_or_inadmissible(
+					!.SearchSpace), NonIgnoredDescendents,
+					CorrectDescendents, [])
 			->
-				Response = question(SkippedSuspect, skipped)
+				list.filter(suspect_inadmissible(
+					!.SearchSpace), BugChildren,
+					InadmissibleChildren),
+				Response = found_bug(BugId, CorrectDescendents,
+					InadmissibleChildren)
 			;
-				%
-				% Try to extend the search space upwards.  If
-				% this fails and we're not at the topmost
-				% traced node, then request that an explicit
-				% supertree be generated.
-				%
+				throw(internal_error("top_down_search",
+					"bug has unexplored or unknown " ++
+					"children"))
+			)
+		;
+			%
+			% Try to extend the search space upwards.  If
+			% this fails and we're not at the topmost
+			% traced node, then request that an explicit
+			% supertree be generated.
+			%
+			(
+				extend_search_space_upwards(
+					IoActionMap, Store, Oracle,
+					!.SearchSpace,
+					ExtendedSearchSpace)
+			->
+				top_down_search(IoActionMap, Store,
+					Oracle, ExtendedSearchSpace,
+					!:SearchSpace, Response)
+			;
+				topmost_det(!.SearchSpace, TopMostId),
+				TopMostNode =
+					get_edt_node(!.SearchSpace,
+					TopMostId),
 				(
-					extend_search_space_upwards(Store,
-						!.SearchSpace,
-						ExtendedSearchSpace)
+					edt_topmost_node(Store, TopMostNode)
 				->
-					top_down_search(Store,
-						ExtendedSearchSpace,
-						!:SearchSpace, Response)
+					% We can't look any higher.
+					Response = no_suspects
 				;
-					topmost_det(!.SearchSpace, TopMostId),
-					TopMostNode =
-						get_edt_node(!.SearchSpace,
-						TopMostId),
-					(
-						edt_topmost_node(Store,
-							TopMostNode)
-					->
-						% We can't look any higher.
-						Response = no_suspects
-					;
-						Response =
-						    require_explicit_supertree
-					)
+					Response = require_explicit_supertree
 				)
 			)
 		)
 	;
-		%
-		% An explicit subtree is required, so pick an implicit root
-		% to make explicit.  pick_implicit_root/3 will choose an
-		% implicit root that is a descendent of the root id of the
-		% search space.  There is no point in making an implicit root
-		% that is not a descendent of the root id explicit, since
-		% all suspects above the root id have been excluded from the
-		% bug search.  pick_implicit_root will also not choose an
-		% implicit root that is a descendent of a correct or
-		% inadmissible node, for the same reason.
-		%
-		(
-			pick_implicit_root(Store, !.SearchSpace, ImplicitRoot)
-		->
-			Response = require_explicit_subtree(ImplicitRoot)
-		;
-			throw(internal_error("top_down_search",
-				"first_unknown_descendent requires an "
-				++ "explicit subtree to be generated, but "
-				++ "pick_implicit_root couldn't find an "
-				++ "implicit root to generate an "
-				++ "explicit subtree from"))
-		)
+		MaybeUnknownDescendent = require_explicit_subtree(
+			RequireExplicitId),
+		Response = require_explicit_subtree(RequireExplicitId)
 	).

-:- pred follow_subterm_end_search(S::in, search_space(T)::in,
-	search_space(T)::out, maybe(suspect_id)::in, suspect_id::in,
+:- pred follow_subterm_end_search(io_action_map::in, S::in, oracle_state::in,
+	search_space(T)::in, search_space(T)::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(Store, !SearchSpace, LastUnknown, SuspectId, ArgPos,
-		TermPath, FallBackSearchMode, NewMode, SearchResponse) :-
-	find_subterm_origin(Store, SuspectId, ArgPos, TermPath, !SearchSpace,
-		FindOriginResponse),
+follow_subterm_end_search(IoActionMap, Store, Oracle, !SearchSpace,
+		LastUnknown, SuspectId, ArgPos, TermPath, FallBackSearchMode,
+		NewMode, SearchResponse) :-
+	find_subterm_origin(IoActionMap, Store, Oracle, SuspectId, ArgPos,
+		TermPath, !SearchSpace, FindOriginResponse),
 	(
 		FindOriginResponse = primitive_op(BindingSuspectId, FileName,
 			LineNo, PrimOpType, Output),
@@ -713,8 +724,7 @@
 			Output = yes,
 			% BindingSuspectId = SuspectId since the
 			% subterm is an output of SuspectId.
-			BindingNode = get_edt_node(!.SearchSpace,
-				SuspectId),
+			BindingNode = get_edt_node(!.SearchSpace, SuspectId),
 			ArgNum = edt_arg_pos_to_user_arg_num(Store,
 				BindingNode, ArgPos),
 			MaybePath = yes([ArgNum | TermPath])
@@ -744,6 +754,12 @@
 		;
 			(
 				LastUnknown = yes(Unknown),
+				% Check that the last unknown suspect is
+				% still unknown (it might not be unknown if,
+				% for example, an erroneous suspect was added
+				% to the search space).
+				suspect_unknown(!.SearchSpace, Unknown)
+			->
 				Reason = binding_node(PrimOpType,
 					FileName, LineNo, MaybePath, ProcLabel,
 					yes),
@@ -751,8 +767,8 @@
 				setup_binary_search(!.SearchSpace,
 					Unknown, NewMode)
 			;
-				LastUnknown = no,
-				search(Store, !SearchSpace, FallBackSearchMode,
+				search(IoActionMap, Store, Oracle,
+					!SearchSpace, FallBackSearchMode,
 					FallBackSearchMode, NewMode,
 					SearchResponse)
 			)
@@ -761,13 +777,19 @@
 		FindOriginResponse = not_found,
 		(
 			LastUnknown = yes(Unknown),
+			% Check that the last unknown suspect is
+			% still unknown (it might not be unknown if,
+			% for example, an erroneous suspect was added
+			% to the search space).
+			suspect_unknown(!.SearchSpace, Unknown)
+		->
 			SearchResponse = question(Unknown,
 				subterm_no_proc_rep),
 			setup_binary_search(!.SearchSpace, Unknown, NewMode)
 		;
-			LastUnknown = no,
-			search(Store, !SearchSpace, FallBackSearchMode,
-				FallBackSearchMode, NewMode, SearchResponse)
+			search(IoActionMap, Store, Oracle, !SearchSpace,
+				FallBackSearchMode, FallBackSearchMode,
+				NewMode, SearchResponse)
 		)
 	;
 		FindOriginResponse = require_explicit_subtree,
@@ -786,7 +808,7 @@
 			LastUnknown)
 	;
 		FindOriginResponse = origin(OriginId, OriginArgPos,
-			OriginTermPath),
+			OriginTermPath, SubtermMode),
 		(
 			suspect_unknown(!.SearchSpace, OriginId)
 		->
@@ -802,17 +824,24 @@
 			% can't return (for example if we come across an
 			% erroneous node where the sub-term is an input).
 			%
-			give_up_subterm_tracking(!.SearchSpace, OriginId)
+			give_up_subterm_tracking(!.SearchSpace, OriginId,
+				SubtermMode)
 		->
 			(
 				LastUnknown = yes(Unknown),
+				% Check that the last unknown suspect is
+				% still unknown (it might not be unknown if,
+				% for example, an erroneous suspect was added
+				% to the search space).
+				suspect_unknown(!.SearchSpace, Unknown)
+			->
 				SearchResponse = question(Unknown,
 					binding_node_eliminated),
 				setup_binary_search(!.SearchSpace,
 					Unknown, NewMode)
 			;
-				LastUnknown = no,
-				search(Store, !SearchSpace, FallBackSearchMode,
+				search(IoActionMap, Store, Oracle,
+					!SearchSpace, FallBackSearchMode,
 					FallBackSearchMode, NewMode,
 					SearchResponse)
 			)
@@ -825,10 +854,10 @@
 			% information to continue (and find_subterm_origin will
 			% respond with not_found).
 			%
-			follow_subterm_end_search(Store, !SearchSpace,
-				NewLastUnknown, OriginId, OriginArgPos,
-				OriginTermPath, FallBackSearchMode, NewMode,
-				SearchResponse)
+			follow_subterm_end_search(IoActionMap, Store, Oracle,
+				!SearchSpace, NewLastUnknown, OriginId,
+				OriginArgPos, OriginTermPath,
+				FallBackSearchMode, NewMode, SearchResponse)
 		)
 	).

@@ -862,12 +891,13 @@
 			"TopId not an ancestor of BottomId"))
 	).

-:- pred binary_search(S::in, array(suspect_id)::in, int::in, int::in, int::in,
+:- pred binary_search(io_action_map::in, S::in, oracle_state::in,
+	array(suspect_id)::in, int::in, int::in, int::in,
 	search_space(T)::in, search_space(T)::out, search_mode::in,
 	search_mode::out, search_response::out) is det <= mercury_edt(S, T).

-binary_search(Store, PathArray, Top, Bottom, LastTested, !SearchSpace,
-		FallBackSearchMode, NewMode, Response) :-
+binary_search(IoActionMap, Store, Oracle, PathArray, Top, Bottom, LastTested,
+		!SearchSpace, FallBackSearchMode, NewMode, Response) :-
 	SuspectId = PathArray ^ elem(LastTested),
 	%
 	% Check what the result of the query about LastTested was and adjust
@@ -895,8 +925,9 @@
 	->
 		% Revert to the fallback search mode when binary search is
 		% over.
-		search(Store, !SearchSpace, FallBackSearchMode,
-			FallBackSearchMode, NewMode, Response)
+		search(IoActionMap, Store, Oracle, !SearchSpace,
+			FallBackSearchMode, FallBackSearchMode, NewMode,
+			Response)
 	;
 		(
 			find_unknown_closest_to_middle(!.SearchSpace,
@@ -911,8 +942,9 @@
 		;
 			% No unknown suspects on the path, so revert to
 			% the fallback search mode.
-			search(Store, !SearchSpace, FallBackSearchMode,
-				FallBackSearchMode, NewMode, Response)
+			search(IoActionMap, Store, Oracle, !SearchSpace,
+				FallBackSearchMode, FallBackSearchMode,
+				NewMode, Response)
 		)
 	).

@@ -964,11 +996,12 @@
 			Unknown)
 	).

-:- pred divide_and_query_search(S::in, search_space(T)::in,
-	search_space(T)::out, search_response::out, search_mode::out) is det
-	<= mercury_edt(S, T).
+:- pred divide_and_query_search(io_action_map::in, S::in, oracle_state::in,
+	search_space(T)::in, search_space(T)::out, search_response::out,
+	search_mode::out) is det <= mercury_edt(S, T).

-divide_and_query_search(Store, !SearchSpace, Response, NewMode) :-
+divide_and_query_search(IoActionMap, Store, Oracle, !SearchSpace, Response,
+		NewMode) :-
 	%
 	% If there's no root yet (because the oracle hasn't asserted any nodes
 	% are erroneous yet), then use top-down search.
@@ -978,66 +1011,77 @@
 	->
 		NewMode = divide_and_query,
 		(
-			children(Store, RootId, !SearchSpace, Children)
+			children(IoActionMap, Store, Oracle, RootId,
+				!SearchSpace, Children)
 		->
-			find_middle_weight(Store, Children, RootId, no,
-				!SearchSpace, Response)
+			find_middle_weight(IoActionMap, Store, Oracle,
+				Children, RootId, no, !SearchSpace, Response)
 		;
 			Response = require_explicit_subtree(RootId)
 		)
 	;
-		top_down_search(Store, !SearchSpace, Response),
+		top_down_search(IoActionMap, Store, Oracle, !SearchSpace,
+			Response),
 		NewMode = divide_and_query
 	).

-	% Call find_middle_weight/7 if we are able to find the children of the
+	% Call find_middle_weight/9 if we are able to find the children of the
 	% given suspect id, otherwise return a require_explicit_subtree
 	% search response in the last argument.
 	%
-:- pred find_middle_weight_if_children(S::in, suspect_id::in, suspect_id::in,
+:- pred find_middle_weight_if_children(io_action_map::in, S::in,
+	oracle_state::in, suspect_id::in, suspect_id::in,
 	maybe(suspect_id)::in, search_space(T)::in, search_space(T)::out,
 	search_response::out) is det <= mercury_edt(S, T).

-find_middle_weight_if_children(Store, SuspectId, TopId, MaybeLastUnknown,
-		!SearchSpace, Response) :-
+find_middle_weight_if_children(IoActionMap, Store, Oracle, SuspectId, TopId,
+		MaybeLastUnknown, !SearchSpace, Response) :-
 	(
-		children(Store, SuspectId, !SearchSpace, Children)
+		children(IoActionMap, Store, Oracle, SuspectId, !SearchSpace,
+			Children)
 	->
-		find_middle_weight(Store, Children, TopId,
+		find_middle_weight(IoActionMap, Store, Oracle, Children, TopId,
 			MaybeLastUnknown, !SearchSpace, Response)
 	;
 		Response = require_explicit_subtree(SuspectId)
 	).

-	% find_middle_weight(Store, SuspectIds, TopId, MaybeLastUnknown,
-	%	!SearchSpace, Response).
+	% find_middle_weight(IoActionMap, Store, Oracle, SuspectIds, TopId,
+	%	MaybeLastUnknown, !SearchSpace, Response).
 	% Find the unknown suspect whose weight is closest to half the weight
 	% of TopId, considering only the heaviest suspect in SuspectIds, the
 	% heaviest child of the heaviest suspect in SuspectIds and so on.
 	% MaybeLastUnknown is the last node that was unknown in the search (if
 	% any).
 	%
-:- pred find_middle_weight(S::in, list(suspect_id)::in, suspect_id::in,
+:- pred find_middle_weight(io_action_map::in, S::in, oracle_state::in,
+	list(suspect_id)::in, suspect_id::in,
 	maybe(suspect_id)::in, search_space(T)::in,
 	search_space(T)::out, search_response::out)
 	is det <= mercury_edt(S, T).

-find_middle_weight(Store, [], TopId, MaybeLastUnknown, !SearchSpace, Response)
-		:-
+find_middle_weight(IoActionMap, Store, Oracle, [], TopId, MaybeLastUnknown,
+		!SearchSpace, Response) :-
 	(
 		MaybeLastUnknown = yes(LastUnknown),
+		% Check that the last unknown suspect is
+		% still unknown (it might not be unknown if,
+		% for example, an erroneous suspect was added
+		% to the search space).
+		suspect_unknown(!.SearchSpace, LastUnknown)
+	->
 		Response = question(LastUnknown, divide_and_query(
 			get_weight(!.SearchSpace, TopId),
 			get_weight(!.SearchSpace, LastUnknown)))
 	;
-		MaybeLastUnknown = no,
 		% This could happen when there were no unknown suspects
 		% encountered during the search, in which case we revert
 		% to top-down search.
-		top_down_search(Store, !SearchSpace, Response)
+		top_down_search(IoActionMap, Store, Oracle, !SearchSpace,
+			Response)
 	).
-find_middle_weight(Store, [SuspectId | SuspectIds], TopId, MaybeLastUnknown,
-		!SearchSpace, Response) :-
+find_middle_weight(IoActionMap, Store, Oracle, [SuspectId | SuspectIds], TopId,
+		MaybeLastUnknown, !SearchSpace, Response) :-
 	TopWeight = get_weight(!.SearchSpace, TopId),
 	Target = TopWeight // 2,
 	%
@@ -1056,14 +1100,21 @@
 		;
 			NewMaybeLastUnknown = MaybeLastUnknown
 		),
-		find_middle_weight_if_children(Store, Heaviest, TopId,
-			NewMaybeLastUnknown, !SearchSpace, Response)
+		find_middle_weight_if_children(IoActionMap, Store, Oracle,
+			Heaviest, TopId, NewMaybeLastUnknown, !SearchSpace,
+			Response)
 	;
 		(
 			suspect_unknown(!.SearchSpace, Heaviest)
 		->
 			(
 				MaybeLastUnknown = yes(LastUnknown),
+				% Check that the last unknown suspect is still
+				% unknown (it might not be unknown if, for
+				% example, an erroneous suspect was added to
+				% the search space).
+				suspect_unknown(!.SearchSpace, LastUnknown)
+			->
 				LastUnknownWeight = get_weight(!.SearchSpace,
 					LastUnknown),
 				%
@@ -1083,23 +1134,28 @@
 							MaxWeight))
 				)
 			;
-				MaybeLastUnknown = no,
 				Response = question(Heaviest,
 					divide_and_query(TopWeight, MaxWeight))
 			)
 		;
 			(
 				MaybeLastUnknown = yes(LastUnknown),
+				% Check that the last unknown suspect is still
+				% unknown (it might not be unknown if, for
+				% example, an erroneous suspect was added to
+				% the search space).
+				suspect_unknown(!.SearchSpace, LastUnknown)
+			->
 				LastUnknownWeight = get_weight(!.SearchSpace,
 					LastUnknown),
 				Response = question(LastUnknown,
 					divide_and_query(TopWeight,
 						LastUnknownWeight))
 			;
-				MaybeLastUnknown = no,
 				% Look deeper until we find an unknown:
-				find_middle_weight_if_children(Store, Heaviest,
-					TopId, no, !SearchSpace, Response)
+				find_middle_weight_if_children(IoActionMap,
+					Store, Oracle, Heaviest, TopId, no,
+					!SearchSpace, Response)
 			)
 		)
 	).
Index: browser/declarative_debugger.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_debugger.m,v
retrieving revision 1.56
diff -u -r1.56 declarative_debugger.m
--- browser/declarative_debugger.m	2 May 2005 04:21:13 -0000	1.56
+++ browser/declarative_debugger.m	3 May 2005 03:19:10 -0000
@@ -194,6 +194,14 @@
 			% the last question asked.
 	;	show_info(io.output_stream).

+	% Answers that are not necessarily obtained from the user.  These
+	% could be answers stored in the knowledge base or answers about
+	% trusted predicates.
+	%
+:- inst non_user_derived_answer
+	--->	truth_value(ground, ground)
+	;	ignore(ground).
+
 	% The evidence that a certain node is a bug.  This consists of the
 	% smallest set of questions whose answers are sufficient to
 	% diagnose that bug.
@@ -408,8 +416,8 @@

 diagnosis_2(Store, AnalysisType, Diagnoser0, {Response, Diagnoser}, !IO) :-
 	Analyser0 = Diagnoser0 ^ analyser_state,
-	start_or_resume_analysis(wrap(Store), AnalysisType,
-		AnalyserResponse, Analyser0, Analyser),
+	start_or_resume_analysis(wrap(Store), Diagnoser0 ^ oracle_state,
+		AnalysisType, AnalyserResponse, Analyser0, Analyser),
 	diagnoser_set_analyser(Analyser, Diagnoser0, Diagnoser1),
 	debug_analyser_state(Analyser, MaybeOrigin),
 	handle_analyser_response(Store, AnalyserResponse, MaybeOrigin,
@@ -472,8 +480,8 @@
 handle_oracle_response(Store, oracle_answer(Answer), Response, !Diagnoser,
 		!IO) :-
 	diagnoser_get_analyser(!.Diagnoser, Analyser0),
-	continue_analysis(wrap(Store), Answer, AnalyserResponse,
-		Analyser0, Analyser),
+	continue_analysis(wrap(Store), !.Diagnoser ^ oracle_state, Answer,
+		AnalyserResponse, Analyser0, Analyser),
 	diagnoser_set_analyser(Analyser, !Diagnoser),
 	debug_analyser_state(Analyser, MaybeOrigin),
 	handle_analyser_response(Store, AnalyserResponse, MaybeOrigin,
Index: browser/declarative_edt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_edt.m,v
retrieving revision 1.7
diff -u -r1.7 declarative_edt.m
--- browser/declarative_edt.m	15 Apr 2005 05:42:34 -0000	1.7
+++ browser/declarative_edt.m	5 May 2005 06:16:10 -0000
@@ -58,10 +58,11 @@

 :- interface.

-:- import_module mdbcomp.program_representation.
-:- import_module mdbcomp.prim_data.
-:- import_module mdb.io_action.
 :- import_module mdb.declarative_debugger.
+:- import_module mdb.declarative_oracle.
+:- import_module mdb.io_action.
+:- import_module mdbcomp.prim_data.
+:- import_module mdbcomp.program_representation.

 :- import_module bool, list, std_util.

@@ -261,25 +262,26 @@
 	%
 :- pred topmost_det(search_space(T)::in, suspect_id::out) is det.

-	% suspect_is_bug(Store, SuspectId, !SearchSpace, CorrectDescendents,
-	%	InadmissibleChildren)
-	% Succeeds if the given suspect is erroneous and has only correct,
-	% inadmissible, pruned or ignored descendents.  The direct children of
-	% the root who are inadmissible are placed in InadmissibleChildren.
-	% CorrectDescendents is all the correct and inadmissible
-	% descendents of the suspect.
+	% non_ignored_descendents(IoActionMap, Store, Oracle, SuspectIds,
+	% 	!SearchSpace, Descendents).
+	% Descendents is the non-ignored children of the suspects in
+	% SuspectIds appended together.  If a child is ignored then it's
+	% non-ignored children are added to the list.  This is done
+	% recursively.  Fails if an explicit subtree is required to find
+	% the children of an ignored suspect.
 	%
-:- pred suspect_is_bug(S::in, suspect_id::in, search_space(T)::in,
-	search_space(T)::out, list(suspect_id)::out, list(suspect_id)::out)
-	is semidet <= mercury_edt(S, T).
+:- pred non_ignored_descendents(io_action_map::in, S::in, oracle_state::in,
+	list(suspect_id)::in, search_space(T)::in, search_space(T)::out,
+	list(suspect_id)::out) is semidet <= mercury_edt(S, T).

-	% children(Store, SuspectId, !SearchSpace, Children).
+	% children(IoActionMap, Store, Oracle, SuspectId, !SearchSpace,
+	% 	Children).
 	% Children is the list of children of SuspectId in the SearchSpace.  If
 	% the children were not in the search space then they are added.  Fails
 	% if SuspectId is the root of an implicit subtree.
 	%
-:- pred children(S::in, suspect_id::in, search_space(T)::in,
-	search_space(T)::out, list(suspect_id)::out)
+:- pred children(io_action_map::in, S::in, oracle_state::in, suspect_id::in,
+	search_space(T)::in, search_space(T)::out, list(suspect_id)::out)
 	is semidet <= mercury_edt(S, T).

 	% parent(SearchSpace, SuspectId, ParentId).
@@ -315,16 +317,17 @@
 :- pred skip_suspect(suspect_id::in, search_space(T)::in, search_space(T)::out)
 	is det.

-	% find_subterm_origin(Store, SuspectId, ArgPos, TermPath, !SearchSpace,
-	% 	Response).
+	% find_subterm_origin(IoActionMap, Store, Oracle, SuspectId, ArgPos,
+	%	TermPath, !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).
 	%
-:- pred find_subterm_origin(S::in, suspect_id::in, arg_pos::in, term_path::in,
-	search_space(T)::in, search_space(T)::out, find_origin_response::out)
+:- pred find_subterm_origin(io_action_map::in, 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)
 	is det <= mercury_edt(S, T).

 :- type find_origin_response
@@ -334,8 +337,9 @@

 			% The subterm originated from the suspect referenced by
 			% argument 1.  The second and third arguments give the
-			% position of the subterm in the origin node.
-	;	origin(suspect_id, arg_pos, term_path)
+			% position of the subterm in the origin node, while the
+			% 4th argument gives the mode of the subterm.
+	;	origin(suspect_id, arg_pos, term_path, subterm_mode)

 			% The subterm was bound by a primitive operation inside
 			% the suspect.  The other arguments are the filename,
@@ -377,21 +381,25 @@
 :- pred incorporate_explicit_subtree(suspect_id::in, T::in,
 	search_space(T)::in, search_space(T)::out) is det.

-	% incorporate_explicit_supertree(Store, Node, !SearchSpace).
+	% incorporate_explicit_supertree(IoActionMap, Store, Oracle, Node,
+	%	!SearchSpace).
 	% Node should be the implicit root in a newly generated supertree
 	% that represents the topmost node of the current search space.
 	% Node's parent will be inserted at the top of the search space.
 	%
-:- pred incorporate_explicit_supertree(S::in, T::in, search_space(T)::in,
+:- pred incorporate_explicit_supertree(io_action_map::in, S::in,
+	oracle_state::in, T::in, search_space(T)::in,
 	search_space(T)::out) is det <= mercury_edt(S, T).

-	% extend_search_space_upwards(Store, !SearchSpace).
+	% extend_search_space_upwards(IoActionMap, Store, Oracle,
+	%	!SearchSpace).
 	% Attempts to add a parent of the current topmost node to the
 	% search space.  Fails if this is not possible because an explicit
 	% supertree is required.
 	%
-:- pred extend_search_space_upwards(S::in, search_space(T)::in,
-	search_space(T)::out) is semidet <= mercury_edt(S, T).
+:- pred extend_search_space_upwards(io_action_map::in, S::in, oracle_state::in,
+	search_space(T)::in, search_space(T)::out)
+	is semidet <= mercury_edt(S, T).

 	% Return the EDT node corresponding to the suspect_id.
 	%
@@ -430,8 +438,8 @@
 	%
 :- pred suspect_ignored(search_space(T)::in, suspect_id::in) is semidet.

-	% first_unknown_descendent(Store, SuspectId, !SearchSpace,
-	%	MaybeDescendent).
+	% first_unknown_descendent(IoActionMap, Store, Oracle, SuspectId,
+	%	!SearchSpace, MaybeDescendent).
 	% Search the search space for a suspect with status = unknown in a
 	% top down fashion, starting with SuspectId.  If no unknown
 	% suspect is found then MaybeDescendent will be no.  If there are no
@@ -439,9 +447,14 @@
 	% skipped, ignored or erroneous suspect is the root of an implicit
 	% subtree, then the call will fail.
 	%
-:- pred first_unknown_descendent(S::in, suspect_id::in,
-	search_space(T)::in, search_space(T)::out, maybe(suspect_id)::out)
-	is semidet <= mercury_edt(S, T).
+:- pred first_unknown_descendent(io_action_map::in, S::in, oracle_state::in,
+	suspect_id::in, search_space(T)::in, search_space(T)::out,
+	maybe_found_descendent::out) is det <= mercury_edt(S, T).
+
+:- type maybe_found_descendent
+	--->	found(suspect_id)
+	;	not_found
+	;	require_explicit_subtree(suspect_id).

 	% choose_skipped_suspect(SearchSpace, Skipped) True iff Skipped is the
 	% skipped suspect in SearchSpace with the lowest skip order (i.e. was
@@ -451,19 +464,6 @@
 :- pred choose_skipped_suspect(search_space(T)::in, suspect_id::out)
 	is semidet.

-	% pick_implicit_root(Store, SearchSpace, ImplicitRoot)
-	% Picks a suspect in SearchSpace who's EDT node is the root of an
-	% implicit subtree. Only suspects with a status of unknown, skipped or
-	% ignored will be considered.  If there are multiple such suspects then
-	% one is committed to.  ImplicitRoot will always be a descendent of the
-	% root of the search space.  XXX currently ImplicitRoot is chosen
-	% naively, but in future better methods could be used to pick an
-	% implicit root (such as the implicit root whos subtree is most lightly
-	% to contain a bug according to some heuristic(s)).
-	%
-:- pred pick_implicit_root(S::in, search_space(T)::in, suspect_id::out)
-	is semidet <= mercury_edt(S, T).
-
 	% get_path(SearchSpace, BottomId, TopId, Path).
 	% Path is InitialPath appended to the list of suspect_id's between
 	% FromId and ToId (inclusive).  ToId should be an ancestor of FromId.
@@ -478,12 +478,16 @@
 :- pred suspect_correct_or_inadmissible(search_space(T)::in, suspect_id::in)
 	is semidet.

+	% Succeeds if the suspect has been marked inadmissible.
+	%
+:- pred suspect_inadmissible(search_space(T)::in, suspect_id::in) is semidet.
+
 	% When tracking a sub-term, should we give up if we reach the given
 	% suspect, because the binding node must lie in a portion of
 	% the tree we've already eliminated?
 	%
-:- pred give_up_subterm_tracking(search_space(T)::in, suspect_id::in)
-	is semidet.
+:- pred give_up_subterm_tracking(search_space(T)::in, suspect_id::in,
+	subterm_mode::in) is semidet.

 	% Mark the root and it's non-ignored children as unknown.
 	% Throws an exception if the search space doesn't have a root.
@@ -614,17 +618,6 @@
 		throw(internal_error("topmost_det", "search space empty"))
 	).

-suspect_is_bug(Store, SuspectId, !SearchSpace, CorrectDescendents,
-		InadmissibleChildren) :-
-	suspect_erroneous(!.SearchSpace, SuspectId),
-	children(Store, SuspectId, !SearchSpace, Children),
-	non_ignored_descendents(Store, Children, !SearchSpace,
-		Descendents),
-	filter(suspect_correct_or_inadmissible(!.SearchSpace),
-		Descendents, CorrectDescendents, []),
-	filter(suspect_inadmissible(!.SearchSpace), Children,
-		InadmissibleChildren).
-
 suspect_correct_or_inadmissible(SearchSpace, SuspectId) :-
 	lookup_suspect(SearchSpace, SuspectId, Suspect),
 	Status = Suspect ^ status,
@@ -639,8 +632,6 @@
 suspect_in_buggy_subtree(SearchSpace, SuspectId) :-
 	in_buggy_subtree(get_status(SearchSpace, SuspectId), yes).

-:- pred suspect_inadmissible(search_space(T)::in, suspect_id::in) is semidet.
-
 suspect_inadmissible(SearchSpace, SuspectId) :-
 	lookup_suspect(SearchSpace, SuspectId, Suspect),
 	Suspect ^ status = inadmissible.
@@ -769,9 +760,9 @@
 	in_erroneous_subtree_complement.
 new_parent_status(unknown) = unknown.

-give_up_subterm_tracking(SearchSpace, SuspectId) :-
+give_up_subterm_tracking(SearchSpace, SuspectId, subterm_in) :-
 	Status = get_status(SearchSpace, SuspectId),
-	(Status = erroneous ; Status = in_erroneous_subtree_complement).
+	excluded_complement(Status, yes).

 	% Mark the suspect as correct or inadmissible.
 	%
@@ -903,8 +894,8 @@
 		FinishId = StartId
 	).

-find_subterm_origin(Store, SuspectId, ArgPos, TermPath, !SearchSpace,
-		Response) :-
+find_subterm_origin(IoActionMap, Store, Oracle, SuspectId, ArgPos, TermPath,
+		!SearchSpace, Response) :-
 	lookup_suspect(!.SearchSpace, SuspectId, Suspect),
 	ImplicitToExplicit = !.SearchSpace ^
 		implicit_roots_to_explicit_roots,
@@ -930,31 +921,32 @@
 		Mode = subterm_in,
 		(
 			Suspect ^ parent = yes(ParentId),
-			resolve_origin(Store, Node, ArgPos, TermPath,
-				ParentId, no, !SearchSpace, Response)
+			resolve_origin(IoActionMap, Store, Oracle, Node,
+				ArgPos, TermPath, ParentId, no, !SearchSpace,
+				Response)
 		;
 			Suspect ^ parent = no,
 			(
-				extend_search_space_upwards(Store,
-					!SearchSpace)
+				extend_search_space_upwards(IoActionMap, Store,
+					Oracle, !SearchSpace)
 			->
 				topmost_det(!.SearchSpace, NewRootId),
-				resolve_origin(Store, Node, ArgPos,
-					TermPath, NewRootId, no, !SearchSpace,
-					Response)
+				resolve_origin(IoActionMap, Store, Oracle,
+					Node, ArgPos, TermPath, NewRootId, no,
+					!SearchSpace, Response)
 			;
 				Response = require_explicit_supertree
 			)
 		)
 	;
 		Mode = subterm_out,
-		resolve_origin(Store, Node, ArgPos,
+		resolve_origin(IoActionMap, Store, Oracle, Node, ArgPos,
 			TermPath, SuspectId, yes, !SearchSpace,
 			Response)
 	).

-	% resolve_origin(Store, Node, ArgPos, TermPath, SuspectId, Output,
-	% 	!SearchSpace, Response).
+	% resolve_origin(IoActionMap, Store, Oracle, Node, ArgPos, TermPath,
+	%	SuspectId, Output, !SearchSpace, Response).
 	% Find the origin of the subterm in Node and report the origin as
 	% SuspectId if the origin is a primitive op or an input and as the
 	% appropriate child of SuspectId if the origin is an output.  SuspectId
@@ -963,12 +955,13 @@
 	% output.  Output should be yes if the sub-term is an output of
 	% SuspectId and no if it isn't.
 	%
-:- pred resolve_origin(S::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) is det <= mercury_edt(S, T).
-
-resolve_origin(Store, Node, ArgPos, TermPath, SuspectId, Output, !SearchSpace,
-		Response) :-
+:- pred resolve_origin(io_action_map::in, 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)
+	is det <= mercury_edt(S, T).
+
+resolve_origin(IoActionMap, Store, Oracle, Node, ArgPos, TermPath, SuspectId,
+		Output, !SearchSpace, Response) :-
 	edt_dependency(Store, Node, ArgPos, TermPath, _, Origin),
 	(
 		Origin = primitive_op(FileName, LineNo, PrimOpType),
@@ -979,7 +972,8 @@
 		Response = not_found
 	;
 		Origin = input(InputArgPos, InputTermPath),
-		Response = origin(SuspectId, InputArgPos, InputTermPath)
+		Response = origin(SuspectId, InputArgPos, InputTermPath,
+			subterm_in)
 	;
 		Origin = output(OriginNode, OutputArgPos, OutputTermPath),
 		(
@@ -992,7 +986,8 @@
 			ExplicitOrigin = OriginNode
 		),
 		(
-			children(Store, SuspectId, !SearchSpace, Children)
+			children(IoActionMap, Store, Oracle, SuspectId,
+				!SearchSpace, Children)
 		->
 			(
 				find_edt_node_in_suspect_list(Children,
@@ -1000,7 +995,7 @@
 					OriginId)
 			->
 				Response = origin(OriginId, OutputArgPos,
-					OutputTermPath)
+					OutputTermPath, subterm_out)
 			;
 				throw(internal_error("find_subterm_origin",
 					"output origin for input subterm "++
@@ -1449,22 +1444,31 @@
 	% the given suspect.  The suspect_ids for the new suspects will
 	% also be returned.
 	%
-:- pred add_children(S::in, list(T)::in, suspect_id::in, suspect_status::in,
-	search_space(T)::in, search_space(T)::out, list(suspect_id)::out)
+:- pred add_children(io_action_map::in, S::in, oracle_state::in, list(T)::in,
+	suspect_id::in, suspect_status::in, search_space(T)::in,
+	search_space(T)::out, list(suspect_id)::out)
 	is det <= mercury_edt(S, T).

-add_children(Store, EDTChildren, SuspectId, Status, !SearchSpace, Children) :-
+add_children(IoActionMap, Store, Oracle, EDTChildren, SuspectId, Status,
+		!SearchSpace, Children) :-
 	Counter0 = !.SearchSpace ^ suspect_id_counter,
 	lookup_suspect(!.SearchSpace, SuspectId, Suspect0),
-	add_children_2(Store, EDTChildren, SuspectId, Status,
-		Suspect0 ^ depth + 1,
-		!SearchSpace, Counter0, Counter, Children),
-	!:SearchSpace = !.SearchSpace ^ suspect_id_counter := Counter,
-	% Lookup the suspect again, since it's weight may have changed.
+	Depth = Suspect0 ^ depth + 1,
+	add_children_2(IoActionMap, Store, Oracle, EDTChildren, SuspectId,
+		Status, Depth, !SearchSpace, Counter0, Counter, Children),
+	% Lookup the suspect again, since it's weight and/or status may have
+	% changed.
 	lookup_suspect(!.SearchSpace, SuspectId, Suspect),
+	!:SearchSpace = !.SearchSpace ^ suspect_id_counter := Counter,
+	SuspectWithChildren = Suspect ^ children := yes(Children),
+	map.set(!.SearchSpace ^ store, SuspectId, SuspectWithChildren,
+		SuspectStoreWithChildren),
+	!:SearchSpace = !.SearchSpace ^ store := SuspectStoreWithChildren,
+	list.foldl(adjust_suspect_status_from_oracle(IoActionMap, Store,
+		Oracle), Children, !SearchSpace),
 	%
 	% Recalc the weight if the suspect is ignored.  This wouldn't have
-	% been done by ignore_suspect/3 since the children wouldn't have been
+	% been done by ignore_suspect/4 since the children wouldn't have been
 	% available.
 	%
 	(
@@ -1473,37 +1477,90 @@
 		calc_suspect_weight(Store, Suspect ^ edt_node, yes(Children),
 			ignored, !.SearchSpace, Weight, _),
 		map.set(!.SearchSpace ^ store, SuspectId,
-			(Suspect ^ weight := Weight)
-				^ children := yes(Children), SuspectStore),
-		!:SearchSpace = !.SearchSpace ^ store := SuspectStore,
+			SuspectWithChildren ^ weight := Weight,
+			SuspectStoreWithWeight),
+		!:SearchSpace = !.SearchSpace ^ store :=
+			SuspectStoreWithWeight,
 		add_weight_to_ancestors(SuspectId, Weight - Suspect ^ weight,
 			!SearchSpace)
 	;
-		map.set(!.SearchSpace ^ store, SuspectId,
-			Suspect ^ children := yes(Children), SuspectStore),
-		!:SearchSpace = !.SearchSpace ^ store := SuspectStore
+		true
 	).

-:- pred add_children_2(S::in, list(T)::in, suspect_id::in, suspect_status::in,
-	int::in, search_space(T)::in, search_space(T)::out, counter::in,
-	counter::out, list(suspect_id)::out) is det <= mercury_edt(S, T).
-
-add_children_2(_, [], _, _, _, SearchSpace, SearchSpace, Counter, Counter, []).
-
-add_children_2(Store, [EDTChild | EDTChildren], SuspectId, Status, Depth,
-		!SearchSpace, !Counter, Children) :-
+:- pred add_children_2(io_action_map::in, S::in, oracle_state::in, list(T)::in,
+	suspect_id::in, suspect_status::in, int::in,
+	search_space(T)::in, search_space(T)::out, counter::in, counter::out,
+	list(suspect_id)::out) is det <= mercury_edt(S, T).
+
+add_children_2(_, _, _, [], _, _, _, !SearchSpace, !Counter, []).
+add_children_2(IoActionMap, Store, Oracle, [EDTChild | EDTChildren],
+		ParentId, Status, Depth, !SearchSpace, !Counter, Children)
+		:-
 	allocate(NextId, !Counter),
 	calc_suspect_weight(Store, EDTChild, no, Status, !.SearchSpace, Weight,
 		ExcessWeight),
 	map.det_insert(!.SearchSpace ^ store, NextId,
-		suspect(yes(SuspectId), EDTChild, Status, Depth, no, Weight),
+		suspect(yes(ParentId), EDTChild, Status, Depth, no, Weight),
 		SuspectStore),
 	!:SearchSpace = !.SearchSpace ^ store := SuspectStore,
 	add_weight_to_ancestors(NextId, ExcessWeight, !SearchSpace),
-	add_children_2(Store, EDTChildren, SuspectId, Status, Depth,
-		!SearchSpace, !Counter, OtherChildren),
+	add_children_2(IoActionMap, Store, Oracle, EDTChildren, ParentId,
+		Status, Depth, !SearchSpace, !Counter, OtherChildren),
 	Children = [NextId | OtherChildren].

+:- pred add_child_to_parent(suspect_id::in, suspect(T)::in, suspect(T)::out)
+	is det.
+
+add_child_to_parent(ChildId, !Parent) :-
+	(
+		!.Parent ^ children = no,
+		NewChildren = [ChildId]
+	;
+		!.Parent ^ children = yes(Children),
+		list.append(Children, [ChildId], NewChildren)
+	),
+	!:Parent = !.Parent ^ children := yes(NewChildren).
+
+:- pred adjust_suspect_status_from_oracle(io_action_map::in, S::in,
+	oracle_state::in, suspect_id::in, search_space(T)::in,
+	search_space(T)::out) is det <= mercury_edt(S, T).
+
+adjust_suspect_status_from_oracle(IoActionMap, Store, Oracle, SuspectId,
+		!SearchSpace) :-
+	lookup_suspect(!.SearchSpace, SuspectId, Suspect),
+	(
+		Suspect ^ status = unknown
+	->
+		edt_question(IoActionMap, Store, Suspect ^ edt_node, Question),
+		(
+			answer_known(Oracle, Question, Answer)
+		->
+			(
+				Answer = ignore(_),
+				ignore_suspect(Store, SuspectId, !SearchSpace)
+			;
+				Answer = truth_value(_, Truth),
+				(
+					Truth = erroneous,
+					assert_suspect_is_erroneous(SuspectId,
+						!SearchSpace)
+				;
+					Truth = correct,
+					assert_suspect_is_correct(SuspectId,
+						!SearchSpace)
+				;
+					Truth = inadmissible,
+					assert_suspect_is_inadmissible(
+						SuspectId, !SearchSpace)
+				)
+			)
+		;
+			true
+		)
+	;
+		true
+	).
+
 initialise_search_space(Store, Node, SearchSpace) :-
 	edt_weight(Store, Node, Weight, _),
 	map.set(init, 0, suspect(no, Node, unknown, 0, no, Weight),
@@ -1522,12 +1579,14 @@
 		!.SearchSpace ^ implicit_roots_to_explicit_roots :=
 		ImplicitToExplicit.

-incorporate_explicit_supertree(Store, Node, !SearchSpace) :-
+incorporate_explicit_supertree(IoActionMap, Store, Oracle, Node,
+		!SearchSpace) :-
 	topmost_det(!.SearchSpace, OldTopMostId),
 	(
 		edt_parent(Store, Node, Parent)
 	->
-		insert_new_topmost_node(Store, Parent, !SearchSpace),
+		insert_new_topmost_node(IoActionMap, Store, Oracle, Parent,
+			!SearchSpace),
 		%
 		% Node implicitly represents the root of the old search space,
 		% which we already have an explicit version of, so we link
@@ -1545,21 +1604,23 @@
 			"no parent"))
 	).

-extend_search_space_upwards(Store, !SearchSpace) :-
+extend_search_space_upwards(IoActionMap, Store, Oracle, !SearchSpace) :-
 	topmost_det(!.SearchSpace, OldTopMostId),
 	edt_parent(Store, get_edt_node(!.SearchSpace, OldTopMostId),
 		NewTopMost),
-	insert_new_topmost_node(Store, NewTopMost, !SearchSpace).
+	insert_new_topmost_node(IoActionMap, Store, Oracle, NewTopMost,
+		!SearchSpace).

 	% Add the given EDT node to the top of the search space.  The given
 	% node should be a parent of the current topmost node in the search
 	% space.
 	%
-:- pred insert_new_topmost_node(S::in, T::in,
-	search_space(T)::in, search_space(T)::out)
+:- pred insert_new_topmost_node(io_action_map::in, S::in, oracle_state::in,
+	T::in, search_space(T)::in, search_space(T)::out)
 	is det <= mercury_edt(S, T).

-insert_new_topmost_node(Store, NewTopMostEDTNode, !SearchSpace) :-
+insert_new_topmost_node(IoActionMap, Store, Oracle, NewTopMostEDTNode,
+		!SearchSpace) :-
 	(
 		edt_children(Store, NewTopMostEDTNode, EDTChildren)
 	->
@@ -1599,7 +1660,7 @@
 					!.SuspectStore
 			),
 			SiblingStatus = new_child_status(NewTopMostStatus),
-			add_children(Store,
+			add_children(IoActionMap, Store, Oracle,
 				append(LeftChildren, RightChildren),
 				NewTopMostId, SiblingStatus,
 				!SearchSpace, ChildrenIds),
@@ -1642,7 +1703,9 @@
 					!.SuspectStore
 			),
 			!:SearchSpace = !.SearchSpace ^ topmost :=
-				yes(NewTopMostId)
+				yes(NewTopMostId),
+			adjust_suspect_status_from_oracle(IoActionMap, Store,
+				Oracle, NewTopMostId, !SearchSpace)
 		;
 			throw(internal_error("insert_new_topmost_node",
 				"couldn't find event number"))
@@ -1684,7 +1747,7 @@
 	lookup_suspect(SearchSpace, SuspectId, Parent),
 	Parent ^ parent = yes(ParentId).

-children(Store, SuspectId, !SearchSpace, Children) :-
+children(IoActionMap, Store, Oracle, SuspectId, !SearchSpace, Children) :-
 	lookup_suspect(!.SearchSpace, SuspectId, Suspect),
 	(
 		Suspect ^ children = yes(Children)
@@ -1692,36 +1755,26 @@
 		Suspect ^ children = no,
 		edt_children(Store, Suspect ^ edt_node, EDTChildren),
 		NewStatus = new_child_status(Suspect ^ status),
-		add_children(Store, EDTChildren, SuspectId, NewStatus,
-			!SearchSpace, Children)
+		add_children(IoActionMap, Store, Oracle, EDTChildren,
+			SuspectId, NewStatus, !SearchSpace, Children)
 	).

-	% non_ignored_descendents(Store, SuspectIds, !SearchSpace,
-	%	Descendents).
-	% Descendents is the non-ignored children of the suspects in
-	% SuspectIds appended together.  If a child is ignored then it's
-	% non-ignored children are added to the list.  This is done
-	% recursively.  Fails if an explicit subtree is required to find
-	% the children of an ignored suspect.
-	%
-:- pred non_ignored_descendents(S::in, list(suspect_id)::in,
-	search_space(T)::in, search_space(T)::out, list(suspect_id)::out)
-	is semidet <= mercury_edt(S, T).
-
-non_ignored_descendents(_, [], !SearchSpace, []).
-non_ignored_descendents(Store, [SuspectId | SuspectIds], !SearchSpace,
-		Descendents) :-
+non_ignored_descendents(_, _, _, [], !SearchSpace, []).
+non_ignored_descendents(IoActionMap, Store, Oracle, [SuspectId | SuspectIds],
+		!SearchSpace, Descendents) :-
 	lookup_suspect(!.SearchSpace, SuspectId, Suspect),
 	(
 		Suspect ^ status = ignored
 	->
-		children(Store, SuspectId, !SearchSpace, Children),
-		non_ignored_descendents(Store, Children, !SearchSpace,
-			Descendents1)
+		children(IoActionMap, Store, Oracle, SuspectId, !SearchSpace,
+			Children),
+		non_ignored_descendents(IoActionMap, Store, Oracle, Children,
+			!SearchSpace, Descendents1)
 	;
 		Descendents1 = [SuspectId]
 	),
-	non_ignored_descendents(Store, SuspectIds, !SearchSpace, Descendents2),
+	non_ignored_descendents(IoActionMap, Store, Oracle, SuspectIds,
+		!SearchSpace, Descendents2),
 	append(Descendents1, Descendents2, Descendents).

 choose_skipped_suspect(SearchSpace, Skipped) :-
@@ -1767,13 +1820,13 @@
 		LeastSkipped = SuspectId2
 	).

-first_unknown_descendent(Store, SuspectId, !SearchSpace,
-		MaybeDescendent) :-
-	first_unknown_descendent_list(Store, [SuspectId], !SearchSpace,
-		MaybeDescendent).
+first_unknown_descendent(IoActionMap, Store, Oracle, SuspectId, !SearchSpace,
+		MaybeFound) :-
+	first_unknown_descendent_list(IoActionMap, Store, Oracle, [SuspectId],
+		!SearchSpace, MaybeFound).

-	% first_unknown_descendent_list(Store, List, !SearchSpace,
-	%	MaybeDescendent).
+	% first_unknown_descendent_list(IoActionMap, Store, Oracle, List,
+	%	!SearchSpace, MaybeDescendent).
 	% Find the first unknown suspect in List.  If one is found then
 	% it is returned through MaybeDescendent.  Otherwise if there are
 	% any skipped, ignored or erroneous suspects in List then look in the
@@ -1783,77 +1836,88 @@
 	% unknown suspects.  MaybeDescendent will be no if there are no
 	% unknown descendents and no explicit subtree's are required.
 	%
-:- pred first_unknown_descendent_list(S::in, list(suspect_id)::in,
-	search_space(T)::in, search_space(T)::out, maybe(suspect_id)::out)
-	is semidet <= mercury_edt(S, T).
-
-first_unknown_descendent_list(Store, SuspectList, !SearchSpace,
-		MaybeDescendent) :-
+:- pred first_unknown_descendent_list(io_action_map::in, S::in,
+	oracle_state::in, list(suspect_id)::in, search_space(T)::in,
+	search_space(T)::out, maybe_found_descendent::out)
+	is det <= mercury_edt(S, T).
+
+first_unknown_descendent_list(IoActionMap, Store, Oracle, SuspectList,
+		!SearchSpace, MaybeFound) :-
 	list.filter(suspect_unknown(!.SearchSpace), SuspectList, UnknownList,
 		Others),
 	(
 		UnknownList = [Unknown | _],
-		MaybeDescendent = yes(Unknown)
+		MaybeFound = found(Unknown)
 	;
 		UnknownList = [],
 		list.filter(suspect_in_buggy_subtree(
 			!.SearchSpace), Others, InBuggySubtree),
-		get_children_list(Store, InBuggySubtree, !SearchSpace,
-			ExplicitRequired, Children),
+		get_children_list(IoActionMap, Store, Oracle, InBuggySubtree,
+			!SearchSpace, ExplicitRequired, Children),
 		(
 			Children = [],
-			ExplicitRequired = no,
-			MaybeDescendent = no
+			(
+				ExplicitRequired = no,
+				MaybeFound = not_found
+			;
+				ExplicitRequired = yes(RequireExplicitId),
+				MaybeFound = require_explicit_subtree(
+					RequireExplicitId)
+			)
 		;
 			Children = [_ | _],
-			first_unknown_descendent_list(Store, Children,
-				!SearchSpace, MaybeDescendentChildren),
+			first_unknown_descendent_list(IoActionMap, Store,
+				Oracle, Children, !SearchSpace,
+				MaybeFound0),
 			(
-				MaybeDescendentChildren = no,
-				ExplicitRequired = no,
-				MaybeDescendent = no
+				MaybeFound0 = not_found,
+				(
+					ExplicitRequired = no,
+					MaybeFound = not_found
+				;
+					ExplicitRequired = yes(
+						RequireExplicitId),
+					MaybeFound = require_explicit_subtree(
+						RequireExplicitId)
+				)
+			;
+				MaybeFound0 = found(_),
+				MaybeFound = MaybeFound0
 			;
-				MaybeDescendentChildren = yes(Unknown),
-				MaybeDescendent = yes(Unknown)
+				MaybeFound0 = require_explicit_subtree(_),
+				MaybeFound = MaybeFound0
 			)
 		)
 	).

-	% get_children_list(Store, SuspectIds, !SearchSpace, ExplicitRequired,
-	%	Children).
+	% get_children_list(IoActionMap, Store, Oracle, SuspectIds,
+	% 	!SearchSpace, ExplicitRequired, Children).
 	% Children is the children of all the suspects in SuspectIds appended
 	% together.  If an explicit subtree is required to find the children
 	% of at least one element of SuspectIds, then ExplicitRequired will be
 	% yes, otherwise it'll be no.  If an explicit subtree is required for
 	% a suspect then it's children are not included in Children.
 	%
-:- pred get_children_list(S::in, list(suspect_id)::in, search_space(T)::in,
-	search_space(T)::out, bool::out, list(suspect_id)::out) is det
-	<= mercury_edt(S, T).
+:- pred get_children_list(io_action_map::in, S::in, oracle_state::in,
+	list(suspect_id)::in, search_space(T)::in, search_space(T)::out,
+	maybe(suspect_id)::out, list(suspect_id)::out)
+	is det <= mercury_edt(S, T).

-get_children_list(_, [], SearchSpace, SearchSpace, no, []).
-get_children_list(Store, [SuspectId | SuspectIds], !SearchSpace,
-		ExplicitRequired, ChildrenList) :-
-	get_children_list(Store, SuspectIds, !SearchSpace,
+get_children_list(_, _, _, [], SearchSpace, SearchSpace, no, []).
+get_children_list(IoActionMap, Store, Oracle, [SuspectId | SuspectIds],
+		!SearchSpace, ExplicitRequired, ChildrenList) :-
+	get_children_list(IoActionMap, Store, Oracle, SuspectIds, !SearchSpace,
 		ExplicitRequired0, ChildrenList0),
 	(
-		children(Store, SuspectId, !SearchSpace, Children)
+		children(IoActionMap, Store, Oracle, SuspectId, !SearchSpace,
+			Children)
 	->
 		append(Children, ChildrenList0, ChildrenList),
 		ExplicitRequired = ExplicitRequired0
 	;
 		ChildrenList = ChildrenList0,
-		ExplicitRequired = yes
+		ExplicitRequired = yes(SuspectId)
 	).
-
-pick_implicit_root(Store, SearchSpace, ImplicitRoot) :-
-	(
-		SearchSpace ^ root = yes(StartId)
-	;
-		SearchSpace ^ root = no,
-		SearchSpace ^ topmost = yes(StartId)
-	),
-	find_first_implicit_root(Store, SearchSpace, [StartId], ImplicitRoot).

 	% Look for an implicit root in the descendents of each suspect in
 	% the list in a depth first fashion.
Index: browser/declarative_oracle.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_oracle.m,v
retrieving revision 1.42
diff -u -r1.42 declarative_oracle.m
--- browser/declarative_oracle.m	2 May 2005 04:21:13 -0000	1.42
+++ browser/declarative_oracle.m	3 May 2005 03:19:10 -0000
@@ -118,6 +118,12 @@
 :- pred set_browser_state(browser_info.browser_persistent_state::in,
 	oracle_state::in, oracle_state::out) is det.

+	% True if the answer to the question is in the knowledge base, or
+	% the predicate is trusted.
+	%
+:- pred answer_known(oracle_state::in, decl_question(T)::in,
+	decl_answer(T)::out(non_user_derived_answer)) is semidet.
+
 %-----------------------------------------------------------------------------%

 :- implementation.
@@ -481,9 +487,6 @@
 set_kb_exceptions_map(KB, M, KB ^ kb_exceptions_map := M).

 %-----------------------------------------------------------------------------%
-
-:- pred answer_known(oracle_state::in, decl_question(T)::in,
-	decl_answer(T)::out) is semidet.

 answer_known(Oracle, Question, Answer) :-
 	Atom = get_decl_question_atom(Question),
Index: tests/debugger/declarative/binary_search.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/binary_search.exp,v
retrieving revision 1.2
diff -u -r1.2 binary_search.exp
--- tests/debugger/declarative/binary_search.exp	6 Jan 2005 03:20:11 -0000	1.2
+++ tests/debugger/declarative/binary_search.exp	3 May 2005 06:52:44 -0000
@@ -53,16 +53,6 @@
 b(yes)
 Valid? b 1
 browser> mark
-silly_even(801, yes)
-Valid? n
-silly_even(701, yes)
-Valid? n
-silly_even(651, yes)
-Valid? n
-silly_even(625, yes)
-Valid? n
-silly_even(614, yes)
-Valid? y
 Found incorrect contour:
 silly_even(618, yes)
 silly_even(619, yes)
Index: tests/debugger/declarative/binary_search.exp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/binary_search.exp2,v
retrieving revision 1.2
diff -u -r1.2 binary_search.exp2
--- tests/debugger/declarative/binary_search.exp2	6 Jan 2005 03:20:11 -0000	1.2
+++ tests/debugger/declarative/binary_search.exp2	5 May 2005 02:40:12 -0000
@@ -55,16 +55,6 @@
 b(yes)
 Valid? b 1
 browser> mark
-silly_even(801, yes)
-Valid? n
-silly_even(701, yes)
-Valid? n
-silly_even(651, yes)
-Valid? n
-silly_even(625, yes)
-Valid? n
-silly_even(614, yes)
-Valid? y
 Found incorrect contour:
 >(619, 0)
 -(619, 1) = 618
@@ -92,16 +82,18 @@
 [11]
 browser> cd 1
 browser> mark
-add1s([6, 7, 8, 9, 10], [7, 8, ...])
+add1s([10], [11])
 Valid? y
-add1s([3, 4, 5, 6, 7, 8, 9, 10], [|]/2)
+add1s([5, 6, 7, 8, 9, 10], [6, ...])
+Valid? y
+add1s([2, 3, 4, 5, 6, 7, 8, 9, ...], [|]/2)
 Valid? n
-add1s([4, 5, 6, 7, 8, 9, 10], [5, ...])
+add1s([3, 4, 5, 6, 7, 8, 9, 10], [|]/2)
 Valid? y
 Found incorrect contour:
-+(3, 1) = 4
-add1s([4, 5, 6, 7, 8, 9, 10], [5, ...])
++(2, 1) = 3
 add1s([3, 4, 5, 6, 7, 8, 9, 10], [|]/2)
+add1s([2, 3, 4, 5, 6, 7, 8, 9, ...], [|]/2)
 Is this a bug? y
      E10:     C7 EXIT pred binary_search.add1s/2-0 (det)
 mdb> c
Index: tests/debugger/declarative/binary_search.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/binary_search.inp,v
retrieving revision 1.1
diff -u -r1.1 binary_search.inp
--- tests/debugger/declarative/binary_search.inp	19 Nov 2004 11:54:24 -0000	1.1
+++ tests/debugger/declarative/binary_search.inp	3 May 2005 06:12:43 -0000
@@ -27,11 +27,6 @@
 dd
 b 1
 mark
-n
-n
-n
-n
-y
 y
 delete 1
 break add1s
Index: tests/debugger/declarative/binary_search.inp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/binary_search.inp2,v
retrieving revision 1.1
diff -u -r1.1 binary_search.inp2
--- tests/debugger/declarative/binary_search.inp2	19 Nov 2004 11:54:24 -0000	1.1
+++ tests/debugger/declarative/binary_search.inp2	5 May 2005 02:37:55 -0000
@@ -27,11 +27,6 @@
 dd
 b 1
 mark
-n
-n
-n
-n
-y
 y
 delete 1
 break add1s
@@ -45,6 +40,7 @@
 ls
 cd 1
 mark
+y
 y
 n
 y
Index: tests/debugger/declarative/family.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/family.exp,v
retrieving revision 1.5
diff -u -r1.5 family.exp
--- tests/debugger/declarative/family.exp	27 Jan 2005 02:38:58 -0000	1.5
+++ tests/debugger/declarative/family.exp	3 May 2005 06:53:26 -0000
@@ -59,8 +59,6 @@
 mdb> dd
 half_siblings(b, a)
 Valid? no
-siblings(b, a)
-Valid? yes
 Found partially uncovered atom:
 common_father(_, _)
 Is this a bug? yes
Index: tests/debugger/declarative/family.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/family.inp,v
retrieving revision 1.2
diff -u -r1.2 family.inp
--- tests/debugger/declarative/family.inp	19 Nov 2004 11:54:32 -0000	1.2
+++ tests/debugger/declarative/family.inp	2 May 2005 09:24:06 -0000
@@ -26,7 +26,6 @@
 dd
 no
 yes
-yes
 continue
 continue
 finish
Index: trace/mercury_trace_declarative.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_declarative.c,v
retrieving revision 1.86
diff -u -r1.86 mercury_trace_declarative.c
--- trace/mercury_trace_declarative.c	2 May 2005 04:21:19 -0000	1.86
+++ trace/mercury_trace_declarative.c	3 May 2005 03:19:50 -0000
@@ -1764,6 +1764,10 @@
 		MR_debug_enabled = MR_TRUE;
 		MR_update_trace_func_enabled();
 		MR_trace_decl_mode = MR_TRACE_INTERACTIVE;
+	} else {
+		MR_debug_enabled = MR_FALSE;
+		MR_update_trace_func_enabled();
+		MR_trace_decl_mode = MR_TRACE_DECL_DEBUG;
 	}

 	io_start = MR_edt_start_io_counter;
@@ -1782,9 +1786,6 @@
 		MR_io_action_map_cache_end = io_end;
 	}

-	MR_debug_enabled = MR_FALSE;
-	MR_update_trace_func_enabled();
-
 	MR_TRACE_CALL_MERCURY(
 		if (new_tree == MR_TRUE) {
 			MR_DD_decl_diagnosis_new_tree(MR_trace_node_store,
@@ -1821,17 +1822,13 @@
 				(MR_Integer *) &topmost_seqno);
 	);

-	MR_debug_enabled = MR_TRUE;
-	MR_update_trace_func_enabled();
-
 	/*
 	** Turn off interactive debugging after the diagnosis in case a new
 	** explicit subtree or supertree needs to be constructed.
 	*/
-	if (MR_trace_decl_in_dd_dd_mode) {
-		MR_debug_enabled = MR_FALSE;
-		MR_trace_decl_mode = MR_TRACE_DECL_DEBUG;
-	}
+	MR_debug_enabled = MR_FALSE;
+	MR_update_trace_func_enabled();
+	MR_trace_decl_mode = MR_TRACE_DECL_DEBUG;

 	MR_trace_call_seqno = event_details->MR_call_seqno;
 	MR_trace_call_depth = event_details->MR_call_depth;

--------------------------------------------------------------------------
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