[m-rev.] for review: debugging tabling procedures

Zoltan Somogyi zs at cs.mu.OZ.AU
Fri Nov 8 12:33:25 AEDT 2002


I want to include this change in the release. If this change is not
in the release, the people I am working with on minimal model tabling
(currently Kostis Sagonas and Peter Stuckey) will not be able to use
an installed release to compile a workspace on the minimal model tabling
branch in debugging grades.

The installation of this change will require workspaces compiled in debugging
grades to be recompiled. Workspaces compiled in non-debugging grades will not
be affected.

BTW, there is currently no check for duplicate pragma memos for the same
procedure. (This may also be true for other pragmas.) We should consider
adding a warning.

Zoltan

Extend the information we record about procedures when debugging is enabled
to include information about the tabling transformation, if the procedure
in question is tabled. This is useful to developers in debugging the tabling
mechanism, and can be useful to general users by helping them understand the
space (and hence time) costs of tabling.

Add a new mdb command "table" that uses this information to print
programmer-selected subsets of the tables of a tabled procedure.

compiler/hlds_pred.m:
	Generalize the existing field in procedures that used to hold
	information about I/O tabling to contain information about tabling
	in general, including forms other than I/O tabling.

compiler/continuation_info.m:
compiler/code_gen.m:
compiler/stack_layout.m:
	Conform to the changes in hlds_pred.m.

compiler/layout.m:
	Provide Mercury parallels for the new data structures in
	mercury_stack_layout.h.

compiler/layout_out.m:
	Generate the new data structures in mercury_stack_layout.h.

compiler/table_gen.m:
	Generate the new data structures in hlds_pred.m.

compiler/llds_common.m:
compiler/opt_debug.m:
	Conform to the changes in layout.m
 
compiler/llds_out.m:
	Abstract out existing code into a new procedure to make it available
	to layout_out.m.

	Make tabling pointer variables their natural type.

compiler/modules.m:
	Fix an old bug: implicitly import table_builtin.m in .mm grades.

doc/mdb_categories:
doc/user_guide.texi:
	Document the new mdb command "table".

runtime/mercury_types.h:
	Move some type definitions here from mercury_tabling.h and
	mercury_stack_layout.h. This was necessary to avoid problems with
	circular #includes, in which a.h #includes b.h to get access to a
	definition, but b.h #includes a.h, which is prevented by the macro
	guarding against duplicate definition, which causes syntax errors
	in the rest of b.h because the rest of b.h depends on typedefs in
	a.h that occur in a.h *after* the #include of b.h.

runtime/mercury_label.h:
	Adjust the list of #includes after the change to mercury_types.h.

runtime/mercury_stack_layout.h:
	Extend the debugging data structures with constructs that describe
	the call tables, answer tables and answer blocks of tabled procedures.

	Delete typedefs that are now in mercury_types.h.

runtime/mercury_tabling.[ch]:
	Add new functions to allow lookups without insertions in hash tables
	containing ints, floats and strings.

	Add new functions to return the entire contents of these hash tables.

	Change to four-space indentation where this wasn't done previously.

trace/mercury_trace_tables.[ch]:
	Rename MR_print_proc_id_for_debugger as MR_print_proc_id_and_nl,
	since this better describes what the function does.

trace/mercury_trace_util.[ch]:
	Add a new function MR_trace_is_integer that reads in signed integers.

	Rename MR_trace_is_number as MR_trace_is_natural_number, since the
	former would now be ambiguous.

	Add a new function MR_trace_is_float that reads in floating point
	values.

library/string.m:
	Document that MR_trace_is_float uses the same logic as
	MR_trace_is_float.

trace/mercury_trace_browse.c:
trace/mercury_trace_vars.c:
	Update calls to MR_trace_is_number.

trace/mercury_trace_internal.c:
	Implement the new mdb command "table".

	Update calls to MR_trace_is_number and to
	MR_print_proc_id_for_debugger.

tests/debugger/print_table.{m,inp,exp}:
	New test case to test the new mdb command.

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

	Disable the sensitive test cases in .mm grades.

tests/debugger/completion.exp:
	Update the expected output to include the new mdb command.

tests/debugger/mdb_command_test.inp:
	Update this automatically generated file to include the new mdb
	command.

cvs diff: Diffing .
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/code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_gen.m,v
retrieving revision 1.105
diff -u -b -r1.105 code_gen.m
--- compiler/code_gen.m	9 Sep 2002 07:48:09 -0000	1.105
+++ compiler/code_gen.m	5 Nov 2002 23:28:24 -0000
@@ -329,10 +329,10 @@
 		Instructions = Instructions0
 	),
 
-	proc_info_get_table_io_decl(ProcInfo, MaybeTableIoDecl),
+	proc_info_get_maybe_proc_table_info(ProcInfo, MaybeTableInfo),
 	(
 		( BasicStackLayout = yes
-		; MaybeTableIoDecl = yes(_TableIoDecl)
+		; MaybeTableInfo = yes(table_io_decl_info(_TableIoDeclInfo))
 		)
 	->
 			% Create the procedure layout structure.
@@ -362,7 +362,7 @@
 			Detism, TotalSlots, MaybeSuccipSlot, EvalMethod,
 			MaybeTraceCallLabel, MaxTraceReg, HeadVars, MaybeGoal,
 			InstMap0, TraceSlotInfo, ForceProcId, VarSet, VarTypes,
-			InternalMap, MaybeTableIoDecl, IsBeingTraced,
+			InternalMap, MaybeTableInfo, IsBeingTraced,
 			NeedsAllNames),
 		global_data_add_new_proc_layout(GlobalData0,
 			proc(PredId, ProcId), ProcLayout, GlobalData1)
Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.44
diff -u -b -r1.44 continuation_info.m
--- compiler/continuation_info.m	30 Aug 2002 07:22:37 -0000	1.44
+++ compiler/continuation_info.m	5 Nov 2002 23:28:24 -0000
@@ -116,13 +116,13 @@
 			internal_map	:: proc_label_layout_info,
 					% Info for each internal label,
 					% needed for basic_stack_layouts.
-			table_io_decl	:: maybe(table_io_decl_info),
+			maybe_table_info :: maybe(proc_table_info),
+			is_being_traced :: bool,
 					% True if the effective trace level
 					% of the procedure is not none.
-			is_being_traced :: bool,
+			need_all_names	:: bool
 					% True iff we need the names of all the
 					% variables.
-			need_all_names	:: bool
 		).
 
 	%
@@ -324,8 +324,8 @@
 	map(prog_var, set(lval))::in, proc_info::in,
 	map(tvar, set(layout_locn))::out) is det.
 
-:- pred continuation_info__generate_table_decl_io_layout(proc_info::in,
-	assoc_list(prog_var, int)::in, table_io_decl_info::out) is det.
+:- pred continuation_info__generate_table_arg_type_info(proc_info::in,
+	assoc_list(prog_var, int)::in, table_arg_infos::out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -766,39 +766,39 @@
 
 %---------------------------------------------------------------------------%
 
-continuation_info__generate_table_decl_io_layout(ProcInfo, NumberedVars,
-		TableIoDeclLayout) :-
+continuation_info__generate_table_arg_type_info(ProcInfo, NumberedVars,
+		TableArgInfos) :-
 	proc_info_vartypes(ProcInfo, VarTypes),
 	set__init(TypeVars0),
-	continuation_info__build_table_io_decl_arg_info(VarTypes,
+	continuation_info__build_table_arg_info(VarTypes,
 		NumberedVars, ArgLayouts, TypeVars0, TypeVars),
 	set__to_sorted_list(TypeVars, TypeVarsList),
-	continuation_info__find_typeinfos_for_tvars_table_io_decl(TypeVarsList,
+	continuation_info__find_typeinfos_for_tvars_table(TypeVarsList,
 		NumberedVars, ProcInfo, TypeInfoDataMap),
-	TableIoDeclLayout = table_io_decl_info(ArgLayouts, TypeInfoDataMap).
+	TableArgInfos = table_arg_infos(ArgLayouts, TypeInfoDataMap).
 
-:- pred continuation_info__build_table_io_decl_arg_info(vartypes::in,
-	assoc_list(prog_var, int)::in, list(table_io_decl_arg_info)::out,
+:- pred continuation_info__build_table_arg_info(vartypes::in,
+	assoc_list(prog_var, int)::in, list(table_arg_info)::out,
 	set(tvar)::in, set(tvar)::out) is det.
 
-continuation_info__build_table_io_decl_arg_info(_, [], [], TypeVars, TypeVars).
-continuation_info__build_table_io_decl_arg_info(VarTypes,
+continuation_info__build_table_arg_info(_, [], [], TypeVars, TypeVars).
+continuation_info__build_table_arg_info(VarTypes,
 		[Var - SlotNum | NumberedVars], [ArgLayout | ArgLayouts],
 		TypeVars0, TypeVars) :-
 	map__lookup(VarTypes, Var, Type),
-	ArgLayout = table_io_decl_arg_info(Var, SlotNum, Type),
+	ArgLayout = table_arg_info(Var, SlotNum, Type),
 	type_util__real_vars(Type, VarTypeVars),
 	set__insert_list(TypeVars0, VarTypeVars, TypeVars1),
-	continuation_info__build_table_io_decl_arg_info(VarTypes,
+	continuation_info__build_table_arg_info(VarTypes,
 		NumberedVars, ArgLayouts, TypeVars1, TypeVars).
 
 %---------------------------------------------------------------------------%
 
-:- pred continuation_info__find_typeinfos_for_tvars_table_io_decl(
+:- pred continuation_info__find_typeinfos_for_tvars_table(
 	list(tvar)::in, assoc_list(prog_var, int)::in, proc_info::in,
-	map(tvar, table_io_decl_locn)::out) is det.
+	map(tvar, table_locn)::out) is det.
 
-continuation_info__find_typeinfos_for_tvars_table_io_decl(TypeVars,
+continuation_info__find_typeinfos_for_tvars_table(TypeVars,
 		NumberedVars, ProcInfo, TypeInfoDataMap) :-
 	proc_info_varset(ProcInfo, VarSet),
 	proc_info_typeinfo_varmap(ProcInfo, TypeInfoMap),
@@ -823,7 +823,7 @@
 			type_info_locn_var(TypeInfoLocn, TypeInfoVar),
 			varset__lookup_name(VarSet, TypeInfoVar, VarString),
 			string__format("%s: %s %s",
-				[s("continuation_info__find_typeinfos_for_tvars_table_io_decl"),
+				[s("continuation_info__find_typeinfos_for_tvars_table"),
 				s("can't find slot for type_info var"),
 				s(VarString)], ErrStr),
 			error(ErrStr)
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.112
diff -u -b -r1.112 hlds_pred.m
--- compiler/hlds_pred.m	24 Oct 2002 04:36:43 -0000	1.112
+++ compiler/hlds_pred.m	6 Nov 2002 06:39:25 -0000
@@ -1566,8 +1566,8 @@
 					% left-to-right, from zero.)
 		).
 
-:- type table_io_decl_arg_info
-	--->	table_io_decl_arg_info(
+:- type table_arg_info
+	--->	table_arg_info(
 			headvar		:: prog_var,
 			slot_num	:: int,
 			arg_type	:: (type)
@@ -1576,14 +1576,49 @@
 	% This type is analogous to llds:layout_locn, but it refers to slots in
 	% the extended answer blocks used by I/O action tabling for declarative
 	% debugging, not to lvals.
-:- type table_io_decl_locn
+:- type table_locn
 	--->	direct(int)
 	;	indirect(int, int).
 
-:- type table_io_decl_info
+:- type table_trie_step
+	--->	table_trie_step_int
+	;	table_trie_step_char
+	;	table_trie_step_string
+	;	table_trie_step_float
+	;	table_trie_step_enum(int)
+	;	table_trie_step_user(type)
+	;	table_trie_step_poly.
+
+:- type table_arg_infos
+	--->	table_arg_infos(
+			list(table_arg_info),
+			map(tvar, table_locn)
+		).
+
+:- type proc_table_info
+
+		% The information we need to display an I/O action to the user.
+		%
+		% The table_arg_type_infos correspond one to one to the
+		% elements of the block saved for an I/O action. The first
+		% element will be the pointer to the proc_layout of the
+		% action's procedure.
 	--->	table_io_decl_info(
-			list(table_io_decl_arg_info),
-			map(tvar, table_io_decl_locn)
+			table_arg_infos
+		)
+
+		% The information we need to interpret the data structures
+		% created by tabling for a procedure, except the information
+		% (such as determinism) that is already available from
+		% proc_layout structures.
+		%
+		% The table_arg_type_infos list first all the input arguments,
+		% then all the output arguments.
+	;	table_gen_info(
+			num_inputs ::		int,
+			num_outputs ::		int,
+			input_steps ::		list(table_trie_step),
+			gen_arg_infos ::	table_arg_infos
 		).
 
 :- pred proc_info_init(arity, list(type), list(mode), maybe(list(mode)),
@@ -1781,12 +1816,12 @@
 :- pred proc_info_set_call_table_tip(proc_info, maybe(prog_var), proc_info).
 :- mode proc_info_set_call_table_tip(in, in, out) is det.
 
-:- pred proc_info_get_table_io_decl(proc_info, maybe(table_io_decl_info)).
-:- mode proc_info_get_table_io_decl(in, out) is det.
+:- pred proc_info_get_maybe_proc_table_info(proc_info, maybe(proc_table_info)).
+:- mode proc_info_get_maybe_proc_table_info(in, out) is det.
 
-:- pred proc_info_set_table_io_decl(proc_info, maybe(table_io_decl_info),
+:- pred proc_info_set_maybe_proc_table_info(proc_info, maybe(proc_table_info),
 	proc_info).
-:- mode proc_info_set_table_io_decl(in, in, out) is det.
+:- mode proc_info_set_maybe_proc_table_info(in, in, out) is det.
 
 :- pred proc_info_get_maybe_deep_profile_info(proc_info::in,
 	maybe(deep_profile_proc_info)::out) is det.
@@ -2024,18 +2059,26 @@
 					% relevant backend must record this
 					% fact in a place accessible to the
 					% debugger.
- 			table_io_decl	:: maybe(table_io_decl_info),
-					% If set, it means that procedure is an
-					% I/O primitive that has been subject
-					% to the --trace-table-decl-io
-					% transformation. The argument will
-					% then describe the structure of the
-					% answer block used by the transformed
-					% code. By putting this information
-					% into a data structure in the
-					% generated code, the compiler
-					% enables the runtime system to print
-					% out I/O action goals.
+ 			maybe_table_info :: maybe(proc_table_info),
+					% If set, it means that procedure
+					% has been subject to a tabling
+					% transformation, either I/O tabling
+					% or the regular kind. In the former
+					% case, the argument will contain all
+					% the information we need to display
+					% I/O actions involving this procedure;
+					% in the latter case, it will contain
+					% all the information we need to display
+					% the call tables, answer tables and
+					% answer blocks of the procedure.
+					% XXX For now, the compiler fully
+					% supports only procedures whose
+					% arguments are all builtin types,
+					% and the debugger further restricts
+					% this to procedures whose arguments
+					% are integers. However, this is still
+					% sufficient for debugging most
+					% problems in the tabling system.
 			maybe_deep_profile_proc_info
 					:: maybe(deep_profile_proc_info)
 		).
@@ -2201,7 +2244,7 @@
 proc_info_get_rl_exprn_id(ProcInfo, ProcInfo^maybe_aditi_rl_id).
 proc_info_get_need_maxfr_slot(ProcInfo, ProcInfo^need_maxfr_slot).
 proc_info_get_call_table_tip(ProcInfo, ProcInfo^call_table_tip).
-proc_info_get_table_io_decl(ProcInfo, ProcInfo^table_io_decl).
+proc_info_get_maybe_proc_table_info(ProcInfo, ProcInfo^maybe_table_info).
 proc_info_get_maybe_deep_profile_info(ProcInfo,
 	ProcInfo^maybe_deep_profile_proc_info).
 
@@ -2232,7 +2275,8 @@
 proc_info_set_rl_exprn_id(ProcInfo, ID, ProcInfo^maybe_aditi_rl_id := yes(ID)).
 proc_info_set_need_maxfr_slot(ProcInfo, NMS, ProcInfo^need_maxfr_slot := NMS).
 proc_info_set_call_table_tip(ProcInfo, CTT, ProcInfo^call_table_tip := CTT).
-proc_info_set_table_io_decl(ProcInfo, TID, ProcInfo^table_io_decl := TID).
+proc_info_set_maybe_proc_table_info(ProcInfo, MTI,
+	ProcInfo^maybe_table_info := MTI).
 proc_info_set_maybe_deep_profile_info(ProcInfo, DPI,
 	ProcInfo^maybe_deep_profile_proc_info := DPI).
 
Index: compiler/layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/layout.m,v
retrieving revision 1.9
diff -u -b -r1.9 layout.m
--- compiler/layout.m	29 Sep 2002 10:30:41 -0000	1.9
+++ compiler/layout.m	5 Nov 2002 23:28:24 -0000
@@ -32,8 +32,11 @@
 
 :- interface.
 
-:- import_module parse_tree__prog_data, libs__trace_params, ll_backend__llds.
-:- import_module backend_libs__rtti, hlds__hlds_goal.
+:- import_module parse_tree__prog_data.
+:- import_module hlds__hlds_goal, hlds__hlds_pred.
+:- import_module ll_backend__llds.
+:- import_module backend_libs__rtti.
+:- import_module libs__trace_params.
 :- import_module bool, std_util, list, assoc_list.
 
 :- type layout_data
@@ -82,6 +85,15 @@
 			table_io_decl_ptis	:: rval,
 						% pseudo-typeinfos for headvars
 			table_io_decl_type_params :: rval
+		)
+	;	table_gen_data(
+			table_gen_proc_ptr	:: rtti_proc_label,
+			table_gen_num_inputs	:: int,
+			table_gen_num_outputs	:: int,
+			table_gen_steps		:: list(table_trie_step),
+			table_gen_ptis		:: rval,
+						% pseudo-typeinfos for headvars
+			table_gen_type_params	:: rval
 		).
 
 :- type call_site_static_data			% defines MR_CallSiteStatic
@@ -141,7 +153,7 @@
 	--->	proc_layout_exec_trace(
 			call_label_layout	:: layout_name,
 			proc_body		:: maybe(rval),
-			maybe_table_io_decl	:: maybe(layout_name),
+			maybe_table_info	:: maybe(layout_name),
 			head_var_nums		:: list(int),
 						% The variable numbers of the
 						% head variables, including the
@@ -184,6 +196,9 @@
 		% A vector of variable names (represented as offsets into
 		% the string table) for a procedure layout structure.
 	;	table_io_decl(rtti_proc_label)
+	;	table_gen_info(rtti_proc_label)
+	;	table_gen_enum_params(rtti_proc_label)
+	;	table_gen_steps(rtti_proc_label)
 	;	closure_proc_id(proc_label, int, proc_label)
 	;	file_layout(module_name, int)
 	;	file_layout_line_number_vector(module_name, int)
Index: compiler/layout_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/layout_out.m,v
retrieving revision 1.16
diff -u -b -r1.16 layout_out.m
--- compiler/layout_out.m	29 Sep 2002 10:30:41 -0000	1.16
+++ compiler/layout_out.m	5 Nov 2002 23:28:24 -0000
@@ -111,6 +111,10 @@
 		PTIVectorRval, TypeParamsRval), DeclSet0, DeclSet) -->
 	output_table_io_decl(RttiProcLabel, Kind, NumPTIs,
 		PTIVectorRval, TypeParamsRval, DeclSet0, DeclSet).
+output_layout_data_defn(table_gen_data(RttiProcLabel, NumInputs, NumOutputs,
+		Steps, PTIVectorRval, TypeParamsRval), DeclSet0, DeclSet) -->
+	output_table_gen(RttiProcLabel, NumInputs, NumOutputs, Steps,
+		PTIVectorRval, TypeParamsRval, DeclSet0, DeclSet).
 
 %-----------------------------------------------------------------------------%
 
@@ -153,6 +157,9 @@
 extract_layout_name(table_io_decl_data(RttiProcLabel, _, _, _, _),
 		LayoutName) :-
 	LayoutName = table_io_decl(RttiProcLabel).
+extract_layout_name(table_gen_data(RttiProcLabel, _, _, _, _, _),
+		LayoutName) :-
+	LayoutName = table_gen_info(RttiProcLabel).
 
 :- pred output_layout_decls(list(layout_name)::in, decl_set::in, decl_set::out,
 	io__state::di, io__state::uo) is det.
@@ -267,6 +274,21 @@
 	io__write_string("_table_io_decl__"),
 	{ ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel) },
 	output_proc_label(ProcLabel).
+output_layout_name(table_gen_info(RttiProcLabel)) -->
+	io__write_string(mercury_data_prefix),
+	io__write_string("_table_gen__"),
+	{ ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel) },
+	output_proc_label(ProcLabel).
+output_layout_name(table_gen_enum_params(RttiProcLabel)) -->
+	io__write_string(mercury_data_prefix),
+	io__write_string("_table_enum_params__"),
+	{ ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel) },
+	output_proc_label(ProcLabel).
+output_layout_name(table_gen_steps(RttiProcLabel)) -->
+	io__write_string(mercury_data_prefix),
+	io__write_string("_table_steps__"),
+	{ ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel) },
+	output_proc_label(ProcLabel).
 
 output_layout_name_storage_type_name(label_layout(Label, LabelVars),
 		_BeingDefined) -->
@@ -364,6 +386,20 @@
 		_BeingDefined) -->
 	io__write_string("static const MR_Table_Io_Decl "),
 	output_layout_name(table_io_decl(RttiProcLabel)).
+output_layout_name_storage_type_name(table_gen_info(RttiProcLabel),
+		_BeingDefined) -->
+	io__write_string("static const MR_Table_Gen "),
+	output_layout_name(table_gen_info(RttiProcLabel)).
+output_layout_name_storage_type_name(table_gen_enum_params(RttiProcLabel),
+		_BeingDefined) -->
+	io__write_string("static const MR_Integer "),
+	output_layout_name(table_gen_enum_params(RttiProcLabel)),
+	io__write_string("[]").
+output_layout_name_storage_type_name(table_gen_steps(RttiProcLabel),
+		_BeingDefined) -->
+	io__write_string("static const MR_Table_Trie_Step "),
+	output_layout_name(table_gen_steps(RttiProcLabel)),
+	io__write_string("[]").
 
 layout_name_would_include_code_addr(label_layout(_, _)) = no.
 layout_name_would_include_code_addr(proc_layout(_, _)) = yes.
@@ -380,6 +416,9 @@
 layout_name_would_include_code_addr(proc_static(_)) = no.
 layout_name_would_include_code_addr(proc_static_call_sites(_)) = no.
 layout_name_would_include_code_addr(table_io_decl(_)) = no.
+layout_name_would_include_code_addr(table_gen_info(_)) = no.
+layout_name_would_include_code_addr(table_gen_enum_params(_)) = no.
+layout_name_would_include_code_addr(table_gen_steps(_)) = no.
 
 :- func label_vars_to_type(label_vars) = string.
 
@@ -424,7 +463,7 @@
 	{ LayoutName = label_layout(Label, LabelVars) },
 	output_layout_name_storage_type_name(LayoutName, yes),
 	io__write_string(" = {\n"),
-	io__write_string("\t(const MR_Proc_Layout *) &"),
+	io__write_string("\t(const MR_Proc_Layout *)\n\t\t&"),
 	output_layout_name(ProcLayoutAddr),
 	io__write_string(",\n\t"),
 	(
@@ -460,11 +499,11 @@
 		{ VarInfo = label_var_info(EncodedVarCount,
 			LocnsTypes, VarNums, TypeParams) },
 		io__write_int(EncodedVarCount),
-		io__write_string(",\n\t(const void *) "),
+		io__write_string(",\n\t(const void *)\n\t\t"),
 		output_rval(LocnsTypes),
-		io__write_string(",\n\t(const MR_uint_least16_t *) "),
+		io__write_string(",\n\t(const MR_uint_least16_t *)\n\t\t"),
 		output_rval(VarNums),
-		io__write_string(",\n\t(const MR_Type_Param_Locns *) "),
+		io__write_string(",\n\t(const MR_Type_Param_Locns *)\n\t\t"),
 		output_rval(TypeParams)
 	;
 		{ MaybeVarInfo = no },
@@ -646,7 +685,7 @@
 
 output_layout_exec_trace_decls(ProcLabel, ExecTrace, DeclSet0, DeclSet) -->
 	{ ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcBody,
-		MaybeTableIoDecl, _HeadVarNums, _VarNames, _MaxVarNum,
+		MaybeTableInfo, _HeadVarNums, _VarNames, _MaxVarNum,
 		_MaxRegNum, _MaybeFromFullSlot, _MaybeIoSeqSlot,
 		_MaybeTrailSlot, _MaybeMaxfrSlot, _EvalMethod,
 		_MaybeCallTableSlot) },
@@ -661,10 +700,10 @@
 		{ DeclSet3 = DeclSet2 }
 	),
 	(
-		{ MaybeTableIoDecl = yes(TableIoDeclName) },
-		output_layout_decl(TableIoDeclName, DeclSet3, DeclSet)
+		{ MaybeTableInfo = yes(TableInfo) },
+		output_layout_decl(TableInfo, DeclSet3, DeclSet)
 	;
-		{ MaybeTableIoDecl = no },
+		{ MaybeTableInfo = no },
 		{ DeclSet = DeclSet3 }
 	).
 
@@ -673,7 +712,7 @@
 
 output_layout_exec_trace_group(ProcLabel, ExecTrace) -->
 	{ ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcBody,
-		MaybeTableIoDecl, HeadVarNums, _VarNames, MaxVarNum,
+		MaybeTableInfo, HeadVarNums, _VarNames, MaxVarNum,
 		MaxRegNum, MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlot,
 		MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot) },
 	io__write_string("\t{\n\t(const MR_Label_Layout *) &"),
@@ -691,14 +730,23 @@
 	),
 	io__write_string(",\n\t"),
 	(
-		{ MaybeTableIoDecl = yes(TableIoDecl) },
+		{ MaybeCallTableSlot = yes(_) },
 		io__write_string("&"),
-		output_layout_name(TableIoDecl)
+		output_tabling_pointer_var_name(ProcLabel)
 	;
-		{ MaybeTableIoDecl = no },
+		{ MaybeCallTableSlot = no },
 		io__write_string("NULL")
 	),
-	io__write_string(",\n\t"),
+	io__write_string(",\n\t{ "),
+	(
+		{ MaybeTableInfo = yes(TableInfo) },
+		io__write_string("(const void *) &"),
+		output_layout_name(TableInfo)
+	;
+		{ MaybeTableInfo = no },
+		io__write_string("NULL")
+	),
+	io__write_string(" },\n\t"),
 	output_layout_name(proc_layout_head_var_nums(ProcLabel)),
 	io__write_string(",\n\t"),
 	output_layout_name(proc_layout_var_names(ProcLabel)),
@@ -1276,7 +1324,7 @@
 	io__state::di, io__state::uo) is det.
 
 output_table_io_decl(RttiProcLabel, ProcLayoutKind, NumPTIs,
-		PTIVectorRval, TypeParamRval, DeclSet0, DeclSet) -->
+		PTIVectorRval, TypeParamsRval, DeclSet0, DeclSet) -->
 	output_rval_decls(PTIVectorRval, "", "", 0, _, DeclSet0, DeclSet1),
 	{ LayoutName = table_io_decl(RttiProcLabel) },
 	{ ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel) },
@@ -1292,9 +1340,124 @@
 	io__write_string(",\n\t(const MR_PseudoTypeInfo *) "),
 	output_rval(PTIVectorRval),
 	io__write_string(",\n\t(const MR_Type_Param_Locns *) "),
-	output_rval(TypeParamRval),
+	output_rval(TypeParamsRval),
 	io__write_string("\n};\n"),
 	{ decl_set_insert(DeclSet2, data_addr(layout_addr(LayoutName)),
 		DeclSet) }.
+
+:- pred output_table_gen(rtti_proc_label::in, int::in, int::in,
+	list(table_trie_step)::in, rval::in, rval::in,
+	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+
+output_table_gen(RttiProcLabel, NumInputs, NumOutputs, Steps,
+		PTIVectorRval, TypeParamsRval, DeclSet0, DeclSet) -->
+	output_table_gen_steps_table(RttiProcLabel, Steps, MaybeEnumParams,
+		DeclSet0, DeclSet1),
+	output_table_gen_enum_params_table(RttiProcLabel, MaybeEnumParams,
+		DeclSet1, DeclSet2),
+	output_rval_decls(PTIVectorRval, "", "", 0, _, DeclSet2, DeclSet3),
+	{ LayoutName = table_gen_info(RttiProcLabel) },
+	io__write_string("\n"),
+	output_layout_name_storage_type_name(LayoutName, yes),
+	io__write_string(" = {\n\t"),
+	io__write_int(NumInputs),
+	io__write_string(",\n\t"),
+	io__write_int(NumOutputs),
+	io__write_string(",\n\t"),
+	output_layout_name(table_gen_steps(RttiProcLabel)),
+	io__write_string(",\n\t"),
+	output_layout_name(table_gen_enum_params(RttiProcLabel)),
+	io__write_string(",\n\t(const MR_PseudoTypeInfo *)\n\t\t"),
+	output_rval(PTIVectorRval),
+	io__write_string(",\n\t(const MR_Type_Param_Locns *)\n\t\t"),
+	output_rval(TypeParamsRval),
+	io__write_string("\n};\n"),
+	{ decl_set_insert(DeclSet3, data_addr(layout_addr(LayoutName)),
+		DeclSet) }.
+
+:- pred output_table_gen_steps_table(rtti_proc_label::in,
+	list(table_trie_step)::in, list(maybe(int))::out,
+	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+
+output_table_gen_steps_table(RttiProcLabel, Steps, MaybeEnumParams,
+		DeclSet0, DeclSet) -->
+	{ LayoutName = table_gen_steps(RttiProcLabel) },
+	io__write_string("\n"),
+	output_layout_name_storage_type_name(LayoutName, yes),
+	io__write_string(" = {\n"),
+	output_table_gen_steps(Steps, MaybeEnumParams),
+	io__write_string("};\n"),
+	{ decl_set_insert(DeclSet0, data_addr(layout_addr(LayoutName)),
+		DeclSet) }.
+
+:- pred output_table_gen_steps(list(table_trie_step)::in,
+	list(maybe(int))::out, io__state::di, io__state::uo) is det.
+
+output_table_gen_steps([], []) --> [].
+output_table_gen_steps([Step | Steps], [MaybeEnumParam | MaybeEnumParams]) -->
+	{
+		Step = table_trie_step_int,
+		StepType = "MR_TABLE_STEP_INT",
+		MaybeEnumParam = no
+	;
+		Step = table_trie_step_char,
+		StepType = "MR_TABLE_STEP_CHAR",
+		MaybeEnumParam = no
+	;
+		Step = table_trie_step_string,
+		StepType = "MR_TABLE_STEP_STRING",
+		MaybeEnumParam = no
+	;
+		Step = table_trie_step_float,
+		StepType = "MR_TABLE_STEP_FLOAT",
+		MaybeEnumParam = no
+	;
+		Step = table_trie_step_enum(EnumRange),
+		StepType = "MR_TABLE_STEP_ENUM",
+		MaybeEnumParam = yes(EnumRange)
+	;
+		Step = table_trie_step_user(_),
+		StepType = "MR_TABLE_STEP_USER",
+		MaybeEnumParam = no
+	;
+		Step = table_trie_step_poly,
+		StepType = "MR_TABLE_STEP_POLY",
+		MaybeEnumParam = no
+	},
+	io__write_string("\t"),
+	io__write_string(StepType),
+	io__write_string(",\n"),
+	output_table_gen_steps(Steps, MaybeEnumParams).
+
+:- pred output_table_gen_enum_params_table(rtti_proc_label::in,
+	list(maybe(int))::in, decl_set::in, decl_set::out,
+	io__state::di, io__state::uo) is det.
+
+output_table_gen_enum_params_table(RttiProcLabel, MaybeEnumParams,
+		DeclSet0, DeclSet) -->
+	{ LayoutName = table_gen_enum_params(RttiProcLabel) },
+	io__write_string("\n"),
+	output_layout_name_storage_type_name(LayoutName, yes),
+	io__write_string(" = {\n"),
+	output_table_gen_enum_params(MaybeEnumParams),
+	io__write_string("};\n"),
+	{ decl_set_insert(DeclSet0, data_addr(layout_addr(LayoutName)),
+		DeclSet) }.
+
+:- pred output_table_gen_enum_params(list(maybe(int))::in,
+	io__state::di, io__state::uo) is det.
+
+output_table_gen_enum_params([]) --> [].
+output_table_gen_enum_params([MaybeEnumParam | MaybeEnumParams]) -->
+	io__write_string("\t"),
+	(
+		{ MaybeEnumParam = no },
+		io__write_int(-1)
+	;
+		{ MaybeEnumParam = yes(EnumRange) },
+		io__write_int(EnumRange)
+	),
+	io__write_string(",\n"),
+	output_table_gen_enum_params(MaybeEnumParams).
 
 %-----------------------------------------------------------------------------%
Index: compiler/llds_common.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_common.m,v
retrieving revision 1.45
diff -u -b -r1.45 llds_common.m
--- compiler/llds_common.m	29 Sep 2002 10:30:41 -0000	1.45
+++ compiler/llds_common.m	5 Nov 2002 23:28:24 -0000
@@ -198,6 +198,13 @@
 	llds_common__process_rval(TVarLocnMap0, TVarLocnMap, Info1, Info),
 	LayoutData = table_io_decl_data(RttiProcLabel, Kind, NumPTIs,
 		PTIVector, TVarLocnMap).
+llds_common__process_layout_data(LayoutData0, LayoutData, Info0, Info) :-
+	LayoutData0 = table_gen_data(RttiProcLabel, NumInputs, NumOutputs,
+		Steps, PTIVector0, TVarLocnMap0),
+	llds_common__process_rval(PTIVector0, PTIVector, Info0, Info1),
+	llds_common__process_rval(TVarLocnMap0, TVarLocnMap, Info1, Info),
+	LayoutData = table_gen_data(RttiProcLabel, NumInputs, NumOutputs,
+		Steps, PTIVector, TVarLocnMap).
 
 :- pred llds_common__process_exec_trace(proc_layout_exec_trace::in,
 	proc_layout_exec_trace::out, common_info::in, common_info::out) is det.
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.201
diff -u -b -r1.201 llds_out.m
--- compiler/llds_out.m	29 Sep 2002 10:30:41 -0000	1.201
+++ compiler/llds_out.m	5 Nov 2002 23:28:24 -0000
@@ -223,6 +223,12 @@
 :- pred llds_out__make_rl_data_name(module_name, string).
 :- mode llds_out__make_rl_data_name(in, out) is det.
 
+	% Print out the name of the tabling variable for the specified
+	% procedure.
+
+:- pred output_tabling_pointer_var_name(proc_label::in,
+	io__state::di, io__state::uo) is det.
+
 	% The following are exported to rtti_out. It may be worthwhile
 	% to put these in a new module (maybe llds_out_util).
 
@@ -952,8 +958,9 @@
 	output_comp_gen_c_module_list(Modules, StackLayoutLabels,
 		DeclSet1, DeclSet).
 
-:- pred output_comp_gen_c_module(comp_gen_c_module::in, map(label, data_addr)::in,
-	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
+:- pred output_comp_gen_c_module(comp_gen_c_module::in,
+	map(label, data_addr)::in, decl_set::in, decl_set::out,
+	io__state::di, io__state::uo) is det.
 
 output_comp_gen_c_module(comp_gen_c_module(ModuleName, Procedures),
 		StackLayoutLabels, DeclSet0, DeclSet) -->
@@ -986,12 +993,16 @@
 
 output_comp_gen_c_var(tabling_pointer_var(ModuleName, ProcLabel),
 		DeclSet0, DeclSet) -->
-	io__write_string("\nMR_Word mercury_var__tabling__"),
-	output_proc_label(ProcLabel),
-	io__write_string(" = 0;\n"),
+	io__write_string("\nMR_TableNode "),
+	output_tabling_pointer_var_name(ProcLabel),
+	io__write_string(" = { 0 };\n"),
 	{ DataAddr = data_addr(ModuleName, tabling_pointer(ProcLabel)) },
 	{ decl_set_insert(DeclSet0, data_addr(DataAddr), DeclSet) }.
 
+output_tabling_pointer_var_name(ProcLabel) -->
+	io__write_string("mercury_var__table_root__"),
+	output_proc_label(ProcLabel).
+
 :- pred output_comp_gen_c_data_list(list(comp_gen_c_data)::in,
 	decl_set::in, decl_set::out, io__state::di, io__state::uo) is det.
 
@@ -3487,8 +3498,7 @@
 		output_base_typeclass_info_name(ClassId, TypeNames)
 	;
 		{ VarName = tabling_pointer(ProcLabel) },
-		io__write_string("mercury_var__tabling__"),
-		output_proc_label(ProcLabel)
+		output_tabling_pointer_var_name(ProcLabel)
 	;
 		{ VarName = deep_profiling_procedure_data(ProcLabel) },
 		io__write_string(mercury_data_prefix),
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.252
diff -u -b -r1.252 modules.m
--- compiler/modules.m	4 Nov 2002 04:03:34 -0000	1.252
+++ compiler/modules.m	5 Nov 2002 23:28:24 -0000
@@ -1965,11 +1965,12 @@
 	UseDeps1 = [MercuryPrivateBuiltin | UseDeps0],
 	(
 		%
-		% we should include MercuryTableBuiltin if
-		% the Items contain a tabling pragma, or if
-		% --trace-table-io is specified
+		% We should include MercuryTableBuiltin if the Items contain
+		% a tabling pragma, or if one of --use-minimal-model and
+		% --trace-table-io is specified.
 		%
 		( contains_tabling_pragma(Items)
+		; globals__lookup_bool_option(Globals, use_minimal_model, yes)
 		; globals__lookup_bool_option(Globals, trace_table_io, yes)
 		)
 	->
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.123
diff -u -b -r1.123 opt_debug.m
--- compiler/opt_debug.m	1 Aug 2002 11:52:21 -0000	1.123
+++ compiler/opt_debug.m	5 Nov 2002 23:28:24 -0000
@@ -495,6 +495,18 @@
 	ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel),
 	opt_debug__dump_proclabel(ProcLabel, ProcLabelStr),
 	string__append_list(["table_io_decl(", ProcLabelStr, ")"], Str).
+opt_debug__dump_layout_name(table_gen_info(RttiProcLabel), Str) :-
+	ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel),
+	opt_debug__dump_proclabel(ProcLabel, ProcLabelStr),
+	string__append_list(["table_gen_info(", ProcLabelStr, ")"], Str).
+opt_debug__dump_layout_name(table_gen_enum_params(RttiProcLabel), Str) :-
+	ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel),
+	opt_debug__dump_proclabel(ProcLabel, ProcLabelStr),
+	string__append_list(["table_gen_enum_params(", ProcLabelStr, ")"], Str).
+opt_debug__dump_layout_name(table_gen_steps(RttiProcLabel), Str) :-
+	ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel),
+	opt_debug__dump_proclabel(ProcLabel, ProcLabelStr),
+	string__append_list(["table_gen_steps(", ProcLabelStr, ")"], Str).
 
 opt_debug__dump_unop(mktag, "mktag").
 opt_debug__dump_unop(tag, "tag").
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.72
diff -u -b -r1.72 stack_layout.m
--- compiler/stack_layout.m	29 Sep 2002 10:30:43 -0000	1.72
+++ compiler/stack_layout.m	5 Nov 2002 23:28:24 -0000
@@ -95,7 +95,7 @@
 	list__foldl(stack_layout__construct_layouts, ProcLayoutList,
 		LayoutInfo2, LayoutInfo),
 	ModuleInfo = LayoutInfo ^ module_info,
-	TableIoDecls = LayoutInfo ^ table_io_decls,
+	TableIoDecls = LayoutInfo ^ table_infos,
 	ProcLayouts = LayoutInfo ^ proc_layouts,
 	InternalLayouts = LayoutInfo ^ internal_layouts,
 	LayoutLabels = LayoutInfo ^ label_set,
@@ -398,14 +398,14 @@
 	proc_label::in, determinism::in, int::in, maybe(int)::in,
 	eval_method::in, maybe(label)::in, int::in, list(prog_var)::in,
 	maybe(hlds_goal)::in, instmap::in, trace_slot_info::in, prog_varset::in,
-	vartypes::in, map(int, string)::in, maybe(table_io_decl_info)::in,
+	vartypes::in, map(int, string)::in, maybe(proc_table_info)::in,
 	proc_layout_kind::in, bool::in, stack_layout_info::in,
 	stack_layout_info::out) is det.
 
 stack_layout__construct_proc_layout(RttiProcLabel, EntryLabel, ProcLabel,
 		Detism, StackSlots, MaybeSuccipLoc, EvalMethod, MaybeCallLabel,
 		MaxTraceReg, HeadVars, MaybeGoal, InstMap, TraceSlotInfo,
-		VarSet, VarTypes, UsedVarNames, MaybeTableIoDeclInfo, Kind,
+		VarSet, VarTypes, UsedVarNames, MaybeTableInfo, Kind,
 		NeedsAllNames) -->
 	{
 		MaybeSuccipLoc = yes(Location)
@@ -466,7 +466,7 @@
 		stack_layout__construct_trace_layout(RttiProcLabel, EvalMethod,
 			MaybeCallLabel, MaxTraceReg, HeadVars, MaybeGoal,
 			InstMap, TraceSlotInfo, VarSet, VarTypes, UsedVarNames,
-			MaybeTableIoDeclInfo, NeedsAllNames, ExecTrace),
+			MaybeTableInfo, NeedsAllNames, ExecTrace),
 		{ MaybeRest = proc_id_and_exec_trace(ExecTrace) }
 	),
 
@@ -476,24 +476,24 @@
 	stack_layout__add_proc_layout_data(Data, LayoutName, EntryLabel),
 
 	(
-		{ MaybeTableIoDeclInfo = no }
+		{ MaybeTableInfo = no }
 	;
-		{ MaybeTableIoDeclInfo = yes(TableIoDeclInfo) },
-		stack_layout__make_table_io_decl_data(RttiProcLabel, Kind,
-			TableIoDeclInfo, TableIoDeclData),
-		stack_layout__add_table_io_decl_data(TableIoDeclData)
+		{ MaybeTableInfo = yes(TableInfo) },
+		stack_layout__make_table_data(RttiProcLabel, Kind,
+			TableInfo, TableData),
+		stack_layout__add_table_data(TableData)
 	).
 
 :- pred stack_layout__construct_trace_layout(rtti_proc_label::in,
 	eval_method::in, maybe(label)::in, int::in, list(prog_var)::in,
 	maybe(hlds_goal)::in, instmap::in, trace_slot_info::in, prog_varset::in,
-	vartypes::in, map(int, string)::in, maybe(table_io_decl_info)::in,
+	vartypes::in, map(int, string)::in, maybe(proc_table_info)::in,
 	bool::in, proc_layout_exec_trace::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__construct_trace_layout(RttiProcLabel, EvalMethod, MaybeCallLabel,
 		MaxTraceReg, HeadVars, MaybeGoal, InstMap, TraceSlotInfo,
-		VarSet, VarTypes, UsedVarNameMap, MaybeTableIoDecl,
+		VarSet, VarTypes, UsedVarNameMap, MaybeTableInfo,
 		NeedsAllNames, ExecTrace) -->
 	stack_layout__construct_var_name_vector(VarSet, UsedVarNameMap,
 		NeedsAllNames, MaxVarNum, VarNameVector),
@@ -525,14 +525,20 @@
 		% The label associated with an event must have variable info.
 	{ CallLabelLayout = label_layout(CallLabel, label_has_var_info) },
 	{
-		MaybeTableIoDecl = no,
-		MaybeTableIoDeclName = no
+		MaybeTableInfo = no,
+		MaybeTableName = no
 	;
-		MaybeTableIoDecl = yes(_),
-		MaybeTableIoDeclName = yes(table_io_decl(RttiProcLabel))
+		MaybeTableInfo = yes(TableInfo),
+		(
+			TableInfo = table_io_decl_info(_),
+			MaybeTableName = yes(table_io_decl(RttiProcLabel))
+		;
+			TableInfo = table_gen_info(_, _, _, _),
+			MaybeTableName = yes(table_gen_info(RttiProcLabel))
+		)
 	},
 	{ ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcRepRval,
-		MaybeTableIoDeclName, HeadVarNumVector, VarNameVector,
+		MaybeTableName, HeadVarNumVector, VarNameVector,
 		MaxVarNum, MaxTraceReg, MaybeFromFullSlot, MaybeIoSeqSlot,
 		MaybeTrailSlots, MaybeMaxfrSlot, EvalMethod,
 		MaybeCallTableSlot) }.
@@ -1091,17 +1097,42 @@
 
 %---------------------------------------------------------------------------%
 
-:- pred stack_layout__make_table_io_decl_data(rtti_proc_label::in,
-	proc_layout_kind::in, table_io_decl_info::in, layout_data::out,
+:- pred stack_layout__make_table_data(rtti_proc_label::in,
+	proc_layout_kind::in, proc_table_info::in, layout_data::out,
+	stack_layout_info::in, stack_layout_info::out) is det.
+
+stack_layout__make_table_data(RttiProcLabel, Kind, TableInfo,
+		TableData) -->
+	(
+		{ TableInfo = table_io_decl_info(TableArgInfo) },
+		stack_layout__convert_table_arg_info(TableArgInfo,
+			NumPTIs, PTIVectorRval, TVarVectorRval),
+		{ TableData = table_io_decl_data(RttiProcLabel, Kind,
+			NumPTIs, PTIVectorRval, TVarVectorRval) }
+	;
+		{ TableInfo = table_gen_info(NumInputs, NumOutputs, Steps,
+			TableArgInfo) },
+		stack_layout__convert_table_arg_info(TableArgInfo,
+			NumPTIs, PTIVectorRval, TVarVectorRval),
+		{ NumArgs = NumInputs + NumOutputs },
+		{ require(unify(NumArgs, NumPTIs),
+			"stack_layout__make_table_data: args mismatch") },
+		{ TableData = table_gen_data(RttiProcLabel,
+			NumInputs, NumOutputs, Steps,
+			PTIVectorRval, TVarVectorRval) }
+	).
+
+:- pred stack_layout__convert_table_arg_info(table_arg_infos::in,
+	int::out, rval::out, rval::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__make_table_io_decl_data(RttiProcLabel, Kind, TableIoDeclInfo,
-		TableIoDeclData) -->
-	{ TableIoDeclInfo = table_io_decl_info(SavedArgs, TVarSlotMap) },
-	{ list__length(SavedArgs, NumPTIs) },
+stack_layout__convert_table_arg_info(TableArgInfos, NumPTIs,
+		PTIVectorRval, TVarVectorRval) -->
+	{ TableArgInfos = table_arg_infos(Args, TVarSlotMap) },
+	{ list__length(Args, NumPTIs) },
 	stack_layout__get_cell_counter(C0),
-	{ list__map_foldl(stack_layout__construct_table_io_decl_arg_pti_rval,
-		SavedArgs, MaybePTIRvalTypes, C0, C1) },
+	{ list__map_foldl(stack_layout__construct_table_arg_pti_rval,
+		Args, MaybePTIRvalTypes, C0, C1) },
 	{ list__map(stack_layout__add_one, MaybePTIRvalTypes, PTITypes) },
 	{ assoc_list__keys(MaybePTIRvalTypes, MaybePTIRvals) },
 	{ PTIVectorTypes = initial(PTITypes, none) },
@@ -1109,17 +1140,15 @@
 	{ Reuse = no },
 	{ PTIVectorRval = create(0, MaybePTIRvals, PTIVectorTypes,
 		must_be_static, CNum,
-		"stack_layout_table_io_decl_ptis", Reuse) },
+		"stack_layout_table_ptis", Reuse) },
 	{ map__map_values(stack_layout__convert_slot_to_locn_map,
 		TVarSlotMap, TVarLocnMap) },
 	{ stack_layout__construct_tvar_vector(TVarLocnMap, TVarVectorRval,
 		C2, C) },
-	stack_layout__set_cell_counter(C),
-	{ TableIoDeclData = table_io_decl_data(RttiProcLabel, Kind, NumPTIs,
-		PTIVectorRval, TVarVectorRval) }.
+	stack_layout__set_cell_counter(C).
 
-:- pred stack_layout__convert_slot_to_locn_map(tvar::in,
-	table_io_decl_locn::in, set(layout_locn)::out) is det.
+:- pred stack_layout__convert_slot_to_locn_map(tvar::in, table_locn::in,
+	set(layout_locn)::out) is det.
 
 stack_layout__convert_slot_to_locn_map(_TVar, SlotLocn, LvalLocns) :-
 	(
@@ -1131,13 +1160,13 @@
 	),
 	LvalLocns = set__make_singleton_set(LvalLocn).
 
-:- pred stack_layout__construct_table_io_decl_arg_pti_rval(
-	table_io_decl_arg_info::in, pair(maybe(rval), llds_type)::out,
+:- pred stack_layout__construct_table_arg_pti_rval(
+	table_arg_info::in, pair(maybe(rval), llds_type)::out,
 	counter::in, counter::out) is det.
 
-stack_layout__construct_table_io_decl_arg_pti_rval(ClosureArg,
+stack_layout__construct_table_arg_pti_rval(ClosureArg,
 		yes(ArgRval) - ArgRvalType, C0, C) :-
-	ClosureArg = table_io_decl_arg_info(_, _, Type),
+	ClosureArg = table_arg_info(_, _, Type),
 	ExistQTvars = [],
 	NumUnivQTvars = -1,
 	ll_pseudo_type_info__construct_typed_llds_pseudo_type_info(Type,
@@ -1476,7 +1505,7 @@
 		trace_stack_layout	:: bool, % generate tracing info?
 		procid_stack_layout	:: bool, % generate proc id info?
 		static_code_addresses	:: bool, % have static code addresses?
-		table_io_decls		:: list(comp_gen_c_data),
+		table_infos		:: list(comp_gen_c_data),
 		proc_layouts		:: list(comp_gen_c_data),
 		internal_layouts	:: list(comp_gen_c_data),
 		label_set		:: map(label, data_addr),
@@ -1514,7 +1543,7 @@
 :- pred stack_layout__get_static_code_addresses(bool::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-:- pred stack_layout__get_table_io_decl_data(list(comp_gen_c_data)::out,
+:- pred stack_layout__get_table_infos(list(comp_gen_c_data)::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 :- pred stack_layout__get_proc_layout_data(list(comp_gen_c_data)::out,
@@ -1540,7 +1569,7 @@
 stack_layout__get_trace_stack_layout(LI ^ trace_stack_layout, LI, LI).
 stack_layout__get_procid_stack_layout(LI ^ procid_stack_layout, LI, LI).
 stack_layout__get_static_code_addresses(LI ^ static_code_addresses, LI, LI).
-stack_layout__get_table_io_decl_data(LI ^ table_io_decls, LI, LI).
+stack_layout__get_table_infos(LI ^ table_infos, LI, LI).
 stack_layout__get_proc_layout_data(LI ^ proc_layouts, LI, LI).
 stack_layout__get_internal_layout_data(LI ^ internal_layouts, LI, LI).
 stack_layout__get_label_set(LI ^ label_set, LI, LI).
@@ -1562,13 +1591,13 @@
 	stack_layout__get_module_info(ModuleInfo),
 	{ module_info_get_cell_counter(ModuleInfo, CellCounter) }.
 
-:- pred stack_layout__add_table_io_decl_data(layout_data::in,
+:- pred stack_layout__add_table_data(layout_data::in,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__add_table_io_decl_data(TableIoDeclData, LI0, LI) :-
-	TableIoDecls0 = LI0 ^ table_io_decls,
+stack_layout__add_table_data(TableIoDeclData, LI0, LI) :-
+	TableIoDecls0 = LI0 ^ table_infos,
 	TableIoDecls = [layout_data(TableIoDeclData) | TableIoDecls0],
-	LI = LI0 ^ table_io_decls := TableIoDecls.
+	LI = LI0 ^ table_infos := TableIoDecls.
 
 :- pred stack_layout__add_proc_layout_data(comp_gen_c_data::in,
 	layout_name::in, label::in,
Index: compiler/table_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/table_gen.m,v
retrieving revision 1.41
diff -u -b -r1.41 table_gen.m
--- compiler/table_gen.m	1 Nov 2002 07:06:58 -0000	1.41
+++ compiler/table_gen.m	5 Nov 2002 23:28:24 -0000
@@ -513,7 +513,7 @@
 		table_gen__create_new_io_goal(OrigGoal, Decl, Unitize,
 			TableIoStates, HeadVars, ArgModes, VarTypes0, VarTypes,
 			VarSet0, VarSet, TableInfo0, TableInfo, Goal,
-			MaybeTableIoDeclInfo),
+			MaybeProcTableInfo),
 		MaybeCallTableTip = no
 	;
 		(
@@ -521,22 +521,25 @@
 			table_gen__create_new_det_goal(EvalMethod, Detism,
 				OrigGoal, PredId, ProcId, HeadVars, ArgModes,
 				VarTypes0, VarTypes, VarSet0, VarSet,
-				TableInfo0, TableInfo, CallTableTip, Goal)
+				TableInfo0, TableInfo, CallTableTip, Goal,
+				ProcTableInfo)
 		;
 			CodeModel = model_semi,
 			table_gen__create_new_semi_goal(EvalMethod, Detism,
 				OrigGoal, PredId, ProcId, HeadVars, ArgModes,
 				VarTypes0, VarTypes, VarSet0, VarSet,
-				TableInfo0, TableInfo, CallTableTip, Goal)
+				TableInfo0, TableInfo, CallTableTip, Goal,
+				ProcTableInfo)
 		;
 			CodeModel = model_non,
 			table_gen__create_new_non_goal(EvalMethod, Detism,
 				OrigGoal, PredId, ProcId, HeadVars, ArgModes,
 				VarTypes0, VarTypes, VarSet0, VarSet,
-				TableInfo0, TableInfo, CallTableTip, Goal)
+				TableInfo0, TableInfo, CallTableTip, Goal,
+				ProcTableInfo)
 		),
 		MaybeCallTableTip = yes(CallTableTip),
-		MaybeTableIoDeclInfo = no
+		MaybeProcTableInfo = yes(ProcTableInfo)
 	),
 
 	table_info_extract(TableInfo, ModuleInfo1, _, _, PredInfo1, ProcInfo1),
@@ -547,7 +550,7 @@
 	proc_info_set_varset(ProcInfo2, VarSet, ProcInfo3),
 	proc_info_set_vartypes(ProcInfo3, VarTypes, ProcInfo4),
 	proc_info_set_call_table_tip(ProcInfo4, MaybeCallTableTip, ProcInfo5),
-	proc_info_set_table_io_decl(ProcInfo5, MaybeTableIoDeclInfo,
+	proc_info_set_maybe_proc_table_info(ProcInfo5, MaybeProcTableInfo,
 		ProcInfo6),
 
 	% Some of the instmap_deltas generated in this module
@@ -577,11 +580,11 @@
 	table_io_is_unitize::in, bool::in, list(prog_var)::in, list(mode)::in,
 	map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, table_info::in, table_info::out,
-	hlds_goal::out, maybe(table_io_decl_info)::out) is det.
+	hlds_goal::out, maybe(proc_table_info)::out) is det.
 
 table_gen__create_new_io_goal(OrigGoal, TableDecl, Unitize, TableIoStates,
 		HeadVars, HeadVarModes, VarTypes0, VarTypes, VarSet0, VarSet,
-		TableInfo0, TableInfo, Goal, MaybeTableIoDeclInfo) :-
+		TableInfo0, TableInfo, Goal, MaybeProcTableInfo) :-
 	OrigGoal = _ - OrigGoalInfo,
 	goal_info_get_nonlocals(OrigGoalInfo, OrigNonLocals),
 	goal_info_get_context(OrigGoalInfo, Context),
@@ -647,9 +650,10 @@
 		NumberedRestoreVars = NumberedSavedOutputVars,
 
 		ProcInfo0 = TableInfo0 ^ table_cur_proc_info,
-		continuation_info__generate_table_decl_io_layout(ProcInfo0,
-			NumberedSavedHeadVars, TableIoDeclInfo),
-		MaybeTableIoDeclInfo = yes(TableIoDeclInfo)
+		continuation_info__generate_table_arg_type_info(ProcInfo0,
+			NumberedSavedHeadVars, TableArgTypeInfo),
+		ProcTableInfo = table_io_decl_info(TableArgTypeInfo),
+		MaybeProcTableInfo = yes(ProcTableInfo)
 	;
 		TableDecl = table_io_proc,
 		VarTypes5 = VarTypes4,
@@ -659,7 +663,7 @@
 			NumberedSavedOutputVars),
 		NumberedRestoreVars = NumberedSavedOutputVars,
 		NumberedSaveVars = NumberedSavedOutputVars,
-		MaybeTableIoDeclInfo = no
+		MaybeProcTableInfo = no
 	),
 
 	list__length(NumberedSaveVars, BlockSize),
@@ -789,11 +793,11 @@
 	hlds_goal::in, pred_id::in, proc_id::in, list(prog_var)::in,
 	list(mode)::in, map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, table_info::in, table_info::out,
-	prog_var::out, hlds_goal::out) is det.
+	prog_var::out, hlds_goal::out, proc_table_info::out) is det.
 
 table_gen__create_new_det_goal(EvalMethod, Detism, OrigGoal, PredId, ProcId,
-		HeadVars, HeadVarModes, VarTypes0, VarTypes,
-		VarSet0, VarSet, TableInfo0, TableInfo, TableVar, Goal) :-
+		HeadVars, HeadVarModes, VarTypes0, VarTypes, VarSet0, VarSet,
+		TableInfo0, TableInfo, TableVar, Goal, ProcTableInfo) :-
 	% even if the original goal doesn't use all of the headvars,
 	% the code generated by the tabling transformation does,
 	% so we need to compute the nonlocals from the headvars rather
@@ -810,7 +814,7 @@
 
 	generate_simple_lookup_goal(InputVars, PredId, ProcId, Context,
 		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
-		TableVar, LookUpGoal),
+		TableVar, LookUpGoal, Steps),
 	generate_call("table_simple_is_complete", [TableVar], semidet,
 		yes(semipure), [], ModuleInfo, Context, CompleteCheckGoal),
 	allocate_slot_numbers(OutputVars, 0, NumberedOutputVars),
@@ -890,7 +894,9 @@
 	goal_info_init(OrigNonLocals, OrigInstMapDelta, det, Context,
 		GoalInfo0),
 	goal_info_add_feature(GoalInfo0, hide_debug_event, GoalInfo),
-	Goal = GoalEx - GoalInfo.
+	Goal = GoalEx - GoalInfo,
+	generate_gen_proc_table_info(TableInfo, Steps, InputVars, OutputVars,
+		ProcTableInfo).
 
 %-----------------------------------------------------------------------------%
 
@@ -901,11 +907,11 @@
 	hlds_goal::in, pred_id::in, proc_id::in, list(prog_var)::in,
 	list(mode)::in, map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, table_info::in, table_info::out,
-	prog_var::out, hlds_goal::out) is det.
+	prog_var::out, hlds_goal::out, proc_table_info::out) is det.
 
 table_gen__create_new_semi_goal(EvalMethod, Detism, OrigGoal, PredId, ProcId,
-		HeadVars, HeadVarModes, VarTypes0, VarTypes,
-		VarSet0, VarSet, TableInfo0, TableInfo, TableVar, Goal) :-
+		HeadVars, HeadVarModes, VarTypes0, VarTypes, VarSet0, VarSet,
+		TableInfo0, TableInfo, TableVar, Goal, ProcTableInfo) :-
 	% even if the original goal doesn't use all of the headvars,
 	% the code generated by the tabling transformation does,
 	% so we need to compute the nonlocals from the headvars rather
@@ -921,7 +927,7 @@
 
 	generate_simple_lookup_goal(InputVars, PredId, ProcId, Context,
 		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
-		TableVar, LookUpGoal),
+		TableVar, LookUpGoal, Steps),
 	generate_call("table_simple_is_complete", [TableVar], semidet,
 		yes(semipure), [], ModuleInfo, Context, CompleteCheckGoal),
 	allocate_slot_numbers(OutputVars, 0, NumberedOutputVars),
@@ -1071,7 +1077,9 @@
 	goal_info_init(OrigNonLocals, OrigInstMapDelta, semidet, Context,
 		GoalInfo0),
 	goal_info_add_feature(GoalInfo0, hide_debug_event, GoalInfo),
-	Goal = GoalEx - GoalInfo.
+	Goal = GoalEx - GoalInfo,
+	generate_gen_proc_table_info(TableInfo, Steps, InputVars, OutputVars,
+		ProcTableInfo).
 
 %-----------------------------------------------------------------------------%
 
@@ -1082,11 +1090,11 @@
 	hlds_goal::in, pred_id::in, proc_id::in, list(prog_var)::in,
 	list(mode)::in, map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, table_info::in, table_info::out,
-	prog_var::out, hlds_goal::out) is det.
+	prog_var::out, hlds_goal::out, proc_table_info::out) is det.
 
 table_gen__create_new_non_goal(EvalMethod, Detism, OrigGoal, PredId, ProcId,
-		HeadVars, HeadVarModes, VarTypes0, VarTypes,
-		VarSet0, VarSet, TableInfo0, TableInfo, TableVar, Goal) :-
+		HeadVars, HeadVarModes, VarTypes0, VarTypes, VarSet0, VarSet,
+		TableInfo0, TableInfo, TableVar, Goal, ProcTableInfo) :-
 	% even if the original goal doesn't use all of the headvars,
 	% the code generated by the tabling transformation does,
 	% so we need to compute the nonlocals from the headvars rather
@@ -1104,7 +1112,7 @@
 
 	generate_non_lookup_goal(InputVars, PredId, ProcId, Context,
 		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
-		TableVar, LookUpGoal),
+		TableVar, LookUpGoal, Steps),
 	generate_call("table_nondet_is_complete", [TableVar], semidet,
 		yes(semipure), [], ModuleInfo, Context, CompleteCheckGoal),
 	generate_non_save_goal(NumberedOutputVars, TableVar, BlockSize, Context,
@@ -1183,7 +1191,9 @@
 	goal_info_init(OrigNonLocals, OrigInstMapDelta, nondet, Context,
 		GoalInfo0),
 	goal_info_add_feature(GoalInfo0, hide_debug_event, GoalInfo),
-	Goal = GoalEx - GoalInfo.
+	Goal = GoalEx - GoalInfo,
+	generate_gen_proc_table_info(TableInfo, Steps, InputVars, OutputVars,
+		ProcTableInfo).
 
 %-----------------------------------------------------------------------------%
 
@@ -1196,6 +1206,23 @@
 
 %-----------------------------------------------------------------------------%
 
+:- pred generate_gen_proc_table_info(table_info::in, list(table_trie_step)::in,
+	list(prog_var)::in, list(prog_var)::in, proc_table_info::out) is det.
+
+generate_gen_proc_table_info(TableInfo, Steps, InputVars, OutputVars,
+		ProcTableInfo) :-
+	ProcInfo = TableInfo ^ table_cur_proc_info,
+	list__append(InputVars, OutputVars, InOutHeadVars),
+	allocate_slot_numbers(InOutHeadVars, 1, NumberedInOutHeadVars),
+	continuation_info__generate_table_arg_type_info(ProcInfo,
+		NumberedInOutHeadVars, TableArgTypeInfo),
+	NumInputs = list__length(InputVars),
+	NumOutputs = list__length(OutputVars),
+	ProcTableInfo = table_gen_info(NumInputs, NumOutputs, Steps,
+		TableArgTypeInfo).
+
+%-----------------------------------------------------------------------------%
+
 :- pred generate_get_table_goal(pred_id::in, proc_id::in,
 	map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out,
@@ -1216,15 +1243,16 @@
 	pred_id::in, proc_id::in, term__context::in,
 	map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, table_info::in, table_info::out,
-	prog_var::out, hlds_goal::out) is det.
+	prog_var::out, hlds_goal::out, list(table_trie_step)::out) is det.
 
 generate_simple_lookup_goal(Vars, PredId, ProcId, Context, VarTypes0, VarTypes,
-		VarSet0, VarSet, TableInfo0, TableInfo, TableVar, Goal) :-
+		VarSet0, VarSet, TableInfo0, TableInfo, TableVar, Goal,
+		Steps) :-
 	generate_get_table_goal(PredId, ProcId, VarTypes0, VarTypes1,
 		VarSet0, VarSet1, PredTableVar, GetTableGoal),
 	generate_lookup_goals(Vars, Context, PredTableVar, TableVar,
 		VarTypes1, VarTypes, VarSet1, VarSet, TableInfo0, TableInfo,
-		LookupGoals),
+		LookupGoals, Steps),
 	GoalEx = conj([GetTableGoal | LookupGoals]),
 	set__singleton_set(NonLocals0, TableVar),
 	set__insert_list(NonLocals0, Vars, NonLocals),
@@ -1243,16 +1271,17 @@
 :- pred generate_non_lookup_goal(list(prog_var)::in, pred_id::in, proc_id::in,
 	term__context::in, map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, table_info::in, table_info::out,
-	prog_var::out, hlds_goal::out) is det.
+	prog_var::out, hlds_goal::out, list(table_trie_step)::out) is det.
 
 generate_non_lookup_goal(Vars, PredId, ProcId, Context, VarTypes0, VarTypes,
-		VarSet0, VarSet, TableInfo0, TableInfo, SubgoalVar, Goal) :-
+		VarSet0, VarSet, TableInfo0, TableInfo, SubgoalVar, Goal,
+		Steps) :-
 	ModuleInfo = TableInfo0 ^ table_module_info,
 	generate_get_table_goal(PredId, ProcId, VarTypes0, VarTypes1,
 		VarSet0, VarSet1, PredTableVar, GetTableGoal),
 	generate_lookup_goals(Vars, Context, PredTableVar, TableNodeVar,
 		VarTypes1, VarTypes2, VarSet1, VarSet2, TableInfo0, TableInfo,
-		LookupGoals),
+		LookupGoals, Steps),
 	generate_new_table_var("SubgoalVar", node_type, VarTypes2, VarTypes,
 		VarSet2, VarSet, SubgoalVar),
 	generate_call("table_nondet_setup", [TableNodeVar, SubgoalVar],
@@ -1280,32 +1309,32 @@
 	prog_var::in, prog_var::out,
 	map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, table_info::in, table_info::out,
-	list(hlds_goal)::out) is det.
+	list(hlds_goal)::out, list(table_trie_step)::out) is det.
 
-generate_lookup_goals([], _, TableVar, TableVar,
-		VarTypes, VarTypes, VarSet, VarSet, TableInfo, TableInfo, []).
+generate_lookup_goals([], _, TableVar, TableVar, VarTypes, VarTypes,
+		VarSet, VarSet, TableInfo, TableInfo, [], []).
 generate_lookup_goals([Var | Rest], Context, TableVar0, TableVar,
 		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
-		[Goal | RestGoals]) :-
+		[Goal | RestGoals], [Step | Steps]) :-
 	ModuleInfo = TableInfo0 ^ table_module_info,
 	map__lookup(VarTypes0, Var, VarType),
 	classify_type(VarType, ModuleInfo, TypeCat),
 	gen_lookup_call_for_type(TypeCat, VarType, TableVar0, Var, Context,
 		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
-		TableVar1, Goal),
+		TableVar1, Goal, Step),
 	generate_lookup_goals(Rest, Context, TableVar1, TableVar,
 		VarTypes1, VarTypes, VarSet1, VarSet, TableInfo1, TableInfo,
-		RestGoals).
+		RestGoals, Steps).
 
 :- pred gen_lookup_call_for_type(builtin_type::in, (type)::in,
 	prog_var::in, prog_var::in, term__context::in,
 	map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, table_info::in, table_info::out,
-	prog_var::out, hlds_goal::out) is det.
+	prog_var::out, hlds_goal::out, table_trie_step::out) is det.
 
 gen_lookup_call_for_type(TypeCat, Type, TableVar, ArgVar, Context,
 		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
-		NextTableVar, Goal) :-
+		NextTableVar, Goal, Step) :-
 	ModuleInfo = TableInfo0 ^ table_module_info,
 
 	( TypeCat = enum_type ->
@@ -1340,9 +1369,10 @@
 			goal_info_init(NonLocals, InstMapDelta, det, Context,
 				GoalInfo),
 			Goal = conj([RangeUnifyGoal, LookupGoal]) - GoalInfo,
+			Step = table_trie_step_enum(EnumRange),
 			TableInfo = TableInfo0
 		;
-			error("gen_lookup: unexpected type")
+			error("gen_lookup_call_for_type: unexpected enum type")
 		)
 	;
 		generate_new_table_var("TableNodeVar", node_type,
@@ -1355,9 +1385,11 @@
 			)
 		->
 			( type_util__vars(Type, []) ->
-				LookupPredName = "table_lookup_insert_user"
+				LookupPredName = "table_lookup_insert_user",
+				Step = table_trie_step_user(Type)
 			;
-				LookupPredName = "table_lookup_insert_poly"
+				LookupPredName = "table_lookup_insert_poly",
+				Step = table_trie_step_poly
 			),
 			make_type_info_var(Type, Context, VarTypes1, VarTypes,
 				VarSet1, VarSet, TableInfo0, TableInfo,
@@ -1372,7 +1404,7 @@
 			CallGoal = _ - GoalInfo,
 			conj_list_to_goal(ConjList, GoalInfo, Goal)
 		;
-			builtin_type_to_string(TypeCat, CatString),
+			builtin_type_lookup_category(TypeCat, CatString, Step),
 			string__append("table_lookup_insert_", CatString,
 				LookupPredName),
 			generate_call(LookupPredName,
@@ -1452,7 +1484,7 @@
 	assoc_list__keys(NumberedOutputVars, OutputVars),
 	generate_lookup_goals(OutputVars, Context,
 		AnsTableVar0, AnsTableVar1, VarTypes1, VarTypes2,
-		VarSet1, VarSet2, TableInfo0, TableInfo1, LookupAnsGoals),
+		VarSet1, VarSet2, TableInfo0, TableInfo1, LookupAnsGoals, _),
 	generate_call("table_nondet_answer_is_not_duplicate", [AnsTableVar1],
 		semidet, yes(impure), [], ModuleInfo, Context,
 		DuplicateCheckGoal),
@@ -1548,7 +1580,7 @@
 		CallGoal = _ - GoalInfo,
 		conj_list_to_goal(ConjList, GoalInfo, Goal)
 	;
-		builtin_type_to_string(TypeCat, CatString),
+		type_save_category(TypeCat, CatString),
 		string__append_list(["table_save_", CatString, "_ans"],
 			LookupPredName),
 		generate_call(LookupPredName, [TableVar, OffsetVar, Var],
@@ -1653,7 +1685,7 @@
 	; not_builtin_type(TypeCat) ->
 		LookupPredName = "table_restore_any_ans"
 	;
-		builtin_type_to_string(TypeCat, CatString),
+		type_save_category(TypeCat, CatString),
 		string__append_list(["table_restore_", CatString, "_ans"],
 			LookupPredName)
 	),
@@ -1824,17 +1856,35 @@
 not_builtin_type(tuple_type).
 not_builtin_type(user_type).
 
-:- pred builtin_type_to_string(builtin_type::in, string::out) is det.
+:- pred builtin_type_lookup_category(builtin_type::in, string::out,
+	table_trie_step::out) is det.
 
-builtin_type_to_string(int_type, 	 "int").
-builtin_type_to_string(char_type, 	 "char").
-builtin_type_to_string(str_type, 	 "string").
-builtin_type_to_string(float_type, 	 "float").
-builtin_type_to_string(pred_type, 	 "pred").
-builtin_type_to_string(tuple_type,	 "any").
-builtin_type_to_string(enum_type, 	 "enum").
-builtin_type_to_string(polymorphic_type, "any").
-builtin_type_to_string(user_type, 	 "any").
+builtin_type_lookup_category(int_type, 	 "int",    table_trie_step_int).
+builtin_type_lookup_category(char_type,  "char",   table_trie_step_char).
+builtin_type_lookup_category(str_type, 	 "string", table_trie_step_string).
+builtin_type_lookup_category(float_type, "float",  table_trie_step_float).
+builtin_type_lookup_category(enum_type,  _, _) :-
+	error("builtin_type_lookup_category: non-builtin-type").
+builtin_type_lookup_category(pred_type, _, _) :-
+	error("builtin_type_lookup_category: non-builtin-type").
+builtin_type_lookup_category(tuple_type,_, _) :-
+	error("builtin_type_lookup_category: non-builtin-type").
+builtin_type_lookup_category(polymorphic_type, _, _) :-
+	error("builtin_type_lookup_category: non-builtin-type").
+builtin_type_lookup_category(user_type, _, _) :-
+	error("builtin_type_lookup_category: non-builtin-type").
+
+:- pred type_save_category(builtin_type::in, string::out) is det.
+
+type_save_category(enum_type, 	 "enum").
+type_save_category(int_type, 	 "int").
+type_save_category(char_type, 	 "char").
+type_save_category(str_type, 	 "string").
+type_save_category(float_type, 	 "float").
+type_save_category(pred_type, 	 "pred").
+type_save_category(tuple_type,	 "any").
+type_save_category(polymorphic_type,  "any").
+type_save_category(user_type, 	 "any").
 
 %-----------------------------------------------------------------------------%
 
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/mdb_categories
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/mdb_categories,v
retrieving revision 1.15
diff -u -b -r1.15 mdb_categories
--- doc/mdb_categories	6 Nov 2002 02:02:25 -0000	1.15
+++ doc/mdb_categories	6 Nov 2002 02:45:57 -0000
@@ -68,6 +68,7 @@
 developer  - Commands that are intended to be of use only to developers
              of the Mercury implementation. The developer commands are
              `nondet_stack', `stack_regs', `all_regs', `proc_stats',
-	     `label_stats', `print_optionals', `unhide_events' and `dd_dd'.
+             `label_stats', `print_optionals', `unhide_events', `dd_dd'
+             and `table'.
 
 end
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.342
diff -u -b -r1.342 user_guide.texi
--- doc/user_guide.texi	7 Nov 2002 06:14:11 -0000	1.342
+++ doc/user_guide.texi	8 Nov 2002 01:20:05 -0000
@@ -3232,6 +3232,19 @@
 @c If a filename is provided, the front end of the debugger is not called
 @c at all.  Instead a representation of the debugging tree is dumped to
 @c the file, which may help diagnose problems in the debugger itself.
+ at sp 1
+ at item table @var{proc} [@var{num1} ...]
+ at kindex table (mdb command)
+Tells the debugger to print the call table of the named procedure,
+together with the saved answer (if any) for each call.
+Reports an error if the named procedure isn't tabled.
+ at sp 1
+For now, this command is supported only for procedures
+whose arguments are all either integers, floats or strings.
+ at sp 1
+If the user specifies one or more integers on the command line,
+the output is restricted to the entries in the call table in which
+the @var{n}th argument is equal to the @var{n}th number on the command line.
 @end table
 
 @node Declarative debugging
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/graphics
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/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/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing java
cvs diff: Diffing java/library
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/string.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/string.m,v
retrieving revision 1.183
diff -u -b -r1.183 string.m
--- library/string.m	29 Oct 2002 07:11:12 -0000	1.183
+++ library/string.m	6 Nov 2002 09:03:03 -0000
@@ -1877,6 +1877,9 @@
 	** double or float.  The %c checks for any erroneous characters
 	** appearing after the float; if there are then sscanf() will
 	** return 2 rather than 1.
+	**
+	** The logic used here is duplicated in the function MR_trace_is_float
+	** trace/mercury_trace_util.c.
 	*/
 	double tmpf;
 	char   tmpc;
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_label.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_label.h,v
retrieving revision 1.10
diff -u -b -r1.10 mercury_label.h
--- runtime/mercury_label.h	4 Dec 2001 00:44:34 -0000	1.10
+++ runtime/mercury_label.h	5 Nov 2002 23:28:24 -0000
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 1994-1998, 2000-2001 The University of Melbourne.
+** Copyright (C) 1994-1998, 2000-2002 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 */
@@ -15,10 +15,9 @@
 #ifndef	MERCURY_LABEL_H
 #define	MERCURY_LABEL_H
 
-#include "mercury_conf_param.h"	    /* for `MR_NEED_ENTRY_LABEL_ARRAY' etc */
-#include "mercury_types.h"	    /* for `MR_Code *' */
-#include "mercury_dlist.h"	    /* for `List' */
-#include "mercury_stack_layout.h"   /* for `MR_Proc_Layout' etc */
+#include "mercury_conf_param.h"	    /* for MR_NEED_ENTRY_LABEL_ARRAY etc */
+#include "mercury_types.h"	    /* for MR_Code, MR_Proc_Layout etc */
+#include "mercury_dlist.h"	    /* for MR_Dlist */
 
 /*
 ** This struct records information about entry labels. Elements in the
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.64
diff -u -b -r1.64 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h	14 Oct 2002 06:48:33 -0000	1.64
+++ runtime/mercury_stack_layout.h	5 Nov 2002 23:28:24 -0000
@@ -34,10 +34,6 @@
 #include "mercury_tags.h"
 #include "mercury_type_info.h"			/* for MR_PseudoTypeInfo */
 
-/* forward declarations */
-typedef	struct MR_Proc_Layout_Struct	MR_Proc_Layout;
-typedef struct MR_Module_Layout_Struct	MR_Module_Layout;
-
 /*-------------------------------------------------------------------------*/
 /*
 ** Definitions for MR_PredFunc. This enum should EXACTLY match the definition
@@ -335,7 +331,7 @@
 	MR_Long_Lval			MR_tp_param_locns[MR_VARIABLE_SIZED];
 } MR_Type_Param_Locns;
 
-typedef	struct MR_Label_Layout_Struct {
+struct MR_Label_Layout_Struct {
 	const MR_Proc_Layout		*MR_sll_entry;
 	MR_int_least8_t			MR_sll_port;
 	MR_int_least8_t			MR_sll_hidden;
@@ -344,7 +340,7 @@
 	const void			*MR_sll_locns_types;
 	const MR_uint_least16_t		*MR_sll_var_nums;
 	const MR_Type_Param_Locns	*MR_sll_tvars;
-} MR_Label_Layout;
+};
 
 typedef	struct MR_Label_Layout_No_Var_Info_Struct {
 	const MR_Proc_Layout		*MR_sll_entry;
@@ -453,6 +449,64 @@
 } MR_Table_Io_Decl;
 
 /*
+** The MR_Table_Gen structure.
+**
+** To enable debugging (especially performance debugging) of tabled predicates,
+** the compiler generates one of these structures for each tabled predicate
+** (except I/O primitives, for which it generates an MR_Table_Io_Decl
+** structure.)
+**
+** Each argument of a tabled predicate is an input or an output. Inputs are put
+** into the call trie, which has one level per input argument. The structure of
+** each level depends on what kind of type the corresponding input argument is;
+** this is recorded in the input_steps field, which points to an array of size
+** num_inputs. If the type is an enum, we cannot interpret the data structures
+** used on that level without also knowing how many alternatives the type has;
+** this is recorded in the corresponding element of the enum_params array,
+** which is likewise of size num_inputs. (Elements of the enum_params array
+** that correspond to arguments whose types are not enums are not meaningful.)
+**
+** The ptis field points to an array of pseudotypeinfos of size num_inputs +
+** num_outputs. The first num_inputs elements give the types of the input
+** arguments, while the remaining num_outputs elements give the types of the
+** output arguments.
+*/
+
+typedef enum {
+	MR_TABLE_STEP_INT,
+	MR_TABLE_STEP_CHAR,
+	MR_TABLE_STEP_STRING,
+	MR_TABLE_STEP_FLOAT,
+	MR_TABLE_STEP_ENUM,
+	MR_TABLE_STEP_USER,
+	MR_TABLE_STEP_POLY,
+} MR_Table_Trie_Step;
+
+typedef struct MR_Table_Gen_Struct {
+	int				MR_table_gen_num_inputs;
+	int				MR_table_gen_num_outputs;
+	const MR_Table_Trie_Step	*MR_table_gen_input_steps;
+	const MR_Integer		*MR_table_gen_enum_params;
+	const MR_PseudoTypeInfo		*MR_table_gen_ptis;
+	const MR_Type_Param_Locns	*MR_table_gen_type_params;
+} MR_Table_Gen;
+
+/*
+** MR_Table_Info: compiler generated information describing the tabling 
+** data structures used by a procedure.
+**
+** For I/O tabled procedures, the information is in the io_decl field.
+** For other kinds of tabled procedures, it is in the gen field.
+** The init field is used for initialization only.
+*/
+
+typedef union {
+	const void			*MR_table_init;
+	const MR_Table_Io_Decl		*MR_table_io_decl;
+	const MR_Table_Gen		*MR_table_gen;
+} MR_Table_Info;
+
+/*
 ** The MR_Stack_Traversal structure contains the following fields:
 **
 ** The code_addr field points to the start of the procedure's code.
@@ -623,7 +677,8 @@
 	const MR_Label_Layout	*MR_exec_call_label;
 	const MR_Module_Layout	*MR_exec_module_layout;
 	MR_Word			*MR_exec_proc_rep;
-	const MR_Table_Io_Decl	*MR_exec_table_io_decl;
+	MR_TrieNode		MR_exec_tabling_pointer;
+	MR_Table_Info		MR_exec_table_info;
 	const MR_int_least16_t	*MR_exec_head_var_nums;
 	const MR_int_least16_t	*MR_exec_used_var_names;
 	MR_int_least16_t	MR_exec_num_head_vars;
@@ -739,6 +794,8 @@
 #define	MR_sle_call_label	MR_sle_exec_trace.MR_exec_call_label
 #define	MR_sle_module_layout	MR_sle_exec_trace.MR_exec_module_layout
 #define	MR_sle_proc_rep	MR_sle_exec_trace.MR_exec_proc_rep
+#define	MR_sle_tabling_pointer	MR_sle_exec_trace.MR_exec_tabling_pointer
+#define	MR_sle_table_info	MR_sle_exec_trace.MR_exec_table_info
 #define	MR_sle_head_var_nums	MR_sle_exec_trace.MR_exec_head_var_nums
 #define	MR_sle_num_head_vars	MR_sle_exec_trace.MR_exec_num_head_vars
 #define	MR_sle_used_var_names	MR_sle_exec_trace.MR_exec_used_var_names
Index: runtime/mercury_tabling.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_tabling.c,v
retrieving revision 1.53
diff -u -b -r1.53 mercury_tabling.c
--- runtime/mercury_tabling.c	30 Sep 2002 06:08:22 -0000	1.53
+++ runtime/mercury_tabling.c	6 Nov 2002 07:43:52 -0000
@@ -11,7 +11,9 @@
 
 #include "mercury_type_info.h"
 #include "mercury_ho_call.h"
+#include "mercury_array_macros.h"
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 /*---------------------------------------------------------------------------*/
@@ -87,7 +89,7 @@
 ** is changed. (This avoids a float multiplication on each insertion.)
 **
 ** The reason why the hash table array contains pointers to slots instead of
-** the slots themselves is that the latter would equire the addresses of some
+** the slots themselves is that the latter would require the addresses of some
 ** hash table slots (those in the array itself and not in a chain) to change
 ** when the table is resized. As for why this is bad, see the documentation
 ** of the MR_TableNode type in mercury_tabling.h.
@@ -124,9 +126,24 @@
 */
 
 #define NUM_OF_PRIMES 16
-static MR_Word primes[NUM_OF_PRIMES] =
-        {127, 257, 509, 1021, 2053, 4099, 8191, 16381, 32771, 65537, 131071,
-        262147, 524287, 1048573, 2097143, 4194301};
+static MR_Word primes[NUM_OF_PRIMES] = {
+    127,
+    257,
+    509,
+    1021,
+    2053,
+    4099,
+    8191,
+    16381,
+    32771,
+    65537,
+    131071,
+    262147,
+    524287,
+    1048573,
+    2097143,
+    4194301
+};
 
 /* Initial size of a new table */
 #define HASH_TABLE_START_SIZE primes[0]
@@ -263,7 +280,7 @@
   #define debug_insert_msg(home_bucket)                         ((void) 0)
 #endif
 
-#define MR_CREATE_HASH_TABLE(table_ptr, table_type, table_field, table_size)  \
+#define MR_CREATE_HASH_TABLE(table_ptr, table_type, table_field, table_size)\
         do {                                                                  \
                 MR_Word         i;                                            \
                 MR_HashTable    *newtable;                                    \
@@ -271,13 +288,13 @@
                 newtable = MR_TABLE_NEW(MR_HashTable);                        \
                                                                               \
                 newtable->size = table_size;                                  \
-                newtable->threshold = (MR_Integer) ((float) table_size        \
-                                * MAX_LOAD_FACTOR);                           \
+        newtable->threshold = (MR_Integer)                                  \
+            ((float) table_size * MAX_LOAD_FACTOR);                         \
                 newtable->value_count = 0;                                    \
                 newtable->freespace.table_field = NULL;                       \
                 newtable->freeleft = 0;                                       \
                 newtable->allocrecord = NULL;                                 \
-                newtable->hash_table = MR_TABLE_NEW_ARRAY(MR_HashTableSlotPtr,\
+        newtable->hash_table = MR_TABLE_NEW_ARRAY(MR_HashTableSlotPtr,      \
                                 table_size);                                  \
                                                                               \
                 for (i = 0; i < table_size; i++) {                            \
@@ -314,18 +331,16 @@
                 table_type              *next_slot;                           \
                                                                               \
                 new_size = next_prime(table->size);                           \
-                new_threshold = (MR_Integer) ((float) new_size                \
-                                * MAX_LOAD_FACTOR);                           \
+        new_threshold = (MR_Integer) ((float) new_size  * MAX_LOAD_FACTOR); \
                 debug_resize_msg(table->size, new_size, new_threshold);       \
                 record_resize_count();                                        \
                                                                               \
-                new_hash_table = MR_TABLE_NEW_ARRAY(MR_HashTableSlotPtr,      \
-                                new_size);                                    \
+        new_hash_table = MR_TABLE_NEW_ARRAY(MR_HashTableSlotPtr, new_size); \
                 for (new_bucket = 0; new_bucket < new_size; new_bucket++) {   \
                         new_hash_table[new_bucket].table_field = NULL;        \
                 }                                                             \
                                                                               \
-                for (old_bucket = 0; old_bucket < table->size; old_bucket++) {\
+        for (old_bucket = 0; old_bucket < table->size; old_bucket++) {      \
                         slot = table->hash_table[old_bucket].table_field;     \
                         while (slot != NULL) {                                \
                                 debug_rehash_msg(old_bucket);                 \
@@ -337,9 +352,8 @@
                                                                               \
                                 new_bucket = abs_hash % new_size;             \
                                 next_slot = slot->next;                       \
-                                slot->next = new_hash_table[new_bucket].      \
-                                        table_field;                          \
-                                new_hash_table[new_bucket].table_field = slot;\
+                slot->next = new_hash_table[new_bucket].table_field;        \
+                new_hash_table[new_bucket].table_field = slot;              \
                                                                               \
                                 slot = next_slot;                             \
                         }                                                     \
@@ -358,7 +372,7 @@
                                                                               \
         home = abs_hash % table->size;                                        \
                                                                               \
-        /* Find if the element is present. If not add it */                   \
+    /* Find the element if it is present. */                                \
         slot = table->hash_table[home].table_field;                           \
         while (slot != NULL) {                                                \
                 debug_probe_msg(home);                                        \
@@ -373,14 +387,20 @@
                 slot = slot->next;                                            \
         }                                                                     \
                                                                               \
+    /* Check whether we are allowed to add the element. */                  \
+    if (insert_only) {                                                      \
+        return NULL;                                                        \
+    }                                                                       \
+                                                                            \
+    /* Add the element. */                                                  \
         debug_insert_msg(home);                                               \
         record_insert_count();                                                \
                                                                               \
         if (table->freeleft == 0) {                                           \
                 MR_AllocRecord  *record;                                      \
                                                                               \
-                table->freespace.table_field = MR_TABLE_NEW_ARRAY(            \
-                                table_type, CHUNK_SIZE);                      \
+        table->freespace.table_field = MR_TABLE_NEW_ARRAY(table_type,       \
+            CHUNK_SIZE);                                                    \
                 table->freeleft = CHUNK_SIZE;                                 \
                                                                               \
                 record = MR_TABLE_NEW(MR_AllocRecord);                        \
@@ -413,6 +433,27 @@
 #define table_field             int_slot_ptr
 #define hash(key)               (key)
 #define equal_keys(k1, k2)      (k1 == k2)
+#define insert_only             MR_FALSE
+MR_GENERIC_HASH_LOOKUP_OR_ADD
+#undef  key_format
+#undef  key_cast
+#undef  table_type
+#undef  table_field
+#undef  hash
+#undef  equal_keys
+#undef  insert_only
+}
+
+MR_TrieNode
+MR_int_hash_lookup(MR_TrieNode t, MR_Integer key)
+{
+#define key_format              "%ld"
+#define key_cast                long
+#define table_type              MR_IntHashTableSlot
+#define table_field             int_slot_ptr
+#define hash(key)               (key)
+#define equal_keys(k1, k2)      (k1 == k2)
+#define insert_only             MR_TRUE
 MR_GENERIC_HASH_LOOKUP_OR_ADD
 #undef  key_format
 #undef  key_cast
@@ -420,6 +461,7 @@
 #undef  table_field
 #undef  hash
 #undef  equal_keys
+#undef  insert_only
 }
 
 /*
@@ -437,14 +479,35 @@
 #define table_field             float_slot_ptr
 #define hash(key)               (MR_hash_float(key))
 #define equal_keys(k1, k2)      (memcmp(&(k1), &(k2), sizeof(MR_Float)) == 0)
+#define insert_only             MR_FALSE
 MR_GENERIC_HASH_LOOKUP_OR_ADD
 #undef  key_format
 #undef  key_cast
-#undef  debug_search_key
 #undef  table_type
 #undef  table_field
 #undef  hash
 #undef  equal_keys
+#undef  insert_only
+}
+
+MR_TrieNode
+MR_float_hash_lookup(MR_TrieNode t, MR_Float key)
+{
+#define key_format              "%f"
+#define key_cast                double
+#define table_type              MR_FloatHashTableSlot
+#define table_field             float_slot_ptr
+#define hash(key)               (MR_hash_float(key))
+#define equal_keys(k1, k2)      (memcmp(&(k1), &(k2), sizeof(MR_Float)) == 0)
+#define insert_only             MR_TRUE
+MR_GENERIC_HASH_LOOKUP_OR_ADD
+#undef  key_format
+#undef  key_cast
+#undef  table_type
+#undef  table_field
+#undef  hash
+#undef  equal_keys
+#undef  insert_only
 }
 
 MR_TrieNode
@@ -456,16 +519,152 @@
 #define table_field             string_slot_ptr
 #define hash(key)               (MR_hash_string(key))
 #define equal_keys(k1, k2)      (MR_strtest(k1, k2) == 0)
+#define insert_only             MR_FALSE
 MR_GENERIC_HASH_LOOKUP_OR_ADD
 #undef  key_format
 #undef  key_cast
-#undef  debug_search_key
 #undef  table_type
 #undef  table_field
 #undef  hash
 #undef  equal_keys
+#undef  insert_only
+}
+
+MR_TrieNode
+MR_string_hash_lookup(MR_TrieNode t, MR_ConstString key)
+{
+#define key_format              "%s"
+#define key_cast                const char *
+#define table_type              MR_StringHashTableSlot
+#define table_field             string_slot_ptr
+#define hash(key)               (MR_hash_string(key))
+#define equal_keys(k1, k2)      (MR_strtest(k1, k2) == 0)
+#define insert_only             MR_TRUE
+MR_GENERIC_HASH_LOOKUP_OR_ADD
+#undef  key_format
+#undef  key_cast
+#undef  table_type
+#undef  table_field
+#undef  hash
+#undef  equal_keys
+#undef  insert_only
+}
+
+static int
+MR_cmp_ints(const void *p1, const void *p2)
+{
+    MR_Integer  i1 = * (MR_Integer *) p1;
+    MR_Integer  i2 = * (MR_Integer *) p2;
+
+    if (i1 < i2) {
+        return -1;
+    } else if (i1 > i2) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+static int
+MR_cmp_floats(const void *p1, const void *p2)
+{
+    MR_Float  f1 = * (MR_Float *) p1;
+    MR_Float  f2 = * (MR_Float *) p2;
+
+    if (f1 < f2) {
+        return -1;
+    } else if (f1 > f2) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+static int
+MR_cmp_strings(const void *p1, const void *p2)
+{
+    MR_ConstString  s1 = * (MR_ConstString *) p1;
+    MR_ConstString  s2 = * (MR_ConstString *) p2;
+
+    return strcmp(s1, s2);
 }
 
+#define MR_INIT_HASH_CONTENTS_ARRAY_SIZE    100
+
+#define MR_HASH_CONTENTS_FUNC_BODY                                      \
+        MR_bool                                                         \
+        func_name(MR_TrieNode t, type_name **values_ptr,                \
+            int *value_next_ptr)                                        \
+        {                                                               \
+            type_name       *values;                                    \
+            int             value_next;                                 \
+            int             value_max;                                  \
+            MR_HashTable    *table;                                     \
+            int             bucket;                                     \
+            table_type      *slot;                                      \
+                                                                        \
+            if (t->MR_hash_table == NULL) {                             \
+                return MR_FALSE;                                        \
+            }                                                           \
+                                                                        \
+            table = t->MR_hash_table;                                   \
+            values = NULL;                                              \
+            value_next = 0;                                             \
+            value_max = 0;                                              \
+                                                                        \
+            for (bucket = 0; bucket < table->size; bucket++) {          \
+                slot = table->hash_table[bucket].table_field;           \
+                while (slot != NULL) {                                  \
+                    MR_ensure_room_for_next(value, type_name,           \
+                        MR_INIT_HASH_CONTENTS_ARRAY_SIZE);              \
+                    values[value_next] = slot->key;                     \
+                    value_next++;                                       \
+                    slot = slot->next;                                  \
+                }                                                       \
+            }                                                           \
+                                                                        \
+            qsort(values, value_next, sizeof(type_name), comp_func);    \
+            *values_ptr = values;                                       \
+            *value_next_ptr = value_next;                               \
+            return MR_TRUE;                                             \
+        }
+
+#define func_name    MR_int_hash_contents
+#define type_name    MR_Integer
+#define table_type   MR_IntHashTableSlot
+#define table_field  int_slot_ptr
+#define comp_func    MR_cmp_ints
+MR_HASH_CONTENTS_FUNC_BODY
+#undef func_name
+#undef type_name
+#undef table_type
+#undef table_field
+#undef comp_func
+
+#define func_name    MR_float_hash_contents
+#define type_name    MR_Float
+#define table_type   MR_FloatHashTableSlot
+#define table_field  float_slot_ptr
+#define comp_func    MR_cmp_floats
+MR_HASH_CONTENTS_FUNC_BODY
+#undef func_name
+#undef type_name
+#undef table_type
+#undef table_field
+#undef comp_func
+
+#define func_name    MR_string_hash_contents
+#define type_name    MR_ConstString
+#define table_type   MR_StringHashTableSlot
+#define table_field  string_slot_ptr
+#define comp_func    MR_cmp_strings
+MR_HASH_CONTENTS_FUNC_BODY
+#undef func_name
+#undef type_name
+#undef table_type
+#undef table_field
+#undef comp_func
+
 /*---------------------------------------------------------------------------*/
 
 /*
@@ -484,8 +683,7 @@
 
 #ifdef  MR_TABLE_DEBUG
         if (key >= range) {
-                MR_fatal_error(
-                        "MR_int_fix_index_lookup_or_add: key out of range");
+        MR_fatal_error("MR_int_fix_index_lookup_or_add: key out of range");
         }
 #endif
 
@@ -505,8 +703,8 @@
 #define MR_START_TABLE_INIT_SIZE        1024
 
 MR_TrieNode
-MR_int_start_index_lookup_or_add(MR_TrieNode table,
-        MR_Integer start, MR_Integer key)
+MR_int_start_index_lookup_or_add(MR_TrieNode table, MR_Integer start,
+    MR_Integer key)
 {
         MR_Integer      diff, size;
 
@@ -514,17 +712,14 @@
 
 #ifdef  MR_TABLE_DEBUG
         if (key < start) {
-                MR_fatal_error(
-                        "MR_int_start_index_lookup_or_add: small too key");
+        MR_fatal_error("MR_int_start_index_lookup_or_add: small too key");
         }
 #endif
 
         if (table->MR_start_table == NULL) {
                 size = MR_max(MR_START_TABLE_INIT_SIZE, diff + 1);
-                table->MR_start_table = MR_TABLE_NEW_ARRAY(MR_TableNode,
-                                        size + 1);
-                memset(table->MR_start_table + 1, 0,
-                                        sizeof(MR_TableNode) * size);
+        table->MR_start_table = MR_TABLE_NEW_ARRAY(MR_TableNode, size + 1);
+        memset(table->MR_start_table + 1, 0, sizeof(MR_TableNode) * size);
                 table->MR_start_table[0].MR_integer = size;
         } else {
                 size = table->MR_start_table[0].MR_integer;
@@ -581,12 +776,9 @@
         ** sense. This is OK, because in that case it will never be used.
         */
 
-        if (MR_type_ctor_rep_is_variable_arity(
-                MR_type_ctor_rep(type_ctor_info)))
-        {
+    if (MR_type_ctor_rep_is_variable_arity(MR_type_ctor_rep(type_ctor_info))) {
                 arity = MR_TYPEINFO_GET_VAR_ARITY_ARITY(type_info);
-                arg_vector = MR_TYPEINFO_GET_VAR_ARITY_ARG_VECTOR(
-                        type_info);
+        arg_vector = MR_TYPEINFO_GET_VAR_ARITY_ARG_VECTOR(type_info);
                 node = MR_int_hash_lookup_or_add(node, arity);
         } else {
                 arity = type_ctor_info->MR_type_ctor_arity;
@@ -644,8 +836,9 @@
         case MR_TYPECTOR_REP_RESERVED_ADDR_USEREQ: 
             {
                 int i;
-                MR_ReservedAddrTypeLayout ra_layout =
-                        MR_type_ctor_layout(type_ctor_info).
+                MR_ReservedAddrTypeLayout   ra_layout;
+                
+                ra_layout = MR_type_ctor_layout(type_ctor_info).
                             MR_layout_reserved_addr;
 
                 /*
@@ -657,7 +850,8 @@
                 {
                     MR_DEBUG_TABLE_ENUM(table,
                         MR_type_ctor_num_functors(type_ctor_info),
-                        ra_layout->MR_ra_constants[data]->MR_ra_functor_ordinal);
+                        ra_layout->MR_ra_constants[data]->
+                            MR_ra_functor_ordinal);
                     break;
                 }
 
@@ -666,7 +860,9 @@
                 ** the symbolic reserved addresses.
                 */
                 for (i = 0; i < ra_layout->MR_ra_num_res_symbolic_addrs; i++) {
-                    if (data == (MR_Word) ra_layout->MR_ra_res_symbolic_addrs[i]) {
+                    if (data == (MR_Word)
+                        ra_layout->MR_ra_res_symbolic_addrs[i])
+                    {
                         int offset = i + ra_layout->MR_ra_num_res_numeric_addrs;
                         MR_DEBUG_TABLE_ENUM(table,
                             MR_type_ctor_num_functors(type_ctor_info),
@@ -713,10 +909,12 @@
                 ptag_layout = &du_type_layout[ptag];
 
                 switch (ptag_layout->MR_sectag_locn) {
+
                 case MR_SECTAG_NONE:
                     functor_desc = ptag_layout->MR_sectag_alternatives[0];
                     arg_vector = (MR_Word *) MR_body(data, ptag);
                     break;
+
                 case MR_SECTAG_LOCAL:
                     sectag = MR_unmkbody(data);
                     functor_desc = ptag_layout->MR_sectag_alternatives[sectag];
@@ -724,15 +922,19 @@
                     assert(functor_desc->MR_du_functor_exist_info == NULL);
                     arg_vector = NULL;
                     break;
+
                 case MR_SECTAG_REMOTE:
                     sectag = MR_field(ptag, data, 0);
                     functor_desc = ptag_layout->MR_sectag_alternatives[sectag];
                     arg_vector = (MR_Word *) MR_body(data, ptag) + 1;
                     break;
+
                 case MR_SECTAG_VARIABLE:
                     MR_fatal_error("MR_table_type(): unexpected variable");
+
                 default:
                     MR_fatal_error("MR_table_type(): unknown sectag_locn");
+
                 }
 
                 MR_DEBUG_TABLE_ENUM(table,
@@ -1002,8 +1204,7 @@
         if (MR_table_hash_lookups == 0) {
                 fprintf(fp, "no successful searches\n");
         } else {
-                fprintf(fp, "successful   %6d, "
-                                "with an average of %6.3f comparisons\n",
+        fprintf(fp, "successful   %6d, with an average of %6.3f comparisons\n",
                         MR_table_hash_lookups,
                         (float) MR_table_hash_lookup_probes /
                                 (float) MR_table_hash_lookups);
@@ -1012,8 +1213,7 @@
         if (MR_table_hash_inserts == 0) {
                 fprintf(fp, "no unsuccessful searches\n");
         } else {
-                fprintf(fp, "unsuccessful %6d, "
-                                "with an average of %6.3f comparisons\n",
+        fprintf(fp, "unsuccessful %6d, with an average of %6.3f comparisons\n",
                         MR_table_hash_inserts,
                         (float) MR_table_hash_insert_probes /
                                 (float) MR_table_hash_inserts);
@@ -1022,8 +1222,7 @@
         fprintf(fp, "rehash operations: %d, per search: %6.3f%%\n",
                         MR_table_hash_resizes,
                         (float) (100 * MR_table_hash_resizes) /
-                        (float) (MR_table_hash_lookups
-                                 + MR_table_hash_inserts));
+            (float) (MR_table_hash_lookups + MR_table_hash_inserts));
         fprintf(fp, "chunk allocations: %d\n", MR_table_hash_allocs);
 #else
         fprintf(fp, "not enabled\n");
Index: runtime/mercury_tabling.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_tabling.h,v
retrieving revision 1.28
diff -u -b -r1.28 mercury_tabling.h
--- runtime/mercury_tabling.h	18 Feb 2002 07:01:21 -0000	1.28
+++ runtime/mercury_tabling.h	6 Nov 2002 07:30:32 -0000
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 1997-2000 The University of Melbourne.
+** Copyright (C) 1997-2000,2002 The University of Melbourne.
 ** This file may only be copied under the terms of the GNU Library General
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 */
@@ -33,14 +33,12 @@
 ** Forward declarations of type names.
 */
 
-typedef	union MR_TableNode_Union		MR_TableNode;
 typedef	struct MR_HashTable_Struct		MR_HashTable;
 typedef	struct MR_Subgoal_Struct		MR_Subgoal;
 typedef	struct MR_SubgoalListNode_Struct	MR_SubgoalListNode;
 typedef	struct MR_AnswerListNode_Struct		MR_AnswerListNode;
 typedef	struct MR_ConsumerListNode_Struct	MR_ConsumerListNode;
 
-typedef MR_TableNode				*MR_TrieNode;
 typedef	MR_SubgoalListNode			*MR_SubgoalList;
 typedef	MR_AnswerListNode			*MR_AnswerList;
 typedef	MR_ConsumerListNode			*MR_ConsumerList;
@@ -119,11 +117,10 @@
 ** meaning until the end of the computation.
 **
 ** The implementation of start tables currently does not obey this requirement.
-** This is okay, for two reasons. First, start tables are not yet used. Second,
-** when they are used, they will be used by I/O tabling, which guarantees that
-** there will be no insertions into the same (or any other) table between
-** getting back a tip node on the one hand and updating it and releasing the
-** pointer to it on the other hand.
+** This is okay, because start tables are used only by I/O tabling, which
+** guarantees that there will be no insertions into the same (or any other)
+** table between getting back a tip node on the one hand and updating it and
+** releasing the pointer to it on the other hand.
 ** 
 ** NOTE: the mercury_type_tables module uses the expandable hash table routines
 ** defined in this module to implement its tables. This is the only use of the
@@ -330,6 +327,35 @@
 				MR_TypeInfo type_info, MR_Word data_value);
 
 /*
+** These functions look to see if the given key is in the given table.
+** If it is, they return the address of the data pointer associated with
+** the key. If it is not, they return NULL.
+**
+** These functions assume that the table is a dynamically resizable hash table.
+*/
+
+extern	MR_TrieNode	MR_int_hash_lookup(MR_TrieNode table,
+				MR_Integer key);
+extern	MR_TrieNode	MR_float_hash_lookup(MR_TrieNode table,
+				MR_Float key);
+extern	MR_TrieNode	MR_string_hash_lookup(MR_TrieNode table,
+				MR_ConstString key);
+
+/*
+** These functions return a dynamically resizable array (using the primitives
+** in mercury_array_macros.h) containing all the elements in the given
+** dynamically resizable hash table.
+*/
+
+extern	MR_bool		MR_int_hash_contents(MR_TrieNode t,
+				MR_Integer **values_ptr, int *value_next_ptr);
+extern	MR_bool		MR_float_hash_contents(MR_TrieNode t,
+				MR_Float **values_ptr, int *value_next_ptr);
+extern	MR_bool		MR_string_hash_contents(MR_TrieNode t,
+				MR_ConstString **values_ptr,
+				int *value_next_ptr);
+
+/*
 ** This function prints statistics about the operation of tabling, if the
 ** collection of such statistics is enabled, on the given stream.
 */
@@ -369,31 +395,34 @@
 
 #else /* MR_NATIVE_GC */
 
+  #define MR_TABLE_NATIVE_GC_MSG					\
+	"Sorry, not implemented: tabling in native gc grades"
+
   #define MR_TABLE_NEW(type)						\
-	(MR_fatal_error("Sorry, not implemented: tabling in native gc grades"), \
+	(MR_fatal_error(MR_TABLE_NATIVE_GC_MSG),			\
 	(void *) NULL)
   #define MR_TABLE_NEW_ARRAY(type, count)				\
-	(MR_fatal_error("Sorry, not implemented: tabling in native gc grades"), \
+	(MR_fatal_error(MR_TABLE_NATIVE_GC_MSG),			\
 	(void *) NULL)
   #define MR_TABLE_RESIZE_ARRAY(pointer, type, count)			\
-	(MR_fatal_error("Sorry, not implemented: tabling in native gc grades"), \
+	(MR_fatal_error(MR_TABLE_NATIVE_GC_MSG),			\
 	(void *) NULL)
   #define MR_table_allocate_bytes(size)					\
-	(MR_fatal_error("Sorry, not implemented: tabling in native gc grades"), \
+	(MR_fatal_error(MR_TABLE_NATIVE_GC_MSG),			\
 	(void *) NULL)
   #define MR_table_reallocate_bytes(pointer, size)				\
-	(MR_fatal_error("Sorry, not implemented: tabling in native gc grades"), \
+	(MR_fatal_error(MR_TABLE_NATIVE_GC_MSG),			\
 	(void *) NULL)
   #define MR_table_allocate_words(size)					\
-	(MR_fatal_error("Sorry, not implemented: tabling in native gc grades"), \
+	(MR_fatal_error(MR_TABLE_NATIVE_GC_MSG), 			\
 	(void *) NULL)
   #define MR_table_reallocate_words(pointer, size)				\
-	(MR_fatal_error("Sorry, not implemented: tabling in native gc grades"), \
+	(MR_fatal_error(MR_TABLE_NATIVE_GC_MSG), 			\
 	(void *) NULL)
   #define MR_table_free(pointer)						\
-	MR_fatal_error("Sorry, not implemented: tabling in native gc grades")
+	MR_fatal_error(MR_TABLE_NATIVE_GC_MSG)
   #define MR_table_list_cons(h, t)					\
-	(MR_fatal_error("Sorry, not implemented: tabling in native gc grades"), \
+	(MR_fatal_error(MR_TABLE_NATIVE_GC_MSG),			\
 	(MR_Word) 0)
 
 #endif /* MR_NATIVE_GC */
Index: runtime/mercury_types.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_types.h,v
retrieving revision 1.29
diff -u -b -r1.29 mercury_types.h
--- runtime/mercury_types.h	9 Aug 2002 05:26:51 -0000	1.29
+++ runtime/mercury_types.h	5 Nov 2002 23:28:25 -0000
@@ -127,6 +127,13 @@
 typedef struct MR_ProfilingMetrics_Struct       MR_ProfilingMetrics;
 
 typedef struct MR_CallSiteDynList_Struct        MR_CallSiteDynList;
+
+typedef struct MR_Proc_Layout_Struct            MR_Proc_Layout;
+typedef struct MR_Module_Layout_Struct          MR_Module_Layout;
+typedef struct MR_Label_Layout_Struct           MR_Label_Layout;
+
+typedef union MR_TableNode_Union                MR_TableNode;
+typedef MR_TableNode                            *MR_TrieNode;
 
 /*
 ** The MR_Box type is used for representing polymorphic types.
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 tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.90
diff -u -b -r1.90 Mmakefile
--- tests/debugger/Mmakefile	17 Oct 2002 12:49:10 -0000	1.90
+++ tests/debugger/Mmakefile	5 Nov 2002 23:28:25 -0000
@@ -32,6 +32,7 @@
 	multi_parameter			\
 	polymorphic_output		\
 	print_goal			\
+	print_table			\
 	queens_rep			\
 	resume_typeinfos		\
 	type_desc_test
@@ -96,6 +97,9 @@
 	SENSITIVE_PROGS :=
     endif
 endif
+ifneq "$(findstring mm,$(GRADE))" ""
+    SENSITIVE_PROGS :=
+endif
 
 ALL_RETRY_PROGS = $(RETRY_PROGS) $(INTERACTIVE_PROGS)
 ALL_NONRETRY_PROGS = $(NONRETRY_PROGS) $(SENSITIVE_PROGS) $(SHALLOW_PROGS)
@@ -301,6 +305,9 @@
 
 print_goal.out: print_goal print_goal.inp
 	$(MDB_STD) ./print_goal < print_goal.inp > print_goal.out 2>&1
+
+print_table.out: print_table print_table.inp
+	$(MDB_STD) ./print_table < print_table.inp > print_table.out 2>&1
 
 queens.out: queens queens.inp
 	$(MDB_STD) ./queens < queens.inp > queens.out 2>&1
Index: tests/debugger/completion.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/completion.exp,v
retrieving revision 1.8
diff -u -b -r1.8 completion.exp
--- tests/debugger/completion.exp	13 Sep 2002 03:37:41 -0000	1.8
+++ tests/debugger/completion.exp	6 Nov 2002 06:30:29 -0000
@@ -13,14 +13,14 @@
 c                  f                  print              stack
 cc_query           finish             print_optionals    stack_regs
 context            forward            printlevel         step
-continue           g                  proc_body          table_io
-current            goto               proc_stats         unalias
-d                  h                  procedures         unhide_events
-dd                 help               query              up
-dd_dd              ignore             quit               v
-delete             io_query           r                  vars
-disable            label_stats        register           view
-document           level              retry              
+continue           g                  proc_body          table
+current            goto               proc_stats         table_io
+d                  h                  procedures         unalias
+dd                 help               query              unhide_events
+dd_dd              ignore             quit               up
+delete             io_query           r                  v
+disable            label_stats        register           vars
+document           level              retry              view
 h     help  
 vars  view  
 help vars 
Index: tests/debugger/mdb_command_test.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/mdb_command_test.inp,v
retrieving revision 1.21
diff -u -b -r1.21 mdb_command_test.inp
--- tests/debugger/mdb_command_test.inp	6 Nov 2002 02:02:32 -0000	1.21
+++ tests/debugger/mdb_command_test.inp	6 Nov 2002 21:14:33 -0000
@@ -53,3 +53,4 @@
 print_optionals      xyzzy xyzzy xyzzy xyzzy xyzzy
 unhide_events        xyzzy xyzzy xyzzy xyzzy xyzzy
 dd_dd                xyzzy xyzzy xyzzy xyzzy xyzzy
+table                xyzzy xyzzy xyzzy xyzzy xyzzy
Index: tests/debugger/print_table.exp
===================================================================
RCS file: tests/debugger/print_table.exp
diff -N tests/debugger/print_table.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/print_table.exp	6 Nov 2002 11:32:31 -0000
@@ -0,0 +1,361 @@
+      E1:     C1  1 CALL pred print_table:main/2-0 (cc_multi) print_table.m:13
+mdb> echo on
+Command echo enabled.
+mdb> context none
+Contexts will not be printed.
+mdb> register --quiet
+mdb> b p
+ 0: + stop  interface pred print_table:p/3-0 (det)
+mdb> c
+      E2:     C2  2 CALL pred print_table:p/3-0 (det)
+mdb> f -n
+      E3:     C2  2 EXIT pred print_table:p/3-0 (det)
+mdb> table p
+memo table for pred print_table:p/3-0 (det):
+<5, 0>: succeeded <0>
+<5, 1>: succeeded <5>
+<5, 2>: succeeded <15>
+<5, 3>: succeeded <30>
+<5, 4>: succeeded <50>
+<5, 5>: succeeded <75>
+end of table (6 entries)
+mdb> table p 5
+memo table for pred print_table:p/3-0 (det):
+<5, 0>: succeeded <0>
+<5, 1>: succeeded <5>
+<5, 2>: succeeded <15>
+<5, 3>: succeeded <30>
+<5, 4>: succeeded <50>
+<5, 5>: succeeded <75>
+end of table (6 entries)
+mdb> table p 5 2
+<5, 2>: succeeded <15>
+mdb> c
+      E4:     C3  2 CALL pred print_table:p/3-0 (det)
+mdb> f -n
+      E5:     C3  2 EXIT pred print_table:p/3-0 (det)
+mdb> table p
+memo table for pred print_table:p/3-0 (det):
+<4, 0>: succeeded <0>
+<4, 1>: succeeded <4>
+<4, 2>: succeeded <12>
+<4, 3>: succeeded <24>
+<5, 0>: succeeded <0>
+<5, 1>: succeeded <5>
+<5, 2>: succeeded <15>
+<5, 3>: succeeded <30>
+<5, 4>: succeeded <50>
+<5, 5>: succeeded <75>
+end of table (10 entries)
+mdb> table p 5
+memo table for pred print_table:p/3-0 (det):
+<5, 0>: succeeded <0>
+<5, 1>: succeeded <5>
+<5, 2>: succeeded <15>
+<5, 3>: succeeded <30>
+<5, 4>: succeeded <50>
+<5, 5>: succeeded <75>
+end of table (6 entries)
+mdb> table p 5 2
+<5, 2>: succeeded <15>
+mdb> table p 4
+memo table for pred print_table:p/3-0 (det):
+<4, 0>: succeeded <0>
+<4, 1>: succeeded <4>
+<4, 2>: succeeded <12>
+<4, 3>: succeeded <24>
+end of table (4 entries)
+mdb> table p 4 2
+<4, 2>: succeeded <12>
+mdb> c
+      E6:     C4  2 CALL pred print_table:p/3-0 (det)
+mdb> f -n
+      E7:     C4  2 EXIT pred print_table:p/3-0 (det)
+mdb> table p
+memo table for pred print_table:p/3-0 (det):
+<2, 0>: succeeded <0>
+<2, 1>: succeeded <2>
+<2, 2>: succeeded <6>
+<4, 0>: succeeded <0>
+<4, 1>: succeeded <4>
+<4, 2>: succeeded <12>
+<4, 3>: succeeded <24>
+<5, 0>: succeeded <0>
+<5, 1>: succeeded <5>
+<5, 2>: succeeded <15>
+<5, 3>: succeeded <30>
+<5, 4>: succeeded <50>
+<5, 5>: succeeded <75>
+end of table (13 entries)
+mdb> table p 5
+memo table for pred print_table:p/3-0 (det):
+<5, 0>: succeeded <0>
+<5, 1>: succeeded <5>
+<5, 2>: succeeded <15>
+<5, 3>: succeeded <30>
+<5, 4>: succeeded <50>
+<5, 5>: succeeded <75>
+end of table (6 entries)
+mdb> table p 5 2
+<5, 2>: succeeded <15>
+mdb> table p 4
+memo table for pred print_table:p/3-0 (det):
+<4, 0>: succeeded <0>
+<4, 1>: succeeded <4>
+<4, 2>: succeeded <12>
+<4, 3>: succeeded <24>
+end of table (4 entries)
+mdb> table p 2 1
+<2, 1>: succeeded <2>
+mdb> c
+      E8:     C5  2 CALL pred print_table:p/3-0 (det)
+mdb> f -n
+      E9:     C5  2 EXIT pred print_table:p/3-0 (det)
+mdb> table p
+memo table for pred print_table:p/3-0 (det):
+<1, 0>: succeeded <0>
+<2, 0>: succeeded <0>
+<2, 1>: succeeded <2>
+<2, 2>: succeeded <6>
+<4, 0>: succeeded <0>
+<4, 1>: succeeded <4>
+<4, 2>: succeeded <12>
+<4, 3>: succeeded <24>
+<5, 0>: succeeded <0>
+<5, 1>: succeeded <5>
+<5, 2>: succeeded <15>
+<5, 3>: succeeded <30>
+<5, 4>: succeeded <50>
+<5, 5>: succeeded <75>
+end of table (14 entries)
+mdb> table p 5
+memo table for pred print_table:p/3-0 (det):
+<5, 0>: succeeded <0>
+<5, 1>: succeeded <5>
+<5, 2>: succeeded <15>
+<5, 3>: succeeded <30>
+<5, 4>: succeeded <50>
+<5, 5>: succeeded <75>
+end of table (6 entries)
+mdb> table p 5 2
+<5, 2>: succeeded <15>
+mdb> table p 4
+memo table for pred print_table:p/3-0 (det):
+<4, 0>: succeeded <0>
+<4, 1>: succeeded <4>
+<4, 2>: succeeded <12>
+<4, 3>: succeeded <24>
+end of table (4 entries)
+mdb> table p 2 1
+<2, 1>: succeeded <2>
+mdb> table p 1 0
+<1, 0>: succeeded <0>
+mdb> delete 1
+mdb: break point #1 does not exist.
+mdb> b q
+ 1: + stop  interface pred print_table:q/3-0 (semidet)
+mdb> c
+     E10:     C6  2 CALL pred print_table:q/3-0 (semidet)
+mdb> f -n
+     E11:     C6  2 EXIT pred print_table:q/3-0 (semidet)
+mdb> table q
+memo table for pred print_table:q/3-0 (semidet):
+<3, 0>: succeeded <0>
+<3, 1>: succeeded <3>
+<3, 2>: succeeded <9>
+end of table (3 entries)
+mdb> table q 3
+memo table for pred print_table:q/3-0 (semidet):
+<3, 0>: succeeded <0>
+<3, 1>: succeeded <3>
+<3, 2>: succeeded <9>
+end of table (3 entries)
+mdb> table q 3 2
+<3, 2>: succeeded <9>
+mdb> table q 4
+call table does not contain 4 in argument position 1.
+mdb> c
+     E12:     C7  2 CALL pred print_table:q/3-0 (semidet)
+mdb> f -n
+     E13:     C7  2 FAIL pred print_table:q/3-0 (semidet)
+mdb> table q
+memo table for pred print_table:q/3-0 (semidet):
+<3, 0>: succeeded <0>
+<3, 1>: succeeded <3>
+<3, 2>: succeeded <9>
+<4, 1>: failed
+<4, 2>: failed
+end of table (5 entries)
+mdb> table q 3
+memo table for pred print_table:q/3-0 (semidet):
+<3, 0>: succeeded <0>
+<3, 1>: succeeded <3>
+<3, 2>: succeeded <9>
+end of table (3 entries)
+mdb> table q 3 2
+<3, 2>: succeeded <9>
+mdb> table q 3 0
+<3, 0>: succeeded <0>
+mdb> table q 4 2
+<4, 2>: failed
+mdb> table q 4 1
+<4, 1>: failed
+mdb> table q 4 0
+call table does not contain 0 in argument position 2.
+mdb> delete 1
+ 1: E stop  interface pred print_table:q/3-0 (semidet)
+mdb> b r
+ 1: + stop  interface pred print_table:r/2-0 (det)
+mdb> c
+     E14:     C8  2 CALL pred print_table:r/2-0 (det)
+mdb> table r
+memo table for pred print_table:r/2-0 (det):
+end of table (0 entries)
+mdb> s
+     E15:     C8  2 COND pred print_table:r/2-0 (det) c2;e;e;c2;?;
+mdb> table r
+memo table for pred print_table:r/2-0 (det):
+<3>: working
+end of table (1 entry)
+mdb> table r 3
+<3>: working
+mdb> c
+     E16:     C9  3 CALL pred print_table:r/2-0 (det)
+mdb> table r
+memo table for pred print_table:r/2-0 (det):
+<3>: working
+end of table (1 entry)
+mdb> f -n
+     E17:     C9  3 EXIT pred print_table:r/2-0 (det)
+mdb> table r
+memo table for pred print_table:r/2-0 (det):
+<0>: succeeded <0>
+<1>: succeeded <1>
+<2>: succeeded <3>
+<3>: working
+end of table (4 entries)
+mdb> f -n 1
+     E18:     C8  2 EXIT pred print_table:r/2-0 (det)
+mdb> table r
+memo table for pred print_table:r/2-0 (det):
+<0>: succeeded <0>
+<1>: succeeded <1>
+<2>: succeeded <3>
+<3>: succeeded <6>
+end of table (4 entries)
+mdb> delete 1
+ 1: E stop  interface pred print_table:r/2-0 (det)
+mdb> b s
+ 1: + stop  interface pred print_table:s/6-0 (det)
+mdb> c
+     E19:    C10  2 CALL pred print_table:s/6-0 (det)
+mdb> table s
+memo table for pred print_table:s/6-0 (det):
+end of table (0 entries)
+mdb> f -n
+     E20:    C10  2 EXIT pred print_table:s/6-0 (det)
+mdb> table s
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 1, "abc", 1>: succeeded <"[3.5abc1]", 4.500000>
+end of table (1 entry)
+mdb> c
+     E21:    C11  2 CALL pred print_table:s/6-0 (det)
+mdb> f -n
+     E22:    C11  2 EXIT pred print_table:s/6-0 (det)
+mdb> table s
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 1, "abc", 1>: succeeded <"[3.5abc1]", 4.500000>
+<3.500000, 2, "abc", 2>: succeeded <"[3.5abc2][3.5abc2]", 5.500000>
+end of table (2 entries)
+mdb> table s 3.5
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 1, "abc", 1>: succeeded <"[3.5abc1]", 4.500000>
+<3.500000, 2, "abc", 2>: succeeded <"[3.5abc2][3.5abc2]", 5.500000>
+end of table (2 entries)
+mdb> table s 3.51
+call table does not contain 3.510000 in argument position 1.
+mdb> table s 3.5 1
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 1, "abc", 1>: succeeded <"[3.5abc1]", 4.500000>
+end of table (1 entry)
+mdb> table s 3.5 1 abc
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 1, "abc", 1>: succeeded <"[3.5abc1]", 4.500000>
+end of table (1 entry)
+mdb> c
+     E23:    C12  2 CALL pred print_table:s/6-0 (det)
+mdb> f -n
+     E24:    C12  2 EXIT pred print_table:s/6-0 (det)
+mdb> c
+     E25:    C13  2 CALL pred print_table:s/6-0 (det)
+mdb> f -n
+     E26:    C13  2 EXIT pred print_table:s/6-0 (det)
+mdb> c
+     E27:    C14  2 CALL pred print_table:s/6-0 (det)
+mdb> f -n
+     E28:    C14  2 EXIT pred print_table:s/6-0 (det)
+mdb> table s
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 1, "abc", 1>: succeeded <"[3.5abc1]", 4.500000>
+<3.500000, 2, "abc", 2>: succeeded <"[3.5abc2][3.5abc2]", 5.500000>
+<3.500000, 2, "xyz", 3>: succeeded <"[3.5xyz2][3.5xyz2][3.5xyz2]", 6.500000>
+<3.500000, 2, "xyz", 4>: succeeded <"[3.5xyz2][3.5xyz2][3.5xyz2][3.5xyz2]", 7.500000>
+<9.200000, 2, "def", 5>: succeeded <"[9.2def2][9.2def2][9.2def2][9.2def2][9.2def2]", 14.200000>
+end of table (5 entries)
+mdb> table s 3.5
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 1, "abc", 1>: succeeded <"[3.5abc1]", 4.500000>
+<3.500000, 2, "abc", 2>: succeeded <"[3.5abc2][3.5abc2]", 5.500000>
+<3.500000, 2, "xyz", 3>: succeeded <"[3.5xyz2][3.5xyz2][3.5xyz2]", 6.500000>
+<3.500000, 2, "xyz", 4>: succeeded <"[3.5xyz2][3.5xyz2][3.5xyz2][3.5xyz2]", 7.500000>
+end of table (4 entries)
+mdb> table s 3.51
+call table does not contain 3.510000 in argument position 1.
+mdb> table s 3.5 1
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 1, "abc", 1>: succeeded <"[3.5abc1]", 4.500000>
+end of table (1 entry)
+mdb> table s 3.5 1 abc
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 1, "abc", 1>: succeeded <"[3.5abc1]", 4.500000>
+end of table (1 entry)
+mdb> table s 3.5 2
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 2, "abc", 2>: succeeded <"[3.5abc2][3.5abc2]", 5.500000>
+<3.500000, 2, "xyz", 3>: succeeded <"[3.5xyz2][3.5xyz2][3.5xyz2]", 6.500000>
+<3.500000, 2, "xyz", 4>: succeeded <"[3.5xyz2][3.5xyz2][3.5xyz2][3.5xyz2]", 7.500000>
+end of table (3 entries)
+mdb> table s 3.5 2 abc
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 2, "abc", 2>: succeeded <"[3.5abc2][3.5abc2]", 5.500000>
+end of table (1 entry)
+mdb> table s 3.5 2 xyz
+memo table for pred print_table:s/6-0 (det):
+<3.500000, 2, "xyz", 3>: succeeded <"[3.5xyz2][3.5xyz2][3.5xyz2]", 6.500000>
+<3.500000, 2, "xyz", 4>: succeeded <"[3.5xyz2][3.5xyz2][3.5xyz2][3.5xyz2]", 7.500000>
+end of table (2 entries)
+mdb> table s 9.1 2 abc
+call table does not contain 9.100000 in argument position 1.
+mdb> table s 9.2 2 abc
+call table does not contain abc in argument position 3.
+mdb> table s 9.2 2 def
+memo table for pred print_table:s/6-0 (det):
+<9.200000, 2, "def", 5>: succeeded <"[9.2def2][9.2def2][9.2def2][9.2def2][9.2def2]", 14.200000>
+end of table (1 entry)
+mdb> table s 9.2 2 xyz
+call table does not contain xyz in argument position 3.
+mdb> delete 1
+ 1: E stop  interface pred print_table:s/6-0 (det)
+mdb> c -S -n
+75
+24
+6
+0
+yes(9)
+no
+6
+[3.5abc1] 4.50000000000000
+[3.5abc2][3.5abc2] 5.50000000000000
+[3.5xyz2][3.5xyz2][3.5xyz2] 6.50000000000000
+[3.5xyz2][3.5xyz2][3.5xyz2][3.5xyz2] 7.50000000000000
+[9.2def2][9.2def2][9.2def2][9.2def2][9.2def2] 14.2000000000000
Index: tests/debugger/print_table.inp
===================================================================
RCS file: tests/debugger/print_table.inp
diff -N tests/debugger/print_table.inp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/print_table.inp	6 Nov 2002 11:13:42 -0000
@@ -0,0 +1,94 @@
+echo on
+context none
+register --quiet
+b p
+c
+f -n
+table p
+table p 5
+table p 5 2
+c
+f -n
+table p
+table p 5
+table p 5 2
+table p 4
+table p 4 2
+c
+f -n
+table p
+table p 5
+table p 5 2
+table p 4
+table p 2 1
+c
+f -n
+table p
+table p 5
+table p 5 2
+table p 4
+table p 2 1
+table p 1 0
+delete 1
+b q
+c
+f -n
+table q
+table q 3
+table q 3 2
+table q 4
+c
+f -n
+table q
+table q 3
+table q 3 2
+table q 3 0
+table q 4 2
+table q 4 1
+table q 4 0
+delete 1
+b r
+c
+table r
+s
+table r
+table r 3
+c
+table r
+f -n
+table r
+f -n 1
+table r
+delete 1
+b s
+c
+table s
+f -n
+table s
+c
+f -n
+table s
+table s 3.5
+table s 3.51
+table s 3.5 1
+table s 3.5 1 abc
+c
+f -n
+c
+f -n
+c
+f -n
+table s
+table s 3.5
+table s 3.51
+table s 3.5 1
+table s 3.5 1 abc
+table s 3.5 2
+table s 3.5 2 abc
+table s 3.5 2 xyz
+table s 9.1 2 abc
+table s 9.2 2 abc
+table s 9.2 2 def
+table s 9.2 2 xyz
+delete 1
+c -S -n
Index: tests/debugger/print_table.m
===================================================================
RCS file: tests/debugger/print_table.m
diff -N tests/debugger/print_table.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/print_table.m	6 Nov 2002 11:31:53 -0000
@@ -0,0 +1,114 @@
+:- module print_table.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is cc_multi.
+
+:- implementation.
+
+:- import_module std_util, int, float, string, list.
+
+main -->
+	{ p(5, 5, P55) },
+	{ p(4, 3, P43) },
+	{ p(2, 2, P22) },
+	{ p(1, 0, P10) },
+	{ q(3, 2, Q32) ->
+		MaybeQ32 = yes(Q32)
+	;
+		MaybeQ32 = no
+	},
+	{ q(4, 2, Q42) ->
+		MaybeQ42 = yes(Q42)
+	;
+		MaybeQ42 = no
+	},
+	{ r(3, R3) },
+	{ s(3.5, 1, "abc", 1, SA, TA) },
+	{ s(3.5, 2, "abc", 2, SB, TB) },
+	{ s(3.5, 2, "xyz", 3, SC, TC) },
+	{ s(3.5, 2, "xyz", 4, SD, TD) },
+	{ s(9.2, 2, "def", 5, SE, TE) },
+	io__write_int(P55),
+	io__nl,
+	io__write_int(P43),
+	io__nl,
+	io__write_int(P22),
+	io__nl,
+	io__write_int(P10),
+	io__nl,
+	io__write(MaybeQ32),
+	io__nl,
+	io__write(MaybeQ42),
+	io__nl,
+	io__write_int(R3),
+	io__nl,
+	io__write_string(SA),
+	io__write_string(" "),
+	io__write_float(TA),
+	io__nl,
+	io__write_string(SB),
+	io__write_string(" "),
+	io__write_float(TB),
+	io__nl,
+	io__write_string(SC),
+	io__write_string(" "),
+	io__write_float(TC),
+	io__nl,
+	io__write_string(SD),
+	io__write_string(" "),
+	io__write_float(TD),
+	io__nl,
+	io__write_string(SE),
+	io__write_string(" "),
+	io__write_float(TE),
+	io__nl.
+
+:- pred p(int::in, int::in, int::out) is det.
+:- pragma memo(p/3).
+
+p(A, B, S) :-
+	( B = 0 ->
+		S = 0
+	;
+		p(A, B - 1, S0),
+		S = A * B + S0
+	).
+
+:- pred q(int::in, int::in, int::out) is semidet.
+:- pragma memo(q/3).
+
+q(A, B, S) :-
+	( B = 0 ->
+		S = 0
+	; A = 4 * B ->
+		fail
+	;
+		q(A, B - 1, S0),
+		S = A * B + S0
+	).
+
+:- pred r(int::in, int::out) is det.
+:- pragma memo(r/2).
+
+r(A, S) :-
+	( A = 0 ->
+		S = 0
+	;
+		r(A - 1, S0),
+		S = A + S0
+	).
+
+:- pred s(float::in, int::in, string::in, int::in, string::out, float::out)
+	is det.
+:- pragma memo(s/6).
+
+s(A, B, C, D, S, T) :-
+	string__format("%3.1f", [f(A)], AS),
+	string__int_to_string(B, BS),
+	string__append_list(["[", AS, C, BS, "]"], S0),
+	S = from_char_list(list__condense(
+		list__duplicate(D, to_char_list(S0)))),
+	T = A + float(D).
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/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: [12:22:19] waiting for uid20308's lock in /home/mercury1/repository/tests/hard_coded
cvs diff: [12:22:49] obtained lock in /home/mercury1/repository/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: [12:22:58] waiting for uid20308's lock in /home/mercury1/repository/tests/invalid
cvs diff: [12:23:28] obtained lock in /home/mercury1/repository/tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: [12:23:41] waiting for uid20308's lock in /home/mercury1/repository/tests/valid
cvs diff: [12:24:11] obtained lock in /home/mercury1/repository/tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/mercury_trace_browse.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_browse.c,v
retrieving revision 1.26
diff -u -b -r1.26 mercury_trace_browse.c
--- trace/mercury_trace_browse.c	5 Aug 2002 21:46:18 -0000	1.26
+++ trace/mercury_trace_browse.c	5 Nov 2002 23:28:25 -0000
@@ -214,7 +214,7 @@
 				&MR_trace_browser_persistent_state);
 		);
 	}
-	else if (MR_streq(param, "depth") && MR_trace_is_number(value, &depth))
+	else if (MR_streq(param, "depth") && MR_trace_is_natural_number(value, &depth))
 	{
 		MR_TRACE_CALL_MERCURY(
 			ML_BROWSE_set_param_depth(print, browse, print_all,
@@ -223,7 +223,7 @@
 				&MR_trace_browser_persistent_state);
 		);
 	}
-	else if (MR_streq(param, "size") && MR_trace_is_number(value, &size))
+	else if (MR_streq(param, "size") && MR_trace_is_natural_number(value, &size))
 	{
 		MR_TRACE_CALL_MERCURY(
 			ML_BROWSE_set_param_size(print, browse, print_all,
@@ -232,7 +232,7 @@
 				&MR_trace_browser_persistent_state);
 		);
 	}
-	else if (MR_streq(param, "width") && MR_trace_is_number(value, &width))
+	else if (MR_streq(param, "width") && MR_trace_is_natural_number(value, &width))
 	{
 		MR_TRACE_CALL_MERCURY(
 			ML_BROWSE_set_param_width(print, browse, print_all,
@@ -241,7 +241,7 @@
 				&MR_trace_browser_persistent_state);
 		);
 	}
-	else if (MR_streq(param, "lines") && MR_trace_is_number(value, &lines))
+	else if (MR_streq(param, "lines") && MR_trace_is_natural_number(value, &lines))
 	{
 		MR_TRACE_CALL_MERCURY(
 			ML_BROWSE_set_param_lines(print, browse, print_all,
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.147
diff -u -b -r1.147 mercury_trace_internal.c
--- trace/mercury_trace_internal.c	6 Nov 2002 02:02:38 -0000	1.147
+++ trace/mercury_trace_internal.c	6 Nov 2002 14:56:09 -0000
@@ -15,6 +15,7 @@
 #include "mercury_array_macros.h"
 #include "mercury_getopt.h"
 #include "mercury_signal.h"
+#include "mercury_builtin_types.h"
 
 #include "mercury_trace.h"
 #include "mercury_trace_internal.h"
@@ -257,6 +258,67 @@
 	const MR_Make_Completer		MR_cmd_arg_completer;
 } MR_Trace_Command_Info;
 
+typedef	struct {
+	MR_Integer			*MR_ctai_values;
+	int				MR_ctai_value_next;
+	int				MR_ctai_cur_index;
+	MR_Integer			MR_ctai_cur_value;
+} MR_Int_Table_Arg_Values;
+
+typedef	struct {
+	MR_Float			*MR_ctaf_values;
+	int				MR_ctaf_value_next;
+	int				MR_ctaf_cur_index;
+	MR_Float			MR_ctaf_cur_value;
+} MR_Float_Table_Arg_Values;
+
+typedef	struct {
+	MR_ConstString			*MR_ctas_values;
+	int				MR_ctas_value_next;
+	int				MR_ctas_cur_index;
+	MR_ConstString			MR_ctas_cur_value;
+} MR_String_Table_Arg_Values;
+
+typedef	union {
+	MR_Int_Table_Arg_Values		MR_cta_values_int;
+	MR_Float_Table_Arg_Values	MR_cta_values_float;
+	MR_String_Table_Arg_Values	MR_cta_values_string;
+} MR_Table_Arg_Values;
+
+#define	MR_cta_int_values		MR_cta_arg_values.MR_cta_values_int.\
+					MR_ctai_values
+#define	MR_cta_int_value_next		MR_cta_arg_values.MR_cta_values_int.\
+					MR_ctai_value_next
+#define	MR_cta_int_cur_index		MR_cta_arg_values.MR_cta_values_int.\
+					MR_ctai_cur_index
+#define	MR_cta_int_cur_value		MR_cta_arg_values.MR_cta_values_int.\
+					MR_ctai_cur_value
+
+#define	MR_cta_float_values		MR_cta_arg_values.MR_cta_values_float.\
+					MR_ctaf_values
+#define	MR_cta_float_value_next		MR_cta_arg_values.MR_cta_values_float.\
+					MR_ctaf_value_next
+#define	MR_cta_float_cur_index		MR_cta_arg_values.MR_cta_values_float.\
+					MR_ctaf_cur_index
+#define	MR_cta_float_cur_value		MR_cta_arg_values.MR_cta_values_float.\
+					MR_ctaf_cur_value
+
+#define	MR_cta_string_values		MR_cta_arg_values.MR_cta_values_string.\
+					MR_ctas_values
+#define	MR_cta_string_value_next	MR_cta_arg_values.MR_cta_values_string.\
+					MR_ctas_value_next
+#define	MR_cta_string_cur_index		MR_cta_arg_values.MR_cta_values_string.\
+					MR_ctas_cur_index
+#define	MR_cta_string_cur_value		MR_cta_arg_values.MR_cta_values_string.\
+					MR_ctas_cur_value
+
+typedef struct {
+	MR_Table_Trie_Step		MR_cta_step;
+	MR_TrieNode			MR_cta_start_node;
+	MR_bool				MR_cta_valid;
+	MR_Table_Arg_Values		MR_cta_arg_values;
+} MR_Call_Table_Arg;
+
 static	void	MR_trace_internal_ensure_init(void);
 static	MR_bool	MR_trace_internal_create_mdb_window(void);
 static	void	MR_trace_internal_init_from_env(void);
@@ -447,6 +509,9 @@
 static MR_Next	MR_trace_cmd_unhide_events(char **words, int word_count,
 			MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info,
 			MR_Event_Details *event_details, MR_Code **jumpaddr);
+static MR_Next	MR_trace_cmd_table(char **words, int word_count,
+			MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info,
+			MR_Event_Details *event_details, MR_Code **jumpaddr);
 static MR_Next	MR_trace_cmd_save(char **words, int word_count,
 			MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info,
 			MR_Event_Details *event_details, MR_Code **jumpaddr);
@@ -515,6 +580,32 @@
 static	void	MR_trace_usage(const char *cat, const char *item);
 static	void	MR_trace_do_noop(void);
 
+static	MR_bool MR_trace_fill_in_int_table_arg_slot(
+			MR_TrieNode *table_cur_ptr,
+			int arg_num, MR_ConstString given_arg,
+			MR_Call_Table_Arg *call_table_arg_ptr);
+static	MR_bool MR_trace_fill_in_float_table_arg_slot(
+			MR_TrieNode *table_cur_ptr,
+			int arg_num, MR_ConstString given_arg,
+			MR_Call_Table_Arg *call_table_arg_ptr);
+static	MR_bool MR_trace_fill_in_string_table_arg_slot(
+			MR_TrieNode *table_cur_ptr,
+			int arg_num, MR_ConstString given_arg,
+			MR_Call_Table_Arg *call_table_arg_ptr);
+static	MR_bool	MR_update_int_table_arg_slot(MR_TrieNode *table_cur_ptr,
+			MR_Call_Table_Arg *call_table_arg_ptr);
+static	MR_bool	MR_update_float_table_arg_slot(MR_TrieNode *table_cur_ptr,
+			MR_Call_Table_Arg *call_table_arg_ptr);
+static	MR_bool	MR_update_string_table_arg_slot(MR_TrieNode *table_cur_ptr,
+			MR_Call_Table_Arg *call_table_arg_ptr);
+static	void	MR_trace_cmd_table_print_tip(const MR_Proc_Layout *proc,
+			int num_inputs, MR_Call_Table_Arg *call_table_args,
+			MR_TrieNode table);
+static	void	MR_trace_print_subgoal(const MR_Proc_Layout *proc,
+			MR_Subgoal *subgoal);
+static	void	MR_print_answerblock(const MR_Proc_Layout *proc,
+			MR_Word *answer_block);
+
 static	void	MR_trace_set_level_and_report(int ancestor_level,
 			MR_bool detailed, MR_bool print_optionals);
 static	void	MR_trace_browse_internal(MR_Word type_info, MR_Word value,
@@ -689,7 +780,7 @@
 		}
 
 		env = getenv("LINES");
-		if (env != NULL && MR_trace_is_number(env, &n)) {
+		if (env != NULL && MR_trace_is_natural_number(env, &n)) {
 			MR_scroll_limit = n;
 		}
 
@@ -1129,17 +1220,17 @@
 }
 
 /*
-** This function is just a wrapper for MR_print_proc_id_for_debugger,
+** This function is just a wrapper for MR_print_proc_id_and_nl,
 ** with the first argument type being `void *' rather than `FILE *',
 ** so that this function's address can be passed to
 ** MR_process_matching_procedures().
 */
 
 static void
-MR_mdb_print_proc_id(void *data, const MR_Proc_Layout *entry_layout)
+MR_mdb_print_proc_id_and_nl(void *data, const MR_Proc_Layout *entry_layout)
 {
 	FILE	*fp = data;
-	MR_print_proc_id_for_debugger(fp, entry_layout);
+	MR_print_proc_id_and_nl(fp, entry_layout);
 }
 
 /* Options to pass to mmc when compiling queries. */
@@ -1251,7 +1342,7 @@
 		cmd->MR_trace_stop_event = MR_trace_event_number + 1;
 		return STOP_INTERACTING;
 	} else if (word_count == 2
-			&& MR_trace_is_number(words[1], &n))
+			&& MR_trace_is_natural_number(words[1], &n))
 	{
 		cmd->MR_trace_cmd = MR_CMD_GOTO;
 		cmd->MR_trace_stop_event = MR_trace_event_number + n;
@@ -1276,7 +1367,7 @@
 			"forward", "goto"))
 	{
 		; /* the usage message has already been printed */
-	} else if (word_count == 2 && MR_trace_is_number(words[1], &n))
+	} else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n))
 			{
 		if (MR_trace_event_number < n) {
 			cmd->MR_trace_cmd = MR_CMD_GOTO;
@@ -1311,7 +1402,7 @@
 	{
 		; /* the usage message has already been printed */
 		return KEEP_INTERACTING;
-	} else if (word_count == 2 && MR_trace_is_number(words[1], &n))
+	} else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n))
 	{
 		stop_depth = depth - n;
 	} else if (word_count == 1) {
@@ -1350,7 +1441,7 @@
 	{
 		; /* the usage message has already been printed */
 		return KEEP_INTERACTING;
-	} else if (word_count == 2 && MR_trace_is_number(words[1], &n))
+	} else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n))
 	{
 		stop_depth = depth - n;
 	} else if (word_count == 1) {
@@ -1391,7 +1482,7 @@
 	{
 		; /* the usage message has already been printed */
 		return KEEP_INTERACTING;
-	} else if (word_count == 2 && MR_trace_is_number(words[1], &n))
+	} else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n))
 	{
 		stop_depth = depth - n;
 	} else if (word_count == 1) {
@@ -1523,7 +1614,7 @@
 	{
 		; /* the usage message has already been printed */
 	} else if (word_count == 2 &&
-			MR_trace_is_number(words[1], &newdepth))
+			MR_trace_is_natural_number(words[1], &newdepth))
 	{
 		cmd->MR_trace_cmd = MR_CMD_MIN_DEPTH;
 		cmd->MR_trace_stop_depth = newdepth;
@@ -1549,7 +1640,7 @@
 	{
 		; /* the usage message has already been printed */
 	} else if (word_count == 2 &&
-			MR_trace_is_number(words[1], &newdepth))
+			MR_trace_is_natural_number(words[1], &newdepth))
 	{
 		cmd->MR_trace_cmd = MR_CMD_MAX_DEPTH;
 		cmd->MR_trace_stop_depth = newdepth;
@@ -1614,7 +1705,9 @@
 			&words, &word_count, "backward", "retry"))
 	{
 		; /* the usage message has already been printed */
-	} else if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
+	} else if (word_count == 2 &&
+		MR_trace_is_natural_number(words[1], &n))
+	{
 		ancestor_level = n;
 	} else if (word_count == 1) {
 		ancestor_level = 0;
@@ -1688,7 +1781,7 @@
 	{
 		; /* the usage message has already been printed */
 	} else if (word_count == 2 &&
-			MR_trace_is_number(words[1], &n))
+			MR_trace_is_natural_number(words[1], &n))
 	{
 		MR_trace_set_level_and_report(n, detailed,
 			MR_print_optionals);
@@ -1713,7 +1806,7 @@
 	{
 		; /* the usage message has already been printed */
 	} else if (word_count == 2 &&
-			MR_trace_is_number(words[1], &n))
+			MR_trace_is_natural_number(words[1], &n))
 	{
 		MR_trace_set_level_and_report(
 			MR_trace_current_level() + n, detailed,
@@ -1743,7 +1836,7 @@
 	{
 		; /* the usage message has already been printed */
 	} else if (word_count == 2 &&
-			MR_trace_is_number(words[1], &n))
+			MR_trace_is_natural_number(words[1], &n))
 	{
 		MR_trace_set_level_and_report(
 			MR_trace_current_level() - n, detailed,
@@ -1828,7 +1921,7 @@
 			fprintf(MR_mdb_err, "mdb: %s.\n", problem);
 		}
 	} else if (word_count == 3 && MR_streq(words[1], "action")
-			&& MR_trace_is_number(words[2], &n))
+			&& MR_trace_is_natural_number(words[2], &n))
 	{
 		const char	*problem;
 
@@ -1893,7 +1986,7 @@
 			fprintf(MR_mdb_err, "mdb: %s.\n", problem);
 		}
 	} else if (word_count == 3 && MR_streq(words[1], "action")
-			&& MR_trace_is_number(words[2], &n))
+			&& MR_trace_is_natural_number(words[2], &n))
 	{
 		const char	*problem;
 
@@ -2160,8 +2253,7 @@
 			for (i = 0; i < matches.match_proc_next; i++)
 			{
 				fprintf(MR_mdb_out, "%d: ", i);
-				MR_print_proc_id_for_debugger(
-					MR_mdb_out,
+				MR_print_proc_id_and_nl(MR_mdb_out,
 					matches.match_procs[i]);
 			}
 
@@ -2193,7 +2285,7 @@
 				}
 
 				MR_free(line2);
-			} else if (MR_trace_is_number(line2, &i)) {
+			} else if (MR_trace_is_natural_number(line2, &i)) {
 				if (0 <= i &&
 					i < matches.match_proc_next)
 				{
@@ -2224,7 +2316,7 @@
 			ignore_count, file, line, &problem);
 		MR_maybe_print_spy_point(slot, problem);
 	} else if (word_count == 2 &&
-			MR_trace_is_number(words[1], &breakline))
+			MR_trace_is_natural_number(words[1], &breakline))
 	{
 		int	slot;
 
@@ -2259,7 +2351,7 @@
 			&words, &word_count, "breakpoint", "ignore"))
 	{
 		; /* the usage message has already been printed */
-	} else if (word_count == 2 && MR_trace_is_number(words[1], &n))
+	} else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n))
 	{
 		if (0 <= n && n < MR_spy_point_next
 				&& MR_spy_points[n]->spy_exists)
@@ -2319,7 +2411,7 @@
 	MR_Code **jumpaddr)
 {
 	int	n;
-	if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
+	if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
 		if (0 <= n && n < MR_spy_point_next
 				&& MR_spy_points[n]->spy_exists)
 		{
@@ -2377,7 +2469,7 @@
 {
 	int	n;
 
-	if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
+	if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
 		if (0 <= n && n < MR_spy_point_next
 				&& MR_spy_points[n]->spy_exists)
 		{
@@ -2437,7 +2529,7 @@
 {
 	int	n;
 
-	if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
+	if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
 		if (0 <= n && n < MR_spy_point_next
 				&& MR_spy_points[n]->spy_exists)
 		{
@@ -2680,7 +2772,7 @@
 				fprintf(MR_mdb_out,
 					"Scroll control enabled.\n");
 			}
-		} else if (MR_trace_is_number(words[1], &n)) {
+		} else if (MR_trace_is_natural_number(words[1], &n)) {
 			MR_scroll_limit = n;
 			if (MR_trace_internal_interacting) {
 				fprintf(MR_mdb_out,
@@ -2855,12 +2947,10 @@
 			MR_trace_add_alias(words[1],
 				words+2, word_count-2);
 			if (MR_trace_internal_interacting) {
-				MR_trace_print_alias(MR_mdb_out,
-					words[1]);
+				MR_trace_print_alias(MR_mdb_out, words[1]);
 			}
 		} else {
-			fprintf(MR_mdb_out,
-				"`%s' is not a valid command.\n",
+			fprintf(MR_mdb_out, "`%s' is not a valid command.\n",
 				words[2]);
 		}
 	}
@@ -2876,8 +2966,7 @@
 	if (word_count == 2) {
 		if (MR_trace_remove_alias(words[1])) {
 			if (MR_trace_internal_interacting) {
-				fprintf(MR_mdb_out,
-					"Alias `%s' removed.\n",
+				fprintf(MR_mdb_out, "Alias `%s' removed.\n",
 					words[1]);
 			}
 		} else {
@@ -2906,7 +2995,7 @@
 	help_text = MR_trace_read_help_text();
 	if (word_count != 3) {
 		MR_trace_usage("help", "document_category");
-	} else if (! MR_trace_is_number(words[1], &slot)) {
+	} else if (! MR_trace_is_natural_number(words[1], &slot)) {
 		MR_trace_usage("help", "document_category");
 	} else {
 		msg = MR_trace_add_cat(words[2], slot, help_text);
@@ -2933,7 +3022,7 @@
 	help_text = MR_trace_read_help_text();
 	if (word_count != 4) {
 		MR_trace_usage("help", "document");
-	} else if (! MR_trace_is_number(words[2], &slot)) {
+	} else if (! MR_trace_is_natural_number(words[2], &slot)) {
 		MR_trace_usage("help", "document");
 	} else {
 		msg = MR_trace_add_item(words[1], words[3], slot,
@@ -3417,6 +3506,666 @@
 }
 
 static MR_Next
+MR_trace_cmd_table(char **words, int word_count,
+	MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info,
+	MR_Event_Details *event_details, MR_Code **jumpaddr)
+{
+	MR_Call_Table_Arg	*call_table_args;
+	MR_Matches_Info		matches;
+	const MR_Proc_Layout	*proc;
+	MR_Proc_Spec		spec;
+	const MR_Table_Gen	*table_gen;
+	MR_TrieNode		table_cur;
+	int			num_inputs;
+	int			n;
+	int			i;
+	int			cur_arg;
+	int			num_tips;
+
+	if (word_count < 2) {
+		MR_trace_usage("developer", "table");
+		return KEEP_INTERACTING;
+	}
+
+	if (! MR_parse_proc_spec(words[1], &spec)) {
+		fflush(MR_mdb_out);
+		fprintf(MR_mdb_err,
+			"mdb: invalid procedure specification.\n");
+		return KEEP_INTERACTING;
+	}
+
+	MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+	matches = MR_search_for_matching_procedures(&spec);
+	if (matches.match_proc_next == 0) {
+		fflush(MR_mdb_out);
+		fprintf(MR_mdb_err,
+			"mdb: there is no such procedure.\n");
+		return KEEP_INTERACTING;
+	} else if (matches.match_proc_next == 1) {
+		proc = matches.match_procs[0];
+	} else {
+		char	buf[100];
+		char	*line2;
+
+		fflush(MR_mdb_out);
+		fprintf(MR_mdb_err, "Ambiguous procedure specification. "
+			"The matches are:\n");
+		for (i = 0; i < matches.match_proc_next; i++)
+		{
+			fprintf(MR_mdb_out, "%d: ", i);
+			MR_print_proc_id_and_nl(MR_mdb_out,
+				matches.match_procs[i]);
+		}
+
+		sprintf(buf, "\nWhich procedure's table do you want to print "
+			"(0-%d)? ",
+			matches.match_proc_next - 1);
+		line2 = MR_trace_getline(buf, MR_mdb_in, MR_mdb_out);
+		n = -1;
+		if (line2 == NULL || !MR_trace_is_natural_number(line2, &n)) {
+			n = -1;
+			fprintf(MR_mdb_out, "none of them\n");
+		} else if (n < 0 || n >= matches.match_proc_next) {
+			n = -1;
+			fprintf(MR_mdb_out, "invalid choice\n");
+		}
+
+		if (line2 != NULL) {
+			MR_free(line2);
+		}
+
+		if (n >= 0) {
+			proc = matches.match_procs[n];
+		} else {
+			return KEEP_INTERACTING;
+		}
+	}
+
+	switch (MR_sle_eval_method(proc)) {
+		case MR_EVAL_METHOD_NORMAL:
+			MR_print_proc_id(MR_mdb_out, proc);
+			fprintf(MR_mdb_out, " isn't tabled.\n");
+			return KEEP_INTERACTING;
+
+		case MR_EVAL_METHOD_LOOP_CHECK:
+		case MR_EVAL_METHOD_MEMO:
+		case MR_EVAL_METHOD_MINIMAL:
+			break;
+
+		case MR_EVAL_METHOD_TABLE_IO:
+		case MR_EVAL_METHOD_TABLE_IO_DECL:
+		case MR_EVAL_METHOD_TABLE_IO_UNITIZE:
+		case MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL:
+			fprintf(MR_mdb_out, "IO tabled predicates do not have"
+				" their own tables.\n");
+			return KEEP_INTERACTING;
+
+		default:
+			MR_fatal_error("unrecognized eval method");
+			return KEEP_INTERACTING;
+	}
+
+	/*
+	** words[0] is the command, words[1] is the procedure spec;
+	** words[2] is the first argument. We step over the command and the
+	** procedure spec, to leave words[] containing only the argument
+	** values.
+	*/
+
+	words += 2;
+	word_count -= 2;
+
+	table_gen = proc->MR_sle_table_info.MR_table_gen;
+	num_inputs = table_gen->MR_table_gen_num_inputs;
+
+	if (word_count > num_inputs) {
+		fprintf(MR_mdb_out, "There are only %d input arguments.\n",
+			num_inputs);
+		return KEEP_INTERACTING;
+	}
+
+	call_table_args = MR_GC_NEW_ARRAY(MR_Call_Table_Arg, num_inputs);
+	if (call_table_args == NULL) {
+		MR_fatal_error("MR_trace_cmd_table: "
+			"couldn't allocate call_table_args");
+	}
+
+	table_cur = proc->MR_sle_tabling_pointer;
+	for (cur_arg = 0; cur_arg < num_inputs; cur_arg++) {
+		switch (table_gen->MR_table_gen_input_steps[cur_arg]) {
+			case MR_TABLE_STEP_INT:
+			case MR_TABLE_STEP_FLOAT:
+			case MR_TABLE_STEP_STRING:
+				/* these are OK */
+				break;
+			default:
+				fprintf(MR_mdb_out, "Sorry, can handle only "
+					"integer, float and string arguments "
+					"for now.\n");
+				MR_GC_free(call_table_args);
+				return KEEP_INTERACTING;
+		}
+
+		call_table_args[cur_arg].MR_cta_step =
+			table_gen->MR_table_gen_input_steps[cur_arg];
+		call_table_args[cur_arg].MR_cta_valid = MR_FALSE;
+	}
+
+	for (cur_arg = 0; cur_arg < word_count; cur_arg++) {
+		MR_bool	success;
+
+		switch (call_table_args[cur_arg].MR_cta_step) {
+			case MR_TABLE_STEP_INT:
+				success =
+					MR_trace_fill_in_int_table_arg_slot(
+						&table_cur, cur_arg + 1,
+						words[cur_arg],
+						&call_table_args[cur_arg]);
+				break;
+
+			case MR_TABLE_STEP_FLOAT:
+				success =
+					MR_trace_fill_in_float_table_arg_slot(
+						&table_cur, cur_arg + 1,
+						words[cur_arg],
+						&call_table_args[cur_arg]);
+				break;
+
+			case MR_TABLE_STEP_STRING:
+				success =
+					MR_trace_fill_in_string_table_arg_slot(
+						&table_cur, cur_arg + 1,
+						words[cur_arg],
+						&call_table_args[cur_arg]);
+				break;
+
+			default:
+				MR_fatal_error("arg not int, float or string "
+					"after check");
+		}
+
+		if (! success) {
+			/* the error message has already been printed */
+			MR_GC_free(call_table_args);
+			return KEEP_INTERACTING;
+		}
+	}
+
+	if (word_count == num_inputs) {
+		MR_trace_cmd_table_print_tip(proc, num_inputs,
+			call_table_args, table_cur);
+		MR_GC_free(call_table_args);
+		return KEEP_INTERACTING;
+	}
+
+	switch (MR_sle_eval_method(proc)) {
+		case MR_EVAL_METHOD_LOOP_CHECK:
+			fprintf(MR_mdb_out, "loopcheck table for ");
+			MR_print_proc_id(MR_mdb_out, proc);
+			fprintf(MR_mdb_out, ":\n");
+			break;
+
+		case MR_EVAL_METHOD_MEMO:
+			fprintf(MR_mdb_out, "memo table for ");
+			MR_print_proc_id(MR_mdb_out, proc);
+			fprintf(MR_mdb_out, ":\n");
+			break;
+
+		case MR_EVAL_METHOD_MINIMAL:
+			fprintf(MR_mdb_out, "minimal model table for ");
+			MR_print_proc_id(MR_mdb_out, proc);
+			fprintf(MR_mdb_out, ":\n");
+			break;
+
+		default:
+			MR_fatal_error("MR_trace_cmd_table: bad eval method");
+	}
+
+	cur_arg = word_count;
+	num_tips = 0;
+	for (;;) {
+		MR_bool	goto_prev_arg;
+
+		switch (call_table_args[cur_arg].MR_cta_step) {
+			case MR_TABLE_STEP_INT:
+				goto_prev_arg = MR_update_int_table_arg_slot(
+					&table_cur, &call_table_args[cur_arg]);
+				break;
+
+			case MR_TABLE_STEP_FLOAT:
+				goto_prev_arg = MR_update_float_table_arg_slot(
+					&table_cur, &call_table_args[cur_arg]);
+				break;
+
+			case MR_TABLE_STEP_STRING:
+				goto_prev_arg = MR_update_string_table_arg_slot(
+					&table_cur, &call_table_args[cur_arg]);
+				break;
+
+
+			default:
+				MR_fatal_error("arg not int, float or string "
+					"after check");
+		}
+
+		if (goto_prev_arg) {
+			goto prev_arg;
+		}
+
+		cur_arg++;
+
+		if (cur_arg >= num_inputs) {
+			MR_trace_cmd_table_print_tip(proc, num_inputs,
+				call_table_args, table_cur);
+			num_tips++;
+			goto prev_arg_last;
+		}
+
+		continue;
+
+	prev_arg:
+		call_table_args[cur_arg].MR_cta_valid = MR_FALSE;
+		/* fall through */
+
+	prev_arg_last:
+		cur_arg--;
+		table_cur = call_table_args[cur_arg].MR_cta_start_node;
+
+		if (cur_arg < word_count) {
+			break;
+		}
+	}
+
+	fprintf(MR_mdb_out, "end of table (%d %s)\n",
+		num_tips, (num_tips == 1 ? "entry" : "entries"));
+	MR_GC_free(call_table_args);
+	return KEEP_INTERACTING;
+}
+
+static MR_bool
+MR_trace_fill_in_int_table_arg_slot(MR_TrieNode *table_cur_ptr,
+	int arg_num, MR_ConstString given_arg,
+	MR_Call_Table_Arg *call_table_arg_ptr)
+{
+	MR_Integer	n;
+	MR_TrieNode	table_next;
+
+	if (! MR_trace_is_integer(given_arg, &n))
+	{
+		fprintf(MR_mdb_out, "argument %d is not an integer.\n",
+			arg_num);
+		return MR_FALSE;
+	}
+
+	table_next = MR_int_hash_lookup(*table_cur_ptr, n);
+	if (table_next == NULL) {
+		fprintf(MR_mdb_out, "call table does not contain "
+			"%d in argument position %d.\n",
+			n, arg_num);
+		return MR_FALSE;
+	}
+
+	call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+	call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+	call_table_arg_ptr->MR_cta_int_values = NULL;
+	call_table_arg_ptr->MR_cta_int_value_next = -1;
+	call_table_arg_ptr->MR_cta_int_cur_index = -1;
+	call_table_arg_ptr->MR_cta_int_cur_value = n;
+	*table_cur_ptr = table_next;
+
+	return MR_TRUE;
+}
+
+static MR_bool
+MR_trace_fill_in_float_table_arg_slot(MR_TrieNode *table_cur_ptr,
+	int arg_num, MR_ConstString given_arg,
+	MR_Call_Table_Arg *call_table_arg_ptr)
+{
+	MR_Float	f;
+	MR_TrieNode	table_next;
+
+	if (! MR_trace_is_float(given_arg, &f))
+	{
+		fprintf(MR_mdb_out, "argument %d is not a float.\n",
+			arg_num);
+		return MR_FALSE;
+	}
+
+	table_next = MR_float_hash_lookup(*table_cur_ptr, f);
+	if (table_next == NULL) {
+		fprintf(MR_mdb_out, "call table does not contain "
+			"%f in argument position %d.\n",
+			f, arg_num);
+		return MR_FALSE;
+	}
+
+	call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+	call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+	call_table_arg_ptr->MR_cta_float_values = NULL;
+	call_table_arg_ptr->MR_cta_float_value_next = -1;
+	call_table_arg_ptr->MR_cta_float_cur_index = -1;
+	call_table_arg_ptr->MR_cta_float_cur_value = f;
+	*table_cur_ptr = table_next;
+
+	return MR_TRUE;
+}
+
+static MR_bool
+MR_trace_fill_in_string_table_arg_slot(MR_TrieNode *table_cur_ptr,
+	int arg_num, MR_ConstString given_arg,
+	MR_Call_Table_Arg *call_table_arg_ptr)
+{
+	MR_ConstString	s;
+	MR_TrieNode	table_next;
+
+	s = given_arg;
+
+	table_next = MR_string_hash_lookup(*table_cur_ptr, s);
+	if (table_next == NULL) {
+		fprintf(MR_mdb_out, "call table does not contain "
+			"%s in argument position %d.\n",
+			s, arg_num);
+		return MR_FALSE;
+	}
+
+	call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+	call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+	call_table_arg_ptr->MR_cta_string_values = NULL;
+	call_table_arg_ptr->MR_cta_string_value_next = -1;
+	call_table_arg_ptr->MR_cta_string_cur_index = -1;
+	call_table_arg_ptr->MR_cta_string_cur_value = s;
+	*table_cur_ptr = table_next;
+
+	return MR_TRUE;
+}
+
+static MR_bool
+MR_update_int_table_arg_slot(MR_TrieNode *table_cur_ptr,
+	MR_Call_Table_Arg *call_table_arg_ptr)
+{
+	MR_TrieNode	table_next;
+	MR_Integer	*values;
+	int		value_next;
+
+	if (call_table_arg_ptr->MR_cta_valid
+		&& call_table_arg_ptr->MR_cta_int_values != NULL)
+	{
+		call_table_arg_ptr->MR_cta_int_cur_index++;
+	} else {
+		if (! MR_int_hash_contents(*table_cur_ptr,
+			&values, &value_next))
+		{
+			return MR_TRUE;
+		}
+
+		call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+		call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+		call_table_arg_ptr->MR_cta_int_values = values;
+		call_table_arg_ptr->MR_cta_int_value_next = value_next;
+		call_table_arg_ptr->MR_cta_int_cur_index = 0;
+	}
+
+	if (call_table_arg_ptr->MR_cta_int_cur_index
+		>= call_table_arg_ptr->MR_cta_int_value_next)
+	{
+		return MR_TRUE;
+	}
+
+	call_table_arg_ptr->MR_cta_int_cur_value =
+		call_table_arg_ptr->MR_cta_int_values[
+			call_table_arg_ptr->MR_cta_int_cur_index];
+
+	table_next = MR_int_hash_lookup(
+		call_table_arg_ptr->MR_cta_start_node, 
+		call_table_arg_ptr->MR_cta_int_cur_value);
+
+	if (table_next == NULL) {
+		MR_fatal_error("MR_update_int_table_arg_slot: bad lookup");
+	}
+
+	*table_cur_ptr = table_next;
+	return MR_FALSE;
+}
+
+static MR_bool
+MR_update_float_table_arg_slot(MR_TrieNode *table_cur_ptr,
+	MR_Call_Table_Arg *call_table_arg_ptr)
+{
+	MR_TrieNode	table_next;
+	MR_Float	*values;
+	int		value_next;
+
+	if (call_table_arg_ptr->MR_cta_valid
+		&& call_table_arg_ptr->MR_cta_float_values != NULL)
+	{
+		call_table_arg_ptr->MR_cta_float_cur_index++;
+	} else {
+		if (! MR_float_hash_contents(*table_cur_ptr,
+			&values, &value_next))
+		{
+			return MR_TRUE;
+		}
+
+		call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+		call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+		call_table_arg_ptr->MR_cta_float_values = values;
+		call_table_arg_ptr->MR_cta_float_value_next = value_next;
+		call_table_arg_ptr->MR_cta_float_cur_index = 0;
+	}
+
+	if (call_table_arg_ptr->MR_cta_float_cur_index
+		>= call_table_arg_ptr->MR_cta_float_value_next)
+	{
+		return MR_TRUE;
+	}
+
+	call_table_arg_ptr->MR_cta_float_cur_value =
+		call_table_arg_ptr->MR_cta_float_values[
+			call_table_arg_ptr->MR_cta_float_cur_index];
+
+	table_next = MR_float_hash_lookup(
+		call_table_arg_ptr->MR_cta_start_node, 
+		call_table_arg_ptr->MR_cta_float_cur_value);
+
+	if (table_next == NULL) {
+		MR_fatal_error("MR_update_float_table_arg_slot: bad lookup");
+	}
+
+	*table_cur_ptr = table_next;
+	return MR_FALSE;
+}
+
+static MR_bool
+MR_update_string_table_arg_slot(MR_TrieNode *table_cur_ptr,
+	MR_Call_Table_Arg *call_table_arg_ptr)
+{
+	MR_TrieNode	table_next;
+	MR_ConstString	*values;
+	int		value_next;
+
+	if (call_table_arg_ptr->MR_cta_valid
+		&& call_table_arg_ptr->MR_cta_string_values != NULL)
+	{
+		call_table_arg_ptr->MR_cta_string_cur_index++;
+	} else {
+		if (! MR_string_hash_contents(*table_cur_ptr,
+			&values, &value_next))
+		{
+			return MR_TRUE;
+		}
+
+		call_table_arg_ptr->MR_cta_start_node = *table_cur_ptr;
+		call_table_arg_ptr->MR_cta_valid = MR_TRUE;
+		call_table_arg_ptr->MR_cta_string_values = values;
+		call_table_arg_ptr->MR_cta_string_value_next = value_next;
+		call_table_arg_ptr->MR_cta_string_cur_index = 0;
+	}
+
+	if (call_table_arg_ptr->MR_cta_string_cur_index
+		>= call_table_arg_ptr->MR_cta_string_value_next)
+	{
+		return MR_TRUE;
+	}
+
+	call_table_arg_ptr->MR_cta_string_cur_value =
+		call_table_arg_ptr->MR_cta_string_values[
+			call_table_arg_ptr->MR_cta_string_cur_index];
+
+	table_next = MR_string_hash_lookup(
+		call_table_arg_ptr->MR_cta_start_node, 
+		call_table_arg_ptr->MR_cta_string_cur_value);
+
+	if (table_next == NULL) {
+		MR_fatal_error("MR_update_string_table_arg_slot: bad lookup");
+	}
+
+	*table_cur_ptr = table_next;
+	return MR_FALSE;
+}
+
+static void
+MR_trace_cmd_table_print_tip(const MR_Proc_Layout *proc, int num_inputs,
+	MR_Call_Table_Arg *call_table_args, MR_TrieNode table)
+{
+	int	i;
+
+	fprintf(MR_mdb_out, "<");
+	for (i = 0; i < num_inputs; i++) {
+		if (i > 0) {
+			fprintf(MR_mdb_out, ", ");
+		}
+
+		switch (call_table_args[i].MR_cta_step) {
+			case MR_TABLE_STEP_INT:
+				fprintf(MR_mdb_out, "%d",
+					call_table_args[i].
+					MR_cta_int_cur_value);
+				break;
+
+			case MR_TABLE_STEP_FLOAT:
+				fprintf(MR_mdb_out, "%f",
+					call_table_args[i].
+					MR_cta_float_cur_value);
+				break;
+
+			case MR_TABLE_STEP_STRING:
+				fprintf(MR_mdb_out, "\"%s\"",
+					call_table_args[i].
+					MR_cta_string_cur_value);
+				break;
+
+			default:
+				MR_fatal_error("arg not int, float or string "
+					"after check");
+		}
+	}
+
+	fprintf(MR_mdb_out, ">: ");
+
+	if (MR_sle_eval_method(proc) == MR_EVAL_METHOD_MINIMAL) {
+		MR_Subgoal	*subgoal;
+		int		subgoal_num;
+
+		fprintf(MR_mdb_out, "trie node %p\n", table);
+		subgoal = table->MR_subgoal;
+		if (subgoal == NULL) {
+			fprintf(MR_mdb_out, "uninitialized\n");
+		} else {
+			MR_trace_print_subgoal(proc, subgoal);
+		}
+	} else if (MR_sle_eval_method(proc) == MR_EVAL_METHOD_MEMO) {
+		switch (table->MR_simpletable_status) {
+			case MR_SIMPLETABLE_UNINITIALIZED:
+				fprintf(MR_mdb_out, "uninitialized\n");
+				break;
+			case MR_SIMPLETABLE_WORKING:
+				fprintf(MR_mdb_out, "working\n");
+				break;
+			case MR_SIMPLETABLE_FAILED:
+				fprintf(MR_mdb_out, "failed\n");
+				break;
+			case MR_SIMPLETABLE_SUCCEEDED:
+				fprintf(MR_mdb_out, "succeeded (no outputs)\n");
+				break;
+			default:
+				fprintf(MR_mdb_out, "succeeded <");
+				MR_print_answerblock(proc,
+					table->MR_answerblock);
+				fprintf(MR_mdb_out, ">\n");
+				break;
+		}
+	} else if (MR_sle_eval_method(proc) == MR_EVAL_METHOD_LOOP_CHECK) {
+		switch (table->MR_simpletable_status) {
+			case MR_SIMPLETABLE_UNINITIALIZED:
+				fprintf(MR_mdb_out, "uninitialized\n");
+				break;
+			case MR_SIMPLETABLE_WORKING:
+				fprintf(MR_mdb_out, "working\n");
+				break;
+			default:
+				MR_fatal_error("MR_trace_cmd_table_print_tip: "
+					"bad loopcheck status");
+		}
+	} else {
+		MR_fatal_error("MR_trace_cmd_table_print_tip: bad eval method");
+	}
+}
+
+static void
+MR_trace_print_subgoal(const MR_Proc_Layout *proc, MR_Subgoal *subgoal)
+{
+	fprintf(MR_mdb_out, "cannot print subgoals yet\n");
+}
+
+static void
+MR_print_answerblock(const MR_Proc_Layout *proc, MR_Word *answer_block)
+{
+	const MR_PseudoTypeInfo	*ptis;
+	MR_PseudoTypeInfo	pti;
+	MR_TypeCtorInfo		tci;
+	int			num_inputs;
+	int			num_outputs;
+	int			i;
+
+	num_inputs = proc->MR_sle_table_info.MR_table_gen->
+		MR_table_gen_num_inputs;
+	num_outputs = proc->MR_sle_table_info.MR_table_gen->
+		MR_table_gen_num_outputs;
+
+	ptis = proc->MR_sle_table_info.MR_table_gen->MR_table_gen_ptis;
+	ptis += num_inputs;
+
+	for (i = 0; i < num_outputs; i++) {
+		if (i > 0) {
+			fprintf(MR_mdb_out, ", ");
+		}
+
+		pti = ptis[i];
+		if (MR_PSEUDO_TYPEINFO_IS_VARIABLE(pti)) {
+			fprintf(MR_mdb_out, "poly");
+			continue;
+		}
+
+		tci = MR_PSEUDO_TYPEINFO_GET_TYPE_CTOR_INFO(pti);
+		if (tci == &MR_TYPE_CTOR_INFO_NAME(builtin, int, 0)) {
+			fprintf(MR_mdb_out, "%ld", (long) answer_block[i]);
+		} else if (tci == &MR_TYPE_CTOR_INFO_NAME(builtin, float, 0)) {
+			fprintf(MR_mdb_out, "%f",
+#ifdef	MR_HIGHLEVEL_CODE
+				(double) MR_unbox_float(answer_block[i]));
+#else
+				(double) MR_word_to_float(answer_block[i]));
+#endif
+		} else if (tci == &MR_TYPE_CTOR_INFO_NAME(builtin, string, 0)) {
+			fprintf(MR_mdb_out, "\"%s\"",
+				(char *) answer_block[i]);
+		} else {
+			fprintf(MR_mdb_out, "value of unsupported type");
+		}
+	}
+}
+
+static MR_Next
 MR_trace_cmd_source(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
 	MR_Event_Info *event_info, MR_Event_Details *event_details,
 	MR_Code **jumpaddr)
@@ -4570,8 +5319,8 @@
 	** with the command word, to put the command word first.
 	*/
 
-	if (raw_word_count > 1 && MR_trace_is_number(raw_words[0], &i)
-			&& ! MR_trace_is_number(raw_words[1], &i)) {
+	if (raw_word_count > 1 && MR_trace_is_natural_number(raw_words[0], &i)
+			&& ! MR_trace_is_natural_number(raw_words[1], &i)) {
 		s = raw_words[0];
 		raw_words[0] = raw_words[1];
 		raw_words[1] = s;
@@ -4691,7 +5440,7 @@
 	if (*word_count == 0) {
 		alias_key = "EMPTY";
 		alias_copy_start = 0;
-	} else if (MR_trace_is_number(*words[0], &n)) {
+	} else if (MR_trace_is_natural_number(*words[0], &n)) {
 		alias_key = "NUMBER";
 		alias_copy_start = 0;
 	} else {
@@ -5287,6 +6036,8 @@
 		MR_trace_on_off_args, MR_trace_null_completer },
 	{ "developer", "dd_dd", MR_trace_cmd_dd_dd,
 		NULL, MR_trace_filename_completer},
+	{ "developer", "table", MR_trace_cmd_table,
+		NULL, MR_trace_null_completer },
 
 	/* End of doc/mdb_command_list. */
 	{ NULL, "NUMBER", NULL,
Index: trace/mercury_trace_tables.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_tables.c,v
retrieving revision 1.21
diff -u -b -r1.21 mercury_trace_tables.c
--- trace/mercury_trace_tables.c	6 Mar 2002 14:35:05 -0000	1.21
+++ trace/mercury_trace_tables.c	5 Nov 2002 23:28:25 -0000
@@ -222,7 +222,7 @@
 		fprintf(fp, "module %s\n", MR_module_infos[i]->MR_ml_name);
 		fprintf(fp, "====================\n");
 		for (j = 0; j < MR_module_infos[i]->MR_ml_proc_count; j++) {
-			MR_print_proc_id_for_debugger(fp,
+			MR_print_proc_id_and_nl(fp,
 				MR_module_infos[i]->MR_ml_procs[j]);
 		}
 	}
@@ -252,8 +252,7 @@
 	} else {
 		fprintf(fp, "List of procedures in module `%s'\n\n", name);
 		for (j = 0; j < module->MR_ml_proc_count; j++) {
-			MR_print_proc_id_for_debugger(fp,
-				module->MR_ml_procs[j]);
+			MR_print_proc_id_and_nl(fp, module->MR_ml_procs[j]);
 		}
 	}
 }
@@ -858,7 +857,7 @@
 }
 
 void
-MR_print_proc_id_for_debugger(FILE *fp, const MR_Proc_Layout *entry_layout)
+MR_print_proc_id_and_nl(FILE *fp, const MR_Proc_Layout *entry_layout)
 {
 	MR_print_proc_id(fp, entry_layout);
 	fprintf(fp, "\n");
Index: trace/mercury_trace_tables.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_tables.h,v
retrieving revision 1.12
diff -u -b -r1.12 mercury_trace_tables.h
--- trace/mercury_trace_tables.h	6 Mar 2002 14:35:06 -0000	1.12
+++ trace/mercury_trace_tables.h	5 Nov 2002 23:28:25 -0000
@@ -140,11 +140,15 @@
 */
 
 extern	void	MR_process_matching_procedures(MR_Proc_Spec *spec,
-			void f(void *, const MR_Proc_Layout *), 
-			void *data);
+			void f(void *, const MR_Proc_Layout *), void *data);
 
-extern	void	MR_print_proc_id_for_debugger(FILE *fp,
-			const MR_Proc_Layout *entry);
+/*
+** MR_print_proc_id_and_nl(fp, proc):
+** 	Print the id of the procedure identified by proc, followed by a
+** 	newline.
+*/
+
+extern	void	MR_print_proc_id_and_nl(FILE *fp, const MR_Proc_Layout *proc);
 
 /*
 ** MR_proc_layout_stats(fp):
Index: trace/mercury_trace_util.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_util.c,v
retrieving revision 1.8
diff -u -b -r1.8 mercury_trace_util.c
--- trace/mercury_trace_util.c	18 Feb 2002 07:01:32 -0000	1.8
+++ trace/mercury_trace_util.c	6 Nov 2002 09:03:54 -0000
@@ -24,7 +24,7 @@
 }
 
 MR_bool
-MR_trace_is_number(const char *word, int *value)
+MR_trace_is_natural_number(const char *word, int *value)
 {
 	if (MR_isdigit(*word)) {
 		*value = *word - '0';
@@ -40,6 +40,51 @@
 	}
 
 	return MR_FALSE;
+}
+
+MR_bool
+MR_trace_is_integer(const char *word, MR_Integer *value)
+{
+	int	sign;
+
+	if (*word == '-') {
+		sign = -1;
+		word++;
+	} else {
+		sign = 1;
+	}
+
+	if (MR_isdigit(*word)) {
+		*value = *word - '0';
+		word++;
+		while (MR_isdigit(*word)) {
+			*value = (*value * 10) + *word - '0';
+			word++;
+		}
+
+		if (*word == '\0') {
+			*value = *value * sign;
+			return MR_TRUE;
+		}
+	}
+
+	return MR_FALSE;
+}
+
+MR_bool
+MR_trace_is_float(const char *word, MR_Float *value)
+{
+	double	tmpf;
+	char   	tmpc;
+	MR_bool	success;
+
+	/* this duplicates the logic of string__to_float */
+	success =
+		(!MR_isspace(word[0])) &&
+		(sscanf(word, "%lf%c", &tmpf, &tmpc) == 1);
+		/* MR_TRUE if sscanf succeeds, MR_FALSE otherwise */
+	*value = tmpf;
+	return success;
 }
 
 void
Index: trace/mercury_trace_util.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_util.h,v
retrieving revision 1.8
diff -u -b -r1.8 mercury_trace_util.h
--- trace/mercury_trace_util.h	22 Jul 2002 07:13:14 -0000	1.8
+++ trace/mercury_trace_util.h	7 Nov 2002 03:25:43 -0000
@@ -16,6 +16,7 @@
 #define MERCURY_TRACE_UTIL_H
 
 #include "mercury_std.h"		/* for MR_bool        */
+#include "mercury_float.h"		/* for MR_Float    */
 #include "mercury_types.h"		/* for MR_Word etc */
 #include "mercury_library_types.h"	/* for MercuryFile */
 #include <stdio.h>			/* for FILE        */
@@ -58,12 +59,22 @@
 			MercuryFile *mercury_file);
 
 /*
-** MR_trace_is_number checks whether the given word contains a natural number,
-** i.e. a sequence of digits. If yes, it puts the value of the number in
-** *value and returns MR_TRUE, otherwise it returns MR_FALSE.
+** MR_trace_is_natural_number checks whether the given word contains a natural
+** number, i.e. a sequence of digits. If yes, it puts the value of the number
+** in *value and returns MR_TRUE, otherwise it returns MR_FALSE.
+**
+** MR_trace_is_integer is similar, but it also allows an initial minus sign
+** to denote a negative number.
+**
+** MR_trace_is_float is similar again, but it also allows an optional
+** fractional part.
 */
 
-extern	MR_bool	MR_trace_is_number(const char *word, int *value);
+extern	MR_bool	MR_trace_is_natural_number(const char *word, int *value);
+
+extern	MR_bool	MR_trace_is_integer(const char *word, MR_Integer *value);
+
+extern	MR_bool	MR_trace_is_float(const char *word, MR_Float *value);
 
 /*
 ** These functions print the values of sets of Mercury abstract machine
Index: trace/mercury_trace_vars.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_vars.c,v
retrieving revision 1.49
diff -u -b -r1.49 mercury_trace_vars.c
--- trace/mercury_trace_vars.c	9 Sep 2002 05:52:18 -0000	1.49
+++ trace/mercury_trace_vars.c	5 Nov 2002 23:28:25 -0000
@@ -907,7 +907,7 @@
         path++;
     }
 
-    if (MR_trace_is_number(word_spec, &n)) {
+    if (MR_trace_is_natural_number(word_spec, &n)) {
         var_spec.MR_var_spec_kind = MR_VAR_SPEC_NUMBER;
         var_spec.MR_var_spec_number = n;
         var_spec.MR_var_spec_name = NULL; /* unused */
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