adding promise_only_solution

Fergus Henderson fjh at cs.mu.OZ.AU
Fri Nov 6 11:36:21 AEDT 1998


As I mentioned at the last Mercury meeting, I'm planning
on adding `promise_only_solution' to the Mercury standard
library before the upcoming release.  One thing I haven't
figured out, though, is exactly where to put it.
One possibility is a new module, called say `promise.m'.
Another possibility is to add it to builtin.m.

Comments?

%-----------------------------------------------------------------------------%
% Copyright (C) 1993-1998 The University of Melbourne.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%-----------------------------------------------------------------------------%
%
% File: promise.m
% Author: fjh
% Stability: low
%
% This module contains predicates/functions that are potentially
% unsafe if used improperly; there is no compile-time or even
% run-time checking for these predicates/functions.
% Beware that misuse of this module may lead to unsound results.
% (If you lie to the compiler, the compiler will get its revenge!)
% 
%-----------------------------------------------------------------------------%
:- module promise.
:- interface.

        % A call to `promise_only_solution(Pred)' constitutes a promise
        % on the part of the caller that `Pred' has at most one
        % solution, i.e. that
        %       not some [X1, X2] (Pred(X1), Pred(X2), X1 \= X2).
        %
        % `promise_only_solution(Pred)' presumes that this assumption is
        % satisfied, and returns the X for which Pred(X) is true, if
	% there is one.
        %
:- func promise_only_solution(pred(T)) = T.
:- mode promise_only_solution(pred(out) is cc_multi) = out is det.
:- mode promise_only_solution(pred(out) is cc_nondet) = out is semidet.

%-----------------------------------------------------------------------------%
:- implementation.

promise_only_solution(Pred) = OutVal :-
        call(cc_cast(Pred), OutVal).

:- func cc_cast(pred(T)) = pred(T).
:- mode cc_cast(pred(out) is cc_nondet) = out(pred(out) is semidet) is det.
:- mode cc_cast(pred(out) is cc_multi) = out(pred(out) is det) is det.

:- pragma c_code(cc_cast(X::(pred(out) is cc_multi)) =
                        (Y::out(pred(out) is det)),
                [will_not_call_mercury, thread_safe],
                "Y = X;").
:- pragma c_code(cc_cast(X::(pred(out) is cc_nondet)) =
                        (Y::out(pred(out) is semidet)),
                [will_not_call_mercury, thread_safe],
                "Y = X;").

%-----------------------------------------------------------------------------%

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.



More information about the developers mailing list