[m-rev.] for review: dependent parallel conjunctions (2/2)

Peter Wang wangp at students.cs.mu.OZ.AU
Thu Jun 22 14:30:10 AEST 2006


(continued.)

Index: library/RESERVED_MACRO_NAMES
===================================================================
RCS file: /home/mercury1/repository/mercury/library/RESERVED_MACRO_NAMES,v
retrieving revision 1.3
diff -u -r1.3 RESERVED_MACRO_NAMES
--- library/RESERVED_MACRO_NAMES	15 Dec 2004 06:57:40 -0000	1.3
+++ library/RESERVED_MACRO_NAMES	21 Jun 2006 11:51:23 -0000
@@ -31,6 +31,7 @@
 __GC
 _GC_H
 HIDE_POINTER
+LINUX_THREADS
 REVEAL_POINTER
 #-----------------------------------------------------------------------------#
 # This is defined by mps_gc/code/mercury_mps.h,
@@ -66,3 +67,8 @@
 mercury__exception__builtin_catch_3_p_3
 mercury__exception__builtin_catch_3_p_4
 mercury__exception__builtin_catch_3_p_5
+#-----------------------------------------------------------------------------#
+# These are defined in when threads are enabled.
+_REENTRANT
+_THREAD_SAFE
+#-----------------------------------------------------------------------------#
Index: library/library.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/library.m,v
retrieving revision 1.96
diff -u -r1.96 library.m
--- library/library.m	5 Apr 2006 07:07:45 -0000	1.96
+++ library/library.m	20 Apr 2006 07:47:36 -0000
@@ -135,6 +135,7 @@
 
 % The modules intended for Mercury system implementors.
 :- import_module mutvar.
+:- import_module par_builtin.
 :- import_module private_builtin.
 :- import_module profiling_builtin.
 :- import_module rtti_implementation.
@@ -229,6 +230,7 @@
 mercury_std_library_module("parser").
 mercury_std_library_module("pprint").
 mercury_std_library_module("pqueue").
+mercury_std_library_module("par_builtin").
 mercury_std_library_module("private_builtin").
 mercury_std_library_module("profiling_builtin").
 mercury_std_library_module("prolog").
Index: library/par_builtin.m
===================================================================
RCS file: library/par_builtin.m
diff -N library/par_builtin.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ library/par_builtin.m	21 Jun 2006 09:17:49 -0000
@@ -0,0 +1,131 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=8 sw=4 sts=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+% Copyright (C) 2006 The University of Melbourne.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%---------------------------------------------------------------------------%
+
+% File: par_builtin.m.
+% Main authors: wangp.
+% Stability: low.
+
+% This file is automatically imported, as if via `use_module', into every
+% module in parallel grades.  It is intended for the builtin procedures that
+% the compiler generates implicit calls to when implementing parallel
+% conjunctions.
+%
+% This module is a private part of the Mercury implementation; user modules
+% should never explicitly import this module. The interface for this module
+% does not get included in the Mercury library reference manual.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- module par_builtin.
+
+%-----------------------------------------------------------------------------%
+
+:- interface.
+
+:- type prom(T).
+
+:- pred new_promise(prom(T)::uo) is det.
+:- pred wait(prom(T)::in, T::out) is det.
+:- impure pred signal(prom(T)::in, T::in) is det.
+
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- pragma foreign_decl("C",
+"
+    typedef struct MR_Promise MR_Promise;
+
+#ifdef MR_THREAD_SAFE
+# ifdef MR_HAVE_SEMAPHORE_H
+    /* POSIX 1003.1b semaphores available. */
+    #include <semaphore.h>
+
+    struct MR_Promise {
+        sem_t   semaphore;
+        MR_Word value;
+    };
+# else /* !MR_HAVE_SEMAPHORE_H */
+    /* Use POSIX thread mutexes and condition variables. */
+    #include <pthread.h>
+
+    struct MR_Promise {
+        pthread_mutex_t mutex;
+        pthread_cond_t cond;
+        MR_Word value;
+    };
+# endif /* !MR_HAVE_SEMAPHORE_H */
+#else /* !MR_THREAD_SAFE */
+    struct MR_Promise {
+    };
+#endif /* !MR_THREAD_SAFE */
+").
+
+:- pragma foreign_type("C", prom(T), "MR_Promise *").
+
+    % Placeholder only.
+:- pragma foreign_type(il, prom(T), "class [mscorlib]System.Object").
+
+:- pragma foreign_proc("C",
+    new_promise(Promise::uo),
+    [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+#ifdef MR_THREAD_SAFE
+# ifdef MR_HAVE_SEMAPHORE_H
+    Promise = MR_GC_NEW(MR_Promise);
+    sem_init(&Promise->semaphore, MR_NO, 0);
+    Promise->value = 0;
+# else
+    Promise = MR_GC_NEW(MR_Promise);
+    pthread_mutex_init(&Promise->mutex, NULL);
+    pthread_cond_init(&Promise->cond, NULL);
+    Promise->value = 0;
+# endif
+#endif
+").
+
+:- pragma foreign_proc("C",
+    wait(Promise::in, Value::out),
+    [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
+"
+#ifdef MR_THREAD_SAFE
+# ifdef MR_HAVE_SEMAPHORE_H
+    sem_wait(&Promise->semaphore);
+    sem_post(&Promise->semaphore);
+    Value = Promise->value;
+# else
+    pthread_mutex_lock(&Promise->mutex);
+    while (!Promise->pass) {
+        pthread_cond_wait(&Promise->cond, &Promise->mutex);
+    }
+    Value = Promise->value;
+    pthread_mutex_unlock(&Promise->mutex);
+# endif
+#endif
+").
+
+:- pragma foreign_proc("C",
+    signal(Promise::in, Value::in),
+    [will_not_call_mercury, thread_safe, will_not_modify_trail],
+"
+#ifdef MR_THREAD_SAFE
+# ifdef MR_HAVE_SEMAPHORE_H
+    Promise->value = Value;
+    sem_post(&Promise->semaphore);
+# else
+    pthread_mutex_lock(&Promise->mutex);
+    Value = Promise->value;
+    pthread_cond_broadcast(&Promise->cond);
+    pthread_mutex_unlock(&Promise->mutex);
+# endif
+#endif
+").
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
Index: library/private_builtin.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/private_builtin.m,v
retrieving revision 1.156
diff -u -r1.156 private_builtin.m
--- library/private_builtin.m	1 May 2006 14:45:18 -0000	1.156
+++ library/private_builtin.m	13 Jun 2006 15:46:40 -0000
@@ -14,9 +14,10 @@
 % module. It is intended for builtins that are just implementation details,
 % such as procedures that the compiler generates implicit calls to when
 % implementing polymorphism, unification, compare/3, etc.
-% Note that the builtins used for tabling and deep profiling are in separate
-% modules (table_builtin.m and profiling_builtin.m).
-% 
+% Note that the builtins used for tabling, deep profiling and parallelism are
+% in separate modules (table_builtin.m, profiling_builtin.m and
+% par_builting.m).
+
 % This module is a private part of the Mercury implementation; user modules
 % should never explicitly import this module. The interface for this module
 % does not get included in the Mercury library reference manual.
Index: mdbcomp/prim_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/mdbcomp/prim_data.m,v
retrieving revision 1.11
diff -u -r1.11 prim_data.m
--- mdbcomp/prim_data.m	8 Jun 2006 08:19:53 -0000	1.11
+++ mdbcomp/prim_data.m	13 Jun 2006 15:46:41 -0000
@@ -204,6 +204,12 @@
 :- pred mercury_term_size_prof_builtin_module(sym_name::out) is det.
 :- func mercury_term_size_prof_builtin_module = sym_name.
 
+    % Returns the name of the module containing the builtins for parallelism.
+    % This module is automatically imported iff building in a .par grade.
+    %
+:- pred mercury_par_builtin_module(sym_name::out) is det.
+:- func mercury_par_builtin_module = sym_name.
+
     % Returns the sym_name of the module with the given name in the
     % Mercury standard library.
     %
@@ -299,6 +305,8 @@
 mercury_profiling_builtin_module(mercury_profiling_builtin_module).
 mercury_term_size_prof_builtin_module = unqualified("term_size_prof_builtin").
 mercury_term_size_prof_builtin_module(mercury_term_size_prof_builtin_module).
+mercury_par_builtin_module = unqualified("par_builtin").
+mercury_par_builtin_module(mercury_par_builtin_module).
 mercury_std_lib_module_name(Name) = unqualified(Name).
 mercury_std_lib_module_name(Name, unqualified(Name)).
 
@@ -308,10 +316,12 @@
     ; mercury_table_builtin_module(Module)
     ; mercury_profiling_builtin_module(Module)
     ; mercury_term_size_prof_builtin_module(Module)
+    ; mercury_par_builtin_module(Module)
     ).
 
 non_traced_mercury_builtin_module(Module) :-
     ( mercury_table_builtin_module(Module)
     ; mercury_profiling_builtin_module(Module)
     ; mercury_term_size_prof_builtin_module(Module)
+    ; mercury_par_builtin_module(Module)
     ).
Index: mdbcomp/program_representation.m
===================================================================
RCS file: /home/mercury1/repository/mercury/mdbcomp/program_representation.m,v
retrieving revision 1.13
diff -u -r1.13 program_representation.m
--- mdbcomp/program_representation.m	8 Jun 2006 08:19:53 -0000	1.13
+++ mdbcomp/program_representation.m	18 Jun 2006 11:33:05 -0000
@@ -542,13 +542,17 @@
     ;
         ModuleNameType = term_size_prof_builtin,
         mercury_term_size_prof_builtin_module(ModuleName)
+    ;
+        ModuleNameType = par_builtin,
+        mercury_par_builtin_module(ModuleName)
     ).
 
 :- type builtin_mod
     --->    builtin
     ;       private_builtin
     ;       table_builtin
-    ;       term_size_prof_builtin.
+    ;       term_size_prof_builtin
+    ;       par_builtin.
 
 :- pred no_type_info_builtin_2(builtin_mod::out, string::in, int::in)
     is semidet.
@@ -569,6 +573,9 @@
 no_type_info_builtin_2(table_builtin, "table_lookup_insert_typeinfo", 3).
 no_type_info_builtin_2(table_builtin, "table_lookup_insert_typeclassinfo", 3).
 no_type_info_builtin_2(term_size_prof_builtin, "increment_size", 2).
+no_type_info_builtin_2(par_builtin, "new_promise", 1).
+no_type_info_builtin_2(par_builtin, "wait", 2).
+no_type_info_builtin_2(par_builtin, "signal", 2).
 
     % True iff the given predicate is defined with an :- external
     % declaration.  Note that the arity includes the hidden type info
Index: runtime/RESERVED_MACRO_NAMES
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/RESERVED_MACRO_NAMES,v
retrieving revision 1.16
diff -u -r1.16 RESERVED_MACRO_NAMES
--- runtime/RESERVED_MACRO_NAMES	15 Dec 2004 06:57:49 -0000	1.16
+++ runtime/RESERVED_MACRO_NAMES	21 Jun 2006 11:51:15 -0000
@@ -31,6 +31,7 @@
 __GC
 _GC_H
 HIDE_POINTER
+LINUX_THREADS
 REVEAL_POINTER
 #-----------------------------------------------------------------------------#
 # This is defined by mps_gc/code/mercury_mps.h,
@@ -65,3 +66,7 @@
 __EXTENSIONS__
 __OPTIMIZE__
 #-----------------------------------------------------------------------------#
+# These are defined in when threads are enabled.
+_REENTRANT
+_THREAD_SAFE
+#-----------------------------------------------------------------------------#
Index: runtime/mercury_conf.h.in
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf.h.in,v
retrieving revision 1.53
diff -u -r1.53 mercury_conf.h.in
--- runtime/mercury_conf.h.in	2 Mar 2006 07:40:47 -0000	1.53
+++ runtime/mercury_conf.h.in	18 Jun 2006 09:23:16 -0000
@@ -129,6 +129,7 @@
 **	MR_HAVE_IEEEFP_H	we have <ieeefp.h>
 **	MR_HAVE_DIRENT_H	we have <dirent.h>
 **	MR_HAVE_MALLOC_H	we have <malloc.h>
+**	MR_HAVE_SEMAPHORE_H	we have <semaphore.h>
 */
 #undef	MR_HAVE_SYS_SIGINFO_H
 #undef	MR_HAVE_SYS_SIGNAL_H
@@ -151,6 +152,7 @@
 #undef	MR_HAVE_IEEEFP_H
 #undef	MR_HAVE_DIRENT_H
 #undef	MR_HAVE_MALLOC_H
+#undef	MR_HAVE_SEMAPHORE_H
 
 /*
 ** MR_HAVE_POSIX_TIMES is defined if we have the POSIX
Index: tests/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/Mmakefile,v
retrieving revision 1.13
diff -u -r1.13 Mmakefile
--- tests/Mmakefile	25 Jan 2006 01:54:26 -0000	1.13
+++ tests/Mmakefile	19 Jun 2006 10:06:52 -0000
@@ -11,6 +11,7 @@
 	invalid \
 	misc_tests \
 	mmc_make \
+	par_conj \
 	recompilation \
 	tabling \
 	term \
Index: tests/par_conj/.cvsignore
===================================================================
RCS file: tests/par_conj/.cvsignore
diff -N tests/par_conj/.cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/.cvsignore	19 Jun 2006 10:31:41 -0000
@@ -0,0 +1,14 @@
+*.d
+*.date
+*.date0
+*.date3
+*.dep
+*.int
+*.int0
+*.int2
+*.int3
+*.opt
+*.optdate
+*.res
+undead_proc.h
+CLEAN
Index: tests/par_conj/Mercury.options
===================================================================
RCS file: tests/par_conj/Mercury.options
diff -N tests/par_conj/Mercury.options
Index: tests/par_conj/Mmakefile
===================================================================
RCS file: tests/par_conj/Mmakefile
diff -N tests/par_conj/Mmakefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/Mmakefile	21 Jun 2006 07:09:57 -0000
@@ -0,0 +1,104 @@
+#-----------------------------------------------------------------------------#
+
+THIS_DIR = par_conj
+
+#-----------------------------------------------------------------------------#
+
+# please keep these lists sorted
+DEP_PAR_CONJ_PROGS= \
+	dep_par_1 \
+	dep_par_2 \
+	dep_par_3 \
+	dep_par_3b \
+	dep_par_3c \
+	dep_par_4 \
+	dep_par_5 \
+	dep_par_5b \
+	dep_par_5c \
+	dep_par_5d \
+	dep_par_6 \
+	dep_par_7 \
+	dep_par_8 \
+	dep_par_9 \
+	dep_par_10 \
+	dep_par_11 \
+	dep_par_11b \
+	dep_par_11c \
+	dep_par_12 \
+	dep_par_13 \
+	dep_par_14 \
+	dep_par_14b \
+	dep_par_14c \
+	dep_par_14d \
+	dep_par_16 \
+	dep_par_17 \
+	dep_par_18 \
+	dep_par_20 \
+	dep_par_21 \
+	dep_par_22 \
+	dep_par_23
+
+INDEP_PAR_CONJ_PROGS = \
+	indep_par_append \
+	indep_par_nested
+
+ifneq "$(findstring decldebug,$(GRADE))" ""
+	OBJ_PROGS =
+	PROGS =
+else
+	# Don't run dependent parallel conjunction programs as they can cause
+	# deadlocks if there are not enough threads available.  This will be
+	# fixed with coroutining support.
+	OBJ_PROGS = $(DEP_PAR_CONJ_PROGS)
+	PROGS = $(OBJ_PROGS) $(INDEP_PAR_CONJ_PROGS)
+endif
+
+# `mmc --make' doesn't expect subdirectories to appear in targets.
+ifeq ($(MMAKE_USE_MMC_MAKE),yes)
+OS_SUBDIR=
+ILS_SUBDIR=
+DLLS_SUBDIR=
+else
+OS_SUBDIR=$(os_subdir)
+ILS_SUBDIR=$(ils_subdir)
+DLLS_SUBDIR=$(dlls_subdir)
+endif
+
+
+ifeq ($(findstring il,$(GRADE)),il)
+	TARGET_OBJ_EXT=dll
+	TARGET_OBJ_SUBDIR=$(DLLS_SUBDIR)
+else
+	TARGET_OBJ_EXT=$(O)
+	TARGET_OBJ_SUBDIR=$(OS_SUBDIR)
+endif
+OBJS =	$(OBJ_PROGS:%=$(TARGET_OBJ_SUBDIR)%.$(TARGET_OBJ_EXT)) \
+		$(IL_PROGS:%=$(ILS_SUBDIR)%.il)
+
+#-----------------------------------------------------------------------------#
+
+TESTS = $(PROGS)
+SUBDIRS=
+TESTS_DIR=..
+include $(TESTS_DIR)/Mmake.common
+
+# Module-specific options should go in Mercury.options so they
+# can be found by `mmc --make'.
+include Mercury.options
+
+%.runtest: %.res ;
+
+$(OBJ_PROGS:%=%.runtest): %.runtest: %.$(TARGET_OBJ_EXT) ;
+
+#-----------------------------------------------------------------------------#
+
+printtests:
+	@echo $(PROGS)
+
+printobjs:
+	@echo $(OBJS)
+
+clean_local:
+	rm -f *.err *.h
+
+#-----------------------------------------------------------------------------#
Index: tests/par_conj/dep_par_1.m
===================================================================
RCS file: tests/par_conj/dep_par_1.m
diff -N tests/par_conj/dep_par_1.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_1.m	19 Jun 2006 12:22:43 -0000
@@ -0,0 +1,14 @@
+% unify
+
+:- module dep_par_1.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+main(!IO) :-
+    ( X = 1
+    & Y = X
+    ),
+    io.write_int(Y, !IO),
+    io.nl(!IO).
Index: tests/par_conj/dep_par_10.m
===================================================================
RCS file: tests/par_conj/dep_par_10.m
diff -N tests/par_conj/dep_par_10.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_10.m	21 Jun 2006 03:57:48 -0000
@@ -0,0 +1,27 @@
+% foreign proc
+
+:- module dep_par_10.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    (
+	X = fp(1)
+    &
+	Y = fp(X)
+    ),
+    io.print(X*Y, !IO),
+    io.nl(!IO).
+
+:- func fp(int) = int.
+
+:- pragma foreign_proc("C",
+    fp(X::in) = (Y::out),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    Y = X+1;
+").
Index: tests/par_conj/dep_par_11.m
===================================================================
RCS file: tests/par_conj/dep_par_11.m
diff -N tests/par_conj/dep_par_11.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_11.m	21 Jun 2006 04:04:49 -0000
@@ -0,0 +1,21 @@
+% conjunction inside parallel conjunction
+
+:- module dep_par_11.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    (
+	X = A + B + C,
+	A = B + C,
+	B = 1,
+	C = 2
+    &
+	U = X + A
+    ),
+    io.print({X,U,C}, !IO),
+    io.nl(!IO).
Index: tests/par_conj/dep_par_11b.m
===================================================================
RCS file: tests/par_conj/dep_par_11b.m
diff -N tests/par_conj/dep_par_11b.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_11b.m	21 Jun 2006 04:05:14 -0000
@@ -0,0 +1,28 @@
+% conjunction with nested parallel conjunction
+
+:- module dep_par_11b.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(IO0, IO) :-
+    p(U),
+    io.write_int(U, IO0, IO1),
+    io.nl(IO1, IO).
+
+:- pred p(int::out) is det.
+p(U) :-
+    (
+	X = A + B + C,
+	(
+	    A = B + C 
+	&
+	    B = 1
+	),
+	C = 2
+    &
+	U = X + A
+    ).
Index: tests/par_conj/dep_par_11c.m
===================================================================
RCS file: tests/par_conj/dep_par_11c.m
diff -N tests/par_conj/dep_par_11c.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_11c.m	21 Jun 2006 04:05:25 -0000
@@ -0,0 +1,28 @@
+% conjunction with nested parallel conjunction (2)
+
+:- module dep_par_11c.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(IO0, IO) :-
+    p(XUC),
+    io.print(XUC, IO0, IO1),
+    io.nl(IO1, IO).
+
+:- pred p({int, int, int}::out) is det.
+p({X,U,C}) :-
+    (
+	X = A + B + C,
+	(
+	    A = B + C 
+	&
+	    B = 1
+	),
+	C = 2
+    &
+	U = X + A
+    ).
Index: tests/par_conj/dep_par_12.m
===================================================================
RCS file: tests/par_conj/dep_par_12.m
diff -N tests/par_conj/dep_par_12.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_12.m	21 Jun 2006 03:58:59 -0000
@@ -0,0 +1,34 @@
+% switch
+
+:- module dep_par_12.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+:- type t
+    --->    t1
+    ;	    t2.
+
+main(!IO) :-
+    T = f,
+    (
+	T = t1,
+	( X = 1
+	& Y = 2
+	)
+    ;
+	T = t2,
+	( Y = 1
+	& X = 2
+	)
+    ),
+    io.write_int(Y, !IO),
+    io.write_int(X, !IO),
+    io.nl(!IO).
+
+:- func f = t.
+:- pragma no_inline(f/0).
+f = t2.
Index: tests/par_conj/dep_par_13.m
===================================================================
RCS file: tests/par_conj/dep_par_13.m
diff -N tests/par_conj/dep_par_13.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_13.m	19 Jun 2006 10:40:31 -0000
@@ -0,0 +1,28 @@
+% scope
+
+:- module dep_par_13.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module list.
+
+main(!IO) :-
+    (
+	some [!X] (
+	    !:X = [],
+	    cons(1, !X),
+	    cons(2, !X),
+	    X = !.X
+	)
+    &
+	some [!Y] (
+	    !:Y = X,
+	    cons(10, !Y),
+	    cons(20, !Y),
+	    Y = !.Y
+	)
+    ),
+    io.print(Y, !IO),
+    io.nl(!IO).
Index: tests/par_conj/dep_par_14.m
===================================================================
RCS file: tests/par_conj/dep_par_14.m
diff -N tests/par_conj/dep_par_14.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_14.m	21 Jun 2006 04:09:04 -0000
@@ -0,0 +1,28 @@
+% There were problems with this and deforestation and
+% --optimise-saved-vars-const.
+
+:- module dep_par_14.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module list.
+
+main(!IO) :-
+    R = [1, 5, 3, 4, 7, 8, 6, 9, 2, 0],
+    p(R, 1, S),
+    io.print(S, !IO),
+    io.nl(!IO).
+
+:- pred p(list(int)::in, int::in, int::out) is det.
+
+p([], A, A).
+p([H|T], A0, A) :-
+    (if H = A0 then
+        ( p(T, A0, A1)
+        & p(T, A1, A)
+        )
+    else
+        A = A0
+    ).
Index: tests/par_conj/dep_par_14b.m
===================================================================
RCS file: tests/par_conj/dep_par_14b.m
diff -N tests/par_conj/dep_par_14b.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_14b.m	21 Jun 2006 04:07:09 -0000
@@ -0,0 +1,29 @@
+% This is the same as dep_par_14 but uses a disjunction instead
+% of an if-then-else.
+
+:- module dep_par_14b.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is cc_multi.
+
+:- implementation.
+:- import_module list.
+
+main(!IX) :-
+    R = [1, 5, 3, 4, 7, 8, 6, 9, 2, 0],
+    p(R, 1, S),
+    io.print(S, !IX),
+    io.nl(!IX).
+
+:- pred p(list(int)::in, int::in, int::out) is cc_multi.
+
+p([], A, A).
+p([H|T], A0, A) :-
+    (
+	H = A0,
+        ( p(T, A0, A1)
+        & p(T, A1, A)
+        )
+    ;
+        A = A0
+    ).
Index: tests/par_conj/dep_par_14c.m
===================================================================
RCS file: tests/par_conj/dep_par_14c.m
diff -N tests/par_conj/dep_par_14c.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_14c.m	21 Jun 2006 04:07:26 -0000
@@ -0,0 +1,36 @@
+% This is the same as dep_par_14 but uses a switch instead
+% of if-then-else.
+
+:- module dep_par_14c.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is cc_multi.
+
+:- implementation.
+:- import_module bool.
+:- import_module list.
+
+main(!IX) :-
+    R = [1, 5, 3, 4, 7, 8, 6, 9, 2, 0],
+    p(R, 1, S),
+    io.print(S, !IX),
+    io.nl(!IX).
+
+:- pred p(list(int)::in, int::in, int::out) is cc_multi.
+
+p([], A, A).
+p([H|T], A0, A) :-
+    eq(H, A0, Eq),
+    (
+	Eq = yes,
+        ( p(T, A0, A1)
+        & p(T, A1, A)
+        )
+    ;
+	Eq = no,
+        A = A0
+    ).
+
+:- pred eq(int::in, int::in, bool::out) is det.
+:- pragma no_inline(eq/3).
+eq(A, B, (if A = B then yes else no)).
Index: tests/par_conj/dep_par_14d.m
===================================================================
RCS file: tests/par_conj/dep_par_14d.m
diff -N tests/par_conj/dep_par_14d.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_14d.m	21 Jun 2006 04:09:48 -0000
@@ -0,0 +1,30 @@
+% dep_par_14 with the deforestation already done
+
+:- module dep_par_14d.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module list.
+
+main(!IO) :-
+    R = [1, 5, 3, 4, 7, 8, 6, 9, 2, 0],
+    R = [_|T],
+    ( p(T, 1, A1)
+    & p(T, A1, S)
+    ),
+    io.print(S, !IO),
+    io.nl(!IO).
+
+:- pred p(list(int)::in, int::in, int::out) is det.
+
+p([], A, A).
+p([H|T], A0, A) :-
+    (if H = A0 then
+        ( p(T, A0, A1)
+        & p(T, A1, A)
+        )
+    else
+        A = A0
+    ).
Index: tests/par_conj/dep_par_16.m
===================================================================
RCS file: tests/par_conj/dep_par_16.m
diff -N tests/par_conj/dep_par_16.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_16.m	21 Jun 2006 04:15:26 -0000
@@ -0,0 +1,18 @@
+% dependent append
+
+:- module dep_par_16.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module list.
+main(!IO) :-
+    As = [1, 2, 3],
+    Bs = [4, 5, 6],
+    ( append(As, Bs, Cs)
+    & append(Cs, As, Ds)
+    ),
+    append(Cs, Ds, Es),
+    io.print(Es, !IO),
+    io.nl(!IO).
Index: tests/par_conj/dep_par_17.m
===================================================================
RCS file: tests/par_conj/dep_par_17.m
diff -N tests/par_conj/dep_par_17.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_17.m	21 Jun 2006 04:10:54 -0000
@@ -0,0 +1,30 @@
+% multiple clauses
+
+:- module dep_par_17.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    p(t1, X),
+    io.write_int(X, !IO),
+    io.nl(!IO).
+
+:- type t ---> t1 ; t2.
+
+:- pred p(t::in, int::out) is det.
+:- pragma no_inline(p/2).
+
+p(t1, X) :-
+    q(1, X1) &
+    q(X1, X).
+p(t2, X) :-
+    q(2, X1) &
+    q(X1, X).
+
+:- pred q(int::in, int::out) is det.
+:- pragma no_inline(q/2).
+q(X, X+1).
Index: tests/par_conj/dep_par_18.m
===================================================================
RCS file: tests/par_conj/dep_par_18.m
diff -N tests/par_conj/dep_par_18.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_18.m	21 Jun 2006 04:12:11 -0000
@@ -0,0 +1,24 @@
+% cut out of from primes.m
+
+:- module dep_par_18.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int, list.
+
+main(!IO) :-
+    integers(0, 5, R),
+    io.print(R, !IO),
+    io.nl(!IO).
+
+:- pred integers(int::in, int::in, list(int)::out) is det.
+
+integers(Low, High, Result) :- 
+    ( Low =< High ->
+	Result = [Low | Rest] &
+	integers(Low+1, High, Rest)
+    ;
+	Result = []
+    ).
Index: tests/par_conj/dep_par_2.m
===================================================================
RCS file: tests/par_conj/dep_par_2.m
diff -N tests/par_conj/dep_par_2.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_2.m	19 Jun 2006 10:37:48 -0000
@@ -0,0 +1,21 @@
+% call
+
+:- module dep_par_2.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    (
+	p(1, X)
+    &
+	p(X, Y)
+    ),
+    io.write_int(Y, !IO),
+    io.nl(!IO).
+
+:- pred p(int::in, int::out) is det.
+p(X, X+1).
Index: tests/par_conj/dep_par_20.m
===================================================================
RCS file: tests/par_conj/dep_par_20.m
diff -N tests/par_conj/dep_par_20.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_20.m	19 Jun 2006 10:40:32 -0000
@@ -0,0 +1,26 @@
+% Uncaught Mercury exception:
+% Software Error: map.lookup: key not found
+%        Key Type: term.var(parse_tree.prog_data.prog_var_type)
+%        Key Value: var(4)
+%        Value Type: ll_backend.var_locn.var_state
+
+:- module dep_par_20.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- type t ---> t.
+
+main(!IO) :-
+    ( T = t
+    & X = T
+    & q(X, Y)
+    ),
+    io.print(Y, !IO),
+    io.nl(!IO).
+
+:- pred q(t::in, t::out) is det.
+:- pragma no_inline(q/2).
+q(X, X).
Index: tests/par_conj/dep_par_21.m
===================================================================
RCS file: tests/par_conj/dep_par_21.m
diff -N tests/par_conj/dep_par_21.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_21.m	21 Jun 2006 04:14:02 -0000
@@ -0,0 +1,33 @@
+% from primes.m
+%
+% Uncaught Mercury exception:
+% Software Error: instmap.m: Unexpected: merge_instmapping_delta_2: error
+% merging var 9
+%
+
+:- module dep_par_21.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+:- import_module list.
+
+main(!IO) :-
+    remove(3, 1..5, Res),
+    io.print(Res, !IO),
+    io.nl(!IO).
+
+:- pred remove(int::in, list(int)::in, list(int)::out) is det.
+
+remove(_P, [], []).
+remove(P, [I | Is], Result) :-
+    M is I mod P &
+    ( M = 0 ->
+	Result = Nis &
+	remove(P, Is, Nis)
+    ;
+	Result = [I | Nis] &
+	remove(P, Is, Nis)
+    ).
Index: tests/par_conj/dep_par_22.m
===================================================================
RCS file: tests/par_conj/dep_par_22.m
diff -N tests/par_conj/dep_par_22.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_22.m	19 Jun 2006 10:40:32 -0000
@@ -0,0 +1,35 @@
+%
+% The switch was not detected.
+% 
+% par22.m:001: Warning: interface for module `par22' does not export anything.
+% par22.m:018: Error: parallel conjunct may fail. The current implementation
+% par22.m:018:   supports only single-solution non-failing parallel conjunctions.
+% par22.m:019:   Unification of `T' and `par22.up' can fail.
+% par22.m:020:   Unification of `T' and `par22.down' can fail.
+% par22.m:020:   Disjunction has multiple clauses with solutions.
+%
+
+:- module dep_par_22.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+main(!IO) :-
+    p(up, X),
+    io.print(X, !IO),
+    io.nl(!IO).
+
+:- type t
+    --->    up
+    ;	    down.
+
+:- pred p(t::in, t::out) is det.
+
+p(T0, X) :-
+    T = T0
+    &
+    ( T = up, X = up
+    ; T = down, X = down
+    ).
Index: tests/par_conj/dep_par_23.m
===================================================================
RCS file: tests/par_conj/dep_par_23.m
diff -N tests/par_conj/dep_par_23.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_23.m	19 Jun 2006 10:40:32 -0000
@@ -0,0 +1,16 @@
+% parallel conjunction inside higher order term
+
+:- module dep_par_23.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+:- import_module list.
+
+main(!IO) :-
+    L0 = [1, 2, 3],
+    L = list.map((func(X) = Y :- Z=X+1 & Y=Z+1), L0),
+    io.print(L, !IO),
+    io.nl(!IO).
Index: tests/par_conj/dep_par_3.m
===================================================================
RCS file: tests/par_conj/dep_par_3.m
diff -N tests/par_conj/dep_par_3.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_3.m	21 Jun 2006 04:01:17 -0000
@@ -0,0 +1,22 @@
+% function call
+
+:- module dep_par_3.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    (
+	X = 1
+    &
+	Y = f(X)
+    ),
+    io.write_int(X*Y, !IO),
+    io.nl(!IO).
+
+:- func f(int) = int.
+:- pragma no_inline(f/1).
+f(X) = (if X = 1 then 2 else 0).
Index: tests/par_conj/dep_par_3b.m
===================================================================
RCS file: tests/par_conj/dep_par_3b.m
diff -N tests/par_conj/dep_par_3b.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_3b.m	21 Jun 2006 04:17:05 -0000
@@ -0,0 +1,22 @@
+% if-then-else expression
+
+:- module dep_par_3b.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    (
+	X = 1
+    &
+	Y = (if f(X) then 2 else 0)
+    ),
+    io.write_int(Y, !IO),
+    io.nl(!IO).
+
+:- pred f(int::in) is semidet.
+:- pragma no_inline(f/1).
+f(1).
Index: tests/par_conj/dep_par_3c.m
===================================================================
RCS file: tests/par_conj/dep_par_3c.m
diff -N tests/par_conj/dep_par_3c.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_3c.m	21 Jun 2006 04:17:13 -0000
@@ -0,0 +1,22 @@
+% if-then-else expression
+
+:- module dep_par_3c.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    (
+	X = 1
+    &
+	Y = (if f(X) then 2 else 0)
+    ),
+    io.write_int(X+Y, !IO),
+    io.nl(!IO).
+
+:- pred f(int::in) is semidet.
+:- pragma no_inline(f/1).
+f(1).
Index: tests/par_conj/dep_par_4.m
===================================================================
RCS file: tests/par_conj/dep_par_4.m
diff -N tests/par_conj/dep_par_4.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_4.m	21 Jun 2006 04:00:04 -0000
@@ -0,0 +1,22 @@
+% function call
+
+:- module dep_par_4.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    V = 1,
+    (
+	X = f(V)
+    &
+	Y = f(X)
+    ),
+    io.print(Y, !IO),
+    io.nl(!IO).
+
+:- func f(int) = int.
+f(X) = X+1.
Index: tests/par_conj/dep_par_5.m
===================================================================
RCS file: tests/par_conj/dep_par_5.m
diff -N tests/par_conj/dep_par_5.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_5.m	19 Jun 2006 10:42:41 -0000
@@ -0,0 +1,17 @@
+% IO
+
+:- module dep_par_5.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    (
+	U = 1
+    &
+	io.write_int(U, !IO)
+    ),
+    io.nl(!IO).
Index: tests/par_conj/dep_par_5b.m
===================================================================
RCS file: tests/par_conj/dep_par_5b.m
diff -N tests/par_conj/dep_par_5b.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_5b.m	19 Jun 2006 11:43:38 -0000
@@ -0,0 +1,17 @@
+% IO
+
+:- module dep_par_5b.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    (
+	io.write_int(1, !IO)
+    &
+	io.write_int(2, !IO)
+    ),
+    io.nl(!IO).
Index: tests/par_conj/dep_par_5c.m
===================================================================
RCS file: tests/par_conj/dep_par_5c.m
diff -N tests/par_conj/dep_par_5c.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_5c.m	21 Jun 2006 04:02:44 -0000
@@ -0,0 +1,17 @@
+% IO, uniqueness
+
+:- module dep_par_5c.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(IO0, IO) :-
+    (
+	io.write_int(1, IO0, IO1),
+	io.nl(IO1, IO)
+    &
+	true
+    ).
Index: tests/par_conj/dep_par_5d.m
===================================================================
RCS file: tests/par_conj/dep_par_5d.m
diff -N tests/par_conj/dep_par_5d.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_5d.m	21 Jun 2006 04:02:53 -0000
@@ -0,0 +1,17 @@
+% IO, uniqueness
+
+:- module dep_par_5d.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(IO0, IO) :-
+    (
+	io.write_int(1, IO0, IO1)
+    ,
+	io.write_int(2, IO1, IO2),
+	io.nl(IO2, IO)
+    ).
Index: tests/par_conj/dep_par_6.m
===================================================================
RCS file: tests/par_conj/dep_par_6.m
diff -N tests/par_conj/dep_par_6.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_6.m	21 Jun 2006 04:00:20 -0000
@@ -0,0 +1,19 @@
+% inner disjunction
+
+:- module dep_par_6.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is cc_multi.
+
+:- implementation.
+
+main(!IO) :-
+    (
+	( X = 1
+	; X = 2
+	)
+    &
+	Y = X
+    ),
+    io.print(Y, !IO),
+    io.nl(!IO).
Index: tests/par_conj/dep_par_7.m
===================================================================
RCS file: tests/par_conj/dep_par_7.m
diff -N tests/par_conj/dep_par_7.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_7.m	21 Jun 2006 04:03:25 -0000
@@ -0,0 +1,19 @@
+% outer disjunction
+
+:- module dep_par_7.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is cc_multi.
+
+:- implementation.
+
+main(IO0, IO) :-
+    ( 
+	( X = 1
+	& Y = X
+	)
+    ;
+	Y = 2
+    ),
+    io.write_int(Y, IO0, IO1),
+    io.nl(IO1, IO).
Index: tests/par_conj/dep_par_8.m
===================================================================
RCS file: tests/par_conj/dep_par_8.m
diff -N tests/par_conj/dep_par_8.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_8.m	21 Jun 2006 04:03:51 -0000
@@ -0,0 +1,21 @@
+% cc_multi
+
+:- module dep_par_8.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is cc_multi.
+
+:- implementation.
+:- import_module int.
+:- import_module list.
+
+main(IO0, IO) :-
+    ( 
+	( member(X, [1,2,3])
+	; X = 0
+	)
+    &
+	Y = X
+    ),
+    io.write_int(Y, IO0, IO1),
+    io.nl(IO1, IO).
Index: tests/par_conj/dep_par_9.m
===================================================================
RCS file: tests/par_conj/dep_par_9.m
diff -N tests/par_conj/dep_par_9.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/dep_par_9.m	19 Jun 2006 10:41:43 -0000
@@ -0,0 +1,27 @@
+% higher-order
+
+:- module dep_par_9.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    HO = get_ho,
+    (
+	X = HO(1)
+    &
+	Y = HO(X)
+    ),
+    io.print(X*Y, !IO),
+    io.nl(!IO).
+
+:- func get_ho = (func(int) = int).
+:- pragma no_inline(get_ho/0).
+get_ho = my_ho.
+
+:- func my_ho(int) = int.
+:- pragma no_inline(my_ho/1).
+my_ho(X) = X+1.
Index: tests/par_conj/indep_par_append.exp
===================================================================
RCS file: tests/par_conj/indep_par_append.exp
diff -N tests/par_conj/indep_par_append.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/indep_par_append.exp	21 Jun 2006 07:45:55 -0000
@@ -0,0 +1 @@
+[1, 2, 3, 4, 5, 6, 4, 5, 6, 1, 2, 3]
Index: tests/par_conj/indep_par_append.m
===================================================================
RCS file: tests/par_conj/indep_par_append.m
diff -N tests/par_conj/indep_par_append.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/indep_par_append.m	21 Jun 2006 04:17:32 -0000
@@ -0,0 +1,18 @@
+% append
+
+:- module indep_par_append.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module list.
+main(!IO) :-
+    As = [1, 2, 3],
+    Bs = [4, 5, 6],
+    ( append(As, Bs, Cs)
+    & append(Bs, As, Ds)
+    ),
+    append(Cs, Ds, Es),
+    io.print(Es, !IO),
+    io.nl(!IO).
Index: tests/par_conj/indep_par_nested.exp
===================================================================
RCS file: tests/par_conj/indep_par_nested.exp
diff -N tests/par_conj/indep_par_nested.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/indep_par_nested.exp	21 Jun 2006 07:46:50 -0000
@@ -0,0 +1 @@
+{100, 101, 102, 103, 200, 201, 202, 203, 300, 301, 302, 303}
Index: tests/par_conj/indep_par_nested.m
===================================================================
RCS file: tests/par_conj/indep_par_nested.m
diff -N tests/par_conj/indep_par_nested.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/indep_par_nested.m	19 Jun 2006 10:37:55 -0000
@@ -0,0 +1,39 @@
+:- module indep_par_nested.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(!IO) :-
+    (
+        A = 100,
+        (
+            B = A + 1
+        &
+            C = A + 2
+        &
+            D = A + 3
+        )
+    &
+        E = 200,
+        (
+            F = E + 1
+        &
+            G = E + 2
+        &
+            H = E + 3
+        )
+    &
+        I = 300,
+        (
+            J = I + 1
+        &
+            K = I + 2
+        &
+            L = I + 3
+        )
+    ),
+    io.print({A,B,C,D,E,F,G,H,I,J,K,L}, !IO),
+    io.nl(!IO).
Index: trace/RESERVED_MACRO_NAMES
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/RESERVED_MACRO_NAMES,v
retrieving revision 1.2
diff -u -r1.2 RESERVED_MACRO_NAMES
--- trace/RESERVED_MACRO_NAMES	15 Dec 2004 06:58:00 -0000	1.2
+++ trace/RESERVED_MACRO_NAMES	21 Jun 2006 11:52:11 -0000
@@ -31,6 +31,7 @@
 __GC
 _GC_H
 HIDE_POINTER
+LINUX_THREADS
 REVEAL_POINTER
 #-----------------------------------------------------------------------------#
 # This is defined by mps_gc/code/mercury_mps.h,
@@ -60,3 +61,7 @@
 __EXTENSIONS__
 __OPTIMIZE__
 #-----------------------------------------------------------------------------#
+# These are defined in when threads are enabled.
+_REENTRANT
+_THREAD_SAFE
+#-----------------------------------------------------------------------------#
--------------------------------------------------------------------------
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