spot/buddy/examples/milner/milner.cxx
Alexandre Duret-Lutz 605dce2aac * configure.ac, Makefile.am, src/Makefile.am, doc/Makefile.am,
examples/Makefile.am, examples/Makefile.def,
examples/adder/Makefile.am, examples/calculator/Makefile.am,
examples/cmilner/Makefile.am, examples/fdd/Makefile.am,
examples/internal/Makefile.am, examples/milner/Makefile.am,
examples/money/Makefile.am, examples/queen/Makefile.am,
examples/solitar/Makefile.am, m4/debug.m4, m4/gccwarns.m4,
ChangeLog, INSTALL: New files.
* config, makefile, src/makefile, doc/makefile,
examples/adder/makefile, examples/calculator/makefile
examples/cmilner/makefile, examples/fdd/makefile,
examples/internal/makefile, examples/milner/makefile,
examples/money/makefile, examples/queen/makefile,
examples/solitare/makefile : Delete.
* examples/adder/adder.cxx, examples/fdd/statespace.cxx,
examples/internal/bddtest.cxx, examples/milner/milner.cxx,
examples/money/money.cxx, examples/queen/queen.cxx,
examples/solitare/solitare.cxx: Include iostream.
* examples/calculator/parser.y: Rename as ...
* examples/calculator/parser.yxx: ... this.  Remove spurious
comas in %token, %right, and %left arguments.
* examples/calculator/parser.h: Rename as ...
* examples/calculator/parser_.h: ... this, because the bison
rule with output parser.h (not tokens.h) from parser.y.
* examples/calculator/lexer.l: Rename as ...
* examples/calculator/lexer.lxx: ... this.  Include parser.h
instead of tokens.h.
* examples/calculator/slist.h
(voidSList::voisSListElem, SList::ite): Fix friend usage.
* src/kernel.h (DEFAULT_CLOCK): Default to 60 if not already
defined.
* README: Update build instruction, and file listing.
2003-05-05 13:44:49 +00:00

185 lines
4.1 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "bdd.h"
#include <iostream>
using namespace std;
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;
}