[m-rev.] for review: delete obsolete predicates from builtin module
Julien Fischer
jfischer at opturion.com
Wed Apr 13 14:49:13 AEST 2022
For review by anyone.
The request for review is for the NEWS file and as a chance for any
last-second objections; the diff itself is trivial.
----------------------------
Delete obsolete predicates from builtin module.
library/builtin:
Delete the promise_only_solution/1 and promise_only_solution_io/4. Both
have have been marked as obsolete since 2015.
Also delete the non-public impure versions of those, get_one_solution/1
and get_one_solution_io/4. Implementing the pure versions was the only
use of these.
compiler/hlds_goal.m:
Delete a reference to promise_only_solution in a comment.
tests/declarative_debugger/trust.exp:
tests/declarative_debugger/trust.inp:
tests/declarative_debugger/trust_1.m:
Replace a call to promise_only_solution/1; this does simplify this test
a little, but does not affect what the trust_1 module was testing, namely
the user-defined comparison on the type exported by that module.
tests/declarative_debugger/exceptions.m:
tests/hard_coded/myset.m:
tests/hard_coded/user_compare.m:
tests/valid_seq/intermod_nested_module_bug2.m:
extras/curs/samples/nibbles.m:
Replace calls to the now deleted predicates.
Julien.
diff --git a/NEWS b/NEWS
index 9f23c5f..70c8d33 100644
--- a/NEWS
+++ b/NEWS
@@ -55,9 +55,16 @@ Changes to the Mercury standard library
- pred `write_bitmap_range/5`
- pred `write_bitmap_range/6`
+### Changes to the `builtin` module
+
+* The following obsolete predicate and function have been removed:
+
+ - func `promise_only_solution/1`
+ - pred `promise_only_solution_io/4`
+
### Changes to the `hash_table` module
-The following obsolete predicates have been removed:
+* The following obsolete predicates have been removed:
- pred `char_hash/2`
- pred `float_hash/2`
diff --git a/compiler/hlds_goal.m b/compiler/hlds_goal.m
index b918268..5d59d70 100644
--- a/compiler/hlds_goal.m
+++ b/compiler/hlds_goal.m
@@ -465,11 +465,6 @@
% context, and the determinism of the scope() goal itself
% will indicate that it cannot succeed more than once.
%
- % This acts like the builtin.promise_only_solution predicate,
- % but without requiring the construction of a closure, a
- % higher order call, and the squeezing of all outputs into
- % a single variable.
- %
% The promise is valid only if the list of outputs of the goal
% inside the scope is a subset of the variables listed here.
% If it is not valid, the compiler must emit an error message.
diff --git a/extras/curs/samples/nibbles.m b/extras/curs/samples/nibbles.m
index 21a0bbc..4fcc5d8 100644
--- a/extras/curs/samples/nibbles.m
+++ b/extras/curs/samples/nibbles.m
@@ -151,7 +151,10 @@ quit_key(27). % escape
:- pred direction_key(int::in, direction::out) is semidet.
-direction_key(Key, promise_only_solution(direction_key_2(Key))).
+direction_key(Key, Direction) :-
+ promise_equivalent_solutions [Direction] (
+ direction_key_2(Key, Direction)
+ ).
:- pred direction_key_2(int::in, direction::out) is cc_nondet.
diff --git a/library/builtin.m b/library/builtin.m
index 7a8a950..73a1a8a 100644
--- a/library/builtin.m
+++ b/library/builtin.m
@@ -183,54 +183,6 @@
%---------------------------------------------------------------------------%
- % A call to the function `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.
- %
- % You can use `promise_only_solution' as a way of introducing
- % `cc_multi' or `cc_nondet' code inside a `det' or `semidet' procedure.
- %
- % Note that misuse of this function may lead to unsound results: if the
- % assumption is not satisfied, the behaviour is undefined. (If you lie
- % to the compiler, the compiler will get its revenge!)
- %
- % NOTE: This function is deprecated and will be removed in a future
- % release. Use a `promise_equivalent_solutions' goal instead.
- %
-:- pragma obsolete(func(promise_only_solution/1)).
-:- func promise_only_solution(pred(T)) = T.
-:- mode promise_only_solution(pred(out) is cc_multi) = out is det.
-:- mode promise_only_solution(pred(uo) is cc_multi) = uo is det.
-:- mode promise_only_solution(pred(out) is cc_nondet) = out is semidet.
-:- mode promise_only_solution(pred(uo) is cc_nondet) = uo is semidet.
-
- % `promise_only_solution_io' is like `promise_only_solution', but for
- % procedures with unique modes (e.g. those that do IO).
- %
- % A call to `promise_only_solution_io(P, X, IO0, IO)' constitutes a
- % promise on the part of the caller that for the given IO0, there is
- % only one value of X and IO for which `P(X, IO0, IO)' is true.
- % `promise_only_solution_io(P, X, IO0, IO)' presumes that this
- % assumption is satisfied, and returns the X and IO for which
- % `P(X, IO0, IO)' is true.
- %
- % Note that misuse of this predicate may lead to unsound results: if
- % the assumption is not satisfied, the behaviour is undefined. (If you
- % lie to the compiler, the compiler will get its revenge!)
- %
- % NOTE: This predicate is deprecated and will be removed in a future
- % release. Use a `promise_equivalent_solutions' goal instead.
- %
-:- pragma obsolete(pred(promise_only_solution_io/4)).
-:- pred promise_only_solution_io(
- pred(T, IO, IO)::in(pred(out, di, uo) is cc_multi), T::out,
- IO::di, IO::uo) is det.
-
-%---------------------------------------------------------------------------%
-
% unify(X, Y) is true iff X = Y.
%
:- pred unify(T::in, T::in) is semidet.
@@ -433,22 +385,6 @@
:- pred compare_representation(comparison_result, T, T).
:- mode compare_representation(uo, in, in) is cc_multi.
- % `get_one_solution' and `get_one_solution_io' are impure alternatives
- % to `promise_one_solution' and `promise_one_solution_io', respectively.
- % They get a solution to the procedure, without requiring any promise
- % that there is only one solution. However, they can only be used in
- % impure code.
- %
-:- pragma obsolete(func(get_one_solution/1)).
-:- impure func get_one_solution(pred(T)) = T.
-:- mode get_one_solution(pred(out) is cc_multi) = out is det.
-:- mode get_one_solution(pred(out) is cc_nondet) = out is semidet.
-
-:- pragma obsolete(pred(get_one_solution_io/4)).
-:- impure pred get_one_solution_io(pred(T, IO, IO), T, IO, IO).
-:- mode get_one_solution_io(pred(out, di, uo) is cc_multi,
- out, di, uo) is det.
-
% Set up Mercury runtime to call special predicates implemented in this
% module.
%
@@ -471,26 +407,6 @@ false :-
%---------------------------------------------------------------------------%
- % XXX The calls to unsafe_promise_unique below work around
- % mode checker limitations.
-:- pragma promise_pure(func(promise_only_solution/1)).
-promise_only_solution(CCPred::(pred(out) is cc_multi)) = (OutVal::out) :-
- impure OutVal = get_one_solution(CCPred).
-promise_only_solution(CCPred::(pred(uo) is cc_multi)) = (OutVal::uo) :-
- impure OutVal0 = get_one_solution(CCPred),
- OutVal = unsafe_promise_unique(OutVal0).
-promise_only_solution(CCPred::(pred(out) is cc_nondet)) = (OutVal::out) :-
- impure OutVal = get_one_solution(CCPred).
-promise_only_solution(CCPred::(pred(uo) is cc_nondet)) = (OutVal::uo) :-
- impure OutVal0 = get_one_solution(CCPred),
- OutVal = unsafe_promise_unique(OutVal0).
-
-:- pragma promise_pure(pred(promise_only_solution_io/4)).
-promise_only_solution_io(Pred, X, !IO) :-
- impure get_one_solution_io(Pred, X, !IO).
-
-%---------------------------------------------------------------------------%
-
% IMPORTANT: any changes or additions to external predicates should be
% reflected in the definition of pred_is_external in
% mdbcomp/program_representation.m. The debugger needs to know what predicates
@@ -1295,20 +1211,6 @@ dynamic_cast(X, Y) :-
%---------------------------------------------------------------------------%
-get_one_solution(CCPred) = OutVal :-
- promise_equivalent_solutions [OutVal] (
- CCPred(OutVal),
- impure impure_true
- ).
-
-get_one_solution_io(Pred, X, !IO) :-
- promise_equivalent_solutions [!:IO, X] (
- Pred(X, !IO),
- impure impure_true
- ).
-
-%---------------------------------------------------------------------------%
-
init_runtime_hooks.
:- pragma foreign_proc("C",
diff --git a/tests/declarative_debugger/exceptions.m b/tests/declarative_debugger/exceptions.m
index ce78d04..1badeaa 100644
--- a/tests/declarative_debugger/exceptions.m
+++ b/tests/declarative_debugger/exceptions.m
@@ -59,7 +59,9 @@ q(MaybeExcp, Solutions) :-
r(Sols) :-
% This is a lie, but is the only way I seem to be able to call try_all
% in a failing context.
- Sols = promise_only_solution(t),
+ promise_equivalent_solutions [Sols] (
+ t(Sols)
+ ),
semidet_fail.
:- pred s(int::out) is multi.
diff --git a/tests/declarative_debugger/trust.exp b/tests/declarative_debugger/trust.exp
index 681f64f..4851d18 100644
--- a/tests/declarative_debugger/trust.exp
+++ b/tests/declarative_debugger/trust.exp
@@ -3,23 +3,12 @@ mdb> mdb> mdb> Contexts will not be printed.
mdb> echo on
Command echo enabled.
mdb> trust trust_1.
-Ambiguous predicate or function specification. The matches are:
-0: pred trust_1.w_cmp/3
-1: pred trust_1.lambda_trust_1_m_21/3
-
-Which predicate or function do you want to trust (0-1 or *)? *
Trusting pred trust_1.w_cmp/3
-Trusting pred trust_1.lambda_trust_1_m_21/3
mdb> trusted
Trusted Objects:
1: predicate trust_1.w_cmp/3
-2: predicate trust_1.lambda_trust_1_m_21/3
mdb> untrust 1
mdb> trusted
-Trusted Objects:
-2: predicate trust_1.lambda_trust_1_m_21/3
-mdb> untrust 2
-mdb> trusted
There are no trusted modules, predicates or functions.
mdb> trust trust_2
Trusting module trust_2
@@ -32,15 +21,15 @@ Which predicate or function do you want to trust (0-1 or *)? 0
Trusting pred trust.main/2
mdb> trusted
Trusted Objects:
-3: module trust_2
-4: predicate trust.main/2
+2: module trust_2
+3: predicate trust.main/2
mdb> trust trust_2
Trusting module trust_2
mdb> trusted
Trusted Objects:
-3: module trust_2
-4: predicate trust.main/2
-mdb> untrust 3
+2: module trust_2
+3: predicate trust.main/2
+mdb> untrust 2
mdb> trust trust_1
Trusting module trust_1
mdb> trust no_such_module
@@ -53,22 +42,22 @@ mdb> trust standard library
Trusting the Mercury standard library
mdb> trusted
Trusted Objects:
-4: predicate trust.main/2
-5: module trust_1
-6: predicate trust_2.concat/3
-7: the Mercury standard library
-mdb> untrust 4
+3: predicate trust.main/2
+4: module trust_1
+5: predicate trust_2.concat/3
+6: the Mercury standard library
+mdb> untrust 3
mdb> trusted
Trusted Objects:
-5: module trust_1
-6: predicate trust_2.concat/3
-7: the Mercury standard library
-mdb> untrust 4
+4: module trust_1
+5: predicate trust_2.concat/3
+6: the Mercury standard library
+mdb> untrust 3
mdb: no such trusted object
mdb> untrust 99
mdb: no such trusted object
+mdb> untrust 4
mdb> untrust 5
-mdb> untrust 6
mdb> step
E2: C2 CALL pred trust.dostuff/2-0 (cc_multi)
mdb> finish
@@ -80,8 +69,6 @@ w_cmp('=', w("aaB"), w("aAB"))
Valid? trust
concat(w("aaa"), w("bbb"), w("aaabbb"))
Valid? trust module
-lambda_trust_1_m_21(w("aaB"), w("aAB"), '=')
-Valid? trust module
Found incorrect contour:
w_cmp('=', w("aaB"), w("aAB"))
concat(w("aaa"), w("bbb"), w("aaabbb"))
diff --git a/tests/declarative_debugger/trust.inp b/tests/declarative_debugger/trust.inp
index df8972d..2d6e0e2 100644
--- a/tests/declarative_debugger/trust.inp
+++ b/tests/declarative_debugger/trust.inp
@@ -3,37 +3,33 @@ untrust 0
context none
echo on
trust trust_1.
-*
trusted
untrust 1
trusted
-untrust 2
-trusted
trust trust_2
trust trust.
0
trusted
trust trust_2
trusted
-untrust 3
+untrust 2
trust trust_1
trust no_such_module
trust trust_2.
trust std lib
trust standard library
trusted
-untrust 4
+untrust 3
trusted
-untrust 4
+untrust 3
untrust 99
+untrust 4
untrust 5
-untrust 6
step
finish
dd -d 3 -n 7
n
trust
trust module
-trust module
y
continue
diff --git a/tests/declarative_debugger/trust_1.m b/tests/declarative_debugger/trust_1.m
index 63c429e..0974b6d 100644
--- a/tests/declarative_debugger/trust_1.m
+++ b/tests/declarative_debugger/trust_1.m
@@ -17,14 +17,9 @@
:- implementation.
w_cmp(R, W1, W2) :-
- R = unsafe_promise_unique(
- promise_only_solution(
- ( pred(R1::out) is cc_multi :-
- W1 = w(S1),
- W2 = w(S2),
- compare(R1, to_upper(S1)`with_type`string,
- to_upper(S2))
- )
- )
- ).
-
+ promise_equivalent_solutions [R1] (
+ W1 = w(S1),
+ W2 = w(S2),
+ compare(R1, to_upper(S1) : string, to_upper(S2))
+ ),
+ R = unsafe_promise_unique(R1).
diff --git a/tests/hard_coded/myset.m b/tests/hard_coded/myset.m
index 596c886..3ee63ce 100644
--- a/tests/hard_coded/myset.m
+++ b/tests/hard_coded/myset.m
@@ -52,12 +52,10 @@ set(List) = set_rep(List).
set_to_list(set_rep(List), List).
-set_to_sorted_list(Set) =
- promise_only_solution(
- ( pred(Sorted::out) is cc_multi :-
- Set = set_rep(Unsorted),
- list.sort(Unsorted, Sorted)
- )
+set_to_sorted_list(Set) = Sorted :-
+ promise_equivalent_solutions [Sorted] (
+ Set = set_rep(Unsorted),
+ list.sort(Unsorted, Sorted)
).
{} = set_rep([]).
@@ -65,21 +63,18 @@ set_to_sorted_list(Set) =
{X} = set_rep([X]).
is_empty(Set) :-
- promise_only_solution(
- ( pred(Empty::out) is cc_multi :-
- Set = set_rep(List),
- Empty = (if List = [] then yes else no)
- )
- ) = yes.
-
-Set1 + Set2 =
- promise_only_solution(
- ( pred(Union::out) is cc_multi :-
- Set1 = set_rep(List1),
- Set2 = set_rep(List2),
- list.append(List1, List2, UnionList),
- Union = set_rep(UnionList)
- )
+ promise_equivalent_solutions [Empty] (
+ Set = set_rep(List),
+ Empty = (if List = [] then yes else no)
+ ),
+ Empty = yes.
+
+Set1 + Set2 = Union :-
+ promise_equivalent_solutions [Union] (
+ Set1 = set_rep(List1),
+ Set2 = set_rep(List2),
+ list.append(List1, List2, UnionList),
+ Union = set_rep(UnionList)
).
% [Element | set_rep(Rest)] = set_rep([Element | Rest]).
diff --git a/tests/hard_coded/user_compare.m b/tests/hard_coded/user_compare.m
index fc09718..961f7b4 100644
--- a/tests/hard_coded/user_compare.m
+++ b/tests/hard_coded/user_compare.m
@@ -43,14 +43,11 @@ main(!IO) :-
:- pred compare_foo(comparison_result::uo, foo::in, foo::in) is det.
compare_foo(Res, Foo1, Foo2) :-
- Res1 = promise_only_solution(
- (pred(Res0::uo) is cc_multi :-
- Foo1 = foo(Int1),
- Foo2 = foo(Int2),
- compare(Res0, Int2, Int1)
- )
- ),
- Res = Res1.
+ promise_equivalent_solutions [Res] (
+ Foo1 = foo(Int1),
+ Foo2 = foo(Int2),
+ compare(Res, Int2, Int1)
+ ).
:- type foreign.
:- pragma foreign_type(c, foreign, "int") where
diff --git a/tests/valid_seq/intermod_nested_module_bug2.m b/tests/valid_seq/intermod_nested_module_bug2.m
index c883115..1138fc6 100644
--- a/tests/valid_seq/intermod_nested_module_bug2.m
+++ b/tests/valid_seq/intermod_nested_module_bug2.m
@@ -21,7 +21,9 @@
:- implementation.
get_request(Res, !IO) :-
- Res = promise_only_solution(get_request0).
+ promise_equivalent_solutions [Res] (
+ get_request0(Res)
+ ).
:- pred get_request0(maybe_error(cgi)::out) is cc_multi.
More information about the reviews
mailing list