[m-rev.] diff: fix suspension handling in minimal model tabling

Zoltan Somogyi zs at cs.mu.OZ.AU
Sat Mar 20 16:51:00 AEDT 2004


Our existing mechanism for detecting when the failure out of a negated context
is due to the suspension of a consumer, and not to genuine failure was flawed
in two ways. First, it did not consider all-solutions predicates to be negated 
contexts; second, in some circumstances it could rely on out-of-date data.

library/std_util.m:
	Wrap predicates called in contexts where all solutions are required
	with calls to the routines wrapping negated contexts. Since the
	routines have empty definitions in all grades except minimal model
	grades, there is extra overhead only in minimal model grades.

runtime/mercury_stacks.[ch]:
	When processing suspensions of consumers in a possibly negated context
	and checking that their generators are complete, disregard consumers
	that have logically been deleted together with their generators
	when execution reached the end of the committed-choice contexts in
	which they were created. Without this change, the generator_in_commit
	test case would get an unnecessary abort.

	Register consumers instead of generators in pneg stack entries,
	and make the generator reachable from the consumer, instead of
	registering just the consumer's generator. The old arrangement
	hid information that could be useful during debugging.

runtime/mercury_minimal_model.c:
	Conform to the change to the mercury_stacks module.

	Rename "pickling" to pruning right branches, since this expresses
	the intent of the operation more directly.

	Fix a bug in the printing of the addresses of the redoip slots
	of pruned stack frames.

	Delete unneeded code.

tests/tabling/Mmakefile:
	Record the fact that we now get the expected error in the
	consumer_in_solutions test case.

tests/tabling/consumer_in_solutions.{exp,exp2}:
	Update the expected output in this test case. The old contents of the
	.exp file is the ideal expected output, but it is not achievable with
	our current approach to implementing minimal model tabling. It has
	therefore been moved to the new .exp2 file.

tests/tabling/generator_in_commit.{m,exp}:
	Make this test case do less computation, to make it more useful in
	tracking down errors. The new version still tests everything the old
	version tested, just not so many times.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
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/error
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/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing java
cvs diff: Diffing java/library
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/std_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/std_util.m,v
retrieving revision 1.293
diff -u -b -r1.293 std_util.m
--- library/std_util.m	19 Mar 2004 14:33:37 -0000	1.293
+++ library/std_util.m	20 Mar 2004 05:44:44 -0000
@@ -874,9 +874,11 @@
 % for do_while (below).
 
 :- pragma promise_pure(builtin_aggregate/4).
+
 builtin_aggregate(GeneratorPred, CollectorPred, Accumulator0, Accumulator) :-
 	% Save some of the Mercury virtual machine registers
 	impure get_registers(HeapPtr, SolutionsHeapPtr, TrailPtr),
+	impure start_all_soln_neg_context,
 
 	% Initialize the accumulator
 	% /* Mutvar := Accumulator0 */
@@ -904,6 +906,8 @@
 		fail
 	;
 		% There are no more solutions.
+		impure end_all_soln_neg_context_no_more,
+
 		% So now we just need to copy the final value
 		% of the accumulator from the solutions heap
 		% back onto the ordinary heap, and then we can
@@ -932,6 +936,7 @@
 do_while(GeneratorPred, CollectorPred, Accumulator0, Accumulator) :-
 	impure get_registers(HeapPtr, SolutionsHeapPtr, TrailPtr),
 	impure new_mutvar(Accumulator0, Mutvar),
+	impure start_all_soln_neg_context,
 	(
 		GeneratorPred(Answer0),
 
@@ -946,9 +951,10 @@
 
 		% if More = yes, then backtrack for the next solution.
 		% if More = no, then we're done.
-		More = no
+		More = no,
+		impure end_all_soln_neg_context_more
 	;
-		true
+		impure end_all_soln_neg_context_no_more
 	),
 	impure get_mutvar(Mutvar, Accumulator1),
 	impure partial_deep_copy(SolutionsHeapPtr, Accumulator1, Accumulator),
@@ -1303,6 +1309,47 @@
 "
 	/* As above, we take no action. */
 ").
+
+:- impure pred start_all_soln_neg_context is det.
+:- impure pred end_all_soln_neg_context_more is det.
+:- impure pred end_all_soln_neg_context_no_more is det.
+
+:- pragma foreign_proc("C", 
+	start_all_soln_neg_context,
+	% In minimal model tabling grades, there are no threads.
+	% In all other grades, this predicate is a noop.
+	[will_not_call_mercury, thread_safe],
+"
+#ifdef MR_USE_MINIMAL_MODEL
+	MR_pneg_enter_cond();
+#endif
+").
+
+:- pragma foreign_proc("C", 
+	end_all_soln_neg_context_more,
+	% In minimal model tabling grades, there are no threads.
+	% In all other grades, this predicate is a noop.
+	[will_not_call_mercury, thread_safe],
+"
+#ifdef MR_USE_MINIMAL_MODEL
+	MR_pneg_enter_then();
+#endif
+").
+
+:- pragma foreign_proc("C", 
+	end_all_soln_neg_context_no_more,
+	% In minimal model tabling grades, there are no threads.
+	% In all other grades, this predicate is a noop.
+	[will_not_call_mercury, thread_safe],
+"
+#ifdef MR_USE_MINIMAL_MODEL
+	MR_pneg_enter_else();
+#endif
+").
+
+start_all_soln_neg_context.
+end_all_soln_neg_context_more.
+end_all_soln_neg_context_no_more.
 
 %-----------------------------------------------------------------------------%
 
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
Index: runtime/mercury_minimal_model.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_minimal_model.c,v
retrieving revision 1.10
diff -u -b -r1.10 mercury_minimal_model.c
--- runtime/mercury_minimal_model.c	15 Mar 2004 05:21:42 -0000	1.10
+++ runtime/mercury_minimal_model.c	19 Mar 2004 05:03:25 -0000
@@ -31,8 +31,8 @@
                     MR_Word *saved_ptr);
 static  MR_Word *real_to_saved_nondet_stack(MR_SavedState *saved_state,
                     MR_Word *real_ptr);
-static  void    pickle_stack_segment(MR_SavedState *saved_state,
-                    MR_Integer already_pickled, MR_Subgoal *subgoal);
+static  void    prune_right_branches(MR_SavedState *saved_state,
+                    MR_Integer already_pruned, MR_Subgoal *subgoal);
 static  void    extend_consumer_stacks(MR_Subgoal *leader,
                     MR_Consumer *consumer);
 static  void    make_subgoal_follow_leader(MR_Subgoal *this_follower,
@@ -334,6 +334,9 @@
         MR_subgoal_addr_name(subgoal),
         MR_subgoal_status(subgoal->MR_sg_status));
     MR_print_nondstackptr(fp, subgoal->MR_sg_generator_fr);
+    if (subgoal->MR_sg_back_ptr == NULL) {
+        fprintf(fp, ", DELETED");
+    }
     fprintf(fp, "\n");
 
     if (proc != NULL) {
@@ -394,15 +397,16 @@
 
     fprintf(fp, "consumer %s", MR_consumer_addr_name(consumer));
 
-#ifdef  MR_TABLE_DEBUG
+    if (consumer->MR_cns_subgoal != NULL) {
     fprintf(fp, ", of subgoal %s",
         MR_subgoal_addr_name(consumer->MR_cns_subgoal));
-#endif
-
     fprintf(fp, "\nreturned answers %d, remaining answers ptr %p\n",
         consumer->MR_cns_num_returned_answers,
         consumer->MR_cns_remaining_answer_list_ptr);
     print_saved_state(fp, &consumer->MR_cns_saved_state);
+    } else {
+        fprintf(fp, ", DELETED\n");
+    }
 }
 
 /*---------------------------------------------------------------------------*/
@@ -824,7 +828,7 @@
         cons_saved_state->MR_ss_non_stack_block_size = arena_size;
         cons_saved_state->MR_ss_non_stack_real_start = arena_start;
 
-        pickle_stack_segment(cons_saved_state, arena_size - extension_size,
+        prune_right_branches(cons_saved_state, arena_size - extension_size,
             NULL);
     }
 
@@ -891,25 +895,24 @@
 MR_declare_entry(MR_table_nondet_commit);
 
 static void
-pickle_stack_segment(MR_SavedState *saved_state, MR_Integer already_pickled,
+prune_right_branches(MR_SavedState *saved_state, MR_Integer already_pruned,
     MR_Subgoal *subgoal)
 {
     MR_Word         *saved_fr;
     MR_Word         *saved_stop_fr;
     MR_Word         *saved_top_fr;
     MR_Word         *saved_next_fr;
-    MR_Word         *real_fr;
     MR_Word         *saved_redoip_addr;
-    MR_Word         *real_redoip_addr;
-    MR_Word         frame_size;
+    MR_Word         *real_fr;
     MR_Word         *real_main_branch_fr;
+    MR_Word         frame_size;
     MR_Integer      cur_gen;
     MR_Integer      cur_cut;
     MR_Integer      cur_pneg;
     MR_bool         ordinary;
     MR_bool         generator_is_at_bottom;
 
-    if (already_pickled > 0) {
+    if (already_pruned > 0) {
         generator_is_at_bottom = MR_TRUE;
     } else {
         generator_is_at_bottom = MR_FALSE;
@@ -917,8 +920,8 @@
 
 #ifdef  MR_TABLE_DEBUG
     if (MR_tablestackdebug) {
-        printf("\nbefore pickling nondet stack, already pickled %d\n",
-            already_pickled);
+        printf("\nbefore pruning nondet stack, already pruned %d\n",
+            already_pruned);
         print_saved_state(stdout, saved_state);
     }
 #endif  /* MR_TABLE_DEBUG */
@@ -928,13 +931,6 @@
         saved_state->MR_ss_non_stack_block_size - 1;
     saved_fr = saved_top_fr;
 
-    /*
-    real_stop_fr = saved_state->MR_ss_non_stack_real_start - 1;
-    real_top_fr = saved_state->MR_ss_non_stack_real_start +
-        saved_state->MR_ss_non_stack_block_size - 1;
-    real_fr = real_top_fr;
-    */
-
     real_main_branch_fr =
         saved_to_real_nondet_stack(saved_state, saved_top_fr);
 
@@ -953,12 +949,6 @@
             ordinary = MR_FALSE;
         }
 
-        /*
-        redoip_offset_from_stop = MR_redoip_addr(saved_fr) - real_stop_fr;
-        saved_redoip_addr = saved_stop_fr + redoip_offset_from_stop;
-        real_redoip_addr = saved_stop_fr + redoip_offset_from_stop;
-        */
-
 #if MR_TABLE_DEBUG
         if (MR_tablestackdebug) {
             printf("considering %s frame ",
@@ -966,20 +956,22 @@
             MR_print_nondstackptr(stdout,
                 saved_to_real_nondet_stack(saved_state, saved_fr));
             printf(" with redoip slot at ");
-            MR_print_nondstackptr(stdout, MR_redoip_addr(saved_fr));
+            MR_print_nondstackptr(stdout,
+                saved_to_real_nondet_stack(saved_state,
+                    MR_redoip_addr(saved_fr)));
             printf("\n");
         }
 #endif
 
-        if (already_pickled > 0) {
+        if (already_pruned > 0) {
 #ifdef  MR_TABLE_DEBUG
             if (MR_tabledebug) {
-                printf("already pickled %d -> %d\n",
-                    already_pickled, already_pickled - frame_size);
+                printf("already pruned %d -> %d\n",
+                    already_pruned, already_pruned - frame_size);
             }
 #endif  /* MR_TABLE_DEBUG */
 
-            already_pickled -= frame_size;
+            already_pruned -= frame_size;
 
             if (real_fr == real_main_branch_fr && ordinary) {
 #ifdef  MR_TABLE_DEBUG
@@ -1001,7 +993,7 @@
         } else if (generator_is_at_bottom && saved_next_fr == saved_stop_fr) {
 #ifdef  MR_TABLE_DEBUG
             if (MR_tabledebug) {
-                printf("completing redoip of bottom frame at ");
+                printf("setting redoip to schedule completion in bottom frame ");
                 MR_print_nondstackptr(stdout,
                     saved_to_real_nondet_stack(saved_state, saved_fr));
                 printf(" (in saved copy)\n");
@@ -1024,7 +1016,7 @@
 
 #ifdef  MR_TABLE_DEBUG
                 if (MR_tabledebug) {
-                    printf("completing redoip of frame at ");
+                    printf("setting redoip to schedule completion in frame ");
                     MR_print_nondstackptr(stdout,
                         saved_to_real_nondet_stack(saved_state, saved_fr));
                     printf(" (in saved copy)\n");
@@ -1407,13 +1399,12 @@
     MR_Word         *common_ancestor;
 
     subgoal = (MR_SubgoalPtr) MR_r1;
-    MR_register_suspension(subgoal);
     consumer = MR_table_allocate_struct(MR_Consumer);
     consumer->MR_cns_remaining_answer_list_ptr = &subgoal->MR_sg_answer_list;
-
-#ifdef  MR_TABLE_DEBUG
     consumer->MR_cns_subgoal = subgoal;
     consumer->MR_cns_num_returned_answers = 0;
+
+#ifdef  MR_TABLE_DEBUG
     MR_enter_consumer_debug(consumer);
 
     if (MR_tabledebug) {
@@ -1427,9 +1418,10 @@
         (const MR_Label_Layout *) &MR_LAYOUT_FROM_LABEL(SUSPEND_LABEL(Call)));
     MR_restore_transient_registers();
 
+    MR_register_suspension(consumer);
+
     common_ancestor = consumer->MR_cns_saved_state.MR_ss_common_ancestor_fr;
-    if (common_ancestor < subgoal->MR_sg_deepest_nca_fr)
-    {
+    if (common_ancestor < subgoal->MR_sg_deepest_nca_fr) {
 #ifdef  MR_TABLE_DEBUG
         if (MR_tabledebug) {
             printf("resetting deepest nca for subgoal %s from ",
@@ -1443,7 +1435,7 @@
         subgoal->MR_sg_deepest_nca_fr = common_ancestor;
     }
 
-    pickle_stack_segment(&consumer->MR_cns_saved_state, 0, subgoal);
+    prune_right_branches(&consumer->MR_cns_saved_state, 0, subgoal);
 
   #ifdef  MR_TABLE_DEBUG
     if (MR_tabledebug) {
Index: runtime/mercury_minimal_model.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_minimal_model.h,v
retrieving revision 1.7
diff -u -b -r1.7 mercury_minimal_model.h
--- runtime/mercury_minimal_model.h	15 Mar 2004 02:17:19 -0000	1.7
+++ runtime/mercury_minimal_model.h	19 Mar 2004 05:03:25 -0000
@@ -84,14 +84,24 @@
 	const MR_Label_Layout	*MR_ss_top_layout;
 } MR_SavedState;
 
-/* The state of a consumer subgoal */
+/*
+** The state of a consumer subgoal.
+**
+** The subgoal field points to the generator subgoal. If it is NULL, then the
+** consumer has logically been deleted.
+**
+** The num_returned answers field gives the number of answers returned to this
+** consumer so far.
+**
+** The answer list fields points into the answer list of the generator
+** subgoal. The list of answers it points to expands transparently whenever
+** the generator subgoal adds an answer to its answer list.
+*/
 struct MR_Consumer_Struct {
 	MR_SavedState		MR_cns_saved_state;
+	MR_Subgoal		*MR_cns_subgoal;
 	MR_Integer		MR_cns_num_returned_answers;
 	MR_AnswerList		*MR_cns_remaining_answer_list_ptr;
-#ifdef	MR_TABLE_DEBUG
-	MR_Subgoal		*MR_cns_subgoal;
-#endif
 };
 
 struct MR_ConsumerListNode_Struct {
Index: runtime/mercury_stacks.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stacks.c,v
retrieving revision 1.11
diff -u -b -r1.11 mercury_stacks.c
--- runtime/mercury_stacks.c	12 Mar 2004 06:02:07 -0000	1.11
+++ runtime/mercury_stacks.c	19 Mar 2004 05:03:25 -0000
@@ -335,6 +335,8 @@
 #endif
 	} else {
 		/* this generator will never complete the subgoal */
+		MR_ConsumerList	consumer_list;
+
 #ifdef	MR_TABLE_DEBUG
 		if (MR_tabledebug) {
 			printf("cleanup: generator %p -> %s deleted\n",
@@ -344,6 +346,22 @@
 #endif
 
 		subgoal->MR_sg_back_ptr->MR_subgoal = NULL;
+		subgoal->MR_sg_back_ptr = NULL;
+
+		for (consumer_list = subgoal->MR_sg_consumer_list;
+			consumer_list != NULL;
+			consumer_list = consumer_list->MR_cl_next)
+		{
+#ifdef	MR_TABLE_DEBUG
+			if (MR_tabledebug) {
+				printf("cleanup: consumer %s is deleted",
+					MR_consumer_addr_name(
+						consumer_list->MR_cl_item));
+			}
+#endif
+
+			consumer_list->MR_cl_item->MR_cns_subgoal = NULL;
+		}
 	}
 }
 
@@ -401,7 +419,7 @@
 /***************************************************************************/
 
 void
-MR_register_suspension(MR_SubgoalPtr subgoal)
+MR_register_suspension(MR_Consumer *consumer)
 {
 	MR_PNegConsumerList	node_ptr;
 
@@ -410,7 +428,7 @@
 	}
 
 	node_ptr = MR_TABLE_NEW(MR_PNegConsumerListNode);
-	node_ptr->MR_pneg_consumer_ptr = subgoal;
+	node_ptr->MR_pneg_consumer_ptr = consumer;
 	node_ptr->MR_pneg_next_consumer = 
 		MR_pneg_stack[MR_pneg_next - 1].MR_pneg_consumers;
 	MR_pneg_stack[MR_pneg_next - 1].MR_pneg_consumers = node_ptr;
@@ -470,6 +488,7 @@
 {
 	MR_PNegConsumerList	l;
 	MR_PNegConsumerList	next;
+	MR_PNegConsumerList	consumer_list;
 
 	MR_restore_transient_registers();
 
@@ -483,15 +502,22 @@
 	}
 #endif
 
-	for (l = MR_pneg_stack[MR_pneg_next].MR_pneg_consumers; l != NULL;
-		l = next)
-	{
+	consumer_list = MR_pneg_stack[MR_pneg_next].MR_pneg_consumers;
+	for (l = consumer_list; l != NULL; l = next) {
+		MR_Subgoal	*subgoal;
+		MR_Consumer	*consumer;
+
 		next = l->MR_pneg_next_consumer;
-		if (l->MR_pneg_consumer_ptr->MR_sg_status !=
-			MR_SUBGOAL_COMPLETE)
-		{
-			MR_fatal_error("MR_pneg_enter_else: failing out of "
-				"negated context with incomplete consumer");
+		consumer = l->MR_pneg_consumer_ptr;
+		if (consumer->MR_cns_subgoal == NULL) {
+			/* this consumer has logically been deleted */
+			continue;
+		}
+
+		subgoal = consumer->MR_cns_subgoal;
+		if (subgoal->MR_sg_status != MR_SUBGOAL_COMPLETE) {
+			MR_fatal_error("failing out of negated context "
+				"with incomplete consumer");
 		}
 
 		MR_table_free(l);
@@ -532,13 +558,15 @@
 	if (p->MR_pneg_consumers == NULL) {
 		fprintf(fp, " none");
 	} else {
+		MR_Consumer	*consumer;
 		int	n;
 
 		for (n = 1, l = p->MR_pneg_consumers; l != NULL;
 			l = l->MR_pneg_next_consumer, n++)
 		{
-			fprintf(fp, " <%d: %s>", n,
-				MR_subgoal_addr_name(l->MR_pneg_consumer_ptr));
+			consumer = l->MR_pneg_consumer_ptr;
+			fprintf(fp, " <%d: %s>",
+				n, MR_consumer_addr_name(consumer));
 		}
 	}
 
Index: runtime/mercury_stacks.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stacks.h,v
retrieving revision 1.42
diff -u -b -r1.42 mercury_stacks.h
--- runtime/mercury_stacks.h	12 Mar 2004 06:02:07 -0000	1.42
+++ runtime/mercury_stacks.h	19 Mar 2004 05:03:25 -0000
@@ -577,7 +577,7 @@
 */
 
 struct MR_PNegConsumerListNodeStruct {
-	MR_Subgoal		*MR_pneg_consumer_ptr;
+	MR_Consumer		*MR_pneg_consumer_ptr;
 	MR_PNegConsumerList	MR_pneg_next_consumer;
 };
 
@@ -588,7 +588,7 @@
 	int			MR_pneg_depth;
 };
 
-extern	void			MR_register_suspension(MR_Subgoal *subgoal);
+extern	void			MR_register_suspension(MR_Consumer *consumer);
 extern	void			MR_pneg_enter_cond(void);
 extern	void			MR_pneg_enter_then(void);
 extern	void			MR_pneg_enter_else(void);
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
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
Index: tests/tabling/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/tabling/Mmakefile,v
retrieving revision 1.28
diff -u -b -r1.28 Mmakefile
--- tests/tabling/Mmakefile	15 Mar 2004 05:21:46 -0000	1.28
+++ tests/tabling/Mmakefile	19 Mar 2004 11:10:28 -0000
@@ -24,6 +24,7 @@
 	combine \
 	completed_consumer_in_solutions \
 	consumer_in_commit \
+	consumer_in_solutions \
 	coup \
 	coup2 \
 	coup3 \
@@ -46,12 +47,6 @@
 NONDET_LOOP_PROGS = \
 	tc_loop
 
-# We don't yet pass the following minimal model tests.
-#
-#	consumer_in_solutions 	it contains interactions between tabling
-#				and constructs that function as committed
-#				or negated contexts.
-
 ALL_SIMPLE_PROGS = $(SIMPLE_NONLOOP_PROGS) $(SIMPLE_LOOP_PROGS)
 ALL_NONDET_PROGS = $(NONDET_NONLOOP_PROGS) $(NONDET_LOOP_PROGS)
 
@@ -113,6 +108,14 @@
 			-e 's/require.m:[0-9]*/require.m:NNNN/g' \
 			< $@.tmp > $@; \
 		rm -f $@.tmp; \
+	fi
+
+consumer_in_solutions.out: consumer_in_solutions
+	if ./$< > $@.tmp 2>&1; then \
+		grep . $@.tmp; \
+		exit 1; \
+	else \
+		mv $@.tmp $@ ; \
 	fi
 
 .PHONY: echo_progs
Index: tests/tabling/consumer_in_solutions.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/tabling/consumer_in_solutions.exp,v
retrieving revision 1.1
diff -u -b -r1.1 consumer_in_solutions.exp
--- tests/tabling/consumer_in_solutions.exp	20 Apr 1999 11:48:38 -0000	1.1
+++ tests/tabling/consumer_in_solutions.exp	18 Mar 2004 16:13:08 -0000
@@ -1 +1 @@
-[1 - [1, 2, 3], 2 - [1, 2, 3], 3 - [1, 2, 3]]
+Mercury runtime: failing out of negated context with incomplete consumer
Index: tests/tabling/consumer_in_solutions.exp2
===================================================================
RCS file: tests/tabling/consumer_in_solutions.exp2
diff -N tests/tabling/consumer_in_solutions.exp2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/tabling/consumer_in_solutions.exp2	20 Mar 2004 05:47:33 -0000
@@ -0,0 +1 @@
+[1 - [1, 2, 3], 2 - [1, 2, 3], 3 - [1, 2, 3]]
Index: tests/tabling/generator_in_commit.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/tabling/generator_in_commit.exp,v
retrieving revision 1.1
diff -u -b -r1.1 generator_in_commit.exp
--- tests/tabling/generator_in_commit.exp	20 Apr 1999 11:48:42 -0000	1.1
+++ tests/tabling/generator_in_commit.exp	19 Mar 2004 05:03:46 -0000
@@ -1 +1 @@
-[21, 22, 23, 24, 25, 26, 27, 28, 29, 42]
+[21, 22, 23, 42]
Index: tests/tabling/generator_in_commit.m
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/tabling/generator_in_commit.m,v
retrieving revision 1.1
diff -u -b -r1.1 generator_in_commit.m
--- tests/tabling/generator_in_commit.m	20 Apr 1999 11:48:42 -0000	1.1
+++ tests/tabling/generator_in_commit.m	19 Mar 2004 05:03:46 -0000
@@ -1,5 +1,7 @@
 % This test case checks whether we get incorrect answers
 % when a generator gets started but not finished inside a commit.
+% One possible problem it tests for is not cleaning up the consumers
+% of such generators properly.
 
 :- module generator_in_commit.
 
@@ -38,7 +40,7 @@
 	(
 		q(Y),
 		X = Y + 1,
-		X < 10
+		X < 4
 	;
 		X = 1
 	).
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list