for review: new method of handling failures, part 7 of 6 :-(

Zoltan Somogyi zs at cs.mu.OZ.AU
Thu Jul 2 16:26:52 AEST 1998


Index: compiler/notes/failure.html
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/notes/failure.html,v
retrieving revision 1.2
diff -u -r1.2 failure.html
--- failure.html	1997/11/05 08:22:26	1.2
+++ failure.html	1998/07/01 12:13:49
@@ -55,7 +55,7 @@
 <ul>
 <li>	succip, the label to go to on success
 <li>	succfr, the value to reset curfr to on success (frame of our caller)
-<li>	redoip, the label to go when backtracking reaches this frame
+<li>	redoip, the label to go to when backtracking reaches this frame
 <li>	prevfr, the address of the previous frame on the nondet stack
 </ul>
 
@@ -407,12 +407,8 @@
 After the code generator emerges from the condition,
 it pops the new entry off the resume point stack.
 Before entry to the then part or to the else part,
-it resets the redoip slot of the frame it hijacked to its saved value.
-Since maxfr may have been changed by the condition pushing new frames,
-the address of the frame in which the restoration is to be performed
-is given by curfr
-(although on entry to the else part maxfr will be equal to its value
-on entry to the if-then-else, which was equal to curfr).
+it resets the redoip slot of the frame it hijacked (pointed to by curfr)
+to its saved value.
 
 <p>
 
@@ -447,14 +443,27 @@
 If the condition may perform a hijacking
 (i.e. if it contains a nondet disjunction, nondet if-then-else
 or a commit across a nondet -as opposed to multi- goal),
-the hijacking we do for the if-then-else may overwrite the same slots
-used by the hijacking inside the condition.
-We avoid this by pushing a junk frame whose redoip slot is do_fail
-before generating code for the condition;
+the hijacking we do for the soft cut of the if-then-else
+may overwrite the same slots used by the hijacking inside the condition.
+We avoid this by pushing a temporary frame onto the nondet stack
+just before entering the condition;
 any hijacks inside the condition will hijack the slots of this frame.
+The temporary frame has only the prevfr, redoip and redofr slots;
+the redoip slot is initialized to do_fail and the redofr slot to curfr.
 The presence of this frame on top of ours then requires us
 to set curfr_is_maxfr to no before entering the condition.
 
+<p>
+
+Before entering the condition, the code generator will set resume_point_known
+to yes, since the resumption point to go to on failure of the condition is
+known (it is the start of the else part). However, this resumption point
+does not apply to failures in the then part. Therefore before entering the
+then part, the code generator will reset resume_point_known to the value
+it had before entering the if-then-else, except if resume_point_known
+has become no during the generation of code for the condition, in which
+case it will continue to be no.
+
 <h3> Handling nondet if-then-elses with semi or det conditions </h3>
 
 We can handle these as we handle nondet if-then-elses with nondet conditions,
@@ -482,29 +491,29 @@
 <ul>
 <li> Best case.
 Before the code generator enters a goal that is being committed across,
-it saves the value of maxfr,
-pushes a new entry on the resume point stack indicating
+it pushes a new entry on the resume point stack indicating
 the resume point for getting control back if the goal has no solutions
 and sets the redoip slot of the top frame (which is this frame)
 to the stack continuation in that resume point.
 The code at this resume point will perform a failure in the manner
-appropriate for whatever entry was originally on top of the resume point stack
-(There is no need to reset maxfr, since the resume point can only be reached
-if all other frames above the one hijacked have failed.)
+appropriate for whatever entry was originally on top of the resume point stack.
 The code after the goal in the success continuation
-will reset maxfr to the saved value.
+will reset maxfr to the value it had originally, which is in curfr.
+Both continuations will reset the redoip slot of the current frame
+to its original value,
+which is the address of the stack label
+in the originally top failure continuation.
 
 <p>
 
 <li> Middle case.
 Before the code generator enters a goal that is being committed across,
-it saves the value of maxfr,
-pushes a new entry on the resume point stack indicating
-the resume point for getting control back if the goal has no solutions
-saves the value of the redoip slot of the top frame (which is this frame).
+it pushes a new entry on the resume point stack indicating
+the resume point for getting control back if the goal has no solutions,
+saves the value of the redoip slot of the top frame (which is this frame)
 and overrides this redoip slot to make it point
 to the stack continuation in the resume point.
-The success continuation will reset maxfr;
+The success continuation will reset maxfr to curfr;
 the failure continuation doesn't have to
 (since the resume point can only be reached
 if all other frames above the one hijacked have failed.)
@@ -561,15 +570,22 @@
 
 <h3> Handling commits across multi goals </h3>
 
+<ul>
+<li>
+If curfr_is_maxfr is yes.
+The code after the goal will reset maxfr to curfr.
+<li>
+If curfr_is_maxfr is no.
 Before the code generator enters a goal that is being committed across,
 it saves the value of maxfr in a stack slot.
 The code after the goal will reset maxfr to the saved value.
+</ul>
 
 <p>
 
-This is the way the code generator handles commits across nondet goals
-except that we do not need to handle failure, and thus do not need to
-set any redoips or hijack anything.
+This is the way the code generator handles commits across nondet goals except
+that we do not need to handle failure of the goal being committed across,
+and thus do not need to set any redoips or hijack anything.
 
 <p>
 
Index: runtime/mercury_engine.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_engine.c,v
retrieving revision 1.9
diff -u -r1.9 mercury_engine.c
--- mercury_engine.c	1998/06/18 04:30:42	1.9
+++ mercury_engine.c	1998/06/30 08:17:57
@@ -8,6 +8,7 @@
 ** Public License - see the file COPYING.LIB in the Mercury distribution.
 */
 
+#define		MR_STACK_TRACE_THIS_MODULE
 #include	"mercury_imp.h"
 
 #include	<stdio.h>
Index: runtime/mercury_grade.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_grade.h,v
retrieving revision 1.9
diff -u -r1.9 mercury_grade.h
--- mercury_grade.h	1998/06/09 02:07:58	1.9
+++ mercury_grade.h	1998/07/01 08:52:50
@@ -31,11 +31,11 @@
 #define MR_PASTE2(p1,p2)	MR_PASTE2_2(p1,p2)
 #define MR_PASTE2_2(p1,p2)	p1##p2
 
-/* paste 12 macros together */
-#define MR_PASTE12(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12) \
-			MR_PASTE12_2(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12)
-#define MR_PASTE12_2(p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12) \
-			p1##p2##p3##p4##p5##p6##p7##p8##p9##p10##p11##p12
+/* paste 13 macros together */
+#define MR_PASTE13(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12) \
+			MR_PASTE13_2(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12)
+#define MR_PASTE13_2(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12) \
+			p0##p1##p2##p3##p4##p5##p6##p7##p8##p9##p10##p11##p12
 
 /*
 ** Here we build up the MR_GRADE macro part at a time,
@@ -45,6 +45,12 @@
 ** changes to compiler/handle_options.m and scripts/mgnuc.in.
 */
 
+#ifdef MR_USE_REDOFR
+  #define MR_GRADE_PART_0	redofr_
+#else
+  #define MR_GRADE_PART_0
+#endif
+
 #ifdef USE_ASM_LABELS
   #define MR_GRADE_PART_1	asm_
 #else
@@ -177,7 +183,8 @@
   #endif
 #endif
 
-#define MR_GRADE		MR_PASTE12(			\
+#define MR_GRADE		MR_PASTE13(			\
+					MR_GRADE_PART_0,	\
 					MR_GRADE_PART_1,	\
 					MR_GRADE_PART_2,	\
 					MR_GRADE_PART_3,	\
Index: runtime/mercury_imp.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_imp.h,v
retrieving revision 1.7
diff -u -r1.7 mercury_imp.h
--- mercury_imp.h	1998/06/09 02:08:02	1.7
+++ mercury_imp.h	1998/07/02 06:51:47
@@ -20,6 +20,20 @@
 #define MERCURY_IMP_H
 
 /*
+** This test allows Mercury developers who have not done a cvs update
+** of the changes introducing the new failure handling method in the
+** code generator to retain the ability to do bootchecks, by adding
+** -DMR_DISABLE_REDOFR to EXTRA_CFLAGS in their Mmake.stage.params,
+** and using bootcheck -r.
+**
+** The test should be deleted once there are no such developers.
+*/
+
+#ifdef	MR_DISABLE_REDOFR
+#undef	MR_USE_REDOFR
+#endif
+
+/*
 ** The #include of "mercury_conf.h" must come before the `#ifdef USE_DLLS',
 ** because mercury_conf.h defines the USE_DLLS macro.
 */
Index: runtime/mercury_stack_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
retrieving revision 1.9
diff -u -r1.9 mercury_stack_trace.c
--- mercury_stack_trace.c	1998/06/18 06:08:05	1.9
+++ mercury_stack_trace.c	1998/07/01 08:53:13
@@ -143,7 +143,6 @@
 	return label_layout;
 }
 
-
 static	MR_Stack_Walk_Step_Result
 MR_stack_walk_step(MR_Stack_Layout_Entry *entry_layout,
 	MR_Stack_Layout_Label **return_label_layout,
@@ -206,6 +205,40 @@
 
 	*return_label_layout = label_layout;
 	return STEP_OK;
+}
+
+void
+MR_dump_nondet_stack_from_layout(FILE *fp, Word *base_maxfr)
+{
+	/*
+	** Change the >= below to > if you don't want the trace to include
+	** the bottom frame created by mercury_wrapper.c (whose redoip/redofr
+	** field can be hijacked by other code).
+	*/
+
+	while (base_maxfr >= MR_nondet_stack_trace_bottom) {
+#ifdef	MR_USE_REDOFR
+		if ((base_maxfr - bt_prevfr(base_maxfr)) < NONDET_FIXED_SIZE) {
+			fprintf(fp, "%p: temp\n", base_maxfr);
+			fprintf(fp, " redoip: ");
+			printlabel(bt_redoip(base_maxfr));
+			fprintf(fp, " redofr: %p\n", bt_redofr(base_maxfr));
+		} else
+#endif
+		{
+			fprintf(fp, "%p: ordinary\n", base_maxfr);
+			fprintf(fp, " redoip: ");
+			printlabel(bt_redoip(base_maxfr));
+#ifdef	MR_USE_REDOFR
+			fprintf(fp, " redofr: %p\n", bt_redofr(base_maxfr));
+#endif
+			fprintf(fp, " succip: ");
+			printlabel(bt_succip(base_maxfr));
+			fprintf(fp, " succfr: %p\n", bt_succfr(base_maxfr));
+		}
+
+		base_maxfr = bt_prevfr(base_maxfr);
+	}
 }
 
 static	MR_Stack_Layout_Entry	*prev_entry_layout;
Index: runtime/mercury_stack_trace.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.h,v
retrieving revision 1.6
diff -u -r1.6 mercury_stack_trace.h
--- mercury_stack_trace.h	1998/06/18 06:08:07	1.6
+++ mercury_stack_trace.h	1998/06/30 07:50:35
@@ -60,6 +60,9 @@
 				int ancestor_level, Word **stack_trace_sp,
 				Word **stack_trace_curfr, const char **problem);
 
+extern	void		MR_dump_nondet_stack_from_layout(FILE *fp,
+				Word *base_maxfr);
+
 /*
 ** MR_stack_trace_bottom should be set to the address of global_success,
 ** the label main/2 goes to on success. Stack dumps terminate when they
@@ -67,5 +70,14 @@
 */
 
 Code	*MR_stack_trace_bottom;
+
+/*
+** MR_nondet_stack_trace_bottom should be set to the address of the buffer
+** nondet stack frame created before calling main. Nondet stack dumps terminate
+** when they reach a stack frame whose redoip contains this address. Note that
+** the redoip and redofr slots of this frame may be hijacked.
+*/
+
+Word	*MR_nondet_stack_trace_bottom;
 
 #endif /* MERCURY_STACK_TRACE_H */
Index: runtime/mercury_stacks.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stacks.h,v
retrieving revision 1.6
diff -u -r1.6 mercury_stacks.h
--- mercury_stacks.h	1998/06/18 06:08:09	1.6
+++ mercury_stacks.h	1998/07/01 08:53:51
@@ -55,7 +55,7 @@
 
 #define	push(w)		(					\
 				*MR_sp = (Word) (w),		\
-				debugpush(*sp, MR_sp),		\
+				debugpush(*MR_sp, MR_sp),	\
 				MR_sp = MR_sp + 1,		\
 				detstack_overflow_check(),	\
 				(void)0				\
@@ -68,6 +68,155 @@
 				/* return */ *MR_sp		\
 			)
 
+#ifdef	MR_USE_REDOFR
+
+/* DEFINITIONS FOR NONDET STACK FRAMES */
+
+#define	PREVFR		(-0)	/* prev frame on stack, set up at call	*/
+#define	REDOIP		(-1)	/* in this proc, set up at clause entry	*/
+#define	REDOFR		(-2)	/* value for curfr on backtracking      */
+#define	SUCCIP		(-3)	/* in caller proc, set up at call	*/
+#define	SUCCFR		(-4)	/* frame of caller proc, set up at call	*/
+
+#ifdef MR_DEBUG_NONDET_STACK
+  #define PREDNM		(-5)	/* for debugging, set up at call */
+  #define bt_prednm(fr)		LVALUE_CAST(const char *, ((Word *) fr)[PREDNM])
+  #define NONDET_FIXED_SIZE	6	/* units: words */
+#else
+  #define bt_prednm(fr)	"unknown"
+  #define NONDET_FIXED_SIZE	5	/* units: words */
+#endif
+
+#define	NONDET_TEMP_SIZE	3	/* prevfr, redoip, redofr */
+
+#define	SAVEVAL		(-NONDET_FIXED_SIZE)
+			/* saved values start at this offset	*/
+
+#define	bt_prevfr(fr)	LVALUE_CAST(Word *, ((Word *) (fr))[PREVFR])
+#define	bt_redoip(fr)	LVALUE_CAST(Code *, ((Word *) (fr))[REDOIP])
+#define	bt_redofr(fr)	LVALUE_CAST(Word *, ((Word *) (fr))[REDOFR])
+#define	bt_succip(fr)	LVALUE_CAST(Code *, ((Word *) (fr))[SUCCIP])
+#define	bt_succfr(fr)	LVALUE_CAST(Word *, ((Word *) (fr))[SUCCFR])
+#define	bt_var(fr,n)	(((Word *) (fr))[SAVEVAL-(n)])
+
+#define	curprevfr	bt_prevfr(MR_curfr)
+#define	curredoip	bt_redoip(MR_curfr)
+#define	curredofr	bt_redofr(MR_curfr)
+#define	cursuccip	bt_succip(MR_curfr)
+#define	cursuccfr	bt_succfr(MR_curfr)
+#define	curprednm	bt_prednm(MR_curfr)
+#define	framevar(n)	bt_var(MR_curfr,n)
+
+#define	based_framevar(base_curfr, n)	bt_var(base_curfr, n)
+#define	saved_framevar(save_area, n)	bt_var(MR_saved_curfr(save_area), n)
+
+/* DEFINITIONS FOR MANIPULATING THE NONDET STACK */
+
+#ifdef MR_DEBUG_NONDET_STACK
+#define mkframe_save_prednm(prednm) (curprednm = prednm)
+#else
+#define mkframe_save_prednm(prednm) /* nothing */
+#endif
+
+#define	mkframe(prednm, numslots, redoip)			\
+			do {					\
+				reg	Word	*prevfr;	\
+				reg	Word	*succfr;	\
+								\
+				prevfr = MR_maxfr;		\
+				succfr = MR_curfr;		\
+				MR_maxfr += (NONDET_FIXED_SIZE + numslots);\
+				MR_curfr = MR_maxfr;		\
+				curredoip = redoip;		\
+				curprevfr = prevfr;		\
+				cursuccip = MR_succip;		\
+				cursuccfr = succfr;		\
+				curredofr = MR_curfr;		\
+				mkframe_save_prednm(prednm);	\
+				debugmkframe();			\
+				nondstack_overflow_check();	\
+			} while (0)
+
+/* just like mkframe, but also reserves space for a struct     */
+/* with the given tag at the bottom of the nondet stack frame  */
+#define	mkpragmaframe(prednm, numslots, structname, redoip)	\
+			do {					\
+				reg	Word	*prevfr;	\
+				reg	Word	*succfr;	\
+								\
+				prevfr = MR_maxfr;		\
+				succfr = MR_curfr;		\
+				MR_maxfr += (NONDET_FIXED_SIZE + numslots \
+					+ sizeof(struct structname));	\
+				MR_curfr = MR_maxfr;		\
+				curredoip = redoip;		\
+				curprevfr = prevfr;		\
+				cursuccip = MR_succip;		\
+				cursuccfr = succfr;		\
+				curredofr = MR_curfr;		\
+				mkframe_save_prednm(prednm);	\
+				debugmkframe();			\
+				nondstack_overflow_check();	\
+			} while (0)
+
+#define	mktempframe(redoip)						\
+			do {					\
+				reg	Word	*prevfr;	\
+				reg	Word	*succfr;	\
+								\
+				prevfr = MR_maxfr;		\
+				succfr = MR_curfr;		\
+				MR_maxfr += NONDET_TEMP_SIZE;	\
+				bt_prevfr(MR_maxfr) = prevfr;	\
+				bt_redoip(MR_maxfr) = redoip;	\
+				bt_redofr(MR_maxfr) = MR_curfr;	\
+				nondstack_overflow_check();	\
+			} while (0)
+
+#define	modframe(redoip)					\
+			do {					\
+				curredoip = redoip;		\
+				debugmodframe();		\
+			} while (0)
+
+#define	succeed()	do {					\
+				reg	Word	*childfr;	\
+								\
+				debugsucceed();			\
+				childfr = MR_curfr;		\
+				MR_curfr = cursuccfr;		\
+				GOTO(bt_succip(childfr));	\
+			} while (0)
+
+#define	succeed_discard()					\
+			do {					\
+				reg	Word	*childfr;	\
+								\
+				debugsucceeddiscard();		\
+				childfr = MR_curfr;		\
+				MR_maxfr = curprevfr;		\
+				MR_curfr = cursuccfr;		\
+				GOTO(bt_succip(childfr));	\
+			} while (0)
+
+
+#define	fail()		do {					\
+				debugfail();			\
+				MR_maxfr = bt_prevfr(MR_maxfr);	\
+				nondstack_underflow_check();	\
+				MR_curfr = bt_redofr(MR_maxfr);	\
+				GOTO(bt_redoip(MR_maxfr));	\
+			} while (0)
+
+
+#define	redo()		do {					\
+				debugredo();			\
+				MR_curfr = bt_redofr(MR_maxfr);	\
+				GOTO(bt_redoip(MR_maxfr));	\
+			} while (0)
+
+#else
+
 /* DEFINITIONS FOR NONDET STACK FRAMES */
 
 #define	REDOIP		(-0)	/* in this proc, set up at clause entry	*/
@@ -77,7 +226,7 @@
 
 #ifdef MR_DEBUG_NONDET_STACK
   #define PREDNM		(-4)	/* for debugging, set up at call */
-  #define bt_prednm(fr)	LVALUE_CAST(const char *, ((Word *) fr)[PREDNM])
+  #define bt_prednm(fr)		LVALUE_CAST(const char *, ((Word *) fr)[PREDNM])
   #define NONDET_FIXED_SIZE_0	5	/* units: words */
 #else
   #define bt_prednm(fr)	"unknown"
@@ -181,15 +330,17 @@
 #define	fail()		do {					\
 				debugfail();			\
 				MR_maxfr = curprevfr;		\
-				MR_curfr = MR_maxfr;			\
+				MR_curfr = MR_maxfr;		\
 				nondstack_underflow_check();	\
 				GOTO(curredoip);		\
 			} while (0)
 
 #define	redo()		do {					\
 				debugredo();			\
-				MR_curfr = MR_maxfr;			\
+				MR_curfr = MR_maxfr;		\
 				GOTO(curredoip);		\
 			} while (0)
+
+#endif /* not MR_USE_REDOFR */
 
 #endif /* not MERCURY_STACKS_H */
Index: runtime/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trace_internal.c,v
retrieving revision 1.7
diff -u -r1.7 mercury_trace_internal.c
--- mercury_trace_internal.c	1998/06/18 06:08:12	1.7
+++ mercury_trace_internal.c	1998/07/01 09:19:27
@@ -40,6 +40,8 @@
 static	MR_spy_point	MR_spy_points[MR_MAX_SPY_POINTS];
 static	int		MR_next_spy_point = 0;
 
+static	bool		MR_supply_newline = FALSE;
+
 static	MR_next	MR_trace_debug_cmd(MR_trace_cmd_info *cmd,
 			const MR_Stack_Layout_Label *layout,
 			MR_trace_port port, int seqno, int depth,
@@ -126,6 +128,10 @@
 		(void) strcpy(line, "a\n");
 	}
 
+	if (MR_supply_newline) {
+		fputs(line, stdout);
+	}
+
 	/*
 	** Handle a possible number prefix on the first word on the line,
 	** separating it out into a word on its own.
@@ -312,11 +318,23 @@
 		} else {
 			printf("This command expects no argument.\n");
 		}
+	} else if (streq(words[0], "D")) {
+		if (word_count == 1) {
+			const char	*result;
+
+			do_init_modules();
+			MR_dump_nondet_stack_from_layout(stdout,
+				MR_saved_maxfr(MR_saved_regs));
+		} else {
+			printf("This command expects no argument.\n");
+		}
 	} else if (streq(words[0], "X")) {
 		printf("sp = %p, curfr = %p, maxfr = %p\n",
 			MR_saved_sp(MR_saved_regs),
 			MR_saved_curfr(MR_saved_regs),
 			MR_saved_maxfr(MR_saved_regs));
+	} else if (streq(words[0], "toggle_echo")) {
+		MR_supply_newline = !MR_supply_newline;
 	} else if (streq(words[0], "b")) {
 		if (word_count != 3) {
 			printf("This command expects two arguments,\n");
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.14
diff -u -r1.14 mercury_wrapper.c
--- mercury_wrapper.c	1998/06/18 04:30:47	1.14
+++ mercury_wrapper.c	1998/06/30 07:47:59
@@ -27,6 +27,7 @@
 **	various cleanups that are needed to terminate cleanly.
 */
 
+#define		MR_STACK_TRACE_THIS_MODULE
 #include	"mercury_imp.h"
 
 #include	<stdio.h>
@@ -942,11 +943,12 @@
 	push(MR_maxfr);
 	mkframe("interpreter", 1, LABEL(global_fail));
 
+	MR_nondet_stack_trace_bottom = MR_maxfr;
+	MR_stack_trace_bottom = LABEL(global_success);
+
 	if (program_entry_point == NULL) {
 		fatal_error("no program entry point supplied");
 	}
-
-	MR_stack_trace_bottom = LABEL(global_success);
 
 #ifdef  PROFILE_TIME
 	if (MR_profiling) MR_prof_turn_on_time_profiling();
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.34
diff -u -r1.34 Mmakefile
--- Mmakefile	1998/06/22 01:06:38	1.34
+++ Mmakefile	1998/07/01 04:55:49
@@ -18,6 +18,7 @@
 	construct \
 	curry \
 	curry2 \
+	cut_test \
 	deep_copy_bug \
 	det_in_semidet_cntxt \
 	division_test \
Index: tools/bootcheck
===================================================================
RCS file: /home/mercury1/repository/mercury/tools/bootcheck,v
retrieving revision 1.58
diff -u -r1.58 bootcheck
--- bootcheck	1998/06/19 05:13:54	1.58
+++ bootcheck	1998/06/22 02:28:26
@@ -61,7 +61,7 @@
 outfile=""
 runtests=true
 do_bootcheck=true
-copy_runtime=false
+copy_runtime=true
 copy_profiler=false
 keep_stage_2=false
 keep_stage_3=false
@@ -673,6 +673,10 @@
 
 	MERCURY_COMPILER=$root/stage2/compiler/mercury_compile
 	export MERCURY_COMPILER
+
+	# just temporarily for ws1
+	# MERCURY_COMPILER=$root/stage1/mercury_compile
+	# export MERCURY_COMPILER
 
 	MERCURY_INT_DIR=$root/stage2/library
 	export MERCURY_INT_DIR

New File: tests/hard_coded/cut_test.exp
===================================================================
best case nondet test 1 failed:      OK.
best case nondet test 2 succeeded:   OK.
middle case nondet test 1 failed:    OK.
middle case nondet test 2 succeeded: OK.
middle case nondet test 3 succeeded: OK.
middle case nondet test 4 succeeded: OK.
worst case nondet test 1 failed:     OK.
worst case nondet test 2 succeeded:  OK.
worst case nondet test 3 succeeded:  OK.
worst case nondet test 4 succeeded:  OK.

New File: tests/hard_coded/cut_test.m
===================================================================
:- module cut_test.

:- interface.

:- import_module io.

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

:- implementation.

:- import_module int.

main -->
	( { best(100) } ->
		io__write_string("best case nondet test 1 succeeded:   BUG.\n")
	;
		io__write_string("best case nondet test 1 failed:      OK.\n")
	),
	( { best(300) } ->
		io__write_string("best case nondet test 2 succeeded:   OK.\n")
	;
		io__write_string("best case nondet test 2 failed:      BUG.\n")
	),
	( { middle(100) } ->
		io__write_string("middle case nondet test 1 succeeded: BUG.\n")
	;
		io__write_string("middle case nondet test 1 failed:    OK.\n")
	),
	( { middle(180) } ->
		io__write_string("middle case nondet test 2 succeeded: OK.\n")
	;
		io__write_string("middle case nondet test 2 failed:    BUG.\n")
	),
	( { middle(190) } ->
		io__write_string("middle case nondet test 3 succeeded: OK.\n")
	;
		io__write_string("middle case nondet test 3 failed:    BUG.\n")
	),
	( { middle(200) } ->
		io__write_string("middle case nondet test 4 succeeded: OK.\n")
	;
		io__write_string("middle case nondet test 4 failed:    BUG.\n")
	),
	( { worst(100) } ->
		io__write_string("worst case nondet test 1 succeeded:  BUG.\n")
	;
		io__write_string("worst case nondet test 1 failed:     OK.\n")
	),
	( { worst(180) } ->
		io__write_string("worst case nondet test 2 succeeded:  OK.\n")
	;
		io__write_string("worst case nondet test 2 failed:     BUG.\n")
	),
	( { worst(190) } ->
		io__write_string("worst case nondet test 3 succeeded:  OK.\n")
	;
		io__write_string("worst case nondet test 3 failed:     BUG.\n")
	),
	( { worst(200) } ->
		io__write_string("worst case nondet test 4 succeeded:  OK.\n")
	;
		io__write_string("worst case nondet test 4 failed:     BUG.\n")
	).

:- pred best(int::in) is semidet.

best(A) :-
	test(A, _).

:- pred middle(int::in) is semidet.

middle(A0) :-
	(
		A1 is A0 + 10
	;
		A1 is A0 + 20
	;
		A1 is A0 + 30
	),
	test(A1, _).

:- pred worst(int::in) is semidet.

worst(A0) :-
	addsome(A0, A1),
	test(A1, _).

:- pred addsome(int::in, int::out) is multi.

addsome(A0, A1) :-
	(
		A1 is A0 + 10
	;
		A1 is A0 + 20
	;
		A1 is A0 + 30
	).

:- pred test(int::in, int::out) is nondet.

test(A, B) :-
	A > 200,
	(
		B is A
	;
		B is A * 2
	;
		B is A * 3
	).




More information about the developers mailing list