[m-rev.] diff: move library changes on the mode-constraints branch onto trunk

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed Feb 26 19:53:48 AEDT 2003


An earlier version of this diff has been reviewed already late last year.
This version addresses the review comments and handles changes on the trunk
since then.

By far the biggest part of the diff is the change to robdd/bryant.c. David
Overton or Peter Schachte may want to look at that, but I doubt if anyone
else would be interested.

Zoltan.

Move changes in the library on the mode-constraints branch onto the trunk.

library/eqvclass.m:
	Add some utility functions and predicates.

library/map.m:
	Add some utility functions and predicates, and some type
	specialization directives.

library/tree234.m:
	Add some utility functions and predicates.

library/robdd.m:
	Add this module, which provides a Mercury interface to the C code in
	robdd/bryant.c. In some places, robustness has been sacrificed for
	speed, and the module is not (yet) as well documented as it could be;
	therefore it is not (yet) included in the documentation.

library/pprint.m:
	Print robdds nicely, since this is essential to debugging code handling
	robdds. (This is why adding robdd.m in some other directory, e.g. the
	compiler, wouldn't really work.)

library/term.m:
	Add a function that returns the highest numbered vars created from
	a var_supply.

library/varset.m:
	Add a function that returns the highest numbered vars created from
	a varset.

library/unsafe.m:
	Add this module here, since it may be needed to debug code in the
	library (e.g. in robdd.m.).

library/library.m:
	Add a reference to the robdd module, and a commented out reference
	to the unsafe module. If a developer needs to use unsafe.m anywhere
	in the Mercury implementation, they can uncomment this reference
	in the relevant workspace.

	Make the list of modules easier to maintain (especially in the case
	of CVS conflicts) by listing one module per line.

	Fix formatting of some foreign_procs.

NEWS:
	Mention the new predicates and functions.

Mmake.workspace:
	Add a new make variable that specifies the location of the robdd
	subdirectory.

Mmakefile:
	Add rules for handling the robdd subdirectory.

tools/bootcheck:
	Add the robdd subdirectory to the stage 2 & 3 directories.

deep_profiler/unsafe.m:
	Remove this module from this directory.

doc/Mmakefile:
	Do not include the robdd and unsafe modules in the documentation.
	The robdd module because (in its present state) it is not stable
	enough, the unsafe module because it is not enabled in installed
	versions of the library.

robdd/Makefile:
	Update the set of default compilation flags. The main code in this
	directory, bryant.c, is #included in library/robdd.m, and the only
	other programs in this directory are test programs.

robdd/Mmakefile:
	New file. Includes a mechanism to compile bryant.c in the robdd
	subdirectory, since this can give cleaner error messages than
	compiling library/robdd.m.
	
robdd/bryant.[ch]:
	Huge cleanup of these files. Add MR_ROBDD_ prefixes to global symbols,
	make the formatting conform to our standards, and fix irregularities
	in the uses of the macros that control the use of optional facilities.

robdd/bryantPrint.[ch]:
robdd/table.[ch]:
robdd/test_abexit.c:
robdd/test_abunify.c:
robdd/test_abglb.c:
robdd/test_iff.c:
robdd/test_rename.c:
robdd/test_restrict.c:
robdd/test_rglb.c:
robdd/test_upclose.c:
robdd/test_var.c:
robdd/test_vars.c:
robdd/timing.[ch]:
robdd/var.h:
	Conform to the changes in bryant.h. Note that since the code in these
	files won't end up in Mercury program code, they don't need to be
	namespace clean.

runtime/mercury.h:
runtime/mercury_heap.h:
runtime/mercury_init.h:
runtime/mercury_memory.h:
	Define GC_I_HIDE_POINTERS before each #include of gc.h (bryant.c
	hides pointers).

runtime/RESERVED_MACRO_NAMES:
	Add HIDE_POINTER and REVEAL_POINTER, since defining GC_I_HIDE_POINTERS
	makes these macros from gc.h visible.

runtime/mercury_reg_workarounds.[ch]:
	Add the MR_memset function.

cvs diff: Diffing .
Index: Mmake.workspace
===================================================================
RCS file: /home/mercury1/repository/mercury/Mmake.workspace,v
retrieving revision 1.12
diff -u -b -r1.12 Mmake.workspace
--- Mmake.workspace	13 Feb 2003 08:28:42 -0000	1.12
+++ Mmake.workspace	19 Feb 2003 04:04:38 -0000
@@ -54,6 +54,7 @@
 MPS_GC_DIR = $(WORKSPACE)/mps_gc/code
 COMPILER_DIR = $(WORKSPACE)/compiler
 UTIL_DIR = $(WORKSPACE)/util
+ROBDD_DIR = $(WORKSPACE)/robdd
 ANALYSIS_DIR = $(WORKSPACE)/analysis
 
 # Specify the MPS "platform"
Index: Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/Mmakefile,v
retrieving revision 1.97
diff -u -b -r1.97 Mmakefile
--- Mmakefile	6 Feb 2003 17:05:02 -0000	1.97
+++ Mmakefile	11 Feb 2003 02:45:22 -0000
@@ -27,6 +27,7 @@
 		util \
 		boehm_gc \
 		runtime \
+		robdd \
 		library \
 		trace \
 		browser \
@@ -155,6 +156,10 @@
 .PHONY: runtime
 runtime: scripts boehm_gc
 	+cd runtime && $(SUBDIR_MMAKE)
+
+.PHONY: robdd
+robdd: scripts boehm_gc
+	cd robdd && $(SUBDIR_MMAKE)
 
 .PHONY: library
 library: dep_library scripts util boehm_gc runtime
Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.304
diff -u -b -r1.304 NEWS
--- NEWS	24 Feb 2003 05:49:27 -0000	1.304
+++ NEWS	26 Feb 2003 08:05:55 -0000
@@ -108,6 +108,18 @@
   These have been replaced by cc_multi versions in which success or failure
   is indicated by returning a maybe type.
 
+* We've added functions get_equivalent_elements, get_minimum_element and 
+  remove_equivalent_elements, and their predicate versions, to eqvclass.m.
+
+* We've added semidet functions max_key and min_key to return the maximum and
+  minimum keys in maps and 2-3-4 trees.
+
+* We've added predicates member, remove_leq, remove_gt, foldl and filter
+  to sparse_bitset.m.
+
+* builtin.m now contains types and insts `unify' and `compare' for use
+  in defining user-defined equality and comparison predicates.
+
 * The following predicates, which were added in 0.11.0, have been deprecated:
 	io.current_input_stream/3
 	io.current_output_stream/3
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
Index: deep_profiler/unsafe.m
===================================================================
RCS file: deep_profiler/unsafe.m
diff -N deep_profiler/unsafe.m
--- deep_profiler/unsafe.m	7 Aug 2002 01:43:29 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,84 +0,0 @@
-%-----------------------------------------------------------------------------%
-% Copyright (C) 1997 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: unsafe.m
-% Author: fjh
-% Stability: low
-%-----------------------------------------------------------------------------%
-
-/*
-** WARNING: the procedures defined in this module are non-logical.
-**          They may have side effects, they may violate type safety,
-**	    they may interfere with certain memory management strategies,
-**	    and in general they may do lots of nasty things.
-**	    They may not work with future release of the Mercury compiler,
-**	    or with other Mercury implementations.
-**          Use only as a last resort, and only with great care!
-**
-** You have been warned.
-*/
-
-%-----------------------------------------------------------------------------%
-
-:- module unsafe.
-:- interface.
-:- import_module io.
-
-/*
-** unsafe_perform_io/1 performs I/O, in an unsafe manner.
-** It can be used to call a goal that does I/O or has
-** side effects from a context where you do not have an io__state.
-** It can be useful for printf-style debugging.
-** But backtracking over a call to `unsafe_perform_io'
-** can be very dangerous indeed, because with certain
-** memory allocation policies it can result in dangling pointers.
-*/
-:- impure pred unsafe_perform_io(pred(io__state, io__state)).
-:- mode unsafe_perform_io(pred(di, uo) is det) is det.
-:- mode unsafe_perform_io(pred(di, uo) is cc_multi) is det.
-
-/*
-** The function unsafe_promise_ground/1 can be used to assert to the
-** compiler that a particular value of inst `any' is in fact ground.
-** The assertion is *not* checked.  If it is false, all hell may break out.
-*/
-:- func unsafe_promise_ground(T::in(any)) = (T::out) is det.
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-:- implementation.
-
-%-----------------------------------------------------------------------------%
-
-:- pragma c_code(unsafe_promise_ground(X::in(any)) = (Y::out), "Y = X;").
-
-%-----------------------------------------------------------------------------%
-
-:- pragma c_code(
-unsafe_perform_io(P::(pred(di, uo) is det)),
-	may_call_mercury,
-"{
-	call_io_pred_det(P);
-}").
-:- pragma c_code(
-unsafe_perform_io(P::(pred(di, uo) is cc_multi)),
-	may_call_mercury,
-"{
-	call_io_pred_cc_multi(P);
-}").
-
-:- pred call_io_pred(pred(io__state, io__state), io__state, io__state).
-:- mode call_io_pred(pred(di, uo) is det, di, uo) is det.
-:- mode call_io_pred(pred(di, uo) is cc_multi, di, uo) is cc_multi.
-
-:- pragma export(call_io_pred(pred(di, uo) is det, di, uo),
-		"call_io_pred_det").
-:- pragma export(call_io_pred(pred(di, uo) is cc_multi, di, uo),
-		"call_io_pred_cc_multi").
-
-call_io_pred(P) --> P.
-
-%-----------------------------------------------------------------------------%
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/Mmakefile,v
retrieving revision 1.34
diff -u -b -r1.34 Mmakefile
--- doc/Mmakefile	24 Jan 2003 07:17:09 -0000	1.34
+++ doc/Mmakefile	27 Jan 2003 23:46:46 -0000
@@ -220,6 +220,10 @@
 				;;					\
 			$(LIBRARY_DIR)/table_builtin.m)			\
 				;;					\
+			$(LIBRARY_DIR)/robdd.m)				\
+				;;					\
+			$(LIBRARY_DIR)/unsafe.m)			\
+				;;					\
 			*)						\
 				echo "* `basename $$filename .m`::"; 	\
 				;;					\
@@ -239,6 +243,10 @@
 			$(LIBRARY_DIR)/rtti_implementation.m)		\
 				;;					\
 			$(LIBRARY_DIR)/table_builtin.m)			\
+				;;					\
+			$(LIBRARY_DIR)/robdd.m)				\
+				;;					\
+			$(LIBRARY_DIR)/unsafe.m)			\
 				;;					\
 			*)						\
 				file="`basename $$filename .m`"; 	\
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing java
cvs diff: Diffing java/library
cvs diff: Diffing java/runtime
cvs diff: Diffing library
Index: library/eqvclass.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/eqvclass.m,v
retrieving revision 1.11
diff -u -b -r1.11 eqvclass.m
--- library/eqvclass.m	12 Nov 2000 08:51:33 -0000	1.11
+++ library/eqvclass.m	3 Jan 2003 05:16:36 -0000
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 1995-1997, 1999 The University of Melbourne.
+% Copyright (C) 1995-1997, 1999, 2003 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.
 %---------------------------------------------------------------------------%
@@ -106,6 +106,30 @@
 
 :- func eqvclass__partition_list_to_eqvclass(list(set(T))) = eqvclass(T).
 
+	% Return the set of elements equivalent to the given element.
+	% This set will of course include the given element.
+
+:- pred eqvclass__get_equivalent_elements(eqvclass(T), T, set(T)).
+:- mode eqvclass__get_equivalent_elements(in, in, out) is det.
+
+:- func eqvclass__get_equivalent_elements(eqvclass(T), T) = set(T).
+
+	% Return the smallest element equivalent to the given element.
+	% This may or may not be the given element.
+
+:- pred eqvclass__get_minimum_element(eqvclass(T), T, T).
+:- mode eqvclass__get_minimum_element(in, in, out) is det.
+
+:- func eqvclass__get_minimum_element(eqvclass(T), T) = T.
+
+	% Remove the given element and all other elements equivalent to it
+	% from the given equivalence class.
+
+:- pred eqvclass__remove_equivalent_elements(eqvclass(T), T, eqvclass(T)).
+:- mode eqvclass__remove_equivalent_elements(in, in, out) is det.
+
+:- func eqvclass__remove_equivalent_elements(eqvclass(T), T) = eqvclass(T).
+
 %---------------------------------------------------------------------------%
 
 :- implementation.
@@ -315,6 +339,23 @@
 	eqvclass__make_partition(Elements, Id, ElementMap1, ElementMap).
 
 %---------------------------------------------------------------------------%
+
+eqvclass__get_equivalent_elements(EC, X,
+		eqvclass__get_equivalent_elements(EC, X)).
+
+eqvclass__get_minimum_element(EC, X, eqvclass__get_minimum_element(EC, X)).
+
+eqvclass__remove_equivalent_elements(eqvclass(Id, P0, E0), X,
+		eqvclass(Id, P, E)) :-
+	( map__search(E0, X, Partition) ->
+		map__det_remove(P0, Partition, Eq, P),
+		map__delete_list(E0, set__to_sorted_list(Eq), E)
+	;
+		P = P0,
+		E = E0
+	).
+
+%---------------------------------------------------------------------------%
 %---------------------------------------------------------------------------%
 % Ralph Becket <rwab1 at cl.cam.ac.uk> 29/04/99
 % 	Function forms added.
@@ -345,3 +386,17 @@
 
 eqvclass__partition_list_to_eqvclass(Xs) = EC :-
 	eqvclass__partition_list_to_eqvclass(Xs, EC).
+
+eqvclass__get_equivalent_elements(eqvclass(_, PartitionMap, ElementMap), X) =
+	( Eqv = map__search(PartitionMap, map__search(ElementMap, X)) ->
+		Eqv
+	;
+		set__make_singleton_set(X)
+	).
+
+eqvclass__get_minimum_element(EC, X) =
+	list__det_head(set__to_sorted_list(
+			eqvclass__get_equivalent_elements(EC, X))).
+
+eqvclass__remove_equivalent_elements(EC0, X) = EC :-
+	eqvclass__remove_equivalent_elements(EC0, X, EC).
Index: library/library.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/library.m,v
retrieving revision 1.67
diff -u -b -r1.67 library.m
--- library/library.m	22 Feb 2003 11:17:35 -0000	1.67
+++ library/library.m	26 Feb 2003 07:50:07 -0000
@@ -30,21 +30,80 @@
 % Please keep both parts of this list in alphabetical order.
 
 % The modules intended for application programmers.
-:- import_module array, array2d, assoc_list, bag, benchmarking.
-:- import_module bimap, bintree, bintree_set, bitmap, bool, bt_array, builtin.
-:- import_module char, construct, cord, counter, deconstruct, dir.
-:- import_module enum, eqvclass, exception.
-:- import_module float, gc, getopt, graph, group, hash_table.
-:- import_module int, integer, io, lexer, list, map, math, multi_map, ops.
-:- import_module parser, pprint, pqueue, prolog, queue.
-:- import_module random, rational, rbtree, relation, require.
-:- import_module set, set_bbbtree, set_ordlist, set_unordlist, sparse_bitset.
-:- import_module stack, std_util, store, string.
-:- import_module term, term_io, tree234, time, type_desc, varset.
+:- import_module array.
+:- import_module array2d.
+:- import_module assoc_list.
+:- import_module bag.
+:- import_module benchmarking.
+:- import_module bimap.
+:- import_module bintree.
+:- import_module bintree_set.
+:- import_module bitmap.
+:- import_module bool.
+:- import_module bt_array.
+:- import_module builtin.
+:- import_module char.
+:- import_module construct.
+:- import_module counter.
+:- import_module cord.
+:- import_module deconstruct.
+:- import_module dir.
+:- import_module enum.
+:- import_module eqvclass.
+:- import_module exception.
+:- import_module float.
+:- import_module gc.
+:- import_module getopt.
+:- import_module graph.
+:- import_module group.
+:- import_module hash_table.
+:- import_module int.
+:- import_module integer.
+:- import_module io.
+:- import_module lexer.
+:- import_module list.
+:- import_module map.
+:- import_module math.
+:- import_module multi_map.
+:- import_module ops.
+:- import_module parser.
+:- import_module pprint.
+:- import_module pqueue.
+:- import_module prolog.
+:- import_module queue.
+:- import_module random.
+:- import_module rational.
+:- import_module rbtree.
+:- import_module relation.
+:- import_module require.
+:- import_module robdd.
+:- import_module set.
+:- import_module set_bbbtree.
+:- import_module set_ordlist.
+:- import_module set_unordlist.
+:- import_module sparse_bitset.
+:- import_module stack.
+:- import_module std_util.
+:- import_module store.
+:- import_module string.
+:- import_module term.
+:- import_module term_io.
+:- import_module time.
+:- import_module tree234.
+:- import_module type_desc.
+:- import_module varset.
 
 % The modules intended for Mercury system implementors.
-:- import_module private_builtin, table_builtin, profiling_builtin.
+:- import_module private_builtin.
+:- import_module profiling_builtin.
 :- import_module rtti_implementation.
+:- import_module table_builtin.
+
+% Uncomment this temporarily (in your own workspace) if you need access to
+% unsafe predicates. In MLDS grades, you would also have to add unsafe to 
+% the list in mercury_std_library_module in the compiler you use to compile
+% the library.
+% :- import_module unsafe.
 
 % library__version must be implemented using pragma c_code,
 % so we can get at the MR_VERSION and MR_FULLARCH configuration
@@ -53,7 +112,8 @@
 % might not have a Mercury compiler around to compile library.m with.
 
 :- pragma foreign_proc("C",
-	library__version(Version::out), [will_not_call_mercury, promise_pure],
+	library__version(Version::out),
+	[will_not_call_mercury, promise_pure],
 "
 	MR_ConstString version_string = 
 		MR_VERSION "", configured for "" MR_FULLARCH;
@@ -69,7 +129,8 @@
 ").
 
 :- pragma foreign_proc("MC++",
-	library__version(Version::out), [will_not_call_mercury, promise_pure],
+	library__version(Version::out),
+	[will_not_call_mercury, promise_pure],
 "
 	// XXX we should use string literals with an S at the start
 	// so this code uses just managed types.
Index: library/map.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/map.m,v
retrieving revision 1.81
diff -u -b -r1.81 map.m
--- library/map.m	19 Aug 2002 06:33:16 -0000	1.81
+++ library/map.m	19 Aug 2002 07:42:51 -0000
@@ -84,6 +84,12 @@
 :- pred map__upper_bound_lookup(map(K,V), K, K, V).
 :- mode map__upper_bound_lookup(in, in, out, out) is det.
 
+	% Return the largest key in the map, if there is one.
+:- func map__max_key(map(K,V)) = K is semidet.
+
+	% Return the smallest key in the map, if there is one.
+:- func map__min_key(map(K,V)) = K is semidet.
+
 	% Search map for data.
 :- pred map__inverse_search(map(K,V), V, K).
 :- mode map__inverse_search(in, in, out) is nondet.
@@ -411,6 +417,19 @@
 :- pragma type_spec(map__select/2, K = var(_)).
 :- pragma type_spec(map__select/3, K = var(_)).
 
+:- pragma type_spec(map__elem/2, K = int).
+:- pragma type_spec(map__elem/2, K = var(_)).
+
+:- pragma type_spec(map__det_elem/2, K = int).
+:- pragma type_spec(map__det_elem/2, K = var(_)).
+
+:- pragma type_spec('map__elem :='/3, K = int).
+:- pragma type_spec('map__elem :='/3, K = var(_)).
+
+:- pragma type_spec('map__det_elem :='/3, K = int).
+:- pragma type_spec('map__det_elem :='/3, K = var(_)).
+
+
 :- implementation.
 :- import_module std_util, require, string.
 
@@ -462,6 +481,10 @@
 		report_lookup_error("map__upper_bound_lookup: key not found",
 			SearchK, V)
 	).
+
+map__max_key(M) = tree234__max_key(M).
+
+map__min_key(M) = tree234__min_key(M).
 
 map__insert(Map0, K, V, Map) :-
 	tree234__insert(Map0, K, V, Map).
Index: library/pprint.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/pprint.m,v
retrieving revision 1.13
diff -u -b -r1.13 pprint.m
--- library/pprint.m	7 Feb 2003 03:55:36 -0000	1.13
+++ library/pprint.m	11 Feb 2003 05:44:07 -0000
@@ -370,7 +370,8 @@
 
 :- implementation.
 
-:- import_module array, map, sparse_bitset, enum, term, exception, ops.
+:- import_module array, map, sparse_bitset, enum, term, exception.
+:- import_module ops, robdd.
 
 :- type doc
     --->    'NIL'
@@ -687,6 +688,9 @@
       else if dynamic_cast_to_map_pair(X, MapPair)
       then    map_pair_to_doc(Depth, MapPair)
 
+      else if dynamic_cast_to_robdd(X, Robdd)
+      then    robdd_to_doc(Depth, Robdd)
+
       else    generic_term_to_doc(Depth, Priority, X)
     ).
 
@@ -956,6 +960,26 @@
 
 %-----------------------------------------------------------------------------%
 
+:- some [T2] pred dynamic_cast_to_robdd(T1, robdd(T2)).
+:-           mode dynamic_cast_to_robdd(in, out) is semidet.
+
+dynamic_cast_to_robdd(X, R) :-
+
+        % If X is a robdd then it has a type with one type argument.
+        %
+    [ArgTypeDesc] = type_args(type_of(X)),
+
+        % Convert ArgTypeDesc to a type variable ArgType.
+        %
+    (_ `with_type` ArgType) `has_type` ArgTypeDesc,
+
+        % Constrain the type of R to be robdd(ArgType) and do the
+        % cast.
+        %
+    dynamic_cast(X, R `with_type` robdd(ArgType)).
+
+%-----------------------------------------------------------------------------%
+
 :- func var_to_doc(int, var(T)) = doc.
 
 var_to_doc(Depth, V) =
@@ -1019,5 +1043,12 @@
 map_pair_to_doc(Depth, map_pair(Key, Value)) =
     to_doc(Depth - 1, Key) ++ text(" -> ") ++
         group(nest(2, line ++ to_doc(Depth - 1, Value))).
+
+%-----------------------------------------------------------------------------%
+
+:- func robdd_to_doc(int, robdd(T)) = doc.
+
+robdd_to_doc(Depth, R) =
+    "robdd_dnf" ++ parentheses(list_to_doc(Depth, dnf(R))).
 
 %-----------------------------------------------------------------------------%
Index: library/robdd.m
===================================================================
RCS file: library/robdd.m
diff -N library/robdd.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ library/robdd.m	6 Jan 2003 02:16:23 -0000
@@ -0,0 +1,1463 @@
+%---------------------------------------------------------------------------%
+% Copyright (C) 2001-2003 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: robdd.m.
+% Main author: dmo
+% Stability: low
+
+% This module contains a Mercury interface to Peter Schachte's C
+% implementation of Reduced Ordered Binary Decision Diagrams (ROBDDs).
+% ROBDDs are an efficent representation for Boolean constraints.
+
+% Boolean variables are represented using the type var(T) from the
+% `term' library module (see the `term' module documentation for
+% more information).
+
+% Example usage:
+%	% Create some variables.
+% 	term__init_var_supply(VarSupply0),
+%	term__create_var(VarSupply0, A, VarSupply1),
+%	term__create_var(VarSupply1, B, VarSupply2),
+%	term__create_var(VarSupply2, C, VarSupply),
+%	
+%	% Create some ROBDDs.
+%	R1 = ( var(A) =:= var(B) * (~var(C)) ),
+%	R2 = ( var(A) =< var(B) ),
+%	
+%	% Test if R1 entails R2 (should succeed).
+%	R1 `entails` R2,
+%
+%	% Project R1 onto A and B.
+%	R3 = restrict(C, R1),
+%
+%	% Test R2 and R3 for equivalence (should succeed).
+%	R2 = R3.
+
+% ROBDDs are implemented so that two ROBDDs, R1 and R2, represent
+% the same Boolean constraint if and only iff `R1 = R2'. Checking
+% equivalence of ROBDDs is fast since it involves only a single
+% pointer comparison.
+
+% XXX This module is not yet sufficiently well tested or documented to be
+% included in the publically available part of the library, so at the moment
+% it is not included in the list of modules mentioned in the library manual.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- module robdd.
+
+:- interface.
+
+:- import_module term, io, sparse_bitset, list, map.
+
+:- type robdd(T).
+:- type robdd == robdd(generic).
+
+:- type vars(T) == sparse_bitset(var(T)). % XXX experiment with different reps.
+
+:- func empty_vars_set = vars(T).
+
+% Constants.
+:- func one = robdd(T).
+:- func zero = robdd(T).
+
+% If-then-else.
+:- func ite(robdd(T), robdd(T), robdd(T)) = robdd(T).
+
+% The functions *, +, =<, =:=, =\= and ~ correspond to the names
+% used in the SICStus clp(B) library.
+
+% Conjunction.
+:- func robdd(T) * robdd(T) = robdd(T).
+
+% Disjunction.
+:- func robdd(T) + robdd(T) = robdd(T).
+
+% Implication.
+:- func (robdd(T) =< robdd(T)) = robdd(T).
+
+% Equivalence.
+:- func (robdd(T) =:= robdd(T)) = robdd(T).
+
+% Non-equivalence (XOR).
+:- func (robdd(T) =\= robdd(T)) = robdd(T).
+
+% Negation.
+:- func (~ robdd(T)) = robdd(T).
+
+%-----------------------------------------------------------------------------%
+
+	% var(X) is the ROBDD that is true iff X is true.
+:- func var(var(T)) = robdd(T).
+
+% The following functions operate on individual variables and are
+% more efficient than the more generic versions above that take
+% ROBDDs as input.
+
+	% not_var(V) = ~ var(V).
+:- func not_var(var(T)) = robdd(T).
+
+	% ite_var(V, FA, FB) = ite(var(V), FA, FB).
+:- func ite_var(var(T), robdd(T), robdd(T)) = robdd(T).
+
+	% eq_vars(X, Y) = ( var(X) =:= var(Y) ).
+:- func eq_vars(var(T), var(T)) = robdd(T).
+
+	% neq_vars(X, Y) = ( var(X) =\= var(Y) ).
+:- func neq_vars(var(T), var(T)) = robdd(T).
+
+	% imp_vars(X, Y) = ( var(X) =< var(Y) ).
+:- func imp_vars(var(T), var(T)) = robdd(T).
+
+	% conj_vars([V1, V2, ..., Vn]) = var(V1) * var(V2) * ... * var(Vn).
+:- func conj_vars(vars(T)) = robdd(T).
+
+	% conj_not_vars([V1, V2, ..., Vn]) = not_var(V1) * ... * not_var(Vn).
+:- func conj_not_vars(vars(T)) = robdd(T).
+
+	% disj_vars([V1, V2, ..., Vn]) = var(V1) + var(V2) + ... + var(Vn).
+:- func disj_vars(vars(T)) = robdd(T).
+
+	% at_most_one_of(Vs) = 
+	%	foreach pair Vi, Vj in Vs where Vi \= Vj. ~(var(Vi) * var(Vj)).
+:- func at_most_one_of(vars(T)) = robdd(T).
+
+	% var_restrict_true(V, F) = restrict(V, F * var(V)).
+:- func var_restrict_true(var(T), robdd(T)) = robdd(T).
+
+	% var_restrict_false(V, F) = restrict(V, F * not_var(V)).
+:- func var_restrict_false(var(T), robdd(T)) = robdd(T).
+
+%-----------------------------------------------------------------------------%
+
+	% X `entails` Y
+	% 	Succeed iff X entails Y.
+	%	Does not create any new ROBDD nodes.
+:- pred robdd(T) `entails` robdd(T).
+:- mode in `entails` in is semidet.
+
+	% Succeed iff the var is entailed by the ROBDD.
+:- pred var_entailed(robdd(T)::in, var(T)::in) is semidet.
+
+	% Return the set of vars entailed by the ROBDD.
+:- func vars_entailed(robdd(T)) = vars_entailed_result(T).
+
+	% Return the set of vars disentailed by the ROBDD.
+:- func vars_disentailed(robdd(T)) = vars_entailed_result(T).
+
+	% definite_vars(R, T, F) <=> T = vars_entailed(R) /\
+	% 			     F = vars_disentailed(R)
+:- pred definite_vars(robdd(T)::in, vars_entailed_result(T)::out,
+		vars_entailed_result(T)::out) is det.
+
+:- func equivalent_vars(robdd(T)) = equivalent_result(T).
+
+:- type entailment_result(T)
+	--->	all_vars
+	;	some_vars(vars :: T).
+
+:- type vars_entailed_result(T) == entailment_result(vars(T)).
+
+:- type equivalent_result(T) == entailment_result(map(var(T), var(T))).
+
+:- func extract_implications(robdd(T)) = imp_vars(T).
+
+	% Existentially quantify away the var in the ROBDD.
+:- func restrict(var(T), robdd(T)) = robdd(T).
+
+	% Existentially quantify away all vars greater than the specified var.
+:- func restrict_threshold(var(T), robdd(T)) = robdd(T).
+
+	% Existentially quantify away all vars for which the predicate fails.
+:- func restrict_filter(pred(var(T)), robdd(T)) = robdd(T).
+:- mode restrict_filter(pred(in) is semidet, in) = out is det.
+
+	% restrict_filter(P, D, R)
+	%	Existentially quantify away all vars for which P fails,
+	%	except, if D fails for a var, do not existentially quantify
+	%	away that var or any greater than it. This means that D can be
+	%	used to set a depth limit on the existential quantification.
+:- func restrict_filter(pred(var(T)), pred(var(T)), robdd(T)) = robdd(T).
+:- mode restrict_filter(pred(in) is semidet, pred(in) is semidet, in) = out
+		is det.
+
+:- func restrict_true_false_vars(vars(T), vars(T), robdd(T)) = robdd(T).
+
+	% Given a leader map, remove all but the least variable in each
+	% equivalence class from the ROBDD.
+	% Note: the leader map MUST correspond to actual equivalences within the
+	% ROBDD, (e.g. have been produced by 'equivalent_vars/1').
+:- func squeeze_equiv(map(var(T), var(T)), robdd(T)) = robdd(T).
+
+:- func make_equiv(map(var(T), var(T))) = robdd(T).
+
+:- func expand_equiv(map(var(T), var(T)), robdd(T)) = robdd(T).
+
+:- func expand_implications(imp_vars(T), robdd(T)) = robdd(T).
+
+:- type imp_vars(T)
+	--->	imp_vars(
+			imps :: imp_map(T),		%  K =>  V  (~K \/  V)
+			rev_imps ::imp_map(T),		% ~K => ~V  ( K \/ ~V)
+			dis_imps :: imp_map(T),		%  K => ~V  (~K \/ ~V)
+			rev_dis_imps :: imp_map(T)	% ~K =>  V  ( K \/  V)
+		).
+
+:- type imp_map(T) == map(var(T), vars(T)).
+
+:- func remove_implications(imp_vars(T), robdd(T)) = robdd(T).
+
+%-----------------------------------------------------------------------------%
+
+:- type literal(T)
+	--->	pos(var(T))
+	;	neg(var(T)).
+
+	% Convert the ROBDD to disjunctive normal form.
+:- func dnf(robdd(T)) = list(list(literal(T))).
+
+% 	% Convert the ROBDD to conjunctive normal form.
+% :- func cnf(robdd(T)) = list(list(literal(T))).
+
+	% Print out the ROBDD in disjunctive normal form.
+:- pred print_robdd(robdd(T)::in, io__state::di, io__state::uo) is det.
+
+	% robdd_to_dot(ROBDD, WriteVar, FileName, IO0, IO).
+	%	Output the ROBDD in a format that can be processed by the 
+	%	graph-drawing program `dot'.
+:- pred robdd_to_dot(robdd(T)::in, write_var(T)::in(write_var),
+		string::in, io__state::di, io__state::uo) is det.
+
+	% robdd_to_dot(ROBDD, WriteVar, IO0, IO).
+	%	Output the ROBDD in a format that can be processed by the 
+	%	graph-drawing program `dot'.
+:- pred robdd_to_dot(robdd(T)::in, write_var(T)::in(write_var),
+		io__state::di, io__state::uo) is det.
+
+:- type write_var(T) == pred(var(T), io__state, io__state).
+:- inst write_var = (pred(in, di, uo) is det).
+
+	% Apply the variable substitution to the ROBDD.
+:- func rename_vars(func(var(T)) = var(T), robdd(T)) = robdd(T).
+
+	% Succeed iff ROBDD = one or ROBDD = zero.
+:- pred is_terminal(robdd(T)::in) is semidet.
+
+	% Output the number of nodes and the depth of the ROBDD.
+:- pred size(robdd(T)::in, int::out, int::out) is det.
+
+	% Output the number of nodes, the depth of the ROBDD and the
+	% variables it contains.
+:- pred size(robdd(T)::in, int::out, int::out, list(var(T))::out) is det.
+
+	% Succeed iff the var is constrained by the ROBDD.
+:- pred var_is_constrained(robdd(T)::in, var(T)::in) is semidet.
+
+	% Succeed iff all the vars in the set are constrained by the ROBDD.
+:- pred vars_are_constrained(robdd(T)::in, vars(T)::in) is semidet.
+
+%-----------------------------------------------------------------------------%
+
+	% labelling(Vars, ROBDD, TrueVars, FalseVars)
+	%	Takes a set of Vars and an ROBDD and returns a value assignment
+	%	for those Vars that is a model of the Boolean function
+	%	represented by the ROBDD.
+	%	The value assignment is returned in the two sets TrueVars (set
+	%	of variables assigned the value 1) and FalseVars (set of
+	%	variables assigned the value 0).
+	%
+	% XXX should try using sparse_bitset here.
+:- pred labelling(vars(T)::in, robdd(T)::in, vars(T)::out,
+		vars(T)::out) is nondet.
+
+	% minimal_model(Vars, ROBDD, TrueVars, FalseVars)
+	%	Takes a set of Vars and an ROBDD and returns a value assignment
+	%	for those Vars that is a minimal model of the Boolean function
+	%	represented by the ROBDD.
+	%	The value assignment is returned in the two sets TrueVars (set
+	%	of variables assigned the value 1) and FalseVars (set of
+	%	variables assigned the value 0).
+	%
+	% XXX should try using sparse_bitset here.
+:- pred minimal_model(vars(T)::in, robdd(T)::in, vars(T)::out,
+		vars(T)::out) is nondet.
+
+%-----------------------------------------------------------------------------%
+
+	% Zero the internal caches used for ROBDD operations.
+	% This allows nodes in the caches to be garbage-collected.
+	% This operation is pure and does not perform any I/O, but we need
+	% to either declare it impure or pass io__states to ensure that
+	% the compiler won't try to optimise away the call.
+
+:- pred clear_caches(io__state::di, io__state::uo) is det.
+
+:- impure pred clear_caches is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module set_unordlist, list, string, map, bool, set_bbbtree, int.
+:- import_module multi_map, require.
+:- import_module hash_table.
+
+% :- import_module unsafe.
+
+:- type robdd(T) ---> robdd(int).
+% :- type robdd(T) ---> robdd(c_pointer).
+% Can't use a c_pointer since we want to memo ROBDD operations and
+% pragma memo does not support c_pointers.
+
+empty_vars_set = sparse_bitset__init.
+
+:- pragma foreign_decl("C", "
+
+#define	NDEBUG
+#define	MR_ROBDD_CLEAR_CACHES
+#define	MR_ROBDD_COMPUTED_TABLE
+#define	MR_ROBDD_EQUAL_TEST
+#define	MR_ROBDD_USE_ITE_CONSTANT
+#define	MR_ROBDD_NEW
+#define	MR_ROBDD_RESTRICT_SET
+
+#include ""../robdd/bryant.h""
+").
+
+:- pragma foreign_code("C", "
+#include ""../robdd/bryant.c""
+").
+
+:- pragma foreign_proc("C",
+	one = (F::out),
+	[will_not_call_mercury, promise_pure],
+"
+	F = (MR_Word) MR_ROBDD_trueVar();
+").
+
+:- pragma foreign_proc("C",
+	zero = (F::out),
+	[will_not_call_mercury, promise_pure],
+"
+	F = (MR_Word) MR_ROBDD_falseVar();
+").
+
+:- pragma foreign_proc("C",
+	var(V::in) = (F::out),
+	[will_not_call_mercury, promise_pure],
+"
+	F = (MR_Word) MR_ROBDD_variableRep(V);
+").
+
+:- pragma foreign_proc("C",
+	ite(F::in, G::in, H::in) = (ITE::out),
+	[will_not_call_mercury, promise_pure],
+"
+	ITE = (MR_Word) MR_ROBDD_ite((MR_ROBDD_node *) F, (MR_ROBDD_node *) G,
+		(MR_ROBDD_node *) H);
+").
+
+:- pragma foreign_proc("C",
+	ite_var(V::in, G::in, H::in) = (ITE::out), 
+	[will_not_call_mercury, promise_pure],
+"
+	ITE = (MR_Word) MR_ROBDD_ite_var(V, (MR_ROBDD_node *) G,
+		(MR_ROBDD_node *) H);
+").
+
+:- pragma promise_pure('*'/2).
+X * Y = R :-
+	R = glb(X, Y),
+
+	% XXX debugging code.
+	%( R = zero ->
+	( (X = zero ; Y = zero) ->
+		impure report_zero_constraint
+	;
+		true
+	).
+
+% XXX :- pragma c_code((X::in) * (Y::in) = (F::out), [will_not_call_mercury],
+:- func glb(robdd(T), robdd(T)) = robdd(T).
+:- pragma foreign_proc("C",
+	glb(X::in, Y::in) = (F::out),
+	[will_not_call_mercury, promise_pure],
+"
+	F = (MR_Word) MR_ROBDD_glb((MR_ROBDD_node *) X, (MR_ROBDD_node *) Y);
+").
+
+% XXX
+:- impure pred report_zero_constraint is det.
+:- pragma foreign_proc("C",
+	report_zero_constraint,
+	[will_not_call_mercury],
+"
+	fprintf(stderr, ""Zero constraint!!!\\n"");
+").
+
+:- pragma foreign_proc("C",
+	(X::in) + (Y::in) = (F::out),
+	[will_not_call_mercury, promise_pure],
+"
+	F = (MR_Word) MR_ROBDD_lub((MR_ROBDD_node *) X, (MR_ROBDD_node *) Y);
+").
+
+:- pragma foreign_proc("C",
+	((X::in) =< (Y::in)) = (F::out),
+	[will_not_call_mercury, promise_pure],
+"
+	F = (MR_Word) MR_ROBDD_implies((MR_ROBDD_node *) X,
+		(MR_ROBDD_node *) Y);
+").
+
+(F =:= G) = ite(F, G, ~G).
+
+(F =\= G) = ite(F, ~G, G).
+
+(~F) = ite(F, zero, one).
+
+:- pragma foreign_proc("C",
+	entails(X::in, Y::in),
+	[will_not_call_mercury, promise_pure],
+"
+	SUCCESS_INDICATOR = (MR_ROBDD_ite_constant((MR_ROBDD_node *) X,
+		(MR_ROBDD_node *) Y, MR_ROBDD_one) == MR_ROBDD_one);
+").
+
+:- pragma foreign_proc("C",
+	var_entailed(F::in, V::in),
+	[will_not_call_mercury, promise_pure],
+"
+	SUCCESS_INDICATOR = MR_ROBDD_var_entailed((MR_ROBDD_node *) F,
+		(int) V);
+").
+
+:- pragma memo(vars_entailed/1).
+
+vars_entailed(R) =
+	( R = one ->
+		some_vars(empty_vars_set)
+	; R = zero ->
+		all_vars
+	;
+		(
+			R^fa = zero
+		->
+			(vars_entailed(R^tr) `intersection` vars_entailed(R^fa))
+				`insert` R^value
+		;
+			vars_entailed(R^tr) `intersection` vars_entailed(R^fa)
+		)
+	).
+
+:- pragma memo(vars_disentailed/1).
+
+vars_disentailed(R) =
+	( R = one ->
+		some_vars(empty_vars_set)
+	; R = zero ->
+		all_vars
+	;
+		(
+			R^tr = zero
+		->
+			(vars_disentailed(R^tr) `intersection`
+				vars_disentailed(R^fa)) `insert` R^value
+		;
+			vars_disentailed(R^tr) `intersection`
+				vars_disentailed(R^fa)
+		)
+	).
+
+:- pragma memo(definite_vars/3).
+
+definite_vars(R, T, F) :-
+	( R = one ->
+		T = some_vars(empty_vars_set),
+		F = some_vars(empty_vars_set)
+	; R = zero ->
+		T = all_vars,
+		F = all_vars
+	;
+		definite_vars(R^tr, T_tr, F_tr),
+		definite_vars(R^fa, T_fa, F_fa),
+		T0 = T_tr `intersection` T_fa,
+		F0 = F_tr `intersection` F_fa,
+		( R^fa = zero ->
+			T = T0 `insert` R^value,
+			F = F0
+		; R^tr = zero ->
+			T = T0,
+			F = F0 `insert` R^value
+		;
+			T = T0,
+			F = F0
+		)
+	).
+
+equivalent_vars(R) = rev_map(equivalent_vars_2(R)).
+
+:- type equivalent_vars_map(T) ---> equivalent_vars_map(map(var(T), vars(T))).
+
+:- func equivalent_vars_2(robdd(T)) =
+	entailment_result(equivalent_vars_map(T)).
+
+:- pragma memo(equivalent_vars_2/1).
+
+equivalent_vars_2(R) = EQ :-
+	( R = one ->
+		EQ = some_vars(equivalent_vars_map(map__init))
+	; R = zero ->
+		EQ = all_vars
+	;
+		EQVars = vars_entailed(R ^ tr) `intersection`
+				vars_disentailed(R ^ fa),
+		EQ0 = equivalent_vars_2(R ^ tr) `intersection`
+				equivalent_vars_2(R ^ fa),
+		(
+			EQVars = all_vars,
+			error("equivalent_vars: unexpected result")
+			% If this condition occurs it means the ROBDD
+			% invariants have been violated somewhere since
+			% both branches of R must have been zero.
+		;
+			EQVars = some_vars(Vars),
+			( empty(Vars) ->
+				EQ = EQ0
+			;
+				(
+					EQ0 = all_vars,
+					error("equivalent_vars: unexpected result")
+					% If this condition occurs it means
+					% the ROBDD invariants have been
+					% violated somewhere since both
+					% branches of R must have been zero.
+				;
+					EQ0 = some_vars(
+						equivalent_vars_map(M0)),
+					map__det_insert(M0, R ^ value, Vars,
+						M),
+					EQ = some_vars(equivalent_vars_map(M))
+				)
+			)
+		)
+	).
+
+:- func rev_map(entailment_result(equivalent_vars_map(T))) =
+		equivalent_result(T).
+
+rev_map(all_vars) = all_vars.
+rev_map(some_vars(equivalent_vars_map(EQ0))) = some_vars(EQ) :-
+	map__foldl2(
+		( pred(V::in, Vs::in, Seen0::in, Seen::out, in, out) is det -->
+		    ( { Seen0 `contains` V } ->
+			{ Seen = Seen0 }
+		    ;
+			^ elem(V) := V,
+			sparse_bitset__foldl((pred(Ve::in, in, out) is det -->
+				^ elem(Ve) := V
+			    ), Vs),
+			{ Seen = Seen0 `sparse_bitset__union` Vs }
+		    )
+		), EQ0, sparse_bitset__init, _, map__init, EQ).
+
+extract_implications(R) = implication_result_to_imp_vars(implications_2(R)).
+
+:- type implication_result(T)
+	--->	implication_result(
+			imp_res(T), %  K ->  V
+			imp_res(T), % ~K -> ~V
+			imp_res(T), %  K -> ~V
+			imp_res(T)  % ~K ->  V
+		).
+
+:- type imp_res(T) == entailment_result(imp_res_2(T)).
+:- type imp_res_2(T) ---> imps(map(var(T), vars_entailed_result(T))).
+
+:- func implications_2(robdd(T)) = implication_result(T).
+:- pragma memo(implications_2/1).
+
+implications_2(R) = implication_result(Imps, RevImps, DisImps, RevDisImps) :-
+	( R = one ->
+		Imps = some_vars(imps(map__init)),
+		RevImps = Imps,
+		DisImps = Imps,
+		RevDisImps = Imps
+	; R = zero ->
+		Imps = all_vars,
+		RevImps = Imps,
+		DisImps = Imps,
+		RevDisImps = Imps
+	;
+		TTVars = vars_entailed(R ^ tr),
+		FFVars = vars_disentailed(R ^ fa),
+		TFVars = vars_disentailed(R ^ tr),
+		FTVars = vars_entailed(R ^ fa),
+
+		implications_2(R ^ tr) =
+			implication_result(Imps0, RevImps0, DisImps0,
+				RevDisImps0),
+		implications_2(R ^ fa) =
+			implication_result(Imps1, RevImps1, DisImps1,
+				RevDisImps1),
+
+		Imps2 = merge_imp_res(TTVars, FTVars, Imps0, Imps1),
+		RevImps2 = merge_imp_res(TFVars, FFVars, RevImps0, RevImps1),
+		DisImps2 = merge_imp_res(TFVars, FFVars, DisImps0, DisImps1),
+		RevDisImps2 = merge_imp_res(TTVars, FTVars, RevDisImps0,
+			RevDisImps1),
+
+		% Imps2 = Imps0 `intersection` Imps1,
+		% RevImps2 = RevImps0 `intersection` RevImps1,
+		% DisImps2 = DisImps0 `intersection` DisImps1,
+		% RevDisImps2 = RevDisImps0 `intersection` RevDisImps1,
+
+		Imps = Imps2 ^ elem(R ^ value) := TTVars,
+		RevImps = RevImps2 ^ elem(R ^ value) := FFVars,
+		DisImps = DisImps2 ^ elem(R ^ value) := TFVars,
+		RevDisImps = RevDisImps2 ^ elem(R ^ value) := FTVars
+	).
+
+:- func merge_imp_res(vars_entailed_result(T), vars_entailed_result(T),
+		imp_res(T), imp_res(T)) = imp_res(T).
+
+merge_imp_res(_, _, all_vars, all_vars) = all_vars.
+merge_imp_res(_, _, some_vars(Imps), all_vars) = some_vars(Imps).
+merge_imp_res(_, _, all_vars, some_vars(Imps)) = some_vars(Imps).
+merge_imp_res(TVars, FVars, some_vars(ImpsA), some_vars(ImpsB)) =
+	some_vars(merge_imp_res_2(TVars, FVars, ImpsA, ImpsB)).
+
+:- func merge_imp_res_2(vars_entailed_result(T), vars_entailed_result(T),
+		imp_res_2(T), imp_res_2(T)) = imp_res_2(T).
+
+merge_imp_res_2(EntailedVarsA, EntailedVarsB, imps(ImpsA), imps(ImpsB)) =
+		imps(Imps) :-
+	KeysA = map__sorted_keys(ImpsA),
+	KeysB = map__sorted_keys(ImpsB),
+	Keys = list__merge_and_remove_dups(KeysA, KeysB),
+	Imps = list__foldl((func(V, M) =
+			M ^ elem(V) := VsA `intersection` VsB :-
+		VsA = ( VsA0 = ImpsA ^ elem(V) -> VsA0 ; EntailedVarsA ),
+		VsB = ( VsB0 = ImpsB ^ elem(V) -> VsB0 ; EntailedVarsB )
+	    ), Keys, map__init).
+
+:- func implication_result_to_imp_vars(implication_result(T)) = imp_vars(T).
+
+implication_result_to_imp_vars(ImpRes) = ImpVars :-
+	ImpRes = implication_result(I0, RI0, DI0, RDI0),
+	I = imp_res_to_imp_map(I0),
+	RI = imp_res_to_imp_map(RI0),
+	DI = imp_res_to_imp_map(DI0),
+	RDI = imp_res_to_imp_map(RDI0),
+	ImpVars = imp_vars(I, RI, DI, RDI).
+
+:- func imp_res_to_imp_map(imp_res(T)) = imp_map(T).
+
+imp_res_to_imp_map(all_vars) = map__init.
+imp_res_to_imp_map(some_vars(imps(IRMap))) =
+	map__foldl(func(V, MaybeVs, M) =
+		(
+			MaybeVs = some_vars(Vs),
+			\+ empty(Vs)
+		->
+			M ^ elem(V) := Vs
+		;
+			M
+		), IRMap, init).
+
+remove_implications(ImpRes, R0) = R :-
+	remove_implications_2(ImpRes, sparse_bitset__init, sparse_bitset__init,
+		R0, R, map__init, _).
+
+:- pred remove_implications_2(imp_vars(T)::in, vars(T)::in,
+	vars(T)::in, robdd(T)::in, robdd(T)::out,
+	robdd_cache(T)::in, robdd_cache(T)::out) is det.
+
+remove_implications_2(ImpRes, True, False, R0, R) -->
+	( { is_terminal(R0) } -> 
+		{ R = R0 }
+	; { True `contains` R0 ^ value } ->
+		remove_implications_2(ImpRes, True, False, R0 ^ tr, R)
+	; { False `contains` R0 ^ value } ->
+		remove_implications_2(ImpRes, True, False, R0 ^ fa, R)
+	; R1 =^ elem(R0) ->
+		{ R = R1 }
+	;
+		{ TrueT = True `union` ImpRes ^ imps ^ get(R0 ^ value) },
+		{ FalseT = False `union` ImpRes ^ dis_imps ^ get(R0 ^ value) },
+		remove_implications_2(ImpRes, TrueT, FalseT, R0 ^ tr, RT),
+
+		{ TrueF = True `union` ImpRes ^ rev_dis_imps ^ get(R0 ^ value)},
+		{ FalseF = False `union` ImpRes ^ rev_imps ^ get(R0 ^ value) },
+		remove_implications_2(ImpRes, TrueF, FalseF, R0 ^ fa, RF),
+
+		{ R = make_node(R0 ^ value, RT, RF) },
+		^ elem(R0) := R
+	).
+
+:- func get(var(T), imp_map(T)) = vars(T).
+
+get(V, IM) = ( Vs = IM ^ elem(V) -> Vs ; init ).
+
+:- typeclass intersectable(T) where [
+	func T `intersection` T = T
+].
+
+:- instance intersectable(sparse_bitset(T)) where [
+	func(intersection/2) is sparse_bitset__intersect
+].
+
+:- instance intersectable(entailment_result(T)) <= intersectable(T) where [
+	( all_vars `intersection` R = R ),
+	( some_vars(Vs) `intersection` all_vars = some_vars(Vs) ),
+	( some_vars(Vs0) `intersection` some_vars(Vs1) =
+		some_vars(Vs0 `intersection` Vs1) )
+].
+
+:- instance intersectable(equivalent_vars_map(T)) where [
+	( equivalent_vars_map(MapA) `intersection` equivalent_vars_map(MapB) =
+		equivalent_vars_map(map__foldl((func(V, VsA, M) =
+			( Vs = VsA `intersect` (MapB ^ elem(V)) ->
+				( empty(Vs) ->
+					M
+				;
+					M ^ elem(V) := Vs
+				)
+			;
+				M
+			)), MapA, map__init))
+	)
+].
+
+:- instance intersectable(imp_res_2(T)) where [
+	imps(MapA) `intersection` imps(MapB) =
+		imps(map__intersect(intersection, MapA, MapB))
+].
+
+:- func 'elem :='(var(T), imp_res(T), vars_entailed_result(T)) = imp_res(T).
+
+'elem :='(_, all_vars, _) = all_vars.
+'elem :='(V, some_vars(imps(M0)), Vs) = some_vars(imps(M0 ^ elem(V) := Vs)).
+
+:- func vars_entailed_result(T) `insert` var(T) = vars_entailed_result(T).
+
+all_vars `insert` _ = all_vars.
+some_vars(Vs) `insert` V = some_vars(Vs `insert` V).
+
+% Access to the struct members.
+% WARNING! These functions are unsafe. You must not call these functions
+% on the terminal robdds (i.e. `zero' and `one').
+:- func value(robdd(T)) = var(T).
+:- func tr(robdd(T)) = robdd(T).
+:- func fa(robdd(T)) = robdd(T).
+
+:- pragma foreign_proc("C",
+	value(F::in) = (Value::out),
+	[will_not_call_mercury, promise_pure],
+"
+	Value = (MR_Word) ((MR_ROBDD_node *) F)->value;
+").
+
+:- pragma foreign_proc("C",
+	tr(F::in) = (Tr::out),
+	[will_not_call_mercury, promise_pure],
+"
+	Tr = (MR_Word) ((MR_ROBDD_node *) F)->tr;
+").
+
+:- pragma foreign_proc("C",
+	fa(F::in) = (Fa::out),
+	[will_not_call_mercury, promise_pure],
+"
+	Fa = (MR_Word) ((MR_ROBDD_node *) F)->fa;
+").
+
+:- pragma inline(value/1).
+:- pragma inline(tr/1).
+:- pragma inline(fa/1).
+
+%------------------------------------------------------------------------%
+
+:- pragma memo(dnf/1).
+
+dnf(R) =
+	( R = zero ->
+		[]
+	; R = one ->
+		[[]]
+	;
+		list__map(func(L) = [pos(R ^ value) | L], dnf(R ^ tr)) ++
+		list__map(func(L) = [neg(R ^ value) | L], dnf(R ^ fa))
+	).
+
+% cnf(R) =
+% 	( R = zero ->
+% 		[[]]
+% 	; R = one ->
+% 		[]
+% 	;
+% 		[pos(R ^ value) | cnf(R ^ tr)] `merge_cnf`
+% 		[neg(R ^ value) | cnf(R ^ fa)]
+% 	).
+% 
+% :- func merge_cnf(list(list(literal(T))), list(list(literal(T)))) =
+% 		list(list(literal(T))).
+% 
+% merge_cnf(As, Bs) =
+% 	( As = [] ->
+% 		Bs
+% 	; Bs = [] ->
+% 		As
+% 	; As = [[]] ->
+% 		As
+% 	; Bs = [[]] % XXX check
+% 	;
+% 		foldl(func(A, Cs0) =
+% 			foldl(func(B, Cs1) = [A ++ B | Cs1], Bs, Cs0),
+% 		    As, [])
+% 	).
+
+% :- pragma foreign_proc("C",
+%	print_robdd(F::in, IO0::di, IO::uo),
+%	[will_not_call_mercury],
+% "
+%	printOut((MR_ROBDD_node *) F);
+%	update_io(IO0, IO);
+% ").
+
+print_robdd(F) -->
+	( { F = one } ->
+		io__write_string("TRUE\n")
+	; { F = zero } ->
+		io__write_string("FALSE\n")
+	;
+		{ init(Trues) },
+		{ init(Falses) },
+		print_robdd_2(F, Trues, Falses)
+	).
+
+:- pred print_robdd_2(robdd(T)::in, set_unordlist(var(T))::in,
+		set_unordlist(var(T))::in, io__state::di, io__state::uo) is det.
+
+print_robdd_2(F, Trues, Falses) -->
+	( { F = one } ->
+		{ All = to_sorted_list(Trues `union` Falses) },
+		io__write_string("("),
+		list__foldl((pred(Var::in, di, uo) is det -->
+			{ Var `set_unordlist__member` Trues ->
+				C = ' '
+			;
+				C = ('~')
+			},
+			{ term__var_to_int(Var, N) },
+			io__format(" %c%02d", [c(C), i(N)])
+		), All),
+		io__write_string(")\n")
+	; { F \= zero } ->
+		print_robdd_2(F^tr, Trues `insert` F^value, Falses),
+		print_robdd_2(F^fa, Trues, Falses `insert` F^value)
+	;
+		% Don't do anything for zero terminal
+		[]
+	).
+
+:- pragma foreign_proc("C",
+	restrict(V::in, F::in) = (R::out),
+	[will_not_call_mercury, promise_pure],
+"
+	R = (MR_Word) MR_ROBDD_restrict(V, (MR_ROBDD_node *) F);
+").
+
+:- pragma foreign_proc("C",
+	restrict_threshold(V::in, F::in) = (R::out),
+	[will_not_call_mercury, promise_pure],
+"
+	R = (MR_Word) MR_ROBDD_restrictThresh(V, (MR_ROBDD_node *) F);
+").
+
+:- pragma memo(rename_vars/2).
+
+rename_vars(Subst, F) = 
+	( is_terminal(F) ->
+		F
+	;
+		ite(var(Subst(F^value)),
+			rename_vars(Subst, F^tr),
+			rename_vars(Subst, F^fa))
+	).
+
+% make_node(Var, Then, Else).
+% The make_node() function. WARNING!! If you use this function you are
+% responsible for making sure that the ROBDD invariant holds that all the
+% variables in both the Then and Else sub graphs are > Var.
+
+:- func make_node(var(T), robdd(T), robdd(T)) = robdd(T).
+:- pragma foreign_proc("C",
+	make_node(Var::in, Then::in, Else::in) = (Node::out),
+	[will_not_call_mercury, promise_pure],
+"
+	Node = (MR_Word) MR_ROBDD_make_node((int) Var, (MR_ROBDD_node *) Then,
+		(MR_ROBDD_node *) Else);
+").
+
+not_var(V) = make_node(V, zero, one).
+
+eq_vars(VarA, VarB) = F :-
+	compare(R, VarA, VarB),
+	(
+		R = (=),
+		F = one
+	;
+		R = (<),
+		F = make_node(VarA, var(VarB), not_var(VarB))
+	;
+		R = (>),
+		F = make_node(VarB, var(VarA), not_var(VarA))
+	).
+
+neq_vars(VarA, VarB) = F :-
+	compare(R, VarA, VarB),
+	(
+		R = (=),
+		F = zero
+	;
+		R = (<),
+		F = make_node(VarA, not_var(VarB), var(VarB))
+	;
+		R = (>),
+		F = make_node(VarB, not_var(VarA), var(VarA))
+	).
+
+imp_vars(VarA, VarB) = F :-
+	compare(R, VarA, VarB),
+	(
+		R = (=),
+		F = one
+	;
+		R = (<),
+		F = make_node(VarA, var(VarB), one)
+	;
+		R = (>),
+		F = make_node(VarB, one, not_var(VarA))
+	).
+
+conj_vars(Vars) = foldr(func(V, R) = make_node(V, R, zero), Vars, one).
+
+conj_not_vars(Vars) = foldr(func(V, R) = make_node(V, zero, R), Vars, one).
+
+disj_vars(Vars) = foldr(func(V, R) = make_node(V, one, R), Vars, zero).
+
+at_most_one_of(Vars) = at_most_one_of_2(Vars, one, one).
+
+:- func at_most_one_of_2(vars(T), robdd(T), robdd(T)) = robdd(T).
+
+at_most_one_of_2(Vars, OneOf0, NoneOf0) = R :-
+	list__foldl2(
+		(pred(V::in, One0::in, One::out, None0::in, None::out) is det :-
+			None = make_node(V, zero, None0),
+			One = make_node(V, None0, One0)
+		), list__reverse(to_sorted_list(Vars)), 
+		OneOf0, R, NoneOf0, _).
+
+:- pragma memo(var_restrict_true/2).
+
+var_restrict_true(V, F0) = F :-
+	( is_terminal(F0) ->
+		F = F0
+	;
+		compare(R, F0^value, V),
+		(
+			R = (<),
+			F = make_node(F0^value,
+				var_restrict_true(V, F0^tr),
+				var_restrict_true(V, F0^fa))
+		;
+			R = (=),
+			F = F0^tr
+		;
+			R = (>),
+			F = F0
+		)
+	).
+
+:- pragma memo(var_restrict_false/2).
+
+var_restrict_false(V, F0) = F :-
+	( is_terminal(F0) ->
+		F = F0
+	;
+		compare(R, F0^value, V),
+		(
+			R = (<),
+			F = make_node(F0^value,
+				var_restrict_false(V, F0^tr),
+				var_restrict_false(V, F0^fa))
+		;
+			R = (=),
+			F = F0^fa
+		;
+			R = (>),
+			F = F0
+		)
+	).
+
+restrict_true_false_vars(TrueVars, FalseVars, R0) = R :-
+% The following code may be useful during debugging, but it is commented out
+% since it should not be needed otherwise.
+% 	size(R0, _Nodes, _Depth), % XXX
+% 	P = (pred(V::in, di, uo) is det --> io__write_int(var_to_int(V))), % XXX
+% 	unsafe_perform_io(robdd_to_dot(R0, P, "rtf.dot")), % XXX
+	restrict_true_false_vars_2(TrueVars, FalseVars, R0, R,
+		init, _).
+
+:- pred restrict_true_false_vars_2(vars(T)::in, vars(T)::in,
+	robdd(T)::in, robdd(T)::out,
+	robdd_cache(T)::in, robdd_cache(T)::out) is det.
+
+restrict_true_false_vars_2(TrueVars0, FalseVars0, R0, R, Seen0, Seen) :-
+	( is_terminal(R0) ->
+		R = R0,
+		Seen = Seen0
+	; empty(TrueVars0), empty(FalseVars0) ->
+		R = R0,
+		Seen = Seen0
+	; search(Seen0, R0, R1) ->
+		R = R1,
+		Seen = Seen0
+	;	
+		Var = R0 ^ value,
+		TrueVars = TrueVars0 `remove_leq` Var,
+		FalseVars = FalseVars0 `remove_leq` Var,
+		( TrueVars0 `contains` Var ->
+			restrict_true_false_vars_2(TrueVars, FalseVars,
+				R0 ^ tr, R, Seen0, Seen2)
+		; FalseVars0 `contains` Var ->
+			restrict_true_false_vars_2(TrueVars, FalseVars,
+				R0 ^ fa, R, Seen0, Seen2)
+		;
+			restrict_true_false_vars_2(TrueVars, FalseVars,
+				R0 ^ tr, R_tr, Seen0, Seen1),
+			restrict_true_false_vars_2(TrueVars, FalseVars,
+				R0 ^ fa, R_fa, Seen1, Seen2),
+			R = make_node(R0 ^ value, R_tr, R_fa)
+		),
+		Seen = det_insert(Seen2, R0, R)
+	).
+
+:- pred robdd_double_hash(robdd(T)::in, int::out, int::out) is det.
+
+robdd_double_hash(R, H1, H2) :-
+	int_double_hash(node_num(R), H1, H2).
+
+restrict_filter(P, F0) =
+	restrict_filter(P, (pred(_::in) is semidet :- true), F0).
+
+restrict_filter(P, D, F0) = F :-
+	filter_2(P, D, F0, F, map__init, _, map__init, _).
+
+:- type robdd_cache(T) == map(robdd(T), robdd(T)).
+:- type var_cache(T) == map(var(T), bool).
+
+:- pred filter_2(pred(var(T)), pred(var(T)), robdd(T), robdd(T),
+	var_cache(T), var_cache(T), robdd_cache(T), robdd_cache(T)).
+:- mode filter_2(pred(in) is semidet, pred(in) is semidet, in, out, in, out,
+	in, out) is det.
+
+filter_2(P, D, F0, F, SeenVars0, SeenVars, SeenNodes0, SeenNodes) :-
+	( is_terminal(F0) ->
+		F = F0,
+		SeenVars = SeenVars0,
+		SeenNodes = SeenNodes0
+	; \+ D(F0^value) ->
+		F = F0,
+		SeenVars = SeenVars0,
+		SeenNodes = SeenNodes0
+	; map__search(SeenNodes0, F0, F1) ->
+		F = F1,
+		SeenVars = SeenVars0,
+		SeenNodes = SeenNodes0
+	;
+		filter_2(P, D, F0^tr, Ftrue, SeenVars0, SeenVars1, SeenNodes0,
+			SeenNodes1),
+		filter_2(P, D, F0^fa, Ffalse, SeenVars1, SeenVars2, SeenNodes1,
+			SeenNodes2),
+		V = F0^value,
+		( map__search(SeenVars0, V, SeenF) ->
+			SeenVars = SeenVars2,
+			(
+				SeenF = yes,
+				F = make_node(V, Ftrue, Ffalse)
+			;
+				SeenF = no,
+				F = Ftrue + Ffalse
+			)
+		; P(V) ->
+			F = make_node(V, Ftrue, Ffalse),
+			map__det_insert(SeenVars2, V, yes, SeenVars)
+		;
+			F = Ftrue + Ffalse,
+			map__det_insert(SeenVars2, V, no, SeenVars)
+		),
+		map__det_insert(SeenNodes2, F0, F, SeenNodes)
+	).
+
+squeeze_equiv(LeaderMap, R0) =
+	( Max = map__max_key(LeaderMap) ->
+		restrict_filter(
+			( pred(V::in) is semidet :-
+				map__search(LeaderMap, V, L) => L = V
+			),
+			( pred(V::in) is semidet :-
+				\+ compare(>, V, Max)
+			), R0)
+	;
+		R0
+	).
+
+make_equiv(LeaderMap) =
+	make_equiv_2(map__sorted_keys(LeaderMap), LeaderMap, init).
+
+:- func make_equiv_2(list(var(T)), map(var(T), var(T)), vars(T)) = robdd(T).
+
+make_equiv_2([], _, _) = one.
+make_equiv_2([V | Vs], LM, Trues) =
+	( L = V ->
+		make_node(V, make_equiv_2(Vs, LM, Trues `insert` V),
+			make_equiv_2(Vs, LM, Trues))
+	; Trues `contains` L ->
+		make_node(V, make_equiv_2(Vs, LM, Trues), zero)
+	;
+		make_node(V, zero, make_equiv_2(Vs, LM, Trues))
+	) :-
+	L = LM ^ det_elem(V).
+
+expand_equiv(LeaderMap, R0) = R :-
+	expand_equiv_2(map__sorted_keys(LeaderMap), LeaderMap, init, R0, R,
+		map__init, _).
+
+:- pred expand_equiv_2(list(var(T))::in, map(var(T), var(T))::in, vars(T)::in,
+	robdd(T)::in, robdd(T)::out,
+	robdd_cache(T)::in, robdd_cache(T)::out) is det.
+
+expand_equiv_2([], _, _, R, R) --> [].
+expand_equiv_2([V | Vs], LM, Trues, R0, R) -->
+	{ L = LM ^ det_elem(V) },
+	( { R0 = zero } ->
+		{ R = zero }
+	; R1 =^ elem(R0) ->
+		{ R = R1 }
+	; { R0 = one } ->
+		{ R = make_equiv_2([V | Vs], LM, Trues) },
+		^ elem(R0) := R
+	; { compare((<), R0 ^ value, V) } ->
+		expand_equiv_2([V | Vs], LM, Trues, R0 ^ tr, Rtr),
+		expand_equiv_2([V | Vs], LM, Trues, R0 ^ fa, Rfa),
+		{ R = make_node(R0 ^ value, Rtr, Rfa) },
+		^ elem(R0) := R
+	; { compare((<), V, R0 ^ value) } ->
+		( { L = V } ->
+			expand_equiv_2(Vs, LM, Trues `insert` V, R0, Rtr),
+			expand_equiv_2(Vs, LM, Trues, R0, Rfa),
+			{ R = make_node(V, Rtr, Rfa) },
+			^ elem(R0) := R
+		; { Trues `contains` L } ->
+			expand_equiv_2(Vs, LM, Trues, R0, Rtr),
+			{ R = make_node(V, Rtr, zero) },
+			^ elem(R0) := R
+		;
+			expand_equiv_2(Vs, LM, Trues, R0, Rfa),
+			{ R = make_node(V, zero, Rfa) },
+			^ elem(R0) := R
+		)
+	; { L = V } ->
+		expand_equiv_2(Vs, LM, Trues `insert` V, R0 ^ tr, Rtr),
+		expand_equiv_2(Vs, LM, Trues, R0 ^ fa, Rfa),
+		{ R = make_node(V, Rtr, Rfa) },
+		^ elem(R0) := R
+	; { Trues `contains` L } -> 
+		expand_equiv_2(Vs, LM, Trues, R0 ^ tr, Rtr),
+		{ R = make_node(V, Rtr, zero) },
+		^ elem(R0) := R
+	;
+		expand_equiv_2(Vs, LM, Trues, R0 ^ fa, Rfa),
+		{ R = make_node(V, zero, Rfa) },
+		^ elem(R0) := R
+	).
+
+%------------------------------------------------------------------------%
+
+% XXX this could be made much more efficient by doing something similar
+% to what we do in expand_equiv.
+
+expand_implications(ImpVars, R) = R ^
+		expand_implications_2(not_var, var, Imps) ^
+		expand_implications_2(var, not_var, RevImps) ^
+		expand_implications_2(not_var, not_var, DisImps) ^
+		expand_implications_2(var, var, RevDisImps) :-
+	ImpVars = imp_vars(Imps, RevImps, DisImps, RevDisImps).
+	
+:- func expand_implications_2(func(var(T)) = robdd(T), func(var(T)) = robdd(T),
+		imp_map(T), robdd(T)) = robdd(T).
+
+expand_implications_2(FA, FB, IM, R0) =
+	map__foldl(func(VA, Vs, R1) =
+		foldl(func(VB, R2) = R2 * (FA(VA) + FB(VB)), Vs, R1),
+		IM, R0).
+
+%------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+	is_terminal(F::in),
+	[will_not_call_mercury, thread_safe, promise_pure],
+"
+	SUCCESS_INDICATOR = IS_TERMINAL(F);
+").
+
+size(F, Nodes, Depth) :-
+	size(F, Nodes, Depth, _).
+
+size(F, Nodes, Depth, Vars) :-
+	size_2(F, 0, Nodes, 0, Depth, 0, set_bbbtree__init, Seen),
+	Vars = sort_and_remove_dups(list__map(value, to_sorted_list(Seen))).
+
+	% XXX should see if sparse_bitset is more efficient than set_bbbtree.
+:- pred size_2(robdd(T)::in, int::in, int::out, int::in, int::out, int::in,
+		set_bbbtree(robdd(T))::in, set_bbbtree(robdd(T))::out) is det.
+
+size_2(F, Nodes0, Nodes, Depth0, Depth, Val0, Seen0, Seen) :-
+	( is_terminal(F) ->
+		Nodes = Nodes0, Depth = Depth0, Seen = Seen0
+	; term__var_to_int(F^value) =< Val0 ->
+		error("robdd invariant broken (possible loop)")
+	; F `member` Seen0 ->
+		Nodes = Nodes0, Depth = Depth0, Seen = Seen0
+	;
+		Val = term__var_to_int(F^value),
+		size_2(F^tr, Nodes0+1, Nodes1, Depth0, Depth1, Val,
+			Seen0, Seen1),
+		size_2(F^fa, Nodes1, Nodes, Depth0, Depth2, Val,
+			Seen1, Seen2),
+		max(Depth1, Depth2, Max),
+		Depth = Max + 1,
+		Seen = Seen2 `insert` F
+	).
+
+var_is_constrained(F, V) :-
+	( is_terminal(F) ->
+		fail
+	;
+		compare(R, F^value, V),
+		(
+			R = (<),
+			( var_is_constrained(F^tr, V)
+			; var_is_constrained(F^fa, V)
+			)
+		;
+			R = (=)
+		)
+	).
+
+vars_are_constrained(F, Vs) :-
+	vars_are_constrained_2(F, to_sorted_list(Vs)).
+
+:- pred vars_are_constrained_2(robdd(T)::in, list(var(T))::in) is semidet.
+
+vars_are_constrained_2(_, []).
+vars_are_constrained_2(F, Vs) :-
+	Vs = [V | Vs1],
+	( is_terminal(F) ->
+		fail
+	;
+		compare(R, F^value, V),
+		(
+			R = (<),
+			Vs2 = Vs
+		;
+			R = (=),
+			Vs2 = Vs1
+		),
+		( vars_are_constrained_2(F^tr, Vs2)
+		; vars_are_constrained_2(F^fa, Vs2)
+		)
+	).
+
+robdd_to_dot(Robdd, WV, Filename) -->
+	io__tell(Filename, Result),
+	(
+		{ Result = ok },
+		robdd_to_dot(Robdd, WV),
+		io__told
+	;
+		{ Result = error(Err) },
+		io__stderr_stream(StdErr),
+		io__nl(StdErr),
+		io__write_string(StdErr, io__error_message(Err)),
+		io__nl(StdErr)
+	).
+
+robdd_to_dot(Robdd, WV) -->
+	io__write_string(
+"digraph G{
+	center=true;
+	size=""7,11"";
+	ordering=out;
+	node [shape=record,height=.1];
+	concentrate=true;
+"),
+	{ multi_map__init(Ranks0) },
+	robdd_to_dot_2(Robdd, WV, set_bbbtree__init, _, Ranks0, Ranks),
+	map__foldl((pred(_::in, Nodes::in, di, uo) is det -->
+		io__write_string("{rank = same; "),
+		list__foldl((pred(Node::in, di, uo) is det -->
+			io__format("%s; ", [s(node_name(Node))])), Nodes),
+		io__write_string("}\n")
+		), Ranks),
+	io__write_string("}\n").
+
+	% XXX should see if sparse_bitset is more efficient than set_bbbtree.
+:- pred robdd_to_dot_2(robdd(T)::in, write_var(T)::in(write_var),
+		set_bbbtree(robdd(T))::in, set_bbbtree(robdd(T))::out,
+		multi_map(var(T), robdd(T))::in,
+		multi_map(var(T), robdd(T))::out,
+		io__state::di, io__state::uo) is det.
+
+robdd_to_dot_2(Robdd, WV, Seen0, Seen, Ranks0, Ranks) -->
+	( { is_terminal(Robdd) } ->
+		{ Seen = Seen0 },
+		{ Ranks = Ranks0 }
+	; { Robdd `member` Seen0 } ->
+		{ Seen = Seen0 },
+		{ Ranks = Ranks0 }
+	;
+		robdd_to_dot_2(Robdd^tr, WV, Seen0, Seen1, Ranks0, Ranks1),
+		robdd_to_dot_2(Robdd^fa, WV, Seen1, Seen2, Ranks1, Ranks2),
+		write_node(Robdd, WV),
+		write_edge(Robdd, Robdd^tr, yes),
+		write_edge(Robdd, Robdd^fa, no),
+		{ Seen = Seen2 `insert` Robdd },
+		{ multi_map__set(Ranks2, Robdd^value, Robdd, Ranks) }
+	).
+
+:- pred write_node(robdd(T)::in, write_var(T)::in(write_var),
+		io__state::di, io__state::uo) is det.
+
+write_node(R, WV) -->
+	io__format("%s [label=""<f0> %s|<f1> ",
+		[s(node_name(R)), s(terminal_name(R^tr))]),
+	WV(R^value),
+	io__format("|<f2> %s", [s(terminal_name(R^fa))]),
+	io__write_string("""];\n").
+
+:- func node_name(robdd(T)) = string.
+
+node_name(R) =
+	( R = one ->
+		"true"
+	; R = zero ->
+		"false"
+	;
+		string__format("node%d", [i(node_num(R))])
+	).
+
+:- func node_num(robdd(T)) = int.
+:- pragma foreign_proc("C",
+	node_num(R::in) = (N::out),
+	[will_not_call_mercury, promise_pure],
+"
+	N = (Integer) R;
+").
+
+:- func terminal_name(robdd(T)) = string.
+
+terminal_name(R) =
+	( R = zero ->
+		"0"
+	; R = one ->
+		"1"
+	;
+		""
+	).
+
+:- pred write_edge(robdd(T)::in, robdd(T)::in, bool::in,
+		io__state::di, io__state::uo) is det.
+
+write_edge(R0, R1, Arc) -->
+	( { is_terminal(R1) } ->
+		[]
+	;
+		io__format("""%s"":%s -> ""%s"":f1 [label=""%s""];\n",
+			[s(node_name(R0)), s(Arc = yes -> "f0" ; "f2"),
+			s(node_name(R1)), s(Arc = yes -> "t" ; "f")])
+	).
+
+labelling(Vars, R, TrueVars, FalseVars) :-
+	labelling_2(to_sorted_list(Vars), R, empty_vars_set, TrueVars,
+		empty_vars_set, FalseVars).
+
+:- pred labelling_2(list(var(T))::in, robdd(T)::in, vars(T)::in,
+		vars(T)::out, vars(T)::in, vars(T)::out) is nondet.
+
+labelling_2([], _, TrueVars, TrueVars, FalseVars, FalseVars).
+labelling_2([V | Vs], R0, TrueVars0, TrueVars, FalseVars0, FalseVars) :-
+	R = var_restrict_false(V, R0),
+	R \= zero,
+	labelling_2(Vs, R, TrueVars0, TrueVars, FalseVars0 `insert` V,
+		FalseVars).
+labelling_2([V | Vs], R0, TrueVars0, TrueVars, FalseVars0, FalseVars) :-
+	R = var_restrict_true(V, R0),
+	R \= zero,
+	labelling_2(Vs, R, TrueVars0 `insert` V, TrueVars, FalseVars0,
+		FalseVars).
+
+minimal_model(Vars, R, TrueVars, FalseVars) :-
+	( empty(Vars) ->
+		TrueVars = empty_vars_set,
+		FalseVars = empty_vars_set
+	;
+		minimal_model_2(to_sorted_list(Vars), R, empty_vars_set,
+			TrueVars0, empty_vars_set, FalseVars0),
+		(
+			TrueVars = TrueVars0,
+			FalseVars = FalseVars0
+		;
+			minimal_model(Vars, R * (~conj_vars(TrueVars0)),
+				TrueVars, FalseVars)
+		)
+	).
+
+:- pred minimal_model_2(list(var(T))::in, robdd(T)::in, vars(T)::in,
+	vars(T)::out, vars(T)::in, vars(T)::out) is semidet.
+
+minimal_model_2([], _, TrueVars, TrueVars, FalseVars, FalseVars).
+minimal_model_2([V | Vs], R0, TrueVars0, TrueVars, FalseVars0, FalseVars) :-
+	R1 = var_restrict_false(V, R0),
+	( R1 \= zero ->
+		minimal_model_2(Vs, R1, TrueVars0, TrueVars,
+			FalseVars0 `insert` V, FalseVars)
+	;
+		R2 = var_restrict_true(V, R0),
+		R2 \= zero,
+		minimal_model_2(Vs, R2, TrueVars0 `insert` V, TrueVars,
+			FalseVars0, FalseVars)
+	).
+
+%-----------------------------------------------------------------------------%
+
+:- pragma promise_pure(clear_caches/2).
+clear_caches -->
+	{ impure clear_caches }.
+
+:- pragma foreign_proc("C",
+	clear_caches,
+	[will_not_call_mercury],
+"
+	MR_ROBDD_init_caches();
+").
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
Index: library/sparse_bitset.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/sparse_bitset.m,v
retrieving revision 1.16
diff -u -b -r1.16 sparse_bitset.m
--- library/sparse_bitset.m	23 Jul 2002 08:26:27 -0000	1.16
+++ library/sparse_bitset.m	19 Aug 2002 07:31:26 -0000
@@ -114,6 +114,12 @@
 :- pred contains(sparse_bitset(T), T) <= enum(T).
 :- mode contains(in, in) is semidet.
 
+	% 'member(X, Set) is true iff 'X' is a member of 'Set'.
+	% For the (in, in) mode, use 'contains/2' instead since it is more
+	% efficient.
+:- pred member(T, sparse_bitset(T)) <= enum(T).
+:- mode member(out, in) is nondet.
+
 	% `insert(Set, X)' returns the union
 	% of `Set' and the set containing only `X'.
 	% Takes O(rep_size(Set)) time and space.
@@ -168,6 +174,22 @@
 :- pred remove_list(sparse_bitset(T), list(T), sparse_bitset(T)) <= enum(T).
 :- mode remove_list(in, in, out) is semidet.
 
+	% `remove_leq(Set, X)' returns `Set' with all elements less than
+	% or equal to `X' removed. In other words, it returns the set
+	% containing all the elements of `Set' which are greater than `X'.
+:- func remove_leq(sparse_bitset(T), T) = sparse_bitset(T) <= enum(T).
+
+:- pred remove_leq(sparse_bitset(T), T, sparse_bitset(T)) <= enum(T).
+:- mode remove_leq(in, in, out) is det.
+
+	% `remove_gt(Set, X)' returns `Set' with all elements greater
+	% than `X' removed. In other words, it returns the set containing
+	% all the elements of `Set' which are less than or equal to `X'.
+:- func remove_gt(sparse_bitset(T), T) = sparse_bitset(T) <= enum(T).
+
+:- pred remove_gt(sparse_bitset(T), T, sparse_bitset(T)) <= enum(T).
+:- mode remove_gt(in, in, out) is det.
+
 	% `remove_least(Set0, X, Set)' is true iff `X' is the
 	% least element in `Set0', and `Set' is the set which
 	% contains all the elements of `Set0' except `X'.
@@ -214,6 +236,9 @@
 	% Takes O(card(Set)) time.
 :- func foldl(func(T, U) = U, sparse_bitset(T), U) = U <= enum(T).
 
+:- pred foldl(pred(T, U, U), sparse_bitset(T), U, U) <= enum(T).
+:- mode foldl(pred(in, in, out) is det, in, in, out) is det.
+
 	% `foldr(Func, Set, Start)' calls Func with each element
 	% of `Set' (in reverse sorted order) and an accumulator
 	% (with the initial value of `Start'), and returns
@@ -221,6 +246,12 @@
 	% Takes O(card(Set)) time.
 :- func foldr(func(T, U) = U, sparse_bitset(T), U) = U <= enum(T).
 
+	% `filter(Pred, Set)' removes those elements from `Set' for which
+	% `Pred' fails. In other words, it returns the set consisting of those
+	% elements of `Set' for which `Pred' succeeds.
+:- func filter(pred(T), sparse_bitset(T)) = sparse_bitset(T) <= enum(T).
+:- mode filter(pred(in) is semidet, in) = out is det.
+
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -330,6 +361,10 @@
 
 foldl(F, sparse_bitset(Set), Acc0) = foldl_2(F, Set, Acc0).
 
+foldl(P, S, Acc0, Acc) :-
+	F = (func(E, A0) = A :- P(E, A0, A)),
+	Acc = foldl(F, S, Acc0).
+
 :- func foldl_2(func(T, U) = U, bitset_impl, U) = U <= enum(T).
 :- pragma type_spec(foldl_2/3, T = int).
 :- pragma type_spec(foldl_2/3, T = var(_)).
@@ -412,6 +447,12 @@
 
 %-----------------------------------------------------------------------------%
 
+% XXX could make this more efficient.
+
+filter(P, S) = S ^ to_sorted_list ^ list__filter(P) ^ sorted_list_to_set.
+
+%-----------------------------------------------------------------------------%
+
 count(Set) = foldl((func(_, Acc) = Acc + 1), Set, 0).
 
 %-----------------------------------------------------------------------------%
@@ -461,6 +502,62 @@
 
 %-----------------------------------------------------------------------------%
 
+remove_leq(sparse_bitset(Set), Elem) =
+	sparse_bitset(remove_leq_2(Set, enum__to_int(Elem))).
+
+:- func remove_leq_2(bitset_impl, int) = bitset_impl.
+
+remove_leq_2([], _) = [].
+remove_leq_2([Data | Rest], Index) = Result :-
+	Offset = Data ^ offset,
+	Result =
+		( Offset + bits_per_int =< Index ->
+			remove_leq_2(Rest, Index)
+		; Offset =< Index ->
+			(
+				Bits = Data ^ bits /\
+					unchecked_left_shift(\ 0,
+						Index - Offset + 1),
+				Bits \= 0
+			->
+				[make_bitset_elem(Offset, Bits) | Rest]
+			;
+				Rest
+			)
+		;
+			[Data | Rest]
+		).
+
+%-----------------------------------------------------------------------------%
+
+remove_gt(sparse_bitset(Set), Elem) =
+	sparse_bitset(remove_gt_2(Set, enum__to_int(Elem))).
+
+:- func remove_gt_2(bitset_impl, int) = bitset_impl.
+
+remove_gt_2([], _) = [].
+remove_gt_2([Data | Rest], Index) = Result :-
+	Offset = Data ^ offset,
+	Result =
+		( Offset + bits_per_int - 1 =< Index ->
+			[Data | remove_gt_2(Rest, Index)]
+		; Offset =< Index ->
+			(
+				Bits = Data ^ bits /\
+					\ unchecked_left_shift(\ 0,
+						Index - Offset + 1),
+				Bits \= 0
+			->
+				[make_bitset_elem(Offset, Bits)]
+			;
+				[]
+			)
+		;
+			[]
+		).
+
+%-----------------------------------------------------------------------------%
+
 remove_least(sparse_bitset(Set0), Elem, sparse_bitset(Set)) :-
 	Set0 = [First | Rest],
 	Bits0 = First ^ bits,
@@ -625,6 +722,16 @@
 
 %-----------------------------------------------------------------------------%
 
+member(X, Set0) :-
+	remove_least(Set0, X0, Set),
+	(
+		X = X0
+	;
+		member(X, Set)
+	).
+
+%-----------------------------------------------------------------------------%
+
 :- func rest(bitset_impl::in(bound([ground | ground]))) =
 		(bitset_impl::out) is det.
 rest([_ | Rest]) = Rest.
@@ -799,6 +906,10 @@
 remove(A, B, remove(A, B)).
 
 remove_list(A, B, remove_list(A, B)).
+
+remove_leq(A, B, remove_leq(A, B)).
+
+remove_gt(A, B, remove_gt(A, B)).
 
 list_to_set(A, list_to_set(A)).
 
Index: library/term.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/term.m,v
retrieving revision 1.101
diff -u -b -r1.101 term.m
--- library/term.m	9 Jul 2002 01:30:24 -0000	1.101
+++ library/term.m	3 Jan 2003 06:00:14 -0000
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 1993-2000 The University of Melbourne.
+% Copyright (C) 1993-2000,2003 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.
 %---------------------------------------------------------------------------%
@@ -299,8 +299,6 @@
 %		Different variables map to different ints.
 %		Other than that, the mapping is unspecified.
 	
-%-----------------------------------------------------------------------------%
-
 	% Given a term context, return the source line number.
 
 :- pred term__context_line(term__context, int).
@@ -394,7 +392,14 @@
 :- pred term__term_to_type_with_int_instead_of_char(term(U), T).
 :- mode term__term_to_type_with_int_instead_of_char(in, out) is semidet.
 
-	% This predidicate is being phased out, because of the problem
+:- func term__var_supply_max_var(var_supply(T)) = var(T).
+% 	term__var_supply_max_var(VarSupply):
+%		Returns the highest numbered variable returned from this
+%		var_supply.
+
+%-----------------------------------------------------------------------------%
+
+	% This predicate is being phased out, because of the problem
 	% mentioned in the "BEWARE:" below.
 :- pragma obsolete(term__compare/4).
 :- pred term__compare(comparison_result, term(T), term(T), substitution(T)).
@@ -1077,7 +1082,7 @@
 	% We number variables using sequential numbers,
 
 term__create_var(var_supply(V0), var(V), var_supply(V)) :-
-	V is V0 + 1.
+	V = V0 + 1.
 
 %------------------------------------------------------------------------------%
 
@@ -1096,6 +1101,8 @@
 :- func unsafe_int_to_var(int) = var(T).
 term__unsafe_int_to_var(Var) = var(Var).
 
+term__var_supply_max_var(var_supply(V)) = var(V).
+
 %-----------------------------------------------------------------------------%
 
 	% substitute a variable name in a term.
Index: library/tree234.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/tree234.m,v
retrieving revision 1.36
diff -u -b -r1.36 tree234.m
--- library/tree234.m	19 Aug 2002 06:33:17 -0000	1.36
+++ library/tree234.m	3 Jan 2003 06:00:56 -0000
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 1994-1997,1999-2000,2002 The University of Melbourne.
+% Copyright (C) 1994-1997,1999-2000,2002-2003 The University of Melbourne.
 % This file may only be copied under the terms of the GNU Library General
 % Public License - see the file COPYING.LIB in the Mercury distribution.
 %---------------------------------------------------------------------------%
@@ -64,6 +64,10 @@
 :- pred tree234__upper_bound_lookup(tree234(K, V), K, K, V).
 :- mode tree234__upper_bound_lookup(in, in, out, out) is det.
 
+:- func tree234__max_key(tree234(K, V)) = K is semidet.
+
+:- func tree234__min_key(tree234(K, V)) = K is semidet.
+
 :- pred tree234__insert(tree234(K, V), K, V, tree234(K, V)).
 :- mode tree234__insert(in, in, in, out) is semidet.
 % :- mode tree234__insert(di_tree234, in, in, uo_tree234) is semidet.
@@ -634,6 +638,30 @@
 	;
 		report_lookup_error("tree234__upper_bound_lookup: key not found.",
 			SearchK, V)
+	).
+
+%------------------------------------------------------------------------------%
+
+tree234__max_key(T0) = MaxKey :-
+	( T0 = two(NodeMaxKey, _, _, NodeMaxSubtree) 
+	; T0 = three(_, _, NodeMaxKey, _, _, _, NodeMaxSubtree)
+	; T0 = four(_, _, _, _, NodeMaxKey, _, _, _, _, NodeMaxSubtree)
+	),
+	( MaxSubtreeKey = tree234__max_key(NodeMaxSubtree) ->
+		MaxKey = MaxSubtreeKey
+	;
+		MaxKey = NodeMaxKey
+	).
+
+tree234__min_key(T0) = MinKey :-
+	( T0 = two(NodeMinKey, _, NodeMinSubtree, _) 
+	; T0 = three(NodeMinKey, _, _, _, NodeMinSubtree, _, _)
+	; T0 = four(NodeMinKey, _, _, _, _, _, NodeMinSubtree, _, _, _)
+	),
+	( MinSubtreeKey = tree234__min_key(NodeMinSubtree) ->
+		MinKey = MinSubtreeKey
+	;
+		MinKey = NodeMinKey
 	).
 
 %------------------------------------------------------------------------------%
Index: library/varset.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/varset.m,v
retrieving revision 1.66
diff -u -b -r1.66 varset.m
--- library/varset.m	9 Jul 2002 01:30:26 -0000	1.66
+++ library/varset.m	3 Jan 2003 06:01:20 -0000
@@ -1,5 +1,5 @@
 %---------------------------------------------------------------------------%
-% Copyright (C) 1993-2000,2002 The University of Melbourne.
+% Copyright (C) 1993-2000,2002-2003 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.
 %---------------------------------------------------------------------------%
@@ -230,6 +230,16 @@
 :- func varset__coerce(varset(T)) = varset(U).
 
 :- implementation.
+
+% Everything below here is not intended to be part of the public interface,
+% and will not be included in the Mercury library reference manual.
+
+:- interface.
+
+	% Returns the highest numbered variable returned from this varset's
+	% var_supply.
+:- func varset__max_var(varset(T)) = var(T).
+
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -599,6 +609,10 @@
 	% generated by the compiler, but type coercion by 
 	% copying was taking about 3% of the compiler's runtime.
 	private_builtin__unsafe_type_cast(A, B).
+
+%-----------------------------------------------------------------------------%
+
+varset__max_var(varset(VarSupply, _, _)) = term__var_supply_max_var(VarSupply).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
cvs diff: Diffing profiler
cvs diff: Diffing robdd
Index: robdd/Makefile
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/Makefile,v
retrieving revision 1.1
diff -u -b -r1.1 Makefile
--- robdd/Makefile	10 Mar 2000 05:17:20 -0000	1.1
+++ robdd/Makefile	26 Feb 2003 08:23:33 -0000
@@ -1,5 +1,10 @@
+#-----------------------------------------------------------------------------#
+# Copyright (C) 2001-2003 University of Melbourne. 
+# This file may only be copied under the terms of the GNU General
+# Public Licence - see the file COPYING in the Mercury distribution.
+#-----------------------------------------------------------------------------#
 #  File     : Makefile
-#  RCS      : $Id: Makefile,v 1.1 2000/03/10 05:17:20 dmo Exp $
+#  RCS      : $Id: Makefile,v 1.1.12.1 2001/02/14 04:42:48 dmo Exp $
 #  Author   : Peter Schachte
 #  Origin   : 1995
 #  Purpose  : Makefile for bryant graph (ROBDD) manipulation code
@@ -39,7 +44,8 @@
 MV=mv
 MKDIR=mkdir
 DEBUG=-g -DDEBUGALL
-OPTIMIZE=-O3 -DNDEBUG -funroll-loops
+#OPTIMIZE=-O3 -DNDEBUG -funroll-loops
+OPTIMIZE=-DNDEBUG
 CC=gcc -I../mylib -I/usr/ucbinclude -I. -ansi
 LIBDIRS=-L/home/staff/pets/quintus/bin3.2/sun4-5
 #LIBS= -L/usr/ucblib -lucb
@@ -55,7 +61,11 @@
 #CHOSENOPTIM=$(DEBUG)
 
 #OPTS=$(DEF)COMPUTED_TABLE $(DEF)EQUAL_TEST
-OPTS=$(DEF)CLEAR_CACHES $(DEF)COMPUTED_TABLE $(DEF)EQUAL_TEST
+OPTS= \
+	$(DEF)CLEAR_CACHES \
+	$(DEF)COMPUTED_TABLE \
+	$(DEF)EQUAL_TEST \
+	$(DEF)USE_ITE_CONSTANT
 #OPTS=$(DEF)CLEAR_CACHES $(DEF)COMPUTED_TABLE $(DEF)EQUAL_TEST $(DEF)STATISTICS
 #WHICH=NAIVE
 #WHICH=OLD
Index: robdd/Mmakefile
===================================================================
RCS file: robdd/Mmakefile
diff -N robdd/Mmakefile
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ robdd/Mmakefile	3 Jan 2003 06:06:48 -0000
@@ -0,0 +1,31 @@
+#-----------------------------------------------------------------------------#
+# Copyright (C) 2003 University of Melbourne. 
+# This file may only be copied under the terms of the GNU General
+# Public Licence - see the file COPYING in the Mercury distribution.
+#-----------------------------------------------------------------------------#
+
+# Mmakefile for Peter Schachte's ROBDD package.
+
+MAIN_TARGET=robdd
+
+MERCURY_DIR=..
+include $(MERCURY_DIR)/Mmake.common
+
+M_ENV		= MERCURY_ALL_C_INCL_DIRS="\
+			-I$(BROWSER_DIR) \
+			-I$(LIBRARY_DIR) \
+			-I$(RUNTIME_DIR) \
+			-I$(BOEHM_GC_DIR) \
+			-I$(BOEHM_GC_DIR)/include \
+		  "
+MGNUC		= $(M_ENV) $(SCRIPTS_DIR)/mgnuc
+
+CFILES	= bryant.c
+
+OBJS		= $(CFILES:.c=.$O)
+PIC_OBJS	= $(CFILES:.c=.$(EXT_FOR_PIC_OBJECTS))
+
+.PHONY: robdd
+robdd: $(OBJS) $(PIC_OBJS)
+
+include Makefile
Index: robdd/bryant.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/bryant.c,v
retrieving revision 1.1
diff -u -b -r1.1 bryant.c
--- robdd/bryant.c	10 Mar 2000 05:17:21 -0000	1.1
+++ robdd/bryant.c	5 Jan 2003 22:23:25 -0000
@@ -1,9 +1,17 @@
+/*
+** vim: ts=4 sw=4 expandtab
+*/
+/*
+** Copyright (C) 1995, 2001-2003 Peter Schachte and 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     : bryant.c
-  RCS      : $Id: bryant.c,v 1.1 2000/03/10 05:17:21 dmo Exp $
+  RCS      : $Id: bryant.c,v 1.1.12.4 2002/05/08 09:35:28 zs Exp $
   Author   : Peter Schachte, based on code by Tania Armstrong
   Purpose  : Manipulation of boolean functions
-  Copyright: © 1995 Peter Schachte.  All rights reserved.
 
 *****************************************************************/
 
@@ -11,86 +19,93 @@
 
 		     Controlling #defined Symbols
 
-
   This code is conditionalized on a number of #defined symbols.  They are:
 
-    STATISTICS		Controls collecting of computed and unique
+    MR_ROBDD_STATISTICS     Controls collecting of computed and unique
 			table hash performance.  If defined,
-			concludeRep() prints out a bunch of
+                            MR_ROBDD_concludeRep() prints out a bunch of
 			statistics.
 
-    CLEAR_CACHES	If defined, all computed and unique tables are
-			cleared on a call to initRep().  This makes
+    MR_ROBDD_CLEAR_CACHES   If defined, all computed and unique tables are
+                            cleared on a call to MR_ROBDD_initRep(). This makes
 			running a number of tests in sequence more
 			fair.
 
-    NAIVE		If defined, uses very naive algorithms for
-			iff_conj_array, renameArray, lub, glb,
-			and probably some I've forgotten.
-
-    OLD			If defined, use slightly less naive algorithms for
-			restrictThresh, restricted_glb, vars_entailed,
-			and iff_conj_array.
-
-    USE_THRESH		Like OLD, except that it does use the new code
-			for restrictThresh.  Implies OLD.
-
-    USE_RGLB		Like USE_THRESH, except that it also uses the
-			new code for restricted_glb.  Implies USE_THRESH.
-
-    NEW			Like USE_RGLB, but uses all the lastest and greatest
-			algorithms.  Implies USE_RGLB.
+    MR_ROBDD_NAIVE          If defined, uses very naive algorithms for
+                            MR_ROBDD_iff_conj_array, MR_ROBDD_renameArray,
+                            MR_ROBDD_lub, MR_ROBDD_glb, and probably some I've
+                            forgotten.
+
+    MR_ROBDD_OLD            If defined, use slightly less naive algorithms for
+                            MR_ROBDD_restrictThresh, MR_ROBDD_restricted_glb,
+                            MR_ROBDD_vars_entailed, and
+                            MR_ROBDD_iff_conj_array.
+
+    MR_ROBDD_USE_THRESH     Like MR_ROBDD_OLD, except that it does use the new
+                            code for MR_ROBDD_restrictThresh. Implies
+                            MR_ROBDD_OLD.
+
+    MR_ROBDD_USE_RGLB       Like MR_ROBDD_USE_THRESH, except that it also uses
+                            the new code for MR_ROBDD_restricted_glb. Implies
+                            MR_ROBDD_USE_THRESH.
+
+    MR_ROBDD_NEW            Like MR_ROBDD_USE_RGLB, but uses all the lastest
+                            and greatest algorithms. Implies MR_ROBDD_USE_RGLB.
+
+    MR_ROBDD_USE_ITE_CONSTANT
+                            Include the MR_ROBDD_ite_constant function, and'
+                            use it to speed up the non-MR_ROBDD_NEW version of
+                            MR_ROBDD_var_entailed (and MR_ROBDD_vars_entailed).
 
-    USE_ITE_CONSTANT	Include the ite_constant function, and use it
-			to speed up the non-NEW version of
-			var_entailed (and vars_entailed).
-
-    SHARING		Include algorithms useful in sharing analysis
+    MR_ROBDD_SHARING        Include algorithms useful in sharing analysis
 			performed using Boolean functions.
 
-    RESTRICT_SET	Only meaningful if OLD && !USE_THRESH.  If
-			defined, then we restrict by making a first pass
-			over the ROBDD finding the set of variables
-			present that are greater than the threshold, and
-			then restrict away each variable in that set.
-
-    WHICH		Is defined to "NAIVE", "OLD", "USE_THRESH",
-			"USE_RGLB", or "NEW", depending on which of
-			the NAIVE, OLD, USE_THRESH, and USE_RGLB
-			variables are defined.  This is automatically
-			defined by bryant.h based on the above
-			variables.
-
-    VE_GLB		(only when OLD is defined) if defined,
-			var_entailed(fn, v) compares the fn to
-			glb(variableRep(v), fn).  The var is entailed
-			if they are equal.  Otherwise computes
-			variableRep(v) -> fn.  The variable is
-			entailed if this is 'one'.
-
-    ELIM_DUPS		If defined, iff_conj_array will not assume
-			that the input array has no duplicates.  It
-			will still assume that it's sorted.
-
-    COMPUTED_TABLE	Enables the computed table in lub, glb, ite,
-			and restricted_glb.
-
-    EQUAL_TEST		If defined, lub(), glb(), and restricted_glb
-			compare their arguments for equality, and if
-			equal return it as value.  ite and ite_var
-			always do this with their last 2 args.  The
-			equality test is pretty cheap, and the savings
-			will sometimes be huge, so this should
-			probably always be defined.
+    MR_ROBDD_RESTRICT_SET   Only meaningful if MR_ROBDD_OLD &&
+                            !MR_ROBDD_USE_THRESH.  If defined, then we restrict
+                            by making a first pass over the ROBDD finding the
+                            set of variables present that are greater than the
+                            threshold, and then restrict away each variable
+                            in that set.
+
+    MR_ROBDD_WHICH          Is defined to "MR_ROBDD_NAIVE", "MR_ROBDD_OLD",
+                            "MR_ROBDD_USE_THRESH", "MR_ROBDD_USE_RGLB", or
+                            "MR_ROBDD_NEW", depending on which of the
+                            MR_ROBDD_NAIVE, MR_ROBDD_OLD, MR_ROBDD_USE_THRESH,
+                            and MR_ROBDD_USE_RGLB variables are defined. This
+                            is automatically defined by bryant.h based on the
+                            above variables.
+
+    MR_ROBDD_VE_GLB         (only when MR_ROBDD_OLD is defined) if defined,
+                            MR_ROBDD_var_entailed(fn, v) compares the fn to
+                            MR_ROBDD_glb(MR_ROBDD_variableRep(v), fn). The var
+                            is entailed if they are equal.  Otherwise computes
+                            MR_ROBDD_variableRep(v) -> fn.  The variable is
+                            entailed if this is 'MR_ROBDD_one'.
+
+    MR_ROBDD_ELIM_DUPS      If defined, MR_ROBDD_iff_conj_array will not assume
+                            that the input array has no duplicates. It will
+                            still assume that it's sorted.
+
+    MR_ROBDD_COMPUTED_TABLE Enables the computed table in MR_ROBDD_lub,
+                            MR_ROBDD_glb, MR_ROBDD_ite, and
+                            MR_ROBDD_restricted_glb.
+
+    MR_ROBDD_EQUAL_TEST     If defined, MR_ROBDD_lub(), MR_ROBDD_glb(), and
+                            MR_ROBDD_restricted_glb compare their arguments for
+                            equality, and if equal return it as value.
+                            MR_ROBDD_ite and MR_ROBDD_ite_var always do this
+                            with their last 2 args. The equality test is pretty
+                            cheap, and the savings will sometimes be huge, so
+                            this should probably always be defined.
 
-    NO_CHEAP_SHIFT	If defined, shifting an integer variable number
+    MR_ROBDD_NO_CHEAP_SHIFT If defined, shifting an integer variable number
 			of places is relatively expensive on this platform,
 			and so should be avoided.  In this case we use a
 			table where possible to avoid shifting.
 
-
 *****************************************************************/
 
+#include "mercury_imp.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
@@ -98,26 +113,44 @@
 #include <limits.h>
 #include "bryant.h"
 
+#ifdef MR_ROBDD_BRYANT_CONSERVATIVE_GC
+
+  /* Don't use pools of nodes with the conservative GC. */
+  #undef MR_ROBDD_POOL
+
+  /* Redefine malloc() and free() to use the GC versions */
+  #define malloc(n) GC_malloc(n)
+  #define free(p) GC_free(p)
+
+#else /* !MR_ROBDD_BRYANT_CONSERVATIVE_GC */
+
+  #define MR_ROBDD_POOL
+
+#endif /* MR_ROBDD_BRYANT_CONSERVATIVE_GC */
+
+#define MR_ROBDD_REVEAL_NODE_POINTER(p) \
+    ((MR_ROBDD_node *) MR_ROBDD_REVEAL_POINTER(p))
 
-#define UNUSED_MAPPING -1	/* this MUST BE -1 */
+#define MR_ROBDD_UNUSED_MAPPING -1    /* this MUST BE -1 */
 
-#if !defined(max)
-#define max(a,b) ((a)<(b) ? (b) : (a))
+#if !defined(MR_ROBDD_max)
+  #define MR_ROBDD_max(a,b) ((a)<(b) ? (b) : (a))
 #endif
-#if !defined(min)
-#define min(a,b) ((a)<(b) ? (a) : (b))
+#if !defined(MR_ROBDD_min)
+  #define MR_ROBDD_min(a,b) ((a)<(b) ? (a) : (b))
 #endif
 
-#define PERCENTAGE(x,y) ((100.0 * (float)(x)) / (float)(y))
+#define MR_ROBDD_PERCENTAGE(x,y) ((100.0 * (float)(x)) / (float)(y))
 
-typedef struct pool {
-    node data[POOL_SIZE];
+#ifdef MR_ROBDD_POOL
+  typedef struct pool {
+    MR_ROBDD_node data[MR_ROBDD_POOL_SIZE];
     struct pool *prev;
-} pool;
+  } pool;
+#endif MR_ROBDD_POOL
 
-
-#if defined(NO_CHEAP_SHIFT) && BITS_PER_WORD == 32
-bitmask following_bits[BITS_PER_WORD] =
+#if defined(MR_ROBDD_NO_CHEAP_SHIFT) && MR_ROBDD_BITS_PER_WORD == 32
+  MR_ROBDD_bitmask MR_ROBDD_following_bits[MR_ROBDD_BITS_PER_WORD] =
     {  0xffffffff, 0xfffffffe, 0xfffffffc, 0xfffffff8,
        0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80,
        0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800,
@@ -128,7 +161,7 @@
        0xf0000000, 0xe0000000, 0xc0000000, 0x80000000
     };
 
-bitmask preceding_bits[BITS_PER_WORD] =
+  MR_ROBDD_bitmask MR_ROBDD_preceding_bits[MR_ROBDD_BITS_PER_WORD] =
     {  0x00000001, 0x00000003, 0x00000007, 0x0000000f,
        0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
        0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
@@ -140,8 +173,7 @@
     };
 #endif
 
-
-unsigned char first_one_bit[256] =
+unsigned char MR_ROBDD_first_one_bit[256] =
     {255, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*  16 */
        4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*  32 */
        5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /*  48 */
@@ -160,7 +192,7 @@
        4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 256 */
     };
 
-unsigned char last_one_bit[256] =
+unsigned char MR_ROBDD_last_one_bit[256] =
     {255, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, /*  16 */
        4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, /*  32 */
        5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, /*  48 */
@@ -179,9 +211,8 @@
        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, /* 256 */
     };
 
-
 /* automatically initialized to all 0 bits: */
-bitset emptyset;
+MR_ROBDD_bitset MR_ROBDD_emptyset;
 
 /****************************************************************
 
@@ -189,115 +220,126 @@
 
  ****************************************************************/
 
-
-#if defined(COMPUTED_TABLE) && defined(CLEAR_CACHES)
-#define CLEAR_CACHE(op)	\
-memset(op##_computed_cache, 0, sizeof(op##_computed_cache))
-#else /* !CLEAR_CACHES || !COMPUTED_TABLE */
-#define CLEAR_CACHE(op)
+#if defined(MR_ROBDD_COMPUTED_TABLE) && defined(MR_ROBDD_CLEAR_CACHES)
+  #define MR_ROBDD_CLEAR_CACHE(op)    \
+    MR_memset(op##_computed_cache, 0, sizeof(op##_computed_cache))
+#else /* !MR_ROBDD_CLEAR_CACHES || !MR_ROBDD_COMPUTED_TABLE */
+  #define MR_ROBDD_CLEAR_CACHE(op)
 #endif
 
+#if defined(MR_ROBDD_STATISTICS)
 
-#if defined(STATISTICS)
-
-/* The largest bucket size to be separately counted.  Larger buckets
- * will be listed as "> MAX_COUNT." 
+  /* The largest bucket size to be separately counted.  Larger buckets
+   * will be listed as "> MR_ROBDD_MAX_COUNT." 
  */
-#define MAX_COUNT 1000
+  #define MR_ROBDD_MAX_COUNT            1000
 
-int unique_table_hits, unique_table_misses;
+  int MR_ROBDD_unique_table_hits, MR_ROBDD_unique_table_misses;
 
-#define DECLARE_FN_COUNT(op) int op##_count;
+  #define MR_ROBDD_DECLARE_FN_COUNT(op) int op##_count;
 
-#define COUNT_FN(fn) (++fn##_count)
+  #define MR_ROBDD_COUNT_FN(fn)         (++fn##_count)
 
-#define INIT_FN_COUNT(fn) fn##_count = 0
-#define PRINT_FN_COUNT(fn) \
+  #define MR_ROBDD_INIT_FN_COUNT(fn)    fn##_count = 0
+  #define MR_ROBDD_PRINT_FN_COUNT(fn) \
   if (fn##_count!=0) printf("%6d calls to " #fn "\n", fn##_count);
 
-#define COUNT_UNIQUE_HIT (++unique_table_hits)
-#define COUNT_UNIQUE_MISS (++unique_table_misses)
+  #define MR_ROBDD_COUNT_UNIQUE_HIT (++MR_ROBDD_unique_table_hits)
+  #define MR_ROBDD_COUNT_UNIQUE_MISS (++MR_ROBDD_unique_table_misses)
 
-#if defined(COMPUTED_TABLE)
+  #if defined(MR_ROBDD_COMPUTED_TABLE)
 
-#define COUNT_HIT(op) (++op##_computed_hits)
-#define COUNT_MISS(op) (++op##_computed_misses, ++cache->count)
-#define INIT_CACHE(op)			\
+    #define MR_ROBDD_COUNT_HIT(op) (++op##_computed_hits)
+    #define MR_ROBDD_COUNT_MISS(op) (++op##_computed_misses, ++cache->count)
+    #define MR_ROBDD_INIT_CACHE(op)                                         \
     do {				\
 	op##_computed_misses = 0;	\
 	op##_computed_hits = 0;		\
-	CLEAR_CACHE(op);		\
+        MR_ROBDD_CLEAR_CACHE(op);                                           \
     } while (0)
 
-#define CACHE_COUNT_MEMBER int count;
-#define PRINT_CACHE_PERFORMANCE(op)					\
-do {									\
+    #define MR_ROBDD_CACHE_COUNT_MEMBER int count;
+    #define MR_ROBDD_PRINT_CACHE_PERFORMANCE(op)                            \
+    do {                                                                    \
     if (op##_computed_misses > 0 ) {					\
-	int i, size_count[MAX_COUNT+2];					\
-	printf(#op " computed table:  %d hits, %d misses, %.2f%% hit rate\n",\
+            int i, size_count[MR_ROBDD_MAX_COUNT+2];                        \
+            printf(                                                         \
+                #op " computed table:  %d hits, %d misses, %.2f%% hit rate\n",\
 	       op##_computed_hits, op##_computed_misses,		\
-		PERCENTAGE(op##_computed_hits,				\
+            MR_ROBDD_PERCENTAGE(op##_computed_hits,                         \
 			   op##_computed_hits + op##_computed_misses));	\
-	memset(size_count, 0, sizeof(size_count));			\
-	for (i=0; i<COMPUTED_TABLE_SIZE; ++i) {				\
+            MR_memset(size_count, 0, sizeof(size_count));                   \
+            for (i=0; i<MR_ROBDD_COMPUTED_TABLE_SIZE; ++i) {                \
 	    int count = op##_computed_cache[i].count;			\
-	    ++size_count[(count<=MAX_COUNT ? count : MAX_COUNT+1)];	\
+                ++size_count[(count<=MR_ROBDD_MAX_COUNT ? count :           \
+                    MR_ROBDD_MAX_COUNT+1)];                                 \
 	}								\
-	print_distribution(size_count, MAX_COUNT);			\
+            MR_ROBDD_print_distribution(size_count, MR_ROBDD_MAX_COUNT);    \
     }									\
-} while (0)
-#else /* !COMPUTED_TABLE */
-#define PRINT_CACHE_PERFORMANCE(op)
-#endif /* COMPUTED_TABLE */
-#else /* ! STATISTICS */
-#define DECLARE_FN_COUNT(op)
-#define COUNT_FN(fn)
-#define INIT_FN_COUNT(fn)
-#define PRINT_FN_COUNT(fn)
-#define COUNT_UNIQUE_HIT
-#define COUNT_UNIQUE_MISS
-#define INIT_CACHE(op) CLEAR_CACHE(op)
-#define PRINT_CACHE_PERFORMANCE(op)
-#if defined(COMPUTED_TABLE)
-#define COUNT_HIT(fn)
-#define COUNT_MISS(fn)
-#define CACHE_COUNT_MEMBER
-#endif /* COMPUTED_TABLE */
-#endif /* STATISTICS */
-
-
-#if defined(EQUAL_TEST)
-#define DIRECT_EQUAL_TEST(f,g,result) if ((f) == (g)) return (result)
-#define ELSE_TRY_EQUAL_TEST(f,g,result) \
-  else DIRECT_EQUAL_TEST(f,g,result);
-#else /* ! EQUAL_TEST */
-#define DIRECT_EQUAL_TEST(f,g,result)
-#define ELSE_TRY_EQUAL_TEST(f,g,result)
+    } while (0)
+
+  #else /* !MR_ROBDD_COMPUTED_TABLE */
+
+    #define MR_ROBDD_PRINT_CACHE_PERFORMANCE(op)
+
+  #endif /* MR_ROBDD_COMPUTED_TABLE */
+#else /* ! MR_ROBDD_STATISTICS */
+
+  #define MR_ROBDD_DECLARE_FN_COUNT(op)
+  #define MR_ROBDD_COUNT_FN(fn)
+  #define MR_ROBDD_INIT_FN_COUNT(fn)
+  #define MR_ROBDD_PRINT_FN_COUNT(fn)
+  #define MR_ROBDD_COUNT_UNIQUE_HIT
+  #define MR_ROBDD_COUNT_UNIQUE_MISS
+  #define MR_ROBDD_INIT_CACHE(op) MR_ROBDD_CLEAR_CACHE(op)
+  #define MR_ROBDD_PRINT_CACHE_PERFORMANCE(op)
+
+  #if defined(MR_ROBDD_COMPUTED_TABLE)
+    #define MR_ROBDD_COUNT_HIT(fn)
+    #define MR_ROBDD_COUNT_MISS(fn)
+    #define MR_ROBDD_CACHE_COUNT_MEMBER
+  #endif /* MR_ROBDD_COMPUTED_TABLE */
+
+#endif /* MR_ROBDD_STATISTICS */
+
+#if defined(MR_ROBDD_EQUAL_TEST)
+  #define MR_ROBDD_DIRECT_EQUAL_TEST(f,g,result)   \
+    if ((f) == (g)) return (result)
+  #define MR_ROBDD_ELSE_TRY_EQUAL_TEST(f,g,result) \
+    else MR_ROBDD_DIRECT_EQUAL_TEST(f,g,result);
+#else /* ! MR_ROBDD_EQUAL_TEST */
+  #define MR_ROBDD_DIRECT_EQUAL_TEST(f,g,result)
+  #define MR_ROBDD_ELSE_TRY_EQUAL_TEST(f,g,result)
 #endif
 
-#if defined(CLEAR_CACHES)
-#define INIT_UNIQUE_TABLE				\
+#if defined(MR_ROBDD_CLEAR_CACHES)
+  #if defined(MR_ROBDD_POOL)
+    #define MR_ROBDD_INIT_UNIQUE_TABLE                                      \
     do {						\
-	memset(unique_table, 0, sizeof(unique_table));	\
-	while (curr_pool!=NULL) {			\
-	    pool *p = curr_pool->prev;			\
-	    free(curr_pool);				\
-	    curr_pool = p;				\
+            MR_memset(MR_ROBDD_unique_table, (char) 0,                      \
+                sizeof(MR_ROBDD_unique_table));                             \
+            while (MR_ROBDD_curr_pool!=NULL) {                              \
+                pool *p = MR_ROBDD_curr_pool->prev;                         \
+                free(MR_ROBDD_curr_pool);                                   \
+                MR_ROBDD_curr_pool = p;                                     \
 	}						\
-	curr_pool_ptr = curr_pool_end_ptr = NULL;	\
-	pool_count = 0;					\
+            MR_ROBDD_curr_pool_ptr = MR_ROBDD_curr_pool_end_ptr = NULL;     \
+            MR_ROBDD_node_count = 0;                                        \
     } while (0)
-#else /* !CLEAR_CACHES */
-#define INIT_UNIQUE_TABLE
-#endif /* CLEAR_CACHES */
-
 
+  #else /* !MR_ROBDD_POOL */
+    #define MR_ROBDD_INIT_UNIQUE_TABLE                                      \
+    MR_memset(MR_ROBDD_unique_table, (char) 0, sizeof(MR_ROBDD_unique_table));
+   #endif /* MR_ROBDD_POOL */
+#else /* !MR_ROBDD_CLEAR_CACHES */
+  #define MR_ROBDD_INIT_UNIQUE_TABLE
+#endif /* MR_ROBDD_CLEAR_CACHES */
 
 /********************************************************************
 
 		      Caching of computed values
 
-  For improved efficiency, if COMPUTED_TABLE is defined we maintain a
+  For improved efficiency, if MR_ROBDD_COMPUTED_TABLE is defined we maintain a
   cache of previously computed values to certain functions, and use
   this to avoid costly computations when possible.  This is
   particularly important for ROBDDs, because the high degree of fan-in
@@ -309,375 +351,411 @@
 
  ********************************************************************/
 
-#if defined(COMPUTED_TABLE)
+#if defined(MR_ROBDD_COMPUTED_TABLE)
 
-#if defined(STATISTICS)
-#define DECLARE_CACHE(op,type)			\
-static int op##_computed_hits;			\
-static int op##_computed_misses;		\
-static type op##_computed_cache[COMPUTED_TABLE_SIZE]
-#else /* !STATISTICS */
-#define DECLARE_CACHE(op,type)			\
-static type op##_computed_cache[COMPUTED_TABLE_SIZE]
-#endif /* STATISTICS */
-
-/**************************** the cache for ite **************************/
-
-#define TERNARY_NODE_HASH(f,g,h) \
-  (((INTCAST(f)>>4)+INTCAST(g)+(INTCAST(h)<<1)) % COMPUTED_TABLE_SIZE)
-
-typedef struct {
-    node *f;
-    node *g;
-    node *h;
-    node *result;
-    CACHE_COUNT_MEMBER
-} ite_cache_entry;
-
-DECLARE_CACHE(ite, ite_cache_entry);
-#if defined(USE_ITE_CONSTANT)
-DECLARE_CACHE(ite_constant, ite_cache_entry);
-#endif /* USE_ITE_CONSTANT */
-
-#define DECLARE_ITE_CACHE_ENTRY ite_cache_entry *cache;
-
-#define TRY_ITE_CACHE(n1,n2,n3,op)				\
-do {								\
-	cache = &op##_computed_cache[TERNARY_NODE_HASH(n1,n2,n3)]; \
+  #if defined(MR_ROBDD_STATISTICS)
+    #define MR_ROBDD_DECLARE_CACHE(op,MR_ROBDD_type)                    \
+    static int op##_computed_hits;                                      \
+    static int op##_computed_misses;                                    \
+    static MR_ROBDD_type op##_computed_cache[MR_ROBDD_COMPUTED_TABLE_SIZE]
+  #else /* !MR_ROBDD_STATISTICS */
+    #define MR_ROBDD_DECLARE_CACHE(op,MR_ROBDD_type)                    \
+    static MR_ROBDD_type op##_computed_cache[MR_ROBDD_COMPUTED_TABLE_SIZE]
+  #endif /* MR_ROBDD_STATISTICS */
+
+/********************* the cache for MR_ROBDD_ite **************************/
+
+  #define MR_ROBDD_TERNARY_NODE_HASH(f,g,h) \
+    (((MR_ROBDD_INTCAST(f)>>4)+MR_ROBDD_INTCAST(g)+(MR_ROBDD_INTCAST(h)<<1)) \
+        % MR_ROBDD_COMPUTED_TABLE_SIZE)
+
+  typedef struct {
+    MR_ROBDD_node *f;
+    MR_ROBDD_node *g;
+    MR_ROBDD_node *h;
+    MR_ROBDD_node *result;
+    MR_ROBDD_CACHE_COUNT_MEMBER
+  } ite_cache_entry;
+
+  MR_ROBDD_DECLARE_CACHE(MR_ROBDD_ite, ite_cache_entry);
+  #if defined(MR_ROBDD_USE_ITE_CONSTANT)
+    MR_ROBDD_DECLARE_CACHE(MR_ROBDD_ite_constant, ite_cache_entry);
+  #endif /* MR_ROBDD_USE_ITE_CONSTANT */
+
+  #define MR_ROBDD_DECLARE_ITE_CACHE_ENTRY ite_cache_entry *cache;
+
+  #define MR_ROBDD_TRY_ITE_CACHE(n1,n2,n3,op)                               \
+    do {                                                                    \
+        cache = &op##_computed_cache[MR_ROBDD_TERNARY_NODE_HASH(n1,n2,n3)]; \
 	if (cache->f==n1 && cache->g==n2 && cache->h==n3) {	\
-	    COUNT_HIT(op);					\
+            MR_ROBDD_COUNT_HIT(op);                                         \
 	    return cache->result;				\
 	}							\
-} while (0)
+    } while (0)
 
-#define UPDATE_ITE_CACHE(n1,n2,n3,node,op)	\
-do {					\
+  #define MR_ROBDD_UPDATE_ITE_CACHE(n1,n2,n3,MR_ROBDD_node,op)              \
+    do {                                                                    \
 	cache->f = n1;			\
 	cache->g = n2;			\
 	cache->h = n3;			\
-	cache->result = node;		\
-	COUNT_MISS(op);			\
-} while (0)
-
+        cache->result = MR_ROBDD_node;                                      \
+        MR_ROBDD_COUNT_MISS(op);                                            \
+    } while (0)
 
 /******************** the cache for unary operations ************/
 
-#define UNARY_NODE_HASH(a) \
-      (INTCAST(a) % COMPUTED_TABLE_SIZE)
+  #define MR_ROBDD_UNARY_NODE_HASH(a) \
+      (MR_ROBDD_INTCAST(a) % MR_ROBDD_COMPUTED_TABLE_SIZE)
 
-typedef struct {
-    node *f;
-    node *result;
-    CACHE_COUNT_MEMBER
-} unary_cache_entry;
-
-#if defined(SHARING)
-DECLARE_CACHE(upclose, unary_cache_entry);
-#if defined(NEW)
-DECLARE_CACHE(complete_one, unary_cache_entry);
-#endif /* NEW */
-#endif /* SHARING */
+  typedef struct {
+    MR_ROBDD_node *f;
+    MR_ROBDD_node *result;
+    MR_ROBDD_CACHE_COUNT_MEMBER
+  } unary_cache_entry;
+
+  #if defined(MR_ROBDD_SHARING)
+    MR_ROBDD_DECLARE_CACHE(MR_ROBDD_upclose, unary_cache_entry);
+    #if defined(MR_ROBDD_NEW)
+      MR_ROBDD_DECLARE_CACHE(MR_ROBDD_complete_one, unary_cache_entry);
+    #endif /* MR_ROBDD_NEW */
+  #endif /* MR_ROBDD_SHARING */
 
-#define DECLARE_UNARY_CACHE_ENTRY unary_cache_entry *cache;
+  #define MR_ROBDD_DECLARE_UNARY_CACHE_ENTRY unary_cache_entry *cache;
 
-#define UPDATE_UNARY_CACHE(n,node,op)	\
-do {					\
+  #define MR_ROBDD_UPDATE_UNARY_CACHE(n,MR_ROBDD_node,op)                   \
+    do {                                                                    \
 	cache->f = n;			\
-	cache->result = node;		\
-	COUNT_MISS(op);		\
-} while (0)
-
-#define TRY_UNARY_CACHE(n,op)						\
-do {									\
-	cache = &((op##_computed_cache)[UNARY_NODE_HASH(n)]);		\
+        cache->result = MR_ROBDD_node;                                      \
+        MR_ROBDD_COUNT_MISS(op);                                            \
+    } while (0)
+
+  #define MR_ROBDD_TRY_UNARY_CACHE(n,op)                                    \
+    do {                                                                    \
+        cache = &((op##_computed_cache)[MR_ROBDD_UNARY_NODE_HASH(n)]);      \
 	if (cache->f==(n)) {						\
-	    COUNT_HIT(op);						\
+            MR_ROBDD_COUNT_HIT(op);                                         \
 	    return cache->result;					\
 	}								\
-} while (0)
-
+    } while (0)
 
-/******************** the cache for var_entailed ************/
+/******************** the cache for MR_ROBDD_var_entailed ************/
 
-#define VAR_ENTAILED_HASH(a,n) \
-      ((INTCAST(a)+n) % COMPUTED_TABLE_SIZE)
+  #define MR_ROBDD_VAR_ENTAILED_HASH(a,n) \
+      ((MR_ROBDD_INTCAST(a)+n) % MR_ROBDD_COMPUTED_TABLE_SIZE)
 
-typedef struct {
-    node *f;
+  typedef struct {
+    MR_ROBDD_node *f;
     int  n;
     int  result;
-    CACHE_COUNT_MEMBER
-} var_entailed_cache_entry;
+    MR_ROBDD_CACHE_COUNT_MEMBER
+  } var_entailed_cache_entry;
+
+  #if defined(MR_ROBDD_USE_RGLB)
+    MR_ROBDD_DECLARE_CACHE(MR_ROBDD_var_entailed, var_entailed_cache_entry);
+  #endif /* MR_ROBDD_USE_RGLB */
 
-#if defined(USE_RGLB)
-DECLARE_CACHE(var_entailed, var_entailed_cache_entry);
-#endif /* USE_RGLB */
-
-#define DECLARE_VAR_ENTAILED_CACHE_ENTRY var_entailed_cache_entry *cache;
-
-#define UPDATE_VAR_ENTAILED_CACHE(node,var,val)	\
-do {						\
-	cache->f = node;			\
+  #define MR_ROBDD_DECLARE_VAR_ENTAILED_CACHE_ENTRY \
+    var_entailed_cache_entry *cache;
+
+  #define MR_ROBDD_UPDATE_VAR_ENTAILED_CACHE(MR_ROBDD_node,var,val)         \
+    do {                                                                    \
+        cache->f = MR_ROBDD_node;                                           \
 	cache->n = var;				\
 	cache->result = val;			\
-	COUNT_MISS(var_entailed);		\
-} while (0)
+        MR_ROBDD_COUNT_MISS(MR_ROBDD_var_entailed);                         \
+    } while (0)
 
-#define TRY_VAR_ENTAILED_CACHE(node,var)		\
-do {							\
-	cache = &((var_entailed_computed_cache)		\
-		  [VAR_ENTAILED_HASH(node,var)]);	\
-	if (cache->f==(node) && cache->n==(var)) {	\
-	    COUNT_HIT(op);				\
+  #define MR_ROBDD_TRY_VAR_ENTAILED_CACHE(MR_ROBDD_node,var)                \
+    do {                                                                    \
+        cache = &((MR_ROBDD_var_entailed_computed_cache)                    \
+              [MR_ROBDD_VAR_ENTAILED_HASH(MR_ROBDD_node,var)]);             \
+        if (cache->f==(MR_ROBDD_node) && cache->n==(var)) {                 \
+            MR_ROBDD_COUNT_HIT(op);                                         \
 	    return cache->result;			\
 	}						\
-} while (0)
-
+    } while (0)
 
 /**************** the cache for unary set-valued operations ********/
 
-typedef struct {
-    node *f;
-    bitset result;
-    CACHE_COUNT_MEMBER
-} unary_bitset_cache_entry;
+  typedef struct {
+    MR_ROBDD_node *f;
+    MR_ROBDD_bitset result;
+    MR_ROBDD_CACHE_COUNT_MEMBER
+  } unary_bitset_cache_entry;
+
+  #if defined(MR_ROBDD_NEW)
+    MR_ROBDD_DECLARE_CACHE(MR_ROBDD_vars_entailed, unary_bitset_cache_entry);
+  #endif
 
-#if defined(NEW)
-DECLARE_CACHE(vars_entailed, unary_bitset_cache_entry);
-#endif
-
-#define DECLARE_UNARY_BITSET_CACHE_ENTRY \
+  #define MR_ROBDD_DECLARE_UNARY_BITSET_CACHE_ENTRY                         \
 	unary_bitset_cache_entry *cache;
 
-
-#define UPDATE_UNARY_BITSET_CACHE(n,set,op)		\
-do {							\
+  #define MR_ROBDD_UPDATE_UNARY_BITSET_CACHE(n,set,op)                      \
+    do {                                                                    \
 	cache->f = n;					\
 	cache->result = set;				\
-	COUNT_MISS(op);					\
-} while (0)
+        MR_ROBDD_COUNT_MISS(op);                                            \
+    } while (0)
 
-#define TRY_UNARY_BITSET_CACHE(n,op)			\
-do {								\
-	cache = &((op##_computed_cache)[UNARY_NODE_HASH(n)]);	\
+  #define MR_ROBDD_TRY_UNARY_BITSET_CACHE(n,op)                             \
+    do {                                                                    \
+        cache = &((op##_computed_cache)[MR_ROBDD_UNARY_NODE_HASH(n)]);      \
 	if (cache->f==(n)) {					\
-	    COUNT_HIT(op);					\
+            MR_ROBDD_COUNT_HIT(op);                                         \
 	    return &cache->result;				\
 	}							\
-} while (0)
-
+    } while (0)
 
 /******************** the cache for symmetric binary operations ************/
 
-/* NB:  Since glb and lub are commutative, cache entries will work both
- * ways round, so we want a symmetrical cache, ie, (a,b) should hash
- * to the same value as (b,a).  We achieve this by first exchanging a and b
- * if a > b (comparing their addresses) in TRY_BIN_CACHE.  We assume that
- * they won't be changed (or exchanged) before UPDATE_BIN_CACHE is called.
- */
-
-#define BINARY_NODE_HASH(a,b) \
-      ((INTCAST(a)+(INTCAST(b)<<1)) % COMPUTED_TABLE_SIZE)
-
-typedef struct {
-    node *f;
-    node *g;
-    node *result;
-    CACHE_COUNT_MEMBER
-} bin_cache_entry;
-
-DECLARE_CACHE(glb, bin_cache_entry);
-DECLARE_CACHE(lub, bin_cache_entry);
-#if defined(SHARING)
-DECLARE_CACHE(bin, bin_cache_entry);
-DECLARE_CACHE(complete, bin_cache_entry);
-#endif
+/*
+** NB:  Since MR_ROBDD_glb and MR_ROBDD_lub are commutative, cache entries
+** will work both ways round, so we want a symmetrical cache, ie, (a,b) should
+** hash to the same value as (b,a).  We achieve this by first exchanging
+** a and b if a > b (comparing their addresses) in MR_ROBDD_TRY_BIN_CACHE.
+** We assume that they won't be changed (or exchanged) before
+** MR_ROBDD_UPDATE_BIN_CACHE is called.
+*/
+
+  #define MR_ROBDD_BINARY_NODE_HASH(a,b) \
+      ((MR_ROBDD_INTCAST(a)+(MR_ROBDD_INTCAST(b)<<1)) % MR_ROBDD_COMPUTED_TABLE_SIZE)
+
+  typedef struct {
+    MR_ROBDD_node *f;
+    MR_ROBDD_node *g;
+    MR_ROBDD_node *result;
+    MR_ROBDD_CACHE_COUNT_MEMBER
+  } bin_cache_entry;
+
+  MR_ROBDD_DECLARE_CACHE(MR_ROBDD_glb, bin_cache_entry);
+  MR_ROBDD_DECLARE_CACHE(MR_ROBDD_lub, bin_cache_entry);
+  #if defined(MR_ROBDD_SHARING)
+    MR_ROBDD_DECLARE_CACHE(MR_ROBDD_bin, bin_cache_entry);
+    MR_ROBDD_DECLARE_CACHE(MR_ROBDD_complete, bin_cache_entry);
+  #endif
 
-#define DECLARE_BIN_CACHE_ENTRY bin_cache_entry *cache;
+  #define MR_ROBDD_DECLARE_BIN_CACHE_ENTRY bin_cache_entry *cache;
 
-#define UPDATE_BIN_CACHE(n1,n2,node,op)	\
-do {					\
+  #define MR_ROBDD_UPDATE_BIN_CACHE(n1,n2,MR_ROBDD_node,op)                 \
+    do {                                                                    \
 	cache->f = n1;			\
 	cache->g = n2;			\
-	cache->result = node;		\
-	COUNT_MISS(op);		\
-} while (0)
-
-#define TRY_BIN_CACHE(n1,n2,op)						\
-do {									\
-	if (n2 < n1) { node *temp = (n2); (n2) = (n1); (n1) = temp; }	\
-	cache = &((op##_computed_cache)[BINARY_NODE_HASH(n1,n2)]);	\
+        cache->result = MR_ROBDD_node;                                      \
+        MR_ROBDD_COUNT_MISS(op);                                            \
+    } while (0)
+
+  #define MR_ROBDD_TRY_BIN_CACHE(n1,n2,op)                                  \
+    do {                                                                    \
+        if (n2 < n1) {                                                      \
+            MR_ROBDD_node *temp = (n2);                                     \
+            (n2) = (n1);                                                    \
+            (n1) = temp;                                                    \
+        }                                                                   \
+        cache = &((op##_computed_cache)[MR_ROBDD_BINARY_NODE_HASH(n1,n2)]); \
 	if (cache->f==(n1) && cache->g==(n2)) {				\
-	    COUNT_HIT(op);						\
+            MR_ROBDD_COUNT_HIT(op);                                         \
 	    return cache->result;					\
 	}								\
-} while (0)
+    } while (0)
 
 /******************** the cache for asymmetric binary operations ************/
 
-#if defined(SHARING) && defined(NEW)
-DECLARE_CACHE(complete_one_or, bin_cache_entry);
+  #if defined(MR_ROBDD_SHARING) && defined(MR_ROBDD_NEW)
+    MR_ROBDD_DECLARE_CACHE(MR_ROBDD_complete_one_or, bin_cache_entry);
+  #endif /* MR_ROBDD_SHARING && MR_ROBDD_NEW */
+
+  #if defined(MR_ROBDD_USE_THRESH)
+    MR_ROBDD_DECLARE_CACHE(MR_ROBDD_restrictThresh, bin_cache_entry);
+  #endif /* MR_ROBDD_USE_THRESH */
 
-#define DECLARE_ASYM_BIN_CACHE_ENTRY bin_cache_entry *cache;
+  #if (defined(MR_ROBDD_SHARING) && defined(MR_ROBDD_NEW)) || defined(MR_ROBDD_USE_THRESH)
 
-#define UPDATE_ASYM_BIN_CACHE(n1,n2,node,op) \
-	UPDATE_BIN_CACHE(n1,n2,node,op)
+    #define MR_ROBDD_DECLARE_ASYM_BIN_CACHE_ENTRY bin_cache_entry *cache;
 
-#define TRY_ASYM_BIN_CACHE(n1,n2,op)					\
-do {									\
-	cache = &((op##_computed_cache)[BINARY_NODE_HASH(n1,n2)]);	\
+    #define MR_ROBDD_UPDATE_ASYM_BIN_CACHE(n1,n2,MR_ROBDD_node,op)          \
+        MR_ROBDD_UPDATE_BIN_CACHE(n1,n2,MR_ROBDD_node,op)
+
+  #define MR_ROBDD_TRY_ASYM_BIN_CACHE(n1,n2,op)                             \
+    do {                                                                    \
+        cache = &((op##_computed_cache)[MR_ROBDD_BINARY_NODE_HASH(n1,n2)]); \
 	if (cache->f==(n1) && cache->g==(n2)) {				\
-	    COUNT_HIT(op);						\
+            MR_ROBDD_COUNT_HIT(op);                                         \
 	    return cache->result;					\
 	}								\
-} while (0)
-#endif /* SHARING && NEW */
+    } while (0)
+
+  #endif /* (MR_ROBDD_SHARING && MR_ROBDD_NEW) || MR_ROBDD_USE_THRESH */
 
 /**************************** the cache for rglb ***********************/
 
-#if defined(USE_RGLB)
+  #if defined(MR_ROBDD_USE_RGLB)
 
-typedef struct {
-    node *f;
-    node *g;
-    node *result;
+    typedef struct {
+    MR_ROBDD_node *f;
+    MR_ROBDD_node *g;
+    MR_ROBDD_node *result;
     int  thresh;
-    CACHE_COUNT_MEMBER
-} rglb_cache_entry;
+    MR_ROBDD_CACHE_COUNT_MEMBER
+    } rglb_cache_entry;
 
-DECLARE_CACHE(rglb, rglb_cache_entry);
+    MR_ROBDD_DECLARE_CACHE(rglb, rglb_cache_entry);
 
-#define DECLARE_RGLB_CACHE_ENTRY rglb_cache_entry *cache;
+    #define MR_ROBDD_DECLARE_RGLB_CACHE_ENTRY rglb_cache_entry *cache;
 
-#define TRY_RGLB_CACHE(n1,n2,th)				\
-do {								\
-	if (n2 < n1) { node *temp = (n2); (n2) = (n1); (n1) = temp; }	\
-	cache = &rglb_computed_cache[BINARY_NODE_HASH(n1,n2)];	\
+    #define MR_ROBDD_TRY_RGLB_CACHE(n1,n2,th)                               \
+    do {                                                                    \
+        if (n2 < n1) {                                                      \
+            MR_ROBDD_node *temp = (n2);                                     \
+            (n2) = (n1);                                                    \
+            (n1) = temp;                                                    \
+        }                                                                   \
+        cache = &rglb_computed_cache[MR_ROBDD_BINARY_NODE_HASH(n1,n2)];     \
 	if (cache->f==(n1) && cache->g==(n2) &&			\
 	    cache->thresh >= th) {				\
-	    COUNT_HIT(rglb);					\
+            MR_ROBDD_COUNT_HIT(rglb);                                       \
 	    if (cache->thresh == th) return cache->result;	\
-	    return restrictThresh(th, cache->result);		\
+            return MR_ROBDD_restrictThresh(th, cache->result);              \
 	}							\
-} while (0)
+    } while (0)
 
-#define UPDATE_RGLB_CACHE(n1,n2,th,node) \
-do {					\
+    #define MR_ROBDD_UPDATE_RGLB_CACHE(n1,n2,th,MR_ROBDD_node)              \
+    do {                                                                    \
 	cache->f = n1;			\
 	cache->g = n2;			\
 	cache->thresh = th;		\
-	cache->result = node;		\
-	COUNT_MISS(rglb);		\
-} while (0)
-
-#endif /* USE_RGLB */
-
-/************************ the cache for complete_or *******************/
-
-#if defined(SHARING) && defined(NEW)
-typedef struct {
-    node *f;
-    node *g;
-    node *prev;
-    node *result;
-    CACHE_COUNT_MEMBER
-} complete_or_cache_entry;
-
-DECLARE_CACHE(complete_or, complete_or_cache_entry);
-
-#define DECLARE_COMPLETE_OR_CACHE_ENTRY complete_or_cache_entry *cache;
-
-#define TRY_COMPLETE_OR_CACHE(n1,n2,pr)				\
-do {								\
-	if (n2 < n1) { node *temp = (n2); (n2) = (n1); (n1) = temp; }	\
-	cache = &complete_or_computed_cache[TERNARY_NODE_HASH(n1,n2,pr)]; \
+        cache->result = MR_ROBDD_node;                                      \
+        MR_ROBDD_COUNT_MISS(rglb);                                          \
+    } while (0)
+
+  #endif /* MR_ROBDD_USE_RGLB */
+
+/************************ the cache for MR_ROBDD_complete_or *******************/
+
+  #if defined(MR_ROBDD_SHARING) && defined(MR_ROBDD_NEW)
+    typedef struct {
+        MR_ROBDD_node *f;
+        MR_ROBDD_node *g;
+        MR_ROBDD_node *prev;
+        MR_ROBDD_node *result;
+        MR_ROBDD_CACHE_COUNT_MEMBER
+    } complete_or_cache_entry;
+
+    MR_ROBDD_DECLARE_CACHE(MR_ROBDD_complete_or, complete_or_cache_entry);
+
+    #define MR_ROBDD_DECLARE_COMPLETE_OR_CACHE_ENTRY \
+        complete_or_cache_entry *cache;
+
+    #define MR_ROBDD_TRY_COMPLETE_OR_CACHE(n1,n2,pr)                        \
+    do {                                                                    \
+        if (n2 < n1) {                                                      \
+            MR_ROBDD_node *temp = (n2);                                     \
+            (n2) = (n1);                                                    \
+            (n1) = temp;                                                    \
+        }                                                                   \
+        cache = &complete_or_computed_cache                                 \
+            [MR_ROBDD_TERNARY_NODE_HASH(n1,n2,pr)];                         \
 	if ((cache->f==n1 && cache->g==n2 && cache->prev==pr)) { \
-	    COUNT_HIT(complete_or);				\
+            MR_ROBDD_COUNT_HIT(MR_ROBDD_complete_or);                       \
 	    return cache->result;				\
 	}							\
-} while (0)
+    } while (0)
 
-#define UPDATE_COMPLETE_OR_CACHE(n1,n2,pr,node) \
-do {					\
+    #define MR_ROBDD_UPDATE_COMPLETE_OR_CACHE(n1,n2,pr,MR_ROBDD_node)       \
+    do {                                                                    \
 	cache->f = n1;			\
 	cache->g = n2;			\
 	cache->prev = pr;		\
-	cache->result = node;		\
-	COUNT_MISS(complete_or);	\
-} while (0)
+        cache->result = MR_ROBDD_node;                                      \
+        MR_ROBDD_COUNT_MISS(MR_ROBDD_complete_or);                          \
+    } while (0)
 
-#endif /* SHARING && NEW */
+  #endif /* MR_ROBDD_SHARING && MR_ROBDD_NEW */
 
-/**************************** the cache for ite_var ***********************/
+/********************* the cache for MR_ROBDD_ite_var ***********************/
 
-#if defined(NEW)
+  #if defined(MR_ROBDD_NEW)
 
-#define ITE_VAR_COMPUTED_HASH(f,g,h) \
-  ((f+INTCAST(g)+(INTCAST(h)<<1)) % COMPUTED_TABLE_SIZE)
+    #define MR_ROBDD_ITE_VAR_COMPUTED_HASH(f,g,h) \
+      ((f+MR_ROBDD_INTCAST(g)+(MR_ROBDD_INTCAST(h)<<1)) \
+        % MR_ROBDD_COMPUTED_TABLE_SIZE)
 
-typedef struct {
+    typedef struct {
     int f;
-    node *g;
-    node *h;
-    node *result;
-    CACHE_COUNT_MEMBER
-} ite_var_cache_entry;
-
-DECLARE_CACHE(ite_var, ite_var_cache_entry);
-
-#define DECLARE_ITE_VAR_CACHE_ENTRY ite_var_cache_entry *cache;
-
-#define TRY_ITE_VAR_CACHE(n1,n2,h)				\
-do {								\
-	cache =							\
-	  &ite_var_computed_cache[ITE_VAR_COMPUTED_HASH(n1,n2,h)];\
+        MR_ROBDD_node   *g;
+        MR_ROBDD_node   *h;
+        MR_ROBDD_node   *result;
+        MR_ROBDD_CACHE_COUNT_MEMBER
+    } ite_var_cache_entry;
+
+    MR_ROBDD_DECLARE_CACHE(MR_ROBDD_ite_var, ite_var_cache_entry);
+
+    #define MR_ROBDD_DECLARE_ITE_VAR_CACHE_ENTRY ite_var_cache_entry *cache;
+
+    #define MR_ROBDD_TRY_ITE_VAR_CACHE(n1,n2,h)                             \
+    do {                                                                    \
+        cache = &MR_ROBDD_ite_var_computed_cache[                           \
+            MR_ROBDD_ITE_VAR_COMPUTED_HASH(n1,n2,h)];                       \
 	if (cache->f==n1 && cache->g==n2 && cache->h==h) {	\
-	    COUNT_HIT(ite_var);				\
+            MR_ROBDD_COUNT_HIT(MR_ROBDD_ite_var);                           \
 	    return cache->result;				\
 	  }							\
-} while (0)
+    } while (0)
 
-#define UPDATE_ITE_VAR_CACHE(n1,n2,h,node)\
-do {					\
+    #define MR_ROBDD_UPDATE_ITE_VAR_CACHE(n1,n2,h,MR_ROBDD_node)            \
+    do {                                                                    \
 	cache->f = n1;			\
 	cache->g = n2;			\
 	cache->h = h;			\
-	cache->result = node;		\
-	COUNT_MISS(ite_var);		\
-} while (0)
+        cache->result = MR_ROBDD_node;                                      \
+        MR_ROBDD_COUNT_MISS(MR_ROBDD_ite_var);                              \
+    } while (0)
 
-#endif /* NEW */
+  #endif /* MR_ROBDD_NEW */
 
+#else /* !MR_ROBDD_COMPUTED_TABLE */
 
-#else /* !COMPUTED_TABLE */
 /**************************** no caching at all **************************/
-#define DECLARE_ITE_CACHE_ENTRY
-#define TRY_ITE_CACHE(n1,n2,n3,op)
-#define UPDATE_ITE_CACHE(n1,n2,n3,node,op)
-#define DECLARE_BIN_CACHE_ENTRY
-#define TRY_BIN_CACHE(n1,n2,op)
-#define UPDATE_BIN_CACHE(n1,n2,node,op)
-#define DECLARE_UNARY_CACHE_ENTRY
-#define UPDATE_UNARY_CACHE(n,node,op)
-#define TRY_UNARY_CACHE(n,op)
-#define DECLARE_ASYM_BIN_CACHE_ENTRY
-#define UPDATE_ASYM_BIN_CACHE(n1,n2,node,op)
-#define TRY_ASYM_BIN_CACHE(n1,n2,op)
-#define DECLARE_RGLB_CACHE_ENTRY
-#define TRY_RGLB_CACHE(n1,n2,th)
-#define UPDATE_RGLB_CACHE(n1,n2,th,node)
-#define DECLARE_ITE_VAR_CACHE_ENTRY
-#define TRY_ITE_VAR_CACHE(n1,n2,h)
-#define UPDATE_ITE_VAR_CACHE(n1,n2,h,node)
-#define DECLARE_COMPLETE_OR_CACHE_ENTRY
-#define TRY_COMPLETE_OR_CACHE(n1,n2,pr)
-#define UPDATE_COMPLETE_OR_CACHE(n1,n2,pr,node)
-
-#undef COMPUTED_TABLE_SIZE
-#define COMPUTED_TABLE_SIZE 0
-#endif /* COMPUTED_TABLE */
 
+  #define MR_ROBDD_DECLARE_ITE_CACHE_ENTRY
+  #define MR_ROBDD_TRY_ITE_CACHE(n1,n2,n3,op)
+  #define MR_ROBDD_UPDATE_ITE_CACHE(n1,n2,n3,MR_ROBDD_node,op)
+
+  #define MR_ROBDD_DECLARE_UNARY_CACHE_ENTRY
+  #define MR_ROBDD_UPDATE_UNARY_CACHE(n,MR_ROBDD_node,op)
+  #define MR_ROBDD_TRY_UNARY_CACHE(n,op)
+
+  #define MR_ROBDD_DECLARE_VAR_ENTAILED_CACHE_ENTRY
+  #define MR_ROBDD_UPDATE_VAR_ENTAILED_CACHE(MR_ROBDD_node,var,val)
+  #define MR_ROBDD_TRY_VAR_ENTAILED_CACHE(MR_ROBDD_node,var)
+
+  #define MR_ROBDD_DECLARE_UNARY_BITSET_CACHE_ENTRY
+  #define MR_ROBDD_UPDATE_UNARY_BITSET_CACHE(n,set,op)
+  #define MR_ROBDD_TRY_UNARY_BITSET_CACHE(n,op)
+
+  #define MR_ROBDD_DECLARE_BIN_CACHE_ENTRY
+  #define MR_ROBDD_TRY_BIN_CACHE(n1,n2,op)
+  #define MR_ROBDD_UPDATE_BIN_CACHE(n1,n2,MR_ROBDD_node,op)
+
+  #define MR_ROBDD_DECLARE_ASYM_BIN_CACHE_ENTRY
+  #define MR_ROBDD_UPDATE_ASYM_BIN_CACHE(n1,n2,MR_ROBDD_node,op)
+  #define MR_ROBDD_TRY_ASYM_BIN_CACHE(n1,n2,op)
+
+  #define MR_ROBDD_DECLARE_RGLB_CACHE_ENTRY
+  #define MR_ROBDD_TRY_RGLB_CACHE(n1,n2,th)
+  #define MR_ROBDD_UPDATE_RGLB_CACHE(n1,n2,th,MR_ROBDD_node)
+
+  #define MR_ROBDD_DECLARE_COMPLETE_OR_CACHE_ENTRY
+  #define MR_ROBDD_TRY_COMPLETE_OR_CACHE(n1,n2,pr)
+  #define MR_ROBDD_UPDATE_COMPLETE_OR_CACHE(n1,n2,pr,MR_ROBDD_node)
+
+  #define MR_ROBDD_DECLARE_ITE_VAR_CACHE_ENTRY
+  #define MR_ROBDD_TRY_ITE_VAR_CACHE(n1,n2,h)
+  #define MR_ROBDD_UPDATE_ITE_VAR_CACHE(n1,n2,h,MR_ROBDD_node)
+
+  #undef MR_ROBDD_COMPUTED_TABLE_SIZE
+  #define MR_ROBDD_COMPUTED_TABLE_SIZE 0
 
+#endif /* MR_ROBDD_COMPUTED_TABLE */
 
 /****************************************************************
 
@@ -685,13 +763,12 @@
 
  ****************************************************************/
 
+static MR_ROBDD_BRYANT_hidden_node_pointer
+    MR_ROBDD_unique_table[MR_ROBDD_UNIQUE_TABLE_SIZE];
 
-static node *unique_table[UNIQUE_TABLE_SIZE];
-
-#define UNIQUE_HASH(var,tr,fa) \
-  (((var)+INTCAST(tr)+(INTCAST(fa)<<1)) % UNIQUE_TABLE_SIZE)
-
-
+#define MR_ROBDD_UNIQUE_HASH(var,tr,fa) \
+  (((var)+MR_ROBDD_INTCAST(tr)+(MR_ROBDD_INTCAST(fa)<<1)) \
+    % MR_ROBDD_UNIQUE_TABLE_SIZE)
 
 /****************************************************************
 
@@ -699,19 +776,22 @@
 
  ****************************************************************/
 
-extern void printBryant(node *a);
-
-node *ite(node *f,node *g,node *h); /* if then else algorithm */
-node *restricted_iff_conj_array(int v0, int n, int arr[], int thresh);
+extern void MR_ROBDD_printBryant(MR_ROBDD_node *a);
 
+/* if then else algorithm */
+MR_ROBDD_node *MR_ROBDD_ite(MR_ROBDD_node *f,MR_ROBDD_node *g,MR_ROBDD_node *h);
+MR_ROBDD_node *MR_ROBDD_restricted_iff_conj_array(int v0, int n, int arr[],
+        int thresh);
+
+MR_ROBDD_node *MR_ROBDD_renameArray(MR_ROBDD_node *in, int count,
+        int mappping[]);
+MR_ROBDD_node *MR_ROBDD_reverseRenameArray(MR_ROBDD_node *in, int count,
+        int rev_mappping[]);
 
-node *renameArray(node *in, int count, int mappping[]);
-node *reverseRenameArray(node *in, int count, int rev_mappping[]);
+MR_ROBDD_node *MR_ROBDD_complete(MR_ROBDD_node *f, MR_ROBDD_node *g);
+MR_ROBDD_node *MR_ROBDD_bin_univ(MR_ROBDD_node *f);
 
-node *complete(node *f, node *g);
-node *bin_univ(node *f);
-
-static int intcompare(const void *i, const void *j);
+static int MR_ROBDD_intcompare(const void *i, const void *j);
 
 /****************************************************************
 
@@ -719,100 +799,118 @@
 
  ****************************************************************/
 
-/*  next_element()	finds the next element in set beginning with var,
- *			and updates var, word, and mask to refer to it.
- *  prev_element()	finds the next earlier element in set.
- *  next_nonelement()	finds the next potential element of set that is in
- *			fact not an element of set.
- *  prev_nonelement()	finds the next earlier non-element of set.
- *
- * NB:  if the initally supplied element is a member of the set, next_element
- *	and prev_element will happily return that one.  Similarly,
- *	next_nonelement and prev_nonelement will happily return the initial
- *	input if it fits the bill.  That is, these find the next or next
- *	earlier element INLCUDING THE INITIAL ONE that meets the criterion.
- */
-
-#if defined(NO_CHEAP_SHIFT)
-__inline int next_element(bitset *set, int *var, int *word, bitmask *mask)
-    {
+/*
+** MR_ROBDD_next_element()
+**     finds the next element in set beginning with var,
+**    and updates var, word, and mask to refer to it.
+** MR_ROBDD_prev_element()
+**     finds the next earlier element in set.
+** MR_ROBDD_next_nonelement()
+**     finds the next potential element of set that is in fact not an element
+**     of set.
+** MR_ROBDD_prev_nonelement()
+**     finds the next earlier non-element of set.
+**
+** NB: if the initally supplied element is a member of the set,
+** MR_ROBDD_next_element and MR_ROBDD_prev_element will happily return
+** that MR_ROBDD_one. Similarly, MR_ROBDD_next_nonelement and
+** MR_ROBDD_prev_nonelement will happily return the initial input if it
+** fits the bill. That is, these find the next or next earlier element
+** INLCUDING THE INITIAL ONE that meets the criterion.
+*/
+
+#if defined(MR_ROBDD_NO_CHEAP_SHIFT)
+
+__inline int
+MR_ROBDD_next_element(MR_ROBDD_bitset *set, int *var, int *word,
+    MR_ROBDD_bitmask *mask)
+{
 	int vr = *var;
 	int wd = *word;
-	bitmask f = FOLLOWING_BITS(vr&(BITS_PER_WORD-1));
-	bitmask *ptr = &(set->bits[wd]);
-	bitmask bits = *ptr;
-	bitmask msk = *mask;
+    MR_ROBDD_bitmask f = MR_ROBDD_FOLLOWING_BITS(vr&(MR_ROBDD_BITS_PER_WORD-1));
+    MR_ROBDD_bitmask *ptr = &(set->bits[wd]);
+    MR_ROBDD_bitmask bits = *ptr;
+    MR_ROBDD_bitmask msk = *mask;
 
 	assert(vr >= 0 && vr < MAXVAR);
 
 	if ((bits&f) == 0) {
 	    do {
-		if (++wd > ((MAXVAR-1)/BITS_PER_WORD)) return FALSE;
+        if (++wd > ((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD)) return MR_FALSE;
 	    } while ((bits=*++ptr) == 0);
-	    vr = wd<<LOG_BITS_PER_WORD;
+        vr = wd<<MR_ROBDD_LOG_BITS_PER_WORD;
 	    msk = 1;
 	}
 	/* I know there's a later bit set in bits, so this is safe */
 	while ((bits&msk) == 0) {
 	    ++vr;
 	    msk <<= 1;
-	    assert(vr < (wd+1)<<LOG_BITS_PER_WORD);
+        assert(vr < (wd+1)<<MR_ROBDD_LOG_BITS_PER_WORD);
 	}
 	*var = vr;
 	*word = wd;
 	*mask = msk;
-	return TRUE;
-    }
-#else /* !NO_CHEAP_SHIFT */
-__inline int next_element(bitset *set, int *var, int *word, bitmask *mask)
-    {
+    return MR_TRUE;
+}
+
+#else /* !MR_ROBDD_NO_CHEAP_SHIFT */
+
+__inline int
+MR_ROBDD_next_element(MR_ROBDD_bitset *set, int *var, int *word,
+    MR_ROBDD_bitmask *mask)
+{
 	int vr = *var;
 	int wd = *word;
-	bitmask *ptr = &(set->bits[wd]);
-	bitmask bits = *ptr&FOLLOWING_BITS(vr&(BITS_PER_WORD-1));
+    MR_ROBDD_bitmask *ptr = &(set->bits[wd]);
+    MR_ROBDD_bitmask bits = *ptr&MR_ROBDD_FOLLOWING_BITS(vr&(MR_ROBDD_BITS_PER_WORD-1));
 
 	assert(vr >= 0 && vr < MAXVAR);
 
 	while (bits == 0) {
-	    if (++wd > (MAXVAR-1)/BITS_PER_WORD) return FALSE;
+        if (++wd > (MAXVAR-1)/MR_ROBDD_BITS_PER_WORD) return MR_FALSE;
 	    bits = *++ptr;
 	}
-	vr = wd<<LOG_BITS_PER_WORD;
+    vr = wd<<MR_ROBDD_LOG_BITS_PER_WORD;
 	/* I know there's a later bit set in bits, so this is safe */
-	while ((bits & CHAR_MASK) == 0) {
-	    bits >>= BITS_PER_CHAR;
-	    vr += BITS_PER_CHAR;
-	    assert(vr < (wd+1)<<LOG_BITS_PER_WORD);
+    while ((bits & MR_ROBDD_CHAR_MASK) == 0) {
+        bits >>= MR_ROBDD_BITS_PER_CHAR;
+        vr += MR_ROBDD_BITS_PER_CHAR;
+        assert(vr < (wd+1)<<MR_ROBDD_LOG_BITS_PER_WORD);
 	}
-	vr += first_one_bit[bits & CHAR_MASK];
+    vr += MR_ROBDD_first_one_bit[bits & MR_ROBDD_CHAR_MASK];
 
 	*var = vr;
 	*word = wd;
-	*mask = 1<<(vr&(BITS_PER_WORD-1));
-	return TRUE;
-    }
-#endif /* NO_CHEAP_SHIFT */
+    *mask = 1<<(vr&(MR_ROBDD_BITS_PER_WORD-1));
+    return MR_TRUE;
+}
 
+#endif /* MR_ROBDD_NO_CHEAP_SHIFT */
 
-#if defined(NO_CHEAP_SHIFT)
-__inline int prev_element(bitset *set, int *var, int *word, bitmask *mask)
-    {
+#if defined(MR_ROBDD_NO_CHEAP_SHIFT)
+
+__inline int
+MR_ROBDD_prev_element(MR_ROBDD_bitset *set, int *var, int *word,
+    MR_ROBDD_bitmask *mask)
+{
 	int vr = *var;
 	int wd = *word;
 
 	assert(vr >= 0 && vr < MAXVAR);
 
-	bitmask f = PRECEDING_BITS(vr&(BITS_PER_WORD-1));
-	bitmask *ptr = &(set->bits[wd]);
-	bitmask bits = *ptr;
-	bitmask msk = *mask;
+    MR_ROBDD_bitmask f = MR_ROBDD_PRECEDING_BITS(vr&(MR_ROBDD_BITS_PER_WORD-1));
+    MR_ROBDD_bitmask *ptr = &(set->bits[wd]);
+    MR_ROBDD_bitmask bits = *ptr;
+    MR_ROBDD_bitmask msk = *mask;
 
 	if ((bits&f) == 0) {
 	    do {
-		if (--wd < 0) return FALSE;
+            if (--wd < 0) {
+                return MR_FALSE;
+            }
 	    } while ((bits=*--ptr) == 0);
-	    vr = (wd<<LOG_BITS_PER_WORD) + BITS_PER_WORD-1;
-	    msk = 1<<(BITS_PER_WORD-1);
+        vr = (wd<<MR_ROBDD_LOG_BITS_PER_WORD) + MR_ROBDD_BITS_PER_WORD-1;
+        msk = 1<<(MR_ROBDD_BITS_PER_WORD-1);
 	}
 	/* I know there's an earlier bit set in bits, so this is safe */
 	while ((bits&msk) == 0) {
@@ -823,57 +921,67 @@
 	*var = vr;
 	*word = wd;
 	*mask = msk;
-	return TRUE;
-    }
-#else /* !NO_CHEAP_SHIFT */
-__inline int prev_element(bitset *set, int *var, int *word, bitmask *mask)
-    {
+    return MR_TRUE;
+}
+
+#else /* !MR_ROBDD_NO_CHEAP_SHIFT */
+
+__inline int
+MR_ROBDD_prev_element(MR_ROBDD_bitset *set, int *var, int *word,
+    MR_ROBDD_bitmask *mask)
+{
 	int vr = *var;
 	int wd = *word;
-	bitmask *ptr = &(set->bits[wd]);
-	bitmask bits = *ptr&PRECEDING_BITS(vr&(BITS_PER_WORD-1));
-	bitmask temp;
+    MR_ROBDD_bitmask *ptr = &(set->bits[wd]);
+    MR_ROBDD_bitmask bits = *ptr&MR_ROBDD_PRECEDING_BITS(vr&(MR_ROBDD_BITS_PER_WORD-1));
+    MR_ROBDD_bitmask temp;
 
 	assert(vr >= 0 && vr < MAXVAR);
 
 	while (bits == 0) {
-	    if (--wd < 0) return FALSE;
+        if (--wd < 0) {
+            return MR_FALSE;
+        }
 	    bits = *--ptr;
 	}
 
-	vr = BITS_PER_WORD - BITS_PER_CHAR;
+    vr = MR_ROBDD_BITS_PER_WORD - MR_ROBDD_BITS_PER_CHAR;
 	/* I know there's an earlier bit set in bits, so this is safe */
-	while ((temp=((bits>>vr)&CHAR_MASK)) == 0) {
-	    vr -= BITS_PER_CHAR;
+    while ((temp=((bits>>vr)&MR_ROBDD_CHAR_MASK)) == 0) {
+        vr -= MR_ROBDD_BITS_PER_CHAR;
 	    assert(vr >= 0);
 	}
-	vr += (int)last_one_bit[(int)temp];
-	vr += (int)wd<<LOG_BITS_PER_WORD;
+    vr += (int)MR_ROBDD_last_one_bit[(int)temp];
+    vr += (int)wd<<MR_ROBDD_LOG_BITS_PER_WORD;
 
 	*var = vr;
 	*word = wd;
-	*mask = 1<<(vr&(BITS_PER_WORD-1));
-	return TRUE;
-    }
-#endif /* NO_CHEAP_SHIFT */
+    *mask = 1<<(vr&(MR_ROBDD_BITS_PER_WORD-1));
+    return MR_TRUE;
+}
 
+#endif /* MR_ROBDD_NO_CHEAP_SHIFT */
 
-__inline int next_nonelement(bitset *set, int *var, int *word, bitmask *mask)
-    {
+__inline int
+MR_ROBDD_next_nonelement(MR_ROBDD_bitset *set, int *var, int *word,
+    MR_ROBDD_bitmask *mask)
+{
 	int vr = *var;
 	int wd = *word;
-	bitmask f = FOLLOWING_BITS(vr&(BITS_PER_WORD-1));
-	bitmask *ptr = &(set->bits[wd]);
-	bitmask bits = *ptr;
-	bitmask msk = *mask;
+    MR_ROBDD_bitmask f = MR_ROBDD_FOLLOWING_BITS(vr&(MR_ROBDD_BITS_PER_WORD-1));
+    MR_ROBDD_bitmask *ptr = &(set->bits[wd]);
+    MR_ROBDD_bitmask bits = *ptr;
+    MR_ROBDD_bitmask msk = *mask;
 
 	assert(vr >= 0 && vr < MAXVAR);
 
 	if ((bits&f) == f) {
 	    do {
-		if (++wd >= MAXVAR/BITS_PER_WORD) return FALSE;
+            if (++wd >= MAXVAR/MR_ROBDD_BITS_PER_WORD) {
+                return MR_FALSE;
+            }
 	    } while ((bits=*++ptr) == ~0);
-	    vr = wd<<LOG_BITS_PER_WORD;
+        vr = wd<<MR_ROBDD_LOG_BITS_PER_WORD;
 	    msk = 1;
 	}
 	/* I know there's a later bit clear in bits, so this is safe */
@@ -884,27 +992,30 @@
 	*var = vr;
 	*word = wd;
 	*mask = msk;
-	return TRUE;
-    }
-
+    return MR_TRUE;
+}
 
-__inline int prev_nonelement(bitset *set, int *var, int *word, bitmask *mask)
-    {
+__inline int
+MR_ROBDD_prev_nonelement(MR_ROBDD_bitset *set, int *var, int *word,
+    MR_ROBDD_bitmask *mask)
+{
 	int vr = *var;
 	    int wd = *word;
-	    bitmask f = PRECEDING_BITS(vr&(BITS_PER_WORD-1));
-	    bitmask *ptr = &(set->bits[wd]);
-	    bitmask bits = *ptr;
-	    bitmask msk = *mask;
+        MR_ROBDD_bitmask f = MR_ROBDD_PRECEDING_BITS(vr&(MR_ROBDD_BITS_PER_WORD-1));
+        MR_ROBDD_bitmask *ptr = &(set->bits[wd]);
+        MR_ROBDD_bitmask bits = *ptr;
+        MR_ROBDD_bitmask msk = *mask;
 
 	assert(vr >= 0 && vr < MAXVAR);
 
 	if ((bits&f) == f) {
 	    do {
-		if (--wd < 0) return FALSE;
+            if (--wd < 0) {
+                return MR_FALSE;
+            }
 	    } while ((bits=*--ptr) == ~0);
-	    vr = (wd<<LOG_BITS_PER_WORD) + BITS_PER_WORD-1;
-	    msk = 1<<(BITS_PER_WORD-1);
+        vr = (wd<<MR_ROBDD_LOG_BITS_PER_WORD) + MR_ROBDD_BITS_PER_WORD-1;
+        msk = 1<<(MR_ROBDD_BITS_PER_WORD-1);
 	}
 	/* I know there's an earlier bit clear in bits, so this is safe */
 	while ((bits&msk) != 0) {
@@ -914,70 +1025,97 @@
 	*var = vr;
 	*word = wd;
 	*mask = msk;
-	return TRUE;
-    }
-
-
+    return MR_TRUE;
+}
 
 /* returns 1 if set1 is identical to set2 */
-__inline int bitset_equal(bitset *set1, bitset *set2)
-    {
-	bitmask *ptr1 = &set1->bits[0];
-	bitmask *ptr2 = &set2->bits[0];
-	bitmask *ptr1end = &set1->bits[((MAXVAR-1)/BITS_PER_WORD)+1];
+__inline int
+MR_ROBDD_bitset_equal(MR_ROBDD_bitset *set1, MR_ROBDD_bitset *set2);
+
+__inline int
+MR_ROBDD_bitset_equal(MR_ROBDD_bitset *set1, MR_ROBDD_bitset *set2)
+{
+    MR_ROBDD_bitmask *ptr1 = &set1->bits[0];
+    MR_ROBDD_bitmask *ptr2 = &set2->bits[0];
+    MR_ROBDD_bitmask *ptr1end =
+        &set1->bits[((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD)+1];
 
 	for (;;) {
-	    if (*ptr1 != *ptr2) return 0;
-	    if (++ptr1 >= ptr1end) return 1;
-	    ++ptr2;
+        if (*ptr1 != *ptr2) {
+            return 0;
 	}
-	
+        if (++ptr1 >= ptr1end) {
+            return 1;
+        }
+        ++ptr2;
     }
+}
 
 /* returns 1 if 2 sets are disjoint, else 0 */
-__inline int bitset_disjoint(bitset *set1, bitset *set2)
-    {
-	bitmask *ptr1 = &set1->bits[0];
-	bitmask *ptr2 = &set2->bits[0];
-	bitmask *ptr1end = &set1->bits[((MAXVAR-1)/BITS_PER_WORD)+1];
+__inline int
+MR_ROBDD_bitset_disjoint(MR_ROBDD_bitset *set1, MR_ROBDD_bitset *set2);
+
+__inline int
+MR_ROBDD_bitset_disjoint(MR_ROBDD_bitset *set1, MR_ROBDD_bitset *set2)
+{
+    MR_ROBDD_bitmask *ptr1 = &set1->bits[0];
+    MR_ROBDD_bitmask *ptr2 = &set2->bits[0];
+    MR_ROBDD_bitmask *ptr1end =
+        &set1->bits[((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD)+1];
 
 	for (;;) {
-	    if ((*ptr1 & *ptr2) != 0) return 0;
-	    if (++ptr1 >= ptr1end) return 1;
-	    ++ptr2;
+        if ((*ptr1 & *ptr2) != 0) {
+            return 0;
 	}
+        if (++ptr1 >= ptr1end) {
+            return 1;
     }
-
+        ++ptr2;
+    }
+}
 
 /* returns 1 if set1 is a subset of set2 */
-__inline int bitset_subset(bitset *set1, bitset *set2)
-    {
-	bitmask *ptr1 = &set1->bits[0];
-	bitmask *ptr2 = &set2->bits[0];
-	bitmask *ptr1end = &set1->bits[((MAXVAR-1)/BITS_PER_WORD)+1];
+__inline int
+MR_ROBDD_bitset_subset(MR_ROBDD_bitset *set1, MR_ROBDD_bitset *set2);
+
+__inline int
+MR_ROBDD_bitset_subset(MR_ROBDD_bitset *set1, MR_ROBDD_bitset *set2)
+{
+    MR_ROBDD_bitmask *ptr1 = &set1->bits[0];
+    MR_ROBDD_bitmask *ptr2 = &set2->bits[0];
+    MR_ROBDD_bitmask *ptr1end =
+        &set1->bits[((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD)+1];
 
 	for (;;) {
-	    if ((*ptr1 | *ptr2) != *ptr2) return 0;
-	    if (++ptr1 >= ptr1end) return 1;
+        if ((*ptr1 | *ptr2) != *ptr2) {
+            return 0;
+        }
+        if (++ptr1 >= ptr1end) {
+            return 1;
+        }
 	    ++ptr2;
 	}
 	
     }
 
-
 /* returns 1 if set1 is a subset of set2 */
-__inline int bitset_empty(bitset *set)
-    {
-	bitmask *ptr = &set->bits[0];
-	bitmask *ptrend = &set->bits[((MAXVAR-1)/BITS_PER_WORD)+1];
+__inline int MR_ROBDD_bitset_empty(MR_ROBDD_bitset *set);
+
+__inline int MR_ROBDD_bitset_empty(MR_ROBDD_bitset *set)
+{
+    MR_ROBDD_bitmask *ptr = &set->bits[0];
+    MR_ROBDD_bitmask *ptrend =
+        &set->bits[((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD)+1];
 
 	for (;;) {
-	    if ((*ptr) != 0) return 0;
-	    if (++ptr >= ptrend) return 1;
+        if ((*ptr) != 0) {
+            return 0;
 	}
-	
+        if (++ptr >= ptrend) {
+            return 1;
     }
-
+    }
+}
 
 /****************************************************************
 
@@ -985,80 +1123,138 @@
 
  ****************************************************************/
 
-static pool *curr_pool = NULL;
-static node *curr_pool_ptr = NULL;
-static node *curr_pool_end_ptr = NULL;
-static int pool_count = 0;
+#if defined(MR_ROBDD_BRYANT_CONSERVATIVE_GC)
 
-static node *alloc_node(int value, node* tr, node* fa)
-    {
+static int MR_ROBDD_removed_nodes = 0;
+
+void MR_ROBDD_remove_node(GC_PTR obj, GC_PTR client_data);
+void MR_ROBDD_remove_node(GC_PTR obj, GC_PTR client_data)
+{
+    MR_ROBDD_node *n = (MR_ROBDD_node *) obj;
+    MR_ROBDD_BRYANT_hidden_node_pointer *bucket =
+          (MR_ROBDD_BRYANT_hidden_node_pointer *) client_data;
+
+    if (MR_ROBDD_REVEAL_NODE_POINTER(n->unique) != NULL) {
+        MR_ROBDD_REVEAL_NODE_POINTER(n->unique)->uprev = n->uprev;
+    }
+
+    if (MR_ROBDD_REVEAL_NODE_POINTER(n->uprev) != NULL) {
+        MR_ROBDD_REVEAL_NODE_POINTER(n->uprev)->unique = n->unique;
+    }
+
+    if (MR_ROBDD_REVEAL_NODE_POINTER(*bucket) == n) {
+        *bucket = n->unique;
+    }
+
+    MR_ROBDD_removed_nodes++;
+}
+
+#endif /* MR_ROBDD_BRYANT_CONSERVATIVE_GC */
+
+#if defined(MR_ROBDD_POOL)
+  static pool           *MR_ROBDD_curr_pool = NULL;
+  static MR_ROBDD_node  *MR_ROBDD_curr_pool_ptr = NULL;
+  static MR_ROBDD_node  *MR_ROBDD_curr_pool_end_ptr = NULL;
+#endif /* MR_ROBDD_POOL */
+
+static int        MR_ROBDD_node_count = 0;
+
+static MR_ROBDD_node *
+MR_ROBDD_alloc_node(int value, MR_ROBDD_node* tr, MR_ROBDD_node* fa,
+    MR_ROBDD_BRYANT_hidden_node_pointer *bucket)
+{
+    MR_ROBDD_node *n;
+#if defined(MR_ROBDD_POOL)
 	pool *newpool;
-	node *n;
 
-	if (curr_pool_ptr >= curr_pool_end_ptr) {
+    if (MR_ROBDD_curr_pool_ptr >= MR_ROBDD_curr_pool_end_ptr) {
 	    /* allocate a new pool */
-            newpool = malloc(sizeof(pool));
-            newpool->prev = curr_pool;
-            curr_pool = newpool;
-            curr_pool_ptr = &(newpool->data[0]);
-            curr_pool_end_ptr = &(newpool->data[POOL_SIZE]);
-            ++pool_count;
-        }
-	n = curr_pool_ptr++;
+        newpool = (pool *) malloc(sizeof(pool));
+        newpool->prev = MR_ROBDD_curr_pool;
+        MR_ROBDD_curr_pool = newpool;
+        MR_ROBDD_curr_pool_ptr = &(newpool->data[0]);
+        MR_ROBDD_curr_pool_end_ptr = &(newpool->data[MR_ROBDD_POOL_SIZE]);
+    }
+    n = MR_ROBDD_curr_pool_ptr++;
+#else /* !MR_ROBDD_POOL */
+    n = (MR_ROBDD_node *) malloc(sizeof(MR_ROBDD_node));
+  #if defined(MR_ROBDD_BRYANT_CONSERVATIVE_GC)
+    GC_register_finalizer(n, MR_ROBDD_remove_node, bucket, 0, 0);
+  #endif
+#endif /* MR_ROBDD_POOL */
+    MR_ROBDD_node_count++;
         n->value = value;
         n->tr = tr;
         n->fa = fa;
         return n;
-    }
+}
 
 /* return the number of graph nodes that have been created. */
-int nodes_in_use(void)
-    {
-        return pool_count*POOL_SIZE - (curr_pool_end_ptr - curr_pool_ptr);
-    }
-
+int
+MR_ROBDD_nodes_in_use(void)
+{
+    return MR_ROBDD_node_count;
+}
 
-DECLARE_FN_COUNT(make_node)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_make_node)
 
-node *make_node(int var, node *tr, node *fa)
-    {
-	node **bucket;
-	node *ptr;
+MR_ROBDD_node *
+MR_ROBDD_make_node(int var, MR_ROBDD_node *tr, MR_ROBDD_node *fa)
+{
+    MR_ROBDD_BRYANT_hidden_node_pointer *bucket;
+    MR_ROBDD_node *ptr;
 
 	assert(var>=0);
 	assert(var<MAXVAR);
 	assert(IS_TERMINAL(tr) || tr->value > var);
 	assert(IS_TERMINAL(fa) || fa->value > var);
 
-	COUNT_FN(make_node);
+    MR_ROBDD_COUNT_FN(MR_ROBDD_make_node);
 
-	if (tr == fa) return tr;
+    if (tr == fa) {
+        return tr;
+    }
 
-	bucket = &unique_table[UNIQUE_HASH(var,tr,fa)];
-	ptr = *bucket;
-	while (ptr!=NULL && (var!=ptr->value || tr!=ptr->tr || fa!=ptr->fa))
-	    ptr = ptr->unique;
+    bucket = &MR_ROBDD_unique_table[MR_ROBDD_UNIQUE_HASH(var,tr,fa)];
 
-	if (ptr!=NULL) {
-	    COUNT_UNIQUE_HIT;
-	    return ptr;
+    /*
+    ** The following check avoids the need to initialise the table
+    ** elements to MR_ROBDD_HIDE_POINTER(NULL).
+    */
+    if (*bucket == 0) {
+        *bucket = MR_ROBDD_HIDE_POINTER(NULL);
 	}
 
-	/* node doesn't exist so create it and put in bucket */
-	COUNT_UNIQUE_MISS;
-	ptr = alloc_node(var, tr, fa);
-	ptr->unique = *bucket;
-	*bucket = ptr;
-	return ptr;
+    ptr = MR_ROBDD_REVEAL_NODE_POINTER(*bucket);
+    while (ptr != NULL && (var!=ptr->value || tr!=ptr->tr || fa!=ptr->fa)) {
+        ptr = MR_ROBDD_REVEAL_NODE_POINTER(ptr->unique);
     }
 
-
-void free_rep(node *n)
-    {
-	/* never free ROBDD nodes */
+    if (ptr != NULL) {
+        MR_ROBDD_COUNT_UNIQUE_HIT;
+        return ptr;
     }
 
+    /* MR_ROBDD_node doesn't exist so create it and put in bucket */
+    MR_ROBDD_COUNT_UNIQUE_MISS;
+    ptr = MR_ROBDD_alloc_node(var, tr, fa, bucket);
+    ptr->unique = *bucket;
+    *bucket = MR_ROBDD_HIDE_POINTER(ptr);
+#ifdef MR_ROBDD_BRYANT_CONSERVATIVE_GC
+    ptr->uprev = MR_ROBDD_HIDE_POINTER(NULL);
+    if (MR_ROBDD_REVEAL_NODE_POINTER(ptr->unique) != NULL) {
+        MR_ROBDD_REVEAL_NODE_POINTER(ptr->unique)->uprev =
+            MR_ROBDD_HIDE_POINTER(ptr);
+    }
+#endif
+    return ptr;
+}
 
+void
+MR_ROBDD_free_rep(MR_ROBDD_node *n)
+{
+    /* never free ROBDD nodes */
+}
 
 /****************************************************************
 
@@ -1066,62 +1262,73 @@
 
  ****************************************************************/
 
-int max_variable(void)
-    {
-	return MAXVAR;
-    }
-
+int MR_ROBDD_max_variable(void);
 
-node *trueVar(void)
-    {
-	return one;
-    }
-
-
-node *falseVar(void)
-    {
-	return zero;
-    }
+int
+MR_ROBDD_max_variable(void)
+{
+    return MAXVAR;
+}
     
+MR_ROBDD_node *
+MR_ROBDD_trueVar(void)
+{
+    return MR_ROBDD_one;
+}
 
-DECLARE_FN_COUNT(variableRep)
+MR_ROBDD_node *
+MR_ROBDD_falseVar(void)
+{
+    return MR_ROBDD_zero;
+}
 
-node *variableRep(int var)
-    {
-	COUNT_FN(variableRep);
-	return make_node(var,one,zero);
-    }
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_variableRep)
 
+MR_ROBDD_node *
+MR_ROBDD_variableRep(int var)
+{
+    MR_ROBDD_COUNT_FN(MR_ROBDD_variableRep);
+    return MR_ROBDD_make_node(var,MR_ROBDD_one,MR_ROBDD_zero);
+}
 
-DECLARE_FN_COUNT(ite)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_ite)
 
-node *ite(node *f,node *g,node *h)
-    {
-	node *f_tr, *f_fa;
-	node *g_tr, *g_fa;
-	node *h_tr, *h_fa;
-	node *newnode;
+MR_ROBDD_node *
+MR_ROBDD_ite(MR_ROBDD_node *f,MR_ROBDD_node *g,MR_ROBDD_node *h)
+{
+    MR_ROBDD_node *f_tr, *f_fa;
+    MR_ROBDD_node *g_tr, *g_fa;
+    MR_ROBDD_node *h_tr, *h_fa;
+    MR_ROBDD_node *newnode;
 	int top;
-	DECLARE_ITE_CACHE_ENTRY
+    MR_ROBDD_DECLARE_ITE_CACHE_ENTRY
 
-	COUNT_FN(ite);
+    MR_ROBDD_COUNT_FN(MR_ROBDD_ite);
 	/* terminal cases */
-	if (f == one)
+    if (f == MR_ROBDD_one) {
 	  return g;
-	if (f == zero)
+    }
+    if (f == MR_ROBDD_zero) {
 	  return h;
-	if ((g == one) && (h == zero))
+    }
+    if ((g == MR_ROBDD_one) && (h == MR_ROBDD_zero)) {
 	  return f;
-	if (g == h)
+    }
+    if (g == h) {
 	  return g;
+    }
 
 	/* look it up in computed table; finished if found */
-	TRY_ITE_CACHE(f, g, h, ite);
+    MR_ROBDD_TRY_ITE_CACHE(f, g, h, MR_ROBDD_ite);
 
 	/* find top variable */
 	top = f->value;		/* we know f is not terminal */
-	if (!IS_TERMINAL(g) && (g->value < top)) top = g->value;
-	if (!IS_TERMINAL(h) && (h->value < top)) top = h->value;
+    if (!IS_TERMINAL(g) && (g->value < top)) {
+        top = g->value;
+    }
+    if (!IS_TERMINAL(h) && (h->value < top)) {
+        top = h->value;
+    }
 	
 	/* find then and else branches for recursive calls */
 	if (f->value==top) {
@@ -1140,51 +1347,61 @@
 	    h_tr = h; h_fa = h;
 	}
 	
-	/* create new node and add to table */
-	newnode = make_node(top,
-			    ite(f_tr, g_tr, h_tr),
-			    ite(f_fa, g_fa, h_fa));
-	UPDATE_ITE_CACHE(f,g,h,newnode,ite);
+    /* create new MR_ROBDD_node and add to table */
+    newnode = MR_ROBDD_make_node(top,
+                MR_ROBDD_ite(f_tr, g_tr, h_tr),
+                MR_ROBDD_ite(f_fa, g_fa, h_fa));
+    MR_ROBDD_UPDATE_ITE_CACHE(f,g,h,newnode,MR_ROBDD_ite);
 	return newnode;
-    }
-
+}
 
-#if defined(USE_ITE_CONSTANT)
+#if defined(MR_ROBDD_USE_ITE_CONSTANT)
 
-/* This is sort of an "approximate ite()."  It returns zero or one if
- * that's what ite() would do.  Otherwise it just returns the
- * pseudo-node `nonterminal' or some real node.  In any case, it does
- * not create any new nodes.
- */
-node *ite_constant(node *f,node *g,node *h)
-    {
-	node *f_tr, *f_fa;
-	node *g_tr, *g_fa;
-	node *h_tr, *h_fa;
-	node *tr_part, *fa_part;
-	node *result;
+/*
+** This is sort of an "approximate MR_ROBDD_ite()."  It returns MR_ROBDD_zero
+** or MR_ROBDD_one if that's what MR_ROBDD_ite() would do.  Otherwise it just
+** returns the pseudo-MR_ROBDD_node `MR_ROBDD_nonterminal' or some real
+** MR_ROBDD_node.  In any case, it does not create any new nodes.
+*/
+
+MR_ROBDD_node *
+MR_ROBDD_ite_constant(MR_ROBDD_node *f,MR_ROBDD_node *g,MR_ROBDD_node *h)
+{
+    MR_ROBDD_node *f_tr, *f_fa;
+    MR_ROBDD_node *g_tr, *g_fa;
+    MR_ROBDD_node *h_tr, *h_fa;
+    MR_ROBDD_node *tr_part, *fa_part;
+    MR_ROBDD_node *result;
 	int top;
-	DECLARE_ITE_CACHE_ENTRY
+    MR_ROBDD_DECLARE_ITE_CACHE_ENTRY
 
-	COUNT_FN(ite);
+    MR_ROBDD_COUNT_FN(MR_ROBDD_ite);
 	/* terminal cases */
-	if (f == one)
+    if (f == MR_ROBDD_one) {
 	    return g;
-	if (f == zero)
+    }
+    if (f == MR_ROBDD_zero) {
 	    return h;
-	if (g == h)
+    }
+    if (g == h) {
 	    return g;
-	if (IS_TERMINAL(g) && IS_TERMINAL(h))
-	    /* either f or ~f, which is nonterminal since f is */
-	    return nonterminal;
+    }
+    if (IS_TERMINAL(g) && IS_TERMINAL(h)) {
+        /* either f or ~f, which is MR_ROBDD_nonterminal since f is */
+        return MR_ROBDD_nonterminal;
+    }
 
 	/* look it up in computed table; finished if found */
-	TRY_ITE_CACHE(f, g, h, ite_constant);
+    MR_ROBDD_TRY_ITE_CACHE(f, g, h, MR_ROBDD_ite_constant);
 
 	/* find top variable */
 	top = f->value;		/* we know f is not terminal */
-	if (!IS_TERMINAL(g) && (g->value < top)) top = g->value;
-	if (!IS_TERMINAL(h) && (h->value < top)) top = h->value;
+    if (!IS_TERMINAL(g) && (g->value < top)) {
+        top = g->value;
+    }
+    if (!IS_TERMINAL(h) && (h->value < top)) {
+        top = h->value;
+    }
 	
 	/* find then and else branches for recursive calls */
 	if (f->value==top) {
@@ -1203,145 +1420,156 @@
 	    h_tr = h; h_fa = h;
 	}
 	
-	tr_part = ite_constant(f_tr, g_tr, h_tr);
-	fa_part = ite_constant(f_fa, g_fa, h_fa);
+    tr_part = MR_ROBDD_ite_constant(f_tr, g_tr, h_tr);
+    fa_part = MR_ROBDD_ite_constant(f_fa, g_fa, h_fa);
 	if (tr_part == fa_part) {
 	    result = tr_part;
 	} else {
-	    result = nonterminal;
+        result = MR_ROBDD_nonterminal;
 	}
 
-	UPDATE_ITE_CACHE(f,g,h,result,ite_constant);
+    MR_ROBDD_UPDATE_ITE_CACHE(f,g,h,result,MR_ROBDD_ite_constant);
 	return result;
-    }
-#endif /* USE_ITE_CONSTANT */
-
+}
+#endif /* MR_ROBDD_USE_ITE_CONSTANT */
 
-DECLARE_FN_COUNT(implies)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_implies)
 
-node *implies(node *a, node *b)
-    {
-	COUNT_FN(implies);
-	return ite(a,b,one);
-    }
+MR_ROBDD_node *
+MR_ROBDD_implies(MR_ROBDD_node *a, MR_ROBDD_node *b)
+{
+    MR_ROBDD_COUNT_FN(MR_ROBDD_implies);
+    return MR_ROBDD_ite(a,b,MR_ROBDD_one);
+}
 
+/* returns a copy of graph a */
 
-node *copy(node *a)        /* returns a copy of graph a */
-    {
+MR_ROBDD_node *
+MR_ROBDD_copy(MR_ROBDD_node *a)
+{
         return a;
-    }
+}
 
+/* returns true if graph a and b are equiv */
 
-int equiv(node *a, node *b)	/* returns true if graph a and b are equiv */
-    {
+int
+MR_ROBDD_equiv(MR_ROBDD_node *a, MR_ROBDD_node *b)
+{
 	return (a == b);
-    }
-
-
-DECLARE_FN_COUNT(lub)
-DECLARE_FN_COUNT(glb)
+}
 
-#if defined(NAIVE)
-node *glb(node *a, node *b)
-    {
-	COUNT_FN(glb);
-	return ite(a,b,zero);
-    }
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_lub)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_glb)
 
+#if defined(MR_ROBDD_NAIVE)
+MR_ROBDD_node *
+MR_ROBDD_glb(MR_ROBDD_node *a, MR_ROBDD_node *b)
+{
+    MR_ROBDD_COUNT_FN(MR_ROBDD_glb);
+    return MR_ROBDD_ite(a,b,MR_ROBDD_zero);
+}
 
-node *lub(node *a, node *b)
-    {
-	COUNT_FN(lub);
-	return ite(a,one,b);
-    }
+MR_ROBDD_node *
+MR_ROBDD_lub(MR_ROBDD_node *a, MR_ROBDD_node *b)
+{
+    MR_ROBDD_COUNT_FN(MR_ROBDD_lub);
+    return MR_ROBDD_ite(a,MR_ROBDD_one,b);
+}
 
-#else /* !NAIVE */
+#else /* !MR_ROBDD_NAIVE */
 
-node *lub(node *f, node *g)
-    {
-	COUNT_FN(lub);
+MR_ROBDD_node *
+MR_ROBDD_lub(MR_ROBDD_node *f, MR_ROBDD_node *g)
+{
+    MR_ROBDD_COUNT_FN(MR_ROBDD_lub);
 	if (IS_TERMINAL(f)) {
-	    return f == one ? one : g;
+        return f == MR_ROBDD_one ? MR_ROBDD_one : g;
 	} else if (IS_TERMINAL(g)) {
-	    return g == one ? one : f;
-	} ELSE_TRY_EQUAL_TEST(f,g,f)
+        return g == MR_ROBDD_one ? MR_ROBDD_one : f;
+    } MR_ROBDD_ELSE_TRY_EQUAL_TEST(f,g,f)
 	else {
-	    node *result;
-	    DECLARE_BIN_CACHE_ENTRY
+        MR_ROBDD_node *result;
+        MR_ROBDD_DECLARE_BIN_CACHE_ENTRY
 
-	    TRY_BIN_CACHE(f, g, lub);
+        MR_ROBDD_TRY_BIN_CACHE(f, g, MR_ROBDD_lub);
 
 	    if (f->value < g->value) {
-		result = make_node(f->value, lub(f->tr, g), lub(f->fa, g));
+            result = MR_ROBDD_make_node(f->value,
+                MR_ROBDD_lub(f->tr, g), MR_ROBDD_lub(f->fa, g));
 	    } else if (f->value > g->value) {
-		result = make_node(g->value, lub(f, g->tr), lub(f, g->fa));
+            result = MR_ROBDD_make_node(g->value,
+                MR_ROBDD_lub(f, g->tr), MR_ROBDD_lub(f, g->fa));
 	    } else /* f->value == g->value */{
-		result = make_node(f->value,
-				   lub(f->tr, g->tr),
-				   lub(f->fa, g->fa));
+            result = MR_ROBDD_make_node(f->value,
+                MR_ROBDD_lub(f->tr, g->tr), MR_ROBDD_lub(f->fa, g->fa));
 	    }
-	    UPDATE_BIN_CACHE(f, g, result, lub);
+        MR_ROBDD_UPDATE_BIN_CACHE(f, g, result, MR_ROBDD_lub);
 	    return result;
 	}
-    }
-
+}
 
-node *glb(node *f, node *g)
-    {
-	COUNT_FN(glb);
+MR_ROBDD_node *
+MR_ROBDD_glb(MR_ROBDD_node *f, MR_ROBDD_node *g)
+{
+    MR_ROBDD_COUNT_FN(MR_ROBDD_glb);
 	if (IS_TERMINAL(f)) {
-	    return f == one ? g : zero;
+        return f == MR_ROBDD_one ? g : MR_ROBDD_zero;
 	} else if (IS_TERMINAL(g)) {
-	    return g == one ? f : zero;
-	} ELSE_TRY_EQUAL_TEST(f,g,f)
+        return g == MR_ROBDD_one ? f : MR_ROBDD_zero;
+    } MR_ROBDD_ELSE_TRY_EQUAL_TEST(f,g,f)
 	else {
-	    node *result;
-	    DECLARE_BIN_CACHE_ENTRY
+        MR_ROBDD_node *result;
+        MR_ROBDD_DECLARE_BIN_CACHE_ENTRY
 
-	    TRY_BIN_CACHE(f, g, glb);
+        MR_ROBDD_TRY_BIN_CACHE(f, g, MR_ROBDD_glb);
 
 	    if (f->value < g->value) {
-		result = make_node(f->value, glb(f->tr, g), glb(f->fa, g));
+            result = MR_ROBDD_make_node(f->value,
+                MR_ROBDD_glb(f->tr, g), MR_ROBDD_glb(f->fa, g));
 	    } else if (f->value > g->value) {
-		result = make_node(g->value, glb(f, g->tr), glb(f, g->fa));
+            result = MR_ROBDD_make_node(g->value,
+                MR_ROBDD_glb(f, g->tr), MR_ROBDD_glb(f, g->fa));
 	    } else /* f->value == g->value */{
-		result = make_node(f->value,
-				   glb(f->tr, g->tr),
-				   glb(f->fa, g->fa));
+            result = MR_ROBDD_make_node(f->value,
+                MR_ROBDD_glb(f->tr, g->tr), MR_ROBDD_glb(f->fa, g->fa));
 	    }
-	    UPDATE_BIN_CACHE(f, g, result, glb);
+        MR_ROBDD_UPDATE_BIN_CACHE(f, g, result, MR_ROBDD_glb);
 	    return result;
 	}
-    }
-
-#endif /* NAIVE */
+}
 
+#endif /* MR_ROBDD_NAIVE */
 
+#if defined(MR_ROBDD_NAIVE)
 
-#if defined(NAIVE)
-node *glb_array(int n, int arr[])
-    {
+MR_ROBDD_node *
+MR_ROBDD_glb_array(int n, int arr[])
+{
 	int i;
-	node *result = one;
+    MR_ROBDD_node *result = MR_ROBDD_one;
 
-	for (i=0; i<n; ++i) {
-	    result = glb(result, variableRep(arr[i]));
+    for (i = 0; i < n; ++i) {
+        result = MR_ROBDD_glb(result, MR_ROBDD_variableRep(arr[i]));
 	}
 	return result;
-    }
-#else /* !NAIVE */
-node *glb_array(int n, int arr[])
-    {
+}
+
+#else /* !MR_ROBDD_NAIVE */
+
+MR_ROBDD_node *
+MR_ROBDD_glb_array(int n, int arr[])
+{
 	int i;
-	node *result = one;
+    MR_ROBDD_node *result = MR_ROBDD_one;
 
-	qsort((char *)arr, n, sizeof(int), intcompare);
-	for (i=n-1; i>=0; --i) {
-	    result = make_node(arr[i], result, zero);
+    qsort((char *)arr, n, sizeof(int), MR_ROBDD_intcompare);
+    for (i = n-1; i >= 0; --i) {
+        result = MR_ROBDD_make_node(arr[i], result, MR_ROBDD_zero);
 	}
 	return result;
-    }
-#endif /* NAIVE */
+}
+
+#endif /* MR_ROBDD_NAIVE */
 
 /****************************************************************
 
@@ -1349,133 +1577,161 @@
 
  ****************************************************************/
 
-DECLARE_FN_COUNT(restrict)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_restrict)
 
 /* restricts c in f. */
-node *restrict(int c, node *f)
-    {
-	COUNT_FN(restrict);
+MR_ROBDD_node *
+MR_ROBDD_restrict(int c, MR_ROBDD_node *f)
+{
+    MR_ROBDD_COUNT_FN(MR_ROBDD_restrict);
         if (IS_TERMINAL(f) || (f->value > c)) {
 	    return f;
         } else if (f->value < c) {
-	    return make_node(f->value, restrict(c,f->tr), restrict(c,f->fa));
+        return MR_ROBDD_make_node(f->value,
+            MR_ROBDD_restrict(c,f->tr), MR_ROBDD_restrict(c,f->fa));
         } else {
-	    return lub(f->tr, f->fa);
-	}
+        return MR_ROBDD_lub(f->tr, f->fa);
     }
+}
 
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_restrictThresh)
 
-DECLARE_FN_COUNT(restrictThresh)
-
-#if !defined(USE_THRESH) && !defined(RESTRICT_SET)
-node *restrictThresh(int lo, int hi, node *a)
-    {
+#if !defined(MR_ROBDD_USE_THRESH) && !defined(MR_ROBDD_RESTRICT_SET)
+MR_ROBDD_node *
+MR_ROBDD_restrictThresh(int lo, int hi, MR_ROBDD_node *a)
+{
 	int i;
 
-	COUNT_FN(restrictThresh);
-	for(i=lo+1; i<=hi; ++i) a = restrict(i, a);
-	return a;
+    MR_ROBDD_COUNT_FN(MR_ROBDD_restrictThresh);
+    for(i = lo+1; i <= hi; ++i) {
+        a = MR_ROBDD_restrict(i, a);
     }
+    return a;
+}
 
-#elif !defined(USE_THRESH) /* && defined(RESTRICT_SET) */
+#elif !defined(MR_ROBDD_USE_THRESH) /* && defined(MR_ROBDD_RESTRICT_SET) */
 
-/* union vars with the set of all variables greater than thresh appearing in
- * the ROBDD rooted at f.
- */
-static void vars_present(node *f, int thresh, bitset *vars)
-    {
+/*
+** union vars with the set of all variables greater than thresh appearing in
+** the ROBDD rooted at f.
+*/
+
+static void
+MR_ROBDD_vars_present(MR_ROBDD_node *f, int thresh, MR_ROBDD_bitset *vars)
+{
 	while (!IS_TERMINAL(f)) {
 	    if (f->value > thresh) {
-		BITSET_ADD_ELEMENT(*vars, f->value);
+            MR_ROBDD_BITSET_ADD_ELEMENT(*vars, f->value);
 	    }
-	    vars_present(f->tr, thresh, vars);
+        MR_ROBDD_vars_present(f->tr, thresh, vars);
 	    f = f->fa;
 	}
-    }
+}
 
-node *restrictThresh(int thresh, node *f)
-    {
-	bitset vars;
+MR_ROBDD_node *
+MR_ROBDD_restrictThresh(int thresh, MR_ROBDD_node *f)
+{
+    MR_ROBDD_bitset vars;
 	int var;
 	int word;
-	bitmask mask;
+    MR_ROBDD_bitmask mask;
 
-	COUNT_FN(restrictThresh);
-	BITSET_CLEAR(vars);
-	vars_present(f, thresh, &vars);
-	REV_FOREACH_ELEMENT(vars, var, word, mask) {
-	    f = restrict(var, f);
+    MR_ROBDD_COUNT_FN(MR_ROBDD_restrictThresh);
+    MR_ROBDD_BITSET_CLEAR(vars);
+    MR_ROBDD_vars_present(f, thresh, &vars);
+    MR_ROBDD_REV_FOREACH_ELEMENT(vars, var, word, mask) {
+        f = MR_ROBDD_restrict(var, f);
 	}
 	return f;
-    }
-#else /* USE_THRESH */
-node *restrictThresh(int thresh, node *f)
-    {
+}
+
+#else /* MR_ROBDD_USE_THRESH */
+
+MR_ROBDD_node *
+MR_ROBDD_restrictThresh(int thresh, MR_ROBDD_node *f)
+{
 	/* restricts all variables greater than thresh. */
 
-	COUNT_FN(restrictThresh);
+    MR_ROBDD_COUNT_FN(MR_ROBDD_restrictThresh);
 	if (IS_TERMINAL(f)) {
 	    return f;
 	} else if (f->value <= thresh) {
-	    return make_node(f->value,
-			     restrictThresh(thresh, f->tr),
-			     restrictThresh(thresh, f->fa));
+        MR_ROBDD_node *result;        
+        MR_ROBDD_DECLARE_ASYM_BIN_CACHE_ENTRY;
+
+        MR_ROBDD_TRY_ASYM_BIN_CACHE((MR_ROBDD_node *) thresh, f, MR_ROBDD_restrictThresh);
+
+        result = MR_ROBDD_make_node(f->value,
+                 MR_ROBDD_restrictThresh(thresh, f->tr),
+                 MR_ROBDD_restrictThresh(thresh, f->fa));
+        MR_ROBDD_UPDATE_ASYM_BIN_CACHE((MR_ROBDD_node *) thresh, f, result, MR_ROBDD_restrictThresh);
+        return result;
 	} else {
-	    return one;
+        return MR_ROBDD_one;
 	}
-    }
-#endif /* USE_THRESH */
+}
 
+#endif /* MR_ROBDD_USE_THRESH */
 
-#if !defined(USE_THRESH) && !defined(RESTRICT_SET)
-node *restricted_glb(int lo, int hi, node *f, node *g)
-    {
-	return restrictThresh(lo, hi, glb(f, g));
-    }
-#elif !defined(USE_RGLB) /* && ( USE_THRESH || RESTRICT_SET ) */
-node *restricted_glb(int thresh, node *f, node *g)
-    {
-	return restrictThresh(thresh, glb(f, g));
-    }
-#else /* USE_RGLB */
-/* returns true iff glb(f,g) is not 'zero' */
-static int exists_glb(node *f, node *g)
-    {
-	if (f == zero) {
-	    return FALSE;
-	} else if (g == zero) {
-	    return FALSE;
-	} else if (f == one) {
-	    /* since we know that g != zero... */
-	    return TRUE;
-	} else if (g == one) {
+#if !defined(MR_ROBDD_USE_THRESH) && !defined(MR_ROBDD_RESTRICT_SET)
+
+MR_ROBDD_node *
+MR_ROBDD_restricted_glb(int lo, int hi, MR_ROBDD_node *f, MR_ROBDD_node *g)
+{
+    return MR_ROBDD_restrictThresh(lo, hi, MR_ROBDD_glb(f, g));
+}
+
+#elif !defined(MR_ROBDD_USE_RGLB) /* && ( MR_ROBDD_USE_THRESH || MR_ROBDD_RESTRICT_SET ) */
+
+MR_ROBDD_node *
+MR_ROBDD_restricted_glb(int thresh, MR_ROBDD_node *f, MR_ROBDD_node *g)
+{
+    return MR_ROBDD_restrictThresh(thresh, MR_ROBDD_glb(f, g));
+}
+
+#else /* MR_ROBDD_USE_RGLB */
+
+/* returns true iff MR_ROBDD_glb(f,g) is not 'MR_ROBDD_zero' */
+static int
+MR_ROBDD_exists_glb(MR_ROBDD_node *f, MR_ROBDD_node *g)
+{
+    if (f == MR_ROBDD_zero) {
+        return MR_FALSE;
+    } else if (g == MR_ROBDD_zero) {
+        return MR_FALSE;
+    } else if (f == MR_ROBDD_one) {
+        /* since we know that g != MR_ROBDD_zero... */
+        return MR_TRUE;
+    } else if (g == MR_ROBDD_one) {
 	    /* likewise f... */
-	    return TRUE;
+        return MR_TRUE;
 	} else if (f->value < g->value) {
-	    return exists_glb(f->tr, g) || exists_glb(f->fa, g);
+        return MR_ROBDD_exists_glb(f->tr, g) || MR_ROBDD_exists_glb(f->fa, g);
 	} else if (f->value > g->value) {
-	    return exists_glb(f, g->tr) || exists_glb(f, g->fa);
+        return MR_ROBDD_exists_glb(f, g->tr) || MR_ROBDD_exists_glb(f, g->fa);
 	} else {
-	    return exists_glb(f->tr, g->tr) || exists_glb(f->fa, g->fa);
+        return MR_ROBDD_exists_glb(f->tr, g->tr) || MR_ROBDD_exists_glb(f->fa, g->fa);
 	}
-    }
-
+}
 
-node *restricted_glb(int c, node *f, node *g)
-    {
+MR_ROBDD_node *
+MR_ROBDD_restricted_glb(int c, MR_ROBDD_node *f, MR_ROBDD_node *g)
+{
 	if (IS_TERMINAL(f)) {
-	    return (f == one) ? restrictThresh(c, g) : zero;
+        return (f == MR_ROBDD_one) ? MR_ROBDD_restrictThresh(c, g)
+            : MR_ROBDD_zero;
 	} else if (IS_TERMINAL(g)) {
-	    return (g == one) ? restrictThresh(c, f) : zero;
-	} ELSE_TRY_EQUAL_TEST(f,g,restrictThresh(c, f))
+        return (g == MR_ROBDD_one) ? MR_ROBDD_restrictThresh(c, f)
+            : MR_ROBDD_zero;
+    } MR_ROBDD_ELSE_TRY_EQUAL_TEST(f,g,MR_ROBDD_restrictThresh(c, f))
 	else {
 	    int v;
-	    node *tr1, *tr2, *fa1, *fa2;
-	    node *result;
+        MR_ROBDD_node *tr1, *tr2, *fa1, *fa2;
+        MR_ROBDD_node *result;
 
-	    DECLARE_RGLB_CACHE_ENTRY
+        MR_ROBDD_DECLARE_RGLB_CACHE_ENTRY
 
-	    TRY_RGLB_CACHE(f, g, c);
+        MR_ROBDD_TRY_RGLB_CACHE(f, g, c);
 
 	    if (f->value < g->value) {
 		v = f->value;
@@ -1498,19 +1754,18 @@
 	    }
 	    if (v > c) {
 		result =
-		  (exists_glb(tr1,tr2)||exists_glb(fa1,fa2)) ? one : zero;
+                (MR_ROBDD_exists_glb(tr1,tr2)||MR_ROBDD_exists_glb(fa1,fa2)) ?
+                    MR_ROBDD_one : MR_ROBDD_zero;
 	    } else {
-		result = make_node(v,
-				   restricted_glb(c, tr1, tr2),
-				   restricted_glb(c, fa1, fa2));
+            result = MR_ROBDD_make_node(v,
+               MR_ROBDD_restricted_glb(c, tr1, tr2),
+               MR_ROBDD_restricted_glb(c, fa1, fa2));
 	    }
-	    UPDATE_RGLB_CACHE(f,g,c,result);
+        MR_ROBDD_UPDATE_RGLB_CACHE(f,g,c,result);
 	    return result;
 	}
-    }
-#endif /* USE_THRESH */
-
-    
+}
+#endif /* MR_ROBDD_USE_THRESH */
 
 /****************************************************************
 
@@ -1518,189 +1773,212 @@
 
  ****************************************************************/
 
-DECLARE_FN_COUNT(renameArray)
-DECLARE_FN_COUNT(reverseRenameArray)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_renameArray)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_reverseRenameArray)
 
-#if defined(NEW)
+#if defined(MR_ROBDD_NEW)
 
-DECLARE_FN_COUNT(ite_var)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_ite_var)
 
-/* A special case version of ite_var, where we know that f < g->value */
-static node *ite_var_g(int f, node *g, node *h)
-    {
-	COUNT_FN(ite_var);
+/* A special case version of MR_ROBDD_ite_var, where we know that f < g->value */
+static MR_ROBDD_node *
+MR_ROBDD_ite_var_g(int f, MR_ROBDD_node *g, MR_ROBDD_node *h)
+{
+    MR_ROBDD_COUNT_FN(MR_ROBDD_ite_var);
 
         assert(IS_TERMINAL(g) || f < g->value);
 
 	if (IS_TERMINAL(h) || f < h->value) {
 	    /* f < g && f < h */
-	    return make_node(f, g, h);
+        return MR_ROBDD_make_node(f, g, h);
 	} else if (f == h->value) {
-	    return make_node(f, g, h->fa);
+        return MR_ROBDD_make_node(f, g, h->fa);
 	} else {
 	    /* h < f < g */
-	    node *result;
-	    DECLARE_ITE_VAR_CACHE_ENTRY
+        MR_ROBDD_node *result;
+        MR_ROBDD_DECLARE_ITE_VAR_CACHE_ENTRY
 
-	    TRY_ITE_VAR_CACHE(f, g, h);
+        MR_ROBDD_TRY_ITE_VAR_CACHE(f, g, h);
 
-	    result = make_node(h->value,
-			       ite_var_g(f, g, h->tr),
-			       ite_var_g(f, g, h->fa));
-	    UPDATE_ITE_VAR_CACHE(f, g, h, result);
+        result = MR_ROBDD_make_node(h->value,
+                   MR_ROBDD_ite_var_g(f, g, h->tr),
+                   MR_ROBDD_ite_var_g(f, g, h->fa));
+        MR_ROBDD_UPDATE_ITE_VAR_CACHE(f, g, h, result);
 	    return result;
 	}
-    }
-
+}
 
-/* A special case version of ite_var, where we know that f < h->value */
-static node *ite_var_h(int f, node *g, node *h)
-    {
-	COUNT_FN(ite_var);
+/*
+** A special case version of MR_ROBDD_ite_var, where we know that
+** f < h->value
+*/
+
+static MR_ROBDD_node *
+MR_ROBDD_ite_var_h(int f, MR_ROBDD_node *g, MR_ROBDD_node *h)
+{
+    MR_ROBDD_COUNT_FN(MR_ROBDD_ite_var);
 
         assert(IS_TERMINAL(h) || f < h->value);
 
 	if (IS_TERMINAL(g) || f < g->value) {
 	    /* f < g && f < h */
-	    return make_node(f, g, h);
+        return MR_ROBDD_make_node(f, g, h);
 	} else if (f == g->value) {
-	    return make_node(f, g->tr, h);
+        return MR_ROBDD_make_node(f, g->tr, h);
 	} else {
 	    /* h < f < g */
-	    node *result;
-	    DECLARE_ITE_VAR_CACHE_ENTRY
+        MR_ROBDD_node *result;
+        MR_ROBDD_DECLARE_ITE_VAR_CACHE_ENTRY
 
-	    TRY_ITE_VAR_CACHE(f, g, h);
-	    result = make_node(g->value,
-			       ite_var_h(f, g->tr, h),
-			       ite_var_h(f, g->fa, h));
-	    UPDATE_ITE_VAR_CACHE(f, g, h, result);
+        MR_ROBDD_TRY_ITE_VAR_CACHE(f, g, h);
+        result = MR_ROBDD_make_node(g->value,
+                   MR_ROBDD_ite_var_h(f, g->tr, h),
+                   MR_ROBDD_ite_var_h(f, g->fa, h));
+        MR_ROBDD_UPDATE_ITE_VAR_CACHE(f, g, h, result);
 	    return result;
 	}
-    }
-
-
-/* A special case version of ite, where we know that !IS_TERMINAL(f) &&
- * f->tr == one && f->fa == zero.  In fact, we refine this further and
- * make f be just (what would have been) f->value.
- *
- * Recall the code for ite:  it finds the minimum value of f, g, and h (call
- * it top), and sets each of ft, gt and ht to the tr branch of the
- * corresponding arg if its value == top, else sets it to the arg itself, and
- * correspondingly for ff, gf, and hf.  Then the value of ite is:
- *
- *    mn(top, i(ft, gt, ht), i(ff, gf, hf))
- *
- * (abbreviating make_node as mn and ite as i).  Given this, we can simplify
- * things in several cases.  Here are all the cases, and the simplified value.
- * (We introduce ig for ite_var_g and ih for ite_var_h as special cases where
- * we know f < g or f < h, respectively.)
- *
- * a)	f = g = h    (1)   mn(f, g->tr, h->fa) *** Impossible
- *
- * b)	f < g < h    (2)   mn(f, g, h)
- * c)	f < g = h    (2)   mn(f, g, h)
- * d)	f < h < g    (2)   mn(f, g, h)
- * e)	f = g < h    (3)   mn(f, g->tr, h) *** Impossible
- * f)	f = h < g    (4)   mn(f, g, h->fa) *** Impossible
- *
- * g)	g < f < h    (5)   mn(gv, ih(f, g->tr, h), ih(f, g->fa, h))
- * h)	g < f = h    (6)   mn(gv, i(f, g->tr, h), i(f, g->fa, h)) *** Impossible
- * i)	g < h < f    (6)   mn(gv, i(f, g->tr, h), i(f, g->fa, h))
- * j)	g = h < f    (7)   mn(gv, i(f, g->tr, h->tr), i(f, g->fa, h->fa))
- *
- * k)	h < f < g    (8)   mn(hv, ig(f, g, h->tr), ig(f, g, h->fa))
- * l)	h < f = g    (9)   mn(hv, i(f, g, h->tr), i(f, g, h->fa)) *** Impossible
- * m)	h < g < f    (9)   mn(hv, i(f, g, h->tr), i(f, g, h->fa))
- */	    
+}
 
-node *ite_var(int f,node *g,node *h)
-    {
-	int g_val = MAXVAR;
-	int h_val = MAXVAR;
-	node *result;
-	DECLARE_ITE_VAR_CACHE_ENTRY
-
-	COUNT_FN(ite_var);
-	DIRECT_EQUAL_TEST(g,h,g);
-	TRY_ITE_VAR_CACHE(f, g, h);
+/*
+** A special case version of MR_ROBDD_ite, where we know that !IS_TERMINAL(f)
+** && f->tr == MR_ROBDD_one && f->fa == MR_ROBDD_zero.  In fact, we refine
+** this further and make f be just (what would have been) f->value.
+**
+** Recall the code for MR_ROBDD_ite: it finds the minimum value of f, g, and h
+** (call it top), and sets each of ft, gt and ht to the tr branch of the
+** corresponding arg if its value == top, else sets it to the arg itself, and
+** correspondingly for ff, gf, and hf.  Then the value of MR_ROBDD_ite is:
+**
+**    mn(top, i(ft, gt, ht), i(ff, gf, hf))
+**
+** (abbreviating MR_ROBDD_make_node as mn and MR_ROBDD_ite as i). Given this,
+** we can simplify things in several cases. Here are all the cases, and the
+** simplified value. (We introduce ig for MR_ROBDD_ite_var_g and ih for
+** MR_ROBDD_ite_var_h as special cases where we know f < g or f < h,
+** respectively.)
+**
+** a)    f = g = h   (1)   mn(f, g->tr, h->fa) *** Impossible
+**
+** b)    f < g < h   (2)   mn(f, g, h)
+** c)    f < g = h   (2)   mn(f, g, h)
+** d)    f < h < g   (2)   mn(f, g, h)
+** e)    f = g < h   (3)   mn(f, g->tr, h) *** Impossible
+** f)    f = h < g   (4)   mn(f, g, h->fa) *** Impossible
+**
+** g)    g < f < h   (5)   mn(gv, ih(f, g->tr, h), ih(f, g->fa, h))
+** h)    g < f = h   (6)   mn(gv, i(f, g->tr, h), i(f, g->fa, h)) *** Impossible
+** i)    g < h < f   (6)   mn(gv, i(f, g->tr, h), i(f, g->fa, h))
+** j)    g = h < f   (7)   mn(gv, i(f, g->tr, h->tr), i(f, g->fa, h->fa))
+**
+** k)    h < f < g   (8)   mn(hv, ig(f, g, h->tr), ig(f, g, h->fa))
+** l)    h < f = g   (9)   mn(hv, i(f, g, h->tr), i(f, g, h->fa)) *** Impossible
+** m)    h < g < f   (9)   mn(hv, i(f, g, h->tr), i(f, g, h->fa))
+*/        
+
+MR_ROBDD_node *
+MR_ROBDD_ite_var(int f,MR_ROBDD_node *g,MR_ROBDD_node *h)
+{
+    int g_val = INT_MAX;
+    int h_val = INT_MAX;
+    MR_ROBDD_node *result;
+    MR_ROBDD_node *g_tr, *g_fa, *h_tr, *h_fa;
+    MR_ROBDD_DECLARE_ITE_VAR_CACHE_ENTRY
+
+    MR_ROBDD_COUNT_FN(MR_ROBDD_ite_var);
+    MR_ROBDD_DIRECT_EQUAL_TEST(g,h,g);
+    MR_ROBDD_TRY_ITE_VAR_CACHE(f, g, h);
 
 	if (!IS_TERMINAL(g)) g_val = g->value;
 	if (!IS_TERMINAL(h)) h_val = h->value;
 
+    if (IS_TERMINAL(g)) {
+        g_tr = g_fa = g;
+    } else {
+        g_tr = g->tr;
+        g_fa = g->fa;
+    }
+    if (IS_TERMINAL(h)) {
+        h_tr = h_fa = h;
+    } else {
+        h_tr = h->tr;
+        h_fa = h->fa;
+    }
+
 	if (f < g_val) {
 	    if (f < h_val) /* case 2 (b,c,d):  f < g && f < h */ {
-		result = make_node(f, g, h);
+            result = MR_ROBDD_make_node(f, g, h);
 	    } else /* case 8 (k):  h < f < g */ {
-		result = make_node(h_val,
-				   ite_var_g(f, g, h->tr),
-				   ite_var_g(f, g, h->fa));
+            result = MR_ROBDD_make_node(h_val,
+                   MR_ROBDD_ite_var_g(f, g, h_tr),
+                   MR_ROBDD_ite_var_g(f, g, h_fa));
 	    }
 	/* g < f */
 	} else if (f < h_val) /* g < f < h */ {
-	    result = make_node(g_val,
-			       ite_var_h(f, g->tr, h),
-			       ite_var_h(f, g->fa, h));
+        result = MR_ROBDD_make_node(g_val,
+                   MR_ROBDD_ite_var_h(f, g_tr, h),
+                   MR_ROBDD_ite_var_h(f, g_fa, h));
 	/* g < f && h < f */
 	} else if (h_val < g_val) /* case 9 (l,m): h < g < f */ {
-	    result = make_node(h_val,
-			       ite_var(f, g, h->tr),
-			       ite_var(f, g, h->fa));
+        result = MR_ROBDD_make_node(h_val,
+                   MR_ROBDD_ite_var(f, g, h_tr),
+                   MR_ROBDD_ite_var(f, g, h_fa));
 	/* g < f && g <= h */
 	} else if (g_val == h_val) /* g == h < f */ {
-	    result = make_node(g_val,
-			       ite_var(f, g->tr, h->tr),
-			       ite_var(f, g->fa, h->fa));
+        result = MR_ROBDD_make_node(g_val,
+                   MR_ROBDD_ite_var(f, g_tr, h_tr),
+                   MR_ROBDD_ite_var(f, g_fa, h_fa));
 	} else /* case 6 (h,i):  g < h < f */ {
-	    result = make_node(g_val,
-			       ite_var(f, g->tr, h),
-			       ite_var(f, g->fa, h));
+        result = MR_ROBDD_make_node(g_val,
+                   MR_ROBDD_ite_var(f, g_tr, h),
+                   MR_ROBDD_ite_var(f, g_fa, h));
 	}
 
-	UPDATE_ITE_VAR_CACHE(f, g, h, result);
+    MR_ROBDD_UPDATE_ITE_VAR_CACHE(f, g, h, result);
 	return result;
-    }
+}
 
-#else /* ! NEW */
-#define ite_var(v,f,g) ite(variableRep(v), f, g)
-#endif /* !NEW */
+#else /* ! MR_ROBDD_NEW */
 
-node *renameArray(node *f, int count, int mapping[])
-    {
+#define MR_ROBDD_ite_var(v,f,g) MR_ROBDD_ite(MR_ROBDD_variableRep(v), f, g)
+
+#endif /* !MR_ROBDD_NEW */
+
+MR_ROBDD_node *
+MR_ROBDD_renameArray(MR_ROBDD_node *f, int count, int mapping[])
+{
 	int newval;
 
-	COUNT_FN(renameArray);
+    MR_ROBDD_COUNT_FN(MR_ROBDD_renameArray);
 	if (IS_TERMINAL(f)) {
 	    return f;
 	} else if (f->value > count) {
-	    return one;
-	} else if (UNUSED_MAPPING==(newval=mapping[f->value])) {
-	    return lub(renameArray(f->tr, count, mapping),
-		       renameArray(f->fa, count, mapping));
-	} else {
-	    return ite_var(newval,
-			   renameArray(f->tr, count, mapping),
-			   renameArray(f->fa, count, mapping));
-	}
+        return MR_ROBDD_one;
+    } else if (MR_ROBDD_UNUSED_MAPPING==(newval=mapping[f->value])) {
+        return MR_ROBDD_lub(MR_ROBDD_renameArray(f->tr, count, mapping),
+               MR_ROBDD_renameArray(f->fa, count, mapping));
+    } else {
+        return MR_ROBDD_ite_var(newval,
+               MR_ROBDD_renameArray(f->tr, count, mapping),
+               MR_ROBDD_renameArray(f->fa, count, mapping));
     }
+}
 
-node *reverseRenameArray(node *f, int count, int mapping[])
-    {
-	int i, val, max;
+MR_ROBDD_node *
+MR_ROBDD_reverseRenameArray(MR_ROBDD_node *f, int count, int mapping[])
+{
+    int i, val, MR_ROBDD_max;
 	int rev_map[MAXVAR];
 
-	COUNT_FN(reverseRenameArray);
+    MR_ROBDD_COUNT_FN(MR_ROBDD_reverseRenameArray);
 	/* NB:  four -1 bytes is the same as a -1 word */
-	memset(rev_map, -1, sizeof(rev_map));
-	for (i=1,max=-1; i<=count; ++i) {
+    MR_memset(rev_map, ~((char) 0), sizeof(rev_map));
+    for (i=1,MR_ROBDD_max=-1; i<=count; ++i) {
 	    rev_map[(val=mapping[i])] = i;
-	    if (max < val) max = val;
-	}
-
-	return renameArray(f, max, rev_map);
+        if (MR_ROBDD_max < val) MR_ROBDD_max = val;
     }
 
-
+    return MR_ROBDD_renameArray(f, MR_ROBDD_max, rev_map);
+}
 
 /****************************************************************
 
@@ -1708,207 +1986,237 @@
 
  ****************************************************************/
 
-#if !defined(USE_THRESH) && !defined(RESTRICT_SET)
-node *abstract_exit(node *context, node *f, int count, int mapping[],
-		    int lo, int hi)
-    {
-	return restricted_glb(lo, hi, context, renameArray(f, count, mapping));
-    }
-#elif 1 /* ( USE_THRESH || RESTRICT_SET ) */
-node *abstract_exit(node *context, node *f, int count, int mapping[],
-		    int thresh)
-    {
-	return restricted_glb(thresh, context, renameArray(f, count, mapping));
-    }
+#if !defined(MR_ROBDD_USE_THRESH) && !defined(MR_ROBDD_RESTRICT_SET)
+
+MR_ROBDD_node *
+MR_ROBDD_abstract_exit(MR_ROBDD_node *context, MR_ROBDD_node *f, int count,
+    int mapping[], int lo, int hi)
+{
+    return MR_ROBDD_restricted_glb(lo, hi, context,
+        MR_ROBDD_renameArray(f, count, mapping));
+}
+
+#elif 1 /* ( MR_ROBDD_USE_THRESH || MR_ROBDD_RESTRICT_SET ) */
+
+MR_ROBDD_node *
+MR_ROBDD_abstract_exit(MR_ROBDD_node *context, MR_ROBDD_node *f, int count,
+    int mapping[], int thresh)
+{
+    return MR_ROBDD_restricted_glb(thresh, context,
+        MR_ROBDD_renameArray(f, count, mapping));
+}
+
 #else /* 0 (this code not used) */
 
-/* returns FALSE iff the function f restricted so that all variables in trues
- * are set to true and all in falses are set to false evaluates to zero.
- */
-int exists_restrict_sets(node *f, bitset *trues, bitset *falses, int hielt)
-    {
+/*
+** returns MR_FALSE iff the function f restricted so that all variables in
+** trues are set to true and all in falses are set to false evaluates to
+** MR_ROBDD_zero.
+*/
+
+int
+MR_ROBDD_exists_restrict_sets(MR_ROBDD_node *f, MR_ROBDD_bitset *trues,
+    MR_ROBDD_bitset *falses, int hielt)
+{
 	for (;;) {
 	    if (IS_TERMINAL(f)) {
-		return f == one;
+            return f == MR_ROBDD_one;
 	    } else if (f->value > hielt) {
-		return TRUE;
+            return MR_TRUE;
 	    } else {
-		int word = BITSET_WORD(f->value);
-		bitmask mask = BITSET_MASK(f->value);
+            int word = MR_ROBDD_BITSET_WORD(f->value);
+            MR_ROBDD_bitmask mask = MR_ROBDD_BITSET_MASK(f->value);
 
-		if (BITSET_MEMBER(*trues,word,mask)) {
+            if (MR_ROBDD_BITSET_MEMBER(*trues,word,mask)) {
 		    f = f->tr;			/* continue loop */
-		} else if (BITSET_MEMBER(*falses,word,mask)) {
+            } else if (MR_ROBDD_BITSET_MEMBER(*falses,word,mask)) {
 		    f = f->fa;			/* continue loop */
-		} else if (exists_restrict_sets(f->tr, trues, falses, hielt)) {
-		    return TRUE;
+            } else if (MR_ROBDD_exists_restrict_sets(f->tr, trues, falses,
+                hielt))
+            {
+                return MR_TRUE;
 		} else {
 		    f = f->fa;
 		}
 	    }
 	}
-    }
-
+}
 
-/* computes the function f restricted so that all variables in trues
- * are set to true and all in falses are set to false.
- */
-node *restrict_sets(node *f, bitset *trues, bitset *falses, int hielt,
-		    int thresh)
-    {
+/*
+** computes the function f restricted so that all variables in trues
+** are set to true and all in falses are set to false.
+*/
+
+MR_ROBDD_node *
+MR_ROBDD_restrict_sets(MR_ROBDD_node *f, MR_ROBDD_bitset *trues,
+    MR_ROBDD_bitset *falses, int hielt, int thresh)
+{
 	for (;;) {
 	    if (IS_TERMINAL(f)) {
 		return f;
 	    } else if (f->value > hielt) {
-		return restrictThresh(thresh, f);
+            return MR_ROBDD_restrictThresh(thresh, f);
 	    } else if (f->value > thresh) {
-		return
-		  exists_restrict_sets(f, trues, falses, hielt) ? one : zero;
+            return MR_ROBDD_exists_restrict_sets(f, trues, falses, hielt)
+                ? MR_ROBDD_one : MR_ROBDD_zero;
 	    } else {
-		int word = BITSET_WORD(f->value);
-		bitmask mask = BITSET_MASK(f->value);
+            int word = MR_ROBDD_BITSET_WORD(f->value);
+            MR_ROBDD_bitmask mask = MR_ROBDD_BITSET_MASK(f->value);
 
-		if (BITSET_MEMBER(*trues,word,mask)) {
+            if (MR_ROBDD_BITSET_MEMBER(*trues,word,mask)) {
 		    f = f->tr;			/* continue loop */
-		} else if (BITSET_MEMBER(*falses,word,mask)) {
+            } else if (MR_ROBDD_BITSET_MEMBER(*falses,word,mask)) {
 		    f = f->fa;			/* continue loop */
 		} else {
-		    return make_node(f->value,
-				     restrict_sets(f->tr, trues, falses, hielt,
+                return MR_ROBDD_make_node(f->value,
+                         MR_ROBDD_restrict_sets(f->tr, trues, falses, hielt,
 						   thresh),
-				     restrict_sets(f->fa, trues, falses, hielt,
+                         MR_ROBDD_restrict_sets(f->fa, trues, falses, hielt,
 						   thresh));
 		}
 	    }
 	}
-    }
-
+}
 
-/* if f->value > thresh, returns one, else if f->value is in either
- * trues (or falses), this returns
- *	follow_path(f->tr (or fa), trues, falses}
- * else it returns f.
- */
-node *follow_path(node *f, bitset *trues, bitset *falses)
-    {
+/*
+** if f->value > thresh, returns MR_ROBDD_one, else if f->value is in either
+** trues (or falses), this returns
+**    MR_ROBDD_follow_path(f->tr (or fa), trues, falses}
+** else it returns f.
+*/
+
+MR_ROBDD_node *
+MR_ROBDD_follow_path(MR_ROBDD_node *f, MR_ROBDD_bitset *trues,
+    MR_ROBDD_bitset *falses)
+{
 
 	while (!IS_TERMINAL(f)) {
-	    int word = BITSET_WORD(f->value);
-	    bitmask mask = BITSET_MASK(f->value);
+        int word = MR_ROBDD_BITSET_WORD(f->value);
+        MR_ROBDD_bitmask mask = MR_ROBDD_BITSET_MASK(f->value);
 	    
-	    if (BITSET_MEMBER(*trues,word,mask)) {
+        if (MR_ROBDD_BITSET_MEMBER(*trues,word,mask)) {
 		f = f->tr;
-	    } else if (BITSET_MEMBER(*falses,word,mask)) {
+        } else if (MR_ROBDD_BITSET_MEMBER(*falses,word,mask)) {
 		f = f->fa;
 	    } else {
 		break;
 	    }
 	}
 	return f;
-    }
+}
 
+/*
+** This function computes
+**
+**    MR_ROBDD_restrictThresh(MR_ROBDD_renameArray(f, count, mapping), thresh)
+**
+*/
 
-/* This function computes
- *
- *    restrictThresh(renameArray(f, count, mapping), thresh)
- *
- */
-node *restricted_rename(node *f, int count, int mapping[], int thresh)
-    {
+MR_ROBDD_node *
+MR_ROBDD_restricted_rename(MR_ROBDD_node *f, int count, int mapping[],
+    int thresh)
+{
 	if (IS_TERMINAL(f)) {
 	    return f;
 	} else {
 	    int newval = mapping[f->value];
-	    node *tr, *fa;
+        MR_ROBDD_node *tr, *fa;
 
-	    tr = restricted_rename(f->tr, count, mapping, thresh);
-	    fa = restricted_rename(f->fa, count, mapping, thresh);
+        tr = MR_ROBDD_restricted_rename(f->tr, count, mapping, thresh);
+        fa = MR_ROBDD_restricted_rename(f->fa, count, mapping, thresh);
 
 	    if (newval > thresh) {
-		return lub(tr, fa);
+            return MR_ROBDD_lub(tr, fa);
 	    } else {
-		return ite_var(newval, tr, fa);
+            return MR_ROBDD_ite_var(newval, tr, fa);
 	    }
 	}
-    }
-
-
+}
 
-/* This function computes
- *
- *    restrictThresh(glb(context1, renameArray(f, count, mapping)), thresh)
- *
- * where context1 is context restricted by the settings in trues and
- * falses.  We know that !IS_TERMINAL(context).
- */
-node *abexit(node *context, node *f, int count, int mapping[], int thresh,
-	     bitset *trues, bitset *falses, int hielt)
-    {
+/*
+** This function computes
+**
+**    MR_ROBDD_restrictThresh(MR_ROBDD_glb(context1,
+**        MR_ROBDD_renameArray(f, count, mapping)), thresh)
+**
+** where context1 is context restricted by the settings in trues and
+** falses.  We know that !IS_TERMINAL(context).
+*/
+
+MR_ROBDD_node *
+MR_ROBDD_abexit(MR_ROBDD_node *context, MR_ROBDD_node *f, int count,
+    int mapping[], int thresh, MR_ROBDD_bitset *trues,
+    MR_ROBDD_bitset *falses, int hielt)
+{
 	if (IS_TERMINAL(f)) {
-	    if (f==one) {
-		return restrict_sets(context, trues, falses, hielt, thresh);
+        if (f==MR_ROBDD_one) {
+            return MR_ROBDD_restrict_sets(context, trues, falses, hielt,
+                thresh);
 	    } else {
 		return f;
 	    }
 	} else {
 	    int newval = mapping[f->value];
-	    node *tr, *fa;
+        MR_ROBDD_node *tr, *fa;
 
 	    if (newval == context->value) {
-		tr = follow_path(context->tr, trues, falses);
-		fa = follow_path(context->fa, trues, falses);
+            tr = MR_ROBDD_follow_path(context->tr, trues, falses);
+            fa = MR_ROBDD_follow_path(context->fa, trues, falses);
 
-		if (tr == one) {
-		    tr = restricted_rename(f->tr, count, mapping, thresh);
-		} else if (tr != zero) {
-		    tr = abexit(tr, f->tr, count, mapping, thresh,
+            if (tr == MR_ROBDD_one) {
+                tr = MR_ROBDD_restricted_rename(f->tr, count, mapping, thresh);
+            } else if (tr != MR_ROBDD_zero) {
+                tr = MR_ROBDD_abexit(tr, f->tr, count, mapping, thresh,
 				trues, falses, hielt);
 		}
-		if (fa == one) {
-		    fa = restricted_rename(f->fa, count, mapping, thresh);
-		} else if (fa != zero) {
-		    fa = abexit(fa, f->fa, count, mapping, thresh,
+            if (fa == MR_ROBDD_one) {
+                fa = MR_ROBDD_restricted_rename(f->fa, count, mapping, thresh);
+            } else if (fa != MR_ROBDD_zero) {
+                fa = MR_ROBDD_abexit(fa, f->fa, count, mapping, thresh,
 				trues, falses, hielt);
 		}
 	    } else {
-		int word = BITSET_WORD(newval);
-		bitmask mask = BITSET_MASK(newval);
+            int word = MR_ROBDD_BITSET_WORD(newval);
+            MR_ROBDD_bitmask mask = MR_ROBDD_BITSET_MASK(newval);
 		int newhi = (newval>hielt ? newval : hielt);
 
-		BITSET_ADD(*trues,word,mask); /* turn on true bit */
-		tr = abexit(context, f->tr, count, mapping, thresh,
+            MR_ROBDD_BITSET_ADD(*trues,word,mask); /* turn on true bit */
+            tr = MR_ROBDD_abexit(context, f->tr, count, mapping, thresh,
 			    trues, falses, newhi);
-		BITSET_TOGGLE(*trues,word,mask); /* turn off true bit */
-		BITSET_ADD(*falses,word,mask); /* turn on false bit */
-		fa = abexit(context, f->fa, count, mapping, thresh,
+            MR_ROBDD_BITSET_TOGGLE(*trues,word,mask); /* turn off true bit */
+            MR_ROBDD_BITSET_ADD(*falses,word,mask); /* turn on false bit */
+            fa = MR_ROBDD_abexit(context, f->fa, count, mapping, thresh,
 			    trues, falses, newhi);
-		BITSET_TOGGLE(*falses,word,mask); /* turn off false bit */
+            MR_ROBDD_BITSET_TOGGLE(*falses,word,mask); /* turn off false bit */
 	    }
 	    if (newval > thresh) {
-		return lub(tr, fa);
+            return MR_ROBDD_lub(tr, fa);
 	    } else {
-		return ite_var(newval, tr, fa);
+            return MR_ROBDD_ite_var(newval, tr, fa);
 	    }
 	}
-    }
-
-
-node *abstract_exit(node *context, node *f, int count, int mapping[],
-		    int thresh)
-    {
-	bitset trues;
-	bitset falses;
+}
 
-	if (context == zero) return zero;
-	if (context == one) return restricted_rename(f, count, mapping, thresh);
+MR_ROBDD_node *
+MR_ROBDD_abstract_exit(MR_ROBDD_node *context, MR_ROBDD_node *f, int count,
+    int mapping[], int thresh)
+{
+    MR_ROBDD_bitset trues;
+    MR_ROBDD_bitset falses;
+
+    if (context == MR_ROBDD_zero)
+        return MR_ROBDD_zero;
+    if (context == MR_ROBDD_one)
+        return MR_ROBDD_restricted_rename(f, count, mapping, thresh);
 
-	BITSET_CLEAR(trues);
-	BITSET_CLEAR(falses);
+    MR_ROBDD_BITSET_CLEAR(trues);
+    MR_ROBDD_BITSET_CLEAR(falses);
 
-	return abexit(context, f, count, mapping, thresh, &trues, &falses, -1);
+    return MR_ROBDD_abexit(context, f, count, mapping, thresh,
+        &trues, &falses, -1);
 }
-#endif /* 0 (end of unused code)  */
 
+#endif /* 0 (end of unused code)  */
 
 /****************************************************************
 
@@ -1916,269 +2224,300 @@
 
  ****************************************************************/
 
-/* NB:  iff_conj_array, and so all the functions that call it, now
- * allow v0 to apear in the array of variables arr[].  This makes the
- * analyzer robust for handling goals like X = f(X,Y).  Since it's
- * cheaper and easier to check this in C, I do it here.
- */
-
-#if defined(ELIM_DUPS)
-#define DECLARE_PREV(init) int prev = (init);
-#define HANDLE_DUP(this,rel)	\
+/*
+** NB:  MR_ROBDD_iff_conj_array, and so all the functions that call it, now
+** allow v0 to apear in the array of variables arr[].  This makes the
+** analyzer robust for handling goals like X = f(X,Y).  Since it's
+** cheaper and easier to check this in C, I do it here.
+*/
+
+#if defined(MR_ROBDD_ELIM_DUPS)
+  #define MR_ROBDD_DECLARE_PREV(init) int prev = (init);
+  #define MR_ROBDD_HANDLE_DUP(this,rel)                                 \
 	if ((this) == prev) continue;	\
 	assert((this) rel prev);	\
 	prev = (this);
 #elif !defined(NDEBUG)
-#define DECLARE_PREV(init) int prev = (init);
-#define HANDLE_DUP(this,rel)	\
+  #define MR_ROBDD_DECLARE_PREV(init) int prev = (init);
+  #define MR_ROBDD_HANDLE_DUP(this,rel)                                 \
 	assert((this) != prev);	\
 	assert((this) rel prev);	\
 	prev = (this);
 #else
-#define DECLARE_PREV(init)
-#define HANDLE_DUP(this,rel)
+  #define MR_ROBDD_DECLARE_PREV(init)
+  #define MR_ROBDD_HANDLE_DUP(this,rel)
 #endif
 
+MR_ROBDD_DECLARE_FN_COUNT(iff_conj)
 
-DECLARE_FN_COUNT(iff_conj)
-
-#if defined(NAIVE)
-node *iff_conj_array(int v0, int n, int arr[])
-    {
-	node *conj = one;
-	node *v_rep = variableRep(v0);
+#if defined(MR_ROBDD_NAIVE)
+MR_ROBDD_node *MR_ROBDD_iff_conj_array(int v0, int n, int arr[])
+{
+    MR_ROBDD_node *conj = MR_ROBDD_one;
+    MR_ROBDD_node *v_rep = MR_ROBDD_variableRep(v0);
 	int i;
-	DECLARE_PREV(-1)
+    MR_ROBDD_DECLARE_PREV(-1)
 
-	COUNT_FN(iff_conj);
+    MR_ROBDD_COUNT_FN(iff_conj);
 	/* We construct the conjunction from the lowest var up to the highest.
 	 * This is a quadratic process, while the other way is linear.
 	 */ 
 	for (i=0; i<n; ++i) {
-	    HANDLE_DUP(arr[i], >)
-	    if (arr[i] != v0) conj = glb(conj, variableRep(arr[i]));
+        MR_ROBDD_HANDLE_DUP(arr[i], >)
+        if (arr[i] != v0) {
+            conj = MR_ROBDD_glb(conj, MR_ROBDD_variableRep(arr[i]));
 	}
-	return glb(implies(conj,v_rep), implies(v_rep,conj));
     }
+    return MR_ROBDD_glb(MR_ROBDD_implies(conj,v_rep),
+        MR_ROBDD_implies(v_rep,conj));
+}
 
-#elif !defined(USE_THRESH)
+#elif !defined(MR_ROBDD_USE_THRESH)
 
-node *iff_conj_array(int v0, int n, int arr[])
-    {
-	node *conj = one;
-	node *pos_v = variableRep(v0);
-	node *neg_v = ite(pos_v, zero, one);
+MR_ROBDD_node *MR_ROBDD_iff_conj_array(int v0, int n, int arr[])
+{
+    MR_ROBDD_node *conj = MR_ROBDD_one;
+    MR_ROBDD_node *pos_v = MR_ROBDD_variableRep(v0);
+    MR_ROBDD_node *neg_v = MR_ROBDD_ite(pos_v, MR_ROBDD_zero, MR_ROBDD_one);
 	int *ptr;
-	DECLARE_PREV(MAXVAR)
+    MR_ROBDD_DECLARE_PREV(MAXVAR)
 
-	COUNT_FN(iff_conj);
+    MR_ROBDD_COUNT_FN(iff_conj);
 	/* Note that to be efficient, we construct the conjunction
 	 * from the highest var down to the lowest.  This is a linear
 	 * process, while the other way is n squared.
 	 */ 
 	for (ptr=&arr[n-1]; ptr>=arr; --ptr) {
 	    int vi = *ptr;
-	    HANDLE_DUP(vi, <)
-	    if (vi != v0) conj = glb(conj, variableRep(vi));
+        MR_ROBDD_HANDLE_DUP(vi, <)
+        if (vi != v0) {
+            conj = MR_ROBDD_glb(conj, MR_ROBDD_variableRep(vi));
 	}
-	return ite(conj, pos_v, neg_v);
     }
+    return MR_ROBDD_ite(conj, pos_v, neg_v);
+}
 
-#else /* USE_THRESH */
+#else /* MR_ROBDD_USE_THRESH */
 
-node *iff_conj_array(int v0, int n, int arr[])
-    {
-	node *thens = one, *elses = zero;
+MR_ROBDD_node *MR_ROBDD_iff_conj_array(int v0, int n, int arr[])
+{
+    MR_ROBDD_node *thens = MR_ROBDD_one, *elses = MR_ROBDD_zero;
 	int *ptr;
 	int vi = 0;	/* this value doesn't matter */
-	DECLARE_PREV(MAXVAR)
+    MR_ROBDD_DECLARE_PREV(MAXVAR)
 
-	COUNT_FN(iff_conj);
-	/* first build part of graph below v0.  For this, we build two
-	 * subgraphs:  one for when v0 is true, and one for false.
-	 * These are called thens and elses.
+    MR_ROBDD_COUNT_FN(iff_conj);
+    /*
+    ** first build part of graph below v0. For this, we build two subgraphs:
+    ** MR_ROBDD_one for when v0 is true, and MR_ROBDD_one for false.
+    ** These are called thens and elses.
 	 */
 
 	for (ptr=&arr[n-1]; ptr>=arr && v0<(vi=*ptr); --ptr) {
-	    HANDLE_DUP(vi, <)
-	    thens = make_node(vi, thens, zero);
-	    elses = make_node(vi, elses, one);
+        MR_ROBDD_HANDLE_DUP(vi, <)
+        thens = MR_ROBDD_make_node(vi, thens, MR_ROBDD_zero);
+        elses = MR_ROBDD_make_node(vi, elses, MR_ROBDD_one);
 	}
 
-	if (v0 == vi) --ptr;
+    if (v0 == vi) {
+        --ptr;
+    }
 
-	/* make v0 node */
-	thens = make_node(v0,thens,elses);
+    /* make v0 MR_ROBDD_node */
+    thens = MR_ROBDD_make_node(v0,thens,elses);
 
 	/* Finally build part of graph above v0.  For this, we build
-	 * only one graph, whose then branch is the graph we've built
+     * only MR_ROBDD_one graph, whose then branch is the graph we've built
 	 * so far and whose else branch is ~v0.
 	 */
 
 	if (ptr >= arr) {
-	    DECLARE_PREV(MAXVAR)
+        MR_ROBDD_DECLARE_PREV(MAXVAR)
 	    /* make ~v0 */
-	    elses = make_node(v0,zero,one);
+        elses = MR_ROBDD_make_node(v0,MR_ROBDD_zero,MR_ROBDD_one);
 
 	    do {
 		vi = *ptr;
-		HANDLE_DUP(vi, <)
-		thens = make_node(vi, thens, elses);
+            MR_ROBDD_HANDLE_DUP(vi, <)
+            thens = MR_ROBDD_make_node(vi, thens, elses);
 	    } while (--ptr >= arr);
 	}
 
 	return thens;
-    }
-#endif /* OLD */
+}
+#endif /* MR_ROBDD_OLD */
 
+MR_ROBDD_node *MR_ROBDD_restricted_iff_conj_array(int v0, int n, int arr[],
+    int thresh)
+{
+    if (v0 > thresh) {
+        return MR_ROBDD_one;
+    }
+    while (--n>=0 && arr[n]>thresh)
+        ;
+    return MR_ROBDD_iff_conj_array(v0, n+1, arr);
+}
 
-node *restricted_iff_conj_array(int v0, int n, int arr[], int thresh)
-    {
-	if (v0 > thresh) return one;
-	while (--n>=0 && arr[n]>thresh);
-	return iff_conj_array(v0, n+1, arr);
-    }
+#if !defined(MR_ROBDD_USE_THRESH) && !defined(MR_ROBDD_RESTRICT_SET)
+MR_ROBDD_node *MR_ROBDD_abstract_unify(MR_ROBDD_node *f, int v0, int n,
+    int arr[], int lo, int hi)
+{
+    return MR_ROBDD_restricted_glb(lo, hi, f,
+        MR_ROBDD_iff_conj_array(v0, n, arr));
+}
 
+#elif 1 /* ( MR_ROBDD_USE_THRESH || MR_ROBDD_RESTRICT_SET ) */
 
+MR_ROBDD_node *MR_ROBDD_abstract_unify(MR_ROBDD_node *f, int v0, int n,
+    int arr[], int thresh)
+{
+    return MR_ROBDD_restricted_glb(thresh, f,
+        MR_ROBDD_iff_conj_array(v0, n, arr));
+}
 
-#if !defined(USE_THRESH) && !defined(RESTRICT_SET)
-node *abstract_unify(node *f, int v0, int n, int arr[], int lo, int hi)
-    {
-	return restricted_glb(lo, hi, f, iff_conj_array(v0, n, arr));
-    }
-#elif 1 /* ( USE_THRESH || RESTRICT_SET ) */
-node *abstract_unify(node *f, int v0, int n, int arr[], int thresh)
-    {
-	return restricted_glb(thresh, f, iff_conj_array(v0, n, arr));
-    }
 #else /* !1 (this code is unused) */
 
-
-static node *build_and(int n, int arr[], node *tr, node *fa)
-    {
+static MR_ROBDD_node *
+MR_ROBDD_build_and(int n, int arr[], MR_ROBDD_node *tr, MR_ROBDD_node *fa)
+{
 	if (n<=0) {
 	    return tr;
 	} else {
-	    return make_node(arr[0],
-			     build_and(n-1, &arr[1], tr, fa),
-			     fa);
+        return MR_ROBDD_make_node(arr[0],
+                 MR_ROBDD_build_and(n-1, &arr[1], tr, fa), fa);
 	}
-    }
-
+}
 
-static node *glb_and(node *f, int n, int arr[])
-    {
-	if (f == zero) {
-	    return zero;
-	} else if (f == one) {
-	    return build_and(n, arr, one, zero);
+static MR_ROBDD_node *MR_ROBDD_glb_and(MR_ROBDD_node *f, int n, int arr[])
+{
+    if (f == MR_ROBDD_zero) {
+        return MR_ROBDD_zero;
+    } else if (f == MR_ROBDD_one) {
+        return MR_ROBDD_build_and(n, arr, MR_ROBDD_one, MR_ROBDD_zero);
 	} else if (n == 0) {
 	    return f;
 	} else {
-	    node *result;
+        MR_ROBDD_node *result;
 	    if (f->value < arr[0]) {
-		result = make_node(f->value,
-				   glb_and(f->tr, n, arr),
-				   glb_and(f->fa, n, arr));
+            result = MR_ROBDD_make_node(f->value,
+                   MR_ROBDD_glb_and(f->tr, n, arr),
+                   MR_ROBDD_glb_and(f->fa, n, arr));
 	    } else if (f->value > arr[0]) {
-		result = make_node(arr[0],
-				   glb_and(f, n-1, &arr[1]),
-				   zero);
+            result = MR_ROBDD_make_node(arr[0],
+                   MR_ROBDD_glb_and(f, n-1, &arr[1]),
+                   MR_ROBDD_zero);
 	    } else /* f->value == arr[0] */{
-		result = make_node(f->value,
-				   glb_and(f->tr, n-1, &arr[1]),
-				   zero);
+            result = MR_ROBDD_make_node(f->value,
+                   MR_ROBDD_glb_and(f->tr, n-1, &arr[1]),
+                   MR_ROBDD_zero);
 	    }
 	    return result;
 	}
-    }
-
+}
 
-static node *glb_nand(node *f, int n, int arr[])
-    {
-	if (f == zero) {
-	    return zero;
-	} else if (f == one) {
-	    return build_and(n, arr, zero, one);
+static MR_ROBDD_node *
+MR_ROBDD_glb_nand(MR_ROBDD_node *f, int n, int arr[])
+{
+    if (f == MR_ROBDD_zero) {
+        return MR_ROBDD_zero;
+    } else if (f == MR_ROBDD_one) {
+        return MR_ROBDD_build_and(n, arr, MR_ROBDD_zero, MR_ROBDD_one);
 	} else if (n == 0) {
-	    return zero;
+        return MR_ROBDD_zero;
 	} else {
-	    node *result;
+        MR_ROBDD_node *result;
 	    if (f->value < arr[0]) {
-		result = make_node(f->value,
-				   glb_nand(f->tr, n, arr),
-				   glb_nand(f->fa, n, arr));
+            result = MR_ROBDD_make_node(f->value,
+                   MR_ROBDD_glb_nand(f->tr, n, arr),
+                   MR_ROBDD_glb_nand(f->fa, n, arr));
 	    } else if (f->value > arr[0]) {
-		result = make_node(arr[0],
-				   glb_nand(f, n-1, &arr[1]),
+            result = MR_ROBDD_make_node(arr[0],
+                   MR_ROBDD_glb_nand(f, n-1, &arr[1]),
 				   f);
 	    } else /* f->value == arr[0] */{
-		result = make_node(f->value,
-				   glb_nand(f->tr, n-1, &arr[1]),
+            result = MR_ROBDD_make_node(f->value,
+                   MR_ROBDD_glb_nand(f->tr, n-1, &arr[1]),
 				   f);
 	    }
 	    return result;
 	}
-    }
-
+}
 
-/* returns zero != glb(f, build_and(n, arr, one, zero)) */
-static int exists_glb_and(node *f, int n, int arr[])
-    {
-	if (f == zero) {
-	    return FALSE;
-	} else if (f == one || n == 0) {
-	    return TRUE;
+/*
+** returns MR_ROBDD_zero != MR_ROBDD_glb(f,
+**  MR_ROBDD_build_and(n, arr, MR_ROBDD_one, MR_ROBDD_zero))
+*/
+
+static int
+MR_ROBDD_exists_glb_and(MR_ROBDD_node *f, int n, int arr[])
+{
+    if (f == MR_ROBDD_zero) {
+        return MR_FALSE;
+    } else if (f == MR_ROBDD_one || n == 0) {
+        return MR_TRUE;
 	} else if (f->value < arr[0]) {
-	    return (exists_glb_and(f->tr, n, arr) ||
-		    exists_glb_and(f->fa, n, arr));
+        return (MR_ROBDD_exists_glb_and(f->tr, n, arr) ||
+            MR_ROBDD_exists_glb_and(f->fa, n, arr));
 	} else {
 	    if (f->value == arr[0]) {
 		f = f->tr;
 	    }
-	    return exists_glb_and(f, n-1, arr+1);
+        return MR_ROBDD_exists_glb_and(f, n-1, arr+1);
 	}
-    }
-
+}
 
-/* returns zero != glb(f, build_and(n, arr, zero, one)) */
-static int exists_glb_nand(node *f, int n, int arr[])
-    {
-	if (f == zero || n == 0) {
-	    return FALSE;
-	} else if (f == one || f->value > arr[0]) {
-	    /* if f->value > arr[0], then the else branch of the node we'd
-	     * build would be one, so we know the graph couldn't == zero.
+/*
+** returns MR_ROBDD_zero != MR_ROBDD_glb(f,
+**  MR_ROBDD_build_and(n, arr, MR_ROBDD_zero, MR_ROBDD_one))
+*/
+
+static int
+MR_ROBDD_exists_glb_nand(MR_ROBDD_node *f, int n, int arr[])
+{
+    if (f == MR_ROBDD_zero || n == 0) {
+        return MR_FALSE;
+    } else if (f == MR_ROBDD_one || f->value > arr[0]) {
+        /*
+        ** if f->value > arr[0], then the else branch of the MR_ROBDD_node we'd
+        ** build would be MR_ROBDD_one, so we know the graph couldn't ==
+        ** MR_ROBDD_zero.
 	     */
-	    return TRUE;
+        return MR_TRUE;
 	} else if (f->value < arr[0]) {
-	    return glb_nand(f->tr, n, arr) || glb_nand(f->fa, n, arr);
-	} else if (f->fa != zero) /* && f->value == arr[0] */ {
-	    /* if f->fa isn't zero, then conjoined with one it won't be zero,
-	     * so the node we'd build won't == zero.
-	     */
-	    return TRUE;
-	} else /* f->value == arr[0] && f->fa == zero */ {
-	    return exists_glb_nand(f->tr, n-1, arr+1);
+        return MR_ROBDD_glb_nand(f->tr, n, arr)
+            || MR_ROBDD_glb_nand(f->fa, n, arr);
+    } else if (f->fa != MR_ROBDD_zero) /* && f->value == arr[0] */ {
+        /*
+        ** if f->fa isn't MR_ROBDD_zero, then conjoined with MR_ROBDD_one
+        ** it won't be MR_ROBDD_zero, so the MR_ROBDD_node we'd build won't
+        ** == MR_ROBDD_zero.
+        */
+        return MR_TRUE;
+    } else /* f->value == arr[0] && f->fa == MR_ROBDD_zero */ {
+        return MR_ROBDD_exists_glb_nand(f->tr, n-1, arr+1);
 	}
-    }
-
+}
 
-/* returns zero != glb(f, iff_conj_array(v0, n, arr)) */
-static int exists_glb_iffconj(node *f, int v0, int n, int arr[])
-    {
-	if (f == zero) {
-	    return FALSE;
-	} else if (f == one) {
-	    return TRUE;
+/*
+** returns MR_ROBDD_zero != MR_ROBDD_glb(f,
+**  MR_ROBDD_iff_conj_array(v0, n, arr))
+*/
+
+static int
+MR_ROBDD_exists_glb_iffconj(MR_ROBDD_node *f, int v0, int n, int arr[])
+{
+    if (f == MR_ROBDD_zero) {
+        return MR_FALSE;
+    } else if (f == MR_ROBDD_one) {
+        return MR_TRUE;
 	} else {
 	    int v = (n>0 && arr[0]<v0) ? arr[0] : v0;
 	    
 	    if (f->value < v) {
-		return (exists_glb_iffconj(f->tr, v0, n, arr) ||
-			exists_glb_iffconj(f->fa, v0, n, arr));
+            return (MR_ROBDD_exists_glb_iffconj(f->tr, v0, n, arr) ||
+                MR_ROBDD_exists_glb_iffconj(f->fa, v0, n, arr));
 	    } else /* f->value >= v */ {
-		node *tr, *fa;
+            MR_ROBDD_node *tr, *fa;
 
 		if (f->value == v) {
 		    tr = f->tr; fa = f->fa;
@@ -2187,38 +2526,41 @@
 		}
 
 		if (v == v0) {
-		    return (exists_glb_nand(fa, n, arr) ||
-			    exists_glb_and(tr, n, arr));
+                return (MR_ROBDD_exists_glb_nand(fa, n, arr) ||
+                    MR_ROBDD_exists_glb_and(tr, n, arr));
 		} else {
-		    return (!var_entailed(fa, v0) ||
-			    exists_glb_iffconj(tr, v0, n-1, &arr[1]));
+                return (!MR_ROBDD_var_entailed(fa, v0) ||
+                    MR_ROBDD_exists_glb_iffconj(tr, v0, n-1, &arr[1]));
 		}
 	    }
 	}
-    }
-
-
+}
 
-/* returns restricted_glb(f, build_and(n, arr, one, zero), thresh) */
-static node *rglb_and(node *f, int n, int arr[], int thresh)
-    {
-	if (f == zero) {
-	    return zero;
-	} else if (f == one) {
+/*
+** returns MR_ROBDD_restricted_glb(f,
+**  MR_ROBDD_build_and(n, arr, MR_ROBDD_one, MR_ROBDD_zero), thresh)
+*/
+
+static MR_ROBDD_node *
+MR_ROBDD_rglb_and(MR_ROBDD_node *f, int n, int arr[], int thresh)
+{
+    if (f == MR_ROBDD_zero) {
+        return MR_ROBDD_zero;
+    } else if (f == MR_ROBDD_one) {
 	    while (--n>=0 && arr[n]>thresh);
-	    return build_and(n+1, arr, one, zero);
+        return MR_ROBDD_build_and(n+1, arr, MR_ROBDD_one, MR_ROBDD_zero);
 	} else if (n == 0) {
-	    return restrictThresh(thresh, f);
+        return MR_ROBDD_restrictThresh(thresh, f);
 	} else {
 	    if (f->value < arr[0]) {
 		if (f->value > thresh) {
-		    return
-		      (exists_glb_and(f->tr, n, arr) ||
-		       exists_glb_and(f->fa, n, arr)) ? one : zero;
-		} else {
-		    return make_node(f->value,
-				       rglb_and(f->tr, n, arr, thresh),
-				       rglb_and(f->fa, n, arr, thresh));
+                return (MR_ROBDD_exists_glb_and(f->tr, n, arr) ||
+                        MR_ROBDD_exists_glb_and(f->fa, n, arr))
+                            ? MR_ROBDD_one : MR_ROBDD_zero;
+            } else {
+                return MR_ROBDD_make_node(f->value,
+                           MR_ROBDD_rglb_and(f->tr, n, arr, thresh),
+                           MR_ROBDD_rglb_and(f->fa, n, arr, thresh));
 		}
 	    } else /* arr[0] <= f->value */ {
 		int v = arr[0];
@@ -2227,122 +2569,135 @@
 		    f = f->tr;
 		}
 		if (v > thresh) {
-		    return exists_glb_and(f, n-1, arr+1) ? one : zero;
+                return MR_ROBDD_exists_glb_and(f, n-1, arr+1)
+                    ? MR_ROBDD_one : MR_ROBDD_zero;
 		} else {
-		    return make_node(v,
-				     rglb_and(f, n-1, arr+1, thresh),
-				     zero);
+                return MR_ROBDD_make_node(v,
+                         MR_ROBDD_rglb_and(f, n-1, arr+1, thresh),
+                         MR_ROBDD_zero);
 		}
 	    }
 	}
-    }
-
+}
 
-/* returns restricted_glb(f, build_and(n, arr, zero, one), thresh) */
-static node *rglb_nand(node *f, int n, int arr[], int thresh)
-    {
-	if (f == zero || n == 0) {
-	    return zero;
-	} else if (f == one) {
-	    /* just restrictThresh(thresh, build_and(n, arr, zero, one)).
-	     * Note that if anything is restricted away, then the whole graph
-	     * degenerates to one.  So...
+/*
+** returns MR_ROBDD_restricted_glb(f,
+**  MR_ROBDD_build_and(n, arr, MR_ROBDD_zero, MR_ROBDD_one), thresh)
+*/
+
+static MR_ROBDD_node *
+MR_ROBDD_rglb_nand(MR_ROBDD_node *f, int n, int arr[], int thresh)
+{
+    if (f == MR_ROBDD_zero || n == 0) {
+        return MR_ROBDD_zero;
+    } else if (f == MR_ROBDD_one) {
+        /*
+        ** just MR_ROBDD_restrictThresh(thresh,
+        ** MR_ROBDD_build_and(n, arr, MR_ROBDD_zero, MR_ROBDD_one)).
+        ** Note that if anything is restricted away, then the whole graph
+        ** degenerates to MR_ROBDD_one.  So...
 	     */
 	    if (arr[n-1]>thresh) {
-		return one;
+            return MR_ROBDD_one;
 	    } else {
-		return build_and(n, arr, zero, one);
+            return MR_ROBDD_build_and(n, arr, MR_ROBDD_zero, MR_ROBDD_one);
 	    }
 	} else {
 	    if (f->value < arr[0]) {
 		if (f->value > thresh) {
-		    return (exists_glb_nand(f->tr, n, arr)||
-			    exists_glb_nand(f->fa, n, arr)) ? one : zero;
-		} else {
-		    return make_node(f->value,
-				     rglb_nand(f->tr, n, arr, thresh),
-				     rglb_nand(f->fa, n, arr, thresh));
+                return (MR_ROBDD_exists_glb_nand(f->tr, n, arr)||
+                        MR_ROBDD_exists_glb_nand(f->fa, n, arr))
+                            ? MR_ROBDD_one : MR_ROBDD_zero;
+            } else {
+                return MR_ROBDD_make_node(f->value,
+                         MR_ROBDD_rglb_nand(f->tr, n, arr, thresh),
+                         MR_ROBDD_rglb_nand(f->fa, n, arr, thresh));
 		}
 	    } else if (f->value > arr[0]) {
 		if (arr[0] > thresh) {
-		    /* because f != zero, restricting all vars yields one */
-		    return one;
+                /* because f != MR_ROBDD_zero, restricting all vars yields MR_ROBDD_one */
+                return MR_ROBDD_one;
 		} else {
-		    return make_node(arr[0],
-				     rglb_nand(f, n-1, arr+1, thresh),
-				     restrictThresh(thresh, f));
+                return MR_ROBDD_make_node(arr[0],
+                         MR_ROBDD_rglb_nand(f, n-1, arr+1, thresh),
+                         MR_ROBDD_restrictThresh(thresh, f));
 		}
-	    } else /* f->value == arr[0] */{
+        } else /* f->value == arr[0] */ {
 		if (arr[0] > thresh) {
-		    return (f->fa != zero ||
-			    exists_glb_nand(f->tr, n-1, arr+1)) ? one : zero;
-		} else {
-		    return make_node(arr[0],
-				     rglb_nand(f->tr, n-1, arr+1, thresh),
-				     restrictThresh(thresh, f->fa));
+                return (f->fa != MR_ROBDD_zero ||
+                    MR_ROBDD_exists_glb_nand(f->tr, n-1, arr+1))
+                        ? MR_ROBDD_one : MR_ROBDD_zero;
+            } else {
+                return MR_ROBDD_make_node(arr[0],
+                         MR_ROBDD_rglb_nand(f->tr, n-1, arr+1, thresh),
+                         MR_ROBDD_restrictThresh(thresh, f->fa));
 		}
 	    }
 	}
-    }
-
+}
 
-/* returns restricted_glb(thresh, f, make_node(v, zero, one)) */
-static node *rglb_notvar(node *f, int v, int thresh)
-    {
-	if (f == zero) {
-	    return zero;
-	} else if (f == one) {
-	    if (v > thresh) return one;
-	    return make_node(v, zero, one);
+/*
+** returns MR_ROBDD_restricted_glb(thresh, f,
+**  MR_ROBDD_make_node(v, MR_ROBDD_zero, MR_ROBDD_one))
+*/
+
+static MR_ROBDD_node *
+MR_ROBDD_rglb_notvar(MR_ROBDD_node *f, int v, int thresh)
+{
+    if (f == MR_ROBDD_zero) {
+        return MR_ROBDD_zero;
+    } else if (f == MR_ROBDD_one) {
+        if (v > thresh) return MR_ROBDD_one;
+        return MR_ROBDD_make_node(v, MR_ROBDD_zero, MR_ROBDD_one);
 	} else {
 	    if (f->value < v) {
 		if (f->value > thresh) {
-		    return
-		      (!var_entailed(f->tr, v) ||
-		       !var_entailed(f->fa, v)) ? one : zero;
-		} else {
-		    return make_node(f->value,
-				     rglb_notvar(f->tr, v, thresh),
-				     rglb_notvar(f->fa, v, thresh));
+                return (!MR_ROBDD_var_entailed(f->tr, v) ||
+                       !MR_ROBDD_var_entailed(f->fa, v))
+                            ? MR_ROBDD_one : MR_ROBDD_zero;
+            } else {
+                return MR_ROBDD_make_node(f->value,
+                         MR_ROBDD_rglb_notvar(f->tr, v, thresh),
+                         MR_ROBDD_rglb_notvar(f->fa, v, thresh));
 		}
 	    } else {
 		if (f->value == v) {
 		    f = f->fa;
 		}
 		if (v > thresh) {
-		    return f==zero ? zero : one;
+                return f==MR_ROBDD_zero ? MR_ROBDD_zero : MR_ROBDD_one;
 		} else {
-		    return make_node(v, zero, restrictThresh(thresh, f));
+                return MR_ROBDD_make_node(v, MR_ROBDD_zero,
+                    MR_ROBDD_restrictThresh(thresh, f));
 		}
 	    }
 	}
-    }
-
-
+}
 
-node *abstract_unify(node *f, int v0, int n, int arr[], int thresh)
-    {
-	if (f == zero) {
-	    return zero;
-	} else if (f == one) {
-	    return restricted_iff_conj_array(v0, n, arr, thresh);
+MR_ROBDD_node *
+MR_ROBDD_abstract_unify(MR_ROBDD_node *f, int v0, int n, int arr[], int thresh)
+{
+    if (f == MR_ROBDD_zero) {
+        return MR_ROBDD_zero;
+    } else if (f == MR_ROBDD_one) {
+        return MR_ROBDD_restricted_iff_conj_array(v0, n, arr, thresh);
 	} else {
 	    int v = (n>0 && arr[0]<v0) ? arr[0] : v0;
-	    node *result;
+        MR_ROBDD_node *result;
 	    
 	    if (f->value < v) {
 		if (f->value > thresh) {
-		    result =
-		      (exists_glb_iffconj(f->tr, v0, n, arr) ||
-		       exists_glb_iffconj(f->fa, v0, n, arr)) ? one : zero;
+                result = (MR_ROBDD_exists_glb_iffconj(f->tr, v0, n, arr) ||
+                        MR_ROBDD_exists_glb_iffconj(f->fa, v0, n, arr))
+                            ? MR_ROBDD_one : MR_ROBDD_zero;
 		} else {
 		    result =
-		      make_node(f->value,
-				abstract_unify(f->tr, v0, n, arr, thresh),
-				abstract_unify(f->fa, v0, n, arr, thresh));
+                  MR_ROBDD_make_node(f->value,
+                    MR_ROBDD_abstract_unify(f->tr, v0, n, arr, thresh),
+                    MR_ROBDD_abstract_unify(f->fa, v0, n, arr, thresh));
 		}
 	    } else /* f->value >= v */ {
-		node *tr = f, *fa = f;
+            MR_ROBDD_node *tr = f, *fa = f;
 
 		if (f->value == v) {
 		    tr = f->tr; fa = f->fa;
@@ -2351,463 +2706,552 @@
 		    int value;
 
 		    if (v == v0) {
-			value = (exists_glb_nand(fa, n, arr) ||
-				 exists_glb_and(tr, n, arr));
+                    value = (MR_ROBDD_exists_glb_nand(fa, n, arr) ||
+                         MR_ROBDD_exists_glb_and(tr, n, arr));
 		    } else {
 			value =
-			  (!var_entailed(fa, v0) ||
-			   exists_glb_iffconj(tr, v0, n-1, &arr[1]));
+                      (!MR_ROBDD_var_entailed(fa, v0) ||
+                       MR_ROBDD_exists_glb_iffconj(tr, v0, n-1, &arr[1]));
 		    }
-		    result = value ? one : zero;
+                result = value ? MR_ROBDD_one : MR_ROBDD_zero;
 		} else {
 		    if (v == v0) {
-			tr = rglb_and(tr, n, arr, thresh);
-			fa = rglb_nand(fa, n, arr, thresh);
+                    tr = MR_ROBDD_rglb_and(tr, n, arr, thresh);
+                    fa = MR_ROBDD_rglb_nand(fa, n, arr, thresh);
 		    } else {
-			tr = abstract_unify(tr, v0, n-1, arr+1, thresh);
-			fa = rglb_notvar(fa, v0, thresh);
+                    tr = MR_ROBDD_abstract_unify(tr, v0, n-1, arr+1, thresh);
+                    fa = MR_ROBDD_rglb_notvar(fa, v0, thresh);
 		    }
-		    result = make_node(v, tr, fa);
+                result = MR_ROBDD_make_node(v, tr, fa);
 		}
 	    }
 	    return result;
 	}
-    }
+}
 
 #endif /* (end of unused code) */
 
-
-
 /****************************************************************
 
 		      Finding Entailed Variables
 
  ****************************************************************/
 
-/* returns TRUE iff var is implied by the boolean function specified by f */
-int var_entailed(node *f, int var)
-    {
-#if defined(NAIVE)
-	return f == glb(f, variableRep(var));
-#elif !defined(USE_THRESH) && !defined(USE_ITE_CONSTANT)
-	return one == implies(f, variableRep(var));
-#elif !defined(USE_RGLB)
-	return one == ite_constant(f, variableRep(var), one);
-#else /* USE_RGLB */
+/*
+** returns MR_TRUE iff var is implied by the boolean function specified by f
+*/
+
+int
+MR_ROBDD_var_entailed(MR_ROBDD_node *f, int var)
+{
+#if defined(MR_ROBDD_NAIVE)
+    return f == MR_ROBDD_glb(f, MR_ROBDD_variableRep(var));
+#elif !defined(MR_ROBDD_USE_THRESH) && !defined(MR_ROBDD_USE_ITE_CONSTANT)
+    return MR_ROBDD_one == MR_ROBDD_implies(f, MR_ROBDD_variableRep(var));
+#elif !defined(MR_ROBDD_USE_RGLB)
+    return MR_ROBDD_one == MR_ROBDD_ite_constant(f, MR_ROBDD_variableRep(var),
+        MR_ROBDD_one);
+#else /* MR_ROBDD_USE_RGLB */
 	if (IS_TERMINAL(f)) {
-	    return f==zero;
+        return f==MR_ROBDD_zero;
 	} else {
-	    DECLARE_VAR_ENTAILED_CACHE_ENTRY
+        MR_ROBDD_DECLARE_VAR_ENTAILED_CACHE_ENTRY
 	    int result;
 
-	    TRY_VAR_ENTAILED_CACHE(f, var);
+        MR_ROBDD_TRY_VAR_ENTAILED_CACHE(f, var);
 	    if (f->value < var) {
-		result = var_entailed(f->tr, var)
-		      && var_entailed(f->fa, var);
+            result = MR_ROBDD_var_entailed(f->tr, var)
+                  && MR_ROBDD_var_entailed(f->fa, var);
 	    } else if (f->value == var) {
-		result = (f->fa==zero);
+            result = (f->fa==MR_ROBDD_zero);
 	    } else /* f->value > var */ {
-		result = FALSE;
+            result = MR_FALSE;
 	    }
-	    UPDATE_VAR_ENTAILED_CACHE(f, var, result);
+        MR_ROBDD_UPDATE_VAR_ENTAILED_CACHE(f, var, result);
 	    return result;
 	}
-#endif /* NEW */
-    }
-
-
-/* returns a bitset of all the variables implied by f.  A variable i
- * is implied by f iff
- *
- *	BITSET_IS_MEMBER(*result, i)
- */
+#endif /* MR_ROBDD_NEW */
+}
 
-#if !defined(NEW)
-bitset *vars_entailed(node *f, int topvar)
-    {
-	static bitset def_vars;
+/*
+** returns a MR_ROBDD_bitset of all the variables implied by f.  A variable i
+** is implied by f iff
+**
+**    MR_ROBDD_BITSET_IS_MEMBER(*result, i)
+*/
+
+#if !defined(MR_ROBDD_NEW)
+MR_ROBDD_bitset *
+MR_ROBDD_vars_entailed(MR_ROBDD_node *f, int MR_ROBDD_topvar)
+{
+    static MR_ROBDD_bitset def_vars;
 	int i;
 
-	BITSET_CLEAR(def_vars);
+    MR_ROBDD_BITSET_CLEAR(def_vars);
 
-	for (i=0; i<topvar; ++i) {
-	    if (var_entailed(f, i)) BITSET_ADD_ELEMENT(def_vars,i);
+    for (i=0; i<MR_ROBDD_topvar; ++i) {
+        if (MR_ROBDD_var_entailed(f, i)) {
+            MR_ROBDD_BITSET_ADD_ELEMENT(def_vars,i);
 	}
-	return &def_vars;
     }
+    return &def_vars;
+}
+
 #elif 0	/* not using this version */
-int topvar(node *f, int n)
-    {
+
+int
+MR_ROBDD_topvar(MR_ROBDD_node *f, int n)
+{
 	int n1;
 
 	if (IS_TERMINAL(f)) return n;
 
-	n1 = topvar(f->tr, f->value);
-	if (n1 > n) n = n1;
-	return topvar(f->fa, n);
+    n1 = MR_ROBDD_topvar(f->tr, f->value);
+    if (n1 > n) {
+        n = n1;
     }
+    return MR_ROBDD_topvar(f->fa, n);
+}
 
-bitset *vars_entailed(node *f)
-    {
-	static bitset def_vars;
-	int i = topvar(f, 0);
+MR_ROBDD_bitset *
+MR_ROBDD_vars_entailed(MR_ROBDD_node *f)
+{
+    static MR_ROBDD_bitset def_vars;
+    int i = MR_ROBDD_topvar(f, 0);
 
-	BITSET_CLEAR(def_vars);
+    MR_ROBDD_BITSET_CLEAR(def_vars);
 
 	for (; i >= 0; --i) {
-	    if (var_entailed(f, i)) BITSET_ADD_ELEMENT(def_vars,i);
+        if (MR_ROBDD_var_entailed(f, i)) {
+            MR_ROBDD_BITSET_ADD_ELEMENT(def_vars,i);
 	}
-	return &def_vars;
     }
-#else /* NEW */
-/* According to Roberto Bagnara's benchmarking, this version is slower
- * than the simpler version below.
- */
-#if defined(OLD_VARS_ENTAILED)
+    return &def_vars;
+}
 
-/* these variables should be local to both vars_entailed and
- * vars_entailed_aux, but that isn't possible in C, so I have to make
- * them global.  They should not be use by any other functions.
- */
-static bitset this_path;
-static bitset entailed;
+#else /* MR_ROBDD_NEW */
 
-void vars_entailed_aux(node *f)
-    {
+/*
+** According to Roberto Bagnara's benchmarking, this version is slower
+** than the simpler version below.
+*/
+
+#if defined(OLD_VARS_ENTAILED)
+
+/*
+** these variables should be local to both MR_ROBDD_vars_entailed and
+** MR_ROBDD_vars_entailed_aux, but that isn't possible in C, so I have to make
+** them global.  They should not be use by any other functions.
+*/
+
+static MR_ROBDD_bitset MR_ROBDD_this_path;
+static MR_ROBDD_bitset MR_ROBDD_entailed;
+
+void
+MR_ROBDD_vars_entailed_aux(MR_ROBDD_node *f)
+{
 	while (!IS_TERMINAL(f)) {
-	    int word = BITSET_WORD(f->value);
-	    bitmask mask = BITSET_MASK(f->value);
+        int word = MR_ROBDD_BITSET_WORD(f->value);
+        MR_ROBDD_bitmask mask = MR_ROBDD_BITSET_MASK(f->value);
 	    
 	    /* turn on bit for then branch */
-	    BITSET_ADD(this_path,word,mask);
-	    vars_entailed_aux(f->tr);
+        MR_ROBDD_BITSET_ADD(MR_ROBDD_this_path,word,mask);
+        MR_ROBDD_vars_entailed_aux(f->tr);
 	    /* turn it off for the else branch */
-	    BITSET_TOGGLE(this_path,word,mask);
+        MR_ROBDD_BITSET_TOGGLE(MR_ROBDD_this_path,word,mask);
 	    f = f->fa;
 	}
 	/* needn't do anything for false terminals */
-	if (f == one) {
-	    BITSET_INTERSECTION(entailed, entailed, this_path);
-	}
+    if (f == MR_ROBDD_one) {
+        MR_ROBDD_BITSET_INTERSECTION(MR_ROBDD_entailed, MR_ROBDD_entailed,
+            MR_ROBDD_this_path);
     }
+}
 
+/*
+** returns a MR_ROBDD_bitset of all the variables implied by f.  A variable i
+** is implied by f iff
+**
+**    MR_ROBDD_BITSET_IS_MEMBER(*result, i)
+*/
+
+MR_ROBDD_bitset *
+MR_ROBDD_vars_entailed(MR_ROBDD_node *f)
+{
+    MR_ROBDD_BITSET_CLEAR(MR_ROBDD_this_path);
+    BITSET_UNIVERSE(MR_ROBDD_entailed);
 
-/* returns a bitset of all the variables implied by f.  A variable i
- * is implied by f iff
- *
- *	BITSET_IS_MEMBER(*result, i)
- */
-bitset *vars_entailed(node *f)
-    {
-
-	BITSET_CLEAR(this_path);
-	BITSET_UNIVERSE(entailed);
+    MR_ROBDD_vars_entailed_aux(f);
+    return &MR_ROBDD_entailed;
+}
 
-	vars_entailed_aux(f);
-	return &entailed;
-    }
-#else /* NEW && !OLD_VARS_ENTAILED */
-/* returns a bitset of all the variables implied by f.  A variable i
- * is implied by f iff
- *
- *	BITSET_IS_MEMBER(*result, i)
- */
+#else /* MR_ROBDD_NEW && !OLD_VARS_ENTAILED */
 
-bitset *vars_entailed(node *f)
-    {
-	static bitset tmp_bitset;
-	DECLARE_UNARY_BITSET_CACHE_ENTRY
+/*
+** returns a MR_ROBDD_bitset of all the variables implied by f.  A variable i
+** is implied by f iff
+**
+**    MR_ROBDD_BITSET_IS_MEMBER(*result, i)
+*/
+
+MR_ROBDD_bitset *
+MR_ROBDD_vars_entailed(MR_ROBDD_node *f)
+{
+    static MR_ROBDD_bitset tmp_bitset;
+    MR_ROBDD_DECLARE_UNARY_BITSET_CACHE_ENTRY
 
-	if (f == zero) {
+    if (f == MR_ROBDD_zero) {
 	    BITSET_UNIVERSE(tmp_bitset);
-	} else if (f == one) {
-	    BITSET_CLEAR(tmp_bitset);
+    } else if (f == MR_ROBDD_one) {
+        MR_ROBDD_BITSET_CLEAR(tmp_bitset);
 	} else {
-	    bitset bs;
+        MR_ROBDD_bitset bs;
 
-	    TRY_UNARY_BITSET_CACHE(f, vars_entailed);
-	    tmp_bitset = *vars_entailed(f->tr);
-	    bs = *vars_entailed(f->fa);
-	    BITSET_INTERSECTION(tmp_bitset, tmp_bitset, bs);
-	    if (f->fa == zero) BITSET_ADD_ELEMENT(tmp_bitset, f->value);
-	    UPDATE_UNARY_BITSET_CACHE(f, tmp_bitset, vars_entailed);
+        MR_ROBDD_TRY_UNARY_BITSET_CACHE(f, MR_ROBDD_vars_entailed);
+        tmp_bitset = *MR_ROBDD_vars_entailed(f->tr);
+        bs = *MR_ROBDD_vars_entailed(f->fa);
+        MR_ROBDD_BITSET_INTERSECTION(tmp_bitset, tmp_bitset, bs);
+        if (f->fa == MR_ROBDD_zero) {
+            MR_ROBDD_BITSET_ADD_ELEMENT(tmp_bitset, f->value);
 	}
-	return &tmp_bitset;
+        MR_ROBDD_UPDATE_UNARY_BITSET_CACHE(f, tmp_bitset,
+            MR_ROBDD_vars_entailed);
     }
-#endif /* NEW && !OLD_VARS_ENTAILED */
-#endif /* NEW */
-
+    return &tmp_bitset;
+}
 
+#endif /* MR_ROBDD_NEW && !OLD_VARS_ENTAILED */
+#endif /* MR_ROBDD_NEW */
 
 /****************************************************************
 
 			Set Sharing Operations
 
  ****************************************************************/
-#if defined(SHARING)
+#if defined(MR_ROBDD_SHARING)
 
-/* returns the Boolean function
- *	~1&~2&...~n | 1&~2&...~n | ~1&2&...~n | ~1&~2&...n
- */
-node *init_set_sharing(int n)
-    {
-	node *result = one;
-	node *other = one;
+/*
+** returns the Boolean function
+**    ~1&~2&...~n | 1&~2&...~n | ~1&2&...~n | ~1&~2&...n
+*/
+
+MR_ROBDD_node *
+MR_ROBDD_init_set_sharing(int n)
+{
+    MR_ROBDD_node *result = MR_ROBDD_one;
+    MR_ROBDD_node *other = MR_ROBDD_one;
 
 	while (n>1) {
-	    other = make_node(n, zero, other);
-	    result = make_node(--n, other, result);
+        other = MR_ROBDD_make_node(n, MR_ROBDD_zero, other);
+        result = MR_ROBDD_make_node(--n, other, result);
 	}
 
 	return result;
-    }
+}
 
+#if defined(MR_ROBDD_NEW)
 
-#if defined(NEW)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_complete_one_or)
 
-DECLARE_FN_COUNT(complete_one_or)
+/* the same as MR_ROBDD_lub(MR_ROBDD_complete_one(f), prev) */
+MR_ROBDD_node *
+MR_ROBDD_complete_one_or(MR_ROBDD_node *f, MR_ROBDD_node *prev)
+{
+    MR_ROBDD_node *result;
+    MR_ROBDD_node *MR_ROBDD_complete_one(MR_ROBDD_node *f);
+    MR_ROBDD_DECLARE_ASYM_BIN_CACHE_ENTRY
 
-/* the same as lub(complete_one(f), prev) */
-node *complete_one_or(node *f, node *prev)
-    {
-	node *result;
-	node *complete_one(node *f);
-	DECLARE_ASYM_BIN_CACHE_ENTRY
-
-	COUNT_FN(complete_one_or);
-
-	if (IS_TERMINAL(prev)) return (prev==one) ? one : complete_one(f);
-	if (IS_TERMINAL(f)) return (f==one) ? one : prev;
-
-	TRY_ASYM_BIN_CACHE(f, prev, complete_one_or);
-
-	/* we want to return:
-	 *     lub(make_node(f->value, lub(complete_one(f->tr),
-	 *				   complete_one(f->fa)),
-	 *		     complete_one(f->fa)),
-	 *	   prev);
-	 * but we want to unfold the outer lub call, so we compare
-	 * prev->value and f->value.  Actually, this isn't right when
-	 * f->value <= prev->value, because the make_node call may return
-	 * a node whose label is > prev->value, but in that case,
-	 *    lub(that, prev) = make_node(prev->value, lub(that, prev->tr),
-	 *				  lub(that, prev->fa))
+    MR_ROBDD_COUNT_FN(MR_ROBDD_complete_one_or);
+
+    if (IS_TERMINAL(prev)) {
+        return (prev==MR_ROBDD_one) ? MR_ROBDD_one : MR_ROBDD_complete_one(f);
+    }
+    if (IS_TERMINAL(f)) {
+        return (f==MR_ROBDD_one) ? MR_ROBDD_one : prev;
+    }
+
+    MR_ROBDD_TRY_ASYM_BIN_CACHE(f, prev, MR_ROBDD_complete_one_or);
+
+    /*
+    ** we want to return:
+    **     MR_ROBDD_lub(MR_ROBDD_make_node(f->value,
+    **          MR_ROBDD_lub(MR_ROBDD_complete_one(f->tr),
+    **                  MR_ROBDD_complete_one(f->fa)),
+    **                  MR_ROBDD_complete_one(f->fa)),
+    **          prev);
+    ** but we want to unfold the outer MR_ROBDD_lub call, so we compare
+    ** prev->value and f->value.  Actually, this isn't right when
+    ** f->value <= prev->value, because the MR_ROBDD_make_node call may return
+    ** a MR_ROBDD_node whose label is > prev->value, but in that case,
+    **    MR_ROBDD_lub(that, prev) = MR_ROBDD_make_node(prev->value,
+    **              MR_ROBDD_lub(that, prev->tr), MR_ROBDD_lub(that, prev->fa))
 	 */
 
 	if (f->value < prev->value) {
-	    node *cfa = complete_one_or(f->fa, prev);
-	    result = make_node(f->value, complete_one_or(f->tr, cfa), cfa);
+        MR_ROBDD_node *cfa = MR_ROBDD_complete_one_or(f->fa, prev);
+        result = MR_ROBDD_make_node(f->value,
+            MR_ROBDD_complete_one_or(f->tr, cfa), cfa);
 	} else if (f->value == prev->value) {
-	    result = make_node(f->value,
-			       complete_one_or(f->tr,
-					       complete_one_or(f->fa,
+        result = MR_ROBDD_make_node(f->value,
+                   MR_ROBDD_complete_one_or(f->tr,
+                           MR_ROBDD_complete_one_or(f->fa,
 							       prev->tr)),
-			       complete_one_or(f->fa, prev->fa));
+                   MR_ROBDD_complete_one_or(f->fa, prev->fa));
 	} else {
-	    result = make_node(prev->value,
-			       complete_one_or(f, prev->tr),
-			       complete_one_or(f, prev->fa));
+        result = MR_ROBDD_make_node(prev->value,
+                   MR_ROBDD_complete_one_or(f, prev->tr),
+                   MR_ROBDD_complete_one_or(f, prev->fa));
 	}
-	UPDATE_ASYM_BIN_CACHE(f, prev, result, complete_one_or);
+    MR_ROBDD_UPDATE_ASYM_BIN_CACHE(f, prev, result, MR_ROBDD_complete_one_or);
 	return result;
-    }
-
+}
 
-DECLARE_FN_COUNT(complete_one)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_complete_one)
 
-node *complete_one(node *f)
-    {
-	node *result, *cfa;
-	DECLARE_UNARY_CACHE_ENTRY
+MR_ROBDD_node *
+MR_ROBDD_complete_one(MR_ROBDD_node *f)
+{
+    MR_ROBDD_node *result, *cfa;
+    MR_ROBDD_DECLARE_UNARY_CACHE_ENTRY
 
-	COUNT_FN(complete_one);
+    MR_ROBDD_COUNT_FN(MR_ROBDD_complete_one);
 
-	if (IS_TERMINAL(f)) return f;
-	TRY_UNARY_CACHE(f, complete_one);
-	cfa = complete_one(f->fa);
-	result = make_node(f->value, complete_one_or(f->tr, cfa), cfa);
-	UPDATE_UNARY_CACHE(f, result, complete_one);
-	return result;
+    if (IS_TERMINAL(f)) {
+        return f;
     }
+    MR_ROBDD_TRY_UNARY_CACHE(f, MR_ROBDD_complete_one);
+    cfa = MR_ROBDD_complete_one(f->fa);
+    result = MR_ROBDD_make_node(f->value,
+        MR_ROBDD_complete_one_or(f->tr, cfa), cfa);
+    MR_ROBDD_UPDATE_UNARY_CACHE(f, result, MR_ROBDD_complete_one);
+    return result;
+}
 
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_complete_or)
 
-DECLARE_FN_COUNT(complete_or)
-
-/* the same as lub(complete(f, g), prev) */
-node *complete_or(node *f, node *g, node *prev)
-    {
-	node *result;
-	node *lo, *hi;
-	DECLARE_COMPLETE_OR_CACHE_ENTRY
+/* the same as MR_ROBDD_lub(MR_ROBDD_complete(f, g), prev) */
+MR_ROBDD_node *
+MR_ROBDD_complete_or(MR_ROBDD_node *f, MR_ROBDD_node *g, MR_ROBDD_node *prev)
+{
+    MR_ROBDD_node *result;
+    MR_ROBDD_node *lo, *hi;
+    MR_ROBDD_DECLARE_COMPLETE_OR_CACHE_ENTRY
 
-	COUNT_FN(complete_or);
+    MR_ROBDD_COUNT_FN(MR_ROBDD_complete_or);
 
-	if (prev == one) return one;
-	if (f == g) return lub(f, prev);
-	if (f == zero || g == zero) return prev;
+    if (prev == MR_ROBDD_one) {
+        return MR_ROBDD_one;
+    }
+    if (f == g) {
+        return MR_ROBDD_lub(f, prev);
+    }
+    if (f == MR_ROBDD_zero || g == MR_ROBDD_zero) {
+        return prev;
+    }
 
-	if (f == one) return complete_one_or(g, prev);
-	if (g == one) return complete_one_or(f, prev);
-	if (prev == zero) return complete(f, g);
+    if (f == MR_ROBDD_one) {
+        return MR_ROBDD_complete_one_or(g, prev);
+    }
+    if (g == MR_ROBDD_one) {
+        return MR_ROBDD_complete_one_or(f, prev);
+    }
+    if (prev == MR_ROBDD_zero) {
+        return MR_ROBDD_complete(f, g);
+    }
 
-	TRY_COMPLETE_OR_CACHE(f, g, prev);
+    MR_ROBDD_TRY_COMPLETE_OR_CACHE(f, g, prev);
 
-	if (f->value > g->value) lo=g, hi=f; else lo=f, hi=g;
+    if (f->value > g->value) {
+        lo=g;
+        hi=f;
+    } else {
+        lo=f;
+        hi=g;
+    }
 
 	if (prev->value < lo->value) {
-	    result = make_node(prev->value,
-			       complete_or(lo, hi, prev->tr),
-			       complete_or(lo, hi, prev->fa));
+        result = MR_ROBDD_make_node(prev->value,
+                   MR_ROBDD_complete_or(lo, hi, prev->tr),
+                   MR_ROBDD_complete_or(lo, hi, prev->fa));
 	} else if (prev->value == lo->value) {
 	    if (lo->value == hi->value) {
-		node *n = complete_or(lo->tr, hi->tr, prev->tr);
-		n = complete_or(lo->tr, hi->fa, n);
-		n = complete_or(lo->fa, hi->tr, n);
-		result = make_node(lo->value, n,
-				   complete_or(lo->fa, hi->fa, prev->fa));
-	    } else {
-		node *n = complete_or(lo->fa, hi, prev->tr);
-		n = complete_or(lo->tr, hi, n);
-		result = make_node(lo->value, n,
-				   complete_or(lo->fa, hi, prev->fa));
+            MR_ROBDD_node *n = MR_ROBDD_complete_or(lo->tr, hi->tr, prev->tr);
+            n = MR_ROBDD_complete_or(lo->tr, hi->fa, n);
+            n = MR_ROBDD_complete_or(lo->fa, hi->tr, n);
+            result = MR_ROBDD_make_node(lo->value, n,
+                       MR_ROBDD_complete_or(lo->fa, hi->fa, prev->fa));
+        } else {
+            MR_ROBDD_node *n = MR_ROBDD_complete_or(lo->fa, hi, prev->tr);
+            n = MR_ROBDD_complete_or(lo->tr, hi, n);
+            result = MR_ROBDD_make_node(lo->value, n,
+                       MR_ROBDD_complete_or(lo->fa, hi, prev->fa));
 	    }
 	} else if (lo->value == hi->value) {
-	    node *n = complete_or(lo->tr, hi->tr, prev);
-	    n = complete_or(lo->tr, hi->fa, n);
-	    n = complete_or(lo->fa, hi->tr, n);
-	    result = make_node(lo->value, n,
-			       complete_or(lo->fa, hi->fa, prev));
-	} else {
-	    node *n = complete_or(lo->fa, hi, prev);
-	    result = make_node(lo->value, complete_or(lo->tr, hi, n), n);
+        MR_ROBDD_node *n = MR_ROBDD_complete_or(lo->tr, hi->tr, prev);
+        n = MR_ROBDD_complete_or(lo->tr, hi->fa, n);
+        n = MR_ROBDD_complete_or(lo->fa, hi->tr, n);
+        result = MR_ROBDD_make_node(lo->value, n,
+                   MR_ROBDD_complete_or(lo->fa, hi->fa, prev));
+    } else {
+        MR_ROBDD_node *n = MR_ROBDD_complete_or(lo->fa, hi, prev);
+        result = MR_ROBDD_make_node(lo->value,
+            MR_ROBDD_complete_or(lo->tr, hi, n), n);
 	}
-	UPDATE_COMPLETE_OR_CACHE(f, g, prev, result);
+    MR_ROBDD_UPDATE_COMPLETE_OR_CACHE(f, g, prev, result);
 
 	return result;
-    }
-#else /* !NEW */
-#define complete_or(x, y, z) lub(complete((x),(y)),(z))
+}
+
+#else /* !MR_ROBDD_NEW */
+
+#define MR_ROBDD_complete_or(x, y, z) \
+    MR_ROBDD_lub(MR_ROBDD_complete((x),(y)),(z))
 #endif
 
-DECLARE_FN_COUNT(complete)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_complete)
 
-node *complete(node *f, node *g)
-    {
-	node *result;
+MR_ROBDD_node *
+MR_ROBDD_complete(MR_ROBDD_node *f, MR_ROBDD_node *g)
+{
+    MR_ROBDD_node *result;
 	int fvar, gvar;
-	DECLARE_BIN_CACHE_ENTRY
+    MR_ROBDD_DECLARE_BIN_CACHE_ENTRY
 
-	COUNT_FN(complete);
+    MR_ROBDD_COUNT_FN(MR_ROBDD_complete);
 
-	if (f == g) return f;
-	if (f == zero || g == zero) return zero;
+    if (f == g) {
+        return f;
+    }
+    if (f == MR_ROBDD_zero || g == MR_ROBDD_zero) {
+        return MR_ROBDD_zero;
+    }
 
-	TRY_BIN_CACHE(f, g, complete);
+    MR_ROBDD_TRY_BIN_CACHE(f, g, MR_ROBDD_complete);
 
-	fvar = (f == one) ? MAXVAR : f->value;
-	gvar = (g == one) ? MAXVAR : g->value;
+    fvar = (f == MR_ROBDD_one) ? MAXVAR : f->value;
+    gvar = (g == MR_ROBDD_one) ? MAXVAR : g->value;
 	if (fvar == gvar) {
-	    result = make_node(fvar,
-			 complete_or(f->fa, g->tr,
-			     complete_or(f->tr, g->tr,
-				 complete(f->tr,g->fa))),
-			 complete(f->fa,g->fa));
+        result = MR_ROBDD_make_node(fvar,
+             MR_ROBDD_complete_or(f->fa, g->tr,
+                 MR_ROBDD_complete_or(f->tr, g->tr,
+                 MR_ROBDD_complete(f->tr,g->fa))),
+             MR_ROBDD_complete(f->fa,g->fa));
 	} else if (fvar < gvar) {
-	    node *cfa = complete(f->fa, g);
+        MR_ROBDD_node *cfa = MR_ROBDD_complete(f->fa, g);
 
-	    result = make_node(fvar, complete_or(f->tr, g, cfa), cfa);
+        result = MR_ROBDD_make_node(fvar, MR_ROBDD_complete_or(f->tr, g, cfa),
+            cfa);
 	} else /* fvar > gvar */ {
-	    node *cfa = complete(f, g->fa);
+        MR_ROBDD_node *cfa = MR_ROBDD_complete(f, g->fa);
 
-	    result = make_node(gvar, complete_or(f, g->tr, cfa), cfa);
+        result = MR_ROBDD_make_node(gvar, MR_ROBDD_complete_or(f, g->tr, cfa),
+            cfa);
 	}
-	UPDATE_BIN_CACHE(f, g, result, complete);
+    MR_ROBDD_UPDATE_BIN_CACHE(f, g, result, MR_ROBDD_complete);
 	return result;
-    }
+}
 
-DECLARE_FN_COUNT(upclose)
+MR_ROBDD_DECLARE_FN_COUNT(MR_ROBDD_upclose)
 
-node *upclose(node *f)
-    {
-	node *utr, *ufa, *result;
-	DECLARE_UNARY_CACHE_ENTRY
+MR_ROBDD_node *
+MR_ROBDD_upclose(MR_ROBDD_node *f)
+{
+    MR_ROBDD_node *utr, *ufa, *result;
+    MR_ROBDD_DECLARE_UNARY_CACHE_ENTRY
 
-	COUNT_FN(upclose);
+    MR_ROBDD_COUNT_FN(MR_ROBDD_upclose);
 
-	if (IS_TERMINAL(f)) return f;
-	TRY_UNARY_CACHE(f, upclose);
-	utr = upclose(f->tr);
-	ufa = upclose(f->fa);
-	result = make_node(f->value, complete_or(utr, ufa, utr), ufa);
-	UPDATE_UNARY_CACHE(f, result, upclose);
-	return result;
+    if (IS_TERMINAL(f)) {
+        return f;
     }
+    MR_ROBDD_TRY_UNARY_CACHE(f, MR_ROBDD_upclose);
+    utr = MR_ROBDD_upclose(f->tr);
+    ufa = MR_ROBDD_upclose(f->fa);
+    result = MR_ROBDD_make_node(f->value, MR_ROBDD_complete_or(utr, ufa, utr),
+        ufa);
+    MR_ROBDD_UPDATE_UNARY_CACHE(f, result, MR_ROBDD_upclose);
+    return result;
+}
 
 /*
- * bin(f, g)
- *
- * We note that the set of Boolean functions of n variables is
- * isomorphic to the powerset of the set of n variables.  Thus we can
- * use a Boolean function to represent a subset of the powerset.  We
- * choose to let the *absence* of a variable from the set be indicated
- * by that variable being true in the boolean function.
- *
- * This function computes the set of all possible unions of sets from
- * f and g.
- */
-
-node *bin(node *f, node *g)
-    {
-	if (f == zero || g == zero) {
-	    return zero;
-	} else if (f == one) {
-	    return bin_univ(g);
-	} else if (g == one) {
-	    return bin_univ(f);
+** MR_ROBDD_bin(f, g)
+**
+** We note that the set of Boolean functions of n variables is
+** isomorphic to the powerset of the set of n variables.  Thus we can
+** use a Boolean function to represent a subset of the powerset.  We
+** choose to let the *absence* of a variable from the set be indicated
+** by that variable being true in the boolean function.
+**
+** This function computes the set of all possible unions of sets from
+** f and g.
+*/
+
+MR_ROBDD_node *
+MR_ROBDD_bin(MR_ROBDD_node *f, MR_ROBDD_node *g)
+{
+    if (f == MR_ROBDD_zero || g == MR_ROBDD_zero) {
+        return MR_ROBDD_zero;
+    } else if (f == MR_ROBDD_one) {
+        return MR_ROBDD_bin_univ(g);
+    } else if (g == MR_ROBDD_one) {
+        return MR_ROBDD_bin_univ(f);
 	} else {
-	    node *result;
-	    DECLARE_BIN_CACHE_ENTRY
+        MR_ROBDD_node *result;
+        MR_ROBDD_DECLARE_BIN_CACHE_ENTRY
 
-	    TRY_BIN_CACHE(f, g, bin);
+        MR_ROBDD_TRY_BIN_CACHE(f, g, MR_ROBDD_bin);
 
 	    if (f->value == g->value) {
-		node *th = bin(f->tr, g->tr);
-		node *el = bin(f->tr, g->fa);
+            MR_ROBDD_node *th = MR_ROBDD_bin(f->tr, g->tr);
+            MR_ROBDD_node *el = MR_ROBDD_bin(f->tr, g->fa);
 
-		if (el != one) {
-		    el = lub(el, bin(f->fa, g->tr));
-		    if (el != one) {
-			el = lub(el, bin(f->fa, g->fa));
+            if (el != MR_ROBDD_one) {
+                el = MR_ROBDD_lub(el, MR_ROBDD_bin(f->fa, g->tr));
+                if (el != MR_ROBDD_one) {
+                    el = MR_ROBDD_lub(el, MR_ROBDD_bin(f->fa, g->fa));
 		    }
 		}
-		result = make_node(f->value, th, el);
+            result = MR_ROBDD_make_node(f->value, th, el);
 	    } else {
-		node *tmp;
+            MR_ROBDD_node *tmp;
 
-		if (f->value > g->value) { tmp = f; f = g; g = tmp; }
+            if (f->value > g->value) {
+                tmp = f; f = g; g = tmp;
+            }
 		/* now f->value < g->value */
-		tmp = bin(f->tr, g);
-		if (tmp == one) return one;
-		result = make_node(f->value, tmp, lub(tmp, bin(f->fa, g)));
+            tmp = MR_ROBDD_bin(f->tr, g);
+            if (tmp == MR_ROBDD_one)
+                return MR_ROBDD_one;
+            result = MR_ROBDD_make_node(f->value, tmp,
+                MR_ROBDD_lub(tmp, MR_ROBDD_bin(f->fa, g)));
 	    }
-	    UPDATE_BIN_CACHE(f, g, result, bin);
+        MR_ROBDD_UPDATE_BIN_CACHE(f, g, result, MR_ROBDD_bin);
 	    return result;
 	}
-    }
-
+}
 
-/* Auxilliary function for bin:  special case code for bin(f, one). */
-node *bin_univ(node *f)
-    {
-	node *g;
+/*
+** Auxilliary function for MR_ROBDD_bin: special case code for
+** MR_ROBDD_bin(f, MR_ROBDD_one).
+*/
+
+MR_ROBDD_node *
+MR_ROBDD_bin_univ(MR_ROBDD_node *f)
+{
+    MR_ROBDD_node *g;
 
-	if (IS_TERMINAL(f)) return f;
-	g = bin_univ(f->tr);
-	if (g == one) return one;
-	return make_node(f->value, g, lub(g, bin_univ(f->fa)));
+    if (IS_TERMINAL(f)) {
+        return f;
     }
+    g = MR_ROBDD_bin_univ(f->tr);
+    if (g == MR_ROBDD_one) {
+        return MR_ROBDD_one;
+    }
+    return MR_ROBDD_make_node(f->value, g,
+        MR_ROBDD_lub(g, MR_ROBDD_bin_univ(f->fa)));
+}
 
-#endif /* SHARING */
+#endif /* MR_ROBDD_SHARING */
 
 /****************************************************************
 
@@ -2815,230 +3259,253 @@
 
  ****************************************************************/
 
+#if defined(MR_ROBDD_STATISTICS)
 
-#if defined(STATISTICS)
-void print_distribution(int array[], int max)
-    {
+void
+MR_ROBDD_print_distribution(int array[], int MR_ROBDD_max)
+{
 	int count;
 	int sum;
 	int total, zero_count;
 
-	for (count=0, total=0; count<=max; ++count) { total += array[count]; }
+    for (count=0, total=0; count<=MR_ROBDD_max; ++count) {
+        total += array[count];
+    }
 	zero_count = array[0];
-	for (count=0, sum=0; count<=max; ++count) {
+    for (count=0, sum=0; count<=MR_ROBDD_max; ++count) {
 	    if (array[count] > 0) {
 		sum += array[count];
-		printf("%5d nodes:%6d %5.2f%% (cum = %6d %5.1f%%, >0 = %6d %5.1f%%)\n",
-		       count, array[count], PERCENTAGE(array[count],total),
-		       sum, PERCENTAGE(sum,total), sum-zero_count,
-		       total==zero_count ? 999.999
-		       : PERCENTAGE(sum-zero_count, total-zero_count));
+            printf(
+                "%5d nodes:%6d %5.2f%% (cum = %6d %5.1f%%, >0 = %6d %5.1f%%)\n",
+                count, array[count], MR_ROBDD_PERCENTAGE(array[count],total),
+                sum, MR_ROBDD_PERCENTAGE(sum,total), sum-zero_count,
+                total == zero_count ? 999.999
+                    : MR_ROBDD_PERCENTAGE(sum-zero_count, total-zero_count));
 	    }
 	}
-	if (array[max+1] > 0) {
+    if (array[MR_ROBDD_max+1] > 0) {
 	    printf(">%4d nodes:%6d %2.2f%%\n",
-		   max, array[max], PERCENTAGE(array[max],total));
+           MR_ROBDD_max, array[MR_ROBDD_max],
+           MR_ROBDD_PERCENTAGE(array[MR_ROBDD_max],total));
 	}
 	printf("\n");
-    }
-#endif /* STATISTICS */
+}
+#endif /* MR_ROBDD_STATISTICS */
 
-void initRep(void)
-    {
-	INIT_FN_COUNT(make_node);
-	INIT_FN_COUNT(variableRep);
-	INIT_FN_COUNT(implies);
-	INIT_FN_COUNT(lub);
-	INIT_FN_COUNT(glb);
-	INIT_FN_COUNT(restrict);
-	INIT_FN_COUNT(restrictThresh);
-	INIT_FN_COUNT(renameArray);
-	INIT_FN_COUNT(reverseRenameArray);
-	INIT_FN_COUNT(ite);
-#if defined(USE_ITE_CONSTANT)
-	INIT_FN_COUNT(ite_constant);
-#endif /* USE_ITE_CONSTANT */
-	INIT_FN_COUNT(iff_conj);
-#if defined(NEW)
-	INIT_FN_COUNT(ite_var);
-	INIT_FN_COUNT(vars_entailed);
+void
+MR_ROBDD_initRep(void)
+{
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_make_node);
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_variableRep);
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_implies);
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_lub);
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_glb);
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_restrict);
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_restrictThresh);
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_renameArray);
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_reverseRenameArray);
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_ite);
+#if defined(MR_ROBDD_USE_ITE_CONSTANT)
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_ite_constant);
+#endif /* MR_ROBDD_USE_ITE_CONSTANT */
+    MR_ROBDD_INIT_FN_COUNT(iff_conj);
+#if defined(MR_ROBDD_NEW)
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_ite_var);
+    MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_vars_entailed);
 #endif
-#if defined(SHARING)
-#if defined(NEW)
-        INIT_FN_COUNT(complete_one_or);
-        INIT_FN_COUNT(complete_one);
-        INIT_FN_COUNT(complete_or);
-#endif /* NEW */
-        INIT_FN_COUNT(complete);
-        INIT_FN_COUNT(upclose);
-#endif /* SHARING */
-	/* This code clears the unique table and all the computed
-	 * caches.  This should make it possible to time repeated
-	 * execution of computations without the effect that after the
-	 * first time the appropriate cache will probably hold the
-	 * right result, so after the first time through the timing is
-	 * useless.  Even if this isn't the case, after the first time
-	 * performing a computation no new nodes will ever be created
-	 * because they will already exist in the unique table.
-	 *
-	 * After this, all old pointers to ROBDDs *must* be forgotten,
-	 * because we free all allocated nodes, thus giving us a fresh
-	 * start.
+#if defined(MR_ROBDD_SHARING)
+  #if defined(MR_ROBDD_NEW)
+        MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_complete_one_or);
+        MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_complete_one);
+        MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_complete_or);
+  #endif /* MR_ROBDD_NEW */
+        MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_complete);
+        MR_ROBDD_INIT_FN_COUNT(MR_ROBDD_upclose);
+#endif /* MR_ROBDD_SHARING */
+    /*
+    ** This code clears the unique table and all the computed
+    ** caches.  This should make it possible to time repeated
+    ** execution of computations without the effect that after the
+    ** first time the appropriate cache will probably hold the
+    ** right result, so after the first time through the timing is
+    ** useless.  Even if this isn't the case, after the first time
+    ** performing a computation no new nodes will ever be created
+    ** because they will already exist in the unique table.
+    **
+    ** After this, all old pointers to ROBDDs *must* be forgotten,
+    ** because we free all allocated nodes, thus giving us a fresh
+    ** start.
 	 */
 
-	INIT_UNIQUE_TABLE;
+    MR_ROBDD_INIT_UNIQUE_TABLE;
 
-	INIT_CACHE(ite);
-#if defined(USE_ITE_CONSTANT)
-	INIT_CACHE(ite_constant);
-#endif /* USE_ITE_CONSTANT */
-#if defined(SHARING)
-	INIT_CACHE(upclose);
-	INIT_CACHE(complete);
-#if defined(NEW)
-	INIT_CACHE(complete_one);
-	INIT_CACHE(complete_or);
-	INIT_CACHE(complete_one_or);
-#endif /* NEW */
-	INIT_CACHE(bin);
-#endif /* SHARING */
-	INIT_CACHE(glb);
-	INIT_CACHE(lub);
-#if defined(USE_RGLB)
-	INIT_CACHE(rglb);
-#endif /* USE_RGLB */
-#if defined(NEW)
-	INIT_CACHE(ite_var);
-	INIT_CACHE(vars_entailed);
-#endif /* NEW */
-    }
+    MR_ROBDD_init_caches();
+}
 
+void
+MR_ROBDD_init_caches(void)
+{
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_ite);
+#if defined(MR_ROBDD_USE_ITE_CONSTANT)
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_ite_constant);
+#endif /* MR_ROBDD_USE_ITE_CONSTANT */
+#if defined(MR_ROBDD_SHARING)
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_upclose);
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_bin);
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_complete);
+#if defined(MR_ROBDD_NEW)
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_complete_one);
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_complete_or);
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_complete_one_or);
+#endif /* MR_ROBDD_NEW */
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_bin);
+#endif /* MR_ROBDD_SHARING */
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_glb);
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_lub);
+#if defined(MR_ROBDD_USE_RGLB)
+    MR_ROBDD_INIT_CACHE(rglb);
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_var_entailed);
+#endif /* MR_ROBDD_USE_RGLB */
+#if defined(MR_ROBDD_NEW)
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_ite_var);
+    MR_ROBDD_INIT_CACHE(MR_ROBDD_vars_entailed);
+#endif /* MR_ROBDD_NEW */
+}
+
+void
+MR_ROBDD_concludeRep(void)
+{
+#if defined(MR_ROBDD_STATISTICS)
+    MR_ROBDD_node *ptr;
+    int size_count[MR_ROBDD_MAX_COUNT+2];
 
-void concludeRep(void)
-    {
-#if defined(STATISTICS)
-	node *ptr;
-	int size_count[MAX_COUNT+2];
 	int i, count;
 
 	printf("\n\n\n================ Operation Counts ================\n\n");
-	PRINT_FN_COUNT(make_node);
-	PRINT_FN_COUNT(variableRep);
-	PRINT_FN_COUNT(implies);
-	PRINT_FN_COUNT(lub);
-	PRINT_FN_COUNT(glb);
-	PRINT_FN_COUNT(restrict);
-	PRINT_FN_COUNT(restrictThresh);
-	PRINT_FN_COUNT(renameArray);
-	PRINT_FN_COUNT(reverseRenameArray);
-	PRINT_FN_COUNT(ite);
-#if defined(USE_ITE_CONSTANT)
-	PRINT_FN_COUNT(ite_constant);
-#endif /* USE_ITE_CONSTANT */
-	PRINT_FN_COUNT(iff_conj);
-#if defined(NEW)
-	PRINT_FN_COUNT(ite_var);
-	PRINT_FN_COUNT(vars_entailed);
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_make_node);
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_variableRep);
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_implies);
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_lub);
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_glb);
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_restrict);
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_restrictThresh);
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_renameArray);
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_reverseRenameArray);
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_ite);
+#if defined(MR_ROBDD_USE_ITE_CONSTANT)
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_ite_constant);
+#endif /* MR_ROBDD_USE_ITE_CONSTANT */
+    MR_ROBDD_PRINT_FN_COUNT(iff_conj);
+#if defined(MR_ROBDD_NEW)
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_ite_var);
+    MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_vars_entailed);
 #endif
-#if defined(SHARING)
-#if defined(NEW)
-        PRINT_FN_COUNT(complete_one_or);
-        PRINT_FN_COUNT(complete_one);
-        PRINT_FN_COUNT(complete_or);
-#endif /* NEW */
-        PRINT_FN_COUNT(complete);
-        PRINT_FN_COUNT(upclose);
-#endif /* SHARING */
+#if defined(MR_ROBDD_SHARING)
+  #if defined(MR_ROBDD_NEW)
+        MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_complete_one_or);
+        MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_complete_one);
+        MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_complete_or);
+  #endif /* MR_ROBDD_NEW */
+        MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_complete);
+        MR_ROBDD_PRINT_FN_COUNT(MR_ROBDD_upclose);
+#endif /* MR_ROBDD_SHARING */
 	printf("\n================ Cache Performance ================\n\n");
-	printf("%d nodes extant\n\n", nodes_in_use());
+    printf("%d nodes extant\n\n", MR_ROBDD_nodes_in_use());
 	printf("Unique table:  %d hits, %d misses, %f%% hits\n",
-	       unique_table_hits, unique_table_misses,
-	       PERCENTAGE(unique_table_hits,
-			  unique_table_hits+unique_table_misses));
-	memset(size_count, 0, sizeof(size_count));
-	for (i=0; i<UNIQUE_TABLE_SIZE; ++i) {
-	    for (ptr=unique_table[i],count=0;
-		 ptr!=NULL;
-		 ptr=ptr->unique,++count);
-	    ++size_count[(count<=MAX_COUNT ? count : MAX_COUNT+1)];
-	}
-	print_distribution(size_count, MAX_COUNT);
-
-	PRINT_CACHE_PERFORMANCE(ite);
-#if defined(USE_ITE_CONSTANT)
-	PRINT_CACHE_PERFORMANCE(ite_constant);
-#endif /* USE_ITE_CONSTANT */
-	PRINT_CACHE_PERFORMANCE(lub);
-	PRINT_CACHE_PERFORMANCE(glb);
-#if defined(SHARING)
-	PRINT_CACHE_PERFORMANCE(upclose);
-	PRINT_CACHE_PERFORMANCE(complete);
-#if defined(NEW)
-	PRINT_CACHE_PERFORMANCE(complete_or);
-	PRINT_CACHE_PERFORMANCE(complete_one_or);
-	PRINT_CACHE_PERFORMANCE(complete_one);
-#endif /* NEW */
-#endif /* SHARING */
-#if defined(USE_RGLB)
-	PRINT_CACHE_PERFORMANCE(rglb);
-#endif /* USE_RGLB */
-#if defined(NEW)
-	PRINT_CACHE_PERFORMANCE(ite_var);
-	PRINT_CACHE_PERFORMANCE(vars_entailed);
-#endif /* NEW */
-#endif /* STATISTICS */
+           MR_ROBDD_unique_table_hits, MR_ROBDD_unique_table_misses,
+           MR_ROBDD_PERCENTAGE(MR_ROBDD_unique_table_hits,
+              MR_ROBDD_unique_table_hits+MR_ROBDD_unique_table_misses));
+    MR_memset(size_count, 0, sizeof(size_count));
+    for (i=0; i<MR_ROBDD_UNIQUE_TABLE_SIZE; ++i) {
+        count = 0;
+        ptr=MR_ROBDD_REVEAL_NODE_POINTER(MR_ROBDD_unique_table[i]);
+        while (ptr!=NULL) {
+             ptr=MR_ROBDD_REVEAL_NODE_POINTER(ptr->unique),++count;
+        }
+        ++size_count[(count <= MR_ROBDD_MAX_COUNT
+            ? count : MR_ROBDD_MAX_COUNT + 1)];
+    }
+    MR_ROBDD_print_distribution(size_count, MR_ROBDD_MAX_COUNT);
+
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(MR_ROBDD_ite);
+#if defined(MR_ROBDD_USE_ITE_CONSTANT)
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(MR_ROBDD_ite_constant);
+#endif /* MR_ROBDD_USE_ITE_CONSTANT */
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(MR_ROBDD_lub);
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(MR_ROBDD_glb);
+#if defined(MR_ROBDD_SHARING)
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(MR_ROBDD_upclose);
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(MR_ROBDD_complete);
+  #if defined(MR_ROBDD_NEW)
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(MR_ROBDD_complete_or);
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(MR_ROBDD_complete_one_or);
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(MR_ROBDD_complete_one);
+  #endif /* MR_ROBDD_NEW */
+#endif /* MR_ROBDD_SHARING */
+#if defined(MR_ROBDD_USE_RGLB)
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(rglb);
+#endif /* MR_ROBDD_USE_RGLB */
+#if defined(MR_ROBDD_NEW)
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(MR_ROBDD_ite_var);
+    MR_ROBDD_PRINT_CACHE_PERFORMANCE(MR_ROBDD_vars_entailed);
+#endif /* MR_ROBDD_NEW */
+#endif /* MR_ROBDD_STATISTICS */
     }
 
-
-
 /****************************************************************
 
 			   Testing Support
 
  ****************************************************************/
 
-/* special version of iff_conj_array() that is the fast version no matter
- * which options are selected.  I hope this gives more reliable test times.
- */
-
-node *testing_iff_conj_array(int v0, int n, int arr[])
-    {
-	node *thens = one, *elses = zero;
+/*
+** special version of MR_ROBDD_iff_conj_array() that is the fast version
+** no matter which options are selected. I hope this gives more reliable
+** test times.
+*/
+
+MR_ROBDD_node *
+MR_ROBDD_testing_iff_conj_array(int v0, int n, int arr[])
+{
+    MR_ROBDD_node *thens = MR_ROBDD_one;
+    MR_ROBDD_node *elses = MR_ROBDD_zero;
 	int *ptr;
 	int vi;
 
-	/* first build part of graph below v0.  For this, we build two
-	 * subgraphs:  one for when v0 is true, and one for false.
-	 * These are called thens and elses.
-	 */
+    /*
+    ** first build part of graph below v0.  For this, we build two
+    ** subgraphs:  MR_ROBDD_one for when v0 is true, and MR_ROBDD_one for false.
+    ** These are called thens and elses.
+    **/
 
 	for (ptr=&arr[n-1]; ptr>=arr && v0<(vi=*ptr); --ptr) {
-	    thens = make_node(vi, thens, zero);
-	    elses = make_node(vi, elses, one);
+        thens = MR_ROBDD_make_node(vi, thens, MR_ROBDD_zero);
+        elses = MR_ROBDD_make_node(vi, elses, MR_ROBDD_one);
 	}
 	
-	/* make v0 node */
-	thens = make_node(v0,thens,elses);
+    /* make v0 MR_ROBDD_node */
+    thens = MR_ROBDD_make_node(v0,thens,elses);
 
-	/* Finally build part of graph above v0.  For this, we build
-	 * only one graph, whose then branch is the graph we've built
-	 * so far and whose else branch is ~v0.
+    /*
+    ** Finally build part of graph above v0.  For this, we build
+    ** only MR_ROBDD_one graph, whose then branch is the graph we've built
+    ** so far and whose else branch is ~v0.
 	 */
 
 	if (ptr >= arr) {
 	    /* make ~v0 */
-	    elses = make_node(v0,zero,one);
+        elses = MR_ROBDD_make_node(v0,MR_ROBDD_zero,MR_ROBDD_one);
 
 	    do {
 		vi = *ptr;
-		thens = make_node(vi, thens, elses);
+            thens = MR_ROBDD_make_node(vi, thens, elses);
 	    } while (--ptr >= arr);
 	}
 
 	return thens;
-    }
+}
     
-static int intcompare(const void *a, const void *b)
-    {
-	return (*((int *)a) - *((int *)b));
-    }
+static int MR_ROBDD_intcompare(const void *a, const void *b)
+{
+    return (* ((int *) a) - * ((int *) b));
+}
Index: robdd/bryant.h
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/bryant.h,v
retrieving revision 1.1
diff -u -b -r1.1 bryant.h
--- robdd/bryant.h	10 Mar 2000 05:17:21 -0000	1.1
+++ robdd/bryant.h	5 Jan 2003 22:23:35 -0000
@@ -1,77 +1,106 @@
+/*
+** Copyright (C) 1995, 2001-2003 Peter Schachte and 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     : bryant.h
-  RCS      : $Id: bryant.h,v 1.1 2000/03/10 05:17:21 dmo Exp $
+  RCS      : $Id: bryant.h,v 1.1.12.2 2002/05/08 09:35:29 zs Exp $
   Author   : Peter Schachte
   Origin   : Sun Jul 30 15:08:53 1995
   Purpose  : header file for users of bryant.c ROBDD package
-  Copyright: © 1995 Peter Schachte.  All rights reserved.
 
 *****************************************************************/
 
+#ifndef MERCURY_BRYANT_H
+#define MERCURY_BRYANT_H
+
 #if defined(QUINTUS)
-#include <quintus/quintus.h>
+  #include <quintus/quintus.h>
 #endif
 #include <string.h>
 #include <assert.h>
 #include "var.h"
-
+#if defined(CONSERVATIVE_GC)
+  #define GC_I_HIDE_POINTERS
+  #include "gc.h"
+  #define MR_ROBDD_BRYANT_CONSERVATIVE_GC
+  #define MR_ROBDD_HIDE_POINTER(p) 	HIDE_POINTER(p)
+  #define MR_ROBDD_REVEAL_POINTER(p)	REVEAL_POINTER(p)
+#else
+  #define MR_ROBDD_HIDE_POINTER(p)	(p)
+  #define MR_ROBDD_REVEAL_POINTER(p)	(p)
+#endif
 /*****************************************************************
 			  Tunable Parameters
 *****************************************************************/
 
 #if defined(AMIGA)
 
-/* number of buckets in unique table */
-#define UNIQUE_TABLE_SIZE 4096
+  /* number of buckets in unique table */
+  #define MR_ROBDD_UNIQUE_TABLE_SIZE 4096
 
-/* number of entries in ite computed table */
-#define ITE_COMPUTED_TABLE_SIZE 4096
+  /* number of entries in MR_ROBDD_ite computed table */
+  #define MR_ROBDD_ITE_COMPUTED_TABLE_SIZE 4096
 
-/* number of entries in computed table for binary functions (and, or) */
-#define BINARY_CACHE_SIZE 4096
+  /* number of entries in computed table for binary functions (and, or) */
+  #define MR_ROBDD_BINARY_CACHE_SIZE 4096
 
-/* allocate bryant nodes this many at a time */
-#define POOL_SIZE 4096
+  /* allocate bryant nodes this many at a time */
+  #define MR_ROBDD_POOL_SIZE 4096
 
 #else
 
-/* number of buckets in unique table */
-#define UNIQUE_TABLE_SIZE 65537		/* first prime number > 64K */
+  /* number of buckets in unique table */
+  #define MR_ROBDD_UNIQUE_TABLE_SIZE 65537		/* first prime number > 64K */
+
+  /* number of entries in MR_ROBDD_ite computed table */
+  #define MR_ROBDD_COMPUTED_TABLE_SIZE 16411	/* first prime number > 16K */
 
-/* number of entries in ite computed table */
-#define COMPUTED_TABLE_SIZE 16411	/* first prime number > 16K */
+  /* allocate bryant nodes this many at a time */
+  #define MR_ROBDD_POOL_SIZE 65535
 
-/* allocate bryant nodes this many at a time */
-#define POOL_SIZE 65535
 #endif
 
 /* number of bits in an unsigned long, and the log (base 2) of that */
-#define BITS_PER_WORD 32
-#define LOG_BITS_PER_WORD 5
+#define MR_ROBDD_BITS_PER_WORD 32
+#define MR_ROBDD_LOG_BITS_PER_WORD 5
 
-/* number of bits in an unsigned char, and a bitmask the size of a char */
-#define BITS_PER_CHAR 8
-#define CHAR_MASK ((1<<BITS_PER_CHAR)-1)
+/* number of bits in an unsigned char, and a MR_ROBDD_bitmask the size of a char */
+#define MR_ROBDD_BITS_PER_CHAR 8
+#define MR_ROBDD_CHAR_MASK ((1<<MR_ROBDD_BITS_PER_CHAR)-1)
 
-#define INTCAST(p) ((size_t)(p))
+#define MR_ROBDD_INTCAST(p) ((size_t)(p))
 
 /****************************************************************
 	       Bryant Graph (ROBDD) Node Data Structure
 ****************************************************************/
 
-typedef struct graphnode {
+typedef struct MR_ROBDD_graphnode {
 	int value;		/* contains name of variable */
-	struct graphnode *tr;	/* true (then) child */
-	struct graphnode *fa;	/* false (else) child */
-	struct graphnode *unique;  /* pointer to next elt in unique table */
-} node, type;
-
-/* zero and one are terminal nodes (sinks). */
-#define zero         ((node *) 0)
-#define one          ((node *) 1)
-#define nonterminal ((node *) 2) /* only used by ite_constant */
+	struct MR_ROBDD_graphnode *tr;	/* true (then) child */
+	struct MR_ROBDD_graphnode *fa;	/* false (else) child */
+#if defined(MR_ROBDD_BRYANT_CONSERVATIVE_GC)
+	GC_hidden_pointer unique; /* pointer to next elt in unique table */
+	GC_hidden_pointer uprev;  /* pointer to the prev elt in unique table */
+#else
+	struct MR_ROBDD_graphnode *unique;  /* pointer to next elt in unique table */
+#endif
+} MR_ROBDD_node, MR_ROBDD_type;
 
-#define IS_TERMINAL(n) (INTCAST(n) <= 1)
+#if defined(MR_ROBDD_BRYANT_CONSERVATIVE_GC)
+  typedef GC_hidden_pointer MR_ROBDD_BRYANT_hidden_node_pointer;
+#else
+  typedef MR_ROBDD_node *MR_ROBDD_BRYANT_hidden_node_pointer;
+#endif
+
+/* MR_ROBDD_zero and MR_ROBDD_one are terminal nodes (sinks). */
+#define MR_ROBDD_zero         ((MR_ROBDD_node *) 0)
+#define MR_ROBDD_one          ((MR_ROBDD_node *) 1)
+#define MR_ROBDD_nonterminal ((MR_ROBDD_node *) 2) /* only used by MR_ROBDD_ite_constant */
+
+#define IS_TERMINAL(n) (MR_ROBDD_INTCAST(n) <= 1)
 
 /****************************************************************
 			Bit Set Data Structure
@@ -79,9 +108,9 @@
 
 /* array must put it into a struct because arrays are pretty feeble in C */
 typedef struct {
-    unsigned long bits[1+(MAXVAR-1)/BITS_PER_WORD];
-} bitset;
-typedef unsigned long bitmask;
+    unsigned long bits[1+(MAXVAR-1)/MR_ROBDD_BITS_PER_WORD];
+} MR_ROBDD_bitset;
+typedef unsigned long MR_ROBDD_bitmask;
 
 /* Operations to add, remove, toggle, and check for membership of a
  * single element.  The first two of these are used to find the word
@@ -90,32 +119,32 @@
  * I'd code the last 4 of these in terms of the first two, so that
  * they would each take only 2 arguments.  But I don't.
  */
-#define BITSET_WORD(elt) ((elt)>>LOG_BITS_PER_WORD)
-#define BITSET_MASK(elt) (1 << ((elt)&(BITS_PER_WORD-1)))
-#define BITSET_CLEAR(set) memset(&set, 0, sizeof(bitset))
-#define BITSET_UNIVERSE(set) memset(&set, ~0, sizeof(bitset))
-#define BITSET_MEMBER(set,word,mask) (0!=((set).bits[(word)]&(mask)))
-#define BITSET_ADD(set,word,mask) (set).bits[(word)] |= (mask)
-#define BITSET_REMOVE(set,word,mask) (set).bits[(word)] &= ~(mask)
-#define BITSET_TOGGLE(set,word,mask) (set).bits[(word)] ^= (mask)
+#define MR_ROBDD_BITSET_WORD(elt) ((elt)>>MR_ROBDD_LOG_BITS_PER_WORD)
+#define MR_ROBDD_BITSET_MASK(elt) (1 << ((elt)&(MR_ROBDD_BITS_PER_WORD-1)))
+#define MR_ROBDD_BITSET_CLEAR(set) memset(&set, 0, sizeof(MR_ROBDD_bitset))
+#define BITSET_UNIVERSE(set) memset(&set, ~0, sizeof(MR_ROBDD_bitset))
+#define MR_ROBDD_BITSET_MEMBER(set,word,mask) (0!=((set).bits[(word)]&(mask)))
+#define MR_ROBDD_BITSET_ADD(set,word,mask) (set).bits[(word)] |= (mask)
+#define MR_ROBDD_BITSET_REMOVE(set,word,mask) (set).bits[(word)] &= ~(mask)
+#define MR_ROBDD_BITSET_TOGGLE(set,word,mask) (set).bits[(word)] ^= (mask)
 
 /* important bit masks */
-#if defined(NO_CHEAP_SHIFT) && BITS_PER_WORD == 32
-#define FOLLOWING_BITS(n) following_bits[n]
-#define PRECEDING_BITS(n) preceding_bits[n]
-#else /* ! NO_CHEAP_SHIFT */
-#define FOLLOWING_BITS(n) ((~0UL)<<(n))
-#define PRECEDING_BITS(n) ((~0UL)>>(BITS_PER_WORD-1-(n)))
-#endif /* NO_CHEAP_SHIFT */
-
-#define BITSET_IS_MEMBER(set,n) \
-  BITSET_MEMBER(set, BITSET_WORD(n), BITSET_MASK(n))
-#define BITSET_ADD_ELEMENT(set,n) \
-  BITSET_ADD(set, BITSET_WORD(n), BITSET_MASK(n))
-#define BITSET_REMOVE_ELEMENT(set,n) \
-  BITSET_REMOVE(set, BITSET_WORD(n), BITSET_MASK(n))
-#define BITSET_TOGGLE_ELEMENT(set,n) \
-  BITSET_TOGGLE(set, BITSET_WORD(n), BITSET_MASK(n))
+#if defined(MR_ROBDD_NO_CHEAP_SHIFT) && MR_ROBDD_BITS_PER_WORD == 32
+  #define MR_ROBDD_FOLLOWING_BITS(n) MR_ROBDD_following_bits[n]
+  #define MR_ROBDD_PRECEDING_BITS(n) MR_ROBDD_preceding_bits[n]
+#else /* ! MR_ROBDD_NO_CHEAP_SHIFT */
+  #define MR_ROBDD_FOLLOWING_BITS(n) ((~0UL)<<(n))
+  #define MR_ROBDD_PRECEDING_BITS(n) ((~0UL)>>(MR_ROBDD_BITS_PER_WORD-1-(n)))
+#endif /* MR_ROBDD_NO_CHEAP_SHIFT */
+
+#define MR_ROBDD_BITSET_IS_MEMBER(set,n) \
+  MR_ROBDD_BITSET_MEMBER(set, MR_ROBDD_BITSET_WORD(n), MR_ROBDD_BITSET_MASK(n))
+#define MR_ROBDD_BITSET_ADD_ELEMENT(set,n) \
+  MR_ROBDD_BITSET_ADD(set, MR_ROBDD_BITSET_WORD(n), MR_ROBDD_BITSET_MASK(n))
+#define MR_ROBDD_BITSET_REMOVE_ELEMENT(set,n) \
+  MR_ROBDD_BITSET_REMOVE(set, MR_ROBDD_BITSET_WORD(n), MR_ROBDD_BITSET_MASK(n))
+#define MR_ROBDD_BITSET_TOGGLE_ELEMENT(set,n) \
+  MR_ROBDD_BITSET_TOGGLE(set, MR_ROBDD_BITSET_WORD(n), MR_ROBDD_BITSET_MASK(n))
 
 /* Macros for operations on sets.  These are destructive: the first
  * argument is modified to hold the result.  The i parameter is just a
@@ -123,118 +152,117 @@
  * should probably be __inline functions, but I don't trust that,
  * either.  Portability, you know.
  */
-#define BITSET_INTERSECTION(set,set1,set2)				\
-  do { int i; for (i=0; i<=((MAXVAR-1)/BITS_PER_WORD); ++i)	\
+#define MR_ROBDD_BITSET_INTERSECTION(set,set1,set2)				\
+  do { int i; for (i=0; i<=((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD); ++i)	\
 	 (set).bits[i] = (set1).bits[i] & (set2).bits[i];} while (0)
-#define BITSET_DIFFERENCE(set,set1,set2)				\
-  do { int i; for (i=0; i<=((MAXVAR-1)/BITS_PER_WORD); ++i)	\
+#define MR_ROBDD_BITSET_DIFFERENCE(set,set1,set2)				\
+  do { int i; for (i=0; i<=((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD); ++i)	\
 	 (set).bits[i] = (set1).bits[i] & ~((set2).bits[i]); } while (0)
-#define BITSET_UNION(set,set1,set2)					\
-  do { int i; for (i=0; i<=((MAXVAR-1)/BITS_PER_WORD); ++i) 	\
+#define MR_ROBDD_BITSET_UNION(set,set1,set2)					\
+  do { int i; for (i=0; i<=((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD); ++i) 	\
 	 (set).bits[i] = (set1).bits[i] | (set2).bits[i]; } while (0)
-#define BITSET_EXCLUSIVE_UNION(set,set1,set2)			\
-  do { int i; for (i=0; i<=((MAXVAR-1)/BITS_PER_WORD); ++i)	\
+#define MR_ROBDD_BITSET_EXCLUSIVE_UNION(set,set1,set2)			\
+  do { int i; for (i=0; i<=((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD); ++i)	\
 	 (set).bits[i] = (set1).bits[i] ^ (set2).bits[i]; } while (0)
 
-#define BITSET_EQUAL(set1, set2) bitset_equal(&set1, &set2)
-#define BITSET_DISJOINT(set1, set2) bitset_disjoint(&set1, &set2)
-#define BITSET_SUBSET(set1, set2) bitset_subset(&set1, &set2)
-#define BITSET_EMPTY(set) bitset_empty(&set)
-
+#define MR_ROBDD_BITSET_EQUAL(set1, set2) MR_ROBDD_bitset_equal(&set1, &set2)
+#define MR_ROBDD_BITSET_DISJOINT(set1, set2) MR_ROBDD_bitset_disjoint(&set1, &set2)
+#define MR_ROBDD_BITSET_SUBSET(set1, set2) MR_ROBDD_bitset_subset(&set1, &set2)
+#define MR_ROBDD_BITSET_EMPTY(set) MR_ROBDD_bitset_empty(&set)
 
 /* Successor and predecessor for possible set elements.  These are
  * expressions that are false if there are no more possible elements.
  */
-#define NEXT_POSSIBLE_ELEMENT(var,word,mask) \
+#define MR_ROBDD_NEXT_POSSIBLE_ELEMENT(var,word,mask) \
   (++var<MAXVAR && ((mask<<=1) || (mask=1,++word)))
-#define PREV_POSSIBLE_ELEMENT(var,word,mask) \
-  (--var>=0 && ((mask>>=1) || (mask=1<<(BITS_PER_WORD-1),--word)))
-
+#define MR_ROBDD_PREV_POSSIBLE_ELEMENT(var,word,mask) \
+  (--var>=0 && ((mask>>=1) || (mask=1<<(MR_ROBDD_BITS_PER_WORD-1),--word)))
 
 /* Enumerating sets.  Use these like for loops:  follow the macro call with
  * a statement (or an open brace, some statements, and a close brace).  The
  * first three iterate from low to high, the last three from high to low.
  */
-#define FOREACH_POSSIBLE_ELEMENT(var,word,mask) \
+#define MR_ROBDD_FOREACH_POSSIBLE_ELEMENT(var,word,mask) \
   for (var=0,word=0,mask=1; var<MAXVAR;		\
-       (void) NEXT_POSSIBLE_ELEMENT(var,word,mask))
-#define FOREACH_ELEMENT(set,var,word,mask) \
-  for (var=0,word=0,mask=1; next_element(&set,&var,&word,&mask); \
-       (void) NEXT_POSSIBLE_ELEMENT(var,word,mask))
-#define FOREACH_NONELEMENT(set,var,word,mask) \
-  for (var=0,word=0,mask=1; next_nonelement(&set,&var,&word,&mask); \
-       (void) NEXT_POSSIBLE_ELEMENT(var,word,mask))
-
-#define REV_FOREACH_POSSIBLE_ELEMENT(var,word,mask) \
-  for (var=MAXVAR-1,word=((MAXVAR-1)/BITS_PER_WORD),mask=1<<(BITS_PER_WORD-1); \
-       var>0; (void) PREV_POSSIBLE_ELEMENT(var,word,mask))
-#define REV_FOREACH_ELEMENT(set,var,word,mask) \
-  for (var=MAXVAR-1,word=((MAXVAR-1)/BITS_PER_WORD),mask=1<<(BITS_PER_WORD-1); \
-       prev_element(&set,&var,&word,&mask); \
-       (void) PREV_POSSIBLE_ELEMENT(var,word,mask))
-#define REV_FOREACH_NONELEMENT(set,var,word,mask) \
-  for (var=MAXVAR-1,word=((MAXVAR-1)/BITS_PER_WORD),mask=1<<(BITS_PER_WORD-1); \
-       prev_nonelement(&set,&var,&word,&mask); \
-       (void) PREV_POSSIBLE_ELEMENT(var,word,mask))
-
+       (void) MR_ROBDD_NEXT_POSSIBLE_ELEMENT(var,word,mask))
+#define MR_ROBDD_FOREACH_ELEMENT(set,var,word,mask) \
+  for (var=0,word=0,mask=1; MR_ROBDD_next_element(&set,&var,&word,&mask); \
+       (void) MR_ROBDD_NEXT_POSSIBLE_ELEMENT(var,word,mask))
+#define MR_ROBDD_FOREACH_NONELEMENT(set,var,word,mask) \
+  for (var=0,word=0,mask=1; MR_ROBDD_next_nonelement(&set,&var,&word,&mask); \
+       (void) MR_ROBDD_NEXT_POSSIBLE_ELEMENT(var,word,mask))
+
+#define MR_ROBDD_REV_FOREACH_POSSIBLE_ELEMENT(var,word,mask) \
+  for (var=MAXVAR-1,word=((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD),mask=1<<(MR_ROBDD_BITS_PER_WORD-1); \
+       var>0; (void) MR_ROBDD_PREV_POSSIBLE_ELEMENT(var,word,mask))
+#define MR_ROBDD_REV_FOREACH_ELEMENT(set,var,word,mask) \
+  for (var=MAXVAR-1,word=((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD),mask=1<<(MR_ROBDD_BITS_PER_WORD-1); \
+       MR_ROBDD_prev_element(&set,&var,&word,&mask); \
+       (void) MR_ROBDD_PREV_POSSIBLE_ELEMENT(var,word,mask))
+#define MR_ROBDD_REV_FOREACH_NONELEMENT(set,var,word,mask) \
+  for (var=MAXVAR-1,word=((MAXVAR-1)/MR_ROBDD_BITS_PER_WORD),mask=1<<(MR_ROBDD_BITS_PER_WORD-1); \
+       MR_ROBDD_prev_nonelement(&set,&var,&word,&mask); \
+       (void) MR_ROBDD_PREV_POSSIBLE_ELEMENT(var,word,mask))
 
 /*****************************************************************
 			  Other Definitions
 *****************************************************************/
 
+#ifndef MR_TRUE
+  #define MR_TRUE 1
+#endif
+#ifndef MR_FALSE
+  #define MR_FALSE 0
+#endif
 
-#define TRUE 1
-#define FALSE 0
+/* sneaky trick to make MR_ROBDD_NEW the default */
+#if !defined(MR_ROBDD_USE_RGLB) \
+      && !defined(MR_ROBDD_USE_THRESH) \
+      && !defined(MR_ROBDD_OLD) \
+      && !defined(MR_ROBDD_NAIVE) \
+      && !defined(MR_ROBDD_NEW)
+  #define MR_ROBDD_NEW
+#endif
 
-/* sneaky trick to make NEW the default */
-#if !defined(USE_RGLB) \
-      && !defined(USE_THRESH) \
-      && !defined(OLD) \
-      && !defined(NAIVE) \
-      && !defined(NEW)
-#define NEW
-#endif
-
-#if defined(NEW)
-#define USE_RGLB
-#endif /* NEW */
-
-#if defined(USE_RGLB)
-#define USE_THRESH
-#endif /* USE_RGLB */
-
-#if defined(USE_THRESH)
-#define OLD
-#if !defined(NEW)
-#define USE_ITE_CONSTANT /* for var_entailed */
-#endif /* !NEW */
-#endif /* USE_THRESH */
-
-#if defined(NEW)
-#define WHICH "NEW"
-#elif defined(USE_RGLB)
-#define WHICH "RGLB"
-#elif defined(USE_THRESH)
-#define WHICH "THRESH"
-#elif defined(OLD)
-#define WHICH "OLD"
-#elif defined(NAIVE)
-#define WHICH "NAIVE"
+#if defined(MR_ROBDD_NEW)
+  #define MR_ROBDD_USE_RGLB
+#endif /* MR_ROBDD_NEW */
+
+#if defined(MR_ROBDD_USE_RGLB)
+  #define MR_ROBDD_USE_THRESH
+#endif /* MR_ROBDD_USE_RGLB */
+
+#if defined(MR_ROBDD_USE_THRESH)
+  #define MR_ROBDD_OLD
+  #if !defined(MR_ROBDD_NEW)
+    #define MR_ROBDD_USE_ITE_CONSTANT /* for MR_ROBDD_var_entailed */
+  #endif /* !MR_ROBDD_NEW */
+#endif /* MR_ROBDD_USE_THRESH */
+
+#if defined(MR_ROBDD_NEW)
+  #define MR_ROBDD_WHICH "MR_ROBDD_NEW"
+#elif defined(MR_ROBDD_USE_RGLB)
+  #define MR_ROBDD_WHICH "RGLB"
+#elif defined(MR_ROBDD_USE_THRESH)
+  #define MR_ROBDD_WHICH "THRESH"
+#elif defined(MR_ROBDD_OLD)
+  #define MR_ROBDD_WHICH "MR_ROBDD_OLD"
+#elif defined(MR_ROBDD_NAIVE)
+  #define MR_ROBDD_WHICH "MR_ROBDD_NAIVE"
 #else
-#error "must define one of NEW, USE_RGLB, USE_THRESH, OLD, or NAIVE."
+  #error "must define MR_ROBDD_one of MR_ROBDD_NEW, MR_ROBDD_USE_RGLB, MR_ROBDD_USE_THRESH, MR_ROBDD_OLD, or MR_ROBDD_NAIVE."
 #endif
 
-
 /*****************************************************************
 				 Public Data
 *****************************************************************/
 
-extern unsigned char first_one_bit[256];
-extern unsigned char last_one_bit[256];
+extern unsigned char MR_ROBDD_first_one_bit[256];
+extern unsigned char MR_ROBDD_last_one_bit[256];
 
-#if defined(NO_CHEAP_SHIFT) && BITS_PER_WORD == 32
-extern bitmask following_bits[BITS_PER_WORD];
-extern bitmask preceding_bits[BITS_PER_WORD];
+#if defined(MR_ROBDD_NO_CHEAP_SHIFT) && MR_ROBDD_BITS_PER_WORD == 32
+  extern MR_ROBDD_bitmask MR_ROBDD_following_bits[MR_ROBDD_BITS_PER_WORD];
+  extern MR_ROBDD_bitmask MR_ROBDD_preceding_bits[MR_ROBDD_BITS_PER_WORD];
 #endif
 
 /*****************************************************************
@@ -242,164 +270,181 @@
 *****************************************************************/
 
 /* this must be called before any other function in this file */
-extern void initRep(void);
+extern void MR_ROBDD_initRep(void);
+
+extern void MR_ROBDD_init_caches(void);
 
 /* this should be called when you're done calling functions in this file */
 /* to clean up memory used by ROBDDs.  After calling this, you must call */
 /* InitRep() again before calling any other functions in this file */
-extern void concludeRep(void);
+extern void MR_ROBDD_concludeRep(void);
 
+/* the basic make a MR_ROBDD_node or return an existing MR_ROBDD_node operation */
+extern MR_ROBDD_node *MR_ROBDD_make_node(int var, MR_ROBDD_node *tr, MR_ROBDD_node *fa);
 
-/* the basic make a node or return an existing node operation */
-extern node *make_node(int var, node *tr, node *fa);
-
-/* returns one (the Boolean function true) */
-extern node *trueVar(void);
-/* returns zero (the Boolean function false) */
-extern node *falseVar(void);
+/* returns MR_ROBDD_one (the Boolean function true) */
+extern MR_ROBDD_node *MR_ROBDD_trueVar(void);
+/* returns MR_ROBDD_zero (the Boolean function false) */
+extern MR_ROBDD_node *MR_ROBDD_falseVar(void);
 /* returns var, as an ROBDD.  */
-extern node *variableRep(int var);
+extern MR_ROBDD_node *MR_ROBDD_variableRep(int var);
+
+/* if then else algorithm */
+extern MR_ROBDD_node *MR_ROBDD_ite(MR_ROBDD_node *f, MR_ROBDD_node *g, MR_ROBDD_node *h);
+
+/* This is sort of an "approximate MR_ROBDD_ite()."  It returns MR_ROBDD_zero or MR_ROBDD_one if
+** that's what MR_ROBDD_ite() would do.  Otherwise it just returns the
+** pseudo-MR_ROBDD_node `MR_ROBDD_nonterminal' or some real MR_ROBDD_node.  In any case, it does
+** not create any new nodes.
+*/
+#ifdef MR_ROBDD_USE_ITE_CONSTANT
+  extern MR_ROBDD_node *MR_ROBDD_ite_constant(MR_ROBDD_node *f,MR_ROBDD_node *g,MR_ROBDD_node *h);
+#endif
 
+extern MR_ROBDD_node *MR_ROBDD_ite_var(int f, MR_ROBDD_node *g, MR_ROBDD_node *h);
 
 /* returns a \wedge b */
-extern node *glb(node *a, node *b);
+extern MR_ROBDD_node *MR_ROBDD_glb(MR_ROBDD_node *a, MR_ROBDD_node *b);
 /* returns a \vee b */
-extern node *lub(node *a, node *b);
+extern MR_ROBDD_node *MR_ROBDD_lub(MR_ROBDD_node *a, MR_ROBDD_node *b);
 /* returns a \rightarrow b */
-extern node *implies(node *a, node *b);
+extern MR_ROBDD_node *MR_ROBDD_implies(MR_ROBDD_node *a, MR_ROBDD_node *b);
 
 /* returns \exists c . a */
-/* extern node *restrict(int c, node *a); */
+extern MR_ROBDD_node *MR_ROBDD_restrict(int c, MR_ROBDD_node *f);
 
 /* returns \bigglb_{0 \leq i \leq n} array[i] */
-extern node *glb_array(int n, int arr[]);
+extern MR_ROBDD_node *MR_ROBDD_glb_array(int n, int arr[]);
 
 /* returns a with variable o renamed to n */
-extern node *changename(int o, int n, node *a);
+extern MR_ROBDD_node *changename(int o, int n, MR_ROBDD_node *a);
 /* returns a with variable 1 renamed to v1, 2 renamed to v2, ... n renamed */
 /* to v_n.  Here n is the number of variables to rename */
-extern node *renameList(node *a, int n, int v1, int v2, int v3, int v4, int v5,
+extern MR_ROBDD_node *renameList(MR_ROBDD_node *a, int n, int v1, int v2, int v3, int v4, int v5,
 		 int v6, int v7, int v8, int v9, int v10, int v11, int v12,
 		 int v13, int v14, int v15, int v16);
 /* returns a with variable v1 renamed to 1, v2 renamed to 2, ... v_n renamed */
 /* to n.  Here n is the number of variables to rename */
-extern node *reverseRenameList(node *a, int n, int v1, int v2, int v3, int v4,
+extern MR_ROBDD_node *reverseRenameList(MR_ROBDD_node *a, int n, int v1, int v2, int v3, int v4,
 			int v5, int v6, int v7, int v8, int v9, int v10,
 			int v11, int v12, int v13, int v14, int v15, int v16);
 /* returns a with variable 0 renamed to mapping[0], 1 renamed to */
 /* mapping[1], ... count renamed to mapping[count]. */
-extern node *renameArray(node *in, int count, int mappping[]);
+extern MR_ROBDD_node *MR_ROBDD_renameArray(MR_ROBDD_node *in, int count, int mappping[]);
 /* returns a with variable mapping[0] renamed to 0, mapping[1] renamed to */
 /* 1, ... mapping[count] renamed to count. */
-extern node *reverseRenameArray(node *in, int count, int rev_mappping[]);
+extern MR_ROBDD_node *MR_ROBDD_reverseRenameArray(MR_ROBDD_node *in, int count, int rev_mappping[]);
 
 /* returns v0 \leftrightarrow \bigwedge_{i=0}^{n} arr[i] */
-extern node *iff_conj_array(int v0, int n, int arr[]);
+extern MR_ROBDD_node *MR_ROBDD_iff_conj_array(int v0, int n, int arr[]);
 /* returns v0 \leftrightarrow \bigwedge_{i=0}^{n} v_i */
-extern node *iff_conj(int v0, int n, int v1, int v2, int v3, int v4, int v5,
+extern MR_ROBDD_node *iff_conj(int v0, int n, int v1, int v2, int v3, int v4, int v5,
 		      int v6, int v7, int v8, int v9, int v10, int v11,
 		      int v12, int v13, int v14, int v15, int v16);
-/* returns non-zero iff f entails variable number var */
-extern int var_entailed(node *f, int var);
+/* returns non-MR_ROBDD_zero iff f entails variable number var */
+extern int MR_ROBDD_var_entailed(MR_ROBDD_node *f, int var);
 
 /* Finds the smallest n such that n \in set and n \geq *var.  word and */
-/* mask must be as set by BITSET_WORD(*var) and BITSET_MASK(*var), */
+/* mask must be as set by MR_ROBDD_BITSET_WORD(*var) and MR_ROBDD_BITSET_MASK(*var), */
 /* respectively.  The resulting n is placed in *var, and *word and *mask */
-/* are updated correspondingly.  Returns TRUE iff there is such an n. */
-int next_element(bitset *set, int *var, int *word, bitmask *mask);
+/* are updated correspondingly.  Returns MR_TRUE iff there is such an n. */
+int MR_ROBDD_next_element(MR_ROBDD_bitset *set, int *var, int *word, MR_ROBDD_bitmask *mask);
 
 /* Finds the largest n such that n \in set and n \leq *var.  word and */
-/* mask must be as set by BITSET_WORD(*var) and BITSET_MASK(*var), */
+/* mask must be as set by MR_ROBDD_BITSET_WORD(*var) and MR_ROBDD_BITSET_MASK(*var), */
 /* respectively.  The resulting n is placed in *var, and *word and *mask */
-/* are updated correspondingly.  Returns TRUE iff there is such an n. */
-int prev_element(bitset *set, int *var, int *word, bitmask *mask);
+/* are updated correspondingly.  Returns MR_TRUE iff there is such an n. */
+int MR_ROBDD_prev_element(MR_ROBDD_bitset *set, int *var, int *word, MR_ROBDD_bitmask *mask);
 
 /* Finds the smallest n such that n \not \in set and n \geq *var.  word and */
-/* mask must be as set by BITSET_WORD(*var) and BITSET_MASK(*var), */
+/* mask must be as set by MR_ROBDD_BITSET_WORD(*var) and MR_ROBDD_BITSET_MASK(*var), */
 /* respectively.  The resulting n is placed in *var, and *word and *mask */
-/* are updated correspondingly.  Returns TRUE iff there is such an n. */
-int next_nonelement(bitset *set, int *var, int *word, bitmask *mask);
+/* are updated correspondingly.  Returns MR_TRUE iff there is such an n. */
+int MR_ROBDD_next_nonelement(MR_ROBDD_bitset *set, int *var, int *word, MR_ROBDD_bitmask *mask);
 
 /* Finds the largest n such that n \not \in set and n \leq *var.  word and */
-/* mask must be as set by BITSET_WORD(*var) and BITSET_MASK(*var), */
+/* mask must be as set by MR_ROBDD_BITSET_WORD(*var) and MR_ROBDD_BITSET_MASK(*var), */
 /* respectively.  The resulting n is placed in *var, and *word and *mask */
-/* are updated correspondingly.  Returns TRUE iff there is such an n. */
-int prev_nonelement(bitset *set, int *var, int *word, bitmask *mask);
+/* are updated correspondingly.  Returns MR_TRUE iff there is such an n. */
+int MR_ROBDD_prev_nonelement(MR_ROBDD_bitset *set, int *var, int *word, MR_ROBDD_bitmask *mask);
 
+#if !defined(MR_ROBDD_USE_THRESH) && !defined(MR_ROBDD_RESTRICT_SET)
 
-#if !defined(USE_THRESH) && !defined(RESTRICT_SET)
+  /* returns a with all variables lo \leq v \leq hi restricted away */
+  extern MR_ROBDD_node *MR_ROBDD_restrictThresh(int lo, int hi, MR_ROBDD_node *a);
 
-/* returns a with all variables lo \leq v \leq hi restricted away */
-extern node *restrictThresh(int lo, int hi, node *a);
+  /* returns f \wedge g with all variables lo \leq v \leq hi restricted away */
+  extern MR_ROBDD_node *MR_ROBDD_restricted_glb(int lo, int hi, MR_ROBDD_node *f, MR_ROBDD_node *g);
 
-/* returns f \wedge g with all variables lo \leq v \leq hi restricted away */
-extern node *restricted_glb(int lo, int hi, node *f, node *g);
-
-/* computes g = f with variable 0 renamed to mapping[0], 1 renamed to */
-/* mapping[1], ... count renamed to mapping[count].  Returns context */
-/* \wedge g with all variables lo \leq v \leq hi restricted away */
-extern node *abstract_exit(node *context, node *f, int count, int mapping[],
+  /* computes g = f with variable 0 renamed to mapping[0], 1 renamed to */
+  /* mapping[1], ... count renamed to mapping[count].  Returns context */
+  /* \wedge g with all variables lo \leq v \leq hi restricted away */
+  extern MR_ROBDD_node *MR_ROBDD_abstract_exit(MR_ROBDD_node *context, MR_ROBDD_node *f, int count, int mapping[],
+		    int lo, int hi);
+  /* returns f \wedge (v0 \leftrightarrow \bigwedge_{i=0}^{n} arr[i]), */
+  /* with all variables lo \leq v \leq hi restricted away */
+  extern MR_ROBDD_node *MR_ROBDD_abstract_unify(MR_ROBDD_node *f, int v0, int n, int arr[],
 		    int lo, int hi);
-/* returns f \wedge (v0 \leftrightarrow \bigwedge_{i=0}^{n} arr[i]), */
-/* with all variables lo \leq v \leq hi restricted away */
-extern node *abstract_unify(node *f, int v0, int n, int arr[], int lo, int hi);
-#else /* USE_THRESH || RESTRICT_SET */
-
-/* returns a with all variables lo \leq v \leq hi restricted away */
-extern node *restrictThresh(int c,node *a);
-
-/* returns f \wedge g with all variables v \geq c restricted away */
-extern node *restricted_glb(int c, node *f, node *g);
-
-/* computes g = f with variable 0 renamed to mapping[0], 1 renamed to */
-/* mapping[1], ... count renamed to mapping[count].  Returns context */
-/* \wedge g with all variables v \geq thresh restricted away */
-extern node *abstract_exit(node *context, node *f, int count, int mapping[],
+
+#else /* MR_ROBDD_USE_THRESH || MR_ROBDD_RESTRICT_SET */
+
+  /* returns a with all variables lo \leq v \leq hi restricted away */
+  extern MR_ROBDD_node *MR_ROBDD_restrictThresh(int c,MR_ROBDD_node *a);
+
+  /* returns f \wedge g with all variables v \geq c restricted away */
+  extern MR_ROBDD_node *MR_ROBDD_restricted_glb(int c, MR_ROBDD_node *f, MR_ROBDD_node *g);
+
+  /* computes g = f with variable 0 renamed to mapping[0], 1 renamed to */
+  /* mapping[1], ... count renamed to mapping[count].  Returns context */
+  /* \wedge g with all variables v \geq thresh restricted away */
+  extern MR_ROBDD_node *MR_ROBDD_abstract_exit(MR_ROBDD_node *context, MR_ROBDD_node *f, int count, int mapping[],
 		    int thresh);
 
-/* returns f \wedge (v0 \leftrightarrow \bigwedge_{i=0}^{n} arr[i]), */
-/* with all variables v \eq thresh restricted away */
-extern node *abstract_unify(node *f, int v0, int n, int arr[], int thresh);
-#endif /* !OLD || USE_THRESH */
-
-#if !defined(NEW)
-/* returns the set of all v entailed by f where v \leq topvar */
-extern bitset *vars_entailed(node *f, int topvar);
-#else /* NEW */
-/* returns the set of all v entailed by f */
-extern bitset *vars_entailed(node *f);
-#endif /* NEW */
+  /* returns f \wedge (v0 \leftrightarrow \bigwedge_{i=0}^{n} arr[i]), */
+  /* with all variables v \eq thresh restricted away */
+  extern MR_ROBDD_node *MR_ROBDD_abstract_unify(MR_ROBDD_node *f, int v0, int n, int arr[], int thresh);
+
+#endif /* !MR_ROBDD_OLD || MR_ROBDD_USE_THRESH */
+
+#if !defined(MR_ROBDD_NEW)
+  /* returns the set of all v MR_ROBDD_entailed by f where v \leq MR_ROBDD_topvar */
+  extern MR_ROBDD_bitset *MR_ROBDD_vars_entailed(MR_ROBDD_node *f, int MR_ROBDD_topvar);
+#else /* MR_ROBDD_NEW */
+  /* returns the set of all v MR_ROBDD_entailed by f */
+  extern MR_ROBDD_bitset *MR_ROBDD_vars_entailed(MR_ROBDD_node *f);
+#endif /* MR_ROBDD_NEW */
 
 /* return the initial set sharing representation for n variables */
-extern node *init_set_sharing(int n);
+extern MR_ROBDD_node *MR_ROBDD_init_set_sharing(int n);
 /* computes the set sharing upward closure of f */
-extern node *upclose(node *f);
-/* performs Langen's bin operation, used for set sharing analysis */
-extern node *bin(node *f, node *g);
+extern MR_ROBDD_node *MR_ROBDD_upclose(MR_ROBDD_node *f);
+/* performs Langen's MR_ROBDD_bin operation, used for set sharing analysis */
+extern MR_ROBDD_node *MR_ROBDD_bin(MR_ROBDD_node *f, MR_ROBDD_node *g);
 
 /* prints out the bryant graph a */
-extern void printOut(node *a);
+extern void printOut(MR_ROBDD_node *a);
 
 /* for profiling purposes:  return the number of ROBDD nodes in use */
-extern int nodes_in_use(void);
-/* for profiling only:  the same as iff_conj_array(), but as efficient */
+extern int MR_ROBDD_nodes_in_use(void);
+/* for profiling only:  the same as MR_ROBDD_iff_conj_array(), but as efficient */
 /* as possible, whatever variables are #defined */
-node *testing_iff_conj_array(int v0, int n, int arr[]);
-
+MR_ROBDD_node *MR_ROBDD_testing_iff_conj_array(int v0, int n, int arr[]);
 
 /* These are not really useful for ROBDDs but are needed for other */
 /* representations of Boolean functions. */
 /* free n */
-extern void free_rep(node *n);
+extern void MR_ROBDD_free_rep(MR_ROBDD_node *n);
 /* free n if it doesn't share with m */
-extern void free_rep_if_diff(node *n, node *m);
-/* returns a copy of a.  For ROBDDs this is just a */
-extern node *copy(node *a);
-/* returns non-zero iff a = b; for ROBDDs, use a==b instead */
-extern int equiv(node *a, node *b);
+extern void free_rep_if_diff(MR_ROBDD_node *n, MR_ROBDD_node *m);
+/* returns a MR_ROBDD_copy of a.  For ROBDDs this is just a */
+extern MR_ROBDD_node *MR_ROBDD_copy(MR_ROBDD_node *a);
+/* returns non-MR_ROBDD_zero iff a = b; for ROBDDs, use a==b instead */
+extern int MR_ROBDD_equiv(MR_ROBDD_node *a, MR_ROBDD_node *b);
 
 /* for a more efficient interface from Quintus Prolog. */
 #if defined(QUINTUS)
-extern node *renameTerm(node *in, QP_term_ref term);
-extern node *reverseRenameTerm(node *in, QP_term_ref term);
+  extern MR_ROBDD_node *renameTerm(MR_ROBDD_node *in, QP_term_ref term);
+  extern MR_ROBDD_node *reverseRenameTerm(MR_ROBDD_node *in, QP_term_ref term);
 #endif /* QUINTUS */
+
+#endif /* MERCURY_BRYANT_H */
Index: robdd/bryantPrint.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/bryantPrint.c,v
retrieving revision 1.1
diff -u -b -r1.1 bryantPrint.c
--- robdd/bryantPrint.c	10 Mar 2000 05:17:21 -0000	1.1
+++ robdd/bryantPrint.c	6 Jan 2003 02:23:06 -0000
@@ -1,3 +1,9 @@
+/*
+** Copyright (C) 2003 Peter Schachte and 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.
+*/
+
 #include <stdio.h>
 #include <stdlib.h>
 #ifdef QUINTUS
@@ -7,42 +13,42 @@
 #include "bryantPrint.h"
 
 
-int print_bryant(node *f, bitset *trues, bitset *falses, int terms);
+int print_bryant(MR_ROBDD_node *f, MR_ROBDD_bitset *trues, MR_ROBDD_bitset *falses, int terms);
 
 
 /* Print out an ROBDD in some readable format.  We display it in disjunctive
  * form.
  */
 
-void printOut(node *f)
+void printOut(MR_ROBDD_node *f)
     {
-	bitset trues, falses;
+	MR_ROBDD_bitset trues, falses;
 
-	if (f == one) {
-	    printf("TRUE");
-	} else if (f == zero) {
-	    printf("FALSE");
+	if (f == MR_ROBDD_one) {
+	    printf("MR_TRUE");
+	} else if (f == MR_ROBDD_zero) {
+	    printf("MR_FALSE");
 	} else {
-	    BITSET_CLEAR(trues);
-	    BITSET_CLEAR(falses);
+	    MR_ROBDD_BITSET_CLEAR(trues);
+	    MR_ROBDD_BITSET_CLEAR(falses);
 	    (void)print_bryant(f, &trues, &falses, 0);
 	}
     }
 
 
-int print_bryant(node *f, bitset *trues, bitset *falses, int terms)
+int print_bryant(MR_ROBDD_node *f, MR_ROBDD_bitset *trues, MR_ROBDD_bitset *falses, int terms)
     {
-	if (f == one) {
-	    bitset all;
+	if (f == MR_ROBDD_one) {
+	    MR_ROBDD_bitset all;
 	    int var;
 	    int word;
-	    bitmask mask;
+	    MR_ROBDD_bitmask mask;
 	    char sep = '(';
 
 	    if (terms>0) printf(" ");
-	    BITSET_UNION(all, *trues, *falses);
-	    FOREACH_ELEMENT(all, var, word, mask) {
-		if (BITSET_MEMBER(*trues, word, mask)) {
+	    MR_ROBDD_BITSET_UNION(all, *trues, *falses);
+	    MR_ROBDD_FOREACH_ELEMENT(all, var, word, mask) {
+		if (MR_ROBDD_BITSET_MEMBER(*trues, word, mask)) {
 		    printf("%c%d", sep, var);
 		} else {
 		    printf("%c~%d", sep, var);
@@ -51,14 +57,14 @@
 	    }
 	    printf(")");
 	    ++terms;
-	} else if (f != zero) {
-	    BITSET_ADD_ELEMENT(*trues, f->value);
+	} else if (f != MR_ROBDD_zero) {
+	    MR_ROBDD_BITSET_ADD_ELEMENT(*trues, f->value);
 	    terms += print_bryant(f->tr, trues, falses, terms);
-	    BITSET_TOGGLE_ELEMENT(*trues, f->value);
-	    BITSET_ADD_ELEMENT(*falses, f->value);
+	    MR_ROBDD_BITSET_TOGGLE_ELEMENT(*trues, f->value);
+	    MR_ROBDD_BITSET_ADD_ELEMENT(*falses, f->value);
 	    terms += print_bryant(f->fa, trues, falses, terms);
-	    BITSET_TOGGLE_ELEMENT(*falses, f->value);
+	    MR_ROBDD_BITSET_TOGGLE_ELEMENT(*falses, f->value);
 	}
-	/* don't do anything for zero terminal */
+	/* don't do anything for MR_ROBDD_zero terminal */
 	return terms;
     }
Index: robdd/table.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/table.c,v
retrieving revision 1.1
diff -u -b -r1.1 table.c
--- robdd/table.c	10 Mar 2000 05:17:21 -0000	1.1
+++ robdd/table.c	6 Jan 2003 02:23:15 -0000
@@ -1,3 +1,9 @@
+/*
+** Copyright (C) 2003 Peter Schachte and 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.
+*/
+
 #include <stdio.h>
 #include <stdlib.h>
 #include "bryant.h"
@@ -5,27 +11,27 @@
 
 #define TABLESIZE 4096
 
-node *lookupUniqueTable(int val, node *tr, node *fa);
-void insertUniqueTable(node *newnode);
+MR_ROBDD_node *lookupUniqueTable(int val, MR_ROBDD_node *tr, MR_ROBDD_node *fa);
+void insertUniqueTable(MR_ROBDD_node *newnode);
 
-node *checkComputed(node *f,node *g, node *h);
-void insertComputed(node *f, node *g, node *h, node *result);
+MR_ROBDD_node *checkComputed(MR_ROBDD_node *f,MR_ROBDD_node *g, MR_ROBDD_node *h);
+void insertComputed(MR_ROBDD_node *f, MR_ROBDD_node *g, MR_ROBDD_node *h, MR_ROBDD_node *result);
 
 void printUnique();	/* prints no. of entries in Unique table */
 
-static node *unique[TABLESIZE];
+static MR_ROBDD_node *unique[TABLESIZE];
 static iteEntry	computed[TABLESIZE];
 
-static int findHashUnique(int var, node *tr, node *fa);
-static int findHashComputed(node *f, node *g, node *h);
+static int findHashUnique(int var, MR_ROBDD_node *tr, MR_ROBDD_node *fa);
+static int findHashComputed(MR_ROBDD_node *f, MR_ROBDD_node *g, MR_ROBDD_node *h);
 
-node *lookupUniqueTable(int val, node *tr, node *fa)
-/* checks to see if node (val,tr,fa) exists, and if so returns pointer to
-that node, otherwise returns null */
-{
-        extern node *unique[];
-        node *entry;
-        node *result;
+MR_ROBDD_node *lookupUniqueTable(int val, MR_ROBDD_node *tr, MR_ROBDD_node *fa)
+/* checks to see if MR_ROBDD_node (val,tr,fa) exists, and if so returns pointer to
+that MR_ROBDD_node, otherwise returns null */
+{
+        extern MR_ROBDD_node *unique[];
+        MR_ROBDD_node *entry;
+        MR_ROBDD_node *result;
 	int hash;
 
         result = NULL;
@@ -43,13 +49,13 @@
         }
         return result;
 }
-void insertUniqueTable(node *newnode)
+void insertUniqueTable(MR_ROBDD_node *newnode)
 {
-/* inserts the node newnode into the unique table */
+/* inserts the MR_ROBDD_node newnode into the unique table */
 /* insertion is at head of list */
-        extern node *unique[];
-        node *first;
-        node *newentry;
+        extern MR_ROBDD_node *unique[];
+        MR_ROBDD_node *first;
+        MR_ROBDD_node *newentry;
 	int hash;
 
 	/* find hash value - get 12 bits, ie. 4096, size of unique */
@@ -61,7 +67,7 @@
 
 void printUnique()
 {
-        node *t;
+        MR_ROBDD_node *t;
         int i;
         int cnt;
 	int total;
@@ -90,7 +96,7 @@
 	printf("total nodes is %d: longest string is %d\n",total,longest);
 }
 
-node *checkComputed(node *f,node *g, node *h)
+MR_ROBDD_node *checkComputed(MR_ROBDD_node *f,MR_ROBDD_node *g, MR_ROBDD_node *h)
 {
 	extern iteEntry computed[];
 	int hash;
@@ -105,14 +111,14 @@
 	}
 	return NULL;
 }
-void insertComputed(node *f, node *g, node *h, node *result)
+void insertComputed(MR_ROBDD_node *f, MR_ROBDD_node *g, MR_ROBDD_node *h, MR_ROBDD_node *result)
 {
 	extern iteEntry computed[];
 	int hash;
 	int i;
 
 	/* find hash value - get 12 bits, ie. 4096, size of computed */
-	/* check hashing function, g or h is always zero or one */
+	/* check hashing function, g or h is always MR_ROBDD_zero or MR_ROBDD_one */
 
 	hash = findHashComputed(f,g,h);
 
@@ -132,14 +138,14 @@
 */
 }
 
-static int findHashUnique(int var, node *tr, node *fa)
+static int findHashUnique(int var, MR_ROBDD_node *tr, MR_ROBDD_node *fa)
 {
 	/* find hash value - get 12 bits, ie. 4096, size of unique */
 	return (var + ((long)tr << 1) +
 			((long)fa >> 2)) & 0xfff;
 }
 
-static int findHashComputed(node *f, node *g, node *h)
+static int findHashComputed(MR_ROBDD_node *f, MR_ROBDD_node *g, MR_ROBDD_node *h)
 {
 	/* find hash value - get 12 bits, ie. 4096, size of computed */
 	return  (((long)h) + ((long)g << 1) +
Index: robdd/table.h
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/table.h,v
retrieving revision 1.1
diff -u -b -r1.1 table.h
--- robdd/table.h	10 Mar 2000 05:17:22 -0000	1.1
+++ robdd/table.h	6 Jan 2003 02:23:23 -0000
@@ -1,6 +1,12 @@
+/*
+** Copyright (C) 2003 Peter Schachte and 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.
+*/
+
 typedef struct IteEntry{
-	node *f;
-	node *g;
-	node *h;
-	node *where;
+	MR_ROBDD_node *f;
+	MR_ROBDD_node *g;
+	MR_ROBDD_node *h;
+	MR_ROBDD_node *where;
 	}iteEntry;
Index: robdd/test_abexit.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/test_abexit.c,v
retrieving revision 1.1
diff -u -b -r1.1 test_abexit.c
--- robdd/test_abexit.c	10 Mar 2000 05:17:22 -0000	1.1
+++ robdd/test_abexit.c	6 Jan 2003 02:25:13 -0000
@@ -1,9 +1,15 @@
+/*
+** Copyright (C) 1995,2003 Peter Schachte and 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     : test_abexit.c
   RCS      : $Id: test_abexit.c,v 1.1 2000/03/10 05:17:22 dmo Exp $
   Author   : Peter Schachte
   Origin   : Tue Aug  1 11:27:35 1995
-  Purpose  : Timing test for bryant graph abstract_exit code
+  Purpose  : Timing test for bryant graph MR_ROBDD_abstract_exit code
 
 *****************************************************************/
 
@@ -24,56 +30,56 @@
     }
 
 
-void init_array(int top, int array[], bitset *usedvars)
+void init_array(int top, int array[], MR_ROBDD_bitset *usedvars)
     {
 	int i, word;
-	bitmask mask;
+	MR_ROBDD_bitmask mask;
 
-	BITSET_CLEAR(*usedvars);
-	FOREACH_POSSIBLE_ELEMENT(i, word, mask) {
+	MR_ROBDD_BITSET_CLEAR(*usedvars);
+	MR_ROBDD_FOREACH_POSSIBLE_ELEMENT(i, word, mask) {
 	    if (i >= top) break;
 	    array[i] = i;
-	    BITSET_ADD(*usedvars, word, mask);
+	    MR_ROBDD_BITSET_ADD(*usedvars, word, mask);
 	}
     }
 
 
 
-int next_array(int n, int varmax, int array[], bitset *usedvars)
+int next_array(int n, int varmax, int array[], MR_ROBDD_bitset *usedvars)
     {
 	int i, word;
-	bitmask mask;
+	MR_ROBDD_bitmask mask;
 	int elt;
 
 	/* Search backward for first cell with "room" to be incremented. */
 	for (i=n-1;; --i) {
-	    if (i<0) return FALSE;	/* no more combinations possible */
+	    if (i<0) return MR_FALSE;	/* no more combinations possible */
 	    elt=array[i];
-	    word = BITSET_WORD(elt);
-	    mask = BITSET_MASK(elt);
-	    BITSET_REMOVE(*usedvars, word, mask);
-	    (void) NEXT_POSSIBLE_ELEMENT(elt, word, mask);
-	    if (next_nonelement(usedvars, &elt, &word, &mask) && elt<varmax)
+	    word = MR_ROBDD_BITSET_WORD(elt);
+	    mask = MR_ROBDD_BITSET_MASK(elt);
+	    MR_ROBDD_BITSET_REMOVE(*usedvars, word, mask);
+	    (void) MR_ROBDD_NEXT_POSSIBLE_ELEMENT(elt, word, mask);
+	    if (MR_ROBDD_next_nonelement(usedvars, &elt, &word, &mask) && elt<varmax)
 	      break;
 	}
 	for (; i<n; ++i) {
 	    array[i] = elt;
-	    BITSET_ADD(*usedvars, word, mask);
+	    MR_ROBDD_BITSET_ADD(*usedvars, word, mask);
 	    elt = 0;
-	    word = BITSET_WORD(0);
-	    mask = BITSET_MASK(0);
-	    if (!next_nonelement(usedvars, &elt, &word, &mask)) return FALSE;
+	    word = MR_ROBDD_BITSET_WORD(0);
+	    mask = MR_ROBDD_BITSET_MASK(0);
+	    if (!MR_ROBDD_next_nonelement(usedvars, &elt, &word, &mask)) return MR_FALSE;
 	}
-	return TRUE;
+	return MR_TRUE;
     }
 
 
-void doit(int n, int array[], int varmax, type *f, type *g, int thresh)
+void doit(int n, int array[], int varmax, MR_ROBDD_type *f, MR_ROBDD_type *g, int thresh)
     {
-	type *result;
+	MR_ROBDD_type *result;
 #ifdef DEBUGALL
 	int i;
-	printf("abstract_exit(");
+	printf("MR_ROBDD_abstract_exit(");
 	printOut(f),
 	printf(", ");
 	printOut(g),
@@ -82,11 +88,11 @@
 	printf("], %d {, %d}) = ", thresh, varmax);
 	fflush(stdout);
 #endif /* DEBUGALL */
-#if !defined(USE_THRESH) && !defined(RESTRICT_SET)
-	result = abstract_exit(f, g, n, array, thresh, varmax);
-#else /* USE_THRESH */
-	result = abstract_exit(f, g, n, array, thresh);
-#endif /* !OLD || USE_THRESH */
+#if !defined(MR_ROBDD_USE_THRESH) && !defined(MR_ROBDD_RESTRICT_SET)
+	result = MR_ROBDD_abstract_exit(f, g, n, array, thresh, varmax);
+#else /* MR_ROBDD_USE_THRESH */
+	result = MR_ROBDD_abstract_exit(f, g, n, array, thresh);
+#endif /* !MR_ROBDD_OLD || MR_ROBDD_USE_THRESH */
 #ifdef DEBUGALL
 	printOut(result);
 	printf("\n");
@@ -95,7 +101,7 @@
     }
 
 
-void dont_doit(int n, int array[], int varmax, type *f, type *g, int thresh)
+void dont_doit(int n, int array[], int varmax, MR_ROBDD_type *f, MR_ROBDD_type *g, int thresh)
     {
     }
 
@@ -104,9 +110,9 @@
     {
 	int varmax, size, repetitions;
 	int array[MAXVAR];
-	bitset set;
+	MR_ROBDD_bitset set;
 	int reps, i, thresh;
-	type *f, *g;
+	MR_ROBDD_type *f, *g;
 	millisec clock0, clock1, clock2, clock3;
 	float runtime, overhead, rate;
 	int test_nodes, overhead_nodes;
@@ -129,12 +135,12 @@
 	if (repetitions <= 0) repetitions = 1;
 
 	for (i=0; i<size/2; ++i) array[i] = i*2;
-	f = testing_iff_conj_array(((size-1)/2)|1, size/2, array);
+	f = MR_ROBDD_testing_iff_conj_array(((size-1)/2)|1, size/2, array);
 
 	for (i=0; i<(size-1)/2; ++i) array[i] = i*2+1;
-	g = testing_iff_conj_array(0, (size-1)/2, array);
+	g = MR_ROBDD_testing_iff_conj_array(0, (size-1)/2, array);
 	for (i=0; i<(size-2)/2; ++i) array[i] = i*2+2;
-	g = glb(g, testing_iff_conj_array(size-1, (size-2)/2, array));
+	g = MR_ROBDD_glb(g, MR_ROBDD_testing_iff_conj_array(size-1, (size-2)/2, array));
 
 	thresh = size/2;
 
@@ -148,13 +154,13 @@
 	    }
 	}
 	clock1 = milli_time();
-	test_nodes = nodes_in_use();
-	initRep();
+	test_nodes = MR_ROBDD_nodes_in_use();
+	MR_ROBDD_initRep();
 
 	for (i=0; i<(size-1)/2; ++i) array[i] = i*2+1;
-	f = testing_iff_conj_array(0, (size-1)/2, array);
+	f = MR_ROBDD_testing_iff_conj_array(0, (size-1)/2, array);
 	for (i=0; i<(size-2)/2; ++i) array[i] = i*2+2;
-	f = glb(f, testing_iff_conj_array(size-1, (size-2)/2, array));
+	f = MR_ROBDD_glb(f, MR_ROBDD_testing_iff_conj_array(size-1, (size-2)/2, array));
 
 	clock2 = milli_time();
 	for (reps=repetitions; reps>0; --reps) {
@@ -165,7 +171,7 @@
 	    }
 	}
 	clock3 = milli_time();
-	overhead_nodes = nodes_in_use();
+	overhead_nodes = MR_ROBDD_nodes_in_use();
 	runtime = (float)(clock1-clock0)/1000;
 	overhead = (float)(clock3-clock2)/1000;
 	rate = ((float)opcount)/(runtime-overhead);
Index: robdd/test_abunify.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/test_abunify.c,v
retrieving revision 1.1
diff -u -b -r1.1 test_abunify.c
--- robdd/test_abunify.c	10 Mar 2000 05:17:22 -0000	1.1
+++ robdd/test_abunify.c	6 Jan 2003 02:25:16 -0000
@@ -1,9 +1,15 @@
+/*
+** Copyright (C) 1995,2003 Peter Schachte and 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     : test_abunify.c
   RCS      : $Id: test_abunify.c,v 1.1 2000/03/10 05:17:22 dmo Exp $
   Author   : Peter Schachte
   Origin   : Fri Aug  4 14:39:44 1995
-  Purpose  : Timing test for bryant graph abstract_unify code
+  Purpose  : Timing test for bryant graph MR_ROBDD_abstract_unify code
 
 *****************************************************************/
 
@@ -18,7 +24,7 @@
 void usage(char *progname)
     {
 	printf("usage:  %s size maxvar [repetitions]\n", progname);
-	printf("  for all possible v <-> v1 & v2 & ... & vsize functions, computes the glb\n");
+	printf("  for all possible v <-> v1 & v2 & ... & vsize functions, computes the MR_ROBDD_glb\n");
 	printf("  of that and each possible v <-> v1 & v2 & ... & vsize function, restricted\n");
 	printf("  to each threshold between 0 and maxvar.  Each v and the vi are between 0\n");
 	printf("  and maxvar inclusive.  If repetitions is >0, this will be done that many\n");
@@ -65,13 +71,13 @@
     }
 
 
-void doit(int thresh, int varmax, type *f, int v0, int n, int arr[])
+void doit(int thresh, int varmax, MR_ROBDD_type *f, int v0, int n, int arr[])
     {
-	type *result;
+	MR_ROBDD_type *result;
 #ifdef DEBUGALL
 	int i;
 
-	printf("abstract_unify(");
+	printf("MR_ROBDD_abstract_unify(");
 	printOut(f);
 	printf(", %d, %d, [", v0, n);
 	if (n>0) {
@@ -82,11 +88,11 @@
 	fflush(stdout);
 #endif /* DEBUGALL */
 #ifndef OVERHEAD
-#if !defined(USE_THRESH) && !defined(RESTRICT_SET)
-	result = abstract_unify(f, v0, n, arr, thresh, varmax);
-#else /* USE_THRESH */
-	result = abstract_unify(f, v0, n, arr, thresh);
-#endif /* OLD */
+#if !defined(MR_ROBDD_USE_THRESH) && !defined(MR_ROBDD_RESTRICT_SET)
+	result = MR_ROBDD_abstract_unify(f, v0, n, arr, thresh, varmax);
+#else /* MR_ROBDD_USE_THRESH */
+	result = MR_ROBDD_abstract_unify(f, v0, n, arr, thresh);
+#endif /* MR_ROBDD_OLD */
 #ifdef DEBUGALL
 	printOut(result);
 	printf("\n");
@@ -96,12 +102,12 @@
     }
 
 
-void dont_doit(int thresh, int varmax, type *f, int v0, int n, int arr[])
+void dont_doit(int thresh, int varmax, MR_ROBDD_type *f, int v0, int n, int arr[])
     {
     }
 
 
-void inner_loop(int varmax, int top, int thresh, type *f)
+void inner_loop(int varmax, int top, int thresh, MR_ROBDD_type *f)
     {
 	int arrayg[MAXVAR];
 	int vg;
@@ -117,7 +123,7 @@
 
 
 
-void dont_inner_loop(int varmax, int top, int thresh, type *f)
+void dont_inner_loop(int varmax, int top, int thresh, MR_ROBDD_type *f)
     {
 	int arrayg[MAXVAR];
 	int vg;
@@ -138,7 +144,7 @@
 	int varmax, size, repetitions;
 	int arrayf[MAXVAR];
 	int reps, vf, thresh;
-	type *f;
+	MR_ROBDD_type *f;
 	millisec clock0, clock1, clock2, clock3;
 	float runtime, overhead, rate;
 	int test_nodes, overhead_nodes;
@@ -166,34 +172,34 @@
 	    for (thresh=0; thresh<=varmax; ++thresh) {
 		for (vf=0; vf<varmax; ++vf) {
 		    init_array(size, vf, arrayf);
-		    f = testing_iff_conj_array(vf, size, arrayf);
+		    f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 		    inner_loop(varmax, size, thresh, f);
 		    while (next_array(size, varmax, vf, arrayf)) {
-			f = testing_iff_conj_array(vf, size, arrayf);
+			f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 			inner_loop(varmax, size, thresh, f);
 		    }
 		}
 	    }
 	}
 	clock1 = milli_time();
-	test_nodes = nodes_in_use();
-	initRep();
+	test_nodes = MR_ROBDD_nodes_in_use();
+	MR_ROBDD_initRep();
 	clock2 = milli_time();
 	for (reps=repetitions; reps>0; --reps) {
 	    for (thresh=0; thresh<=varmax; ++thresh) {
 		for (vf=0; vf<varmax; ++vf) {
 		    init_array(size, vf, arrayf);
-		    f = testing_iff_conj_array(vf, size, arrayf);
+		    f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 		    dont_inner_loop(varmax, size, thresh, f);
 		    while (next_array(size, varmax, vf, arrayf)) {
-			f = testing_iff_conj_array(vf, size, arrayf);
+			f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 			dont_inner_loop(varmax, size, thresh, f);
 		    }
 		}
 	    }
 	}
 	clock3 = milli_time();
-	overhead_nodes = nodes_in_use();
+	overhead_nodes = MR_ROBDD_nodes_in_use();
 	runtime = (float)(clock1-clock0)/1000;
 	overhead = (float)(clock3-clock2)/1000;
 	rate = ((float)opcount)/(runtime-overhead);
Index: robdd/test_glb.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/test_glb.c,v
retrieving revision 1.1
diff -u -b -r1.1 test_glb.c
--- robdd/test_glb.c	10 Mar 2000 05:17:22 -0000	1.1
+++ robdd/test_glb.c	6 Jan 2003 02:25:20 -0000
@@ -1,9 +1,15 @@
+/*
+** Copyright (C) 1995,2003 Peter Schachte and 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   : test_glb.c
     RCS    : $Id: test_glb.c,v 1.1 2000/03/10 05:17:22 dmo Exp $
     Author : Peter Schachte
     Origin : Thu Jul 13 14:25:12 1995
-    Purpose: Timing test for bryant graph glb code
+    Purpose: Timing test for bryant graph MR_ROBDD_glb code
 
 *****************************************************************/
 
@@ -20,7 +26,7 @@
     {
 	printf("usage:  %s size maxvar [repetitions]\n", progname);
 	printf("  creates all possible pairs of v <-> v1 & v2 & ... & vsize functions and\n");
-	printf("  computes their glb.  Each V and the vi are between 0 and maxvar inclusive.\n");
+	printf("  computes their MR_ROBDD_glb.  Each V and the vi are between 0 and maxvar inclusive.\n");
 	printf("  If repetitions is >0, this will be done that many times.\n");
     }
 
@@ -64,11 +70,11 @@
     }
 
 
-void doit(type *f, type *g)
+void doit(MR_ROBDD_type *f, MR_ROBDD_type *g)
     {
-	type *result;
+	MR_ROBDD_type *result;
 #ifdef DEBUGALL
-	printf("glb("),
+	printf("MR_ROBDD_glb("),
 	printOut(f),
 	printf(", ");
 	printOut(g),
@@ -76,7 +82,7 @@
 	fflush(stdout);
 #endif /* DEBUGALL */
 #ifndef OVERHEAD
-	result = glb(f, g);
+	result = MR_ROBDD_glb(f, g);
 #endif /* !OVERHEAD */
 #ifdef DEBUGALL
 	printOut(result);
@@ -85,22 +91,22 @@
 	++opcount;
     }
 
-void dont_doit(type *f, type *g)
+void dont_doit(MR_ROBDD_type *f, MR_ROBDD_type *g)
     {
     }
 
-void inner_loop(int varmax, int top, type *f)
+void inner_loop(int varmax, int top, MR_ROBDD_type *f)
     {
 	int arrayg[33];
 	int vg;
-	type *g;
+	MR_ROBDD_type *g;
 
 	for (vg=0; vg<varmax; ++vg) {
 	    init_array(top, vg, arrayg);
-	    g = testing_iff_conj_array(vg, top, arrayg);
+	    g = MR_ROBDD_testing_iff_conj_array(vg, top, arrayg);
 	    doit(f, g);
 	    while (next_array(top, varmax, vg, arrayg)) {
-		g = testing_iff_conj_array(vg, top, arrayg);
+		g = MR_ROBDD_testing_iff_conj_array(vg, top, arrayg);
 		doit(f, g);
 	    }
 	}
@@ -108,18 +114,18 @@
 
 
 
-void dont_inner_loop(int varmax, int top, type *f)
+void dont_inner_loop(int varmax, int top, MR_ROBDD_type *f)
     {
 	int arrayg[33];
 	int vg;
-	type *g;
+	MR_ROBDD_type *g;
 
 	for (vg=0; vg<varmax; ++vg) {
 	    init_array(top, vg, arrayg);
-	    g = testing_iff_conj_array(vg, top, arrayg);
+	    g = MR_ROBDD_testing_iff_conj_array(vg, top, arrayg);
 	    dont_doit(f, g);
 	    while (next_array(top, varmax, vg, arrayg)) {
-		g = testing_iff_conj_array(vg, top, arrayg);
+		g = MR_ROBDD_testing_iff_conj_array(vg, top, arrayg);
 		dont_doit(f, g);
 	    }
 	}
@@ -132,7 +138,7 @@
 	int varmax, size, repetitions;
 	int arrayf[VARLIMIT];
 	int reps, vf;
-	type *f;
+	MR_ROBDD_type *f;
 	millisec clock0, clock1, clock2, clock3;
 	float runtime, overhead, rate;
 	int test_nodes, overhead_nodes;
@@ -159,31 +165,31 @@
 	for (reps=repetitions; reps>0; --reps) {
 	    for (vf=0; vf<varmax; ++vf) {
 		init_array(size, vf, arrayf);
-		f = testing_iff_conj_array(vf, size, arrayf);
+		f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 		inner_loop(varmax, size, f);
 		while (next_array(size, varmax, vf, arrayf)) {
-		    f = testing_iff_conj_array(vf, size, arrayf);
+		    f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 		    inner_loop(varmax, size, f);
 		}
 	    }
 	}
 	clock1 = milli_time();
-	test_nodes = nodes_in_use();
-	initRep();
+	test_nodes = MR_ROBDD_nodes_in_use();
+	MR_ROBDD_initRep();
 	clock2 = milli_time();
 	for (reps=repetitions; reps>0; --reps) {
 	    for (vf=0; vf<varmax; ++vf) {
 		init_array(size, vf, arrayf);
-		f = testing_iff_conj_array(vf, size, arrayf);
+		f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 		dont_inner_loop(varmax, size, f);
 		while (next_array(size, varmax, vf, arrayf)) {
-		    f = testing_iff_conj_array(vf, size, arrayf);
+		    f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 		    dont_inner_loop(varmax, size, f);
 		}
 	    }
 	}
 	clock3 = milli_time();
-	overhead_nodes = nodes_in_use();
+	overhead_nodes = MR_ROBDD_nodes_in_use();
 	runtime = (float)(clock1-clock0)/1000;
 	overhead = (float)(clock3-clock2)/1000;
 	rate = ((float)opcount)/(runtime-overhead);
Index: robdd/test_iff.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/test_iff.c,v
retrieving revision 1.1
diff -u -b -r1.1 test_iff.c
--- robdd/test_iff.c	10 Mar 2000 05:17:22 -0000	1.1
+++ robdd/test_iff.c	6 Jan 2003 02:25:24 -0000
@@ -1,9 +1,15 @@
+/*
+** Copyright (C) 1995,2003 Peter Schachte and 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   : test.c
     RCS    : $Id: test_iff.c,v 1.1 2000/03/10 05:17:22 dmo Exp $
     Author : Peter Schachte
     Origin : Tue Jun 20 15:51:07 1995
-    Purpose: Timing test for bryant graph iff_conj_array code
+    Purpose: Timing test for bryant graph MR_ROBDD_iff_conj_array code
 
 *****************************************************************/
 
@@ -67,7 +73,7 @@
 
 void doit(int v0, int top, int array[])
     {
-	type *f;
+	MR_ROBDD_type *f;
 #ifdef DEBUGALL
 	int i;
 
@@ -77,7 +83,7 @@
 	}
 #endif /* DEBUGALL */
 #ifndef OVERHEAD
-	f = iff_conj_array(v0, top, array);
+	f = MR_ROBDD_iff_conj_array(v0, top, array);
 #ifdef DEBUGALL
 	printf(" ==> ");
 	printOut(f);
@@ -129,8 +135,8 @@
 	    }
 	}
 	clock1 = milli_time();
-	test_nodes = nodes_in_use();
-	initRep();
+	test_nodes = MR_ROBDD_nodes_in_use();
+	MR_ROBDD_initRep();
 	clock2 = milli_time();
 	for (reps=repetitions; reps>0; --reps) {
 	    for (v0=0; v0<varmax; ++v0) {
@@ -142,7 +148,7 @@
 	    }
 	}
 	clock3 = milli_time();
-	overhead_nodes = nodes_in_use();
+	overhead_nodes = MR_ROBDD_nodes_in_use();
 	runtime = (float)(clock1-clock0)/1000;
 	overhead = (float)(clock3-clock2)/1000;
 	rate = ((float)opcount)/(runtime-overhead);
Index: robdd/test_rename.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/test_rename.c,v
retrieving revision 1.1
diff -u -b -r1.1 test_rename.c
--- robdd/test_rename.c	10 Mar 2000 05:17:22 -0000	1.1
+++ robdd/test_rename.c	6 Jan 2003 02:25:29 -0000
@@ -1,9 +1,15 @@
+/*
+** Copyright (C) 1995,2003 Peter Schachte and 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     : test_rename.c
   RCS      : $Id: test_rename.c,v 1.1 2000/03/10 05:17:22 dmo Exp $
   Author   : Peter Schachte
   Origin   : Sat Jul 29 20:53:11 1995
-  Purpose  : Timing test for bryant graph renameArray code
+  Purpose  : Timing test for bryant graph MR_ROBDD_renameArray code
 
 *****************************************************************/
 
@@ -24,56 +30,56 @@
     }
 
 
-void init_array(int top, int array[], bitset *usedvars)
+void init_array(int top, int array[], MR_ROBDD_bitset *usedvars)
     {
 	int i, word;
-	bitmask mask;
+	MR_ROBDD_bitmask mask;
 
-	BITSET_CLEAR(*usedvars);
-	FOREACH_POSSIBLE_ELEMENT(i, word, mask) {
+	MR_ROBDD_BITSET_CLEAR(*usedvars);
+	MR_ROBDD_FOREACH_POSSIBLE_ELEMENT(i, word, mask) {
 	    if (i >= top) break;
 	    array[i] = i;
-	    BITSET_ADD(*usedvars, word, mask);
+	    MR_ROBDD_BITSET_ADD(*usedvars, word, mask);
 	}
     }
 
 
 
-int next_array(int n, int varmax, int array[], bitset *usedvars)
+int next_array(int n, int varmax, int array[], MR_ROBDD_bitset *usedvars)
     {
 	int i, word;
-	bitmask mask;
+	MR_ROBDD_bitmask mask;
 	int elt;
 
 	/* Search backward for first cell with "room" to be incremented. */
 	for (i=n-1;; --i) {
-	    if (i<0) return FALSE;	/* no more combinations possible */
+	    if (i<0) return MR_FALSE;	/* no more combinations possible */
 	    elt=array[i];
-	    word = BITSET_WORD(elt);
-	    mask = BITSET_MASK(elt);
-	    BITSET_REMOVE(*usedvars, word, mask);
-	    (void) NEXT_POSSIBLE_ELEMENT(elt, word, mask);
-	    if (next_nonelement(usedvars, &elt, &word, &mask) && elt<varmax)
+	    word = MR_ROBDD_BITSET_WORD(elt);
+	    mask = MR_ROBDD_BITSET_MASK(elt);
+	    MR_ROBDD_BITSET_REMOVE(*usedvars, word, mask);
+	    (void) MR_ROBDD_NEXT_POSSIBLE_ELEMENT(elt, word, mask);
+	    if (MR_ROBDD_next_nonelement(usedvars, &elt, &word, &mask) && elt<varmax)
 	      break;
 	}
 	for (; i<n; ++i) {
 	    array[i] = elt;
-	    BITSET_ADD(*usedvars, word, mask);
+	    MR_ROBDD_BITSET_ADD(*usedvars, word, mask);
 	    elt = 0;
-	    word = BITSET_WORD(0);
-	    mask = BITSET_MASK(0);
-	    if (!next_nonelement(usedvars, &elt, &word, &mask)) return FALSE;
+	    word = MR_ROBDD_BITSET_WORD(0);
+	    mask = MR_ROBDD_BITSET_MASK(0);
+	    if (!MR_ROBDD_next_nonelement(usedvars, &elt, &word, &mask)) return MR_FALSE;
 	}
-	return TRUE;
+	return MR_TRUE;
     }
 
 
-void doit(int n, int array[], int varmax, type *f)
+void doit(int n, int array[], int varmax, MR_ROBDD_type *f)
     {
-	type *result;
+	MR_ROBDD_type *result;
 #ifdef DEBUGALL
 	int i;
-	printf("renameArray(");
+	printf("MR_ROBDD_renameArray(");
 	printOut(f),
 	printf(", %d, [%d", n, array[0]);
 	for (i=1; i<n; ++i) printf(",%d", array[i]);
@@ -81,7 +87,7 @@
 	fflush(stdout);
 #endif /* DEBUGALL */
 #ifndef OVERHEAD
-	result = renameArray(f, n, array);
+	result = MR_ROBDD_renameArray(f, n, array);
 #ifdef DEBUGALL
 	printOut(result);
 	printf("\n");
@@ -91,7 +97,7 @@
     }
 
 
-void dont_doit(int n, int array[], int varmax, type *f)
+void dont_doit(int n, int array[], int varmax, MR_ROBDD_type *f)
     {
     }
 
@@ -100,9 +106,9 @@
     {
 	int varmax, size, repetitions;
 	int array[MAXVAR];
-	bitset set;
+	MR_ROBDD_bitset set;
 	int reps, i;
-	type *f;
+	MR_ROBDD_type *f;
 	millisec clock0, clock1, clock2, clock3;
 	float runtime, overhead, rate;
 	int test_nodes, overhead_nodes;
@@ -125,9 +131,9 @@
 	if (repetitions <= 0) repetitions = 1;
 
 	for (i=0; i<(size-1)/2; ++i) array[i] = i*2+1;
-	f = testing_iff_conj_array(0, (size-1)/2, array);
+	f = MR_ROBDD_testing_iff_conj_array(0, (size-1)/2, array);
 	for (i=0; i<(size-2)/2; ++i) array[i] = i*2+2;
-	f = glb(f, testing_iff_conj_array(size-1, (size-2)/2, array));
+	f = MR_ROBDD_glb(f, MR_ROBDD_testing_iff_conj_array(size-1, (size-2)/2, array));
 
 	opcount = 0;
 	clock0 = milli_time();
@@ -139,13 +145,13 @@
 	    }
 	}
 	clock1 = milli_time();
-	test_nodes = nodes_in_use();
-	initRep();
+	test_nodes = MR_ROBDD_nodes_in_use();
+	MR_ROBDD_initRep();
 
 	for (i=0; i<(size-1)/2; ++i) array[i] = i*2+1;
-	f = testing_iff_conj_array(0, (size-1)/2, array);
+	f = MR_ROBDD_testing_iff_conj_array(0, (size-1)/2, array);
 	for (i=0; i<(size-2)/2; ++i) array[i] = i*2+2;
-	f = glb(f, testing_iff_conj_array(size-1, (size-2)/2, array));
+	f = MR_ROBDD_glb(f, MR_ROBDD_testing_iff_conj_array(size-1, (size-2)/2, array));
 
 	clock2 = milli_time();
 	for (reps=repetitions; reps>0; --reps) {
@@ -156,7 +162,7 @@
 	    }
 	}
 	clock3 = milli_time();
-	overhead_nodes = nodes_in_use();
+	overhead_nodes = MR_ROBDD_nodes_in_use();
 	runtime = (float)(clock1-clock0)/1000;
 	overhead = (float)(clock3-clock2)/1000;
 	rate = ((float)opcount)/(runtime-overhead);
Index: robdd/test_restrict.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/test_restrict.c,v
retrieving revision 1.1
diff -u -b -r1.1 test_restrict.c
--- robdd/test_restrict.c	10 Mar 2000 05:17:22 -0000	1.1
+++ robdd/test_restrict.c	6 Jan 2003 02:25:33 -0000
@@ -1,9 +1,15 @@
+/*
+** Copyright (C) 1995,2003 Peter Schachte and 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     : test_restrict.c
   RCS      : $Id: test_restrict.c,v 1.1 2000/03/10 05:17:22 dmo Exp $
   Author   : Peter Schachte
   Origin   : Mon Jul 17 19:54:11 1995
-  Purpose  : Timing test for bryant graph restrictThresh code
+  Purpose  : Timing test for bryant graph MR_ROBDD_restrictThresh code
 
 *****************************************************************/
 
@@ -66,21 +72,21 @@
     }
 
 
-void doit(int thresh, int varmax, type *f)
+void doit(int thresh, int varmax, MR_ROBDD_type *f)
     {
-	type *result;
+	MR_ROBDD_type *result;
 #ifdef DEBUGALL
-	printf("restrictThresh(%d, [%d,]", thresh, varmax-1),
+	printf("MR_ROBDD_restrictThresh(%d, [%d,]", thresh, varmax-1),
 	printOut(f),
 	printf(") =");
 	fflush(stdout);
 #endif /* DEBUGALL */
 #ifndef OVERHEAD
-#if !defined(USE_THRESH) && !defined(RESTRICT_SET)
-	result = restrictThresh(thresh, varmax-1, f);
-#else /* USE_THRESH */
-	result = restrictThresh(thresh, f);
-#endif /* OLD */
+#if !defined(MR_ROBDD_USE_THRESH) && !defined(MR_ROBDD_RESTRICT_SET)
+	result = MR_ROBDD_restrictThresh(thresh, varmax-1, f);
+#else /* MR_ROBDD_USE_THRESH */
+	result = MR_ROBDD_restrictThresh(thresh, f);
+#endif /* MR_ROBDD_OLD */
 #ifdef DEBUGALL
 	printOut(result);
 	printf("\n");
@@ -90,7 +96,7 @@
     }
 
 
-void dont_doit(int thresh, int varmax, type *f)
+void dont_doit(int thresh, int varmax, MR_ROBDD_type *f)
     {
     }
 
@@ -100,7 +106,7 @@
 	int varmax, size, repetitions;
 	int array[VARLIMIT];
 	int reps, v0, thresh;
-	type *f;
+	MR_ROBDD_type *f;
 	millisec clock0, clock1, clock2, clock3;
 	float runtime, overhead, rate;
 	int test_nodes, overhead_nodes;
@@ -128,34 +134,34 @@
 	    for (v0=0; v0<varmax; ++v0) {
 		for (thresh=0; thresh<varmax; thresh++) {
 		    init_array(size, v0, array);
-		    f = testing_iff_conj_array(v0, size, array);
+		    f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 		    doit(thresh, varmax, f);
 		    while (next_array(size, varmax, v0, array)) {
-			f = testing_iff_conj_array(v0, size, array);
+			f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 			doit(thresh, varmax, f);
 		    }
 		}
 	    }
 	}
 	clock1 = milli_time();
-	test_nodes = nodes_in_use();
-	initRep();
+	test_nodes = MR_ROBDD_nodes_in_use();
+	MR_ROBDD_initRep();
 	clock2 = milli_time();
 	for (reps=repetitions; reps>0; --reps) {
 	    for (v0=0; v0<varmax; ++v0) {
 		for (thresh=0; thresh<varmax; thresh++) {
 		    init_array(size, v0, array);
-		    f = testing_iff_conj_array(v0, size, array);
+		    f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 		    dont_doit(thresh, varmax, f);
 		    while (next_array(size, varmax, v0, array)) {
-			f = testing_iff_conj_array(v0, size, array);
+			f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 			dont_doit(thresh, varmax, f);
 		    }
 		}
 	    }
 	}
 	clock3 = milli_time();
-	overhead_nodes = nodes_in_use();
+	overhead_nodes = MR_ROBDD_nodes_in_use();
 	runtime = (float)(clock1-clock0)/1000;
 	overhead = (float)(clock3-clock2)/1000;
 	rate = ((float)opcount)/(runtime-overhead);
Index: robdd/test_rglb.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/test_rglb.c,v
retrieving revision 1.1
diff -u -b -r1.1 test_rglb.c
--- robdd/test_rglb.c	10 Mar 2000 05:17:22 -0000	1.1
+++ robdd/test_rglb.c	6 Jan 2003 02:25:40 -0000
@@ -1,9 +1,15 @@
+/*
+** Copyright (C) 1995,2003 Peter Schachte and 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     : test_rglb.c
   RCS      : $Id: test_rglb.c,v 1.1 2000/03/10 05:17:22 dmo Exp $
   Author   : Peter Schachte
   Origin   : Thu Jul 13 17:57:03 1995
-  Purpose  : Timing test for bryant graph restricted_glb code
+  Purpose  : Timing test for bryant graph MR_ROBDD_restricted_glb code
 
 *****************************************************************/
 
@@ -21,7 +27,7 @@
     {
 	printf("usage:  %s size maxvar [repetitions]\n", progname);
 	printf("  creates all possible pairs of v <-> v1 & v2 & ... & vsize functions, computes\n");
-	printf("  their glb, and restricts this to each threshold between 0 and maxvar.  Each V\n");
+	printf("  their MR_ROBDD_glb, and restricts this to each threshold between 0 and maxvar.  Each V\n");
 	printf("  and the vi are between 0 and maxvar inclusive.  If repetitions is >0, this\n");
 	printf("  will be done that many times.\n");
     }
@@ -66,11 +72,11 @@
     }
 
 
-void doit(int thresh, int varmax, type *f, type *g)
+void doit(int thresh, int varmax, MR_ROBDD_type *f, MR_ROBDD_type *g)
     {
-	type *result;
+	MR_ROBDD_type *result;
 #ifdef DEBUGALL
-	printf("restricted_glb(%d, [%d,]", thresh, varmax),
+	printf("MR_ROBDD_restricted_glb(%d, [%d,]", thresh, varmax),
 	printOut(f),
 	printf(", ");
 	printOut(g),
@@ -78,11 +84,11 @@
 	fflush(stdout);
 #endif /* DEBUGALL */
 #ifndef OVERHEAD
-#if !defined(USE_THRESH) && !defined(RESTRICT_SET)
-	result = restricted_glb(thresh, varmax, f, g);
-#else /* USE_THRESH */
-	result = restricted_glb(thresh, f, g);
-#endif /* OLD */
+#if !defined(MR_ROBDD_USE_THRESH) && !defined(MR_ROBDD_RESTRICT_SET)
+	result = MR_ROBDD_restricted_glb(thresh, varmax, f, g);
+#else /* MR_ROBDD_USE_THRESH */
+	result = MR_ROBDD_restricted_glb(thresh, f, g);
+#endif /* MR_ROBDD_OLD */
 #ifdef DEBUGALL
 	printOut(result);
 	printf("\n");
@@ -92,23 +98,23 @@
     }
 
 
-void dont_doit(int thresh, int varmax, type *f, type *g)
+void dont_doit(int thresh, int varmax, MR_ROBDD_type *f, MR_ROBDD_type *g)
     {
     }
 
 
-void inner_loop(int varmax, int top, int thresh, type *f)
+void inner_loop(int varmax, int top, int thresh, MR_ROBDD_type *f)
     {
 	int arrayg[33];
 	int vg;
-	type *g;
+	MR_ROBDD_type *g;
 
 	for (vg=0; vg<varmax; ++vg) {
 	    init_array(top, vg, arrayg);
-	    g = testing_iff_conj_array(vg, top, arrayg);
+	    g = MR_ROBDD_testing_iff_conj_array(vg, top, arrayg);
 	    doit(thresh, varmax, f, g);
 	    while (next_array(top, varmax, vg, arrayg)) {
-		g = testing_iff_conj_array(vg, top, arrayg);
+		g = MR_ROBDD_testing_iff_conj_array(vg, top, arrayg);
 		doit(thresh, varmax, f, g);
 	    }
 	}
@@ -116,18 +122,18 @@
 
 
 
-void dont_inner_loop(int varmax, int top, int thresh, type *f)
+void dont_inner_loop(int varmax, int top, int thresh, MR_ROBDD_type *f)
     {
 	int arrayg[33];
 	int vg;
-	type *g;
+	MR_ROBDD_type *g;
 
 	for (vg=0; vg<varmax; ++vg) {
 	    init_array(top, vg, arrayg);
-	    g = testing_iff_conj_array(vg, top, arrayg);
+	    g = MR_ROBDD_testing_iff_conj_array(vg, top, arrayg);
 	    dont_doit(thresh, varmax, f, g);
 	    while (next_array(top, varmax, vg, arrayg)) {
-		g = testing_iff_conj_array(vg, top, arrayg);
+		g = MR_ROBDD_testing_iff_conj_array(vg, top, arrayg);
 		dont_doit(thresh, varmax, f, g);
 	    }
 	}
@@ -140,7 +146,7 @@
 	int varmax, size, repetitions;
 	int arrayf[VARLIMIT];
 	int reps, vf, thresh;
-	type *f;
+	MR_ROBDD_type *f;
 	millisec clock0, clock1, clock2, clock3;
 	float runtime, overhead, rate;
 	int test_nodes, overhead_nodes;
@@ -168,34 +174,34 @@
 	    for (thresh=0; thresh<=varmax; ++thresh) {
 		for (vf=0; vf<varmax; ++vf) {
 		    init_array(size, vf, arrayf);
-		    f = testing_iff_conj_array(vf, size, arrayf);
+		    f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 		    inner_loop(varmax, size, thresh, f);
 		    while (next_array(size, varmax, vf, arrayf)) {
-			f = testing_iff_conj_array(vf, size, arrayf);
+			f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 			inner_loop(varmax, size, thresh, f);
 		    }
 		}
 	    }
 	}
 	clock1 = milli_time();
-	test_nodes = nodes_in_use();
-	initRep();
+	test_nodes = MR_ROBDD_nodes_in_use();
+	MR_ROBDD_initRep();
 	clock2 = milli_time();
 	for (reps=repetitions; reps>0; --reps) {
 	    for (thresh=0; thresh<=varmax; ++thresh) {
 		for (vf=0; vf<varmax; ++vf) {
 		    init_array(size, vf, arrayf);
-		    f = testing_iff_conj_array(vf, size, arrayf);
+		    f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 		    dont_inner_loop(varmax, size, thresh, f);
 		    while (next_array(size, varmax, vf, arrayf)) {
-			f = testing_iff_conj_array(vf, size, arrayf);
+			f = MR_ROBDD_testing_iff_conj_array(vf, size, arrayf);
 			dont_inner_loop(varmax, size, thresh, f);
 		    }
 		}
 	    }
 	}
 	clock3 = milli_time();
-	overhead_nodes = nodes_in_use();
+	overhead_nodes = MR_ROBDD_nodes_in_use();
 	runtime = (float)(clock1-clock0)/1000;
 	overhead = (float)(clock3-clock2)/1000;
 	rate = ((float)opcount)/(runtime-overhead);
Index: robdd/test_upclose.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/test_upclose.c,v
retrieving revision 1.1
diff -u -b -r1.1 test_upclose.c
--- robdd/test_upclose.c	10 Mar 2000 05:17:22 -0000	1.1
+++ robdd/test_upclose.c	6 Jan 2003 02:25:46 -0000
@@ -1,3 +1,9 @@
+/*
+** Copyright (C) 1998,2003 Peter Schachte and 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   : test_upclose
     RCS    : $Id: test_upclose.c,v 1.1 2000/03/10 05:17:22 dmo Exp $
@@ -25,21 +31,21 @@
 
 
 #if 0
-node *boolfn(unsigned long n)
+MR_ROBDD_node *boolfn(unsigned long n)
     {
 	int d;
 	unsigned long tr, fa;
-	node *trfn, *fafn;
+	MR_ROBDD_node *trfn, *fafn;
 
-	if (n == 0) return zero;
-	if (n == 1) return one;
+	if (n == 0) return MR_ROBDD_zero;
+	if (n == 1) return MR_ROBDD_one;
 
-	for (d = LOG_BITS_PER_WORD-1; (fa=(n>>(1<<d)))==0 && d >= 0; --d);
+	for (d = MR_ROBDD_LOG_BITS_PER_WORD-1; (fa=(n>>(1<<d)))==0 && d >= 0; --d);
 	tr = n & ((1<<(1<<d))-1);
 	trfn = boolfn(tr);
 	fa ^= tr;
 	fafn = boolfn(fa);
-	return make_node((LOG_BITS_PER_WORD-d), trfn, fafn);
+	return MR_ROBDD_make_node((MR_ROBDD_LOG_BITS_PER_WORD-d), trfn, fafn);
     }
 #endif
 
@@ -57,17 +63,17 @@
     }
 
 
-node *randboolfn(int depth, int level)
+MR_ROBDD_node *randboolfn(int depth, int level)
     {
-	node *result;
+	MR_ROBDD_node *result;
 
 	if (bits <= 0) rnd = rand(), bits = rand_bits;
 
 	if (level == 0) {
-	    result = (rnd&1) ? one : zero;
+	    result = (rnd&1) ? MR_ROBDD_one : MR_ROBDD_zero;
 	    bits--; rnd >>= 1;
 	} else {
-	    result = make_node(depth-level,
+	    result = MR_ROBDD_make_node(depth-level,
 			       randboolfn(depth, level-1),
 			       randboolfn(depth, level-1));
 	}
@@ -76,17 +82,17 @@
 
 void doit(int depth, int num)
     {
-	node *f = randboolfn(depth, depth);
-	node *uf;
+	MR_ROBDD_node *f = randboolfn(depth, depth);
+	MR_ROBDD_node *uf;
 
 #ifdef DEBUGALL
-	printf("%6d upclose(", num);
+	printf("%6d MR_ROBDD_upclose(", num);
 	printOut(f);
 	printf(") ==> ");
 	fflush(stdout);
 #endif /* DEBUGALL */
 #ifndef OVERHEAD
-	uf = upclose(f);
+	uf = MR_ROBDD_upclose(f);
 #ifdef DEBUGALL
 	if (f == uf) {
 	    printf("UNCHANGED");
@@ -127,23 +133,23 @@
 	if (repetitions <= 0) repetitions = 1;
 
 	opcount = 0;
-	initRep();
+	MR_ROBDD_initRep();
 	init_random();
 	clock0 = milli_time();
 	for (reps=0; reps<repetitions; ++reps) {
 	    doit(depth, reps);
 	}
 	clock1 = milli_time();
-	test_nodes = nodes_in_use();
-	concludeRep();
-	initRep();
+	test_nodes = MR_ROBDD_nodes_in_use();
+	MR_ROBDD_concludeRep();
+	MR_ROBDD_initRep();
 	init_random();
 	clock2 = milli_time();
 	for (reps=0; reps<repetitions; ++reps) {
 	    dont_doit(depth, reps);
 	}
 	clock3 = milli_time();
-	overhead_nodes = nodes_in_use();
+	overhead_nodes = MR_ROBDD_nodes_in_use();
 	runtime = (float)(clock1-clock0)/1000;
 	overhead = (float)(clock3-clock2)/1000;
 	rate = ((float)opcount)/(runtime-overhead);
Index: robdd/test_var.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/test_var.c,v
retrieving revision 1.1
diff -u -b -r1.1 test_var.c
--- robdd/test_var.c	10 Mar 2000 05:17:23 -0000	1.1
+++ robdd/test_var.c	6 Jan 2003 02:25:51 -0000
@@ -1,9 +1,15 @@
+/*
+** Copyright (C) 1995,2003 Peter Schachte and 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     : test_var.c
   RCS      : $Id: test_var.c,v 1.1 2000/03/10 05:17:23 dmo Exp $
   Author   : Peter Schachte
   Origin   : Tue Jul 18 14:28:15 1995
-  Purpose  : Timing test for bryant graph var_entailed function
+  Purpose  : Timing test for bryant graph MR_ROBDD_var_entailed function
 
 *****************************************************************/
 
@@ -22,7 +28,7 @@
 	printf("usage:  %s size maxvar [repetitions]\n", progname);
 	printf("  creates all possible v <-> v1 & v2 & ... & vsize functions and conjoins this\n");
 	printf("  with each variable between 0 and maxvar, and then determines for each variable\n");
-	printf("   between 0 and maxvar if that variable is entailed by this function.\n");
+	printf("   between 0 and maxvar if that variable is MR_ROBDD_entailed by this function.\n");
 	printf("  V and the vi are between 0 and maxvar inclusive.  If repetitions is >0,\n");
 	printf("  this will be done that many times.\n");
     }
@@ -67,18 +73,18 @@
     }
 
 
-void doit(int w, type *f)
+void doit(int w, MR_ROBDD_type *f)
     {
 	int result;
 
 #ifdef DEBUGALL
-	printf("var_entailed(");
+	printf("MR_ROBDD_var_entailed(");
 	printOut(f),
 	printf(", %d) = ", w);
 	fflush(stdout);
 #endif /* DEBUGALL */
 #ifndef OVERHEAD
-	result = var_entailed(f, w);
+	result = MR_ROBDD_var_entailed(f, w);
 #ifdef DEBUGALL
 	printf("%s\n", (result ? "true" : "false"));
 #endif /* DEBUGALL */
@@ -87,18 +93,18 @@
     }
 
 
-void dont_doit(int w, type *f)
+void dont_doit(int w, MR_ROBDD_type *f)
     {
     }
 
 
-void inner_loop(int varmax, type *f)
+void inner_loop(int varmax, MR_ROBDD_type *f)
     {
-	type *g;
+	MR_ROBDD_type *g;
 	int v, w;
 
 	for (v=0; v<varmax; ++v) {
-	    g = glb(variableRep(v), f);
+	    g = MR_ROBDD_glb(MR_ROBDD_variableRep(v), f);
 	    for (w=0; w<varmax; ++w) {
 		doit(w, g);
 	    }
@@ -106,13 +112,13 @@
     }
 
 
-void dont_inner_loop(int varmax, type *f)
+void dont_inner_loop(int varmax, MR_ROBDD_type *f)
     {
-	type *g;
+	MR_ROBDD_type *g;
 	int v, w;
 
 	for (v=0; v<varmax; ++v) {
-	    g = glb(variableRep(v), f);
+	    g = MR_ROBDD_glb(MR_ROBDD_variableRep(v), f);
 	    for (w=0; w<varmax; ++w) {
 		dont_doit(w, g);
 	    }
@@ -126,7 +132,7 @@
 	int varmax, size, repetitions;
 	int array[VARLIMIT];
 	int reps, v0;
-	type *f;
+	MR_ROBDD_type *f;
 	millisec clock0, clock1, clock2, clock3;
 	float runtime, overhead, rate;
 	int test_nodes, overhead_nodes;
@@ -153,31 +159,31 @@
 	for (reps=repetitions; reps>0; --reps) {
 	    for (v0=0; v0<varmax; ++v0) {
 		init_array(size, v0, array);
-		f = testing_iff_conj_array(v0, size, array);
+		f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 		inner_loop(varmax, f);
 		while (next_array(size, varmax, v0, array)) {
-		    f = testing_iff_conj_array(v0, size, array);
+		    f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 		    inner_loop(varmax, f);
 		}
 	    }
 	}
 	clock1 = milli_time();
-	test_nodes = nodes_in_use();
-	initRep();
+	test_nodes = MR_ROBDD_nodes_in_use();
+	MR_ROBDD_initRep();
 	clock2 = milli_time();
 	for (reps=repetitions; reps>0; --reps) {
 	    for (v0=0; v0<varmax; ++v0) {
 		init_array(size, v0, array);
-		f = testing_iff_conj_array(v0, size, array);
+		f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 		dont_inner_loop(varmax, f);
 		while (next_array(size, varmax, v0, array)) {
-		    f = testing_iff_conj_array(v0, size, array);
+		    f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 		    dont_inner_loop(varmax, f);
 		}
 	    }
 	}
 	clock3 = milli_time();
-	overhead_nodes = nodes_in_use();
+	overhead_nodes = MR_ROBDD_nodes_in_use();
 	runtime = (float)(clock1-clock0)/1000;
 	overhead = (float)(clock3-clock2)/1000;
 	rate = ((float)opcount)/(runtime-overhead);
Index: robdd/test_vars.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/test_vars.c,v
retrieving revision 1.1
diff -u -b -r1.1 test_vars.c
--- robdd/test_vars.c	10 Mar 2000 05:17:23 -0000	1.1
+++ robdd/test_vars.c	6 Jan 2003 02:25:55 -0000
@@ -1,9 +1,15 @@
+/*
+** Copyright (C) 1995,2003 Peter Schachte and 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     : test_vars.c
   RCS      : $Id: test_vars.c,v 1.1 2000/03/10 05:17:23 dmo Exp $
   Author   : Peter Schachte
   Origin   : Tue Jul 18 20:13:51 1995
-  Purpose  : Timing test for bryant graph vars_entailed function
+  Purpose  : Timing test for bryant graph MR_ROBDD_vars_entailed function
 
 *****************************************************************/
 
@@ -22,7 +28,7 @@
 	printf("usage:  %s size maxvar [repetitions]\n", progname);
 	printf("  creates all possible v <-> v1 & v2 & ... & vsize functions and conjoins this\n");
 	printf("  with each variable between 0 and maxvar, and then determines the set of\n");
-	printf("  variables entailed by this function.  V and the vi are between 0 and maxvar\n");
+	printf("  variables MR_ROBDD_entailed by this function.  V and the vi are between 0 and maxvar\n");
 	printf("  inclusive.  If repetitions is >0, this will be done that many times.\n");
     }
 
@@ -66,27 +72,27 @@
     }
 
 
-void doit(int top, type *f)
+void doit(int top, MR_ROBDD_type *f)
     {
-	bitset *set;
+	MR_ROBDD_bitset *set;
 #ifdef DEBUGALL
 	int var;
-	bitmask mask;
+	MR_ROBDD_bitmask mask;
 	int word;
 
-	printf("vars_entailed(");
+	printf("MR_ROBDD_vars_entailed(");
 	printOut(f),
 	printf("[, %d]) =", top);
 	fflush(stdout);
 #endif /* DEBUGALL */
 #ifndef OVERHEAD
-#ifndef NEW
-	set = vars_entailed(f, top);
-#else /* !NAIVE */
-	set = vars_entailed(f);
-#endif /* OLD */
+#ifndef MR_ROBDD_NEW
+	set = MR_ROBDD_vars_entailed(f, top);
+#else /* !MR_ROBDD_NAIVE */
+	set = MR_ROBDD_vars_entailed(f);
+#endif /* MR_ROBDD_OLD */
 #ifdef DEBUGALL
-	FOREACH_ELEMENT(*set,var,word,mask) {
+	MR_ROBDD_FOREACH_ELEMENT(*set,var,word,mask) {
 	    printf(" %d", var);
 	}
 	printf("\n");
@@ -96,30 +102,30 @@
     }
 
 
-void dont_doit(int top, type *f)
+void dont_doit(int top, MR_ROBDD_type *f)
     {
     }
 
 
-void inner_loop(int varmax, type *f)
+void inner_loop(int varmax, MR_ROBDD_type *f)
     {
-	type *g;
+	MR_ROBDD_type *g;
 	int v;
 
 	for (v=0; v<varmax; ++v) {
-	    g = glb(variableRep(v), f);
+	    g = MR_ROBDD_glb(MR_ROBDD_variableRep(v), f);
 	    doit(varmax, g);
 	}
     }
 
 
-void dont_inner_loop(int varmax, type *f)
+void dont_inner_loop(int varmax, MR_ROBDD_type *f)
     {
-	type *g;
+	MR_ROBDD_type *g;
 	int v;
 
 	for (v=0; v<varmax; ++v) {
-	    g = glb(variableRep(v), f);
+	    g = MR_ROBDD_glb(MR_ROBDD_variableRep(v), f);
 	    dont_doit(varmax, g);
 	}
     }
@@ -130,7 +136,7 @@
 	int varmax, size, repetitions;
 	int array[VARLIMIT];
 	int reps, v0;
-	type *f;
+	MR_ROBDD_type *f;
 	millisec clock0, clock1, clock2, clock3;
 	float runtime, overhead, rate;
 	int test_nodes, overhead_nodes;
@@ -157,31 +163,31 @@
 	for (reps=repetitions; reps>0; --reps) {
 	    for (v0=0; v0<varmax; ++v0) {
 		init_array(size, v0, array);
-		f = testing_iff_conj_array(v0, size, array);
+		f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 		inner_loop(varmax, f);
 		while (next_array(size, varmax, v0, array)) {
-		    f = testing_iff_conj_array(v0, size, array);
+		    f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 		    inner_loop(varmax, f);
 		}
 	    }
 	}
 	clock1 = milli_time();
-	test_nodes = nodes_in_use();
-	initRep();
+	test_nodes = MR_ROBDD_nodes_in_use();
+	MR_ROBDD_initRep();
 	clock2 = milli_time();
 	for (reps=repetitions; reps>0; --reps) {
 	    for (v0=0; v0<varmax; ++v0) {
 		init_array(size, v0, array);
-		f = testing_iff_conj_array(v0, size, array);
+		f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 		dont_inner_loop(varmax, f);
 		while (next_array(size, varmax, v0, array)) {
-		    f = testing_iff_conj_array(v0, size, array);
+		    f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
 		    dont_inner_loop(varmax, f);
 		}
 	    }
 	}
 	clock3 = milli_time();
-	overhead_nodes = nodes_in_use();
+	overhead_nodes = MR_ROBDD_nodes_in_use();
 	runtime = (float)(clock1-clock0)/1000;
 	overhead = (float)(clock3-clock2)/1000;
 	rate = ((float)opcount)/(runtime-overhead);
Index: robdd/timing.c
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/timing.c,v
retrieving revision 1.1
diff -u -b -r1.1 timing.c
--- robdd/timing.c	10 Mar 2000 05:17:23 -0000	1.1
+++ robdd/timing.c	6 Jan 2003 02:26:02 -0000
@@ -1,10 +1,15 @@
+/*
+** Copyright (C) 1995,2003 Peter Schachte and 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     : timing.c
   RCS      : $Id: timing.c,v 1.1 2000/03/10 05:17:23 dmo Exp $
   Author   : 
   Origin   : Sat Aug 12 15:20:42 1995
   Purpose  : Provide timing information for benchmarking
-  Copyright: © 1995 Peter Schachte.  All rights reserved.
 
 *****************************************************************/
 
@@ -26,14 +31,14 @@
 #if 0
 #include <sys/rusage.h>
 #else
-void getrusage(int, struct rusage *);
+int getrusage(int, struct rusage *);
 #endif
 
 millisec milli_time(void)
     {
 	struct rusage p;
 
-	getrusage(RUSAGE_SELF, &p);
+	(void) getrusage(RUSAGE_SELF, &p);
 	return (millisec)(p.ru_utime.tv_sec * 1000) +
 	       (millisec)(p.ru_utime.tv_usec / 1000);
     }
Index: robdd/timing.h
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/timing.h,v
retrieving revision 1.1
diff -u -b -r1.1 timing.h
--- robdd/timing.h	10 Mar 2000 05:17:23 -0000	1.1
+++ robdd/timing.h	6 Jan 2003 02:26:12 -0000
@@ -1,3 +1,9 @@
+/*
+** Copyright (C) 1995,2003 Peter Schachte and 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     : timing.h
   RCS      : $Id: timing.h,v 1.1 2000/03/10 05:17:23 dmo Exp $
Index: robdd/var.h
===================================================================
RCS file: /home/mercury1/repository/mercury/robdd/var.h,v
retrieving revision 1.1
diff -u -b -r1.1 var.h
--- robdd/var.h	10 Mar 2000 05:17:22 -0000	1.1
+++ robdd/var.h	6 Jan 2003 02:26:34 -0000
@@ -1,13 +1,17 @@
+/*
+** Copyright (C) 1998,2003 Peter Schachte and 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     : var.h
   RCS      : $Id: var.h,v 1.1 2000/03/10 05:17:22 dmo Exp $
   Author   : Peter Schachte
   Origin   : Mon Oct 12 06:09:27 1998
   Purpose  : Definitions common to all representations of Boolean variables
-  Copyright: © 1998 .  All rights reserved.
 
 *****************************************************************/
-
 
 /* the most variables we can support */
 #define MAXVAR 64
cvs diff: Diffing runtime
Index: runtime/RESERVED_MACRO_NAMES
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/RESERVED_MACRO_NAMES,v
retrieving revision 1.14
diff -u -b -r1.14 RESERVED_MACRO_NAMES
--- runtime/RESERVED_MACRO_NAMES	27 Sep 2002 08:51:44 -0000	1.14
+++ runtime/RESERVED_MACRO_NAMES	29 Sep 2002 10:35:19 -0000
@@ -30,6 +30,8 @@
 # These are defined by boehm_gc/gc.h.
 __GC
 _GC_H
+HIDE_POINTER
+REVEAL_POINTER
 #-----------------------------------------------------------------------------#
 # This is defined by mps_gc/code/mercury_mps.h,
 # which uses this macro for its header guard.
Index: runtime/mercury.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury.h,v
retrieving revision 1.65
diff -u -b -r1.65 mercury.h
--- runtime/mercury.h	29 Sep 2002 09:38:41 -0000	1.65
+++ runtime/mercury.h	29 Sep 2002 10:35:19 -0000
@@ -42,6 +42,7 @@
   #endif
   #ifdef MR_BOEHM_GC
     #include "gc.h"
+    #define GC_I_HIDE_POINTERS
     #ifdef MR_INLINE_ALLOC
       #include "gc_inl.h"
     #endif
Index: runtime/mercury_heap.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_heap.h,v
retrieving revision 1.27
diff -u -b -r1.27 mercury_heap.h
--- runtime/mercury_heap.h	22 Nov 2002 08:50:41 -0000	1.27
+++ runtime/mercury_heap.h	24 Nov 2002 21:14:47 -0000
@@ -26,6 +26,7 @@
     #include "mercury_mps.h"
   #endif
   #ifdef MR_BOEHM_GC
+    #define GC_I_HIDE_POINTERS
     #include "gc.h"
   #endif
 
Index: runtime/mercury_init.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_init.h,v
retrieving revision 1.39
diff -u -b -r1.39 mercury_init.h
--- runtime/mercury_init.h	21 Aug 2002 11:27:42 -0000	1.39
+++ runtime/mercury_init.h	26 Aug 2002 02:01:05 -0000
@@ -92,6 +92,7 @@
     #include "mercury_mps.h"	/* for GC_INIT(), GC_stack_bottom */
   #endif
   #ifdef MR_BOEHM_GC
+    #define GC_I_HIDE_POINTERS
     #include "gc.h"		/* for GC_INIT(), GC_stack_bottom */
   #endif
 #endif
Index: runtime/mercury_memory.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_memory.h,v
retrieving revision 1.18
diff -u -b -r1.18 mercury_memory.h
--- runtime/mercury_memory.h	21 Aug 2002 11:27:43 -0000	1.18
+++ runtime/mercury_memory.h	26 Aug 2002 01:59:25 -0000
@@ -31,6 +31,7 @@
     #include "mercury_mps.h"	/* for GC_FREE */
   #endif
   #if defined(MR_BOEHM_GC)
+    #define GC_I_HIDE_POINTERS
     #include "gc.h"		/* for GC_FREE */
   #endif
 #endif
Index: runtime/mercury_reg_workarounds.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_reg_workarounds.c,v
retrieving revision 1.6
diff -u -b -r1.6 mercury_reg_workarounds.c
--- runtime/mercury_reg_workarounds.c	22 Nov 2002 08:50:41 -0000	1.6
+++ runtime/mercury_reg_workarounds.c	26 Feb 2003 08:46:37 -0000
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 1998, 2000, 2002 The University of Melbourne.
+** Copyright (C) 1998, 2001-2003 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.
 */
@@ -46,6 +46,19 @@
 
 	while (nbytes-- > 0)
 		*d++ = *s++;
+}
+
+/*
+** See the header file for documentation on why we need this function.
+*/
+
+void
+MR_memset(void *dest, char c, size_t nbytes)
+{
+	char		*d = (char *) dest;
+
+	while (nbytes-- > 0)
+		*d++ = c;
 }
 
 #endif /* MR_CANNOT_USE_STRUCTURE_ASSIGNMENT && MR_USE_GCC_GLOBAL_REGISTERS */
Index: runtime/mercury_reg_workarounds.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_reg_workarounds.h,v
retrieving revision 1.5
diff -u -b -r1.5 mercury_reg_workarounds.h
--- runtime/mercury_reg_workarounds.h	22 Nov 2002 08:50:41 -0000	1.5
+++ runtime/mercury_reg_workarounds.h	26 Feb 2003 08:47:24 -0000
@@ -1,5 +1,5 @@
 /*
-** Copyright (C) 1998-2000, 2002 The University of Melbourne.
+** Copyright (C) 1998-2003 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.
 */
@@ -43,11 +43,13 @@
   ** c_code may call the builtin functions.
   */
   extern	void	MR_memcpy(void *dest, const void *src, size_t nbytes);
+  extern	void	MR_memset(void *dest, char c, size_t nbytes);
 
 #else /* !MR_CANNOT_USE_STRUCTURE_ASSIGNMENT || !MR_USE_GCC_GLOBAL_REGISTERS */
 
   #define MR_assign_structure(dest, src)	((dest) = (src))
   #define MR_memcpy(dest, src, nbytes)		memcpy((dest), (src), (nbytes))
+  #define MR_memset(dest, c, nbytes)		memset((dest), (c), (nbytes))
 
 #endif /* !MR_CANNOT_USE_STRUCTURE_ASSIGNMENT || !MR_USE_GCC_GLOBAL_REGISTERS */
 
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
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
Index: tools/bootcheck
===================================================================
RCS file: /home/mercury1/repository/mercury/tools/bootcheck,v
retrieving revision 1.146
diff -u -b -r1.146 bootcheck
--- tools/bootcheck	15 Feb 2003 21:52:50 -0000	1.146
+++ tools/bootcheck	19 Feb 2003 04:05:05 -0000
@@ -545,9 +545,18 @@
 			$LN_S $root/trace/*.c .
 			cp $root/trace/Mmake* .
 			cd $root/stage2
+			rm -f robdd
+			mkdir robdd
+			cd robdd
+			$LN_S $root/robdd/*.h .
+			$LN_S $root/robdd/*.c .
+			cp $root/robdd/Mmake* .
+			cp $root/robdd/Make* .
+			cd $root/stage2
 		else
 			$LN_S $root/runtime .
 			$LN_S $root/trace .
+			$LN_S $root/robdd .
 		fi
 		if $copy_boehm_gc
 		then
@@ -836,6 +845,7 @@
 	$LN_S $root/doc .
 	$LN_S $root/runtime .
 	$LN_S $root/trace .
+	$LN_S $root/robdd .
 	$LN_S $root/scripts .
 	$LN_S $root/util .
 	$LN_S $root/profiler .
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