spot/buddy/examples/milner/milner.cxx
Alexandre Duret-Lutz ad8d24222a buddy: rename libbdd to libbddx
* buddy/src/bdd.h, buddy/src/bvec.h, buddy/src/fdd.h: Rename as...
* buddy/src/bddx.h, buddy/src/bvecx.h, buddy/src/fddx.h: ... these.
* buddy/src/Makefile.am: Build libbddx.la instead of libbdd.la.
* buddy/examples/Makefile.def: Use it.
* Makefile.am, buddy/src/bddtest.cxx, buddy/src/bvec.c,
buddy/src/cppext.cxx, buddy/src/fdd.c, buddy/src/imatrix.h,
buddy/src/kernel.h, buddy/examples/adder/adder.cxx,
buddy/examples/bddcalc/parser_.h, buddy/examples/bddtest/bddtest.cxx,
buddy/examples/cmilner/cmilner.c, buddy/examples/fdd/fdd.cxx,
buddy/examples/milner/milner.cxx, buddy/examples/money/money.cxx,
buddy/examples/queen/queen.cxx, buddy/examples/solitare/solitare.cxx,
m4/buddy.m4, src/ltlvisit/apcollect.hh, src/ltlvisit/simplify.hh,
src/misc/bddlt.hh, src/misc/bddop.hh, src/misc/minato.hh,
src/priv/acccompl.hh, src/priv/accconv.hh, src/priv/accmap.hh,
src/priv/bddalloc.cc, src/tgba/bdddict.hh, src/tgba/bddprint.hh,
src/tgba/tgbamask.hh, src/tgba/tgbasafracomplement.cc,
src/tgbaalgos/emptiness.hh, src/tgbaalgos/gtec/sccstack.hh,
src/tgbaalgos/neverclaim.cc, src/tgbaalgos/powerset.cc,
src/tgbaalgos/sccfilter.hh, src/tgbaalgos/sccinfo.hh,
src/tgbaalgos/weight.hh, wrap/python/buddy.i: Adjust.
* NEWS, README: Document it.
2014-10-30 20:58:10 +01:00

178 lines
3.9 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "bddx.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)
{
using namespace std ;
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);
}
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);
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;
//bdd_printstat();
cout << "Nodenum: " << bdd_getnodenum() << endl;
bdd_done();
return 0;
}