[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