for review: big step towards a usable debugger, round 3 (part 1 of 3)

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed Apr 8 18:48:05 AEST 1998


This change makes the tracer a lot more useful. The major points are:

- you can now print the values of live variables at all trace ports,
  not just at entry and exit ports;

- you can now print the values of polymorphic variables;

- you can now set spy points;

- you can now say "give me back control when execution starts going
  forward again";

- the implementation no longer saves and restores a thousand pseudo-registers
  unnecessarily;

- the implementation no longer insists that stack layouts must be present
  either for all labels or for none;

- you can now execute programs compiled with tracing without user intervention
  if that is what you want.

The last change makes bootstrapping with --generate-trace possible in theory,
although this has not yet been done successfully.

The three major things remaining to be done to make the tracer an adequate
replacement for Prolog debugging are

- a real term browser;

- a redo capability

- being able to trace different modules at different levels
  (full/interface/none).

Two less important things to do are making the representation of typeinfos
themselves type correct :-( and not including partially clobbered variables
in trace events (we already filter out fully clobbered variables, which are
the vast majority of all at-least-partially clobbered variables).

compiler/trace.m:
	We now record information about what (non-fully-clobbered) variables
	are live where in a label that we associate with each event,
	a label we allocate for this purpose. Since the stack layouts can
	only describe registers and stack slots, generating a trace event
	may now require materializing some variables and moving some others
	from fields to registers or stack slots.

	We now recognize three kinds of events: external, normal internal
	and nondet pragma C code internal. We have different predicates
	for generating each kind of event, since the three kinds of callers
	are different and have different information available.

compiler/arg_info.m:
compiler/code_info.m:
	Move some code that always belonged in arg_info.m to arg_info.m
	from code_info.m.

compiler/code_exprn.m:
	Add a predicate to find out which registers are in use, so the tracer
	can avoid saving and restoring registers that are not use.

compiler/code_gen.m:
	Reorganize the handling of epilogs. Whereas epilogs used to generate
	the failure handling code, this is now done in generate_category_code,
	because failure handling is now complicated by having to save the
	input args for the fail event, and the setup for this naturally
	belongs in generate_category_code.

	Rename generate_{prolog,epilog} as generate_{entry,exit}, since
	this makes clear that the latter now only handles success
	continuations, not failure continuations.

	Spell prologue and epilogue correctly elsewhere.

	Also move the responsibility for the call event to
	generate_category_code.

	Move Tyson's recent additions for tracing to trace.m in a generalized
	form, since they are now needed for all events, not just call and exit.

	Remove obsolete code for eager code generation.

compiler/code_info.m:
	Add a predicate to call the new predicate in code_exprn.

	Export a predicate for trace.m.

	Considerably simplify the treatment of continuation_infos,
	with code_info structures now storing only the stuff that can change
	during code generation (due to trace events).

compiler/code_util.m:
compiler/opt_util.m:
compiler/vn_filter.m:
compiler/trace.m:
	Move some code to code_util.m from opt_util.m and generalize it a bit,
	since the new predicate in code_exprn.m now needs the functionality.
	Make trace.m and vn_filter.m refer to the moved predicates by their
	new name.

compiler/continuation_info.m:
	Major reorganization and simplification of the data structures.
	The data that changes during code generation is now stored in the
	code generator state; data that is only available after code generation
	is combined with the info from the code generator state and put into
	the HLDS; data that is available only after optimization is put
	directly into the HLDS.

	Do not add continuation_info records for labels that are not used
	either by tracing or by agc. For labels that are used by either,
	always include stack layout information if any variables are live.

	(The removal of an unnecessary layer of maybe's wasn't ready
	for this time around; Tom will remove this layer soon.)

compiler/continuation_info.m:
compiler/stack_layout.m:
	Do not associate the stack layout information at procedure entry and
	exit with the per-procedure data structure. Since we now associate this
	info with the labels of those events instead, they do not need special
	handling. However, do include a pointer to the layout structure of
	the label associated with the call event in the per-procedure data,
	so that we can later implement redo in the debugger.

compiler/stack_layout.m:
	Handle the possibility that the set of type variables that are needed
	at a point is not numbered 1-N without any missing type var numbers.
	This can happen if all variables whose types include a low-numbered
	type variable die before some of those whose types include a higher-
	numbered type variable.

compiler/*_switch*.m:
compiler/ite_gen.m:
compiler/disj_gen.m:
	When creating trace events, associate not just a goal path but
	also a pre-death set with events that represent entry to a computation
	branch. Trace.m now needs the pre-death set so that it can avoid
	trying to flush variables that are not supposed to be live in the
	computation branch being traced.

	Since putting variable values in positions that can be described
	by stack layouts (which includes only registers and stack slots,
	not fields etc) may require generating code, make sure that this
	code is generated when code_info has the appropriate contents
	(i.e. just before the generating the code the entrance to which
	the event refers to).

compiler/pragma_c_gen.m:
	Add two new event types to signify entry to the C code fragments
	executed on first call and on later reentries.

compiler/handle_options.m:
	Handle some more implications of tracing, and document them better.
	One of these changes (follow_vars) ought to allow munta to pass
	the debugger test cases.

compiler/llds_out.m:
	When generating init_{entry,label,local} operations, append a suffix
	_sl to the macro name if the label whose info is being registered
	has a stack layout record. This will cause the stack layout to be
	registered also. For other labels, the macro without the _sl will
	register NULL instead.

compiler/live_vars.m:
compiler/liveness.m:
compiler/store_alloc.m:
	If tracing is on, try to preserve the input arguments throughout
	the execution of the procedure. This is not possible if any part
	of an input argument is clobbered, but in the absence of a utility
	predicate that can test for this, we ignore the issue for now.

compiler/mercury_compile.m:
	Do not invoke continuation_info__process_instructions to add
	stack layout information about call return sites unless we are doing
	agc. (Tracing does not require this info, and it is big.)

	Pass info on which labels have stack layout records to llds_out.m.

	Fix some misleading progress messages.

compiler/{lambda,polymorphism,goal_util}.m:
	Enforce the invariant that if the signature of a procedure created
	for a lambda goal includes a type variable, it also includes the
	typeinfo for that type variable.

	(This change is from Simon.)

library/{benchmarking,std_util}.m:
	Add the _sl suffix to init_* macros in hand-written code where
	necessary.

library/require.m:
	When error is called from a program that does tracing, make it
	print the number of the last event.

runtime/mercury_{conf_param.h,trace.c}:
util/mkinit.c:
	Rename MR_USE_DEBUGGER as MR_USE_EXTERNAL_DEBUGGER, since we
	have an internal one as well.

runtime/mercury_goto.h:
	For each of the init_{entry,label,local} macros, and the macros
	they invoke, add a new variant (denoted by a _sl suffix on the
	macro name) that will cause the stack layout record associated
	with the label to be registered also. For labels initialized
	with the variants without the _sl, initialization will register
	NULL instead.

runtime/mercury_{memory,misc}.c:
	In several locations, just before exiting with a fatal error in
	a program that does tracing, print the number of the last event.

runtime/mercury_regorder.h:
	Add two new macros, MR_NUM_SPECIAL_REG and MR_MAX_SPECIAL_REG_MR
	that mercury_trace.c uses to decide how much fake_reg to save and
	restore.

runtime/mercury_stack_layout.h:
	Change the definition of MR_Var_Shape_Info to reflect the real type
	of one of its fields more closely.

	Make the type names conform to the Mercury style guide
	With_Studly_Cap_Names.

	Fix the name and the definition of MR_DETISM_DET_CODE_MODEL.

runtime/mercury_stack_layout.c:
	Use the new forms of the type names.

runtime/mercury_trace.[ch]:
runtime/mercury_wrapper.c:
	Add support for turning tracing on and off and for choosing the
	external or internal debugger.

	Modify the prototype of MR_trace() to reflect the new arg giving
	the number of the highest numbered rN register in use at the call.

	Support the new trace ports for nondet pragma C code.

runtime/mercury_trace.c:
	Implement a new command set more in line with what we intend to
	grow towards in the future:
	
	[N] s/S/CR to skip N events
	f/F to finish the execution of the current call
	c/C to continue to the end

	The upper case versions print events as they go, the lower case
	ones don't.

	Add several new commands:

	N g/G to go to event #N
	r to skip all following exit and fail ports until we come to
		another port type
	b module pred
		to add a breakpoint (which actually functions like a spy point)
	? to list all breakpoints
	+ to enable a numbered breakpoint
	- to disable a numbered breakpoint

	Save/restore only the necessary registers, not all of them.

	Do not indent trace events by the depth, since the depth can get
	very large (4800 in one case I looked at).

	Provide functions for other parts of the runtime and the library
	to call to print the number of the last trace event.

	There is a reference here back to the library, but this will
	go away when the tabling change is committed.

runtime/mercury_trace.[ch]:
	Add a new function, MR_trace_report. This function, which is for
	invocation in the event of a fatal error, reports what the number
	of the last event was (if tracing is enabled). This should allow
	the programmer to go more directly to the source of the problem.

runtime/mercury_wrapper.[ch]:
	Remove the long obsolete code for initializing r[123] with integers.

scripts/mdb:
	A new script for turning on the tracing code in an executable.

scripts/Mmakefile:
bindist/Mmakefile:
bindist/bindist.Makefile.in:
	Include mdb in the list of scripts to be installed.

doc/Mmakefile:
	Include mdb in the list of scripts with autogenerated man pages.

tests/misc_tests/Mmakefile:
tests/misc_tests/debugger_regs.*:
tests/misc_tests/debugger_test.*:
	Move the tests of the debugger to the new tests/debugger directory.
	In the process, give debugger_test back its original name,
	"interpreter", and give it an input script that tests the new
	debugger commands while avoiding the printing of excessively large
	terms (although they still overflow 80 columns).

tests/debugger/Mmakefile:
tests/debugger/runtests:
tests/debugger/debugger_regs.*:
tests/debugger/interpreter.*:
	The moved test cases and copied Mmakefile/runtests.

tests/misc_tests/queens.*:
	A new test case to test the printing of variables in polymorphic
	procedures.

The rest of this message has the changes outside of the runtime, library
and compiler directories, relative to the repository. The next two messages
will have the changes in the runtime, library and compiler directories,
relative to the earlier reviewed proposal.

Zoltan.

Index: bindist/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/bindist/Mmakefile,v
retrieving revision 1.10
diff -u -r1.10 Mmakefile
--- Mmakefile	1998/02/11 16:58:11	1.10
+++ Mmakefile	1998/03/31 08:22:49
@@ -24,7 +24,8 @@
 		  ../NEWS ../RELEASE_NOTES ../BUGS ../WORK_IN_PROGRESS \
 		  ../VERSION
 
-SCRIPT_FILES	= ../scripts/*.in ../scripts/*.sh-subr ../scripts/Mmake.rules
+SCRIPT_FILES	= ../scripts/*.in ../scripts/mdb ../scripts/*.sh-subr \
+		  ../scripts/Mmake.rules
 
 CONFIG_FILES	= ../config.sub ../config.guess ../install-sh
 
Index: bindist/bindist.Makefile.in
===================================================================
RCS file: /home/mercury1/repository/mercury/bindist/bindist.Makefile.in,v
retrieving revision 1.9
diff -u -r1.9 bindist.Makefile.in
--- bindist.Makefile.in	1997/10/21 14:56:54	1.9
+++ bindist.Makefile.in	1998/03/31 08:23:48
@@ -18,7 +18,7 @@
 INSTALL_SCRIPTS		= scripts/c2init scripts/mmc \
 			scripts/mercury_update_interface scripts/mgnuc \
 			scripts/mint scripts/ml scripts/mmake scripts/mprof \
-			scripts/mkfifo_using_mknod
+			scripts/mdb scripts/mkfifo_using_mknod
 
 SICSTUS_SCRIPTS		= scripts/msc scripts/msl \
 			scripts/msp scripts/sicstus_conv
Index: doc/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/Mmakefile,v
retrieving revision 1.7
diff -u -r1.7 Mmakefile
--- Mmakefile	1998/03/11 22:07:20	1.7
+++ Mmakefile	1998/04/01 06:19:44
@@ -75,7 +75,8 @@
 	library_1.html faq_1.html transition_guide_1.html
 
 .PHONY: manpages
-manpages: c2init.1 mmc.1 mgnuc.1 ml.1 mmake.1 msc.1 mprof.1 mprof_merge_runs.1
+manpages: c2init.1 mmc.1 mgnuc.1 ml.1 mmake.1 mdb.1 msc.1 mprof.1 \
+	mprof_merge_runs.1
 
 #-----------------------------------------------------------------------------#
 
Index: scripts/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/scripts/Mmakefile,v
retrieving revision 1.6
diff -u -r1.6 Mmakefile
--- Mmakefile	1997/11/21 07:11:00	1.6
+++ Mmakefile	1998/03/14 06:07:48
@@ -14,7 +14,7 @@
 
 #-----------------------------------------------------------------------------#
 
-SCRIPTS = mmake mmc c2init mgnuc ml mprof mprof_merge_runs mint \
+SCRIPTS = mmake mmc mdb c2init mgnuc ml mprof mprof_merge_runs mint \
 	  sicstus_conv mtags vpath_find mercury_update_interface \
 	  mkfifo_using_mknod
 NUPROLOG_SCRIPTS = mnc mnl mnp
Index: tests/misc_tests/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/misc_tests/Mmakefile,v
retrieving revision 1.6
diff -u -r1.6 Mmakefile
--- Mmakefile	1998/02/16 17:23:15	1.6
+++ Mmakefile	1998/03/18 00:57:55
@@ -9,41 +9,14 @@
 mdemangle_test.out: mdemangle_test.inp
 	mdemangle < mdemangle_test.inp > mdemangle_test.out 2>&1
 
-debugger_regs.out: debugger_regs debugger_regs.inp
-	./debugger_regs debugger_regs.m < debugger_regs.inp \
-		> debugger_regs.out 2>&1
-
-debugger_test.out: debugger_test debugger_test.inp
-	./debugger_test debugger_test.m < debugger_test.inp \
-		> debugger_test.out 2>&1
-
 pretty_print_test.out: pretty_print_test.ugly
 	cp pretty_print_test.ugly pretty_print_test.out
 
 #-----------------------------------------------------------------------------#
 
-STACK_LAYOUT_PROGS=	\
-	debugger_regs	\
-	debugger_test
-
-OTHER_PROGS =
+PROGS =
 
 OTHER_TESTS = mdemangle_test pretty_print_test
-
-MCFLAGS-debugger_regs = --generate-trace
-MCFLAGS-debugger_test = --generate-trace
-
-# Not all grades can be used with stack layouts
-#
-ifeq ($(GRADE),jump) 
-	PROGS=$(OTHER_PROGS)
-else
-	ifeq ($(GRADE),fast)
-		PROGS=$(OTHER_PROGS)
-	else
-		PROGS=$(STACK_LAYOUT_PROGS) $(OTHER_PROGS)
-	endif
-endif
 
 #-----------------------------------------------------------------------------#
 
Index: util/mkinit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/util/mkinit.c,v
retrieving revision 1.29
diff -u -r1.29 mkinit.c
--- mkinit.c	1998/03/11 22:07:38	1.29
+++ mkinit.c	1998/03/31 10:18:18
@@ -133,7 +133,7 @@
 	"	MR_library_initializer = ML_io_init_state;\n"
 	"	MR_library_finalizer = ML_io_finalize_state;\n"
 	"	MR_library_trace_browser = ENTRY(mercury__io__print_3_0);\n"
-	"#ifdef MR_USE_DEBUGGER\n"
+	"#ifdef MR_USE_EXTERNAL_DEBUGGER\n"
 	"	MR_DI_output_current = ML_DI_output_current;\n"
 	"	MR_DI_found_match = ML_DI_found_match;\n"
 	"	MR_DI_read_request_from_socket = ML_DI_read_request_from_socket;\n"

New File: scripts/mdb
===================================================================
#!/bin/sh
#---------------------------------------------------------------------------#
# Copyright (C) 1998 The University of Melbourne.
# This file may only be copied under the terms of the GNU General
# Public License - see the file COPYING in the Mercury distribution.
#---------------------------------------------------------------------------#
#
# IMPORTANT: the manpage is produced automatically from this help
# message, so if you change the help message, don't forget to check
# that the manpage still looks OK.
Help="\
Name:	mdb - Mercury debugger
Usage:	mdb executable [<options>]...
Description:
	The arguments of this command form a command line.
	If the executable named by this command line is a Mercury program
	compiled with --generate-trace, mdb will cause this program to be
	executed under the supervision of the Mercury internal debugger.
	Otherwise, mdb will execute the command line as if the mdb prefix
	weren't there.
Environment variables:
	MERCURY_OPTIONS.
"

case $# in
	0)	echo "Usage: mdb <executable> [<arg> ...]"
		exit 1;;
esac

case $1 in
	--help)
		echo "$Help"
		exit 0;;
esac

MERCURY_OPTIONS="$MERCURY_OPTIONS -Di"
export MERCURY_OPTIONS
exec "$@"

New File: tests/debugger/Mmakefile
===================================================================
#-----------------------------------------------------------------------------#

main_target: check

include ../Mmake.common

#-----------------------------------------------------------------------------#

DEBUGGER_PROGS=	\
	debugger_regs	\
	interpreter	\
	queens

MCFLAGS = --generate-trace

# Not all grades can be used with stack layouts
#
ifeq ($(GRADE),jump) 
	PROGS=
else
	ifeq ($(GRADE),fast)
		PROGS=
	else
		PROGS=$(DEBUGGER_PROGS)
	endif
endif

#-----------------------------------------------------------------------------#

debugger_regs.out: debugger_regs debugger_regs.inp
	mdb ./debugger_regs < debugger_regs.inp > debugger_regs.out

interpreter.out: interpreter interpreter.inp
	mdb ./interpreter interpreter.m < interpreter.inp > interpreter.out

queens.out: queens queens.inp
	mdb ./queens < queens.inp > queens.out

#-----------------------------------------------------------------------------#

DEPS=	$(PROGS:%=%.dep)
DEPENDS=$(PROGS:%=%.depend)
OUTS=	$(PROGS:%=%.out)
RESS=	$(PROGS:%=%.res)
MODS=	$(PROGS:%=%.mod)

#-----------------------------------------------------------------------------#

dep:	$(DEPS)

depend:	$(DEPENDS)

check:	$(OUTS) $(RESS)

mods:	$(MODS)

all:	$(PROGS)

#-----------------------------------------------------------------------------#

New File: tests/debugger/debugger_regs.exp
===================================================================
       1:      1  1 CALL DET   debugger_regs:main/2-0 
mtrace>        2:      2  2 CALL DET   debugger_regs:data/41-0 
mtrace>        3:      2  2 EXIT DET   debugger_regs:data/41-0 
mtrace>           HeadVar__1           		[1, 2, 3, 4, 5]
          HeadVar__2           		a0
          HeadVar__3           		a1
          HeadVar__4           		a2
          HeadVar__5           		a3
          HeadVar__6           		a4
          HeadVar__7           		a5
          HeadVar__8           		a6
          HeadVar__9           		a7
          HeadVar__10          		a8
          HeadVar__11          		a9
          HeadVar__12          		b0
          HeadVar__13          		b1
          HeadVar__14          		b2
          HeadVar__15          		b3
          HeadVar__16          		b4
          HeadVar__17          		b5
          HeadVar__18          		b6
          HeadVar__19          		b7
          HeadVar__20          		b8
          HeadVar__21          		b9
          HeadVar__22          		c0
          HeadVar__23          		c1
          HeadVar__24          		c2
          HeadVar__25          		c3
          HeadVar__26          		c4
          HeadVar__27          		c5
          HeadVar__28          		c6
          HeadVar__29          		c7
          HeadVar__30          		c8
          HeadVar__31          		c9
          HeadVar__32          		d0
          HeadVar__33          		d1
          HeadVar__34          		d2
          HeadVar__35          		d3
          HeadVar__36          		d4
          HeadVar__37          		d5
          HeadVar__38          		d6
          HeadVar__39          		d7
          HeadVar__40          		d8
          HeadVar__41          		d9
mtrace> a0a1a2a3a4a5a6a7a8a9
b0b1b2b3b4b5b6b7b8b9
c0c1c2c3c4c5c6c7c8c9
d0d1d2d3d4d5d6d7d8d9

New File: tests/debugger/debugger_regs.inp
===================================================================


p
c

New File: tests/debugger/debugger_regs.m
===================================================================
<same as in tests/misc_tests>
New File: tests/debugger/interpreter.exp
===================================================================
       1:      1  1 CALL DET   interpreter:main/2-0 
mtrace> valid commands are:
a, EOF:			abort the current execution.
b module pred:		set breakpoint in module:pred.
c:			continue to end of program, not printing the trace.
C:			continue to end of program, printing the trace.
f:			finish this call, not printing the trace.
F:			finish this call, printing the trace.
<N> g:			go to event #N, not printing the trace.
<N> G:			go to event #N, printing the trace.
p:			print the variables live at this point.
r:			continue until forward execution is resumed.
[<N>] s, [N] CR:	skip N events, not printing the trace.
[<N>] S:		skip N events, printing the trace.
?:			list all the breakpoints.
+ N:			enable breakpoint #N.
- N:			disable breakpoint #N.
mtrace> Pure Prolog Interpreter.
<rest of output snipped to avoid overflowing line limits>
New File: tests/debugger/interpreter.inp
===================================================================
h
10s
p
30 g
p
F
p

f


c

New File: tests/debugger/interpreter.m
===================================================================
<same as in tests/misc_tests>
New File: tests/debugger/queens.exp
===================================================================
       1:      1  1 CALL CCMUL queens:main/2-0 
mtrace>           HeadVar__1           		state('<<c_pointer>>')
mtrace>        2:      2  2 CALL DET   queens:data/1-0 
mtrace> mtrace: no live variables
mtrace>        3:      2  2 EXIT DET   queens:data/1-0 
mtrace>           HeadVar__1           		[1, 2, 3, 4, 5]
mtrace>        4:      3  2 CALL NON   queens:queen/2-0 
mtrace>           HeadVar__1           		[1, 2, 3, 4, 5]
mtrace>        5:      4  3 CALL NON   queens:qperm/2-0 
mtrace>           HeadVar__1           		[1, 2, 3, 4, 5]
mtrace>        6:      4  3 SWTC NON   queens:qperm/2-0 s1;
mtrace>           HeadVar__1           		[1, 2, 3, 4, 5]
mtrace>        7:      5  4 CALL NON   queens:qdelete/3-0 
mtrace>           HeadVar__2           		[1, 2, 3, 4, 5]
mtrace>        8:      5  4 DISJ NON   queens:qdelete/3-0 c2;d1;
mtrace>           HeadVar__2           		[1, 2, 3, 4, 5]
          V_11                 		1
          V_10                 		[2, 3, 4, 5]
mtrace>        9:      5  4 EXIT NON   queens:qdelete/3-0 
mtrace>           HeadVar__1           		1
          HeadVar__3           		[2, 3, 4, 5]
          HeadVar__2           		[1, 2, 3, 4, 5]
mtrace>       10:      6  4 CALL NON   queens:qperm/2-0 
mtrace>           HeadVar__1           		[2, 3, 4, 5]
mtrace>       11:      6  4 SWTC NON   queens:qperm/2-0 s1;
mtrace>           HeadVar__1           		[2, 3, 4, 5]
mtrace>       12:      7  5 CALL NON   queens:qdelete/3-0 
mtrace>           HeadVar__2           		[2, 3, 4, 5]
mtrace>       13:      7  5 DISJ NON   queens:qdelete/3-0 c2;d1;
mtrace>           HeadVar__2           		[2, 3, 4, 5]
          V_11                 		2
          V_10                 		[3, 4, 5]
mtrace>       14:      7  5 EXIT NON   queens:qdelete/3-0 
mtrace>           HeadVar__1           		2
          HeadVar__3           		[3, 4, 5]
          HeadVar__2           		[2, 3, 4, 5]
mtrace>       15:      8  5 CALL NON   queens:qperm/2-0 
mtrace>           HeadVar__1           		[3, 4, 5]
mtrace>       16:      8  5 SWTC NON   queens:qperm/2-0 s1;
mtrace>           HeadVar__1           		[3, 4, 5]
mtrace>       17:      9  6 CALL NON   queens:qdelete/3-0 
mtrace>           HeadVar__2           		[3, 4, 5]
mtrace>       18:      9  6 DISJ NON   queens:qdelete/3-0 c2;d1;
mtrace>           HeadVar__2           		[3, 4, 5]
          V_11                 		3
          V_10                 		[4, 5]
mtrace>       19:      9  6 EXIT NON   queens:qdelete/3-0 
mtrace>           HeadVar__1           		3
          HeadVar__3           		[4, 5]
          HeadVar__2           		[3, 4, 5]
mtrace>       20:     10  6 CALL NON   queens:qperm/2-0 
mtrace>           HeadVar__1           		[4, 5]
mtrace>       21:     10  6 SWTC NON   queens:qperm/2-0 s1;
mtrace>           HeadVar__1           		[4, 5]
mtrace>       22:     11  7 CALL NON   queens:qdelete/3-0 
mtrace>           HeadVar__2           		[4, 5]
mtrace>       23:     11  7 DISJ NON   queens:qdelete/3-0 c2;d1;
mtrace>           HeadVar__2           		[4, 5]
          V_11                 		4
          V_10                 		[5]
mtrace>       24:     11  7 EXIT NON   queens:qdelete/3-0 
mtrace>           HeadVar__1           		4
          HeadVar__3           		[5]
          HeadVar__2           		[4, 5]
mtrace>       25:     12  7 CALL NON   queens:qperm/2-0 
mtrace>           HeadVar__1           		[5]
mtrace>       26:     12  7 SWTC NON   queens:qperm/2-0 s1;
mtrace>           HeadVar__1           		[5]
mtrace>       27:     13  8 CALL NON   queens:qdelete/3-0 
mtrace>           HeadVar__2           		[5]
mtrace>       28:     13  8 DISJ NON   queens:qdelete/3-0 c2;d1;
mtrace>           HeadVar__2           		[5]
          V_11                 		5
          V_10                 		[]
mtrace>       29:     13  8 EXIT NON   queens:qdelete/3-0 
mtrace>           HeadVar__1           		5
          HeadVar__3           		[]
          HeadVar__2           		[5]
mtrace>       30:     14  8 CALL NON   queens:qperm/2-0 
mtrace>           HeadVar__1           		[]
mtrace>       31:     14  8 SWTC NON   queens:qperm/2-0 s2;
mtrace> mtrace>       32:     14  8 EXIT NON   queens:qperm/2-0 
mtrace>           HeadVar__2           		[]
          HeadVar__1           		[]
mtrace>       33:     12  7 EXIT NON   queens:qperm/2-0 
mtrace>           HeadVar__2           		[5]
          HeadVar__1           		[5]
mtrace>       34:     10  6 EXIT NON   queens:qperm/2-0 
mtrace>           HeadVar__2           		[4, 5]
          HeadVar__1           		[4, 5]
mtrace>       35:      8  5 EXIT NON   queens:qperm/2-0 
mtrace>           HeadVar__2           		[3, 4, 5]
          HeadVar__1           		[3, 4, 5]
mtrace>       36:      6  4 EXIT NON   queens:qperm/2-0 
mtrace>           HeadVar__2           		[2, 3, 4, 5]
          HeadVar__1           		[2, 3, 4, 5]
mtrace>       37:      4  3 EXIT NON   queens:qperm/2-0 
mtrace>           HeadVar__2           		[1, 2, 3, 4, 5]
          HeadVar__1           		[1, 2, 3, 4, 5]
mtrace>       38:     15  3 CALL SEMI  queens:safe/1-0 
mtrace>           HeadVar__1           		[1, 2, 3, 4, 5]
mtrace>       39:     15  3 SWTC SEMI  queens:safe/1-0 s1;
mtrace>           HeadVar__1           		[1, 2, 3, 4, 5]
mtrace>       40:     16  4 CALL SEMI  queens:nodiag/3-0 
mtrace>           HeadVar__1           		1
          HeadVar__2           		1
          HeadVar__3           		[2, 3, 4, 5]
mtrace>       41:     16  4 SWTC SEMI  queens:nodiag/3-0 s1;
mtrace>           HeadVar__1           		1
          HeadVar__2           		1
          HeadVar__3           		[2, 3, 4, 5]
mtrace>       42:     16  4 THEN SEMI  queens:nodiag/3-0 s1;c4;t;
      43:     16  4 FAIL SEMI  queens:nodiag/3-0 
      44:     15  3 FAIL SEMI  queens:safe/1-0 
      45:     14  8 FAIL NON   queens:qperm/2-0 
      46:     13  8 DISJ NON   queens:qdelete/3-0 c2;d2;
      47:     17  9 CALL NON   queens:qdelete/3-0 
      48:     17  9 FAIL NON   queens:qdelete/3-0 
      49:     13  8 FAIL NON   queens:qdelete/3-0 
      50:     12  7 FAIL NON   queens:qperm/2-0 
      51:     11  7 DISJ NON   queens:qdelete/3-0 c2;d2;
      52:     18  8 CALL NON   queens:qdelete/3-0 
      53:     18  8 DISJ NON   queens:qdelete/3-0 c2;d1;
      54:     18  8 EXIT NON   queens:qdelete/3-0 
      55:     11  7 EXIT NON   queens:qdelete/3-0 
      56:     19  7 CALL NON   queens:qperm/2-0 
      57:     19  7 SWTC NON   queens:qperm/2-0 s1;
      58:     20  8 CALL NON   queens:qdelete/3-0 
      59:     20  8 DISJ NON   queens:qdelete/3-0 c2;d1;
      60:     20  8 EXIT NON   queens:qdelete/3-0 
      61:     21  8 CALL NON   queens:qperm/2-0 
      62:     21  8 SWTC NON   queens:qperm/2-0 s2;
      63:     21  8 EXIT NON   queens:qperm/2-0 
      64:     19  7 EXIT NON   queens:qperm/2-0 
      65:     10  6 EXIT NON   queens:qperm/2-0 
      66:      8  5 EXIT NON   queens:qperm/2-0 
      67:      6  4 EXIT NON   queens:qperm/2-0 
      68:      4  3 EXIT NON   queens:qperm/2-0 
      69:     22  3 CALL SEMI  queens:safe/1-0 
      70:     22  3 SWTC SEMI  queens:safe/1-0 s1;
      71:     23  4 CALL SEMI  queens:nodiag/3-0 
      72:     23  4 SWTC SEMI  queens:nodiag/3-0 s1;
      73:     23  4 THEN SEMI  queens:nodiag/3-0 s1;c4;t;
      74:     23  4 FAIL SEMI  queens:nodiag/3-0 
      75:     22  3 FAIL SEMI  queens:safe/1-0 
      76:     21  8 FAIL NON   queens:qperm/2-0 
      77:     20  8 DISJ NON   queens:qdelete/3-0 c2;d2;
      78:     24  9 CALL NON   queens:qdelete/3-0 
      79:     24  9 FAIL NON   queens:qdelete/3-0 
      80:     20  8 FAIL NON   queens:qdelete/3-0 
      81:     19  7 FAIL NON   queens:qperm/2-0 
      82:     18  8 DISJ NON   queens:qdelete/3-0 c2;d2;
      83:     25  9 CALL NON   queens:qdelete/3-0 
      84:     25  9 FAIL NON   queens:qdelete/3-0 
      85:     18  8 FAIL NON   queens:qdelete/3-0 
      86:     11  7 FAIL NON   queens:qdelete/3-0 
      87:     10  6 FAIL NON   queens:qperm/2-0 
      88:      9  6 DISJ NON   queens:qdelete/3-0 c2;d2;
      89:     26  7 CALL NON   queens:qdelete/3-0 
      90:     26  7 DISJ NON   queens:qdelete/3-0 c2;d1;
      91:     26  7 EXIT NON   queens:qdelete/3-0 
      92:      9  6 EXIT NON   queens:qdelete/3-0 
      93:     27  6 CALL NON   queens:qperm/2-0 
      94:     27  6 SWTC NON   queens:qperm/2-0 s1;
      95:     28  7 CALL NON   queens:qdelete/3-0 
      96:     28  7 DISJ NON   queens:qdelete/3-0 c2;d1;
      97:     28  7 EXIT NON   queens:qdelete/3-0 
      98:     29  7 CALL NON   queens:qperm/2-0 
      99:     29  7 SWTC NON   queens:qperm/2-0 s1;
     100:     30  8 CALL NON   queens:qdelete/3-0 
     101:     30  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     102:     30  8 EXIT NON   queens:qdelete/3-0 
     103:     31  8 CALL NON   queens:qperm/2-0 
     104:     31  8 SWTC NON   queens:qperm/2-0 s2;
     105:     31  8 EXIT NON   queens:qperm/2-0 
     106:     29  7 EXIT NON   queens:qperm/2-0 
     107:     27  6 EXIT NON   queens:qperm/2-0 
     108:      8  5 EXIT NON   queens:qperm/2-0 
     109:      6  4 EXIT NON   queens:qperm/2-0 
     110:      4  3 EXIT NON   queens:qperm/2-0 
     111:     32  3 CALL SEMI  queens:safe/1-0 
     112:     32  3 SWTC SEMI  queens:safe/1-0 s1;
     113:     33  4 CALL SEMI  queens:nodiag/3-0 
     114:     33  4 SWTC SEMI  queens:nodiag/3-0 s1;
     115:     33  4 THEN SEMI  queens:nodiag/3-0 s1;c4;t;
     116:     33  4 FAIL SEMI  queens:nodiag/3-0 
     117:     32  3 FAIL SEMI  queens:safe/1-0 
     118:     31  8 FAIL NON   queens:qperm/2-0 
     119:     30  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     120:     34  9 CALL NON   queens:qdelete/3-0 
     121:     34  9 FAIL NON   queens:qdelete/3-0 
     122:     30  8 FAIL NON   queens:qdelete/3-0 
     123:     29  7 FAIL NON   queens:qperm/2-0 
     124:     28  7 DISJ NON   queens:qdelete/3-0 c2;d2;
     125:     35  8 CALL NON   queens:qdelete/3-0 
     126:     35  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     127:     35  8 EXIT NON   queens:qdelete/3-0 
     128:     28  7 EXIT NON   queens:qdelete/3-0 
     129:     36  7 CALL NON   queens:qperm/2-0 
     130:     36  7 SWTC NON   queens:qperm/2-0 s1;
     131:     37  8 CALL NON   queens:qdelete/3-0 
     132:     37  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     133:     37  8 EXIT NON   queens:qdelete/3-0 
     134:     38  8 CALL NON   queens:qperm/2-0 
     135:     38  8 SWTC NON   queens:qperm/2-0 s2;
     136:     38  8 EXIT NON   queens:qperm/2-0 
     137:     36  7 EXIT NON   queens:qperm/2-0 
     138:     27  6 EXIT NON   queens:qperm/2-0 
     139:      8  5 EXIT NON   queens:qperm/2-0 
     140:      6  4 EXIT NON   queens:qperm/2-0 
     141:      4  3 EXIT NON   queens:qperm/2-0 
     142:     39  3 CALL SEMI  queens:safe/1-0 
     143:     39  3 SWTC SEMI  queens:safe/1-0 s1;
     144:     40  4 CALL SEMI  queens:nodiag/3-0 
     145:     40  4 SWTC SEMI  queens:nodiag/3-0 s1;
     146:     40  4 THEN SEMI  queens:nodiag/3-0 s1;c4;t;
     147:     40  4 FAIL SEMI  queens:nodiag/3-0 
     148:     39  3 FAIL SEMI  queens:safe/1-0 
     149:     38  8 FAIL NON   queens:qperm/2-0 
     150:     37  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     151:     41  9 CALL NON   queens:qdelete/3-0 
     152:     41  9 FAIL NON   queens:qdelete/3-0 
     153:     37  8 FAIL NON   queens:qdelete/3-0 
     154:     36  7 FAIL NON   queens:qperm/2-0 
     155:     35  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     156:     42  9 CALL NON   queens:qdelete/3-0 
     157:     42  9 FAIL NON   queens:qdelete/3-0 
     158:     35  8 FAIL NON   queens:qdelete/3-0 
     159:     28  7 FAIL NON   queens:qdelete/3-0 
     160:     27  6 FAIL NON   queens:qperm/2-0 
     161:     26  7 DISJ NON   queens:qdelete/3-0 c2;d2;
     162:     43  8 CALL NON   queens:qdelete/3-0 
     163:     43  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     164:     43  8 EXIT NON   queens:qdelete/3-0 
     165:     26  7 EXIT NON   queens:qdelete/3-0 
     166:      9  6 EXIT NON   queens:qdelete/3-0 
     167:     44  6 CALL NON   queens:qperm/2-0 
     168:     44  6 SWTC NON   queens:qperm/2-0 s1;
     169:     45  7 CALL NON   queens:qdelete/3-0 
     170:     45  7 DISJ NON   queens:qdelete/3-0 c2;d1;
     171:     45  7 EXIT NON   queens:qdelete/3-0 
     172:     46  7 CALL NON   queens:qperm/2-0 
     173:     46  7 SWTC NON   queens:qperm/2-0 s1;
     174:     47  8 CALL NON   queens:qdelete/3-0 
     175:     47  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     176:     47  8 EXIT NON   queens:qdelete/3-0 
     177:     48  8 CALL NON   queens:qperm/2-0 
     178:     48  8 SWTC NON   queens:qperm/2-0 s2;
     179:     48  8 EXIT NON   queens:qperm/2-0 
     180:     46  7 EXIT NON   queens:qperm/2-0 
     181:     44  6 EXIT NON   queens:qperm/2-0 
     182:      8  5 EXIT NON   queens:qperm/2-0 
     183:      6  4 EXIT NON   queens:qperm/2-0 
     184:      4  3 EXIT NON   queens:qperm/2-0 
     185:     49  3 CALL SEMI  queens:safe/1-0 
     186:     49  3 SWTC SEMI  queens:safe/1-0 s1;
     187:     50  4 CALL SEMI  queens:nodiag/3-0 
     188:     50  4 SWTC SEMI  queens:nodiag/3-0 s1;
     189:     50  4 THEN SEMI  queens:nodiag/3-0 s1;c4;t;
     190:     50  4 FAIL SEMI  queens:nodiag/3-0 
     191:     49  3 FAIL SEMI  queens:safe/1-0 
     192:     48  8 FAIL NON   queens:qperm/2-0 
     193:     47  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     194:     51  9 CALL NON   queens:qdelete/3-0 
     195:     51  9 FAIL NON   queens:qdelete/3-0 
     196:     47  8 FAIL NON   queens:qdelete/3-0 
     197:     46  7 FAIL NON   queens:qperm/2-0 
     198:     45  7 DISJ NON   queens:qdelete/3-0 c2;d2;
     199:     52  8 CALL NON   queens:qdelete/3-0 
     200:     52  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     201:     52  8 EXIT NON   queens:qdelete/3-0 
     202:     45  7 EXIT NON   queens:qdelete/3-0 
     203:     53  7 CALL NON   queens:qperm/2-0 
     204:     53  7 SWTC NON   queens:qperm/2-0 s1;
     205:     54  8 CALL NON   queens:qdelete/3-0 
     206:     54  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     207:     54  8 EXIT NON   queens:qdelete/3-0 
     208:     55  8 CALL NON   queens:qperm/2-0 
     209:     55  8 SWTC NON   queens:qperm/2-0 s2;
     210:     55  8 EXIT NON   queens:qperm/2-0 
     211:     53  7 EXIT NON   queens:qperm/2-0 
     212:     44  6 EXIT NON   queens:qperm/2-0 
     213:      8  5 EXIT NON   queens:qperm/2-0 
     214:      6  4 EXIT NON   queens:qperm/2-0 
     215:      4  3 EXIT NON   queens:qperm/2-0 
     216:     56  3 CALL SEMI  queens:safe/1-0 
     217:     56  3 SWTC SEMI  queens:safe/1-0 s1;
     218:     57  4 CALL SEMI  queens:nodiag/3-0 
     219:     57  4 SWTC SEMI  queens:nodiag/3-0 s1;
     220:     57  4 THEN SEMI  queens:nodiag/3-0 s1;c4;t;
     221:     57  4 FAIL SEMI  queens:nodiag/3-0 
     222:     56  3 FAIL SEMI  queens:safe/1-0 
     223:     55  8 FAIL NON   queens:qperm/2-0 
     224:     54  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     225:     58  9 CALL NON   queens:qdelete/3-0 
     226:     58  9 FAIL NON   queens:qdelete/3-0 
     227:     54  8 FAIL NON   queens:qdelete/3-0 
     228:     53  7 FAIL NON   queens:qperm/2-0 
     229:     52  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     230:     59  9 CALL NON   queens:qdelete/3-0 
     231:     59  9 FAIL NON   queens:qdelete/3-0 
     232:     52  8 FAIL NON   queens:qdelete/3-0 
     233:     45  7 FAIL NON   queens:qdelete/3-0 
     234:     44  6 FAIL NON   queens:qperm/2-0 
     235:     43  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     236:     60  9 CALL NON   queens:qdelete/3-0 
     237:     60  9 FAIL NON   queens:qdelete/3-0 
     238:     43  8 FAIL NON   queens:qdelete/3-0 
     239:     26  7 FAIL NON   queens:qdelete/3-0 
     240:      9  6 FAIL NON   queens:qdelete/3-0 
     241:      8  5 FAIL NON   queens:qperm/2-0 
     242:      7  5 DISJ NON   queens:qdelete/3-0 c2;d2;
     243:     61  6 CALL NON   queens:qdelete/3-0 
     244:     61  6 DISJ NON   queens:qdelete/3-0 c2;d1;
     245:     61  6 EXIT NON   queens:qdelete/3-0 
     246:      7  5 EXIT NON   queens:qdelete/3-0 
     247:     62  5 CALL NON   queens:qperm/2-0 
     248:     62  5 SWTC NON   queens:qperm/2-0 s1;
     249:     63  6 CALL NON   queens:qdelete/3-0 
     250:     63  6 DISJ NON   queens:qdelete/3-0 c2;d1;
     251:     63  6 EXIT NON   queens:qdelete/3-0 
     252:     64  6 CALL NON   queens:qperm/2-0 
     253:     64  6 SWTC NON   queens:qperm/2-0 s1;
     254:     65  7 CALL NON   queens:qdelete/3-0 
     255:     65  7 DISJ NON   queens:qdelete/3-0 c2;d1;
     256:     65  7 EXIT NON   queens:qdelete/3-0 
     257:     66  7 CALL NON   queens:qperm/2-0 
     258:     66  7 SWTC NON   queens:qperm/2-0 s1;
     259:     67  8 CALL NON   queens:qdelete/3-0 
     260:     67  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     261:     67  8 EXIT NON   queens:qdelete/3-0 
     262:     68  8 CALL NON   queens:qperm/2-0 
     263:     68  8 SWTC NON   queens:qperm/2-0 s2;
     264:     68  8 EXIT NON   queens:qperm/2-0 
     265:     66  7 EXIT NON   queens:qperm/2-0 
     266:     64  6 EXIT NON   queens:qperm/2-0 
     267:     62  5 EXIT NON   queens:qperm/2-0 
     268:      6  4 EXIT NON   queens:qperm/2-0 
     269:      4  3 EXIT NON   queens:qperm/2-0 
     270:     69  3 CALL SEMI  queens:safe/1-0 
     271:     69  3 SWTC SEMI  queens:safe/1-0 s1;
     272:     70  4 CALL SEMI  queens:nodiag/3-0 
     273:     70  4 SWTC SEMI  queens:nodiag/3-0 s1;
     274:     70  4 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     275:     70  4 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     276:     71  5 CALL SEMI  queens:nodiag/3-0 
     277:     71  5 SWTC SEMI  queens:nodiag/3-0 s1;
     278:     71  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     279:     71  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     280:     72  6 CALL SEMI  queens:nodiag/3-0 
     281:     72  6 SWTC SEMI  queens:nodiag/3-0 s1;
     282:     72  6 THEN SEMI  queens:nodiag/3-0 s1;c4;t;
     283:     72  6 FAIL SEMI  queens:nodiag/3-0 
     284:     71  5 FAIL SEMI  queens:nodiag/3-0 
     285:     70  4 FAIL SEMI  queens:nodiag/3-0 
     286:     69  3 FAIL SEMI  queens:safe/1-0 
     287:     68  8 FAIL NON   queens:qperm/2-0 
     288:     67  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     289:     73  9 CALL NON   queens:qdelete/3-0 
     290:     73  9 FAIL NON   queens:qdelete/3-0 
     291:     67  8 FAIL NON   queens:qdelete/3-0 
     292:     66  7 FAIL NON   queens:qperm/2-0 
     293:     65  7 DISJ NON   queens:qdelete/3-0 c2;d2;
     294:     74  8 CALL NON   queens:qdelete/3-0 
     295:     74  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     296:     74  8 EXIT NON   queens:qdelete/3-0 
     297:     65  7 EXIT NON   queens:qdelete/3-0 
     298:     75  7 CALL NON   queens:qperm/2-0 
     299:     75  7 SWTC NON   queens:qperm/2-0 s1;
     300:     76  8 CALL NON   queens:qdelete/3-0 
     301:     76  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     302:     76  8 EXIT NON   queens:qdelete/3-0 
     303:     77  8 CALL NON   queens:qperm/2-0 
     304:     77  8 SWTC NON   queens:qperm/2-0 s2;
     305:     77  8 EXIT NON   queens:qperm/2-0 
     306:     75  7 EXIT NON   queens:qperm/2-0 
     307:     64  6 EXIT NON   queens:qperm/2-0 
     308:     62  5 EXIT NON   queens:qperm/2-0 
     309:      6  4 EXIT NON   queens:qperm/2-0 
     310:      4  3 EXIT NON   queens:qperm/2-0 
     311:     78  3 CALL SEMI  queens:safe/1-0 
     312:     78  3 SWTC SEMI  queens:safe/1-0 s1;
     313:     79  4 CALL SEMI  queens:nodiag/3-0 
     314:     79  4 SWTC SEMI  queens:nodiag/3-0 s1;
     315:     79  4 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     316:     79  4 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     317:     80  5 CALL SEMI  queens:nodiag/3-0 
     318:     80  5 SWTC SEMI  queens:nodiag/3-0 s1;
     319:     80  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     320:     80  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     321:     81  6 CALL SEMI  queens:nodiag/3-0 
     322:     81  6 SWTC SEMI  queens:nodiag/3-0 s1;
     323:     81  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     324:     81  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     325:     82  7 CALL SEMI  queens:nodiag/3-0 
     326:     82  7 SWTC SEMI  queens:nodiag/3-0 s1;
     327:     82  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     328:     82  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     329:     83  8 CALL SEMI  queens:nodiag/3-0 
     330:     83  8 SWTC SEMI  queens:nodiag/3-0 s2;
     331:     83  8 EXIT SEMI  queens:nodiag/3-0 
     332:     82  7 EXIT SEMI  queens:nodiag/3-0 
     333:     81  6 EXIT SEMI  queens:nodiag/3-0 
     334:     80  5 EXIT SEMI  queens:nodiag/3-0 
     335:     79  4 EXIT SEMI  queens:nodiag/3-0 
     336:     84  4 CALL SEMI  queens:safe/1-0 
     337:     84  4 SWTC SEMI  queens:safe/1-0 s1;
     338:     85  5 CALL SEMI  queens:nodiag/3-0 
     339:     85  5 SWTC SEMI  queens:nodiag/3-0 s1;
     340:     85  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     341:     85  5 THEN SEMI  queens:nodiag/3-0 s1;c4;e;t;
     342:     85  5 FAIL SEMI  queens:nodiag/3-0 
     343:     84  4 FAIL SEMI  queens:safe/1-0 
     344:     78  3 FAIL SEMI  queens:safe/1-0 
     345:     77  8 FAIL NON   queens:qperm/2-0 
     346:     76  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     347:     86  9 CALL NON   queens:qdelete/3-0 
     348:     86  9 FAIL NON   queens:qdelete/3-0 
     349:     76  8 FAIL NON   queens:qdelete/3-0 
     350:     75  7 FAIL NON   queens:qperm/2-0 
     351:     74  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     352:     87  9 CALL NON   queens:qdelete/3-0 
     353:     87  9 FAIL NON   queens:qdelete/3-0 
     354:     74  8 FAIL NON   queens:qdelete/3-0 
     355:     65  7 FAIL NON   queens:qdelete/3-0 
     356:     64  6 FAIL NON   queens:qperm/2-0 
     357:     63  6 DISJ NON   queens:qdelete/3-0 c2;d2;
     358:     88  7 CALL NON   queens:qdelete/3-0 
     359:     88  7 DISJ NON   queens:qdelete/3-0 c2;d1;
     360:     88  7 EXIT NON   queens:qdelete/3-0 
     361:     63  6 EXIT NON   queens:qdelete/3-0 
     362:     89  6 CALL NON   queens:qperm/2-0 
     363:     89  6 SWTC NON   queens:qperm/2-0 s1;
     364:     90  7 CALL NON   queens:qdelete/3-0 
     365:     90  7 DISJ NON   queens:qdelete/3-0 c2;d1;
     366:     90  7 EXIT NON   queens:qdelete/3-0 
     367:     91  7 CALL NON   queens:qperm/2-0 
     368:     91  7 SWTC NON   queens:qperm/2-0 s1;
     369:     92  8 CALL NON   queens:qdelete/3-0 
     370:     92  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     371:     92  8 EXIT NON   queens:qdelete/3-0 
     372:     93  8 CALL NON   queens:qperm/2-0 
     373:     93  8 SWTC NON   queens:qperm/2-0 s2;
     374:     93  8 EXIT NON   queens:qperm/2-0 
     375:     91  7 EXIT NON   queens:qperm/2-0 
     376:     89  6 EXIT NON   queens:qperm/2-0 
     377:     62  5 EXIT NON   queens:qperm/2-0 
     378:      6  4 EXIT NON   queens:qperm/2-0 
     379:      4  3 EXIT NON   queens:qperm/2-0 
     380:     94  3 CALL SEMI  queens:safe/1-0 
     381:     94  3 SWTC SEMI  queens:safe/1-0 s1;
     382:     95  4 CALL SEMI  queens:nodiag/3-0 
     383:     95  4 SWTC SEMI  queens:nodiag/3-0 s1;
     384:     95  4 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     385:     95  4 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     386:     96  5 CALL SEMI  queens:nodiag/3-0 
     387:     96  5 SWTC SEMI  queens:nodiag/3-0 s1;
     388:     96  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     389:     96  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     390:     97  6 CALL SEMI  queens:nodiag/3-0 
     391:     97  6 SWTC SEMI  queens:nodiag/3-0 s1;
     392:     97  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     393:     97  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     394:     98  7 CALL SEMI  queens:nodiag/3-0 
     395:     98  7 SWTC SEMI  queens:nodiag/3-0 s1;
     396:     98  7 THEN SEMI  queens:nodiag/3-0 s1;c4;t;
     397:     98  7 FAIL SEMI  queens:nodiag/3-0 
     398:     97  6 FAIL SEMI  queens:nodiag/3-0 
     399:     96  5 FAIL SEMI  queens:nodiag/3-0 
     400:     95  4 FAIL SEMI  queens:nodiag/3-0 
     401:     94  3 FAIL SEMI  queens:safe/1-0 
     402:     93  8 FAIL NON   queens:qperm/2-0 
     403:     92  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     404:     99  9 CALL NON   queens:qdelete/3-0 
     405:     99  9 FAIL NON   queens:qdelete/3-0 
     406:     92  8 FAIL NON   queens:qdelete/3-0 
     407:     91  7 FAIL NON   queens:qperm/2-0 
     408:     90  7 DISJ NON   queens:qdelete/3-0 c2;d2;
     409:    100  8 CALL NON   queens:qdelete/3-0 
     410:    100  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     411:    100  8 EXIT NON   queens:qdelete/3-0 
     412:     90  7 EXIT NON   queens:qdelete/3-0 
     413:    101  7 CALL NON   queens:qperm/2-0 
     414:    101  7 SWTC NON   queens:qperm/2-0 s1;
     415:    102  8 CALL NON   queens:qdelete/3-0 
     416:    102  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     417:    102  8 EXIT NON   queens:qdelete/3-0 
     418:    103  8 CALL NON   queens:qperm/2-0 
     419:    103  8 SWTC NON   queens:qperm/2-0 s2;
     420:    103  8 EXIT NON   queens:qperm/2-0 
     421:    101  7 EXIT NON   queens:qperm/2-0 
     422:     89  6 EXIT NON   queens:qperm/2-0 
     423:     62  5 EXIT NON   queens:qperm/2-0 
     424:      6  4 EXIT NON   queens:qperm/2-0 
     425:      4  3 EXIT NON   queens:qperm/2-0 
     426:    104  3 CALL SEMI  queens:safe/1-0 
     427:    104  3 SWTC SEMI  queens:safe/1-0 s1;
     428:    105  4 CALL SEMI  queens:nodiag/3-0 
     429:    105  4 SWTC SEMI  queens:nodiag/3-0 s1;
     430:    105  4 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     431:    105  4 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     432:    106  5 CALL SEMI  queens:nodiag/3-0 
     433:    106  5 SWTC SEMI  queens:nodiag/3-0 s1;
     434:    106  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     435:    106  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     436:    107  6 CALL SEMI  queens:nodiag/3-0 
     437:    107  6 SWTC SEMI  queens:nodiag/3-0 s1;
     438:    107  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     439:    107  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     440:    108  7 CALL SEMI  queens:nodiag/3-0 
     441:    108  7 SWTC SEMI  queens:nodiag/3-0 s1;
     442:    108  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     443:    108  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     444:    109  8 CALL SEMI  queens:nodiag/3-0 
     445:    109  8 SWTC SEMI  queens:nodiag/3-0 s2;
     446:    109  8 EXIT SEMI  queens:nodiag/3-0 
     447:    108  7 EXIT SEMI  queens:nodiag/3-0 
     448:    107  6 EXIT SEMI  queens:nodiag/3-0 
     449:    106  5 EXIT SEMI  queens:nodiag/3-0 
     450:    105  4 EXIT SEMI  queens:nodiag/3-0 
     451:    110  4 CALL SEMI  queens:safe/1-0 
     452:    110  4 SWTC SEMI  queens:safe/1-0 s1;
     453:    111  5 CALL SEMI  queens:nodiag/3-0 
     454:    111  5 SWTC SEMI  queens:nodiag/3-0 s1;
     455:    111  5 THEN SEMI  queens:nodiag/3-0 s1;c4;t;
     456:    111  5 FAIL SEMI  queens:nodiag/3-0 
     457:    110  4 FAIL SEMI  queens:safe/1-0 
     458:    104  3 FAIL SEMI  queens:safe/1-0 
     459:    103  8 FAIL NON   queens:qperm/2-0 
     460:    102  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     461:    112  9 CALL NON   queens:qdelete/3-0 
     462:    112  9 FAIL NON   queens:qdelete/3-0 
     463:    102  8 FAIL NON   queens:qdelete/3-0 
     464:    101  7 FAIL NON   queens:qperm/2-0 
     465:    100  8 DISJ NON   queens:qdelete/3-0 c2;d2;
     466:    113  9 CALL NON   queens:qdelete/3-0 
     467:    113  9 FAIL NON   queens:qdelete/3-0 
     468:    100  8 FAIL NON   queens:qdelete/3-0 
     469:     90  7 FAIL NON   queens:qdelete/3-0 
     470:     89  6 FAIL NON   queens:qperm/2-0 
     471:     88  7 DISJ NON   queens:qdelete/3-0 c2;d2;
     472:    114  8 CALL NON   queens:qdelete/3-0 
     473:    114  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     474:    114  8 EXIT NON   queens:qdelete/3-0 
     475:     88  7 EXIT NON   queens:qdelete/3-0 
     476:     63  6 EXIT NON   queens:qdelete/3-0 
     477:    115  6 CALL NON   queens:qperm/2-0 
     478:    115  6 SWTC NON   queens:qperm/2-0 s1;
     479:    116  7 CALL NON   queens:qdelete/3-0 
     480:    116  7 DISJ NON   queens:qdelete/3-0 c2;d1;
     481:    116  7 EXIT NON   queens:qdelete/3-0 
     482:    117  7 CALL NON   queens:qperm/2-0 
     483:    117  7 SWTC NON   queens:qperm/2-0 s1;
     484:    118  8 CALL NON   queens:qdelete/3-0 
     485:    118  8 DISJ NON   queens:qdelete/3-0 c2;d1;
     486:    118  8 EXIT NON   queens:qdelete/3-0 
     487:    119  8 CALL NON   queens:qperm/2-0 
     488:    119  8 SWTC NON   queens:qperm/2-0 s2;
     489:    119  8 EXIT NON   queens:qperm/2-0 
     490:    117  7 EXIT NON   queens:qperm/2-0 
     491:    115  6 EXIT NON   queens:qperm/2-0 
     492:     62  5 EXIT NON   queens:qperm/2-0 
     493:      6  4 EXIT NON   queens:qperm/2-0 
     494:      4  3 EXIT NON   queens:qperm/2-0 
     495:    120  3 CALL SEMI  queens:safe/1-0 
     496:    120  3 SWTC SEMI  queens:safe/1-0 s1;
     497:    121  4 CALL SEMI  queens:nodiag/3-0 
     498:    121  4 SWTC SEMI  queens:nodiag/3-0 s1;
     499:    121  4 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     500:    121  4 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     501:    122  5 CALL SEMI  queens:nodiag/3-0 
     502:    122  5 SWTC SEMI  queens:nodiag/3-0 s1;
     503:    122  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     504:    122  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     505:    123  6 CALL SEMI  queens:nodiag/3-0 
     506:    123  6 SWTC SEMI  queens:nodiag/3-0 s1;
     507:    123  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     508:    123  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     509:    124  7 CALL SEMI  queens:nodiag/3-0 
     510:    124  7 SWTC SEMI  queens:nodiag/3-0 s1;
     511:    124  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     512:    124  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     513:    125  8 CALL SEMI  queens:nodiag/3-0 
     514:    125  8 SWTC SEMI  queens:nodiag/3-0 s2;
     515:    125  8 EXIT SEMI  queens:nodiag/3-0 
     516:    124  7 EXIT SEMI  queens:nodiag/3-0 
     517:    123  6 EXIT SEMI  queens:nodiag/3-0 
     518:    122  5 EXIT SEMI  queens:nodiag/3-0 
     519:    121  4 EXIT SEMI  queens:nodiag/3-0 
     520:    126  4 CALL SEMI  queens:safe/1-0 
     521:    126  4 SWTC SEMI  queens:safe/1-0 s1;
     522:    127  5 CALL SEMI  queens:nodiag/3-0 
     523:    127  5 SWTC SEMI  queens:nodiag/3-0 s1;
     524:    127  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     525:    127  5 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     526:    128  6 CALL SEMI  queens:nodiag/3-0 
     527:    128  6 SWTC SEMI  queens:nodiag/3-0 s1;
     528:    128  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     529:    128  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     530:    129  7 CALL SEMI  queens:nodiag/3-0 
     531:    129  7 SWTC SEMI  queens:nodiag/3-0 s1;
     532:    129  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     533:    129  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     534:    130  8 CALL SEMI  queens:nodiag/3-0 
     535:    130  8 SWTC SEMI  queens:nodiag/3-0 s2;
     536:    130  8 EXIT SEMI  queens:nodiag/3-0 
     537:    129  7 EXIT SEMI  queens:nodiag/3-0 
     538:    128  6 EXIT SEMI  queens:nodiag/3-0 
     539:    127  5 EXIT SEMI  queens:nodiag/3-0 
     540:    131  5 CALL SEMI  queens:safe/1-0 
     541:    131  5 SWTC SEMI  queens:safe/1-0 s1;
     542:    132  6 CALL SEMI  queens:nodiag/3-0 
     543:    132  6 SWTC SEMI  queens:nodiag/3-0 s1;
     544:    132  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     545:    132  6 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     546:    133  7 CALL SEMI  queens:nodiag/3-0 
     547:    133  7 SWTC SEMI  queens:nodiag/3-0 s1;
     548:    133  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     549:    133  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     550:    134  8 CALL SEMI  queens:nodiag/3-0 
     551:    134  8 SWTC SEMI  queens:nodiag/3-0 s2;
     552:    134  8 EXIT SEMI  queens:nodiag/3-0 
     553:    133  7 EXIT SEMI  queens:nodiag/3-0 
     554:    132  6 EXIT SEMI  queens:nodiag/3-0 
     555:    135  6 CALL SEMI  queens:safe/1-0 
     556:    135  6 SWTC SEMI  queens:safe/1-0 s1;
     557:    136  7 CALL SEMI  queens:nodiag/3-0 
     558:    136  7 SWTC SEMI  queens:nodiag/3-0 s1;
     559:    136  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;
     560:    136  7 ELSE SEMI  queens:nodiag/3-0 s1;c4;e;e;
     561:    137  8 CALL SEMI  queens:nodiag/3-0 
     562:    137  8 SWTC SEMI  queens:nodiag/3-0 s2;
     563:    137  8 EXIT SEMI  queens:nodiag/3-0 
     564:    136  7 EXIT SEMI  queens:nodiag/3-0 
     565:    138  7 CALL SEMI  queens:safe/1-0 
     566:    138  7 SWTC SEMI  queens:safe/1-0 s1;
     567:    139  8 CALL SEMI  queens:nodiag/3-0 
     568:    139  8 SWTC SEMI  queens:nodiag/3-0 s2;
     569:    139  8 EXIT SEMI  queens:nodiag/3-0 
     570:    140  8 CALL SEMI  queens:safe/1-0 
     571:    140  8 SWTC SEMI  queens:safe/1-0 s2;
     572:    140  8 EXIT SEMI  queens:safe/1-0 
     573:    138  7 EXIT SEMI  queens:safe/1-0 
     574:    135  6 EXIT SEMI  queens:safe/1-0 
     575:    131  5 EXIT SEMI  queens:safe/1-0 
     576:    126  4 EXIT SEMI  queens:safe/1-0 
     577:    120  3 EXIT SEMI  queens:safe/1-0 
     578:      3  2 EXIT NON   queens:queen/2-0 
     579:      1  1 THEN CCMUL queens:main/2-0 t;
     580:    141  2 CALL DET   queens:print_list/3-0 
     581:    141  2 ELSE DET   queens:print_list/3-0 e;
[     582:    142  3 CALL DET   queens:print_list_2/3-0 
     583:    142  3 SWTC DET   queens:print_list_2/3-0 s1;
1     584:    142  3 ELSE DET   queens:print_list_2/3-0 s1;c3;e;
,      585:    143  4 CALL DET   queens:print_list_2/3-0 
     586:    143  4 SWTC DET   queens:print_list_2/3-0 s1;
3     587:    143  4 ELSE DET   queens:print_list_2/3-0 s1;c3;e;
,      588:    144  5 CALL DET   queens:print_list_2/3-0 
     589:    144  5 SWTC DET   queens:print_list_2/3-0 s1;
5     590:    144  5 ELSE DET   queens:print_list_2/3-0 s1;c3;e;
,      591:    145  6 CALL DET   queens:print_list_2/3-0 
     592:    145  6 SWTC DET   queens:print_list_2/3-0 s1;
2     593:    145  6 ELSE DET   queens:print_list_2/3-0 s1;c3;e;
,      594:    146  7 CALL DET   queens:print_list_2/3-0 
     595:    146  7 SWTC DET   queens:print_list_2/3-0 s1;
4     596:    146  7 THEN DET   queens:print_list_2/3-0 s1;c3;t;
     597:    146  7 EXIT DET   queens:print_list_2/3-0 
     598:    145  6 EXIT DET   queens:print_list_2/3-0 
     599:    144  5 EXIT DET   queens:print_list_2/3-0 
     600:    143  4 EXIT DET   queens:print_list_2/3-0 
     601:    142  3 EXIT DET   queens:print_list_2/3-0 
]
     602:    141  2 EXIT DET   queens:print_list/3-0 
     603:      1  1 EXIT CCMUL queens:main/2-0 

New File: tests/debugger/queens.inp
===================================================================
p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p

p
C

New File: tests/debugger/queens.m
===================================================================
:- module queens.

:- interface.

:- import_module io.

:- pred main(io__state, io__state).
:- mode main(di, uo) is cc_multi.

:- implementation.

:- import_module list, int.

main -->
	( { data(Data), queen(Data, Out) } ->
		print_list(Out)
	;
		io__write_string("No solution\n")
	).

:- pred data(list(int)).
:- mode data(out) is det.

:- pred queen(list(int), list(int)).
:- mode queen(in, out) is nondet.

:- pred qperm(list(T), list(T)).
:- mode qperm(in, out) is nondet.

:- pred qdelete(T, list(T), list(T)).
:- mode qdelete(out, in, out) is nondet.

:- pred safe(list(int)).
:- mode safe(in) is semidet.

:- pred nodiag(int, int, list(int)).
:- mode nodiag(in, in, in) is semidet.

data([1,2,3,4,5]).

queen(Data, Out) :-
	qperm(Data, Out),
	safe(Out).

qperm([], []).
qperm([X|Y], K) :-
	qdelete(U, [X|Y], Z),
	K = [U|V],
	qperm(Z, V).

qdelete(A, [A|L], L).
qdelete(X, [A|Z], [A|R]) :-
	qdelete(X, Z, R).

safe([]).
safe([N|L]) :-
	nodiag(N, 1, L),
	safe(L).

nodiag(_, _, []).
nodiag(B, D, [N|L]) :-
	NmB is N - B,
	BmN is B - N,
	( D = NmB ->
		fail
	; D = BmN ->
		fail
	;
		true
	),
	D1 is D + 1,
	nodiag(B, D1, L).

:- pred print_list(list(int), io__state, io__state).
:- mode print_list(in, di, uo) is det.

print_list(Xs) -->
	(
		{ Xs = [] }
	->
		io__write_string("[]\n")
	;
		io__write_string("["),
		print_list_2(Xs),
		io__write_string("]\n")
	).

:- pred print_list_2(list(int), io__state, io__state).
:- mode print_list_2(in, di, uo) is det.

print_list_2([]) --> [].
print_list_2([X|Xs]) --> 
	io__write_int(X),
	(
		{ Xs = [] }
	->
		[]
	;
		io__write_string(", "),
		print_list_2(Xs)
	).

New File: tests/debugger/runtests
===================================================================
#!/bin/sh
# Test whether the code generated by the Mercury compiler
# is producing the expected output.
# Return a status of 0 (true) if everything is all right, and 1 otherwise.

. ../handle_options

mmake $jfactor clean > /dev/null 2>&1
mmake $jfactor depend || exit 1
eval mmake -k $jfactor $gradeopt $flagsopt $cflagsopt check
checkstatus=$?

cat *.res > .allres
if test ! -s .allres -a "$checkstatus" = 0
then
	echo "the tests in the debugger directory succeeded"
	rm -f .allres
	exit 0
else
	echo "the tests in the debugger directory failed"
	echo "the differences are:"
	cat .allres
	exit 1
fi




More information about the developers mailing list