For review: making terms polymorphic

Thomas Charles CONWAY conway at cs.mu.OZ.AU
Wed Nov 4 08:55:03 AEDT 1998


Hi

Zoltan, can you please review this?
Given the excessive size (about 20K lines) of the diff, and it's
excuciatingly boring nature, I've made it publicly readable on
	/home/mercury1/conway/DIFF.var

Duplicated in this post are the interesting bits, since they're
more worthy of everyone's attention.

I'm not planning to commit this till the code freeze ends.

Thomas
-- 
Thomas Conway <conway at cs.mu.oz.au> )O+
To a killer whale, otters are like hairy popcorn -- Paul Dayton

These changes make `var' and `term' polymorphic. This allows us to make
variables and terms representing types of a different type to those
representing program terms and those representing insts.

These changes do not *fix* any existing problems (for instance
there was a messy conflation of program variables and inst variables,
and where necessary I've just called varset__init(InstVarSet) with
an XXX comment).

NEWS:
	Mention the changes to the standard library.

library/term.m:
	Make term, var and var_supply polymorphic.
	Add new predicates:
		term__generic_term/1
		term__coerce/2
		term__coerce_var/2
		term__coerce_var_supply/2

library/varset.m:
	Make varset polymorphic.
	Add the new predicate:
		varset__coerce/2

compiler/prog_data.m:
	Introduce type equivalences for the different kinds of
	vars, terms, and varsets that we use (tvar and tvarset
	were already there but have been changed to use the
	polymorphic var and term).

	Also change the various kinds of items to use the appropriate
	kinds of var/varset.

compiler/*.m:
	Thousands of boring changes to make the compiler type correct
	with the different types for type, program and inst vars and
	varsets.

Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.122
diff -u -r1.122 NEWS
--- NEWS	1998/10/20 02:02:29	1.122
+++ NEWS	1998/11/03 21:38:07
@@ -319,6 +319,11 @@
   See the "benchmarking" chapter of the Mercury Library Reference Manual
   for details.
 
+* Term, var, var_supply and varset are now polymorphic. This allows one to
+  distinguish between terms, etc denoting different kinds of things by
+  making them differently typed. The new coercion predicates listed below
+  allow one to coerce terms, etc between types.
+
 * Miscellaneous new predicates.
 
   The Mercury standard library now includes the following new predicates:
@@ -343,6 +348,10 @@
 	  set__count/2
 	  set_ordlist__count/2
 	  store__new_cyclic_mutvar/4
+	  term__coerce/2
+	  term__coerce_var/2
+	  term__coerce_var_supply/2
+	  varset__coerce/2
 	  varset__select/3
 
   In addition, there are four new system constants added to the float
Index: library/io.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/io.m,v
retrieving revision 1.166
diff -u -r1.166 io.m
--- io.m	1998/10/30 05:11:50	1.166
+++ io.m	1998/11/02 05:13:07
@@ -1839,6 +1839,7 @@
 		%
 		{ term__univ_to_term(Univ, Term) },
 		{ varset__init(VarSet) },
+		{ term__generic_term(Term) },
 		term_io__write_term(VarSet, Term)
 	;
 		io__write_ordinary_term(Univ, Priority)
Index: library/parser.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/parser.m,v
retrieving revision 1.30
diff -u -r1.30 parser.m
--- parser.m	1998/05/21 16:52:13	1.30
+++ parser.m	1998/11/02 05:11:16
@@ -41,12 +41,12 @@
 % parser__read_term/{3,4}:
 %	Reads in (and parses) terms from the current input stream.
 
-:- pred parser__read_term(read_term, io__state, io__state).
+:- pred parser__read_term(read_term(T), io__state, io__state).
 :- mode parser__read_term(out, di, uo) is det.
 % parser__read_term(Result):
 %	Reads a term from the current input stream.
 
-:- pred parser__read_term(string, read_term, io__state, io__state).
+:- pred parser__read_term(string, read_term(T), io__state, io__state).
 :- mode parser__read_term(in, out, di, uo) is det.
 % parser__read_term(FileName, Result):
 %	Reads a term from the current input stream.
@@ -69,12 +69,12 @@
 	% specify the length of the string and the position within the
 	% string at which to start parsing.
 
-:- pred parser__read_term_from_string(string, string, posn, read_term).
+:- pred parser__read_term_from_string(string, string, posn, read_term(T)).
 :- mode parser__read_term_from_string(in, in, out, out) is det.
 %	parser__read_term_from_string(FileName, String, EndPos, Term).
 
 :- pred parser__read_term_from_string(string, string, int, posn, posn,
-					read_term).
+					read_term(T)).
 :- mode parser__read_term_from_string(in, in, in, in, out, out) is det.
 %	parser__read_term_from_string(FileName, String, MaxOffset, StartPos,
 %				    EndPos, Term).
@@ -84,7 +84,7 @@
 % parser__parse_tokens/3:
 %	Parses a list of tokens.
 
-:- pred parser__parse_tokens(string, token_list, read_term).
+:- pred parser__parse_tokens(string, token_list, read_term(T)).
 :- mode parser__parse_tokens(in, in, out) is det.
 	% parser__parse_tokens(FileName, TokenList, Result):
 
@@ -133,8 +133,8 @@
 			Tokens, LeftOverTokens, Result)
 	).
 
-:- pred parser__check_for_errors(parse(term), varset, token_list, token_list,
-				 read_term).
+:- pred parser__check_for_errors(parse(term(T)), varset(T),
+		token_list, token_list, read_term(T)).
 :- mode parser__check_for_errors(in, in, in, in, out) is det.
 
 parser__check_for_errors(error(ErrorMessage, ErrorTokens), _VarSet, Tokens,
@@ -204,7 +204,8 @@
 		parser__check_for_bad_token(Tokens, Message, LineNum)
 	).
 
-:- pred parser__parse_whole_term(parse(term), parser__state, parser__state).
+:- pred parser__parse_whole_term(parse(term(T)),
+		parser__state(T), parser__state(T)).
 :- mode parser__parse_whole_term(out, in, out) is det.
 
 parser__parse_whole_term(Term) -->
@@ -222,13 +223,13 @@
 
 
 
-:- pred parser__parse_term(parse(term), parser__state, parser__state).
+:- pred parser__parse_term(parse(term(T)), parser__state(T), parser__state(T)).
 :- mode parser__parse_term(out, in, out) is det.
 
 parser__parse_term(Term) -->
 	parser__parse_term_2(1201, no, Term).
 
-:- pred parser__parse_arg(parse(term), parser__state, parser__state).
+:- pred parser__parse_arg(parse(term(T)), parser__state(T), parser__state(T)).
 :- mode parser__parse_arg(out, in, out) is det.
 
 parser__parse_arg(Term) -->
@@ -240,8 +241,8 @@
 	% The above is because we need bug-for-bug compatibility
 	% with the NU-Prolog parser in order to support e.g. `::' in args.
 
-:- pred parser__parse_term_2(int, bool, parse(term),
-				parser__state, parser__state).
+:- pred parser__parse_term_2(int, bool, parse(term(T)),
+				parser__state(T), parser__state(T)).
 :- mode parser__parse_term_2(in, in, out, in, out) is det.
 
 parser__parse_term_2(MaxPriority, IsArg, Term) -->
@@ -254,8 +255,8 @@
 		{ Term = LeftTerm0 }
 	).
 
-:- pred parser__parse_left_term(int, bool, int, parse(term),
-				parser__state, parser__state).
+:- pred parser__parse_left_term(int, bool, int, parse(term(T)),
+				parser__state(T), parser__state(T)).
 :- mode parser__parse_left_term(in, in, out, out, in, out) is det.
 
 parser__parse_left_term(MaxPriority, IsArg, OpPriority, Term) -->
@@ -349,8 +350,8 @@
 		{ OpPriority = 0 }
 	).
 
-:- pred parser__parse_rest(int, bool, int, term, parse(term),
-				parser__state, parser__state).
+:- pred parser__parse_rest(int, bool, int, term(T), parse(term(T)),
+				parser__state(T), parser__state(T)).
 :- mode parser__parse_rest(in, in, in, in, out, in, out) is det.
 
 parser__parse_rest(MaxPriority, IsArg, LeftPriority, LeftTerm, Term) -->
@@ -399,8 +400,8 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred parser__parse_simple_term(token, token_context, int, parse(term),
-				parser__state, parser__state).
+:- pred parser__parse_simple_term(token, token_context, int, parse(term(T)),
+				parser__state(T), parser__state(T)).
 :- mode parser__parse_simple_term(in, in, in, out, in, out) is det.
 
 parser__parse_simple_term(Token, Context, Priority, Term) -->
@@ -423,8 +424,8 @@
 	% term --> variable		% priority 0
 	% term -->
 
-:- pred parser__parse_simple_term_2(token, token_context, int, parse(term),
-				parser__state, parser__state).
+:- pred parser__parse_simple_term_2(token, token_context, int, parse(term(T)),
+				parser__state(T), parser__state(T)).
 :- mode parser__parse_simple_term_2(in, in, in, out, in, out) is semidet.
 
 parser__parse_simple_term_2(name(Atom), Context, Prec, Term) -->
@@ -529,7 +530,7 @@
 		)
 	).
 
-:- pred parser__parse_list(parse(term), parser__state, parser__state).
+:- pred parser__parse_list(parse(term(T)), parser__state(T), parser__state(T)).
 :- mode parser__parse_list(out, in, out) is det.
 
 parser__parse_list(List) -->
@@ -578,7 +579,8 @@
 	    { List = Arg0 }
 	).
 
-:- pred parser__parse_args(parse(list(term)), parser__state, parser__state).
+:- pred parser__parse_args(parse(list(term(T))),
+		parser__state(T), parser__state(T)).
 :- mode parser__parse_args(out, in, out) is det.
 
 parser__parse_args(List) -->
@@ -613,14 +615,15 @@
 
 	% Routines that manipulate the parser state.
 
-:- type parser__state
+:- type parser__state(T)
 	--->	parser__state(
 			string,		% the name of the stream being parsed
 			ops__table,	% the current set of operators
-			varset,		% the names of the variables in the
+			varset(T),	% the names of the variables in the
 					% term being parsed
 			token_list,	% the remaining tokens
-			map(string, var)% a map from variable name to variable
+			map(string, var(T))
+					% a map from variable name to variable
 					% so we know when to make a fresh var
 		).
 
@@ -633,7 +636,7 @@
 	% it was some other sort of error, so issue the usual
 	% error message.
 
-:- pred parser__unexpected(string, parse(T), parser__state, parser__state).
+:- pred parser__unexpected(string, parse(U), parser__state(T), parser__state(T)).
 :- mode parser__unexpected(in, out, in, out) is det.
 
 parser__unexpected(UsualMessage, Error) -->
@@ -643,8 +646,8 @@
 		parser__error(UsualMessage, Error)
 	).
 
-:- pred parser__unexpected_tok(token, token_context, string, parse(T),
-				parser__state, parser__state).
+:- pred parser__unexpected_tok(token, token_context, string, parse(U),
+				parser__state(T), parser__state(T)).
 :- mode parser__unexpected_tok(in, in, in, out, in, out) is det.
 
 parser__unexpected_tok(Token, Context, UsualMessage, Error) -->
@@ -667,7 +670,7 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred parser__error(string, parse(T), parser__state, parser__state).
+:- pred parser__error(string, parse(U), parser__state(T), parser__state(T)).
 :- mode parser__error(in, out, in, out) is det.
 
 parser__error(Message, error(Message, Tokens), ParserState, ParserState) :-
@@ -700,7 +703,7 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred parser__init_state(string, token_list, parser__state).
+:- pred parser__init_state(string, token_list, parser__state(T)).
 :- mode parser__init_state(in, in, out) is det.
 
 parser__init_state(FileName, Tokens, ParserState) :-
@@ -709,7 +712,7 @@
 	map__init(Names),
 	ParserState = parser__state(FileName, OpTable, VarSet, Tokens, Names).
 
-:- pred parser__final_state(parser__state, varset, token_list).
+:- pred parser__final_state(parser__state(T), varset(T), token_list).
 :- mode parser__final_state(in, out, out) is det.
 
 parser__final_state(parser__state(_FileName, _OpTable, VarSet, TokenList,
@@ -717,13 +720,14 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred parser__get_token(token, parser__state, parser__state).
+:- pred parser__get_token(token, parser__state(T), parser__state(T)).
 :- mode parser__get_token(out, in, out) is semidet.
 
 parser__get_token(Token) -->
 	parser__get_token(Token, _Context).
 
-:- pred parser__get_token(token, token_context, parser__state, parser__state).
+:- pred parser__get_token(token, token_context,
+		parser__state(T), parser__state(T)).
 :- mode parser__get_token(out, out, in, out) is semidet.
 :- mode parser__get_token(in, in, out, in) is det.
 
@@ -732,20 +736,22 @@
 		parser__state(FileName, OpTable, VarSet, Tokens, Names)) :-
 	Tokens0 = token_cons(Token, Context, Tokens).
 
-:- pred parser__unget_token(token, token_context, parser__state, parser__state).
+:- pred parser__unget_token(token, token_context,
+		parser__state(T), parser__state(T)).
 :- mode parser__unget_token(in, in, in, out) is det.
 :- mode parser__unget_token(out, out, out, in) is semidet.
 
 parser__unget_token(Token, Context, ParseState0, ParseState) :-
 	parser__get_token(Token, Context, ParseState, ParseState0).
 
-:- pred parser__peek_token(token, parser__state, parser__state).
+:- pred parser__peek_token(token, parser__state(T), parser__state(T)).
 :- mode parser__peek_token(out, in, out) is semidet.
 
 parser__peek_token(Token) -->
 	parser__peek_token(Token, _Context).
 
-:- pred parser__peek_token(token, token_context, parser__state, parser__state).
+:- pred parser__peek_token(token, token_context,
+		parser__state(T), parser__state(T)).
 :- mode parser__peek_token(out, out, in, out) is semidet.
 
 parser__peek_token(Token, Context) -->
@@ -754,7 +760,7 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred parser__add_var(string, var, parser__state, parser__state).
+:- pred parser__add_var(string, var(T), parser__state(T), parser__state(T)).
 :- mode parser__add_var(in, out, in, out) is det.
 
 parser__add_var(VarName, Var,
@@ -772,7 +778,7 @@
 		map__det_insert(Names0, VarName, Var, Names)
 	).
 
-:- pred parser__get_ops_table(ops__table, parser__state, parser__state).
+:- pred parser__get_ops_table(ops__table, parser__state(T), parser__state(T)).
 :- mode parser__get_ops_table(out, in, out) is det.
 
 parser__get_ops_table(OpTable) -->
@@ -797,7 +803,7 @@
 	Priority < MaxPriority.
 
 :- pred parser__get_term_context(token_context, term__context,
-				parser__state, parser__state).
+				parser__state(T), parser__state(T)).
 :- mode parser__get_term_context(in, out, in, out) is det.
 
 parser__get_term_context(TokenContext, TermContext) -->
Index: library/term.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/term.m,v
retrieving revision 1.86
diff -u -r1.86 term.m
--- term.m	1998/10/02 20:14:52	1.86
+++ term.m	1998/11/03 21:44:56
@@ -10,6 +10,8 @@
 
 % This file provides a type `term' used to represent Prolog terms,
 % and various predicates to manipulate terms and substitutions.
+% Terms are polymorphic so that terms representing different kinds of
+% thing can be made to be of different types so they don't get mixed up.
 
 %-----------------------------------------------------------------------------%
 
@@ -19,8 +21,9 @@
 
 %-----------------------------------------------------------------------------%
 
-:- type term		--->	term__functor(const, list(term), term__context)
-			;	term__variable(var).
+:- type term(T)		--->	term__functor(const, list(term(T)),
+					term__context)
+			;	term__variable(var(T)).
 :- type const		--->	term__atom(string)
 			;	term__integer(int)
 			;	term__string(string)
@@ -29,19 +32,27 @@
 :- type term__context   --->    term__context(string, int).
 				% file name, line number.
 
-:- type var.
-:- type var_supply.
+:- type var(T).
+:- type var_supply(T).
+
+:- type generic
+	--->	generic.
+
+:- type term	==	term(generic).
+:- type var	==	var(generic).
 
 %-----------------------------------------------------------------------------%
 
 	% The following predicates can convert values of (almost)
 	% any type to the type `term' and back again.
 
-:- type term_to_type_result(T)
+:- type term_to_type_result(T, U)
 	--->	ok(T)
-	;	error(term_to_type_error).
+	;	error(term_to_type_error(U)).
 
-:- pred term__try_term_to_type(term, term_to_type_result(T)).
+:- type term_to_type_result(T) == term_to_type_result(T, generic).
+
+:- pred term__try_term_to_type(term(U), term_to_type_result(T, U)).
 :- mode term__try_term_to_type(in, out) is det.
 	% term__try_term_to_type(Term, Result):
 	% Try to convert the given term to a ground value of type T.
@@ -57,10 +68,10 @@
 	% ArgContexts specifies the path from the root of the term
 	% to the offending subterm.
 
-:- type term_to_type_error
-	--->	type_error(term, type_info, term__context,
+:- type term_to_type_error(T)
+	--->	type_error(term(T), type_info, term__context,
 			term_to_type_context)
-	;	mode_error(var, term_to_type_context).
+	;	mode_error(var(T), term_to_type_context).
 
 :- type term_to_type_context == list(term_to_type_arg_context).
 
@@ -71,75 +82,77 @@
 			term__context	% filename & line number
 		).
 
-:- pred term__term_to_type(term, T).
+:- pred term__term_to_type(term(U), T).
 :- mode term__term_to_type(in, out) is semidet.
 	% term_to_type(Term, Type) :- try_term_to_type(Term, ok(Type)).
 
-:- pred term__det_term_to_type(term, T).
+:- pred term__det_term_to_type(term(_), T).
 :- mode term__det_term_to_type(in, out) is det.
 	% like term_to_type, but calls error/1 rather than failing.
 
-:- pred term__type_to_term(T, term).
+:- pred term__type_to_term(T, term(_)).
 :- mode term__type_to_term(in, out) is det.
 	% converts a value to a term representation of that value
 
-:- pred term__univ_to_term(univ, term).
+:- pred term__univ_to_term(univ, term(_)).
 :- mode term__univ_to_term(in, out) is det.
 	% calls term__type_to_term on the value stored in the univ
 	% (as distinct from the univ itself).
 
 %-----------------------------------------------------------------------------%
 
-:- pred term__vars(term, list(var)).
+:- pred term__vars(term(T), list(var(T))).
 :- mode term__vars(in, out) is det.
 %	term__vars(Term, Vars)
 %		Vars is the list of variables contained in Term, in the order 
 %		obtained by traversing the term depth first, left-to-right.
 
-:- pred term__vars_2(term, list(var), list(var)).
+:- pred term__vars_2(term(T), list(var(T)), list(var(T))).
 :- mode term__vars_2(in, in, out) is det.
 %		As above, but with an accumulator.
 
-:- pred term__vars_list(list(term), list(var)).
+:- pred term__vars_list(list(term(T)), list(var(T))).
 :- mode term__vars_list(in, out) is det.
 %	term__vars_list(TermList, Vars)
 %		Vars is the list of variables contained in TermList, in the
 %		order obtained by traversing the list of terms depth-first,
 %		left-to-right.
 
-:- pred term__contains_var(term, var).
+:- pred term__contains_var(term(T), var(T)).
 :- mode term__contains_var(in, in) is semidet.
 :- mode term__contains_var(in, out) is nondet.
 %	term__contains_var(Term, Var)
 %		True if Term contains Var. (On backtracking returns all the 
 %		variables contained in Term.)
 
-:- pred term__contains_var_list(list(term), var).
+:- pred term__contains_var_list(list(term(T)), var(T)).
 :- mode term__contains_var_list(in, in) is semidet.
 :- mode term__contains_var_list(in, out) is nondet.
 %	term__contains_var_list(TermList, Var)
 %		True if TermList contains Var. (On backtracking returns all the 
 %		variables contained in Term.)
 
-:- type substitution == map(var, term).
+:- type substitution(T) == map(var(T), term(T)).
+:- type substitution	== substitution(generic).
 
-:- pred term__unify(term, term, substitution, substitution).
+:- pred term__unify(term(T), term(T), substitution(T), substitution(T)).
 :- mode term__unify(in, in, in, out) is semidet.
 %	term__unify(Term1, Term2, Bindings0, Bindings)
 %		unify (with occur check) two terms with respect to a set
 %	 	of bindings and possibly update the set of bindings
 
-:- pred term__substitute(term, var, term, term).
+:- pred term__substitute(term(T), var(T), term(T), term(T)).
 :- mode term__substitute(in, in, in, out) is det.
 %	term__substitute(Term0, Var, Replacement, Term) :
 %		replace all occurrences of Var in Term0 with Replacement,
 %		and return the result in Term.
 
-:- pred term__substitute_list(list(term), var, term, list(term)).
+:- pred term__substitute_list(list(term(T)), var(T), term(T), list(term(T))).
 :- mode term__substitute_list(in, in, in, out) is det.
 %		as above, except for a list of terms rather than a single term
 
-:- pred term__substitute_corresponding(list(var), list(term), term, term).
+:- pred term__substitute_corresponding(list(var(T)), list(term(T)),
+		term(T), term(T)).
 :- mode term__substitute_corresponding(in, in, in, out) is det.
 %       term__substitute_corresponding(Vars, Repls, Term0, Term).
 %		replace all occurrences of variables in Vars with
@@ -148,75 +161,75 @@
 %	        length as Repls, the behaviour is undefined and probably
 %		harmful.
 
-:- pred term__substitute_corresponding_list(list(var), list(term), list(term),
-						list(term)).
+:- pred term__substitute_corresponding_list(list(var(T)), list(term(T)),
+		list(term(T)), list(term(T))).
 :- mode term__substitute_corresponding_list(in, in, in, out) is det.
 %       term__substitute_corresponding_list(Vars, Repls, TermList0, TermList).
 %		As above, except applies to a list of terms rather than a
 %		single term.
 
-:- pred term__apply_rec_substitution(term, substitution, term).
+:- pred term__apply_rec_substitution(term(T), substitution(T), term(T)).
 :- mode term__apply_rec_substitution(in, in, out) is det.
 %	term__apply_rec_substitution(Term0, Substitution, Term) :
 %		recursively apply substitution to Term0 until
 %		no more substitions can be applied, and then
 %		return the result in Term.
 
-:- pred term__apply_rec_substitution_to_list(list(term), substitution,
-						list(term)).
+:- pred term__apply_rec_substitution_to_list(list(term(T)), substitution(T),
+						list(term(T))).
 :- mode term__apply_rec_substitution_to_list(in, in, out) is det.
 
-:- pred term__apply_substitution(term, substitution, term).
+:- pred term__apply_substitution(term(T), substitution(T), term(T)).
 :- mode term__apply_substitution(in, in, out) is det.
 %	term__apply_substitution(Term0, Substitution, Term) :
 %		apply substitution to Term0 and return the result in Term.
 
-:- pred term__apply_substitution_to_list(list(term), substitution,
-						list(term)).
+:- pred term__apply_substitution_to_list(list(term(T)), substitution(T),
+						list(term(T))).
 :- mode term__apply_substitution_to_list(in, in, out) is det.
 %	term__apply_substitution_to_list(TermList0, Substitution, TermList) :
 %		as above, except for a list of terms rather than a single term
 
 
-:- pred term__occurs(term, var, substitution).
+:- pred term__occurs(term(T), var(T), substitution(T)).
 :- mode term__occurs(in, in, in) is semidet.
 %	term__occurs(Term0, Var, Substitution) :
 %		true iff Var occurs in the term resulting after
 %		applying Substitution to Term0.
 
-:- pred term__occurs_list(list(term), var, substitution).
+:- pred term__occurs_list(list(term(T)), var(T), substitution(T)).
 :- mode term__occurs_list(in, in, in) is semidet.
 %		as above, except for a list of terms rather than a single term
 
-:- pred term__relabel_variable(term, var, var, term).
+:- pred term__relabel_variable(term(T), var(T), var(T), term(T)).
 :- mode term__relabel_variable(in, in, in, out) is det.
 %	term__relabel_variable(Term0, OldVar, NewVar, Term) :
 %		replace all occurences of OldVar in Term0 with
 %		NewVar and put the result in Term.
 
-:- pred term__relabel_variables(list(term), var, var, list(term)).
+:- pred term__relabel_variables(list(term(T)), var(T), var(T), list(term(T))).
 :- mode term__relabel_variables(in, in, in, out) is det.
 %	term__relabel_variables(Terms0, OldVar, NewVar, Terms) :
 %		same as term__relabel_variable but for a list of terms.
 
-:- pred term__apply_variable_renaming(term, map(var, var), term).
+:- pred term__apply_variable_renaming(term(T), map(var(T), var(T)), term(T)).
 :- mode term__apply_variable_renaming(in, in, out) is det.
 % 		same as term__relabel_variable, except relabels
 % 		multiple variables. If a variable is not in the
 % 		map, it is not replaced.
 
-:- pred term__apply_variable_renaming_to_list(list(term), map(var, var),
-							 list(term)).
+:- pred term__apply_variable_renaming_to_list(list(term(T)),
+		map(var(T), var(T)), list(term(T))).
 :- mode term__apply_variable_renaming_to_list(in, in, out) is det.
 %		applies term__apply_variable_renaming to a list of terms.
 		
 
-:- pred term__is_ground(term, substitution).
+:- pred term__is_ground(term(T), substitution(T)).
 :- mode term__is_ground(in, in) is semidet.
 %	term__is_ground(Term, Bindings) is true iff no variables contained
 %		in Term are non-ground in Bindings.
 
-:- pred term__is_ground(term).
+:- pred term__is_ground(term(T)).
 :- mode term__is_ground(in) is semidet.
 %	term__is_ground(Term) is true iff Term contains no variables.
 
@@ -225,19 +238,19 @@
 	% To manage a supply of variables, use the following 2 predicates.
 	% (We might want to give these a unique mode later.)
 
-:- pred term__init_var_supply(var_supply).
+:- pred term__init_var_supply(var_supply(T)).
 :- mode term__init_var_supply(out) is det.
 :- mode term__init_var_supply(in) is semidet. % implied
 %	term__init_var_supply(VarSupply) :
 %		returns a fresh var_supply for producing fresh variables.
 
-:- pred term__create_var(var_supply, var, var_supply).
+:- pred term__create_var(var_supply(T), var(T), var_supply(T)).
 :- mode term__create_var(in, out, out) is det.
 %	term__create_var(VarSupply0, Variable, VarSupply) :
 %		create a fresh variable (var) and return the
 %		updated var_supply.
 
-:- pred term__var_to_int(var, int).
+:- pred term__var_to_int(var(T), int).
 :- mode term__var_to_int(in, out) is det.
 %		Convert a variable to an int.
 %		Different variables map to different ints.
@@ -268,18 +281,38 @@
 	% of vars.  Abort (call error/1) if the list contains
 	% any non-variables.
 
-:- pred term__term_list_to_var_list(list(term), list(var)).
+:- pred term__term_list_to_var_list(list(term(T)), list(var(T))).
 :- mode term__term_list_to_var_list(in, out) is det.
 
 	% Convert a list of terms which are all vars into a list
 	% of vars (or vice versa).
 
-:- pred term__var_list_to_term_list(list(var), list(term)).
+:- pred term__var_list_to_term_list(list(var(T)), list(term(T))).
 :- mode term__var_list_to_term_list(in, out) is det.
 :- mode term__var_list_to_term_list(out, in) is semidet.
 
 %-----------------------------------------------------------------------------%
 
+	% In the absence of type qualifiers, this predicate is useful for
+	% avoiding unbound type variables.
+
+:- pred term__generic_term(term).
+:- mode term__generic_term(in) is det.
+
+	% Coerce a term of type `T' into a term of type `U'.
+:- pred term__coerce(term(T), term(U)).
+:- mode term__coerce(in, out) is det.
+
+	% Coerce a var of type `T' into a var of type `U'.
+:- pred term__coerce_var(var(T), var(U)).
+:- mode term__coerce_var(in, out) is det.
+
+	% Coerce a var_supply of type `T' into a var_supply of type `U'.
+:- pred term__coerce_var_supply(var_supply(T), var_supply(U)).
+:- mode term__coerce_var_supply(in, out) is det.
+
+%-----------------------------------------------------------------------------%
+
 :- implementation.
 
 % Everything below here is not intended to be part of the public interface,
@@ -292,7 +325,7 @@
 	% This predidicate is being phased out, because of the problem
 	% mentioned in the "BEWARE:" below.
 :- pragma obsolete(term__compare/4).
-:- pred term__compare(comparison_result, term, term, substitution).
+:- pred term__compare(comparison_result, term(T), term(T), substitution(T)).
 :- mode term__compare(out, in, in, in) is semidet.
 %	term__compare(Comparison, Term1, Term2, Bindings) is true iff
 %		there is a binding of Comparison to <, =, or > such
@@ -311,8 +344,10 @@
 
 %-----------------------------------------------------------------------------%
 
-:- type var_supply	==	int.
-:- type var		==	int.
+:- type var_supply(T)
+	--->	var_supply(int).
+:- type var(T)
+	--->	var(int).
 
 %-----------------------------------------------------------------------------%
 
@@ -331,15 +366,15 @@
 		Result = error(Error)
 	).
 
-:- pred term__try_term_to_univ(term::in, type_info::in,
-		term_to_type_result(univ)::out) is det.
+:- pred term__try_term_to_univ(term(T)::in, type_info::in,
+		term_to_type_result(univ, T)::out) is det.
 
 term__try_term_to_univ(Term, Type, Result) :-
 	term__try_term_to_univ_2(Term, Type, [], Result).
 	
-:- pred term__try_term_to_univ_2(term::in, type_info::in,
+:- pred term__try_term_to_univ_2(term(T)::in, type_info::in,
 		term_to_type_context::in,
-		term_to_type_result(univ)::out) is det.
+		term_to_type_result(univ, T)::out) is det.
 
 term__try_term_to_univ_2(term__variable(Var), _Type, Context,
 		error(mode_error(Var, Context))).
@@ -380,9 +415,9 @@
 
 :- pred term__term_to_univ_special_case(string::in, string::in, 
 		list(type_info)::in, 
-		term::in(bound(term__functor(ground, ground, ground))),
+		term(T)::in(bound(term__functor(ground, ground, ground))),
 		type_info::in, term_to_type_context::in,
-		term_to_type_result(univ)::out) is semidet.
+		term_to_type_result(univ, T)::out) is semidet.
 /*
 ** XXX the following clauses for mercury_builtin:* are
 ** for bootstrapping only, and should eventually be deleted
@@ -479,9 +514,9 @@
 :- pred same_type(T::unused, T::unused) is det.
 same_type(_, _).
 
-:- pred term__term_list_to_univ_list(list(term)::in, list(type_info)::in,
+:- pred term__term_list_to_univ_list(list(term(T))::in, list(type_info)::in,
 		term__const::in, int::in, term_to_type_context::in,
-		term__context::in, term_to_type_result(list(univ))::out)
+		term__context::in, term_to_type_result(list(univ), T)::out)
 		is semidet.
 term__term_list_to_univ_list([], [], _, _, _, _, ok([])).
 term__term_list_to_univ_list([ArgTerm|ArgTerms], [Type|Types],
@@ -617,7 +652,7 @@
 
 :- pred term__univ_to_term_special_case(string::in, string::in, 
 		list(type_info)::in, univ::in, term__context::in,
-		term::out) is semidet.
+		term(T)::out) is semidet.
 
 /*
 ** XXX the following clauses for mercury_builtin:* are
@@ -693,7 +728,7 @@
 	term__univ_to_term(ListUniv, ArgsTerm).
 
 :- pred term__univ_list_to_term_list(list(univ)::in,
-				list(term)::out) is det.
+				list(term(T))::out) is det.
 
 term__univ_list_to_term_list([], []).
 term__univ_list_to_term_list([Value|Values], [Term|Terms]) :-
@@ -701,7 +736,8 @@
 	term__univ_list_to_term_list(Values, Terms).
 
 % given a type_info, return a term that represents the name of that type.
-:- pred type_info_to_term(term__context::in, type_info::in, term::out) is det.
+:- pred type_info_to_term(term__context::in, type_info::in,
+		term(T)::out) is det.
 type_info_to_term(Context, TypeInfo, Term) :-
 	type_ctor_and_args(TypeInfo, TypeCtor, ArgTypes),
 	TypeName = type_ctor_name(TypeCtor),
@@ -746,7 +782,7 @@
 term__vars_2(term__functor(_,Args,_), Vs0, Vs) :-
 	term__vars_2_list(Args, Vs0, Vs).
 
-:- pred term__vars_2_list(list(term), list(var), list(var)).
+:- pred term__vars_2_list(list(term(T)), list(var(T)), list(var(T))).
 :- mode term__vars_2_list(in, in, out) is det.
 
 term__vars_2_list([], Vs, Vs).
@@ -774,7 +810,7 @@
 	%
 	% CURRENTLY NOT USED.
 
-:- pred term__contains_functor(term, const, list(term)).
+:- pred term__contains_functor(term(T), const, list(term(T))).
 % :- mode term__contains_functor(in, in, in) is semidet.
 :- mode term__contains_functor(in, out, out) is nondet.
 
@@ -790,7 +826,7 @@
 	%
 	% CURRENTLY NOT USED.
 
-:- pred term__subterm(term, term).
+:- pred term__subterm(term(T), term(T)).
 :- mode term__subterm(in, in) is semidet.
 :- mode term__subterm(in, out) is multidet.
 
@@ -898,7 +934,8 @@
 term__unify(term__functor(F, AsX, _), term__functor(F, AsY, _)) -->
 	term__unify_list(AsX, AsY).
 
-:- pred term__unify_list(list(term), list(term), substitution, substitution).
+:- pred term__unify_list(list(term(T)), list(term(T)),
+		substitution(T), substitution(T)).
 :- mode term__unify_list(in, in, in, out) is semidet.
 
 term__unify_list([], []) --> [].
@@ -974,8 +1011,8 @@
 		)
 	).
 
-:- pred term__substitute_corresponding_2(list(var), list(term),
-					substitution, substitution).
+:- pred term__substitute_corresponding_2(list(var(T)), list(term(T)),
+					substitution(T), substitution(T)).
 :- mode term__substitute_corresponding_2(in, in, in, out) is semidet.
 
 term__substitute_corresponding_2([], [], Subst, Subst).
@@ -1029,16 +1066,16 @@
 %-----------------------------------------------------------------------------%
 
 	% create a new supply of variables
-term__init_var_supply(0).
+term__init_var_supply(var_supply(0)).
 
 	% We number variables using sequential numbers,
 
-term__create_var(VarSupply0, VarSupply, VarSupply) :-
-	VarSupply is VarSupply0 + 1.
+term__create_var(var_supply(V0), var(V), var_supply(V)) :-
+	V is V0 + 1.
 
 %-----------------------------------------------------------------------------%
 
-term__var_to_int(Var, Var).
+term__var_to_int(var(Var), Var).
 
 %-----------------------------------------------------------------------------%
 
@@ -1105,7 +1142,7 @@
 term__is_ground(term__functor(_, Args, _), Bindings) :-
 	term__is_ground_2(Args, Bindings).
 
-:- pred term__is_ground_2(list(term), substitution).
+:- pred term__is_ground_2(list(term(T)), substitution(T)).
 :- mode term__is_ground_2(in, in) is semidet.
 
 term__is_ground_2([], _Bindings).
@@ -1118,7 +1155,7 @@
 term__is_ground(term__functor(_, Args, _)) :-
 	term__is_ground_2(Args).
 
-:- pred term__is_ground_2(list(term)).
+:- pred term__is_ground_2(list(term(T))).
 :- mode term__is_ground_2(in) is semidet.
 
 term__is_ground_2([]).
@@ -1136,4 +1173,17 @@
 	compare(Cmp, TermA, TermB).
 
 %-----------------------------------------------------------------------------%
+
+term__generic_term(_).
+
+%-----------------------------------------------------------------------------%
+
+term__coerce(term__variable(var(V)), term__variable(var(V))).
+term__coerce(term__functor(Cons, Args0, Ctxt),
+		term__functor(Cons, Args, Ctxt)) :-
+	list__map(term__coerce, Args0, Args).
+
+term__coerce_var(var(V), var(V)).
+
+term__coerce_var_supply(var_supply(Supply), var_supply(Supply)).
 
Index: library/term_io.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/term_io.m,v
retrieving revision 1.53
diff -u -r1.53 term_io.m
--- term_io.m	1998/03/03 17:26:09	1.53
+++ term_io.m	1998/11/02 05:11:50
@@ -35,8 +35,11 @@
 %		Does not modify the io__state.
 *****/
 
-:- type read_term ---> eof ; error(string, int) ; term(varset, term).
-:- pred term_io__read_term(read_term, io__state, io__state).
+:- type read_term(T) ---> eof ; error(string, int) ; term(varset(T), term(T)).
+
+:- type read_term	== read_term(generic).
+
+:- pred term_io__read_term(read_term(T), io__state, io__state).
 :- mode term_io__read_term(out, di, uo) is det.
 
 %	term_io__read_term(Result, IO0, IO1).
@@ -45,11 +48,11 @@
 %		representation. Binds Result to either `eof',
 %		`term(VarSet, Term)', or `error(Message, LineNumber)'.
 
-:- pred term_io__write_term(varset, term, io__state, io__state).
+:- pred term_io__write_term(varset(T), term(T), io__state, io__state).
 :- mode term_io__write_term(in, in, di, uo) is det.
 %		Writes a term to standard output.
 
-:- pred term_io__write_term_nl(varset, term, io__state, io__state).
+:- pred term_io__write_term_nl(varset(T), term(T), io__state, io__state).
 :- mode term_io__write_term_nl(in, in, di, uo) is det.
 %		As above, except it appends a period and new-line.
 
@@ -57,7 +60,7 @@
 :- mode term_io__write_constant(in, di, uo) is det.
 %		Writes a constant (integer, float, or atom) to stdout.
 
-:- pred term_io__write_variable(var, varset, io__state, io__state).
+:- pred term_io__write_variable(var(T), varset(T), io__state, io__state).
 :- mode term_io__write_variable(in, in, di, uo) is det.
 %		Writes a variable to stdout.
 
@@ -114,7 +117,7 @@
 term_io__write_variable(Variable, VarSet) -->
 	term_io__write_variable_2(Variable, VarSet, 0, _, _).
 
-:- pred term_io__write_variable_2(var, varset, int, varset, int,
+:- pred term_io__write_variable_2(var(T), varset(T), int, varset(T), int,
 				io__state, io__state).
 :- mode term_io__write_variable_2(in, in, in, out, out, di, uo) is det.
 
@@ -148,7 +151,7 @@
 term_io__write_term(VarSet, Term) -->
 	term_io__write_term_2(Term, VarSet, 0, _, _).
 
-:- pred term_io__write_term_2(term, varset, int, varset, int,
+:- pred term_io__write_term_2(term(T), varset(T), int, varset(T), int,
 				io__state, io__state).
 :- mode term_io__write_term_2(in, in, in, out, out, di, uo) is det.
 
@@ -156,8 +159,8 @@
 	{ ops__max_priority(MaxPriority) },
 	term_io__write_term_3(Term, MaxPriority + 1, VarSet0, N0, VarSet, N).
 
-:- pred term_io__write_term_3(term, ops__priority, varset, int, varset, int,
-				io__state, io__state).
+:- pred term_io__write_term_3(term(T), ops__priority, varset(T), int, varset(T),
+		int, io__state, io__state).
 :- mode term_io__write_term_3(in, in, in, in, out, out, di, uo) is det.
 
 term_io__write_term_3(term__variable(Id), _, VarSet0, N0, VarSet, N) -->
@@ -307,7 +310,7 @@
 adjust_priority(Priority, y, Priority).
 adjust_priority(Priority, x, Priority - 1).
 
-:- pred term_io__write_list_tail(term, varset, int, varset, int,
+:- pred term_io__write_list_tail(term(T), varset(T), int, varset(T), int,
 				io__state, io__state).
 :- mode term_io__write_list_tail(in, in, in, out, out, di, uo) is det.
 
@@ -335,7 +338,7 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred term_io__write_term_args(list(term), varset, int, varset, int,
+:- pred term_io__write_term_args(list(term(T)), varset(T), int, varset(T), int,
 				io__state, io__state).
 :- mode term_io__write_term_args(in, in, in, out, out, di, uo) is det.
 
Index: library/varset.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/library/varset.m,v
retrieving revision 1.59
diff -u -r1.59 varset.m
--- varset.m	1998/06/23 05:43:13	1.59
+++ varset.m	1998/11/03 03:29:54
@@ -30,74 +30,76 @@
 :- interface.
 :- import_module term, list, map, set, assoc_list.
 
-:- type varset.
+:- type varset(T).
+
+:- type varset	==	varset(generic).
 
 	% construct an empty varset.
-:- pred varset__init(varset).
+:- pred varset__init(varset(T)).
 :- mode varset__init(out) is det.
 
 	% check whether a varset is empty.
-:- pred varset__is_empty(varset).
+:- pred varset__is_empty(varset(T)).
 :- mode varset__is_empty(in) is semidet.
 
 	% create a new variable
-:- pred varset__new_var(varset, var, varset).
+:- pred varset__new_var(varset(T), var(T), varset(T)).
 :- mode varset__new_var(in, out, out) is det.
 
 	% create a new named variable
-:- pred varset__new_named_var(varset, string, var, varset).
+:- pred varset__new_named_var(varset(T), string, var(T), varset(T)).
 :- mode varset__new_named_var(in, in, out, out) is det.
 
 	% create multiple new variables
-:- pred varset__new_vars(varset, int, list(var), varset).
+:- pred varset__new_vars(varset(T), int, list(var(T)), varset(T)).
 :- mode varset__new_vars(in, in, out, out) is det.
 
 	% delete the name and value for a variable
-:- pred varset__delete_var(varset, var, varset).
+:- pred varset__delete_var(varset(T), var(T), varset(T)).
 :- mode varset__delete_var(in, in, out) is det.
 
 	% delete the names and values for a list of variables
-:- pred varset__delete_vars(varset, list(var), varset).
+:- pred varset__delete_vars(varset(T), list(var(T)), varset(T)).
 :- mode varset__delete_vars(in, in, out) is det.
 
 	% return a list of all the variables in a varset
-:- pred varset__vars(varset, list(var)).
+:- pred varset__vars(varset(T), list(var(T))).
 :- mode varset__vars(in, out) is det.
 
 	% set the name of a variable
-:- pred varset__name_var(varset, var, string, varset).
+:- pred varset__name_var(varset(T), var(T), string, varset(T)).
 :- mode varset__name_var(in, in, in, out) is det.
 
 	% lookup the name of a variable;
 	% create one if it doesn't have one using V_ as a prefix
-:- pred varset__lookup_name(varset, var, string).
+:- pred varset__lookup_name(varset(T), var(T), string).
 :- mode varset__lookup_name(in, in, out) is det.
 
 	% lookup the name of a variable;
 	% create one if it doesn't have one using the specified prefix
-:- pred varset__lookup_name(varset, var, string, string).
+:- pred varset__lookup_name(varset(T), var(T), string, string).
 :- mode varset__lookup_name(in, in, in, out) is det.
 
 	% lookup the name of a variable;
 	% fail if it doesn't have one
-:- pred varset__search_name(varset, var, string).
+:- pred varset__search_name(varset(T), var(T), string).
 :- mode varset__search_name(in, in, out) is semidet.
 
 	% bind a value to a variable
 	% (will overwrite any existing binding).
-:- pred varset__bind_var(varset, var, term, varset).
+:- pred varset__bind_var(varset(T), var(T), term(T), varset(T)).
 :- mode varset__bind_var(in, in, in, out) is det.
 
 	% bind a set of terms to a set of variables.
-:- pred varset__bind_vars(varset, substitution, varset).
+:- pred varset__bind_vars(varset(T), substitution(T), varset(T)).
 :- mode varset__bind_vars(in, in, out) is det.
 
 	% lookup the value of a variable
-:- pred varset__search_var(varset, var, term).
+:- pred varset__search_var(varset(T), var(T), term(T)).
 :- mode varset__search_var(in, in, out) is semidet.
 
 	% get the bindings for all the bound variables.
-:- pred varset__lookup_vars(varset, substitution).
+:- pred varset__lookup_vars(varset(T), substitution(T)).
 :- mode varset__lookup_vars(in, out) is det.
 
 	% Combine two different varsets, renaming apart:
@@ -107,21 +109,22 @@
 	% and Terms is Terms0 renamed accordingly.
 	% (Any bindings in NewVarSet are ignored.)
 
-:- pred varset__merge(varset, varset, list(term), varset, list(term)).
+:- pred varset__merge(varset(T), varset(T), list(term(T)),
+		varset(T), list(term(T))).
 :- mode varset__merge(in, in, in, out, out) is det.
 
 	% As above, except return the substitution directly
 	% rather than applying it to a list of terms.
 
-:- pred varset__merge_subst(varset, varset, varset, substitution).
+:- pred varset__merge_subst(varset(T), varset(T), varset(T), substitution(T)).
 :- mode varset__merge_subst(in, in, out, out) is det.
 
 	% get the bindings for all the bound variables.
-:- pred varset__get_bindings(varset, substitution).
+:- pred varset__get_bindings(varset(T), substitution(T)).
 :- mode varset__get_bindings(in, out) is det.
 
 	% set the bindings for all the bound variables.
-:- pred varset__set_bindings(varset, substitution, varset).
+:- pred varset__set_bindings(varset(T), substitution(T), varset(T)).
 :- mode varset__set_bindings(in, in, out) is det.
 
 	% Create a map from names to variables.
@@ -129,13 +132,13 @@
 	% shared by more than one variable. Therefore this predicate
 	% is only really useful if it is already known that no two
 	% variables share the same name.
-:- pred varset__create_name_var_map(varset, map(string, var)).
+:- pred varset__create_name_var_map(varset(T), map(string, var(T))).
 :- mode varset__create_name_var_map(in, out) is det.
 
 	% Return an association list giving the name of each variable.
 	% Every variable has an entry in the returned association list,
 	% even if it shares its name with another variable.
-:- pred varset__var_name_list(varset, assoc_list(var, string)).
+:- pred varset__var_name_list(varset(T), assoc_list(var(T), string)).
 :- mode varset__var_name_list(in, out) is det.
 
 	% Given a list of variable and varset in which some variables have
@@ -143,12 +146,12 @@
 	% return another varset in which every variable has a unique name.
 	% If necessary, names will have suffixes added on the end;
 	% the second argument gives the suffix to use.
-:- pred varset__ensure_unique_names(list(var), string, varset, varset).
+:- pred varset__ensure_unique_names(list(var(T)), string, varset(T), varset(T)).
 :- mode varset__ensure_unique_names(in, in, in, out) is det.
 
 	% Given a varset and a set of variables, remove the names
 	% and values of any other variables stored in the varset.
-:- pred varset__select(varset, set(var), varset).
+:- pred varset__select(varset(T), set(var(T)), varset(T)).
 :- mode varset__select(in, in, out) is det.
 
 	% Given a varset and a list of variables, construct a new varset
@@ -156,18 +159,23 @@
 	% Also return a substitution mapping the selected variables in the
 	% original varset into variables in the new varset. The relative
 	% ordering of variables in the original varset is maintained.
-:- pred varset__squash(varset, list(var), varset, map(var, var)).
+:- pred varset__squash(varset(T), list(var(T)), varset(T), map(var(T), var(T))).
 :- mode varset__squash(in, in, out, out) is det.
 
+	% Coerce the types of the variables in a varset.
+:- pred varset__coerce(varset(T), varset(U)).
+:- mode varset__coerce(in, out) is det.
+
+:- implementation.
 %-----------------------------------------------------------------------------%
 
 :- implementation.
 :- import_module int, list, map, std_util, assoc_list, set, require, string.
 
-:- type varset		--->	varset(
-					var_supply,
-					map(var, string),
-					map(var, term)
+:- type varset(T)	--->	varset(
+					var_supply(T),
+					map(var(T), string),
+					map(var(T), term(T))
 				).
 
 %-----------------------------------------------------------------------------%
@@ -196,7 +204,8 @@
 varset__new_vars(Varset0, NumVars, NewVars, Varset) :-
 	varset__new_vars_2(Varset0, NumVars, [], NewVars, Varset).
 
-:- pred varset__new_vars_2(varset, int, list(var), list(var), varset).
+:- pred varset__new_vars_2(varset(T), int, list(var(T)),
+		list(var(T)), varset(T)).
 :- mode varset__new_vars_2(in, in, in, out, out) is det.
 
 varset__new_vars_2(Varset0, NumVars, NewVars0, NewVars, Varset) :-
@@ -237,8 +246,8 @@
 	varset__vars_2(V0, MaxId0, [], L1),
 	list__reverse(L1, L).
 
-:- pred varset__vars_2(var_supply, var_supply, list(var),
-			list(var)).
+:- pred varset__vars_2(var_supply(T), var_supply(T), list(var(T)),
+			list(var(T))).
 :- mode varset__vars_2(in, in, in, out) is det.
 
 varset__vars_2(N, Max, L0, L) :-
@@ -304,7 +313,7 @@
 	map__to_assoc_list(Subst, VarTermList),
 	varset__bind_vars_2(VarTermList, Varset0, Varset).
 
-:- pred varset__bind_vars_2(assoc_list(var, term), varset, varset).
+:- pred varset__bind_vars_2(assoc_list(var(T), term(T)), varset(T), varset(T)).
 :- mode varset__bind_vars_2(in, in, out) is det.
 
 varset__bind_vars_2([], Varset, Varset).
@@ -347,8 +356,9 @@
 	varset__merge_subst_2(N, MaxId, Names, Vals, VarSet0, Subst0,
 				VarSet, Subst).
 
-:- pred varset__merge_subst_2(var_supply, var_supply, map(var, string),
-	map(var, term), varset, substitution, varset, substitution).
+:- pred varset__merge_subst_2(var_supply(T), var_supply(T), map(var(T), string),
+	map(var(T), term(T)), varset(T), substitution(T),
+	varset(T), substitution(T)).
 :- mode varset__merge_subst_2(in, in, in, in, in, in, out, out) is det.
 
 varset__merge_subst_2(N, Max, Names, Vals, VarSet0, Subst0, VarSet, Subst) :-
@@ -392,8 +402,8 @@
 	varset__ensure_unique_names_2(AllVars, Suffix, UsedNames, VarNameMap0,
 		VarNameMap1, VarNameMap).
 
-:- pred varset__ensure_unique_names_2(list(var), string, set(string),
-	map(var, string), map(var, string), map(var, string)).
+:- pred varset__ensure_unique_names_2(list(var(T)), string, set(string),
+	map(var(T), string), map(var(T), string), map(var(T), string)).
 :- mode varset__ensure_unique_names_2(in, in, in, in, in, out) is det.
 
 varset__ensure_unique_names_2([], _, _, _, VarNameMap, VarNameMap).
@@ -462,7 +472,8 @@
 	map__from_corresponding_lists(KeptVars, NewVars, Subst),
 	copy_var_names(VarNames, Subst, NewVarSet1, NewVarSet).
 
-:- pred copy_var_names(assoc_list(var, string), map(var, var), varset, varset).
+:- pred copy_var_names(assoc_list(var(T), string), map(var(T), var(T)),
+		varset(T), varset(T)).
 :- mode copy_var_names(in, in, in, out) is det.
 
 copy_var_names([], _Subst, NewVarSet, NewVarSet).
@@ -473,6 +484,26 @@
 		NewVarSet1 = NewVarSet0
 	),
 	copy_var_names(Rest, Subst, NewVarSet1, NewVarSet).
+
+%-----------------------------------------------------------------------------%
+
+varset__coerce(varset(S0, N0, B0), varset(S, N, B)) :-
+	term__coerce_var_supply(S0, S),
+	map__to_assoc_list(N0, NList0),
+	list__map(lambda([P0::in, P::out] is det, (
+		P0 = V0 - Name,
+		P = V - Name,
+		term__coerce_var(V0, V)
+	)), NList0, NList),
+	map__from_assoc_list(NList, N),
+	map__to_assoc_list(B0, BList0),
+	list__map(lambda([Q0::in, Q::out] is det, (
+		Q0 = V0 - Binding0,
+		Q = V - Binding,
+		term__coerce_var(V0, V),
+		term__coerce(Binding0, Binding)
+	)), BList0, BList),
+	map__from_assoc_list(BList, B).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: compiler/prog_data.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/prog_data.m,v
retrieving revision 1.41
diff -u -r1.41 prog_data.m
--- prog_data.m	1998/11/02 09:49:05	1.41
+++ prog_data.m	1998/11/03 04:09:06
@@ -19,7 +19,8 @@
 :- interface.
 
 :- import_module hlds_data, hlds_pred, (inst), purity, term_util.
-:- import_module list, map, varset, term, std_util.
+:- import_module varset, term.
+:- import_module list, map, term, std_util.
 
 %-----------------------------------------------------------------------------%
 
@@ -37,54 +38,55 @@
 
 :- type item_list	==	list(item_and_context).
 
-:- type item_and_context ==	pair(item, term__context).
+:- type item_and_context ==	pair(item, prog_context).
 
 :- type item		
-	--->	pred_clause(varset, sym_name, list(term), goal)
+	--->	pred_clause(prog_varset, sym_name, list(prog_term), goal)
 		%      VarNames, PredName, HeadArgs, ClauseBody
 
-	;	func_clause(varset, sym_name, list(term), term, goal)
+	;	func_clause(prog_varset, sym_name, list(prog_term),
+			prog_term, goal)
 		%      VarNames, PredName, HeadArgs, Result, ClauseBody
 
-	; 	type_defn(varset, type_defn, condition)
-	; 	inst_defn(varset, inst_defn, condition)
-	; 	mode_defn(varset, mode_defn, condition)
-	; 	module_defn(varset, module_defn)
-
-	; 	pred(tvarset, existq_tvars, sym_name, list(type_and_mode),
-			maybe(determinism), condition, purity,
-			class_constraints)
-		%       VarNames, ExistentiallyQuantifiedTypeVars,
-		%	PredName, ArgTypes, Deterministicness, Cond,
-		%	Purity, TypeClassContext
-
-	; 	func(tvarset, existq_tvars, sym_name, list(type_and_mode),
-			type_and_mode, maybe(determinism), condition, purity,
-			class_constraints)
-		%       VarNames, ExistentiallyQuantifiedTypeVars,
-		%       PredName, ArgTypes, ReturnType,
-		%       Deterministicness, Cond,
-		%	Purity, TypeClassContext
+	; 	type_defn(tvarset, type_defn, condition)
+	; 	inst_defn(inst_varset, inst_defn, condition) % XXX
+	; 	mode_defn(inst_varset, mode_defn, condition) % XXX
+	; 	module_defn(prog_varset, module_defn)
+
+	; 	pred(tvarset, inst_varset, existq_tvars, sym_name,
+			list(type_and_mode), maybe(determinism), condition,
+			purity, class_constraints)
+		%       TypeVarNames, InstVarNames,
+		%	ExistentiallyQuantifiedTypeVars, PredName, ArgTypes,
+		%	Deterministicness, Cond, Purity, TypeClassContext
+
+	; 	func(tvarset, inst_varset, existq_tvars, sym_name,
+			list(type_and_mode), type_and_mode, maybe(determinism),
+			condition, purity, class_constraints)
+		%       TypeVarNames, InstVarNames,
+		%	ExistentiallyQuantifiedTypeVars, PredName, ArgTypes,
+		%	ReturnType, Deterministicness, Cond, Purity,
+		%	TypeClassContext
 
-	; 	pred_mode(varset, sym_name, list(mode), maybe(determinism),
+	; 	pred_mode(inst_varset, sym_name, list(mode), maybe(determinism),
 			condition)
 		%       VarNames, PredName, ArgModes, Deterministicness,
 		%       Cond
 
-	; 	func_mode(varset, sym_name, list(mode), mode,
+	; 	func_mode(inst_varset, sym_name, list(mode), mode,
 			maybe(determinism), condition)
 		%       VarNames, PredName, ArgModes, ReturnValueMode,
 		%       Deterministicness, Cond
 
 	;	pragma(pragma_type)
 
-	;	typeclass(list(class_constraint), class_name, list(var),
-			class_interface, varset)
+	;	typeclass(list(class_constraint), class_name, list(tvar),
+			class_interface, tvarset)
 		%	Constraints, ClassName, ClassParams, 
 		%	ClassMethods, VarNames
 
 	;	instance(list(class_constraint), class_name, list(type),
-			instance_interface, varset)
+			instance_interface, tvarset)
 		%	DerivingClass, ClassName, Types, 
 		%	MethodInstances, VarNames
 
@@ -103,7 +105,7 @@
 	;	c_code(string)
 
 	;	c_code(pragma_c_code_attributes, sym_name, pred_or_func,
-			list(pragma_var), varset, pragma_c_code_impl)
+			list(pragma_var), prog_varset, pragma_c_code_impl)
 			% Set of C code attributes, eg.:
 			%	whether or not the C code may call Mercury,
 			%	whether or not the C code is thread-safe
@@ -191,26 +193,26 @@
 					% had time to adapt to the new way
 					% of handling model_non pragmas.)
 			string,		% The C code of the procedure.
-			maybe(term__context)
+			maybe(prog_context)
 		)
 	;	nondet(			% This is a C definition of a model_non
 					% procedure.
 			string,
-			maybe(term__context),
+			maybe(prog_context),
 					% The info saved for the time when
 					% backtracking reenters this procedure
 					% is stored in a C struct. This arg
 					% contains the field declarations.
 
 			string,
-			maybe(term__context),
+			maybe(prog_context),
 					% Gives the code to be executed when
 					% the procedure is called for the first 
 					% time. This code may access the input
 					% variables.
 
 			string,	
-			maybe(term__context),
+			maybe(prog_context),
 					% Gives the code to be executed when
 					% control backtracks into the procedure.
 					% This code may not access the input
@@ -220,7 +222,7 @@
 					% How should the shared code be
 					% treated during code generation.
 			string,	
-			maybe(term__context)
+			maybe(prog_context)
 					% Shared code that is executed after
 					% both the previous code fragments.
 					% May not access the input variables.
@@ -237,7 +239,7 @@
 	% list of types is a member of the specified type class.
 	% It is an invariant of this data structure that
 	% the types in a class constraint do not contain any
-	% information in their term__context fields.
+	% information in their prog_context fields.
 	% This invariant is needed to ensure that we can do
 	% unifications, map__lookups, etc., and get the
 	% expected semantics.
@@ -258,32 +260,32 @@
 :- type class_interface  == list(class_method).	
 
 :- type class_method
-	--->	pred(tvarset, existq_tvars, sym_name, list(type_and_mode),
-			maybe(determinism), condition,
-			class_constraints, term__context)
+	--->	pred(tvarset, inst_varset, existq_tvars, sym_name,
+			list(type_and_mode), maybe(determinism), condition,
+			class_constraints, prog_context)
 		%       VarNames, ExistentiallyQuantifiedTypeVars,
 		%	PredName, ArgTypes, Determinism, Cond
 		%	ClassContext, Context
 
-	; 	func(tvarset, existq_tvars, sym_name, list(type_and_mode),
-			type_and_mode,
+	; 	func(tvarset, inst_varset, existq_tvars, sym_name,
+			list(type_and_mode), type_and_mode,
 			maybe(determinism), condition,
-			class_constraints, term__context)
+			class_constraints, prog_context)
 		%       VarNames, ExistentiallyQuantfiedTypeVars,
 		%	PredName, ArgTypes, ReturnType,
 		%	Determinism, Cond
 		%	ClassContext, Context
 
-	; 	pred_mode(varset, sym_name, list(mode),
+	; 	pred_mode(inst_varset, sym_name, list(mode),
 			maybe(determinism), condition,
-			term__context)
+			prog_context)
 		%       VarNames, PredName, ArgModes,
 		%	Determinism, Cond
 		%	Context
 
-	; 	func_mode(varset, sym_name, list(mode), mode,
+	; 	func_mode(inst_varset, sym_name, list(mode), mode,
 			maybe(determinism), condition,
-			term__context)
+			prog_context)
 		%       VarNames, PredName, ArgModes,
 		%	ReturnValueMode,
 		%	Determinism, Cond
@@ -291,10 +293,10 @@
 	.
 
 :- type instance_method	
-	--->	func_instance(sym_name, sym_name, arity, term__context)
+	--->	func_instance(sym_name, sym_name, arity, prog_context)
 				% Method, Instance, Arity, 
 				% Line number of declaration
-	;	pred_instance(sym_name, sym_name, arity, term__context)
+	;	pred_instance(sym_name, sym_name, arity, prog_context)
 				% Method, Instance, Arity, 
 				% Line number of declaration
 	.
@@ -338,7 +340,7 @@
 	;	thread_safe.
 
 :- type pragma_var    
-	--->	pragma_var(var, string, mode).
+	--->	pragma_var(prog_var, string, mode).
 	  	% variable, name, mode
 		% we explicitly store the name because we need the real
 		% name in code_gen
@@ -352,7 +354,7 @@
 
 % clause/4 defined above
 
-:- type goal		==	pair(goal_expr, term__context).
+:- type goal		==	pair(goal_expr, prog_context).
 
 :- type goal_expr	
 	% conjunctions
@@ -367,26 +369,32 @@
 	;	fail		% empty disjunction
 
 	% quantifiers
-	;	{ some(vars,goal) }
+	;	{ some(prog_vars, goal) }
 				% existential quantification
 				% (The curly braces just quote the 'some'/2.)
-	;	all(vars,goal)	% universal quantification
+	;	all(prog_vars, goal)	% universal quantification
 
 	% implications
-	;	implies(goal,goal)	% A => B
-	;	equivalent(goal,goal)	% A <=> B
+	;	implies(goal, goal)	% A => B
+	;	equivalent(goal, goal)	% A <=> B
 
 	% negation and if-then-else
 	;	not(goal)
-	;	if_then(vars,goal,goal)
-	;	if_then_else(vars,goal,goal,goal)
+	;	if_then(prog_vars, goal, goal)
+	;	if_then_else(prog_vars, goal, goal, goal)
 
 	% atomic goals
-	;	call(sym_name, list(term), purity)
-	;	unify(term, term).
+	;	call(sym_name, list(prog_term), purity)
+	;	unify(prog_term, prog_term).
 
+:- type prog_var_type	--->	prog_var_type.
+:- type prog_var	==	var(prog_var_type).
+:- type prog_varset	==	varset(prog_var_type).
+:- type prog_substitution ==	substitution(prog_var_type).
+:- type prog_term	==	term(prog_var_type).
+:- type prog_context	==	term__context.
 :- type goals		==	list(goal).
-:- type vars		==	list(var).
+:- type prog_vars	==	list(prog_var).
 
 %-----------------------------------------------------------------------------%
 
@@ -421,17 +429,21 @@
 :- type equality_pred	==	sym_name.
 
 	% probably type parameters should be variables not terms.
-:- type type_param	==	term.
+:- type type_param	==	term(tvar_type).
 
 	% Module qualified types are represented as ':'/2 terms.
 	% Use type_util:type_to_type_id to convert a type to a qualified
 	% type_id and a list of arguments.
 	% type_util:construct_type to construct a type from a type_id 
 	% and a list of arguments.
-:- type (type)		==	term.
+:- type (type)		==	term(tvar_type).
+:- type type_term	==	term(tvar_type).
 
-:- type tvar		==	var.	% used for type variables
-:- type tvarset		==	varset. % used for sets of type variables
+:- type tvar_type	--->	type_var.
+:- type tvar		==	var(tvar_type).
+					% used for type variables
+:- type tvarset		==	varset(tvar_type).
+					% used for sets of type variables
 :- type tsubst		==	map(tvar, type). % used for type substitutions
 
 	% existq_tvars is used to record the set of type variables which are
@@ -455,6 +467,11 @@
 	% type terms (see above), we need a separate data structure for inst 
 	% terms.
 
+:- type inst_var_type	--->	inst_var_type.
+:- type inst_var	==	var(inst_var_type).
+:- type inst_term	==	term(inst_var_type).
+:- type inst_varset	==	varset(inst_var_type).
+
 % inst_defn/3 defined above
 
 :- type inst_defn	
@@ -462,7 +479,7 @@
 	;	abstract_inst(sym_name, list(inst_param)).
 
 	% probably inst parameters should be variables not terms
-:- type inst_param	==	term.
+:- type inst_param	==	inst_term.
 
 	% An `inst_name' is used as a key for the inst_table.
 	% It is either a user-defined inst `user_inst(Name, Args)',



More information about the developers mailing list