for review: (ugly) work-around for unique mode & lambda problem
Fergus Henderson
fjh at cs.mu.OZ.AU
Sun Feb 15 17:23:03 AEDT 1998
extras/trailed_update/samples/interpreter.m:
extras/trailed_update/samples/interpreter.exp:
Work around a (spurious) unique mode error, which was
caused by the recent changes to make unique mode checking
of higher-order terms and lambda expressions more strict.
The work-around is to avoid the use of the higher-order
pred unsorted_aggregate/4, and instead use impure code (ugh).
In the long term, a better solution would be to add support
for `call-once' higher-order modes.
Index: interpreter.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/extras/trailed_update/samples/interpreter.m,v
retrieving revision 1.3
diff -u -u -r1.3 interpreter.m
--- interpreter.m 1997/10/12 13:39:20 1.3
+++ interpreter.m 1998/02/15 05:59:58
@@ -28,6 +28,7 @@
:- implementation.
:- import_module list, string, term, varset, term_io, require, std_util.
:- import_module store, tr_store, map, multi_map.
+:- import_module unsafe.
main -->
io__write_string("Pure Prolog Interpreter.\n\n"),
@@ -68,11 +69,40 @@
{ store__init(Store0) },
{ map__init(VarMap0) },
{ term_to_my_term(Goal, MyGoal, VarMap0, VarMap, Store0, Store1) },
- unsorted_aggregate(solve(Database, MyGoal, Store1),
- write_solution(VarSet, VarMap, MyGoal)),
- io__write_string("No (more) solutions.\n"),
+ print_solutions(VarSet, VarMap, MyGoal, Store1, Database),
main_loop(Database).
+:- pred print_solutions(varset, map(var, my_var(S)), my_term(S),
+ store(S), database, io__state, io__state).
+:- mode print_solutions(in, in, in, mdi, in, di, uo) is det.
+
+/***
+% Alas, the following code gets a (spurious) unique mode error,
+% because the compiler thinks that `Store0' has inst `ground'
+% rather than `mostly_unique' when it is passed as a curried
+% argument of a higher-order term. The compiler doesn't know
+% that unsorted_aggregate will only call its higher-order argument
+% once per forward execution.
+%
+% Instead, we use the impure code below.
+%
+print_solutions(VarSet, VarMap, MyGoal, Store0, Database) -->
+ unsorted_aggregate(
+ solve(Database, MyGoal, Store0),
+ write_solution(VarSet, VarMap, MyGoal)),
+ io__write_string("No (more) solutions.\n").
+***/
+
+:- pragma promise_pure(print_solutions/7).
+print_solutions(VarSet, VarMap, MyGoal, Store0, Database) -->
+ (
+ { solve(Database, MyGoal, Store0, Store1) },
+ { impure write_solution(VarSet, VarMap, MyGoal, Store1) },
+ { fail }
+ ;
+ io__write_string("No (more) solutions.\n")
+ ).
+
:- pred write_solution(varset, map(var, my_var(S)), my_term(S), store(S),
io__state, io__state).
:- mode write_solution(in, in, in, mdi, di, uo) is det.
@@ -84,6 +114,18 @@
{ my_term_to_term(MyGoal, Goal, VarSet0, VarSet, VarMap0, _VarMap,
Store0, _Store) },
term_io__write_term_nl(VarSet, Goal).
+
+:- impure pred write_solution(varset, map(var, my_var(S)), my_term(S),
+ store(S)).
+:- mode write_solution(in, in, in, mdi) is det.
+
+write_solution(VarSet0, VarToMyVarMap, MyGoal, Store0) :-
+ map__keys(VarToMyVarMap, Vars),
+ map__values(VarToMyVarMap, MyVars),
+ map__from_corresponding_lists(MyVars, Vars, VarMap0),
+ my_term_to_term(MyGoal, Goal, VarSet0, VarSet, VarMap0, _VarMap,
+ Store0, _Store),
+ impure unsafe_perform_io(term_io__write_term_nl(VarSet, Goal)).
%-----------------------------------------------------------------------------%
--
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