[m-dev.] For review: making terms polymorphic

Thomas Charles CONWAY conway at cs.mu.OZ.AU
Thu Nov 5 08:59:17 AEDT 1998


Fergus Henderson, you write:
> 
> Since the change is not completely backwards compatible, the
> news file should explain what people will need to do to fix
> their code.
> 

How is it incompatible? Existing code shouldn't need changing.

> > +	% 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.
> 
> A comment here saying what the predicate does (not just what it is
> useful for) would be helpful.
> 
> "In the absence of type qualifiers" is not going to be clear
> to most people.
> 

How about this:
	% term__generic_term(Term) is true iff `Term' is a term of type
	% `term' ie `term(generic)'.
	% It is useful because in some instances it doesn't matter what
	% the type of a term is, and passing it to this predicate will
	% ground the type avoiding unbound type variable warnings.

> > Index: compiler/prog_data.m
> ...
> > +	; 	inst_defn(inst_varset, inst_defn, condition) % XXX
> > +	; 	mode_defn(inst_varset, mode_defn, condition) % XXX
> 
> You should explain these XXXs.

Opps, I forgot to remove them.

> 
> > +:- 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).
> 
> A comment here would be helpful.
> 

Here's the diff of the changed files:
	NEWS
	library/term.m
	library/varset.m
	compiler/prog_data.m

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

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/04 21:37:51
@@ -319,6 +319,15 @@
   See the "benchmarking" chapter of the Mercury Library Reference Manual
   for details.
 
+* The types `term', `var', `var_supply' and `varset' are now polymorphic.
+  This allows one to distinguish between terms, etc. denoting different kinds
+  of things by giving them different types. The new coercion predicates
+  listed below allow one to coerce terms, etc between types.
+
+  The monomorphic versions of these have been retained as equivalences
+  to the polymorphic ones with the type variable instantiated to a dummy
+  type `generic'.
+
 * Miscellaneous new predicates.
 
   The Mercury standard library now includes the following new predicates:
@@ -343,6 +352,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/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/04 21:46:33
@@ -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)).
+
+:- type term_to_type_result(T) == term_to_type_result(T, generic).
 
-:- pred term__try_term_to_type(term, term_to_type_result(T)).
+:- 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,17 +281,39 @@
 	% 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.
 
 %-----------------------------------------------------------------------------%
+	
+	% term__generic_term(Term) is true iff `Term' is a term of type
+	% `term' ie `term(generic)'.
+	% It is useful because in some instances it doesn't matter what
+	% the type of a term is, and passing it to this predicate will
+	% ground the type avoiding unbound type variable warnings.
+:- 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.
 
@@ -292,7 +327,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 +346,10 @@
 
 %-----------------------------------------------------------------------------%
 
-:- type var_supply	==	int.
-:- type var		==	int.
+:- type var_supply(T)
+	--->	var_supply(int).
+:- type var(T)
+	--->	var(int).
 
 %-----------------------------------------------------------------------------%
 
@@ -331,15 +368,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 +417,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 +516,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 +654,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 +730,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 +738,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 +784,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 +812,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 +828,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 +936,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 +1013,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 +1068,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 +1144,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 +1157,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 +1175,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/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/04 21:49:08
@@ -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,31 @@
 		NewVarSet1 = NewVarSet0
 	),
 	copy_var_names(Rest, Subst, NewVarSet1, NewVarSet).
+
+%-----------------------------------------------------------------------------%
+
+varset__coerce(varset(S0, N0, B0), varset(S, N, B)) :-
+		% Coerce the var_supply
+	term__coerce_var_supply(S0, S),
+
+		% Coerce all the vars in the mapping from vars to names
+	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),
+
+		% Coerce all the vars and terms in the substitution
+	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/04 21:55:33
@@ -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)
+	; 	mode_defn(inst_varset, mode_defn, condition)
+	; 	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,43 +260,45 @@
 :- 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)
-		%       VarNames, ExistentiallyQuantifiedTypeVars,
+	--->	pred(tvarset, inst_varset, existq_tvars, sym_name,
+			list(type_and_mode), maybe(determinism), condition,
+			class_constraints, prog_context)
+		%       TypeVarNames, InstVarNames,
+		%	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)
-		%       VarNames, ExistentiallyQuantfiedTypeVars,
+			class_constraints, prog_context)
+		%       TypeVarNames, InstVarNames,
+		%	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)
-		%       VarNames, PredName, ArgModes,
+			prog_context)
+		%       InstVarNames, 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)
-		%       VarNames, PredName, ArgModes,
+			prog_context)
+		%       InstVarNames, PredName, ArgModes,
 		%	ReturnValueMode,
 		%	Determinism, Cond
 		%	Context
 	.
 
 :- 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 +342,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 +356,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 +371,40 @@
 	;	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).
+
+
+	% These type equivalences are for the type of program variables
+	% and associated structures.
+
+:- 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_vars	==	list(prog_var).
+
+	% A prog_context is just a term__context.
+
+:- type prog_context	==	term__context.
 
 :- type goals		==	list(goal).
-:- type vars		==	list(var).
 
 %-----------------------------------------------------------------------------%
 
@@ -421,17 +439,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 +477,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 +489,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