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