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