[m-rev.] for review: extending I/O tabling towards declarative debugging

Zoltan Somogyi zs at cs.mu.OZ.AU
Fri Jan 18 15:54:22 AEDT 2002


For review by Mark.

Estimated hours taken: 40
Branches: main

A large step towards declarative debugging of goals that do I/O. This step
does everything needed for that except modify the declarative debugger itself;
that is for Mark to do.

The new functionality is enabled by the new option --trace-table-io-decl.
It can be tested by the new debugger commands "print action <action-number>"
and "browse action <action-number>"

The new option is currently not documented, because the declarative debugger
does not yet use the information it provides. The new debugger commands are
not documented because they are meant only for implementors, at least for
now.

Since this change adds a field to proc_layout structures, any workspaces
compiled with debugging enabled will need to do a cvs update when this change
is installed.

compiler/options.m:
	Add the option --trace-table-io-decl. When set, this causes the
	compiler to transform I/O action primitives to allow declarative
	debugging of I/O actions.

compiler/handle_options.m:
	Make --trace-table-io-decl imply --trace-table-io.

compiler/table_gen.m:
	Perform the transformation, which is similar to the existing
	--trace-table-io transformation, but preserves the identity of all
	non-io-state arguments (not just the outputs) and the identity
	of the I/O primitive itself.

	Provide better names for variables generated by tabling
	transformations.

compiler/goal_util.m:
	Add extra parameters to procedures whose job it is to create new
	goals to name the variables in those goals.

compiler/layout.m:
	Add a new layout structure to contain the information the runtime
	system needs to interpret the information saved by the new
	transformation.

compiler/layout_out.m:
	Output the new layout structure.

compiler/continuation_info.m:
	Add a field to proc_layouts to point to the declarative I/O tabling
	structure, and another to identify the proc_layout without using LLDS
	types.

compiler/code_gen.m:
	Provide the definition of this field when appropriate.

compiler/hlds_pred.m:
	Add a field to proc_infos to store the information from the tabling
	transformation until code generation.

compiler/stack_layout.m:
	Add a mechanism for transforming the high level description of I/O
	action tabling data in proc_infos to the low level description we need
	to generate C data structures.

compiler/hlds_data.m:
	Add a new cons_id and a new cons_tag; they are used to refer to I/O
	tabling structures in code generated by the new transformation.

compiler/*.m:
	Handle the updates to global data types above.

library/Mmakefile:
	Record the dependence of table_builtin.m on
	runtime/mercury_tabling_macros.h.

library/table_builtin.m:
	Modernize some old code.

library/varset.m:
	Add a mechanism for creating a variable that is named iff the caller
	has a name for it.

runtime/mercury_layout_util.[ch]:
	Add a function for materializing type parameters from an answer block,
	not from registers or a closure.

runtime/mercury_stack_layout.h:
	Declare a C type for the data structure holding information about
	I/O primitives transformed by --trace-table-io-decl, and add a field
	to proc_layout structures to point to these new structures.

	Add a new evaluation method for --trace-table-io-decl.

runtime/mercury_tabling_macros.h:
	Add some conditionally-compiled debugging code to the primitive for
	saving answers.

trace/mercury_trace_vars.[ch]:
	Add functions for printing I/O action goals.

trace/mercury_trace_internal.c:
	Add code for recognizing and implementing commands to print I/O
	action goals.

trace/mercury_trace.c:
	Add code for handling the new eval method.

tests/debugger/tabled_read.{m,inp,exp*}:
	Add a polymorphic I/O action primitive, add calls to it, and test
	the printing of both monomorphic and polymorphic action goals.

tests/debugger/Mmakefile:
	Compile tabled_read.m with --trace-table-io-decl instead of simply
	--trace-table-io.

Zoltan.

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/bytecode_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/bytecode_gen.m,v
retrieving revision 1.65
diff -u -b -r1.65 bytecode_gen.m
--- compiler/bytecode_gen.m	2001/10/31 16:58:06	1.65
+++ compiler/bytecode_gen.m	2001/12/25 08:11:52
@@ -741,6 +741,9 @@
 		ConsId = tabling_pointer_const(_, _),
 		sorry(this_file, "bytecode cannot implement tabling")
 	;
+		ConsId = table_io_decl(_),
+		sorry(this_file, "bytecode cannot implement table io decl")
+	;
 		ConsId = deep_profiling_proc_static(_),
 		sorry(this_file, "bytecode cannot implement deep profiling")
 	).
@@ -773,6 +776,8 @@
 	unexpected(this_file, "tabling_pointer_constant cons tag for non-tabling_pointer_constant cons id").
 bytecode_gen__map_cons_tag(deep_profiling_proc_static_tag(_), _) :-
 	unexpected(this_file, "deep_profiling_proc_static_tag cons tag for non-deep_profiling_proc_static cons id").
+bytecode_gen__map_cons_tag(table_io_decl_tag(_), _) :-
+	unexpected(this_file, "table_io_decl_tag cons tag for non-table_io_decl cons id").
 bytecode_gen__map_cons_tag(reserved_address(_), _) :-
 	% These should only be generated if the --num-reserved-addresses
 	% or --num-reserved-objects options are used.
Index: compiler/code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_gen.m,v
retrieving revision 1.97
diff -u -b -r1.97 code_gen.m
--- compiler/code_gen.m	2001/04/24 03:58:51	1.97
+++ compiler/code_gen.m	2001/12/26 13:20:57
@@ -75,7 +75,7 @@
 :- import_module code_aux, code_util, middle_rec, llds_out.
 
 % Misc compiler modules
-:- import_module builtin_ops, passes_aux.
+:- import_module builtin_ops, passes_aux, rtti.
 :- import_module globals, options.
 
 % Standard library modules
@@ -313,8 +313,15 @@
 		Instructions = Instructions0
 	),
 
-	( BasicStackLayout = yes ->
+	proc_info_get_table_io_decl(ProcInfo, MaybeTableIoDecl),
+	(
+		( BasicStackLayout = yes
+		; MaybeTableIoDecl = yes(_TableIoDecl)
+		)
+	->
 			% Create the procedure layout structure.
+		RttiProcLabel = rtti__make_proc_label(ModuleInfo,
+			PredId, ProcId),
 		code_info__get_layout_info(InternalMap, CodeInfo, _),
 		code_util__make_local_entry_label(ModuleInfo, PredId, ProcId,
 			no, EntryLabel),
@@ -322,10 +329,11 @@
 		proc_info_get_initial_instmap(ProcInfo, ModuleInfo, InstMap0),
 		proc_info_varset(ProcInfo, VarSet),
 		proc_info_vartypes(ProcInfo, VarTypes),
-		ProcLayout = proc_layout_info(EntryLabel, Detism, TotalSlots,
-			MaybeSuccipSlot, EvalMethod, MaybeTraceCallLabel,
-			MaxTraceReg, Goal, InstMap0, TraceSlotInfo,
-			ForceProcId, VarSet, VarTypes, InternalMap),
+		ProcLayout = proc_layout_info(RttiProcLabel, EntryLabel,
+			Detism, TotalSlots, MaybeSuccipSlot, EvalMethod,
+			MaybeTraceCallLabel, MaxTraceReg, Goal, InstMap0,
+			TraceSlotInfo, ForceProcId, VarSet, VarTypes,
+			InternalMap, MaybeTableIoDecl),
 		global_data_add_new_proc_layout(GlobalData0,
 			proc(PredId, ProcId), ProcLayout, GlobalData1)
 	;
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.133
diff -u -b -r1.133 code_util.m
--- compiler/code_util.m	2001/10/31 16:58:07	1.133
+++ compiler/code_util.m	2001/12/25 07:46:52
@@ -694,6 +694,7 @@
 		tabling_pointer_constant(PredId,ProcId)).
 code_util__cons_id_to_tag(deep_profiling_proc_static(PPId), _, _,
 		deep_profiling_proc_static_tag(PPId)).
+code_util__cons_id_to_tag(table_io_decl(PPId), _, _, table_io_decl_tag(PPId)).
 code_util__cons_id_to_tag(cons(Name, Arity), Type, ModuleInfo, Tag) :-
 	(
 			% handle the `character' type specially
Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.38
diff -u -b -r1.38 continuation_info.m
--- compiler/continuation_info.m	2000/10/13 13:55:17	1.38
+++ compiler/continuation_info.m	2001/12/28 07:44:59
@@ -52,7 +52,7 @@
 :- interface.
 
 :- import_module llds, hlds_module, hlds_pred, hlds_goal, prog_data.
-:- import_module (inst), instmap, trace, globals.
+:- import_module (inst), instmap, trace, rtti, globals.
 :- import_module bool, std_util, list, assoc_list, set, map.
 
 	%
@@ -61,6 +61,8 @@
 	%
 :- type proc_layout_info
 	--->	proc_layout_info(
+			rtti_proc_label	:: rtti_proc_label,
+					% The identity of the procedure.
 			entry_label	:: label,
 					% Determines which stack is used.
 			detism		:: determinism,
@@ -104,9 +106,10 @@
 			varset		:: prog_varset,
 					% The names of all the variables.
 			vartypes	:: vartypes,
-			internal_map	:: proc_label_layout_info
+			internal_map	:: proc_label_layout_info,
 					% Info for each internal label,
 					% needed for basic_stack_layouts.
+			table_io_decl	:: maybe(table_io_decl_info)
 		).
 
 	%
@@ -307,6 +310,9 @@
 	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.
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -727,6 +733,75 @@
 			string__format("%s: %s %s",
 			    [s("continuation_info__find_typeinfos_for_tvars"),
 				s("can't find rval for type_info var"),
+				s(VarString)], ErrStr),
+			error(ErrStr)
+		)
+	)),
+	list__map(FindLocn, TypeInfoLocns, TypeInfoVarLocns),
+	map__from_corresponding_lists(TypeVars, TypeInfoVarLocns,
+		TypeInfoDataMap).
+
+%---------------------------------------------------------------------------%
+
+continuation_info__generate_table_decl_io_layout(ProcInfo, NumberedVars,
+		TableIoDeclLayout) :-
+	proc_info_vartypes(ProcInfo, VarTypes),
+	set__init(TypeVars0),
+	continuation_info__build_table_io_decl_arg_info(VarTypes,
+		NumberedVars, ArgLayouts, TypeVars0, TypeVars),
+	set__to_sorted_list(TypeVars, TypeVarsList),
+	continuation_info__find_typeinfos_for_tvars_table_io_decl(TypeVarsList,
+		NumberedVars, ProcInfo, TypeInfoDataMap),
+	TableIoDeclLayout = table_io_decl_info(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,
+	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,
+		[Var - SlotNum | NumberedVars], [ArgLayout | ArgLayouts],
+		TypeVars0, TypeVars) :-
+	map__lookup(VarTypes, Var, Type),
+	ArgLayout = table_io_decl_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,
+		NumberedVars, ArgLayouts, TypeVars1, TypeVars).
+
+%---------------------------------------------------------------------------%
+
+:- pred continuation_info__find_typeinfos_for_tvars_table_io_decl(
+	list(tvar)::in, assoc_list(prog_var, int)::in, proc_info::in,
+	map(tvar, table_io_decl_locn)::out) is det.
+
+continuation_info__find_typeinfos_for_tvars_table_io_decl(TypeVars,
+		NumberedVars, ProcInfo, TypeInfoDataMap) :-
+	proc_info_varset(ProcInfo, VarSet),
+	proc_info_typeinfo_varmap(ProcInfo, TypeInfoMap),
+	map__apply_to_list(TypeVars, TypeInfoMap, TypeInfoLocns),
+	FindLocn = lambda([TypeInfoLocn::in, Locn::out] is det, (
+		(
+			(
+				TypeInfoLocn = typeclass_info(TypeInfoVar,
+					FieldNum),
+				assoc_list__search(NumberedVars, TypeInfoVar,
+					Slot),
+				LocnPrime = indirect(Slot, FieldNum)
+			;
+				TypeInfoLocn = type_info(TypeInfoVar),
+				assoc_list__search(NumberedVars, TypeInfoVar,
+					Slot),
+				LocnPrime = direct(Slot)
+			)
+		->
+			Locn = LocnPrime
+		;
+			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("can't find slot for type_info var"),
 				s(VarString)], ErrStr),
 			error(ErrStr)
 		)
Index: compiler/dependency_graph.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dependency_graph.m,v
retrieving revision 1.54
diff -u -b -r1.54 dependency_graph.m
--- compiler/dependency_graph.m	2001/05/31 05:59:32	1.54
+++ compiler/dependency_graph.m	2001/12/25 07:46:58
@@ -395,6 +395,7 @@
 :- pred dependency_graph__add_arcs_in_cons(cons_id, relation_key,
 			dependency_graph, dependency_graph).
 :- mode dependency_graph__add_arcs_in_cons(in, in, in, out) is det.
+
 dependency_graph__add_arcs_in_cons(cons(_, _), _Caller,
 				DepGraph, DepGraph).
 dependency_graph__add_arcs_in_cons(int_const(_), _Caller,
@@ -434,6 +435,8 @@
 dependency_graph__add_arcs_in_cons(tabling_pointer_const(_, _),
 				_Caller, DepGraph, DepGraph).
 dependency_graph__add_arcs_in_cons(deep_profiling_proc_static(_),
+				_Caller, DepGraph, DepGraph).
+dependency_graph__add_arcs_in_cons(table_io_decl(_),
 				_Caller, DepGraph, DepGraph).
 
 %-----------------------------------------------------------------------------%
Index: compiler/goal_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/goal_util.m,v
retrieving revision 1.71
diff -u -b -r1.71 goal_util.m
--- compiler/goal_util.m	2001/11/26 09:30:56	1.71
+++ compiler/goal_util.m	2001/12/09 03:32:17
@@ -212,8 +212,8 @@
 	%
 :- pred goal_util__generate_simple_call(module_name::in, string::in,
 		list(prog_var)::in, determinism::in, maybe(goal_feature)::in,
-		assoc_list(prog_var, inst)::in, module_info::in,
-		term__context::in, hlds_goal::out) is det.
+	assoc_list(prog_var, inst)::in, module_info::in, term__context::in,
+	hlds_goal::out) is det.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -1272,15 +1272,14 @@
 	;
 		instmap_delta_from_assoc_list(InstMap, InstMapDelta)
 	),
-	goal_info_init(NonLocals, InstMapDelta, Detism,
+	goal_info_init(NonLocals, InstMapDelta, Detism, Context,
 		CallGoalInfo0),
-	goal_info_set_context(CallGoalInfo0, Context, CallGoalInfo1),
 	(
 		MaybeFeature = yes(Feature),
-		goal_info_add_feature(CallGoalInfo1, Feature, CallGoalInfo)
+		goal_info_add_feature(CallGoalInfo0, Feature, CallGoalInfo)
 	;
 		MaybeFeature = no,
-		CallGoalInfo = CallGoalInfo1
+		CallGoalInfo = CallGoalInfo0
 	),
 	CallGoal = Call - CallGoalInfo.
 
Index: compiler/handle_options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/handle_options.m,v
retrieving revision 1.125
diff -u -b -r1.125 handle_options.m
--- compiler/handle_options.m	2002/01/11 07:44:29	1.125
+++ compiler/handle_options.m	2002/01/14 08:18:31
@@ -498,6 +498,9 @@
 		[]
 	),
 
+	% --trace-table-io-decl is an extension of --trace-table-io
+	option_implies(trace_table_io_decl, trace_table_io, bool(yes)),
+
 	% Execution tracing requires
 	% 	- disabling optimizations that would change
 	% 	  the trace being generated (except with --trace-optimized)
Index: compiler/higher_order.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/higher_order.m,v
retrieving revision 1.92
diff -u -b -r1.92 higher_order.m
--- compiler/higher_order.m	2002/01/09 06:12:37	1.92
+++ compiler/higher_order.m	2002/01/09 06:57:20
@@ -954,10 +954,10 @@
 		[IndexGoal, CallGoal | Goals],
 		[ResultVar | Vars], ProcInfo0, ProcInfo) :-
 	MakeResultType(Arg, ResultType),
-	proc_info_create_var_from_type(ProcInfo0, ResultType,
+	proc_info_create_var_from_type(ProcInfo0, ResultType, no,
 		ResultVar, ProcInfo1),
 	MaybeContext = no,
-	make_int_const_construction(Index, IndexGoal,
+	make_int_const_construction(Index, no, IndexGoal,
 		IndexVar, ProcInfo1, ProcInfo2),
 	CallArgs = [TypeClassInfoVar, IndexVar, ResultVar],
 
@@ -2206,7 +2206,8 @@
 		error("generate_unsafe_type_cast: pred table lookup failed")
 	),
 	hlds_pred__initial_proc_id(ProcId),
-	proc_info_create_var_from_type(ProcInfo0, ToType, CastArg, ProcInfo),
+	proc_info_create_var_from_type(ProcInfo0, ToType, no,
+		CastArg, ProcInfo),
 	set__list_to_set([Arg, CastArg], NonLocals),
 	instmap_delta_from_assoc_list([CastArg - ground(shared, none)],
 		InstMapDelta),
@@ -2220,8 +2221,8 @@
 
 unwrap_no_tag_arg(WrappedType, Context, Constructor, Arg, UnwrappedArg,
 		Goal, ProcInfo0, ProcInfo) :-
-	proc_info_create_var_from_type(ProcInfo0, WrappedType, UnwrappedArg,
-		ProcInfo),
+	proc_info_create_var_from_type(ProcInfo0, WrappedType, no,
+		UnwrappedArg, ProcInfo),
 	ConsId = cons(Constructor, 1),
 	UniModes = [(ground(shared, none) - free) ->
 			(ground(shared, none) - ground(shared, none))],
Index: compiler/hlds_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_data.m,v
retrieving revision 1.63
diff -u -b -r1.63 hlds_data.m
--- compiler/hlds_data.m	2002/01/16 01:13:18	1.63
+++ compiler/hlds_data.m	2002/01/17 11:52:39
@@ -55,7 +55,11 @@
 				% that points to the table that implements
 				% memoization, loop checking or the minimal
 				% model semantics for the given procedure.
-			;	deep_profiling_proc_static(rtti_proc_label).
+			;	deep_profiling_proc_static(rtti_proc_label)
+				% The address of a procedure's layout
+				% structure, used e.g. for I/O tabling for
+				% declarative debugging.
+			;	table_io_decl(rtti_proc_label).
 
 	% A cons_defn is the definition of a constructor (i.e. a constant
 	% or a functor) for a particular type.
@@ -190,8 +194,9 @@
 	error("cons_id_arity: can't get arity of tabling_pointer_const").
 cons_id_arity(deep_profiling_proc_static(_), _) :-
 	error("cons_id_arity: can't get arity of deep_profiling_proc_static").
+cons_id_arity(table_io_decl(_), _) :-
+	error("cons_id_arity: can't get arity of table_io_decl").
 
-
 cons_id_maybe_arity(cons(_, Arity), yes(Arity)).
 cons_id_maybe_arity(int_const(_), yes(0)).
 cons_id_maybe_arity(string_const(_), yes(0)).
@@ -202,6 +207,7 @@
 cons_id_maybe_arity(base_typeclass_info_const(_, _, _, _), no).
 cons_id_maybe_arity(tabling_pointer_const(_, _), no).
 cons_id_maybe_arity(deep_profiling_proc_static(_), no).
+cons_id_maybe_arity(table_io_decl(_), no).
 
 make_functor_cons_id(term__atom(Name), Arity,
 		cons(unqualified(Name), Arity)).
@@ -364,6 +370,10 @@
 	;	deep_profiling_proc_static_tag(rtti_proc_label)
 			% This is for constants representing procedure
 			% descriptions for deep profiling.
+	;	table_io_decl_tag(rtti_proc_label)
+			% This is for constants representing the structure
+			% that allows us to decode the contents of the memory
+			% block containing the headvars of I/O primitives.
 	;	single_functor
 			% This is for types with a single functor
 			% (and possibly also some constants represented
@@ -469,6 +479,7 @@
 get_primary_tag(base_typeclass_info_constant(_, _, _)) = no.
 get_primary_tag(tabling_pointer_constant(_, _)) = no.
 get_primary_tag(deep_profiling_proc_static_tag(_)) = no.
+get_primary_tag(table_io_decl_tag(_)) = no.
 get_primary_tag(single_functor) = yes(0).
 get_primary_tag(unshared_tag(PrimaryTag)) = yes(PrimaryTag).
 get_primary_tag(shared_remote_tag(PrimaryTag, _SecondaryTag)) =
@@ -488,6 +499,7 @@
 get_secondary_tag(base_typeclass_info_constant(_, _, _)) = no.
 get_secondary_tag(tabling_pointer_constant(_, _)) = no.
 get_secondary_tag(deep_profiling_proc_static_tag(_)) = no.
+get_secondary_tag(table_io_decl_tag(_)) = no.
 get_secondary_tag(single_functor) = no.
 get_secondary_tag(unshared_tag(_)) = no.
 get_secondary_tag(shared_remote_tag(_PrimaryTag, SecondaryTag)) =
Index: compiler/hlds_goal.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_goal.m,v
retrieving revision 1.91
diff -u -b -r1.91 hlds_goal.m
--- compiler/hlds_goal.m	2002/01/09 06:12:39	1.91
+++ compiler/hlds_goal.m	2002/01/09 07:28:27
@@ -925,50 +925,51 @@
 :- pred make_const_construction(prog_var, cons_id, hlds_goal).
 :- mode make_const_construction(in, in, out) is det.
 
-:- pred make_int_const_construction(int, hlds_goal, prog_var,
-		map(prog_var, type), map(prog_var, type),
-		prog_varset, prog_varset).
-:- mode make_int_const_construction(in, out, out, in, out, in, out) is det.
+:- pred make_int_const_construction(int, maybe(string), hlds_goal, prog_var,
+	map(prog_var, type), map(prog_var, type), prog_varset, prog_varset).
+:- mode make_int_const_construction(in, in, out, out, in, out, in, out) is det.
 
-:- pred make_string_const_construction(string, hlds_goal, prog_var,
-		map(prog_var, type), map(prog_var, type),
+:- pred make_string_const_construction(string, maybe(string),
+	hlds_goal, prog_var, map(prog_var, type), map(prog_var, type),
 		prog_varset, prog_varset).
-:- mode make_string_const_construction(in, out, out, in, out, in, out) is det.
+:- mode make_string_const_construction(in, in, out, out, in, out, in, out)
+	is det.
 
-:- pred make_float_const_construction(float, hlds_goal, prog_var,
-		map(prog_var, type), map(prog_var, type),
+:- pred make_float_const_construction(float, maybe(string),
+	hlds_goal, prog_var, map(prog_var, type), map(prog_var, type),
 		prog_varset, prog_varset).
-:- mode make_float_const_construction(in, out, out, in, out, in, out) is det.
+:- mode make_float_const_construction(in, in, out, out, in, out, in, out)
+	is det.
 
-:- pred make_char_const_construction(char, hlds_goal, prog_var,
-		map(prog_var, type), map(prog_var, type),
-		prog_varset, prog_varset).
-:- mode make_char_const_construction(in, out, out, in, out, in, out) is det.
+:- pred make_char_const_construction(char, maybe(string), hlds_goal, prog_var,
+	map(prog_var, type), map(prog_var, type), prog_varset, prog_varset).
+:- mode make_char_const_construction(in, in, out, out, in, out, in, out)
+	is det.
 
-:- pred make_const_construction(cons_id, (type), hlds_goal, prog_var,
-		map(prog_var, type), map(prog_var, type),
+:- pred make_const_construction(cons_id, (type), maybe(string),
+	hlds_goal, prog_var, map(prog_var, type), map(prog_var, type),
 		prog_varset, prog_varset).
-:- mode make_const_construction(in, in, out, out, in, out, in, out) is det.
+:- mode make_const_construction(in, in, in, out, out, in, out, in, out) is det.
 
-:- pred make_int_const_construction(int, hlds_goal, prog_var,
+:- pred make_int_const_construction(int, maybe(string), hlds_goal, prog_var,
 		proc_info, proc_info).
-:- mode make_int_const_construction(in, out, out, in, out) is det.
+:- mode make_int_const_construction(in, in, out, out, in, out) is det.
 
-:- pred make_string_const_construction(string, hlds_goal, prog_var,
-		proc_info, proc_info).
-:- mode make_string_const_construction(in, out, out, in, out) is det.
+:- pred make_string_const_construction(string, maybe(string),
+	hlds_goal, prog_var, proc_info, proc_info).
+:- mode make_string_const_construction(in, in, out, out, in, out) is det.
 
-:- pred make_float_const_construction(float, hlds_goal, prog_var,
-		proc_info, proc_info).
-:- mode make_float_const_construction(in, out, out, in, out) is det.
+:- pred make_float_const_construction(float, maybe(string),
+	hlds_goal, prog_var, proc_info, proc_info).
+:- mode make_float_const_construction(in, in, out, out, in, out) is det.
 
-:- pred make_char_const_construction(char, hlds_goal, prog_var,
+:- pred make_char_const_construction(char, maybe(string), hlds_goal, prog_var,
 		proc_info, proc_info).
-:- mode make_char_const_construction(in, out, out, in, out) is det.
+:- mode make_char_const_construction(in, in, out, out, in, out) is det.
 
-:- pred make_const_construction(cons_id, (type), hlds_goal, prog_var,
-		proc_info, proc_info).
-:- mode make_const_construction(in, in, out, out, in, out) is det.
+:- pred make_const_construction(cons_id, (type), maybe(string), hlds_goal,
+	prog_var, proc_info, proc_info).
+:- mode make_const_construction(in, in, in, out, out, in, out) is det.
 
 	% Given the variable info field from a pragma foreign_code, get all the
 	% variable names.
@@ -1729,53 +1730,62 @@
 
 %-----------------------------------------------------------------------------%
 
-make_int_const_construction(Int, Goal, Var, ProcInfo0, ProcInfo) :-
-	proc_info_create_var_from_type(ProcInfo0, int_type, Var, ProcInfo),
+make_int_const_construction(Int, MaybeName, Goal, Var, ProcInfo0, ProcInfo) :-
+	proc_info_create_var_from_type(ProcInfo0, int_type, MaybeName,
+		Var, ProcInfo),
 	make_int_const_construction(Var, Int, Goal).
 
-make_string_const_construction(String, Goal, Var, ProcInfo0, ProcInfo) :-
-	proc_info_create_var_from_type(ProcInfo0, string_type, Var, ProcInfo),
+make_string_const_construction(String, MaybeName, Goal, Var,
+		ProcInfo0, ProcInfo) :-
+	proc_info_create_var_from_type(ProcInfo0, string_type, MaybeName,
+		Var, ProcInfo),
 	make_string_const_construction(Var, String, Goal).
 
-make_float_const_construction(Float, Goal, Var, ProcInfo0, ProcInfo) :-
-	proc_info_create_var_from_type(ProcInfo0, float_type, Var, ProcInfo),
+make_float_const_construction(Float, MaybeName, Goal, Var,
+		ProcInfo0, ProcInfo) :-
+	proc_info_create_var_from_type(ProcInfo0, float_type, MaybeName,
+		Var, ProcInfo),
 	make_float_const_construction(Var, Float, Goal).
 
-make_char_const_construction(Char, Goal, Var, ProcInfo0, ProcInfo) :-
-	proc_info_create_var_from_type(ProcInfo0, char_type, Var, ProcInfo),
+make_char_const_construction(Char, MaybeName, Goal, Var,
+		ProcInfo0, ProcInfo) :-
+	proc_info_create_var_from_type(ProcInfo0, char_type, MaybeName,
+		Var, ProcInfo),
 	make_char_const_construction(Var, Char, Goal).
 
-make_const_construction(ConsId, Type, Goal, Var, ProcInfo0, ProcInfo) :-
-	proc_info_create_var_from_type(ProcInfo0, Type, Var, ProcInfo),
+make_const_construction(ConsId, Type, MaybeName, Goal, Var,
+		ProcInfo0, ProcInfo) :-
+	proc_info_create_var_from_type(ProcInfo0, Type, MaybeName,
+		Var, ProcInfo),
 	make_const_construction(Var, ConsId, Goal).
 
-make_int_const_construction(Int, Goal, Var, VarTypes0, VarTypes,
+make_int_const_construction(Int, MaybeName, Goal, Var, VarTypes0, VarTypes,
 		VarSet0, VarSet) :-
-	varset__new_var(VarSet0, Var, VarSet),
+	varset__new_maybe_named_var(VarSet0, MaybeName, Var, VarSet),
 	map__det_insert(VarTypes0, Var, int_type, VarTypes),
 	make_int_const_construction(Var, Int, Goal).
 
-make_string_const_construction(String, Goal, Var, VarTypes0, VarTypes,
-		VarSet0, VarSet) :-
-	varset__new_var(VarSet0, Var, VarSet),
+make_string_const_construction(String, MaybeName, Goal, Var,
+		VarTypes0, VarTypes, VarSet0, VarSet) :-
+	varset__new_maybe_named_var(VarSet0, MaybeName, Var, VarSet),
 	map__det_insert(VarTypes0, Var, string_type, VarTypes),
 	make_string_const_construction(Var, String, Goal).
 
-make_float_const_construction(Float, Goal, Var, VarTypes0, VarTypes,
-		VarSet0, VarSet) :-
-	varset__new_var(VarSet0, Var, VarSet),
+make_float_const_construction(Float, MaybeName, Goal, Var,
+		VarTypes0, VarTypes, VarSet0, VarSet) :-
+	varset__new_maybe_named_var(VarSet0, MaybeName, Var, VarSet),
 	map__det_insert(VarTypes0, Var, float_type, VarTypes),
 	make_float_const_construction(Var, Float, Goal).
 
-make_char_const_construction(Char, Goal, Var, VarTypes0, VarTypes,
-		VarSet0, VarSet) :-
-	varset__new_var(VarSet0, Var, VarSet),
+make_char_const_construction(Char, MaybeName, Goal, Var,
+		VarTypes0, VarTypes, VarSet0, VarSet) :-
+	varset__new_maybe_named_var(VarSet0, MaybeName, Var, VarSet),
 	map__det_insert(VarTypes0, Var, char_type, VarTypes),
 	make_char_const_construction(Var, Char, Goal).
 
-make_const_construction(ConsId, Type, Goal, Var, VarTypes0, VarTypes,
-		VarSet0, VarSet) :-
-	varset__new_var(VarSet0, Var, VarSet),
+make_const_construction(ConsId, Type, MaybeName, Goal, Var,
+		VarTypes0, VarTypes, VarSet0, VarSet) :-
+	varset__new_maybe_named_var(VarSet0, MaybeName, Var, VarSet),
 	map__det_insert(VarTypes0, Var, Type, VarTypes),
 	make_const_construction(Var, ConsId, Goal).
 
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.272
diff -u -b -r1.272 hlds_out.m
--- compiler/hlds_out.m	2002/01/16 01:13:19	1.272
+++ compiler/hlds_out.m	2002/01/17 11:52:39
@@ -317,6 +317,7 @@
 	"<tabling_pointer>").
 hlds_out__cons_id_to_string(deep_profiling_proc_static(_),
 	"<deep_profiling_proc_static>").
+hlds_out__cons_id_to_string(table_io_decl(_), "<table_io_decl>").
 
 hlds_out__write_cons_id(cons(SymName, Arity)) -->
 	prog_out__write_sym_name_and_arity(SymName / Arity).
@@ -338,6 +339,8 @@
 	io__write_string("<tabling_pointer>").
 hlds_out__write_cons_id(deep_profiling_proc_static(_)) -->
 	io__write_string("<deep_profiling_proc_static>").
+hlds_out__write_cons_id(table_io_decl(_)) -->
+	io__write_string("<table_io_decl>").
 
 	% The code of this predicate duplicates the functionality of
 	% error_util__describe_one_pred_name. Changes here should be made
@@ -2211,6 +2214,16 @@
 		io__write_string(" (mode "),
 		io__write_int(ProcIdInt),
 		io__write_string("))")
+	;
+		{ ConsId = table_io_decl(RttiProcLabel) },
+		{ rtti__proc_label_pred_proc_id(RttiProcLabel,
+			PredId, ProcId) },
+		io__write_string("table_io_decl("),
+		hlds_out__write_pred_id(ModuleInfo, PredId),
+		{ proc_id_to_int(ProcId, ProcIdInt) },
+		io__write_string(" (mode "),
+		io__write_int(ProcIdInt),
+		io__write_string("))")
 	).
 
 hlds_out__write_var_modes([], [], _, _, _) --> [].
@@ -3243,6 +3256,8 @@
 	io__write_string("minimal").
 hlds_out__write_eval_method(eval_table_io) -->
 	io__write_string("table_io").
+hlds_out__write_eval_method(eval_table_io_decl) -->
+	io__write_string("table_io_decl").
 
 %-----------------------------------------------------------------------------%
 
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.101
diff -u -b -r1.101 hlds_pred.m
--- compiler/hlds_pred.m	2001/08/24 15:44:47	1.101
+++ compiler/hlds_pred.m	2002/01/14 13:37:35
@@ -1499,6 +1499,26 @@
 					% left-to-right, from zero.)
 		).
 
+:- type table_io_decl_arg_info
+	--->	table_io_decl_arg_info(
+			headvar		:: prog_var,
+			slot_num	:: int,
+			arg_type	:: (type)
+		).
+
+	% 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
+	--->	direct(int)
+	;	indirect(int, int).
+
+:- type table_io_decl_info
+	--->	table_io_decl_info(
+			list(table_io_decl_arg_info),
+			map(tvar, table_io_decl_locn)
+		).
+
 :- pred proc_info_init(arity, list(type), list(mode), maybe(list(mode)),
 	maybe(list(is_live)), maybe(determinism), prog_context,
 	is_address_taken, proc_info).
@@ -1691,6 +1711,13 @@
 :- 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_set_table_io_decl(proc_info, maybe(table_io_decl_info),
+	proc_info).
+:- mode proc_info_set_table_io_decl(in, in, out) is det.
+
 :- pred proc_info_get_maybe_deep_profile_info(proc_info::in,
 	maybe(deep_profile_proc_info)::out) is det.
 
@@ -1718,8 +1745,9 @@
 :- mode proc_info_ensure_unique_names(in, out) is det.
 
 	% Create a new variable of the given type to the procedure.
-:- pred proc_info_create_var_from_type(proc_info, type, prog_var, proc_info).
-:- mode proc_info_create_var_from_type(in, in, out, out) is det.
+:- pred proc_info_create_var_from_type(proc_info, type, maybe(string),
+	prog_var, proc_info).
+:- mode proc_info_create_var_from_type(in, in, in, out, out) is det.
 
 	% Create a new variable for each element of the list of types.
 :- pred proc_info_create_vars_from_types(proc_info,
@@ -1926,6 +1954,18 @@
 					% 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_deep_profile_proc_info
 					:: maybe(deep_profile_proc_info)
 		).
@@ -1960,7 +2000,7 @@
 		MaybeArgLives, ClauseBody, MContext, StackSlots, MaybeDet,
 		InferredDet, CanProcess, ArgInfo, InitialLiveness, TVarsMap,
 		TCVarsMap, eval_normal, no, no, DeclaredModes, IsAddressTaken,
-		RLExprn, no, no, no
+		RLExprn, no, no, no, no
 	).
 
 proc_info_set(DeclaredDetism, BodyVarSet, BodyTypes, HeadVars, HeadModes,
@@ -1975,7 +2015,7 @@
 		InstVarSet, HeadLives, Goal, Context,
 		StackSlots, DeclaredDetism, InferredDetism, CanProcess, ArgInfo,
 		Liveness, TVarMap, TCVarsMap, eval_normal, ArgSizes,
-		Termination, no, IsAddressTaken, RLExprn, no, no, no).
+		Termination, no, IsAddressTaken, RLExprn, no, no, no, no).
 
 proc_info_create(VarSet, VarTypes, HeadVars, HeadModes, InstVarSet,
 		Detism, Goal, Context, TVarMap, TCVarsMap,
@@ -1996,7 +2036,7 @@
 		InstVarSet, MaybeHeadLives, Goal, Context, StackSlots,
 		MaybeDeclaredDetism, Detism, yes, [], Liveness, TVarMap,
 		TCVarsMap, eval_normal, no, no, no, IsAddressTaken,
-		RLExprn, no, no, no).
+		RLExprn, no, no, no, no).
 
 proc_info_set_body(ProcInfo0, VarSet, VarTypes, HeadVars, Goal,
 		TI_VarMap, TCI_VarMap, ProcInfo) :-
@@ -2084,6 +2124,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_deep_profile_info(ProcInfo,
 	ProcInfo^maybe_deep_profile_proc_info).
 
@@ -2114,8 +2155,9 @@
 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_maybe_deep_profile_info(ProcInfo, CTT,
-	ProcInfo^maybe_deep_profile_proc_info := CTT).
+proc_info_set_table_io_decl(ProcInfo, TID, ProcInfo^table_io_decl := TID).
+proc_info_set_maybe_deep_profile_info(ProcInfo, DPI,
+	ProcInfo^maybe_deep_profile_proc_info := DPI).
 
 proc_info_get_typeinfo_vars(Vars, VarTypes, TVarMap, TypeInfoVars) :-
 	set__to_sorted_list(Vars, VarList),
@@ -2183,10 +2225,10 @@
 	varset__ensure_unique_names(AllVars, "p", VarSet0, VarSet),
 	proc_info_set_varset(ProcInfo0, VarSet, ProcInfo).
 
-proc_info_create_var_from_type(ProcInfo0, Type, NewVar, ProcInfo) :-
+proc_info_create_var_from_type(ProcInfo0, Type, MaybeName, NewVar, ProcInfo) :-
 	proc_info_varset(ProcInfo0, VarSet0),
 	proc_info_vartypes(ProcInfo0, VarTypes0),
-	varset__new_var(VarSet0, NewVar, VarSet),
+	varset__new_maybe_named_var(VarSet0, MaybeName, NewVar, VarSet),
 	map__det_insert(VarTypes0, NewVar, Type, VarTypes),
 	proc_info_set_varset(ProcInfo0, VarSet, ProcInfo1),
 	proc_info_set_vartypes(ProcInfo1, VarTypes, ProcInfo).
@@ -2715,42 +2757,49 @@
 eval_method_to_string(eval_normal,		"normal").
 eval_method_to_string(eval_loop_check,		"loop_check").
 eval_method_to_string(eval_table_io,		"table_io").
+eval_method_to_string(eval_table_io_decl,	"table_io_decl").
 eval_method_to_string(eval_memo,		"memo").
 eval_method_to_string(eval_minimal, 		"minimal_model").
 
 eval_method_needs_stratification(eval_normal) = no.
 eval_method_needs_stratification(eval_loop_check) = no.
 eval_method_needs_stratification(eval_table_io) = no.
+eval_method_needs_stratification(eval_table_io_decl) = no.
 eval_method_needs_stratification(eval_memo) = no.
 eval_method_needs_stratification(eval_minimal) = yes.
 
 eval_method_has_per_proc_tabling_pointer(eval_normal) = no.
 eval_method_has_per_proc_tabling_pointer(eval_loop_check) = yes.
 eval_method_has_per_proc_tabling_pointer(eval_table_io) = no.
+eval_method_has_per_proc_tabling_pointer(eval_table_io_decl) = no.
 eval_method_has_per_proc_tabling_pointer(eval_memo) = yes.
 eval_method_has_per_proc_tabling_pointer(eval_minimal) = yes.
 
 eval_method_requires_tabling_transform(eval_normal) = no.
 eval_method_requires_tabling_transform(eval_loop_check) = yes.
 eval_method_requires_tabling_transform(eval_table_io) = yes.
+eval_method_requires_tabling_transform(eval_table_io_decl) = yes.
 eval_method_requires_tabling_transform(eval_memo) = yes.
 eval_method_requires_tabling_transform(eval_minimal) = yes.
 
 eval_method_requires_ground_args(eval_normal) = no.
 eval_method_requires_ground_args(eval_loop_check) = yes.
 eval_method_requires_ground_args(eval_table_io) = yes.
+eval_method_requires_ground_args(eval_table_io_decl) = yes.
 eval_method_requires_ground_args(eval_memo) = yes.
 eval_method_requires_ground_args(eval_minimal) = yes.
 
 eval_method_destroys_uniqueness(eval_normal) = no.
 eval_method_destroys_uniqueness(eval_loop_check) = yes.
 eval_method_destroys_uniqueness(eval_table_io) = no.
+eval_method_destroys_uniqueness(eval_table_io_decl) = no.
 eval_method_destroys_uniqueness(eval_memo) = yes.
 eval_method_destroys_uniqueness(eval_minimal) = yes.
 
 eval_method_change_determinism(eval_normal, Detism, Detism).
 eval_method_change_determinism(eval_loop_check, Detism, Detism).
 eval_method_change_determinism(eval_table_io, Detism, Detism).
+eval_method_change_determinism(eval_table_io_decl, Detism, Detism).
 eval_method_change_determinism(eval_memo, Detism, Detism).
 eval_method_change_determinism(eval_minimal, Det0, Det) :-
 	det_conjunction_detism(semidet, Det0, Det).
Index: compiler/layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/layout.m,v
retrieving revision 1.3
diff -u -b -r1.3 layout.m
--- compiler/layout.m	2001/07/03 08:16:05	1.3
+++ compiler/layout.m	2001/12/28 11:01:07
@@ -71,6 +71,14 @@
 			proc_static_line_number :: int,
 			proc_is_in_interface	:: bool,
 			call_site_statics	:: list(call_site_static_data)
+		)
+	;	table_io_decl_data(
+			table_io_decl_proc_ptr	:: rtti_proc_label,
+			table_io_decl_kind	:: proc_layout_kind,
+			table_io_decl_num_ptis	:: int,
+			table_io_decl_ptis	:: rval,
+						% pseudo-typeinfos for headvars
+			table_io_decl_type_params :: rval
 		).
 
 :- type call_site_static_data			% defines MR_CallSiteStatic
@@ -130,6 +138,7 @@
 	--->	proc_layout_exec_trace(
 			call_label_layout	:: layout_name,
 			proc_body		:: maybe(rval),
+			maybe_table_io_decl	:: maybe(layout_name),
 			var_names		:: list(int), % offsets
 			max_var_num		:: int,
 			max_r_num		:: int,
@@ -158,6 +167,7 @@
 	;	proc_layout_var_names(proc_label)
 		% A vector of variable names (represented as offsets into
 		% the string table) for a procedure layout structure.
+	;	table_io_decl(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.5
diff -u -b -r1.5 layout_out.m
--- compiler/layout_out.m	2001/07/03 08:16:05	1.5
+++ compiler/layout_out.m	2002/01/14 03:57:19
@@ -10,7 +10,7 @@
 % are defined in runtime/mercury_stack_layout.h, where the documentation
 % of the semantics of the various kinds of layout structures can also be found.
 %
-% This module is should be, but as yet isn't, independent of whether we are
+% This module should be, but as yet isn't, independent of whether we are
 % compiling to LLDS or MLDS.
 %
 % Author: zs.
@@ -104,6 +104,10 @@
 		IsInInterface, CallSites), DeclSet0, DeclSet) -->
 	output_proc_static_data_defn(RttiProcLabel, FileName, LineNumber,
 		IsInInterface, CallSites, DeclSet0, DeclSet).
+output_layout_data_defn(table_io_decl_data(RttiProcLabel, Kind, NumPTIs,
+		PTIVectorRval, TypeParamsRval), DeclSet0, DeclSet) -->
+	output_table_io_decl(RttiProcLabel, Kind, NumPTIs,
+		PTIVectorRval, TypeParamsRval, DeclSet0, DeclSet).
 
 %-----------------------------------------------------------------------------%
 
@@ -143,6 +147,9 @@
 	LayoutName = module_layout(ModuleName).
 extract_layout_name(proc_static_data(RttiProcLabel, _, _, _, _), LayoutName) :-
 	LayoutName = proc_static(RttiProcLabel).
+extract_layout_name(table_io_decl_data(RttiProcLabel, _, _, _, _),
+		LayoutName) :-
+	LayoutName = table_io_decl(RttiProcLabel).
 
 :- pred output_layout_decls(list(layout_name)::in, decl_set::in, decl_set::out,
 	io__state::di, io__state::uo) is det.
@@ -248,6 +255,11 @@
 	io__write_string("_proc_static_call_sites__"),
 	{ ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel) },
 	output_proc_label(ProcLabel).
+output_layout_name(table_io_decl(RttiProcLabel)) -->
+	io__write_string(mercury_data_prefix),
+	io__write_string("_table_io_decl__"),
+	{ ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel) },
+	output_proc_label(ProcLabel).
 
 output_layout_name_storage_type_name(label_layout(Label, LabelVars),
 		_BeingDefined) -->
@@ -335,6 +347,10 @@
 	io__write_string("static const MR_CallSiteStatic "),
 	output_layout_name(proc_static_call_sites(RttiProcLabel)),
 	io__write_string("[]").
+output_layout_name_storage_type_name(table_io_decl(RttiProcLabel),
+		_BeingDefined) -->
+	io__write_string("static const MR_Table_Io_Decl "),
+	output_layout_name(table_io_decl(RttiProcLabel)).
 
 layout_name_would_include_code_addr(label_layout(_, _)) = no.
 layout_name_would_include_code_addr(proc_layout(_, _)) = yes.
@@ -349,6 +365,7 @@
 layout_name_would_include_code_addr(module_layout(_)) = no.
 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.
 
 :- func label_vars_to_type(label_vars) = string.
 
@@ -599,18 +616,26 @@
 
 output_layout_exec_trace_decls(ProcLabel, ExecTrace, DeclSet0, DeclSet) -->
 	{ ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcBody,
-		_VarNames, _MaxVarNum, _MaxRegNum, _MaybeFromFullSlot,
-		_MaybeIoSeqSlot, _MaybeTrailSlot, _MaybeMaxfrSlot, _EvalMethod,
-		_MaybeCallTableSlot, _MaybeDeclDebugSlot) },
+		MaybeTableIoDecl, _VarNames, _MaxVarNum, _MaxRegNum,
+		_MaybeFromFullSlot, _MaybeIoSeqSlot, _MaybeTrailSlot,
+		_MaybeMaxfrSlot, _EvalMethod, _MaybeCallTableSlot,
+		_MaybeDeclDebugSlot) },
 	{ ModuleName = get_defining_module_name(ProcLabel) },
 	output_layout_decl(CallLabelLayout, DeclSet0, DeclSet1),
 	output_layout_decl(module_layout(ModuleName), DeclSet1, DeclSet2),
 	(
 		{ MaybeProcBody = yes(ProcBody) },
-		output_rval_decls(ProcBody, "", "", 0, _, DeclSet2, DeclSet)
+		output_rval_decls(ProcBody, "", "", 0, _, DeclSet2, DeclSet3)
 	;
 		{ MaybeProcBody = no },
-		{ DeclSet = DeclSet2 }
+		{ DeclSet3 = DeclSet2 }
+	),
+	(
+		{ MaybeTableIoDecl = yes(TableIoDeclName) },
+		output_layout_decl(TableIoDeclName, DeclSet3, DeclSet)
+	;
+		{ MaybeTableIoDecl = no },
+		{ DeclSet = DeclSet3 }
 	).
 
 :- pred output_layout_exec_trace_group(proc_label::in,
@@ -618,9 +643,10 @@
 
 output_layout_exec_trace_group(ProcLabel, ExecTrace) -->
 	{ ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeProcBody,
-		_VarNames, MaxVarNum, MaxRegNum, MaybeFromFullSlot,
-		MaybeIoSeqSlot, MaybeTrailSlot, MaybeMaxfrSlot, EvalMethod,
-		MaybeCallTableSlot, MaybeDeclDebugSlot) },
+		MaybeTableIoDecl, _VarNames, MaxVarNum, MaxRegNum,
+		MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlot,
+		MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot,
+		MaybeDeclDebugSlot) },
 	io__write_string("\t{\n\t(const MR_Label_Layout *) &"),
 	output_layout_name(CallLabelLayout),
 	io__write_string(",\n\t(const MR_Module_Layout *) &"),
@@ -635,6 +661,15 @@
 		io__write_int(0)
 	),
 	io__write_string(",\n\t"),
+	(
+		{ MaybeTableIoDecl = yes(TableIoDecl) },
+		io__write_string("&"),
+		output_layout_name(TableIoDecl)
+	;
+		{ MaybeTableIoDecl = no },
+		io__write_string("NULL")
+	),
+	io__write_string(",\n\t"),
 	output_layout_name(proc_layout_var_names(ProcLabel)),
 	io__write_string(",\n\t"),
 	io__write_int(MaxVarNum),
@@ -670,6 +705,7 @@
 eval_method_to_c_string(eval_loop_check) = "MR_EVAL_METHOD_LOOP_CHECK".
 eval_method_to_c_string(eval_memo) =       "MR_EVAL_METHOD_MEMO".
 eval_method_to_c_string(eval_table_io) =   "MR_EVAL_METHOD_TABLE_IO".
+eval_method_to_c_string(eval_table_io_decl) = "MR_EVAL_METHOD_TABLE_IO_DECL".
 eval_method_to_c_string(eval_minimal) =	   "MR_EVAL_METHOD_MINIMAL".
 
 :- pred output_proc_layout_var_names(proc_label::in, list(int)::in, int::in,
@@ -1169,5 +1205,33 @@
 		{ CallSiteStatic = callback(_, _, _) },
 		{ DeclSet = DeclSet0 }
 	).
+
+%-----------------------------------------------------------------------------%
+
+:- pred output_table_io_decl(rtti_proc_label::in, proc_layout_kind::in,
+	int::in, rval::in, rval::in, decl_set::in, decl_set::out,
+	io__state::di, io__state::uo) is det.
+
+output_table_io_decl(RttiProcLabel, ProcLayoutKind, NumPTIs,
+		PTIVectorRval, TypeParamRval, DeclSet0, DeclSet) -->
+	output_rval_decls(PTIVectorRval, "", "", 0, _, DeclSet0, DeclSet1),
+	{ LayoutName = table_io_decl(RttiProcLabel) },
+	{ ProcLabel = code_util__make_proc_label_from_rtti(RttiProcLabel) },
+	{ ProcLayoutName = proc_layout(ProcLabel, ProcLayoutKind) },
+	output_layout_decl(ProcLayoutName, DeclSet1, DeclSet2),
+
+	io__write_string("\n"),
+	output_layout_name_storage_type_name(LayoutName, yes),
+	io__write_string(" = {\n\t(const MR_Proc_Layout *) &"),
+	output_layout_name(ProcLayoutName),
+	io__write_string(",\n\t"),
+	io__write_int(NumPTIs),
+	io__write_string(",\n\t(const MR_PseudoTypeInfo *) "),
+	output_rval(PTIVectorRval),
+	io__write_string(",\n\t(const MR_Type_Param_Locns *) "),
+	output_rval(TypeParamRval),
+	io__write_string("\n};\n"),
+	{ decl_set_insert(DeclSet2, data_addr(layout_addr(LayoutName)),
+		DeclSet) }.
 
 %-----------------------------------------------------------------------------%
Index: compiler/llds_common.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_common.m,v
retrieving revision 1.39
diff -u -b -r1.39 llds_common.m
--- compiler/llds_common.m	2001/07/03 08:16:05	1.39
+++ compiler/llds_common.m	2001/12/28 11:07:05
@@ -191,20 +191,29 @@
 llds_common__process_layout_data(LayoutData0, LayoutData, Info, Info) :-
 	LayoutData0 = proc_static_data(_, _, _, _, _),
 	LayoutData = LayoutData0.
+llds_common__process_layout_data(LayoutData0, LayoutData, Info0, Info) :-
+	LayoutData0 = table_io_decl_data(RttiProcLabel, Kind, NumPTIs,
+		PTIVector0, TVarLocnMap0),
+	llds_common__process_rval(PTIVector0, PTIVector, Info0, Info1),
+	llds_common__process_rval(TVarLocnMap0, TVarLocnMap, Info1, Info),
+	LayoutData = table_io_decl_data(RttiProcLabel, Kind, NumPTIs,
+		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.
 
 llds_common__process_exec_trace(ExecTrace0, ExecTrace, Info0, Info) :-
 	ExecTrace0 = proc_layout_exec_trace(CallLabel, MaybeProcBody0,
-		VarNames, MaxVarNum, MaxReg, MaybeFromFullSlot, MaybeIoSeqSlot,
-		MaybeTrailSlot, MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot,
+		MaybeTableIoDecl, VarNames, MaxVarNum, MaxReg,
+		MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlot,
+		MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot,
 		MaybeDeclDebugSlot),
 	llds_common__process_maybe_rval(MaybeProcBody0, MaybeProcBody,
 		Info0, Info),
 	ExecTrace = proc_layout_exec_trace(CallLabel, MaybeProcBody,
-		VarNames, MaxVarNum, MaxReg, MaybeFromFullSlot, MaybeIoSeqSlot,
-		MaybeTrailSlot, MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot,
+		MaybeTableIoDecl, VarNames, MaxVarNum, MaxReg,
+		MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlot,
+		MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot,
 		MaybeDeclDebugSlot).
 
 :- pred llds_common__process_procs(list(c_procedure)::in,
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.183
diff -u -b -r1.183 llds_out.m
--- compiler/llds_out.m	2001/12/31 04:26:36	1.183
+++ compiler/llds_out.m	2001/12/31 04:43:02
@@ -55,6 +55,10 @@
 	io__state, io__state).
 :- mode output_rval_decls(in, in, in, in, out, in, out, di, uo) is det.
 
+:- pred output_rvals_decls(list(rval)::in, string::in, string::in,
+	int::in, int::out, decl_set::in, decl_set::out,
+	io__state::di, io__state::uo) is det.
+
 	% output an rval (not converted to any particular type,
 	% but instead output as its "natural" type)
 
@@ -2299,6 +2303,15 @@
 		N0, N, DeclSet0, DeclSet) -->
 	output_mem_ref_decls(MemRef, FirstIndent, LaterIndent,
 		N0, N, DeclSet0, DeclSet).
+
+output_rvals_decls([], _FirstIndent, _LaterIndent, N, N,
+		DeclSet, DeclSet) --> [].
+output_rvals_decls([Rval | Rvals], FirstIndent, LaterIndent, N0, N,
+		DeclSet0, DeclSet) -->
+	output_rval_decls(Rval, FirstIndent, LaterIndent, N0, N1,
+		DeclSet0, DeclSet1),
+	output_rvals_decls(Rvals, FirstIndent, LaterIndent, N1, N,
+		DeclSet1, DeclSet).
 
 :- pred output_mem_ref_decls(mem_ref, string, string, int, int,
 	decl_set, decl_set, io__state, io__state).
Index: compiler/magic.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/magic.m,v
retrieving revision 1.27
diff -u -b -r1.27 magic.m
--- compiler/magic.m	2001/04/07 14:04:45	1.27
+++ compiler/magic.m	2001/12/25 15:13:42
@@ -1054,7 +1054,7 @@
 
 	JoinProcInfo0 = CProcInfo,
 	proc_info_create_var_from_type(JoinProcInfo0,
-		ClosureVarType, ClosureVar, JoinProcInfo1),
+		ClosureVarType, no, ClosureVar, JoinProcInfo1),
 
 
 	%
@@ -1267,7 +1267,7 @@
 		hlds_goal::out, proc_info::in, proc_info::out) is det.
 
 magic__make_const(Type, ConsId, Var, Goal, ProcInfo0, ProcInfo) :-
-	proc_info_create_var_from_type(ProcInfo0, Type, Var, ProcInfo),
+	proc_info_create_var_from_type(ProcInfo0, Type, no, Var, ProcInfo),
 	set__singleton_set(NonLocals, Var),
 	Inst = bound(unique, [functor(ConsId, [])]),
 	instmap_delta_init_reachable(Delta0),
@@ -1630,7 +1630,7 @@
 		{ proc_info_vartypes(ProcInfo0, VarTypes) },
 		{ map__lookup(VarTypes, Arg, ArgType) },
 		{ proc_info_create_var_from_type(ProcInfo0,
-			ArgType, NewArg, ProcInfo) },
+			ArgType, no, NewArg, ProcInfo) },
 		magic_info_set_proc_info(ProcInfo),
 		{ IntroducedArgs1 = [NewArg | IntroducedArgs0] },
 		{ in_mode(InMode) },
@@ -1746,7 +1746,7 @@
 		{ proc_info_vartypes(ProcInfo0, VarTypes0) },
 		{ map__lookup(VarTypes0, Arg, Type) },
 		{ proc_info_create_var_from_type(ProcInfo0, 
-			Type, NewArg, ProcInfo) },
+			Type, no, NewArg, ProcInfo) },
 		magic_info_set_proc_info(ProcInfo),
 		{ map__init(Subn0) },
 		{ map__det_insert(Subn0, Arg, NewArg, Subn) },
Index: compiler/magic_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/magic_util.m,v
retrieving revision 1.16
diff -u -b -r1.16 magic_util.m
--- compiler/magic_util.m	2002/01/16 01:13:24	1.16
+++ compiler/magic_util.m	2002/01/17 11:52:40
@@ -739,8 +739,8 @@
 		ArgTypes = ArgTypes1,
 		construct_higher_order_type(predicate, (aditi_bottom_up),
 			ArgTypes, ClosureType),
-		proc_info_create_var_from_type(ProcInfo0, 
-			ClosureType, InputVar, ProcInfo)
+		proc_info_create_var_from_type(ProcInfo0, ClosureType, no,
+			InputVar, ProcInfo)
 	;
 		error("magic_util__get_input_var")
 	).
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.201
diff -u -b -r1.201 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	2002/01/16 01:13:29	1.201
+++ compiler/mercury_to_mercury.m	2002/01/17 11:52:40
@@ -1370,6 +1370,8 @@
 	add_string("<tabling pointer>").
 mercury_format_cons_id(deep_profiling_proc_static(_), _) -->
 	add_string("<deep_profiling_proc_static>").
+mercury_format_cons_id(table_io_decl(_), _) -->
+	add_string("<table_io_decl>").
 
 :- pred mercury_format_mode_defn(inst_varset::in, sym_name::in,
 	list(inst_var)::in, mode_defn::in, prog_context::in,
@@ -3537,6 +3539,8 @@
 	output_string("eval_memo").
 output_eval_method(eval_table_io) -->
 	output_string("eval_table_io").
+output_eval_method(eval_table_io_decl) -->
+	output_string("eval_table_io_decl").
 output_eval_method(eval_minimal) -->
 	output_string("eval_minimal").
 
Index: compiler/ml_unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_unify_gen.m,v
retrieving revision 1.49
diff -u -b -r1.49 ml_unify_gen.m
--- compiler/ml_unify_gen.m	2002/01/11 07:41:26	1.49
+++ compiler/ml_unify_gen.m	2002/01/11 09:17:13
@@ -442,6 +442,9 @@
 ml_gen_constant(deep_profiling_proc_static_tag(_), _, _) -->
 	{ error("ml_gen_constant: deep_profiling_proc_static_tag not yet supported") }.
 
+ml_gen_constant(table_io_decl_tag(_), _, _) -->
+	{ error("ml_gen_constant: table_io_decl_tag not yet supported") }.
+
 ml_gen_constant(code_addr_constant(PredId, ProcId), _, ProcAddrRval) -->
 	ml_gen_proc_addr_rval(PredId, ProcId, ProcAddrRval).
 
@@ -1673,6 +1676,9 @@
 		{ Tag = deep_profiling_proc_static_tag(_) },
 		{ MLDS_Statements = [] }
 	;
+		{ Tag = table_io_decl_tag(_) },
+		{ MLDS_Statements = [] }
+	;
 		{ Tag = no_tag },
 		( { Args = [Arg], Modes = [Mode] } ->
 			ml_variable_type(Arg, ArgType),
@@ -1785,6 +1791,9 @@
 		Tag = deep_profiling_proc_static_tag(_),
 		error("ml_tag_offset_and_argnum")
 	;
+		Tag = table_io_decl_tag(_),
+		error("ml_tag_offset_and_argnum")
+	;
 		Tag = no_tag,
 		error("ml_tag_offset_and_argnum")
 	;
@@ -2109,6 +2118,9 @@
 ml_gen_tag_test_rval(deep_profiling_proc_static_tag(_), _, _, _) = _ :-
 	% This should never happen
 	error("Attempted deep_profiling_proc_static unification").
+ml_gen_tag_test_rval(table_io_decl_tag(_), _, _, _) = _ :-
+	% This should never happen
+	error("Attempted proc_layout unification").
 ml_gen_tag_test_rval(no_tag, _, _, _Rval) = const(true).
 ml_gen_tag_test_rval(single_functor, _, _, _Rval) = const(true).
 ml_gen_tag_test_rval(unshared_tag(UnsharedTag), _, _, Rval) =
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.117
diff -u -b -r1.117 opt_debug.m
--- compiler/opt_debug.m	2001/10/24 07:43:12	1.117
+++ compiler/opt_debug.m	2001/12/28 11:00:52
@@ -478,6 +478,10 @@
 	opt_debug__dump_proclabel(ProcLabel, ProcLabelStr),
 	string__append_list(["proc_static_call_sites(", ProcLabelStr, ")"],
 		Str).
+opt_debug__dump_layout_name(table_io_decl(RttiProcLabel), Str) :-
+	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_unop(mktag, "mktag").
 opt_debug__dump_unop(tag, "tag").
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.350
diff -u -b -r1.350 options.m
--- compiler/options.m	2001/12/16 08:11:09	1.350
+++ compiler/options.m	2001/12/17 02:06:18
@@ -114,6 +114,7 @@
 		;	trace
 		;	trace_optimized
 		;	trace_table_io
+		;	trace_table_io_decl
 		;	trace_table_io_states
 		;	delay_death
 		;	suppress_trace
@@ -609,6 +610,7 @@
 	trace			-	string("default"),
 	trace_optimized		-	bool(no),
 	trace_table_io		-	bool(no),
+	trace_table_io_decl	-	bool(no),
 	trace_table_io_states	-	bool(no),
 	suppress_trace		-	string(""),
 	delay_death		-	bool(yes),
@@ -1088,6 +1090,7 @@
 long_option("trace-optimised",		trace_optimized).
 long_option("trace-optimized",		trace_optimized).
 long_option("trace-table-io",		trace_table_io).
+long_option("trace-table-io-decl",	trace_table_io_decl).
 long_option("trace-table-io-states",	trace_table_io_states).
 long_option("suppress-trace",		suppress_trace).
 long_option("delay-death",		delay_death).
@@ -2025,6 +2028,9 @@
 %		"--trace-table-io",
 %		"\tEnable the tabling of I/O actions, to allow the debugger",
 %		"\tto execute retry commands across I/O actions.",
+%		"--trace-table-io-decl",
+%		"\tSet up I/O tabling so that the declarative debugger can",
+%		"\tmake use of it.",
 %		"--trace-table-io-states",
 %		"\tWhen tabling I/O actions, table the io__state arguments",
 %		"\ttogether with the others. This should be required iff",
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.74
diff -u -b -r1.74 prog_data.m
--- compiler/prog_data.m	2002/01/16 01:13:39	1.74
+++ compiler/prog_data.m	2002/01/17 11:52:40
@@ -317,6 +317,8 @@
 	;	eval_loop_check		% loop check only
 	;	eval_memo		% memoing + loop check 
 	;	eval_table_io		% memoing I/O actions for debugging
+	;	eval_table_io_decl	% memoing I/O actions for declarative
+					% debugging
 	;	eval_minimal.		% minimal model 
 					% evaluation 
 %
Index: compiler/prog_rep.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_rep.m,v
retrieving revision 1.8
diff -u -b -r1.8 prog_rep.m
--- compiler/prog_rep.m	2001/05/31 05:59:52	1.8
+++ compiler/prog_rep.m	2001/12/25 07:57:47
@@ -98,6 +98,8 @@
 	Rep = "$tabling_pointer_const".
 prog_rep__represent_cons_id(deep_profiling_proc_static(_), Rep) :-
 	Rep = "$deep_profiling_procedure_data".
+prog_rep__represent_cons_id(table_io_decl(_), Rep) :-
+	Rep = "$table_io_decl".
 
 :- pred prog_rep__represent_sym_name(sym_name::in, string::out) is det.
 
Index: compiler/rl_exprn.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/rl_exprn.m,v
retrieving revision 1.21
diff -u -b -r1.21 rl_exprn.m
--- compiler/rl_exprn.m	2001/05/31 05:59:52	1.21
+++ compiler/rl_exprn.m	2001/12/25 07:58:12
@@ -505,6 +505,9 @@
 rl_exprn__set_term_arg_cons_id_code(deep_profiling_proc_static(_),
 		_, _, _, _, _, _) -->
 	{ error("rl_exprn__set_term_arg_cons_id_code") }.
+rl_exprn__set_term_arg_cons_id_code(table_io_decl(_),
+		_, _, _, _, _, _) -->
+	{ error("rl_exprn__set_term_arg_cons_id_code") }.
 
 :- pred rl_exprn__set_term_arg_cons_id_code_2(aditi_type::in, tuple_num::in,
 		int::in, bool::in, bytecode::out) is det.
@@ -1154,6 +1157,9 @@
 	; 
 		{ ConsId = deep_profiling_proc_static(_) },
 		{ error("rl_exprn__unify: unsupported cons_id - deep_profiling_proc_static") }
+	; 
+		{ ConsId = table_io_decl(_) },
+		{ error("rl_exprn__unify: unsupported cons_id - table_io_decl") }
 	).
 		
 rl_exprn__unify(deconstruct(Var, ConsId, Args, UniModes, CanFail, _CanCGC),
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.60
diff -u -b -r1.60 stack_layout.m
--- compiler/stack_layout.m	2001/01/29 06:47:20	1.60
+++ compiler/stack_layout.m	2001/12/28 11:10:28
@@ -78,8 +78,8 @@
 	StringTable0 = string_table(StringMap0, [], 0),
 	LayoutInfo0 = stack_layout_info(ModuleInfo0,
 		AgcLayout, TraceLayout, ProcIdLayout,
-		TraceLevel, TraceSuppress,
-		StaticCodeAddr, [], [], LayoutLabels0, [],
+		TraceLevel, TraceSuppress, StaticCodeAddr,
+		[], [], [], LayoutLabels0, [],
 		StringTable0, LabelTables0, map__init),
 	stack_layout__lookup_string_in_table("", _, LayoutInfo0, LayoutInfo1),
 	stack_layout__lookup_string_in_table("<too many variables>", _,
@@ -87,6 +87,7 @@
 	list__foldl(stack_layout__construct_layouts, ProcLayoutList,
 		LayoutInfo2, LayoutInfo),
 	ModuleInfo = LayoutInfo ^ module_info,
+	TableIoDecls = LayoutInfo ^ table_io_decl,
 	ProcLayouts = LayoutInfo ^ proc_layouts,
 	InternalLayouts = LayoutInfo ^ internal_layouts,
 	LayoutLabels = LayoutInfo ^ label_set,
@@ -99,6 +100,7 @@
 		ConcatStrings),
 
 	PossiblyDynamicLayouts = ProcLayouts,
+	StaticLayouts0 = list__append(TableIoDecls, InternalLayouts),
 	( TraceLayout = yes ->
 		module_info_name(ModuleInfo0, ModuleName),
 		globals__lookup_bool_option(Globals, rtti_line_numbers,
@@ -115,9 +117,9 @@
 		ModuleLayout = layout_data(module_layout_data(ModuleName,
 			StringOffset, ConcatStrings, ProcLayoutNames,
 			SourceFileLayouts, TraceLevel)),
-		StaticLayouts = [ModuleLayout | InternalLayouts]
+		StaticLayouts = [ModuleLayout | StaticLayouts0]
 	;
-		StaticLayouts = InternalLayouts
+		StaticLayouts = StaticLayouts0
 	).
 
 :- pred stack_layout__valid_proc_layout(proc_layout_info::in) is semidet.
@@ -236,17 +238,21 @@
 	stack_layout_info::in, stack_layout_info::out) is det.
 
 stack_layout__construct_layouts(ProcLayoutInfo) -->
-	{ ProcLayoutInfo = proc_layout_info(EntryLabel, Detism, StackSlots,
-		SuccipLoc, EvalMethod, MaybeCallLabel, MaxTraceReg,
+	{ ProcLayoutInfo = proc_layout_info(RttiProcLabel, EntryLabel, Detism,
+		StackSlots, SuccipLoc, EvalMethod, MaybeCallLabel, MaxTraceReg,
 		Goal, InstMap, TraceSlotInfo, ForceProcIdLayout,
-		VarSet, VarTypes, InternalMap) },
+		VarSet, VarTypes, InternalMap, MaybeTableIoDecl) },
 	{ map__to_assoc_list(InternalMap, Internals) },
 	stack_layout__set_cur_proc_named_vars(map__init),
 
 	{ code_util__extract_proc_label_from_label(EntryLabel, ProcLabel) },
 	stack_layout__get_procid_stack_layout(ProcIdLayout0),
 	{ bool__or(ProcIdLayout0, ForceProcIdLayout, ProcIdLayout) },
-	( { ProcIdLayout = yes } ->
+	(
+		{ ProcIdLayout = yes
+		; MaybeTableIoDecl = yes(_)
+		}
+	->
 		{ UserOrCompiler = proc_label_user_or_compiler(ProcLabel) },
 		stack_layout__get_trace_stack_layout(TraceLayout),
 		{
@@ -269,10 +275,10 @@
 	{ list__foldl(stack_layout__update_label_table, InternalLayouts,
 		LabelTables0, LabelTables) },
 	stack_layout__set_label_tables(LabelTables),
-	stack_layout__construct_proc_layout(EntryLabel, ProcLabel, Detism,
-		StackSlots, SuccipLoc, EvalMethod, MaybeCallLabel, MaxTraceReg,
-		Goal, InstMap, TraceSlotInfo, VarSet, VarTypes, NamedVars,
-		Kind).
+	stack_layout__construct_proc_layout(RttiProcLabel, EntryLabel,
+		ProcLabel, Detism, StackSlots, SuccipLoc, EvalMethod,
+		MaybeCallLabel, MaxTraceReg, Goal, InstMap, TraceSlotInfo,
+		VarSet, VarTypes, NamedVars, MaybeTableIoDecl, Kind).
 
 %---------------------------------------------------------------------------%
 
@@ -369,17 +375,18 @@
 
 	% Construct a procedure-specific layout.
 
-:- pred stack_layout__construct_proc_layout(label::in, proc_label::in,
-	determinism::in, int::in, maybe(int)::in, eval_method::in,
-	maybe(label)::in, int::in, hlds_goal::in, instmap::in,
+:- pred stack_layout__construct_proc_layout(rtti_proc_label::in, label::in,
+	proc_label::in, determinism::in, int::in, maybe(int)::in,
+	eval_method::in, maybe(label)::in, int::in, hlds_goal::in, instmap::in,
 	trace_slot_info::in, prog_varset::in, vartypes::in,
-	map(int, string)::in, proc_layout_kind::in,
-	stack_layout_info::in, stack_layout_info::out) is det.
+	map(int, string)::in, maybe(table_io_decl_info)::in,
+	proc_layout_kind::in, stack_layout_info::in, stack_layout_info::out)
+	is det.
 
-stack_layout__construct_proc_layout(EntryLabel, ProcLabel, Detism, StackSlots,
-		MaybeSuccipLoc, EvalMethod, MaybeCallLabel, MaxTraceReg, Goal,
-		InstMap, TraceSlotInfo, VarSet, VarTypes, UsedVarNames, Kind)
-		-->
+stack_layout__construct_proc_layout(RttiProcLabel, EntryLabel, ProcLabel,
+		Detism, StackSlots, MaybeSuccipLoc, EvalMethod, MaybeCallLabel,
+		MaxTraceReg, Goal, InstMap, TraceSlotInfo, VarSet, VarTypes,
+		UsedVarNames, MaybeTableIoDeclInfo, Kind) -->
 	{
 		MaybeSuccipLoc = yes(Location)
 	->
@@ -436,26 +443,37 @@
 		{ MaybeRest = proc_id_only }
 	;
 		{ Kind = proc_layout_exec_trace(_) },
-		stack_layout__construct_trace_layout(EvalMethod, MaybeCallLabel,
-			MaxTraceReg, Goal, InstMap, TraceSlotInfo, VarSet,
-			VarTypes, UsedVarNames, ExecTrace),
+		stack_layout__construct_trace_layout(RttiProcLabel, EvalMethod,
+			MaybeCallLabel, MaxTraceReg, Goal, InstMap,
+			TraceSlotInfo, VarSet, VarTypes, UsedVarNames,
+			MaybeTableIoDeclInfo, ExecTrace),
 		{ MaybeRest = proc_id_and_exec_trace(ExecTrace) }
 	),
 
 	{ ProcLayout = proc_layout_data(ProcLabel, TraversalGroup, MaybeRest) },
 	{ Data = layout_data(ProcLayout) },
 	{ LayoutName = proc_layout(ProcLabel, Kind) },
-	stack_layout__add_proc_layout_data(Data, LayoutName, EntryLabel).
+	stack_layout__add_proc_layout_data(Data, LayoutName, EntryLabel),
+
+	(
+		{ MaybeTableIoDeclInfo = no }
+	;
+		{ MaybeTableIoDeclInfo = yes(TableIoDeclInfo) },
+		stack_layout__make_table_decl_io_data(RttiProcLabel, Kind,
+			TableIoDeclInfo, TableIoDeclData),
+		stack_layout__add_table_decl_io_data(TableIoDeclData)
+	).
 
-:- pred stack_layout__construct_trace_layout(eval_method::in, maybe(label)::in,
-	int::in, hlds_goal::in, instmap::in, trace_slot_info::in,
-	prog_varset::in, vartypes::in, map(int, string)::in,
+:- pred stack_layout__construct_trace_layout(rtti_proc_label::in,
+	eval_method::in, maybe(label)::in, int::in, hlds_goal::in,
+	instmap::in, trace_slot_info::in, prog_varset::in, vartypes::in,
+	map(int, string)::in, maybe(table_io_decl_info)::in,
 	proc_layout_exec_trace::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
-stack_layout__construct_trace_layout(EvalMethod, MaybeCallLabel, MaxTraceReg,
-		Goal, InstMap, TraceSlotInfo, VarSet, VarTypes, UsedVarNameMap,
-		ExecTrace) -->
+stack_layout__construct_trace_layout(RttiProcLabel, EvalMethod, MaybeCallLabel,
+		MaxTraceReg, Goal, InstMap, TraceSlotInfo, VarSet, VarTypes,
+		UsedVarNameMap, MaybeTableIoDecl, ExecTrace) -->
 	stack_layout__construct_var_name_vector(VarSet, UsedVarNameMap,
 		MaxVarNum, VarNameVector),
 	stack_layout__get_trace_level(TraceLevel),
@@ -486,8 +504,15 @@
 		MaybeCallTableSlot, MaybeDeclSlots) },
 		% The label associated with an event must have variable info.
 	{ CallLabelLayout = label_layout(CallLabel, label_has_var_info) },
+	{
+		MaybeTableIoDecl = no,
+		MaybeTableIoDeclName = no
+	;
+		MaybeTableIoDecl = yes(_),
+		MaybeTableIoDeclName = yes(table_io_decl(RttiProcLabel))
+	},
 	{ ExecTrace = proc_layout_exec_trace(CallLabelLayout, MaybeGoalRepRval,
-		VarNameVector, MaxVarNum, MaxTraceReg,
+		MaybeTableIoDeclName, VarNameVector, MaxVarNum, MaxTraceReg,
 		MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlots,
 		MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot,
 		MaybeDeclSlots) }.
@@ -1016,11 +1041,7 @@
 	list__map_foldl(stack_layout__construct_closure_arg_rval,
 		ClosureArgs, MaybeArgRvalsTypes, C0, C),
 	assoc_list__keys(MaybeArgRvalsTypes, MaybeArgRvals),
-	AddOne = (pred(Pair::in, CountLldsType::out) is det :-
-		Pair = _ - LldsType,
-		CountLldsType = 1 - yes(LldsType)
-	),
-	list__map(AddOne, MaybeArgRvalsTypes, ArgRvalTypes),
+	list__map(stack_layout__add_one, MaybeArgRvalsTypes, ArgRvalTypes),
 	list__length(MaybeArgRvals, Length),
 	ClosureArgRvals = [yes(const(int_const(Length))) | MaybeArgRvals],
 	ClosureArgTypes = [1 - yes(integer) | ArgRvalTypes].
@@ -1043,6 +1064,65 @@
 	ll_pseudo_type_info__construct_typed_llds_pseudo_type_info(Type,
 		NumUnivQTvars, ExistQTvars, ArgRval, ArgRvalType, C0, C).
 
+:- pred stack_layout__add_one(pair(maybe(rval), llds_type)::in,
+	pair(int, maybe(llds_type))::out) is det.
+
+stack_layout__add_one(_MaybeRval - LldsType, 1 - yes(LldsType)).
+
+%---------------------------------------------------------------------------%
+
+:- pred stack_layout__make_table_decl_io_data(rtti_proc_label::in,
+	proc_layout_kind::in, table_io_decl_info::in, layout_data::out,
+	stack_layout_info::in, stack_layout_info::out) is det.
+
+stack_layout__make_table_decl_io_data(RttiProcLabel, Kind, TableIoDeclInfo,
+		TableIoDeclData) -->
+	{ TableIoDeclInfo = table_io_decl_info(SavedArgs, TVarSlotMap) },
+	{ list__length(SavedArgs, 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(stack_layout__add_one, MaybePTIRvalTypes, PTITypes) },
+	{ assoc_list__keys(MaybePTIRvalTypes, MaybePTIRvals) },
+	{ PTIVectorTypes = initial(PTITypes, none) },
+	{ counter__allocate(CNum, C1, C2) },
+	{ Reuse = no },
+	{ PTIVectorRval = create(0, MaybePTIRvals, PTIVectorTypes,
+		must_be_static, CNum,
+		"stack_layout_table_io_decl_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) }.
+
+:- pred stack_layout__convert_slot_to_locn_map(tvar::in,
+	table_io_decl_locn::in, set(layout_locn)::out) is det.
+
+stack_layout__convert_slot_to_locn_map(_TVar, SlotLocn, LvalLocns) :-
+	(
+		SlotLocn = direct(SlotNum),
+		LvalLocn = direct(reg(r, SlotNum))
+	;
+		SlotLocn = indirect(SlotNum, Offset),
+		LvalLocn = indirect(reg(r, SlotNum), Offset)
+	),
+	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,
+	counter::in, counter::out) is det.
+
+stack_layout__construct_table_io_decl_arg_pti_rval(ClosureArg,
+		yes(ArgRval) - ArgRvalType, C0, C) :-
+	ClosureArg = table_io_decl_arg_info(_, _, Type),
+	ExistQTvars = [],
+	NumUnivQTvars = -1,
+	ll_pseudo_type_info__construct_typed_llds_pseudo_type_info(Type,
+		NumUnivQTvars, ExistQTvars, ArgRval, ArgRvalType, C0, C).
+
 %---------------------------------------------------------------------------%
 
 	% Construct a representation of the type of a value.
@@ -1380,6 +1460,7 @@
 		trace_level		:: trace_level,
 		trace_suppress_items	:: trace_suppress_items,
 		static_code_addresses	:: bool, % have static code addresses?
+		table_io_decl		:: 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),
@@ -1423,6 +1504,9 @@
 :- 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,
+	stack_layout_info::in, stack_layout_info::out) is det.
+
 :- pred stack_layout__get_proc_layout_data(list(comp_gen_c_data)::out,
 	stack_layout_info::in, stack_layout_info::out) is det.
 
@@ -1448,6 +1532,7 @@
 stack_layout__get_trace_level(LI ^ trace_level, LI, LI).
 stack_layout__get_trace_suppress(LI ^ trace_suppress_items, LI, LI).
 stack_layout__get_static_code_addresses(LI ^ static_code_addresses, LI, LI).
+stack_layout__get_table_io_decl_data(LI ^ table_io_decl, 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).
@@ -1468,6 +1553,14 @@
 stack_layout__get_cell_counter(CellCounter) -->
 	stack_layout__get_module_info(ModuleInfo),
 	{ module_info_get_cell_counter(ModuleInfo, CellCounter) }.
+
+:- pred stack_layout__add_table_decl_io_data(layout_data::in,
+	stack_layout_info::in, stack_layout_info::out) is det.
+
+stack_layout__add_table_decl_io_data(TableIoDeclData, LI0, LI) :-
+	TableIoDecls0 = LI0 ^ table_io_decl,
+	TableIoDecls = [layout_data(TableIoDeclData) | TableIoDecls0],
+	LI = LI0 ^ table_io_decl := TableIoDecls.
 
 :- pred stack_layout__add_proc_layout_data(comp_gen_c_data::in,
 	layout_name::in, label::in,
Index: compiler/switch_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/switch_util.m,v
retrieving revision 1.5
diff -u -b -r1.5 switch_util.m
--- compiler/switch_util.m	2001/10/31 16:58:10	1.5
+++ compiler/switch_util.m	2001/12/25 09:10:51
@@ -293,6 +293,7 @@
 switch_util__switch_priority(base_typeclass_info_constant(_, _, _), 6).
 switch_util__switch_priority(tabling_pointer_constant(_, _), 6).
 switch_util__switch_priority(deep_profiling_proc_static_tag(_), 6).
+switch_util__switch_priority(table_io_decl_tag(_), 6).
 
 	% Determine the range of an atomic type.
 	% Fail if the type isn't the sort of type that has a range
Index: compiler/table_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/table_gen.m,v
retrieving revision 1.30
diff -u -b -r1.30 table_gen.m
--- compiler/table_gen.m	2001/11/26 09:30:58	1.30
+++ compiler/table_gen.m	2002/01/14 14:28:44
@@ -218,6 +218,13 @@
 % sure that the primitive meets the requirement. Unfortunately, this cannot be
 % automated, since automation would require analysis of arbitrary C code.
 %
+% The transformation for tabling I/O for declarative debugging is a variant
+% of the usual transformation of I/O primitives. In this variant, the answer
+% block contains not only the answers, but also a pointer to the primitive's
+% proc layout structure and the values of the input aruments. The code we
+% generate will fill in the slots containing this extra information before
+% it executes the original goal.
+%
 %-----------------------------------------------------------------------------%
 
 :- module table_gen.
@@ -238,11 +245,11 @@
 :- import_module hlds_module, hlds_goal, hlds_data, (inst), inst_match.
 :- import_module globals, options, passes_aux, prog_data, mode_util, type_util.
 :- import_module code_util, quantification, modes, purity, prog_util.
-:- import_module code_model.
+:- import_module code_model, continuation_info, rtti, llds.
 
 :- import_module term, varset.
-:- import_module bool, list, set, map, require, std_util, int.
-:- import_module assoc_list, string, llds.
+:- import_module bool, int, string, list, assoc_list.
+:- import_module set, map, require, std_util.
 
 %-----------------------------------------------------------------------------%
 
@@ -250,47 +257,46 @@
 	% The reason for this duplication is that this module needs a variant
 	% of this code that is able to handle passing a module_info to
 	% polymorphism and getting an updated module_info back.
-table_gen__process_module(Module0, Module) :-
-	module_info_preds(Module0, Preds0),
+table_gen__process_module(ModuleInfo0, ModuleInfo) :-
+	module_info_preds(ModuleInfo0, Preds0),
 	map__keys(Preds0, PredIds),
-	table_gen__process_preds(PredIds, Module0, Module).
+	table_gen__process_preds(PredIds, ModuleInfo0, ModuleInfo).
 
-:- pred table_gen__process_preds(list(pred_id)::in, module_info::in,
-	module_info::out) is det.
+:- pred table_gen__process_preds(list(pred_id)::in,
+	module_info::in, module_info::out) is det.
 
-table_gen__process_preds([], Module, Module).
-table_gen__process_preds([PredId | PredIds], Module0, Module) :-
-	table_gen__process_pred(PredId, Module0, Module1),
-	table_gen__process_preds(PredIds, Module1, Module).
+table_gen__process_preds([], ModuleInfo, ModuleInfo).
+table_gen__process_preds([PredId | PredIds], ModuleInfo0, ModuleInfo) :-
+	table_gen__process_pred(PredId, ModuleInfo0, ModuleInfo1),
+	table_gen__process_preds(PredIds, ModuleInfo1, ModuleInfo).
 
 :- pred table_gen__process_pred(pred_id::in, module_info::in, module_info::out)
 	is det.
 
-table_gen__process_pred(PredId, Module0, Module) :-
-	module_info_pred_info(Module0, PredId, PredInfo),
+table_gen__process_pred(PredId, ModuleInfo0, ModuleInfo) :-
+	module_info_pred_info(ModuleInfo0, PredId, PredInfo),
 	pred_info_procids(PredInfo, ProcIds),
-	table_gen__process_procs(PredId, ProcIds, Module0, Module).
+	table_gen__process_procs(PredId, ProcIds, ModuleInfo0, ModuleInfo).
 
 :- pred table_gen__process_procs(pred_id::in, list(proc_id)::in,
 	module_info::in, module_info::out) is det.
 
-table_gen__process_procs(_PredId, [], Module, Module).
-table_gen__process_procs(PredId, [ProcId | ProcIds], Module0,
-		Module) :-
-	module_info_preds(Module0, PredTable),
+table_gen__process_procs(_PredId, [], ModuleInfo, ModuleInfo).
+table_gen__process_procs(PredId, [ProcId | ProcIds], ModuleInfo0, ModuleInfo) :-
+	module_info_preds(ModuleInfo0, PredTable),
 	map__lookup(PredTable, PredId, PredInfo),
 	pred_info_procedures(PredInfo, ProcTable),
 	map__lookup(ProcTable, ProcId, ProcInfo0),
 
+	module_info_globals(ModuleInfo0, Globals),
 	proc_info_eval_method(ProcInfo0, EvalMethod),
 
 	( eval_method_requires_tabling_transform(EvalMethod) = yes ->
 		table_gen__process_proc(EvalMethod, PredId, ProcId, ProcInfo0,
-			PredInfo, Module0, Module1)
+			PredInfo, ModuleInfo0, ModuleInfo1)
 	;
-		module_info_globals(Module0, Globals),
 		globals__lookup_bool_option(Globals, trace_table_io, yes),
-		proc_info_has_io_state_pair(Module0, ProcInfo0,
+		proc_info_has_io_state_pair(ModuleInfo0, ProcInfo0,
 			_InArgNum, _OutArgNum),
 		proc_info_interface_code_model(ProcInfo0, model_det),
 		proc_info_goal(ProcInfo0, BodyGoal),
@@ -301,14 +307,22 @@
 			tabled_for_io(Attrs, tabled_for_io)
 		)
 	->
-		proc_info_set_eval_method(ProcInfo0, eval_table_io, ProcInfo1),
-		table_gen__process_proc(eval_table_io, PredId, ProcId,
-			ProcInfo1, PredInfo, Module0, Module1)
+		globals__lookup_bool_option(Globals, trace_table_io_decl,
+			TraceTableIoDecl),
+		(
+			TraceTableIoDecl = yes,
+			TableIoMethod = eval_table_io_decl
 	;
-		Module1 = Module0
+			TraceTableIoDecl = no,
+			TableIoMethod = eval_table_io
 	),
-
-	table_gen__process_procs(PredId, ProcIds, Module1, Module).
+		proc_info_set_eval_method(ProcInfo0, TableIoMethod, ProcInfo1),
+		table_gen__process_proc(TableIoMethod, PredId, ProcId,
+			ProcInfo1, PredInfo, ModuleInfo0, ModuleInfo1)
+	;
+		ModuleInfo1 = ModuleInfo0
+	),
+	table_gen__process_procs(PredId, ProcIds, ModuleInfo1, ModuleInfo).
 
 %-----------------------------------------------------------------------------%
 
@@ -317,8 +331,9 @@
 	is det.
 
 table_gen__process_proc(EvalMethod, PredId, ProcId, ProcInfo0, PredInfo0,
-		Module0, Module) :-
-	table_info_init(Module0, PredInfo0, ProcInfo0, TableInfo0),
+		ModuleInfo0, ModuleInfo) :-
+	table_info_init(ModuleInfo0, PredId, ProcId, PredInfo0, ProcInfo0,
+		TableInfo0),
 
 	% grab the appropriate fields from the pred_info and proc_info
 	proc_info_interface_determinism(ProcInfo0, Detism),
@@ -329,13 +344,22 @@
 	proc_info_goal(ProcInfo0, OrigGoal),
 	proc_info_argmodes(ProcInfo0, ArgModes),
 
-	( EvalMethod = eval_table_io ->
-		module_info_globals(Module0, Globals),
+	(
+		(
+			EvalMethod = eval_table_io,
+			TableDecl = no
+		;
+			EvalMethod = eval_table_io_decl,
+			TableDecl = yes
+		)
+	->
+		module_info_globals(ModuleInfo0, Globals),
 		globals__lookup_bool_option(Globals, trace_table_io_states,
 			TableIoStates),
-		table_gen__create_new_io_goal(OrigGoal, TableIoStates,
-			HeadVars, ArgModes, VarTypes0, VarTypes,
-			VarSet0, VarSet, TableInfo0, TableInfo, Goal),
+		table_gen__create_new_io_goal(OrigGoal, TableDecl,
+			TableIoStates, HeadVars, ArgModes, VarTypes0, VarTypes,
+			VarSet0, VarSet, TableInfo0, TableInfo, Goal,
+			MaybeTableIoDeclInfo),
 		MaybeCallTableTip = no
 	;
 		(
@@ -343,26 +367,25 @@
 			table_gen__create_new_det_goal(EvalMethod, Detism,
 				OrigGoal, PredId, ProcId, HeadVars, ArgModes,
 				VarTypes0, VarTypes, VarSet0, VarSet,
-				TableInfo0, TableInfo, CallTableTip, Goal),
-			MaybeCallTableTip = yes(CallTableTip)
+				TableInfo0, TableInfo, CallTableTip, Goal)
 		;
 			CodeModel = model_semi,
 			table_gen__create_new_semi_goal(EvalMethod, Detism,
 				OrigGoal, PredId, ProcId, HeadVars, ArgModes,
 				VarTypes0, VarTypes, VarSet0, VarSet,
-				TableInfo0, TableInfo, CallTableTip, Goal),
-			MaybeCallTableTip = yes(CallTableTip)
+				TableInfo0, TableInfo, CallTableTip, Goal)
 		;
 			CodeModel = model_non,
 			table_gen__create_new_non_goal(EvalMethod, Detism,
 				OrigGoal, PredId, ProcId, HeadVars, ArgModes,
 				VarTypes0, VarTypes, VarSet0, VarSet,
-				TableInfo0, TableInfo, CallTableTip, Goal),
-			MaybeCallTableTip = yes(CallTableTip)
-		)
+				TableInfo0, TableInfo, CallTableTip, Goal)
 	),
+		MaybeCallTableTip = yes(CallTableTip),
+		MaybeTableIoDeclInfo = no
+	),
 
-	table_info_extract(TableInfo, Module1, PredInfo1, ProcInfo1),
+	table_info_extract(TableInfo, ModuleInfo1, _, _, PredInfo1, ProcInfo1),
 
 	% set the new values of the fields in proc_info and pred_info
 	% and save in the module info
@@ -370,22 +393,25 @@
 	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,
+		ProcInfo6),
 
 	% Some of the instmap_deltas generated in this module
 	% are pretty dodgy (especially those for if-then-elses), so
 	% recompute them here.
 
 	RecomputeAtomic = no,
-	recompute_instmap_delta_proc(RecomputeAtomic, ProcInfo5, ProcInfo,
-		Module1, Module2),
+	recompute_instmap_delta_proc(RecomputeAtomic, ProcInfo6, ProcInfo,
+		ModuleInfo1, ModuleInfo2),
 
 	pred_info_procedures(PredInfo1, ProcTable1),
 	map__det_update(ProcTable1, ProcId, ProcInfo, ProcTable),
 	pred_info_set_procedures(PredInfo1, ProcTable, PredInfo2),
-	repuritycheck_proc(Module2, proc(PredId, ProcId), PredInfo2, PredInfo),
-	module_info_preds(Module2, PredTable1),
+	repuritycheck_proc(ModuleInfo2, proc(PredId, ProcId), PredInfo2,
+		PredInfo),
+	module_info_preds(ModuleInfo2, PredTable1),
 	map__det_update(PredTable1, PredId, PredInfo, PredTable),
-	module_info_set_preds(Module2, PredTable, Module).
+	module_info_set_preds(ModuleInfo2, PredTable, ModuleInfo).
 
 %-----------------------------------------------------------------------------%
 
@@ -393,31 +419,37 @@
 		% Transform procedures that do I/O.
 		%
 
-:- pred table_gen__create_new_io_goal(hlds_goal::in, bool::in,
+:- pred table_gen__create_new_io_goal(hlds_goal::in, bool::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) is det.
+	hlds_goal::out, maybe(table_io_decl_info)::out) is det.
 
-table_gen__create_new_io_goal(OrigGoal, TableIoStates, HeadVars, HeadVarModes,
-		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
-		Goal) :-
+table_gen__create_new_io_goal(OrigGoal, TableDecl, TableIoStates,
+		HeadVars, HeadVarModes, VarTypes0, VarTypes, VarSet0, VarSet,
+		TableInfo0, TableInfo, Goal, MaybeTableIoDeclInfo) :-
 	OrigGoal = _ - OrigGoalInfo,
 	goal_info_get_nonlocals(OrigGoalInfo, OrigNonLocals),
 	goal_info_get_context(OrigGoalInfo, Context),
 
-	table_info_get_module_info(TableInfo0, Module),
+	ModuleInfo = TableInfo0 ^ table_module_info,
 
-	get_input_output_vars(HeadVars, HeadVarModes, Module, InputVars,
+	get_input_output_vars(HeadVars, HeadVarModes, ModuleInfo, InputVars,
 		OutputVars),
 	(
 		TableIoStates = yes,
 		IoStateAssignToVars = [],
-		SavedOutputVars = OutputVars
+		IoStateAssignFromVars = [],
+		SavedOutputVars = OutputVars,
+		SavedHeadVars = HeadVars
 	;
 		TableIoStates = no,
+		list__filter(table_gen__var_is_io_state(VarTypes0),
+			OutputVars, IoStateAssignToVars, SavedOutputVars),
 		list__filter(table_gen__var_is_io_state(VarTypes0),
-			OutputVars, IoStateAssignToVars, SavedOutputVars)
+			InputVars, IoStateAssignFromVars, _SavedInputVars),
+		list__filter(table_gen__var_is_io_state(VarTypes0),
+			HeadVars, _, SavedHeadVars)
 	),
 
 	generate_new_table_var("TableVar0", VarTypes0, VarTypes1,
@@ -430,23 +462,59 @@
 		semidet, yes(impure), [TableVar0 - ground(shared, none),
 		CounterVar - ground(shared, none),
 		StartVar - ground(shared, none)],
-		Module, Context, InRangeGoal),
+		ModuleInfo, Context, InRangeGoal),
 
 	generate_new_table_var("TableVar", VarTypes3, VarTypes4,
 		VarSet3, VarSet4, TableVar),
 	generate_call("table_lookup_insert_start_int",
 		[TableVar0, StartVar, CounterVar, TableVar],
 		det, yes(impure), [TableVar - ground(unique, none)],
-		Module, Context, LookupGoal),
+		ModuleInfo, Context, LookupGoal),
 
 	generate_call("table_io_has_occurred", [TableVar],
-		semidet, yes(semipure), [], Module, Context, OccurredGoal),
+		semidet, yes(semipure), [], ModuleInfo, Context, OccurredGoal),
 
-	generate_restore_goal(SavedOutputVars, TableVar, Module, Context,
-		VarTypes4, VarTypes6, VarSet4, VarSet6, RestoreAnsGoal0),
+	(
+		TableDecl = yes,
+		PredId = TableInfo0 ^ table_cur_pred_id,
+		ProcId = TableInfo0 ^ table_cur_proc_id,
+		RttiProcLabel = rtti__make_proc_label(ModuleInfo,
+			PredId, ProcId),
+		TableIoDeclConsId = table_io_decl(RttiProcLabel),
+		get_table_var_type(TableVarType),
+		make_const_construction(TableIoDeclConsId, TableVarType,
+			yes("TableIoDeclPtr"), TableIoDeclGoal,
+			TableIoDeclPtrVar, VarTypes4, VarTypes5,
+			VarSet4, VarSet5),
+		allocate_slot_numbers(SavedHeadVars, 1, NumberedSavedHeadVars),
+		NumberedSaveVars = [TableIoDeclPtrVar - 0 |
+			NumberedSavedHeadVars],
+		list__filter(key_belong_to_list(SavedOutputVars),
+			NumberedSaveVars, NumberedSavedOutputVars),
+		NumberedRestoreVars = NumberedSavedOutputVars,
+		list__length(NumberedSaveVars, BlockSize),
+
+		ProcInfo0 = TableInfo0 ^ table_cur_proc_info,
+		continuation_info__generate_table_decl_io_layout(ProcInfo0,
+			NumberedSavedHeadVars, TableIoDeclInfo),
+		MaybeTableIoDeclInfo = yes(TableIoDeclInfo)
+	;
+		TableDecl = no,
+		VarTypes5 = VarTypes4,
+		VarSet5 = VarSet4,
+		true_goal(TableIoDeclGoal),
+		allocate_slot_numbers(SavedOutputVars, 0,
+			NumberedSavedOutputVars),
+		NumberedRestoreVars = NumberedSavedOutputVars,
+		NumberedSaveVars = NumberedSavedOutputVars,
+		list__length(NumberedSavedOutputVars, BlockSize),
+		MaybeTableIoDeclInfo = no
+	),
 
-	list__filter(table_gen__var_is_io_state(VarTypes), InputVars,
-		IoStateAssignFromVars, _SavedInputVars),
+	generate_restore_goal(NumberedRestoreVars, TableVar,
+		ModuleInfo, Context, VarTypes5, VarTypes6, VarSet5, VarSet6,
+		RestoreAnsGoal0),
+
 	(
 		TableIoStates = yes,
 		RestoreAnsGoal = RestoreAnsGoal0
@@ -469,7 +537,7 @@
 			[IoStateAssignFromVar, IoStateAssignToVar], det, no,
 			[IoStateAssignFromVar - ground(clobbered, none),
 			IoStateAssignToVar - ground(unique, none)],
-			Module, Context, IoStateAssignGoal),
+			ModuleInfo, Context, IoStateAssignGoal),
 
 		RestoreAnsGoalEx = conj([RestoreAnsGoal0, IoStateAssignGoal]),
 		create_instmap_delta([RestoreAnsGoal0, IoStateAssignGoal],
@@ -482,19 +550,21 @@
 			RestoreAnsNonLocals),
 		instmap_delta_restrict(RestoreAnsInstMapDelta0,
 			RestoreAnsNonLocals, RestoreAnsInstMapDelta),
-		init_goal_info(RestoreAnsNonLocals, RestoreAnsInstMapDelta,
+		goal_info_init(RestoreAnsNonLocals, RestoreAnsInstMapDelta,
 			det, Context, RestoreAnsGoalInfo),
 		RestoreAnsGoal = RestoreAnsGoalEx - RestoreAnsGoalInfo
 	),
-	generate_save_goal(OutputVars, TableVar, Context, VarTypes6, VarTypes,
-		VarSet6, VarSet, TableInfo0, TableInfo, SaveAnsGoal),
-
-	CallSaveAnsGoalEx = conj([OrigGoal, SaveAnsGoal]),
-	create_instmap_delta([OrigGoal, SaveAnsGoal], CallSaveAnsInstMapDelta0),
+	generate_save_goal(NumberedSaveVars, TableVar, BlockSize,
+		Context, VarTypes6, VarTypes, VarSet6, VarSet,
+		TableInfo0, TableInfo, SaveAnsGoal),
+
+	CallSaveAnsGoalEx = conj([OrigGoal, TableIoDeclGoal, SaveAnsGoal]),
+	create_instmap_delta([OrigGoal, TableIoDeclGoal, SaveAnsGoal],
+		CallSaveAnsInstMapDelta0),
 	set__insert(OrigNonLocals, TableVar, CallSaveAnsNonLocals),
 	instmap_delta_restrict(CallSaveAnsInstMapDelta0,
 		CallSaveAnsNonLocals, CallSaveAnsInstMapDelta),
-	init_goal_info(CallSaveAnsNonLocals, CallSaveAnsInstMapDelta, det,
+	goal_info_init(CallSaveAnsNonLocals, CallSaveAnsInstMapDelta, det,
 		Context, CallSaveAnsGoalInfo),
 	CallSaveAnsGoal = CallSaveAnsGoalEx - CallSaveAnsGoalInfo,
 
@@ -506,7 +576,7 @@
 	set__insert(OrigNonLocals, TableVar, GenIfNecNonLocals),
 	instmap_delta_restrict(GenIfNecInstMapDelta0, GenIfNecNonLocals,
 		GenIfNecInstMapDelta),
-	init_goal_info(GenIfNecNonLocals, GenIfNecInstMapDelta, det, Context,
+	goal_info_init(GenIfNecNonLocals, GenIfNecInstMapDelta, det, Context,
 		GenIfNecGoalInfo),
 	GenIfNecGoal = GenIfNecGoalEx - GenIfNecGoalInfo,
 
@@ -517,7 +587,7 @@
 		CheckAndGenAnsNonLocals),
 	instmap_delta_restrict(CheckAndGenAnsInstMapDelta0,
 		CheckAndGenAnsNonLocals, CheckAndGenAnsInstMapDelta),
-	init_goal_info(CheckAndGenAnsNonLocals, CheckAndGenAnsInstMapDelta,
+	goal_info_init(CheckAndGenAnsNonLocals, CheckAndGenAnsInstMapDelta,
 		det, Context, CheckAndGenAnsGoalInfo),
 	CheckAndGenAnsGoal = CheckAndGenAnsGoalEx - CheckAndGenAnsGoalInfo,
 
@@ -527,7 +597,7 @@
 		BodyInstMapDelta0),
 	instmap_delta_restrict(BodyInstMapDelta0, OrigNonLocals,
 		BodyInstMapDelta),
-	init_goal_info(OrigNonLocals, BodyInstMapDelta, det, Context,
+	goal_info_init(OrigNonLocals, BodyInstMapDelta, det, Context,
 		BodyGoalInfo),
 	Goal = BodyGoalEx - BodyGoalInfo.
 
@@ -552,22 +622,26 @@
 	goal_info_get_instmap_delta(OrigGoalInfo, OrigInstMapDelta),
 	goal_info_get_context(OrigGoalInfo, Context),
 
-	table_info_get_module_info(TableInfo0, Module),
+	ModuleInfo = TableInfo0 ^ table_module_info,
 
-	get_input_output_vars(HeadVars, HeadVarModes, Module, InputVars,
+	get_input_output_vars(HeadVars, HeadVarModes, ModuleInfo, InputVars,
 		OutputVars),
 
 	generate_simple_lookup_goal(InputVars, PredId, ProcId, Context,
 		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
 		TableVar, LookUpGoal),
 	generate_call("table_simple_is_complete", [TableVar], semidet,
-		yes(semipure), [], Module, Context, CompleteCheckGoal),
-	generate_save_goal(OutputVars, TableVar, Context, VarTypes1, VarTypes2,
-		VarSet1, VarSet2, TableInfo1, TableInfo, SaveAnsGoal0),
-	generate_restore_goal(OutputVars, TableVar, Module, Context,
-		VarTypes2, VarTypes3, VarSet2, VarSet3, RestoreAnsGoal0),
+		yes(semipure), [], ModuleInfo, Context, CompleteCheckGoal),
+	allocate_slot_numbers(OutputVars, 0, NumberedOutputVars),
+	list__length(NumberedOutputVars, BlockSize),
+	generate_save_goal(NumberedOutputVars, TableVar, BlockSize,
+		Context, VarTypes1, VarTypes2, VarSet1, VarSet2,
+		TableInfo1, TableInfo, SaveAnsGoal0),
+	generate_restore_goal(NumberedOutputVars, TableVar,
+		ModuleInfo, Context, VarTypes2, VarTypes3, VarSet2, VarSet3,
+		RestoreAnsGoal0),
 	generate_call("table_simple_mark_as_inactive", [TableVar], det,
-		yes(impure), [], Module, Context, MarkAsInactiveGoal),
+		yes(impure), [], ModuleInfo, Context, MarkAsInactiveGoal),
 	generate_loop_error_goal(TableInfo, Context, VarTypes3, VarTypes,
 		VarSet3, VarSet, LoopErrorGoal),
 	( Detism = erroneous ->
@@ -593,16 +667,16 @@
 	),
 
 	generate_call("table_simple_is_active", [TableVar], semidet,
-		yes(semipure), [], Module, Context, ActiveCheckGoal),
+		yes(semipure), [], ModuleInfo, Context, ActiveCheckGoal),
 	generate_call("table_simple_mark_as_active", [TableVar], det,
-		yes(impure), [], Module, Context, MarkAsActiveGoal),
+		yes(impure), [], ModuleInfo, Context, MarkAsActiveGoal),
 
 	NoLoopGenAnsGoalEx = conj([MarkAsActiveGoal, OrigGoal, SaveAnsGoal]),
 	create_instmap_delta([MarkAsActiveGoal, OrigGoal, SaveAnsGoal],
 		NoLoopGenInstMapDelta0),
 	instmap_delta_restrict(NoLoopGenInstMapDelta0, GenAnsNonLocals,
 		NoLoopGenInstMapDelta),
-	init_goal_info(GenAnsNonLocals, NoLoopGenInstMapDelta, det, Context,
+	goal_info_init(GenAnsNonLocals, NoLoopGenInstMapDelta, det, Context,
 		NoLoopGenGoalInfo),
 	NoLoopGenAnsGoal = NoLoopGenAnsGoalEx - NoLoopGenGoalInfo,
 
@@ -613,7 +687,7 @@
 		NoLoopGenAnsGoal], GenAnsInstMapDelta0),
 	instmap_delta_restrict(GenAnsInstMapDelta0, GenAnsNonLocals,
 		GenAnsInstMapDelta),
-	init_goal_info(GenAnsNonLocals, GenAnsInstMapDelta, det, Context,
+	goal_info_init(GenAnsNonLocals, GenAnsInstMapDelta, det, Context,
 		GenAnsGoalInfo),
 
 	GenAnsGoal = GenAnsGoalEx - GenAnsGoalInfo,
@@ -624,12 +698,12 @@
 		ITEInstMapDelta0),
 	instmap_delta_restrict(ITEInstMapDelta0, GenAnsNonLocals,
 		ITEInstMapDelta),
-	init_goal_info(GenAnsNonLocals, ITEInstMapDelta, det, Context,
+	goal_info_init(GenAnsNonLocals, ITEInstMapDelta, det, Context,
 		ITEGoalInfo),
 	ITEGoal = ITEGoalEx - ITEGoalInfo,
 
 	GoalEx = conj([LookUpGoal, ITEGoal]),
-	init_goal_info(OrigNonLocals, OrigInstMapDelta, det, Context,
+	goal_info_init(OrigNonLocals, OrigInstMapDelta, det, Context,
 		GoalInfo),
 
 	Goal = GoalEx - GoalInfo.
@@ -657,28 +731,32 @@
 	goal_info_get_instmap_delta(OrigGoalInfo, OrigInstMapDelta),
 	goal_info_get_context(OrigGoalInfo, Context),
 
-	table_info_get_module_info(TableInfo0, Module),
-	get_input_output_vars(HeadVars, HeadVarModes, Module, InputVars,
+	ModuleInfo = TableInfo0 ^ table_module_info,
+	get_input_output_vars(HeadVars, HeadVarModes, ModuleInfo, InputVars,
 		OutputVars),
 
 	generate_simple_lookup_goal(InputVars, PredId, ProcId, Context,
 		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
 		TableVar, LookUpGoal),
 	generate_call("table_simple_is_complete", [TableVar], semidet,
-		yes(semipure), [], Module, Context, CompleteCheckGoal),
-	generate_save_goal(OutputVars, TableVar, Context, VarTypes1, VarTypes2,
-		VarSet1, VarSet2, TableInfo1, TableInfo, SaveAnsGoal0),
-	generate_restore_goal(OutputVars, TableVar, Module, Context,
-		VarTypes2, VarTypes3, VarSet2, VarSet3, RestoreTrueAnsGoal),
+		yes(semipure), [], ModuleInfo, Context, CompleteCheckGoal),
+	allocate_slot_numbers(OutputVars, 0, NumberedOutputVars),
+	list__length(NumberedOutputVars, BlockSize),
+	generate_save_goal(NumberedOutputVars, TableVar, BlockSize,
+		Context, VarTypes1, VarTypes2, VarSet1, VarSet2,
+		TableInfo1, TableInfo, SaveAnsGoal0),
+	generate_restore_goal(NumberedOutputVars, TableVar,
+		ModuleInfo, Context, VarTypes2, VarTypes3, VarSet2, VarSet3,
+		RestoreTrueAnsGoal),
 	generate_loop_error_goal(TableInfo, Context,
 		VarTypes3, VarTypes, VarSet3, VarSet, LoopErrorGoal),
 	generate_call("table_simple_mark_as_failed", [TableVar],
-		det, yes(impure), [], Module, Context, MarkAsFailedGoal0),
+		det, yes(impure), [], ModuleInfo, Context, MarkAsFailedGoal0),
 	append_fail(MarkAsFailedGoal0, MarkAsFailedGoal),
 	generate_call("table_simple_has_succeeded", [TableVar], semidet,
-		yes(semipure), [], Module, Context, HasSucceededCheckGoal),
+		yes(semipure), [], ModuleInfo, Context, HasSucceededCheckGoal),
 	generate_call("table_simple_mark_as_inactive", [TableVar],
-		det, yes(impure), [], Module, Context, MarkAsInactiveGoal),
+		det, yes(impure), [], ModuleInfo, Context, MarkAsInactiveGoal),
 
 	set__insert(OrigNonLocals, TableVar, GenAnsNonLocals),
 
@@ -698,16 +776,18 @@
 			SaveAnsGoal = SaveAnsGoal0
 		),
 		generate_call("table_simple_is_active", [TableVar], semidet,
-			yes(semipure), [], Module, Context, ActiveCheckGoal),
+			yes(semipure), [], ModuleInfo, Context,
+			ActiveCheckGoal),
 		generate_call("table_simple_mark_as_active", [TableVar], det,
-			yes(impure), [], Module, Context, MarkAsActiveGoal),
+			yes(impure), [], ModuleInfo, Context,
+			MarkAsActiveGoal),
 
 		NoLoopGenAnsGoalEx = conj([MarkAsActiveGoal, OrigGoal]),
 		create_instmap_delta([MarkAsActiveGoal, OrigGoal],
 			NoLoopGenInstMapDelta0),
 		instmap_delta_restrict(NoLoopGenInstMapDelta0, GenAnsNonLocals,
 			NoLoopGenInstMapDelta),
-		init_goal_info(GenAnsNonLocals, NoLoopGenInstMapDelta, semidet,
+		goal_info_init(GenAnsNonLocals, NoLoopGenInstMapDelta, semidet,
 			Context, NoLoopGenGoalInfo),
 		NoLoopGenAnsGoal = NoLoopGenAnsGoalEx - NoLoopGenGoalInfo,
 
@@ -717,7 +797,7 @@
 			NoLoopGenAnsGoal], GenTrueAnsInstMapDelta0),
 		instmap_delta_restrict(GenTrueAnsInstMapDelta0,
 			GenAnsNonLocals, GenTrueAnsInstMapDelta),
-		init_goal_info(GenAnsNonLocals, GenTrueAnsInstMapDelta,
+		goal_info_init(GenAnsNonLocals, GenTrueAnsInstMapDelta,
 			semidet, Context, GenTrueAnsGoalInfo),
 
 		GenTrueAnsGoal = GenTrueAnsGoalEx - GenTrueAnsGoalInfo
@@ -727,10 +807,12 @@
 		SaveAnsGoal = SaveAnsGoal0,
 
 		generate_call("table_simple_is_inactive", [TableVar], semidet,
-			yes(semipure), [], Module, Context, InactiveCheckGoal),
+			yes(semipure), [], ModuleInfo, Context,
+			InactiveCheckGoal),
 
 		generate_call("table_simple_mark_as_active", [TableVar], det,
-			yes(impure), [], Module, Context, MarkAsActiveGoal),
+			yes(impure), [], ModuleInfo, Context,
+			MarkAsActiveGoal),
 
 		GenTrueAnsGoalEx = conj([InactiveCheckGoal,
 			MarkAsActiveGoal, OrigGoal]),
@@ -739,7 +821,7 @@
 			OrigGoal, SaveAnsGoal], GenTrueAnsInstMapDelta0),
 		instmap_delta_restrict(GenTrueAnsInstMapDelta0,
 			GenAnsNonLocals, GenTrueAnsInstMapDelta),
-		init_goal_info(GenAnsNonLocals, GenTrueAnsInstMapDelta,
+		goal_info_init(GenAnsNonLocals, GenTrueAnsInstMapDelta,
 			semidet, Context, GenTrueAnsGoalInfo),
 
 		GenTrueAnsGoal = GenTrueAnsGoalEx - GenTrueAnsGoalInfo
@@ -770,7 +852,7 @@
 			RestoreTrueAnsGoal], RestInstMapDelta0),
 		instmap_delta_restrict(RestInstMapDelta0, RestNonLocals,
 			RestInstMapDelta),
-		init_goal_info(RestNonLocals, RestInstMapDelta, semidet,
+		goal_info_init(RestNonLocals, RestInstMapDelta, semidet,
 			Context, RestAnsGoalInfo),
 		RestoreAnsGoal = RestAnsGoalEx - RestAnsGoalInfo
 	),
@@ -781,7 +863,7 @@
 		GenAnsGoalInstMapDelta0),
 	instmap_delta_restrict(GenAnsGoalInstMapDelta0, GenAnsNonLocals,
 		GenAnsGoalInstMapDelta),
-	init_goal_info(GenAnsNonLocals, GenAnsGoalInstMapDelta, semidet,
+	goal_info_init(GenAnsNonLocals, GenAnsGoalInstMapDelta, semidet,
 		Context, GenAnsGoalInfo),
 	GenAnsGoal = GenAnsGoalEx - GenAnsGoalInfo,
 
@@ -791,12 +873,12 @@
 		ITEInstMapDelta0),
 	instmap_delta_restrict(ITEInstMapDelta0, GenAnsNonLocals,
 		ITEInstMapDelta),
-	init_goal_info(GenAnsNonLocals, ITEInstMapDelta, semidet,
+	goal_info_init(GenAnsNonLocals, ITEInstMapDelta, semidet,
 		Context, ITEGoalInfo),
 	ITEGoal = ITEGoalEx - ITEGoalInfo,
 
 	GoalEx = conj([LookUpGoal, ITEGoal]),
-	init_goal_info(OrigNonLocals, OrigInstMapDelta, semidet, Context,
+	goal_info_init(OrigNonLocals, OrigInstMapDelta, semidet, Context,
 		GoalInfo),
 
 	Goal = GoalEx - GoalInfo.
@@ -824,30 +906,34 @@
 	goal_info_get_instmap_delta(OrigGoalInfo, OrigInstMapDelta),
 	goal_info_get_context(OrigGoalInfo, Context),
 
-	table_info_get_module_info(TableInfo0, Module),
-	get_input_output_vars(HeadVars, HeadVarModes, Module, InputVars,
+	ModuleInfo = TableInfo0 ^ table_module_info,
+	get_input_output_vars(HeadVars, HeadVarModes, ModuleInfo, InputVars,
 		OutputVars),
+	allocate_slot_numbers(OutputVars, 0, NumberedOutputVars),
+	list__length(NumberedOutputVars, BlockSize),
 
 	generate_non_lookup_goal(InputVars, PredId, ProcId, Context,
 		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
 		TableVar, LookUpGoal),
 	generate_call("table_nondet_is_complete", [TableVar], semidet,
-		yes(semipure), [], Module, Context, CompleteCheckGoal),
-	generate_non_save_goal(OutputVars, TableVar, Context,
+		yes(semipure), [], ModuleInfo, Context, CompleteCheckGoal),
+	generate_non_save_goal(NumberedOutputVars, TableVar, BlockSize, Context,
 		VarTypes1, VarTypes2, VarSet1, VarSet2, TableInfo1, TableInfo,
 		SaveAnsGoal0),
-	generate_restore_all_goal(Detism, OutputVars, TableVar, Module, Context,
-		VarTypes2, VarTypes3, VarSet2, VarSet3, RestoreAllAnsGoal),
+	generate_restore_all_goal(Detism, NumberedOutputVars, TableVar,
+		ModuleInfo, Context, VarTypes2, VarTypes3, VarSet2, VarSet3,
+		RestoreAllAnsGoal),
 	generate_call("table_nondet_is_active", [TableVar], semidet,
-		yes(semipure), [], Module, Context, IsActiveCheckGoal),
-	generate_suspend_goal(OutputVars, TableVar, Module, Context,
-		VarTypes3, VarTypes4, VarSet3, VarSet4, SuspendGoal),
+		yes(semipure), [], ModuleInfo, Context, IsActiveCheckGoal),
+	generate_suspend_goal(NumberedOutputVars, TableVar,
+		ModuleInfo, Context, VarTypes3, VarTypes4, VarSet3, VarSet4,
+		SuspendGoal),
 	generate_loop_error_goal(TableInfo, Context, VarTypes4, VarTypes,
 		VarSet4, VarSet, LoopErrorGoal),
 	generate_call("table_nondet_mark_as_active", [TableVar], det,
-		yes(impure), [], Module, Context, MarkAsActiveGoal),
+		yes(impure), [], ModuleInfo, Context, MarkAsActiveGoal),
 	generate_call("table_nondet_resume", [TableVar], det, yes(impure),
-		[], Module, Context, ResumeGoal0),
+		[], ModuleInfo, Context, ResumeGoal0),
 	append_fail(ResumeGoal0, ResumeGoal1),
 
 	true_goal(TrueGoal),
@@ -880,7 +966,7 @@
 		GenAnsGoalPart1IMD0),
 	instmap_delta_restrict(GenAnsGoalPart1IMD0, GenAnsGoalPart1NonLocals,
 		GenAnsGoalPart1IMD),
-	init_goal_info(GenAnsGoalPart1NonLocals, GenAnsGoalPart1IMD, nondet,
+	goal_info_init(GenAnsGoalPart1NonLocals, GenAnsGoalPart1IMD, nondet,
 		Context, GenAnsGoalPart1GoalInfo),
 	GenAnsGoalPart1 = GenAnsGoalPart1Ex - GenAnsGoalPart1GoalInfo,
 
@@ -909,7 +995,7 @@
 	),
 
 	GoalEx = conj([LookUpGoal, ITE2Goal]),
-	init_goal_info(OrigNonLocals, OrigInstMapDelta, nondet, Context,
+	goal_info_init(OrigNonLocals, OrigInstMapDelta, nondet, Context,
 		GoalInfo),
 
 	Goal = GoalEx - GoalInfo.
@@ -958,7 +1044,7 @@
 	set__singleton_set(NonLocals0, TableVar),
 	set__insert_list(NonLocals0, Vars, NonLocals),
 	instmap_delta_from_assoc_list([], InstMapDelta),
-	init_goal_info(NonLocals, InstMapDelta, det, Context, GoalInfo0),
+	goal_info_init(NonLocals, InstMapDelta, det, Context, GoalInfo0),
 	goal_info_get_features(GoalInfo0, Features0),
 	set__insert(Features0, call_table_gen, Features),
 	goal_info_set_features(GoalInfo0, Features, GoalInfo),
@@ -976,7 +1062,7 @@
 
 generate_non_lookup_goal(Vars, PredId, ProcId, Context, VarTypes0, VarTypes,
 		VarSet0, VarSet, TableInfo0, TableInfo, SubgoalVar, Goal) :-
-	table_info_get_module_info(TableInfo0, Module),
+	ModuleInfo = TableInfo0 ^ table_module_info,
 	generate_get_table_goal(PredId, ProcId, VarTypes0, VarTypes1,
 		VarSet0, VarSet1, PredTableVar, GetTableGoal),
 	generate_lookup_goals(Vars, Context, PredTableVar, TableNodeVar,
@@ -986,7 +1072,7 @@
 		VarSet2, VarSet, SubgoalVar),
 	generate_call("table_nondet_setup", [TableNodeVar, SubgoalVar],
 		det, yes(impure), [SubgoalVar - ground(unique, none)],
-		Module, Context, SetupGoal),
+		ModuleInfo, Context, SetupGoal),
 
 	list__append([GetTableGoal | LookupGoals], [SetupGoal], Goals),
 	GoalEx = conj(Goals),
@@ -994,7 +1080,7 @@
 	set__insert_list(NonLocals0, Vars, NonLocals),
 	create_instmap_delta(Goals, InstMapDelta0),
 	instmap_delta_restrict(InstMapDelta0, NonLocals, InstMapDelta),
-	init_goal_info(NonLocals, InstMapDelta, det, Context, GoalInfo0),
+	goal_info_init(NonLocals, InstMapDelta, det, Context, GoalInfo0),
 	goal_info_get_features(GoalInfo0, Features0),
 	set__insert(Features0, call_table_gen, Features),
 	goal_info_set_features(GoalInfo0, Features, GoalInfo),
@@ -1016,9 +1102,9 @@
 generate_lookup_goals([Var | Rest], Context, TableVar0, TableVar,
 		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
 		[Goal | RestGoals]) :-
-	table_info_get_module_info(TableInfo0, Module),
+	ModuleInfo = TableInfo0 ^ table_module_info,
 	map__lookup(VarTypes0, Var, VarType),
-	classify_type(VarType, Module, TypeCat),
+	classify_type(VarType, ModuleInfo, TypeCat),
 	gen_lookup_call_for_type(TypeCat, VarType, TableVar0, Var, Context,
 		VarTypes0, VarTypes1, VarSet0, VarSet1, TableInfo0, TableInfo1,
 		TableVar1, Goal),
@@ -1035,13 +1121,13 @@
 gen_lookup_call_for_type(TypeCat, Type, TableVar, ArgVar, Context,
 		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
 		NextTableVar, Goal) :-
-	table_info_get_module_info(TableInfo0, Module),
+	ModuleInfo = TableInfo0 ^ table_module_info,
 
 	( TypeCat = enum_type ->
 		(
 			type_to_type_id(Type, TypeId, _)
 		->
-			module_info_types(Module, TypeDefnTable),
+			module_info_types(ModuleInfo, TypeDefnTable),
 			map__lookup(TypeDefnTable, TypeId, TypeDefn),
 			hlds_data__get_type_defn_body(TypeDefn, TypeBody),
 			(
@@ -1063,12 +1149,12 @@
 				[TableVar, RangeVar, ArgVar, NextTableVar],
 				det, yes(impure),
 				[NextTableVar - ground(unique, none)],
-				Module, Context, LookupGoal),
+				ModuleInfo, Context, LookupGoal),
 			set__init(NonLocals0),
 			set__insert_list(NonLocals0, [TableVar, ArgVar],
 				NonLocals),
 			instmap_delta_from_assoc_list([], InstMapDelta),
-			init_goal_info(NonLocals, InstMapDelta, det, Context,
+			goal_info_init(NonLocals, InstMapDelta, det, Context,
 				GoalInfo),
 			Goal = conj([RangeUnifyGoal, LookupGoal]) - GoalInfo,
 			TableInfo = TableInfo0
@@ -1096,8 +1182,8 @@
 
 			generate_call(LookupPredName,
 				[TypeInfoVar, TableVar, ArgVar, NextTableVar],
-				det, yes(impure), InstMapAL, Module, Context,
-				CallGoal),
+				det, yes(impure), InstMapAL, ModuleInfo,
+				Context, CallGoal),
 
 			list__append(ExtraGoals, [CallGoal], ConjList),
 			CallGoal = _ - GoalInfo,
@@ -1108,8 +1194,8 @@
 				LookupPredName),
 			generate_call(LookupPredName,
 				[TableVar, ArgVar, NextTableVar],
-				det, yes(impure), InstMapAL, Module, Context,
-				Goal),
+				det, yes(impure), InstMapAL, ModuleInfo,
+				Context, Goal),
 			VarTypes = VarTypes1,
 			VarSet = VarSet1,
 			TableInfo = TableInfo0
@@ -1118,130 +1204,131 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred generate_save_goal(list(prog_var)::in, prog_var::in, term__context::in,
+:- pred generate_save_goal(assoc_list(prog_var, int)::in,
+	prog_var::in, int::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,
 	hlds_goal::out) is det.
-
-generate_save_goal(AnsList, TableVar, Context, VarTypes0, VarTypes,
-		VarSet0, VarSet, TableInfo0, TableInfo, Goal) :-
-	table_info_get_module_info(TableInfo0, Module),
 
-	list__length(AnsList, NumAnsVars),
-	(
-		NumAnsVars \= 0
-	->
-		gen_int_construction("NumAnsVars", NumAnsVars, VarTypes0,
-			VarTypes1, VarSet0, VarSet1, NumAnsVarsVar,
-			NumAnsVarsUnifyGoal),
+generate_save_goal(NumberedVars, TableVar, BlockSize, Context,
+		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
+		Goal) :-
+	ModuleInfo = TableInfo0 ^ table_module_info,
+	( BlockSize > 0 ->
+		gen_int_construction("BlockSize", BlockSize, VarTypes0,
+			VarTypes1, VarSet0, VarSet1, BlockSizeVar,
+			BlockSizeVarUnifyGoal),
 
 		generate_new_table_var("AnswerTableVar", VarTypes1, VarTypes2,
 			VarSet1, VarSet2, AnsTableVar),
 
 		generate_call("table_create_ans_block",
-			[TableVar, NumAnsVarsVar, AnsTableVar], det,
-			yes(impure),
-			[AnsTableVar - ground(unique, none)], Module, Context,
-			CreateAnsBlockGoal),
+			[TableVar, BlockSizeVar, AnsTableVar], det,
+			yes(impure), [AnsTableVar - ground(unique, none)],
+			ModuleInfo, Context, CreateAnsBlockGoal),
 
-		generate_save_goals(AnsList, AnsTableVar, 0, Context,
+		generate_save_goals(NumberedVars, AnsTableVar, Context,
 			VarTypes2, VarTypes, VarSet2, VarSet,
 			TableInfo0, TableInfo, SaveGoals),
 
-		GoalEx = conj([NumAnsVarsUnifyGoal, CreateAnsBlockGoal |
+		GoalEx = conj([BlockSizeVarUnifyGoal, CreateAnsBlockGoal |
 			SaveGoals]),
 		set__singleton_set(NonLocals0, TableVar),
-		set__insert_list(NonLocals0, AnsList, NonLocals),
-		create_instmap_delta([NumAnsVarsUnifyGoal, CreateAnsBlockGoal |
-			SaveGoals], InstMapDelta0),
+		assoc_list__keys(NumberedVars, Vars),
+		set__insert_list(NonLocals0, Vars, NonLocals),
+		create_instmap_delta([BlockSizeVarUnifyGoal, CreateAnsBlockGoal
+			| SaveGoals], InstMapDelta0),
 		instmap_delta_restrict(InstMapDelta0, NonLocals, InstMapDelta),
-		init_goal_info(NonLocals, InstMapDelta, det, Context,
+		goal_info_init(NonLocals, InstMapDelta, det, Context,
 			GoalInfo),
 		Goal = GoalEx - GoalInfo
 	;
 		VarTypes = VarTypes0,
 		VarSet = VarSet0,
 		generate_call("table_simple_mark_as_succeeded", [TableVar], det,
-			yes(impure), [], Module, Context, Goal),
+			yes(impure), [], ModuleInfo, Context, Goal),
 		TableInfo = TableInfo0
 	).
 
-:- pred generate_non_save_goal(list(prog_var)::in, prog_var::in,
-	term__context::in, map(prog_var, type)::in, map(prog_var, type)::out,
+:- pred generate_non_save_goal(assoc_list(prog_var, int)::in,
+	prog_var::in, int::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,
 	hlds_goal::out) is det.
 
-generate_non_save_goal(AnsList, TableVar, Context, VarTypes0, VarTypes,
-		VarSet0, VarSet, TableInfo0, TableInfo, Goal) :-
-	table_info_get_module_info(TableInfo0, Module),
+generate_non_save_goal(NumberedOutputVars, TableVar, BlockSize, Context,
+		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
+		Goal) :-
+	ModuleInfo = TableInfo0 ^ table_module_info,
 
 	generate_new_table_var("AnswerTableVar", VarTypes0, VarTypes1,
 		VarSet0, VarSet1, AnsTableVar0),
 	generate_call("table_nondet_get_ans_table", [TableVar, AnsTableVar0],
 		det, yes(impure), [AnsTableVar0 - ground(unique, none)],
-		Module, Context, GetAnsTableGoal),
-	generate_lookup_goals(AnsList, Context, AnsTableVar0, AnsTableVar1,
-		VarTypes1, VarTypes2, VarSet1, VarSet2, TableInfo0, TableInfo1,
-		LookupAnsGoals),
+		ModuleInfo, Context, GetAnsTableGoal),
+	assoc_list__keys(NumberedOutputVars, OutputVars),
+	generate_lookup_goals(OutputVars, Context,
+		AnsTableVar0, AnsTableVar1, VarTypes1, VarTypes2,
+		VarSet1, VarSet2, TableInfo0, TableInfo1, LookupAnsGoals),
 	generate_call("table_nondet_answer_is_not_duplicate", [AnsTableVar1],
-		semidet, yes(impure), [], Module, Context, DuplicateCheckGoal),
+		semidet, yes(impure), [], ModuleInfo, Context,
+		DuplicateCheckGoal),
 
 	generate_new_table_var("AnswerSlotVar", VarTypes2, VarTypes3,
 		VarSet2, VarSet3, AnsSlotVar),
 	generate_call("table_nondet_new_ans_slot", [TableVar, AnsSlotVar], det,
 		yes(impure), [AnsSlotVar - ground(unique, none)],
-		Module, Context, NewAnsSlotGoal),
+		ModuleInfo, Context, NewAnsSlotGoal),
 
-	list__length(AnsList, NumAnsVars),
-	gen_int_construction("NumAnsVars", NumAnsVars, VarTypes3, VarTypes4,
-		VarSet3, VarSet4, NumAnsVarsVar, NumAnsVarsUnifyGoal),
+	gen_int_construction("BlockSize", BlockSize, VarTypes3, VarTypes4,
+		VarSet3, VarSet4, BlockSizeVar, BlockSizeVarUnifyGoal),
 	generate_new_table_var("AnswerBlock", VarTypes4, VarTypes5,
 		VarSet4, VarSet5, AnsBlockVar),
 	generate_call("table_create_ans_block",
-		[AnsSlotVar, NumAnsVarsVar, AnsBlockVar], det, yes(impure),
+		[AnsSlotVar, BlockSizeVar, AnsBlockVar], det, yes(impure),
 		[AnsBlockVar - ground(unique, none)],
-		Module, Context, CreateAnsBlockGoal),
+		ModuleInfo, Context, CreateAnsBlockGoal),
 
-	generate_save_goals(AnsList, AnsBlockVar, 0, Context,
+	generate_save_goals(NumberedOutputVars, AnsBlockVar, Context,
 		VarTypes5, VarTypes, VarSet5, VarSet, TableInfo1, TableInfo,
 		SaveGoals),
 
 	list__append([GetAnsTableGoal | LookupAnsGoals],
-		[DuplicateCheckGoal, NewAnsSlotGoal, NumAnsVarsUnifyGoal,
+		[DuplicateCheckGoal, NewAnsSlotGoal, BlockSizeVarUnifyGoal,
 		CreateAnsBlockGoal | SaveGoals], Goals),
 
 	GoalEx = conj(Goals),
 	set__singleton_set(NonLocals0, TableVar),
-	set__insert_list(NonLocals0, AnsList, NonLocals),
+	set__insert_list(NonLocals0, OutputVars, NonLocals),
 	create_instmap_delta(Goals, InstMapDelta0),
 	instmap_delta_restrict(InstMapDelta0, NonLocals, InstMapDelta),
-	init_goal_info(NonLocals, InstMapDelta, semidet, Context, GoalInfo),
+	goal_info_init(NonLocals, InstMapDelta, semidet, Context, GoalInfo),
 	Goal = GoalEx - GoalInfo.
 
-:- pred generate_save_goals(list(prog_var)::in, prog_var::in, int::in,
+:- pred generate_save_goals(assoc_list(prog_var, int)::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,
 	list(hlds_goal)::out) is det.
 
-generate_save_goals([], _TableVar, _Offset, _Context,
+generate_save_goals([], _TableVar, _Context,
 		VarTypes, VarTypes, VarSet, VarSet, TableInfo, TableInfo, []).
-generate_save_goals([Var | Rest], TableVar, Offset0, Context,
+generate_save_goals([NumberedVar | NumberedRest], TableVar, Context,
 		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
 		Goals) :-
 
-	gen_int_construction("OffsetVar", Offset0, VarTypes0, VarTypes1,
+	NumberedVar = Var - Offset,
+	gen_int_construction("OffsetVar", Offset, VarTypes0, VarTypes1,
 		VarSet0, VarSet1, OffsetVar, OffsetUnifyGoal),
 
-	table_info_get_module_info(TableInfo0, Module),
+	ModuleInfo = TableInfo0 ^ table_module_info,
 	map__lookup(VarTypes1, Var, VarType),
-	classify_type(VarType, Module, TypeCat),
+	classify_type(VarType, ModuleInfo, TypeCat),
 
 	gen_save_call_for_type(TypeCat, VarType, TableVar, Var, OffsetVar,
 		Context, VarTypes1, VarTypes2, VarSet1, VarSet2,
 		TableInfo0, TableInfo1, CallGoal),
 
-	Offset is Offset0 + 1,
-	generate_save_goals(Rest, TableVar, Offset, Context,
+	generate_save_goals(NumberedRest, TableVar, Context,
 		VarTypes2, VarTypes, VarSet2, VarSet, TableInfo1, TableInfo,
 		RestGoals),
 
@@ -1256,11 +1343,11 @@
 gen_save_call_for_type(TypeCat, Type, TableVar, Var, OffsetVar, Context,
 		VarTypes0, VarTypes, VarSet0, VarSet, TableInfo0, TableInfo,
 		Goal) :-
-	table_info_get_module_info(TableInfo0, Module),
+	ModuleInfo = TableInfo0 ^ table_module_info,
 	( type_util__type_is_io_state(Type) ->
 		LookupPredName = "table_save_io_state_ans",
 		generate_call(LookupPredName, [TableVar, OffsetVar, Var],
-			det, yes(impure), [], Module, Context, Goal),
+			det, yes(impure), [], ModuleInfo, Context, Goal),
 
 		VarTypes = VarTypes0,
 		VarSet = VarSet0,
@@ -1272,7 +1359,7 @@
 
 		generate_call("table_save_any_ans",
 			[TypeInfoVar, TableVar, OffsetVar, Var],
-			det, yes(impure), [], Module, Context, CallGoal),
+			det, yes(impure), [], ModuleInfo, Context, CallGoal),
 
 		list__append(ExtraGoals, [CallGoal], ConjList),
 		CallGoal = _ - GoalInfo,
@@ -1282,7 +1369,7 @@
 		string__append_list(["table_save_", CatString, "_ans"],
 			LookupPredName),
 		generate_call(LookupPredName, [TableVar, OffsetVar, Var],
-			det, yes(impure), [], Module, Context, Goal),
+			det, yes(impure), [], ModuleInfo, Context, Goal),
 
 		VarTypes = VarTypes0,
 		VarSet = VarSet0,
@@ -1291,32 +1378,36 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred generate_restore_goal(list(prog_var)::in, prog_var::in,
+:- pred generate_restore_goal(assoc_list(prog_var, int)::in, prog_var::in,
 	module_info::in, term__context::in,
 	map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, hlds_goal::out) is det.
 
-generate_restore_goal(OutputVars, TableVar, Module, Context,
+generate_restore_goal(NumberedOutputVars, TableVar, ModuleInfo, Context,
 		VarTypes0, VarTypes, VarSet0, VarSet, Goal) :-
 
-	generate_restore_goals(OutputVars, TableVar, 0, Module, Context,
-		VarTypes0, VarTypes, VarSet0, VarSet, RestoreGoals),
+	generate_restore_goals(NumberedOutputVars, TableVar,
+		ModuleInfo, Context, VarTypes0, VarTypes, VarSet0, VarSet,
+		RestoreGoals),
 
 	GoalEx = conj(RestoreGoals),
 	set__singleton_set(NonLocals0, TableVar),
+	assoc_list__keys(NumberedOutputVars, OutputVars),
 	set__insert_list(NonLocals0, OutputVars, NonLocals),
 	create_instmap_delta(RestoreGoals, InstMapDelta0),
 	instmap_delta_restrict(InstMapDelta0, NonLocals, InstMapDelta),
-	init_goal_info(NonLocals, InstMapDelta, det, Context, GoalInfo),
+	goal_info_init(NonLocals, InstMapDelta, det, Context, GoalInfo),
 	Goal = GoalEx - GoalInfo.
 
-:- pred generate_restore_all_goal(determinism::in, list(prog_var)::in,
-	prog_var::in, module_info::in, term__context::in,
+:- pred generate_restore_all_goal(determinism::in,
+	assoc_list(prog_var, int)::in, prog_var::in,
+	module_info::in, term__context::in,
 	map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, hlds_goal::out) is det.
 
-generate_restore_all_goal(Detism, OutputVars, TableVar, Module, Context,
-		VarTypes0, VarTypes, VarSet0, VarSet, Goal) :-
+generate_restore_all_goal(Detism, NumberedOutputVars, TableVar,
+		ModuleInfo, Context, VarTypes0, VarTypes, VarSet0, VarSet,
+		Goal) :-
 
 	generate_new_table_var("AnswerTable", VarTypes0, VarTypes1,
 		VarSet0, VarSet1, AnsTableVar),
@@ -1329,50 +1420,51 @@
 	),
 	generate_call(ReturnAllAns, [TableVar, AnsTableVar],
 		Detism, yes(semipure), [AnsTableVar - ground(unique, none)],
-		Module, Context, ReturnAnsBlocksGoal),
+		ModuleInfo, Context, ReturnAnsBlocksGoal),
 
-	generate_restore_goals(OutputVars, AnsTableVar, 0, Module, Context,
-		VarTypes1, VarTypes, VarSet1, VarSet, RestoreGoals),
+	generate_restore_goals(NumberedOutputVars, AnsTableVar, ModuleInfo,
+		Context, VarTypes1, VarTypes, VarSet1, VarSet, RestoreGoals),
 
 	GoalEx = conj([ReturnAnsBlocksGoal | RestoreGoals]),
 	set__singleton_set(NonLocals0, TableVar),
+	assoc_list__keys(NumberedOutputVars, OutputVars),
 	set__insert_list(NonLocals0, OutputVars, NonLocals),
 	create_instmap_delta([ReturnAnsBlocksGoal | RestoreGoals],
 		InstMapDelta0),
 	instmap_delta_restrict(InstMapDelta0, NonLocals, InstMapDelta),
-	init_goal_info(NonLocals, InstMapDelta, nondet, Context, GoalInfo),
+	goal_info_init(NonLocals, InstMapDelta, nondet, Context, GoalInfo),
 	Goal = GoalEx - GoalInfo.
 
-:- pred generate_restore_goals(list(prog_var)::in, prog_var::in, int::in,
+:- pred generate_restore_goals(assoc_list(prog_var, int)::in, prog_var::in,
 	module_info::in, term__context::in,
 	map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, list(hlds_goal)::out) is det.
 
-generate_restore_goals([], _TableVar, _Offset, _Module, _Context,
+generate_restore_goals([], _TableVar, _ModuleInfo, _Context,
 		VarTypes, VarTypes, VarSet, VarSet, []).
-generate_restore_goals([Var | Rest], TableVar, Offset0, Module, Context,
-		VarTypes0, VarTypes, VarSet0, VarSet,
+generate_restore_goals([NumberedVar | NumberedRest], TableVar,
+		ModuleInfo, Context, VarTypes0, VarTypes, VarSet0, VarSet,
 		[OffsetUnifyGoal, CallGoal | RestGoals]) :-
 
-	gen_int_construction("OffsetVar", Offset0, VarTypes0, VarTypes1,
+	NumberedVar = Var - Offset,
+	gen_int_construction("OffsetVar", Offset, VarTypes0, VarTypes1,
 		VarSet0, VarSet1, OffsetVar, OffsetUnifyGoal),
 
 	map__lookup(VarTypes1, Var, VarType),
-	classify_type(VarType, Module, TypeCat),
+	classify_type(VarType, ModuleInfo, TypeCat),
 
 	gen_restore_call_for_type(TypeCat, VarType, TableVar, Var, OffsetVar,
-		Module, Context, CallGoal),
+		ModuleInfo, Context, CallGoal),
 
-	Offset is Offset0 + 1,
-	generate_restore_goals(Rest, TableVar, Offset, Module, Context,
+	generate_restore_goals(NumberedRest, TableVar, ModuleInfo, Context,
 		VarTypes1, VarTypes, VarSet1, VarSet, RestGoals).
 
 :- pred gen_restore_call_for_type(builtin_type::in, (type)::in,
 	prog_var::in, prog_var::in, prog_var::in, module_info::in,
 	term__context::in, hlds_goal::out) is det.
 
-gen_restore_call_for_type(TypeCat, Type, TableVar, Var, OffsetVar, Module,
-		Context, Goal) :-
+gen_restore_call_for_type(TypeCat, Type, TableVar, Var, OffsetVar,
+		ModuleInfo, Context, Goal) :-
 	( type_util__type_is_io_state(Type) ->
 		LookupPredName = "table_restore_io_state_ans"
 	; not_builtin_type(TypeCat) ->
@@ -1384,34 +1476,36 @@
 	),
 	generate_call(LookupPredName, [TableVar, OffsetVar, Var], det,
 		yes(impure), [Var - ground(shared, none)],
-		Module, Context, Goal).
+		ModuleInfo, Context, Goal).
 
 %-----------------------------------------------------------------------------%
 
-:- pred generate_suspend_goal(list(prog_var)::in, prog_var::in,
+:- pred generate_suspend_goal(assoc_list(prog_var, int)::in, prog_var::in,
 	module_info::in, term__context::in,
 	map(prog_var, type)::in, map(prog_var, type)::out,
 	prog_varset::in, prog_varset::out, hlds_goal::out) is det.
 
-generate_suspend_goal(OutputVars, TableVar, Module, Context,
+generate_suspend_goal(NumberedOutputVars, TableVar, ModuleInfo, Context,
 		VarTypes0, VarTypes, VarSet0, VarSet, Goal) :-
 
 	generate_new_table_var("AnswerTable", VarTypes0, VarTypes1,
 		VarSet0, VarSet1, AnsTableVar),
 	generate_call("table_nondet_suspend", [TableVar, AnsTableVar],
 		nondet, yes(semipure), [AnsTableVar - ground(unique, none)],
-		Module, Context, ReturnAnsBlocksGoal),
+		ModuleInfo, Context, ReturnAnsBlocksGoal),
 
-	generate_restore_goals(OutputVars, AnsTableVar, 0, Module, Context,
-		VarTypes1, VarTypes, VarSet1, VarSet, RestoreGoals),
+	generate_restore_goals(NumberedOutputVars, AnsTableVar,
+		ModuleInfo, Context, VarTypes1, VarTypes, VarSet1, VarSet,
+		RestoreGoals),
 
 	GoalEx = conj([ReturnAnsBlocksGoal | RestoreGoals]),
 	set__singleton_set(NonLocals0, TableVar),
+	assoc_list__keys(NumberedOutputVars, OutputVars),
 	set__insert_list(NonLocals0, OutputVars, NonLocals),
 	create_instmap_delta([ReturnAnsBlocksGoal | RestoreGoals],
 		InstMapDelta0),
 	instmap_delta_restrict(InstMapDelta0, NonLocals, InstMapDelta),
-	init_goal_info(NonLocals, InstMapDelta, nondet, Context, GoalInfo),
+	goal_info_init(NonLocals, InstMapDelta, nondet, Context, GoalInfo),
 	Goal = GoalEx - GoalInfo.
 
 %-----------------------------------------------------------------------------%
@@ -1422,8 +1516,8 @@
 
 generate_loop_error_goal(TableInfo, Context, VarTypes0, VarTypes,
 		VarSet0, VarSet, Goal) :-
-	table_info_get_module_info(TableInfo, ModuleInfo),
-	table_info_get_pred_info(TableInfo, PredInfo),
+	ModuleInfo = TableInfo ^ table_module_info,
+	PredInfo = TableInfo ^ table_cur_pred_info,
 
 	pred_info_module(PredInfo, Module),
 	pred_info_name(PredInfo, Name),
@@ -1445,7 +1539,7 @@
 	create_instmap_delta([MessageConsGoal, CallGoal],
 		InstMapDelta0),
 	instmap_delta_restrict(InstMapDelta0, NonLocals, InstMapDelta),
-	init_goal_info(NonLocals, InstMapDelta, erroneous, Context, GoalInfo),
+	goal_info_init(NonLocals, InstMapDelta, erroneous, Context, GoalInfo),
 	Goal = GoalEx - GoalInfo.
 
 %-----------------------------------------------------------------------------%
@@ -1463,11 +1557,11 @@
 	maybe(goal_feature)::in, assoc_list(prog_var, inst)::in,
 	module_info::in, term__context::in, hlds_goal::out) is det.
 
-generate_call(PredName, Args, Detism, MaybeFeature, InstMap, Module, Context,
-		CallGoal) :-
+generate_call(PredName, Args, Detism, MaybeFeature, InstMap,
+		ModuleInfo, Context, CallGoal) :-
 	mercury_table_builtin_module(BuiltinModule),
 	goal_util__generate_simple_call(BuiltinModule, PredName, Args, Detism,
-		MaybeFeature, InstMap, Module, Context, CallGoal).
+		MaybeFeature, InstMap, ModuleInfo, Context, CallGoal).
 
 :- pred append_fail(hlds_goal::in, hlds_goal::out) is det.
 
@@ -1476,8 +1570,8 @@
 	goal_info_get_nonlocals(GoalInfo, NonLocals),
 	goal_info_get_context(GoalInfo, Context),
 	instmap_delta_init_unreachable(UnreachInstMapDelta),
-	init_goal_info(NonLocals, UnreachInstMapDelta, failure,
-		Context, ConjGoalInfo),
+	goal_info_init(NonLocals, UnreachInstMapDelta, failure, Context,
+		ConjGoalInfo),
 	fail_goal(FailGoal),
 	GoalAndThenFail = conj([Goal, FailGoal]) - ConjGoalInfo.
 
@@ -1488,9 +1582,8 @@
 
 gen_int_construction(VarName, VarValue, VarTypes0, VarTypes, VarSet0, VarSet,
 		Var, Goal) :-
-	make_int_const_construction(VarValue, Goal, Var,
-		VarTypes0, VarTypes, VarSet0, VarSet1),
-	varset__name_var(VarSet1, Var, VarName, VarSet).
+	make_int_const_construction(VarValue, yes(VarName), Goal, Var,
+		VarTypes0, VarTypes, VarSet0, VarSet).
 
 :- pred gen_string_construction(string::in, string::in,
 	map(prog_var, type)::in, map(prog_var, type)::out,
@@ -1499,9 +1592,8 @@
 
 gen_string_construction(VarName, VarValue, VarTypes0, VarTypes, VarSet0, VarSet,
 		Var, Goal) :-
-	make_string_const_construction(VarValue, Goal, Var,
-		VarTypes0, VarTypes, VarSet0, VarSet1),
-	varset__name_var(VarSet1, Var, VarName, VarSet).
+	make_string_const_construction(VarValue, yes(VarName), Goal, Var,
+		VarTypes0, VarTypes, VarSet0, VarSet).
 
 :- pred get_table_var_type((type)::out) is det.
 
@@ -1517,12 +1609,15 @@
 	error("get_input_output_vars: lists not same length").
 get_input_output_vars([], [_|_], _, _, _) :-
 	error("get_input_output_vars: lists not same length").
-get_input_output_vars([Var | RestV], [Mode | RestM], Module, InVars, OutVars) :-
-	( mode_is_fully_input(Module, Mode) ->
-		get_input_output_vars(RestV, RestM, Module, InVars0, OutVars),
+get_input_output_vars([Var | RestV], [Mode | RestM], ModuleInfo,
+		InVars, OutVars) :-
+	( mode_is_fully_input(ModuleInfo, Mode) ->
+		get_input_output_vars(RestV, RestM, ModuleInfo,
+			InVars0, OutVars),
 		InVars = [Var | InVars0]
-	; mode_is_fully_output(Module, Mode) ->
-		get_input_output_vars(RestV, RestM, Module, InVars, OutVars0),
+	; mode_is_fully_output(ModuleInfo, Mode) ->
+		get_input_output_vars(RestV, RestM, ModuleInfo,
+			InVars, OutVars0),
 		OutVars = [Var | OutVars0]
 	;
 		error(
@@ -1589,7 +1684,8 @@
 	%
 	% Extract the information from table_info
 	%
-	table_info_extract(TableInfo0, ModuleInfo0, PredInfo0, ProcInfo0),
+	table_info_extract(TableInfo0, ModuleInfo0, PredId, ProcId,
+		PredInfo0, ProcInfo0),
 
 	%
 	% Put the varset and vartypes from the simplify_info
@@ -1617,51 +1713,45 @@
 	% Put the new module_info, pred_info, and proc_info back in the
 	% table_info.
 	%
-	table_info_init(ModuleInfo, PredInfo, ProcInfo, TableInfo).
+	table_info_init(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo,
+		TableInfo).
 
 %-----------------------------------------------------------------------------%
 
-	% The goal_info_init/4 predicate in hlds_goal.m does almost everything
-	% tabling wants in initializing the goal_infos of the new goals it
-	% creates, but it does not fill in the context.  We need to use the
-	% predicate init_goal_info/5 (below) to fill in the context, so that
-	% when debugging is enabled, the call event and the internal events
-	% that record the working of tabling get the correct contexts recorded
-	% for them in the RTTI.
-
-:- pred init_goal_info(set(prog_var)::in, instmap_delta::in, determinism::in,
-	term__context::in, hlds_goal_info::out) is det.
-
-init_goal_info(NonLocals, InstMapDelta, Detism, Context, GoalInfo) :-
-	goal_info_init(NonLocals, InstMapDelta, Detism, GoalInfo0),
-	goal_info_set_context(GoalInfo0, Context, GoalInfo).
+:- pred allocate_slot_numbers(list(prog_var)::in, int::in,
+	assoc_list(prog_var, int)::out) is det.
 
-%-----------------------------------------------------------------------------%
+allocate_slot_numbers([], _, []).
+allocate_slot_numbers([Var | Vars], Offset0, [Var - Offset0 | NumberedVars]) :-
+	allocate_slot_numbers(Vars, Offset0 + 1, NumberedVars).
 
-:- type table_info ---> table_info(module_info, pred_info, proc_info).
+:- pred key_belong_to_list(list(T)::in, pair(T, U)::in) is semidet.
 
-:- pred table_info_init(module_info::in, pred_info::in, proc_info::in,
-	table_info::out) is det.
-:- pred table_info_extract(table_info::in,
-	module_info::out, pred_info::out, proc_info::out) is det.
+key_belong_to_list(List, Key - _Value) :-
+	list__member(Key, List).
 
-:- pred table_info_get_module_info(table_info::in, module_info::out) is det.
-:- pred table_info_get_pred_info(table_info::in, pred_info::out) is det.
-:- pred table_info_get_proc_info(table_info::in, proc_info::out) is det.
+%-----------------------------------------------------------------------------%
 
-table_info_init(ModuleInfo, PredInfo, ProcInfo, TableInfo) :-
-	TableInfo = table_info(ModuleInfo, PredInfo, ProcInfo).
+:- type table_info
+	---> table_info(
+			table_module_info	:: module_info,
+			table_cur_pred_id	:: pred_id,
+			table_cur_proc_id	:: proc_id,
+			table_cur_pred_info	:: pred_info,
+			table_cur_proc_info	:: proc_info
+		).
 
-table_info_extract(TableInfo, ModuleInfo, PredInfo, ProcInfo) :-
-	TableInfo = table_info(ModuleInfo, PredInfo, ProcInfo).
+:- pred table_info_init(module_info::in, pred_id::in, proc_id::in,
+	pred_info::in, proc_info::in, table_info::out) is det.
 
-table_info_get_module_info(TableInfo, ModuleInfo) :-
-	TableInfo = table_info(ModuleInfo, _PredInfo, _ProcInfo).
+:- pred table_info_extract(table_info::in, module_info::out,
+	pred_id::out, proc_id::out, pred_info::out, proc_info::out) is det.
 
-table_info_get_pred_info(TableInfo, PredInfo) :-
-	TableInfo = table_info(_ModuleInfo, PredInfo, _ProcInfo).
+table_info_init(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo, TableInfo) :-
+	TableInfo = table_info(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo).
 
-table_info_get_proc_info(TableInfo, ProcInfo) :-
-	TableInfo = table_info(_ModuleInfo, _PredInfo, ProcInfo).
+table_info_extract(TableInfo, ModuleInfo, PredId, ProcId, PredInfo, ProcInfo)
+		:-
+	TableInfo = table_info(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo).
 
 %-----------------------------------------------------------------------------%
Index: compiler/unify_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unify_gen.m,v
retrieving revision 1.117
diff -u -b -r1.117 unify_gen.m
--- compiler/unify_gen.m	2001/10/31 16:58:10	1.117
+++ compiler/unify_gen.m	2001/12/25 10:46:23
@@ -254,6 +254,9 @@
 unify_gen__generate_tag_test_rval_2(deep_profiling_proc_static_tag(_), _, _) :-
 	% This should never happen
 	error("Attempted deep_profiling_proc_static_tag unification").
+unify_gen__generate_tag_test_rval_2(table_io_decl_tag(_), _, _) :-
+	% This should never happen
+	error("Attempted table_io_decl_tag unification").
 unify_gen__generate_tag_test_rval_2(no_tag, _Rval, TestRval) :-
 	TestRval = const(true).
 unify_gen__generate_tag_test_rval_2(single_functor, _Rval, TestRval) :-
@@ -418,6 +421,15 @@
 	),
 	{ DataAddr = layout_addr(proc_static(RttiProcLabel)) },
 	code_info__assign_const_to_var(Var, const(data_addr_const(DataAddr))).
+unify_gen__generate_construction_2(table_io_decl_tag(RttiProcLabel),
+		Var, Args, _Modes, _, _, empty) -->
+	( { Args = [] } ->
+		[]
+	;
+		{ error("unify_gen: proc_layout has args") }
+	),
+	{ DataAddr = layout_addr(table_io_decl(RttiProcLabel)) },
+	code_info__assign_const_to_var(Var, const(data_addr_const(DataAddr))).
 unify_gen__generate_construction_2(code_addr_constant(PredId, ProcId),
 		Var, Args, _Modes, _, _, empty) -->
 	( { Args = [] } ->
@@ -800,6 +812,9 @@
 	;
 		{ Tag = deep_profiling_proc_static_tag(_) },
 		{ Code = empty }
+	;
+		{ Tag = table_io_decl_tag(_) },
+		{ error("unify_gen__generate_det_deconstruction: table_io_decl_tag") }
 	;
 		{ Tag = no_tag },
 		( { Args = [Arg], Modes = [Mode] } ->
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/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 library
Index: library/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/library/Mmakefile,v
retrieving revision 1.82
diff -u -b -r1.82 Mmakefile
--- library/Mmakefile	2002/01/09 06:41:31	1.82
+++ library/Mmakefile	2002/01/14 10:15:05
@@ -305,6 +305,10 @@
 	../runtime/mercury_deconstruct_macros.h \
 	../runtime/mercury_deconstruct.h
 
+$(os_subdir)table_builtin.$O \
+$(os_subdir)table_builtin.pic_o \
+	: ../runtime/mercury_tabling_macros.h
+
 #-----------------------------------------------------------------------------#
 
 realclean_local:
Index: library/table_builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/table_builtin.m,v
retrieving revision 1.11
diff -u -b -r1.11 table_builtin.m
--- library/table_builtin.m	2001/12/31 04:26:49	1.11
+++ library/table_builtin.m	2002/01/14 10:11:50
@@ -180,7 +180,8 @@
 :- implementation.
 
 :- pragma foreign_proc("C",
-	table_simple_is_complete(T::in), will_not_call_mercury, "
+	table_simple_is_complete(T::in), [will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -198,7 +199,8 @@
 ").
 
 :- pragma foreign_proc("C",
-	table_simple_has_succeeded(T::in), will_not_call_mercury, "
+	table_simple_has_succeeded(T::in), [will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -215,7 +217,8 @@
 ").
 
 :- pragma foreign_proc("C",
-	table_simple_has_failed(T::in), will_not_call_mercury, "
+	table_simple_has_failed(T::in), [will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -232,7 +235,8 @@
 ").
 
 :- pragma foreign_proc("C",
-	table_simple_is_active(T::in), will_not_call_mercury, "
+	table_simple_is_active(T::in), [will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -249,7 +253,8 @@
 ").
 
 :- pragma foreign_proc("C",
-	table_simple_is_inactive(T::in), will_not_call_mercury, "
+	table_simple_is_inactive(T::in), [will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -266,7 +271,8 @@
 ").
 
 :- pragma foreign_proc("C",
-	table_simple_mark_as_succeeded(T::in), will_not_call_mercury, "
+	table_simple_mark_as_succeeded(T::in), [will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -280,7 +286,8 @@
 ").
 
 :- pragma foreign_proc("C",
-	table_simple_mark_as_failed(T::in), will_not_call_mercury, "
+	table_simple_mark_as_failed(T::in), [will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -294,7 +301,8 @@
 ").
 
 :- pragma foreign_proc("C",
-	table_simple_mark_as_active(T::in), will_not_call_mercury, "
+	table_simple_mark_as_active(T::in), [will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -308,7 +316,8 @@
 ").
 
 :- pragma foreign_proc("C",
-	table_simple_mark_as_inactive(T::in), will_not_call_mercury, "
+	table_simple_mark_as_inactive(T::in), [will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -324,47 +333,56 @@
 
 
 :- pragma foreign_proc("MC++",
-	table_simple_is_complete(_T::in), will_not_call_mercury, "
+	table_simple_is_complete(_T::in), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
-	table_simple_has_succeeded(_T::in), will_not_call_mercury, "
+	table_simple_has_succeeded(_T::in), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
-	table_simple_has_failed(_T::in), will_not_call_mercury, "
+	table_simple_has_failed(_T::in), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
-	table_simple_is_active(_T::in), will_not_call_mercury, "
+	table_simple_is_active(_T::in), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
-	table_simple_is_inactive(_T::in), will_not_call_mercury, "
+	table_simple_is_inactive(_T::in), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
-	table_simple_mark_as_succeeded(_T::in), will_not_call_mercury, "
+	table_simple_mark_as_succeeded(_T::in), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
-	table_simple_mark_as_failed(_T::in), will_not_call_mercury, "
+	table_simple_mark_as_failed(_T::in), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
-	table_simple_mark_as_active(_T::in), will_not_call_mercury, "
+	table_simple_mark_as_active(_T::in), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
-	table_simple_mark_as_inactive(_T::in), will_not_call_mercury, "
+	table_simple_mark_as_inactive(_T::in), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
@@ -466,13 +484,17 @@
 	[will_not_call_mercury],
 "
 	if (MR_io_tabling_enabled) {
+		MR_Unsigned	old_counter;
+
+		old_counter = MR_io_tabling_counter;
+
 		MR_io_tabling_counter++;
 
 		if (MR_io_tabling_start < MR_io_tabling_counter 
 			&& MR_io_tabling_counter <= MR_io_tabling_end)
 		{
 			T = (MR_Word) &MR_io_tabling_pointer;
-			Counter = MR_io_tabling_counter;
+			Counter = (MR_Word) old_counter;
 			Start = MR_io_tabling_start;
 			if (MR_io_tabling_counter > MR_io_tabling_counter_hwm)
 			{
@@ -499,7 +521,7 @@
 #ifdef	MR_TABLE_DEBUG
 	if (MR_tabledebug) {
 		printf(""checking %p for previous execution: %p\\n"",
-			table, &table->MR_answerblock);
+			table, table->MR_answerblock);
 	}
 #endif
 	SUCCESS_INDICATOR = (table->MR_answerblock != NULL);
@@ -598,7 +620,8 @@
 :- implementation.
 
 :- pragma foreign_proc("C",
-	table_nondet_setup(T0::in, T::out), will_not_call_mercury, "
+	table_nondet_setup(T0::in, T::out), [will_not_call_mercury],
+"
 #ifndef	MR_USE_MINIMAL_MODEL
 	MR_fatal_error(""minimal model code entered when not enabled"");
 #else
@@ -660,7 +683,8 @@
 ").
 
 :- pragma foreign_proc("MC++",
-	table_nondet_setup(_T0::in, _T::out), will_not_call_mercury, "
+	table_nondet_setup(_T0::in, _T::out), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
@@ -705,7 +729,8 @@
 ").
 
 :- pragma foreign_proc("C",
-	table_nondet_is_active(T::in), will_not_call_mercury, "
+	table_nondet_is_active(T::in), [will_not_call_mercury],
+"
 #ifdef	MR_USE_MINIMAL_MODEL
 	MR_TrieNode	table;
 
@@ -718,7 +743,8 @@
 ").
 
 :- pragma foreign_proc("C",
-	table_nondet_mark_as_active(T::in), will_not_call_mercury, "
+	table_nondet_mark_as_active(T::in), [will_not_call_mercury],
+"
 #ifdef	MR_USE_MINIMAL_MODEL
 	MR_TrieNode	table;
 
@@ -734,7 +760,8 @@
 
 :- pragma foreign_proc("C",
 	table_nondet_get_ans_table(T::in, AT::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 #ifdef	MR_USE_MINIMAL_MODEL
 	MR_TrieNode	table;
 
@@ -748,7 +775,8 @@
 
 :- pragma foreign_proc("C",
 	table_nondet_answer_is_not_duplicate(T::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 #ifndef	MR_USE_MINIMAL_MODEL
 	MR_fatal_error(""minimal model code entered when not enabled"");
 #else
@@ -772,7 +800,8 @@
 
 :- pragma foreign_proc("C",
 	table_nondet_new_ans_slot(T::in, Slot::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 #ifndef	MR_USE_MINIMAL_MODEL
 	MR_fatal_error(""minimal model code entered when not enabled"");
 #else
@@ -887,30 +916,35 @@
 ").
 
 :- pragma foreign_proc("MC++",
-	table_nondet_is_active(_T::in), will_not_call_mercury, "
+	table_nondet_is_active(_T::in), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
-	table_nondet_mark_as_active(_T::in), will_not_call_mercury, "
+	table_nondet_mark_as_active(_T::in), [will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_nondet_get_ans_table(_T::in, _AT::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_nondet_answer_is_not_duplicate(_T::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_nondet_new_ans_slot(_T::in, _Slot::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
@@ -1081,7 +1115,8 @@
 ").
 
 :- pragma foreign_proc("C", table_lookup_insert_int(T0::in, I::in, T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table0, table;
 
 	table0 = (MR_TrieNode) T0;
@@ -1091,7 +1126,8 @@
 
 :- pragma foreign_proc("C",
 	table_lookup_insert_start_int(T0::in, S::in, I::in, T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table0, table;
 
 	table0 = (MR_TrieNode) T0;
@@ -1102,7 +1138,8 @@
 
 :- pragma foreign_proc("C",
 	table_lookup_insert_char(T0::in, C::in, T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table0, table;
 
 	table0 = (MR_TrieNode) T0;
@@ -1111,7 +1148,8 @@
 ").
 
 :- pragma foreign_proc("C", table_lookup_insert_string(T0::in, S::in, T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table0, table;
 
 	table0 = (MR_TrieNode) T0;
@@ -1120,7 +1158,8 @@
 ").
 
 :- pragma foreign_proc("C", table_lookup_insert_float(T0::in, F::in, T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table0, table;
 
 	table0 = (MR_TrieNode) T0;
@@ -1130,7 +1169,8 @@
 
 :- pragma foreign_proc("C", 
 	table_lookup_insert_enum(T0::in, R::in, V::in, T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table0, table;
 
 	table0 = (MR_TrieNode) T0;
@@ -1140,7 +1180,8 @@
 
 :- pragma foreign_proc("C",
 	table_lookup_insert_user(T0::in, V::in, T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table0, table;
 
 	table0 = (MR_TrieNode) T0;
@@ -1150,7 +1191,8 @@
 
 :- pragma foreign_proc("C",
 	table_lookup_insert_poly(T0::in, V::in, T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table0, table;
 
 	table0 = (MR_TrieNode) T0;
@@ -1160,27 +1202,28 @@
 
 :- pragma foreign_proc("C",
 	table_save_int_ans(T::in, Offset::in, I::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
-	MR_TABLE_SAVE_ANSWER(table, Offset, I,
-		&MR_TYPE_CTOR_INFO_INT);
+	MR_TABLE_SAVE_ANSWER(table, Offset, I, &MR_TYPE_CTOR_INFO_INT);
 ").
 
 :- pragma foreign_proc("C",
 	table_save_char_ans(T::in, Offset::in, C::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
-	MR_TABLE_SAVE_ANSWER(table, Offset, C,
-		&MR_TYPE_CTOR_INFO_CHAR);
+	MR_TABLE_SAVE_ANSWER(table, Offset, C, &MR_TYPE_CTOR_INFO_CHAR);
 ").
 
 :- pragma foreign_proc("C",
 	table_save_string_ans(T::in, Offset::in, S::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -1190,24 +1233,24 @@
 
 :- pragma foreign_proc("C",
 	table_save_float_ans(T::in, Offset::in, F::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
 #ifdef MR_HIGHLEVEL_CODE
-	MR_TABLE_SAVE_ANSWER(table, Offset,
-		(MR_Word) MR_box_float(F),
+	MR_TABLE_SAVE_ANSWER(table, Offset, (MR_Word) MR_box_float(F),
 		&MR_TYPE_CTOR_INFO_FLOAT);
 #else
-	MR_TABLE_SAVE_ANSWER(table, Offset,
-		MR_float_to_word(F),
+	MR_TABLE_SAVE_ANSWER(table, Offset, MR_float_to_word(F),
 		&MR_TYPE_CTOR_INFO_FLOAT);
 #endif
 ").
 
 :- pragma foreign_proc("C",
 	table_save_io_state_ans(T::in, Offset::in, S::ui),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -1217,7 +1260,8 @@
 
 :- pragma foreign_proc("C", 
 	table_save_any_ans(T::in, Offset::in, V::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -1226,7 +1270,8 @@
 
 :- pragma foreign_proc("C",
 	table_restore_int_ans(T::in, Offset::in, I::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -1235,7 +1280,8 @@
 
 :- pragma foreign_proc("C",
 	table_restore_char_ans(T::in, Offset::in, C::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -1244,7 +1290,8 @@
 
 :- pragma foreign_proc("C",
 	table_restore_string_ans(T::in, Offset::in, S::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -1253,7 +1300,8 @@
 
 :- pragma foreign_proc("C",
 	table_restore_float_ans(T::in, Offset::in, F::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -1266,7 +1314,8 @@
 
 :- pragma foreign_proc("C",
 	table_restore_io_state_ans(T::in, Offset::in, V::uo),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -1275,7 +1324,8 @@
 
 :- pragma foreign_proc("C",
 	table_restore_any_ans(T::in, Offset::in, V::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table;
 
 	table = (MR_TrieNode) T;
@@ -1284,7 +1334,8 @@
 
 :- pragma foreign_proc("C",
 	table_create_ans_block(T0::in, Size::in, T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	MR_TrieNode	table0;
 
 	table0 = (MR_TrieNode) T0;
@@ -1303,128 +1354,149 @@
 
 :- pragma foreign_proc("MC++",
 	table_lookup_insert_int(_T0::in, _I::in, _T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_lookup_insert_start_int(_T0::in, _S::in, _I::in, _T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_lookup_insert_char(_T0::in, _C::in, _T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_lookup_insert_string(_T0::in, _S::in, _T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_lookup_insert_float(_T0::in, _F::in, _T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++", 
 	table_lookup_insert_enum(_T0::in, _R::in, _V::in, _T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_lookup_insert_user(_T0::in, _V::in, _T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_lookup_insert_poly(_T0::in, _V::in, _T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_save_int_ans(_T::in, _Offset::in, _I::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_save_char_ans(_T::in, _Offset::in, _C::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_save_string_ans(_T::in, _Offset::in, _S::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_save_float_ans(_T::in, _Offset::in, _F::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_save_io_state_ans(_T::in, _Offset::in, _S::ui),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 
 :- pragma foreign_proc("MC++",
 	table_save_any_ans(_T::in, _Offset::in, _V::in),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_restore_int_ans(_T::in, _Offset::in, _I::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_restore_char_ans(_T::in, _Offset::in, _C::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_restore_string_ans(_T::in, _Offset::in, _S::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_restore_float_ans(_T::in, _Offset::in, _F::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_restore_io_state_ans(_T::in, _Offset::in, _V::uo),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_restore_any_ans(_T::in, _Offset::in, _V::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
 :- pragma foreign_proc("MC++",
 	table_create_ans_block(_T0::in, _Size::in, _T::out),
-		will_not_call_mercury, "
+	[will_not_call_mercury],
+"
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
 
@@ -1432,7 +1504,6 @@
 	table_report_statistics, will_not_call_mercury, "
 	mercury::runtime::Errors::SORRY(""foreign code for this function"");
 ").
-
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
Index: library/varset.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/varset.m,v
retrieving revision 1.64
diff -u -b -r1.64 varset.m
--- library/varset.m	2000/11/12 08:51:39	1.64
+++ library/varset.m	2001/12/25 15:10:22
@@ -28,7 +28,7 @@
 
 :- module varset.
 :- interface.
-:- import_module term, list, map, set, assoc_list.
+:- import_module std_util, term, list, map, set, assoc_list.
 
 :- type varset(T).
 
@@ -52,6 +52,11 @@
 :- pred varset__new_named_var(varset(T), string, var(T), varset(T)).
 :- mode varset__new_named_var(in, in, out, out) is det.
 
+	% create a new variable, and maybe give it a name
+:- pred varset__new_maybe_named_var(varset(T), maybe(string),
+	var(T), varset(T)).
+:- mode varset__new_maybe_named_var(in, in, out, out) is det.
+
 	% create multiple new variables
 :- pred varset__new_vars(varset(T), int, list(var(T)), varset(T)).
 :- mode varset__new_vars(in, in, out, out) is det.
@@ -223,7 +228,7 @@
 %-----------------------------------------------------------------------------%
 
 :- implementation.
-:- import_module bool, int, list, map, std_util, assoc_list.
+:- import_module bool, int, list, map, assoc_list.
 :- import_module set, require, string.
 
 :- type varset(T)	--->	varset(
@@ -254,6 +259,17 @@
 		varset(MaxId, Names, Vals)) :-
 	term__create_var(MaxId0, Var, MaxId),
 	map__set(Names0, Var, Name, Names).
+
+varset__new_maybe_named_var(varset(MaxId0, Names0, Vals), MaybeName, Var,
+		varset(MaxId, Names, Vals)) :-
+	term__create_var(MaxId0, Var, MaxId),
+	(
+		MaybeName = no,
+		Names = Names0
+	;
+		MaybeName = yes(Name),
+		map__set(Names0, Var, Name, Names)
+	).
 
 varset__new_vars(Varset0, NumVars, NewVars, Varset) :-
 	varset__new_vars_2(Varset0, NumVars, [], NewVars, Varset).
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_layout_util.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_layout_util.c,v
retrieving revision 1.24
diff -u -b -r1.24 mercury_layout_util.c
--- runtime/mercury_layout_util.c	2001/12/10 06:50:10	1.24
+++ runtime/mercury_layout_util.c	2002/01/14 11:42:02
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 1998-2001 The University of Melbourne.
+** Copyright (C) 1998-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.
 */
@@ -17,6 +17,8 @@
 
 static MR_Word MR_lookup_closure_long_lval(MR_Long_Lval locn,
 	MR_Closure *closure, bool *succeeded);
+static MR_Word MR_lookup_answer_block_long_lval(MR_Long_Lval locn,
+	MR_Word *answer_block, int block_size, bool *succeeded);
 
 void
 MR_copy_regs_to_saved_regs(int max_mr_num, MR_Word *saved_regs)
@@ -149,6 +151,42 @@
 	}
 }
 
+MR_TypeInfoParams
+MR_materialize_answer_block_typeinfos(const MR_Type_Param_Locns *tvar_locns,
+	MR_Word *answer_block, int block_size)
+{
+	if (tvar_locns != NULL) {
+		MR_TypeInfoParams	type_params;
+		bool			succeeded;
+		MR_Integer		count;
+		int			i;
+
+		count = tvar_locns->MR_tp_param_count;
+		type_params = (MR_TypeInfoParams)
+			MR_NEW_ARRAY(MR_Word, count + 1);
+
+		for (i = 0; i < count; i++) {
+			if (tvar_locns->MR_tp_param_locns[i] != 0)
+			{
+				type_params[i + 1] = (MR_TypeInfo)
+					MR_lookup_answer_block_long_lval(
+						tvar_locns->
+							MR_tp_param_locns[i],
+						answer_block, block_size,
+						&succeeded);
+				if (! succeeded) {
+					MR_fatal_error("missing type param in "
+					    "MR_materialize_answer_block_typeinfos");
+				}
+			}
+		}
+
+		return type_params;
+	} else {
+		return NULL;
+	}
+}
+
 int
 MR_get_register_number_long(MR_Long_Lval locn)
 {
@@ -268,8 +306,7 @@
 			if (! *succeeded) {
 				break;
 			}
-			value = MR_typeclass_info_type_info(baseaddr,
-				offset);
+			value = MR_typeclass_info_type_info(baseaddr, offset);
 			*succeeded = TRUE;
 			break;
 
@@ -282,6 +319,110 @@
 		default:
 			if (MR_print_locn) {
 				printf("closure DEFAULT\n");
+			}
+			break;
+	}
+
+	return value;
+}
+
+static MR_Word
+MR_lookup_answer_block_long_lval(MR_Long_Lval locn, MR_Word *answer_block,
+	int block_size, bool *succeeded)
+{
+	int	locn_num;
+	int	offset;
+	MR_Word	value;
+	MR_Word	baseaddr;
+	MR_Word	sublocn;
+
+	*succeeded = FALSE;
+	value = 0;
+
+	locn_num = (int) MR_LONG_LVAL_NUMBER(locn);
+	switch (MR_LONG_LVAL_TYPE(locn)) {
+		case MR_LONG_LVAL_TYPE_R:
+			if (MR_print_locn) {
+				printf("answer_block r%d\n", locn_num);
+			}
+			if (locn_num <= block_size) {
+				value = answer_block[locn_num];
+				*succeeded = TRUE;
+			}
+			break;
+
+		case MR_LONG_LVAL_TYPE_F:
+			if (MR_print_locn) {
+				printf("answer_block f%d\n", locn_num);
+			}
+			break;
+
+		case MR_LONG_LVAL_TYPE_STACKVAR:
+			if (MR_print_locn) {
+				printf("answer_block stackvar%d\n", locn_num);
+			}
+			break;
+
+		case MR_LONG_LVAL_TYPE_FRAMEVAR:
+			if (MR_print_locn) {
+				printf("answer_block framevar%d\n", locn_num);
+			}
+			break;
+
+		case MR_LONG_LVAL_TYPE_SUCCIP:
+			if (MR_print_locn) {
+				printf("answer_block succip\n");
+			}
+			break;
+
+		case MR_LONG_LVAL_TYPE_MAXFR:
+			if (MR_print_locn) {
+				printf("answer_block maxfr\n");
+			}
+			break;
+
+		case MR_LONG_LVAL_TYPE_CURFR:
+			if (MR_print_locn) {
+				printf("answer_block curfr\n");
+			}
+			break;
+
+		case MR_LONG_LVAL_TYPE_HP:
+			if (MR_print_locn) {
+				printf("answer_block hp\n");
+			}
+			break;
+
+		case MR_LONG_LVAL_TYPE_SP:
+			if (MR_print_locn) {
+				printf("answer_block sp\n");
+			}
+			break;
+
+		case MR_LONG_LVAL_TYPE_INDIRECT:
+			offset = MR_LONG_LVAL_INDIRECT_OFFSET(locn_num);
+			sublocn = MR_LONG_LVAL_INDIRECT_BASE_LVAL(locn_num);
+			if (MR_print_locn) {
+				printf("answer_block offset %d from ", offset);
+			}
+			baseaddr = MR_lookup_answer_block_long_lval(sublocn,
+					answer_block, block_size, succeeded);
+			if (! *succeeded) {
+				break;
+			}
+			value = MR_typeclass_info_type_info(baseaddr, offset);
+			*succeeded = TRUE;
+			break;
+
+		case MR_LONG_LVAL_TYPE_UNKNOWN:
+			if (MR_print_locn) {
+				printf("answer_block unknown\n");
+			}
+			break;
+
+		default:
+			if (MR_print_locn) {
+				printf("answer_block DEFAULT\n");
 			}
 			break;
 	}
Index: runtime/mercury_layout_util.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_layout_util.h,v
retrieving revision 1.15
diff -u -b -r1.15 mercury_layout_util.h
--- runtime/mercury_layout_util.h	2001/08/07 23:12:26	1.15
+++ runtime/mercury_layout_util.h	2002/01/14 11:41:39
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 1998-2001 The University of Melbourne.
+** Copyright (C) 1998-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.
 */
@@ -64,6 +64,9 @@
 extern	MR_TypeInfoParams	MR_materialize_closure_typeinfos(
 					const MR_Type_Param_Locns *tvar_locns,
 					MR_Closure *closure);
+extern	MR_TypeInfoParams	MR_materialize_answer_block_typeinfos(
+					const MR_Type_Param_Locns *tvar_locns,
+					MR_Word *answer_block, int block_size);
 
 
 /*
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.53
diff -u -b -r1.53 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h	2001/12/10 06:50:11	1.53
+++ runtime/mercury_stack_layout.h	2002/01/14 04:43:27
@@ -32,6 +32,7 @@
 #include "mercury_types.h"
 #include "mercury_std.h"			/* for MR_VARIABLE_SIZED */
 #include "mercury_tags.h"
+#include "mercury_type_info.h"			/* for MR_PseudoTypeInfo */
 
 /* forward declarations */
 typedef	struct MR_Proc_Layout_Struct	MR_Proc_Layout;
@@ -414,6 +415,29 @@
 */
 
 /*
+** The MR_Table_Io_Decl structure.
+**
+** To enable declarative debugging of I/O actions, the compiler generates one
+** of these structures for each I/O primitive. The compiler transforms the
+** bodies of those primitives to create a block of memory and fill it in with
+** (a) a pointer to the primitive's MR_Table_Io_Decl structure and (2) the
+** values of the primitive's arguments (both input and output, but excluding
+** the I/O states). The array of pseudo-typeinfos pointed to by the ptis field
+** gives the types of these arguments, while the arity field gives the number
+** of arguments (and thus the size of the ptis array, and the size of the block
+** exclusive of the pointer). The proc field allows us to identify the
+** primitive procedure. This is all the information we need to describe the
+** I/O action to the user.
+*/
+
+typedef struct MR_Table_Io_Decl_Struct {
+	const MR_Proc_Layout		*MR_table_io_decl_proc;
+	MR_Integer			MR_table_io_decl_arity;
+	const MR_PseudoTypeInfo		*MR_table_io_decl_ptis;
+	const MR_Type_Param_Locns	*MR_table_io_decl_type_params;
+} MR_Table_Io_Decl;
+
+/*
 ** The MR_Stack_Traversal structure contains the following fields:
 **
 ** The code_addr field points to the start of the procedure's code.
@@ -576,7 +600,8 @@
 	MR_EVAL_METHOD_LOOP_CHECK,
 	MR_EVAL_METHOD_MEMO,
 	MR_EVAL_METHOD_MINIMAL,
-	MR_EVAL_METHOD_TABLE_IO
+	MR_EVAL_METHOD_TABLE_IO,
+	MR_EVAL_METHOD_TABLE_IO_DECL
 } MR_EvalMethod;
 
 typedef	MR_int_least8_t		MR_EvalMethodInt;
@@ -585,6 +610,7 @@
 	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;
 	const MR_int_least16_t	*MR_exec_used_var_names;
 	MR_int_least16_t	MR_exec_max_var_num;
 	MR_int_least16_t	MR_exec_max_r_num;
Index: runtime/mercury_tabling_macros.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_tabling_macros.h,v
retrieving revision 1.6
diff -u -b -r1.6 mercury_tabling_macros.h
--- runtime/mercury_tabling_macros.h	2000/12/06 06:05:46	1.6
+++ runtime/mercury_tabling_macros.h	2002/01/14 10:25:38
@@ -380,6 +380,18 @@
 	),								\
 	((table)->MR_answerblock)[(offset)])
 
+#define MR_TABLE_SAVE_ANSWER(table, offset, value, type_info)		\
+	do {								\
+		if (MR_tabledebug)					\
+			printf("saving to answer block: %p -> %p, "	\
+				"slot %d = %lx\n",			\
+				table, table->MR_answerblock,		\
+				(int) (offset), (long) (value));	\
+		(table)->MR_answerblock[offset] =			\
+			MR_make_permanent((value),			\
+					(MR_TypeInfo) (type_info));	\
+	} while(0)
+
 #else
 
 #define MR_TABLE_CREATE_ANSWER_BLOCK(table, num_slots)	 		\
@@ -391,11 +403,11 @@
 #define MR_TABLE_GET_ANSWER(table, offset)				\
 	((table)->MR_answerblock)[(offset)]
 
-#endif
-
 #define MR_TABLE_SAVE_ANSWER(table, offset, value, type_info)		\
 	do {								\
 		(table)->MR_answerblock[offset] =			\
 			MR_make_permanent((value),			\
 					(MR_TypeInfo) (type_info));	\
 	} while(0)
+
+#endif
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.61
diff -u -b -r1.61 Mmakefile
--- tests/debugger/Mmakefile	2002/01/09 07:04:10	1.61
+++ tests/debugger/Mmakefile	2002/01/14 03:53:58
@@ -44,7 +44,7 @@
 	shallow
 
 MCFLAGS-shallow = --trace shallow
-MCFLAGS-tabled_read = --trace-table-io
+MCFLAGS-tabled_read = --trace-table-io-decl
 # By default, we reclaim heap on failure in non-Boehm-gc grades.
 # The extra stack slots required for this reclamation cause spurious
 # differences from the expected output on the nondet_stack test case.
Index: tests/debugger/tabled_read.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/tabled_read.exp,v
retrieving revision 1.1
diff -u -b -r1.1 tabled_read.exp
--- tests/debugger/tabled_read.exp	2000/12/06 06:05:54	1.1
+++ tests/debugger/tabled_read.exp	2002/01/14 16:20:42
@@ -11,9 +11,9 @@
 mdb> table_io start
 io tabling started
 mdb> continue
-       7:      3  2 CALL pred tabled_read:test/5-0 (det)
+       8:      4  3 CALL pred tabled_read:test/5-0 (det)
 mdb> finish -n
-      34:      3  2 EXIT pred tabled_read:test/5-0 (det)
+      35:      4  3 EXIT pred tabled_read:test/5-0 (det)
 mdb> print *
        HeadVar__1             	'<<c_pointer>>'
        HeadVar__2             	0
@@ -22,40 +22,79 @@
 mdb> retry
 Retry across I/O operations is not always safe.
 Are you sure you want to do it? y
-       7:      3  2 CALL pred tabled_read:test/5-0 (det)
+       8:      4  3 CALL pred tabled_read:test/5-0 (det)
 mdb> print *
        HeadVar__1             	'<<c_pointer>>'
        HeadVar__2             	0
        HeadVar__4             	state('<<c_pointer>>')
 mdb> finish -n
-      34:      3  2 EXIT pred tabled_read:test/5-0 (det)
+      35:      4  3 EXIT pred tabled_read:test/5-0 (det)
 mdb> print *
        HeadVar__1             	'<<c_pointer>>'
        HeadVar__2             	0
        HeadVar__3             	123
        HeadVar__5             	state('<<c_pointer>>')
-mdb> table_io end
-io tabling ended
+mdb> break tabled_read__poly_test
+ 1: + stop  interface pred tabled_read:poly_test/6-0 (det)
 mdb> continue
 123
-      37:     12  2 CALL pred tabled_read:test/5-0 (det)
+      38:     13  3 CALL pred tabled_read:poly_test/6-0 (det)
 mdb> finish -n
-      60:     12  2 EXIT pred tabled_read:test/5-0 (det)
+      65:     13  3 EXIT pred tabled_read:poly_test/6-0 (det)
 mdb> print *
        HeadVar__1             	'<<c_pointer>>'
-       HeadVar__2             	0
-       HeadVar__3             	456
-       HeadVar__5             	state('<<c_pointer>>')
+       HeadVar__2             	['a', 'b', 'c']
+       HeadVar__3             	0
+       HeadVar__4             	456
+       HeadVar__6             	state('<<c_pointer>>')
 mdb> retry
 Retry across I/O operations is not always safe.
 Are you sure you want to do it? y
-      37:     12  2 CALL pred tabled_read:test/5-0 (det)
+      38:     13  3 CALL pred tabled_read:poly_test/6-0 (det)
 mdb> finish -n
-      60:     12  2 EXIT pred tabled_read:test/5-0 (det)
+      65:     13  3 EXIT pred tabled_read:poly_test/6-0 (det)
 mdb> print *
        HeadVar__1             	'<<c_pointer>>'
-       HeadVar__2             	0
-       HeadVar__3             	789
-       HeadVar__5             	state('<<c_pointer>>')
+       HeadVar__2             	['a', 'b', 'c']
+       HeadVar__3             	0
+       HeadVar__4             	456
+       HeadVar__6             	state('<<c_pointer>>')
+mdb> delete *
+ 0: E stop  interface pred tabled_read:test/5-0 (det)
+ 1: E stop  interface pred tabled_read:poly_test/6-0 (det)
+mdb> break part_2
+ 0: + stop  interface pred tabled_read:part_2/3-0 (det)
+mdb> continue
+456
+      69:     22  2 CALL pred tabled_read:part_2/3-0 (det)
+mdb> table_io end
+io tabling ended
+mdb> print action 0
+open_input("tabled_read.data", 0, '<<c_pointer>>')
+mdb> print action 1
+read_char_code('<<c_pointer>>', 49)
+mdb> browse action 1
+browser> p
+read_char_code('<<c_pointer>>', 49)
+browser> ^1
+browser> p
+'<<c_pointer>>'
+browser> quit
+mdb> print action 2
+read_char_code('<<c_pointer>>', 50)
+mdb> print action 3
+read_char_code('<<c_pointer>>', 51)
+mdb> print action 4
+read_char_code('<<c_pointer>>', 10)
+mdb> print action 5
+poly_read_char_code(<<typeinfo>>, <<c_pointer>>, [|]('a', [|]('b', [|]('c', []))), 52)
+mdb> print action 6
+poly_read_char_code(<<typeinfo>>, <<c_pointer>>, [|]('a', [|]('b', [|]('c', []))), 53)
+mdb> print action 7
+poly_read_char_code(<<typeinfo>>, <<c_pointer>>, [|]('a', [|]('b', [|]('c', []))), 54)
+mdb> print action 8
+poly_read_char_code(<<typeinfo>>, <<c_pointer>>, [|]('a', [|]('b', [|]('c', []))), 10)
+mdb> print action 9
+mdb: I/O action number not in range.
 mdb> continue -S
 789
Index: tests/debugger/tabled_read.exp2
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/tabled_read.exp2,v
retrieving revision 1.1
diff -u -b -r1.1 tabled_read.exp2
--- tests/debugger/tabled_read.exp2	2001/01/15 00:55:32	1.1
+++ tests/debugger/tabled_read.exp2	2002/01/14 19:43:50
@@ -11,9 +11,9 @@
 mdb> table_io start
 io tabling started
 mdb> continue
-       7:      3  2 CALL pred tabled_read:test/5-0 (det)
+       8:      4  3 CALL pred tabled_read:test/5-0 (det)
 mdb> finish -n
-      56:      3  2 EXIT pred tabled_read:test/5-0 (det)
+      57:      4  3 EXIT pred tabled_read:test/5-0 (det)
 mdb> print *
        HeadVar__1             	'<<c_pointer>>'
        HeadVar__2             	0
@@ -22,40 +22,79 @@
 mdb> retry
 Retry across I/O operations is not always safe.
 Are you sure you want to do it? y
-       7:      3  2 CALL pred tabled_read:test/5-0 (det)
+       8:      4  3 CALL pred tabled_read:test/5-0 (det)
 mdb> print *
        HeadVar__1             	'<<c_pointer>>'
        HeadVar__2             	0
        HeadVar__4             	state('<<c_pointer>>')
 mdb> finish -n
-      56:      3  2 EXIT pred tabled_read:test/5-0 (det)
+      57:      4  3 EXIT pred tabled_read:test/5-0 (det)
 mdb> print *
        HeadVar__1             	'<<c_pointer>>'
        HeadVar__2             	0
        HeadVar__3             	123
        HeadVar__5             	state('<<c_pointer>>')
-mdb> table_io end
-io tabling ended
+mdb> break tabled_read__poly_test
+ 1: + stop  interface pred tabled_read:poly_test/6-0 (det)
 mdb> continue
 123
-      59:     23  2 CALL pred tabled_read:test/5-0 (det)
+      60:     24  3 CALL pred tabled_read:poly_test/6-0 (det)
 mdb> finish -n
-     104:     23  2 EXIT pred tabled_read:test/5-0 (det)
+     109:     24  3 EXIT pred tabled_read:poly_test/6-0 (det)
 mdb> print *
        HeadVar__1             	'<<c_pointer>>'
-       HeadVar__2             	0
-       HeadVar__3             	456
-       HeadVar__5             	state('<<c_pointer>>')
+       HeadVar__2             	['a', 'b', 'c']
+       HeadVar__3             	0
+       HeadVar__4             	456
+       HeadVar__6             	state('<<c_pointer>>')
 mdb> retry
 Retry across I/O operations is not always safe.
 Are you sure you want to do it? y
-      59:     23  2 CALL pred tabled_read:test/5-0 (det)
+      60:     24  3 CALL pred tabled_read:poly_test/6-0 (det)
 mdb> finish -n
-     104:     23  2 EXIT pred tabled_read:test/5-0 (det)
+     109:     24  3 EXIT pred tabled_read:poly_test/6-0 (det)
 mdb> print *
        HeadVar__1             	'<<c_pointer>>'
-       HeadVar__2             	0
-       HeadVar__3             	789
-       HeadVar__5             	state('<<c_pointer>>')
+       HeadVar__2             	['a', 'b', 'c']
+       HeadVar__3             	0
+       HeadVar__4             	456
+       HeadVar__6             	state('<<c_pointer>>')
+mdb> delete *
+ 0: E stop  interface pred tabled_read:test/5-0 (det)
+ 1: E stop  interface pred tabled_read:poly_test/6-0 (det)
+mdb> break part_2
+ 0: + stop  interface pred tabled_read:part_2/3-0 (det)
+mdb> continue
+456
+     113:     44  2 CALL pred tabled_read:part_2/3-0 (det)
+mdb> table_io end
+io tabling ended
+mdb> print action 0
+open_input("tabled_read.data", 0, '<<c_pointer>>')
+mdb> print action 1
+read_char_code('<<c_pointer>>', 49)
+mdb> browse action 1
+browser> p
+read_char_code('<<c_pointer>>', 49)
+browser> ^1
+browser> p
+'<<c_pointer>>'
+browser> quit
+mdb> print action 2
+read_char_code('<<c_pointer>>', 50)
+mdb> print action 3
+read_char_code('<<c_pointer>>', 51)
+mdb> print action 4
+read_char_code('<<c_pointer>>', 10)
+mdb> print action 5
+poly_read_char_code(<<typeinfo>>, <<c_pointer>>, [|]('a', [|]('b', [|]/2)), 52)
+mdb> print action 6
+poly_read_char_code(<<typeinfo>>, <<c_pointer>>, [|]('a', [|]('b', [|]/2)), 53)
+mdb> print action 7
+poly_read_char_code(<<typeinfo>>, <<c_pointer>>, [|]('a', [|]('b', [|]/2)), 54)
+mdb> print action 8
+poly_read_char_code(<<typeinfo>>, <<c_pointer>>, [|]('a', [|]('b', [|]/2)), 10)
+mdb> print action 9
+mdb: I/O action number not in range.
 mdb> continue -S
 789
Index: tests/debugger/tabled_read.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/tabled_read.inp,v
retrieving revision 1.1
diff -u -b -r1.1 tabled_read.inp
--- tests/debugger/tabled_read.inp	2000/12/06 06:05:54	1.1
+++ tests/debugger/tabled_read.inp	2002/01/14 16:20:40
@@ -12,7 +12,7 @@
 print *
 finish -n
 print *
-table_io end
+break tabled_read__poly_test
 continue
 finish -n
 print *
@@ -20,4 +20,23 @@
 y
 finish -n
 print *
+delete *
+break part_2
+continue
+table_io end
+print action 0
+print action 1
+browse action 1
+p
+^1
+p
+quit
+print action 2
+print action 3
+print action 4
+print action 5
+print action 6
+print action 7
+print action 8
+print action 9
 continue -S
Index: tests/debugger/tabled_read.m
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/tabled_read.m,v
retrieving revision 1.2
diff -u -b -r1.2 tabled_read.m
--- tests/debugger/tabled_read.m	2001/02/05 06:58:49	1.2
+++ tests/debugger/tabled_read.m	2002/01/14 16:16:07
@@ -12,19 +12,33 @@
 
 :- implementation.
 
-:- import_module char, int.
+:- import_module list, char, int.
 
 main -->
 	tabled_read__open_input("tabled_read.data", Res, Stream),
 	( { Res = 0 } ->
-		tabled_read__test(Stream, 0, N),
-		tabled_read__write_int(N),
-		tabled_read__test(Stream, 0, M),
-		tabled_read__write_int(M)
+		tabled_read__part_1(Stream),
+		tabled_read__part_2(Stream)
 	;
 		io__write_string("could not open tabled_read.data\n")
 	).
 
+:- pred tabled_read__part_1(c_pointer::in, io__state::di, io__state::uo)
+	is det. 
+
+tabled_read__part_1(Stream) -->
+	tabled_read__test(Stream, 0, A),
+	tabled_read__write_int(A),
+	tabled_read__poly_test(Stream, ['a', 'b', 'c'], 0, B),
+	tabled_read__write_int(B).
+
+:- pred tabled_read__part_2(c_pointer::in, io__state::di, io__state::uo)
+	is det.
+
+tabled_read__part_2(Stream) -->
+	tabled_read__test(Stream, 0, A),
+	tabled_read__write_int(A).
+
 :- pred tabled_read__test(c_pointer::in, int::in, int::out,
 	io__state::di, io__state::uo) is det.
 
@@ -40,13 +54,29 @@
 		{ N = SoFar }
 	).
 
+:- pred tabled_read__poly_test(c_pointer::in, T::in, int::in, int::out,
+	io__state::di, io__state::uo) is det.
+
+tabled_read__poly_test(Stream, Unused, SoFar, N) -->
+	tabled_read__poly_read_char_code(Stream, Unused, CharCode),
+	(
+		{ char__to_int(Char, CharCode) },
+		{ char__is_digit(Char) },
+		{ char__digit_to_int(Char, CharInt) }
+	->
+		tabled_read__poly_test(Stream, Unused, SoFar * 10 + CharInt, N)
+	;
+		{ N = SoFar }
+	).
+
 :- pragma c_header_code("#include <stdio.h>").
 
 :- pred tabled_read__open_input(string::in, int::out, c_pointer::out,
 	io__state::di, io__state::uo) is det.
 
 :- pragma c_code(tabled_read__open_input(FileName::in, Res::out, Stream::out,
-		IO0::di, IO::uo), [will_not_call_mercury, tabled_for_io],
+	IO0::di, IO::uo),
+	[will_not_call_mercury, tabled_for_io],
 "
 	Stream = (MR_Word) fopen((const char *) FileName, ""r"");
 	Res = Stream? 0 : -1;
@@ -57,16 +87,29 @@
 	io__state::di, io__state::uo) is det.
 
 :- pragma c_code(tabled_read__read_char_code(Stream::in, CharCode::out,
-		IO0::di, IO::uo), [will_not_call_mercury, tabled_for_io],
+	IO0::di, IO::uo),
+	[will_not_call_mercury, tabled_for_io],
+"
+	CharCode = getc((FILE *) Stream);
+	IO = IO0;
+").
+
+:- pred tabled_read__poly_read_char_code(c_pointer::in, T::in, int::out,
+	io__state::di, io__state::uo) is det.
+
+:- pragma c_code(tabled_read__poly_read_char_code(Stream::in, Unused::in,
+	CharCode::out, IO0::di, IO::uo),
+	[will_not_call_mercury, tabled_for_io],
 "
+	/* ignore Unused */
 	CharCode = getc((FILE *) Stream);
 	IO = IO0;
 ").
 
 :- pred tabled_read__write_int(int::in, io__state::di, io__state::uo) is det.
 
-:- pragma c_code(tabled_read__write_int(N::in,
-		IO0::di, IO::uo), [may_call_mercury, thread_safe],
+:- pragma c_code(tabled_read__write_int(N::in, IO0::di, IO::uo),
+	[will_not_call_mercury],
 "{
 	printf(""%d\\n"", (int) N);
 	IO = IO0;
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/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/mercury_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.45
diff -u -b -r1.45 mercury_trace.c
--- trace/mercury_trace.c	2001/12/04 00:44:38	1.45
+++ trace/mercury_trace.c	2001/12/04 00:51:39
@@ -1352,11 +1352,18 @@
 		return;
 
 	case MR_EVAL_METHOD_TABLE_IO:
+	case MR_EVAL_METHOD_TABLE_IO_DECL:
 		return;
 	}
 
-	MR_fatal_error(
-		"unknown evaluation method in MR_maybe_record_call_table");
+	{
+		char	buf[256];
+
+		sprintf(buf, "unknown evaluation method %d "
+				"in MR_maybe_record_call_table",
+				MR_sle_eval_method(level_layout));
+		MR_fatal_error(buf);
+	}
 }
 
 static void
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.111
diff -u -b -r1.111 mercury_trace_internal.c
--- trace/mercury_trace_internal.c	2002/01/12 09:08:14	1.111
+++ trace/mercury_trace_internal.c	2002/01/14 04:17:20
@@ -1065,6 +1065,7 @@
 		}
 	} else if (streq(words[0], "print")) {
 		MR_Browse_Format	format;
+		int			n;
 
 		if (! MR_trace_options_format(&format, &words, &word_count,
 					"browsing", "print"))
@@ -1105,11 +1106,25 @@
 				fflush(MR_mdb_out);
 				fprintf(MR_mdb_err, "mdb: %s.\n", problem);
 			}
+		} else if (word_count == 3 && streq(words[1], "action")
+				&& MR_trace_is_number(words[2], &n))
+		{
+			const char	*problem;
+
+			problem = MR_trace_browse_action(MR_mdb_out, n,
+					MR_trace_browse_goal_internal,
+					MR_BROWSE_CALLER_PRINT, format);
+
+			if (problem != NULL) {
+				fflush(MR_mdb_out);
+				fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+			}
 		} else {
 			MR_trace_usage("browsing", "print");
 		}
 	} else if (streq(words[0], "browse")) {
 		MR_Browse_Format	format;
+		int			n;
 
 		if (! MR_trace_options_format(&format, &words, &word_count,
 					"browsing", "browse"))
@@ -1142,6 +1157,19 @@
 					words[1], MR_trace_browse_internal,
 					MR_BROWSE_CALLER_BROWSE, format, TRUE);
 			}
+
+			if (problem != NULL) {
+				fflush(MR_mdb_out);
+				fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+			}
+		} else if (word_count == 3 && streq(words[1], "action")
+				&& MR_trace_is_number(words[2], &n))
+		{
+			const char	*problem;
+
+			problem = MR_trace_browse_action(MR_mdb_out, n,
+					MR_trace_browse_goal_internal,
+					MR_BROWSE_CALLER_BROWSE, format);
 
 			if (problem != NULL) {
 				fflush(MR_mdb_out);
Index: trace/mercury_trace_vars.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_vars.c,v
retrieving revision 1.31
diff -u -b -r1.31 mercury_trace_vars.c
--- trace/mercury_trace_vars.c	2002/01/18 04:02:24	1.31
+++ trace/mercury_trace_vars.c	2002/01/18 04:23:26
@@ -111,6 +111,9 @@
 				MR_PseudoTypeInfo pseudo_type_info);
 static	int		MR_trace_compare_var_details(const void *arg1,
 				const void *arg2);
+static	void		MR_generate_proc_name_from_layout(const MR_Proc_Layout
+				*proc_layout, MR_ConstString *proc_name_ptr,
+				int *arity_ptr, MR_Word *is_func_ptr);
 static	const char *	MR_trace_browse_one_path(FILE *out,
 				MR_Var_Spec var_spec, char *path,
 				MR_Browser browser,
@@ -447,7 +450,7 @@
 	}
 
 	slot_max = slot;
-	free(type_params);
+	MR_free(type_params);
 
 	if (slot_max > 0) {
 		qsort(MR_point.MR_point_vars, slot_max,
@@ -656,6 +659,31 @@
 	return NULL;
 }
 
+static void
+MR_generate_proc_name_from_layout(const MR_Proc_Layout *proc_layout,
+	MR_ConstString *proc_name_ptr, int *arity_ptr, MR_Word *is_func_ptr)
+{
+	if (MR_PROC_LAYOUT_COMPILER_GENERATED(proc_layout)) {
+		*proc_name_ptr = proc_layout->MR_sle_proc_id.
+			MR_proc_comp.MR_comp_pred_name;
+		*arity_ptr = proc_layout->MR_sle_proc_id.
+			MR_proc_comp.MR_comp_arity;
+		*is_func_ptr = MR_BOOL_NO;
+	} else {
+		*proc_name_ptr = proc_layout->MR_sle_proc_id.
+			MR_proc_user.MR_user_name;
+		*arity_ptr = proc_layout->MR_sle_proc_id.
+			MR_proc_user.MR_user_arity;
+		if (proc_layout->MR_sle_proc_id.MR_proc_user.
+				MR_user_pred_or_func == MR_FUNCTION)
+		{
+			*is_func_ptr = MR_BOOL_YES;
+		} else {
+			*is_func_ptr = MR_BOOL_NO;
+		}
+	}
+}
+
 /*
 ** The following declaration allocates a cell to a typeinfo even if though
 ** its arity is zero. This wastes a word of space but avoids depending on the
@@ -689,25 +717,8 @@
 	int			slot;
 
 	proc_layout = MR_point.MR_point_level_entry;
-	if (MR_PROC_LAYOUT_COMPILER_GENERATED(proc_layout)) {
-		proc_name = proc_layout->MR_sle_proc_id.
-			MR_proc_comp.MR_comp_pred_name;
-		arity = proc_layout->MR_sle_proc_id.
-			MR_proc_comp.MR_comp_arity;
-		is_func = MR_BOOL_NO;
-	} else {
-		proc_name = proc_layout->MR_sle_proc_id.
-			MR_proc_user.MR_user_name;
-		arity = proc_layout->MR_sle_proc_id.
-			MR_proc_user.MR_user_arity;
-		if (proc_layout->MR_sle_proc_id.MR_proc_user.
-				MR_user_pred_or_func == MR_FUNCTION)
-		{
-			is_func = MR_BOOL_YES;
-		} else {
-			is_func = MR_BOOL_NO;
-		}
-	}
+	MR_generate_proc_name_from_layout(proc_layout, &proc_name, &arity,
+		&is_func);
 
 	vars = MR_point.MR_point_vars;
 	for (slot = MR_point.MR_point_var_count - 1; slot >= 0; slot--) {
@@ -731,6 +742,63 @@
 		arg_list = MR_list_cons(arg, arg_list);
 	}
 
+	(*browser)(proc_name, arg_list, is_func, caller, format);
+	return NULL;
+}
+
+const char *
+MR_trace_browse_action(FILE *out, int action_number, MR_GoalBrowser browser,
+	MR_Browse_Caller_Type caller, MR_Browse_Format format)
+{
+	const MR_Table_Io_Decl	*table_io_decl;
+	const MR_Proc_Layout	*proc_layout;
+	MR_ConstString		proc_name;
+	MR_Word			is_func;
+	MR_Word			arg_list;
+	MR_Word			arg;
+	int			filtered_arity;
+	int			arity;
+	int			hv;
+	MR_TrieNode		answer_block_trie;
+	MR_Word			*answer_block;
+	MR_TypeInfo		*type_params;
+	MR_TypeInfo		type_info;
+
+	if (! (MR_io_tabling_start <= action_number
+		&& action_number < MR_io_tabling_counter_hwm))
+	{
+		return "I/O action number not in range";
+	}
+
+	MR_DEBUG_NEW_TABLE_START_INT(answer_block_trie,
+		(MR_TrieNode) &MR_io_tabling_pointer,
+		MR_io_tabling_start, action_number);
+	answer_block = answer_block_trie->MR_answerblock;
+
+	if (answer_block == NULL) {
+		return "I/O action number not in range";
+	}
+
+	table_io_decl = (const MR_Table_Io_Decl *) answer_block[0];
+	proc_layout = table_io_decl->MR_table_io_decl_proc;
+	filtered_arity = table_io_decl->MR_table_io_decl_arity;
+
+	MR_generate_proc_name_from_layout(proc_layout, &proc_name, &arity,
+		&is_func);
+
+	type_params = MR_materialize_answer_block_typeinfos(
+			table_io_decl->MR_table_io_decl_type_params,
+			answer_block, filtered_arity);
+
+	arg_list = MR_list_empty();
+	for (hv = filtered_arity; hv >= 1; hv--) {
+		type_info = MR_create_type_info(type_params,
+			table_io_decl->MR_table_io_decl_ptis[hv - 1]);
+		MR_new_univ_on_hp(arg, type_info, answer_block[hv]);
+		arg_list = MR_list_cons(arg, arg_list);
+	}
+
+	MR_free(type_params);
 	(*browser)(proc_name, arg_list, is_func, caller, format);
 	return NULL;
 }
Index: trace/mercury_trace_vars.h
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_vars.h,v
retrieving revision 1.14
diff -u -b -r1.14 mercury_trace_vars.h
--- trace/mercury_trace_vars.h	2002/01/12 09:08:15	1.14
+++ trace/mercury_trace_vars.h	2002/01/14 04:06:56
@@ -110,11 +110,23 @@
 /*
 ** Print the call of the current level as a goal.
 **
-** The names are printed to the given file if the file pointer is non-NULL.
+** The goal is printed to the given file if the file pointer is non-NULL.
 ** The goal is printed by giving it to the specified browser.
 */
 
 extern	const char	*MR_trace_browse_one_goal(FILE *out,
+				MR_GoalBrowser browser,
+				MR_Browse_Caller_Type caller,
+				MR_Browse_Format format);
+
+/*
+** Print I/O action action_number a goal.
+**
+** The goal is printed to the given file if the file pointer is non-NULL.
+** The goal is printed by giving it to the specified browser.
+*/
+
+extern	const char	*MR_trace_browse_action(FILE *out, int action_number,
 				MR_GoalBrowser browser,
 				MR_Browse_Caller_Type caller,
 				MR_Browse_Format format);
cvs diff: Diffing util
--------------------------------------------------------------------------
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