[m-dev.] diff: fix DD bug in implicit subtrees

Mark Anthony BROWN dougl at cs.mu.OZ.AU
Fri Jul 14 17:03:41 AEST 2000


Estimated hours taken: 8

Fix a bug in the handling of implicit subtrees: the debugger was not
always skipping gaps in the contours properly.  The fix is to find an
earlier contour when a dead end is reached (at FAIL, REDO and NEGF events).

The bug was in step_left_in_contour/2, but the same bug appeared in
wrong_answer_children/4 which was doing essentially the same work.
To avoid problems like this in future, the latter has been rewritten
in terms of the former.  Similarly, missing_answer_children/4 has been
rewritten in terms of a new function step_in_stratum/2.

browser/declarative_debugger.m:
	Rewrite {wrong,missing}_answer_children in terms of the
	step functions.

browser/declarative_execution.m:
	Export the step functions for use in the mercury_edt instance;
	this means that they must be polymorphic (the previous monomorphic
	versions are now called *_store).  step_left_in_contour/2
	is the same as before except that it also handles REDO nodes,
	and the clauses are grouped together logically (for readibility).
	step_in_stratum/2 is a new function.

tests/debugger/declarative/Mmakefile:
tests/debugger/declarative/untraced_subgoal.m:
tests/debugger/declarative/untraced_subgoal_sub.m:
tests/debugger/declarative/untraced_subgoal.inp:
tests/debugger/declarative/untraced_subgoal.exp:
	A test case for this change.  This test is only effective if
	there are no events from the sub-module, so it is disabled in
	debug grades.

Index: browser/declarative_debugger.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_debugger.m,v
retrieving revision 1.15
diff -u -r1.15 declarative_debugger.m
--- browser/declarative_debugger.m	2000/05/08 18:16:23	1.15
+++ browser/declarative_debugger.m	2000/07/14 05:38:53
@@ -403,59 +403,37 @@
 wrong_answer_children(Store, NodeId, Ns0, Ns) :-
 	det_trace_node_from_id(Store, NodeId, Node),
 	(
-		Node = call(_, _, _, _, _, _),
-		Ns = Ns0
-	;
-		Node = neg(_, _, _),
+		( Node = call(_, _, _, _, _, _)
+		; Node = neg(_, _, _)
+		; Node = cond(_, _, failed)
+		)
+	->
+			%
+			% We have reached the end of the contour.
+			%
 		Ns = Ns0
 	;
-		Node = exit(_, Call, _, _, _),
-		call_node_from_id(Store, Call, call(Prec, _, _, _, _, _)),
-		wrong_answer_children(Store, Prec, [dynamic(NodeId) | Ns0], Ns)
-	;
-		Node = redo(_, _),
-		error("wrong_answer_children: unexpected REDO node")
-	;
-		Node = fail(_, Call, _, _),
-		call_node_from_id(Store, Call, call(Prec, _, _, _, _, _)),
-		wrong_answer_children(Store, Prec, [dynamic(NodeId) | Ns0], Ns)
-	;
-		Node = cond(Prec, _, Flag),
 		(
-			Flag = succeeded
+			Node = exit(_, _, _, _, _)
 		->
-			wrong_answer_children(Store, Prec, Ns0, Ns)
+				%
+				% Add a child for this node.
+				%
+			Ns1 = [dynamic(NodeId) | Ns0]
 		;
-			Ns = Ns0
-		)
-	;
-		Node = switch(Back, _),
-		wrong_answer_children(Store, Back, Ns0, Ns)
-	;
-		Node = first_disj(Back, _),
-		wrong_answer_children(Store, Back, Ns0, Ns)
-	;
-		Node = later_disj(_, _, FirstDisj),
-		first_disj_node_from_id(Store, FirstDisj, first_disj(Back, _)),
-		wrong_answer_children(Store, Back, Ns0, Ns)
-	;
-		Node = then(Back, _),
-		wrong_answer_children(Store, Back, Ns0, Ns)
-	;
-		Node = else(Prec, Cond),
-		missing_answer_children(Store, Prec, Ns0, Ns1),
-		cond_node_from_id(Store, Cond, cond(Back, _, _)),
-		wrong_answer_children(Store, Back, Ns1, Ns)
-	;
-		Node = neg_succ(Prec, Neg),
-		missing_answer_children(Store, Prec, Ns0, Ns1),
-		neg_node_from_id(Store, Neg, neg(Back, _, _)),
-		wrong_answer_children(Store, Back, Ns1, Ns)
-	;
-		Node = neg_fail(Prec, Neg),
-		wrong_answer_children(Store, Prec, Ns0, Ns1),
-		neg_node_from_id(Store, Neg, neg(Back, _, _)),
-		wrong_answer_children(Store, Back, Ns1, Ns)
+			( Node = else(Prec, _)
+			; Node = neg_succ(Prec, _)
+			)
+		->
+				%
+				% There is a nested context.
+				% 
+			missing_answer_children(Store, Prec, Ns0, Ns1)
+		;
+			Ns1 = Ns0
+		),
+		Next = step_left_in_contour(Store, Node),
+		wrong_answer_children(Store, Next, Ns1, Ns)
 	).
 
 :- pred missing_answer_children(S, R, list(edt_node(R)), list(edt_node(R)))
@@ -465,77 +443,46 @@
 missing_answer_children(Store, NodeId, Ns0, Ns) :-
 	det_trace_node_from_id(Store, NodeId, Node),
 	(
-		Node = call(_, _, _, _, _, _),
-		Ns = Ns0
-	;
-		Node = neg(_, _, _),
+		( Node = call(_, _, _, _, _, _)
+		; Node = neg(_, _, _)
+		; Node = cond(_, _, failed)
+		)
+	->
+			%
+			% We have reached the boundary of the stratum.
+			%
 		Ns = Ns0
 	;
-		Node = exit(_, Call, Redo, _, _),
 		(
-			maybe_redo_node_from_id(Store, Redo, redo(Prec0, _))
+			( Node = exit(_, _, _, _, _)
+			; Node = fail(_, _, _, _)
+			)
 		->
-			Prec = Prec0
+				%
+				% Add a child for this node.
+				%
+			Ns1 = [dynamic(NodeId) | Ns0]
 		;
-			call_node_from_id(Store, Call, CallNode),
-			CallNode = call(Prec, _, _, _, _, _)
-		),
-		missing_answer_children(Store, Prec, [dynamic(NodeId) | Ns0],
-				Ns)
-	;
-		Node = redo(_, Exit),
-		exit_node_from_id(Store, Exit, exit(Prec, _, _, _, _)),
-		missing_answer_children(Store, Prec, Ns0, Ns)
-	;
-		Node = fail(_, CallId, MaybeRedo, _),
-		(
-			maybe_redo_node_from_id(Store, MaybeRedo, Redo)
+			Node = neg_fail(Prec, _)
 		->
-			Redo = redo(Prec, _),
-			Next = Prec
+				%
+				% There is a nested successful context.
+				% 
+			wrong_answer_children(Store, Prec, Ns0, Ns1)
 		;
-			call_node_from_id(Store, CallId, Call),
-			Call = call(Back, _, _, _, _, _),
-			Next = Back
-		),
-		missing_answer_children(Store, Next, [dynamic(NodeId) | Ns0],
-				Ns)
-	;
-		Node = cond(Prec, _, Flag),
-		(
-			Flag = succeeded
+			( Node = else(Prec, _)
+			; Node = neg_succ(Prec, _)
+			)
 		->
-			missing_answer_children(Store, Prec, Ns0, Ns)
+				%
+				% There is a nested failed context.
+				%
+			missing_answer_children(Store, Prec, Ns0, Ns1)
 		;
-			Ns = Ns0
-		)
-	;
-		Node = switch(Prec, _),
-		missing_answer_children(Store, Prec, Ns0, Ns)
-	;
-		Node = first_disj(Prec, _),
-		missing_answer_children(Store, Prec, Ns0, Ns)
-	;
-		Node = later_disj(Prec, _, _),
-		missing_answer_children(Store, Prec, Ns0, Ns)
-	;
-		Node = then(Prec, _),
-		missing_answer_children(Store, Prec, Ns0, Ns)
-	;
-		Node = else(Prec, Cond),
-		missing_answer_children(Store, Prec, Ns0, Ns1),
-		cond_node_from_id(Store, Cond, cond(Back, _, _)),
-		missing_answer_children(Store, Back, Ns1, Ns)
-	;
-		Node = neg_succ(Prec, Neg),
-		missing_answer_children(Store, Prec, Ns0, Ns1),
-		neg_node_from_id(Store, Neg, neg(Back, _, _)),
-		missing_answer_children(Store, Back, Ns1, Ns)
-	;
-		Node = neg_fail(Prec, Neg),
-		wrong_answer_children(Store, Prec, Ns0, Ns1),
-		neg_node_from_id(Store, Neg, neg(Back, _, _)),
-		missing_answer_children(Store, Back, Ns1, Ns)
+			Ns1 = Ns0
+		),
+		Next = step_in_stratum(Store, Node),
+		missing_answer_children(Store, Next, Ns1, Ns)
 	).
 
 :- pred edt_subtree_details(S, edt_node(R), event_number, sequence_number)
Index: browser/declarative_execution.m
===================================================================
RCS file: /home/mercury1/repository/mercury/browser/declarative_execution.m,v
retrieving revision 1.10
diff -u -r1.10 declarative_execution.m
--- browser/declarative_execution.m	2000/06/14 15:39:31	1.10
+++ browser/declarative_execution.m	2000/07/14 05:39:02
@@ -126,7 +126,7 @@
 	% Members of this typeclass represent an entire annotated
 	% trace.  The second parameter is the type of identifiers
 	% for trace nodes, and the first parameter is the type of
-	% an abstract mapping from the identfiers to the nodes they
+	% an abstract mapping from identifiers to the nodes they
 	% identify.
 	%
 :- typeclass annotated_trace(S, R) where [
@@ -139,6 +139,29 @@
 	mode trace_node_from_id(in, in, out) is semidet
 ].
 
+	% Given any node in an annotated trace, find the most recent
+	% node in the same contour (ie. the last node which has not been
+	% backtracked over, skipping negations, failed conditions, the
+	% bodies of calls, and alternative disjuncts).  Throw an exception
+	% if there is no such node (ie. if we are at the start of a
+	% negation, call, or failed condition).
+	%
+	% In some cases the contour may reach a dead end.  This can
+	% happen if, for example, a DISJ node is not present because
+	% it is beyond the depth bound or in a module that is not traced;
+	% "stepping left" will arrive at a FAIL, REDO or NEGF node.  Since
+	% it is not possible to follow the original contour in these
+	% circumstances, we follow the previous contour instead.
+	%
+:- func step_left_in_contour(S, trace_node(R)) = R <= annotated_trace(S, R).
+
+	% Given any node in an annotated trace, find the most recent
+	% node in the same stratum (ie. the most recent node, skipping
+	% negations, failed conditions, and the bodies of calls).
+	% Throw an exception if there is no such node (ie. if we are at
+	% the start of a negation, call, or failed negation).
+	%
+:- func step_in_stratum(S, trace_node(R)) = R <= annotated_trace(S, R).
 
 	% The following procedures also dereference the identifiers,
 	% but they give an error if the node is not of the expected type.
@@ -224,6 +247,121 @@
 :- implementation.
 :- import_module map, require, store.
 
+step_left_in_contour(Store, exit(_, Call, _, _, _)) = Prec :-
+	call_node_from_id(Store, Call, call(Prec, _, _, _, _, _)).
+step_left_in_contour(_, switch(Prec, _)) = Prec.
+step_left_in_contour(_, first_disj(Prec, _)) = Prec.
+step_left_in_contour(Store, later_disj(_, _, FirstDisj)) = Prec :-
+	first_disj_node_from_id(Store, FirstDisj, first_disj(Prec, _)).
+step_left_in_contour(_, cond(Prec, _, Status)) = Node :-
+	(
+		Status = failed
+	->
+		error("step_left_in_contour: failed COND node")
+	;
+		Node = Prec
+	).
+step_left_in_contour(_, then(Prec, _)) = Prec.
+step_left_in_contour(Store, else(_, Cond)) = Prec :-
+	cond_node_from_id(Store, Cond, cond(Prec, _, _)).
+step_left_in_contour(Store, neg_succ(_, Neg)) = Prec :-
+	neg_node_from_id(Store, Neg, neg(Prec, _, _)).
+	%
+	% The following cases are at the left end of a contour,
+	% so we cannot step any further.
+	%
+step_left_in_contour(_, call(_, _, _, _, _, _)) = _ :-
+	error("step_left_in_contour: unexpected CALL node").
+step_left_in_contour(_, neg(_, _, _)) = _ :-
+	error("step_left_in_contour: unexpected NEGE node").
+	%
+	% In the remaining cases we have reached a dead end, so we
+	% step to the previous contour instead.
+	%
+step_left_in_contour(Store, Node) = Prec :-
+	Node = fail(_, _, _, _),
+	find_prev_contour(Store, Node, Prec).
+step_left_in_contour(Store, Node) = Prec :-
+	Node = redo(_, _),
+	find_prev_contour(Store, Node, Prec).
+step_left_in_contour(Store, Node) = Prec :-
+	Node = neg_fail(_, _),
+	find_prev_contour(Store, Node, Prec).
+
+	% Given any node which is not on a contour, find a node on
+	% the previous contour in the same stratum.
+	%
+:- pred find_prev_contour(S, trace_node(R), R) <= annotated_trace(S, R).
+:- mode find_prev_contour(in, in, out) is semidet.
+:- mode find_prev_contour(in, in(trace_node_reverse), out) is det.
+
+:- inst trace_node_reverse =
+	bound(	fail(ground, ground, ground, ground)
+	;	redo(ground, ground)
+	;	neg_fail(ground, ground)).
+
+find_prev_contour(Store, fail(_, Call, _, _), OnContour) :-
+	call_node_from_id(Store, Call, call(OnContour, _, _, _, _, _)).
+find_prev_contour(Store, redo(_, Exit), OnContour) :-
+	exit_node_from_id(Store, Exit, exit(OnContour, _, _, _, _)).
+find_prev_contour(Store, neg_fail(_, Neg), OnContour) :-
+	neg_node_from_id(Store, Neg, neg(OnContour, _, _)).
+	%
+	% The following cases are at the left end of a contour,
+	% so there are no previous contours in the same stratum.
+	%
+find_prev_contour(_, call(_, _, _, _, _, _), _) :-
+	error("find_prev_contour: reached CALL node").
+find_prev_contour(_, cond(_, _, _), _) :-
+	error("find_prev_contour: reached COND node").
+find_prev_contour(_, neg(_, _, _), _) :-
+	error("find_prev_contour: reached NEGE node").
+
+step_in_stratum(Store, exit(_, Call, MaybeRedo, _, _)) = Next :-
+	(
+		maybe_redo_node_from_id(Store, MaybeRedo, Redo)
+	->
+		Redo = redo(Next, _)
+	;
+		call_node_from_id(Store, Call, call(Next, _, _, _, _, _))
+	).
+step_in_stratum(Store, fail(_, Call, MaybeRedo, _)) = Next :-
+	(
+		maybe_redo_node_from_id(Store, MaybeRedo, Redo)
+	->
+		Redo = redo(Next, _)
+	;
+		call_node_from_id(Store, Call, call(Next, _, _, _, _, _))
+	).
+step_in_stratum(Store, redo(_, Exit)) = Next :-
+	exit_node_from_id(Store, Exit, exit(Next, _, _, _, _)).
+step_in_stratum(_, switch(Next, _)) = Next.
+step_in_stratum(_, first_disj(Next, _)) = Next.
+step_in_stratum(_, later_disj(Next, _, _)) = Next.
+step_in_stratum(_, cond(Prec, _, Status)) = Next :-
+	(
+		Status = failed
+	->
+		error("step_in_stratum: failed COND node")
+	;
+		Next = Prec
+	).
+step_in_stratum(_, then(Next, _)) = Next.
+step_in_stratum(Store, else(_, Cond)) = Next :-
+	cond_node_from_id(Store, Cond, cond(Next, _, _)).
+step_in_stratum(Store, neg_succ(_, Neg)) = Next :-
+	neg_node_from_id(Store, Neg, neg(Next, _, _)).
+step_in_stratum(Store, neg_fail(_, Neg)) = Next :-
+	neg_node_from_id(Store, Neg, neg(Next, _, _)).
+	%
+	% The following cases mark the boundary of the stratum,
+	% so we cannot step any further.
+	%
+step_in_stratum(_, call(_, _, _, _, _, _)) = _ :-
+	error("step_in_stratum: unexpected CALL node").
+step_in_stratum(_, neg(_, _, _)) = _ :-
+	error("step_in_stratum: unexpected NEGE node").
+
 det_trace_node_from_id(Store, NodeId, Node) :-
 	(
 		trace_node_from_id(Store, NodeId, Node0)
@@ -503,83 +641,36 @@
 	null_trace_node_id(NULL).
 trace_node_first_disj(later_disj(_, _, FirstDisj), FirstDisj).	
 
-	% Given any node in an annotated trace, find the most recent
-	% node in the same contour (ie. the last node which has not been
-	% backtracked over, skipping negations, conditions, the bodies
-	% of calls, and alternative disjuncts).  Return the NULL reference
-	% if there is no such node (eg. if we are at the start of a
-	% negation, condition, or call).
+	% Export a version of this function to be called by C code
+	% in trace/declarative_debugger.c.
 	%
-:- func step_left_in_contour(trace_node_store, trace_node(trace_node_id))
+:- func step_left_in_contour_store(trace_node_store, trace_node(trace_node_id))
 		= trace_node_id.
-:- pragma export(step_left_in_contour(in, in) = out,
+:- pragma export(step_left_in_contour_store(in, in) = out,
 		"MR_DD_step_left_in_contour").
 
-step_left_in_contour(_, call(_, _, _, _, _, _)) = _ :-
-	error("step_left_in_contour: unexpected CALL node").
-step_left_in_contour(_, cond(Prec, _, Status)) = Node :-
-	(
-		Status = succeeded
-	->
-		Node = Prec
-	;
-		null_trace_node_id(Node)
-	).
-step_left_in_contour(_, neg(_, _, _)) = _ :-
-	error("step_left_in_contour: unexpected NEGE node").
-step_left_in_contour(Store, exit(_, Call, _, _, _)) = Prec :-
-	call_node_from_id(Store, Call, call(Prec, _, _, _, _, _)).
-step_left_in_contour(Store, fail(_, Call, _, _)) = Prec :-
-	call_node_from_id(Store, Call, call(Prec, _, _, _, _, _)).
-step_left_in_contour(_, redo(_, _)) = _ :-
-	error("step_left_in_contour: unexpected REDO node").
-step_left_in_contour(_, switch(Prec, _)) = Prec.
-step_left_in_contour(_, first_disj(Prec, _)) = Prec.
-step_left_in_contour(Store, later_disj(_, _, FirstDisj)) = Prec :-
-	first_disj_node_from_id(Store, FirstDisj, first_disj(Prec, _)).
-step_left_in_contour(_, then(Prec, _)) = Prec.
-step_left_in_contour(Store, else(_, Cond)) = Prec :-
-	cond_node_from_id(Store, Cond, cond(Prec, _, _)).
-step_left_in_contour(Store, neg_succ(_, Neg)) = Prec :-
-	neg_node_from_id(Store, Neg, neg(Prec, _, _)).
-step_left_in_contour(Store, neg_fail(_, Neg)) = Prec :-
-	neg_node_from_id(Store, Neg, neg(Prec, _, _)).
+step_left_in_contour_store(Store, Node) = step_left_in_contour(Store, Node).
 
-	% Given any node in an annotated trace, find a node in
-	% the previous contour.
+	% Export a version of this function to be called by C code
+	% in trace/declarative_debugger.c.  If called with a node
+	% that is already on a contour, this function returns the
+	% same node.  This saves the C code from having to perform
+	% that check itself.
 	%
-:- func find_prev_contour(trace_node_store, trace_node_id)
+:- func find_prev_contour_store(trace_node_store, trace_node_id)
 		= trace_node_id.
-:- pragma export(find_prev_contour(in, in) = out,
+:- pragma export(find_prev_contour_store(in, in) = out,
 		"MR_DD_find_prev_contour").
 
-find_prev_contour(Store, NodeId) = OnContour :-
-	det_trace_node_from_id(Store, NodeId, Node),
-	find_prev_contour_1(Store, NodeId, Node, OnContour).
-
-:- pred find_prev_contour_1(trace_node_store, trace_node_id,
-		trace_node(trace_node_id), trace_node_id).
-:- mode find_prev_contour_1(in, in, in, out) is det.
-
-find_prev_contour_1(_, _, call(_, _, _, _, _, _), _) :-
-	error("find_prev_contour: reached CALL node").
-find_prev_contour_1(_, Exit, exit(_, _, _, _, _), Exit).
-find_prev_contour_1(Store, _, redo(_, Exit), OnContour) :-
-	exit_node_from_id(Store, Exit, exit(OnContour, _, _, _, _)).
-find_prev_contour_1(Store, _, fail(_, Call, _, _), OnContour) :-
-	call_node_from_id(Store, Call, call(OnContour, _, _, _, _, _)).
-find_prev_contour_1(_, _, cond(_, _, _), _) :-
-	error("find_prev_contour: reached COND node").
-find_prev_contour_1(_, Then, then(_, _), Then).
-find_prev_contour_1(_, Else, else(_, _), Else).
-find_prev_contour_1(_, _, neg(_, _, _), _) :-
-	error("find_prev_contour: reached NEGE node").
-find_prev_contour_1(_, NegS, neg_succ(_, _), NegS).
-find_prev_contour_1(Store, _, neg_fail(_, Neg), OnContour) :-
-	neg_node_from_id(Store, Neg, neg(OnContour, _, _)).
-find_prev_contour_1(_, Swtc, switch(_, _), Swtc).
-find_prev_contour_1(_, FirstDisj, first_disj(_, _), FirstDisj).
-find_prev_contour_1(_, LaterDisj, later_disj(_, _, _), LaterDisj).
+find_prev_contour_store(Store, Id) = Prev :-
+	det_trace_node_from_id(Store, Id, Node),
+	(
+		find_prev_contour(Store, Node, Prev0)
+	->
+		Prev = Prev0
+	;
+		Prev = Id
+	).
 
 	% Print a text representation of a trace node, useful
 	% for debugging purposes.
Index: tests/debugger/declarative/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/declarative/Mmakefile,v
retrieving revision 1.16
diff -u -r1.16 Mmakefile
--- tests/debugger/declarative/Mmakefile	2000/06/21 19:00:22	1.16
+++ tests/debugger/declarative/Mmakefile	2000/07/14 05:39:11
@@ -35,6 +35,10 @@
 	queens			\
 	small
 
+# The following should not be run in `debug' grades.
+NONDEBUG_DECLARATIVE_PROGS=	\
+	untraced_subgoal
+
 NONWORKING_DECLARATIVE_PROGS=	\
 	family			\
 	higher_order		\
@@ -45,6 +49,14 @@
 MLFLAGS = --trace
 C2INITFLAGS = --trace
 
+MCFLAGS-untraced_subgoal_sub=--trace minimum
+
+ifneq "$(findstring .debug,$(GRADE))" ""
+    PROGS_2=$(DECLARATIVE_PROGS)
+else
+    PROGS_2=$(DECLARATIVE_PROGS) $(NONDEBUG_DECLARATIVE_PROGS)
+endif
+
 # Debugging does not work in MLDS (hl*) grades.
 # Base grades `jump' and `fast' cannot be used with
 # stack layouts (which are required for tracing).
@@ -55,7 +67,7 @@
 else
     ifneq "$(findstring .gc,$(GRADE))" ""
         ifneq "$(findstring asm_,$(GRADE))" ""
-            PROGS=$(DECLARATIVE_PROGS)
+            PROGS=$(PROGS_2)
         else
             ifneq "$(findstring jump,$(GRADE))" ""
                 PROGS=
@@ -63,7 +75,7 @@
                 ifneq "$(findstring fast,$(GRADE))" ""
                     PROGS=
                 else
-                    PROGS=$(DECLARATIVE_PROGS)
+                    PROGS=$(PROGS_2)
                 endif
             endif
         endif
@@ -133,6 +145,10 @@
 
 solutions.out: solutions solutions.inp
 	$(MDB) ./solutions < solutions.inp > solutions.out 2>&1
+
+untraced_subgoal.out: untraced_subgoal untraced_subgoal.inp
+	$(MDB) ./untraced_subgoal < untraced_subgoal.inp \
+			> untraced_subgoal.out 2>&1
 
 #-----------------------------------------------------------------------------#


New file tests/debugger/declarative/untraced_subgoal.m:
 
:- module untraced_subgoal.
:- interface.
:- import_module io.
:- pred main(io__state::di, io__state::uo) is det.
:- implementation.
:- import_module int, untraced_subgoal_sub.

main -->
	(
		{ p(1, X) },
		{ X > 10 }
	->
		io__write_string("yes\n")
	;
		io__write_string("no\n")
	),
	(
		{ p(2, Y) },
		{ Y > 10 }
	->
		io__write_string("yes\n")
	;
		io__write_string("no\n")
	).

:- pred p(int::in, int::out) is nondet.

p(1, X) :-
	untraced_subgoal_sub__q(X).

p(2, X) :-
	untraced_subgoal_sub__q(X),
	r(X, Y),
	s(Y).

:- pred r(int::in, int::out) is det.

r(X, X).

:- pred s(int::out) is multi.

s(2).
s(3).


New file tests/debugger/declarative/untraced_subgoal_sub.m:
 
:- module untraced_subgoal_sub.
:- interface.
:- pred q(int::out) is multi.
:- implementation.
q(1).
q(2).


New file tests/debugger/declarative/untraced_subgoal.inp:
 
echo on
register --quiet
break p
continue
finish
continue
finish
dd
yes
continue
finish
dd
yes
continue
finish
dd
yes
yes
yes
yes
continue
finish
dd
yes
yes
yes
continue


New file tests/debugger/declarative/untraced_subgoal.exp:
 
       1:      1  1 CALL pred untraced_subgoal:main/2-0 (det) untraced_subgoal.m:8
mdb> echo on
Command echo enabled.
mdb> register --quiet
mdb> break p
 0: + stop  interface pred untraced_subgoal:p/2-0 (nondet)
mdb> continue
       3:      2  2 CALL pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:10)
mdb> finish
       5:      2  2 EXIT pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:10)
mdb> continue
       6:      2  2 REDO pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:10)
mdb> finish
       7:      2  2 EXIT pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:10)
mdb> dd
Found incorrect contour:
p(1, 2)
Is this a bug? yes
       7:      2  2 EXIT pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:10)
mdb> continue
       8:      2  2 REDO pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:10)
mdb> finish
       9:      2  2 FAIL pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:10)
mdb> dd
Found partially uncovered atom:
p(1, _)
Is this a bug? yes
       9:      2  2 FAIL pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:10)
mdb> continue
no
      12:      3  2 CALL pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:18)
mdb> finish
      29:      3  2 EXIT pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:18)
mdb> dd
r(1, 1)
Valid? yes
r(2, 2)
Valid? yes
s(2)
Valid? yes
Found incorrect contour:
p(2, 2)
Is this a bug? yes
      29:      3  2 EXIT pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:18)
mdb> continue
      30:      3  2 REDO pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:18)
mdb> finish
      31:      3  2 FAIL pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:18)
mdb> dd
s(3)
Valid? yes
Call s(_)
Solutions:
	s(2)
	s(3)
Complete? yes
Found partially uncovered atom:
p(2, _)
Is this a bug? yes
      31:      3  2 FAIL pred untraced_subgoal:p/2-0 (nondet) untraced_subgoal.m:28 (untraced_subgoal.m:18)
mdb> continue
no

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