[m-rev.] for review: bug fix for try_all/2

Mark Brown mark at cs.mu.OZ.AU
Fri Dec 10 02:12:24 AEDT 2004


On 10-Dec-2004, Julien Fischer <juliensf at cs.mu.OZ.AU> wrote:
> 
> On Fri, 10 Dec 2004, Mark Brown wrote:
> 
> > Estimated hours taken: 1
> >
> > Improve the interface of exception__try_all by separating the output into
> > a maybe-exception and a list of solutions.  This makes it easier to test
> > whether an exception occurred, and removes the need for solutions to be
> > wrapped in an exception_result.
> >
> > This also obviates a bug in the previous implementation/documentation
> > of try_all.
> >
> > Although this change is not backwards compatible, the fact that no one
> > reported the existing bug for the last four years suggests that that
> > shouldn't be much of an issue.
> >
> Even so, it would be better to not suddenly delete it.  It would
> be preferable to stick an obsolete pragma on the old version for now,
> along with a comment that this interface is not going to be supported
> for much longer.

Okay.  New log message and relative diff are below.

> 
> 
> > NEWS:
> > 	Mention the change.
> >
> > library/exception.m:
> > 	Modify the interface, implementation and documentation of try_all
> > 	to reflect the above.
> >
> > 	Rewrite the documentation of incremental_try_all so as not to refer
> > 	to the old version of try_all.  The meaning of incremental_try_all
> > 	is not changed.
> >
> > tests/hard_coded/exceptions/test_try_all.{m,exp}:
> > 	Update the test case to reflect the new interface.
> >
> That looks fine otherwise.

I'll go ahead and commit this soon.

Cheers,
Mark.

Estimated hours taken: 1

Improve the interface of exception__try_all by separating the output into
a maybe-exception and a list of solutions.  This makes it easier to test
whether an exception occurred, and removes the need for solutions to be
wrapped in an exception_result.

This also obviates a bug in the previous implementation/documentation
of try_all whereby it was putting the exception at the start of the results
list instead of the end, as documented.

Although this change is not backwards compatible, the fact that no one
reported the existing bug for the last four years suggests that that
shouldn't be much of an issue.

NEWS:
	Mention the change.

library/exception.m:
	Add try_all/3, which is like try_all/2 except as described above.

	Make try_all/2 obsolete.  Modify its documentation to reflect its
	actual behaviour.  Implement it in terms of try_all/3.

	Rewrite the documentation of incremental_try_all so as not to refer
	to try_all/2.  The meaning of incremental_try_all is not changed.

tests/hard_coded/exceptions/test_try_all.{m,exp}:
	Update the test case to reflect the new interface.


diff -u library/exception.m library/exception.m
--- library/exception.m	9 Dec 2004 12:42:56 -0000
+++ library/exception.m	9 Dec 2004 14:51:22 -0000
@@ -126,6 +126,47 @@
 :- inst [] ---> [].
 :- inst nil_or_singleton_list ---> [] ; [ground].
 
+	% try_all(Goal, ResultList):
+	%
+	% NOTE: This predicate has been superseded by try_all/3 and is now
+	% obsolete.  It may be removed in a future release.
+	%
+	% Operational semantics:
+	%	Try to find all solutions to Goal(R), using backtracking.
+	%	Collect the solutions found in the ResultList, until
+	%	the goal either throws an exception or fails.
+	%	If it throws an exception, put that exception at the start
+	%	of the ResultList.
+	%
+	% Declaratively:
+	%       try_all(Goal, ResultList) <=>
+	%		(if
+	%			ResultList = [First | AllButFirst],
+	%			First = exception(_)
+	%		then
+	%			all [M] (list__member(M, AllButFirst) =>
+	%				(M = succeeded(R), Goal(R))),
+	%		else
+	%			all [M] (list__member(M, ResultList) =>
+	%				(M = succeeded(R), Goal(R))),
+	%			all [R] (Goal(R) =>
+	%				list__member(succeeded(R),
+	%					ResultList)),
+	%		).
+
+:- pragma obsolete(exception.try_all/2).
+
+:- pred try_all(pred(T), list(exception_result(T))).
+:- mode try_all(pred(out) is det,     out(try_all_det))     is cc_multi.
+:- mode try_all(pred(out) is semidet, out(try_all_semidet)) is cc_multi.
+:- mode try_all(pred(out) is multi,   out(try_all_multi))   is cc_multi.
+:- mode try_all(pred(out) is nondet,  out(try_all_nondet))  is cc_multi.
+
+:- inst try_all_det ---> [cannot_fail].
+:- inst try_all_semidet ---> [] ; [cannot_fail].
+:- inst try_all_multi ---> [cannot_fail | try_all_nondet].
+:- inst try_all_nondet == list_skel(cannot_fail).
+
 	% incremental_try_all(Goal, AccumulatorPred, Acc0, Acc):
 	%
 	% Declaratively it is equivalent to:
@@ -512,4 +553,15 @@
 	error("exception.process_one_exception_result: unexpected failure").
 
+try_all(Goal, Results) :-
+	try_all(Goal, MaybeException, Solutions),
+	Results0 = list.map((func(S) = succeeded(S)), Solutions),
+	(
+		MaybeException = no,
+		Results = Results0
+	;
+		MaybeException = yes(Exception),
+		Results = [exception(Exception) | Results0]
+	).
+
 incremental_try_all(Goal, AccPred, Acc0, Acc) :-
 	unsorted_aggregate((pred(Result::out) is nondet :-
--------------------------------------------------------------------------
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