Files
mercury/robdd/test_var.c
Zoltan Somogyi 95b64f73a1 Move changes in the library on the mode-constraints branch onto the trunk.
Estimated hours taken: unknown (but probably several weeks by dmo)
Branches: main

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.

configure.in:
	Check whether the compiler can handle local foreign_decls, since
	robdd.m now needs this.

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). This impact of this #define is so small that it is
	not measurable.

runtime/RESERVED_MACRO_NAMES:
library/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.

tests/debugger/declarative/if_then_else.{inp,exp}:
tests/debugger/declarative/ite_2.{inp,exp,exp2}:
	Avoid a name conflict with the predicate ite in robdd.m.
2004-12-15 06:58:00 +00:00

195 lines
4.7 KiB
C

/*
** Copyright (C) 1995,2003-2004 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
Author : Peter Schachte
Origin : Tue Jul 18 14:28:15 1995
Purpose : Timing test for bryant graph MR_ROBDD_var_entailed function
*****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "bryant.h"
#include "timing.h"
#define VARLIMIT 1024
int opcount;
void usage(char *progname)
{
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 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");
}
void init_array(int top, int v0, int array[])
{
int i, val;
for (i=0, val=0; i<top; ++i, ++val) {
if (val==v0) ++val;
array[i] = val;
}
}
int next_array(int n, int varmax, int v0, int array[])
{
int i;
int limit;
int val;
/* Search backward for first cell with "room" to be
* incremented. This is complicated by the need to avoid
* using the value v0.
*/
for (i=n-1, limit=varmax-1;; --i, --limit) {
if (i<0) return 0; /* no more combinations possible */
if (limit==v0) --limit;
if (++array[i]==v0) ++array[i];
if (array[i]<=limit) break;
}
/* Now we've incremented array[i], and must set
* array[i+1..n-1] to successive values (avoiding v0).
*/
for (val=array[i]+1, ++i; i<n; ++i, ++val) {
if (val==v0) ++val;
array[i] = val;
}
return 1;
}
void doit(int w, MR_ROBDD_type *f)
{
int result;
#ifdef DEBUGALL
printf("MR_ROBDD_var_entailed(");
printOut(f),
printf(", %d) = ", w);
fflush(stdout);
#endif /* DEBUGALL */
#ifndef OVERHEAD
result = MR_ROBDD_var_entailed(f, w);
#ifdef DEBUGALL
printf("%s\n", (result ? "true" : "false"));
#endif /* DEBUGALL */
#endif /* !OVERHEAD */
++opcount;
}
void dont_doit(int w, MR_ROBDD_type *f)
{
}
void inner_loop(int varmax, MR_ROBDD_type *f)
{
MR_ROBDD_type *g;
int v, w;
for (v=0; v<varmax; ++v) {
g = MR_ROBDD_glb(MR_ROBDD_variableRep(v), f);
for (w=0; w<varmax; ++w) {
doit(w, g);
}
}
}
void dont_inner_loop(int varmax, MR_ROBDD_type *f)
{
MR_ROBDD_type *g;
int v, w;
for (v=0; v<varmax; ++v) {
g = MR_ROBDD_glb(MR_ROBDD_variableRep(v), f);
for (w=0; w<varmax; ++w) {
dont_doit(w, g);
}
}
}
int main(int argc, char **argv)
{
int varmax, size, repetitions;
int array[VARLIMIT];
int reps, v0;
MR_ROBDD_type *f;
millisec clock0, clock1, clock2, clock3;
float runtime, overhead, rate;
int test_nodes, overhead_nodes;
if (argc < 3) {
usage(argv[0]);
return 20;
}
if ((varmax=atoi(argv[2]))<1 || varmax>=VARLIMIT) {
usage(argv[0]);
printf("\n varmax must be between 1 <= varmax < %d\n", VARLIMIT);
return 20;
}
if ((size=atoi(argv[1]))<0 || size>=varmax) {
usage(argv[0]);
printf("\n size must be between 0 <= size < varmax\n");
return 20;
}
repetitions=(argc>3 ? atoi(argv[3]) : 1);
if (repetitions <= 0) repetitions = 1;
opcount = 0;
clock0 = milli_time();
for (reps=repetitions; reps>0; --reps) {
for (v0=0; v0<varmax; ++v0) {
init_array(size, v0, array);
f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
inner_loop(varmax, f);
while (next_array(size, varmax, v0, array)) {
f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
inner_loop(varmax, f);
}
}
}
clock1 = milli_time();
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 = MR_ROBDD_testing_iff_conj_array(v0, size, array);
dont_inner_loop(varmax, f);
while (next_array(size, varmax, v0, array)) {
f = MR_ROBDD_testing_iff_conj_array(v0, size, array);
dont_inner_loop(varmax, f);
}
}
}
clock3 = milli_time();
overhead_nodes = MR_ROBDD_nodes_in_use();
runtime = (float)(clock1-clock0)/1000;
overhead = (float)(clock3-clock2)/1000;
rate = ((float)opcount)/(runtime-overhead);
printf("%s %d %d %d: %.3f - %.3f = %.3f secs, %d ops, %d nodes, %.1f ops/sec\n",
argv[0], size, varmax, repetitions,
runtime, overhead, (runtime-overhead), opcount,
test_nodes-overhead_nodes, rate);
return 0;
}