[m-rev.] for review: pred_table.m, hlds_clauses.m and hlds_rtti.m

Zoltan Somogyi zs at cs.mu.OZ.AU
Fri Mar 24 12:13:46 AEDT 2006


For review (of the idea, not really the implementation) by anyone.

Zoltan.

Move the stuff currently in hlds_pred.m that deals with clauses into a new
module, hlds_clauses.m.

Move the stuff currently in hlds_pred.m that deals with RTTI into a new
module, hlds_rtti.m.

Move the stuff currently in hlds_module.m that deals with predicate tables
into a new module, pred_table.m.

These changes make hlds_pred.m and hlds_module.m much more cohesive, but there
are no changes in algorithms.

compiler/hlds_clauses.m:
compiler/hlds_rtti.m:
compiler/pred_table.m:
	New modules as described above. In some cases, fix mixleading or
	ambiguous predicate names in the process, and convert a few predicates
	to functions.

compiler/hlds_pred.m:
compiler/hlds_module.m:
	Delete the stuff moved to other modules.

compiler/*.m:
	In modules that need the functionality moved a new module, import
	the new module. It is rare for all the new modules to be needed,
	and many modules don't need any of the new modules at all. (For
	example, of the 200+ modules that import hlds_module.m, only about 40
	need pred_table.m.)

	Conform to the few minor changes to e.g. predicate names.

compiler/notes/compiler_design.html:
	Document the new modules.

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/accumulator.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/accumulator.m,v
retrieving revision 1.52
diff -u -b -r1.52 accumulator.m
--- compiler/accumulator.m	17 Mar 2006 01:40:10 -0000	1.52
+++ compiler/accumulator.m	22 Mar 2006 04:19:21 -0000
@@ -168,6 +168,7 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
 :- import_module hlds.instmap.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/add_class.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_class.m,v
retrieving revision 1.12
diff -u -b -r1.12 add_class.m
--- compiler/add_class.m	17 Mar 2006 01:40:10 -0000	1.12
+++ compiler/add_class.m	22 Mar 2006 05:27:23 -0000
@@ -50,12 +50,14 @@
 :- import_module check_hlds.clause_to_proc.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.make_hlds.add_clause.
 :- import_module hlds.make_hlds.add_pred.
 :- import_module hlds.make_hlds.add_type.
 :- import_module hlds.make_hlds.make_hlds_error.
 :- import_module hlds.make_hlds.make_hlds_warn.
 :- import_module hlds.make_hlds.state_var.
+:- import_module hlds.pred_table.
 :- import_module libs.compiler_util.
 :- import_module parse_tree.error_util.
 :- import_module parse_tree.prog_out.
Index: compiler/add_clause.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_clause.m,v
retrieving revision 1.18
diff -u -b -r1.18 add_clause.m
--- compiler/add_clause.m	21 Mar 2006 22:25:25 -0000	1.18
+++ compiler/add_clause.m	22 Mar 2006 04:17:46 -0000
@@ -61,6 +61,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.pred_table.
 :- import_module hlds.make_hlds.add_pragma.
 :- import_module hlds.make_hlds.add_pred.
 :- import_module hlds.make_hlds.field_access.
Index: compiler/add_heap_ops.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_heap_ops.m,v
retrieving revision 1.24
diff -u -b -r1.24 add_heap_ops.m
--- compiler/add_heap_ops.m	17 Mar 2006 01:40:10 -0000	1.24
+++ compiler/add_heap_ops.m	22 Mar 2006 04:02:29 -0000
@@ -48,6 +48,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.instmap.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
 :- import_module mdbcomp.prim_data.
Index: compiler/add_pragma.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_pragma.m,v
retrieving revision 1.26
diff -u -b -r1.26 add_pragma.m
--- compiler/add_pragma.m	17 Mar 2006 01:40:10 -0000	1.26
+++ compiler/add_pragma.m	22 Mar 2006 04:38:56 -0000
@@ -117,12 +117,14 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.make_hlds.add_pred.
 :- import_module hlds.make_hlds.make_hlds_error.
 :- import_module hlds.make_hlds.make_hlds_passes.
 :- import_module hlds.make_hlds.make_hlds_warn.
 :- import_module hlds.make_hlds.qual_info.
 :- import_module hlds.make_tags.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
@@ -131,9 +133,9 @@
 :- import_module ll_backend.fact_table.
 :- import_module parse_tree.error_util.
 :- import_module parse_tree.modules.
+:- import_module parse_tree.prog_ctgc.
 :- import_module parse_tree.prog_foreign.
 :- import_module parse_tree.prog_io.
-:- import_module parse_tree.prog_ctgc.
 :- import_module parse_tree.prog_out.
 :- import_module parse_tree.prog_type.
 :- import_module parse_tree.prog_type_subst.
Index: compiler/add_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_pred.m,v
retrieving revision 1.13
diff -u -b -r1.13 add_pred.m
--- compiler/add_pred.m	17 Mar 2006 01:40:11 -0000	1.13
+++ compiler/add_pred.m	22 Mar 2006 04:18:19 -0000
@@ -14,6 +14,7 @@
 
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.pred_table.
 :- import_module mdbcomp.prim_data.
 :- import_module hlds.make_hlds.make_hlds_passes.
 :- import_module parse_tree.prog_data.
@@ -64,6 +65,7 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.make_hlds.make_hlds_error.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/add_special_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_special_pred.m,v
retrieving revision 1.9
diff -u -b -r1.9 add_special_pred.m
--- compiler/add_special_pred.m	17 Mar 2006 01:40:11 -0000	1.9
+++ compiler/add_special_pred.m	22 Mar 2006 04:18:36 -0000
@@ -56,6 +56,7 @@
 :- import_module check_hlds.type_util.
 :- import_module check_hlds.unify_proc.
 :- import_module hlds.make_hlds.add_pred.
+:- import_module hlds.pred_table.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/add_trail_ops.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/add_trail_ops.m,v
retrieving revision 1.32
diff -u -b -r1.32 add_trail_ops.m
--- compiler/add_trail_ops.m	17 Mar 2006 01:40:11 -0000	1.32
+++ compiler/add_trail_ops.m	22 Mar 2006 04:02:41 -0000
@@ -72,6 +72,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.instmap.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/assertion.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/assertion.m,v
retrieving revision 1.45
diff -u -b -r1.45 assertion.m
--- compiler/assertion.m	24 Feb 2006 05:49:24 -0000	1.45
+++ compiler/assertion.m	22 Mar 2006 03:39:38 -0000
@@ -129,6 +129,7 @@
 
 :- import_module check_hlds.type_util.
 :- import_module hlds.goal_util.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_out.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/base_typeclass_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/base_typeclass_info.m,v
retrieving revision 1.42
diff -u -b -r1.42 base_typeclass_info.m
--- compiler/base_typeclass_info.m	17 Mar 2006 01:40:11 -0000	1.42
+++ compiler/base_typeclass_info.m	22 Mar 2006 03:26:00 -0000
@@ -45,6 +45,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
Index: compiler/build_mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/build_mode_constraints.m,v
retrieving revision 1.12
diff -u -b -r1.12 build_mode_constraints.m
--- compiler/build_mode_constraints.m	24 Feb 2006 05:49:24 -0000	1.12
+++ compiler/build_mode_constraints.m	22 Mar 2006 03:40:08 -0000
@@ -196,6 +196,7 @@
 :- import_module check_hlds.goal_path.
 :- import_module check_hlds.inst_match.
 :- import_module check_hlds.mode_util.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.passes_aux.
 :- import_module libs.compiler_util.
Index: compiler/bytecode_backend.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/bytecode_backend.m,v
retrieving revision 1.4
diff -u -b -r1.4 bytecode_backend.m
Index: compiler/bytecode_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/bytecode_gen.m,v
retrieving revision 1.100
diff -u -b -r1.100 bytecode_gen.m
--- compiler/bytecode_gen.m	22 Mar 2006 02:56:12 -0000	1.100
+++ compiler/bytecode_gen.m	22 Mar 2006 03:36:15 -0000
@@ -98,7 +98,7 @@
     ;
         ProcIds = [_ | _],
         gen_pred(PredId, ProcIds, PredInfo, ModuleInfo, ProcsCode, !IO),
-        predicate_name(ModuleInfo, PredId, PredName),
+        PredName = predicate_name(ModuleInfo, PredId),
         list.length(ProcIds, ProcsCount),
         Arity = pred_info_orig_arity(PredInfo),
         get_is_func(PredInfo, IsFunc),
@@ -390,8 +390,8 @@
 
 gen_builtin(PredId, ProcId, Args, ByteInfo, Code) :-
     get_module_info(ByteInfo, ModuleInfo),
-    predicate_module(ModuleInfo, PredId, ModuleName),
-    predicate_name(ModuleInfo, PredId, PredName),
+    ModuleName = predicate_module(ModuleInfo, PredId),
+    PredName = predicate_name(ModuleInfo, PredId),
     (
         builtin_ops.translate_builtin(ModuleName, PredName, ProcId,
             Args, SimpleCode)
Index: compiler/call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/call_gen.m,v
retrieving revision 1.172
diff -u -b -r1.172 call_gen.m
--- compiler/call_gen.m	17 Mar 2006 01:40:12 -0000	1.172
+++ compiler/call_gen.m	22 Mar 2006 03:40:32 -0000
@@ -506,8 +506,8 @@
 
 call_gen.generate_builtin(CodeModel, PredId, ProcId, Args, Code, !CI) :-
     code_info.get_module_info(!.CI, ModuleInfo),
-    predicate_module(ModuleInfo, PredId, ModuleName),
-    predicate_name(ModuleInfo, PredId, PredName),
+    ModuleName = predicate_module(ModuleInfo, PredId),
+    PredName = predicate_name(ModuleInfo, PredId),
     (
         builtin_ops.translate_builtin(ModuleName, PredName,
             ProcId, Args, SimpleCode0)
Index: compiler/check_hlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/check_hlds.m,v
retrieving revision 1.12
diff -u -b -r1.12 check_hlds.m
Index: compiler/check_typeclass.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/check_typeclass.m,v
retrieving revision 1.88
diff -u -b -r1.88 check_typeclass.m
--- compiler/check_typeclass.m	17 Mar 2006 01:40:12 -0000	1.88
+++ compiler/check_typeclass.m	22 Mar 2006 04:08:47 -0000
@@ -91,7 +91,9 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
Index: compiler/clause_to_proc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/clause_to_proc.m,v
retrieving revision 1.63
diff -u -b -r1.63 clause_to_proc.m
--- compiler/clause_to_proc.m	17 Mar 2006 01:40:12 -0000	1.63
+++ compiler/clause_to_proc.m	22 Mar 2006 05:27:48 -0000
@@ -9,8 +9,10 @@
 :- module check_hlds.clause_to_proc.
 :- interface.
 
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.pred_table.
 
 :- import_module list.
 :- import_module std_util.
@@ -66,6 +68,7 @@
 :- import_module hlds.goal_util.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.make_hlds.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/closure_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/closure_analysis.m,v
retrieving revision 1.7
diff -u -b -r1.7 closure_analysis.m
Index: compiler/code_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_info.m,v
retrieving revision 1.314
diff -u -b -r1.314 code_info.m
--- compiler/code_info.m	17 Mar 2006 01:40:13 -0000	1.314
+++ compiler/code_info.m	22 Mar 2006 04:39:30 -0000
@@ -63,6 +63,7 @@
 :- import_module check_hlds.type_util.
 :- import_module hlds.arg_info.
 :- import_module hlds.hlds_code_util.
+:- import_module hlds.hlds_rtti.
 :- import_module libs.compiler_util.
 :- import_module libs.options.
 :- import_module libs.trace_params.
@@ -3503,8 +3504,8 @@
     get_proc_info(CI, ProcInfo),
     proc_info_vartypes(ProcInfo, VarTypes),
     proc_info_rtti_varmaps(ProcInfo, RttiVarMaps),
-    proc_info_maybe_complete_with_typeinfo_vars(Vars0, TypeInfoLiveness,
-        VarTypes, RttiVarMaps, Vars1),
+    maybe_complete_with_typeinfo_vars(Vars0, TypeInfoLiveness, VarTypes,
+        RttiVarMaps, Vars1),
     set.difference(Vars1, OutArgs, Vars),
     set.to_sorted_list(Vars, Variables),
     list.map(associate_stack_slot(CI), Variables, VarLocs).
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.165
diff -u -b -r1.165 code_util.m
--- compiler/code_util.m	17 Mar 2006 01:40:13 -0000	1.165
+++ compiler/code_util.m	22 Mar 2006 03:16:32 -0000
@@ -20,6 +20,7 @@
 :- import_module hlds.hlds_llds.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module libs.globals.
 :- import_module ll_backend.llds.
 :- import_module mdbcomp.prim_data.
Index: compiler/common.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/common.m,v
retrieving revision 1.90
diff -u -b -r1.90 common.m
--- compiler/common.m	17 Mar 2006 01:40:13 -0000	1.90
+++ compiler/common.m	22 Mar 2006 03:41:49 -0000
@@ -98,6 +98,7 @@
 :- import_module hlds.goal_util.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_module.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
Index: compiler/compiler_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/compiler_util.m,v
retrieving revision 1.3
diff -u -b -r1.3 compiler_util.m
--- compiler/compiler_util.m	18 Nov 2005 06:22:53 -0000	1.3
+++ compiler/compiler_util.m	22 Mar 2006 02:42:46 -0000
@@ -13,7 +13,7 @@
 %
 %-----------------------------------------------------------------------------%
 
-:- module libs__compiler_util.
+:- module libs.compiler_util.
 
 :- interface.
 
@@ -56,7 +56,7 @@
     % Report a warning to the specified stream, and set the exit status
     % to error if the --halt-at-warn option is set.
     %
-:- pred report_warning(io__output_stream::in, string::in, io::di, io::uo)
+:- pred report_warning(io.output_stream::in, string::in, io::di, io::uo)
     is det.
 
 %-----------------------------------------------------------------------------%
@@ -78,13 +78,13 @@
     %
 sorry(Module, What) = _ :- sorry(Module, What).
 sorry(Module, What) :-
-    string__format("%s: Sorry, not implemented: %s",
+    string.format("%s: Sorry, not implemented: %s",
         [s(Module), s(What)], ErrorMessage),
     error(ErrorMessage).
 
 unexpected(Module, What) = _ :- unexpected(Module, What).
 unexpected(Module, What) :-
-    string__format("%s: Unexpected: %s", [s(Module), s(What)], ErrorMessage),
+    string.format("%s: Unexpected: %s", [s(Module), s(What)], ErrorMessage),
     error(ErrorMessage).
 
 expect(Goal, Module, Message) :-
@@ -95,21 +95,21 @@
     ).
 
 record_warning(!IO) :-
-    globals__io_lookup_bool_option(halt_at_warn, HaltAtWarn, !IO),
+    globals.io_lookup_bool_option(halt_at_warn, HaltAtWarn, !IO),
     (
         HaltAtWarn = yes,
-        io__set_exit_status(1, !IO)
+        io.set_exit_status(1, !IO)
     ;
         HaltAtWarn = no
     ).
 
 report_warning(Message, !IO) :-
     record_warning(!IO),
-    io__write_string(Message, !IO).
+    io.write_string(Message, !IO).
 
 report_warning(Stream, Message, !IO) :-
     record_warning(!IO),
-    io__write_string(Stream, Message, !IO).
+    io.write_string(Stream, Message, !IO).
 
 %-----------------------------------------------------------------------------%
 :- end_module compiler_util.
Index: compiler/complexity.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/complexity.m,v
retrieving revision 1.12
diff -u -b -r1.12 complexity.m
--- compiler/complexity.m	17 Mar 2006 01:40:14 -0000	1.12
+++ compiler/complexity.m	22 Mar 2006 04:19:44 -0000
@@ -65,6 +65,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.instmap.
+:- import_module hlds.pred_table.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
Index: compiler/const_prop.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/const_prop.m,v
retrieving revision 1.35
diff -u -b -r1.35 const_prop.m
--- compiler/const_prop.m	17 Mar 2006 01:40:14 -0000	1.35
+++ compiler/const_prop.m	22 Mar 2006 04:19:57 -0000
@@ -89,8 +89,8 @@
 
 evaluate_call(PredId, ProcId, Args, VarTypes, InstMap, ModuleInfo, Goal,
         GoalInfo0, GoalInfo) :-
-    predicate_module(ModuleInfo, PredId, ModuleName),
-    predicate_name(ModuleInfo, PredId, PredName),
+    ModuleName =predicate_module(ModuleInfo, PredId),
+    PredName = predicate_name(ModuleInfo, PredId),
     proc_id_to_int(ProcId, ProcInt),
     LookupArgs = (func(Var) = arg_hlds_info(Var, Type, Inst) :-
         instmap.lookup_var(InstMap, Var, Inst),
Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.69
diff -u -b -r1.69 continuation_info.m
--- compiler/continuation_info.m	17 Mar 2006 01:40:14 -0000	1.69
+++ compiler/continuation_info.m	22 Mar 2006 03:17:02 -0000
@@ -55,6 +55,7 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module libs.globals.
 :- import_module libs.trace_params.
Index: compiler/cse_detection.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/cse_detection.m,v
retrieving revision 1.95
diff -u -b -r1.95 cse_detection.m
--- compiler/cse_detection.m	17 Mar 2006 01:40:14 -0000	1.95
+++ compiler/cse_detection.m	22 Mar 2006 03:11:16 -0000
@@ -46,6 +46,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
Index: compiler/dead_proc_elim.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dead_proc_elim.m,v
retrieving revision 1.109
diff -u -b -r1.109 dead_proc_elim.m
--- compiler/dead_proc_elim.m	17 Mar 2006 01:40:15 -0000	1.109
+++ compiler/dead_proc_elim.m	22 Mar 2006 04:41:15 -0000
@@ -69,10 +69,12 @@
 
 :- implementation.
 
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_error_util.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
Index: compiler/deep_profiling.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/deep_profiling.m,v
retrieving revision 1.45
diff -u -b -r1.45 deep_profiling.m
--- compiler/deep_profiling.m	17 Mar 2006 01:40:15 -0000	1.45
+++ compiler/deep_profiling.m	22 Mar 2006 04:01:22 -0000
@@ -38,6 +38,7 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_pred.
 :- import_module hlds.instmap.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
@@ -438,7 +439,7 @@
 maybe_transform_procedure(ModuleInfo, PredId, ProcId, !ProcTable) :-
     map.lookup(!.ProcTable, ProcId, ProcInfo0),
     proc_info_goal(ProcInfo0, Goal0),
-    predicate_module(ModuleInfo, PredId, PredModuleName),
+    PredModuleName = predicate_module(ModuleInfo, PredId),
     (
         % XXX We need to eliminate nondet C code...
         Goal0 = foreign_proc(_, _, _, _, _, Impl) - _,
Index: compiler/deforest.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/deforest.m,v
retrieving revision 1.60
diff -u -b -r1.60 deforest.m
--- compiler/deforest.m	17 Mar 2006 01:40:15 -0000	1.60
+++ compiler/deforest.m	22 Mar 2006 04:20:42 -0000
@@ -646,8 +646,8 @@
         % If both goals are calls create a new predicate for the conjunction
         % to be deforested and process it.
         pd_info_get_module_info(!.PDInfo, ModuleInfo0),
-        predicate_name(ModuleInfo0, PredId1, PredName1),
-        predicate_name(ModuleInfo0, PredId2, PredName2),
+        PredName1 = predicate_name(ModuleInfo0, PredId1),
+        PredName2 = predicate_name(ModuleInfo0, PredId2),
         pd_debug_message("deforesting calls to %s and %s\n",
             [s(PredName1), s(PredName2)], !IO),
         call_call(ConjNonLocals, EarlierGoal, BetweenGoals,
@@ -673,7 +673,7 @@
         PredProcId \= CurrPredProcId,
         \+ set.member(PredProcId, Parents0)
     ->
-        predicate_name(ModuleInfo, PredId, CurrPredName),
+        CurrPredName = predicate_name(ModuleInfo, PredId),
         pd_debug_message("Pushing call to %s into goal\n",
             [s(CurrPredName)], !IO),
         set.insert(Parents0, proc(PredId, ProcId), Parents),
@@ -953,7 +953,7 @@
         % If we see an opportunity to fold, take it.
         VersionPredProcId = proc(VersionPredId, _),
         pd_info_get_module_info(!.PDInfo, ModuleInfo0),
-        predicate_name(ModuleInfo0, VersionPredId, FoldPredName),
+        FoldPredName = predicate_name(ModuleInfo0, VersionPredId),
         pd_debug_message("Folded with %s\n", [s(FoldPredName)], !IO),
         ( set.member(VersionPredProcId, Parents) ->
             FoldCostDelta = cost_of_recursive_fold
@@ -1105,7 +1105,7 @@
 
             pd_info_get_module_info(!.PDInfo, ModuleInfo),
 
-            predicate_name(ModuleInfo, PredId, PredName),
+            PredName = predicate_name(ModuleInfo, PredId),
             pd_debug_message("\nCreated predicate %s\n", [s(PredName)], !IO),
             ( MaybeLaterGoal = yes(call(PredId2, ProcId2, _, _, _, _) - _) ->
                 CalledPreds = [proc(PredId1, ProcId1), proc(PredId2, ProcId2)]
Index: compiler/delay_construct.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/delay_construct.m,v
retrieving revision 1.17
diff -u -b -r1.17 delay_construct.m
--- compiler/delay_construct.m	17 Mar 2006 01:40:15 -0000	1.17
+++ compiler/delay_construct.m	22 Mar 2006 04:41:36 -0000
@@ -45,6 +45,7 @@
 :- import_module check_hlds.inst_match.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module hlds.passes_aux.
 :- import_module libs.compiler_util.
@@ -226,7 +227,7 @@
         Goal0 = GoalExpr0 - GoalInfo0,
         delay_construct_skippable(GoalExpr0, GoalInfo0),
         goal_info_get_nonlocals(GoalInfo0, NonLocals),
-        proc_info_maybe_complete_with_typeinfo_vars(NonLocals,
+        maybe_complete_with_typeinfo_vars(NonLocals,
             DelayInfo ^ body_typeinfo_liveness,
             DelayInfo ^ vartypes,
             DelayInfo ^ rtti_varmaps, CompletedNonLocals),
Index: compiler/dependency_graph.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dependency_graph.m,v
retrieving revision 1.84
diff -u -b -r1.84 dependency_graph.m
--- compiler/dependency_graph.m	17 Mar 2006 01:40:16 -0000	1.84
+++ compiler/dependency_graph.m	22 Mar 2006 04:21:00 -0000
@@ -117,6 +117,7 @@
 :- import_module backend_libs.proc_label.
 :- import_module check_hlds.mode_util.
 :- import_module hlds.goal_util.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module libs.compiler_util.
Index: compiler/det_analysis.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/det_analysis.m,v
retrieving revision 1.190
diff -u -b -r1.190 det_analysis.m
--- compiler/det_analysis.m	22 Mar 2006 00:45:59 -0000	1.190
+++ compiler/det_analysis.m	22 Mar 2006 03:42:22 -0000
@@ -115,6 +115,7 @@
 :- import_module hlds.goal_util.
 :- import_module hlds.hlds_out.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module libs.compiler_util.
 :- import_module libs.options.
 :- import_module parse_tree.error_util.
Index: compiler/equiv_type_hlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/equiv_type_hlds.m,v
retrieving revision 1.28
diff -u -b -r1.28 equiv_type_hlds.m
--- compiler/equiv_type_hlds.m	17 Mar 2006 01:40:17 -0000	1.28
+++ compiler/equiv_type_hlds.m	22 Mar 2006 04:21:15 -0000
@@ -38,6 +38,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
Index: compiler/export.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/export.m,v
retrieving revision 1.96
diff -u -b -r1.96 export.m
--- compiler/export.m	17 Mar 2006 01:40:17 -0000	1.96
+++ compiler/export.m	22 Mar 2006 03:26:23 -0000
@@ -86,6 +86,7 @@
 :- import_module hlds.arg_info.
 :- import_module hlds.code_model.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.pred_table.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
Index: compiler/frameopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/frameopt.m,v
retrieving revision 1.97
diff -u -b -r1.97 frameopt.m
Index: compiler/goal_path.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_path.m,v
retrieving revision 1.32
diff -u -b -r1.32 goal_path.m
--- compiler/goal_path.m	17 Mar 2006 01:40:19 -0000	1.32
+++ compiler/goal_path.m	22 Mar 2006 03:42:33 -0000
@@ -56,6 +56,7 @@
 :- implementation.
 
 :- import_module check_hlds.type_util.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module libs.compiler_util.
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.127
diff -u -b -r1.127 goal_util.m
--- compiler/goal_util.m	17 Mar 2006 01:40:19 -0000	1.127
+++ compiler/goal_util.m	22 Mar 2006 03:12:42 -0000
@@ -17,10 +17,13 @@
 :- module hlds.goal_util.
 :- interface.
 
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
+:- import_module hlds.pred_table.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
 
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.260
diff -u -b -r1.260 handle_options.m
--- compiler/handle_options.m	17 Mar 2006 01:40:20 -0000	1.260
+++ compiler/handle_options.m	22 Mar 2006 05:34:36 -0000
@@ -5,15 +5,15 @@
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
-
+%
 % File: handle_options.m.
 % Main authors: fjh, zs.
-
+%
 % This module does post-processing on the command-line options, after
 % getopt has done its stuff.
-
+%
 % It also contains code for handling the --grade option.
-
+%
 %-----------------------------------------------------------------------------%
 
 :- module libs.handle_options.
Index: compiler/hhf.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hhf.m,v
retrieving revision 1.17
diff -u -b -r1.17 hhf.m
--- compiler/hhf.m	17 Mar 2006 01:40:20 -0000	1.17
+++ compiler/hhf.m	22 Mar 2006 03:12:52 -0000
@@ -20,6 +20,7 @@
 :- module hlds.hhf.
 :- interface.
 
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_pred.
 :- import_module hlds.hlds_module.
 :- import_module hlds.inst_graph.
Index: compiler/higher_order.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.148
diff -u -b -r1.148 higher_order.m
--- compiler/higher_order.m	17 Mar 2006 01:40:20 -0000	1.148
+++ compiler/higher_order.m	22 Mar 2006 04:24:35 -0000
@@ -46,11 +46,14 @@
 :- import_module check_hlds.type_util.
 :- import_module check_hlds.unify_proc.
 :- import_module hlds.goal_util.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
@@ -2501,7 +2504,7 @@
         % structures are derived from the names of predicates, duplicate
         % predicate names lead to duplicate global variable names and hence to
         % link errors.
-        predicate_name(ModuleInfo0, CallerPredId, PredName0),
+        PredName0 = predicate_name(ModuleInfo0, CallerPredId),
         proc_id_to_int(CallerProcId, CallerProcInt),
 
         % The higher_order_arg_order_version part is to avoid segmentation
Index: compiler/hlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds.m,v
retrieving revision 1.219
diff -u -b -r1.219 hlds.m
--- compiler/hlds.m	28 Oct 2005 02:10:08 -0000	1.219
+++ compiler/hlds.m	22 Mar 2006 03:07:07 -0000
@@ -19,13 +19,16 @@
 
 % The HLDS data structure itself
 :- include_module assertion.
+:- include_module hlds_clauses.
 :- include_module hlds_data.
 :- include_module hlds_goal.
 :- include_module hlds_llds.
 :- include_module hlds_module.
 :- include_module hlds_pred.
+:- include_module hlds_rtti.
 :- include_module inst_graph.
 :- include_module instmap.
+:- include_module pred_table.
 :- include_module special_pred.
 
 % Modules for creating the HLDS
Index: compiler/hlds_clauses.m
===================================================================
RCS file: compiler/hlds_clauses.m
diff -N compiler/hlds_clauses.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ compiler/hlds_clauses.m	22 Mar 2006 04:33:35 -0000
@@ -0,0 +1,311 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 1996-2006 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.
+%-----------------------------------------------------------------------------%
+%
+% File: hlds_clauses.m.
+% Main authors: fjh, conway.
+%
+% This module defines the part of the HLDS that deals with clauses.
+%
+%-----------------------------------------------------------------------------%
+
+:- module hlds.hlds_clauses.
+:- interface.
+
+:- import_module hlds.hlds_goal.
+:- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
+:- import_module parse_tree.prog_data.
+
+:- import_module bool.
+:- import_module list.
+
+    % The clauses_info structure contains the clauses for a predicate
+    % after conversion from the item_list by make_hlds.m.
+    % Typechecking is performed on the clauses info, then the clauses
+    % are copied to create the proc_info for each procedure.
+    % After mode analysis the clauses and the procedure goals are not
+    % guaranteed to be the same, and the clauses are only kept so that
+    % the optimized goal can be compared with the original in HLDS dumps.
+:- type clauses_info
+    --->    clauses_info(
+                varset                  :: prog_varset,
+
+                explicit_vartypes       :: vartypes,
+                                        % Variable types from explicit
+                                        % qualifications.
+
+                tvar_name_map           :: tvar_name_map,
+                                        % Map from variable name to type
+                                        % variable for the type variables
+                                        % occurring in the argument types.
+                                        % This is used to process explicit
+                                        % type qualifications.
+
+                vartypes                :: vartypes,
+                                        % Variable types inferred by
+                                        % typecheck.m.
+
+                headvars                :: list(prog_var),
+                                        % The head variables.
+
+                clauses_rep             :: clauses_rep,
+
+                clauses_rtti_varmaps    :: rtti_varmaps,
+                                        % This field is computed by
+                                        % polymorphism.m.
+
+                have_foreign_clauses    :: bool
+                                        % Do we have foreign language clauses?
+        ).
+
+:- pred clauses_info_init(int::in, clauses_info::out) is det.
+
+:- pred clauses_info_init_for_assertion(prog_vars::in, clauses_info::out)
+    is det.
+
+:- type clauses_rep.
+
+:- func init_clauses_rep = 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.
+
+:- pred clauses_info_varset(clauses_info::in, prog_varset::out) is det.
+
+    % 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_rtti_varmaps(clauses_info::in, rtti_varmaps::out) is det.
+
+:- pred clauses_info_headvars(clauses_info::in, list(prog_var)::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.
+
+:- 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.
+
+:- pred clauses_info_set_rtti_varmaps(rtti_varmaps::in,
+    clauses_info::in, clauses_info::out) is det.
+
+:- type clause
+    --->    clause(
+                applicable_procs    :: list(proc_id),
+                                    % Modes for which this clause applies
+                                    % ([] means it applies to all modes).
+
+                clause_body         :: hlds_goal,
+                clause_lang         :: implementation_language,
+                clause_context      :: prog_context
+            ).
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module check_hlds.inst_match.
+:- import_module check_hlds.mode_util.
+:- import_module check_hlds.type_util.
+:- import_module hlds.goal_form.
+:- import_module hlds.goal_util.
+:- import_module hlds.make_hlds.
+:- import_module libs.compiler_util.
+:- import_module libs.options.
+:- import_module parse_tree.prog_type.
+:- import_module parse_tree.prog_type_subst.
+:- import_module parse_tree.prog_util.
+
+:- import_module int.
+:- import_module map.
+:- import_module string.
+:- import_module svmap.
+:- import_module term.
+:- import_module varset.
+
+clauses_info_init(Arity, ClausesInfo) :-
+    map.init(VarTypes),
+    map.init(TVarNameMap),
+    varset.init(VarSet0),
+    make_n_fresh_vars("HeadVar__", Arity, HeadVars, VarSet0, VarSet),
+    rtti_varmaps_init(RttiVarMaps),
+    HasForeignClauses = no,
+    set_clause_list([], ClausesRep),
+    ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
+        HeadVars, ClausesRep, RttiVarMaps, HasForeignClauses).
+
+clauses_info_init_for_assertion(HeadVars, ClausesInfo) :-
+    map.init(VarTypes),
+    map.init(TVarNameMap),
+    varset.init(VarSet),
+    rtti_varmaps_init(RttiVarMaps),
+    HasForeignClauses = no,
+    set_clause_list([], ClausesRep),
+    ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
+        HeadVars, ClausesRep, RttiVarMaps, HasForeignClauses).
+
+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_rtti_varmaps(CI, CI ^ clauses_rtti_varmaps).
+
+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_rtti_varmaps(X, CI, CI ^ clauses_rtti_varmaps := X).
+
+:- type clauses_rep
+    --->    rev(list(clause))
+    ;       forw(list(clause))
+    ;       both(
+                rev :: list(clause),
+                forw :: list(clause)
+            ).
+
+init_clauses_rep = forw([]).
+
+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)
+    ).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "hlds_clauses.m".
+
+%-----------------------------------------------------------------------------%
+:- end_module hlds.hlds_clauses.
+%-----------------------------------------------------------------------------%
Index: compiler/hlds_module.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_module.m,v
retrieving revision 1.131
diff -u -b -r1.131 hlds_module.m
--- compiler/hlds_module.m	9 Mar 2006 04:56:33 -0000	1.131
+++ compiler/hlds_module.m	22 Mar 2006 03:32:47 -0000
@@ -29,13 +29,14 @@
 :- import_module check_hlds.unify_proc.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.pred_table.
 :- import_module hlds.special_pred.
 :- import_module libs.globals.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.module_qual.
 :- import_module parse_tree.prog_data.
-:- import_module parse_tree.prog_item.
 :- import_module parse_tree.prog_foreign.
+:- import_module parse_tree.prog_item.
 :- import_module recompilation.
 
 :- import_module list.
@@ -564,6 +565,15 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred predicate_id(module_info::in, pred_id::in, module_name::out,
+    string::out, arity::out) is det.
+
+:- func predicate_module(module_info, pred_id) = module_name.
+:- func predicate_name(module_info, pred_id) = string.
+:- func predicate_arity(module_info, pred_id) = arity.
+
+%-----------------------------------------------------------------------------%
+
 :- implementation.
 
 :- import_module libs.compiler_util.
@@ -1134,6 +1144,30 @@
         := [FileName | FileNames].
 
 %-----------------------------------------------------------------------------%
+
+predicate_id(ModuleInfo, PredId, ModuleName, PredName, Arity) :-
+    module_info_preds(ModuleInfo, Preds),
+    map.lookup(Preds, PredId, PredInfo),
+    ModuleName = pred_info_module(PredInfo),
+    PredName = pred_info_name(PredInfo),
+    Arity = pred_info_orig_arity(PredInfo).
+    
+predicate_module(ModuleInfo, PredId) = ModuleName :-
+    module_info_preds(ModuleInfo, Preds),
+    map.lookup(Preds, PredId, PredInfo),
+    ModuleName = pred_info_module(PredInfo).
+    
+predicate_name(ModuleInfo, PredId) = PredName :-
+    module_info_preds(ModuleInfo, Preds),
+    map.lookup(Preds, PredId, PredInfo),
+    PredName = pred_info_name(PredInfo).
+    
+predicate_arity(ModuleInfo, PredId) = Arity :-
+    module_info_preds(ModuleInfo, Preds),
+    map.lookup(Preds, PredId, PredInfo), 
+    Arity = pred_info_orig_arity(PredInfo).
+
+%-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
 :- interface.
@@ -1183,1166 +1217,6 @@
     DepInfo ^ dep_graph := DepGraph).
 hlds_dependency_info_set_dependency_ordering(DepOrd, DepInfo,
     DepInfo ^ dep_ord := DepOrd).
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-:- interface.
-
-:- type predicate_table.
-
-:- type pred_table  ==  map(pred_id, pred_info).
-
-    % Various predicates for accessing the predicate_table type.
-    % The predicate_table holds information about the predicates
-    % and functions defined in this module or imported from other modules.
-    % The primary key for this table is the `pred_id', but there
-    % are also secondary indexes on each of name, name+arity, and
-    % module+name+arity, for both functions and predicates.
-
-    % Initialize the predicate table
-    %
-:- pred predicate_table_init(predicate_table::out) is det.
-
-    % Balance all the binary trees in the predicate table
-    %
-:- pred predicate_table_optimize(predicate_table::in, predicate_table::out)
-    is det.
-
-    % Get the pred_id->pred_info map.
-    %
-:- pred predicate_table_get_preds(predicate_table::in, pred_table::out) is det.
-
-    % Restrict the predicate table to the list of predicates. This predicate
-    % should only be used when the set of predicates to restrict the table
-    % to is significantly smaller then the predicate_table size, as rather than
-    % removing entries from the table it builds a new table from scratch.
-    %
-:- pred predicate_table_restrict(partial_qualifier_info::in,
-    list(pred_id)::in, predicate_table::in, predicate_table::out) is det.
-
-    % Set the pred_id->pred_info map.
-    % NB You shouldn't modify the keys in this table, only
-    % use predicate_table_insert, predicate_table_remove_predid and
-    % predicate_table_remove_predicate.
-    %
-:- pred predicate_table_set_preds(pred_table::in,
-    predicate_table::in, predicate_table::out) is det.
-
-    % Get a list of all the valid predids in the predicate_table.
-    %
-:- pred predicate_table_get_predids(predicate_table::in, list(pred_id)::out)
-    is det.
-
-    % Remove a pred_id from the valid list.
-    %
-:- pred predicate_table_remove_predid(pred_id::in,
-    predicate_table::in, predicate_table::out) is det.
-:- pred predicate_table_remove_predicate(pred_id::in,
-    predicate_table::in, predicate_table::out) is det.
-
-    % Search the table for (a) predicates or functions (b) predicates only
-    % or (c) functions only matching this (possibly module-qualified) sym_name.
-    %
-:- pred predicate_table_search_sym(predicate_table::in, is_fully_qualified::in,
-    sym_name::in, list(pred_id)::out) is semidet.
-
-:- pred predicate_table_search_pred_sym(predicate_table::in,
-    is_fully_qualified::in, sym_name::in, list(pred_id)::out) is semidet.
-
-:- pred predicate_table_search_func_sym(predicate_table::in,
-    is_fully_qualified::in, sym_name::in, list(pred_id)::out) is semidet.
-
-    % Search the table for (a) predicates or functions (b) predicates only
-    % or (c) functions only matching this (possibly module-qualified)
-    % sym_name & arity.
-    %
-:- pred predicate_table_search_sym_arity(predicate_table::in,
-    is_fully_qualified::in, sym_name::in, arity::in, list(pred_id)::out)
-    is semidet.
-
-:- pred predicate_table_search_pred_sym_arity(predicate_table::in,
-    is_fully_qualified::in, sym_name::in, arity::in, list(pred_id)::out)
-    is semidet.
-
-:- pred predicate_table_search_func_sym_arity(predicate_table::in,
-    is_fully_qualified::in, sym_name::in, arity::in, list(pred_id)::out)
-    is semidet.
-
-    % Search the table for (a) predicates or functions
-    % (b) predicates only or (c) functions only matching this name.
-    %
-:- pred predicate_table_search_name(predicate_table::in, string::in,
-    list(pred_id)::out) is semidet.
-
-:- pred predicate_table_search_pred_name(predicate_table::in, string::in,
-    list(pred_id)::out) is semidet.
-
-:- pred predicate_table_search_func_name(predicate_table::in, string::in,
-    list(pred_id)::out) is semidet.
-
-    % Search the table for (a) predicates or functions (b) predicates only
-    % or (c) functions only matching this name & arity. When searching for
-    % functions, the arity used is the arity of the function, not the arity
-    % N+1 predicate that it gets converted to.
-    %
-:- pred predicate_table_search_name_arity(predicate_table::in, string::in,
-    arity::in, list(pred_id)::out) is semidet.
-
-:- pred predicate_table_search_pred_name_arity(predicate_table::in, string::in,
-    arity::in, list(pred_id)::out) is semidet.
-
-:- pred predicate_table_search_func_name_arity(predicate_table::in, string::in,
-    arity::in, list(pred_id)::out) is semidet.
-
-    % Search the table for (a) predicates or functions (b) predicates only
-    % or (c) functions only matching this module, name & arity. When searching
-    % for functions, the arity used is the arity of the function, not the arity
-    % N+1 predicate that it gets converted to.
-    %
-    % Note that in cases (b) and (c) it was previously the case that there
-    % could only be one matching pred_id, since each predicate or function
-    % could be uniquely identified by its module, name, arity, and category
-    % (function/predicate). However this is no longer true, due to nested
-    % modules. (For example, `pred foo:bar/2' might match both
-    % `pred mod1:foo:bar/2' and `pred mod2:foo:bar/2'). I hope it doesn't
-    % break anything too badly...
-    %
-    % (`m_n_a' here is short for "module, name, arity".)
-
-    % Is the item known to be fully qualified? If so, a search for
-    % `pred foo.bar/2' will not match `pred baz.foo.bar/2'.
-:- type is_fully_qualified
-    --->    is_fully_qualified
-    ;       may_be_partially_qualified.
-
-:- pred predicate_table_search_m_n_a(predicate_table::in,
-    is_fully_qualified::in, module_name::in, string::in, arity::in,
-    list(pred_id)::out) is semidet.
-
-:- pred predicate_table_search_pred_m_n_a(predicate_table::in,
-    is_fully_qualified::in, module_name::in, string::in, arity::in,
-    list(pred_id)::out) is semidet.
-
-:- pred predicate_table_search_func_m_n_a(predicate_table::in,
-    is_fully_qualified::in, module_name::in, string::in, arity::in,
-    list(pred_id)::out) is semidet.
-
-    % Search the table for predicates or functions matching this pred_or_func
-    % category, module, name, and arity. When searching for functions, the
-    % arity used is the arity of the predicate that the function gets converted
-    % to, i.e. the arity of the function plus one.
-    % NB. This is opposite to what happens with the search predicates
-    % declared above!!
-    %
-:- pred predicate_table_search_pf_m_n_a(predicate_table::in,
-    is_fully_qualified::in, pred_or_func::in, module_name::in, string::in,
-    arity::in, list(pred_id)::out) is semidet.
-
-    % Search the table for predicates or functions matching this pred_or_func
-    % category, name, and arity. When searching for functions, the arity used
-    % is the arity of the predicate that the function gets converted to,
-    % i.e. the arity of the function plus one.
-    % NB. This is opposite to what happens with the search predicates
-    % declared above!!
-    %
-:- pred predicate_table_search_pf_name_arity(predicate_table::in,
-    pred_or_func::in, string::in, arity::in, list(pred_id)::out)
-    is semidet.
-
-    % Search the table for predicates or functions matching this pred_or_func
-    % category, sym_name, and arity. When searching for functions, the arity
-    % used is the arity of the predicate that the function gets converted to,
-    % i.e. the arity of the function plus one.
-    % NB. This is opposite to what happens with the search predicates
-    % declared above!!
-    %
-:- pred predicate_table_search_pf_sym_arity(predicate_table::in,
-    is_fully_qualified::in, pred_or_func::in, sym_name::in, arity::in,
-    list(pred_id)::out) is semidet.
-
-    % Search the table for predicates or functions matching
-    % this pred_or_func category and sym_name.
-    %
-:- pred predicate_table_search_pf_sym(predicate_table::in,
-    is_fully_qualified::in, pred_or_func::in, sym_name::in,
-    list(pred_id)::out) is semidet.
-
-    % predicate_table_insert(PredTable0, PredInfo,
-    %   NeedQual, PartialQualInfo, PredId, PredTable):
-    %
-    % Insert PredInfo into PredTable0 and assign it a new pred_id.
-    % You should check beforehand that the pred doesn't already
-    % occur in the table.
-    %
-:- pred predicate_table_insert(pred_info::in, need_qualifier::in,
-    partial_qualifier_info::in, pred_id::out,
-    predicate_table::in, predicate_table::out) is det.
-
-    % Equivalent to predicate_table_insert/6, except that only the
-    % fully-qualified version of the predicate will be inserted into the
-    % predicate symbol table. This is useful for creating % compiler-generated
-    % predicates which will only ever be accessed via fully-qualified names.
-    %
-:- pred predicate_table_insert(pred_info::in, pred_id::out,
-    predicate_table::in, predicate_table::out) is det.
-
-:- pred predicate_id(module_info::in, pred_id::in, module_name::out,
-    string::out, arity::out) is det.
-
-:- pred predicate_module(module_info::in, pred_id::in, module_name::out)
-    is det.
-:- pred predicate_name(module_info::in, pred_id::in, string::out) is det.
-:- pred predicate_arity(module_info::in, pred_id::in, arity::out) is det.
-
-    % Find a predicate which matches the given name and argument types.
-    % Abort if there is no matching pred.
-    % Abort if there are multiple matching preds.
-    % 
-:- pred resolve_pred_overloading(module_info::in, pred_markers::in,
-    list(mer_type)::in, tvarset::in, sym_name::in, sym_name::out, pred_id::out)
-    is det.
-
-    % Find a predicate or function from the list of pred_ids which matches the
-    % given name and argument types.  If the constraint_search argument is
-    % provided then also check that the class context is consistent with what
-    % is expected.  Fail if there is no matching pred.  Abort if there are
-    % multiple matching preds.
-    %
-:- pred find_matching_pred_id(module_info::in, list(pred_id)::in, tvarset::in,
-    list(mer_type)::in, maybe(constraint_search)::in(maybe(constraint_search)),
-    pred_id::out, sym_name::out) is semidet.
-
-    % A means to check that the required constraints are available, without
-    % knowing in advance how many are required.
-    %
-:- type constraint_search == pred(int, list(prog_constraint)).
-:- inst constraint_search == (pred(in, out) is semidet).
-
-    % Get the pred_id and proc_id matching a higher-order term with
-    % the given argument types, aborting with an error if none is found.
-    %
-:- pred get_pred_id_and_proc_id(is_fully_qualified::in, sym_name::in,
-    pred_or_func::in, tvarset::in, list(mer_type)::in, module_info::in,
-    pred_id::out, proc_id::out) is det.
-
-    % Get the pred_id matching a higher-order term with
-    % the given argument types, failing if none is found.
-    %
-:- pred get_pred_id(is_fully_qualified::in, sym_name::in, pred_or_func::in,
-    tvarset::in, list(mer_type)::in, module_info::in, pred_id::out) is semidet.
-
-    % Given a pred_id, return the single proc_id, aborting
-    % if there are no modes or more than one mode.
-    %
-:- pred get_proc_id(module_info::in, pred_id::in, proc_id::out) is det.
-
-:- type mode_no
-    --->    only_mode           % The pred must have exactly one mode.
-    ;       mode_no(int).       % The Nth mode, counting from 0.
-
-:- pred lookup_builtin_pred_proc_id(module_info::in, module_name::in,
-    string::in, pred_or_func::in, arity::in, mode_no::in,
-    pred_id::out, proc_id::out) is det.
-
-%-----------------------------------------------------------------------------%
-
-:- implementation.
-
-:- type predicate_table
-    --->    predicate_table(
-                preds               :: pred_table,
-                                    % Map from pred_id to pred_info.
-
-                next_pred_id        :: pred_id,
-                                    % The next available pred_id.
-
-                pred_ids            :: list(pred_id),
-                                    % The keys of the pred_table - cached
-                                    % here for efficiency.
-
-                accessibility_table :: accessibility_table,
-                                    % How is the predicate accessible?
-
-                % Indexes on predicates
-
-                pred_name_index     :: name_index,
-                                    % Map from pred name to pred_id.
-
-                pred_name_arity_index :: name_arity_index,
-                                    % Map from pred name & arity to pred_id.
-
-                pred_module_name_arity_index :: module_name_arity_index,
-                                    % Map from pred module, name & arity
-                                    % to pred_id.
-
-                % Indexes on functions
-
-                func_name_index     :: name_index,
-                                    % Map from func name to pred_id.
-
-                func_name_arity_index :: name_arity_index,
-                                    % Map from func name & arity to pred_id.
-
-                func_module_name_arity_index :: module_name_arity_index
-                                    % Map from func module, name & arity
-                                    % to pred_id.
-            ).
-
-:- type accessibility_table == map(pred_id, name_accessibility).
-
-:- type name_accessibility
-    --->    access(
-                % Is this predicate accessible by its unqualified name.
-                accessible_by_unqualifed_name       :: bool,
-
-                % Is this predicate accessible by any partially qualified
-                % names.
-                accessible_by_partially_qualified_names :: bool
-            ).
-
-:- type name_index  == map(string, list(pred_id)).
-
-:- type name_arity_index == map(name_arity, list(pred_id)).
-:- type name_arity ---> string / arity.
-
-    % First search on module and name, then search on arity. The two levels
-    % are needed because typecheck.m needs to be able to search on module
-    % and name only for higher-order terms.
-:- type module_name_arity_index ==
-    map(pair(module_name, string), map(arity, list(pred_id))).
-
-predicate_table_init(PredicateTable) :-
-    PredicateTable = predicate_table(Preds, NextPredId, PredIds,
-        AccessibilityTable,
-        Pred_N_Index, Pred_NA_Index, Pred_MNA_Index,
-        Func_N_Index, Func_NA_Index, Func_MNA_Index),
-    map.init(Preds),
-    NextPredId = hlds_pred.initial_pred_id,
-    PredIds = [],
-    map.init(AccessibilityTable),
-    map.init(Pred_N_Index),
-    map.init(Pred_NA_Index),
-    map.init(Pred_MNA_Index),
-    map.init(Func_N_Index),
-    map.init(Func_NA_Index),
-    map.init(Func_MNA_Index).
-
-predicate_table_optimize(PredicateTable0, PredicateTable) :-
-    PredicateTable0 = predicate_table(A, B, C, D,
-        Pred_N_Index0, Pred_NA_Index0, Pred_MNA_Index0,
-        Func_N_Index0, Func_NA_Index0, Func_MNA_Index0),
-    map.optimize(Pred_N_Index0, Pred_N_Index),
-    map.optimize(Pred_NA_Index0, Pred_NA_Index),
-    map.optimize(Pred_MNA_Index0, Pred_MNA_Index),
-    map.optimize(Func_N_Index0, Func_N_Index),
-    map.optimize(Func_NA_Index0, Func_NA_Index),
-    map.optimize(Func_MNA_Index0, Func_MNA_Index),
-    PredicateTable = predicate_table(A, B, C, D,
-        Pred_N_Index, Pred_NA_Index, Pred_MNA_Index,
-        Func_N_Index, Func_NA_Index, Func_MNA_Index).
-
-predicate_table_get_preds(PredicateTable, PredicateTable ^ preds).
-
-predicate_table_set_preds(Preds, PredicateTable,
-    PredicateTable ^ preds := Preds).
-
-predicate_table_get_predids(PredicateTable, PredicateTable ^ pred_ids).
-
-predicate_table_remove_predid(PredId, PredicateTable0, PredicateTable) :-
-    list.delete_all(PredicateTable0 ^ pred_ids, PredId, PredIds),
-    PredicateTable = PredicateTable0 ^ pred_ids := PredIds.
-
-predicate_table_remove_predicate(PredId, PredicateTable0, PredicateTable) :-
-    PredicateTable0 = predicate_table(Preds0, NextPredId, PredIds0,
-        AccessibilityTable0,
-        PredN0, PredNA0, PredMNA0, FuncN0, FuncNA0, FuncMNA0),
-    list.delete_all(PredIds0, PredId, PredIds),
-    map.det_remove(Preds0, PredId, PredInfo, Preds),
-    map.det_remove(AccessibilityTable0, PredId, _, AccessibilityTable),
-    Module = pred_info_module(PredInfo),
-    Name = pred_info_name(PredInfo),
-    Arity = pred_info_orig_arity(PredInfo),
-    IsPredOrFunc = pred_info_is_pred_or_func(PredInfo),
-    (
-        IsPredOrFunc = predicate,
-        predicate_table_remove_from_index(Module, Name, Arity, PredId,
-            PredN0, PredN, PredNA0, PredNA, PredMNA0, PredMNA),
-        PredicateTable = predicate_table(Preds, NextPredId, PredIds,
-            AccessibilityTable,
-            PredN, PredNA, PredMNA, FuncN0, FuncNA0, FuncMNA0)
-    ;
-        IsPredOrFunc = function,
-        FuncArity = Arity - 1,
-        predicate_table_remove_from_index(Module, Name, FuncArity,
-            PredId, FuncN0, FuncN, FuncNA0, FuncNA,
-            FuncMNA0, FuncMNA),
-        PredicateTable = predicate_table(Preds, NextPredId, PredIds,
-            AccessibilityTable,
-            PredN0, PredNA0, PredMNA0, FuncN, FuncNA, FuncMNA)
-    ).
-
-:- pred predicate_table_remove_from_index(module_name::in, string::in, int::in,
-    pred_id::in, name_index::in, name_index::out,
-    name_arity_index::in, name_arity_index::out,
-    module_name_arity_index::in, module_name_arity_index::out) is det.
-
-predicate_table_remove_from_index(Module, Name, Arity, PredId,
-        !N, !NA, !MNA) :-
-    do_remove_from_index(Name, PredId, !N),
-    do_remove_from_index(Name / Arity, PredId, !NA),
-    do_remove_from_m_n_a_index(Module, Name, Arity, PredId, !MNA).
-
-:- pred do_remove_from_index(T::in, pred_id::in,
-    map(T, list(pred_id))::in, map(T, list(pred_id))::out) is det.
-
-do_remove_from_index(T, PredId, Index0, Index) :-
-    ( map.search(Index0, T, NamePredIds0) ->
-        list.delete_all(NamePredIds0, PredId, NamePredIds),
-        (
-            NamePredIds = [],
-            map.delete(Index0, T, Index)
-        ;
-            NamePredIds = [_ | _],
-            map.det_update(Index0, T, NamePredIds, Index)
-        )
-    ;
-        Index = Index0
-    ).
-
-:- pred do_remove_from_m_n_a_index(module_name::in, string::in, int::in,
-    pred_id::in, module_name_arity_index::in, module_name_arity_index::out)
-    is det.
-
-do_remove_from_m_n_a_index(Module, Name, Arity, PredId, MNA0, MNA) :-
-    map.lookup(MNA0, Module - Name, Arities0),
-    map.lookup(Arities0, Arity, PredIds0),
-    list.delete_all(PredIds0, PredId, PredIds),
-    (
-        PredIds = [],
-        map.delete(Arities0, Arity, Arities),
-        ( map.is_empty(Arities) ->
-            map.delete(MNA0, Module - Name, MNA)
-        ;
-            map.det_update(MNA0, Module - Name, Arities, MNA)
-        )
-    ;
-        PredIds = [_ | _],
-        map.det_update(Arities0, Arity, PredIds, Arities),
-        map.det_update(MNA0, Module - Name, Arities, MNA)
-    ).
-
-%-----------------------------------------------------------------------------%
-
-:- pred predicate_table_reverse_predids(predicate_table::in,
-    predicate_table::out) is det.
-
-predicate_table_reverse_predids(PredicateTable0, PredicateTable) :-
-    list.reverse(PredicateTable0 ^ pred_ids, PredIds),
-    PredicateTable = PredicateTable0 ^ pred_ids := PredIds.
-
-%-----------------------------------------------------------------------------%
-
-predicate_table_search_sym(PredicateTable, may_be_partially_qualified,
-        unqualified(Name), PredIdList) :-
-    predicate_table_search_name(PredicateTable, Name, PredIdList).
-predicate_table_search_sym(PredicateTable, IsFullyQualified,
-        qualified(Module, Name), PredIdList) :-
-    predicate_table_search_module_name(PredicateTable, IsFullyQualified,
-        Module, Name, PredIdList),
-    PredIdList = [_ | _].
-
-predicate_table_search_pred_sym(PredicateTable, may_be_partially_qualified,
-        unqualified(Name), PredIdList) :-
-    predicate_table_search_pred_name(PredicateTable, Name, PredIdList).
-predicate_table_search_pred_sym(PredicateTable, IsFullyQualified,
-        qualified(Module, Name), PredIdList) :-
-    predicate_table_search_pred_module_name(PredicateTable,
-        IsFullyQualified, Module, Name, PredIdList),
-    PredIdList = [_ | _].
-
-predicate_table_search_func_sym(PredicateTable, may_be_partially_qualified,
-        unqualified(Name), PredIdList) :-
-    predicate_table_search_func_name(PredicateTable, Name, PredIdList).
-predicate_table_search_func_sym(PredicateTable, IsFullyQualified,
-        qualified(Module, Name), PredIdList) :-
-    predicate_table_search_func_module_name(PredicateTable,
-        IsFullyQualified, Module, Name, PredIdList),
-    PredIdList = [_ | _].
-
-%-----------------------------------------------------------------------------%
-
-predicate_table_search_sym_arity(PredicateTable, IsFullyQualified,
-        qualified(Module, Name), Arity, PredIdList) :-
-    predicate_table_search_m_n_a(PredicateTable,
-        IsFullyQualified, Module, Name, Arity, PredIdList).
-predicate_table_search_sym_arity(PredicateTable, may_be_partially_qualified,
-        unqualified(Name), Arity, PredIdList) :-
-    predicate_table_search_name_arity(PredicateTable, Name, Arity, PredIdList).
-
-predicate_table_search_pred_sym_arity(PredicateTable, IsFullyQualified,
-        qualified(Module, Name), Arity, PredIdList) :-
-    predicate_table_search_pred_m_n_a(PredicateTable,
-        IsFullyQualified, Module, Name, Arity, PredIdList).
-predicate_table_search_pred_sym_arity(PredicateTable,
-        may_be_partially_qualified, unqualified(Name),
-        Arity, PredIdList) :-
-    predicate_table_search_pred_name_arity(PredicateTable, Name, Arity,
-        PredIdList).
-
-predicate_table_search_func_sym_arity(PredicateTable, IsFullyQualified,
-        qualified(Module, Name), Arity, PredIdList) :-
-    predicate_table_search_func_m_n_a(PredicateTable,
-        IsFullyQualified, Module, Name, Arity, PredIdList).
-predicate_table_search_func_sym_arity(PredicateTable,
-        may_be_partially_qualified, unqualified(Name),
-        Arity, PredIdList) :-
-    predicate_table_search_func_name_arity(PredicateTable, Name, Arity,
-        PredIdList).
-
-%-----------------------------------------------------------------------------%
-
-predicate_table_search_name(PredicateTable, Name, PredIds) :-
-    ( predicate_table_search_pred_name(PredicateTable, Name, PredPredIds0) ->
-        PredPredIds = PredPredIds0
-    ;
-        PredPredIds = []
-    ),
-    ( predicate_table_search_func_name(PredicateTable, Name, FuncPredIds0) ->
-        FuncPredIds = FuncPredIds0
-    ;
-        FuncPredIds = []
-    ),
-    list.append(FuncPredIds, PredPredIds, PredIds),
-    PredIds = [_ | _].
-
-predicate_table_search_pred_name(PredicateTable, PredName, PredIds) :-
-    map.search(PredicateTable ^ pred_name_index, PredName, PredIds).
-
-predicate_table_search_func_name(PredicateTable, FuncName, PredIds) :-
-    map.search(PredicateTable ^ func_name_index, FuncName, PredIds).
-
-%-----------------------------------------------------------------------------%
-
-:- pred predicate_table_search_module_name(predicate_table::in,
-    is_fully_qualified::in, module_name::in, string::in,
-    list(pred_id)::out) is semidet.
-
-predicate_table_search_module_name(PredicateTable, IsFullyQualified,
-        Module, Name, PredIds) :-
-    (
-        predicate_table_search_pred_module_name(PredicateTable,
-            IsFullyQualified, Module, Name, PredPredIds0)
-    ->
-        PredPredIds = PredPredIds0
-    ;
-        PredPredIds = []
-    ),
-    (
-        predicate_table_search_func_module_name(PredicateTable,
-            IsFullyQualified, Module, Name, FuncPredIds0)
-    ->
-        FuncPredIds = FuncPredIds0
-    ;
-        FuncPredIds = []
-    ),
-    list.append(FuncPredIds, PredPredIds, PredIds),
-    PredIds = [_ | _].
-
-:- pred predicate_table_search_pred_module_name(predicate_table::in,
-    is_fully_qualified::in, module_name::in, string::in,
-    list(pred_id)::out) is semidet.
-
-predicate_table_search_pred_module_name(PredicateTable, IsFullyQualified,
-        Module, PredName, PredIds) :-
-    Pred_MNA_Index = PredicateTable ^ pred_module_name_arity_index,
-    map.search(Pred_MNA_Index, Module - PredName, Arities),
-    map.values(Arities, PredIdLists),
-    list.condense(PredIdLists, PredIds0),
-    maybe_filter_pred_ids_matching_module(IsFullyQualified,
-        Module, PredicateTable, PredIds0, PredIds).
-
-:- pred predicate_table_search_func_module_name(predicate_table::in,
-    is_fully_qualified::in, module_name::in, string::in,
-    list(pred_id)::out) is semidet.
-
-predicate_table_search_func_module_name(PredicateTable, IsFullyQualified,
-        Module, FuncName, PredIds) :-
-    Func_MNA_Index = PredicateTable ^ func_module_name_arity_index,
-    map.search(Func_MNA_Index, Module - FuncName, Arities),
-    map.values(Arities, PredIdLists),
-    list.condense(PredIdLists, PredIds0),
-    maybe_filter_pred_ids_matching_module(IsFullyQualified,
-        Module, PredicateTable, PredIds0, PredIds).
-
-%-----------------------------------------------------------------------------%
-
-predicate_table_search_name_arity(PredicateTable, Name, Arity, PredIds) :-
-    (
-        predicate_table_search_pred_name_arity(PredicateTable,
-            Name, Arity, PredPredIds0)
-    ->
-        PredPredIds = PredPredIds0
-    ;
-        PredPredIds = []
-    ),
-    (
-        predicate_table_search_func_name_arity(PredicateTable,
-            Name, Arity, FuncPredIds0)
-    ->
-        FuncPredIds = FuncPredIds0
-    ;
-        FuncPredIds = []
-    ),
-    list.append(FuncPredIds, PredPredIds, PredIds),
-    PredIds = [_ | _].
-
-predicate_table_search_pred_name_arity(PredicateTable, PredName, Arity,
-        PredIds) :-
-    PredNameArityIndex = PredicateTable ^ pred_name_arity_index,
-    map.search(PredNameArityIndex, PredName / Arity, PredIds).
-
-predicate_table_search_func_name_arity(PredicateTable, FuncName, Arity,
-        PredIds) :-
-    FuncNameArityIndex = PredicateTable ^ func_name_arity_index,
-    map.search(FuncNameArityIndex, FuncName / Arity, PredIds).
-
-%-----------------------------------------------------------------------------%
-
-predicate_table_search_m_n_a(PredicateTable, IsFullyQualified,
-        Module, Name, Arity, PredIds) :-
-    (
-        predicate_table_search_pred_m_n_a(PredicateTable,
-            IsFullyQualified, Module, Name, Arity, PredPredIds0)
-    ->
-        PredPredIds = PredPredIds0
-    ;
-        PredPredIds = []
-    ),
-    (
-        predicate_table_search_func_m_n_a(PredicateTable,
-            IsFullyQualified, Module, Name, Arity, FuncPredIds0)
-    ->
-        FuncPredIds = FuncPredIds0
-    ;
-        FuncPredIds = []
-    ),
-    list.append(FuncPredIds, PredPredIds, PredIds),
-    PredIds = [_ | _].
-
-predicate_table_search_pred_m_n_a(PredicateTable, IsFullyQualified,
-        Module, PredName, Arity, !:PredIds) :-
-    P_MNA_Index = PredicateTable ^ pred_module_name_arity_index,
-    map.search(P_MNA_Index, Module - PredName, ArityIndex),
-    map.search(ArityIndex, Arity, !:PredIds),
-    maybe_filter_pred_ids_matching_module(IsFullyQualified, Module,
-        PredicateTable, !PredIds).
-
-predicate_table_search_func_m_n_a(PredicateTable, IsFullyQualified,
-        Module, FuncName, Arity, !:PredIds) :-
-    F_MNA_Index = PredicateTable ^ func_module_name_arity_index,
-    map.search(F_MNA_Index, Module - FuncName, ArityIndex),
-    map.search(ArityIndex, Arity, !:PredIds),
-    maybe_filter_pred_ids_matching_module(IsFullyQualified, Module,
-        PredicateTable, !PredIds).
-
-:- pred maybe_filter_pred_ids_matching_module(is_fully_qualified::in,
-    module_name::in, predicate_table::in, list(pred_id)::in,
-    list(pred_id)::out) is det.
-
-maybe_filter_pred_ids_matching_module(may_be_partially_qualified, _, _,
-        !PredIds).
-maybe_filter_pred_ids_matching_module(is_fully_qualified, ModuleName,
-        PredicateTable, !PredIds) :-
-    predicate_table_get_preds(PredicateTable, Preds),
-    list.filter(pred_id_matches_module(Preds, ModuleName), !PredIds).
-
-:- pred pred_id_matches_module(pred_table::in, module_name::in, pred_id::in)
-    is semidet.
-
-pred_id_matches_module(Preds, ModuleName, PredId) :-
-    map.lookup(Preds, PredId, PredInfo),
-    ModuleName = pred_info_module(PredInfo).
-
-%-----------------------------------------------------------------------------%
-
-predicate_table_search_pf_m_n_a(PredicateTable, IsFullyQualified,
-        predicate, Module, Name, Arity, PredIds) :-
-    predicate_table_search_pred_m_n_a(PredicateTable, IsFullyQualified,
-        Module, Name, Arity, PredIds).
-predicate_table_search_pf_m_n_a(PredicateTable, IsFullyQualified,
-        function, Module, Name, Arity, PredIds) :-
-    FuncArity = Arity - 1,
-    predicate_table_search_func_m_n_a(PredicateTable, IsFullyQualified,
-        Module, Name, FuncArity, PredIds).
-
-predicate_table_search_pf_name_arity(PredicateTable, predicate, Name, Arity,
-        PredIds) :-
-    predicate_table_search_pred_name_arity(PredicateTable, Name, Arity,
-        PredIds).
-predicate_table_search_pf_name_arity(PredicateTable, function, Name, Arity,
-        PredIds) :-
-    FuncArity = Arity - 1,
-    predicate_table_search_func_name_arity(PredicateTable, Name, FuncArity,
-        PredIds).
-
-predicate_table_search_pf_sym_arity(PredicateTable, IsFullyQualified,
-        PredOrFunc, qualified(Module, Name), Arity, PredIdList) :-
-    predicate_table_search_pf_m_n_a(PredicateTable,
-        IsFullyQualified, PredOrFunc,
-        Module, Name, Arity, PredIdList).
-predicate_table_search_pf_sym_arity(PredicateTable, may_be_partially_qualified,
-        PredOrFunc, unqualified(Name), Arity, PredIdList) :-
-    predicate_table_search_pf_name_arity(PredicateTable, PredOrFunc,
-        Name, Arity, PredIdList).
-
-predicate_table_search_pf_sym(PredicateTable, IsFullyQualified, predicate,
-        SymName, PredIdList) :-
-    predicate_table_search_pred_sym(PredicateTable, IsFullyQualified,
-        SymName, PredIdList).
-predicate_table_search_pf_sym(PredicateTable, IsFullyQualified,
-        function, SymName, PredIdList) :-
-    predicate_table_search_func_sym(PredicateTable, IsFullyQualified,
-        SymName, PredIdList).
-
-%-----------------------------------------------------------------------------%
-
-predicate_table_restrict(PartialQualInfo, PredIds, OrigPredicateTable,
-        PredicateTable) :-
-    predicate_table_reset(OrigPredicateTable, PredicateTable0),
-    predicate_table_get_preds(OrigPredicateTable, Preds),
-    AccessibilityTable = OrigPredicateTable ^ accessibility_table,
-
-    % Note that we use foldr here rather than foldl, so that the PredIds list
-    % in the predicate table is the same as the PredIds list argument here
-    % (if we used foldl, it would get reversed, since each new predicate
-    % inserted into the table gets its pred_id added at the start of the list).
-    list.foldr(reinsert_for_restrict(PartialQualInfo, Preds,
-        AccessibilityTable), PredIds, PredicateTable0, PredicateTable).
-
-:- pred reinsert_for_restrict(partial_qualifier_info::in, pred_table::in,
-    accessibility_table::in, pred_id::in,
-    predicate_table::in, predicate_table::out) is det.
-
-reinsert_for_restrict(PartialQualInfo, Preds, AccessibilityTable, PredId,
-        !Table) :-
-    PredInfo = map.lookup(Preds, PredId),
-    Access = map.lookup(AccessibilityTable, PredId),
-    Access = access(Unqualified, PartiallyQualified),
-    (
-        Unqualified = yes,
-        NeedQual = may_be_unqualified
-    ;
-        Unqualified = no,
-        NeedQual = must_be_qualified
-    ),
-    (
-        PartiallyQualified = yes,
-        MaybeQualInfo = yes(PartialQualInfo)
-    ;
-        PartiallyQualified = no,
-        MaybeQualInfo = no
-    ),
-    predicate_table_insert_2(yes(PredId), PredInfo,
-        NeedQual, MaybeQualInfo, _, !Table).
-
-:- pred predicate_table_reset(predicate_table::in, predicate_table::out)
-    is det.
-
-predicate_table_reset(PredicateTable0, PredicateTable) :-
-    NextPredId = PredicateTable0 ^ next_pred_id,
-    PredicateTable = predicate_table(map.init, NextPredId, [], map.init,
-        map.init, map.init, map.init, map.init, map.init, map.init).
-
-%-----------------------------------------------------------------------------%
-
-predicate_table_insert(PredInfo, PredId, !PredicateTable) :-
-    predicate_table_insert_2(no, PredInfo, must_be_qualified, no, PredId,
-        !PredicateTable).
-
-predicate_table_insert(PredInfo, NeedQual, QualInfo, PredId,
-        !PredicateTable) :-
-    predicate_table_insert_2(no, PredInfo, NeedQual, yes(QualInfo), PredId,
-        !PredicateTable).
-
-:- pred predicate_table_insert_2(maybe(pred_id)::in, pred_info::in,
-    need_qualifier::in, maybe(partial_qualifier_info)::in, pred_id::out,
-    predicate_table::in, predicate_table::out) is det.
-
-predicate_table_insert_2(MaybePredId, PredInfo, NeedQual, MaybeQualInfo,
-        PredId, !PredicateTable) :-
-
-    !.PredicateTable = predicate_table(Preds0, NextPredId0, PredIds0,
-        AccessibilityTable0,
-        Pred_N_Index0, Pred_NA_Index0, Pred_MNA_Index0,
-        Func_N_Index0, Func_NA_Index0, Func_MNA_Index0),
-    Module = pred_info_module(PredInfo),
-    Name = pred_info_name(PredInfo),
-    Arity = pred_info_orig_arity(PredInfo),
-    (
-        MaybePredId = yes(PredId),
-        NextPredId = NextPredId0
-    ;
-        % Allocate a new pred_id.
-        MaybePredId = no,
-        PredId = NextPredId0,
-        hlds_pred.next_pred_id(PredId, NextPredId)
-    ),
-    % Insert the pred_id into either the function or predicate indices,
-    % as appropriate.
-    PredOrFunc = pred_info_is_pred_or_func(PredInfo),
-    (
-        PredOrFunc = predicate,
-        predicate_table_do_insert(Module, Name, Arity,
-            NeedQual, MaybeQualInfo, PredId,
-            AccessibilityTable0, AccessibilityTable,
-            Pred_N_Index0, Pred_N_Index,
-            Pred_NA_Index0, Pred_NA_Index,
-            Pred_MNA_Index0, Pred_MNA_Index),
-
-        Func_N_Index = Func_N_Index0,
-        Func_NA_Index = Func_NA_Index0,
-        Func_MNA_Index = Func_MNA_Index0
-    ;
-        PredOrFunc = function,
-        FuncArity = Arity - 1,
-        predicate_table_do_insert(Module, Name, FuncArity,
-            NeedQual, MaybeQualInfo, PredId,
-            AccessibilityTable0, AccessibilityTable,
-            Func_N_Index0, Func_N_Index,
-            Func_NA_Index0, Func_NA_Index,
-            Func_MNA_Index0, Func_MNA_Index),
-
-        Pred_N_Index = Pred_N_Index0,
-        Pred_NA_Index = Pred_NA_Index0,
-        Pred_MNA_Index = Pred_MNA_Index0
-    ),
-
-    % Insert the pred_id into the pred_id list.
-    PredIds = [PredId | PredIds0],
-
-    % Save the pred_info for this pred_id.
-    map.det_insert(Preds0, PredId, PredInfo, Preds),
-
-    !:PredicateTable = predicate_table(Preds, NextPredId, PredIds,
-        AccessibilityTable,
-        Pred_N_Index, Pred_NA_Index, Pred_MNA_Index,
-        Func_N_Index, Func_NA_Index, Func_MNA_Index).
-
-:- pred predicate_table_do_insert(module_name::in, string::in, arity::in,
-    need_qualifier::in, maybe(partial_qualifier_info)::in, pred_id::in,
-    accessibility_table::in, accessibility_table::out,
-    name_index::in, name_index::out,
-    name_arity_index::in, name_arity_index::out,
-    module_name_arity_index::in, module_name_arity_index::out) is det.
-
-predicate_table_do_insert(Module, Name, Arity, NeedQual, MaybeQualInfo,
-        PredId, !AccessibilityTable, !N_Index, !NA_Index, !MNA_Index) :-
-    (
-        NeedQual = may_be_unqualified,
-        % Insert the unqualified name into the name index.
-        svmulti_map.set(Name, PredId, !N_Index),
-
-        % Insert the unqualified name/arity into the name/arity index.
-        NA = Name / Arity,
-        svmulti_map.set(NA, PredId, !NA_Index),
-
-        AccessibleByUnqualifiedName = yes
-    ;
-        NeedQual = must_be_qualified,
-        AccessibleByUnqualifiedName = no
-    ),
-    (
-        MaybeQualInfo = yes(QualInfo),
-
-        % Insert partially module-qualified versions of the name into the
-        % module.name/arity index.
-        get_partial_qualifiers(Module, QualInfo, PartialQuals),
-        list.foldl((pred(AncModule::in, MNAs0::in, MNAs::out) is det :-
-                insert_into_mna_index(AncModule, Name, Arity, PredId,
-                    MNAs0, MNAs)
-            ), PartialQuals, !MNA_Index),
-
-        AccessibleByPartiallyQualifiedNames = yes
-    ;
-        MaybeQualInfo = no,
-        AccessibleByPartiallyQualifiedNames = no
-    ),
-    % Insert the fully-qualified name into the module.name/arity index.
-    insert_into_mna_index(Module, Name, Arity, PredId, !MNA_Index),
-    Access = access(AccessibleByUnqualifiedName,
-        AccessibleByPartiallyQualifiedNames),
-    svmap.set(PredId, Access, !AccessibilityTable).
-
-:- pred insert_into_mna_index(module_name::in, string::in, arity::in,
-    pred_id::in, module_name_arity_index::in,
-    module_name_arity_index::out) is det.
-
-insert_into_mna_index(Module, Name, Arity, PredId, !MNA_Index) :-
-    ( map.search(!.MNA_Index, Module - Name, MN_Arities0) ->
-        multi_map.set(MN_Arities0, Arity, PredId, MN_Arities),
-        svmap.det_update(Module - Name, MN_Arities, !MNA_Index)
-    ;
-        map.init(MN_Arities0),
-        map.det_insert(MN_Arities0, Arity, [PredId], MN_Arities),
-        svmap.det_insert(Module - Name, MN_Arities, !MNA_Index)
-    ).
-
-%-----------------------------------------------------------------------------%
-
-resolve_pred_overloading(ModuleInfo, CallerMarkers, ArgTypes, TVarSet,
-        PredName0, PredName, PredId) :-
-    % Note: calls to preds declared in `.opt' files should always be
-    % module qualified, so they should not be considered
-    % when resolving overloading.
-
-    module_info_get_predicate_table(ModuleInfo, PredTable),
-    (
-        predicate_table_search_pred_sym(PredTable,
-            calls_are_fully_qualified(CallerMarkers), PredName0, PredIds0)
-    ->
-        PredIds = PredIds0
-    ;
-        PredIds = []
-    ),
-
-    % Check if there any of the candidate pred_ids have argument/return types
-    % which subsume the actual argument/return types of this function call.
-    (
-        find_matching_pred_id(ModuleInfo, PredIds, TVarSet, ArgTypes,
-            no, PredId1, PredName1)
-    ->
-        PredId = PredId1,
-        PredName = PredName1
-    ;
-        % If there is no matching predicate for this call, then this predicate
-        % must have a type error which should have been caught by typechecking.
-        unexpected(this_file, "type error in pred call: no matching pred")
-    ).
-
-find_matching_pred_id(ModuleInfo, [PredId | PredIds], TVarSet, ArgTypes,
-        MaybeConstraintSearch, ThePredId, PredName) :-
-    (
-        % Lookup the argument types of the candidate predicate
-        % (or the argument types + return type of the candidate function).
-        %
-        module_info_pred_info(ModuleInfo, PredId, PredInfo),
-        pred_info_arg_types(PredInfo, PredTVarSet, PredExistQVars0,
-            PredArgTypes0),
-        pred_info_tvar_kinds(PredInfo, PredKindMap),
-
-        arg_type_list_subsumes(TVarSet, ArgTypes, PredTVarSet, PredKindMap,
-            PredExistQVars0, PredArgTypes0),
-
-        (
-            MaybeConstraintSearch = no
-        ;
-            MaybeConstraintSearch = yes(ConstraintSearch),
-            % Lookup the universal constraints on the condidate predicate.
-            pred_info_get_class_context(PredInfo, ProgConstraints),
-            ProgConstraints = constraints(UnivConstraints, _),
-            list.length(UnivConstraints, NumConstraints),
-            ConstraintSearch(NumConstraints, ProvenConstraints),
-            univ_constraints_match(ProvenConstraints, UnivConstraints)
-        )
-    ->
-        % We've found a matching predicate.
-        % Was there was more than one matching predicate/function?
-
-        PName = pred_info_name(PredInfo),
-        Module = pred_info_module(PredInfo),
-        PredName = qualified(Module, PName),
-        (
-            find_matching_pred_id(ModuleInfo, PredIds, TVarSet, ArgTypes,
-                MaybeConstraintSearch, _OtherPredId, _)
-        ->
-            % XXX this should report an error properly, not
-            % via error/1
-            unexpected(this_file, "Type error in predicate call: " ++
-                "unresolvable predicate overloading. " ++
-                "You need to use an explicit module qualifier. " ++
-                "Compile with -V to find out where.")
-        ;
-            ThePredId = PredId
-        )
-    ;
-        find_matching_pred_id(ModuleInfo, PredIds, TVarSet, ArgTypes,
-            MaybeConstraintSearch, ThePredId, PredName)
-    ).
-
-    % Check that the universal constraints proven in the caller match the
-    % constraints on the callee.
-    %
-    % XXX we should rename apart the callee constraints and check that the
-    % proven constraints are instances of them.  This would give us better
-    % overloading resolution.  For the moment, we just check that the names
-    % and arities match, which is sufficient to prevent any compiler aborts
-    % in later stages.
-    %
-:- pred univ_constraints_match(list(prog_constraint)::in,
-    list(prog_constraint)::in) is semidet.
-
-univ_constraints_match([], []).
-univ_constraints_match([ProvenConstraint | ProvenConstraints],
-        [CalleeConstraint | CalleeConstraints]) :-
-    ProvenConstraint = constraint(Name, ProvenArgs),
-    list.length(ProvenArgs, Arity),
-    CalleeConstraint = constraint(Name, CalleeArgs),
-    list.length(CalleeArgs, Arity),
-    univ_constraints_match(ProvenConstraints, CalleeConstraints).
-
-get_pred_id(IsFullyQualified, SymName, PredOrFunc, TVarSet,
-        ArgTypes, ModuleInfo, PredId) :-
-    module_info_get_predicate_table(ModuleInfo, PredicateTable),
-    list.length(ArgTypes, Arity),
-    (
-        predicate_table_search_pf_sym_arity(PredicateTable, IsFullyQualified,
-            PredOrFunc, SymName, Arity, PredIds),
-        % Resolve overloading using the argument types.
-        find_matching_pred_id(ModuleInfo, PredIds, TVarSet, ArgTypes, no,
-            PredId0, _PredName)
-    ->
-        PredId = PredId0
-    ;
-        % Undefined/invalid pred or func.
-        fail
-    ).
-
-get_pred_id_and_proc_id(IsFullyQualified, SymName, PredOrFunc, TVarSet,
-        ArgTypes, ModuleInfo, PredId, ProcId) :-
-    (
-        get_pred_id(IsFullyQualified, SymName, PredOrFunc, TVarSet,
-            ArgTypes, ModuleInfo, PredId0)
-    ->
-        PredId = PredId0
-    ;
-        % Undefined/invalid pred or func. The type-checker should ensure
-        % that this never happens
-        list.length(ArgTypes, Arity),
-        PredOrFuncStr = prog_out.pred_or_func_to_str(PredOrFunc),
-        mdbcomp.prim_data.sym_name_to_string(SymName, Name2),
-        string.int_to_string(Arity, ArityString),
-        string.append_list(["get_pred_id_and_proc_id: ",
-            "undefined/invalid ", PredOrFuncStr,
-            "\n`", Name2, "/", ArityString, "'"], Msg),
-        unexpected(this_file, Msg)
-    ),
-    get_proc_id(ModuleInfo, PredId, ProcId).
-
-get_proc_id(ModuleInfo, PredId, ProcId) :-
-    module_info_pred_info(ModuleInfo, PredId, PredInfo),
-    ProcIds = pred_info_procids(PredInfo),
-    ( ProcIds = [ProcId0] ->
-        ProcId = ProcId0
-    ;
-        Name = pred_info_name(PredInfo),
-        PredOrFunc = pred_info_is_pred_or_func(PredInfo),
-        Arity = pred_info_orig_arity(PredInfo),
-        PredOrFuncStr = prog_out.pred_or_func_to_str(PredOrFunc),
-        string.int_to_string(Arity, ArityString),
-        (
-            ProcIds = [],
-            string.append_list([
-                "cannot take address of ", PredOrFuncStr,
-                "\n`", Name, "/", ArityString, "' with no modes.\n",
-                "(Sorry, confused by earlier errors -- bailing out.)"],
-                Message)
-        ;
-            ProcIds = [_ | _],
-            string.append_list([
-                "sorry, not implemented: ",
-                "taking address of ", PredOrFuncStr,
-                "\n`", Name, "/", ArityString, "' with multiple modes.\n",
-                "(use an explicit lambda expression instead)"],
-                Message)
-        ),
-        unexpected(this_file, Message)
-    ).
-
-lookup_builtin_pred_proc_id(Module, ModuleName, ProcName, PredOrFunc,
-        Arity, ModeNo, PredId, ProcId) :-
-    module_info_get_predicate_table(Module, PredTable),
-    (
-        (
-            PredOrFunc = predicate,
-            predicate_table_search_pred_m_n_a(PredTable, is_fully_qualified,
-                ModuleName, ProcName, Arity, [PredId0])
-        ;
-            PredOrFunc = function,
-            predicate_table_search_func_m_n_a(PredTable, is_fully_qualified,
-                ModuleName, ProcName, Arity, [PredId0])
-        )
-    ->
-        PredId = PredId0
-    ;
-        % Some of the table builtins are polymorphic, and for them we need
-        % to subtract one from the arity to take into account the type_info
-        % argument. XXX The caller should supply us with the exact arity.
-        % Guessing how many of the arguments are typeinfos and/or
-        % typeclass_infos, as this code here does, is error-prone as well as
-        % inefficient.
-        (
-            PredOrFunc = predicate,
-            predicate_table_search_pred_m_n_a(PredTable, is_fully_qualified,
-                ModuleName, ProcName, Arity - 1, [PredId0])
-        ;
-            PredOrFunc = function,
-            predicate_table_search_func_m_n_a(PredTable, is_fully_qualified,
-                ModuleName, ProcName, Arity - 1, [PredId0])
-        )
-    ->
-        PredId = PredId0
-    ;
-        string.int_to_string(Arity, ArityS),
-        string.append_list(["can't locate ", ProcName, "/", ArityS],
-            ErrorMessage),
-        unexpected(this_file, ErrorMessage)
-    ),
-    module_info_pred_info(Module, PredId, PredInfo),
-    ProcIds = pred_info_procids(PredInfo),
-    (
-        ModeNo = only_mode,
-        ( ProcIds = [ProcId0] ->
-            ProcId = ProcId0
-        ;
-            unexpected(this_file,
-                string.format("expected single mode for %s/%d",
-                    [s(ProcName), i(Arity)]))
-        )
-    ;
-        ModeNo = mode_no(N),
-        ( list.index0(ProcIds, N, ProcId0) ->
-            ProcId = ProcId0
-        ;
-            unexpected(this_file,
-                string.format("there is no mode %d for %s/%d",
-                    [i(N), s(ProcName), i(Arity)]))
-        )
-    ).
-
-%-----------------------------------------------------------------------------%
-
-predicate_id(ModuleInfo, PredId, ModuleName, PredName, Arity) :-
-    module_info_preds(ModuleInfo, Preds),
-    map.lookup(Preds, PredId, PredInfo),
-    ModuleName = pred_info_module(PredInfo),
-    PredName = pred_info_name(PredInfo),
-    Arity = pred_info_orig_arity(PredInfo).
-
-predicate_module(ModuleInfo, PredId, ModuleName) :-
-    module_info_preds(ModuleInfo, Preds),
-    map.lookup(Preds, PredId, PredInfo),
-    ModuleName = pred_info_module(PredInfo).
-
-predicate_name(ModuleInfo, PredId, PredName) :-
-    module_info_preds(ModuleInfo, Preds),
-    map.lookup(Preds, PredId, PredInfo),
-    PredName = pred_info_name(PredInfo).
-
-predicate_arity(ModuleInfo, PredId, Arity) :-
-    module_info_preds(ModuleInfo, Preds),
-    map.lookup(Preds, PredId, PredInfo),
-    Arity = pred_info_orig_arity(PredInfo).
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.386
diff -u -b -r1.386 hlds_out.m
--- compiler/hlds_out.m	21 Mar 2006 22:25:26 -0000	1.386
+++ compiler/hlds_out.m	22 Mar 2006 04:00:50 -0000
@@ -32,6 +32,7 @@
 :- module hlds.hlds_out.
 :- interface.
 
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
@@ -261,6 +262,8 @@
 :- import_module check_hlds.type_util.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_llds.
+:- import_module hlds.hlds_rtti.
+:- import_module hlds.pred_table.
 :- import_module hlds.instmap.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
@@ -1178,8 +1181,8 @@
 
 write_clause_head(ModuleInfo, PredId, VarSet, AppendVarNums, HeadTerms,
         PredOrFunc, !IO) :-
-    predicate_name(ModuleInfo, PredId, PredName),
-    predicate_module(ModuleInfo, PredId, ModuleName),
+    PredName = predicate_name(ModuleInfo, PredId),
+    ModuleName = predicate_module(ModuleInfo, PredId),
     (
         PredOrFunc = function,
         pred_args_to_func_args(HeadTerms, FuncArgs, RetVal),
@@ -3635,7 +3638,7 @@
     ),
 
     write_indent(Indent, !IO),
-    predicate_name(ModuleInfo, PredId, PredName),
+    PredName = predicate_name(ModuleInfo, PredId),
     PredOrFunc = pred_info_is_pred_or_func(PredInfo),
     varset.init(ModeVarSet),
     (
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.193
diff -u -b -r1.193 hlds_pred.m
--- compiler/hlds_pred.m	9 Mar 2006 04:56:34 -0000	1.193
+++ compiler/hlds_pred.m	22 Mar 2006 05:28:17 -0000
@@ -19,14 +19,16 @@
 
 :- import_module check_hlds.mode_constraint_robdd.
 :- import_module check_hlds.mode_errors.
-:- import_module check_hlds.mode_errors.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_llds.
 :- import_module hlds.hlds_module.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.inst_graph.
-:- import_module hlds.special_pred.
 :- import_module hlds.instmap.
+:- import_module hlds.pred_table.
+:- import_module hlds.special_pred.
 :- import_module libs.globals.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
@@ -47,6 +49,7 @@
 :- import_module check_hlds.type_util.
 :- import_module hlds.goal_form.
 :- import_module hlds.goal_util.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.make_hlds.
 :- import_module libs.compiler_util.
 :- import_module libs.options.
@@ -136,868 +139,8 @@
 
 :- type pred_proc_list  ==  list(pred_proc_id).
 
-:- type prog_var_name == string.
-
-    % The rtti_proc_label type holds all the information about a procedure
-    % that we need to compute the entry label for that procedure
-    % in the target language (the llds.code_addr or mlds.code_addr).
-
-:- type rtti_proc_label
-    --->    rtti_proc_label(
-                pred_or_func            ::  pred_or_func,
-                this_module             ::  module_name,
-                proc_module             ::  module_name,
-                proc_name               ::  string,
-                proc_arity              ::  arity,
-                proc_arg_types          ::  list(mer_type),
-                pred_id                 ::  pred_id,
-                proc_id                 ::  proc_id,
-                proc_headvars           ::  assoc_list(prog_var,
-                                                prog_var_name),
-                proc_arg_modes          ::  list(arg_mode),
-                proc_interface_detism   ::  determinism,
-
-                % The following booleans hold values computed from the
-                % pred_info, using procedures
-                %   pred_info_is_imported/1,
-                %   pred_info_is_pseudo_imported/1,
-                %   pred_info_get_origin/1
-                % respectively.
-                % We store booleans here, rather than storing the
-                % pred_info, to avoid retaining a reference to the
-                % parts of the pred_info that we aren't interested in,
-                % so that those parts can be garbage collected.
-                % We use booleans rather than an import_status
-                % so that we can continue to use the above-mentioned
-                % abstract interfaces rather than hard-coding tests
-                % on the import_status.
-
-                pred_is_imported        ::  bool,
-                pred_is_pseudo_imported ::  bool,
-                pred_info_origin        ::  pred_origin,
-
-                % The following boolean holds a value computed from the
-                % proc_info, using procedure_is_exported/2
-
-                proc_is_exported        ::  bool,
-
-                % The following bool is true if the procedure was
-                % imported, either because the containing predicate
-                % was imported, or because it was pseudoimported
-                % and the procedure is an in-in unify procedure.
-
-                proc_is_imported        ::  bool
-            ).
-
-%-----------------------------------------------------------------------------%
-%
-% Types and predicates to store information about RTTI.
-%
-
-    % Describes the class constraints on an instance method implementation.
-    % This information is used by polymorphism.m to ensure that the
-    % type_info and typeclass_info arguments are added in the order in
-    % which they will be passed in by do_call_class_method.
-    %
-:- type instance_method_constraints
-    --->    instance_method_constraints(
-                class_id,
-                list(mer_type),         % The types in the head of the
-                                        % instance declaration.
-                list(prog_constraint),  % The universal constraints
-                                        % on the instance declaration.
-                prog_constraints        % The contraints on the method's
-                                        % type declaration in the
-                                        % `:- typeclass' declaration.
-            ).
-
-    %  A type_info_locn specifies how to access a type_info.
-    %
-:- type type_info_locn
-    --->    type_info(prog_var)
-                % It is a normal type_info, i.e. the type
-                % is not constrained.
-
-    ;       typeclass_info(prog_var, int).
-                % The type_info is packed inside a
-                % typeclass_info. If the int is N, it is
-                % the Nth type_info inside the typeclass_info,
-                % but there may be several superclass pointers
-                % before the block of type_infos, so it won't
-                % be the Nth word of the typeclass_info.
-                %
-                % To find the type_info inside the
-                % typeclass_info, use the predicate
-                % type_info_from_typeclass_info from Mercury
-                % code; from C code use the macro
-                % 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,
-    type_info_locn::in, type_info_locn::out) is det.
-
-    % This type describes the contents of a prog_var.
-    %
-:- type rtti_var_info
-    --->    type_info_var(mer_type)
-            % The variable holds a type_info for the given type.
-
-    ;       typeclass_info_var(prog_constraint)
-            % The variable holds a typeclass_info for the given
-            % constraint.
-
-    ;       non_rtti_var.
-            % The variable does not directly hold any run time
-            % type information.
-
-    % This records information about how type_infos and typeclass_infos
-    % were introduced in the polymorphism transformation.
-    %
-:- type rtti_varmaps.
-
-    % Returns an empty rtti_varmaps structure.
-    %
-:- pred rtti_varmaps_init(rtti_varmaps::out) is det.
-
-    % Succeeds iff the rtti_varmaps contain no information about any
-    % type variables.
-    %
-:- pred rtti_varmaps_no_tvars(rtti_varmaps::in) is semidet.
-
-    % Find the location of a type_info.
-    %
-:- pred rtti_lookup_type_info_locn(rtti_varmaps::in, tvar::in,
-    type_info_locn::out) is det.
-
-    % Find the location of a type_info, if it is known.
-    %
-:- pred rtti_search_type_info_locn(rtti_varmaps::in, tvar::in,
-    type_info_locn::out) is semidet.
-
-    % Find the prog_var which contains the typeclass_info for a given
-    % constraint and which can be reused.
-    %
-:- pred rtti_lookup_typeclass_info_var(rtti_varmaps::in, prog_constraint::in,
-    prog_var::out) is det.
-
-    % Find the prog_var which contains the typeclass_info for a given
-    % constraint and which can be reused, if it is known.
-    %
-:- pred rtti_search_typeclass_info_var(rtti_varmaps::in, prog_constraint::in,
-    prog_var::out) is semidet.
-
-    % Find what RTTI, if any, is stored in a prog_var.
-    %
-:- pred rtti_varmaps_var_info(rtti_varmaps::in, prog_var::in,
-    rtti_var_info::out) is det.
-
-    % Insert the location of a type_info.  Abort if such information
-    % already exists.
-    %
-:- pred rtti_det_insert_type_info_locn(tvar::in, type_info_locn::in,
-    rtti_varmaps::in, rtti_varmaps::out) is det.
-
-    % Set the location of a type_info, overwriting any previous
-    % information.
-    %
-:- pred rtti_set_type_info_locn(tvar::in, type_info_locn::in,
-    rtti_varmaps::in, rtti_varmaps::out) is det.
-
-    % Insert the prog_var which contains the typeclass_info for a
-    % given constraint.  Abort if such information already exists.
-    %
-:- pred rtti_det_insert_typeclass_info_var(prog_constraint::in, prog_var::in,
-    rtti_varmaps::in, rtti_varmaps::out) is det.
-
-    % Set the prog_var which contains the typeclass_info for a given
-    % constraint, overwriting any previous information.
-    %
-:- pred rtti_set_typeclass_info_var(prog_constraint::in, prog_var::in,
-    rtti_varmaps::in, rtti_varmaps::out) is det.
-
-    % Make the given typeclass_info var available for reuse in later
-    % goals.  Abort if we know nothing about this variable.
-    %
-:- pred rtti_reuse_typeclass_info_var(prog_var::in,
-    rtti_varmaps::in, rtti_varmaps::out) is det.
-
-    % For a prog_var which holds a type_info, set the type that the
-    % type_info is for.  Abort if such information already exists.
-    %
-:- pred rtti_det_insert_type_info_type(prog_var::in, mer_type::in,
-    rtti_varmaps::in, rtti_varmaps::out) is det.
-
-    % For a prog_var which holds a type_info, set the type that the
-    % type_info is for, overwriting any previous information.
-    %
-:- pred rtti_set_type_info_type(prog_var::in, mer_type::in,
-    rtti_varmaps::in, rtti_varmaps::out) is det.
-
-    % rtti_var_info_duplicate(Var, NewVar, !RttiVarMaps)
-    %
-    % Duplicate the rtti_var_info we have about Var for NewVar.
-    %
-:- pred rtti_var_info_duplicate(prog_var::in, prog_var::in,
-    rtti_varmaps::in, rtti_varmaps::out) is det.
-
-    % Returns all of the tvars that we have information about in the
-    % rtti_varmaps structure.
-    %
-:- pred rtti_varmaps_tvars(rtti_varmaps::in, list(tvar)::out) is det.
-
-    % Returns all of the types that we have information about in the
-    % rtti_varmaps structure, including those types which appear in the
-    % arguments of constraints.
-    %
-:- pred rtti_varmaps_types(rtti_varmaps::in, list(mer_type)::out) is det.
-
-    % Returns all of the prog_constraints which have typeclass_infos
-    % stored in a prog_var we can reuse.
-    %
-:- pred rtti_varmaps_reusable_constraints(rtti_varmaps::in,
-    list(prog_constraint)::out) is det.
-
-    % Returns all of the prog_vars which are known to contain a type_info
-    % or typeclass_info.
-    %
-:-  pred rtti_varmaps_rtti_prog_vars(rtti_varmaps::in, list(prog_var)::out)
-    is det.
-
-    % apply_substitutions_to_rtti_varmaps(TRenaming, TSubst, Subst,
-    %   !RttiVarMaps)
-    %
-    % Apply substitutions to the rtti_varmaps data.  TRenaming is applied
-    % to all types first, then TSubst is applied to all types.  Subst
-    % is applied to all prog_vars.
-    %
-:- pred apply_substitutions_to_rtti_varmaps(tvar_renaming::in, tsubst::in,
-    map(prog_var, prog_var)::in, rtti_varmaps::in, rtti_varmaps::out)
-    is det.
-
-    % rtti_varmaps_transform_types(Pred, !RttiVarMaps)
-    %
-    % Apply the transformation predicate to every type appearing in the
-    % rtti_varmaps structure, including those in the arguments of constraints.
-    %
-:- pred rtti_varmaps_transform_types(
-    pred(mer_type, mer_type)::in(pred(in, out) is det),
-    rtti_varmaps::in, rtti_varmaps::out) is det.
-
-    % rtti_varmaps_overlay(A, B, C)
-    %
-    % Merge the information in rtti_varmaps A and B to produce C.  Where
-    % information conflicts, use the information in B rather than A.
-    %
-:- pred rtti_varmaps_overlay(rtti_varmaps::in,
-    rtti_varmaps::in, rtti_varmaps::out) is det.
-
-%-----------------------------------------------------------------------------%
-
-:- implementation.
-
-type_info_locn_var(type_info(Var), Var).
-type_info_locn_var(typeclass_info(Var, _), Var).
-
-type_info_locn_set_var(Var, type_info(_), type_info(Var)).
-type_info_locn_set_var(Var, typeclass_info(_, Num), typeclass_info(Var, Num)).
-
-:- type rtti_varmaps
-    --->    rtti_varmaps(
-                tci_varmap          :: typeclass_info_varmap,
-                ti_varmap           :: type_info_varmap,
-                ti_type_map         :: type_info_type_map,
-                tci_constraint_map  :: typeclass_info_constraint_map
-            ).
-
-    % A typeclass_info_varmap is a map which for each type class constraint
-    % records which variable contains the typeclass_info for that
-    % constraint.  The constraints covered by this map are those which
-    % are passed in as head arguments and those which are produced as
-    % existential constraints from calls or deconstructions.  These are
-    % the constraints for which it is safe to reuse the variable associated
-    % with the constraint.
-    %
-:- type typeclass_info_varmap == map(prog_constraint, prog_var).
-
-    % A type_info_varmap is a map which for each type variable
-    % records where the type_info for that type variable is stored.
-    %
-    % XXX this doesn't record the information that we want.  For a
-    % constraint such as foo(list(T)) we can't properly record the
-    % location of the type_info for T, since it does not occupy a slot
-    % in the typeclass_info directly, but is inside the type_info for
-    % list(T).
-    %
-:- type type_info_varmap == map(tvar, type_info_locn).
-
-    % Every program variable which holds a type_info is a key in this
-    % map.  The value associated with a given key is the type that the
-    % type_info is for.
-    %
-:- type type_info_type_map == map(prog_var, mer_type).
-
-    % Every program variable which holds a typeclass_info is a key in this
-    % map.  The value associated with a given key is the prog_constraint
-    % that the typeclass_info is for.
-    %
-:- type typeclass_info_constraint_map == map(prog_var, prog_constraint).
-
-rtti_varmaps_init(rtti_varmaps(TCIMap, TIMap, TypeMap, ConstraintMap)) :-
-    map.init(TCIMap),
-    map.init(TIMap),
-    map.init(TypeMap),
-    map.init(ConstraintMap).
-
-rtti_varmaps_no_tvars(VarMaps) :-
-    map.is_empty(VarMaps ^ ti_varmap).
-
-rtti_lookup_type_info_locn(VarMaps, TVar, Locn) :-
-    map.lookup(VarMaps ^ ti_varmap, TVar, Locn).
-
-rtti_search_type_info_locn(VarMaps, TVar, Locn) :-
-    map.search(VarMaps ^ ti_varmap, TVar, Locn).
-
-rtti_lookup_typeclass_info_var(VarMaps, Constraint, ProgVar) :-
-    map.lookup(VarMaps ^ tci_varmap, Constraint, ProgVar).
-
-rtti_search_typeclass_info_var(VarMaps, Constraint, ProgVar) :-
-    map.search(VarMaps ^ tci_varmap, Constraint, ProgVar).
-
-rtti_varmaps_var_info(VarMaps, Var, VarInfo) :-
-    ( map.search(VarMaps ^ ti_type_map, Var, Type) ->
-        VarInfo = type_info_var(Type)
-    ; map.search(VarMaps ^ tci_constraint_map, Var, Constraint) ->
-        VarInfo = typeclass_info_var(Constraint)
-    ;
-        VarInfo = non_rtti_var
-    ).
-
-rtti_det_insert_type_info_locn(TVar, Locn, !VarMaps) :-
-    Map0 = !.VarMaps ^ ti_varmap,
-    map.det_insert(Map0, TVar, Locn, Map),
-    !:VarMaps = !.VarMaps ^ ti_varmap := Map,
-    maybe_check_type_info_var(Locn, TVar, !VarMaps).
-
-rtti_set_type_info_locn(TVar, Locn, !VarMaps) :-
-    Map0 = !.VarMaps ^ ti_varmap,
-    map.set(Map0, TVar, Locn, Map),
-    !:VarMaps = !.VarMaps ^ ti_varmap := Map,
-    maybe_check_type_info_var(Locn, TVar, !VarMaps).
-
-:- pred maybe_check_type_info_var(type_info_locn::in, tvar::in,
-    rtti_varmaps::in, rtti_varmaps::out) is det.
-
-maybe_check_type_info_var(type_info(Var), TVar, !VarMaps) :-
-    ( map.search(!.VarMaps ^ ti_type_map, Var, Type) ->
-        ( Type = variable(TVar, _) ->
-            true
-        ;
-            unexpected(this_file, "inconsistent info in rtti_varmaps")
-        )
-    ;
-        unexpected(this_file, "missing info in rtti_varmaps")
-    ).
-maybe_check_type_info_var(typeclass_info(_, _), _, !VarMaps).
-
-rtti_det_insert_typeclass_info_var(Constraint, ProgVar, !VarMaps) :-
-    Map0 = !.VarMaps ^ tci_constraint_map,
-    map.det_insert(Map0, ProgVar, Constraint, Map),
-    !:VarMaps = !.VarMaps ^ tci_constraint_map := Map.
-
-rtti_set_typeclass_info_var(Constraint, ProgVar, !VarMaps) :-
-    Map0 = !.VarMaps ^ tci_constraint_map,
-    map.set(Map0, ProgVar, Constraint, Map),
-    !:VarMaps = !.VarMaps ^ tci_constraint_map := Map.
-
-rtti_reuse_typeclass_info_var(ProgVar, !VarMaps) :-
-    ( map.search(!.VarMaps ^ tci_constraint_map, ProgVar, Constraint) ->
-        Map0 = !.VarMaps ^ tci_varmap,
-        map.set(Map0, Constraint, ProgVar, Map),
-        !:VarMaps = !.VarMaps ^ tci_varmap := Map
-    ;
-        unexpected(this_file,
-            "rtti_reuse_typeclass_info_var: variable not known")
-    ).
-
-rtti_det_insert_type_info_type(ProgVar, Type, !VarMaps) :-
-    Map0 = !.VarMaps ^ ti_type_map,
-    map.det_insert(Map0, ProgVar, Type, Map),
-    !:VarMaps = !.VarMaps ^ ti_type_map := Map.
-
-rtti_set_type_info_type(ProgVar, Type, !VarMaps) :-
-    Map0 = !.VarMaps ^ ti_type_map,
-    map.set(Map0, ProgVar, Type, Map),
-    !:VarMaps = !.VarMaps ^ ti_type_map := Map.
-
-rtti_var_info_duplicate(Var, NewVar, !VarMaps) :-
-    rtti_varmaps_var_info(!.VarMaps, Var, VarInfo),
-    (
-        VarInfo = type_info_var(Type),
-        rtti_det_insert_type_info_type(NewVar, Type, !VarMaps)
-    ;
-        VarInfo = typeclass_info_var(Constraint),
-        rtti_det_insert_typeclass_info_var(Constraint, NewVar, !VarMaps)
-    ;
-        VarInfo = non_rtti_var
-    ).
-
-rtti_varmaps_tvars(VarMaps, TVars) :-
-    map.keys(VarMaps ^ ti_varmap, TVars).
-
-rtti_varmaps_types(VarMaps, Types) :-
-    solutions(rtti_varmaps_is_known_type(VarMaps), Types).
-
-:- pred rtti_varmaps_is_known_type(rtti_varmaps::in, mer_type::out) is nondet.
-
-rtti_varmaps_is_known_type(VarMaps, Type) :-
-    map.values(VarMaps ^ ti_type_map, Types),
-    list.member(Type, Types).
-rtti_varmaps_is_known_type(VarMaps, Type) :-
-    map.values(VarMaps ^ tci_constraint_map, Constraints),
-    list.member(constraint(_, Types), Constraints),
-    list.member(Type, Types).
-
-rtti_varmaps_reusable_constraints(VarMaps, Constraints) :-
-    map.keys(VarMaps ^ tci_varmap, Constraints).
-
-rtti_varmaps_rtti_prog_vars(VarMaps, Vars) :-
-    map.keys(VarMaps ^ ti_type_map, TIVars),
-    map.keys(VarMaps ^ tci_constraint_map, TCIVars),
-    list.append(TIVars, TCIVars, Vars).
-
-apply_substitutions_to_rtti_varmaps(TRenaming, TSubst, Subst, !RttiVarMaps) :-
-    (
-        % Optimize the simple case.
-        map.is_empty(Subst),
-        map.is_empty(TSubst),
-        map.is_empty(TRenaming)
-    ->
-        true
-    ;
-        !.RttiVarMaps = rtti_varmaps(TCIMap0, TIMap0, TypeMap0,
-            ConstraintMap0),
-        map.foldl(apply_substs_to_tci_map(TRenaming, TSubst, Subst),
-            TCIMap0, map.init, TCIMap),
-        map.foldl(apply_substs_to_ti_map(TRenaming, TSubst, Subst),
-            TIMap0, map.init, TIMap),
-        map.foldl(apply_substs_to_type_map(TRenaming, TSubst, Subst),
-            TypeMap0, map.init, TypeMap),
-        map.foldl(apply_substs_to_constraint_map(TRenaming, TSubst, Subst),
-            ConstraintMap0, map.init, ConstraintMap),
-        !:RttiVarMaps = rtti_varmaps(TCIMap, TIMap, TypeMap, ConstraintMap)
-    ).
-
-:- pred apply_subst_to_prog_var(map(prog_var, prog_var)::in,
-    prog_var::in, prog_var::out) is det.
-
-apply_subst_to_prog_var(Subst, Var0, Var) :-
-    ( map.search(Subst, Var0, Var1) ->
-        Var = Var1
-    ;
-        Var = Var0
-    ).
-
-:- pred apply_substs_to_tci_map(tvar_renaming::in, tsubst::in,
-    map(prog_var, prog_var)::in, prog_constraint::in, prog_var::in,
-    typeclass_info_varmap::in, typeclass_info_varmap::out) is det.
-
-apply_substs_to_tci_map(TRenaming, TSubst, Subst, Constraint0, Var0, !Map) :-
-    apply_variable_renaming_to_prog_constraint(TRenaming, Constraint0,
-        Constraint1),
-    apply_rec_subst_to_prog_constraint(TSubst, Constraint1, Constraint),
-    apply_subst_to_prog_var(Subst, Var0, Var),
-    svmap.set(Constraint, Var, !Map).
-
-    % Update a map entry from tvar to type_info_locn, using the type renaming
-    % and substitution to rename tvars and a variable substitution to rename
-    % vars. The type renaming is applied before the type substitution.
-    %
-    % If tvar maps to a another type variable, we keep the new variable, if
-    % it maps to a type, we remove it from the map.
-    %
-:- pred apply_substs_to_ti_map(tvar_renaming::in, tsubst::in,
-    map(prog_var, prog_var)::in, tvar::in, type_info_locn::in,
-    type_info_varmap::in, type_info_varmap::out) is det.
-
-apply_substs_to_ti_map(TRenaming, TSubst, Subst, TVar, Locn, !Map) :-
-    type_info_locn_var(Locn, Var),
-    apply_subst_to_prog_var(Subst, Var, NewVar),
-    type_info_locn_set_var(NewVar, Locn, NewLocn),
-    apply_variable_renaming_to_tvar(TRenaming, TVar, NewTVar1),
-    % We don't use the correct kinds here, but that doesn't matter because
-    % the resulting kind will be thrown away anyway.
-    apply_rec_subst_to_tvar(map.init, TSubst, NewTVar1, NewType),
-    (
-        % If the tvar is still a variable, insert it into the map with the
-        % new var.
-        NewType = variable(NewTVar, _)
-    ->
-        % Don't abort if two old type variables map to the same new type
-        % variable.
-        svmap.set(NewTVar, NewLocn, !Map)
-    ;
-        true
-    ).
-
-:- pred apply_substs_to_type_map(tvar_renaming::in, tsubst::in,
-    map(prog_var, prog_var)::in, prog_var::in, mer_type::in,
-    type_info_type_map::in, type_info_type_map::out) is det.
-
-apply_substs_to_type_map(TRenaming, TSubst, Subst, Var0, Type0, !Map) :-
-    apply_variable_renaming_to_type(TRenaming, Type0, Type1),
-    apply_rec_subst_to_type(TSubst, Type1, Type),
-    apply_subst_to_prog_var(Subst, Var0, Var),
-    ( map.search(!.Map, Var, ExistingType) ->
-        ( Type = ExistingType ->
-            true
-        ;
-            unexpected(this_file, "inconsistent type_infos")
-        )
-    ;
-        svmap.det_insert(Var, Type, !Map)
-    ).
-
-:- pred apply_substs_to_constraint_map(tvar_renaming::in, tsubst::in,
-    map(prog_var, prog_var)::in, prog_var::in, prog_constraint::in,
-    typeclass_info_constraint_map::in, typeclass_info_constraint_map::out)
-    is det.
-
-apply_substs_to_constraint_map(TRenaming, TSubst, Subst, Var0, Constraint0,
-        !Map) :-
-    apply_variable_renaming_to_prog_constraint(TRenaming, Constraint0,
-        Constraint1),
-    apply_rec_subst_to_prog_constraint(TSubst, Constraint1, Constraint),
-    apply_subst_to_prog_var(Subst, Var0, Var),
-    ( map.search(!.Map, Var, ExistingConstraint) ->
-        ( Constraint = ExistingConstraint ->
-            true
-        ;
-            unexpected(this_file, "inconsistent typeclass_infos")
-        )
-    ;
-        svmap.det_insert(Var, Constraint, !Map)
-    ).
-
-rtti_varmaps_transform_types(Pred, !RttiVarMaps) :-
-    TciMap0 = !.RttiVarMaps ^ tci_varmap,
-    TypeMap0 = !.RttiVarMaps ^ ti_type_map,
-    ConstraintMap0 = !.RttiVarMaps ^ tci_constraint_map,
-    map.foldl(apply_constraint_key_transformation(Pred), TciMap0,
-    map.init, TciMap),
-    Pred2 = (pred(_::in, V::in, W::out) is det :-
-            Pred(V, W)
-    ),
-    map.map_values(Pred2, TypeMap0, TypeMap),
-    map.map_values(apply_constraint_value_transformation(Pred),
-        ConstraintMap0, ConstraintMap),
-    !:RttiVarMaps = !.RttiVarMaps ^ tci_varmap := TciMap,
-    !:RttiVarMaps = !.RttiVarMaps ^ ti_type_map := TypeMap,
-    !:RttiVarMaps = !.RttiVarMaps ^ tci_constraint_map := ConstraintMap.
-
-:- pred apply_constraint_key_transformation(
-    pred(mer_type, mer_type)::in(pred(in, out) is det),
-    prog_constraint::in, prog_var::in,
-    typeclass_info_varmap::in, typeclass_info_varmap::out) is det.
-
-apply_constraint_key_transformation(Pred, Constraint0, Var, !Map) :-
-    Constraint0 = constraint(Name, Args0),
-    list.map(Pred, Args0, Args),
-    Constraint = constraint(Name, Args),
-    svmap.set(Constraint, Var, !Map).
-
-:- pred apply_constraint_value_transformation(
-    pred(mer_type, mer_type)::in(pred(in, out) is det),
-    prog_var::in, prog_constraint::in, prog_constraint::out) is det.
-
-apply_constraint_value_transformation(Pred, _, Constraint0, Constraint) :-
-    Constraint0 = constraint(Name, Args0),
-    list.map(Pred, Args0, Args),
-    Constraint = constraint(Name, Args).
-
-rtti_varmaps_overlay(VarMapsA, VarMapsB, VarMaps) :-
-    VarMapsA = rtti_varmaps(TCImapA, TImapA, TypeMapA, ConstraintMapA),
-    VarMapsB = rtti_varmaps(TCImapB, TImapB, TypeMapB, ConstraintMapB),
-
-        % Prefer VarMapsB for this information.
-        %
-    map.overlay(TCImapA, TCImapB, TCImap),
-    map.overlay(TImapA, TImapB, TImap),
-
-        % On the other hand, we insist that this information is consistent.
-        %
-    map.merge(TypeMapA, TypeMapB, TypeMap),
-    map.merge(ConstraintMapA, ConstraintMapB, ConstraintMap),
-
-    VarMaps = rtti_varmaps(TCImap, TImap, TypeMap, ConstraintMap).
-
-%-----------------------------------------------------------------------------%
-
-:- interface.
-
-    % The clauses_info structure contains the clauses for a predicate
-    % after conversion from the item_list by make_hlds.m.
-    % Typechecking is performed on the clauses info, then the clauses
-    % are copied to create the proc_info for each procedure.
-    % After mode analysis the clauses and the procedure goals are not
-    % guaranteed to be the same, and the clauses are only kept so that
-    % the optimized goal can be compared with the original in HLDS dumps.
-:- type clauses_info
-    --->    clauses_info(
-                varset                  :: prog_varset,
-
-                explicit_vartypes       :: vartypes,
-                                        % Variable types from explicit
-                                        % qualifications.
-
-                tvar_name_map           :: tvar_name_map,
-                                        % Map from variable name to type
-                                        % variable for the type variables
-                                        % occurring in the argument types.
-                                        % This is used to process explicit
-                                        % type qualifications.
-
-                vartypes                :: vartypes,
-                                        % Variable types inferred by
-                                        % typecheck.m.
-
-                headvars                :: list(prog_var),
-                                        % The head variables.
-
-                clauses_rep             :: clauses_rep,
-
-                clauses_rtti_varmaps    :: rtti_varmaps,
-                                        % This field is computed by
-                                        % polymorphism.m.
-
-                have_foreign_clauses    :: bool
-                                        % Do we have foreign language clauses?
-        ).
-
-:- pred clauses_info_init(int::in, clauses_info::out) is det.
-
-:- pred clauses_info_init_for_assertion(prog_vars::in, clauses_info::out)
-    is det.
-
-:- 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.
-
-:- pred clauses_info_varset(clauses_info::in, prog_varset::out) is det.
-
-    % 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_rtti_varmaps(clauses_info::in, rtti_varmaps::out) is det.
-
-:- pred clauses_info_headvars(clauses_info::in, list(prog_var)::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.
-
-:- 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.
-
-:- pred clauses_info_set_rtti_varmaps(rtti_varmaps::in,
-    clauses_info::in, clauses_info::out) is det.
-
-:- type clause
-    --->    clause(
-                applicable_procs    :: list(proc_id),
-                                    % Modes for which this clause applies
-                                    % ([] means it applies to all modes).
-
-                clause_body         :: hlds_goal,
-                clause_lang         :: implementation_language,
-                clause_context      :: prog_context
-            ).
-
 %-----------------------------------------------------------------------------%
 
-:- implementation.
-
-clauses_info_init(Arity, ClausesInfo) :-
-    map.init(VarTypes),
-    map.init(TVarNameMap),
-    varset.init(VarSet0),
-    make_n_fresh_vars("HeadVar__", Arity, HeadVars, VarSet0, VarSet),
-    rtti_varmaps_init(RttiVarMaps),
-    HasForeignClauses = no,
-    set_clause_list([], ClausesRep),
-    ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
-        HeadVars, ClausesRep, RttiVarMaps, HasForeignClauses).
-
-clauses_info_init_for_assertion(HeadVars, ClausesInfo) :-
-    map.init(VarTypes),
-    map.init(TVarNameMap),
-    varset.init(VarSet),
-    rtti_varmaps_init(RttiVarMaps),
-    HasForeignClauses = no,
-    set_clause_list([], ClausesRep),
-    ClausesInfo = clauses_info(VarSet, VarTypes, TVarNameMap, VarTypes,
-        HeadVars, ClausesRep, RttiVarMaps, HasForeignClauses).
-
-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_rtti_varmaps(CI, CI ^ clauses_rtti_varmaps).
-
-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_rtti_varmaps(X, CI, CI ^ clauses_rtti_varmaps := 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).
@@ -1888,7 +1031,7 @@
     UnprovenBodyConstraints = [],
 
     % The empty list of clauses is a little white lie.
-    Clauses = forw([]),
+    Clauses = init_clauses_rep,
     map.init(TVarNameMap),
     proc_info_rtti_varmaps(ProcInfo, RttiVarMaps),
     HasForeignClauses = no,
@@ -2658,20 +1801,6 @@
 :- pred proc_info_get_initial_instmap(proc_info::in, module_info::in,
     instmap::out) is det.
 
-    % For a set of variables V, find all the type variables in the types
-    % of the variables in V, and return set of typeinfo variables for
-    % those type variables. (find all typeinfos for variables in V).
-    %
-    % This set of typeinfos is often needed in liveness computation
-    % for accurate garbage collection - live variables need to have
-    % their typeinfos stay live too.
-    %
-:- pred proc_info_get_typeinfo_vars(set(prog_var)::in, vartypes::in,
-    rtti_varmaps::in, set(prog_var)::out) is det.
-
-:- pred proc_info_maybe_complete_with_typeinfo_vars(set(prog_var)::in,
-    bool::in, vartypes::in, rtti_varmaps::in, set(prog_var)::out) is det.
-
 :- pred proc_info_ensure_unique_names(proc_info::in, proc_info::out) is det.
 
     % Create a new variable of the given type to the procedure.
@@ -3187,63 +2316,6 @@
 proc_info_set_structure_sharing(Sharing, !ProcInfo) :- 
     !:ProcInfo = !.ProcInfo ^ proc_sub_info ^ maybe_structure_sharing :=
         yes(Sharing).
-
-proc_info_get_typeinfo_vars(Vars, VarTypes, RttiVarMaps, TypeInfoVars) :-
-    TVarMap = RttiVarMaps ^ ti_varmap,
-    set.to_sorted_list(Vars, VarList),
-    proc_info_get_typeinfo_vars_2(VarList, VarTypes, TVarMap, TypeInfoVarList),
-    set.list_to_set(TypeInfoVarList, TypeInfoVars).
-
-    % Auxiliary predicate - traverses variables and builds a list of
-    % variables that store typeinfos for these variables.
-    %
-:- pred proc_info_get_typeinfo_vars_2(list(prog_var)::in,
-    vartypes::in, type_info_varmap::in, list(prog_var)::out) is det.
-
-proc_info_get_typeinfo_vars_2([], _, _, []).
-proc_info_get_typeinfo_vars_2([Var | Vars], VarTypes, TVarMap, TypeInfoVars) :-
-    ( map.search(VarTypes, Var, Type) ->
-        prog_type.vars(Type, TypeVars),
-        (
-            TypeVars = [],
-            % Optimize common case,
-            proc_info_get_typeinfo_vars_2(Vars, VarTypes, TVarMap,
-                TypeInfoVars)
-        ;
-            TypeVars = [_ | _],
-            % XXX It's possible there are some complications with
-            % higher order pred types here -- if so, maybe
-            % treat them specially.
-
-            % The type_info is either stored in a variable, or in a
-            % typeclass_info. Either get the type_info variable or
-            % the typeclass_info variable.
-            LookupVar = (pred(TVar::in, TVarVar::out) is det :-
-                    map.lookup(TVarMap, TVar, Locn),
-                    type_info_locn_var(Locn, TVarVar)
-                ),
-            list.map(LookupVar, TypeVars, TypeInfoVars0),
-
-            proc_info_get_typeinfo_vars_2(Vars, VarTypes, TVarMap,
-                TypeInfoVars1),
-            list.append(TypeInfoVars0, TypeInfoVars1, TypeInfoVars)
-        )
-    ;
-        unexpected(this_file,
-            "proc_info_get_typeinfo_vars_2: var not found in typemap")
-    ).
-
-proc_info_maybe_complete_with_typeinfo_vars(Vars0, TypeInfoLiveness,
-        VarTypes, RttiVarMaps, Vars) :-
-    (
-        TypeInfoLiveness = yes,
-        proc_info_get_typeinfo_vars(Vars0, VarTypes, RttiVarMaps,
-            TypeInfoVars),
-        set.union(Vars0, TypeInfoVars, Vars)
-    ;
-        TypeInfoLiveness = no,
-        Vars = Vars0
-    ).
 
 proc_info_ensure_unique_names(!ProcInfo) :-
     proc_info_vartypes(!.ProcInfo, VarTypes),
Index: compiler/hlds_rtti.m
===================================================================
RCS file: compiler/hlds_rtti.m
diff -N compiler/hlds_rtti.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ compiler/hlds_rtti.m	22 Mar 2006 04:16:42 -0000
@@ -0,0 +1,727 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 1996-2006 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.
+%-----------------------------------------------------------------------------%
+%
+% File: hlds_rtti.m.
+% Main authors: Mark Brown.
+%
+% This module defines the part of the HLDS that deals with predicates
+% and procedures.
+%
+%-----------------------------------------------------------------------------%
+
+:- module hlds.hlds_rtti.
+:- interface.
+
+:- import_module hlds.hlds_pred.
+:- import_module mdbcomp.prim_data.
+:- import_module parse_tree.prog_data.
+
+:- import_module assoc_list.
+:- import_module bool.
+:- import_module list.
+:- import_module map.
+:- import_module set.
+
+:- type prog_var_name == string.
+
+    % The rtti_proc_label type holds all the information about a procedure
+    % that we need to compute the entry label for that procedure
+    % in the target language (the llds.code_addr or mlds.code_addr).
+
+:- type rtti_proc_label
+    --->    rtti_proc_label(
+                pred_or_func            ::  pred_or_func,
+                this_module             ::  module_name,
+                proc_module             ::  module_name,
+                proc_name               ::  string,
+                proc_arity              ::  arity,
+                proc_arg_types          ::  list(mer_type),
+                pred_id                 ::  pred_id,
+                proc_id                 ::  proc_id,
+                proc_headvars           ::  assoc_list(prog_var,
+                                                prog_var_name),
+                proc_arg_modes          ::  list(arg_mode),
+                proc_interface_detism   ::  determinism,
+
+                % The following booleans hold values computed from the
+                % pred_info, using procedures
+                %   pred_info_is_imported/1,
+                %   pred_info_is_pseudo_imported/1,
+                %   pred_info_get_origin/1
+                % respectively.
+                % We store booleans here, rather than storing the
+                % pred_info, to avoid retaining a reference to the
+                % parts of the pred_info that we aren't interested in,
+                % so that those parts can be garbage collected.
+                % We use booleans rather than an import_status
+                % so that we can continue to use the above-mentioned
+                % abstract interfaces rather than hard-coding tests
+                % on the import_status.
+
+                pred_is_imported        ::  bool,
+                pred_is_pseudo_imported ::  bool,
+                pred_info_origin        ::  pred_origin,
+
+                % The following boolean holds a value computed from the
+                % proc_info, using procedure_is_exported/2
+
+                proc_is_exported        ::  bool,
+
+                % The following bool is true if the procedure was
+                % imported, either because the containing predicate
+                % was imported, or because it was pseudoimported
+                % and the procedure is an in-in unify procedure.
+
+                proc_is_imported        ::  bool
+            ).
+
+%-----------------------------------------------------------------------------%
+%
+% Types and predicates to store information about RTTI.
+%
+
+    % Describes the class constraints on an instance method implementation.
+    % This information is used by polymorphism.m to ensure that the
+    % type_info and typeclass_info arguments are added in the order in
+    % which they will be passed in by do_call_class_method.
+    %
+:- type instance_method_constraints
+    --->    instance_method_constraints(
+                class_id,
+                list(mer_type),         % The types in the head of the
+                                        % instance declaration.
+                list(prog_constraint),  % The universal constraints
+                                        % on the instance declaration.
+                prog_constraints        % The contraints on the method's
+                                        % type declaration in the
+                                        % `:- typeclass' declaration.
+            ).
+
+    %  A type_info_locn specifies how to access a type_info.
+    %
+:- type type_info_locn
+    --->    type_info(prog_var)
+                % It is a normal type_info, i.e. the type
+                % is not constrained.
+
+    ;       typeclass_info(prog_var, int).
+                % The type_info is packed inside a
+                % typeclass_info. If the int is N, it is
+                % the Nth type_info inside the typeclass_info,
+                % but there may be several superclass pointers
+                % before the block of type_infos, so it won't
+                % be the Nth word of the typeclass_info.
+                %
+                % To find the type_info inside the
+                % typeclass_info, use the predicate
+                % type_info_from_typeclass_info from Mercury
+                % code; from C code use the macro
+                % 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,
+    type_info_locn::in, type_info_locn::out) is det.
+
+    % This type describes the contents of a prog_var.
+    %
+:- type rtti_var_info
+    --->    type_info_var(mer_type)
+            % The variable holds a type_info for the given type.
+
+    ;       typeclass_info_var(prog_constraint)
+            % The variable holds a typeclass_info for the given
+            % constraint.
+
+    ;       non_rtti_var.
+            % The variable does not directly hold any run time
+            % type information.
+
+    % This records information about how type_infos and typeclass_infos
+    % were introduced in the polymorphism transformation.
+    %
+:- type rtti_varmaps.
+
+    % Returns an empty rtti_varmaps structure.
+    %
+:- pred rtti_varmaps_init(rtti_varmaps::out) is det.
+
+    % Succeeds iff the rtti_varmaps contain no information about any
+    % type variables.
+    %
+:- pred rtti_varmaps_no_tvars(rtti_varmaps::in) is semidet.
+
+    % Find the location of a type_info.
+    %
+:- pred rtti_lookup_type_info_locn(rtti_varmaps::in, tvar::in,
+    type_info_locn::out) is det.
+
+    % Find the location of a type_info, if it is known.
+    %
+:- pred rtti_search_type_info_locn(rtti_varmaps::in, tvar::in,
+    type_info_locn::out) is semidet.
+
+    % Find the prog_var which contains the typeclass_info for a given
+    % constraint and which can be reused.
+    %
+:- pred rtti_lookup_typeclass_info_var(rtti_varmaps::in, prog_constraint::in,
+    prog_var::out) is det.
+
+    % Find the prog_var which contains the typeclass_info for a given
+    % constraint and which can be reused, if it is known.
+    %
+:- pred rtti_search_typeclass_info_var(rtti_varmaps::in, prog_constraint::in,
+    prog_var::out) is semidet.
+
+    % Find what RTTI, if any, is stored in a prog_var.
+    %
+:- pred rtti_varmaps_var_info(rtti_varmaps::in, prog_var::in,
+    rtti_var_info::out) is det.
+
+    % Insert the location of a type_info.  Abort if such information
+    % already exists.
+    %
+:- pred rtti_det_insert_type_info_locn(tvar::in, type_info_locn::in,
+    rtti_varmaps::in, rtti_varmaps::out) is det.
+
+    % Set the location of a type_info, overwriting any previous
+    % information.
+    %
+:- pred rtti_set_type_info_locn(tvar::in, type_info_locn::in,
+    rtti_varmaps::in, rtti_varmaps::out) is det.
+
+    % Insert the prog_var which contains the typeclass_info for a
+    % given constraint.  Abort if such information already exists.
+    %
+:- pred rtti_det_insert_typeclass_info_var(prog_constraint::in, prog_var::in,
+    rtti_varmaps::in, rtti_varmaps::out) is det.
+
+    % Set the prog_var which contains the typeclass_info for a given
+    % constraint, overwriting any previous information.
+    %
+:- pred rtti_set_typeclass_info_var(prog_constraint::in, prog_var::in,
+    rtti_varmaps::in, rtti_varmaps::out) is det.
+
+    % Make the given typeclass_info var available for reuse in later
+    % goals.  Abort if we know nothing about this variable.
+    %
+:- pred rtti_reuse_typeclass_info_var(prog_var::in,
+    rtti_varmaps::in, rtti_varmaps::out) is det.
+
+    % For a prog_var which holds a type_info, set the type that the
+    % type_info is for.  Abort if such information already exists.
+    %
+:- pred rtti_det_insert_type_info_type(prog_var::in, mer_type::in,
+    rtti_varmaps::in, rtti_varmaps::out) is det.
+
+    % For a prog_var which holds a type_info, set the type that the
+    % type_info is for, overwriting any previous information.
+    %
+:- pred rtti_set_type_info_type(prog_var::in, mer_type::in,
+    rtti_varmaps::in, rtti_varmaps::out) is det.
+
+    % rtti_var_info_duplicate(Var, NewVar, !RttiVarMaps)
+    %
+    % Duplicate the rtti_var_info we have about Var for NewVar.
+    %
+:- pred rtti_var_info_duplicate(prog_var::in, prog_var::in,
+    rtti_varmaps::in, rtti_varmaps::out) is det.
+
+    % Returns all of the tvars that we have information about in the
+    % rtti_varmaps structure.
+    %
+:- pred rtti_varmaps_tvars(rtti_varmaps::in, list(tvar)::out) is det.
+
+    % Returns all of the types that we have information about in the
+    % rtti_varmaps structure, including those types which appear in the
+    % arguments of constraints.
+    %
+:- pred rtti_varmaps_types(rtti_varmaps::in, list(mer_type)::out) is det.
+
+    % Returns all of the prog_constraints which have typeclass_infos
+    % stored in a prog_var we can reuse.
+    %
+:- pred rtti_varmaps_reusable_constraints(rtti_varmaps::in,
+    list(prog_constraint)::out) is det.
+
+    % Returns all of the prog_vars which are known to contain a type_info
+    % or typeclass_info.
+    %
+:-  pred rtti_varmaps_rtti_prog_vars(rtti_varmaps::in, list(prog_var)::out)
+    is det.
+
+    % apply_substitutions_to_rtti_varmaps(TRenaming, TSubst, Subst,
+    %   !RttiVarMaps)
+    %
+    % Apply substitutions to the rtti_varmaps data.  TRenaming is applied
+    % to all types first, then TSubst is applied to all types.  Subst
+    % is applied to all prog_vars.
+    %
+:- pred apply_substitutions_to_rtti_varmaps(tvar_renaming::in, tsubst::in,
+    map(prog_var, prog_var)::in, rtti_varmaps::in, rtti_varmaps::out)
+    is det.
+
+    % rtti_varmaps_transform_types(Pred, !RttiVarMaps)
+    %
+    % Apply the transformation predicate to every type appearing in the
+    % rtti_varmaps structure, including those in the arguments of constraints.
+    %
+:- pred rtti_varmaps_transform_types(
+    pred(mer_type, mer_type)::in(pred(in, out) is det),
+    rtti_varmaps::in, rtti_varmaps::out) is det.
+
+    % rtti_varmaps_overlay(A, B, C)
+    %
+    % Merge the information in rtti_varmaps A and B to produce C.  Where
+    % information conflicts, use the information in B rather than A.
+    %
+:- pred rtti_varmaps_overlay(rtti_varmaps::in,
+    rtti_varmaps::in, rtti_varmaps::out) is det.
+
+    % For a set of variables V, find all the type variables in the types
+    % of the variables in V, and return set of typeinfo variables for
+    % those type variables. (find all typeinfos for variables in V).
+    %
+    % This set of typeinfos is often needed in liveness computation
+    % for accurate garbage collection - live variables need to have
+    % their typeinfos stay live too.
+    %
+:- pred get_typeinfo_vars(set(prog_var)::in, vartypes::in, rtti_varmaps::in,
+    set(prog_var)::out) is det.
+
+:- pred maybe_complete_with_typeinfo_vars(set(prog_var)::in,
+    bool::in, vartypes::in, rtti_varmaps::in, set(prog_var)::out) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module check_hlds.inst_match.
+:- import_module check_hlds.mode_util.
+:- import_module check_hlds.type_util.
+:- import_module hlds.goal_form.
+:- import_module hlds.goal_util.
+:- import_module hlds.make_hlds.
+:- import_module libs.compiler_util.
+:- import_module libs.options.
+:- import_module parse_tree.prog_type.
+:- import_module parse_tree.prog_type_subst.
+:- import_module parse_tree.prog_util.
+
+:- import_module int.
+:- import_module std_util.
+:- import_module string.
+:- import_module svmap.
+:- import_module term.
+:- import_module varset.
+
+type_info_locn_var(type_info(Var), Var).
+type_info_locn_var(typeclass_info(Var, _), Var).
+
+type_info_locn_set_var(Var, type_info(_), type_info(Var)).
+type_info_locn_set_var(Var, typeclass_info(_, Num), typeclass_info(Var, Num)).
+
+:- type rtti_varmaps
+    --->    rtti_varmaps(
+                tci_varmap          :: typeclass_info_varmap,
+                ti_varmap           :: type_info_varmap,
+                ti_type_map         :: type_info_type_map,
+                tci_constraint_map  :: typeclass_info_constraint_map
+            ).
+
+    % A typeclass_info_varmap is a map which for each type class constraint
+    % records which variable contains the typeclass_info for that
+    % constraint.  The constraints covered by this map are those which
+    % are passed in as head arguments and those which are produced as
+    % existential constraints from calls or deconstructions.  These are
+    % the constraints for which it is safe to reuse the variable associated
+    % with the constraint.
+    %
+:- type typeclass_info_varmap == map(prog_constraint, prog_var).
+
+    % A type_info_varmap is a map which for each type variable
+    % records where the type_info for that type variable is stored.
+    %
+    % XXX this doesn't record the information that we want.  For a
+    % constraint such as foo(list(T)) we can't properly record the
+    % location of the type_info for T, since it does not occupy a slot
+    % in the typeclass_info directly, but is inside the type_info for
+    % list(T).
+    %
+:- type type_info_varmap == map(tvar, type_info_locn).
+
+    % Every program variable which holds a type_info is a key in this
+    % map.  The value associated with a given key is the type that the
+    % type_info is for.
+    %
+:- type type_info_type_map == map(prog_var, mer_type).
+
+    % Every program variable which holds a typeclass_info is a key in this
+    % map.  The value associated with a given key is the prog_constraint
+    % that the typeclass_info is for.
+    %
+:- type typeclass_info_constraint_map == map(prog_var, prog_constraint).
+
+rtti_varmaps_init(rtti_varmaps(TCIMap, TIMap, TypeMap, ConstraintMap)) :-
+    map.init(TCIMap),
+    map.init(TIMap),
+    map.init(TypeMap),
+    map.init(ConstraintMap).
+
+rtti_varmaps_no_tvars(VarMaps) :-
+    map.is_empty(VarMaps ^ ti_varmap).
+
+rtti_lookup_type_info_locn(VarMaps, TVar, Locn) :-
+    map.lookup(VarMaps ^ ti_varmap, TVar, Locn).
+
+rtti_search_type_info_locn(VarMaps, TVar, Locn) :-
+    map.search(VarMaps ^ ti_varmap, TVar, Locn).
+
+rtti_lookup_typeclass_info_var(VarMaps, Constraint, ProgVar) :-
+    map.lookup(VarMaps ^ tci_varmap, Constraint, ProgVar).
+
+rtti_search_typeclass_info_var(VarMaps, Constraint, ProgVar) :-
+    map.search(VarMaps ^ tci_varmap, Constraint, ProgVar).
+
+rtti_varmaps_var_info(VarMaps, Var, VarInfo) :-
+    ( map.search(VarMaps ^ ti_type_map, Var, Type) ->
+        VarInfo = type_info_var(Type)
+    ; map.search(VarMaps ^ tci_constraint_map, Var, Constraint) ->
+        VarInfo = typeclass_info_var(Constraint)
+    ;
+        VarInfo = non_rtti_var
+    ).
+
+rtti_det_insert_type_info_locn(TVar, Locn, !VarMaps) :-
+    Map0 = !.VarMaps ^ ti_varmap,
+    map.det_insert(Map0, TVar, Locn, Map),
+    !:VarMaps = !.VarMaps ^ ti_varmap := Map,
+    maybe_check_type_info_var(Locn, TVar, !VarMaps).
+
+rtti_set_type_info_locn(TVar, Locn, !VarMaps) :-
+    Map0 = !.VarMaps ^ ti_varmap,
+    map.set(Map0, TVar, Locn, Map),
+    !:VarMaps = !.VarMaps ^ ti_varmap := Map,
+    maybe_check_type_info_var(Locn, TVar, !VarMaps).
+
+:- pred maybe_check_type_info_var(type_info_locn::in, tvar::in,
+    rtti_varmaps::in, rtti_varmaps::out) is det.
+
+maybe_check_type_info_var(type_info(Var), TVar, !VarMaps) :-
+    ( map.search(!.VarMaps ^ ti_type_map, Var, Type) ->
+        ( Type = variable(TVar, _) ->
+            true
+        ;
+            unexpected(this_file, "inconsistent info in rtti_varmaps")
+        )
+    ;
+        unexpected(this_file, "missing info in rtti_varmaps")
+    ).
+maybe_check_type_info_var(typeclass_info(_, _), _, !VarMaps).
+
+rtti_det_insert_typeclass_info_var(Constraint, ProgVar, !VarMaps) :-
+    Map0 = !.VarMaps ^ tci_constraint_map,
+    map.det_insert(Map0, ProgVar, Constraint, Map),
+    !:VarMaps = !.VarMaps ^ tci_constraint_map := Map.
+
+rtti_set_typeclass_info_var(Constraint, ProgVar, !VarMaps) :-
+    Map0 = !.VarMaps ^ tci_constraint_map,
+    map.set(Map0, ProgVar, Constraint, Map),
+    !:VarMaps = !.VarMaps ^ tci_constraint_map := Map.
+
+rtti_reuse_typeclass_info_var(ProgVar, !VarMaps) :-
+    ( map.search(!.VarMaps ^ tci_constraint_map, ProgVar, Constraint) ->
+        Map0 = !.VarMaps ^ tci_varmap,
+        map.set(Map0, Constraint, ProgVar, Map),
+        !:VarMaps = !.VarMaps ^ tci_varmap := Map
+    ;
+        unexpected(this_file,
+            "rtti_reuse_typeclass_info_var: variable not known")
+    ).
+
+rtti_det_insert_type_info_type(ProgVar, Type, !VarMaps) :-
+    Map0 = !.VarMaps ^ ti_type_map,
+    map.det_insert(Map0, ProgVar, Type, Map),
+    !:VarMaps = !.VarMaps ^ ti_type_map := Map.
+
+rtti_set_type_info_type(ProgVar, Type, !VarMaps) :-
+    Map0 = !.VarMaps ^ ti_type_map,
+    map.set(Map0, ProgVar, Type, Map),
+    !:VarMaps = !.VarMaps ^ ti_type_map := Map.
+
+rtti_var_info_duplicate(Var, NewVar, !VarMaps) :-
+    rtti_varmaps_var_info(!.VarMaps, Var, VarInfo),
+    (
+        VarInfo = type_info_var(Type),
+        rtti_det_insert_type_info_type(NewVar, Type, !VarMaps)
+    ;
+        VarInfo = typeclass_info_var(Constraint),
+        rtti_det_insert_typeclass_info_var(Constraint, NewVar, !VarMaps)
+    ;
+        VarInfo = non_rtti_var
+    ).
+
+rtti_varmaps_tvars(VarMaps, TVars) :-
+    map.keys(VarMaps ^ ti_varmap, TVars).
+
+rtti_varmaps_types(VarMaps, Types) :-
+    solutions(rtti_varmaps_is_known_type(VarMaps), Types).
+
+:- pred rtti_varmaps_is_known_type(rtti_varmaps::in, mer_type::out) is nondet.
+
+rtti_varmaps_is_known_type(VarMaps, Type) :-
+    map.values(VarMaps ^ ti_type_map, Types),
+    list.member(Type, Types).
+rtti_varmaps_is_known_type(VarMaps, Type) :-
+    map.values(VarMaps ^ tci_constraint_map, Constraints),
+    list.member(constraint(_, Types), Constraints),
+    list.member(Type, Types).
+
+rtti_varmaps_reusable_constraints(VarMaps, Constraints) :-
+    map.keys(VarMaps ^ tci_varmap, Constraints).
+
+rtti_varmaps_rtti_prog_vars(VarMaps, Vars) :-
+    map.keys(VarMaps ^ ti_type_map, TIVars),
+    map.keys(VarMaps ^ tci_constraint_map, TCIVars),
+    list.append(TIVars, TCIVars, Vars).
+
+apply_substitutions_to_rtti_varmaps(TRenaming, TSubst, Subst, !RttiVarMaps) :-
+    (
+        % Optimize the simple case.
+        map.is_empty(Subst),
+        map.is_empty(TSubst),
+        map.is_empty(TRenaming)
+    ->
+        true
+    ;
+        !.RttiVarMaps = rtti_varmaps(TCIMap0, TIMap0, TypeMap0,
+            ConstraintMap0),
+        map.foldl(apply_substs_to_tci_map(TRenaming, TSubst, Subst),
+            TCIMap0, map.init, TCIMap),
+        map.foldl(apply_substs_to_ti_map(TRenaming, TSubst, Subst),
+            TIMap0, map.init, TIMap),
+        map.foldl(apply_substs_to_type_map(TRenaming, TSubst, Subst),
+            TypeMap0, map.init, TypeMap),
+        map.foldl(apply_substs_to_constraint_map(TRenaming, TSubst, Subst),
+            ConstraintMap0, map.init, ConstraintMap),
+        !:RttiVarMaps = rtti_varmaps(TCIMap, TIMap, TypeMap, ConstraintMap)
+    ).
+
+:- pred apply_subst_to_prog_var(map(prog_var, prog_var)::in,
+    prog_var::in, prog_var::out) is det.
+
+apply_subst_to_prog_var(Subst, Var0, Var) :-
+    ( map.search(Subst, Var0, Var1) ->
+        Var = Var1
+    ;
+        Var = Var0
+    ).
+
+:- pred apply_substs_to_tci_map(tvar_renaming::in, tsubst::in,
+    map(prog_var, prog_var)::in, prog_constraint::in, prog_var::in,
+    typeclass_info_varmap::in, typeclass_info_varmap::out) is det.
+
+apply_substs_to_tci_map(TRenaming, TSubst, Subst, Constraint0, Var0, !Map) :-
+    apply_variable_renaming_to_prog_constraint(TRenaming, Constraint0,
+        Constraint1),
+    apply_rec_subst_to_prog_constraint(TSubst, Constraint1, Constraint),
+    apply_subst_to_prog_var(Subst, Var0, Var),
+    svmap.set(Constraint, Var, !Map).
+
+    % Update a map entry from tvar to type_info_locn, using the type renaming
+    % and substitution to rename tvars and a variable substitution to rename
+    % vars. The type renaming is applied before the type substitution.
+    %
+    % If tvar maps to a another type variable, we keep the new variable, if
+    % it maps to a type, we remove it from the map.
+    %
+:- pred apply_substs_to_ti_map(tvar_renaming::in, tsubst::in,
+    map(prog_var, prog_var)::in, tvar::in, type_info_locn::in,
+    type_info_varmap::in, type_info_varmap::out) is det.
+
+apply_substs_to_ti_map(TRenaming, TSubst, Subst, TVar, Locn, !Map) :-
+    type_info_locn_var(Locn, Var),
+    apply_subst_to_prog_var(Subst, Var, NewVar),
+    type_info_locn_set_var(NewVar, Locn, NewLocn),
+    apply_variable_renaming_to_tvar(TRenaming, TVar, NewTVar1),
+    % We don't use the correct kinds here, but that doesn't matter because
+    % the resulting kind will be thrown away anyway.
+    apply_rec_subst_to_tvar(map.init, TSubst, NewTVar1, NewType),
+    (
+        % If the tvar is still a variable, insert it into the map with the
+        % new var.
+        NewType = variable(NewTVar, _)
+    ->
+        % Don't abort if two old type variables map to the same new type
+        % variable.
+        svmap.set(NewTVar, NewLocn, !Map)
+    ;
+        true
+    ).
+
+:- pred apply_substs_to_type_map(tvar_renaming::in, tsubst::in,
+    map(prog_var, prog_var)::in, prog_var::in, mer_type::in,
+    type_info_type_map::in, type_info_type_map::out) is det.
+
+apply_substs_to_type_map(TRenaming, TSubst, Subst, Var0, Type0, !Map) :-
+    apply_variable_renaming_to_type(TRenaming, Type0, Type1),
+    apply_rec_subst_to_type(TSubst, Type1, Type),
+    apply_subst_to_prog_var(Subst, Var0, Var),
+    ( map.search(!.Map, Var, ExistingType) ->
+        ( Type = ExistingType ->
+            true
+        ;
+            unexpected(this_file, "inconsistent type_infos")
+        )
+    ;
+        svmap.det_insert(Var, Type, !Map)
+    ).
+
+:- pred apply_substs_to_constraint_map(tvar_renaming::in, tsubst::in,
+    map(prog_var, prog_var)::in, prog_var::in, prog_constraint::in,
+    typeclass_info_constraint_map::in, typeclass_info_constraint_map::out)
+    is det.
+
+apply_substs_to_constraint_map(TRenaming, TSubst, Subst, Var0, Constraint0,
+        !Map) :-
+    apply_variable_renaming_to_prog_constraint(TRenaming, Constraint0,
+        Constraint1),
+    apply_rec_subst_to_prog_constraint(TSubst, Constraint1, Constraint),
+    apply_subst_to_prog_var(Subst, Var0, Var),
+    ( map.search(!.Map, Var, ExistingConstraint) ->
+        ( Constraint = ExistingConstraint ->
+            true
+        ;
+            unexpected(this_file, "inconsistent typeclass_infos")
+        )
+    ;
+        svmap.det_insert(Var, Constraint, !Map)
+    ).
+
+rtti_varmaps_transform_types(Pred, !RttiVarMaps) :-
+    TciMap0 = !.RttiVarMaps ^ tci_varmap,
+    TypeMap0 = !.RttiVarMaps ^ ti_type_map,
+    ConstraintMap0 = !.RttiVarMaps ^ tci_constraint_map,
+    map.foldl(apply_constraint_key_transformation(Pred), TciMap0,
+    map.init, TciMap),
+    Pred2 = (pred(_::in, V::in, W::out) is det :-
+            Pred(V, W)
+    ),
+    map.map_values(Pred2, TypeMap0, TypeMap),
+    map.map_values(apply_constraint_value_transformation(Pred),
+        ConstraintMap0, ConstraintMap),
+    !:RttiVarMaps = !.RttiVarMaps ^ tci_varmap := TciMap,
+    !:RttiVarMaps = !.RttiVarMaps ^ ti_type_map := TypeMap,
+    !:RttiVarMaps = !.RttiVarMaps ^ tci_constraint_map := ConstraintMap.
+
+:- pred apply_constraint_key_transformation(
+    pred(mer_type, mer_type)::in(pred(in, out) is det),
+    prog_constraint::in, prog_var::in,
+    typeclass_info_varmap::in, typeclass_info_varmap::out) is det.
+
+apply_constraint_key_transformation(Pred, Constraint0, Var, !Map) :-
+    Constraint0 = constraint(Name, Args0),
+    list.map(Pred, Args0, Args),
+    Constraint = constraint(Name, Args),
+    svmap.set(Constraint, Var, !Map).
+
+:- pred apply_constraint_value_transformation(
+    pred(mer_type, mer_type)::in(pred(in, out) is det),
+    prog_var::in, prog_constraint::in, prog_constraint::out) is det.
+
+apply_constraint_value_transformation(Pred, _, Constraint0, Constraint) :-
+    Constraint0 = constraint(Name, Args0),
+    list.map(Pred, Args0, Args),
+    Constraint = constraint(Name, Args).
+
+rtti_varmaps_overlay(VarMapsA, VarMapsB, VarMaps) :-
+    VarMapsA = rtti_varmaps(TCImapA, TImapA, TypeMapA, ConstraintMapA),
+    VarMapsB = rtti_varmaps(TCImapB, TImapB, TypeMapB, ConstraintMapB),
+
+        % Prefer VarMapsB for this information.
+        %
+    map.overlay(TCImapA, TCImapB, TCImap),
+    map.overlay(TImapA, TImapB, TImap),
+
+        % On the other hand, we insist that this information is consistent.
+        %
+    map.merge(TypeMapA, TypeMapB, TypeMap),
+    map.merge(ConstraintMapA, ConstraintMapB, ConstraintMap),
+
+    VarMaps = rtti_varmaps(TCImap, TImap, TypeMap, ConstraintMap).
+
+%-----------------------------------------------------------------------------%
+
+get_typeinfo_vars(Vars, VarTypes, RttiVarMaps, TypeInfoVars) :-
+    TVarMap = RttiVarMaps ^ ti_varmap,
+    set.to_sorted_list(Vars, VarList),
+    get_typeinfo_vars_2(VarList, VarTypes, TVarMap, TypeInfoVarList),
+    set.list_to_set(TypeInfoVarList, TypeInfoVars).
+
+    % Auxiliary predicate - traverses variables and builds a list of
+    % variables that store typeinfos for these variables.
+    %
+:- pred get_typeinfo_vars_2(list(prog_var)::in,
+    vartypes::in, type_info_varmap::in, list(prog_var)::out) is det.
+
+get_typeinfo_vars_2([], _, _, []).
+get_typeinfo_vars_2([Var | Vars], VarTypes, TVarMap, TypeInfoVars) :-
+    ( map.search(VarTypes, Var, Type) ->
+        prog_type.vars(Type, TypeVars),
+        (
+            TypeVars = [],
+            % Optimize common case,
+            get_typeinfo_vars_2(Vars, VarTypes, TVarMap, TypeInfoVars)
+        ;
+            TypeVars = [_ | _],
+            % XXX It's possible there are some complications with
+            % higher order pred types here -- if so, maybe
+            % treat them specially.
+
+            % The type_info is either stored in a variable, or in a
+            % typeclass_info. Either get the type_info variable or
+            % the typeclass_info variable.
+            LookupVar = (pred(TVar::in, TVarVar::out) is det :-
+                    map.lookup(TVarMap, TVar, Locn),
+                    type_info_locn_var(Locn, TVarVar)
+                ),
+            list.map(LookupVar, TypeVars, TypeInfoVarsHead),
+
+            get_typeinfo_vars_2(Vars, VarTypes, TVarMap, TypeInfoVarsTail),
+            TypeInfoVars = TypeInfoVarsHead ++ TypeInfoVarsTail
+        )
+    ;
+        unexpected(this_file, "get_typeinfo_vars_2: var not found in typemap")
+    ).
+
+maybe_complete_with_typeinfo_vars(Vars0, TypeInfoLiveness, VarTypes,
+        RttiVarMaps, Vars) :-
+    (
+        TypeInfoLiveness = yes,
+        get_typeinfo_vars(Vars0, VarTypes, RttiVarMaps, TypeInfoVars),
+        set.union(Vars0, TypeInfoVars, Vars)
+    ;
+        TypeInfoLiveness = no,
+        Vars = Vars0
+    ).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "hlds_rtti.m".
+
+%-----------------------------------------------------------------------------%
+:- end_module hlds.hlds_rtti.
+%-----------------------------------------------------------------------------%
Index: compiler/inlining.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/inlining.m,v
retrieving revision 1.135
diff -u -b -r1.135 inlining.m
--- compiler/inlining.m	17 Mar 2006 01:40:21 -0000	1.135
+++ compiler/inlining.m	22 Mar 2006 03:19:16 -0000
@@ -80,9 +80,11 @@
 :- module transform_hlds.inlining.
 :- interface.
 
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module parse_tree.prog_data.
 
 :- import_module bool.
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.194
diff -u -b -r1.194 intermod.m
--- compiler/intermod.m	17 Mar 2006 01:40:22 -0000	1.194
+++ compiler/intermod.m	22 Mar 2006 04:22:12 -0000
@@ -98,12 +98,14 @@
 :- import_module check_hlds.mode_util.
 :- import_module check_hlds.type_util.
 :- import_module hlds.goal_util.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
 :- import_module hlds.instmap.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.85
diff -u -b -r1.85 jumpopt.m
--- compiler/jumpopt.m	17 Mar 2006 01:40:22 -0000	1.85
+++ compiler/jumpopt.m	22 Mar 2006 05:34:12 -0000
@@ -5,12 +5,12 @@
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
-
+%
 % File: jumpopt.m.
 % Author: zs.
-
+%
 % This module contains code that optimizes jumps to jumps.
-
+%
 %-----------------------------------------------------------------------------%
 
 :- module ll_backend.jumpopt.
Index: compiler/lambda.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/lambda.m,v
retrieving revision 1.112
diff -u -b -r1.112 lambda.m
--- compiler/lambda.m	17 Mar 2006 01:40:23 -0000	1.112
+++ compiler/lambda.m	22 Mar 2006 05:29:06 -0000
@@ -5,10 +5,10 @@
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
-
+%
 % File: lambda.m.
 % Main author: fjh.
-
+%
 % This module is a pass over the HLDS to deal with lambda expressions.
 %
 % Lambda expressions are converted into separate predicates, so for
@@ -90,6 +90,8 @@
 :- import_module hlds.goal_util.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
+:- import_module hlds.hlds_rtti.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout.m,v
retrieving revision 1.24
diff -u -b -r1.24 layout.m
--- compiler/layout.m	17 Mar 2006 01:40:23 -0000	1.24
+++ compiler/layout.m	22 Mar 2006 03:17:16 -0000
@@ -35,6 +35,7 @@
 :- interface.
 
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module libs.trace_params.
 :- import_module ll_backend.llds.
 :- import_module mdbcomp.prim_data.
Index: compiler/layout_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/layout_out.m,v
retrieving revision 1.61
diff -u -b -r1.61 layout_out.m
--- compiler/layout_out.m	21 Mar 2006 02:33:34 -0000	1.61
+++ compiler/layout_out.m	22 Mar 2006 03:45:05 -0000
@@ -100,6 +100,7 @@
 :- import_module backend_libs.rtti.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/lco.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/lco.m,v
retrieving revision 1.33
diff -u -b -r1.33 lco.m
--- compiler/lco.m	17 Mar 2006 01:40:23 -0000	1.33
+++ compiler/lco.m	22 Mar 2006 05:34:03 -0000
@@ -5,10 +5,10 @@
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
-
+%
 % File: lco.m.
 % Author: zs.
-
+%
 % Transform predicates with calls that are tail recursive modulo construction
 % where (1) all recursive calls have the same args participating in the "modulo
 % construction" part and (2) all the other output args are returned in the same
@@ -99,7 +99,7 @@
 % 			capture addr of Mid1 in Addr1
 % 		store_at_ref(Ref1, Out1)
 % 		p'(In1, ... InN, Addr1, Out2... OutM)
-
+%
 %-----------------------------------------------------------------------------%
 
 :- module transform_hlds.lco.
@@ -124,13 +124,13 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_pred.
 :- import_module hlds.instmap.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
+:- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
 :- import_module parse_tree.prog_mode.
 :- import_module transform_hlds.dependency_graph.
-
-:- import_module mdbcomp.prim_data.
 
 :- import_module assoc_list.
 :- import_module bag.
Index: compiler/live_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/live_vars.m,v
retrieving revision 1.116
diff -u -b -r1.116 live_vars.m
--- compiler/live_vars.m	17 Mar 2006 01:40:23 -0000	1.116
+++ compiler/live_vars.m	22 Mar 2006 05:25:14 -0000
@@ -68,6 +68,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_llds.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module libs.compiler_util.
 :- import_module ll_backend.liveness.
@@ -514,16 +515,13 @@
 :- pred maybe_add_typeinfo_liveness(proc_info::in, bool::in,
 	set(prog_var)::in, set(prog_var)::in, set(prog_var)::out) is det.
 
-maybe_add_typeinfo_liveness(ProcInfo, TypeInfoLiveness, OutVars,
-		!LiveVars) :-
+maybe_add_typeinfo_liveness(ProcInfo, TypeInfoLiveness, OutVars, !LiveVars) :-
 	(
         TypeInfoLiveness = yes,
 		proc_info_vartypes(ProcInfo, VarTypes),
 		proc_info_rtti_varmaps(ProcInfo, RttiVarMaps),
-		proc_info_get_typeinfo_vars(!.LiveVars, VarTypes, RttiVarMaps,
-			TypeInfoVarsLive),
-		proc_info_get_typeinfo_vars(OutVars, VarTypes, RttiVarMaps,
-			TypeInfoVarsOut),
+        get_typeinfo_vars(!.LiveVars, VarTypes, RttiVarMaps, TypeInfoVarsLive),
+        get_typeinfo_vars(OutVars, VarTypes, RttiVarMaps, TypeInfoVarsOut),
 		set.union(!.LiveVars, TypeInfoVarsOut, !:LiveVars),
 		set.union(!.LiveVars, TypeInfoVarsLive, !:LiveVars)
 	;
Index: compiler/liveness.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/liveness.m,v
retrieving revision 1.142
diff -u -b -r1.142 liveness.m
--- compiler/liveness.m	17 Mar 2006 01:40:23 -0000	1.142
+++ compiler/liveness.m	22 Mar 2006 04:41:02 -0000
@@ -185,6 +185,7 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_llds.
 :- import_module hlds.hlds_out.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module hlds.passes_aux.
 :- import_module hlds.quantification.
@@ -1534,8 +1535,8 @@
     module_info_pred_info(ModuleInfo, PredId, PredInfo),
     proc_info_rtti_varmaps(ProcInfo, RttiVarMaps),
     body_should_use_typeinfo_liveness(PredInfo, Globals, TypeinfoLiveness),
-    proc_info_maybe_complete_with_typeinfo_vars(NonLocals0,
-        TypeinfoLiveness, VarTypes, RttiVarMaps, NonLocals),
+    maybe_complete_with_typeinfo_vars(NonLocals0, TypeinfoLiveness, VarTypes,
+        RttiVarMaps, NonLocals),
     set.intersect(!.Liveness, NonLocals, !:Liveness).
 
 :- pred initial_liveness_2(list(prog_var)::in, list(mer_mode)::in,
@@ -1567,8 +1568,8 @@
     % to these.
     proc_info_vartypes(ProcInfo, VarTypes),
     proc_info_rtti_varmaps(ProcInfo, RttiVarMaps),
-    proc_info_maybe_complete_with_typeinfo_vars(Deadness0,
-        LiveInfo ^ typeinfo_liveness, VarTypes, RttiVarMaps, Deadness).
+    maybe_complete_with_typeinfo_vars(Deadness0, LiveInfo ^ typeinfo_liveness,
+        VarTypes, RttiVarMaps, Deadness).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -1646,9 +1647,8 @@
     set(prog_var)::in, set(prog_var)::out) is det.
 
 liveness.maybe_complete_with_typeinfos(LiveInfo, Vars0, Vars) :-
-    proc_info_maybe_complete_with_typeinfo_vars(Vars0,
-        LiveInfo ^ typeinfo_liveness, LiveInfo ^ vartypes,
-        LiveInfo ^ rtti_varmaps, Vars).
+    maybe_complete_with_typeinfo_vars(Vars0, LiveInfo ^ typeinfo_liveness,
+        LiveInfo ^ vartypes, LiveInfo ^ rtti_varmaps, Vars).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.521
diff -u -b -r1.521 make_hlds.m
--- compiler/make_hlds.m	23 Feb 2006 09:36:55 -0000	1.521
+++ compiler/make_hlds.m	22 Mar 2006 03:09:48 -0000
@@ -24,6 +24,7 @@
 :- module hlds__make_hlds.
 :- interface.
 
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
Index: compiler/make_hlds_passes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/make_hlds_passes.m,v
retrieving revision 1.35
diff -u -b -r1.35 make_hlds_passes.m
--- compiler/make_hlds_passes.m	21 Mar 2006 22:25:26 -0000	1.35
+++ compiler/make_hlds_passes.m	22 Mar 2006 05:34:54 -0000
@@ -104,6 +104,7 @@
 :- import_module hlds.make_hlds.make_hlds_error.
 :- import_module hlds.make_hlds.make_hlds_warn.
 :- import_module hlds.make_hlds.qual_info.
+:- import_module hlds.pred_table.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.287
diff -u -b -r1.287 mercury_to_mercury.m
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.64
diff -u -b -r1.64 ml_call_gen.m
--- compiler/ml_call_gen.m	17 Mar 2006 01:40:28 -0000	1.64
+++ compiler/ml_call_gen.m	22 Mar 2006 04:02:55 -0000
@@ -884,8 +884,8 @@
         !Info) :-
     ml_gen_var_list(!.Info, ArgVars, ArgLvals),
     ml_gen_info_get_module_info(!.Info, ModuleInfo),
-    predicate_module(ModuleInfo, PredId, ModuleName),
-    predicate_name(ModuleInfo, PredId, PredName),
+    ModuleName = predicate_module(ModuleInfo, PredId),
+    PredName = predicate_name(ModuleInfo, PredId),
     (
         builtin_ops.translate_builtin(ModuleName, PredName,
             ProcId, ArgLvals, SimpleCode0)
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.172
diff -u -b -r1.172 ml_code_gen.m
--- compiler/ml_code_gen.m	17 Mar 2006 01:40:28 -0000	1.172
+++ compiler/ml_code_gen.m	22 Mar 2006 04:03:23 -0000
@@ -772,6 +772,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_pred.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.104
diff -u -b -r1.104 ml_code_util.m
--- compiler/ml_code_util.m	17 Mar 2006 01:40:28 -0000	1.104
+++ compiler/ml_code_util.m	22 Mar 2006 03:18:18 -0000
@@ -21,6 +21,7 @@
 :- import_module hlds.code_model.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module libs.globals.
 :- import_module mdbcomp.prim_data.
 :- import_module ml_backend.mlds.
Index: compiler/mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_constraints.m,v
retrieving revision 1.24
diff -u -b -r1.24 mode_constraints.m
--- compiler/mode_constraints.m	17 Mar 2006 01:40:31 -0000	1.24
+++ compiler/mode_constraints.m	22 Mar 2006 03:45:45 -0000
@@ -22,6 +22,7 @@
 :- import_module check_hlds.abstract_mode_constraints.
 :- import_module check_hlds.prop_mode_constraints.
 :- import_module hlds.hlds_module.
+
 :- import_module io.
 
 %-----------------------------------------------------------------------------%
@@ -50,6 +51,7 @@
 :- import_module check_hlds.mode_ordering.
 :- import_module check_hlds.mode_util.
 :- import_module hlds.hhf.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_pred.
Index: compiler/mode_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_info.m,v
retrieving revision 1.83
diff -u -b -r1.83 mode_info.m
--- compiler/mode_info.m	17 Mar 2006 01:40:32 -0000	1.83
+++ compiler/mode_info.m	22 Mar 2006 02:24:08 -0000
@@ -23,6 +23,7 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.pred_table.
 :- import_module hlds.instmap.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
Index: compiler/mode_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mode_util.m,v
retrieving revision 1.182
diff -u -b -r1.182 mode_util.m
--- compiler/mode_util.m	9 Mar 2006 04:56:35 -0000	1.182
+++ compiler/mode_util.m	22 Mar 2006 05:31:36 -0000
@@ -5,12 +5,12 @@
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
-
+%
 % File: mode_util.m.
 % Main author: fjh.
-
+%
 % This module contains utility predicates for dealing with modes and insts.
-
+%
 %-----------------------------------------------------------------------------%
 
 :- module check_hlds.mode_util.
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.327
diff -u -b -r1.327 modes.m
--- compiler/modes.m	17 Mar 2006 01:40:32 -0000	1.327
+++ compiler/modes.m	22 Mar 2006 03:56:15 -0000
@@ -355,10 +355,12 @@
 :- import_module check_hlds.type_util.
 :- import_module check_hlds.unify_proc.
 :- import_module check_hlds.unique_modes.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_out.
 :- import_module hlds.make_hlds.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.163
diff -u -b -r1.163 opt_debug.m
--- compiler/opt_debug.m	21 Mar 2006 02:33:36 -0000	1.163
+++ compiler/opt_debug.m	22 Mar 2006 03:54:54 -0000
@@ -120,6 +120,7 @@
 :- import_module backend_libs.name_mangle.
 :- import_module backend_libs.proc_label.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.special_pred.
 :- import_module libs.globals.
 :- import_module libs.options.
Index: compiler/options.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.505
diff -u -b -r1.505 options.m
--- compiler/options.m	17 Mar 2006 01:40:33 -0000	1.505
+++ compiler/options.m	22 Mar 2006 05:32:57 -0000
@@ -3872,18 +3872,18 @@
         "\tslow compilation.",
         "--no-common-struct",
         "\tDisable optimization of common term structures.",
-/*
-	Common goal optimization should not be turned off, since it can
-	break programs that would otherwise compile properly (e.g.,
-	benchmarks/icfp2000).  This is kept as a developer-only option.
 
-        "--no-common-goal",
-        "\tDisable optimization of common goals.",
-        "\tAt the moment this optimization",
-        "\tdetects only common deconstruction unifications.",
-        "\tDisabling this optimization reduces the class of predicates",
-        "\tthat the compiler considers to be deterministic.",
-*/
+%       Common goal optimization should not be turned off, since it can
+%       break programs that would otherwise compile properly (e.g.,
+%       benchmarks/icfp2000). This is kept as a developer-only option.
+%
+%       "--no-common-goal",
+%       "\tDisable optimization of common goals.",
+%       "\tAt the moment this optimization",
+%       "\tdetects only common deconstruction unifications.",
+%       "\tDisabling this optimization reduces the class of predicates",
+%       "\tthat the compiler considers to be deterministic.",
+
         "--constraint-propagation",
         "\tEnable the constraint propagation transformation,",
         "\twhich attempts to transform the code so that goals",
Index: compiler/ordering_mode_constraints.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ordering_mode_constraints.m,v
retrieving revision 1.4
diff -u -b -r1.4 ordering_mode_constraints.m
--- compiler/ordering_mode_constraints.m	24 Feb 2006 05:49:37 -0000	1.4
+++ compiler/ordering_mode_constraints.m	22 Mar 2006 03:46:43 -0000
@@ -103,6 +103,7 @@
 :- import_module check_hlds.abstract_mode_constraints.
 :- import_module check_hlds.clause_to_proc.
 :- import_module check_hlds.mcsolver.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_error_util.
 :- import_module hlds.hlds_goal.
 :- import_module libs.compiler_util.
Index: compiler/pd_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/pd_debug.m,v
retrieving revision 1.17
diff -u -b -r1.17 pd_debug.m
--- compiler/pd_debug.m	17 Mar 2006 01:40:34 -0000	1.17
+++ compiler/pd_debug.m	22 Mar 2006 04:22:51 -0000
@@ -126,7 +126,7 @@
         !IO) :-
     Version = version_info(Goal - GoalInfo, _, Args, _, InstMap,
         InitialCost, CostDelta, Parents, _),
-    predicate_name(ModuleInfo, PredId, PredName),
+    PredName = predicate_name(ModuleInfo, PredId),
     io.write_string(PredName, !IO),
     io.write_string(": (PredProcId :", !IO),
     PredProcId = proc(PredId, ProcId),
Index: compiler/pd_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/pd_info.m,v
retrieving revision 1.26
diff -u -b -r1.26 pd_info.m
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.293
diff -u -b -r1.293 polymorphism.m
--- compiler/polymorphism.m	17 Mar 2006 01:40:35 -0000	1.293
+++ compiler/polymorphism.m	22 Mar 2006 03:56:31 -0000
@@ -177,6 +177,7 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
 
@@ -378,11 +379,13 @@
 :- import_module check_hlds.type_util.
 :- import_module check_hlds.unify_proc.
 :- import_module hlds.goal_util.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_code_util.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_out.
 :- import_module hlds.instmap.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
Index: compiler/post_typecheck.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/post_typecheck.m,v
retrieving revision 1.96
diff -u -b -r1.96 post_typecheck.m
--- compiler/post_typecheck.m	17 Mar 2006 01:40:35 -0000	1.96
+++ compiler/post_typecheck.m	22 Mar 2006 03:59:18 -0000
@@ -85,7 +85,7 @@
 
     % Handle any unresolved overloading for a predicate call.
     %
-:- pred resolve_pred_overloading(list(prog_var)::in,
+:- pred finally_resolve_pred_overloading(list(prog_var)::in,
     pred_info::in, module_info::in, sym_name::in, sym_name::out,
     pred_id::in, pred_id::out) is det.
 
@@ -111,9 +111,11 @@
 :- import_module check_hlds.type_util.
 :- import_module hlds.assertion.
 :- import_module hlds.goal_util.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_error_util.
 :- import_module hlds.hlds_out.
+:- import_module hlds.pred_table.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
@@ -399,7 +401,7 @@
 
 %-----------------------------------------------------------------------------%
 
-resolve_pred_overloading(Args0, CallerPredInfo, ModuleInfo, !PredName,
+finally_resolve_pred_overloading(Args0, CallerPredInfo, ModuleInfo, !PredName,
         !PredId) :-
     % In the case of a call to an overloaded predicate, typecheck.m
     % does not figure out the correct pred_id. We must do that here.
Index: compiler/pred_table.m
===================================================================
RCS file: compiler/pred_table.m
diff -N compiler/pred_table.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ compiler/pred_table.m	22 Mar 2006 03:33:24 -0000
@@ -0,0 +1,1181 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 1996-2006 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.
+%-----------------------------------------------------------------------------%
+
+% File: pred_table.m.
+% Main authors: fjh, conway.
+
+% This module defines the part of the High Level Data Structure or HLDS
+% that allows the compiler to look up predicates by name (qualified,
+% unqualified or some mixture) and/or arity.
+
+%-----------------------------------------------------------------------------%
+
+:- module hlds.pred_table.
+:- interface.
+
+:- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_module.
+:- import_module mdbcomp.prim_data.
+:- import_module parse_tree.module_qual.
+:- import_module parse_tree.prog_data.
+
+:- import_module list.
+:- import_module map.
+:- import_module std_util.
+
+:- implementation.
+
+:- import_module libs.compiler_util.
+:- import_module parse_tree.modules.
+:- import_module parse_tree.prog_out.
+:- import_module parse_tree.prog_type.
+:- import_module parse_tree.prog_util.
+
+:- import_module bool.
+:- import_module int.
+:- import_module multi_map.
+:- import_module string.
+:- import_module svmap.
+:- import_module svmulti_map.
+
+%-----------------------------------------------------------------------------%
+
+:- interface.
+
+:- type predicate_table.
+
+:- type pred_table  ==  map(pred_id, pred_info).
+
+    % Various predicates for accessing the predicate_table type.
+    % The predicate_table holds information about the predicates
+    % and functions defined in this module or imported from other modules.
+    % The primary key for this table is the `pred_id', but there
+    % are also secondary indexes on each of name, name+arity, and
+    % module+name+arity, for both functions and predicates.
+
+    % Initialize the predicate table
+    %
+:- pred predicate_table_init(predicate_table::out) is det.
+
+    % Balance all the binary trees in the predicate table
+    %
+:- pred predicate_table_optimize(predicate_table::in, predicate_table::out)
+    is det.
+
+    % Get the pred_id->pred_info map.
+    %
+:- pred predicate_table_get_preds(predicate_table::in, pred_table::out) is det.
+
+    % Restrict the predicate table to the list of predicates. This predicate
+    % should only be used when the set of predicates to restrict the table
+    % to is significantly smaller then the predicate_table size, as rather than
+    % removing entries from the table it builds a new table from scratch.
+    %
+:- pred predicate_table_restrict(partial_qualifier_info::in,
+    list(pred_id)::in, predicate_table::in, predicate_table::out) is det.
+
+    % Set the pred_id->pred_info map.
+    % NB You shouldn't modify the keys in this table, only
+    % use predicate_table_insert, predicate_table_remove_predid and
+    % predicate_table_remove_predicate.
+    %
+:- pred predicate_table_set_preds(pred_table::in,
+    predicate_table::in, predicate_table::out) is det.
+
+    % Get a list of all the valid predids in the predicate_table.
+    %
+:- pred predicate_table_get_predids(predicate_table::in, list(pred_id)::out)
+    is det.
+
+    % Remove a pred_id from the valid list.
+    %
+:- pred predicate_table_remove_predid(pred_id::in,
+    predicate_table::in, predicate_table::out) is det.
+:- pred predicate_table_remove_predicate(pred_id::in,
+    predicate_table::in, predicate_table::out) is det.
+
+    % Reverse the order of pred_ids stored in the predicate_table.
+    %
+:- pred predicate_table_reverse_predids(predicate_table::in,
+    predicate_table::out) is det.
+
+    % Search the table for (a) predicates or functions (b) predicates only
+    % or (c) functions only matching this (possibly module-qualified) sym_name.
+    %
+:- pred predicate_table_search_sym(predicate_table::in, is_fully_qualified::in,
+    sym_name::in, list(pred_id)::out) is semidet.
+
+:- pred predicate_table_search_pred_sym(predicate_table::in,
+    is_fully_qualified::in, sym_name::in, list(pred_id)::out) is semidet.
+
+:- pred predicate_table_search_func_sym(predicate_table::in,
+    is_fully_qualified::in, sym_name::in, list(pred_id)::out) is semidet.
+
+    % Search the table for (a) predicates or functions (b) predicates only
+    % or (c) functions only matching this (possibly module-qualified)
+    % sym_name & arity.
+    %
+:- pred predicate_table_search_sym_arity(predicate_table::in,
+    is_fully_qualified::in, sym_name::in, arity::in, list(pred_id)::out)
+    is semidet.
+
+:- pred predicate_table_search_pred_sym_arity(predicate_table::in,
+    is_fully_qualified::in, sym_name::in, arity::in, list(pred_id)::out)
+    is semidet.
+
+:- pred predicate_table_search_func_sym_arity(predicate_table::in,
+    is_fully_qualified::in, sym_name::in, arity::in, list(pred_id)::out)
+    is semidet.
+
+    % Search the table for (a) predicates or functions
+    % (b) predicates only or (c) functions only matching this name.
+    %
+:- pred predicate_table_search_name(predicate_table::in, string::in,
+    list(pred_id)::out) is semidet.
+
+:- pred predicate_table_search_pred_name(predicate_table::in, string::in,
+    list(pred_id)::out) is semidet.
+
+:- pred predicate_table_search_func_name(predicate_table::in, string::in,
+    list(pred_id)::out) is semidet.
+
+    % Search the table for (a) predicates or functions (b) predicates only
+    % or (c) functions only matching this name & arity. When searching for
+    % functions, the arity used is the arity of the function, not the arity
+    % N+1 predicate that it gets converted to.
+    %
+:- pred predicate_table_search_name_arity(predicate_table::in, string::in,
+    arity::in, list(pred_id)::out) is semidet.
+
+:- pred predicate_table_search_pred_name_arity(predicate_table::in, string::in,
+    arity::in, list(pred_id)::out) is semidet.
+
+:- pred predicate_table_search_func_name_arity(predicate_table::in, string::in,
+    arity::in, list(pred_id)::out) is semidet.
+
+    % Search the table for (a) predicates or functions (b) predicates only
+    % or (c) functions only matching this module, name & arity. When searching
+    % for functions, the arity used is the arity of the function, not the arity
+    % N+1 predicate that it gets converted to.
+    %
+    % Note that in cases (b) and (c) it was previously the case that there
+    % could only be one matching pred_id, since each predicate or function
+    % could be uniquely identified by its module, name, arity, and category
+    % (function/predicate). However this is no longer true, due to nested
+    % modules. (For example, `pred foo:bar/2' might match both
+    % `pred mod1:foo:bar/2' and `pred mod2:foo:bar/2'). I hope it doesn't
+    % break anything too badly...
+    %
+    % (`m_n_a' here is short for "module, name, arity".)
+
+    % Is the item known to be fully qualified? If so, a search for
+    % `pred foo.bar/2' will not match `pred baz.foo.bar/2'.
+:- type is_fully_qualified
+    --->    is_fully_qualified
+    ;       may_be_partially_qualified.
+
+:- pred predicate_table_search_m_n_a(predicate_table::in,
+    is_fully_qualified::in, module_name::in, string::in, arity::in,
+    list(pred_id)::out) is semidet.
+
+:- pred predicate_table_search_pred_m_n_a(predicate_table::in,
+    is_fully_qualified::in, module_name::in, string::in, arity::in,
+    list(pred_id)::out) is semidet.
+
+:- pred predicate_table_search_func_m_n_a(predicate_table::in,
+    is_fully_qualified::in, module_name::in, string::in, arity::in,
+    list(pred_id)::out) is semidet.
+
+    % Search the table for predicates or functions matching this pred_or_func
+    % category, module, name, and arity. When searching for functions, the
+    % arity used is the arity of the predicate that the function gets converted
+    % to, i.e. the arity of the function plus one.
+    % NB. This is opposite to what happens with the search predicates
+    % declared above!!
+    %
+:- pred predicate_table_search_pf_m_n_a(predicate_table::in,
+    is_fully_qualified::in, pred_or_func::in, module_name::in, string::in,
+    arity::in, list(pred_id)::out) is semidet.
+
+    % Search the table for predicates or functions matching this pred_or_func
+    % category, name, and arity. When searching for functions, the arity used
+    % is the arity of the predicate that the function gets converted to,
+    % i.e. the arity of the function plus one.
+    % NB. This is opposite to what happens with the search predicates
+    % declared above!!
+    %
+:- pred predicate_table_search_pf_name_arity(predicate_table::in,
+    pred_or_func::in, string::in, arity::in, list(pred_id)::out)
+    is semidet.
+
+    % Search the table for predicates or functions matching this pred_or_func
+    % category, sym_name, and arity. When searching for functions, the arity
+    % used is the arity of the predicate that the function gets converted to,
+    % i.e. the arity of the function plus one.
+    % NB. This is opposite to what happens with the search predicates
+    % declared above!!
+    %
+:- pred predicate_table_search_pf_sym_arity(predicate_table::in,
+    is_fully_qualified::in, pred_or_func::in, sym_name::in, arity::in,
+    list(pred_id)::out) is semidet.
+
+    % Search the table for predicates or functions matching
+    % this pred_or_func category and sym_name.
+    %
+:- pred predicate_table_search_pf_sym(predicate_table::in,
+    is_fully_qualified::in, pred_or_func::in, sym_name::in,
+    list(pred_id)::out) is semidet.
+
+    % predicate_table_insert(PredTable0, PredInfo,
+    %   NeedQual, PartialQualInfo, PredId, PredTable):
+    %
+    % Insert PredInfo into PredTable0 and assign it a new pred_id.
+    % You should check beforehand that the pred doesn't already
+    % occur in the table.
+    %
+:- pred predicate_table_insert(pred_info::in, need_qualifier::in,
+    partial_qualifier_info::in, pred_id::out,
+    predicate_table::in, predicate_table::out) is det.
+
+    % Equivalent to predicate_table_insert/6, except that only the
+    % fully-qualified version of the predicate will be inserted into the
+    % predicate symbol table. This is useful for creating % compiler-generated
+    % predicates which will only ever be accessed via fully-qualified names.
+    %
+:- pred predicate_table_insert(pred_info::in, pred_id::out,
+    predicate_table::in, predicate_table::out) is det.
+
+    % Find a predicate which matches the given name and argument types.
+    % Abort if there is no matching pred.
+    % Abort if there are multiple matching preds.
+    % 
+:- pred resolve_pred_overloading(module_info::in, pred_markers::in,
+    list(mer_type)::in, tvarset::in, sym_name::in, sym_name::out, pred_id::out)
+    is det.
+
+    % Find a predicate or function from the list of pred_ids which matches the
+    % given name and argument types.  If the constraint_search argument is
+    % provided then also check that the class context is consistent with what
+    % is expected.  Fail if there is no matching pred.  Abort if there are
+    % multiple matching preds.
+    %
+:- pred find_matching_pred_id(module_info::in, list(pred_id)::in, tvarset::in,
+    list(mer_type)::in, maybe(constraint_search)::in(maybe(constraint_search)),
+    pred_id::out, sym_name::out) is semidet.
+
+    % A means to check that the required constraints are available, without
+    % knowing in advance how many are required.
+    %
+:- type constraint_search == pred(int, list(prog_constraint)).
+:- inst constraint_search == (pred(in, out) is semidet).
+
+    % Get the pred_id and proc_id matching a higher-order term with
+    % the given argument types, aborting with an error if none is found.
+    %
+:- pred get_pred_id_and_proc_id(is_fully_qualified::in, sym_name::in,
+    pred_or_func::in, tvarset::in, list(mer_type)::in, module_info::in,
+    pred_id::out, proc_id::out) is det.
+
+    % Get the pred_id matching a higher-order term with
+    % the given argument types, failing if none is found.
+    %
+:- pred get_pred_id(is_fully_qualified::in, sym_name::in, pred_or_func::in,
+    tvarset::in, list(mer_type)::in, module_info::in, pred_id::out) is semidet.
+
+    % Given a pred_id, return the single proc_id, aborting
+    % if there are no modes or more than one mode.
+    %
+:- pred get_proc_id(module_info::in, pred_id::in, proc_id::out) is det.
+
+:- type mode_no
+    --->    only_mode           % The pred must have exactly one mode.
+    ;       mode_no(int).       % The Nth mode, counting from 0.
+
+:- pred lookup_builtin_pred_proc_id(module_info::in, module_name::in,
+    string::in, pred_or_func::in, arity::in, mode_no::in,
+    pred_id::out, proc_id::out) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- type predicate_table
+    --->    predicate_table(
+                preds               :: pred_table,
+                                    % Map from pred_id to pred_info.
+
+                next_pred_id        :: pred_id,
+                                    % The next available pred_id.
+
+                pred_ids            :: list(pred_id),
+                                    % The keys of the pred_table - cached
+                                    % here for efficiency.
+
+                accessibility_table :: accessibility_table,
+                                    % How is the predicate accessible?
+
+                % Indexes on predicates
+
+                pred_name_index     :: name_index,
+                                    % Map from pred name to pred_id.
+
+                pred_name_arity_index :: name_arity_index,
+                                    % Map from pred name & arity to pred_id.
+
+                pred_module_name_arity_index :: module_name_arity_index,
+                                    % Map from pred module, name & arity
+                                    % to pred_id.
+
+                % Indexes on functions
+
+                func_name_index     :: name_index,
+                                    % Map from func name to pred_id.
+
+                func_name_arity_index :: name_arity_index,
+                                    % Map from func name & arity to pred_id.
+
+                func_module_name_arity_index :: module_name_arity_index
+                                    % Map from func module, name & arity
+                                    % to pred_id.
+            ).
+
+:- type accessibility_table == map(pred_id, name_accessibility).
+
+:- type name_accessibility
+    --->    access(
+                % Is this predicate accessible by its unqualified name.
+                accessible_by_unqualifed_name       :: bool,
+
+                % Is this predicate accessible by any partially qualified
+                % names.
+                accessible_by_partially_qualified_names :: bool
+            ).
+
+:- type name_index  == map(string, list(pred_id)).
+
+:- type name_arity_index == map(name_arity, list(pred_id)).
+:- type name_arity ---> string / arity.
+
+    % First search on module and name, then search on arity. The two levels
+    % are needed because typecheck.m needs to be able to search on module
+    % and name only for higher-order terms.
+:- type module_name_arity_index ==
+    map(pair(module_name, string), map(arity, list(pred_id))).
+
+predicate_table_init(PredicateTable) :-
+    PredicateTable = predicate_table(Preds, NextPredId, PredIds,
+        AccessibilityTable,
+        Pred_N_Index, Pred_NA_Index, Pred_MNA_Index,
+        Func_N_Index, Func_NA_Index, Func_MNA_Index),
+    map.init(Preds),
+    NextPredId = hlds_pred.initial_pred_id,
+    PredIds = [],
+    map.init(AccessibilityTable),
+    map.init(Pred_N_Index),
+    map.init(Pred_NA_Index),
+    map.init(Pred_MNA_Index),
+    map.init(Func_N_Index),
+    map.init(Func_NA_Index),
+    map.init(Func_MNA_Index).
+
+predicate_table_optimize(PredicateTable0, PredicateTable) :-
+    PredicateTable0 = predicate_table(A, B, C, D,
+        Pred_N_Index0, Pred_NA_Index0, Pred_MNA_Index0,
+        Func_N_Index0, Func_NA_Index0, Func_MNA_Index0),
+    map.optimize(Pred_N_Index0, Pred_N_Index),
+    map.optimize(Pred_NA_Index0, Pred_NA_Index),
+    map.optimize(Pred_MNA_Index0, Pred_MNA_Index),
+    map.optimize(Func_N_Index0, Func_N_Index),
+    map.optimize(Func_NA_Index0, Func_NA_Index),
+    map.optimize(Func_MNA_Index0, Func_MNA_Index),
+    PredicateTable = predicate_table(A, B, C, D,
+        Pred_N_Index, Pred_NA_Index, Pred_MNA_Index,
+        Func_N_Index, Func_NA_Index, Func_MNA_Index).
+
+predicate_table_get_preds(PredicateTable, PredicateTable ^ preds).
+
+predicate_table_set_preds(Preds, PredicateTable,
+    PredicateTable ^ preds := Preds).
+
+predicate_table_get_predids(PredicateTable, PredicateTable ^ pred_ids).
+
+predicate_table_remove_predid(PredId, PredicateTable0, PredicateTable) :-
+    list.delete_all(PredicateTable0 ^ pred_ids, PredId, PredIds),
+    PredicateTable = PredicateTable0 ^ pred_ids := PredIds.
+
+predicate_table_remove_predicate(PredId, PredicateTable0, PredicateTable) :-
+    PredicateTable0 = predicate_table(Preds0, NextPredId, PredIds0,
+        AccessibilityTable0,
+        PredN0, PredNA0, PredMNA0, FuncN0, FuncNA0, FuncMNA0),
+    list.delete_all(PredIds0, PredId, PredIds),
+    map.det_remove(Preds0, PredId, PredInfo, Preds),
+    map.det_remove(AccessibilityTable0, PredId, _, AccessibilityTable),
+    Module = pred_info_module(PredInfo),
+    Name = pred_info_name(PredInfo),
+    Arity = pred_info_orig_arity(PredInfo),
+    IsPredOrFunc = pred_info_is_pred_or_func(PredInfo),
+    (
+        IsPredOrFunc = predicate,
+        predicate_table_remove_from_index(Module, Name, Arity, PredId,
+            PredN0, PredN, PredNA0, PredNA, PredMNA0, PredMNA),
+        PredicateTable = predicate_table(Preds, NextPredId, PredIds,
+            AccessibilityTable,
+            PredN, PredNA, PredMNA, FuncN0, FuncNA0, FuncMNA0)
+    ;
+        IsPredOrFunc = function,
+        FuncArity = Arity - 1,
+        predicate_table_remove_from_index(Module, Name, FuncArity,
+            PredId, FuncN0, FuncN, FuncNA0, FuncNA,
+            FuncMNA0, FuncMNA),
+        PredicateTable = predicate_table(Preds, NextPredId, PredIds,
+            AccessibilityTable,
+            PredN0, PredNA0, PredMNA0, FuncN, FuncNA, FuncMNA)
+    ).
+
+:- pred predicate_table_remove_from_index(module_name::in, string::in, int::in,
+    pred_id::in, name_index::in, name_index::out,
+    name_arity_index::in, name_arity_index::out,
+    module_name_arity_index::in, module_name_arity_index::out) is det.
+
+predicate_table_remove_from_index(Module, Name, Arity, PredId,
+        !N, !NA, !MNA) :-
+    do_remove_from_index(Name, PredId, !N),
+    do_remove_from_index(Name / Arity, PredId, !NA),
+    do_remove_from_m_n_a_index(Module, Name, Arity, PredId, !MNA).
+
+:- pred do_remove_from_index(T::in, pred_id::in,
+    map(T, list(pred_id))::in, map(T, list(pred_id))::out) is det.
+
+do_remove_from_index(T, PredId, Index0, Index) :-
+    ( map.search(Index0, T, NamePredIds0) ->
+        list.delete_all(NamePredIds0, PredId, NamePredIds),
+        (
+            NamePredIds = [],
+            map.delete(Index0, T, Index)
+        ;
+            NamePredIds = [_ | _],
+            map.det_update(Index0, T, NamePredIds, Index)
+        )
+    ;
+        Index = Index0
+    ).
+
+:- pred do_remove_from_m_n_a_index(module_name::in, string::in, int::in,
+    pred_id::in, module_name_arity_index::in, module_name_arity_index::out)
+    is det.
+
+do_remove_from_m_n_a_index(Module, Name, Arity, PredId, MNA0, MNA) :-
+    map.lookup(MNA0, Module - Name, Arities0),
+    map.lookup(Arities0, Arity, PredIds0),
+    list.delete_all(PredIds0, PredId, PredIds),
+    (
+        PredIds = [],
+        map.delete(Arities0, Arity, Arities),
+        ( map.is_empty(Arities) ->
+            map.delete(MNA0, Module - Name, MNA)
+        ;
+            map.det_update(MNA0, Module - Name, Arities, MNA)
+        )
+    ;
+        PredIds = [_ | _],
+        map.det_update(Arities0, Arity, PredIds, Arities),
+        map.det_update(MNA0, Module - Name, Arities, MNA)
+    ).
+
+%-----------------------------------------------------------------------------%
+
+predicate_table_reverse_predids(PredicateTable0, PredicateTable) :-
+    list.reverse(PredicateTable0 ^ pred_ids, PredIds),
+    PredicateTable = PredicateTable0 ^ pred_ids := PredIds.
+
+%-----------------------------------------------------------------------------%
+
+predicate_table_search_sym(PredicateTable, may_be_partially_qualified,
+        unqualified(Name), PredIdList) :-
+    predicate_table_search_name(PredicateTable, Name, PredIdList).
+predicate_table_search_sym(PredicateTable, IsFullyQualified,
+        qualified(Module, Name), PredIdList) :-
+    predicate_table_search_module_name(PredicateTable, IsFullyQualified,
+        Module, Name, PredIdList),
+    PredIdList = [_ | _].
+
+predicate_table_search_pred_sym(PredicateTable, may_be_partially_qualified,
+        unqualified(Name), PredIdList) :-
+    predicate_table_search_pred_name(PredicateTable, Name, PredIdList).
+predicate_table_search_pred_sym(PredicateTable, IsFullyQualified,
+        qualified(Module, Name), PredIdList) :-
+    predicate_table_search_pred_module_name(PredicateTable,
+        IsFullyQualified, Module, Name, PredIdList),
+    PredIdList = [_ | _].
+
+predicate_table_search_func_sym(PredicateTable, may_be_partially_qualified,
+        unqualified(Name), PredIdList) :-
+    predicate_table_search_func_name(PredicateTable, Name, PredIdList).
+predicate_table_search_func_sym(PredicateTable, IsFullyQualified,
+        qualified(Module, Name), PredIdList) :-
+    predicate_table_search_func_module_name(PredicateTable,
+        IsFullyQualified, Module, Name, PredIdList),
+    PredIdList = [_ | _].
+
+%-----------------------------------------------------------------------------%
+
+predicate_table_search_sym_arity(PredicateTable, IsFullyQualified,
+        qualified(Module, Name), Arity, PredIdList) :-
+    predicate_table_search_m_n_a(PredicateTable,
+        IsFullyQualified, Module, Name, Arity, PredIdList).
+predicate_table_search_sym_arity(PredicateTable, may_be_partially_qualified,
+        unqualified(Name), Arity, PredIdList) :-
+    predicate_table_search_name_arity(PredicateTable, Name, Arity, PredIdList).
+
+predicate_table_search_pred_sym_arity(PredicateTable, IsFullyQualified,
+        qualified(Module, Name), Arity, PredIdList) :-
+    predicate_table_search_pred_m_n_a(PredicateTable,
+        IsFullyQualified, Module, Name, Arity, PredIdList).
+predicate_table_search_pred_sym_arity(PredicateTable,
+        may_be_partially_qualified, unqualified(Name),
+        Arity, PredIdList) :-
+    predicate_table_search_pred_name_arity(PredicateTable, Name, Arity,
+        PredIdList).
+
+predicate_table_search_func_sym_arity(PredicateTable, IsFullyQualified,
+        qualified(Module, Name), Arity, PredIdList) :-
+    predicate_table_search_func_m_n_a(PredicateTable,
+        IsFullyQualified, Module, Name, Arity, PredIdList).
+predicate_table_search_func_sym_arity(PredicateTable,
+        may_be_partially_qualified, unqualified(Name),
+        Arity, PredIdList) :-
+    predicate_table_search_func_name_arity(PredicateTable, Name, Arity,
+        PredIdList).
+
+%-----------------------------------------------------------------------------%
+
+predicate_table_search_name(PredicateTable, Name, PredIds) :-
+    ( predicate_table_search_pred_name(PredicateTable, Name, PredPredIds0) ->
+        PredPredIds = PredPredIds0
+    ;
+        PredPredIds = []
+    ),
+    ( predicate_table_search_func_name(PredicateTable, Name, FuncPredIds0) ->
+        FuncPredIds = FuncPredIds0
+    ;
+        FuncPredIds = []
+    ),
+    list.append(FuncPredIds, PredPredIds, PredIds),
+    PredIds = [_ | _].
+
+predicate_table_search_pred_name(PredicateTable, PredName, PredIds) :-
+    map.search(PredicateTable ^ pred_name_index, PredName, PredIds).
+
+predicate_table_search_func_name(PredicateTable, FuncName, PredIds) :-
+    map.search(PredicateTable ^ func_name_index, FuncName, PredIds).
+
+%-----------------------------------------------------------------------------%
+
+:- pred predicate_table_search_module_name(predicate_table::in,
+    is_fully_qualified::in, module_name::in, string::in,
+    list(pred_id)::out) is semidet.
+
+predicate_table_search_module_name(PredicateTable, IsFullyQualified,
+        Module, Name, PredIds) :-
+    (
+        predicate_table_search_pred_module_name(PredicateTable,
+            IsFullyQualified, Module, Name, PredPredIds0)
+    ->
+        PredPredIds = PredPredIds0
+    ;
+        PredPredIds = []
+    ),
+    (
+        predicate_table_search_func_module_name(PredicateTable,
+            IsFullyQualified, Module, Name, FuncPredIds0)
+    ->
+        FuncPredIds = FuncPredIds0
+    ;
+        FuncPredIds = []
+    ),
+    list.append(FuncPredIds, PredPredIds, PredIds),
+    PredIds = [_ | _].
+
+:- pred predicate_table_search_pred_module_name(predicate_table::in,
+    is_fully_qualified::in, module_name::in, string::in,
+    list(pred_id)::out) is semidet.
+
+predicate_table_search_pred_module_name(PredicateTable, IsFullyQualified,
+        Module, PredName, PredIds) :-
+    Pred_MNA_Index = PredicateTable ^ pred_module_name_arity_index,
+    map.search(Pred_MNA_Index, Module - PredName, Arities),
+    map.values(Arities, PredIdLists),
+    list.condense(PredIdLists, PredIds0),
+    maybe_filter_pred_ids_matching_module(IsFullyQualified,
+        Module, PredicateTable, PredIds0, PredIds).
+
+:- pred predicate_table_search_func_module_name(predicate_table::in,
+    is_fully_qualified::in, module_name::in, string::in,
+    list(pred_id)::out) is semidet.
+
+predicate_table_search_func_module_name(PredicateTable, IsFullyQualified,
+        Module, FuncName, PredIds) :-
+    Func_MNA_Index = PredicateTable ^ func_module_name_arity_index,
+    map.search(Func_MNA_Index, Module - FuncName, Arities),
+    map.values(Arities, PredIdLists),
+    list.condense(PredIdLists, PredIds0),
+    maybe_filter_pred_ids_matching_module(IsFullyQualified,
+        Module, PredicateTable, PredIds0, PredIds).
+
+%-----------------------------------------------------------------------------%
+
+predicate_table_search_name_arity(PredicateTable, Name, Arity, PredIds) :-
+    (
+        predicate_table_search_pred_name_arity(PredicateTable,
+            Name, Arity, PredPredIds0)
+    ->
+        PredPredIds = PredPredIds0
+    ;
+        PredPredIds = []
+    ),
+    (
+        predicate_table_search_func_name_arity(PredicateTable,
+            Name, Arity, FuncPredIds0)
+    ->
+        FuncPredIds = FuncPredIds0
+    ;
+        FuncPredIds = []
+    ),
+    list.append(FuncPredIds, PredPredIds, PredIds),
+    PredIds = [_ | _].
+
+predicate_table_search_pred_name_arity(PredicateTable, PredName, Arity,
+        PredIds) :-
+    PredNameArityIndex = PredicateTable ^ pred_name_arity_index,
+    map.search(PredNameArityIndex, PredName / Arity, PredIds).
+
+predicate_table_search_func_name_arity(PredicateTable, FuncName, Arity,
+        PredIds) :-
+    FuncNameArityIndex = PredicateTable ^ func_name_arity_index,
+    map.search(FuncNameArityIndex, FuncName / Arity, PredIds).
+
+%-----------------------------------------------------------------------------%
+
+predicate_table_search_m_n_a(PredicateTable, IsFullyQualified,
+        Module, Name, Arity, PredIds) :-
+    (
+        predicate_table_search_pred_m_n_a(PredicateTable,
+            IsFullyQualified, Module, Name, Arity, PredPredIds0)
+    ->
+        PredPredIds = PredPredIds0
+    ;
+        PredPredIds = []
+    ),
+    (
+        predicate_table_search_func_m_n_a(PredicateTable,
+            IsFullyQualified, Module, Name, Arity, FuncPredIds0)
+    ->
+        FuncPredIds = FuncPredIds0
+    ;
+        FuncPredIds = []
+    ),
+    list.append(FuncPredIds, PredPredIds, PredIds),
+    PredIds = [_ | _].
+
+predicate_table_search_pred_m_n_a(PredicateTable, IsFullyQualified,
+        Module, PredName, Arity, !:PredIds) :-
+    P_MNA_Index = PredicateTable ^ pred_module_name_arity_index,
+    map.search(P_MNA_Index, Module - PredName, ArityIndex),
+    map.search(ArityIndex, Arity, !:PredIds),
+    maybe_filter_pred_ids_matching_module(IsFullyQualified, Module,
+        PredicateTable, !PredIds).
+
+predicate_table_search_func_m_n_a(PredicateTable, IsFullyQualified,
+        Module, FuncName, Arity, !:PredIds) :-
+    F_MNA_Index = PredicateTable ^ func_module_name_arity_index,
+    map.search(F_MNA_Index, Module - FuncName, ArityIndex),
+    map.search(ArityIndex, Arity, !:PredIds),
+    maybe_filter_pred_ids_matching_module(IsFullyQualified, Module,
+        PredicateTable, !PredIds).
+
+:- pred maybe_filter_pred_ids_matching_module(is_fully_qualified::in,
+    module_name::in, predicate_table::in, list(pred_id)::in,
+    list(pred_id)::out) is det.
+
+maybe_filter_pred_ids_matching_module(may_be_partially_qualified, _, _,
+        !PredIds).
+maybe_filter_pred_ids_matching_module(is_fully_qualified, ModuleName,
+        PredicateTable, !PredIds) :-
+    predicate_table_get_preds(PredicateTable, Preds),
+    list.filter(pred_id_matches_module(Preds, ModuleName), !PredIds).
+
+:- pred pred_id_matches_module(pred_table::in, module_name::in, pred_id::in)
+    is semidet.
+
+pred_id_matches_module(Preds, ModuleName, PredId) :-
+    map.lookup(Preds, PredId, PredInfo),
+    ModuleName = pred_info_module(PredInfo).
+
+%-----------------------------------------------------------------------------%
+
+predicate_table_search_pf_m_n_a(PredicateTable, IsFullyQualified,
+        predicate, Module, Name, Arity, PredIds) :-
+    predicate_table_search_pred_m_n_a(PredicateTable, IsFullyQualified,
+        Module, Name, Arity, PredIds).
+predicate_table_search_pf_m_n_a(PredicateTable, IsFullyQualified,
+        function, Module, Name, Arity, PredIds) :-
+    FuncArity = Arity - 1,
+    predicate_table_search_func_m_n_a(PredicateTable, IsFullyQualified,
+        Module, Name, FuncArity, PredIds).
+
+predicate_table_search_pf_name_arity(PredicateTable, predicate, Name, Arity,
+        PredIds) :-
+    predicate_table_search_pred_name_arity(PredicateTable, Name, Arity,
+        PredIds).
+predicate_table_search_pf_name_arity(PredicateTable, function, Name, Arity,
+        PredIds) :-
+    FuncArity = Arity - 1,
+    predicate_table_search_func_name_arity(PredicateTable, Name, FuncArity,
+        PredIds).
+
+predicate_table_search_pf_sym_arity(PredicateTable, IsFullyQualified,
+        PredOrFunc, qualified(Module, Name), Arity, PredIdList) :-
+    predicate_table_search_pf_m_n_a(PredicateTable,
+        IsFullyQualified, PredOrFunc,
+        Module, Name, Arity, PredIdList).
+predicate_table_search_pf_sym_arity(PredicateTable, may_be_partially_qualified,
+        PredOrFunc, unqualified(Name), Arity, PredIdList) :-
+    predicate_table_search_pf_name_arity(PredicateTable, PredOrFunc,
+        Name, Arity, PredIdList).
+
+predicate_table_search_pf_sym(PredicateTable, IsFullyQualified, predicate,
+        SymName, PredIdList) :-
+    predicate_table_search_pred_sym(PredicateTable, IsFullyQualified,
+        SymName, PredIdList).
+predicate_table_search_pf_sym(PredicateTable, IsFullyQualified,
+        function, SymName, PredIdList) :-
+    predicate_table_search_func_sym(PredicateTable, IsFullyQualified,
+        SymName, PredIdList).
+
+%-----------------------------------------------------------------------------%
+
+predicate_table_restrict(PartialQualInfo, PredIds, OrigPredicateTable,
+        PredicateTable) :-
+    predicate_table_reset(OrigPredicateTable, PredicateTable0),
+    predicate_table_get_preds(OrigPredicateTable, Preds),
+    AccessibilityTable = OrigPredicateTable ^ accessibility_table,
+
+    % Note that we use foldr here rather than foldl, so that the PredIds list
+    % in the predicate table is the same as the PredIds list argument here
+    % (if we used foldl, it would get reversed, since each new predicate
+    % inserted into the table gets its pred_id added at the start of the list).
+    list.foldr(reinsert_for_restrict(PartialQualInfo, Preds,
+        AccessibilityTable), PredIds, PredicateTable0, PredicateTable).
+
+:- pred reinsert_for_restrict(partial_qualifier_info::in, pred_table::in,
+    accessibility_table::in, pred_id::in,
+    predicate_table::in, predicate_table::out) is det.
+
+reinsert_for_restrict(PartialQualInfo, Preds, AccessibilityTable, PredId,
+        !Table) :-
+    PredInfo = map.lookup(Preds, PredId),
+    Access = map.lookup(AccessibilityTable, PredId),
+    Access = access(Unqualified, PartiallyQualified),
+    (
+        Unqualified = yes,
+        NeedQual = may_be_unqualified
+    ;
+        Unqualified = no,
+        NeedQual = must_be_qualified
+    ),
+    (
+        PartiallyQualified = yes,
+        MaybeQualInfo = yes(PartialQualInfo)
+    ;
+        PartiallyQualified = no,
+        MaybeQualInfo = no
+    ),
+    predicate_table_insert_2(yes(PredId), PredInfo,
+        NeedQual, MaybeQualInfo, _, !Table).
+
+:- pred predicate_table_reset(predicate_table::in, predicate_table::out)
+    is det.
+
+predicate_table_reset(PredicateTable0, PredicateTable) :-
+    NextPredId = PredicateTable0 ^ next_pred_id,
+    PredicateTable = predicate_table(map.init, NextPredId, [], map.init,
+        map.init, map.init, map.init, map.init, map.init, map.init).
+
+%-----------------------------------------------------------------------------%
+
+predicate_table_insert(PredInfo, PredId, !PredicateTable) :-
+    predicate_table_insert_2(no, PredInfo, must_be_qualified, no, PredId,
+        !PredicateTable).
+
+predicate_table_insert(PredInfo, NeedQual, QualInfo, PredId,
+        !PredicateTable) :-
+    predicate_table_insert_2(no, PredInfo, NeedQual, yes(QualInfo), PredId,
+        !PredicateTable).
+
+:- pred predicate_table_insert_2(maybe(pred_id)::in, pred_info::in,
+    need_qualifier::in, maybe(partial_qualifier_info)::in, pred_id::out,
+    predicate_table::in, predicate_table::out) is det.
+
+predicate_table_insert_2(MaybePredId, PredInfo, NeedQual, MaybeQualInfo,
+        PredId, !PredicateTable) :-
+
+    !.PredicateTable = predicate_table(Preds0, NextPredId0, PredIds0,
+        AccessibilityTable0,
+        Pred_N_Index0, Pred_NA_Index0, Pred_MNA_Index0,
+        Func_N_Index0, Func_NA_Index0, Func_MNA_Index0),
+    Module = pred_info_module(PredInfo),
+    Name = pred_info_name(PredInfo),
+    Arity = pred_info_orig_arity(PredInfo),
+    (
+        MaybePredId = yes(PredId),
+        NextPredId = NextPredId0
+    ;
+        % Allocate a new pred_id.
+        MaybePredId = no,
+        PredId = NextPredId0,
+        hlds_pred.next_pred_id(PredId, NextPredId)
+    ),
+    % Insert the pred_id into either the function or predicate indices,
+    % as appropriate.
+    PredOrFunc = pred_info_is_pred_or_func(PredInfo),
+    (
+        PredOrFunc = predicate,
+        predicate_table_do_insert(Module, Name, Arity,
+            NeedQual, MaybeQualInfo, PredId,
+            AccessibilityTable0, AccessibilityTable,
+            Pred_N_Index0, Pred_N_Index,
+            Pred_NA_Index0, Pred_NA_Index,
+            Pred_MNA_Index0, Pred_MNA_Index),
+
+        Func_N_Index = Func_N_Index0,
+        Func_NA_Index = Func_NA_Index0,
+        Func_MNA_Index = Func_MNA_Index0
+    ;
+        PredOrFunc = function,
+        FuncArity = Arity - 1,
+        predicate_table_do_insert(Module, Name, FuncArity,
+            NeedQual, MaybeQualInfo, PredId,
+            AccessibilityTable0, AccessibilityTable,
+            Func_N_Index0, Func_N_Index,
+            Func_NA_Index0, Func_NA_Index,
+            Func_MNA_Index0, Func_MNA_Index),
+
+        Pred_N_Index = Pred_N_Index0,
+        Pred_NA_Index = Pred_NA_Index0,
+        Pred_MNA_Index = Pred_MNA_Index0
+    ),
+
+    % Insert the pred_id into the pred_id list.
+    PredIds = [PredId | PredIds0],
+
+    % Save the pred_info for this pred_id.
+    map.det_insert(Preds0, PredId, PredInfo, Preds),
+
+    !:PredicateTable = predicate_table(Preds, NextPredId, PredIds,
+        AccessibilityTable,
+        Pred_N_Index, Pred_NA_Index, Pred_MNA_Index,
+        Func_N_Index, Func_NA_Index, Func_MNA_Index).
+
+:- pred predicate_table_do_insert(module_name::in, string::in, arity::in,
+    need_qualifier::in, maybe(partial_qualifier_info)::in, pred_id::in,
+    accessibility_table::in, accessibility_table::out,
+    name_index::in, name_index::out,
+    name_arity_index::in, name_arity_index::out,
+    module_name_arity_index::in, module_name_arity_index::out) is det.
+
+predicate_table_do_insert(Module, Name, Arity, NeedQual, MaybeQualInfo,
+        PredId, !AccessibilityTable, !N_Index, !NA_Index, !MNA_Index) :-
+    (
+        NeedQual = may_be_unqualified,
+        % Insert the unqualified name into the name index.
+        svmulti_map.set(Name, PredId, !N_Index),
+
+        % Insert the unqualified name/arity into the name/arity index.
+        NA = Name / Arity,
+        svmulti_map.set(NA, PredId, !NA_Index),
+
+        AccessibleByUnqualifiedName = yes
+    ;
+        NeedQual = must_be_qualified,
+        AccessibleByUnqualifiedName = no
+    ),
+    (
+        MaybeQualInfo = yes(QualInfo),
+
+        % Insert partially module-qualified versions of the name into the
+        % module.name/arity index.
+        get_partial_qualifiers(Module, QualInfo, PartialQuals),
+        list.foldl((pred(AncModule::in, MNAs0::in, MNAs::out) is det :-
+                insert_into_mna_index(AncModule, Name, Arity, PredId,
+                    MNAs0, MNAs)
+            ), PartialQuals, !MNA_Index),
+
+        AccessibleByPartiallyQualifiedNames = yes
+    ;
+        MaybeQualInfo = no,
+        AccessibleByPartiallyQualifiedNames = no
+    ),
+    % Insert the fully-qualified name into the module.name/arity index.
+    insert_into_mna_index(Module, Name, Arity, PredId, !MNA_Index),
+    Access = access(AccessibleByUnqualifiedName,
+        AccessibleByPartiallyQualifiedNames),
+    svmap.set(PredId, Access, !AccessibilityTable).
+
+:- pred insert_into_mna_index(module_name::in, string::in, arity::in,
+    pred_id::in, module_name_arity_index::in,
+    module_name_arity_index::out) is det.
+
+insert_into_mna_index(Module, Name, Arity, PredId, !MNA_Index) :-
+    ( map.search(!.MNA_Index, Module - Name, MN_Arities0) ->
+        multi_map.set(MN_Arities0, Arity, PredId, MN_Arities),
+        svmap.det_update(Module - Name, MN_Arities, !MNA_Index)
+    ;
+        map.init(MN_Arities0),
+        map.det_insert(MN_Arities0, Arity, [PredId], MN_Arities),
+        svmap.det_insert(Module - Name, MN_Arities, !MNA_Index)
+    ).
+
+%-----------------------------------------------------------------------------%
+
+resolve_pred_overloading(ModuleInfo, CallerMarkers, ArgTypes, TVarSet,
+        PredName0, PredName, PredId) :-
+    % Note: calls to preds declared in `.opt' files should always be
+    % module qualified, so they should not be considered
+    % when resolving overloading.
+
+    module_info_get_predicate_table(ModuleInfo, PredTable),
+    (
+        predicate_table_search_pred_sym(PredTable,
+            calls_are_fully_qualified(CallerMarkers), PredName0, PredIds0)
+    ->
+        PredIds = PredIds0
+    ;
+        PredIds = []
+    ),
+
+    % Check if there any of the candidate pred_ids have argument/return types
+    % which subsume the actual argument/return types of this function call.
+    (
+        find_matching_pred_id(ModuleInfo, PredIds, TVarSet, ArgTypes,
+            no, PredId1, PredName1)
+    ->
+        PredId = PredId1,
+        PredName = PredName1
+    ;
+        % If there is no matching predicate for this call, then this predicate
+        % must have a type error which should have been caught by typechecking.
+        unexpected(this_file, "type error in pred call: no matching pred")
+    ).
+
+find_matching_pred_id(ModuleInfo, [PredId | PredIds], TVarSet, ArgTypes,
+        MaybeConstraintSearch, ThePredId, PredName) :-
+    (
+        % Lookup the argument types of the candidate predicate
+        % (or the argument types + return type of the candidate function).
+        %
+        module_info_pred_info(ModuleInfo, PredId, PredInfo),
+        pred_info_arg_types(PredInfo, PredTVarSet, PredExistQVars0,
+            PredArgTypes0),
+        pred_info_tvar_kinds(PredInfo, PredKindMap),
+
+        arg_type_list_subsumes(TVarSet, ArgTypes, PredTVarSet, PredKindMap,
+            PredExistQVars0, PredArgTypes0),
+
+        (
+            MaybeConstraintSearch = no
+        ;
+            MaybeConstraintSearch = yes(ConstraintSearch),
+            % Lookup the universal constraints on the condidate predicate.
+            pred_info_get_class_context(PredInfo, ProgConstraints),
+            ProgConstraints = constraints(UnivConstraints, _),
+            list.length(UnivConstraints, NumConstraints),
+            ConstraintSearch(NumConstraints, ProvenConstraints),
+            univ_constraints_match(ProvenConstraints, UnivConstraints)
+        )
+    ->
+        % We've found a matching predicate.
+        % Was there was more than one matching predicate/function?
+
+        PName = pred_info_name(PredInfo),
+        Module = pred_info_module(PredInfo),
+        PredName = qualified(Module, PName),
+        (
+            find_matching_pred_id(ModuleInfo, PredIds, TVarSet, ArgTypes,
+                MaybeConstraintSearch, _OtherPredId, _)
+        ->
+            % XXX this should report an error properly, not
+            % via error/1
+            unexpected(this_file, "Type error in predicate call: " ++
+                "unresolvable predicate overloading. " ++
+                "You need to use an explicit module qualifier. " ++
+                "Compile with -V to find out where.")
+        ;
+            ThePredId = PredId
+        )
+    ;
+        find_matching_pred_id(ModuleInfo, PredIds, TVarSet, ArgTypes,
+            MaybeConstraintSearch, ThePredId, PredName)
+    ).
+
+    % Check that the universal constraints proven in the caller match the
+    % constraints on the callee.
+    %
+    % XXX we should rename apart the callee constraints and check that the
+    % proven constraints are instances of them.  This would give us better
+    % overloading resolution.  For the moment, we just check that the names
+    % and arities match, which is sufficient to prevent any compiler aborts
+    % in later stages.
+    %
+:- pred univ_constraints_match(list(prog_constraint)::in,
+    list(prog_constraint)::in) is semidet.
+
+univ_constraints_match([], []).
+univ_constraints_match([ProvenConstraint | ProvenConstraints],
+        [CalleeConstraint | CalleeConstraints]) :-
+    ProvenConstraint = constraint(Name, ProvenArgs),
+    list.length(ProvenArgs, Arity),
+    CalleeConstraint = constraint(Name, CalleeArgs),
+    list.length(CalleeArgs, Arity),
+    univ_constraints_match(ProvenConstraints, CalleeConstraints).
+
+get_pred_id(IsFullyQualified, SymName, PredOrFunc, TVarSet,
+        ArgTypes, ModuleInfo, PredId) :-
+    module_info_get_predicate_table(ModuleInfo, PredicateTable),
+    list.length(ArgTypes, Arity),
+    (
+        predicate_table_search_pf_sym_arity(PredicateTable, IsFullyQualified,
+            PredOrFunc, SymName, Arity, PredIds),
+        % Resolve overloading using the argument types.
+        find_matching_pred_id(ModuleInfo, PredIds, TVarSet, ArgTypes, no,
+            PredId0, _PredName)
+    ->
+        PredId = PredId0
+    ;
+        % Undefined/invalid pred or func.
+        fail
+    ).
+
+get_pred_id_and_proc_id(IsFullyQualified, SymName, PredOrFunc, TVarSet,
+        ArgTypes, ModuleInfo, PredId, ProcId) :-
+    (
+        get_pred_id(IsFullyQualified, SymName, PredOrFunc, TVarSet,
+            ArgTypes, ModuleInfo, PredId0)
+    ->
+        PredId = PredId0
+    ;
+        % Undefined/invalid pred or func. The type-checker should ensure
+        % that this never happens
+        list.length(ArgTypes, Arity),
+        PredOrFuncStr = prog_out.pred_or_func_to_str(PredOrFunc),
+        mdbcomp.prim_data.sym_name_to_string(SymName, Name2),
+        string.int_to_string(Arity, ArityString),
+        string.append_list(["get_pred_id_and_proc_id: ",
+            "undefined/invalid ", PredOrFuncStr,
+            "\n`", Name2, "/", ArityString, "'"], Msg),
+        unexpected(this_file, Msg)
+    ),
+    get_proc_id(ModuleInfo, PredId, ProcId).
+
+get_proc_id(ModuleInfo, PredId, ProcId) :-
+    module_info_pred_info(ModuleInfo, PredId, PredInfo),
+    ProcIds = pred_info_procids(PredInfo),
+    ( ProcIds = [ProcId0] ->
+        ProcId = ProcId0
+    ;
+        Name = pred_info_name(PredInfo),
+        PredOrFunc = pred_info_is_pred_or_func(PredInfo),
+        Arity = pred_info_orig_arity(PredInfo),
+        PredOrFuncStr = prog_out.pred_or_func_to_str(PredOrFunc),
+        string.int_to_string(Arity, ArityString),
+        (
+            ProcIds = [],
+            string.append_list([
+                "cannot take address of ", PredOrFuncStr,
+                "\n`", Name, "/", ArityString, "' with no modes.\n",
+                "(Sorry, confused by earlier errors -- bailing out.)"],
+                Message)
+        ;
+            ProcIds = [_ | _],
+            string.append_list([
+                "sorry, not implemented: ",
+                "taking address of ", PredOrFuncStr,
+                "\n`", Name, "/", ArityString, "' with multiple modes.\n",
+                "(use an explicit lambda expression instead)"],
+                Message)
+        ),
+        unexpected(this_file, Message)
+    ).
+
+lookup_builtin_pred_proc_id(Module, ModuleName, ProcName, PredOrFunc,
+        Arity, ModeNo, PredId, ProcId) :-
+    module_info_get_predicate_table(Module, PredTable),
+    (
+        (
+            PredOrFunc = predicate,
+            predicate_table_search_pred_m_n_a(PredTable, is_fully_qualified,
+                ModuleName, ProcName, Arity, [PredId0])
+        ;
+            PredOrFunc = function,
+            predicate_table_search_func_m_n_a(PredTable, is_fully_qualified,
+                ModuleName, ProcName, Arity, [PredId0])
+        )
+    ->
+        PredId = PredId0
+    ;
+        % Some of the table builtins are polymorphic, and for them we need
+        % to subtract one from the arity to take into account the type_info
+        % argument. XXX The caller should supply us with the exact arity.
+        % Guessing how many of the arguments are typeinfos and/or
+        % typeclass_infos, as this code here does, is error-prone as well as
+        % inefficient.
+        (
+            PredOrFunc = predicate,
+            predicate_table_search_pred_m_n_a(PredTable, is_fully_qualified,
+                ModuleName, ProcName, Arity - 1, [PredId0])
+        ;
+            PredOrFunc = function,
+            predicate_table_search_func_m_n_a(PredTable, is_fully_qualified,
+                ModuleName, ProcName, Arity - 1, [PredId0])
+        )
+    ->
+        PredId = PredId0
+    ;
+        string.int_to_string(Arity, ArityS),
+        string.append_list(["can't locate ", ProcName, "/", ArityS],
+            ErrorMessage),
+        unexpected(this_file, ErrorMessage)
+    ),
+    module_info_pred_info(Module, PredId, PredInfo),
+    ProcIds = pred_info_procids(PredInfo),
+    (
+        ModeNo = only_mode,
+        ( ProcIds = [ProcId0] ->
+            ProcId = ProcId0
+        ;
+            unexpected(this_file,
+                string.format("expected single mode for %s/%d",
+                    [s(ProcName), i(Arity)]))
+        )
+    ;
+        ModeNo = mode_no(N),
+        ( list.index0(ProcIds, N, ProcId0) ->
+            ProcId = ProcId0
+        ;
+            unexpected(this_file,
+                string.format("there is no mode %d for %s/%d",
+                    [i(N), s(ProcName), i(Arity)]))
+        )
+    ).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "pred_table.m".
+
+%-----------------------------------------------------------------------------%
Index: compiler/proc_label.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/proc_label.m,v
retrieving revision 1.16
diff -u -b -r1.16 proc_label.m
--- compiler/proc_label.m	17 Mar 2006 01:40:36 -0000	1.16
+++ compiler/proc_label.m	22 Mar 2006 03:10:34 -0000
@@ -21,6 +21,7 @@
 
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
 
Index: compiler/prog_item.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_item.m,v
retrieving revision 1.9
diff -u -b -r1.9 prog_item.m
Index: compiler/prog_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_out.m,v
retrieving revision 1.68
diff -u -b -r1.68 prog_out.m
Index: compiler/purity.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/purity.m,v
retrieving revision 1.91
diff -u -b -r1.91 purity.m
--- compiler/purity.m	17 Mar 2006 01:40:38 -0000	1.91
+++ compiler/purity.m	22 Mar 2006 04:07:46 -0000
@@ -163,11 +163,13 @@
 :- import_module check_hlds.typecheck.
 :- import_module check_hlds.type_util.
 :- import_module check_hlds.unify_proc.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_error_util.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
@@ -462,8 +464,8 @@
     ModuleInfo = !.Info ^ module_info,
     (
         RunPostTypecheck = yes,
-        post_typecheck.resolve_pred_overloading(Vars, PredInfo,
-            ModuleInfo, Name0, Name, PredId0, PredId),
+        finally_resolve_pred_overloading(Vars, PredInfo, ModuleInfo,
+            Name0, Name, PredId0, PredId),
         (
             % Convert any calls to private_builtin.unsafe_type_cast
             % into unsafe_type_cast generic calls.
Index: compiler/recompilation.usage.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/recompilation.usage.m,v
retrieving revision 1.29
diff -u -b -r1.29 recompilation.usage.m
--- compiler/recompilation.usage.m	22 Mar 2006 06:28:06 -0000	1.29
+++ compiler/recompilation.usage.m	23 Mar 2006 01:03:29 -0000
@@ -88,6 +88,7 @@
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
Index: compiler/recompilation.version.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/recompilation.version.m,v
retrieving revision 1.41
diff -u -b -r1.41 recompilation.version.m
Index: compiler/rtti.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rtti.m,v
retrieving revision 1.67
diff -u -b -r1.67 rtti.m
--- compiler/rtti.m	17 Mar 2006 01:40:39 -0000	1.67
+++ compiler/rtti.m	22 Mar 2006 03:10:14 -0000
@@ -29,6 +29,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
 
Index: compiler/rtti_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rtti_out.m,v
retrieving revision 1.63
diff -u -b -r1.63 rtti_out.m
--- compiler/rtti_out.m	21 Mar 2006 02:33:36 -0000	1.63
+++ compiler/rtti_out.m	22 Mar 2006 03:37:15 -0000
@@ -105,6 +105,7 @@
 :- import_module hlds.code_model.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
Index: compiler/rtti_to_mlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rtti_to_mlds.m,v
retrieving revision 1.68
diff -u -b -r1.68 rtti_to_mlds.m
--- compiler/rtti_to_mlds.m	17 Mar 2006 01:40:39 -0000	1.68
+++ compiler/rtti_to_mlds.m	22 Mar 2006 03:38:29 -0000
@@ -63,6 +63,7 @@
 :- import_module hlds.code_model.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module libs.compiler_util.
 :- import_module mdbcomp.prim_data.
 :- import_module ml_backend.ml_closure_gen.
@@ -1314,8 +1315,7 @@
 %-----------------------------------------------------------------------------%
 
 :- pred gen_init_method(module_info::in, int::in, rtti_proc_label::in,
-    mlds_initializer::out, list(mlds_defn)::in, list(mlds_defn)::out)
-    is det.
+    mlds_initializer::out, list(mlds_defn)::in, list(mlds_defn)::out) is det.
 
 gen_init_method(ModuleInfo, NumExtra, RttiProcLabel, Init, !ExtraDefns) :-
     % We can't store the address of the typeclass method directly in the
Index: compiler/saved_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/saved_vars.m,v
retrieving revision 1.60
diff -u -b -r1.60 saved_vars.m
--- compiler/saved_vars.m	21 Mar 2006 22:25:29 -0000	1.60
+++ compiler/saved_vars.m	22 Mar 2006 03:17:50 -0000
@@ -46,6 +46,7 @@
 :- import_module hlds.goal_util.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.passes_aux.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.170
diff -u -b -r1.170 simplify.m
--- compiler/simplify.m	21 Mar 2006 22:25:29 -0000	1.170
+++ compiler/simplify.m	22 Mar 2006 03:49:03 -0000
@@ -37,6 +37,7 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module libs.globals.
 
@@ -105,6 +106,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_module.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
Index: compiler/size_prof.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/size_prof.m,v
retrieving revision 1.33
diff -u -b -r1.33 size_prof.m
--- compiler/size_prof.m	17 Mar 2006 01:40:40 -0000	1.33
+++ compiler/size_prof.m	22 Mar 2006 04:23:12 -0000
@@ -116,6 +116,8 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
+:- import_module hlds.hlds_rtti.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.112
diff -u -b -r1.112 stack_layout.m
--- compiler/stack_layout.m	17 Mar 2006 01:40:40 -0000	1.112
+++ compiler/stack_layout.m	22 Mar 2006 04:01:38 -0000
@@ -80,6 +80,7 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
@@ -88,8 +89,8 @@
 :- import_module ll_backend.code_util.
 :- import_module ll_backend.layout.
 :- import_module ll_backend.layout_out.
-:- import_module ll_backend.ll_pseudo_type_info.
 :- import_module ll_backend.llds_out.
+:- import_module ll_backend.ll_pseudo_type_info.
 :- import_module ll_backend.prog_rep.
 :- import_module ll_backend.trace.
 :- import_module mdbcomp.program_representation.
Index: compiler/table_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/table_gen.m,v
retrieving revision 1.103
diff -u -b -r1.103 table_gen.m
--- compiler/table_gen.m	17 Mar 2006 01:40:42 -0000	1.103
+++ compiler/table_gen.m	22 Mar 2006 05:31:27 -0000
@@ -5,10 +5,10 @@
 % This file may only be copied under the terms of the GNU General
 % Public License - see the file COPYING in the Mercury distribution.
 %-----------------------------------------------------------------------------%
-
+%
 % File: table_gen.m.
 % Main authors: zs, ohutch.
-
+%
 % This module transforms HLDS code to implement loop detection, memoing,
 % minimal model evaluation, or I/O idempotence. The transformation involves
 % adding calls to predicates defined in library/table_builtin.m and in
@@ -33,7 +33,7 @@
 % undesirable interactions with if-then-else, solutions, and (possibly)
 % negated contexts in general. However, the detection is done at runtime,
 % since there is no known way of doing this compile time.
-
+%
 %-----------------------------------------------------------------------------%
 
 :- module transform_hlds.table_gen.
@@ -71,6 +71,7 @@
 :- import_module hlds.hlds_pred.
 :- import_module hlds.instmap.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
@@ -176,7 +177,7 @@
         globals.lookup_bool_option(Globals, trace_table_io_all, TransformAll),
         globals.lookup_bool_option(Globals, trace_table_io_require, Require),
         proc_info_goal(ProcInfo0, BodyGoal),
-        predicate_module(!.ModuleInfo, PredId, PredModuleName),
+        PredModuleName = predicate_module(!.ModuleInfo, PredId),
         should_io_procedure_be_transformed(TransformAll, Require, BodyGoal,
             PredModuleName, AnnotationIsMissing, TransformPrimitive),
         (
Index: compiler/term_constr_errors.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_constr_errors.m,v
retrieving revision 1.2
diff -u -b -r1.2 term_constr_errors.m
Index: compiler/term_constr_pass2.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_constr_pass2.m,v
retrieving revision 1.3
diff -u -b -r1.3 term_constr_pass2.m
Index: compiler/term_constr_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/term_constr_util.m,v
retrieving revision 1.5
diff -u -b -r1.5 term_constr_util.m
Index: compiler/termination.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/termination.m,v
retrieving revision 1.61
diff -u -b -r1.61 termination.m
Index: compiler/transform_hlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/transform_hlds.m,v
retrieving revision 1.21
diff -u -b -r1.21 transform_hlds.m
--- compiler/transform_hlds.m	16 Dec 2005 12:17:55 -0000	1.21
+++ compiler/transform_hlds.m	22 Mar 2006 05:28:51 -0000
@@ -1,4 +1,6 @@
 %-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
 % Copyright (C) 2002-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.
Index: compiler/type_class_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/type_class_info.m,v
retrieving revision 1.16
diff -u -b -r1.16 type_class_info.m
--- compiler/type_class_info.m	17 Mar 2006 01:40:43 -0000	1.16
+++ compiler/type_class_info.m	22 Mar 2006 03:26:45 -0000
@@ -43,18 +43,19 @@
 
 :- implementation.
 
+:- import_module backend_libs.base_typeclass_info.
+:- import_module backend_libs.pseudo_type_info.
 :- import_module check_hlds.type_util.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_io.
 :- import_module parse_tree.prog_out.
-:- import_module backend_libs.pseudo_type_info.
-:- import_module backend_libs.base_typeclass_info.
 
 :- import_module assoc_list.
 :- import_module int.
Index: compiler/type_ctor_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/type_ctor_info.m,v
retrieving revision 1.74
diff -u -b -r1.74 type_ctor_info.m
--- compiler/type_ctor_info.m	17 Mar 2006 01:40:44 -0000	1.74
+++ compiler/type_ctor_info.m	22 Mar 2006 03:37:57 -0000
@@ -73,8 +73,9 @@
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.make_tags.
-:- import_module hlds.special_pred.
+:- import_module hlds.pred_table.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.388
diff -u -b -r1.388 typecheck.m
--- compiler/typecheck.m	17 Mar 2006 01:40:44 -0000	1.388
+++ compiler/typecheck.m	22 Mar 2006 04:10:09 -0000
@@ -111,12 +111,15 @@
 :- import_module check_hlds.typeclasses.
 :- import_module check_hlds.type_util.
 :- import_module hlds.goal_util.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_error_util.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/typecheck_errors.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck_errors.m,v
retrieving revision 1.15
diff -u -b -r1.15 typecheck_errors.m
--- compiler/typecheck_errors.m	17 Mar 2006 01:40:45 -0000	1.15
+++ compiler/typecheck_errors.m	22 Mar 2006 03:49:56 -0000
@@ -104,6 +104,7 @@
 :- import_module hlds.hlds_error_util.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
+:- import_module hlds.pred_table.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
Index: compiler/typecheck_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/typecheck_info.m,v
retrieving revision 1.7
diff -u -b -r1.7 typecheck_info.m
--- compiler/typecheck_info.m	17 Mar 2006 01:40:45 -0000	1.7
+++ compiler/typecheck_info.m	22 Mar 2006 02:23:57 -0000
@@ -22,6 +22,7 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.pred_table.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
 
Index: compiler/unify_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unify_gen.m,v
retrieving revision 1.161
diff -u -b -r1.161 unify_gen.m
--- compiler/unify_gen.m	17 Mar 2006 01:40:45 -0000	1.161
+++ compiler/unify_gen.m	22 Mar 2006 04:02:12 -0000
@@ -53,6 +53,7 @@
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
 :- import_module libs.options.
Index: compiler/unify_proc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unify_proc.m,v
retrieving revision 1.161
diff -u -b -r1.161 unify_proc.m
--- compiler/unify_proc.m	17 Mar 2006 01:40:45 -0000	1.161
+++ compiler/unify_proc.m	22 Mar 2006 03:21:26 -0000
@@ -48,10 +48,12 @@
 :- interface.
 
 :- import_module check_hlds.mode_info.
+:- import_module hlds.hlds_clauses.
 :- import_module hlds.hlds_data.
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_module.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.pred_table.
 :- import_module mdbcomp.prim_data.
 :- import_module parse_tree.prog_data.
 
@@ -148,6 +150,7 @@
 :- import_module hlds.instmap.
 :- import_module hlds.make_hlds.
 :- import_module hlds.quantification.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
 :- import_module libs.globals.
Index: compiler/unused_args.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/unused_args.m,v
retrieving revision 1.124
diff -u -b -r1.124 unused_args.m
--- compiler/unused_args.m	17 Mar 2006 01:40:46 -0000	1.124
+++ compiler/unused_args.m	22 Mar 2006 04:42:03 -0000
@@ -86,9 +86,11 @@
 :- import_module hlds.hlds_goal.
 :- import_module hlds.hlds_out.
 :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
 :- import_module hlds.instmap.
 :- import_module hlds.make_hlds.
 :- import_module hlds.passes_aux.
+:- import_module hlds.pred_table.
 :- import_module hlds.quantification.
 :- import_module hlds.special_pred.
 :- import_module libs.compiler_util.
@@ -1316,8 +1318,8 @@
         VeryVerbose = yes,
         PredProc = proc(PredId, ProcId),
         io.write_string("% Fixing up `", !IO),
-        predicate_name(!.ModuleInfo, PredId, Name),
-        predicate_arity(!.ModuleInfo, PredId, Arity),
+        Name = predicate_name(!.ModuleInfo, PredId),
+        Arity = predicate_arity(!.ModuleInfo, PredId),
         proc_id_to_int(ProcId, ProcInt),
         io.write_string(Name, !IO),
         io.write_string("/", !IO),
cvs diff: Diffing compiler/notes
Index: compiler/notes/compiler_design.html
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/notes/compiler_design.html,v
retrieving revision 1.114
diff -u -b -r1.114 compiler_design.html
--- compiler/notes/compiler_design.html	24 Feb 2006 01:42:09 -0000	1.114
+++ compiler/notes/compiler_design.html	22 Mar 2006 03:06:40 -0000
@@ -466,17 +466,27 @@
 by assigning tags to each functor.
 
 <p>
-The HLDS data structure itself is spread over four modules:
+The HLDS data structure itself is spread over the following modules:
 
 <ol>
-<li> hlds_data.m defines the parts of the HLDS concerned with
-	  function symbols, types, insts, modes and determinisms;
-<li> hlds_goal.m defines the part of the HLDS concerned with the
-	  structure of goals, including the annotations on goals;
-<li> hlds_pred.m defines the part of the HLDS concerning
-	  predicates and procedures;
-<li> hlds_module.m defines the top-level parts of the HLDS,
-	  including the type module_info.
+<li>
+hlds_data.m defines the parts of the HLDS concerned with
+function symbols, types, insts, modes and determinisms;
+<li>
+hlds_goal.m defines the part of the HLDS concerned with the
+structure of goals, including the annotations on goals;
+<li>
+hlds_clauses.m defines the part of the HLDS concerning clauses.
+<li>
+hlds_rtti.m defines the part of the HLDS concerning RTTI.
+<li>
+hlds_pred.m defines the part of the HLDS concerning predicates and procedures;
+<li>
+pred_table.m defines the tables that index predicates and functions
+on various combinations of (qualified and unqualified) names and arity.
+<li>
+hlds_module.m defines the top-level parts of the HLDS,
+including the type module_info.
 </ol>
 
 <p>
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
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/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
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/solver_types
cvs diff: Diffing extras/solver_types/library
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/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
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
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/trailing
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