[m-dev.] for review: polymorphic ground insts

David Overton dmo at ender.cs.mu.oz.au
Mon Feb 21 17:22:12 AEDT 2000


On Thu, 10 Feb, 2000 at 06:35:09PM EST, Fergus Henderson wrote:
> On 09-Feb-2000, David Overton <dmo at ender.cs.mu.oz.au> wrote:
> hlds_pred.m:
> >  :- type proc_info
> >  	--->	procedure(
> > -			maybe(determinism),
> > +			declared_determinism :: maybe(determinism),
> >  					% _declared_ determinism
> >  					% or `no' if there was no detism decl
> [... 20 lines later ...]
> > -			stack_slots,	% stack allocations
> > -			determinism,	% _inferred_ determinism
> > -			bool,		% no if we must not process this
> > +			stack_slots :: stack_slots,	% stack allocations
> > +			inferred_determinism :: determinism,
> > +					% _inferred_ determinism
> > +			can_process :: bool,
> > +					% no if we must not process this
> 
> It would be a good idea to move the declaration
> of the `declared_determinism' field next to the declaration
> of the `inferred_determinism' field.

Done.

> You might want to consider
> rearranging the order of the other fields too.
> Some of these fields occur in "historical order", because
> previously it was very tedious to reorder fields.
> Now that we're using records, we should make sure to declare
> the fields in the order that makes things easiest to read.
> 
> > +proc_info_get_rl_exprn_id(ProcInfo, ProcInfo^rl_exprn_id).
> > +
> >  % :- type proc_info
> >  % 	--->	procedure(
> >  % A			maybe(determinism),
> 
> You should probably delete that comment now.
> (It just duplicates the type declaration,
> annotating each field with a letter for use
> in the definitions of access predicates.)

Done.

> 
> > +++ compiler/inst.m	2000/02/04 00:04:23
> > @@ -1,5 +1,5 @@
> >  %-----------------------------------------------------------------------------%
> > -% Copyright (C) 1997, 1999 The University of Melbourne.
> > +% Copyright (C) 1997, 2000 The University of Melbourne.
> 
> That should be
> 
> % Copyright (C) 1997, 1999-2000 The University of Melbourne.

Done.

> 
> > @@ -34,7 +34,7 @@
> >  	;		free(type)
> >  	;		bound(uniqueness, list(bound_inst))
> >  				% The list(bound_inst) must be sorted
> > -	;		ground(uniqueness, maybe(pred_inst_info))
> > +	;		ground(uniqueness, ground_inst_info)
> >  				% The pred_inst_info is used for
> >  				% higher-order pred modes
> 
> That comment is unclear now.  You should update it to reflect
> your change.

Done.

> 
> > +:- type ground_inst_info
> > +	--->	higher_order(pred_inst_info)
> > +	;	constrained_inst_var(inst_var)
> > +	;	none.
> 
> Some comments here would also be helpful.

Done.

> 
> > +++ compiler/inst_match.m	2000/02/08 04:57:39
> > @@ -1,5 +1,5 @@
> >  %-----------------------------------------------------------------------------%
> > -% Copyright (C) 1995-1998 The University of Melbourne.
> > +% Copyright (C) 1995-2000 The University of Melbourne.
> 
> That should probably be "1995-1998, 2000".

Done.

> 
> > +inst_matches_initial_3(bound(UniqA, ListA),
> > +		ground(UniqB, constrained_inst_var(V)), _, _,
> > +		ModuleInfo0, ModuleInfo, Sub0, Sub) :-
> > +	unique_matches_initial(UniqA, UniqB),
> > +	bound_inst_list_is_ground(ListA, ModuleInfo0),
> > +	bound_inst_list_matches_uniq(ListA, UniqB, ModuleInfo0),
> > +	abstractly_unify_inst(live, bound(UniqA, ListA), ground(UniqB, none),
> > +		fake_unify, ModuleInfo0, Inst, _Det, ModuleInfo1),
> > +	update_inst_var_sub(V, Inst, ModuleInfo1, ModuleInfo, Sub0, Sub).
> 
> Hmm... it might be helpful to have a comment explaining
> what the call to update_inst_var_sub does... either that,
> or the definition of update_inst_var_sub should have some
> detailed comments.

Done.

> 
> > +inst_matches_initial_3(ground(UniqA, GII), bound(UniqB, List), MaybeType,
> > +		Expansions, ModuleInfo0, ModuleInfo, Sub0, Sub) :-
> 
> I found it easiest if each variable from the insts was suffixed with
> `A' (for the LHS) or `B' (for the RHS).  So I suggest s/GII/GII_A/
> and s/List/ListA/g.  Similarly in a few other spots, e.g. you use
> `V' in a number of places where I think `InstVarA' or `InstVarB'
> would be clearer.

Done.

> 
> > +:- pred ground_matches_initial_bound_inst_list(uniqueness, list(bound_inst),
> > +	maybe(type), expansions, module_info, module_info,
> > +	inst_var_sub, inst_var_sub).
> > +:- mode ground_matches_initial_bound_inst_list(in, in, in, in, in, out,
> > +	in, out) is semidet.
> 
> I think you should add a comment here saying that this predicate assumes that
> the check of `bound_inst_list_is_complete_for_type' is done by the caller.
> Otherwise, the definition of `matches_initial' would lead the reader to
> expect that this predicate should perform that check.

Done.

> 
> > +:- pred bound_inst_list_is_complete_for_type(set(inst_name), module_info,
> > +		list(bound_inst), type).
> > +:- mode bound_inst_list_is_complete_for_type(in, in, in, in) is semidet.
> 
> It would be helpful to have a comment here explaining what it means for a
> inst or a bound_inst_list to be "complete" for a type.

Done.

> 
> > +inst_is_complete_for_type(Expansions, ModuleInfo, Inst, Type) :-
> > +	( Inst = defined_inst(InstName) ->
> > +		( set__member(InstName, Expansions) ->
> > +			true
> > +		;
> > +			inst_lookup(ModuleInfo, InstName, ExpandedInst),
> > +			inst_is_complete_for_type(Expansions `insert` InstName,
> > +				ModuleInfo, ExpandedInst, Type)
> 
> I think it would be best to keep the module qualifier, i.e.
> make that "`set__insert`" rather than just "`insert`".

Done.

> 
> > +		)
> > +	; Inst = bound(_, List) ->
> > +		bound_inst_list_is_complete_for_type(Expansions, ModuleInfo,
> > +			List, Type)
> > +	;
> > +		true
> > +	).
> 
> I think that logically speaking, if Inst = not_reached, then
> this predicate should fail.  After all, not_reached is basically
> equivalent to a special representation of `bound(_, [])', and
> this predicate fails for `bound(_, [])'.

Done.

> 
> (I think this doesn't affect the behaviour of your changes, since you
> check for not_reached elsewhere anyway.  But still...)
> 
> > +:- pred equivalent_cons_ids(cons_id, cons_id).
> > +:- mode equivalent_cons_ids(in, in) is semidet.
> 
> It might be nice to have a comment here explaining what kind of equivalence
> this computes.
> 

Done.

> > +%-----------------------------------------------------------------------------%
> > +
> > +:- pred update_inst_var_sub(inst_var, inst, module_info, module_info,
> > +		inst_var_sub, inst_var_sub).
> > +:- mode update_inst_var_sub(in, in, in, out, in, out) is semidet.
> > +
> > +update_inst_var_sub(V, InstA, ModuleInfo0, ModuleInfo, Sub0, Sub) :-
> > +	( map__search(Sub0, V, InstB) ->
> > +		inst_merge(InstA, InstB, ModuleInfo0, Inst, ModuleInfo),
> > +		map__det_update(Sub0, V, Inst, Sub)
> > +	;
> > +		ModuleInfo = ModuleInfo0,
> > +		map__det_insert(Sub0, V, InstA, Sub)
> > +	).
> 
> It would be a good idea to document this predicate better.
> For example, what is it's purpose?  And why does it use `inst_merge'?

Done.

> 
> > +%-----------------------------------------------------------------------------%
> > +
> > +:- pred ground_inst_info_matches_initial(ground_inst_info, ground_inst_info,
> > +		uniqueness, uniqueness, maybe(type), expansions,
> > +		module_info, module_info, inst_var_sub, inst_var_sub).
> > +:- mode ground_inst_info_matches_initial(in, in, in, in, in, in, in, out, in,
> > +		out) is semidet.
> > +
> > +ground_inst_info_matches_initial(_, none, _, _, _, _, M, M) --> [].
> > +ground_inst_info_matches_initial(higher_order(PredInstA),
> > +		higher_order(PredInstB), _, _, Type, Expansions,
> > +		ModuleInfo0, ModuleInfo) -->
> > +	pred_inst_matches_initial(PredInstA, PredInstB, Type, Expansions,
> > +		ModuleInfo0, ModuleInfo).
> 
> Why do you ignore the uniquenesses here?

This predicate is not supposed to check uniqueness.

> If this predicate is not supposed to check the uniquenesses,
> that should be documented.

Ok.

> 
> > +ground_inst_info_matches_initial(GroundInstInfoA, constrained_inst_var(V),
> > +		UniqA, UniqB, _, _, ModuleInfo0, ModuleInfo) -->
> > +	{ GroundInstInfoA = constrained_inst_var(_) ->
> > +		Inst = ground(UniqA, GroundInstInfoA),
> > +		ModuleInfo1 = ModuleInfo0
> > +	;
> > +		abstractly_unify_inst(live, ground(UniqA, GroundInstInfoA),
> > +			ground(UniqB, none), fake_unify, ModuleInfo0, Inst,
> > +			_Det, ModuleInfo1)
> > +	},
> 
> Why is the if-then-else there needed?
> Hmm, you ignore the uniqueness in the "then" case, but you check
> the uniqueness in the "else" case... why?
> Is there any other difference between the two cases?

Ok, this bit was wrong.  The uniqueness of Inst should be UniqB.  We
have already checked that UniqA matches_initial UniqB.

> 
> > +:- pred maybe_get_arg_types(module_info, maybe(type), cons_id,
> > +		list(maybe(type))).
> > +:- mode maybe_get_arg_types(in, in, in, out) is det.
> > +
> > +maybe_get_arg_types(ModuleInfo, MaybeType, ConsId0, MaybeTypes) :-
> > +	( ConsId0 = cons(SymName, Arity) ->
> > +		( SymName = qualified(_, Name) ->
> > +			% type_util__get_cons_id_arg_types expects an 
> > +			% unqualified cons_id.
> 
> It would be a good idea to add that comment to type_util.m too.

Done.

> > @@ -551,9 +804,9 @@
> >  		% insts in ListB, or if ListB does not contain a complete list
> >  		% of all the constructors for the type in question.
> >  	%%% error("not implemented: `ground' matches_final `bound(...)'").
> 
> Did you consider fixing this bug in the same way as you fixed
> the similar one in inst_matches_initial?

The only reason I didn't do it is because it didn't seem quite as
important as for inst_matches_initial.  I've have now tried to fix
the similar bugs in inst_matches_final and inst_matches_binding.
Unfortunately, without alias tracking, this fix causes lots of code to
break.  E.g., the following code, which occurs in several places in
the compiler:

	:- pred p is semidet.
	:- pred q(list(int)::out) is det.

	p :- q([_]).

	q([1,2,3,4]).

creates a unification proc for list(T) where the second argument has
mode `ground -> bound([ground | bound([])))'.  When mode checking this
proc, because there is no alias tracking, the final inst inferred is
`bound([ground | ground])' which does not match_final with the expected
final inst.

So at the moment I have disabled the test in inst_matches_final and
inst_matches_binding.  Do you have a better (short-term) solution
until alias tracking is ready for the main branch?

> > +ground_inst_info_matches_final(constrained_inst_var(I),
> > +		constrained_inst_var(I), _, _).
> 
> Hmm...

What is the problem with this?

> 
> > +ground_inst_info_matches_binding(constrained_inst_var(_),
> > +		constrained_inst_var(_), _). % AAA
> 
> Hmm again...  what's the "AAA" comment for?

The "AAA" comment was to remind me to go back and look at this again,
which I forgot to do.  I think this should actually be:

	ground_inst_info_matches_binding(constrained_inst_var(InstVar),
		constrained_inst_var(InstVar), _, _).

So I've changed it to that.  There were several other "AAA" comments
in the code which I've also fixed up.

On Thu, Feb 17, 2000 at 07:50:27PM +1100, Fergus Henderson wrote:
> 
> > -:- pred inst_name_apply_substitution(inst_name, inst_subst, inst_name).
> > -:- mode inst_name_apply_substitution(in, in, out) is det.
> > +:- pred inst_name_apply_substitution(inst_name, inst_var_sub, inst_name).
> > +:- mode inst_name_apply_substitution(in, in, out) is semidet.
> 
> It would be helpful to document when/why this predicate fails.
> 
> >  inst_name_apply_substitution(user_inst(Name, Args0), Subst,
> >  		user_inst(Name, Args)) :-
> >  	inst_list_apply_substitution(Args0, Subst, Args).
> > -inst_name_apply_substitution(unify_inst(Live, InstA0, InstB0, Real), Subst,
> > -		unify_inst(Live, InstA, InstB, Real)) :-
> > -	inst_apply_substitution(InstA0, Subst, InstA),
> > -	inst_apply_substitution(InstB0, Subst, InstB).
> 
> Hmm... why don't you apply the substitution to the insts in the inst_name?
> I think it would be worth adding a comment explaining that.

Done.

> > -recompute_instmap_delta(RecomputeAtomic, Goal0 - GoalInfo0, Goal - GoalInfo,
> > -		VarTypes, InstMap0, InstMapDelta) -->
> > +recompute_instmap_delta_1(RecomputeAtomic, Goal0 - GoalInfo0, Goal - GoalInfo,
> > +		VarTypes, InstMap0, InstMapDelta, RI0, RI) :-
> >  	( 
> > -		{ RecomputeAtomic = no },
> > -		( 
> > -			{ goal_is_atomic(Goal0) }
> > -		;
> > +		RecomputeAtomic = no,
> > +		goal_is_atomic(Goal0),
> > +		Goal0 \= unify(_,lambda_goal(_,_,_,_,_,_,_,_),_,_,_)
> >  			% Lambda expressions always need to be processed.
> > -			{ Goal0 = unify(_, Rhs, _, _, _) },
> > -			{ Rhs \= lambda_goal(_, _, _, _, _, _, _, _) }
> > -		)
> 
> Hmm... you seem to have changed the semantics there:
> you changed a disjunction into a conjunction.
> I don't think that was mentioned in the log message.
> What's the purpose of that change?

The purpose is to make sure that lambda goals are not skipped when
RecomputeAtomic = no.
I have added this to the log message.

> > +:- pred lift(pred(T, module_info, module_info), T, recompute_info,
> > +		recompute_info).
> > +:- mode lift(pred(out, in, out) is det, out, in, out) is det.
> > +
> > +lift(P, R) -->
> > +	ModuleInfo0 =^ module_info,
> > +	{ P(R, ModuleInfo0, ModuleInfo) },
> > +	^module_info := ModuleInfo.
> 
> Hmm, "lift" is a rather generic name... a brief comment
> explaining what this predicate does would be helpful, I think.

Done.

> 
> > +recompute_instmap_delta_call(PredId, ProcId, Args, VarTypes, InstMap,
> > +		InstMapDelta) -->
> > +	ModuleInfo =^ module_info,
> > +	{ module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _, ProcInfo) },
> > +	{ proc_info_interface_determinism(ProcInfo, Detism) },
> > +	( { determinism_components(Detism, _, at_most_zero) } ->
> > +		{ instmap_delta_init_unreachable(InstMapDelta) }
> > +	;
> > +		{ proc_info_argmodes(ProcInfo, ArgModes0) },
> > +		{ proc_info_inst_varset(ProcInfo, ProcInstVarSet) },
> > +		InstVarSet =^ inst_varset,
> > +		{ rename_apart_inst_vars(InstVarSet, ProcInstVarSet,
> > +			ArgModes0, ArgModes1) },
> > +		{ mode_list_get_initial_insts(ArgModes1, ModuleInfo,
> > +			InitialInsts) },
> > +		{ map__init(InstVarSub0) },
> > +		lift(recompute_instmap_delta_call_1(Args, VarTypes, InstMap,
> > +			InitialInsts, InstVarSub0), InstVarSub),
> > +
> > +		{ mode_list_apply_substitution(ArgModes1, InstVarSub,
> > +			ArgModes2) },
> > +		lift(recompute_instmap_delta_call_2(Args, InstMap,
> > +			ArgModes2), ArgModes),
> > +		{ instmap_delta_from_mode_list(Args, ArgModes,
> > +			ModuleInfo, InstMapDelta) }
> > +	).
> 
> Hmm, that's a moderately complicated bit of code... some
> comments here might help.

Done.

> 
> > +:- pred recompute_instmap_delta_call_1(list(prog_var), vartypes, instmap,
> > +	list(inst), inst_var_sub, inst_var_sub, module_info, module_info).
> > +:- mode recompute_instmap_delta_call_1(in, in, in, in, in, out, in, out) is det.
> 
> This predicate seems poorly named to me...
> I don't think it is actually recomputing any instmap deltas,
> instead I think it is just computing a substitution?

I have renamed it to `compute_inst_var_sub'.

> 
> > +recompute_instmap_delta_call_1([Arg | Args], VarTypes, InstMap, [Inst | Insts],
> > +		Sub0, Sub, ModuleInfo0, ModuleInfo) :-
> > +	% This is similar to modecheck_var_has_inst.
> > +	( instmap__is_reachable(InstMap) ->
> > +		instmap__lookup_var(InstMap, Arg, ArgInst),
> > +		map__lookup(VarTypes, Arg, Type),
> > +		(
> > +			inst_matches_initial(ArgInst, Inst, Type, ModuleInfo0,
> > +				ModuleInfo1, Sub0, Sub1)
> > +		->
> > +			ModuleInfo2 = ModuleInfo1,
> > +			Sub2 = Sub1
> > +		;
> > +			% AAA error("recompute_instmap_delta_call_1: inst_matches_initial failed")
> > +			ModuleInfo2 = ModuleInfo0,
> > +			Sub2 = Sub0
> 
> I think you need some comments here.
> Why do you ignore the failure if inst_matches_initial fails?

The call to error should not be commented out.  I have fixed this.

> > -compare_inst_list_2([], [], _, same, _).
> > +compare_inst_list_2([], [], _, [], same, _).
> >  compare_inst_list_2([InstA | InstsA], [InstB | InstsB],
> > -		no, Result, ModuleInfo) :-
> > -	compare_inst(InstA, InstB, no, Result0, ModuleInfo),
> > -	compare_inst_list_2(InstsA, InstsB, no, Result1, ModuleInfo),
> > +		std_util:no, [Type | Types], Result, ModuleInfo) :-
> 
> Please use `__' rather than `:' for the module qualifier.
> But I would advise not using the module qualifier here,
> just write `no' rather than `std_util__no'.

Done.

On Thu, Feb 17, 2000 at 09:01:37PM +1100, Fergus Henderson wrote:
> On 09-Feb-2000, David Overton <dmo at ender.cs.mu.oz.au> wrote:
> > Index: compiler/modes.m
> > @@ -607,11 +607,27 @@
> >  	{ pred_info_procedures(PredInfo0, Procs0) },
> >  	{ map__keys(Procs0, ProcIds) },
> >  	( { WhatToCheck = check_modes } ->
> > -		( { ProcIds = [] } ->
> > +		(
> > +			{ ProcIds = [] }
> > +		->
> >  			maybe_report_error_no_modes(PredId, PredInfo0,
> >  					ModuleInfo0),
> >  			{ NumErrors0 = 0 }
> >  		;
> > +			{ module_info_get_special_pred_map(ModuleInfo0,
> > +				SpecialPredMap) },
> > +			{ map__member(SpecialPredMap, unify - _, PredId) }
> > +		->
> > +			% Don't check for indistinguishable modes in unification
> > +			% predicates.
> 
> Calling map__member on the special_pred_map is likely to be quite
> inefficient.  If you want to check whether a predicate is a unification
> predicate, it would be more efficient to just check the name and arity,
> e.g. via
> 
> 		special_pred_name_arity(unify, _, PredName, Arity),
> 		pred_info_name(PredInfo0, PredName),
> 		pred_info_arity(PredInfo0, PredArity)
> 

Done.

> > +++ compiler/prog_data.m	2000/02/03 03:44:26
> > @@ -698,7 +698,7 @@
> >  	;	abstract_inst(sym_name, list(inst_param)).
> >  
> >  	% probably inst parameters should be variables not terms
> > -:- type inst_param	==	inst_term.
> > +:- type inst_param	==	inst_var.
> 
> You can delete that comment now.
> 
> It would probably be best to do a global s/inst_param/inst_var/g
> and then just delete the inst_param type.

Done.

> 
> > +++ compiler/special_pred.m	2000/02/07 04:02:01
> > @@ -67,6 +67,11 @@
> >  	% mode num for special procs is always 0 (the first mode)
> >  special_pred_mode_num(_, 0).
> >  
> > +	% XXX If the type has only one value, the determinism should be `det'.
> > +	% However, this predicate is called by make_hlds before all the type
> > +	% information is available, so we can't check that here.
> > +	% There is a pass over the unify preds at the end of make_hlds to
> > +	% fix up the determinism.
> >  special_pred_info(unify, Type, "__Unify__", [Type, Type], [In, In], semidet) :-
> >  	in_mode(In).
> 
> I don't think that comment deserves an XXX.
> An XXX should mark something that is or at least might be wrong,
> and which thus deserves revisiting.  But in this case the comment
> in the last sentence says that the problem is already solved,
> so it doesn't need revisiting, right?
> 
> But that information about what special_pred_info returns is needed
> to understand how to use that predicate, so a comment like that one
> should go in the interface section of the module.

This comment is actually incorrect because I realised that the mode 0
(in, in) unification procedure needs to be semidet so that it can be
called from the polymorphic unify.  I have removed this comment and
placed a more accurate comment in the interface.

> 
> > Index: compiler/type_util.m
> > ===================================================================
> > RCS file: /home/mercury1/repository/mercury/compiler/type_util.m,v
> > retrieving revision 1.79
> > diff -u -r1.79 type_util.m
> > --- compiler/type_util.m	2000/02/08 06:59:28	1.79
> > +++ compiler/type_util.m	2000/02/09 00:19:41
> > @@ -171,6 +171,11 @@
> >  :- pred type_util__get_cons_id_arg_types(module_info::in, (type)::in,
> >  		cons_id::in, list(type)::out) is det.
> >  
> > +	% The same as type_util__get_cons_id_arg_types except that the
> > +	% cons_id is output non-deterministically.
> > +:- pred type_util__cons_id_arg_types(module_info::in, (type)::in,
> > +		cons_id::out, list(type)::out) is nondet.
> 
> Why not just call type_util__get_cons_id_arg_types
> and then list__member?

In type_util__get_cons_id_arg_types, the cons_id is input, not output.

> 
> >  	% Given a type and a cons_id, look up the definitions of that
> >  	% type and constructor. Aborts if the cons_id is not user-defined.
> >  :- pred type_util__get_type_and_cons_defn(module_info, (type), cons_id,
> > @@ -664,20 +669,39 @@
> >  			ConsId, TypeDefn, ConsDefn),
> >  		ConsDefn = hlds_cons_defn(ExistQVars0, _Constraints0,
> >  				ArgTypes0, _, _),
> > -		ArgTypes0 \= []
> > +		ArgTypes0 \= [],
> > +
> > +		% XXX handle ExistQVars
> > +		ExistQVars0 = []
> >  	->
> >  		hlds_data__get_type_defn_tparams(TypeDefn, TypeDefnParams),
> >  		term__term_list_to_var_list(TypeDefnParams, TypeDefnVars),
> >  
> > -		% XXX handle ExistQVars
> > -		require(unify(ExistQVars0, []),
> > -	"type_util__get_cons_id_arg_types: existentially typed cons_id"),
> > -
> >  		map__from_corresponding_lists(TypeDefnVars, TypeArgs, TSubst),
> >  		term__apply_substitution_to_list(ArgTypes0, TSubst, ArgTypes)
> >  	;
> >  		ArgTypes = []
> >  	).
> 
> That change is not documented in your log message.
> The change breaks the documentation for that predicate.
> And I don't understand the rationale for it.

I've undone that change.  It slipped in accidentally.
> 
> > Index: library/array.m
> > ===================================================================
> e RCS file: /home/mercury1/repository/mercury/library/array.m,v
> > retrieving revision 1.67
> > diff -u -r1.67 array.m
> > --- library/array.m	2000/01/19 09:45:16	1.67
> > +++ library/array.m	2000/02/04 02:15:56
> > @@ -93,30 +93,30 @@
> >  	% Note: in this implementation, the lower bound is always zero.
> >  :- pred array__min(array(_T), int).
> >  :- mode array__min(array_ui, out) is det.
> > -:- mode array__min(in, out) is det.
> > +%:- mode array__min(in, out) is det.
> >  
> >  	% array__max returns the upper bound of the array.
> >  :- pred array__max(array(_T), int).
> >  :- mode array__max(array_ui, out) is det.
> > -:- mode array__max(in, out) is det.
> > +%:- mode array__max(in, out) is det.
> 
> You should explain why all those modes are commented out.
> 
> In fact, I don't understand why those modes need to be commented out.

Actually, it turns out that they don't.  I'll remove those changes to
the library.

> Anyway, that completes my review.
> Apart from the issues I've raised so far,
> and the couple of things that you yourself listed
> as still do be done, this looks good.
> This change will need another round of reviewing, IMHO.
> I'd like to see a relative diff next time.

Here's the first part of the relative diff.  The rest follows in a
second post.

--- ./cvslog	Thu Feb 17 11:52:04 2000
+++ .././cvslog	Mon Feb 21 17:07:03 2000
@@ -1,6 +1,6 @@
 
 
-Estimated hours taken: 40
+Estimated hours taken: 50
 
 Allow polymorphic ground insts.  This change assumes that all inst
 parameters in the mode declaration for a predicate or function are
@@ -28,10 +28,19 @@
 		- handles inst_matches_initial(ground(...), bound(...), ...)
 		  properly (this requires knowing the type of the variable).
 
+	  The last change has also been made for inst_matches_final
+	  and inst_matches_binding.  However, the check is disabled for
+	  now because, without alias tracking, the mode checker
+	  becomes too conservative.
+
 compiler/hlds_pred.m:
 compiler/mode_info.m:
 compiler/simplify.m:
+compiler/det_util.m:
 	Include the inst_varset in the proc_info, mode_info and simplify_info.
+	Add a vartypes field to the det_info.
+	Remove the vartypes field from the simplify_info since it is
+	now in the det_info.
 	Use record syntax for these data structures and their access predicates
 	to make future changes easier.
 
@@ -40,7 +49,10 @@
 	insts to ground(shared, constrained_inst_var(V)).
 
 compiler/prog_data.m:
-	Use inst_vars instead of inst_terms for inst_params.
+compiler/hlds_data.m:
+compiler/make_hlds.m:
+compiler/mode_util.m:
+	Use inst_vars instead of inst_params.
 
 compiler/modes.m:
 compiler/modecheck_call.m:
@@ -51,6 +63,10 @@
 	inst_matches_initial) and apply this to the final insts of the
 	called procedure before checking/recomputing them.
 
+compiler/mode_util.m:
+	Make sure that recompute_instmap_delta recomputes the
+	instmap_deltas for lambda_goals even when RecomputeAtomic = no.
+
 compiler/type_util.m:
 	Add a new predicate, type_util__cons_id_arg_types which
 	nondeterministically returns the cons_ids and argument types for a
@@ -59,15 +75,20 @@
 compiler/accumulator.m:
 compiler/check_typeclass.m:
 compiler/clause_to_proc.m:
+compiler/common.m:
 compiler/deforest.m:
+compiler/det_analysis.m:
+compiler/det_report.m:
+compiler/det_util.m:
 compiler/dnf.m:
 compiler/follow_code.m:
+compiler/goal_util.m:
 compiler/higher_order.m:
 compiler/inst_util.m:
+compiler/instmap.m:
 compiler/lambda.m:
 compiler/magic.m:
 compiler/magic_util.m:
-compiler/make_hlds.m:
 compiler/mercury_to_mercury.m:
 compiler/modecheck_unify.m:
 compiler/module_qual.m:
@@ -79,21 +100,6 @@
 compiler/saved_vars.m:
 compiler/table_gen.m:
 compiler/unify_proc.m:
-	Pass inst_varsets where needed.
+compiler/unused_args.m:
+	Pass inst_varsets and types where needed.
 	Changes to reflect change in definition of the inst data type.
-
-library/array.m:
-library/term.m:
-library/io.m:
-	Temporarily remove the (in, out) versions of some predicates
-	in the array module since they now match_initial with the
-	(array_di, array_uo) versions and cause a `duplicate mode
-	declaration' error.  (`array_di' and `array_uo' are not
-	currently defined as unique modes since unique mode checking
-	has not been fully implemented yet.  Once it has, the (in, out)
-	modes will need to be put back).
-
-	Insert `inst_casts' from `ground' to `uniq_array' in various
-	places to allow bootstrapping of the library without the
-	(in, out) modes.  These casts can be removed once this change
-	has bootstrapped.
--- ./mercury/compiler/accumulator.m	Fri Feb 11 10:44:32 2000
+++ .././mercury/compiler/accumulator.m	Wed Feb 16 16:34:08 2000
@@ -324,18 +324,20 @@
 	proc_info_goal(ProcInfo0, Goal0),
 	proc_info_headvars(ProcInfo0, HeadVars),
 	proc_info_get_initial_instmap(ProcInfo0, ModuleInfo0, InitialInstMap),
+	proc_info_vartypes(ProcInfo0, VarTypes),
 
 	accumulator__simplify(Goal0, Goal),
 	accumulator__rearrange_goal(PredId, ProcId, Goal, InitialInstMap,
-			ModuleInfo0, FullyStrict, GoalType, Base, Rec),
+		ModuleInfo0, VarTypes, FullyStrict, GoalType, Base, Rec),
 
 	accumulator__create_accumulator_pred(Rec, PredInfo0, ProcInfo0,
 			HstoAs_Subst, NewPredId, NewProcId, NewPredName,
 			ModuleInfo0, ModuleInfo1),
 
 	accumulator__transform(GoalType, Base, Rec, Goal, DoLCO, FullyStrict,
-			ModuleInfo1, HeadVars, HstoAs_Subst, NewPredId,
-			NewProcId, NewPredName, OrigGoal, Warnings, AccGoal),
+			ModuleInfo1, HeadVars, VarTypes, HstoAs_Subst,
+			NewPredId, NewProcId, NewPredName, OrigGoal, Warnings,
+			AccGoal),
 
 	accumulator__update_accumulator_pred(NewPredId, NewProcId, AccGoal,
 			ModuleInfo1, ModuleInfo),
@@ -411,11 +413,11 @@
 	% of module.
 	%
 :- pred accumulator__rearrange_goal(pred_id::in, proc_id::in,
-		hlds_goal::in, instmap::in, module_info::in, bool::in,
-		top_level::out, base_goal::out, rec_goal::out) is semidet.
+	hlds_goal::in, instmap::in, module_info::in, vartypes::in,
+	bool::in, top_level::out, base_goal::out, rec_goal::out) is semidet.
 
 accumulator__rearrange_goal(PredId, ProcId, Goal, InitialInstMap, ModuleInfo,
-		FullyStrict, Type, Base, Rec) :-
+		VarTypes, FullyStrict, Type, Base, Rec) :-
 	(
 		Goal = switch(_Var, _CanFail, Cases, _StoreMap) - _GoalInfo,
 		Cases = [case(_IdA, GoalA), case(_IdB, GoalB)],
@@ -425,15 +427,15 @@
 		(
 			accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, [],
-					InitialInstMap, ModuleInfo, FullyStrict,
-					GoalAList, Rec0),
+					InitialInstMap, ModuleInfo, VarTypes,
+					FullyStrict, GoalAList, Rec0),
 
 				% Make sure that the base case doesn't
 				% contain a recursive call.
 			\+ accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, [],
-					InitialInstMap, ModuleInfo, FullyStrict,
-					GoalBList, _)
+					InitialInstMap, ModuleInfo, VarTypes,
+					FullyStrict, GoalBList, _)
 		->
 			Type = switch_rec_base,
 			Base = base(GoalBList),
@@ -441,15 +443,15 @@
 		;
 			accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, [],
-					InitialInstMap, ModuleInfo, FullyStrict,
-					GoalBList, Rec0),
+					InitialInstMap, ModuleInfo, VarTypes,
+					FullyStrict, GoalBList, Rec0),
 
 				% Make sure that the base case doesn't
 				% contain a recursive call.
 			\+ accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, [],
-					InitialInstMap, ModuleInfo, FullyStrict,
-					GoalAList, _)
+					InitialInstMap, ModuleInfo, VarTypes,
+					FullyStrict, GoalAList, _)
 		->
 			Type = switch_base_rec,
 			Base = base(GoalAList),
@@ -466,15 +468,15 @@
 		(
 			accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, [],
-					InitialInstMap, ModuleInfo, FullyStrict,
-					GoalAList, Rec0),
+					InitialInstMap, ModuleInfo, VarTypes,
+					FullyStrict, GoalAList, Rec0),
 
 				% Make sure that the base case doesn't
 				% contain a recursive call.
 			\+ accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, [],
-					InitialInstMap, ModuleInfo, FullyStrict,
-					GoalBList, _)
+					InitialInstMap, ModuleInfo, VarTypes,
+					FullyStrict, GoalBList, _)
 		->
 			Type = disj_rec_base,
 			Base = base(GoalBList),
@@ -482,15 +484,15 @@
 		;
 			accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, [],
-					InitialInstMap, ModuleInfo, FullyStrict,
-					GoalBList, Rec0),
+					InitialInstMap, ModuleInfo, VarTypes,
+					FullyStrict, GoalBList, Rec0),
 
 				% Make sure that the base case doesn't
 				% contain a recursive call.
 			\+ accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, [],
-					InitialInstMap, ModuleInfo, FullyStrict,
-					GoalAList, _)
+					InitialInstMap, ModuleInfo, VarTypes,
+					FullyStrict, GoalAList, _)
 		->
 			Type = disj_base_rec,
 			Base = base(GoalAList),
@@ -514,14 +516,14 @@
 			accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, IfList,
 					BeforeThenInstMap, ModuleInfo,
-					FullyStrict, ThenList, Rec0),
+					VarTypes, FullyStrict, ThenList, Rec0),
 
 				% Make sure that the base case doesn't
 				% contain a recursive call.
 			\+ accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, [],
-					InitialInstMap, ModuleInfo, FullyStrict,
-					ElseList, _)
+					InitialInstMap, ModuleInfo, VarTypes,
+					FullyStrict, ElseList, _)
 		->
 			Type = ite_rec_base,
 			Base = base(ElseList),
@@ -529,15 +531,15 @@
 		;
 			accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, [],
-					InitialInstMap, ModuleInfo, FullyStrict,
-					ElseList, Rec0),
+					InitialInstMap, ModuleInfo, VarTypes,
+					FullyStrict, ElseList, Rec0),
 
 				% Make sure that the base case doesn't
 				% contain a recursive call.
 			\+ accumulator__split_recursive_case(PredId, ProcId,
 					InitialInstMap, [],
-					InitialInstMap, ModuleInfo, FullyStrict,
-					ThenList, _)
+					InitialInstMap, ModuleInfo, VarTypes,
+					FullyStrict, ThenList, _)
 		->
 			Type = ite_base_rec,
 			Base = base(ThenList),
@@ -718,16 +720,16 @@
 	%
 :- pred accumulator__transform(top_level::in, base_goal::in, rec_goal::in,
 		hlds_goal::in, bool::in, bool::in, module_info::in,
-		prog_vars::in, subst::in, pred_id::in,
+		prog_vars::in, vartypes::in, subst::in, pred_id::in,
 		proc_id::in, sym_name::in,
 		hlds_goal::out, warnings::out, hlds_goal::out) is semidet.
 
 accumulator__transform(TopLevel, base(BaseGoalList), recursive(PreDP, DP, R, C),
-		Goal, DoLCO, FullyStrict, ModuleInfo, HeadVars,
+		Goal, DoLCO, FullyStrict, ModuleInfo, HeadVars, VarTypes,
 		HstoAs_Subst, NewPredId, NewProcId, NewPredName,
 		OrigGoal, Warnings, NewGoal) :-
 
-	accumulator__Ys_descended_from_Y0s(HeadVars, DP, ModuleInfo),
+	accumulator__Ys_descended_from_Y0s(HeadVars, DP, VarTypes, ModuleInfo),
 
 	accumulator__orig_base_case(BaseGoalList, OrigBaseGoal),
 
@@ -739,7 +741,7 @@
 			Y0stoYs_Subst, HstoAs_Subst, NewBaseGoal),
 	accumulator__new_recursive_case(DP, C, R, DoLCO, FullyStrict,
 			ModuleInfo, NewPredId, NewProcId, NewPredName,
-			Vars, HeadVars, Y0stoYs_Subst, HstoAs_Subst,
+			Vars, HeadVars, VarTypes, Y0stoYs_Subst, HstoAs_Subst,
 			Warnings, NewRecGoal),
 
 	accumulator__top_level(TopLevel, Goal, OrigBaseGoal, OrigRecGoal,
@@ -866,12 +868,12 @@
 	%
 :- pred accumulator__split_recursive_case(pred_id::in, proc_id::in,
 		instmap::in, hlds_goals::in,
-		instmap::in, module_info::in, bool::in,
+		instmap::in, module_info::in, vartypes::in, bool::in,
 		hlds_goals::in, rec_goal::out) is semidet.
 
-accumulator__split_recursive_case(PredId, ProcId,
-		PreInstMap, PreGoals,
-		InitialInstMap, ModuleInfo, FullyStrict, Goals, RecGoal) :-
+accumulator__split_recursive_case(PredId, ProcId, PreInstMap, PreGoals,
+		InitialInstMap, ModuleInfo, VarTypes, FullyStrict, Goals,
+		RecGoal) :-
 	solutions(accumulator__split_goals(Goals, PredId, ProcId), Solns),
 	Solns = [recursive(DP0, R, C0)],
 	calculate_instmap(DP0, InitialInstMap, InitialInstMapBeforeR),
@@ -881,7 +883,7 @@
 		% that only goals which contain dynamic variables are
 		% left after the recursive call, simplifying the latter
 		% stages.
-	move_goals(R, InitialInstMapBeforeR, ModuleInfo, FullyStrict,
+	move_goals(R, InitialInstMapBeforeR, ModuleInfo, VarTypes, FullyStrict,
 			C0, PreC0, PostC0),
 	list__append(DP0, PreC0, DP),
 	C = PostC0,
@@ -934,31 +936,30 @@
 	% recursive form, much harder to do though.  Look into this
 	% later. NB you need LCO for the else case.
 	%
-:- pred move_goals(hlds_goal::in, instmap::in, module_info::in, bool::in,
-		hlds_goals::in, hlds_goals::out, hlds_goals::out) is det.
+:- pred move_goals(hlds_goal::in, instmap::in, module_info::in, vartypes::in,		bool::in, hlds_goals::in, hlds_goals::out, hlds_goals::out) is det.
 
-move_goals(_StartGoal, _IMBeforeStartGoal, _MI, _FullyStrict, [], [], []).
-move_goals(StartGoal, InstMapBeforeStartGoal, ModuleInfo, FullyStrict,
-		[Goal|Goals], PreGoals, PostGoals) :-
+move_goals(_StartGoal, _IMBeforeStartGoal, _MI, _VT, _FullyStrict, [], [], []).
+move_goals(StartGoal, InstMapBeforeStartGoal, ModuleInfo, VarTypes,
+		FullyStrict, [Goal|Goals], PreGoals, PostGoals) :-
 
 	StartGoal = _GoalExpr - GoalInfo,
 	goal_info_get_instmap_delta(GoalInfo, InstMapDelta),
 	instmap__apply_instmap_delta(InstMapBeforeStartGoal,
 			InstMapDelta, InstMapBeforeGoal),
 	(
-		goal_util__can_reorder_goals(ModuleInfo, FullyStrict,
+		goal_util__can_reorder_goals(ModuleInfo, VarTypes, FullyStrict,
 				InstMapBeforeStartGoal, StartGoal,
 				InstMapBeforeGoal, Goal)
 	->
 		move_goals(StartGoal, InstMapBeforeStartGoal, ModuleInfo,
-				FullyStrict, Goals, PreGoals0, PostGoals),
+			VarTypes, FullyStrict, Goals, PreGoals0, PostGoals),
 		PreGoals = [Goal | PreGoals0]
 	;
-		move_goals(Goal, InstMapBeforeGoal, ModuleInfo, FullyStrict,
-				Goals, PreGoalsForGoal, PostGoalsForGoal),
-		move_goals(StartGoal, InstMapBeforeStartGoal,
-				ModuleInfo, FullyStrict, PreGoalsForGoal,
-				PreGoals, PostGoalsForStartGoal),
+		move_goals(Goal, InstMapBeforeGoal, ModuleInfo, VarTypes,
+			FullyStrict, Goals, PreGoalsForGoal, PostGoalsForGoal),
+		move_goals(StartGoal, InstMapBeforeStartGoal, ModuleInfo,
+			VarTypes, FullyStrict, PreGoalsForGoal, PreGoals,
+			PostGoalsForStartGoal),
 		
 		list__append(PostGoalsForStartGoal, [Goal | PostGoalsForGoal],
 				PostGoals)
@@ -975,11 +976,12 @@
 	% DP, list of goals then it cannot be descended from the Y0s.
 	%
 :- pred accumulator__Ys_descended_from_Y0s(prog_vars::in,
-		a_goals::in, module_info::in) is semidet.
+		a_goals::in, vartypes::in, module_info::in) is semidet.
 
-accumulator__Ys_descended_from_Y0s(HeadVars, DecomposeProcess, ModuleInfo) :-
+accumulator__Ys_descended_from_Y0s(HeadVars, DecomposeProcess, VarTypes,
+		ModuleInfo) :-
 	accumulator__vars_to_accumulate(HeadVars, DecomposeProcess,
-			ModuleInfo, ChangedHeadVars),
+			VarTypes, ModuleInfo, ChangedHeadVars),
 
 	ChangedHeadVars = [].
 
@@ -998,17 +1000,18 @@
 	% that are headvars.
 	%
 :- pred accumulator__vars_to_accumulate(prog_vars::in, a_goals::in,
-		module_info::in, prog_vars::out) is det.
+		vartypes::in, module_info::in, prog_vars::out) is det.
 
-accumulator__vars_to_accumulate(HeadVars, C, ModuleInfo, VarsToAccumulate) :-
+accumulator__vars_to_accumulate(HeadVars, C, VarTypes, ModuleInfo,
+		VarsToAccumulate) :-
 	C = goal(ComposeGoals, InstMapBeforeCompose),
 		
 	goal_list_instmap_delta(ComposeGoals, InstMapDelta),
 	instmap__apply_instmap_delta(InstMapBeforeCompose,
 			InstMapDelta,InstMapAfterCompose),
 
-	instmap_changed_vars(InstMapBeforeCompose,
-			InstMapAfterCompose, ModuleInfo, ChangedVars),
+	instmap_changed_vars(InstMapBeforeCompose, InstMapAfterCompose,
+		VarTypes, ModuleInfo, ChangedVars),
 
 	Member = (pred(M::in) is semidet :- set__member(M, ChangedVars)),
 	list__filter(Member, HeadVars, VarsToAccumulate).
@@ -1052,11 +1055,11 @@
 	%
 	% This predicate is currently unused.
 	%
-:- pred accumulator__static_vars_in_recursive_call(a_goal::in,
-		a_goals::in, module_info::in, prog_vars::out) is det.
+:- pred accumulator__static_vars_in_recursive_call(a_goal::in, a_goals::in,
+		vartypes::in, module_info::in, prog_vars::out) is det.
 
 accumulator__static_vars_in_recursive_call(Recursive, Compose,
-		ModuleInfo, Vars) :-
+		VarTypes, ModuleInfo, Vars) :-
 
 	Recursive = goal(_RecGoalExpr - RecGoalInfo, InstMapBeforeRec),
 	Compose = goal(ComposeGoals, _InstMapBeforeCompose),
@@ -1066,7 +1069,7 @@
 	instmap__apply_instmap_delta(InstMapBeforeRec, RecInstMapDelta,
 			InstMapAfterRec),
 	instmap_changed_vars(InstMapBeforeRec, InstMapAfterRec,
-			ModuleInfo, ChangedVars),
+			VarTypes, ModuleInfo, ChangedVars),
 
 	set__difference(RecNonLocals, ChangedVars, PossibleStaticVars),
 
@@ -1188,20 +1191,20 @@
 :- pred accumulator__new_recursive_case(a_goals::in, a_goals::in,
 		a_goal::in, bool::in, bool::in,
 		module_info::in, pred_id::in, proc_id::in,
-		sym_name::in, prog_vars::in, prog_vars::in, subst::in,
-		subst::in, warnings::out, hlds_goal::out) is semidet.
+		sym_name::in, prog_vars::in, prog_vars::in, vartypes::in,
+		subst::in, subst::in, warnings::out, hlds_goal::out) is semidet.
 
 accumulator__new_recursive_case(DP, C, R0, DoLCO, FullyStrict,
-		ModuleInfo, PredId, ProcId, Name, Hs, HeadVars,
+		ModuleInfo, PredId, ProcId, Name, Hs, HeadVars, VarTypes,
 		Y0stoYs_Subst, HstoAs_Subst, Warnings, Goal) :-
 	DP = goal(DecomposeProcess, _InstMapBeforeDecomposeProcess),
 	C  = goal(Compose, InstMapBeforeCompose),
 	R0 = goal(Recursive0, _InstMapBeforeRecursive0),
 
-	assoc_info_init(ModuleInfo, HeadVars, DP, C, R0,
+	assoc_info_init(ModuleInfo, HeadVars, VarTypes, DP, C, R0,
 		Y0stoYs_Subst, HstoAs_Subst, AssocInfo0),
 	accumulator__check_assoc(Compose, InstMapBeforeCompose, ModuleInfo,
-			FullyStrict, PreRecGoal0, PostRecGoal0,
+			VarTypes, FullyStrict, PreRecGoal0, PostRecGoal0,
 			AssocInfo0, AssocInfo),
 
 	(
@@ -1374,19 +1377,19 @@
 	% that goal into AGs.
 	%
 :- pred accumulator__check_assoc(hlds_goals::in, instmap::in,
-		module_info::in, bool::in, hlds_goals::out,
+		module_info::in, vartypes::in, bool::in, hlds_goals::out,
 		hlds_goals::out, assoc_info::in, assoc_info::out) is semidet.
 
-accumulator__check_assoc([], _InstMap, _MI, _FullyStrict, [], []) --> [].
+accumulator__check_assoc([], _InstMap, _MI, _VT, _FullyStrict, [], []) --> [].
 accumulator__check_assoc([Goal0 | Goal0s], InstMapBeforeGoal0,
-		ModuleInfo, FullyStrict, MovedGoals, AfterGoals) -->
+		ModuleInfo, VarTypes, FullyStrict, MovedGoals, AfterGoals) -->
 	(
 		{ goal_is_construction_unification(Goal0) }
 	->
-		{ move_goals(Goal0, InstMapBeforeGoal0, ModuleInfo, FullyStrict,
-				Goal0s, PreGoal0s, PostGoal0s) },
+		{ move_goals(Goal0, InstMapBeforeGoal0, ModuleInfo, VarTypes,
+			FullyStrict, Goal0s, PreGoal0s, PostGoal0s) },
 		accumulator__check_assoc(PreGoal0s, InstMapBeforeGoal0,
-				ModuleInfo, FullyStrict,
+				ModuleInfo, VarTypes, FullyStrict,
 				MovedGoals, AfterGoal0s),
 		{ list__append(AfterGoal0s, [Goal0 | PostGoal0s], AfterGoals) }
 	;
@@ -1398,7 +1401,7 @@
 
 		accumulator__check_goal(Goal0, Goal),
 		accumulator__check_assoc(Goal0s, InstMapBeforeGoal0s,
-				ModuleInfo, FullyStrict,
+				ModuleInfo, VarTypes, FullyStrict,
 				MovedGoal0s, AfterGoals),
 		{ MovedGoals = [Goal | MovedGoal0s] }
 	).
@@ -1749,12 +1752,14 @@
 
 	proc_info_argmodes(ProcInfo, Modes),
 	pred_info_get_assertions(PredInfo, Assertions),
+	proc_info_vartypes(ProcInfo, VarTypes),
 
 	(
 		commutativity_assertion(set__to_sorted_list(Assertions),
 				ModuleInfo, Args0, PossibleStaticVars0)
 	->
-		check_modes(Args0, PossibleStaticVars0, Modes, ModuleInfo),
+		check_modes(Args0, PossibleStaticVars0, Modes, VarTypes,
+			ModuleInfo),
 		Args = Args0,
 		PossibleStaticVars = PossibleStaticVars0,
 		AssocInfo = AssocInfo0,
@@ -1780,7 +1785,8 @@
 				)
 			), Args0, Args),
 
-		check_modes(Args, PossibleStaticVars, Modes, ModuleInfo),
+		check_modes(Args, PossibleStaticVars, Modes, VarTypes,
+			ModuleInfo),
 
 			% Determine what variables can be static
 		pred_info_module(PredInfo, ModuleName),
@@ -1897,29 +1903,30 @@
 	% doesn't change (ie an in mode).
 	%
 :- pred check_modes(prog_vars::in, set(prog_var)::in,
-		list(mode)::in, module_info::in) is semidet.
+		list(mode)::in, vartypes::in, module_info::in) is semidet.
 
-check_modes([], _, _, _).
-check_modes([V | Vs], PossibleStaticVars, [M | Ms], ModuleInfo) :-
+check_modes([], _, _, _, _).
+check_modes([V | Vs], PossibleStaticVars, [M | Ms], VarTypes, ModuleInfo) :-
 	(
 		set__member(V, PossibleStaticVars)
 	->
 		mode_get_insts(ModuleInfo, M, InitialInst, FinalInst),
-		inst_matches_final(InitialInst, FinalInst, ModuleInfo)
+		map__lookup(VarTypes, V, Type),
+		inst_matches_final(InitialInst, FinalInst, Type, ModuleInfo)
 	;
 		true
 	),
-	check_modes(Vs, PossibleStaticVars, Ms, ModuleInfo).
+	check_modes(Vs, PossibleStaticVars, Ms, VarTypes, ModuleInfo).
 
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-:- pred assoc_info_init(module_info::in, prog_vars::in, a_goals::in,
-		a_goals::in, a_goal::in,
+:- pred assoc_info_init(module_info::in, prog_vars::in, vartypes::in,
+		a_goals::in, a_goals::in, a_goal::in,
 		subst::in, subst::in, assoc_info::out) is det.
 
-assoc_info_init(ModuleInfo, HeadVars, DP, Compose, R, Y0stoYs_Subst,
+assoc_info_init(ModuleInfo, HeadVars, VarTypes, DP, Compose, R, Y0stoYs_Subst,
 		HstoAs_Subst, AssocInfo) :-
 	DP = goal(Decompose, _InstMapBeforeDecomposeProcess),
 	R = goal(_RecGoalExpr - RecGoalInfo, _InstMapBeforeRecursive),
@@ -1930,7 +1937,8 @@
 		% Set up the OrigDynVarMap
 		%
 	reverse_subst(Y0stoYs_Subst, YstoY0s_Subst),
-	accumulator__vars_to_accumulate(HeadVars, Compose, ModuleInfo, Ys),
+	accumulator__vars_to_accumulate(HeadVars, Compose, VarTypes,
+		ModuleInfo, Ys),
 	list__map(map__lookup(YstoY0s_Subst), Ys, Y0s),
 
 	assoc_list__from_corresponding_lists(Y0s, Y0s, AssocDynamicList),
--- ./mercury/compiler/common.m	Fri Feb 11 10:44:41 2000
+++ .././mercury/compiler/common.m	Wed Feb 16 15:07:36 2000
@@ -402,12 +402,13 @@
 	(
 		goal_info_get_determinism(GoalInfo, Det),
 		common__check_call_detism(Det),
+		simplify_info_get_var_types(Info0, VarTypes),
 		simplify_info_get_module_info(Info0, ModuleInfo),
 		module_info_pred_proc_info(ModuleInfo, PredId,
 			ProcId, _, ProcInfo),
 		proc_info_argmodes(ProcInfo, ArgModes),
-	    	common__partition_call_args(ModuleInfo, ArgModes, Args,
-			InputArgs, OutputArgs, OutputModes)
+	    	common__partition_call_args(VarTypes, ModuleInfo, ArgModes,
+	    		Args, InputArgs, OutputArgs, OutputModes)
 	->
 		common__optimise_call_2(seen_call(PredId, ProcId), InputArgs,
 			OutputArgs, OutputModes, Goal0, GoalInfo, Goal,
@@ -421,8 +422,9 @@
 		GoalInfo, Goal, Info0, Info) :-
 	(
 		common__check_call_detism(Det),
+		simplify_info_get_var_types(Info0, VarTypes),
 		simplify_info_get_module_info(Info0, ModuleInfo),
-	    	common__partition_call_args(ModuleInfo, Modes, Args,
+	    	common__partition_call_args(VarTypes, ModuleInfo, Modes, Args,
 			InputArgs, OutputArgs, OutputModes)
 	->
 		common__optimise_call_2(higher_order_call,
@@ -516,21 +518,22 @@
 	% Partition the arguments of a call into inputs and outputs,
 	% failing if any of the outputs have a unique component
 	% or if any of the outputs contain any `any' insts.
-:- pred common__partition_call_args(module_info::in, list(mode)::in,
-		list(prog_var)::in, list(prog_var)::out,
+:- pred common__partition_call_args(vartypes::in, module_info::in,
+		list(mode)::in, list(prog_var)::in, list(prog_var)::out,
 		list(prog_var)::out, list(mode)::out) is semidet.
 
-common__partition_call_args(_, [], [_ | _], _, _, _) :-
+common__partition_call_args(_, _, [], [_ | _], _, _, _) :-
 	error("common__partition_call_args").
-common__partition_call_args(_, [_ | _], [], _, _, _) :-
+common__partition_call_args(_, _, [_ | _], [], _, _, _) :-
 	error("common__partition_call_args").
-common__partition_call_args(_, [], [], [], [], []).
-common__partition_call_args(ModuleInfo, [ArgMode | ArgModes], [Arg | Args],
-		InputArgs, OutputArgs, OutputModes) :-
-	common__partition_call_args(ModuleInfo, ArgModes, Args,
+common__partition_call_args(_, _, [], [], [], [], []).
+common__partition_call_args(VarTypes, ModuleInfo, [ArgMode | ArgModes],
+		[Arg | Args], InputArgs, OutputArgs, OutputModes) :-
+	common__partition_call_args(VarTypes, ModuleInfo, ArgModes, Args,
 		InputArgs1, OutputArgs1, OutputModes1),
 	mode_get_insts(ModuleInfo, ArgMode, InitialInst, FinalInst),
-	( inst_matches_binding(InitialInst, FinalInst, ModuleInfo) ->
+	map__lookup(VarTypes, Arg, Type),
+	( inst_matches_binding(InitialInst, FinalInst, Type, ModuleInfo) ->
 		InputArgs = [Arg | InputArgs1],
 		OutputArgs = OutputArgs1,
 		OutputModes = OutputModes1
@@ -544,7 +547,7 @@
 		% between the different variables.
 		% (inst_matches_binding applied to identical insts
 		% fails only for `any' insts.)
-		inst_matches_binding(FinalInst, FinalInst, ModuleInfo),
+		inst_matches_binding(FinalInst, FinalInst, Type, ModuleInfo),
 
 		% Don't optimize calls where a partially instantiated
 		% variable is further instantiated. That case is difficult
--- ./mercury/compiler/det_analysis.m	Fri Feb 11 10:44:46 2000
+++ .././mercury/compiler/det_analysis.m	Thu Feb 17 14:48:56 2000
@@ -257,7 +257,8 @@
 		% Infer the determinism of the goal
 	proc_info_goal(Proc0, Goal0),
 	proc_info_get_initial_instmap(Proc0, ModuleInfo0, InstMap0),
-	det_info_init(ModuleInfo0, PredId, ProcId, Globals, DetInfo),
+	proc_info_vartypes(Proc0, VarTypes),
+	det_info_init(ModuleInfo0, VarTypes, PredId, ProcId, Globals, DetInfo),
 	det_infer_goal(Goal0, InstMap0, SolnContext, DetInfo,
 			Goal, Detism1, Msgs),
 
--- ./mercury/compiler/det_report.m	Fri Feb 11 10:44:47 2000
+++ .././mercury/compiler/det_report.m	Thu Feb 17 15:04:48 2000
@@ -179,9 +179,10 @@
 				ProcId, ModuleInfo1, Message,
 				DeclaredDetism, InferredDetism),
 			{ proc_info_goal(ProcInfo0, Goal) },
+			{ proc_info_vartypes(ProcInfo0, VarTypes) },
 			globals__io_get_globals(Globals),
-			{ det_info_init(ModuleInfo1, PredId, ProcId, Globals,
-				DetInfo) },
+			{ det_info_init(ModuleInfo1, VarTypes, PredId, ProcId,
+				Globals, DetInfo) },
 			det_diagnose_goal(Goal, DeclaredDetism, [], DetInfo, _)
 			% XXX with the right verbosity options, we want to
 			% call report_determinism_problem only if diagnose
@@ -1262,7 +1263,10 @@
 	hlds_out__write_determinism(InferredDetism),
 	io__write_string("'.\n"),
 	globals__io_get_globals(Globals),
-	{ det_info_init(ModuleInfo, PredId, ProcId, Globals, DetInfo) },
+	{ module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _, ProcInfo) },
+	{ proc_info_vartypes(ProcInfo, VarTypes) },
+	{ det_info_init(ModuleInfo, VarTypes, PredId, ProcId, Globals,
+		DetInfo) },
 	det_diagnose_goal(Goal, DeclaredDetism, [], DetInfo, _),
 	io__set_exit_status(1).
 det_report_msg(par_conj_not_det(InferredDetism, PredId,
@@ -1289,7 +1293,10 @@
 	prog_out__write_context(Context),
 	io__write_string("  non-failing parallel conjunctions.\n"),
 	globals__io_get_globals(Globals),
-	{ det_info_init(ModuleInfo, PredId, ProcId, Globals, DetInfo) },
+	{ module_info_pred_proc_info(ModuleInfo, PredId, ProcId, _, ProcInfo) },
+	{ proc_info_vartypes(ProcInfo, VarTypes) },
+	{ det_info_init(ModuleInfo, VarTypes, PredId, ProcId, Globals,
+		DetInfo) },
 	det_diagnose_conj(Goals, det, [], DetInfo, _),
 	io__set_exit_status(1).
 det_report_msg(pragma_c_code_without_det_decl(PredId, ProcId),
--- ./mercury/compiler/det_util.m	Fri Feb 11 10:44:47 2000
+++ .././mercury/compiler/det_util.m	Thu Feb 17 14:54:48 2000
@@ -61,8 +61,9 @@
 :- pred det_no_output_vars(set(prog_var), instmap, instmap_delta, det_info).
 :- mode det_no_output_vars(in, in, in, in) is semidet.
 
-:- pred det_info_init(module_info, pred_id, proc_id, globals, det_info).
-:- mode det_info_init(in, in, in, in, out) is det.
+:- pred det_info_init(module_info, vartypes, pred_id, proc_id, globals,
+		det_info).
+:- mode det_info_init(in, in, in, in, in, out) is det.
 
 :- pred det_info_get_module_info(det_info, module_info).
 :- mode det_info_get_module_info(in, out) is det.
@@ -85,6 +86,9 @@
 :- pred det_info_set_module_info(det_info, module_info, det_info).
 :- mode det_info_set_module_info(in, in, out) is det.
 
+:- func vartypes(det_info) = vartypes.
+:- func 'vartypes:='(det_info, vartypes) = det_info.
+
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -152,32 +156,35 @@
 
 det_no_output_vars(Vars, InstMap, InstMapDelta, DetInfo) :-
 	det_info_get_module_info(DetInfo, ModuleInfo),
-	instmap__no_output_vars(InstMap, InstMapDelta, Vars, ModuleInfo).
+	instmap__no_output_vars(InstMap, InstMapDelta, Vars, DetInfo^vartypes,
+		ModuleInfo).
 
 %-----------------------------------------------------------------------------%
 
-:- type det_info	--->	det_info(
-					module_info,
-					pred_id,	% the id of the proc
-					proc_id, 	% currently processed
-					bool,		% --reorder-conj
-					bool,		% --reorder-disj
-					bool		% --fully-strict
-				).
+:- type det_info	
+	--->	det_info(
+		module_info :: module_info,
+		vartypes :: vartypes,
+		pred_id :: pred_id,	% the id of the proc
+		proc_id :: proc_id, 	% currently processed
+		reorder_conj :: bool,	% --reorder-conj
+		reorder_disj :: bool,	% --reorder-disj
+		fully_strict :: bool	% --fully-strict
+	).
 
-det_info_init(ModuleInfo, PredId, ProcId, Globals, DetInfo) :-
+det_info_init(ModuleInfo, VarTypes, PredId, ProcId, Globals, DetInfo) :-
 	globals__lookup_bool_option(Globals, reorder_conj, ReorderConj),
 	globals__lookup_bool_option(Globals, reorder_disj, ReorderDisj),
 	globals__lookup_bool_option(Globals, fully_strict, FullyStrict),
-	DetInfo = det_info(ModuleInfo, PredId, ProcId,
+	DetInfo = det_info(ModuleInfo, VarTypes, PredId, ProcId,
 		ReorderConj, ReorderDisj, FullyStrict).
 
-det_info_get_module_info(det_info(ModuleInfo, _, _, _, _, _), ModuleInfo).
-det_info_get_pred_id(det_info(_, PredId, _, _, _, _), PredId).
-det_info_get_proc_id(det_info(_, _, ProcId, _, _, _), ProcId).
-det_info_get_reorder_conj(det_info(_, _, _, ReorderConj, _, _), ReorderConj).
-det_info_get_reorder_disj(det_info(_, _, _, _, ReorderDisj, _), ReorderDisj).
-det_info_get_fully_strict(det_info(_, _, _, _, _, FullyStrict), FullyStrict).
+det_info_get_module_info(DetInfo, DetInfo^module_info).
+det_info_get_pred_id(DetInfo, DetInfo^pred_id).
+det_info_get_proc_id(DetInfo, DetInfo^proc_id).
+det_info_get_reorder_conj(DetInfo, DetInfo^reorder_conj).
+det_info_get_reorder_disj(DetInfo, DetInfo^reorder_disj).
+det_info_get_fully_strict(DetInfo, DetInfo^fully_strict).
 
-det_info_set_module_info(det_info(_, B, C, D, E, F), ModuleInfo,
-		det_info(ModuleInfo, B, C, D, E, F)).
+det_info_set_module_info(DetInfo, ModuleInfo,
+		DetInfo^module_info := ModuleInfo).
--- ./mercury/compiler/goal_util.m	Fri Feb 11 10:44:54 2000
+++ .././mercury/compiler/goal_util.m	Wed Feb 16 16:30:56 2000
@@ -179,8 +179,8 @@
 	% - any possible change in termination behaviour is allowed
 	% 	according to the semantics options.
 	%
-:- pred goal_util__can_reorder_goals(module_info::in, bool::in, instmap::in,
-		hlds_goal::in, instmap::in, hlds_goal::in) is semidet.
+:- pred goal_util__can_reorder_goals(module_info::in, vartypes::in, bool::in,
+	instmap::in, hlds_goal::in, instmap::in, hlds_goal::in) is semidet.
 
 	% goal_util__reordering_maintains_termination(ModuleInfo,
 	%		 FullyStrict, Goal1, Goal2)
@@ -1036,8 +1036,9 @@
 %-----------------------------------------------------------------------------%
 
 
-goal_util__can_reorder_goals(ModuleInfo, FullyStrict, InstmapBeforeEarlierGoal,
-		EarlierGoal, InstmapBeforeLaterGoal, LaterGoal) :-
+goal_util__can_reorder_goals(ModuleInfo, VarTypes, FullyStrict,
+		InstmapBeforeEarlierGoal, EarlierGoal, InstmapBeforeLaterGoal,
+		LaterGoal) :-
 
 	EarlierGoal = _ - EarlierGoalInfo,
 	LaterGoal = _ - LaterGoalInfo,
@@ -1054,7 +1055,7 @@
 	% on the outputs of the current goal.
 	%
 	\+ goal_depends_on_earlier_goal(LaterGoal, EarlierGoal,
-			InstmapBeforeEarlierGoal, ModuleInfo),
+			InstmapBeforeEarlierGoal, VarTypes, ModuleInfo),
 
 	%
 	% Don't reorder the goals if the later goal changes the 
@@ -1064,7 +1065,7 @@
 	% full mode analysis in other cases.
 	%
 	\+ goal_depends_on_earlier_goal(EarlierGoal, LaterGoal, 
-			InstmapBeforeLaterGoal, ModuleInfo).
+			InstmapBeforeLaterGoal, VarTypes, ModuleInfo).
 
 
 goal_util__reordering_maintains_termination(ModuleInfo, FullyStrict, 
@@ -1103,17 +1104,17 @@
 	%
 	% This code does work on the alias branch.
 	%
-:- pred goal_depends_on_earlier_goal(hlds_goal::in,
-		hlds_goal::in, instmap::in, module_info::in) is semidet.
+:- pred goal_depends_on_earlier_goal(hlds_goal::in, hlds_goal::in, instmap::in,
+		vartypes::in, module_info::in) is semidet.
 
 goal_depends_on_earlier_goal(_ - LaterGoalInfo, _ - EarlierGoalInfo,
-		InstMapBeforeEarlierGoal, ModuleInfo) :-
+		InstMapBeforeEarlierGoal, VarTypes, ModuleInfo) :-
 	goal_info_get_instmap_delta(EarlierGoalInfo, EarlierInstMapDelta),
 	instmap__apply_instmap_delta(InstMapBeforeEarlierGoal,
 			EarlierInstMapDelta, InstMapAfterEarlierGoal),
 
 	instmap_changed_vars(InstMapBeforeEarlierGoal, InstMapAfterEarlierGoal,
-			ModuleInfo, EarlierChangedVars),
+			VarTypes, ModuleInfo, EarlierChangedVars),
 
 	goal_info_get_nonlocals(LaterGoalInfo, LaterGoalNonLocals),
 	set__intersect(EarlierChangedVars, LaterGoalNonLocals, Intersection),
--- ./mercury/compiler/hlds_data.m	Fri Feb 11 10:44:56 2000
+++ .././mercury/compiler/hlds_data.m	Fri Feb 18 16:03:54 2000
@@ -435,7 +435,7 @@
 	--->	hlds_inst_defn(
 			inst_varset,		% The names of the inst
 						% parameters (if any).
-			list(inst_param),	% The inst parameters (if any).
+			list(inst_var),		% The inst parameters (if any).
 						% ([I] in the above example.)
 			hlds_inst_body,	% The definition of this inst.
 			condition,		% Unused (reserved for
@@ -632,7 +632,7 @@
 	--->	hlds_mode_defn(
 			inst_varset,		% The names of the inst
 						% parameters (if any).
-			list(inst_param),	% The list of the inst
+			list(inst_var),		% The list of the inst
 						% parameters (if any).
 						% (e.g. [I] for the second
 						% example above.)
--- ./mercury/compiler/hlds_pred.m	Fri Feb 11 10:44:59 2000
+++ .././mercury/compiler/hlds_pred.m	Tue Feb 15 14:23:12 2000
@@ -1548,9 +1548,6 @@
 
 :- type proc_info
 	--->	procedure(
-			declared_determinism :: maybe(determinism),
-					% _declared_ determinism
-					% or `no' if there was no detism decl
 			varset :: prog_varset,	% variable names
 			vartypes :: vartypes,	% variable types
 			headvars :: list(prog_var),	% head vars
@@ -1565,6 +1562,9 @@
 					% (or the context of the first clause,
 					% if there was no mode declaration).
 			stack_slots :: stack_slots,	% stack allocations
+			declared_determinism :: maybe(determinism),
+					% _declared_ determinism
+					% or `no' if there was no detism decl
 			inferred_determinism :: determinism,
 					% _inferred_ determinism
 			can_process :: bool,
@@ -1646,8 +1646,8 @@
 	map__init(TCVarsMap),
 	RLExprn = no,
 	NewProc = procedure(
-		MaybeDet, BodyVarSet, BodyTypes, HeadVars, Modes, InstVarSet,
-		MaybeArgLives, ClauseBody, MContext, StackSlots,
+		BodyVarSet, BodyTypes, HeadVars, Modes, InstVarSet,
+		MaybeArgLives, ClauseBody, MContext, StackSlots, MaybeDet,
 		InferredDet, CanProcess, ArgInfo, InitialLiveness,
 		TVarsMap, TCVarsMap, eval_normal, no, no, DeclaredModes,
 		IsAddressTaken, RLExprn
@@ -1660,9 +1660,9 @@
 		ProcInfo) :-
 	RLExprn = no,
 	ProcInfo = procedure(
-		DeclaredDetism, BodyVarSet, BodyTypes, HeadVars,
+		BodyVarSet, BodyTypes, HeadVars,
 		HeadModes, InstVarSet, HeadLives, Goal, Context,
-		StackSlots, InferredDetism, CanProcess, ArgInfo,
+		StackSlots, DeclaredDetism, InferredDetism, CanProcess, ArgInfo,
 		Liveness, TVarMap, TCVarsMap, eval_normal, ArgSizes,
 		Termination, no, IsAddressTaken, RLExprn).
 
@@ -1672,9 +1672,9 @@
 	set__init(Liveness),
 	MaybeHeadLives = no,
 	RLExprn = no,
-	ProcInfo = procedure(yes(Detism), VarSet, VarTypes, HeadVars, HeadModes,
+	ProcInfo = procedure(VarSet, VarTypes, HeadVars, HeadModes,
 		InstVarSet, MaybeHeadLives, Goal, Context, StackSlots,
-		Detism, yes, [], Liveness, TVarMap, TCVarsMap,
+		yes(Detism), Detism, yes, [], Liveness, TVarMap, TCVarsMap,
 		eval_normal, no, no, no, IsAddressTaken, RLExprn).
 
 proc_info_set_body(ProcInfo0, VarSet, VarTypes, HeadVars, Goal,
@@ -1784,72 +1784,6 @@
 proc_info_is_address_taken(ProcInfo, ProcInfo^is_address_taken).
 
 proc_info_get_rl_exprn_id(ProcInfo, ProcInfo^rl_exprn_id).
-
-% :- type proc_info
-% 	--->	procedure(
-% A			maybe(determinism),
-% 					% _declared_ determinism
-% 					% or `no' if there was no detism decl
-% B			varset,		% variable names
-% C 			map(var, type),	% variable types
-% D			list(prog_var),	% head vars
-% E			list(mode), 	% modes of args
-% F			maybe(list(is_live)),
-% 					% liveness (in the mode analysis sense)
-% 					% of the arguments
-% G			hlds_goal,	% Body
-% H			prog_context,
-%					% The context of the `:- mode' decl
-% 					% (or the context of the first clause,
-% 					% if there was no mode declaration).
-% I			stack_slots,	% stack allocations
-% J			determinism,	% _inferred_ determinism
-% K			bool,		% no if we must not process this
-% 					% procedure yet (used to delay
-% 					% mode checking etc. for complicated
-% 					% modes of unification procs until
-% 					% the end of the unique_modes pass.)
-% L			list(arg_info),	% calling convention of each arg:
-% 					% information computed by arg_info.m
-% 					% (based on the modes etc.)
-% 					% and used by code generation
-% 					% to determine how each argument
-% 					% should be passed.
-% M			liveness_info,	% the initial liveness,
-% 					% for code generation
-% N			type_info_varmap,	
-% 					% typeinfo vars for type parameters
-% O			typeclass_info_varmap,
-% 					% typeclass_info vars for class
-% 					% constraints
-% P			eval_method,
-%					% info on how the proc sould be 
-%					% evaluated
-% Q			maybe(arg_size_info),
-% 					% Information about the relative sizes
-% 					% of the input and output args of the
-% 					% procedure. Set by termination
-% 					% analysis.
-% R			maybe(termination_info),
-% 					% The termination properties of the
-% 					% procedure. Set by termination
-% 					% analysis.
-% S			maybe(list(mode)),
-% 					% declared modes of arguments.
-% T			is_address_taken
-%					% Is the address of this procedure
-%					% taken? If yes, we will need to use
-%					% typeinfo liveness for them, so that
-%					% deep_copy and accurate gc have the
-%					% RTTI they need for copying closures.
-% U			maybe(rl_exprn_id)
-%					% For predicates with an
-%					% `aditi_top_down' marker, which are
-%					% executed top-down on the Aditi side
-%					% of the connection, we generate an RL
-%					% expression, for which this is an
-%					% identifier. See rl_update.m.
-%		).
 
 proc_info_set_varset(ProcInfo, X, ProcInfo^varset := X).
 
--- ./mercury/compiler/inst.m	Fri Feb 11 10:44:59 2000
+++ .././mercury/compiler/inst.m	Tue Feb 15 14:29:05 2000
@@ -1,5 +1,5 @@
 %-----------------------------------------------------------------------------%
-% Copyright (C) 1997, 2000 The University of Melbourne.
+% Copyright (C) 1997, 1999-2000 The University of Melbourne.
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
@@ -35,8 +35,8 @@
 	;		bound(uniqueness, list(bound_inst))
 				% The list(bound_inst) must be sorted
 	;		ground(uniqueness, ground_inst_info)
-				% The pred_inst_info is used for
-				% higher-order pred modes
+				% The ground_inst_info holds extra information
+				% about the ground inst.
 	;		not_reached
 	;		inst_var(inst_var)
 				% A defined_inst is possibly recursive
@@ -65,13 +65,18 @@
 					% on backtracking, so we will need to
 					% restore the old value on backtracking
 
+	% The ground_inst_info type gives extra information about ground insts.
 :- type ground_inst_info
 	--->	higher_order(pred_inst_info)
+			% The ground inst is higher-order.
 	;	constrained_inst_var(inst_var)
+			% The ground inst is an inst variable that is
+			% constrained to be ground.
 	;	none.
+			% No extra information is available.
 
 	% higher-order predicate terms are given the inst
-	%	`ground(shared, yes(PredInstInfo))'
+	%	`ground(shared, higher_order(PredInstInfo))'
 	% where the PredInstInfo contains the extra modes and the determinism
 	% for the predicate.  Note that the higher-order predicate term
 	% itself must be ground.
-- 
David Overton       Department of Computer Science & Software Engineering
PhD Student         The University of Melbourne, Australia
+61 3 8344 9159     http://www.cs.mu.oz.au/~dmo
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list