[m-rev.] for post-commit review: speed up the compilation of large predicates

Zoltan Somogyi zs at cs.mu.OZ.AU
Mon May 23 12:45:04 AEST 2005


Fix several performance problems that arose when compiling predicates defined
by lots of facts, e.g. 16000 facts of the edge relation used in my recent
paper with Kostis on tabling. We couldn't use fact tables because they return
solutions in a different order, which would be OK semantically but which
invalidated the performance comparison we tried to make. I had to either fix
fact tables to use standard order or fix the performance problems of the usual
path of compilation. The latter is more generally useful, and reduces the
chances of any similar surprises.

The first performance problem was the quadratic complexity of always adding
clauses at the end of the clause list. The fix is to keep the list in reverse
order while it is being added to. This takes the time to read in the 16000-fact
predicate from 80+s to ~1s.

The second performance problem was our use of generate/test to check whether
any clause had impure code when copying the clauses to procs. Since we don't
have tail recursion for model_non code, this couldn't reuse stack frames, and
as a result ran at memory speed, not cache speed. The fix is to use an explicit
recursive predicate. (A better fix would be to implement proper tail recursion
for model_non code, but that would take significantly longer.) This fix
doesn't make much difference in the usual grades, but makes a significant
difference in debug grades.

The third performance problem is the quadratic or worse behavior of the mode
checker when merging the instmaps of disjuncts at the ends of large
disjunctions. With our old setup, this was inevitable, since given a bunch of
facts of the form

	edge(1, 2).
	edge(2, 3).
	edge(3, 4).
	...

etc, the instmap delta the mode checker builds for HeadVar__1 for the
disjunction of clauses is free -> bound(1; 2; 3; ...). The solution to that
is to add a new pragma, mode_check_clauses, that causes the mode checker
to check each clause individually, and to create a simple free -> ground
(or whatever the declared mode calls for) instmap delta for HeadVar__1.
We should consider making this pragma be implied for predicates defined
by lots of facts, but this diff does not do that. This change takes the
time to modecheck that 16000-fact predicate from ~360s to ~5s.

Theoretically, another way of tackling the problem would have been to
introduce widening, in which any list of functors inside "bound()" whose
length was above the threshold would be replaced by "ground", if the arguments
of the functors themselves were bound. However, that change would be much more
complex, and its behavior would be hard for users to predict. In a future
constraint-based mode system with separate passes for computing
producers/consumers and for computing the set of function symbols a
variable can be bound to, we could simply disable the latter pass
for predicates like this.

There are at least three other performance problems left. The fourth is
the same as the third, except for unique mode checking. The fifth is in
simplification, and the sixth is in equiv_type_hlds. I'll work on those next.

compiler/hlds_pred.m:
	Instead of exposing the clause list part of the clause_info, make it
	an abstract type. Make the abstract type keep the reverse list when
	adding clauses to the list, the forward list when the later parts
	of the compiler manipulate the clause list, and both when it is
	convenient to do so. Add the predicates necessary to manipulate
	this more complex representation. Move the code manipulating
	clauses_infos into its own implementation section, next to its
	declarations.

	Add a new mode_check_clauses predicate marker, which records the
	presence of the new pragma.

	Fix departures from our coding standard.

compiler/clause_to_proc.m:
	Replace the generate/test code with an explicit loop, as
	mentioned above.

compiler/prog_data.m:
	Add the new pragma.

compiler/prog_io_pragma.m:
	Recognize the new pragma.

compiler/modes.m:
	Implement separate mode checking of clauses.

	Convert the file to use four-space indentation to reduce the number of
	bad line breaks. Give some predicates more meaningful names.
	Use error_util to print some error messages. Fix departures from
	our coding standard.

compiler/make_hlds.m:
compiler/hlds_out.m:
compiler/intermod.m:
compiler/mercury_to_mercury.m:
compiler/module_qual.m:
compiler/modules.m:
compiler/recompilation.version.m:
	Handle the new pragma.

compiler/*.m:
	Conform to the change in hlds_pred.m and/or prog_data.m.
	In some cases, convert files to four-space indentation.

tests/hard_coded/mode_check_clauses.{m,exp}:
	A new test case to check that the mode_check_clauses pragma works
	correctly.

tests/hard_coded/Mmakefile:
	Enable the new test case.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/assertion.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/assertion.m,v
retrieving revision 1.35
diff -u -b -r1.35 assertion.m
--- compiler/assertion.m	24 Mar 2005 05:33:58 -0000	1.35
+++ compiler/assertion.m	21 May 2005 06:09:13 -0000
@@ -484,7 +484,7 @@
 	assertion_table_lookup(AssertTable, AssertId, PredId),
 	module_info_pred_info(Module, PredId, PredInfo),
 	pred_info_clauses_info(PredInfo, ClausesInfo),
-	clauses_info_clauses(ClausesInfo, Clauses),
+	clauses_info_clauses_only(ClausesInfo, Clauses),
 	( Clauses = [clause(_ProcIds, Goal0, _Lang, _Context)] ->
 		assertion__normalise_goal(Goal0, Goal)
 	;
Index: compiler/clause_to_proc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/clause_to_proc.m,v
retrieving revision 1.46
diff -u -b -r1.46 clause_to_proc.m
--- compiler/clause_to_proc.m	24 Mar 2005 02:00:16 -0000	1.46
+++ compiler/clause_to_proc.m	21 May 2005 10:05:00 -0000
@@ -157,8 +157,9 @@
 	copy_clauses_to_procs_2(ProcIds, ClausesInfo, Procs1, Procs).
 
 copy_clauses_to_proc(ProcId, ClausesInfo, !Proc) :-
-	ClausesInfo = clauses_info(VarSet0, _, _, VarTypes, HeadVars, Clauses,
-		TI_VarMap, TCI_VarMap, _),
+	ClausesInfo = clauses_info(VarSet0, _, _, VarTypes, HeadVars,
+		ClausesRep, TI_VarMap, TCI_VarMap, _),
+	get_clause_list(ClausesRep, Clauses),
 	select_matching_clauses(Clauses, ProcId, MatchingClauses),
 	get_clause_goals(MatchingClauses, GoalList),
 	( GoalList = [SingleGoal] ->
@@ -208,10 +209,7 @@
 		% The disjunction is impure/semipure if any of the disjuncts
 		% is impure/semipure.
 		%
-		(
-			list__member(_SubGoal - SubGoalInfo, GoalList),
-			\+ goal_info_is_pure(SubGoalInfo)
-		->
+		( contains_nonpure_goal(GoalList) ->
 			list__map(get_purity, GoalList, PurityList),
 			Purity = list__foldl(worst_purity, PurityList, (pure)),
 			add_goal_info_purity_feature(GoalInfo2, Purity,
@@ -225,6 +223,16 @@
 	proc_info_set_body(VarSet, VarTypes, HeadVars, Goal,
 		TI_VarMap, TCI_VarMap, !Proc).
 
+:- pred contains_nonpure_goal(list(hlds_goal)::in) is semidet.
+
+contains_nonpure_goal([Goal | Goals]) :-
+	(
+		Goal = _ - GoalInfo,
+		\+ goal_info_is_pure(GoalInfo)
+	;
+		contains_nonpure_goal(Goals)
+	).
+
 :- func set_arg_names(foreign_arg, prog_varset) = prog_varset.
 
 set_arg_names(foreign_arg(Arg, MaybeNameMode, _), Vars0) = Vars :-
@@ -261,7 +269,7 @@
 
 get_clause_goals([], []).
 get_clause_goals([Clause | Clauses], Goals) :-
+	get_clause_goals(Clauses, Goals1),
 	Clause = clause(_, Goal, _, _),
 	goal_to_disj_list(Goal, GoalList),
-	list__append(GoalList, Goals1, Goals),
-	get_clause_goals(Clauses, Goals1).
+	list__append(GoalList, Goals1, Goals).
Index: compiler/dead_proc_elim.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dead_proc_elim.m,v
retrieving revision 1.99
diff -u -b -r1.99 dead_proc_elim.m
--- compiler/dead_proc_elim.m	20 Apr 2005 12:57:09 -0000	1.99
+++ compiler/dead_proc_elim.m	21 May 2005 07:30:32 -0000
@@ -860,7 +860,8 @@
 				Needed, NeededNames),
 			module_info_pred_info(ModuleInfo, PredId, PredInfo),
 			pred_info_clauses_info(PredInfo, ClausesInfo),
-			clauses_info_clauses(ClausesInfo, Clauses),
+			clauses_info_clauses_rep(ClausesInfo, ClausesRep),
+			get_clause_list_any_order(ClausesRep, Clauses),
 			list__foldl(dead_pred_elim_process_clause, Clauses,
 				DeadInfo1, DeadInfo2)
 		),
Index: compiler/dependency_graph.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dependency_graph.m,v
retrieving revision 1.76
diff -u -b -r1.76 dependency_graph.m
--- compiler/dependency_graph.m	24 Mar 2005 05:34:00 -0000	1.76
+++ compiler/dependency_graph.m	21 May 2005 07:27:20 -0000
@@ -346,7 +346,8 @@
 		true
 	;
 		pred_info_clauses_info(PredInfo, ClausesInfo),
-		clauses_info_clauses(ClausesInfo, Clauses),
+		clauses_info_clauses_rep(ClausesInfo, ClausesRep),
+		get_clause_list_any_order(ClausesRep, Clauses),
 		Goals = list__map(func(clause(_, Goal, _, _)) = Goal, Clauses),
 		relation__lookup_element(!.DepGraph, PredId, Caller),
 		dependency_graph__add_arcs_in_list(Goals, Caller, !DepGraph)
Index: compiler/goal_path.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_path.m,v
retrieving revision 1.24
diff -u -b -r1.24 goal_path.m
--- compiler/goal_path.m	1 Apr 2005 14:28:55 -0000	1.24
+++ compiler/goal_path.m	21 May 2005 05:42:52 -0000
@@ -72,7 +72,7 @@
 
 goal_path__fill_slots_in_clauses(ModuleInfo, OmitModeEquivPrefix, !PredInfo) :-
 	pred_info_clauses_info(!.PredInfo, ClausesInfo0),
-	clauses_info_clauses(ClausesInfo0, Clauses0),
+	clauses_info_clauses_only(ClausesInfo0, Clauses0),
 	clauses_info_vartypes(ClausesInfo0, VarTypes),
 	SlotInfo = slot_info(VarTypes, ModuleInfo, OmitModeEquivPrefix),
 	list__map_foldl(fill_slots_in_clause(SlotInfo), Clauses0, Clauses,
Index: compiler/hhf.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hhf.m,v
retrieving revision 1.6
diff -u -b -r1.6 hhf.m
--- compiler/hhf.m	24 Mar 2005 05:34:02 -0000	1.6
+++ compiler/hhf.m	21 May 2005 06:09:57 -0000
@@ -126,7 +126,7 @@
 	Info0 = hhf_info(InstGraph0, VarSet0, VarTypes0),
 
 	clauses_info_headvars(!.ClausesInfo, HeadVars),
-	clauses_info_clauses(!.ClausesInfo, Clauses0),
+	clauses_info_clauses(Clauses0, !ClausesInfo),
 
 	(
 	%	% For simple mode checking we do not give the inst_graph any
Index: compiler/higher_order.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.127
diff -u -b -r1.127 higher_order.m
--- compiler/higher_order.m	1 Apr 2005 14:28:55 -0000	1.127
+++ compiler/higher_order.m	21 May 2005 07:27:49 -0000
@@ -2524,8 +2524,9 @@
 
 	% This isn't looked at after here, and just clutters up
 	% hlds dumps if it's filled in.
+	set_clause_list([], ClausesRep),
 	ClausesInfo = clauses_info(EmptyVarSet, EmptyVarTypes,
-		EmptyTVarNameMap, EmptyVarTypes, [], [],
+		EmptyTVarNameMap, EmptyVarTypes, [], ClausesRep,
 		EmptyTIMap, EmptyTCIMap, no),
 	Origin = transformed(Transform, OrigOrigin, CallerPredId),
 	pred_info_init(PredModule, SymName, Arity, PredOrFunc, Context, Origin,
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.355
diff -u -b -r1.355 hlds_out.m
--- compiler/hlds_out.m	11 May 2005 08:52:24 -0000	1.355
+++ compiler/hlds_out.m	21 May 2005 10:54:17 -0000
@@ -952,8 +952,8 @@
 	;
 		true
 	),
-	ClausesInfo = clauses_info(VarSet, _, _, VarTypes, HeadVars, Clauses,
-		TypeInfoMap, TypeClassInfoMap, _),
+	ClausesInfo = clauses_info(VarSet, _, _, VarTypes, HeadVars,
+		ClausesRep, TypeInfoMap, TypeClassInfoMap, _),
 	( string__contains_char(Verbose, 'C') ->
 		hlds_out__write_indent(Indent, !IO),
 		io__write_string("% pred id: ", !IO),
@@ -1020,7 +1020,9 @@
 		hlds_out__write_var_types(Indent, VarSet, AppendVarNums,
 			VarTypes, TVarSet, !IO),
 
-		( Clauses \= [] ->
+		get_clause_list(ClausesRep, Clauses),
+		(
+			Clauses = [_ | _],
 			set_dump_opts_for_clauses(SavedDumpString, !IO),
 			hlds_out__write_clauses(Indent, ModuleInfo, PredId,
 				VarSet, AppendVarNums, HeadVars, PredOrFunc,
@@ -1028,7 +1030,7 @@
 			globals__io_set_option(dump_hlds_options,
 				string(SavedDumpString), !IO)
 		;
-			true
+			Clauses = []
 		),
 
 		pred_info_get_origin(PredInfo, Origin),
@@ -1155,6 +1157,7 @@
 hlds_out__marker_name(supp_magic, "supp_magic").
 hlds_out__marker_name(context, "context").
 hlds_out__marker_name(calls_are_fully_qualified, "calls_are_fully_qualified").
+hlds_out__marker_name(mode_check_clauses, "mode_check_clauses").
 
 hlds_out__write_marker(Marker, !IO) :-
 	hlds_out__marker_name(Marker, Name),
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.161
diff -u -b -r1.161 hlds_pred.m
--- compiler/hlds_pred.m	7 Apr 2005 06:32:08 -0000	1.161
+++ compiler/hlds_pred.m	21 May 2005 10:11:44 -0000
@@ -220,7 +220,7 @@
 						% typecheck.m.
 		headvars		:: list(prog_var),
 						% head vars
-		clauses			:: list(clause),
+		clauses_rep		:: clauses_rep,
 						% the following two
 						% fields are computed
 						% by polymorphism.m
@@ -231,6 +231,30 @@
 						% language clauses?
 	).
 
+:- type clauses_rep.
+
+	% Returns yes iff the given clauses_rep represents the empty list of
+	% clauses.
+	%
+:- func clause_list_is_empty(clauses_rep) = bool.
+
+	% Adds the given clause to the end of the clause list.
+	%
+:- pred add_clause(clause::in, clauses_rep::in, clauses_rep::out) is det.
+
+	% Get the list of clauses in the given clauses_rep in whatever order
+	% happens to be efficient.
+	%
+:- pred get_clause_list_any_order(clauses_rep::in, list(clause)::out) is det.
+
+	% Get the list of clauses in the given clauses_rep in program order.
+	%
+:- pred get_clause_list(clauses_rep::in, list(clause)::out) is det.
+
+	% Set the list of clauses to the one given.
+	%
+:- pred set_clause_list(list(clause)::in, clauses_rep::out) is det.
+
 :- type vartypes == map(prog_var, type).
 
 :- type tvar_name_map == map(string, tvar).
@@ -239,10 +263,12 @@
 
 	% This partial map holds the types specified by any explicit
 	% type qualifiers in the clauses.
+	%
 :- pred clauses_info_explicit_vartypes(clauses_info::in, vartypes::out) is det.
 
 	% This map contains the types of all the variables, as inferred
 	% by typecheck.m.
+	%
 :- pred clauses_info_vartypes(clauses_info::in, vartypes::out) is det.
 
 :- pred clauses_info_type_info_varmap(clauses_info::in, type_info_varmap::out)
@@ -253,7 +279,17 @@
 
 :- pred clauses_info_headvars(clauses_info::in, list(prog_var)::out) is det.
 
-:- pred clauses_info_clauses(clauses_info::in, list(clause)::out) is det.
+:- pred clauses_info_clauses_rep(clauses_info::in, clauses_rep::out) is det.
+
+	% Return the list of clauses in program order.
+	%
+:- pred clauses_info_clauses_only(clauses_info::in, list(clause)::out) is det.
+
+	% Return the list of clauses in program order, and if necessary update
+	% the cache of this info in the clauses_info.
+	%
+:- pred clauses_info_clauses(list(clause)::out,
+	clauses_info::in, clauses_info::out) is det.
 
 :- pred clauses_info_set_headvars(list(prog_var)::in,
 	clauses_info::in, clauses_info::out) is det.
@@ -261,16 +297,21 @@
 :- pred clauses_info_set_clauses(list(clause)::in,
 	clauses_info::in, clauses_info::out) is det.
 
+:- pred clauses_info_set_clauses_rep(clauses_rep::in,
+	clauses_info::in, clauses_info::out) is det.
+
 :- pred clauses_info_set_varset(prog_varset::in,
 	clauses_info::in, clauses_info::out) is det.
 
 	% This partial map holds the types specified by any explicit
 	% type qualifiers in the clauses.
+	%
 :- pred clauses_info_set_explicit_vartypes(vartypes::in,
 	clauses_info::in, clauses_info::out) is det.
 
 	% This map contains the types of all the variables, as inferred
 	% by typecheck.m.
+	%
 :- pred clauses_info_set_vartypes(vartypes::in,
 	clauses_info::in, clauses_info::out) is det.
 
@@ -293,6 +334,106 @@
 
 %-----------------------------------------------------------------------------%
 
+:- implementation.
+
+clauses_info_varset(CI, CI ^ varset).
+clauses_info_explicit_vartypes(CI, CI ^ explicit_vartypes).
+clauses_info_vartypes(CI, CI ^ vartypes).
+clauses_info_headvars(CI, CI ^ headvars).
+clauses_info_clauses_rep(CI, CI ^ clauses_rep).
+clauses_info_type_info_varmap(CI, CI ^ clause_type_info_varmap).
+clauses_info_typeclass_info_varmap(CI, CI ^ clause_typeclass_info_varmap).
+
+clauses_info_set_varset(X, CI, CI ^ varset := X).
+clauses_info_set_explicit_vartypes(X, CI, CI ^ explicit_vartypes := X).
+clauses_info_set_vartypes(X, CI, CI ^ vartypes := X).
+clauses_info_set_headvars(X, CI, CI ^ headvars := X).
+clauses_info_set_clauses(X, CI, CI ^ clauses_rep := forw(X)).
+clauses_info_set_clauses_rep(X, CI, CI ^ clauses_rep := X).
+clauses_info_set_type_info_varmap(X, CI, CI ^ clause_type_info_varmap := X).
+clauses_info_set_typeclass_info_varmap(X, CI,
+	CI ^ clause_typeclass_info_varmap := X).
+
+:- type clauses_rep
+	--->	rev(list(clause))
+	;	forw(list(clause))
+	;	both(rev :: list(clause), forw :: list(clause)).
+
+clause_list_is_empty(ClausesRep) = IsEmpty :-
+	(
+		ClausesRep = rev(List)
+	;
+		ClausesRep = forw(List)
+	;
+		ClausesRep = both(List, _)
+	),
+	(
+		List = [],
+		IsEmpty = yes
+	;
+		List = [_ | _],
+		IsEmpty = no
+	).
+
+get_clause_list_any_order(ClausesRep, Clauses) :-
+	(
+		ClausesRep = rev(Clauses)
+	;
+		ClausesRep = forw(Clauses)
+	;
+		ClausesRep = both(_, Clauses)
+	).
+
+get_clause_list(ClausesRep, Clauses) :-
+	(
+		ClausesRep = rev(RevClauses),
+		list__reverse(RevClauses, Clauses)
+	;
+		ClausesRep = forw(Clauses)
+	;
+		ClausesRep = both(_, Clauses)
+	).
+
+set_clause_list(Clauses, forw(Clauses)).
+
+clauses_info_clauses_only(CI, Clauses) :-
+	ClausesRep = CI ^ clauses_rep,
+	get_clause_list(ClausesRep, Clauses).
+
+clauses_info_clauses(Clauses, !CI) :-
+	ClausesRep = !.CI ^ clauses_rep,
+	(
+		ClausesRep = rev(RevClauses),
+		list__reverse(RevClauses, Clauses),
+		!:CI = !.CI ^ clauses_rep := both(RevClauses, Clauses)
+	;
+		ClausesRep = forw(Clauses)
+	;
+		ClausesRep = both(_, Clauses)
+	).
+
+add_clause(Clause, !ClausesRep) :-
+	% We keep the clause list in reverse order, to make it possible
+	% to add other clauses without quadratic behavior.
+	(
+		!.ClausesRep = rev(RevClauses0),
+		RevClauses = [Clause | RevClauses0],
+		!:ClausesRep = rev(RevClauses)
+	;
+		!.ClausesRep = forw(Clauses0),
+		list__reverse(Clauses0, RevClauses0),
+		RevClauses = [Clause | RevClauses0],
+		!:ClausesRep = rev(RevClauses)
+	;
+		!.ClausesRep = both(RevClauses0, _),
+		RevClauses = [Clause | RevClauses0],
+		!:ClausesRep = rev(RevClauses)
+	).
+
+%-----------------------------------------------------------------------------%
+
+:- interface.
+
 :- type implementation_language
 	--->	mercury
 	; 	foreign_language(foreign_language).
@@ -357,7 +498,7 @@
 	% the current module, or imported from some other module.
 	% Only predicates can have status pseudo_exported or pseudo_imported.
 	% Only types can have status abstract_exported or abstract_imported.
-
+	%
 :- type import_status
 	--->	external(import_status)
 				% Declared `:- external'.
@@ -402,25 +543,29 @@
 				% and the module does not contain any
 				% sub-modules.
 
-	% returns yes if the status indicates that the item was
+	% Returns yes if the status indicates that the item was
 	% in any way exported -- that is, if it could be used
 	% by any other module, or by sub-modules of this module.
+	%
 :- pred status_is_exported(import_status::in, bool::out) is det.
 
-	% returns yes if the status indicates that the item was
+	% Returns yes if the status indicates that the item was
 	% exported to importing modules (not just to sub-modules).
+	%
 :- pred status_is_exported_to_non_submodules(import_status::in, bool::out)
 	is det.
 
-	% returns yes if the status indicates that the item was
+	% Returns yes if the status indicates that the item was
 	% in any way imported -- that is, if it was defined in
 	% some other module, or in a sub-module of this module.
 	% This is the opposite of status_defined_in_this_module.
+	%
 :- pred status_is_imported(import_status::in, bool::out) is det.
 
-	% returns yes if the status indicates that the item was
+	% Returns yes if the status indicates that the item was
 	% defined in this module.  This is the opposite of
 	% status_is_imported.
+	%
 :- pred status_defined_in_this_module(import_status::in, bool::out) is det.
 
 	% Are calls from a predicate with the given import_status
@@ -432,7 +577,7 @@
 	% Predicates can be marked with various boolean flags, called
 	% "markers".
 
-	% an abstract set of markers.
+	% An abstract set of markers.
 :- type pred_markers.
 
 :- type marker
@@ -561,6 +706,14 @@
 				% fully qualified. This occurs for
 				% predicates read from `.opt' files
 				% and compiler-generated predicates.
+	;	mode_check_clauses
+				% Each clause of the predicate should be
+				% modechecked separately. Used for predicates
+				% defined by lots of clauses (usually facts)
+				% for which the compiler's quadratic behavior
+				% during mode checking (in instmap__merge and
+				% inst_match.bound_inst_list_contains_instname)
+				% would be unacceptable.
 	.
 
 	% An abstract set of attributes.
@@ -622,9 +775,11 @@
 				% MR_typeclass_info_superclass_info.
 
 	% type_info_locn_var(TypeInfoLocn, Var):
+	%
 	% 	Var is the variable corresponding to the TypeInfoLocn. Note
 	% 	that this does *not* mean that Var is a type_info; it may be
 	% 	a typeclass_info in which the type_info is nested.
+	%
 :- pred type_info_locn_var(type_info_locn::in, prog_var::out) is det.
 
 :- pred type_info_locn_set_var(prog_var::in,
@@ -721,7 +876,7 @@
 	%
 	% Return a pred_info whose fields are filled in from the information
 	% (direct and indirect) in the arguments, and from defaults.
-
+	%
 :- pred pred_info_init(module_name::in, sym_name::in, arity::in,
 	pred_or_func::in, prog_context::in, pred_origin::in, import_status::in,
 	goal_type::in, pred_markers::in, list(type)::in, tvarset::in,
@@ -737,7 +892,7 @@
 	% (direct and indirect) in the arguments, and from defaults. The given
 	% proc_info becomes the only procedure of the predicate (currently)
 	% and its proc_id is returned as the second last argument.
-
+	%
 :- pred pred_info_create(module_name::in, sym_name::in, pred_or_func::in,
 	prog_context::in, pred_origin::in, import_status::in, pred_markers::in,
 	list(type)::in, tvarset::in, existq_tvars::in, prog_constraints::in,
@@ -753,7 +908,7 @@
 	% call the created predicate. ExtraArgs is the list of extra
 	% type_infos and typeclass_infos required by typeinfo liveness
 	% which were added to the front of the argument list.
-
+	%
 :- pred hlds_pred__define_new_pred(pred_origin::in,
 	hlds_goal::in, hlds_goal::out, list(prog_var)::in, list(prog_var)::out,
 	instmap::in, string::in, tvarset::in, vartypes::in,
@@ -764,7 +919,7 @@
 
 	% Various predicates for accessing the information stored in the
 	% pred_id and pred_info data structures.
-
+	%
 :- type head_type_params == list(tvar).
 
 :- func pred_info_module(pred_info) =  module_name.
@@ -781,6 +936,7 @@
 	% The `is_pred_or_func' field of the pred_info records whether
 	% a pred_info is really for a predicate or whether it is for
 	% what was originally a function.
+	%
 :- func pred_info_is_pred_or_func(pred_info) = pred_or_func.
 
 :- pred pred_info_context(pred_info::in, prog_context::out) is det.
@@ -1084,7 +1240,7 @@
 	% polymorphically-typed arguments whose type depends on the
 	% values of those type_info-related variables;
 	% accurate GC for the MLDS back-end relies on this.
-:- type pred_info --->
+ :- type pred_info --->
 	pred_info(
 		module_name	:: module_name,
 				% module in which pred occurs
@@ -1205,8 +1361,8 @@
 		Context, Origin, Status, GoalType, Markers, Attributes,
 		ArgTypes, TypeVarSet, TypeVarSet, ExistQVars, HeadTypeParams,
 		ClassContext, ClassProofs, ClassConstraintMap,
-		UnprovenBodyConstraints, inst_graph_info_init, [], Assertions,
-		User, Indexes, ClausesInfo, Procs).
+		UnprovenBodyConstraints, inst_graph_info_init, [],
+		Assertions, User, Indexes, ClausesInfo, Procs).
 
 pred_info_create(ModuleName, SymName, PredOrFunc, Context, Origin, Status,
 		Markers, ArgTypes, TypeVarSet, ExistQVars, ClassContext,
@@ -1225,7 +1381,7 @@
 	Indexes = [],
 
 	% The empty list of clauses is a little white lie.
-	Clauses = [],
+	Clauses = forw([]),
 	map__init(TVarNameMap),
 	proc_info_typeinfo_varmap(ProcInfo, TypeInfoMap),
 	proc_info_typeclass_info_varmap(ProcInfo, TypeClassInfoMap),
@@ -1669,25 +1825,6 @@
 attributes_to_attribute_list(Attributes, Attributes).
 
 attribute_list_to_attributes(Attributes, Attributes).
-
-%-----------------------------------------------------------------------------%
-
-clauses_info_varset(CI, CI ^ varset).
-clauses_info_explicit_vartypes(CI, CI ^ explicit_vartypes).
-clauses_info_vartypes(CI, CI ^ vartypes).
-clauses_info_headvars(CI, CI ^ headvars).
-clauses_info_clauses(CI, CI ^ clauses).
-clauses_info_type_info_varmap(CI, CI ^ clause_type_info_varmap).
-clauses_info_typeclass_info_varmap(CI, CI ^ clause_typeclass_info_varmap).
-
-clauses_info_set_varset(X, CI, CI ^ varset := X).
-clauses_info_set_explicit_vartypes(X, CI, CI ^ explicit_vartypes := X).
-clauses_info_set_vartypes(X, CI, CI ^ vartypes := X).
-clauses_info_set_headvars(X, CI, CI ^ headvars := X).
-clauses_info_set_clauses(X, CI, CI ^ clauses := X).
-clauses_info_set_type_info_varmap(X, CI, CI ^ clause_type_info_varmap := X).
-clauses_info_set_typeclass_info_varmap(X, CI,
-	CI ^ clause_typeclass_info_varmap := X).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: compiler/instmap.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/instmap.m,v
retrieving revision 1.39
diff -u -b -r1.39 instmap.m
--- compiler/instmap.m	24 Mar 2005 05:34:04 -0000	1.39
+++ compiler/instmap.m	21 May 2005 10:00:32 -0000
@@ -104,7 +104,6 @@
 :- pred instmap_delta_changed_vars(instmap_delta::in, set(prog_var)::out)
 	is det.
 
-	%
 	% instmap_changed_vars(IMA, IMB, MI, CV)
 	%
 	% Given an earlier instmap, IMA, and a later instmap, IMB,
@@ -160,6 +159,7 @@
 
 	% Bind a variable in an instmap to a functor at the beginning
 	% of a case in a switch. Aborts on compiler generated cons_ids.
+	%
 :- pred instmap_delta_bind_var_to_functor(prog_var::in, (type)::in,
 	cons_id::in, instmap::in, instmap_delta::in, instmap_delta::out,
 	module_info::in, module_info::out) is det.
@@ -169,6 +169,7 @@
 
 	% Update the given instmap to include the initial insts of the
 	% lambda variables.
+	%
 :- pred instmap__pre_lambda_update(module_info::in, list(prog_var)::in,
 	list(mode)::in, instmap::in, instmap::out) is det.
 
@@ -193,28 +194,28 @@
 	instmap::out) is det.
 
 	% Given an instmap_delta and an instmap_delta, apply the
-	% second instmap_delta to the first to produce a new
-	% instmap_delta.
+	% second instmap_delta to the first to produce a new instmap_delta.
 	%
 :- pred instmap_delta_apply_instmap_delta(instmap_delta::in, instmap_delta::in,
 	overlay_how::in, instmap_delta::out) is det.
 
 	% instmap_merge(NonLocalVars, InstMaps, MergeContext):
-	%       Merge the `InstMaps' resulting from different branches
-	%       of a disjunction or if-then-else, and update the
-	%       instantiatedness of all the nonlocal variables,
-	%       checking that it is the same for every branch.
+	%
+	% Merge the `InstMaps' resulting from different branches of a
+	% disjunction or if-then-else, and update the instantiatedness
+	% of all the nonlocal variables, checking that it is the same
+	% for every branch.
 	%
 :- pred instmap__merge(set(prog_var)::in, list(instmap)::in, merge_context::in,
 	mode_info::in, mode_info::out) is det.
 
 	% instmap__unify(NonLocalVars, InstMapNonlocalvarPairss):
-	%       Unify the `InstMaps' in the list of pairs resulting
-	%	from different branches of a parallel conjunction and
-	%	update the instantiatedness of all the nonlocal variables.
-	%	The variable locking that is done when modechecking
-	%	the individual conjuncts ensures that variables have
-	%	at most one producer.
+	%
+	% Unify the `InstMaps' in the list of pairs resulting from different
+	% branches of a parallel conjunction and update the instantiatedness
+	% of all the nonlocal variables. The variable locking that is done
+	% when modechecking the individual conjuncts ensures that variables
+	% have at most one producer.
 	%
 :- pred instmap__unify(set(prog_var)::in, list(pair(instmap,
 	set(prog_var)))::in, mode_info::in, mode_info::out) is det.
@@ -243,30 +244,37 @@
 	% `instmap__no_output_vars(Instmap, InstmapDelta, Vars, ModuleInfo)'
 	% is true if none of the vars in the set Vars could have become more
 	% instantiated when InstmapDelta is applied to Instmap.
+	%
 :- pred instmap__no_output_vars(instmap::in, instmap_delta::in,
 	set(prog_var)::in, vartypes::in, module_info::in) is semidet.
 
 	% merge_instmap_delta(InitialInstMap, NonLocals,
-	%	InstMapDeltaA, InstMapDeltaB, ModuleInfo0, ModuleInfo)
+	%	InstMapDeltaA, InstMapDeltaB, !ModuleInfo):
+	%
 	% Merge the instmap_deltas of different branches of an if-then-else,
 	% disj or switch.
+	%
 :- pred merge_instmap_delta(instmap::in, set(prog_var)::in, vartypes::in,
 	instmap_delta::in, instmap_delta::in, instmap_delta::out,
 	module_info::in, module_info::out) is det.
 
 	% merge_instmap_deltas(Vars, InstMapDeltas,
-	%	MergedInstMapDelta, ModuleInfo0, ModuleInfo)
-	% takes a list of instmap deltas from the branches of an if-then-else,
+	%	MergedInstMapDelta, ModuleInfo):
+	%
+	% Takes a list of instmap deltas from the branches of an if-then-else,
 	% switch, or disj and merges them. This is used in situations
 	% where the bindings are known to be compatible.
+	%
 :- pred merge_instmap_deltas(instmap::in, set(prog_var)::in, vartypes::in,
 	list(instmap_delta)::in, instmap_delta::out,
 	module_info::in, module_info::out) is det.
 
 	% unify_instmap_delta(InitialInstMap, NonLocals,
 	%	InstMapDeltaA, InstMapDeltaB, !ModuleInfo)
+	%
 	% Unify the instmap_deltas of different branches of a parallel
 	% conjunction.
+	%
 :- pred unify_instmap_delta(instmap::in, set(prog_var)::in, instmap_delta::in,
 	instmap_delta::in, instmap_delta::out,
 	module_info::in, module_info::out) is det.
@@ -294,6 +302,7 @@
 	assoc_list(prog_var, inst)::out) is det.
 
 	% Apply the specified procedure to all insts in an instmap_delta.
+	%
 :- pred instmap_delta_map_foldl(
 	pred(prog_var, inst, inst, T, T)::in(pred(in, in, out, in, out) is det),
 	instmap_delta::in, instmap_delta::out, T::in, T::out) is det.
@@ -698,7 +707,7 @@
 	merge_errors::out) is det.
 
 instmap__merge_2([], _, _, !InstMap, !ModuleInfo, []).
-instmap__merge_2([Var|Vars], InstMapList, VarTypes, !InstMap, !ModuleInfo,
+instmap__merge_2([Var | Vars], InstMapList, VarTypes, !InstMap, !ModuleInfo,
 		!:ErrorList) :-
 	instmap__merge_2(Vars, InstMapList, VarTypes, !InstMap, !ModuleInfo,
 		!:ErrorList),
@@ -714,11 +723,11 @@
 	).
 
 	% instmap_merge_var(InstMaps, Var, ModuleInfo, Insts, Error):
-	%       Let `Insts' be the list of the inst of `Var' in the
-	%       corresponding `InstMaps'.  Let `Error' be yes iff
-	%       there are two instmaps for which the inst of `Var'
-	%       is incompatible.
-
+	%
+	% Let `Insts' be the list of the inst of `Var' in the corresponding
+	% `InstMaps'.  Let `Error' be yes iff there are two instmaps
+	% for which the inst of `Var' is incompatible.
+	%
 :- pred instmap__merge_var(list(instmap)::in, prog_var::in, (type)::in,
 	list(inst)::out, (inst)::out, module_info::in, module_info::out,
 	bool::out) is det.
@@ -796,13 +805,14 @@
 
 			% If there were any errors, then add the error
 			% to the list of possible errors in the mode_info.
-		( ErrorList = [FirstError | _] ->
+		(
+			ErrorList = [FirstError | _],
 			FirstError = Var - _,
 			set__singleton_set(WaitingVars, Var),
 			mode_info_error(WaitingVars,
 				mode_error_par_conj(ErrorList), !ModeInfo)
 		;
-			true
+			ErrorList = []
 		),
 		mode_info_set_instmap(reachable(InstMapping), !ModeInfo)
 	;
@@ -813,9 +823,11 @@
 
 	% instmap__unify_2(Vars, InitialInstMap, InstMaps, ModuleInfo,
 	%		ErrorList):
-	%       Let `ErrorList' be the list of variables in `Vars' for
-	%       which there are two instmaps in `InstMaps' for which the insts
+	%
+	% Let `ErrorList' be the list of variables in `Vars' for which
+	% there are two instmaps in `InstMaps' for which the insts
 	%       of the variable is incompatible.
+	%
 :- pred instmap__unify_2(list(prog_var)::in, instmap::in,
 	list(pair(instmap, set(prog_var)))::in, module_info::in,
 	map(prog_var, inst)::in, module_info::out,
@@ -838,11 +850,10 @@
 
 	% instmap__unify_var(InstMaps, Var, InitialInstMap, ModuleInfo,
 	%		Insts, Error):
-	%       Let `Insts' be the list of the inst of `Var' in
-	%       each of the corresponding `InstMaps'.  Let `Error' be yes
-	%	iff there are two instmaps for which the inst of `Var'
-	%       is incompatible.
-
+	% Let `Insts' be the list of the inst of `Var' in each of the
+	% corresponding `InstMaps'.  Let `Error' be yes iff there are two
+	% instmaps for which the inst of `Var' is incompatible.
+	%
 :- pred instmap__unify_var(list(pair(instmap, set(prog_var)))::in,
 	prog_var::in, list(inst)::in, list(inst)::out, (inst)::in, (inst)::out,
 	module_info::in, module_info::out, bool::in, bool::out) is det.
@@ -877,7 +888,7 @@
 	% Given two instmaps and a set of variables, compute an instmap delta
 	% which records the change in the instantiation state of those
 	% variables.
-
+	%
 compute_instmap_delta(unreachable, _, _, unreachable).
 compute_instmap_delta(reachable(_), unreachable, _, unreachable).
 compute_instmap_delta(reachable(InstMapA), reachable(InstMapB), NonLocals,
@@ -937,7 +948,7 @@
 %-----------------------------------------------------------------------------%
 
 	% Given two instmap deltas, merge them to produce a new instmap_delta.
-
+	%
 merge_instmap_delta(_, _, _, unreachable, InstMapDelta, InstMapDelta,
 		!ModuleInfo).
 merge_instmap_delta(_, _, _, reachable(InstMapping), unreachable,
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.170
diff -u -b -r1.170 intermod.m
--- compiler/intermod.m	20 Apr 2005 12:57:11 -0000	1.170
+++ compiler/intermod.m	21 May 2005 10:59:50 -0000
@@ -255,23 +255,25 @@
 		% Write a declaration to the `.opt' file for
 		% `exported_to_submodules' predicates.
 		intermod__add_proc(PredId, DoWrite0, !Info),
-		clauses_info_clauses(ClausesInfo0, Clauses0),
+		clauses_info_clauses_rep(ClausesInfo0, ClausesRep0),
 		(
 			DoWrite0 = yes,
 			clauses_info_vartypes(ClausesInfo0, VarTypes),
 			pred_info_typevarset(PredInfo0, TVarSet),
 			intermod_info_set_var_types(VarTypes, !Info),
 			intermod_info_set_tvarset(TVarSet, !Info),
+			get_clause_list(ClausesRep0, Clauses0),
 			intermod__traverse_clauses(Clauses0, Clauses, DoWrite,
-				!Info)
+				!Info),
+			set_clause_list(Clauses, ClausesRep)
 		;
 			DoWrite0 = no,
-			Clauses = Clauses0,
+			ClausesRep = ClausesRep0,
 			DoWrite = no
 		),
 		(
 			DoWrite = yes,
-			clauses_info_set_clauses(Clauses,
+			clauses_info_set_clauses_rep(ClausesRep,
 				ClausesInfo0, ClausesInfo),
 			pred_info_set_clauses_info(ClausesInfo,
 				PredInfo0, PredInfo),
@@ -320,7 +322,7 @@
 	),
 	(
 		pred_info_clauses_info(PredInfo, ClauseInfo),
-		clauses_info_clauses(ClauseInfo, Clauses),
+		clauses_info_clauses_only(ClauseInfo, Clauses),
 
 		[ProcId | _ProcIds] = pred_info_procids(PredInfo),
 		pred_info_procedures(PredInfo, Procs),
@@ -1612,7 +1614,7 @@
 	pred_info_clauses_info(PredInfo, ClausesInfo),
 	clauses_info_varset(ClausesInfo, VarSet),
 	clauses_info_headvars(ClausesInfo, HeadVars),
-	clauses_info_clauses(ClausesInfo, Clauses),
+	clauses_info_clauses_only(ClausesInfo, Clauses),
 
 	( pred_info_get_goal_type(PredInfo, promise(PromiseType)) ->
 		( Clauses = [Clause] ->
@@ -1872,6 +1874,7 @@
 	% This marker should only occur after the magic sets transformation.
 	error("intermod__should_output_marker: generate_inline").
 intermod__should_output_marker(calls_are_fully_qualified, no).
+intermod__should_output_marker(mode_check_clauses, yes).
 
 :- pred get_pragma_foreign_code_vars(list(foreign_arg)::in, list(mode)::in,
 	prog_varset::in, prog_varset::out, list(pragma_var)::out) is det.
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.512
diff -u -b -r1.512 make_hlds.m
--- compiler/make_hlds.m	20 Apr 2005 12:57:11 -0000	1.512
+++ compiler/make_hlds.m	21 May 2005 13:15:20 -0000
@@ -887,6 +887,10 @@
         add_pred_marker("check_termination", Name, Arity, ImportStatus,
             Context, check_termination, [terminates, does_not_terminate],
             !ModuleInfo, !IO)
+    ;
+        Pragma = mode_check_clauses(Name, Arity),
+        add_pred_marker("mode_check_clauses", Name, Arity, ImportStatus,
+            Context, mode_check_clauses, [], !ModuleInfo, !IO)
     ).
 add_item_decl_pass_2(Item, _Context, !Status, !ModuleInfo, !IO) :-
     Item = pred_or_func(_TypeVarSet, _InstVarSet, _ExistQVars,
@@ -1690,8 +1694,9 @@
             map__init(TCI_VarMap),
             map__init(TVarNameMap),
             HasForeignClauses = no,
+            set_clause_list([Clause], ClausesRep),
             Clauses = clauses_info(ArgVarSet, VarTypes0,
-                TVarNameMap, VarTypes0, Args, [Clause],
+                TVarNameMap, VarTypes0, Args, ClausesRep,
                 TI_VarMap, TCI_VarMap, HasForeignClauses),
             pred_info_get_markers(PredInfo0, Markers0),
             add_marker(calls_are_fully_qualified, Markers0, Markers),
@@ -2219,12 +2224,13 @@
 %-----------------------------------------------------------------------------%
 
     % add_pred_marker(ModuleInfo0, PragmaName, Name, Arity, Status,
-    %   Context, Marker, ConflictMarkers, ModuleInfo, IO0, IO)
+    %   Context, Marker, ConflictMarkers, ModuleInfo, !IO):
     %
     % Adds Marker to the marker list of the pred(s) with give Name and
     % Arity, updating the ModuleInfo. If the named pred does not exist,
     % or the pred already has a marker in ConflictMarkers, report
     % an error.
+    %
 :- pred add_pred_marker(string::in, sym_name::in, arity::in, import_status::in,
     prog_context::in, marker::in, list(marker)::in,
     module_info::in, module_info::out, io::di, io::uo) is det.
@@ -4002,14 +4008,14 @@
         % put the clause we just built into the pred_info,
         % annotateed with the appropriate types
         %
-    ClauseList = [Clause],
     map__from_corresponding_lists(HeadVars, Types, VarTypes),
     map__init(TVarNameMap),
     map__init(TI_VarMap),
     map__init(TCI_VarMap),
     HasForeignClauses = no,
+    set_clause_list([Clause], ClausesRep),
     ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
-        HeadVars, ClauseList, TI_VarMap, TCI_VarMap, HasForeignClauses),
+        HeadVars, ClausesRep, TI_VarMap, TCI_VarMap, HasForeignClauses),
     pred_info_set_clauses_info(ClausesInfo, !PredInfo),
 
         %
@@ -4944,9 +4950,9 @@
     map__init(TI_VarMap),
     map__init(TCI_VarMap),
     HasForeignClauses = no,
+    set_clause_list([IntroducedClause], ClausesRep),
     ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
-        HeadVars, [IntroducedClause], TI_VarMap, TCI_VarMap,
-        HasForeignClauses).
+        HeadVars, ClausesRep, TI_VarMap, TCI_VarMap, HasForeignClauses).
 
     % handle the arbitrary clauses syntax
 produce_instance_method_clauses(clauses(InstanceClauses), PredOrFunc,
@@ -5237,15 +5243,15 @@
             pred_info_clause_goal_type(!.PredInfo)
         ->
             pred_info_clauses_info(!.PredInfo, CInfo0),
-            clauses_info_clauses(CInfo0, ClauseList0),
+            clauses_info_clauses_only(CInfo0, ClauseList0),
             ClauseList = list__map(
-                (func(C) =
+                (func(C) = Res :-
+                    AllProcIds = pred_info_all_procids(!.PredInfo),
                     ( C = clause([], Goal, mercury, Ctxt) ->
-                        clause(AllProcIds, Goal, mercury, Ctxt)
+                        Res = clause(AllProcIds, Goal, mercury, Ctxt)
                     ;
-                        C
-                    ) :-
-                    AllProcIds = pred_info_all_procids(!.PredInfo)
+                        Res = C
+                    )
                 ), ClauseList0),
             clauses_info_set_clauses(ClauseList, CInfo0, CInfo),
             pred_info_set_clauses_info(CInfo, !PredInfo)
@@ -6308,8 +6314,9 @@
     map__init(TI_VarMap),
     map__init(TCI_VarMap),
     HasForeignClauses = no,
+    set_clause_list([], ClausesRep),
     ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
-        HeadVars, [], TI_VarMap, TCI_VarMap, HasForeignClauses).
+        HeadVars, ClausesRep, TI_VarMap, TCI_VarMap, HasForeignClauses).
 
 :- pred clauses_info_init(int::in, clauses_info::out) is det.
 
@@ -6321,8 +6328,9 @@
     map__init(TI_VarMap),
     map__init(TCI_VarMap),
     HasForeignClauses = no,
+    set_clause_list([], ClausesRep),
     ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
-        HeadVars, [], TI_VarMap, TCI_VarMap, HasForeignClauses).
+        HeadVars, ClausesRep, TI_VarMap, TCI_VarMap, HasForeignClauses).
 
 :- pred clauses_info_add_clause(list(proc_id)::in,
     prog_varset::in, tvarset::in, list(prog_term)::in, goal::in,
@@ -6336,10 +6344,11 @@
         Status, PredOrFunc, Arity, GoalType, Goal, VarSet, TVarSet,
         !ClausesInfo, Warnings, !ModuleInfo, !QualInfo, !IO) :-
     !.ClausesInfo = clauses_info(VarSet0, ExplicitVarTypes0,
-        TVarNameMap0, InferredVarTypes, HeadVars, ClauseList0,
+        TVarNameMap0, InferredVarTypes, HeadVars, ClausesRep0,
         TI_VarMap, TCI_VarMap, HasForeignClauses),
+    IsEmpty = clause_list_is_empty(ClausesRep0),
     (
-        ClauseList0 = [],
+        IsEmpty = yes,
         % Create the mapping from type variable name, used to
         % rename type variables occurring in explicit type
         % qualifications. The version of this mapping stored
@@ -6349,7 +6358,7 @@
         % qualifications are local to the clause in which they appear.
         varset__create_name_var_map(TVarSet0, TVarNameMap)
     ;
-        ClauseList0 = [_ | _],
+        IsEmpty = no,
         TVarNameMap = TVarNameMap0
     ),
     update_qual_info(TVarNameMap, TVarSet0, ExplicitVarTypes0, Status,
@@ -6373,36 +6382,34 @@
         FoundError = no,
         Goal = Goal0,
 
-            % If we have foreign clauses, we should only
-            % add this clause for modes *not* covered by the
-            % foreign clauses.
+            % If we have foreign clauses, we should only add this clause
+            % for modes *not* covered by the foreign clauses.
         (
             HasForeignClauses = yes,
+            get_clause_list_any_order(ClausesRep0, AnyOrderClauseList),
             ForeignModeIds = list__condense(list__filter_map(
                 (func(C) = ProcIds is semidet :-
                     C = clause(ProcIds, _, ClauseLang, _),
                     not ClauseLang = mercury
                 ),
-                ClauseList0)),
+                AnyOrderClauseList)),
             ModeIds = list__delete_elems(ModeIds0, ForeignModeIds),
             (
                 ModeIds = [],
-                ClauseList = ClauseList0
+                ClausesRep = ClausesRep0
             ;
                 ModeIds = [_ | _],
-                % XXX we should avoid append - this gives O(N*N)
-                list__append(ClauseList0,
-                    [clause(ModeIds, Goal, mercury, Context)], ClauseList)
+                Clause = clause(ModeIds, Goal, mercury, Context),
+                add_clause(Clause, ClausesRep0, ClausesRep)
             )
         ;
             HasForeignClauses = no,
-            % XXX we should avoid append - this gives O(N*N)
-            list__append(ClauseList0,
-                [clause(ModeIds0, Goal, mercury, Context)], ClauseList)
+            Clause = clause(ModeIds0, Goal, mercury, Context),
+            add_clause(Clause, ClausesRep0, ClausesRep)
         ),
         qual_info_get_var_types(!.QualInfo, ExplicitVarTypes),
         !:ClausesInfo = clauses_info(VarSet, ExplicitVarTypes, TVarNameMap,
-            InferredVarTypes, HeadVars, ClauseList, TI_VarMap, TCI_VarMap,
+            InferredVarTypes, HeadVars, ClausesRep, TI_VarMap, TCI_VarMap,
             HasForeignClauses)
     ).
 
@@ -6425,8 +6432,9 @@
         PredName, Arity, !ClausesInfo, !ModuleInfo, !IO) :-
 
     !.ClausesInfo = clauses_info(VarSet0, ExplicitVarTypes, TVarNameMap,
-        InferredVarTypes, HeadVars, ClauseList, TI_VarMap, TCI_VarMap,
+        InferredVarTypes, HeadVars, ClauseRep, TI_VarMap, TCI_VarMap,
         _HasForeignClauses),
+    get_clause_list(ClauseRep, ClauseList),
 
         % Find all the existing clauses for this mode, and
         % extract their implementation language and clause number
@@ -6518,8 +6526,9 @@
             NewClauseList = [NewClause | NewClauseListTail]
         ),
         HasForeignClauses = yes,
+        set_clause_list(NewClauseList, NewClauseRep),
         !:ClausesInfo = clauses_info(VarSet, ExplicitVarTypes, TVarNameMap,
-            InferredVarTypes, HeadVars, NewClauseList,
+            InferredVarTypes, HeadVars, NewClauseRep,
             TI_VarMap, TCI_VarMap, HasForeignClauses)
     ).
 
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.258
diff -u -b -r1.258 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	20 Apr 2005 12:57:12 -0000	1.258
+++ compiler/mercury_to_mercury.m	21 May 2005 13:19:00 -0000
@@ -660,6 +660,10 @@
         Pragma = check_termination(Pred, Arity),
         mercury_output_pragma_decl(Pred, Arity, predicate,
             "check_termination", !IO)
+    ;
+        Pragma = mode_check_clauses(Pred, Arity),
+        mercury_output_pragma_decl(Pred, Arity, predicate,
+            "mode_check_clauses", !IO)
     ).
 
 mercury_output_item(_, promise(PromiseType, Goal0, VarSet, UnivVars), _,
Index: compiler/mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_constraints.m,v
retrieving revision 1.9
diff -u -b -r1.9 mode_constraints.m
--- compiler/mode_constraints.m	30 Mar 2005 00:50:21 -0000	1.9
+++ compiler/mode_constraints.m	21 May 2005 05:43:36 -0000
@@ -271,7 +271,7 @@
 	( pred_info_is_imported(PredInfo0) ->
 		true
 	;
-		clauses_info_clauses(ClausesInfo0, Clauses0),
+		clauses_info_clauses_only(ClausesInfo0, Clauses0),
 		clauses_info_vartypes(ClausesInfo0, VarTypes),
 		NRInfo0 = number_robdd_info(!.MCI, !.ModuleInfo, VarTypes),
 
@@ -927,7 +927,7 @@
 	map__foldl2(input_output_constraints(HeadVars, InstGraph),
 		InstGraph, !Constraint, !ConstraintInfo),
 
-	clauses_info_clauses(!.ClausesInfo, Clauses),
+	clauses_info_clauses(Clauses, !ClausesInfo),
 	list__map(pred(clause(_, Goal, _, _)::in, Goal::out) is det, Clauses,
 		Goals),
 	DisjGoal = disj(Goals),
Index: compiler/modecheck_unify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modecheck_unify.m,v
retrieving revision 1.79
diff -u -b -r1.79 modecheck_unify.m
--- compiler/modecheck_unify.m	31 Mar 2005 00:31:12 -0000	1.79
+++ compiler/modecheck_unify.m	21 May 2005 12:58:34 -0000
@@ -362,7 +362,7 @@
 			modecheck_goal(Goal0, Goal1, !ModeInfo, !IO)
 		),
 		mode_list_get_final_insts(Modes, ModuleInfo0, FinalInsts),
-		modecheck_final_insts(Vars, FinalInsts, Goal1, Goal,
+		modecheck_lambda_final_insts(Vars, FinalInsts, Goal1, Goal,
 			!ModeInfo),
 		mode_checkpoint(exit, "lambda goal", !ModeInfo, !IO),
 
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.297
diff -u -b -r1.297 modes.m
--- compiler/modes.m	24 Mar 2005 05:34:10 -0000	1.297
+++ compiler/modes.m	23 May 2005 02:37:40 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1994-2005 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.
@@ -140,47 +142,47 @@
 :- import_module std_util.
 
 	% modecheck(HLDS0, HLDS, UnsafeToContinue):
+    %
 	% Perform mode inference and checking for a whole module.
-	% UnsafeToContinue = yes means that mode inference
-	% was halted prematurely, due to an error, and that
-	% we should therefore not perform determinism-checking, because we
-	% might get internal errors.
-
+    % UnsafeToContinue = yes means that mode inference was halted
+    % prematurely, due to an error, and that we should therefore
+    % not perform determinism-checking, because we might get
+    % internal errors.
+    %
 :- pred modecheck(module_info::in, module_info::out, bool::out,
 	io::di, io::uo) is det.
 
-	% Mode-check or unique-mode-check the code for all the predicates
+    % Mode-check or unique-mode-check the code of all the predicates
 	% in a module.
+    %
 :- pred check_pred_modes(how_to_check_goal::in, may_change_called_proc::in,
 	module_info::in, module_info::out, bool::out, io::di, io::uo) is det.
 
 	% Mode-check or unique-mode-check the code for single predicate.
-
+    %
 :- pred modecheck_pred_mode(pred_id::in, pred_info::in, how_to_check_goal::in,
 	may_change_called_proc::in, module_info::in, module_info::out,
 	int::out, io::di, io::uo) is det.
 
-	% Mode-check the code for predicate in a given mode.
+    % Mode-check the code for the given predicate in a given mode.
 	% Returns the number of errs found and a bool `Changed'
-	% which is true iff another pass of fixpoint analysis
-	% may be needed.
-
+    % which is true iff another pass of fixpoint analysis may be needed.
+    %
 :- pred modecheck_proc(proc_id::in, pred_id::in,
 	module_info::in, module_info::out, int::out, bool::out,
 	io::di, io::uo) is det.
 
-	% Mode-check or unique-mode-check the code for predicate in a
-	% given mode.
+    % Mode-check or unique-mode-check the code for the given predicate
+    % in a given mode.
 	% Returns the number of errs found and a bool `Changed'
-	% which is true iff another pass of fixpoint analysis
-	% may be needed.
-
-:- pred modecheck_proc(proc_id::in, pred_id::in, how_to_check_goal::in,
+    % which is true iff another pass of fixpoint analysis may be needed.
+    %
+:- pred modecheck_proc_general(proc_id::in, pred_id::in, how_to_check_goal::in,
 	may_change_called_proc::in, module_info::in, module_info::out,
 	int::out, bool::out, io::di, io::uo) is det.
 
-	% Mode-check the code for predicate in a given mode.
-
+    % Mode-check the code for the given predicate in the given mode.
+    %
 :- pred modecheck_proc_info(proc_id::in, pred_id::in,
 	module_info::in, module_info::out, proc_info::in, proc_info::out,
 	int::out, io::di, io::uo) is det.
@@ -199,8 +201,7 @@
 :- pred get_live_vars(list(prog_var)::in, list(is_live)::in,
 	list(prog_var)::out) is det.
 
-	%
-	% calculate the argument number offset that needs to be passed to
+    % Calculate the argument number offset that needs to be passed to
 	% modecheck_var_list_is_live, modecheck_var_has_inst_list, and
 	% modecheck_set_var_inst_list.  This offset number is calculated
 	% so that real arguments get positive argument numbers and
@@ -226,17 +227,17 @@
 	bool::in, int::in, inst_var_sub::out,
 	mode_info::in, mode_info::out) is det.
 
-	% modecheck_set_var_inst(Var, Inst, MaybeUInst, ModeInfo0, ModeInfo).
-	%	Assign the given Inst to the given Var, after checking that
-	%	it is okay to do so.  If the inst to be assigned is the
-	%	result of an abstract unification then the MaybeUInst
-	%	argument should be the initial inst of the _other_ side of
-	%	the unification.  This allows more precise (i.e. less
-	%	conservative) checking in the case that Inst contains `any'
-	%	components and Var is locked (i.e. is a nonlocal variable in
-	%	a negated context).  Where the inst is not the result of an
-	%	abstract unification then MaybeUInst should be `no'.
-
+    % modecheck_set_var_inst(Var, Inst, MaybeUInst, ModeInfo0, ModeInfo):
+    %
+    % Assign the given Inst to the given Var, after checking that it is
+    % okay to do so.  If the inst to be assigned is the result of an
+    % abstract unification then the MaybeUInst argument should be the
+    % initial inst of the _other_ side of the unification. This allows
+    % more precise (i.e. less conservative) checking in the case that
+    % Inst contains `any' components and Var is locked (i.e. is a
+    % nonlocal variable in a negated context). Where the inst is not
+    % the result of an abstract unification then MaybeUInst should be `no'.
+    %
 :- pred modecheck_set_var_inst(prog_var::in, (inst)::in, maybe(inst)::in,
 	mode_info::in, mode_info::out) is det.
 
@@ -244,10 +245,10 @@
 	list(inst)::in, int::in, list(prog_var)::out, extra_goals::out,
 	mode_info::in, mode_info::out) is det.
 
-	% check that the final insts of the head vars of a lambda
+    % Check that the final insts of the head vars of a lambda
 	% goal matches their expected insts.
 	%
-:- pred modecheck_final_insts(list(prog_var)::in, list(inst)::in,
+:- pred modecheck_lambda_final_insts(list(prog_var)::in, list(inst)::in,
 	hlds_goal::in, hlds_goal::out, mode_info::in, mode_info::out) is det.
 
 :- pred mode_info_add_goals_live_vars(list(hlds_goal)::in,
@@ -257,18 +258,19 @@
 	mode_info::in, mode_info::out) is det.
 
 	% modecheck_functor_test(ConsId, Var):
-	%	update the instmap to reflect the fact that
-	%	Var was bound to ConsId.
+    %
+    % Update the instmap to reflect the fact that Var was bound to ConsId.
 	% This is used for the functor tests in `switch' statements.
 	%
 :- pred modecheck_functor_test(prog_var::in, cons_id::in,
 	mode_info::in, mode_info::out) is det.
 
 	% compute_goal_instmap_delta(InstMap0, Goal,
-	%	GoalInfo0, GoalInfo, ModeInfo0, ModeInfo).
+    %   GoalInfo0, GoalInfo, ModeInfo0, ModeInfo):
 	%
 	% Work out the instmap_delta for a goal from
 	% the instmaps before and after the goal.
+    %
 :- pred compute_goal_instmap_delta(instmap::in, hlds_goal_expr::in,
 	hlds_goal_info::in, hlds_goal_info::out,
 	mode_info::in, mode_info::out) is det.
@@ -281,7 +283,7 @@
 	mode_info::in, mode_info::out, io::di, io::uo) is det.
 
 	% Mode-check a single goal-expression.
-
+    %
 :- pred modecheck_goal_expr(hlds_goal_expr::in, hlds_goal_info::in,
 	hlds_goal_expr::out, mode_info::in, mode_info::out,
 	io::di, io::uo) is det.
@@ -290,12 +292,9 @@
 	--->	no_extra_goals
 	;	extra_goals(
 			extra_before_main	:: list(hlds_goal),
-						% goals to insert before
-						% the main goal
+                                    % goals to insert before the main goal
 			extra_after_main	:: list(hlds_goal)
-						% goals to append after
-						% the main goal
-
+                                    % goals to append after the main goal
 		).
 
 :- type after_goals
@@ -304,17 +303,16 @@
 			after_instmap		:: instmap,
 						% instmap at end of main goal
 			after_goals		:: list(hlds_goal)
-						% goals to append after
-						% the main goal
+                                    % goals to append after the main goal
 		).
 
-	% append_extra_goals inserts adds some goals to the
+    % Append_extra_goals inserts adds some goals to the
 	% list of goals to insert before/after the main goal.
 	%
 :- pred append_extra_goals(extra_goals::in, extra_goals::in,
 	extra_goals::out) is det.
 
-	% handle_extra_goals combines MainGoal and ExtraGoals into a single
+    % Handle_extra_goals combines MainGoal and ExtraGoals into a single
 	% hlds_goal_expr, rerunning mode analysis on the entire
 	% conjunction if ExtraGoals is not empty.
 	%
@@ -346,16 +344,16 @@
 :- import_module check_hlds__delay_info.
 :- import_module check_hlds__inst_match.
 :- import_module check_hlds__inst_util.
+:- import_module check_hlds__modecheck_call.
+:- import_module check_hlds__modecheck_unify.
 :- import_module check_hlds__mode_debug.
 :- import_module check_hlds__mode_errors.
 :- import_module check_hlds__mode_info.
 :- import_module check_hlds__mode_util.
-:- import_module check_hlds__modecheck_call.
-:- import_module check_hlds__modecheck_unify.
 :- import_module check_hlds__polymorphism.
 :- import_module check_hlds__purity.
-:- import_module check_hlds__type_util.
 :- import_module check_hlds__typecheck.
+:- import_module check_hlds__type_util.
 :- import_module check_hlds__unify_proc.
 :- import_module check_hlds__unique_modes.
 :- import_module hlds__hlds_data.
@@ -367,6 +365,7 @@
 :- import_module libs__globals.
 :- import_module libs__options.
 :- import_module mdbcomp__prim_data.
+:- import_module parse_tree__error_util.
 :- import_module parse_tree__mercury_to_mercury.
 :- import_module parse_tree__module_qual.
 :- import_module parse_tree__prog_mode.
@@ -392,8 +391,8 @@
 	globals__io_lookup_bool_option(verbose, Verbose, !IO),
 
 	maybe_write_string(Verbose, "% Mode-checking clauses...\n", !IO),
-	check_pred_modes(check_modes, may_change_called_proc,
-		!Module, UnsafeToContinue, !IO),
+    check_pred_modes(check_modes, may_change_called_proc, !Module,
+        UnsafeToContinue, !IO),
 	maybe_report_stats(Statistics, !IO).
 
 %-----------------------------------------------------------------------------%
@@ -415,31 +414,29 @@
 		WhatToCheck = check_modes,
 		(
 			UnsafeToContinue = yes,
-			write_mode_inference_messages(PredIds, no,
-				!.ModuleInfo, !IO)
+            write_mode_inference_messages(PredIds, no, !.ModuleInfo, !IO)
 		;
 			UnsafeToContinue = no
 		)
 	).
 
 	% Iterate over the list of pred_ids in a module.
-
+    %
 :- pred modecheck_to_fixpoint(list(pred_id)::in, int::in,
 	how_to_check_goal::in, may_change_called_proc::in,
-	module_info::in, module_info::out, bool::out,
-	io::di, io::uo) is det.
+    module_info::in, module_info::out, bool::out, io::di, io::uo) is det.
 
 modecheck_to_fixpoint(PredIds, MaxIterations, WhatToCheck, MayChangeCalledProc,
 		!ModuleInfo, UnsafeToContinue, !IO) :-
-	% save the old procedure bodies so that we can restore them for the
-	% next pass
+    % Save the old procedure bodies so that we can restore them for the
+    % next pass.
 	module_info_preds(!.ModuleInfo, OldPredTable0),
 
-	% analyze everything which has the "can-process" flag set to `yes'
+    % Analyze everything which has the "can-process" flag set to `yes'.
 	list__foldl4(maybe_modecheck_pred(WhatToCheck, MayChangeCalledProc),
 		PredIds, !ModuleInfo, no, Changed1, 0, NumErrors, !IO),
 
-	% analyze the procedures whose "can-process" flag was no;
+    % Analyze the procedures whose "can-process" flag was no;
 	% those procedures were inserted into the unify requests queue.
 	modecheck_queued_procs(WhatToCheck, OldPredTable0, OldPredTable,
 		!ModuleInfo, Changed2, !IO),
@@ -447,54 +444,48 @@
 
 	bool__or(Changed1, Changed2, Changed),
 
-	% stop if we have reached a fixpoint or found any errors
+    % Stop if we have reached a fixpoint or found any errors.
 	( ( Changed = no ; NumErrors > 0 ; ExitStatus \= 0 ) ->
 		UnsafeToContinue = Changed
 	;
-		% stop if we exceed the iteration limit
+        % Stop if we have exceeded the iteration limit.
 		( MaxIterations =< 1 ->
 			report_max_iterations_exceeded(!IO),
 			UnsafeToContinue = yes
 		;
-			globals__io_lookup_bool_option(debug_modes, DebugModes,
-				!IO),
+            globals__io_lookup_bool_option(debug_modes, DebugModes, !IO),
 			(
 				DebugModes = yes,
-				write_mode_inference_messages(PredIds, no,
-					!.ModuleInfo, !IO)
+                write_mode_inference_messages(PredIds, no, !.ModuleInfo, !IO)
 			;
 				DebugModes = no
 			),
 
 			%
-			% Mode analysis may have modified the procedure
-			% bodies, since it does some optimizations such
-			% as deleting unreachable code.  But since we didn't
-			% reach a fixpoint yet, the mode information is not
-			% correct yet, and so those optimizations will have
-			% been done based on incomplete information, and so
-			% they may therefore produce incorrect results.
-			% Thus we need to restore the old procedure bodies.
+            % Mode analysis may have modified the procedure bodies,
+            % since it does some optimizations such as deleting unreachable
+            % code. But since we didn't reach a fixpoint yet, the mode
+            % information is not yet correct, and so those optimizations
+            % will have been done based on incomplete information, and so
+            % they may produce incorrect results. We thus need to restore
+            % the old procedure bodies.
 			%
 
 			(
 				WhatToCheck = check_modes,
-				% restore the proc_info goals from the
-				% clauses in the pred_info
-				copy_module_clauses_to_procs(PredIds,
-					!ModuleInfo)
+                % Restore the proc_info goals from the
+                % clauses in the pred_info.
+                copy_module_clauses_to_procs(PredIds, !ModuleInfo)
 			;
 				WhatToCheck = check_unique_modes,
-				% restore the proc_info goals from the
-				% proc_infos in the old module_info
-				copy_pred_bodies(OldPredTable, PredIds,
-					!ModuleInfo)
+                % Restore the proc_info goals from the
+                % proc_infos in the old module_info.
+                copy_pred_bodies(OldPredTable, PredIds, !ModuleInfo)
 			),
 
 			MaxIterations1 = MaxIterations - 1,
-			modecheck_to_fixpoint(PredIds, MaxIterations1,
-				WhatToCheck, MayChangeCalledProc,
-				!ModuleInfo, UnsafeToContinue, !IO)
+            modecheck_to_fixpoint(PredIds, MaxIterations1, WhatToCheck,
+                MayChangeCalledProc, !ModuleInfo, UnsafeToContinue, !IO)
 		)
 	).
 
@@ -512,21 +503,24 @@
 	io__format("(The current limit is %d iterations.)\n",
 		[i(MaxIterations)], !IO).
 
-% copy_pred_bodies(OldPredTable, ProcId, ModuleInfo0, ModuleInfo):
-%	copy the procedure bodies for all procedures of the specified
-%	PredIds from OldPredTable into ModuleInfo0, giving ModuleInfo.
+    % copy_pred_bodies(OldPredTable, ProcId, ModuleInfo0, ModuleInfo):
+    %
+    % Copy the procedure bodies for all procedures of the specified PredIds
+    % from OldPredTable into ModuleInfo0, giving ModuleInfo.
+    %
 :- pred copy_pred_bodies(pred_table::in, list(pred_id)::in,
 	module_info::in, module_info::out) is det.
 
 copy_pred_bodies(OldPredTable, PredIds, !ModuleInfo) :-
 	module_info_preds(!.ModuleInfo, PredTable0),
-	list__foldl(copy_pred_body(OldPredTable), PredIds,
-		PredTable0, PredTable),
+    list__foldl(copy_pred_body(OldPredTable), PredIds, PredTable0, PredTable),
 	module_info_set_preds(PredTable, !ModuleInfo).
 
-% copy_pred_body(OldPredTable, ProcId, PredTable0, PredTable):
-%	copy the procedure bodies for all procedures of the specified
-%	PredId from OldPredTable into PredTable0, giving PredTable.
+    % copy_pred_body(OldPredTable, ProcId, PredTable0, PredTable):
+    %
+    % Copy the procedure bodies for all procedures of the specified PredId
+    % from OldPredTable into PredTable0, giving PredTable.
+    %
 :- pred copy_pred_body(pred_table::in, pred_id::in,
 	pred_table::in, pred_table::out) is det.
 
@@ -552,9 +546,11 @@
 		map__set(PredTable0, PredId, PredInfo, PredTable)
 	).
 
-% copy_proc_body(OldProcTable, ProcId, ProcTable0, ProcTable):
-%	copy the body of the specified ProcId from OldProcTable
-%	into ProcTable0, giving ProcTable.
+    % copy_proc_body(OldProcTable, ProcId, ProcTable0, ProcTable):
+    %
+    % Copy the body of the specified ProcId from OldProcTable
+    % into ProcTable0, giving ProcTable.
+    %
 :- pred copy_proc_body(proc_table::in, proc_id::in,
 	proc_table::in, proc_table::out) is det.
 
@@ -578,9 +574,8 @@
 			)
 		;
 			%
-			% don't modecheck class methods, because they
-			% are generated already mode-correct and with
-			% correct instmap deltas.
+            % don't modecheck class methods, because they are generated
+            % already mode-correct and with correct instmap deltas.
 			%
 			pred_info_get_markers(PredInfo, PredMarkers),
 			check_marker(PredMarkers, class_method)
@@ -607,15 +602,13 @@
 		write_modes_progress_message(PredId, PredInfo0, !.ModuleInfo,
 			WhatToCheck, !IO),
 		modecheck_pred_mode_2(PredId, PredInfo0, WhatToCheck,
-			MayChangeCalledProc, !ModuleInfo, !Changed,
-			ErrsInThisPred, !IO),
+            MayChangeCalledProc, !ModuleInfo, !Changed, ErrsInThisPred, !IO),
 		( ErrsInThisPred = 0 ->
 			true
 		;
 			module_info_num_errors(!.ModuleInfo, ModNumErrors0),
 			ModNumErrors1 = ModNumErrors0 + ErrsInThisPred,
-			module_info_set_num_errors(ModNumErrors1,
-				!ModuleInfo),
+            module_info_set_num_errors(ModNumErrors1, !ModuleInfo),
 			module_info_remove_predid(PredId, !ModuleInfo)
 		),
 		!:NumErrors = !.NumErrors + ErrsInThisPred,
@@ -659,7 +652,7 @@
 %-----------------------------------------------------------------------------%
 
 	% Mode-check the code for single predicate.
-
+    %
 modecheck_pred_mode(PredId, PredInfo0, WhatToCheck, MayChangeCalledProc,
 		!ModuleInfo, NumErrors, !IO) :-
 	modecheck_pred_mode_2(PredId, PredInfo0, WhatToCheck,
@@ -678,8 +671,7 @@
 		(
 			some [ProcInfo] (
 				map__member(ProcTable, _ProcId, ProcInfo),
-				proc_info_maybe_declared_argmodes(ProcInfo,
-					yes(_))
+                proc_info_maybe_declared_argmodes(ProcInfo, yes(_))
 			)
 		->
 			% there was at least one declared mode for this
@@ -687,56 +679,53 @@
 			true
 		;
 			% there were no declared modes for this procedure
-			maybe_report_error_no_modes(PredId, PredInfo0,
-				!.ModuleInfo, !IO)
+            maybe_report_error_no_modes(PredId, PredInfo0, !.ModuleInfo, !IO)
 		)
 	;
 		WhatToCheck = check_unique_modes
 	),
-	% Note that we use pred_info_procids rather than
-	% pred_info_all_procids here, which means that we
-	% don't process modes that have already been inferred
-	% as invalid.
+    % Note that we use pred_info_procids rather than pred_info_all_procids
+    % here, which means that we don't process modes that have already been
+    % inferred as invalid.
 	ProcIds = pred_info_procids(PredInfo0),
 	modecheck_procs(ProcIds, PredId, WhatToCheck, MayChangeCalledProc,
 		!ModuleInfo, !Changed, 0, NumErrors, !IO).
 
 	% Iterate over the list of modes for a predicate.
-
+    %
 :- pred modecheck_procs(list(proc_id)::in, pred_id::in, how_to_check_goal::in,
 	may_change_called_proc::in, module_info::in, module_info::out,
-	bool::in, bool::out, int::in, int::out, io::di, io::uo)
-	is det.
+    bool::in, bool::out, int::in, int::out, io::di, io::uo) is det.
 
 modecheck_procs([], _PredId, _, _, !ModuleInfo, !Changed, !Errs, !IO).
 modecheck_procs([ProcId | ProcIds], PredId, WhatToCheck, MayChangeCalledProc,
 		!ModuleInfo, !Changed, !Errs, !IO) :-
-	% mode-check that mode of the predicate
-	modecheck_proc_2(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
+    % Mode-check that mode of the predicate.
+    maybe_modecheck_proc(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
 		!ModuleInfo, !Changed, NumErrors, !IO),
 	!:Errs = !.Errs + NumErrors,
-		% recursively process the remaining modes
+    % Recursively process the remaining modes.
 	modecheck_procs(ProcIds, PredId, WhatToCheck, MayChangeCalledProc,
 		!ModuleInfo, !Changed, !Errs, !IO).
 
 %-----------------------------------------------------------------------------%
 
 	% Mode-check the code for predicate in a given mode.
-
+    %
 modecheck_proc(ProcId, PredId, !ModuleInfo, NumErrors, Changed, !IO) :-
-	modecheck_proc(ProcId, PredId, check_modes, may_change_called_proc,
+    modecheck_proc_general(ProcId, PredId, check_modes, may_change_called_proc,
 		!ModuleInfo, NumErrors, Changed, !IO).
 
-modecheck_proc(ProcId, PredId, WhatToCheck, MayChangeCalledProc, !ModuleInfo,
-		NumErrors, Changed, !IO) :-
-	modecheck_proc_2(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
+modecheck_proc_general(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
+        !ModuleInfo, NumErrors, Changed, !IO) :-
+    maybe_modecheck_proc(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
 		!ModuleInfo, no, Changed, NumErrors, !IO).
 
-:- pred modecheck_proc_2(proc_id::in, pred_id::in, how_to_check_goal::in,
+:- pred maybe_modecheck_proc(proc_id::in, pred_id::in, how_to_check_goal::in,
 	may_change_called_proc::in, module_info::in, module_info::out,
 	bool::in, bool::out, int::out, io::di, io::uo) is det.
 
-modecheck_proc_2(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
+maybe_modecheck_proc(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
 		!ModuleInfo, !Changed, NumErrors, !IO) :-
 		% get the proc_info from the module_info
 	module_info_pred_proc_info(!.ModuleInfo, PredId, ProcId,
@@ -745,7 +734,7 @@
 		NumErrors = 0
 	;
 			% modecheck it
-		modecheck_proc_3(ProcId, PredId, WhatToCheck,
+        do_modecheck_proc(ProcId, PredId, WhatToCheck,
 			MayChangeCalledProc, !ModuleInfo, ProcInfo0, ProcInfo,
 			!Changed, NumErrors, !IO),
 
@@ -761,15 +750,15 @@
 
 modecheck_proc_info(ProcId, PredId, !ModuleInfo, !ProcInfo, NumErrors, !IO) :-
 	WhatToCheck = check_modes,
-	modecheck_proc_3(ProcId, PredId, WhatToCheck, may_change_called_proc,
+    do_modecheck_proc(ProcId, PredId, WhatToCheck, may_change_called_proc,
 		!ModuleInfo, !ProcInfo, no, _Changed, NumErrors, !IO).
 
-:- pred modecheck_proc_3(proc_id::in, pred_id::in, how_to_check_goal::in,
+:- pred do_modecheck_proc(proc_id::in, pred_id::in, how_to_check_goal::in,
 	may_change_called_proc::in, module_info::in, module_info::out,
 	proc_info::in, proc_info::out, bool::in, bool::out, int::out,
 	io::di, io::uo) is det.
 
-modecheck_proc_3(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
+do_modecheck_proc(ProcId, PredId, WhatToCheck, MayChangeCalledProc,
 		!ModuleInfo, !ProcInfo, !Changed, NumErrors, !IO) :-
 		% extract the useful fields in the proc_info
 	proc_info_headvars(!.ProcInfo, HeadVars),
@@ -782,98 +771,165 @@
 		% we use the context of the mode declaration.
 	module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
 	pred_info_clauses_info(PredInfo, ClausesInfo),
-	clauses_info_clauses(ClausesInfo, ClauseList),
-	( ClauseList = [FirstClause | _] ->
+    clauses_info_clauses_only(ClausesInfo, ClauseList),
+    (
+        ClauseList = [FirstClause | _],
 		FirstClause = clause(_, _, _, Context)
 	;
+        ClauseList = [],
 		proc_info_context(!.ProcInfo, Context)
 	),
 
 	%
-	% modecheck the clause - first set the initial instantiation
-	% of the head arguments, mode-check the body, and
-	% then check that the final instantiation matches that in
-	% the mode declaration
+    % Modecheck the body. First set the initial instantiation of the head
+    % arguments, then modecheck the body, and then check that the final
+    % instantiation matches that in the mode declaration.
 	%
 
-		% construct the initial instmap
+    some [!ModeInfo] (
+            % Construct the initial instmap.
 	mode_list_get_initial_insts(ArgModes0, !.ModuleInfo, ArgInitialInsts),
 	assoc_list__from_corresponding_lists(HeadVars, ArgInitialInsts,
 		InstAL),
 	instmap__from_assoc_list(InstAL, InstMap0),
 
-		% construct the initial set of live vars:
-		% initially, only the non-clobbered head variables are live
+            % Construct the initial set of live vars:
+            % initially, only the non-clobbered head variables are live.
 	get_live_vars(HeadVars, ArgLives0, LiveVarsList),
 	set__list_to_set(LiveVarsList, LiveVars),
 
-		% initialize the mode info
+            % Initialize the mode info.
 	mode_info_init(!.ModuleInfo, PredId, ProcId, Context, LiveVars,
-		InstMap0, WhatToCheck, MayChangeCalledProc, ModeInfo0),
-	mode_info_set_changed_flag(!.Changed, ModeInfo0, ModeInfo1),
+            InstMap0, WhatToCheck, MayChangeCalledProc, !:ModeInfo),
+        mode_info_set_changed_flag(!.Changed, !ModeInfo),
 
-		% modecheck the procedure body
-	( WhatToCheck = check_unique_modes ->
-		unique_modes__check_goal(Body0, Body1, ModeInfo1, ModeInfo2,
-			!IO)
-	;
-		modecheck_goal(Body0, Body1, ModeInfo1, ModeInfo2, !IO)
-	),
-
-		% Check that final insts match those specified in the
-		% mode declaration
-	mode_list_get_final_insts(ArgModes0, !.ModuleInfo, ArgFinalInsts0),
 	pred_info_get_markers(PredInfo, Markers),
 	( check_marker(Markers, infer_modes) ->
 		InferModes = yes
 	;
 		InferModes = no
 	),
-	modecheck_final_insts_2(HeadVars, ArgFinalInsts0, InferModes,
-		ArgFinalInsts, Body1, Body, ModeInfo2, ModeInfo3),
+        mode_list_get_final_insts(ArgModes0, !.ModuleInfo, ArgFinalInsts0),
 
-	( InferModes = yes ->
+        (
+            WhatToCheck = check_modes,
+            InferModes = no,
+            check_marker(Markers, mode_check_clauses),
+            Body0 = disj(Disjuncts0) - BodyGoalInfo0,
+            Disjuncts0 = [_ | _],
+            goal_info_get_nonlocals(BodyGoalInfo0, BodyNonLocals),
+            mode_info_get_var_types(!.ModeInfo, VarTypes0),
+            SolverNonLocals = list__filter(
+                is_solver_var(VarTypes0, !.ModuleInfo),
+                set__to_sorted_list(BodyNonLocals)),
+            SolverNonLocals = []
+        ->
+            goal_info_get_context(BodyGoalInfo0, BodyContext),
+            term__context_init(EmptyContext),
+            ( BodyContext = EmptyContext ->
+                true 
+            ;
+                mode_info_set_context(BodyContext, !ModeInfo)
+            ),
+
+            (
+                WhatToCheck = check_modes,
+                % Modecheck each clause of the procedure body separately.
+                Disjuncts1 = flatten_disjs(Disjuncts0),
+                list__map_foldl2(
+                    modecheck_clause(HeadVars, InstMap0, ArgFinalInsts0),
+                    Disjuncts1, Disjuncts, !ModeInfo, !IO),
+
+                % Manufacture an instmap_delta for the disjunction as a whole.
+                assoc_list__from_corresponding_lists(HeadVars, ArgFinalInsts0,
+                    HeadVarFinalInsts),
+                instmap__from_assoc_list(HeadVarFinalInsts, FinalInstMap),
+                compute_instmap_delta(InstMap0, FinalInstMap, BodyNonLocals,
+                    DeltaInstMap),
+                goal_info_set_instmap_delta(BodyGoalInfo0, DeltaInstMap,
+                    BodyGoalInfo),
+                Body = disj(Disjuncts) - BodyGoalInfo,
+                ArgFinalInsts = ArgFinalInsts0
+            ;
+                WhatToCheck = check_unique_modes,
+                error("do_modecheck_proc: unexpected check_unique_modes")
+            )
+        ;
+            % Modecheck the procedure body as a single goal.
+            (
+                WhatToCheck = check_modes,
+                modecheck_goal(Body0, Body1, !ModeInfo, !IO)
+            ;
+                WhatToCheck = check_unique_modes,
+                unique_modes__check_goal(Body0, Body1, !ModeInfo, !IO)
+            ),
+
+                % Check that final insts match those specified in the
+                % mode declaration.
+            modecheck_final_insts(HeadVars, InferModes, ArgFinalInsts0,
+                ArgFinalInsts, Body1, Body, !ModeInfo)
+        ),
+
+        (
+            InferModes = yes,
 		% For inferred predicates, we don't report the
 		% error(s) here; instead we just save them in the
 		% proc_info, thus marking that procedure as invalid.
-		ModeInfo = ModeInfo3,
 		% This is sometimes handy for debugging:
-		% report_mode_errors(ModeInfo3, ModeInfo),
-		mode_info_get_errors(ModeInfo, ModeErrors),
+            % report_mode_errors(!ModeInfo),
+            mode_info_get_errors(!.ModeInfo, ModeErrors),
 		!:ProcInfo = !.ProcInfo ^ mode_errors := ModeErrors,
 		NumErrors = 0
 	;
+            InferModes = no,
 		% report any errors we found
-		report_mode_errors(ModeInfo3, ModeInfo, !IO),
-		mode_info_get_num_errors(ModeInfo, NumErrors)
+            report_mode_errors(!ModeInfo, !IO),
+            mode_info_get_num_errors(!.ModeInfo, NumErrors)
 	),
 	% save away the results
 	inst_lists_to_mode_list(ArgInitialInsts, ArgFinalInsts, ArgModes),
-	mode_info_get_changed_flag(ModeInfo, !:Changed),
-	mode_info_get_module_info(ModeInfo, !:ModuleInfo),
-	mode_info_get_varset(ModeInfo, VarSet),
-	mode_info_get_var_types(ModeInfo, VarTypes),
+        mode_info_get_changed_flag(!.ModeInfo, !:Changed),
+        mode_info_get_module_info(!.ModeInfo, !:ModuleInfo),
+        mode_info_get_varset(!.ModeInfo, VarSet),
+        % VarTypes may be the same as VarTypes0, since mode checking can
+        % add new variables (e.g. when handling calls in implied modes).
+        mode_info_get_var_types(!.ModeInfo, VarTypes),
 	proc_info_set_goal(Body, !ProcInfo),
 	proc_info_set_varset(VarSet, !ProcInfo),
 	proc_info_set_vartypes(VarTypes, !ProcInfo),
-	proc_info_set_argmodes(ArgModes, !ProcInfo).
+        proc_info_set_argmodes(ArgModes, !ProcInfo)
+    ).
+
+:- pred modecheck_clause(list(prog_var)::in, instmap::in, list(inst)::in,
+    hlds_goal::in, hlds_goal::out, mode_info::in, mode_info::out,
+    io::di, io::uo) is det.
+
+modecheck_clause(HeadVars, InstMap0, ArgFinalInsts0, Disjunct0, Disjunct,
+        !ModeInfo, !IO) :-
+    mode_info_set_instmap(InstMap0, !ModeInfo),
+    modecheck_goal(Disjunct0, Disjunct1, !ModeInfo, !IO),
 
-	% modecheck_final_insts for a lambda expression
-modecheck_final_insts(HeadVars, ArgFinalInsts, !Goal, !ModeInfo) :-
+        % Check that final insts match those specified in the
+        % mode declaration.
+    modecheck_final_insts(HeadVars, no, ArgFinalInsts0,
+        _ArgFinalInsts, Disjunct1, Disjunct, !ModeInfo).
+
+    % Modecheck_final_insts for a lambda expression.
+    %
+modecheck_lambda_final_insts(HeadVars, ArgFinalInsts, !Goal, !ModeInfo) :-
 		% for lambda expressions, modes must always be
 		% declared, we never infer them.
 	InferModes = no,
-	modecheck_final_insts_2(HeadVars, ArgFinalInsts, InferModes,
+    modecheck_final_insts(HeadVars, InferModes, ArgFinalInsts,
 		_NewFinalInsts, !Goal, !ModeInfo).
 
-:- pred modecheck_final_insts_2(list(prog_var)::in, list(inst)::in, bool::in,
-	list(inst)::out, hlds_goal::in, hlds_goal::out,
+:- pred modecheck_final_insts(list(prog_var)::in, bool::in,
+    list(inst)::in, list(inst)::out, hlds_goal::in, hlds_goal::out,
 	mode_info::in, mode_info::out) is det.
 
-	% check that the final insts of the head vars matches their
-	% expected insts
+    % Check that the final insts of the head vars match their expected insts.
 	%
-modecheck_final_insts_2(HeadVars, FinalInsts0, InferModes, FinalInsts,
+modecheck_final_insts(HeadVars, InferModes, FinalInsts0, FinalInsts,
 		Body0, Body, !ModeInfo) :-
 	mode_info_get_module_info(!.ModeInfo, ModuleInfo),
 	mode_info_get_errors(!.ModeInfo, Errors),
@@ -883,7 +939,8 @@
 	% first mode error anyway, and the resulting FinalInsts
 	% will not be used; but it improves the readability of the
 	% rejected modes.
-	( Errors \= [] ->
+    (
+        Errors = [_ | _],
 		% If there were any mode errors, something must have
 		% changed, since if the procedure had mode errors
 		% in a previous pass then it wouldn't have been
@@ -891,16 +948,16 @@
 		Changed0 = yes,
 		instmap__init_unreachable(InstMap)
 	;
+        Errors = [],
 		Changed0 = no,
 		mode_info_get_instmap(!.ModeInfo, InstMap)
 	),
 	mode_info_get_var_types(!.ModeInfo, VarTypes),
 	instmap__lookup_vars(HeadVars, InstMap, VarFinalInsts1),
 	map__apply_to_list(HeadVars, VarTypes, ArgTypes),
-
-	( InferModes = yes ->
-		normalise_insts(VarFinalInsts1, ArgTypes, ModuleInfo,
-			VarFinalInsts2),
+    (
+        InferModes = yes,
+        normalise_insts(VarFinalInsts1, ArgTypes, ModuleInfo, VarFinalInsts2),
 		%
 		% make sure we set the final insts of any variables which
 		% we assumed were dead to `clobbered'.
@@ -913,16 +970,15 @@
 		map__lookup(Procs, ProcId, ProcInfo),
 		proc_info_arglives(ProcInfo, ModuleInfo, ArgLives),
 		maybe_clobber_insts(VarFinalInsts2, ArgLives, FinalInsts),
-		check_final_insts(HeadVars, FinalInsts0, FinalInsts,
-			InferModes, 1, ModuleInfo, Body0, Body, no, Changed1,
-			!ModeInfo),
+        check_final_insts(HeadVars, FinalInsts0, FinalInsts, InferModes, 1,
+            ModuleInfo, Body0, Body, no, Changed1, !ModeInfo),
 		mode_info_get_changed_flag(!.ModeInfo, Changed2),
 		bool__or_list([Changed0, Changed1, Changed2], Changed),
 		mode_info_set_changed_flag(Changed, !ModeInfo)
 	;
+        InferModes = no,
 		check_final_insts(HeadVars, FinalInsts0, VarFinalInsts1,
-			InferModes, 1, ModuleInfo, Body0, Body, no, _Changed1,
-			!ModeInfo),
+            InferModes, 1, ModuleInfo, Body0, Body, no, _Changed1, !ModeInfo),
 		FinalInsts = FinalInsts0
 	).
 
@@ -975,11 +1031,10 @@
 				%
 				inst_match__inst_is_free(ModuleInfo, VarInst),
 				inst_match__inst_is_any(ModuleInfo, Inst),
-				type_util__type_is_solver_type(ModuleInfo,
-					Type)
+                type_util__type_is_solver_type(ModuleInfo, Type)
 			->
-				prepend_initialisation_call(Var, Type,
-					VarInst, !Goal, !ModeInfo)
+                prepend_initialisation_call(Var, Type, VarInst, !Goal,
+                    !ModeInfo)
 			;
 				% If we're inferring the mode, then don't
 				% report an error, just set changed to yes
@@ -991,15 +1046,9 @@
 			;
 				% XXX this might need to be reconsidered now
 				% we have unique modes
-				(
-					inst_matches_initial(VarInst, Inst,
-						Type, ModuleInfo)
-				->
+                ( inst_matches_initial(VarInst, Inst, Type, ModuleInfo) ->
 					Reason = too_instantiated
-				;
-					inst_matches_initial(Inst, VarInst,
-						Type, ModuleInfo)
-				->
+                ; inst_matches_initial(Inst, VarInst, Type, ModuleInfo) ->
 					Reason = not_instantiated_enough
 				;
 					% I don't think this can happen.
@@ -1008,14 +1057,12 @@
 				),
 				set__init(WaitingVars),
 				mode_info_error(WaitingVars,
-					mode_error_final_inst(ArgNum,
-						Var, VarInst, Inst, Reason),
+                    mode_error_final_inst(ArgNum, Var, VarInst, Inst, Reason),
 					!ModeInfo)
 			)
 		),
 		check_final_insts(VarsTail, InstsTail, VarInstsTail,
-			InferModes, ArgNum + 1, ModuleInfo,
-			!Goal, !Changed, !ModeInfo)
+            InferModes, ArgNum + 1, ModuleInfo, !Goal, !Changed, !ModeInfo)
 	;
 		error("check_final_insts: length mismatch")
 	).
@@ -1071,8 +1118,7 @@
 		%
 	mode_info_get_instmap(!.ModeInfo, InstMap0),
 	modecheck_goal_expr(Goal0, GoalInfo0, Goal, !ModeInfo, !IO),
-	compute_goal_instmap_delta(InstMap0, Goal, GoalInfo0, GoalInfo,
-		!ModeInfo).
+    compute_goal_instmap_delta(InstMap0, Goal, GoalInfo0, GoalInfo, !ModeInfo).
 
 compute_goal_instmap_delta(InstMap0, Goal, GoalInfo0, GoalInfo, !ModeInfo) :-
 	( Goal = conj([]) ->
@@ -1089,8 +1135,7 @@
 	;
 		goal_info_get_nonlocals(GoalInfo0, NonLocals),
 		mode_info_get_instmap(!.ModeInfo, InstMap),
-		compute_instmap_delta(InstMap0, InstMap,
-			NonLocals, DeltaInstMap)
+        compute_instmap_delta(InstMap0, InstMap, NonLocals, DeltaInstMap)
 	),
 	goal_info_set_instmap_delta(GoalInfo0, DeltaInstMap, GoalInfo).
 
@@ -1109,21 +1154,26 @@
 	% To make sure that we don't try to bind a variable more than
 	% once (by binding it in more than one conjunct), we maintain a
 	% datastructure that keeps track of three things:
-	%	the set of variables that are nonlocal to the conjuncts
+    %
+    % - the set of variables that are nonlocal to the conjuncts
 	%	(which may be a superset of the nonlocals of the par_conj
 	%	as a whole);
-	%	the set of nonlocal variables that have been bound in the
+    % - the set of nonlocal variables that have been bound in the
 	%	current conjunct; and
-	%	the set of variables that were bound in previous conjuncts.
+    % - the set of variables that were bound in previous conjuncts.
+    %
 	% When binding a variable, we check that it wasn't in the set of
 	% variables bound in other conjuncts, and we add it to the set of
 	% variables bound in this conjunct.
+    %
 	% At the end of the conjunct, we add the set of variables bound in
 	% this conjunct to the set of variables bound in previous conjuncts
 	% and set the set of variables bound in the current conjunct to
 	% empty.
+    %
 	% A stack of these structures is maintained to handle nested parallel
 	% conjunctions properly.
+    %
 modecheck_goal_expr(par_conj(List0), GoalInfo0, par_conj(List), !ModeInfo,
 		!IO) :-
 	mode_checkpoint(enter, "par_conj", !ModeInfo, !IO),
@@ -1135,18 +1185,22 @@
 
 modecheck_goal_expr(disj(Disjs0), GoalInfo0, Goal, !ModeInfo, !IO) :-
 	mode_checkpoint(enter, "disj", !ModeInfo, !IO),
-	( Disjs0 = [] ->	% for efficiency, optimize common case
+    (
+        Disjs0 = [],    % for efficiency, optimize common case
 		Goal = disj(Disjs0),
 		instmap__init_unreachable(InstMap),
 		mode_info_set_instmap(InstMap, !ModeInfo)
 	;
+        % If you modify this code, you may also need to modify
+        % modecheck_clause or the code that calls it.
+
+        Disjs0 = [_ | _],
 		goal_info_get_nonlocals(GoalInfo0, NonLocals),
 		modecheck_disj_list(Disjs0, Disjs1, InstMapList0,
 			!ModeInfo, !IO),
 		mode_info_get_var_types(!.ModeInfo, VarTypes),
 		handle_solver_vars_in_disjs(set__to_sorted_list(NonLocals),
-			VarTypes, Disjs1, Disjs2, InstMapList0, InstMapList,
-			!ModeInfo),
+            VarTypes, Disjs1, Disjs2, InstMapList0, InstMapList, !ModeInfo),
 		Disjs = flatten_disjs(Disjs2),
 		instmap__merge(NonLocals, InstMapList, disj, !ModeInfo),
 		disj_list_to_goal(Disjs, GoalInfo0, Goal - _GoalInfo)
@@ -1185,8 +1239,7 @@
 	mode_info_get_var_types(!.ModeInfo, VarTypes),
 	handle_solver_vars_in_ite(set__to_sorted_list(NonLocals), VarTypes,
 		Then1, Then, Else1, Else,
-		InstMapThen1, InstMapThen, InstMapElse1, InstMapElse,
-		!ModeInfo),
+        InstMapThen1, InstMapThen, InstMapElse1, InstMapElse, !ModeInfo),
 	mode_info_set_instmap(InstMap0, !ModeInfo),
 	instmap__merge(NonLocals, [InstMapThen, InstMapElse], if_then_else,
 		!ModeInfo),
@@ -1250,8 +1303,7 @@
 			% efficient than letting the usual more ordering
 			% algorithm delay it repeatedly.
 
-			list__reverse([UnifyTermGoal | UnifyArgGoals],
-				RevConj),
+            list__reverse([UnifyTermGoal | UnifyArgGoals], RevConj),
 			RevSubGoal0 = conj(RevConj) - SubGoalInfo,
 			mode_checkpoint(enter, "ground scope", !ModeInfo, !IO),
 			modecheck_goal(RevSubGoal0, SubGoal, !ModeInfo, !IO),
@@ -1317,8 +1369,7 @@
 	;
 		GenericCall = unsafe_cast,
 		(
-			goal_info_has_feature(GoalInfo0,
-				keep_constant_binding),
+            goal_info_has_feature(GoalInfo0, keep_constant_binding),
 			mode_info_get_instmap(!.ModeInfo, InstMap),
 			(
 				Args0 = [Arg1Prime, _Arg2Prime],
@@ -1351,8 +1402,7 @@
 		;
 			Modes = Modes0
 		),
-		modecheck_builtin_cast(Modes, Args0, Args, Det, ExtraGoals,
-			!ModeInfo),
+        modecheck_builtin_cast(Modes, Args0, Args, Det, ExtraGoals, !ModeInfo),
 		AllArgs0 = Args0,
 		AllArgs = Args
 	;
@@ -1383,11 +1433,13 @@
 modecheck_goal_expr(switch(Var, CanFail, Cases0), GoalInfo0,
 		switch(Var, CanFail, Cases), !ModeInfo, !IO) :-
 	mode_checkpoint(enter, "switch", !ModeInfo, !IO),
-	( Cases0 = [] ->
+    (
+        Cases0 = [],
 		Cases = [],
 		instmap__init_unreachable(InstMap),
 		mode_info_set_instmap(InstMap, !ModeInfo)
 	;
+        Cases0 = [_ | _],
 		goal_info_get_nonlocals(GoalInfo0, NonLocals),
 		modecheck_case_list(Cases0, Var, Cases, InstMapList,
 			!ModeInfo, !IO),
@@ -1395,10 +1447,12 @@
 	),
 	mode_checkpoint(exit, "switch", !ModeInfo, !IO).
 
-	% to modecheck a pragma_c_code, we just modecheck the proc for
+    % To modecheck a foreign_proc, we just modecheck the proc for
 	% which it is the goal.
-modecheck_goal_expr(foreign_proc(Attributes, PredId, ProcId0, Args0, ExtraArgs,
-		PragmaCode), GoalInfo, Goal, !ModeInfo, !IO) :-
+    %
+modecheck_goal_expr(ForeignProc, GoalInfo, Goal, !ModeInfo, !IO) :-
+    ForeignProc = foreign_proc(Attributes, PredId, ProcId0, Args0, ExtraArgs,
+        PragmaCode),
 	mode_checkpoint(enter, "pragma_foreign_code", !ModeInfo, !IO),
 	mode_info_get_call_id(!.ModeInfo, PredId, CallId),
 	mode_info_get_instmap(!.ModeInfo, InstMap0),
@@ -1478,8 +1532,7 @@
 		handle_extra_goals_contexts(AfterGoals0, Context, AfterGoals),
 		list__append(BeforeGoals, [Goal0 | AfterGoals], GoalList0),
 
-		mode_info_get_may_change_called_proc(!.ModeInfo,
-			MayChangeCalledProc0),
+        mode_info_get_may_change_called_proc(!.ModeInfo, MayChangeCalledProc0),
 
 		% Make sure we don't go into an infinite loop if
 		% there is a bug in the code to add extra goals.
@@ -1487,8 +1540,8 @@
 
 		% We've already worked out which procedure should be called,
 		% we don't need to do it again.
-		mode_info_set_may_change_called_proc(
-			may_not_change_called_proc, !ModeInfo),
+        mode_info_set_may_change_called_proc(may_not_change_called_proc,
+            !ModeInfo),
 
 		mode_info_set_instmap(InstMap0, !ModeInfo),
 
@@ -1505,12 +1558,10 @@
 		% argument unifications, which turns them into assignments,
 		% and we end up repeating the process forever.
 		mode_info_add_goals_live_vars(GoalList0, !ModeInfo),
-		modecheck_conj_list_no_delay(GoalList0, GoalList,
-			!ModeInfo, !IO),
+        modecheck_conj_list_no_delay(GoalList0, GoalList, !ModeInfo, !IO),
 		Goal = conj(GoalList),
 		mode_info_set_checking_extra_goals(no, !ModeInfo),
-		mode_info_set_may_change_called_proc(MayChangeCalledProc0,
-			!ModeInfo)
+        mode_info_set_may_change_called_proc(MayChangeCalledProc0, !ModeInfo)
 	;
 		Goal = MainGoal
 	).
@@ -1538,147 +1589,120 @@
 handle_solver_vars_in_disjs(NonLocals, VarTypes, Disjs0, Disjs,
 		InstMaps0, InstMaps, !ModeInfo) :-
 	mode_info_get_module_info(!.ModeInfo, ModuleInfo),
-	EnsureInitialised =
-		solver_vars_that_must_be_initialised(NonLocals, VarTypes,
-		ModuleInfo, InstMaps0),
+    EnsureInitialised = solver_vars_that_must_be_initialised(NonLocals,
+        VarTypes, ModuleInfo, InstMaps0),
 	add_necessary_disj_init_calls(Disjs0, Disjs, InstMaps0, InstMaps,
 		EnsureInitialised, !ModeInfo).
 
-
 :- pred handle_solver_vars_in_ite(list(prog_var)::in,
 	map(prog_var, (type))::in,
 	hlds_goal::in, hlds_goal::out, hlds_goal::in, hlds_goal::out,
 	instmap::in, instmap::out, instmap::in, instmap::out, mode_info::in,
 	mode_info::out) is det.
 
-handle_solver_vars_in_ite(NonLocals, VarTypes,
-		Then0, Then, Else0, Else,
-		ThenInstMap0, ThenInstMap, ElseInstMap0, ElseInstMap,
-		!ModeInfo) :-
-
+handle_solver_vars_in_ite(NonLocals, VarTypes, Then0, Then, Else0, Else,
+        ThenInstMap0, ThenInstMap, ElseInstMap0, ElseInstMap, !ModeInfo) :-
 	mode_info_get_module_info(!.ModeInfo, ModuleInfo),
-	EnsureInitialised =
-		solver_vars_that_must_be_initialised(NonLocals, VarTypes,
-		ModuleInfo, [ThenInstMap0, ElseInstMap0]),
+    EnsureInitialised = solver_vars_that_must_be_initialised(NonLocals,
+        VarTypes, ModuleInfo, [ThenInstMap0, ElseInstMap0]),
 
-	ThenVarsToInit =
-		solver_vars_to_init(EnsureInitialised, ModuleInfo,
+    ThenVarsToInit = solver_vars_to_init(EnsureInitialised, ModuleInfo,
 		ThenInstMap0),
-	construct_initialisation_calls(ThenVarsToInit, ThenInitCalls,
-		!ModeInfo),
+    construct_initialisation_calls(ThenVarsToInit, ThenInitCalls, !ModeInfo),
 	Then = append_init_calls_to_goal(ThenInitCalls, Then0),
 	ThenInstMap = set_vars_to_inst_any(ThenVarsToInit, ThenInstMap0),
 
-	ElseVarsToInit =
-		solver_vars_to_init(EnsureInitialised, ModuleInfo,
+    ElseVarsToInit = solver_vars_to_init(EnsureInitialised, ModuleInfo,
 		ElseInstMap0),
-	construct_initialisation_calls(ElseVarsToInit, ElseInitCalls,
-		!ModeInfo),
+    construct_initialisation_calls(ElseVarsToInit, ElseInitCalls, !ModeInfo),
 	Else = append_init_calls_to_goal(ElseInitCalls, Else0),
 	ElseInstMap = set_vars_to_inst_any(ElseVarsToInit, ElseInstMap0).
 
-
 :- func solver_vars_that_must_be_initialised(list(prog_var),
-	map(prog_var, (type)), module_info, list(instmap)) = list(prog_var).
+    vartypes, module_info, list(instmap)) = list(prog_var).
+
+solver_vars_that_must_be_initialised(Vars, VarTypes, ModuleInfo, InstMaps) =
+    list__filter(
+        solver_var_must_be_initialised(VarTypes, ModuleInfo, InstMaps),
+        Vars).
 
-solver_vars_that_must_be_initialised([], _VarTypes, _ModuleInfo, _InstMaps) =
-	[].
+:- pred solver_var_must_be_initialised(vartypes::in, module_info::in,
+    list(instmap)::in, prog_var::in) is semidet.
 
-solver_vars_that_must_be_initialised([Var | Vars], VarTypes, ModuleInfo,
-		InstMaps) =
-	( if
-		VarType = VarTypes ^ elem(Var),
+solver_var_must_be_initialised(VarTypes, ModuleInfo, InstMaps, Var) :-
+    map__lookup(VarTypes, Var, VarType),
 		type_util__type_is_solver_type(ModuleInfo, VarType),
 		list__member(InstMap, InstMaps),
 		instmap__lookup_var(InstMap, Var, Inst),
-		not inst_match__inst_is_free(ModuleInfo, Inst)
-	  then
-	  	[ Var | solver_vars_that_must_be_initialised(Vars, VarTypes,
-			ModuleInfo, InstMaps) ]
-	  else
-	  	solver_vars_that_must_be_initialised(Vars, VarTypes,
-			ModuleInfo, InstMaps)
-	).
+    not inst_match__inst_is_free(ModuleInfo, Inst).
+
+:- pred is_solver_var(vartypes::in, module_info::in, prog_var::in) is semidet.
 
+is_solver_var(VarTypes, ModuleInfo, Var) :-
+    map__lookup(VarTypes, Var, VarType),
+    type_util__type_is_solver_type(ModuleInfo, VarType).
 
 :- pred add_necessary_disj_init_calls(list(hlds_goal)::in,
 	list(hlds_goal)::out, list(instmap)::in, list(instmap)::out,
 	list(prog_var)::in, mode_info::in, mode_info::out) is det.
 
 add_necessary_disj_init_calls([], [], [], [], _EnsureInitialised, !ModeInfo).
-
 add_necessary_disj_init_calls([], _, [_ | _], _, _, _, _) :-
 	error("modes.add_necessary_init_calls: mismatched lists").
-
 add_necessary_disj_init_calls([_ | _], _, [], _, _, _, _) :-
 	error("modes.add_necessary_init_calls: mismatched lists").
-
 add_necessary_disj_init_calls([Goal0 | Goals0], [Goal | Goals],
 		[InstMap0 | InstMaps0], [InstMap | InstMaps],
 		EnsureInitialised, !ModeInfo) :-
 	mode_info_get_module_info(!.ModeInfo, ModuleInfo),
-	VarsToInit =
-		solver_vars_to_init(EnsureInitialised, ModuleInfo, InstMap0),
+    VarsToInit = solver_vars_to_init(EnsureInitialised, ModuleInfo, InstMap0),
 	construct_initialisation_calls(VarsToInit, InitCalls, !ModeInfo),
 	Goal = append_init_calls_to_goal(InitCalls, Goal0),
 	InstMap = set_vars_to_inst_any(VarsToInit, InstMap0),
 	add_necessary_disj_init_calls(Goals0, Goals, InstMaps0, InstMaps,
 		EnsureInitialised, !ModeInfo).
 
-
 :- func append_init_calls_to_goal(list(hlds_goal), hlds_goal) = hlds_goal.
 
 append_init_calls_to_goal(InitCalls, Goal0) = Goal :-
 	Goal0 = GoalExpr - GoalInfo,
-	(
-		GoalExpr = disj(Disjs0)
-	->
-		Disjs = list__map(append_init_calls_to_goal(InitCalls),
-				Disjs0),
+    ( GoalExpr = disj(Disjs0) ->
+        Disjs = list__map(append_init_calls_to_goal(InitCalls), Disjs0),
 		Goal  = disj(Disjs) - GoalInfo
 	;
 		goal_to_conj_list(Goal0, Conjs),
 		conj_list_to_goal(Conjs ++ InitCalls, GoalInfo, Goal)
 	).
 
-
 :- func flatten_disjs(list(hlds_goal)) = list(hlds_goal).
 
 flatten_disjs(Disjs) = list__foldr(flatten_disj, Disjs, []).
 
-
 :- func flatten_disj(hlds_goal, list(hlds_goal)) = list(hlds_goal).
 
 flatten_disj(Disj, Disjs0) = Disjs :-
-	(
-		Disj = disj(Disjs1) - _GoalInfo
-	->
+    ( Disj = disj(Disjs1) - _GoalInfo ->
 		Disjs = list__foldr(flatten_disj, Disjs1, Disjs0)
 	;
 		Disjs = [Disj | Disjs0]
 	).
 
-
 :- func solver_vars_to_init(list(prog_var), module_info, instmap) =
 	list(prog_var).
 
-solver_vars_to_init([], _ModuleInfo, _InstMap) = [].
+solver_vars_to_init(Vars, ModuleInfo, InstMap) =
+    list__filter(solver_var_to_init(ModuleInfo, InstMap), Vars).
 
-solver_vars_to_init([Var | Vars], ModuleInfo, InstMap) =
-	( if
-		instmap__lookup_var(InstMap, Var, Inst),
-		inst_match__inst_is_free(ModuleInfo, Inst)
-	  then
-	  	[Var | solver_vars_to_init(Vars, ModuleInfo, InstMap)]
-	  else
-	  	solver_vars_to_init(Vars, ModuleInfo, InstMap)
-	).
+:- pred solver_var_to_init(module_info::in, instmap::in, prog_var::in)
+    is semidet.
 
+solver_var_to_init(ModuleInfo, InstMap, Var) :-
+    instmap__lookup_var(InstMap, Var, Inst),
+    inst_match__inst_is_free(ModuleInfo, Inst).
 
 :- func set_vars_to_inst_any(list(prog_var), instmap) = instmap.
 
 set_vars_to_inst_any([], InstMap) = InstMap.
-
 set_vars_to_inst_any([Var | Vars], InstMap0) = InstMap :-
 	instmap__set(InstMap0, Var, any_inst, InstMap1),
 	InstMap = set_vars_to_inst_any(Vars, InstMap1).
@@ -1687,6 +1711,7 @@
 
 	% Modecheck a conjunction without doing any reordering.
 	% This is used by handle_extra_goals above.
+    %
 :- pred modecheck_conj_list_no_delay(list(hlds_goal)::in, list(hlds_goal)::out,
 	mode_info::in, mode_info::out, io::di, io::uo) is det.
 
@@ -1700,8 +1725,7 @@
 	( instmap__is_unreachable(InstMap) ->
 		% We should not mode-analyse the remaining goals, since they
 		% are unreachable.  Instead we optimize them away, so that
-		% later passes won't complain about them not having mode
-		% information.
+        % later passes won't complain about them not having mode information.
 		mode_info_remove_goals_live_vars(Goals0, !ModeInfo),
 		Goals  = []
 	;
@@ -1717,8 +1741,7 @@
 	mode_info_get_errors(!.ModeInfo, OldErrors),
 	mode_info_set_errors([], !ModeInfo),
 
-	mode_info_get_may_initialise_solver_vars(MayInitEntryValue,
-		!.ModeInfo),
+    mode_info_get_may_initialise_solver_vars(MayInitEntryValue, !.ModeInfo),
 
 	mode_info_get_delay_info(!.ModeInfo, DelayInfo0),
 	delay_info__enter_conj(DelayInfo0, DelayInfo1),
@@ -1730,7 +1753,6 @@
 		% Try to schedule goals without inserting any solver
 		% initialisation calls by setting the mode_info flag
 		% may_initialise_solver_vars to no.
-		%
 	mode_info_set_may_initialise_solver_vars(no, !ModeInfo),
 
 	modecheck_conj_list_2(Goals0, Goals1,
@@ -1742,7 +1764,6 @@
 
 		% Otherwise try scheduling by inserting solver
 		% initialisation calls where necessary.
-		%
 	modecheck_delayed_solver_goals(Goals2, DelayedGoals0, DelayedGoals,
 		RevImpurityErrors0, RevImpurityErrors, !ModeInfo, !IO),
 
@@ -1752,16 +1773,18 @@
 	list__append(OldErrors, NewErrors, Errors),
 	mode_info_set_errors(Errors, !ModeInfo),
 
-	( DelayedGoals \= [] ->
+    (
+        DelayedGoals = [_ | _],
 		% the variables in the delayed goals should not longer
 		% be considered live (the conjunction itself will
 		% delay, and its nonlocals will be made live)
 		mode_info_set_live_vars(LiveVars1, !ModeInfo)
 	;
-		true
+        DelayedGoals = []
 	),
 	% we only report impurity errors if there were no other errors
-	( DelayedGoals = [] ->
+    (
+        DelayedGoals = [],
 		%
 		% report all the impurity errors
 		% (making sure we report the errors in the correct order)
@@ -1770,16 +1793,16 @@
 		mode_info_get_errors(!.ModeInfo, Errors5),
 		list__append(Errors5, ImpurityErrors, Errors6),
 		mode_info_set_errors(Errors6, !ModeInfo)
-	; DelayedGoals = [delayed_goal(_DVars, Error, _DGoal)] ->
+    ;
+        DelayedGoals = [delayed_goal(_DVars, Error, _DGoal)],
 		mode_info_add_error(Error, !ModeInfo)
 	;
+        DelayedGoals = [_, _ | _],
 		get_all_waiting_vars(DelayedGoals, Vars),
-		mode_info_error(Vars,
-			mode_error_conj(DelayedGoals, conj_floundered),
+        mode_info_error(Vars, mode_error_conj(DelayedGoals, conj_floundered),
 			!ModeInfo)
 	),
 		% Restore the value of the may_initialise_solver_vars flag.
-		%
 	mode_info_set_may_initialise_solver_vars(MayInitEntryValue, !ModeInfo).
 
 mode_info_add_goals_live_vars([], !ModeInfo).
@@ -1813,7 +1836,7 @@
 	% goal in the conjunction.  If successful, we wakeup a newly
 	% pending goal (if any), and if not, we delay the goal.  Then we
 	% continue attempting to schedule all the rest of the goals.
-
+    %
 modecheck_conj_list_2([], [], !ImpurityErrors, !ModeInfo, !IO).
 modecheck_conj_list_2([Goal0 | Goals0], Goals, !ImpurityErrors, !ModeInfo,
 		!IO) :-
@@ -1847,8 +1870,7 @@
 		mode_info_set_errors([], !ModeInfo),
 		mode_info_set_instmap(InstMap0, !ModeInfo),
 		mode_info_add_live_vars(NonLocalVars, !ModeInfo),
-		delay_info__delay_goal(DelayInfo0, FirstErrorInfo,
-			Goal0, DelayInfo1),
+        delay_info__delay_goal(DelayInfo0, FirstErrorInfo, Goal0, DelayInfo1),
 		%  delaying an impure goal is an impurity error
 		(
 			Impure = yes,
@@ -1892,8 +1914,7 @@
 		mode_info_remove_goals_live_vars(Goals1, !ModeInfo),
 		Goals2  = []
 	;
-		modecheck_conj_list_2(Goals1, Goals2, !ImpurityErrors,
-			!ModeInfo, !IO)
+        modecheck_conj_list_2(Goals1, Goals2, !ImpurityErrors, !ModeInfo, !IO)
 	),
 	(
 		Errors = [_ | _],
@@ -1990,8 +2011,7 @@
 				% Extract the HLDS goals from the delayed
 				% goals.
 				%
-			Goals0 = list__map(hlds_goal_from_delayed_goal,
-					DelayedGoals0),
+            Goals0 = list__map(hlds_goal_from_delayed_goal, DelayedGoals0),
 
 				% Work out which vars are already
 				% instantiated (i.e. have non-free insts).
@@ -2001,13 +2021,11 @@
 			NonFreeVars0 = set__list_to_set(
 				non_free_vars_in_assoc_list(VarInsts)),
 
-				% Find the set of vars whose instantiation
-				% should lead to a a deterministic
-				% schedule.
+                % Find the set of vars whose instantiation should lead to
+                % a deterministic schedule.
 				%
 			CandidateInitVars = promise_only_solution(
-				candidate_init_vars(!.ModeInfo, Goals0,
-				NonFreeVars0)),
+                candidate_init_vars(!.ModeInfo, Goals0, NonFreeVars0)),
 
 				% And verify that all of these vars are
 				% solver type vars (and can therefore be
@@ -2018,17 +2036,16 @@
 			all [Var] (
 				set__member(Var, CandidateInitVars)
 			=>
-				(	map__lookup(VarTypes, Var, VarType),
-					type_util__type_is_solver_type(
-						ModuleInfo, VarType)
+                (
+                    map__lookup(VarTypes, Var, VarType),
+                    type_util__type_is_solver_type(ModuleInfo, VarType)
 				)
 			)
 		->
 				% Construct the inferred initialisation goals
 				% and try scheduling again.
 				%
-			CandidateInitVarList =
-				set__to_sorted_list(CandidateInitVars),
+            CandidateInitVarList = set__to_sorted_list(CandidateInitVars),
 			construct_initialisation_calls(CandidateInitVarList,
 				InitGoals, !ModeInfo),
 			Goals1 = InitGoals ++ Goals0,
@@ -2039,12 +2056,11 @@
 
 			mode_info_add_goals_live_vars(InitGoals, !ModeInfo),
 
-			modecheck_conj_list_2(Goals1, Goals,
-				!ImpurityErrors, !ModeInfo, !IO),
+            modecheck_conj_list_2(Goals1, Goals, !ImpurityErrors, !ModeInfo,
+                !IO),
 
 			mode_info_get_delay_info(!.ModeInfo, DelayInfo2),
-			delay_info__leave_conj(DelayInfo2, DelayedGoals,
-				DelayInfo3),
+            delay_info__leave_conj(DelayInfo2, DelayedGoals, DelayInfo3),
 			mode_info_set_delay_info(DelayInfo3, !ModeInfo)
 		;
 				% We couldn't identify a deterministic
@@ -2156,7 +2172,6 @@
 		% here we assume that the disjunction is a det switch
 		% and that we can ignore it for the purposes of identifying
 		% candidate vars for initialisation.
-		%
 	Goal = disj(_Goals) - _GoalInfo.
 
 candidate_init_vars_3(ModeInfo, Goal, !NonFree, !CandidateVars) :-
@@ -2165,8 +2180,7 @@
 		% arms are det.  This isn't very accurate and may
 		% need refinement.
 		%
-	Goal = if_then_else(_LocalVars, _CondGoal, ThenGoal, ElseGoal) -
-			_GoalInfo,
+    Goal = if_then_else(_LocalVars, _CondGoal, ThenGoal, ElseGoal) - _GoalInfo,
 	candidate_init_vars_3(ModeInfo, ThenGoal, !.NonFree, NonFreeThen,
 		!CandidateVars),
 	candidate_init_vars_3(ModeInfo, ElseGoal, !.NonFree, NonFreeElse,
@@ -2266,8 +2280,7 @@
 		% This arg is unused.
 		true
 	),
-	candidate_init_vars_call(ModeInfo, Args, Modes,
-		!NonFree, !CandidateVars).
+    candidate_init_vars_call(ModeInfo, Args, Modes, !NonFree, !CandidateVars).
 
 	% We may still have some unscheduled goals.  This may be because some
 	% initialisation calls are needed to turn some solver type vars
@@ -2363,16 +2376,16 @@
 	delay_info__enter_conj(DelayInfo2, DelayInfo3),
 	redelay_goals(HeadVarUnificationGoals, DelayInfo3, DelayInfo),
 	mode_info_set_delay_info(DelayInfo, !ModeInfo),
-	( NonHeadVarUnificationGoals = [] ->
-		true
+    (
+        NonHeadVarUnificationGoals = []
 	;
+        NonHeadVarUnificationGoals = [_ | _],
 		get_all_waiting_vars(NonHeadVarUnificationGoals, Vars),
 		ModeError = mode_error_conj(NonHeadVarUnificationGoals,
 			goals_followed_by_impure_goal(Goal)),
 		mode_info_get_context(!.ModeInfo, Context),
 		mode_info_get_mode_context(!.ModeInfo, ModeContext),
-		ImpurityError = mode_error_info(Vars, ModeError,
-			Context, ModeContext),
+        ImpurityError = mode_error_info(Vars, ModeError, Context, ModeContext),
 		!:ImpurityErrors = [ImpurityError | !.ImpurityErrors]
 	).
 
@@ -2439,7 +2452,6 @@
 	mode_info_set_instmap(InstMap0, !ModeInfo),
 	modecheck_disj_list(Goals0, Goals, InstMaps, !ModeInfo, !IO).
 
-
 :- pred modecheck_case_list(list(case)::in, prog_var::in, list(case)::out,
 	list(instmap)::out, mode_info::in, mode_info::out,
 	io::di, io::uo) is det.
@@ -2530,8 +2542,8 @@
 	mode_info_get_instmap(!.ModeInfo, InstMap),
 	mode_info_set_instmap(InstMap0, !ModeInfo),
 	mode_info_lock_vars(par_conj, Bound1, !ModeInfo),
-	modecheck_par_conj_list(Goals0, Goals, NonLocals, InstMaps,
-		!ModeInfo, !IO),
+    modecheck_par_conj_list(Goals0, Goals, NonLocals, InstMaps, !ModeInfo,
+        !IO),
 	mode_info_unlock_vars(par_conj, Bound1, !ModeInfo).
 
 %-----------------------------------------------------------------------------%
@@ -2587,8 +2599,7 @@
 		)
 	->
 		set__singleton_set(WaitingVars, VarId),
-		mode_info_error(WaitingVars, mode_error_var_is_live(VarId),
-			!ModeInfo)
+        mode_info_error(WaitingVars, mode_error_var_is_live(VarId), !ModeInfo)
 	;
 		true
 	).
@@ -2646,8 +2657,7 @@
 	;
 		set__singleton_set(WaitingVars, VarId),
 		mode_info_error(WaitingVars,
-			mode_error_var_has_inst(VarId, VarInst, Inst),
-			!ModeInfo)
+            mode_error_var_has_inst(VarId, VarInst, Inst), !ModeInfo)
 	).
 
 %-----------------------------------------------------------------------------%
@@ -2675,24 +2685,24 @@
 		!ExtraGoals, !ModeInfo) :-
 	ArgNum = ArgNum0 + 1,
 	mode_info_set_call_arg_context(ArgNum, !ModeInfo),
-	modecheck_set_var_inst(Var0, InitialInst, FinalInst,
+    modecheck_set_var_inst_call(Var0, InitialInst, FinalInst,
 		Var, !ExtraGoals, !ModeInfo),
 	modecheck_set_var_inst_list_2(Vars0, InitialInsts, FinalInsts, ArgNum,
 		Vars, !ExtraGoals, !ModeInfo).
 
-:- pred modecheck_set_var_inst(prog_var::in, (inst)::in, (inst)::in,
+:- pred modecheck_set_var_inst_call(prog_var::in, (inst)::in, (inst)::in,
 	prog_var::out, extra_goals::in, extra_goals::out,
 	mode_info::in, mode_info::out) is det.
 
-modecheck_set_var_inst(Var0, InitialInst, FinalInst, Var, !ExtraGoals,
+modecheck_set_var_inst_call(Var0, InitialInst, FinalInst, Var, !ExtraGoals,
 		!ModeInfo) :-
 	mode_info_get_instmap(!.ModeInfo, InstMap0),
 	( instmap__is_reachable(InstMap0) ->
 		% The new inst must be computed by unifying the
 		% old inst and the proc's final inst
 		instmap__lookup_var(InstMap0, Var0, VarInst0),
-		handle_implied_mode(Var0, VarInst0, InitialInst, Var,
-			!ExtraGoals, !ModeInfo),
+        handle_implied_mode(Var0, VarInst0, InitialInst, Var, !ExtraGoals,
+            !ModeInfo),
 		modecheck_set_var_inst(Var0, FinalInst, no, !ModeInfo),
 		( Var = Var0 ->
 			true
@@ -2704,10 +2714,10 @@
 	).
 
 	% Note that there are two versions of modecheck_set_var_inst,
-	% one with arity 7 and one with arity 5.
+    % one with arity 7 (suffixed with _call) and one with arity 5.
 	% The former is used for predicate calls, where we may need
 	% to introduce unifications to handle calls to implied modes.
-
+    %
 modecheck_set_var_inst(Var0, FinalInst, MaybeUInst, !ModeInfo) :-
 	mode_info_get_parallel_vars(!.ModeInfo, PVars0),
 	mode_info_get_instmap(!.ModeInfo, InstMap0),
@@ -2718,8 +2728,7 @@
 		mode_info_get_module_info(!.ModeInfo, ModuleInfo0),
 		(
 			abstractly_unify_inst(dead, Inst0, FinalInst,
-				fake_unify, UnifyInst, _Det,
-				ModuleInfo0, ModuleInfo1)
+                fake_unify, UnifyInst, _Det, ModuleInfo0, ModuleInfo1)
 		->
 			ModuleInfo = ModuleInfo1,
 			Inst = UnifyInst
@@ -2765,16 +2774,15 @@
 				% be allowed because it has only been unified
 				% with a free variable.
 				MaybeUInst = yes(UInst),
-				inst_is_at_least_as_instantiated(Inst, UInst,
-					Type, ModuleInfo),
-				inst_matches_binding_allow_any_any(Inst,
-					Inst0, Type, ModuleInfo)
+                inst_is_at_least_as_instantiated(Inst, UInst, Type,
+                    ModuleInfo),
+                inst_matches_binding_allow_any_any(Inst, Inst0, Type,
+                    ModuleInfo)
 			)
 		->
 			set__singleton_set(WaitingVars, Var0),
 			mode_info_error(WaitingVars,
-				mode_error_bind_var(Reason0, Var0, Inst0, Inst),
-				!ModeInfo
+                mode_error_bind_var(Reason0, Var0, Inst0, Inst), !ModeInfo
 			)
 		;
 			instmap__set(InstMap0, Var0, Inst, InstMap),
@@ -2799,9 +2807,9 @@
 		mode_info_set_parallel_vars(PVars, !ModeInfo)
 	).
 
-% If this was a call to an implied mode for that variable, then we need to
-% introduce a fresh variable.
-
+    % If this was a call to an implied mode for that variable, then we need to
+    % introduce a fresh variable.
+    %
 :- pred handle_implied_mode(prog_var::in, (inst)::in, (inst)::in,
 	prog_var::out, extra_goals::in, extra_goals::out,
 	mode_info::in, mode_info::out) is det.
@@ -2851,8 +2859,7 @@
 
 		mode_info_get_context(!.ModeInfo, Context),
 		mode_info_get_mode_context(!.ModeInfo, ModeContext),
-		mode_context_to_unify_context(!.ModeInfo, ModeContext,
-			UnifyContext),
+        mode_context_to_unify_context(!.ModeInfo, ModeContext, UnifyContext),
 		CallUnifyContext = yes(call_unify_context(Var, var(Var),
 			UnifyContext)),
  		(
@@ -2864,16 +2871,14 @@
  			% Create code to initialize the variable to
  			% inst `any', by calling the solver type's
  			% initialisation predicate.
- 			insert_extra_initialisation_call(Var, VarType,
-				InitialInst, Context, CallUnifyContext,
-				!ExtraGoals, !ModeInfo)
+            insert_extra_initialisation_call(Var, VarType, InitialInst,
+                Context, CallUnifyContext, !ExtraGoals, !ModeInfo)
  		;
 			% If the type is a type variable,
 			% or isn't a solver type then give up.
 			set__singleton_set(WaitingVars, Var0),
 			mode_info_error(WaitingVars,
-				mode_error_implied_mode(Var0, VarInst0,
-					InitialInst),
+                mode_error_implied_mode(Var0, VarInst0, InitialInst),
 				!ModeInfo)
 		)
 	;
@@ -2883,8 +2888,7 @@
 		Var = Var0,
 		set__singleton_set(WaitingVars, Var0),
 		mode_info_error(WaitingVars,
-			mode_error_implied_mode(Var0, VarInst0, InitialInst),
-			!ModeInfo)
+            mode_error_implied_mode(Var0, VarInst0, InitialInst), !ModeInfo)
 	;
 		% This is the simple case of implied modes,
 		% where the declared mode was free -> ...
@@ -2903,8 +2907,7 @@
 		% append the goals together in the appropriate order:
 		% ExtraGoals0, then NewUnify
 		NewUnifyExtraGoal = extra_goals([], [ExtraGoal]),
-		append_extra_goals(!.ExtraGoals, NewUnifyExtraGoal,
-			!:ExtraGoals)
+        append_extra_goals(!.ExtraGoals, NewUnifyExtraGoal, !:ExtraGoals)
 	).
 
 :- pred insert_extra_initialisation_call(prog_var::in, (type)::in, (inst)::in,
@@ -3025,8 +3028,7 @@
 		eval_method_requires_ground_args(EvalMethod) = yes,
 		\+ only_fully_in_out_modes(Modes, !.ModuleInfo)
 	->
-		report_eval_method_requires_ground_args(ProcInfo,
-			!ModuleInfo, !IO)
+        report_eval_method_requires_ground_args(ProcInfo, !ModuleInfo, !IO)
 	;
 		true
 	),
@@ -3034,8 +3036,7 @@
 		eval_method_destroys_uniqueness(EvalMethod) = yes,
 		\+ only_nonunique_modes(Modes, !.ModuleInfo)
 	->
-		report_eval_method_destroys_uniqueness(ProcInfo,
-			!ModuleInfo, !IO)
+        report_eval_method_destroys_uniqueness(ProcInfo, !ModuleInfo, !IO)
 	;
 		true
 	),
@@ -3104,23 +3105,20 @@
 	proc_info_context(ProcInfo, Context),
 	EvalMethodS = eval_method_to_string(EvalMethod),
 	globals__io_lookup_bool_option(verbose_errors, VerboseErrors, !IO),
-	prog_out__write_context(Context, !IO),
-	io__write_string("Sorry, not implemented: `pragma ", !IO),
-	io__write_string(EvalMethodS, !IO),
-	io__write_string("'\n", !IO),
-	prog_out__write_context(Context, !IO),
-	io__write_string("  declaration not allowed for procedure with\n",
-		!IO),
-	prog_out__write_context(Context, !IO),
-	io__write_string("  partially instantiated modes.\n", !IO),
+    Pieces1 = [words("Sorry, not implemented:"),
+        fixed("`pragma " ++ EvalMethodS ++ "'"),
+        words("declaration not allowed for procedure"),
+        words("with partially instantiated modes.")],
 	(
 		VerboseErrors = yes,
-		io__write_string(
-"	Tabling of predicates/functions with partially instantiated modes
-	is not currently implemented.\n", !IO)
+        Pieces2 = [words("Tabling of predicates/functions"),
+            words("with partially instantiated modes"),
+            words("is not currently implemented.")]
 	;
-		VerboseErrors = no
+        VerboseErrors = no,
+        Pieces2 = []
 	),
+    write_error_pieces(Context, 0, Pieces1 ++ Pieces2, !IO),
 	module_info_incr_errors(!ModuleInfo).
 
 :- pred report_eval_method_destroys_uniqueness(proc_info::in,
@@ -3131,24 +3129,21 @@
 	proc_info_context(ProcInfo, Context),
 	EvalMethodS = eval_method_to_string(EvalMethod),
 	globals__io_lookup_bool_option(verbose_errors, VerboseErrors, !IO),
-	prog_out__write_context(Context, !IO),
-	io__write_string("Error: `pragma ", !IO),
-	io__write_string(EvalMethodS, !IO),
-	io__write_string("'\n", !IO),
-	prog_out__write_context(Context, !IO),
-	io__write_string("  declaration not allowed for procedure with\n",
-		!IO),
-	prog_out__write_context(Context, !IO),
-	io__write_string("  unique modes.\n", !IO),
+    Pieces1 = [words("Error:"),
+        fixed("`pragma " ++ EvalMethodS ++ "'"),
+        words("declaration not allowed for procedure"),
+        words("with unique modes.")],
 	(
 		VerboseErrors = yes,
-		io__write_string(
-"	Tabling of predicates/functions with unique modes is not allowed
-	as this would lead to a copying of the unique arguments which
-	would result in them no longer being unique.\n", !IO)
+        Pieces2 = [words("Tabling of predicates/functions with unique modes"),
+            words("is not allowed as this would lead to a copying"),
+            words("of the unique arguments which would result"),
+            words("in them no longer being unique.")]
 	;
-		VerboseErrors = no
+        VerboseErrors = no,
+        Pieces2 = []
 	),
+    write_error_pieces(Context, 0, Pieces1 ++ Pieces2, !IO),
 	module_info_incr_errors(!ModuleInfo).
 
 :- pred report_wrong_mode_for_main(proc_info::in,
@@ -3156,8 +3151,8 @@
 
 report_wrong_mode_for_main(ProcInfo, !ModuleInfo, !IO) :-
 	proc_info_context(ProcInfo, Context),
-	prog_out__write_context(Context, !IO),
-	io__write_string("Error: main/2 must have mode `(di, uo)'.\n", !IO),
+    Pieces = [words("Error: main/2 must have mode `(di, uo)'.")],
+    write_error_pieces(Context, 0, Pieces, !IO),
 	module_info_incr_errors(!ModuleInfo).
 
 %-----------------------------------------------------------------------------%
@@ -3165,14 +3160,18 @@
 
 	% Given a list of variables, and a list of livenesses,
 	% select the live variables.
-
-get_live_vars([_ | _], [], _) :- error("get_live_vars: length mismatch").
-get_live_vars([], [_ | _], _) :- error("get_live_vars: length mismatch").
+    %
+get_live_vars([_ | _], [], _) :-
+    error("get_live_vars: length mismatch").
+get_live_vars([], [_ | _], _) :-
+    error("get_live_vars: length mismatch").
 get_live_vars([], [], []).
 get_live_vars([Var | Vars], [IsLive | IsLives], LiveVars) :-
-	( IsLive = live ->
+    (
+        IsLive = live,
 		LiveVars = [Var | LiveVars0]
 	;
+        IsLive = dead,
 		LiveVars = LiveVars0
 	),
 	get_live_vars(Vars, IsLives, LiveVars0).
@@ -3181,10 +3180,9 @@
 %-----------------------------------------------------------------------------%
 
 	% XXX - At the moment we don't check for circular modes or insts.
-	% (If they aren't used, the compiler will probably not
-	% detect the error; if they are, it will probably go into
-	% an infinite loop).
-
+    % (If they aren't used, the compiler will probably not detect the error;
+    % if they are, it will probably go into an infinite loop).
+    %
 :- pred check_circular_modes(module_info::in, module_info::out,
 	io::di, io::uo) is det.
 
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.105
diff -u -b -r1.105 module_qual.m
--- compiler/module_qual.m	7 May 2005 15:49:23 -0000	1.105
+++ compiler/module_qual.m	21 May 2005 13:19:27 -0000
@@ -1069,6 +1069,7 @@
 qualify_pragma(X at terminates(_, _), X, !Info, !IO).
 qualify_pragma(X at does_not_terminate(_, _), X, !Info, !IO).
 qualify_pragma(X at check_termination(_, _), X, !Info, !IO).
+qualify_pragma(X at mode_check_clauses(_, _), X, !Info, !IO).
 
 :- pred qualify_pragma_vars(list(pragma_var)::in, list(pragma_var)::out,
 	mq_info::in, mq_info::out, io::di, io::uo) is det.
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.331
diff -u -b -r1.331 modules.m
--- compiler/modules.m	22 May 2005 11:16:10 -0000	1.331
+++ compiler/modules.m	23 May 2005 02:09:09 -0000
@@ -2052,6 +2052,7 @@
 pragma_allowed_in_interface(naive(_, _), no).
 pragma_allowed_in_interface(psn(_, _), no).
 pragma_allowed_in_interface(owner(_, _, _), yes).
+pragma_allowed_in_interface(mode_check_clauses(_, _), yes).
 
 check_for_no_exports(Items, ModuleName, !IO) :-
     globals__io_lookup_bool_option(warn_nothing_exported, ExportWarning, !IO),
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.264
diff -u -b -r1.264 polymorphism.m
--- compiler/polymorphism.m	20 Apr 2005 12:57:14 -0000	1.264
+++ compiler/polymorphism.m	21 May 2005 05:47:56 -0000
@@ -578,37 +578,36 @@
 	clauses_info::in, clauses_info::out, poly_info::out, list(mode)::out)
 	is det.
 
-polymorphism__process_clause_info(PredInfo0, ModuleInfo0,
-	ClausesInfo0, ClausesInfo, Info, ExtraArgModes) :-
-
-	init_poly_info(ModuleInfo0, PredInfo0, ClausesInfo0, Info0),
-	clauses_info_headvars(ClausesInfo0, HeadVars0),
+polymorphism__process_clause_info(PredInfo0, ModuleInfo0, !ClausesInfo, !:Info,
+		ExtraArgModes) :-
+	init_poly_info(ModuleInfo0, PredInfo0, !.ClausesInfo, !:Info),
+	clauses_info_headvars(!.ClausesInfo, HeadVars0),
 
 	polymorphism__setup_headvars(PredInfo0, HeadVars0, HeadVars,
 		ExtraArgModes, _HeadTypeVars, UnconstrainedTVars,
-		ExtraTypeInfoHeadVars, ExistTypeClassInfoHeadVars,
-		Info0, Info1),
+		ExtraTypeInfoHeadVars, ExistTypeClassInfoHeadVars, !Info),
 
-	clauses_info_clauses(ClausesInfo0, Clauses0),
+	clauses_info_clauses_only(!.ClausesInfo, Clauses0),
 	list__map_foldl(
 		polymorphism__process_clause(PredInfo0,
 			HeadVars0, HeadVars, UnconstrainedTVars,
 			ExtraTypeInfoHeadVars,
 			ExistTypeClassInfoHeadVars),
-		Clauses0, Clauses, Info1, Info),
+		Clauses0, Clauses, !Info),
 
 	%
 	% Set the new values of the fields in clauses_info.
 	%
-	poly_info_get_varset(Info, VarSet),
-	poly_info_get_var_types(Info, VarTypes),
-	poly_info_get_type_info_map(Info, TypeInfoMap),
-	poly_info_get_typeclass_info_map(Info, TypeClassInfoMap),
-	clauses_info_explicit_vartypes(ClausesInfo0, ExplicitVarTypes),
+	poly_info_get_varset(!.Info, VarSet),
+	poly_info_get_var_types(!.Info, VarTypes),
+	poly_info_get_type_info_map(!.Info, TypeInfoMap),
+	poly_info_get_typeclass_info_map(!.Info, TypeClassInfoMap),
+	clauses_info_explicit_vartypes(!.ClausesInfo, ExplicitVarTypes),
+	set_clause_list(Clauses, ClausesRep),
 	map__init(TVarNameMap), % This is only used while adding the clauses.
-	ClausesInfo = clauses_info(VarSet, ExplicitVarTypes, TVarNameMap,
-		VarTypes, HeadVars, Clauses, TypeInfoMap, TypeClassInfoMap,
-		ClausesInfo0 ^ have_foreign_clauses).
+	!:ClausesInfo = clauses_info(VarSet, ExplicitVarTypes, TVarNameMap,
+		VarTypes, HeadVars, ClausesRep, TypeInfoMap, TypeClassInfoMap,
+		!.ClausesInfo ^ have_foreign_clauses).
 
 :- pred polymorphism__process_clause(pred_info::in, list(prog_var)::in,
 	list(prog_var)::in, list(tvar)::in,
Index: compiler/post_typecheck.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/post_typecheck.m,v
retrieving revision 1.73
diff -u -b -r1.73 post_typecheck.m
--- compiler/post_typecheck.m	22 Apr 2005 08:08:19 -0000	1.73
+++ compiler/post_typecheck.m	21 May 2005 06:07:42 -0000
@@ -806,7 +806,7 @@
 promise_ex_goal(ExclusiveDecl, Module, Goal) :-
         module_info_pred_info(Module, ExclusiveDecl, PredInfo),
         pred_info_clauses_info(PredInfo, ClausesInfo),
-        clauses_info_clauses(ClausesInfo, Clauses),
+        clauses_info_clauses_only(ClausesInfo, Clauses),
         (
 		Clauses = [clause(_ProcIds, Goal0, _Lang, _Context)]
 	->
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.126
diff -u -b -r1.126 prog_data.m
--- compiler/prog_data.m	20 Apr 2005 12:57:15 -0000	1.126
+++ compiler/prog_data.m	21 May 2005 13:08:22 -0000
@@ -524,6 +524,11 @@
 			checkterm_name	:: sym_name,
 			checkterm_arity	:: arity
 			% Predname, Arity
+		)
+
+	;	mode_check_clauses(
+			mode_check_clause_name	:: sym_name,
+			mode_check_clause_arity	:: arity
 		).
 
 %
Index: compiler/prog_io_pragma.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_io_pragma.m,v
retrieving revision 1.81
diff -u -b -r1.81 prog_io_pragma.m
--- compiler/prog_io_pragma.m	7 Apr 2005 06:32:14 -0000	1.81
+++ compiler/prog_io_pragma.m	21 May 2005 13:07:27 -0000
@@ -1237,6 +1237,13 @@
     ;
         Result = error("error in `:- pragma exceptions'", ErrorTerm)
     ).
+
+parse_pragma_type(ModuleName, "mode_check_clauses", PragmaTerms, ErrorTerm,
+        _VarSet, Result) :-
+    parse_simple_pragma(ModuleName, "mode_check_clauses",
+        (pred(Name::in, Arity::in, Pragma::out) is det :-
+            Pragma = mode_check_clauses(Name, Arity)),
+        PragmaTerms, ErrorTerm, Result).
 
     % This parses a pragma that refers to a predicate or function.
     %
Index: compiler/prop_mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prop_mode_constraints.m,v
retrieving revision 1.3
diff -u -b -r1.3 prop_mode_constraints.m
--- compiler/prop_mode_constraints.m	22 Mar 2005 06:40:21 -0000	1.3
+++ compiler/prop_mode_constraints.m	21 May 2005 05:48:24 -0000
@@ -180,7 +180,7 @@
 		% Needed for defined modes.
 	pred_info_clauses_info(PredInfo, ClausesInfo),
 	clauses_info_headvars(ClausesInfo, HeadVars),
-	clauses_info_clauses(ClausesInfo, Clauses),
+	clauses_info_clauses_only(ClausesInfo, Clauses),
 	clauses_info_varset(ClausesInfo, ProgVarset),
 	Goals = list.map((func(clause(_, ClauseBody, _, _)) = ClauseBody),
 		Clauses),
Index: compiler/purity.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/purity.m,v
retrieving revision 1.74
diff -u -b -r1.74 purity.m
--- compiler/purity.m	26 Apr 2005 07:38:00 -0000	1.74
+++ compiler/purity.m	21 May 2005 05:55:47 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1997-2005 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.
@@ -112,6 +114,7 @@
 %	inline (since ordering is not an issue for them).
 %
 %-----------------------------------------------------------------------------%
+
 :- module check_hlds__purity.
 :- interface.
 
@@ -122,11 +125,6 @@
 :- import_module bool.
 :- import_module io.
 
-% The purity type itself is defined in prog_data.m as follows:
-% :- type purity	--->	pure
-% 			;	(semipure)
-% 			;	(impure).
-
 	% Purity check a whole module.  Also do the post-typecheck stuff
 	% described above, and eliminate double negations and calls
 	% to `private_builtin.unsafe_type_cast/2'.
@@ -292,11 +290,10 @@
 		module_info_set_pred_info(PredId, PredInfo, !ModuleInfo)
 	),
 
-		% finish processing of promise declarations
+        % Finish processing of promise declarations.
 	pred_info_get_goal_type(PredInfo, GoalType),
 	( GoalType = promise(PromiseType) ->
-		post_typecheck__finish_promise(PromiseType, PredId,
-			!ModuleInfo, !IO)
+        post_typecheck__finish_promise(PromiseType, PredId, !ModuleInfo, !IO)
 	;
 		true
 	),
@@ -329,30 +326,29 @@
 puritycheck_pred(PredId, !PredInfo, ModuleInfo, NumErrors, !IO) :-
 	pred_info_get_purity(!.PredInfo, DeclPurity) ,
 	pred_info_get_promised_purity(!.PredInfo, PromisedPurity),
-
-	pred_info_clauses_info(!.PredInfo, ClausesInfo0),
+    some [!ClausesInfo] (
+        pred_info_clauses_info(!.PredInfo, !:ClausesInfo),
 	ProcIds = pred_info_procids(!.PredInfo),
-	clauses_info_clauses(ClausesInfo0, Clauses0),
-	clauses_info_vartypes(ClausesInfo0, VarTypes0),
-	clauses_info_varset(ClausesInfo0, VarSet0),
+        clauses_info_clauses(Clauses0, !ClausesInfo),
+        clauses_info_vartypes(!.ClausesInfo, VarTypes0),
+        clauses_info_varset(!.ClausesInfo, VarSet0),
 	RunPostTypecheck = yes,
 	PurityInfo0 = purity_info(ModuleInfo, RunPostTypecheck,
-		!.PredInfo, VarTypes0, VarSet0, [],
-		dont_make_implicit_promises),
+            !.PredInfo, VarTypes0, VarSet0, [], dont_make_implicit_promises),
 	pred_info_get_goal_type(!.PredInfo, GoalType),
 	compute_purity(GoalType, Clauses0, Clauses, ProcIds, pure, Purity,
 		PurityInfo0, PurityInfo),
 	PurityInfo = purity_info(_, _, !:PredInfo,
 		VarTypes, VarSet, RevMessages, _),
-	clauses_info_set_vartypes(VarTypes, ClausesInfo0, ClausesInfo1),
-	clauses_info_set_varset(VarSet, ClausesInfo1, ClausesInfo2),
+        clauses_info_set_vartypes(VarTypes, !ClausesInfo),
+        clauses_info_set_varset(VarSet, !ClausesInfo),
 	Messages = list__reverse(RevMessages),
 	list__foldl(report_post_typecheck_message(ModuleInfo), Messages, !IO),
-	NumErrors0 = list__length(
-		list__filter((pred(error(_)::in) is semidet),
+        NumErrors0 = list__length(list__filter((pred(error(_)::in) is semidet),
 		Messages)),
-	clauses_info_set_clauses(Clauses, ClausesInfo2, ClausesInfo),
-	pred_info_set_clauses_info(ClausesInfo, !PredInfo),
+        clauses_info_set_clauses(Clauses, !ClausesInfo),
+        pred_info_set_clauses_info(!.ClausesInfo, !PredInfo)
+    ),
 	WorstPurity = Purity,
 	perform_pred_purity_checks(!.PredInfo, Purity, DeclPurity,
 		PromisedPurity, PurityCheckResult),
@@ -369,8 +365,7 @@
 	;
 		PurityCheckResult = insufficient_decl,
 		NumErrors = NumErrors0 + 1,
-		error_inferred_impure(ModuleInfo, !.PredInfo, PredId, Purity,
-			!IO)
+        error_inferred_impure(ModuleInfo, !.PredInfo, PredId, Purity, !IO)
 	;
 		PurityCheckResult = unnecessary_promise_pure,
 		NumErrors = NumErrors0,
@@ -389,8 +384,7 @@
 	proc_info_varset(ProcInfo0, VarSet0),
 	RunPostTypeCheck = no,
 	PurityInfo0 = purity_info(ModuleInfo, RunPostTypeCheck,
-		!.PredInfo, VarTypes0, VarSet0, [],
-		dont_make_implicit_promises),
+        !.PredInfo, VarTypes0, VarSet0, [], dont_make_implicit_promises),
 	compute_goal_purity(Goal0, Goal, Bodypurity, PurityInfo0, PurityInfo),
 	PurityInfo = purity_info(_, _, !:PredInfo, VarTypes, VarSet, _, _),
 	proc_info_set_goal(Goal, ProcInfo0, ProcInfo1),
@@ -501,8 +495,7 @@
 	).
 
 :- pred compute_expr_purity(hlds_goal_expr::in, hlds_goal_expr::out,
-	hlds_goal_info::in, purity::out, purity_info::in, purity_info::out)
-	is det.
+    hlds_goal_info::in, purity::out, purity_info::in, purity_info::out) is det.
 
 compute_expr_purity(conj(Goals0), conj(Goals), _, Purity, !Info) :-
 	compute_goals_purity(Goals0, Goals, pure, Purity, !Info).
@@ -520,17 +513,14 @@
 		(
 			% Convert any calls to private_builtin.unsafe_type_cast
 			% into unsafe_cast goals.
-			Name = qualified(
-				mercury_private_builtin_module,
+            Name = qualified(mercury_private_builtin_module,
 				"unsafe_type_cast"),
 			Vars = [InputArg, OutputArg]
 		->
-			Goal = generic_call(unsafe_cast,
-				[InputArg, OutputArg],
+            Goal = generic_call(unsafe_cast, [InputArg, OutputArg],
 				[in_mode, out_mode], det)
 		;
-			Goal = call(PredId, ProcId, Vars,
-				BIState, UContext, Name)
+            Goal = call(PredId, ProcId, Vars, BIState, UContext, Name)
 		)
 	;
 		RunPostTypecheck = no,
@@ -563,13 +553,12 @@
 			RunPostTypecheck = yes,
 			ModuleInfo = !.Info ^ module_info,
 			PredInfo = !.Info ^ pred_info,
-			post_typecheck__finish_aditi_builtin(ModuleInfo,
-				PredInfo, Args, Context, Builtin0, Builtin,
-				CallId0, CallId, Modes, MaybeMessage),
+            post_typecheck__finish_aditi_builtin(ModuleInfo, PredInfo, Args,
+                Context, Builtin0, Builtin, CallId0, CallId, Modes,
+                MaybeMessage),
 			(
 				MaybeMessage = yes(Message),
-				purity_info_add_message(
-					error(aditi_builtin_error(Message)),
+                purity_info_add_message(error(aditi_builtin_error(Message)),
 					!Info)
 			;
 				MaybeMessage = no
@@ -594,8 +583,7 @@
 		RHS = lambda_goal(LambdaPurity, F, EvalMethod,
 			modes_are_ok, H, Vars, Modes, K, Goal - Info0),
 		compute_expr_purity(Goal0, Goal, Info0, GoalPurity, !Info),
-		check_closure_purity(GoalInfo, LambdaPurity, GoalPurity,
-			!Info),
+        check_closure_purity(GoalInfo, LambdaPurity, GoalPurity, !Info),
 
 		VarTypes = !.Info ^ vartypes,
 		(
@@ -615,8 +603,8 @@
 			),
 			map__apply_to_list(Vars, VarTypes, LambdaVarTypes),
 			SeenState = no,
-			fix_aditi_state_modes(SeenState, StateMode,
-				LambdaVarTypes, Modes0, Modes)
+            fix_aditi_state_modes(SeenState, StateMode, LambdaVarTypes,
+                Modes0, Modes)
 		),
 		GoalExpr = unify(Var, RHS, Mode, Unification, UnifyContext),
 		% the unification itself is always pure,
@@ -632,10 +620,10 @@
 			PredInfo0 = !.Info ^ pred_info,
 			VarTypes0 = !.Info ^ vartypes,
 			VarSet0 = !.Info ^ varset,
-			post_typecheck__resolve_unify_functor(Var, ConsId,
-				Args, Mode, Unification, UnifyContext,
-				GoalInfo, ModuleInfo, PredInfo0, PredInfo,
-				VarTypes0, VarTypes, VarSet0, VarSet, Goal1),
+            post_typecheck__resolve_unify_functor(Var, ConsId, Args, Mode,
+                Unification, UnifyContext, GoalInfo, ModuleInfo,
+                PredInfo0, PredInfo, VarTypes0, VarTypes, VarSet0, VarSet,
+                Goal1),
 			!:Info = !.Info ^ vartypes := VarTypes,
 			!:Info = !.Info ^ varset := VarSet,
 			!:Info = !.Info ^ pred_info := PredInfo
@@ -644,8 +632,8 @@
 			Goal1 = Unif0 - GoalInfo
 		),
 		( Goal1 = unify(_, _, _, _, _) - _ ->
-			check_higher_order_purity(GoalInfo, ConsId,
-				Var, Args, ActualPurity, !Info),
+            check_higher_order_purity(GoalInfo, ConsId, Var, Args,
+                ActualPurity, !Info),
 			Goal = Goal1
 		;
 			compute_goal_purity(Goal1, Goal, ActualPurity, !Info)
@@ -783,8 +771,7 @@
 		!.Info ^ implicit_purity = dont_make_implicit_promises
 	->
 		goal_info_get_context(GoalInfo, Context),
-		Message = impure_unification_expr_error(Context,
-			DeclaredPurity),
+        Message = impure_unification_expr_error(Context, DeclaredPurity),
 		purity_info_add_message(error(Message), !Info)
 	;
 		true
@@ -792,14 +779,14 @@
 
 	% the possible results of a purity check
 :- type purity_check_result
-	--->	no_worries		% all is well
-	;	insufficient_decl	% purity decl is less than
+    --->    no_worries                  % All is well.
+    ;       insufficient_decl           % Purity decl is less than
 					% required.
-	;	inconsistent_promise    % promise is given
-					% but decl is impure
-	;	unnecessary_promise_pure % purity promise is given
-					% but not required
-	;	unnecessary_decl.	% purity decl is more than is
+    ;       inconsistent_promise        % Promise is given
+                                        % but decl is impure.
+    ;       unnecessary_promise_pure    % Purity promise is given
+                                        % but not required.
+    ;       unnecessary_decl.           % Purity decl is more than is
 					% required.
 
 	% Peform purity checking of the actual and declared purity,
@@ -918,8 +905,7 @@
 		less_pure(ActualPurity, DeclaredPurity)
 	->
 		purity_info_add_message(
-			error(missing_body_impurity_error(Context, PredId)),
-			!Info)
+            error(missing_body_impurity_error(Context, PredId)), !Info)
 	;
 		% We don't warn about exaggerated impurity decls in
 		% class methods or instance methods --- it just
@@ -1074,8 +1060,7 @@
 		PromisedPurity = (impure),
 		error("purity__warn_unnecessary_promise_pure: promise_impure?")
 	),
-	Pieces1 = [words("warning: unnecessary `" ++ Pragma ++ "' pragma."),
-		nl],
+    Pieces1 = [words("warning: unnecessary `" ++ Pragma ++ "' pragma."), nl],
 	globals__io_lookup_bool_option(verbose_errors, VerboseErrors, !IO),
 	(
 		VerboseErrors = yes,
@@ -1144,13 +1129,10 @@
 	io__set_exit_status(1, !IO),
 	(
 		Message = missing_body_impurity_error(Context, PredId),
-		error_missing_body_impurity_decl(ModuleInfo, PredId, Context,
-			!IO)
+        error_missing_body_impurity_decl(ModuleInfo, PredId, Context, !IO)
 	;
-		Message = closure_purity_error(Context, DeclaredPurity,
-			ActualPurity),
-		report_error_closure_purity(Context, DeclaredPurity,
-			ActualPurity, !IO)
+        Message = closure_purity_error(Context, DeclaredPurity, ActualPurity),
+        report_error_closure_purity(Context, DeclaredPurity, ActualPurity, !IO)
 	;
 		Message = impure_unification_expr_error(Context, Purity),
 		impure_unification_expr_error(Context, Purity, !IO)
@@ -1162,10 +1144,10 @@
 report_post_typecheck_message(ModuleInfo, warning(Warning), !IO) :-
 	record_warning(!IO),
 	(
-		Warning = unnecessary_body_impurity_decl(Context,
-			PredId, DeclaredPurity),
-		warn_unnecessary_body_impurity_decl(ModuleInfo, PredId,
-			Context, DeclaredPurity, !IO)
+        Warning = unnecessary_body_impurity_decl(Context, PredId,
+            DeclaredPurity),
+        warn_unnecessary_body_impurity_decl(ModuleInfo, PredId, Context,
+            DeclaredPurity, !IO)
 	;
 		Warning = redundant_promise_purity(Context, PromisedPurity,
 			InsidePurity),
@@ -1219,8 +1201,7 @@
 		Pieces2 = [words("No purity indicator is necessary.")]
 	;
 		Pieces2 = [words("A purity indicator of"),
-			fixed("`" ++ ActualPurityName ++ "'"),
-			words("is sufficient.")]
+            fixed("`" ++ ActualPurityName ++ "'"), words("is sufficient.")]
 	),
 	write_error_pieces(Context, 0, Pieces1 ++ Pieces2, !IO).
 
@@ -1273,20 +1254,20 @@
 
 :- type purity_info
 	--->	purity_info(
-			% fields not changed by purity checking.
+                % Fields not changed by purity checking.
 			module_info		:: module_info,
 			run_post_typecheck	:: bool,
 
-			% fields which may be changed.
+                % Fields which may be changed.
 			pred_info		:: pred_info,
 			vartypes		:: vartypes,
 			varset			:: prog_varset,
 			messages		:: post_typecheck_messages,
 			implicit_purity		:: implicit_purity_promise
-				% If this is make_implicit_promises then purity
-				% annotations are optional in the current scope
-				% and purity warnings/errors should not be
-				% generated.
+                                    % If this is make_implicit_promises then
+                                    % purity annotations are optional in the
+                                    % current scope and purity warnings/errors
+                                    % should not be generated.
 		).
 
 :- pred purity_info_add_message(post_typecheck_message::in,
Index: compiler/recompilation.version.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/recompilation.version.m,v
retrieving revision 1.18
diff -u -b -r1.18 recompilation.version.m
--- compiler/recompilation.version.m	20 Apr 2005 12:57:16 -0000	1.18
+++ compiler/recompilation.version.m	21 May 2005 13:24:16 -0000
@@ -630,6 +630,7 @@
 is_pred_pragma(terminates(Name, Arity), yes(no - Name / Arity)).
 is_pred_pragma(does_not_terminate(Name, Arity), yes(no - Name / Arity)).
 is_pred_pragma(check_termination(Name, Arity), yes(no - Name / Arity)).
+is_pred_pragma(mode_check_clauses(Name, Arity), yes(no - Name / Arity)).
 
 	% XXX This is a bit brittle (need to be careful with term__contexts).
 	% For example, it won't work for clauses.
Index: compiler/table_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/table_gen.m,v
retrieving revision 1.80
diff -u -b -r1.80 table_gen.m
--- compiler/table_gen.m	1 Apr 2005 14:29:02 -0000	1.80
+++ compiler/table_gen.m	21 May 2005 10:54:59 -0000
@@ -1801,6 +1801,7 @@
 keep_marker(does_not_terminate) = yes.
 keep_marker(check_termination) = no.
 keep_marker(calls_are_fully_qualified) = yes.
+keep_marker(mode_check_clauses) = yes.
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.372
diff -u -b -r1.372 typecheck.m
--- compiler/typecheck.m	23 Apr 2005 06:29:47 -0000	1.372
+++ compiler/typecheck.m	23 May 2005 02:36:48 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 1993-2005 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.
@@ -206,9 +208,8 @@
 			true
 		),
 		( Iteration < NumIterations ->
-			typecheck_to_fixpoint(Iteration + 1, NumIterations,
-				PredIds, !Module, FoundError,
-				ExceededIterationLimit, !IO)
+            typecheck_to_fixpoint(Iteration + 1, NumIterations, PredIds,
+                !Module, FoundError, ExceededIterationLimit, !IO)
 		;
 			typecheck_report_max_iterations_exceeded(!IO),
 			FoundError = yes,
@@ -304,18 +305,19 @@
 		% type.
 		(
 			is_unify_or_compare_pred(!.PredInfo),
-			\+ special_pred_needs_typecheck(!.PredInfo,
-				!.ModuleInfo)
+            \+ special_pred_needs_typecheck(!.PredInfo, !.ModuleInfo)
 		;
 			pred_info_is_builtin(!.PredInfo)
 		)
 	->
 		pred_info_clauses_info(!.PredInfo, ClausesInfo0),
-		clauses_info_clauses(ClausesInfo0, Clauses0),
-		( Clauses0 = [] ->
+        clauses_info_clauses_rep(ClausesInfo0, ClausesRep0),
+        IsEmpty = clause_list_is_empty(ClausesRep0),
+        (
+            IsEmpty = yes,
 			pred_info_mark_as_external(!PredInfo)
 		;
-			true
+            IsEmpty = no
 		),
 		Error = no,
 		Changed = no
@@ -334,8 +336,7 @@
 	( Iteration = 1 ->
 		% Goal paths are used to identify typeclass constraints.
 		goal_path__fill_slots_in_clauses(!.ModuleInfo, no, !PredInfo),
-		maybe_add_field_access_function_clause(!.ModuleInfo,
-			!PredInfo),
+        maybe_add_field_access_function_clause(!.ModuleInfo, !PredInfo),
 		maybe_improve_headvar_names(Globals, !PredInfo),
 
 		% The goal_type of the pred_info may have been changed
@@ -344,75 +345,76 @@
 	;
 		true
 	),
-	pred_info_arg_types(!.PredInfo, _ArgTypeVarSet, ExistQVars0,
-		ArgTypes0),
-	pred_info_clauses_info(!.PredInfo, ClausesInfo0),
-	clauses_info_clauses(ClausesInfo0, Clauses0),
-	clauses_info_headvars(ClausesInfo0, HeadVars),
-	clauses_info_varset(ClausesInfo0, VarSet0),
-	clauses_info_explicit_vartypes(ClausesInfo0, ExplicitVarTypes0),
+    pred_info_arg_types(!.PredInfo, _ArgTypeVarSet, ExistQVars0, ArgTypes0),
+    some [!ClausesInfo, !Info, !HeadTypeParams] (
+        pred_info_clauses_info(!.PredInfo, !:ClausesInfo),
+        clauses_info_clauses_rep(!.ClausesInfo, ClausesRep0),
+        clauses_info_headvars(!.ClausesInfo, HeadVars),
+        clauses_info_varset(!.ClausesInfo, VarSet0),
+        clauses_info_explicit_vartypes(!.ClausesInfo, ExplicitVarTypes0),
 	pred_info_get_markers(!.PredInfo, Markers0),
 	% Handle the --allow-stubs and --warn-stubs options.
 	% If --allow-stubs is set, and there are no clauses,
 	% issue a warning if --warn-stubs is set, and then
 	% generate a "stub" clause that just throws an exception.
 	(
-		Clauses0 = [],
+            clause_list_is_empty(ClausesRep0) = yes,
 		globals__lookup_bool_option(Globals, allow_stubs, yes),
 		\+ check_marker(Markers0, class_method)
 	->
 		globals__lookup_bool_option(Globals, warn_stubs, WarnStubs),
 		(
 			WarnStubs = yes,
-			report_no_clauses("Warning", PredId,
-				!.PredInfo, !.ModuleInfo, !IO)
+                report_no_clauses("Warning", PredId, !.PredInfo, !.ModuleInfo,
+                    !IO)
 		;
 			WarnStubs = no
 		),
 		PredPieces = describe_one_pred_name(!.ModuleInfo,
 			should_module_qualify, PredId),
 		PredName = error_pieces_to_string(PredPieces),
-		generate_stub_clause(PredName, !PredInfo, !.ModuleInfo,
-			StubClause, VarSet0, VarSet),
-		Clauses1 = [StubClause],
-		clauses_info_set_clauses(Clauses1, ClausesInfo0, ClausesInfo1),
-		clauses_info_set_varset(VarSet, ClausesInfo1, ClausesInfo2)
+            generate_stub_clause(PredName, !PredInfo, !.ModuleInfo, StubClause,
+                VarSet0, VarSet),
+            set_clause_list([StubClause], ClausesRep1),
+            clauses_info_set_clauses([StubClause], !ClausesInfo),
+            clauses_info_set_varset(VarSet, !ClausesInfo)
 	;
 		VarSet = VarSet0,
-		Clauses1 = Clauses0,
-		ClausesInfo2 = ClausesInfo0
+            ClausesRep1 = ClausesRep0
 	),
+        clause_list_is_empty(ClausesRep1) = ClausesRep1IsEmpty,
 	(
-		Clauses1 = []
-	->
+            ClausesRep1IsEmpty = yes,
 		% There are no clauses for class methods.
 		% The clauses are generated later on,
 		% in polymorphism__expand_class_method_bodies
 		( check_marker(Markers0, class_method) ->
 			% For the moment, we just insert the types
 			% of the head vars into the clauses_info
-			map__from_corresponding_lists(HeadVars, ArgTypes0,
-				VarTypes),
-			clauses_info_set_vartypes(VarTypes,
-				ClausesInfo2, ClausesInfo),
-			pred_info_set_clauses_info(ClausesInfo, !PredInfo),
-				% We also need to set the head_type_params
-				% field to indicate that all the existentially
-				% quantified tvars in the head of this
-				% pred are indeed bound by this predicate.
-			term__vars_list(ArgTypes0,
-				HeadVarsIncludingExistentials),
-			pred_info_set_head_type_params(
-				HeadVarsIncludingExistentials, !PredInfo),
+                map__from_corresponding_lists(HeadVars, ArgTypes0, VarTypes),
+                clauses_info_set_vartypes(VarTypes, !ClausesInfo),
+                pred_info_set_clauses_info(!.ClausesInfo, !PredInfo),
+                    % We also need to set the head_type_params field
+                    % to indicate that all the existentially quantified tvars
+                    % in the head of this pred are indeed bound by this
+                    % predicate.
+                term__vars_list(ArgTypes0, HeadVarsIncludingExistentials),
+                pred_info_set_head_type_params(HeadVarsIncludingExistentials,
+                    !PredInfo),
 			Error = no,
 			Changed = no
 		;
-			report_no_clauses("Error", PredId, !.PredInfo,
-				!.ModuleInfo, !IO),
+                report_no_clauses("Error", PredId, !.PredInfo, !.ModuleInfo,
+                    !IO),
 			Error = yes,
 			Changed = no
-		)
+            ),
+            % XXX rafe FIXME:  Deleting this call to ignore causes the state
+            % variable transformation to malfunction, leading to a bogus mode
+            % error.
+            ignore(!.ClausesInfo)
 	;
+            ClausesRep1IsEmpty = no,
 		pred_info_typevarset(!.PredInfo, TypeVarSet0),
 		pred_info_import_status(!.PredInfo, Status),
 		( check_marker(Markers0, infer_type) ->
@@ -425,58 +427,49 @@
 			Inferring = yes,
 			write_pred_progress_message("% Inferring type of ",
 				PredId, !.ModuleInfo, !IO),
-			HeadTypeParams3 = [],
+                !:HeadTypeParams = [],
 			PredConstraints = constraints([], [])
 		;
 			Inferring = no,
-			write_pred_progress_message("% Type-checking ",
-				PredId, !.ModuleInfo, !IO),
-			term__vars_list(ArgTypes0, HeadTypeParams0),
-			pred_info_get_class_context(!.PredInfo,
-				PredConstraints),
-			constraint_list_get_tvars(
-				PredConstraints ^ univ_constraints, UnivTVars),
-			list__append(UnivTVars, HeadTypeParams0,
-				HeadTypeParams1),
-			list__sort_and_remove_dups(HeadTypeParams1,
-				HeadTypeParams2),
-			list__delete_elems(HeadTypeParams2, ExistQVars0,
-				HeadTypeParams3)
+                write_pred_progress_message("% Type-checking ", PredId,
+                    !.ModuleInfo, !IO),
+                term__vars_list(ArgTypes0, !:HeadTypeParams),
+                pred_info_get_class_context(!.PredInfo, PredConstraints),
+                constraint_list_get_tvars(PredConstraints ^ univ_constraints,
+                    UnivTVars),
+                list__append(UnivTVars, !HeadTypeParams),
+                list__sort_and_remove_dups(!HeadTypeParams),
+                list__delete_elems(!.HeadTypeParams, ExistQVars0,
+                    !:HeadTypeParams)
 		),
 
 		module_info_classes(!.ModuleInfo, ClassTable),
 		make_head_hlds_constraints(ClassTable, TypeVarSet0,
 			PredConstraints, Constraints),
-		(
-			pred_info_is_field_access_function(!.ModuleInfo,
-				!.PredInfo)
-		->
+            ( pred_info_is_field_access_function(!.ModuleInfo, !.PredInfo) ->
 			IsFieldAccessFunction = yes
 		;
 			IsFieldAccessFunction = no
 		),
 		pred_info_get_markers(!.PredInfo, Markers),
-		typecheck_info_init(!.ModuleInfo, PredId,
-			IsFieldAccessFunction, TypeVarSet0, VarSet,
-			ExplicitVarTypes0, HeadTypeParams3, Constraints,
-			Status, Markers, Info1),
-		typecheck_info_get_type_assign_set(Info1, OrigTypeAssignSet),
+            typecheck_info_init(!.ModuleInfo, PredId, IsFieldAccessFunction,
+                TypeVarSet0, VarSet, ExplicitVarTypes0, !.HeadTypeParams,
+                Constraints, Status, Markers, !:Info),
+            typecheck_info_get_type_assign_set(!.Info, OrigTypeAssignSet),
+            get_clause_list(ClausesRep1, Clauses1),
 		typecheck_clause_list(HeadVars, ArgTypes0,
-			Clauses1, Clauses, Info1, Info2, !IO),
+                Clauses1, Clauses, !Info, !IO),
 		% we need to perform a final pass of context reduction
 		% at the end, before checking the typeclass constraints
-		perform_context_reduction(OrigTypeAssignSet, Info2, Info3,
-			!IO),
-		typecheck_check_for_ambiguity(whole_pred, HeadVars,
-			Info3, Info4, !IO),
-		typecheck_info_get_final_info(Info4, HeadTypeParams3,
+            perform_context_reduction(OrigTypeAssignSet, !Info, !IO),
+            typecheck_check_for_ambiguity(whole_pred, HeadVars, !Info, !IO),
+            typecheck_info_get_final_info(!.Info, !.HeadTypeParams,
 			ExistQVars0, ExplicitVarTypes0, TypeVarSet,
-			HeadTypeParams4, InferredVarTypes0,
+                !:HeadTypeParams, InferredVarTypes0,
 			InferredTypeConstraints0, ConstraintProofs,
 			ConstraintMap, TVarRenaming, ExistTypeRenaming),
 		map__optimize(InferredVarTypes0, InferredVarTypes),
-		clauses_info_set_vartypes(InferredVarTypes,
-			ClausesInfo2, ClausesInfo3),
+            clauses_info_set_vartypes(InferredVarTypes, !ClausesInfo),
 
 		%
 		% Apply substitutions to the explicit vartypes.
@@ -492,10 +485,9 @@
 		apply_variable_renaming_to_type_map(TVarRenaming,
 			ExplicitVarTypes1, ExplicitVarTypes),
 
-		clauses_info_set_explicit_vartypes(ExplicitVarTypes,
-			ClausesInfo3, ClausesInfo4),
-		clauses_info_set_clauses(Clauses, ClausesInfo4, ClausesInfo),
-		pred_info_set_clauses_info(ClausesInfo, !PredInfo),
+            clauses_info_set_explicit_vartypes(ExplicitVarTypes, !ClausesInfo),
+            clauses_info_set_clauses(Clauses, !ClausesInfo),
+            pred_info_set_clauses_info(!.ClausesInfo, !PredInfo),
 		pred_info_set_typevarset(TypeVarSet, !PredInfo),
 		pred_info_set_constraint_proofs(ConstraintProofs, !PredInfo),
 		pred_info_set_constraint_map(ConstraintMap, !PredInfo),
@@ -520,8 +512,8 @@
 		% bound in to types that make the constraints satisfiable,
 		% causing the error to go away.
 		%
-		pred_info_set_unproven_body_constraints(
-			UnprovenBodyConstraints, !PredInfo),
+            pred_info_set_unproven_body_constraints(UnprovenBodyConstraints,
+                !PredInfo),
 
 		(
 			Inferring = yes,
@@ -530,19 +522,16 @@
 			% types must be existentially quantified
 			%
 			infer_existential_types(ArgTypeVars, ExistQVars,
-				HeadTypeParams4, HeadTypeParams),
+                    !HeadTypeParams),
 
 			%
 			% Now save the information we inferred in the pred_info
 			%
-			pred_info_set_head_type_params(HeadTypeParams,
-				!PredInfo),
-			pred_info_set_arg_types(TypeVarSet, ExistQVars,
-				ArgTypes, !PredInfo),
-			pred_info_get_class_context(!.PredInfo,
-				OldTypeConstraints),
-			pred_info_set_class_context(InferredTypeConstraints,
+                pred_info_set_head_type_params(!.HeadTypeParams, !PredInfo),
+                pred_info_set_arg_types(TypeVarSet, ExistQVars, ArgTypes,
 				!PredInfo),
+                pred_info_get_class_context(!.PredInfo, OldTypeConstraints),
+                pred_info_set_class_context(InferredTypeConstraints, !PredInfo),
 			%
 			% Check if anything changed
 			%
@@ -550,10 +539,8 @@
 				% If the argument types and the type
 				% constraints are identical up to renaming,
 				% then nothing has changed.
-				argtypes_identical_up_to_renaming(
-					ExistQVars0, ArgTypes0,
-					OldTypeConstraints,
-					ExistQVars, ArgTypes,
+                    argtypes_identical_up_to_renaming(ExistQVars0, ArgTypes0,
+                        OldTypeConstraints, ExistQVars, ArgTypes,
 					InferredTypeConstraints)
 			->
 				Changed = no
@@ -562,8 +549,7 @@
 			)
 		;
 			Inferring = no,
-			pred_info_set_head_type_params(HeadTypeParams4,
-				!PredInfo),
+                pred_info_set_head_type_params(!.HeadTypeParams, !PredInfo),
 			pred_info_get_origin(!.PredInfo, Origin0),
 
 			%
@@ -578,23 +564,23 @@
 
 			% apply any type substititions that map existentially
 			% quantified type variables to other type vars
-			( ExistQVars0 = [] ->
+                (
+                    ExistQVars0 = [],
 				% optimize common case
 				ExistQVars1 = [],
 				ArgTypes1 = ArgTypes0,
 				PredConstraints1 = PredConstraints,
 				Origin1 = Origin0
 			;
+                    ExistQVars0 = [_ | _],
 				apply_var_renaming_to_var_list(ExistQVars0,
 					ExistTypeRenaming, ExistQVars1),
 				term__apply_variable_renaming_to_list(
-					ArgTypes0, ExistTypeRenaming,
-					ArgTypes1),
+                        ArgTypes0, ExistTypeRenaming, ArgTypes1),
 				apply_variable_renaming_to_prog_constraints(
-					ExistTypeRenaming,
-					PredConstraints, PredConstraints1),
-				rename_instance_method_constraints(
-					ExistTypeRenaming, Origin0, Origin1)
+                        ExistTypeRenaming, PredConstraints, PredConstraints1),
+                    rename_instance_method_constraints(ExistTypeRenaming,
+                        Origin0, Origin1)
 			),
 
 			% rename them all to match the new typevarset
@@ -602,24 +588,27 @@
 				TVarRenaming, ExistQVars),
 			term__apply_variable_renaming_to_list(ArgTypes1,
 				TVarRenaming, RenamedOldArgTypes),
-			apply_variable_renaming_to_prog_constraints(
-				TVarRenaming, PredConstraints1,
-				RenamedOldConstraints),
+                apply_variable_renaming_to_prog_constraints(TVarRenaming,
+                    PredConstraints1, RenamedOldConstraints),
 			rename_instance_method_constraints(TVarRenaming,
 				Origin1, Origin),
 
 			% save the results in the pred_info
 			pred_info_set_arg_types(TypeVarSet, ExistQVars,
 				RenamedOldArgTypes, !PredInfo),
-			pred_info_set_class_context(RenamedOldConstraints,
-				!PredInfo),
+                pred_info_set_class_context(RenamedOldConstraints, !PredInfo),
 			pred_info_set_origin(Origin, !PredInfo),
 
 			Changed = no
 		),
-		typecheck_info_get_found_error(Info4, Error)
+            typecheck_info_get_found_error(!.Info, Error)
+        )
 	).
 
+:- pred ignore(T::in) is det.
+
+ignore(_).
+
 	% Mark the predicate as a stub, and generate a clause of the form
 	%	<p>(...) :-
 	%		PredName = "<Predname>",
@@ -631,8 +620,7 @@
 	% depending on whether the predicate is part of
 	% the Mercury standard library or not.
 :- pred generate_stub_clause(string::in, pred_info::in, pred_info::out,
-	module_info::in, clause::out, prog_varset::in, prog_varset::out)
-	is det.
+    module_info::in, clause::out, prog_varset::in, prog_varset::out) is det.
 
 generate_stub_clause(PredName, !PredInfo, ModuleInfo, StubClause, !VarSet) :-
 	%
@@ -674,9 +662,8 @@
 
 rename_instance_method_constraints(Renaming, Origin0, Origin) :-
 	( Origin0 = instance_method(Constraints0) ->
-		Constraints0 = instance_method_constraints(ClassId,
-			InstanceTypes0, InstanceConstraints0,
-			ClassMethodClassContext0),
+        Constraints0 = instance_method_constraints(ClassId, InstanceTypes0,
+            InstanceConstraints0, ClassMethodClassContext0),
 		term__apply_variable_renaming_to_list(InstanceTypes0,
 			Renaming, InstanceTypes),
 		apply_variable_renaming_to_prog_constraint_list(Renaming,
@@ -684,8 +671,7 @@
 		apply_variable_renaming_to_prog_constraints(Renaming,
 			ClassMethodClassContext0, ClassMethodClassContext),
 		Constraints = instance_method_constraints(ClassId,
-			InstanceTypes, InstanceConstraints,
-			ClassMethodClassContext),
+            InstanceTypes, InstanceConstraints, ClassMethodClassContext),
 		Origin = instance_method(Constraints)
 	;
 		Origin = Origin0
@@ -759,7 +745,8 @@
 
 is_head_class_constraint(HeadTypeVars, constraint(_Name, Types)) :-
 	all [TVar] (
-		term__contains_var_list(Types, TVar) =>
+            term__contains_var_list(Types, TVar)
+        =>
 			list__member(TVar, HeadTypeVars)
 	).
 
@@ -878,10 +865,10 @@
 maybe_add_field_access_function_clause(ModuleInfo, !PredInfo) :-
 	pred_info_import_status(!.PredInfo, ImportStatus),
 	pred_info_clauses_info(!.PredInfo, ClausesInfo0),
-	clauses_info_clauses(ClausesInfo0, Clauses0),
+    clauses_info_clauses_rep(ClausesInfo0, ClausesRep0),
 	(
 		pred_info_is_field_access_function(ModuleInfo, !.PredInfo),
-		Clauses0 = [],
+        clause_list_is_empty(ClausesRep0) = yes,
 		status_defined_in_this_module(ImportStatus, yes)
 	->
 		clauses_info_headvars(ClausesInfo0, HeadVars),
@@ -922,7 +909,7 @@
 
 maybe_improve_headvar_names(Globals, !PredInfo) :-
 	pred_info_clauses_info(!.PredInfo, ClausesInfo0),
-	clauses_info_clauses(ClausesInfo0, Clauses0),
+    clauses_info_clauses_only(ClausesInfo0, Clauses0),
 	clauses_info_headvars(ClausesInfo0, HeadVars0),
 	clauses_info_varset(ClausesInfo0, VarSet0),
 	(
@@ -932,8 +919,7 @@
 		% places the original argument terms, not just the argument
 		% variables in the clause head, and this pass would make it
 		% difficult to work out what were the original arguments).
-		globals__lookup_bool_option(Globals,
-			make_optimization_interface, yes)
+        globals__lookup_bool_option(Globals, make_optimization_interface, yes)
 	->
 		true
 	;
@@ -953,12 +939,10 @@
 		conj_list_to_goal(list__reverse(RevConj), GoalInfo, Goal),
 
 		apply_partial_map_to_list(HeadVars0, Subst, HeadVars),
-		clauses_info_set_headvars(HeadVars,
-			ClausesInfo0, ClausesInfo1),
+        clauses_info_set_headvars(HeadVars, ClausesInfo0, ClausesInfo1),
 
 		SingleClause = clause(A, Goal, C, D),
-		clauses_info_set_clauses([SingleClause],
-			ClausesInfo1, ClausesInfo2),
+        clauses_info_set_clauses([SingleClause], ClausesInfo1, ClausesInfo2),
 		clauses_info_set_varset(VarSet, ClausesInfo2, ClausesInfo),
 		pred_info_set_clauses_info(ClausesInfo, !PredInfo)
 	;
@@ -969,8 +953,7 @@
 		%
 		list__foldl2(find_headvar_names_in_clause(VarSet0, HeadVars0),
 			Clauses0, map__init, HeadVarNames, yes, _),
-		map__foldl(maybe_update_headvar_name, HeadVarNames,
-			VarSet0, VarSet),
+        map__foldl(maybe_update_headvar_name, HeadVarNames, VarSet0, VarSet),
 		clauses_info_set_varset(VarSet, ClausesInfo0, ClausesInfo),
 		pred_info_set_clauses_info(ClausesInfo, !PredInfo)
 	).
@@ -1012,8 +995,7 @@
 				; list__member(OtherGoal, !.RevConj)
 				),
 				OtherGoal = _ - OtherGoalInfo,
-				goal_info_get_nonlocals(OtherGoalInfo,
-					OtherNonLocals),
+                goal_info_get_nonlocals(OtherGoalInfo, OtherNonLocals),
 				set__member(HeadVar, OtherNonLocals)
 			))
 		->
@@ -1026,37 +1008,27 @@
 			%
 			(
 				\+ varset__search_name(!.VarSet, OtherVar, _),
-				varset__search_name(!.VarSet, HeadVar,
-					HeadVarName)
+                varset__search_name(!.VarSet, HeadVar, HeadVarName)
 			->
-				varset__name_var(!.VarSet, OtherVar,
-					HeadVarName, !:VarSet)
+                varset__name_var(!.VarSet, OtherVar, HeadVarName, !:VarSet)
 			;
 				true
 			)
 		;
 			!:RevConj = [Goal | !.RevConj],
 			SeenVars = SeenVars0,
-			(
-				varset__search_name(!.VarSet, OtherVar,
-					OtherVarName)
-			->
+            ( varset__search_name(!.VarSet, OtherVar, OtherVarName) ->
 				%
 				% The unification can't be eliminated,
 				% so just rename the head variable.
 				%
-				varset__name_var(!.VarSet, HeadVar,
-					OtherVarName, !:VarSet)
-			;
-				varset__search_name(!.VarSet, HeadVar,
-					HeadVarName)
-			->
+                varset__name_var(!.VarSet, HeadVar, OtherVarName, !:VarSet)
+            ; varset__search_name(!.VarSet, HeadVar, HeadVarName) ->
 				%
 				% If the variable wasn't named, use the
 				% `HeadVar__n' name.
 				%
-				varset__name_var(!.VarSet, OtherVar,
-					HeadVarName, !:VarSet)
+                varset__name_var(!.VarSet, OtherVar, HeadVarName, !:VarSet)
 			;
 				true
 			)
@@ -1081,8 +1053,7 @@
 	Goal = Clause ^ clause_body,
 	goal_to_conj_list(Goal, Conj),
 	ClauseHeadVarMap = list__foldl(
-		find_headvar_names_in_goal(VarSet, HeadVars),
-		Conj, map__init),
+        find_headvar_names_in_goal(VarSet, HeadVars), Conj, map__init),
 	(
 		IsFirstClause = yes,
 		HeadVarMap = ClauseHeadVarMap
@@ -1093,10 +1064,8 @@
 		HeadVarMap1 = map__foldl(
 			(func(HeadVar, MaybeHeadVarName, Map) =
 				(
-					map__search(Map, HeadVar,
-						MaybeClauseHeadVarName),
-					MaybeHeadVarName =
-						MaybeClauseHeadVarName
+                    map__search(Map, HeadVar, MaybeClauseHeadVarName),
+                    MaybeHeadVarName = MaybeClauseHeadVarName
 				->
 					Map
 				;
@@ -1124,18 +1093,15 @@
 
 find_headvar_names_in_goal(VarSet, HeadVars, Goal, HeadVarMap0) = HeadVarMap :-
 	( goal_is_headvar_unification(HeadVars, Goal, HeadVar, OtherVar) ->
-		maybe_pred(varset__search_name(VarSet), OtherVar,
-			MaybeOtherVarName),
+        maybe_pred(varset__search_name(VarSet), OtherVar, MaybeOtherVarName),
 		( map__search(HeadVarMap0, HeadVar, MaybeHeadVarName) ->
 			( MaybeOtherVarName = MaybeHeadVarName ->
 				HeadVarMap = HeadVarMap0
 			;
-				HeadVarMap = map__det_update(HeadVarMap0,
-					HeadVar, no)
+                HeadVarMap = map__det_update(HeadVarMap0, HeadVar, no)
 			)
 		;
-			HeadVarMap = map__set(HeadVarMap0, HeadVar,
-				MaybeOtherVarName)
+            HeadVarMap = map__set(HeadVarMap0, HeadVar, MaybeOtherVarName)
 		)
 	;
 		HeadVarMap = HeadVarMap0
@@ -1168,8 +1134,7 @@
 typecheck_clause_list(HeadVars, ArgTypes, [Clause0 | Clauses0],
 		[Clause | Clauses], !Info, !IO) :-
 	typecheck_clause(HeadVars, ArgTypes, Clause0, Clause, !Info, !IO),
-	typecheck_clause_list(HeadVars, ArgTypes, Clauses0, Clauses, !Info,
-		!IO).
+    typecheck_clause_list(HeadVars, ArgTypes, Clauses0, Clauses, !Info, !IO).
 
 %-----------------------------------------------------------------------------%
 
@@ -1268,31 +1233,21 @@
 				% are identical (which means that the ambiguity
 				% must have occurred in the body)
 				%
-				type_assign_get_var_types(TypeAssign1,
-					VarTypes1),
-				type_assign_get_var_types(TypeAssign2,
-					VarTypes2),
-				type_assign_get_type_bindings(TypeAssign1,
-					TypeBindings1),
-				type_assign_get_type_bindings(TypeAssign2,
-					TypeBindings2),
-				map__apply_to_list(HeadVars, VarTypes1,
-					HeadTypes1),
-				map__apply_to_list(HeadVars, VarTypes2,
-					HeadTypes2),
-				term__apply_rec_substitution_to_list(
-					HeadTypes1, TypeBindings1,
+                type_assign_get_var_types(TypeAssign1, VarTypes1),
+                type_assign_get_var_types(TypeAssign2, VarTypes2),
+                type_assign_get_type_bindings(TypeAssign1, TypeBindings1),
+                type_assign_get_type_bindings(TypeAssign2, TypeBindings2),
+                map__apply_to_list(HeadVars, VarTypes1, HeadTypes1),
+                map__apply_to_list(HeadVars, VarTypes2, HeadTypes2),
+                term__apply_rec_substitution_to_list(HeadTypes1, TypeBindings1,
 					FinalHeadTypes1),
-				term__apply_rec_substitution_to_list(
-					HeadTypes2, TypeBindings2,
+                term__apply_rec_substitution_to_list(HeadTypes2, TypeBindings2,
 					FinalHeadTypes2),
-				identical_up_to_renaming(FinalHeadTypes1,
-					FinalHeadTypes2)
+                identical_up_to_renaming(FinalHeadTypes1, FinalHeadTypes2)
 			)
 		->
 			typecheck_info_set_found_error(yes, !Info),
-			report_ambiguity_error(!.Info, TypeAssign1,
-				TypeAssign2, !IO)
+            report_ambiguity_error(!.Info, TypeAssign1, TypeAssign2, !IO)
 		;
 			true
 		)
@@ -1496,8 +1451,7 @@
 	empty_hlds_constraints(EmptyConstraints),
 	ExistQVars = [],
 	typecheck_var_has_polymorphic_type_list([PredVar | Args], TypeVarSet,
-		ExistQVars, [PredVarType | ArgTypes], EmptyConstraints,
-		!Info, !IO).
+        ExistQVars, [PredVarType | ArgTypes], EmptyConstraints, !Info, !IO).
 
 :- pred higher_order_pred_type(purity::in, int::in, lambda_eval_method::in,
 	tvarset::out, (type)::out, list(type)::out) is det.
@@ -1550,8 +1504,8 @@
 	% XXX using the old version of !Builtin in typecheck_aditi_state_args
 	% looks wrong; it should be documented or fixed - zs
 	Builtin0 = !.Builtin,
-	typecheck_aditi_builtin_2(CallId, OtherArgs, GoalPath,
-		!Builtin, !Info, !IO),
+    typecheck_aditi_builtin_2(CallId, OtherArgs, GoalPath, !Builtin, !Info,
+        !IO),
 	typecheck_aditi_state_args(Builtin0, CallId, State0, State, !Info,
 		!IO).
 
@@ -1575,8 +1529,7 @@
 	InsertDeleteAdjustArgTypes =
 		(pred(RelationArgTypes::in, UpdateArgTypes::out) is det :-
 			construct_higher_order_type((pure), PredOrFunc,
-				(aditi_bottom_up), RelationArgTypes,
-				ClosureType),
+                (aditi_bottom_up), RelationArgTypes, ClosureType),
 			UpdateArgTypes = [ClosureType]
 	),
 
@@ -1585,11 +1538,9 @@
 	% the tuple to delete, and one for the tuple to insert.
 	ModifyAdjustArgTypes =
 		(pred(RelationArgTypes::in, AditiModifyTypes::out) is det :-
-			list__append(RelationArgTypes, RelationArgTypes,
-				ClosureArgTypes),
-			construct_higher_order_pred_type((pure),
-				(aditi_bottom_up), ClosureArgTypes,
-				ClosureType),
+            list__append(RelationArgTypes, RelationArgTypes, ClosureArgTypes),
+            construct_higher_order_pred_type((pure), (aditi_bottom_up),
+                ClosureArgTypes, ClosureType),
 			AditiModifyTypes = [ClosureType]
 	),
 	(
@@ -1777,8 +1728,7 @@
 		make_body_hlds_constraints(ClassTable, PredTypeVarSet,
 			GoalPath, PredClassContext, PredConstraints),
 		typecheck_var_has_polymorphic_type_list(Args, PredTypeVarSet,
-			PredExistQVars, PredArgTypes, PredConstraints,
-			!Info, !IO)
+            PredExistQVars, PredArgTypes, PredConstraints, !Info, !IO)
 	).
 
 :- pred typecheck_call_overloaded_pred(list(pred_id)::in, list(prog_var)::in,
@@ -1804,8 +1754,7 @@
 	% Then unify the types of the call arguments with the
 	% called predicates' arg types.
 	%
-	typecheck_var_has_arg_type_list(Args, 1, ArgsTypeAssignSet, !Info,
-		!IO).
+    typecheck_var_has_arg_type_list(Args, 1, ArgsTypeAssignSet, !Info, !IO).
 
 :- pred get_overloaded_pred_arg_types(list(pred_id)::in, pred_table::in,
 	class_table::in, goal_path::in, adjust_arg_types::in(adjust_arg_types),
@@ -1840,8 +1789,7 @@
 	module_info_get_predicate_table(ModuleInfo, PredTable),
 	(
 		predicate_table_search_pred_sym(PredTable,
-			calls_are_fully_qualified(CallerMarkers),
-			PredName0, PredIds0)
+            calls_are_fully_qualified(CallerMarkers), PredName0, PredIds0)
 	->
 		PredIds = PredIds0
 	;
@@ -1926,8 +1874,7 @@
 	typecheck_info_get_type_assign_set(!.Info, TypeAssignSet0),
 	rename_apart(TypeAssignSet0, PredTypeVarSet, PredExistQVars,
 		PredArgTypes, PredConstraints, [], ArgsTypeAssignSet),
-	typecheck_var_has_arg_type_list(Args, 1, ArgsTypeAssignSet, !Info,
-		!IO).
+    typecheck_var_has_arg_type_list(Args, 1, ArgsTypeAssignSet, !Info, !IO).
 
 :- pred rename_apart(type_assign_set::in, tvarset::in, existq_tvars::in,
 	list(type)::in, hlds_constraints::in,
@@ -1941,8 +1888,7 @@
 	%
 	type_assign_rename_apart(TypeAssign0, PredTypeVarSet, PredArgTypes,
 		TypeAssign1, ParentArgTypes, Subst),
-	apply_substitution_to_var_list(PredExistQVars, Subst,
-		ParentExistQVars),
+    apply_substitution_to_var_list(PredExistQVars, Subst, ParentExistQVars),
 	apply_subst_to_constraints(Subst, PredConstraints, ParentConstraints),
 
 	%
@@ -1968,10 +1914,8 @@
 type_assign_rename_apart(TypeAssign0, PredTypeVarSet, PredArgTypes,
 		TypeAssign, ParentArgTypes, Subst) :-
 	type_assign_get_typevarset(TypeAssign0, TypeVarSet0),
-	varset__merge_subst(TypeVarSet0, PredTypeVarSet, TypeVarSet,
-		Subst),
-	term__apply_substitution_to_list(PredArgTypes, Subst,
-		ParentArgTypes),
+    varset__merge_subst(TypeVarSet0, PredTypeVarSet, TypeVarSet, Subst),
+    term__apply_substitution_to_list(PredArgTypes, Subst, ParentArgTypes),
 	type_assign_set_typevarset(TypeVarSet, TypeAssign0, TypeAssign).
 
 %-----------------------------------------------------------------------------%
@@ -2052,24 +1996,19 @@
 		ArgTypes0 = [Type | ArgTypes],
 		( map__search(VarTypes0, Var, VarType) ->
 			(
-				type_assign_unify_type(TypeAssign0, VarType,
-					Type, TypeAssign1)
+                type_assign_unify_type(TypeAssign0, VarType, Type, TypeAssign1)
 			->
 				NewTypeAssign = args(TypeAssign1, ArgTypes,
 					ClassContext),
-				!:ArgTypeAssignSet =
-					[NewTypeAssign | !.ArgTypeAssignSet]
+                !:ArgTypeAssignSet = [NewTypeAssign | !.ArgTypeAssignSet]
 			;
 				true
 			)
 		;
 			map__det_insert(VarTypes0, Var, Type, VarTypes),
-			type_assign_set_var_types(VarTypes, TypeAssign0,
-				TypeAssign),
-			NewTypeAssign = args(TypeAssign, ArgTypes,
-				ClassContext),
-			!:ArgTypeAssignSet = [NewTypeAssign |
-				!.ArgTypeAssignSet]
+            type_assign_set_var_types(VarTypes, TypeAssign0, TypeAssign),
+            NewTypeAssign = args(TypeAssign, ArgTypes, ClassContext),
+            !:ArgTypeAssignSet = [NewTypeAssign | !.ArgTypeAssignSet]
 		)
 	;
 		ArgTypes0 = [],
@@ -2129,8 +2068,7 @@
 		map__search(VarTypes0, Var, VarType)
 	->
 		( %%% if some [TypeAssign1]
-			type_assign_unify_type(TypeAssign0, VarType, Type,
-				TypeAssign1)
+            type_assign_unify_type(TypeAssign0, VarType, Type, TypeAssign1)
 		->
 			!:TypeAssignSet = [TypeAssign1 | !.TypeAssignSet]
 		;
@@ -2198,8 +2136,7 @@
 
 check_warn_too_much_overloading(!Info, !IO) :-
 	(
-		typecheck_info_get_warned_about_overloading(!.Info,
-			AlreadyWarned),
+        typecheck_info_get_warned_about_overloading(!.Info, AlreadyWarned),
 		AlreadyWarned = no,
 		typecheck_info_get_type_assign_set(!.Info, TypeAssignSet),
 		list__length(TypeAssignSet, Count),
@@ -2267,8 +2204,8 @@
 		ConsDefnList, InvalidConsDefnList),
 	(
 		ConsDefnList = [],
-		report_error_undef_cons(!.Info, InvalidConsDefnList,
-			Functor, Arity, !IO),
+        report_error_undef_cons(!.Info, InvalidConsDefnList, Functor, Arity,
+            !IO),
 		typecheck_info_set_found_error(yes, !Info)
 	;
 		ConsDefnList = [_ | _],
@@ -2317,9 +2254,8 @@
 			TypeAssignSet = [],
 			ArgsTypeAssignSet = [_ | _]
 		->
-			report_error_functor_arg_types(!.Info, Var,
-				ConsDefnList, Functor, Args,
-				ArgsTypeAssignSet, !IO),
+            report_error_functor_arg_types(!.Info, Var, ConsDefnList,
+                Functor, Args, ArgsTypeAssignSet, !IO),
 			typecheck_info_set_found_error(yes, !Info)
 		;
 			true
@@ -2330,12 +2266,10 @@
 		%
 		(
 			TypeAssignSet = [],
-			typecheck_info_set_type_assign_set(TypeAssignSet0,
-				!Info)
+            typecheck_info_set_type_assign_set(TypeAssignSet0, !Info)
 		;
 			TypeAssignSet = [_ | _],
-			typecheck_info_set_type_assign_set(TypeAssignSet,
-				!Info)
+            typecheck_info_set_type_assign_set(TypeAssignSet, !Info)
 		)
 	).
 
@@ -2419,8 +2353,7 @@
 	ConsTypeAssign = args(TypeAssign, ArgTypes, _),
 	type_assign_var_has_type_list(Args, ArgTypes, TypeAssign, Info,
 		!TypeAssignSet),
-	typecheck_functor_arg_types(ConsTypeAssigns, Args, Info,
-		!TypeAssignSet).
+    typecheck_functor_arg_types(ConsTypeAssigns, Args, Info, !TypeAssignSet).
 
 	% Iterate over all the possible type assignments.
 	%
@@ -2454,8 +2387,7 @@
 			% both X and Y already have types - just
 			% unify their types
 			(
-				type_assign_unify_type(TypeAssign0,
-					TypeX, TypeY, TypeAssign3)
+                type_assign_unify_type(TypeAssign0, TypeX, TypeY, TypeAssign3)
 			->
 				!:TypeAssignSet = [TypeAssign3 |
 					!.TypeAssignSet]
@@ -2466,8 +2398,7 @@
 			% Y is a fresh variable which hasn't been
 			% assigned a type yet
 			map__det_insert(VarTypes0, Y, TypeX, VarTypes),
-			type_assign_set_var_types(VarTypes, TypeAssign0,
-				TypeAssign),
+            type_assign_set_var_types(VarTypes, TypeAssign0, TypeAssign),
 			!:TypeAssignSet = [TypeAssign | !.TypeAssignSet]
 		)
 	;
@@ -2475,8 +2406,7 @@
 			% X is a fresh variable which hasn't been
 			% assigned a type yet
 			map__det_insert(VarTypes0, X, TypeY, VarTypes),
-			type_assign_set_var_types(VarTypes,
-				TypeAssign0, TypeAssign),
+            type_assign_set_var_types(VarTypes, TypeAssign0, TypeAssign),
 			!:TypeAssignSet = [TypeAssign | !.TypeAssignSet]
 		;
 			% both X and Y are fresh variables -
@@ -2493,8 +2423,7 @@
 			;
 				VarTypes = VarTypes1
 			),
-			type_assign_set_var_types(VarTypes, TypeAssign1,
-				TypeAssign),
+            type_assign_set_var_types(VarTypes, TypeAssign1, TypeAssign),
 			!:TypeAssignSet = [TypeAssign | !.TypeAssignSet]
 		)
 	).
@@ -2522,8 +2451,7 @@
 				% functor.
 				%
 			empty_hlds_constraints(EmptyConstraints),
-			ArgsTypeAssign = args(TypeAssign2, ArgTypes,
-				EmptyConstraints),
+            ArgsTypeAssign = args(TypeAssign2, ArgTypes, EmptyConstraints),
 			!:TypeAssignSet = [ArgsTypeAssign | !.TypeAssignSet]
 		;
 			true
@@ -2592,8 +2520,7 @@
 		% be used as deconstructors rather than as constructors.
 		%
 	type_assign_get_typeclass_constraints(TypeAssign2, OldConstraints),
-	merge_hlds_constraints(ConstraintsToAdd, OldConstraints,
-		ClassConstraints),
+    merge_hlds_constraints(ConstraintsToAdd, OldConstraints, ClassConstraints),
 	type_assign_set_typeclass_constraints(ClassConstraints, TypeAssign2,
 		TypeAssign).
 
@@ -2791,9 +2718,8 @@
 				PredTypeParams, PredType),
 			make_body_hlds_constraints(ClassTable, PredTypeVarSet,
 				GoalPath, PredClassContext, PredConstraints),
-			ConsInfo = cons_type_info(PredTypeVarSet,
-				PredExistQVars, PredType, ArgTypes,
-				PredConstraints),
+            ConsInfo = cons_type_info(PredTypeVarSet, PredExistQVars,
+                PredType, ArgTypes, PredConstraints),
 			!:ConsInfos = [ConsInfo | !.ConsInfos],
 
 			% If the predicate has an Aditi marker,
@@ -2803,11 +2729,9 @@
 			pred_info_get_markers(PredInfo, Markers),
 			( check_marker(Markers, aditi) ->
 				construct_higher_order_pred_type(Purity,
-					(aditi_bottom_up), PredTypeParams,
-					PredType2),
+                    (aditi_bottom_up), PredTypeParams, PredType2),
 				ConsInfo2 = cons_type_info(PredTypeVarSet,
-					PredExistQVars, PredType2,
-					ArgTypes, PredConstraints),
+                    PredExistQVars, PredType2, ArgTypes, PredConstraints),
 				!:ConsInfos = [ConsInfo2 | !.ConsInfos]
 			;
 				true
@@ -2834,15 +2758,13 @@
 			( FuncArgTypeParams = [] ->
 				FuncType = FuncReturnTypeParam
 			;
-				construct_higher_order_func_type(Purity,
-					normal, FuncArgTypeParams,
-					FuncReturnTypeParam, FuncType)
+                construct_higher_order_func_type(Purity, normal,
+                    FuncArgTypeParams, FuncReturnTypeParam, FuncType)
 			),
 			make_body_hlds_constraints(ClassTable, PredTypeVarSet,
 				GoalPath, PredClassContext, PredConstraints),
 			ConsInfo = cons_type_info(PredTypeVarSet,
-				PredExistQVars, FuncType, FuncArgTypes,
-				PredConstraints),
+                PredExistQVars, FuncType, FuncArgTypes, PredConstraints),
 			!:ConsInfos = [ConsInfo | !.ConsInfos]
 		;
 			error("make_pred_cons_info: split_list failed")
@@ -2947,9 +2869,8 @@
 	unqualify_name(FuncName, UnqualFuncName),
 	(
 		Info ^ is_field_access_function = no,
-		\+ predicate_table_search_func_m_n_a(PredTable,
-			is_fully_qualified, TypeModule, UnqualFuncName,
-			Arity, _)
+        \+ predicate_table_search_func_m_n_a(PredTable, is_fully_qualified,
+            TypeModule, UnqualFuncName, Arity, _)
 	;
 		Info ^ is_field_access_function = yes
 	),
@@ -3058,10 +2979,9 @@
 			% whose type requires that the fields are of the
 			% same type. It probably won't come up too often.
 			%
-			list__replace_nth_det(ConsArgTypes, FieldNumber,
-				int_type, ArgTypesWithoutField),
-			term__vars_list(ArgTypesWithoutField,
-				TVarsInOtherArgs),
+            list__replace_nth_det(ConsArgTypes, FieldNumber, int_type,
+                ArgTypesWithoutField),
+            term__vars_list(ArgTypesWithoutField, TVarsInOtherArgs),
 			set__intersect(
 				set__list_to_set(TVarsInField),
 				set__intersect(
@@ -3081,8 +3001,7 @@
 				list__sort_and_remove_dups(TVarsOnlyInField0,
 					TVarsOnlyInField),
 				list__length(TVarsOnlyInField, NumNewTVars),
-				varset__new_vars(TVarSet0, NumNewTVars,
-					NewTVars, TVarSet),
+                varset__new_vars(TVarSet0, NumNewTVars, NewTVars, TVarSet),
 				map__from_corresponding_lists(TVarsOnlyInField,
 					NewTVars, TVarRenaming),
 				term__apply_variable_renaming(FieldType,
@@ -3097,18 +3016,15 @@
 				% the call to `'field :='/2'.  Note that we
 				% have already flipped the constraints.
 				%
-				term__vars_list([FunctorType, FieldType],
-					CallTVars0),
+                term__vars_list([FunctorType, FieldType], CallTVars0),
 				set__list_to_set(CallTVars0, CallTVars),
-				project_and_rename_constraints(ClassTable,
-					TVarSet, CallTVars, TVarRenaming,
-					Constraints0, Constraints),
+                project_and_rename_constraints(ClassTable, TVarSet, CallTVars,
+                    TVarRenaming, Constraints0, Constraints),
 
 				RetType = OutputFunctorType,
 				ArgTypes = [FunctorType, RenamedFieldType],
-				ConsTypeInfo = ok(cons_type_info(TVarSet,
-					ExistQVars, RetType, ArgTypes,
-					Constraints))
+                ConsTypeInfo = ok(cons_type_info(TVarSet, ExistQVars,
+                    RetType, ArgTypes, Constraints))
 			;
 				%
 				% This field cannot be set. Pass out some
@@ -3120,10 +3036,8 @@
 				%
 				set__to_sorted_list(ExistQVarsInFieldAndOthers,
 					ExistQVarsInFieldAndOthers1),
-				ConsTypeInfo =
-					error(invalid_field_update(FieldName,
-						FieldDefn, TVarSet0,
-						ExistQVarsInFieldAndOthers1))
+                ConsTypeInfo = error(invalid_field_update(FieldName,
+                    FieldDefn, TVarSet0, ExistQVarsInFieldAndOthers1))
 			)
 		)
 	).
@@ -3345,10 +3259,7 @@
 	% Check if Functor is the name of a predicate which takes at least
 	% Arity arguments.  If so, insert the resulting cons_type_info
 	% at the start of the list.
-	(
-		builtin_pred_type(Info, Functor, Arity, GoalPath,
-			PredConsInfoList)
-	->
+    ( builtin_pred_type(Info, Functor, Arity, GoalPath, PredConsInfoList) ->
 		list__append(ConsInfoList3, PredConsInfoList, ConsInfoList4)
 	;
 		ConsInfoList4 = ConsInfoList3
@@ -3375,9 +3286,7 @@
 		(pred(ok(ConsInfo)::in, ConsInfo::out) is semidet),
 		MaybeConsInfoList, ConsInfoList, ConsErrors0),
 	(
-		list__map(
-			(pred(error(ConsError)::in, ConsError::out)
-				is semidet),
+        list__map((pred(error(ConsError)::in, ConsError::out) is semidet),
 			ConsErrors0, ConsErrors1)
 	->
 		ConsErrors = ConsErrors1
@@ -3447,8 +3356,7 @@
 		\+ is_unify_or_compare_pred(PredInfo),
 		\+ pred_info_import_status(PredInfo, opt_imported)
 	->
-		ConsTypeInfo = error(foreign_type_constructor(TypeCtor,
-			TypeDefn))
+        ConsTypeInfo = error(foreign_type_constructor(TypeCtor, TypeDefn))
 	;
 		% Do not allow constructors for abstract_imported types unless
 		% the current predicate is opt_imported.
Index: compiler/unify_proc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unify_proc.m,v
retrieving revision 1.144
diff -u -b -r1.144 unify_proc.m
--- compiler/unify_proc.m	22 Mar 2005 06:40:30 -0000	1.144
+++ compiler/unify_proc.m	21 May 2005 06:09:03 -0000
@@ -715,9 +715,10 @@
 	map__init(TVarNameMap),
 	map__init(TI_VarMap),
 	map__init(TCI_VarMap),
+	set_clause_list(Clauses, ClausesRep),
 	HasForeignClauses = yes,
 	ClauseInfo = clauses_info(VarSet, Types, TVarNameMap, Types, Args,
-		Clauses, TI_VarMap, TCI_VarMap, HasForeignClauses).
+		ClausesRep, TI_VarMap, TCI_VarMap, HasForeignClauses).
 
 
 :- pred unify_proc__generate_initialise_clauses(module_info::in, (type)::in,
Index: compiler/unique_modes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unique_modes.m,v
retrieving revision 1.88
diff -u -b -r1.88 unique_modes.m
--- compiler/unique_modes.m	24 Mar 2005 05:34:16 -0000	1.88
+++ compiler/unique_modes.m	22 May 2005 01:19:04 -0000
@@ -44,15 +44,18 @@
 :- import_module bool.
 :- import_module io.
 
-	% check every predicate in a module
+	% Check every predicate in a module.
+	%
 :- pred unique_modes__check_module(module_info::in, module_info::out,
 	io::di, io::uo) is det.
 
-	% just check a single procedure
+	% Just check a single procedure.
+	%
 :- pred unique_modes__check_proc(proc_id::in, pred_id::in, module_info::in,
 	module_info::out, bool::out, io::di, io::uo) is det.
 
-	% just check a single goal
+	% Just check a single goal.
+	%
 :- pred unique_modes__check_goal(hlds_goal::in, hlds_goal::out,
 	mode_info::in, mode_info::out, io::di, io::uo) is det.
 
@@ -99,7 +102,7 @@
 		!ModuleInfo, _UnsafeToContinue, !IO).
 
 unique_modes__check_proc(ProcId, PredId, !ModuleInfo, Changed, !IO) :-
-	modecheck_proc(ProcId, PredId, check_unique_modes,
+	modecheck_proc_general(ProcId, PredId, check_unique_modes,
 		may_change_called_proc, !ModuleInfo, NumErrors, Changed, !IO),
 	( NumErrors \= 0 ->
 		io__set_exit_status(1, !IO)
@@ -276,9 +279,11 @@
 unique_modes__check_goal_2(conj(List0), _GoalInfo0, conj(List), !ModeInfo,
 		!IO) :-
 	mode_checkpoint(enter, "conj", !ModeInfo, !IO),
-	( List0 = [] ->	% for efficiency, optimize common case
+	(
+		List0 = [],	% for efficiency, optimize common case
 		List = []
 	;
+		List0 = [_ | _],
 		mode_info_add_goals_live_vars(List0, !ModeInfo),
 		unique_modes__check_conj(List0, List, !ModeInfo, !IO)
 	),
@@ -302,15 +307,17 @@
 unique_modes__check_goal_2(disj(List0), GoalInfo0, disj(List), !ModeInfo,
 		!IO) :-
 	mode_checkpoint(enter, "disj", !ModeInfo, !IO),
-	( List0 = [] ->
+	(
+		List0 = [],
 		List = [],
 		instmap__init_unreachable(InstMap),
 		mode_info_set_instmap(InstMap, !ModeInfo)
 	;
+		List0 = [_ | _],
 		%
-		% If the disjunction creates a choice point (i.e. is model_non),
-		% then mark all the variables which are live at the
-		% start of the disjunction and whose inst is `unique'
+		% If the disjunction creates a choice point (i.e. is
+		% model_non), then mark all the variables which are live
+		% at the start of the disjunction and whose inst is `unique'
 		% as instead being only `mostly_unique', since those variables
 		% may be needed again after we backtrack to that choice point
 		% and resume forward execution again.
@@ -508,11 +515,13 @@
 unique_modes__check_goal_2(switch(Var, CanFail, Cases0), GoalInfo0,
 		switch(Var, CanFail, Cases), !ModeInfo, !IO) :-
 	mode_checkpoint(enter, "switch", !ModeInfo, !IO),
-	( Cases0 = [] ->
+	(
+		Cases0 = [],
 		Cases = [],
 		instmap__init_unreachable(InstMap),
 		mode_info_set_instmap(InstMap, !ModeInfo)
 	;
+		Cases0 = [_ | _],
 		goal_info_get_nonlocals(GoalInfo0, NonLocals),
 		unique_modes__check_case_list(Cases0, Var, Cases, InstMapList,
 			!ModeInfo, !IO),
@@ -563,7 +572,9 @@
 	proc_info_never_succeeds(ProcInfo, NeverSucceeds),
 	unique_modes__check_call_modes(ArgVars, ProcArgModes0, ArgOffset,
 		InterfaceDeterminism, NeverSucceeds, !ModeInfo),
-	( ProcInfo ^ mode_errors = [_|_] ->
+	ModeErrors = ProcInfo ^ mode_errors,
+	(
+		ModeErrors = [_ | _],
 		% mode error in callee for this mode
 		WaitingVars = set__list_to_set(ArgVars),
 		mode_info_get_instmap(!.ModeInfo, InstMap),
@@ -574,7 +585,7 @@
 				ProcInfo ^ mode_errors),
 			!ModeInfo)
 	;
-		true
+		ModeErrors = []
 	),
 
 	%
@@ -612,7 +623,10 @@
 		modecheck_call_pred(PredId, yes(Determinism), ProcId0, ProcId,
 			ArgVars, NewArgVars, ExtraGoals, !ModeInfo),
 
-		( NewArgVars = ArgVars, ExtraGoals = no_extra_goals ->
+		(
+			NewArgVars = ArgVars,
+			ExtraGoals = no_extra_goals
+		->
 			true
 		;
 			% this shouldn't happen, since modes.m should do
@@ -645,17 +659,22 @@
 	inst_list_apply_substitution(FinalInsts0, InstVarSub, FinalInsts),
 	modecheck_set_var_inst_list(ArgVars, InitialInsts, FinalInsts,
 		ArgOffset, NewArgVars, ExtraGoals, !ModeInfo),
-	( NewArgVars = ArgVars, ExtraGoals = no_extra_goals ->
+	(
+		NewArgVars = ArgVars,
+		ExtraGoals = no_extra_goals
+	->
 		true
 	;
 		% this shouldn't happen, since modes.m should do
 		% all the handling of implied modes
 		error("unique_modes.m: call to implied mode?")
 	),
-	( NeverSucceeds = yes ->
+	(
+		NeverSucceeds = yes,
 		instmap__init_unreachable(InstMap),
 		mode_info_set_instmap(InstMap, !ModeInfo)
 	;
+		NeverSucceeds = no,
 		%
 		% Check whether we are at a call to a nondet predicate.
 		% If so, mark all the currently nondet-live variables
@@ -707,8 +726,7 @@
 	goal_get_nonlocals(Goal, NonLocals),
 	set__to_sorted_list(NonLocals, NonLocalsList),
 	bag__from_list(NonLocalsList, NonLocalsMultiSet1),
-	bag__union(NonLocalsMultiSet0, NonLocalsMultiSet1,
-		NonLocalsMultiSet).
+	bag__union(NonLocalsMultiSet0, NonLocalsMultiSet1, NonLocalsMultiSet).
 
 	% To unique-modecheck a parallel conjunction, we find the variables
 	% that are nonlocal to more than one conjunct and make them shared,
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.255
diff -u -b -r1.255 Mmakefile
--- tests/hard_coded/Mmakefile	26 Apr 2005 07:38:02 -0000	1.255
+++ tests/hard_coded/Mmakefile	22 May 2005 02:26:43 -0000
@@ -112,6 +112,7 @@
 	mapped_module \
 	merge_and_remove_dups \
 	minint_bug \
+	mode_check_clauses \
 	mode_choice \
 	multi_map_test \
 	multimode \
Index: tests/hard_coded/mode_check_clauses.exp
===================================================================
RCS file: tests/hard_coded/mode_check_clauses.exp
diff -N tests/hard_coded/mode_check_clauses.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/mode_check_clauses.exp	22 May 2005 02:27:27 -0000
@@ -0,0 +1,2 @@
+02 test works
+11 test works
Index: tests/hard_coded/mode_check_clauses.m
===================================================================
RCS file: tests/hard_coded/mode_check_clauses.m
diff -N tests/hard_coded/mode_check_clauses.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/mode_check_clauses.m	22 May 2005 02:30:41 -0000
@@ -0,0 +1,1061 @@
+:- module mode_check_clauses.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module std_util.
+
+main(!IO) :-
+	solutions(test02_base, Base02),
+	solutions(test02_pragma, Pragma02),
+	solutions(test11_base(1), Base11),
+	solutions(test11_pragma(1), Pragma11),
+	( Base02 = Pragma02 ->
+		io__write_string("02 test works\n", !IO)
+	;
+		io__write_string("02 test doesn't work\n", !IO)
+	),
+	( Base11 = Pragma11 ->
+		io__write_string("11 test works\n", !IO)
+	;
+		io__write_string("11 test doesn't work\n", !IO)
+	).
+
+:- pred test02_base(pair(int)::out) is multi.
+
+test02_base(A - B) :-
+	cycle500_base(A, B).
+
+:- pred test11_base(int::in, int::out) is nondet.
+
+test11_base(A, B) :-
+	cycle500_base(A, B).
+
+:- pred test02_pragma(pair(int)::out) is multi.
+
+test02_pragma(A - B) :-
+	cycle500_pragma(A, B).
+
+:- pred test11_pragma(int::in, int::out) is nondet.
+
+test11_pragma(A, B) :-
+	cycle500_pragma(A, B).
+
+:- pred cycle500_base(int, int).
+:- mode cycle500_base(in, out) is semidet.
+:- mode cycle500_base(out, out) is multi.
+
+cycle500_base(0,1).
+cycle500_base(1,2).
+cycle500_base(2,3).
+cycle500_base(3,4).
+cycle500_base(4,5).
+cycle500_base(5,6).
+cycle500_base(6,7).
+cycle500_base(7,8).
+cycle500_base(8,9).
+cycle500_base(9,10).
+cycle500_base(10,11).
+cycle500_base(11,12).
+cycle500_base(12,13).
+cycle500_base(13,14).
+cycle500_base(14,15).
+cycle500_base(15,16).
+cycle500_base(16,17).
+cycle500_base(17,18).
+cycle500_base(18,19).
+cycle500_base(19,20).
+cycle500_base(20,21).
+cycle500_base(21,22).
+cycle500_base(22,23).
+cycle500_base(23,24).
+cycle500_base(24,25).
+cycle500_base(25,26).
+cycle500_base(26,27).
+cycle500_base(27,28).
+cycle500_base(28,29).
+cycle500_base(29,30).
+cycle500_base(30,31).
+cycle500_base(31,32).
+cycle500_base(32,33).
+cycle500_base(33,34).
+cycle500_base(34,35).
+cycle500_base(35,36).
+cycle500_base(36,37).
+cycle500_base(37,38).
+cycle500_base(38,39).
+cycle500_base(39,40).
+cycle500_base(40,41).
+cycle500_base(41,42).
+cycle500_base(42,43).
+cycle500_base(43,44).
+cycle500_base(44,45).
+cycle500_base(45,46).
+cycle500_base(46,47).
+cycle500_base(47,48).
+cycle500_base(48,49).
+cycle500_base(49,50).
+cycle500_base(50,51).
+cycle500_base(51,52).
+cycle500_base(52,53).
+cycle500_base(53,54).
+cycle500_base(54,55).
+cycle500_base(55,56).
+cycle500_base(56,57).
+cycle500_base(57,58).
+cycle500_base(58,59).
+cycle500_base(59,60).
+cycle500_base(60,61).
+cycle500_base(61,62).
+cycle500_base(62,63).
+cycle500_base(63,64).
+cycle500_base(64,65).
+cycle500_base(65,66).
+cycle500_base(66,67).
+cycle500_base(67,68).
+cycle500_base(68,69).
+cycle500_base(69,70).
+cycle500_base(70,71).
+cycle500_base(71,72).
+cycle500_base(72,73).
+cycle500_base(73,74).
+cycle500_base(74,75).
+cycle500_base(75,76).
+cycle500_base(76,77).
+cycle500_base(77,78).
+cycle500_base(78,79).
+cycle500_base(79,80).
+cycle500_base(80,81).
+cycle500_base(81,82).
+cycle500_base(82,83).
+cycle500_base(83,84).
+cycle500_base(84,85).
+cycle500_base(85,86).
+cycle500_base(86,87).
+cycle500_base(87,88).
+cycle500_base(88,89).
+cycle500_base(89,90).
+cycle500_base(90,91).
+cycle500_base(91,92).
+cycle500_base(92,93).
+cycle500_base(93,94).
+cycle500_base(94,95).
+cycle500_base(95,96).
+cycle500_base(96,97).
+cycle500_base(97,98).
+cycle500_base(98,99).
+cycle500_base(99,100).
+cycle500_base(100,101).
+cycle500_base(101,102).
+cycle500_base(102,103).
+cycle500_base(103,104).
+cycle500_base(104,105).
+cycle500_base(105,106).
+cycle500_base(106,107).
+cycle500_base(107,108).
+cycle500_base(108,109).
+cycle500_base(109,110).
+cycle500_base(110,111).
+cycle500_base(111,112).
+cycle500_base(112,113).
+cycle500_base(113,114).
+cycle500_base(114,115).
+cycle500_base(115,116).
+cycle500_base(116,117).
+cycle500_base(117,118).
+cycle500_base(118,119).
+cycle500_base(119,120).
+cycle500_base(120,121).
+cycle500_base(121,122).
+cycle500_base(122,123).
+cycle500_base(123,124).
+cycle500_base(124,125).
+cycle500_base(125,126).
+cycle500_base(126,127).
+cycle500_base(127,128).
+cycle500_base(128,129).
+cycle500_base(129,130).
+cycle500_base(130,131).
+cycle500_base(131,132).
+cycle500_base(132,133).
+cycle500_base(133,134).
+cycle500_base(134,135).
+cycle500_base(135,136).
+cycle500_base(136,137).
+cycle500_base(137,138).
+cycle500_base(138,139).
+cycle500_base(139,140).
+cycle500_base(140,141).
+cycle500_base(141,142).
+cycle500_base(142,143).
+cycle500_base(143,144).
+cycle500_base(144,145).
+cycle500_base(145,146).
+cycle500_base(146,147).
+cycle500_base(147,148).
+cycle500_base(148,149).
+cycle500_base(149,150).
+cycle500_base(150,151).
+cycle500_base(151,152).
+cycle500_base(152,153).
+cycle500_base(153,154).
+cycle500_base(154,155).
+cycle500_base(155,156).
+cycle500_base(156,157).
+cycle500_base(157,158).
+cycle500_base(158,159).
+cycle500_base(159,160).
+cycle500_base(160,161).
+cycle500_base(161,162).
+cycle500_base(162,163).
+cycle500_base(163,164).
+cycle500_base(164,165).
+cycle500_base(165,166).
+cycle500_base(166,167).
+cycle500_base(167,168).
+cycle500_base(168,169).
+cycle500_base(169,170).
+cycle500_base(170,171).
+cycle500_base(171,172).
+cycle500_base(172,173).
+cycle500_base(173,174).
+cycle500_base(174,175).
+cycle500_base(175,176).
+cycle500_base(176,177).
+cycle500_base(177,178).
+cycle500_base(178,179).
+cycle500_base(179,180).
+cycle500_base(180,181).
+cycle500_base(181,182).
+cycle500_base(182,183).
+cycle500_base(183,184).
+cycle500_base(184,185).
+cycle500_base(185,186).
+cycle500_base(186,187).
+cycle500_base(187,188).
+cycle500_base(188,189).
+cycle500_base(189,190).
+cycle500_base(190,191).
+cycle500_base(191,192).
+cycle500_base(192,193).
+cycle500_base(193,194).
+cycle500_base(194,195).
+cycle500_base(195,196).
+cycle500_base(196,197).
+cycle500_base(197,198).
+cycle500_base(198,199).
+cycle500_base(199,200).
+cycle500_base(200,201).
+cycle500_base(201,202).
+cycle500_base(202,203).
+cycle500_base(203,204).
+cycle500_base(204,205).
+cycle500_base(205,206).
+cycle500_base(206,207).
+cycle500_base(207,208).
+cycle500_base(208,209).
+cycle500_base(209,210).
+cycle500_base(210,211).
+cycle500_base(211,212).
+cycle500_base(212,213).
+cycle500_base(213,214).
+cycle500_base(214,215).
+cycle500_base(215,216).
+cycle500_base(216,217).
+cycle500_base(217,218).
+cycle500_base(218,219).
+cycle500_base(219,220).
+cycle500_base(220,221).
+cycle500_base(221,222).
+cycle500_base(222,223).
+cycle500_base(223,224).
+cycle500_base(224,225).
+cycle500_base(225,226).
+cycle500_base(226,227).
+cycle500_base(227,228).
+cycle500_base(228,229).
+cycle500_base(229,230).
+cycle500_base(230,231).
+cycle500_base(231,232).
+cycle500_base(232,233).
+cycle500_base(233,234).
+cycle500_base(234,235).
+cycle500_base(235,236).
+cycle500_base(236,237).
+cycle500_base(237,238).
+cycle500_base(238,239).
+cycle500_base(239,240).
+cycle500_base(240,241).
+cycle500_base(241,242).
+cycle500_base(242,243).
+cycle500_base(243,244).
+cycle500_base(244,245).
+cycle500_base(245,246).
+cycle500_base(246,247).
+cycle500_base(247,248).
+cycle500_base(248,249).
+cycle500_base(249,250).
+cycle500_base(250,251).
+cycle500_base(251,252).
+cycle500_base(252,253).
+cycle500_base(253,254).
+cycle500_base(254,255).
+cycle500_base(255,256).
+cycle500_base(256,257).
+cycle500_base(257,258).
+cycle500_base(258,259).
+cycle500_base(259,260).
+cycle500_base(260,261).
+cycle500_base(261,262).
+cycle500_base(262,263).
+cycle500_base(263,264).
+cycle500_base(264,265).
+cycle500_base(265,266).
+cycle500_base(266,267).
+cycle500_base(267,268).
+cycle500_base(268,269).
+cycle500_base(269,270).
+cycle500_base(270,271).
+cycle500_base(271,272).
+cycle500_base(272,273).
+cycle500_base(273,274).
+cycle500_base(274,275).
+cycle500_base(275,276).
+cycle500_base(276,277).
+cycle500_base(277,278).
+cycle500_base(278,279).
+cycle500_base(279,280).
+cycle500_base(280,281).
+cycle500_base(281,282).
+cycle500_base(282,283).
+cycle500_base(283,284).
+cycle500_base(284,285).
+cycle500_base(285,286).
+cycle500_base(286,287).
+cycle500_base(287,288).
+cycle500_base(288,289).
+cycle500_base(289,290).
+cycle500_base(290,291).
+cycle500_base(291,292).
+cycle500_base(292,293).
+cycle500_base(293,294).
+cycle500_base(294,295).
+cycle500_base(295,296).
+cycle500_base(296,297).
+cycle500_base(297,298).
+cycle500_base(298,299).
+cycle500_base(299,300).
+cycle500_base(300,301).
+cycle500_base(301,302).
+cycle500_base(302,303).
+cycle500_base(303,304).
+cycle500_base(304,305).
+cycle500_base(305,306).
+cycle500_base(306,307).
+cycle500_base(307,308).
+cycle500_base(308,309).
+cycle500_base(309,310).
+cycle500_base(310,311).
+cycle500_base(311,312).
+cycle500_base(312,313).
+cycle500_base(313,314).
+cycle500_base(314,315).
+cycle500_base(315,316).
+cycle500_base(316,317).
+cycle500_base(317,318).
+cycle500_base(318,319).
+cycle500_base(319,320).
+cycle500_base(320,321).
+cycle500_base(321,322).
+cycle500_base(322,323).
+cycle500_base(323,324).
+cycle500_base(324,325).
+cycle500_base(325,326).
+cycle500_base(326,327).
+cycle500_base(327,328).
+cycle500_base(328,329).
+cycle500_base(329,330).
+cycle500_base(330,331).
+cycle500_base(331,332).
+cycle500_base(332,333).
+cycle500_base(333,334).
+cycle500_base(334,335).
+cycle500_base(335,336).
+cycle500_base(336,337).
+cycle500_base(337,338).
+cycle500_base(338,339).
+cycle500_base(339,340).
+cycle500_base(340,341).
+cycle500_base(341,342).
+cycle500_base(342,343).
+cycle500_base(343,344).
+cycle500_base(344,345).
+cycle500_base(345,346).
+cycle500_base(346,347).
+cycle500_base(347,348).
+cycle500_base(348,349).
+cycle500_base(349,350).
+cycle500_base(350,351).
+cycle500_base(351,352).
+cycle500_base(352,353).
+cycle500_base(353,354).
+cycle500_base(354,355).
+cycle500_base(355,356).
+cycle500_base(356,357).
+cycle500_base(357,358).
+cycle500_base(358,359).
+cycle500_base(359,360).
+cycle500_base(360,361).
+cycle500_base(361,362).
+cycle500_base(362,363).
+cycle500_base(363,364).
+cycle500_base(364,365).
+cycle500_base(365,366).
+cycle500_base(366,367).
+cycle500_base(367,368).
+cycle500_base(368,369).
+cycle500_base(369,370).
+cycle500_base(370,371).
+cycle500_base(371,372).
+cycle500_base(372,373).
+cycle500_base(373,374).
+cycle500_base(374,375).
+cycle500_base(375,376).
+cycle500_base(376,377).
+cycle500_base(377,378).
+cycle500_base(378,379).
+cycle500_base(379,380).
+cycle500_base(380,381).
+cycle500_base(381,382).
+cycle500_base(382,383).
+cycle500_base(383,384).
+cycle500_base(384,385).
+cycle500_base(385,386).
+cycle500_base(386,387).
+cycle500_base(387,388).
+cycle500_base(388,389).
+cycle500_base(389,390).
+cycle500_base(390,391).
+cycle500_base(391,392).
+cycle500_base(392,393).
+cycle500_base(393,394).
+cycle500_base(394,395).
+cycle500_base(395,396).
+cycle500_base(396,397).
+cycle500_base(397,398).
+cycle500_base(398,399).
+cycle500_base(399,400).
+cycle500_base(400,401).
+cycle500_base(401,402).
+cycle500_base(402,403).
+cycle500_base(403,404).
+cycle500_base(404,405).
+cycle500_base(405,406).
+cycle500_base(406,407).
+cycle500_base(407,408).
+cycle500_base(408,409).
+cycle500_base(409,410).
+cycle500_base(410,411).
+cycle500_base(411,412).
+cycle500_base(412,413).
+cycle500_base(413,414).
+cycle500_base(414,415).
+cycle500_base(415,416).
+cycle500_base(416,417).
+cycle500_base(417,418).
+cycle500_base(418,419).
+cycle500_base(419,420).
+cycle500_base(420,421).
+cycle500_base(421,422).
+cycle500_base(422,423).
+cycle500_base(423,424).
+cycle500_base(424,425).
+cycle500_base(425,426).
+cycle500_base(426,427).
+cycle500_base(427,428).
+cycle500_base(428,429).
+cycle500_base(429,430).
+cycle500_base(430,431).
+cycle500_base(431,432).
+cycle500_base(432,433).
+cycle500_base(433,434).
+cycle500_base(434,435).
+cycle500_base(435,436).
+cycle500_base(436,437).
+cycle500_base(437,438).
+cycle500_base(438,439).
+cycle500_base(439,440).
+cycle500_base(440,441).
+cycle500_base(441,442).
+cycle500_base(442,443).
+cycle500_base(443,444).
+cycle500_base(444,445).
+cycle500_base(445,446).
+cycle500_base(446,447).
+cycle500_base(447,448).
+cycle500_base(448,449).
+cycle500_base(449,450).
+cycle500_base(450,451).
+cycle500_base(451,452).
+cycle500_base(452,453).
+cycle500_base(453,454).
+cycle500_base(454,455).
+cycle500_base(455,456).
+cycle500_base(456,457).
+cycle500_base(457,458).
+cycle500_base(458,459).
+cycle500_base(459,460).
+cycle500_base(460,461).
+cycle500_base(461,462).
+cycle500_base(462,463).
+cycle500_base(463,464).
+cycle500_base(464,465).
+cycle500_base(465,466).
+cycle500_base(466,467).
+cycle500_base(467,468).
+cycle500_base(468,469).
+cycle500_base(469,470).
+cycle500_base(470,471).
+cycle500_base(471,472).
+cycle500_base(472,473).
+cycle500_base(473,474).
+cycle500_base(474,475).
+cycle500_base(475,476).
+cycle500_base(476,477).
+cycle500_base(477,478).
+cycle500_base(478,479).
+cycle500_base(479,480).
+cycle500_base(480,481).
+cycle500_base(481,482).
+cycle500_base(482,483).
+cycle500_base(483,484).
+cycle500_base(484,485).
+cycle500_base(485,486).
+cycle500_base(486,487).
+cycle500_base(487,488).
+cycle500_base(488,489).
+cycle500_base(489,490).
+cycle500_base(490,491).
+cycle500_base(491,492).
+cycle500_base(492,493).
+cycle500_base(493,494).
+cycle500_base(494,495).
+cycle500_base(495,496).
+cycle500_base(496,497).
+cycle500_base(497,498).
+cycle500_base(498,499).
+cycle500_base(499,500).
+cycle500_base(500,0).
+
+:- pred cycle500_pragma(int, int).
+:- mode cycle500_pragma(in, out) is semidet.
+:- mode cycle500_pragma(out, out) is multi.
+
+:- pragma mode_check_clauses(cycle500_pragma/2).
+
+cycle500_pragma(0,1).
+cycle500_pragma(1,2).
+cycle500_pragma(2,3).
+cycle500_pragma(3,4).
+cycle500_pragma(4,5).
+cycle500_pragma(5,6).
+cycle500_pragma(6,7).
+cycle500_pragma(7,8).
+cycle500_pragma(8,9).
+cycle500_pragma(9,10).
+cycle500_pragma(10,11).
+cycle500_pragma(11,12).
+cycle500_pragma(12,13).
+cycle500_pragma(13,14).
+cycle500_pragma(14,15).
+cycle500_pragma(15,16).
+cycle500_pragma(16,17).
+cycle500_pragma(17,18).
+cycle500_pragma(18,19).
+cycle500_pragma(19,20).
+cycle500_pragma(20,21).
+cycle500_pragma(21,22).
+cycle500_pragma(22,23).
+cycle500_pragma(23,24).
+cycle500_pragma(24,25).
+cycle500_pragma(25,26).
+cycle500_pragma(26,27).
+cycle500_pragma(27,28).
+cycle500_pragma(28,29).
+cycle500_pragma(29,30).
+cycle500_pragma(30,31).
+cycle500_pragma(31,32).
+cycle500_pragma(32,33).
+cycle500_pragma(33,34).
+cycle500_pragma(34,35).
+cycle500_pragma(35,36).
+cycle500_pragma(36,37).
+cycle500_pragma(37,38).
+cycle500_pragma(38,39).
+cycle500_pragma(39,40).
+cycle500_pragma(40,41).
+cycle500_pragma(41,42).
+cycle500_pragma(42,43).
+cycle500_pragma(43,44).
+cycle500_pragma(44,45).
+cycle500_pragma(45,46).
+cycle500_pragma(46,47).
+cycle500_pragma(47,48).
+cycle500_pragma(48,49).
+cycle500_pragma(49,50).
+cycle500_pragma(50,51).
+cycle500_pragma(51,52).
+cycle500_pragma(52,53).
+cycle500_pragma(53,54).
+cycle500_pragma(54,55).
+cycle500_pragma(55,56).
+cycle500_pragma(56,57).
+cycle500_pragma(57,58).
+cycle500_pragma(58,59).
+cycle500_pragma(59,60).
+cycle500_pragma(60,61).
+cycle500_pragma(61,62).
+cycle500_pragma(62,63).
+cycle500_pragma(63,64).
+cycle500_pragma(64,65).
+cycle500_pragma(65,66).
+cycle500_pragma(66,67).
+cycle500_pragma(67,68).
+cycle500_pragma(68,69).
+cycle500_pragma(69,70).
+cycle500_pragma(70,71).
+cycle500_pragma(71,72).
+cycle500_pragma(72,73).
+cycle500_pragma(73,74).
+cycle500_pragma(74,75).
+cycle500_pragma(75,76).
+cycle500_pragma(76,77).
+cycle500_pragma(77,78).
+cycle500_pragma(78,79).
+cycle500_pragma(79,80).
+cycle500_pragma(80,81).
+cycle500_pragma(81,82).
+cycle500_pragma(82,83).
+cycle500_pragma(83,84).
+cycle500_pragma(84,85).
+cycle500_pragma(85,86).
+cycle500_pragma(86,87).
+cycle500_pragma(87,88).
+cycle500_pragma(88,89).
+cycle500_pragma(89,90).
+cycle500_pragma(90,91).
+cycle500_pragma(91,92).
+cycle500_pragma(92,93).
+cycle500_pragma(93,94).
+cycle500_pragma(94,95).
+cycle500_pragma(95,96).
+cycle500_pragma(96,97).
+cycle500_pragma(97,98).
+cycle500_pragma(98,99).
+cycle500_pragma(99,100).
+cycle500_pragma(100,101).
+cycle500_pragma(101,102).
+cycle500_pragma(102,103).
+cycle500_pragma(103,104).
+cycle500_pragma(104,105).
+cycle500_pragma(105,106).
+cycle500_pragma(106,107).
+cycle500_pragma(107,108).
+cycle500_pragma(108,109).
+cycle500_pragma(109,110).
+cycle500_pragma(110,111).
+cycle500_pragma(111,112).
+cycle500_pragma(112,113).
+cycle500_pragma(113,114).
+cycle500_pragma(114,115).
+cycle500_pragma(115,116).
+cycle500_pragma(116,117).
+cycle500_pragma(117,118).
+cycle500_pragma(118,119).
+cycle500_pragma(119,120).
+cycle500_pragma(120,121).
+cycle500_pragma(121,122).
+cycle500_pragma(122,123).
+cycle500_pragma(123,124).
+cycle500_pragma(124,125).
+cycle500_pragma(125,126).
+cycle500_pragma(126,127).
+cycle500_pragma(127,128).
+cycle500_pragma(128,129).
+cycle500_pragma(129,130).
+cycle500_pragma(130,131).
+cycle500_pragma(131,132).
+cycle500_pragma(132,133).
+cycle500_pragma(133,134).
+cycle500_pragma(134,135).
+cycle500_pragma(135,136).
+cycle500_pragma(136,137).
+cycle500_pragma(137,138).
+cycle500_pragma(138,139).
+cycle500_pragma(139,140).
+cycle500_pragma(140,141).
+cycle500_pragma(141,142).
+cycle500_pragma(142,143).
+cycle500_pragma(143,144).
+cycle500_pragma(144,145).
+cycle500_pragma(145,146).
+cycle500_pragma(146,147).
+cycle500_pragma(147,148).
+cycle500_pragma(148,149).
+cycle500_pragma(149,150).
+cycle500_pragma(150,151).
+cycle500_pragma(151,152).
+cycle500_pragma(152,153).
+cycle500_pragma(153,154).
+cycle500_pragma(154,155).
+cycle500_pragma(155,156).
+cycle500_pragma(156,157).
+cycle500_pragma(157,158).
+cycle500_pragma(158,159).
+cycle500_pragma(159,160).
+cycle500_pragma(160,161).
+cycle500_pragma(161,162).
+cycle500_pragma(162,163).
+cycle500_pragma(163,164).
+cycle500_pragma(164,165).
+cycle500_pragma(165,166).
+cycle500_pragma(166,167).
+cycle500_pragma(167,168).
+cycle500_pragma(168,169).
+cycle500_pragma(169,170).
+cycle500_pragma(170,171).
+cycle500_pragma(171,172).
+cycle500_pragma(172,173).
+cycle500_pragma(173,174).
+cycle500_pragma(174,175).
+cycle500_pragma(175,176).
+cycle500_pragma(176,177).
+cycle500_pragma(177,178).
+cycle500_pragma(178,179).
+cycle500_pragma(179,180).
+cycle500_pragma(180,181).
+cycle500_pragma(181,182).
+cycle500_pragma(182,183).
+cycle500_pragma(183,184).
+cycle500_pragma(184,185).
+cycle500_pragma(185,186).
+cycle500_pragma(186,187).
+cycle500_pragma(187,188).
+cycle500_pragma(188,189).
+cycle500_pragma(189,190).
+cycle500_pragma(190,191).
+cycle500_pragma(191,192).
+cycle500_pragma(192,193).
+cycle500_pragma(193,194).
+cycle500_pragma(194,195).
+cycle500_pragma(195,196).
+cycle500_pragma(196,197).
+cycle500_pragma(197,198).
+cycle500_pragma(198,199).
+cycle500_pragma(199,200).
+cycle500_pragma(200,201).
+cycle500_pragma(201,202).
+cycle500_pragma(202,203).
+cycle500_pragma(203,204).
+cycle500_pragma(204,205).
+cycle500_pragma(205,206).
+cycle500_pragma(206,207).
+cycle500_pragma(207,208).
+cycle500_pragma(208,209).
+cycle500_pragma(209,210).
+cycle500_pragma(210,211).
+cycle500_pragma(211,212).
+cycle500_pragma(212,213).
+cycle500_pragma(213,214).
+cycle500_pragma(214,215).
+cycle500_pragma(215,216).
+cycle500_pragma(216,217).
+cycle500_pragma(217,218).
+cycle500_pragma(218,219).
+cycle500_pragma(219,220).
+cycle500_pragma(220,221).
+cycle500_pragma(221,222).
+cycle500_pragma(222,223).
+cycle500_pragma(223,224).
+cycle500_pragma(224,225).
+cycle500_pragma(225,226).
+cycle500_pragma(226,227).
+cycle500_pragma(227,228).
+cycle500_pragma(228,229).
+cycle500_pragma(229,230).
+cycle500_pragma(230,231).
+cycle500_pragma(231,232).
+cycle500_pragma(232,233).
+cycle500_pragma(233,234).
+cycle500_pragma(234,235).
+cycle500_pragma(235,236).
+cycle500_pragma(236,237).
+cycle500_pragma(237,238).
+cycle500_pragma(238,239).
+cycle500_pragma(239,240).
+cycle500_pragma(240,241).
+cycle500_pragma(241,242).
+cycle500_pragma(242,243).
+cycle500_pragma(243,244).
+cycle500_pragma(244,245).
+cycle500_pragma(245,246).
+cycle500_pragma(246,247).
+cycle500_pragma(247,248).
+cycle500_pragma(248,249).
+cycle500_pragma(249,250).
+cycle500_pragma(250,251).
+cycle500_pragma(251,252).
+cycle500_pragma(252,253).
+cycle500_pragma(253,254).
+cycle500_pragma(254,255).
+cycle500_pragma(255,256).
+cycle500_pragma(256,257).
+cycle500_pragma(257,258).
+cycle500_pragma(258,259).
+cycle500_pragma(259,260).
+cycle500_pragma(260,261).
+cycle500_pragma(261,262).
+cycle500_pragma(262,263).
+cycle500_pragma(263,264).
+cycle500_pragma(264,265).
+cycle500_pragma(265,266).
+cycle500_pragma(266,267).
+cycle500_pragma(267,268).
+cycle500_pragma(268,269).
+cycle500_pragma(269,270).
+cycle500_pragma(270,271).
+cycle500_pragma(271,272).
+cycle500_pragma(272,273).
+cycle500_pragma(273,274).
+cycle500_pragma(274,275).
+cycle500_pragma(275,276).
+cycle500_pragma(276,277).
+cycle500_pragma(277,278).
+cycle500_pragma(278,279).
+cycle500_pragma(279,280).
+cycle500_pragma(280,281).
+cycle500_pragma(281,282).
+cycle500_pragma(282,283).
+cycle500_pragma(283,284).
+cycle500_pragma(284,285).
+cycle500_pragma(285,286).
+cycle500_pragma(286,287).
+cycle500_pragma(287,288).
+cycle500_pragma(288,289).
+cycle500_pragma(289,290).
+cycle500_pragma(290,291).
+cycle500_pragma(291,292).
+cycle500_pragma(292,293).
+cycle500_pragma(293,294).
+cycle500_pragma(294,295).
+cycle500_pragma(295,296).
+cycle500_pragma(296,297).
+cycle500_pragma(297,298).
+cycle500_pragma(298,299).
+cycle500_pragma(299,300).
+cycle500_pragma(300,301).
+cycle500_pragma(301,302).
+cycle500_pragma(302,303).
+cycle500_pragma(303,304).
+cycle500_pragma(304,305).
+cycle500_pragma(305,306).
+cycle500_pragma(306,307).
+cycle500_pragma(307,308).
+cycle500_pragma(308,309).
+cycle500_pragma(309,310).
+cycle500_pragma(310,311).
+cycle500_pragma(311,312).
+cycle500_pragma(312,313).
+cycle500_pragma(313,314).
+cycle500_pragma(314,315).
+cycle500_pragma(315,316).
+cycle500_pragma(316,317).
+cycle500_pragma(317,318).
+cycle500_pragma(318,319).
+cycle500_pragma(319,320).
+cycle500_pragma(320,321).
+cycle500_pragma(321,322).
+cycle500_pragma(322,323).
+cycle500_pragma(323,324).
+cycle500_pragma(324,325).
+cycle500_pragma(325,326).
+cycle500_pragma(326,327).
+cycle500_pragma(327,328).
+cycle500_pragma(328,329).
+cycle500_pragma(329,330).
+cycle500_pragma(330,331).
+cycle500_pragma(331,332).
+cycle500_pragma(332,333).
+cycle500_pragma(333,334).
+cycle500_pragma(334,335).
+cycle500_pragma(335,336).
+cycle500_pragma(336,337).
+cycle500_pragma(337,338).
+cycle500_pragma(338,339).
+cycle500_pragma(339,340).
+cycle500_pragma(340,341).
+cycle500_pragma(341,342).
+cycle500_pragma(342,343).
+cycle500_pragma(343,344).
+cycle500_pragma(344,345).
+cycle500_pragma(345,346).
+cycle500_pragma(346,347).
+cycle500_pragma(347,348).
+cycle500_pragma(348,349).
+cycle500_pragma(349,350).
+cycle500_pragma(350,351).
+cycle500_pragma(351,352).
+cycle500_pragma(352,353).
+cycle500_pragma(353,354).
+cycle500_pragma(354,355).
+cycle500_pragma(355,356).
+cycle500_pragma(356,357).
+cycle500_pragma(357,358).
+cycle500_pragma(358,359).
+cycle500_pragma(359,360).
+cycle500_pragma(360,361).
+cycle500_pragma(361,362).
+cycle500_pragma(362,363).
+cycle500_pragma(363,364).
+cycle500_pragma(364,365).
+cycle500_pragma(365,366).
+cycle500_pragma(366,367).
+cycle500_pragma(367,368).
+cycle500_pragma(368,369).
+cycle500_pragma(369,370).
+cycle500_pragma(370,371).
+cycle500_pragma(371,372).
+cycle500_pragma(372,373).
+cycle500_pragma(373,374).
+cycle500_pragma(374,375).
+cycle500_pragma(375,376).
+cycle500_pragma(376,377).
+cycle500_pragma(377,378).
+cycle500_pragma(378,379).
+cycle500_pragma(379,380).
+cycle500_pragma(380,381).
+cycle500_pragma(381,382).
+cycle500_pragma(382,383).
+cycle500_pragma(383,384).
+cycle500_pragma(384,385).
+cycle500_pragma(385,386).
+cycle500_pragma(386,387).
+cycle500_pragma(387,388).
+cycle500_pragma(388,389).
+cycle500_pragma(389,390).
+cycle500_pragma(390,391).
+cycle500_pragma(391,392).
+cycle500_pragma(392,393).
+cycle500_pragma(393,394).
+cycle500_pragma(394,395).
+cycle500_pragma(395,396).
+cycle500_pragma(396,397).
+cycle500_pragma(397,398).
+cycle500_pragma(398,399).
+cycle500_pragma(399,400).
+cycle500_pragma(400,401).
+cycle500_pragma(401,402).
+cycle500_pragma(402,403).
+cycle500_pragma(403,404).
+cycle500_pragma(404,405).
+cycle500_pragma(405,406).
+cycle500_pragma(406,407).
+cycle500_pragma(407,408).
+cycle500_pragma(408,409).
+cycle500_pragma(409,410).
+cycle500_pragma(410,411).
+cycle500_pragma(411,412).
+cycle500_pragma(412,413).
+cycle500_pragma(413,414).
+cycle500_pragma(414,415).
+cycle500_pragma(415,416).
+cycle500_pragma(416,417).
+cycle500_pragma(417,418).
+cycle500_pragma(418,419).
+cycle500_pragma(419,420).
+cycle500_pragma(420,421).
+cycle500_pragma(421,422).
+cycle500_pragma(422,423).
+cycle500_pragma(423,424).
+cycle500_pragma(424,425).
+cycle500_pragma(425,426).
+cycle500_pragma(426,427).
+cycle500_pragma(427,428).
+cycle500_pragma(428,429).
+cycle500_pragma(429,430).
+cycle500_pragma(430,431).
+cycle500_pragma(431,432).
+cycle500_pragma(432,433).
+cycle500_pragma(433,434).
+cycle500_pragma(434,435).
+cycle500_pragma(435,436).
+cycle500_pragma(436,437).
+cycle500_pragma(437,438).
+cycle500_pragma(438,439).
+cycle500_pragma(439,440).
+cycle500_pragma(440,441).
+cycle500_pragma(441,442).
+cycle500_pragma(442,443).
+cycle500_pragma(443,444).
+cycle500_pragma(444,445).
+cycle500_pragma(445,446).
+cycle500_pragma(446,447).
+cycle500_pragma(447,448).
+cycle500_pragma(448,449).
+cycle500_pragma(449,450).
+cycle500_pragma(450,451).
+cycle500_pragma(451,452).
+cycle500_pragma(452,453).
+cycle500_pragma(453,454).
+cycle500_pragma(454,455).
+cycle500_pragma(455,456).
+cycle500_pragma(456,457).
+cycle500_pragma(457,458).
+cycle500_pragma(458,459).
+cycle500_pragma(459,460).
+cycle500_pragma(460,461).
+cycle500_pragma(461,462).
+cycle500_pragma(462,463).
+cycle500_pragma(463,464).
+cycle500_pragma(464,465).
+cycle500_pragma(465,466).
+cycle500_pragma(466,467).
+cycle500_pragma(467,468).
+cycle500_pragma(468,469).
+cycle500_pragma(469,470).
+cycle500_pragma(470,471).
+cycle500_pragma(471,472).
+cycle500_pragma(472,473).
+cycle500_pragma(473,474).
+cycle500_pragma(474,475).
+cycle500_pragma(475,476).
+cycle500_pragma(476,477).
+cycle500_pragma(477,478).
+cycle500_pragma(478,479).
+cycle500_pragma(479,480).
+cycle500_pragma(480,481).
+cycle500_pragma(481,482).
+cycle500_pragma(482,483).
+cycle500_pragma(483,484).
+cycle500_pragma(484,485).
+cycle500_pragma(485,486).
+cycle500_pragma(486,487).
+cycle500_pragma(487,488).
+cycle500_pragma(488,489).
+cycle500_pragma(489,490).
+cycle500_pragma(490,491).
+cycle500_pragma(491,492).
+cycle500_pragma(492,493).
+cycle500_pragma(493,494).
+cycle500_pragma(494,495).
+cycle500_pragma(495,496).
+cycle500_pragma(496,497).
+cycle500_pragma(497,498).
+cycle500_pragma(498,499).
+cycle500_pragma(499,500).
+cycle500_pragma(500,0).
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list