Initial revision

This commit is contained in:
Alexandre Duret-Lutz 2003-05-05 10:57:53 +00:00
parent 1fa73989e0
commit cf5dd46350
67 changed files with 44947 additions and 0 deletions

View file

@ -0,0 +1,36 @@
# --------------------------------
# Makefile for milner test example
# --------------------------------
# --- Compiler flags
CFLAGS = -g -pedantic -Wall -ansi -L../../src -I../../src
# --- C++ compiler
CPP = g++
# --- C compiler
CC = gcc
# --- Do not touch ---
.SUFFIXES: .cxx .c
.cxx.o:
$(CPP) $(CFLAGS) -c $<
.c.o:
$(CC) $(CFLAGS) -c $<
milner: milner.o bddlib
$(CPP) $(CFLAGS) milner.o -o milner -lbdd -lm
bddlib:
cd ../../src; make
clean:
rm -f *~
rm -f *.o
rm -f milner
milner.o: ../../src/bdd.h

View file

@ -0,0 +1,183 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "bdd.h"
int N; // Number of cyclers
bdd normvar; // Current state variables
bdd primvar; // Next state variables
bddPair *renamepair; // Variable pairs for renaming
/* Build a BDD expressing that all other variables than 'z' is unchanged.
*/
bdd A(bdd* x, bdd* y, int z)
{
bdd res = bddtrue;
int i;
for(i=0 ; i<N ; i++)
if(i != z)
res &= bdd_apply(x[i],y[i],bddop_biimp);
return res;
}
/* Loop through all cyclers and create the transition relation for each
of them.
*/
bdd transitions(bdd* t, bdd* tp, bdd* h, bdd* hp, bdd* c, bdd* cp)
{
int i;
bdd P; // Cycler i's handling of the token
bdd E; // Cycler i's handling of it's task
bdd T = bddfalse; // The monolithic transition relation
for(i=0 ; i<N ; i++)
{
P = ((c[i]>cp[i]) & (tp[i]>t[i]) & hp[i] & A(c,cp,i)
& A(t,tp,i) & A(h,hp,i))
| ((h[i]>hp[i]) & cp[(i+1)%N] & A(c,cp,(i+1)%N) & A(h,hp,i)
& A(t,tp,N));
E = t[i] & !tp[i] & A(t,tp,i) & A(h,hp,N) & A(c,cp,N);
T |= P | E;
}
return T;
}
/* Create a BDD for the initial state.
*/
bdd initial_state(bdd* t, bdd* h, bdd* c)
{
int i;
bdd I = c[0] & !h[0] & !t[0];
for(i=1; i<N; i++)
I &= !c[i] & !h[i] & !t[i];
return I;
}
/* Calculate the reachable states.
*/
bdd reachable_states(bdd I, bdd T)
{
bdd R = I, // Reachable state space
prevR, // Previously reached state space
tmp;
do
{
prevR = R;
#if 0
// Apply and exist as different operations => slow
tmp = T & bx;
tmp = bdd_exist(tmp, normvar);
#else
// Apply and exist as one operation => fast
tmp = bdd_appex(R, T, bddop_and, normvar);
#endif
tmp = bdd_replace(tmp, renamepair);
R |= tmp;
}
while(prevR != R);
return R;
}
int main(int argc, char** argv)
{
int n;
if(argc < 2)
{
cerr << "usage: milner N\n";
cerr << " N number of cyclers\n";
exit(1);
}
N = atoi(argv[1]);
if (N <= 0)
{
cerr << "The number of cyclers must be more than zero\n";
exit(2);
}
long clk1 = clock();
bdd_init(500000, 50000);
bdd_setvarnum(N*6);
bdd* c = new bdd[N];
bdd* cp = new bdd[N];
bdd* t = new bdd[N];
bdd* tp = new bdd[N];
bdd* h = new bdd[N];
bdd* hp = new bdd[N];
int *nvar = new int[N*3];
int *pvar = new int[N*3];
for (n=0 ; n<N*3 ; n++)
{
nvar[n] = n*2;
pvar[n] = n*2+1;
}
normvar = bdd_makeset(nvar, N*3);
primvar = bdd_makeset(pvar, N*3);
renamepair = bdd_newpair();
bdd_setpairs(renamepair, pvar, nvar, N*3);
for (n=0 ; n<N ; n++)
{
c[n] = bdd_ithvar(n*6);
cp[n] = bdd_ithvar(n*6+1);
t[n] = bdd_ithvar(n*6+2);
tp[n] = bdd_ithvar(n*6+3);
h[n] = bdd_ithvar(n*6+4);
hp[n] = bdd_ithvar(n*6+5);
#if 0
bdd_addvarblock(c[n], BDD_REORDER_FIXED);
bdd_addvarblock(cp[n], BDD_REORDER_FIXED);
bdd_addvarblock(t[n], BDD_REORDER_FIXED);
bdd_addvarblock(tp[n], BDD_REORDER_FIXED);
bdd_addvarblock(h[n], BDD_REORDER_FIXED);
bdd_addvarblock(hp[n], BDD_REORDER_FIXED);
bdd_addvarblock(c[n] & cp[n] & t[n] & tp[n] & h[n] & hp[n],
BDD_REORDER_FREE);
#endif
}
bdd I = initial_state(t,h,c);
bdd T = transitions(t,tp,h,hp,c,cp);
bdd R = reachable_states(I,T);
long clk2 = clock();
bddStat s;
bdd_stats(&s);
cout << "SatCount R = " << bdd_satcount(R) << endl;
cout << "Calc = " << (double)N*pow(2.0,1.0+N)*pow(2.0,3.0*N) << endl;
cout << "Nodes = " << s.produced << endl;
cout << endl << "Number of nodes in T is " << bdd_nodecount( T ) << endl;
cout << "Number of nodes in R is " << bdd_nodecount( R ) << endl << endl;
cout << (float)(clk2 - clk1)/(float)(CLOCKS_PER_SEC) << " sec.\n";
//bdd_printstat();
cout << "Nodenum: " << bdd_getnodenum() << endl;
bdd_done();
return 0;
}

View file

@ -0,0 +1,15 @@
MILNERS SCHEDULER - AN EXAMPLE OF BDDs USED FOR STATE SPACE CALCULATION
-----------------------------------------------------------------------
Please read chapter seven in "An Introduction To Binary Decision
Diagrams" which is supplied in the "doc" directory. This chapter will
explain the example.
The program is called as "milner N" where N is the number of
cyclers. It will output the size of the reachable state space for the
system (compared to the true calculated size - for debugging purpose)
and a set of cache statistics.
Please also note that this file is used as an internal benchmark for
the author, so do not be too supprised if you find some strange debug
information in the code ...