Exemple #1
0
bdd reachable_states(bdd I, bdd T)
{
   bdd C, by, bx = bddfalse;
   bdd tmp1;
   
   do
   {
      bdd_addref(bx);
      
      by = bx;
#if 1
      tmp1 = bdd_addref( bdd_apply(T, bx, bddop_and) );
      C = bdd_addref( bdd_exist(tmp1, normvarset) );
      bdd_delref(tmp1);
#else
      C = bdd_addref( bdd_appex(bx, T, bddop_and, normvar, N*3) );
#endif
      
      tmp1 = bdd_addref( bdd_replace(C, pairs) );
      bdd_delref(C);
      C = tmp1;

      tmp1 = bdd_apply(I, C, bddop_or);
      bdd_delref(C);

      bdd_delref(bx);
      bx = tmp1;
      
      /*printf("."); fflush(stdout);*/
   }
   while(bx != by);
   
   printf("\n");
   return bx;
}
Exemple #2
0
BDD pre_all(TransitionSystem *model, BDD p) {
	//pre_all = S - pre_exists(S - p) where S is the set of all states
	BDD S = bdd_addref(bdd_or(model->all_states, model->pseudo_end));
	BDD s_diff_p = bdd_addref(bdd_apply(S, p, bddop_diff));
	BDD pres = bdd_addref(pre_exists(model, s_diff_p));

	BDD res = bdd_apply(model->all_states, pres, bddop_diff);
	bdd_delref(s_diff_p);
	bdd_delref(pres);
	bdd_delref(S);
	return res;
}
Exemple #3
0
/*
NAME    {* fdd\_makeset *}
SECTION {* fdd *}
SHORT   {* creates a variable set for N finite domain blocks *}
PROTO   {* BDD fdd_makeset(int *varset, int varnum) *}
DESCR   {* Returns a BDD defining all the variable sets used to define
           the variable blocks in the array {\tt varset}. The argument
	   {\tt varnum} defines the size of {\tt varset}. *}
RETURN  {* The correct BDD or the constant false on errors. *}
ALSO    {* fdd\_ithset, bdd\_makeset *}
*/
BDD fdd_makeset(int *varset, int varnum)
{
   BDD res=bddtrue, tmp;
   int n;

   if (!bddrunning)
   {
      bdd_error(BDD_RUNNING);
      return bddfalse;
   }

   for (n=0 ; n<varnum ; n++)
      if (varset[n] < 0  ||  varset[n] >= fdvarnum)
      {
	 bdd_error(BDD_VAR);
	 return bddfalse;
      }

   for (n=0 ; n<varnum ; n++)
   {
      bdd_addref(res);
      tmp = bdd_apply(domain[varset[n]].var, res, bddop_and);
      bdd_delref(res);
      res = tmp;
   }

   return res;
}
Exemple #4
0
/*
 * removes reference from l
 */
BDD f_bdd_and_with(BDD l, BDD r)
{
	BDD res = bdd_addref(bdd_apply(l, r, bddop_and));
	bdd_delref(l);

	return res;
}
Exemple #5
0
/*
NAME    {* fdd\_intaddvarblock *}
SECTION {* fdd *}
SHORT   {* adds a new variable block for reordering *}
PROTO   {* int fdd_intaddvarblock(int first, int last, int fixed) *}
DESCR   {* Works exactly like {\tt bdd\_addvarblock} except that
           {\tt fdd\_intaddvarblock} takes a range of FDD variables
	   instead of BDD variables. *}
RETURN  {* Zero on success, otherwise a negative error code. *}
ALSO    {* bdd\_addvarblock, bdd\_intaddvarblock, bdd\_reorder *}
*/
int fdd_intaddvarblock(int first, int last, int fixed)
{
   bdd res = bddtrue, tmp;
   int n, err;

   if (!bddrunning)
      return bdd_error(BDD_RUNNING);

   if (first > last ||  first < 0  ||  last >= fdvarnum)
      return bdd_error(BDD_VARBLK);

   for (n=first ; n<=last ; n++)
   {
      bdd_addref(res);
      tmp = bdd_apply(domain[n].var, res, bddop_and);
      bdd_delref(res);
      res = tmp;
   }

   bdd_addref(res); /* Added by Jaco van de Pol, 25 march 2010 */

   err = bdd_addvarblock(res, fixed);

   bdd_delref(res);
   return err;
}
Exemple #6
0
/*
 * removes reference from l
 */
BDD f_bdd_or_with(BDD l, BDD r)
{
	//deletes left argument
	BDD res = bdd_addref(bdd_apply(l, r, bddop_or));
	bdd_delref(l);

	return res;
}
Exemple #7
0
bdd A(bdd* x, bdd* y, int z)
{
   bdd res = bddtrue, tmp1, tmp2;
   int i;
   
   for(i=0 ; i<N ; i++)
      if(i != z)
      {
	 bdd_addref(res);
	 tmp1 = bdd_addref(bdd_apply(x[i],y[i],bddop_biimp));
	 tmp2 = bdd_apply(res, tmp1, bddop_and);
	 bdd_delref(tmp1);
	 bdd_delref(res);
	 res = tmp2;
      }
   
   return res;
}
Exemple #8
0
/*
NAME    {* fdd\_domain *}
SECTION {* fdd *}
SHORT   {* BDD encoding of the domain of a FDD variable *}
PROTO   {* BDD fdd_domain(int var) *}
DESCR   {* Returns what corresponds to a disjunction of all possible
           values of the variable  {\tt var}.
	   This is more efficient than doing
	   {\tt fdd\_ithvar(var,0) OR fdd\_ithvar(var,1) ...} explicitely
	   for all values in the domain of {\tt var}. *}
RETURN  {* The encoding of the domain*}
*/
BDD fdd_domain(int var)
{
   int n,val;
   Domain *dom;
   BDD d;

   if (!bddrunning)
   {
      bdd_error(BDD_RUNNING);
      return bddfalse;
   }

   if (var < 0  ||  var >= fdvarnum)
   {
      bdd_error(BDD_VAR);
      return bddfalse;
   }

      /* Encode V<=X-1. V is the variables in 'var' and X is the domain size */

   dom = &domain[var];
   val = dom->realsize-1;
   d = bddtrue;

   for (n=0 ; n<dom->binsize ; n++)
   {
      BDD tmp;

      if (val & 0x1)
	 tmp = bdd_apply( bdd_nithvar(dom->ivar[n]), d, bddop_or );
      else
	 tmp = bdd_apply( bdd_nithvar(dom->ivar[n]), d, bddop_and );

      val >>= 1;

      bdd_addref(tmp);
      bdd_delref(d);
      d = tmp;
   }

   return d;
}
Exemple #9
0
bdd initial_state(bdd* t, bdd* h, bdd* c)
{
   int i;
   bdd I, tmp1, tmp2, tmp3;

   tmp1 = bdd_addref( bdd_not(h[0]) );
   
   tmp2 = bdd_addref( bdd_apply(c[0], tmp1, bddop_and) );
   bdd_delref(tmp1);

   tmp1 = bdd_addref( bdd_not(t[0]) );

   I = bdd_apply(tmp1, tmp2, bddop_and);
   bdd_delref(tmp1);
   bdd_delref(tmp2);

   
   for(i=1; i<N; i++)
   {
      bdd_addref(I);

      tmp1 = bdd_addref( bdd_not(c[i]) );
      tmp2 = bdd_addref( bdd_not(h[i]) );

      tmp3 = bdd_addref( bdd_apply(tmp1, tmp2, bddop_and) );
      bdd_delref(tmp1);
      bdd_delref(tmp2);

      tmp1 = bdd_addref( bdd_not(t[i]) );
      tmp2 = bdd_addref( bdd_apply(tmp3, tmp1, bddop_and) );
      bdd_delref(tmp3);
      bdd_delref(tmp1);

      tmp1 = bdd_apply(I, tmp2, bddop_and);
      bdd_delref(tmp2);
      bdd_delref(I);

      I = tmp1;
   }
   
   return I;
}
int main(int ac,char**av)
{
  BDD a,b,c;
  bdd_init(N_NODES, CACHESIZE);
  bdd_setvarnum(2);
  a = bdd_ithvar(0);
  b = bdd_ithvar(1);  
  c = bdd_apply(a, b, bddop_less);
  bdd_fnprintdot("less.dot", c);
  bdd_done();
}
Exemple #11
0
/*
NAME    {* fdd\_ithvar *}
SECTION {* fdd *}
SHORT   {* the BDD for the i'th FDD set to a specific value *}
PROTO   {* BDD fdd_ithvar(int var, int val) *}
DESCR   {* Returns the BDD that defines the value {\tt val} for the
           finite domain block {\tt var}. The encoding places the
	   Least Significant Bit at the top of the BDD tree
	   (which means they will have the lowest variable index).
	   The returned BDD will be $V_0 \conj V_1 \conj \ldots
	   \conj V_N$ where each $V_i$ will be in positive or negative form
	   depending on the value of {\tt val}. *}
RETURN  {* The correct BDD or the constant false BDD on error. *}
ALSO    {* fdd\_ithset *}
*/
BDD fdd_ithvar(int var, int val)
{
   int n;
   int v=1, tmp;

   if (!bddrunning)
   {
      bdd_error(BDD_RUNNING);
      return bddfalse;
   }

   if (var < 0  ||  var >= fdvarnum)
   {
      bdd_error(BDD_VAR);
      return bddfalse;
   }

   if (val < 0  ||  val >= domain[var].realsize)
   {
      bdd_error(BDD_RANGE);
      return bddfalse;
   }

   for (n=0 ; n<domain[var].binsize ; n++)
   {
      bdd_addref(v);

      if (val & 0x1)
	 tmp = bdd_apply(bdd_ithvar(domain[var].ivar[n]), v, bddop_and);
      else
	 tmp = bdd_apply(bdd_nithvar(domain[var].ivar[n]), v, bddop_and);

      bdd_delref(v);
      v = tmp;
      val >>= 1;
   }

   return v;
}
Exemple #12
0
/*
NAME    {* fdd\_equals *}
SECTION {* fdd *}
SHORT   {* returns a BDD setting two FD. blocks equal *}
PROTO   {* BDD fdd_equals(int f, int g) *}
DESCR   {* Builds a BDD which is true for all the possible assignments to
           the variable blocks {\tt f} and {\tt g} that makes the blocks
	   equal. This is more or less just a shorthand for calling
	   {\tt fdd\_equ()}. *}
RETURN  {* The correct BDD or the constant false on errors. *}
*/
BDD fdd_equals(int left, int right)
{
   BDD e = bddtrue, tmp1, tmp2;
   int n;

   if (!bddrunning)
   {
      bdd_error(BDD_RUNNING);
      return bddfalse;
   }

   if (left < 0  ||  left >= fdvarnum  ||  right < 0  ||  right >= fdvarnum)
   {
      bdd_error(BDD_VAR);
      return bddfalse;
   }
   if (domain[left].realsize != domain[right].realsize)
   {
      bdd_error(BDD_RANGE);
      return bddfalse;
   }

   for (n=0 ; n<domain[left].binsize ; n++)
   {
      tmp1 = bdd_addref( bdd_apply(bdd_ithvar(domain[left].ivar[n]),
				   bdd_ithvar(domain[right].ivar[n]),
				   bddop_biimp) );

      tmp2 = bdd_addref( bdd_apply(e, tmp1, bddop_and) );
      bdd_delref(tmp1);
      bdd_delref(e);
      e = tmp2;
   }

   bdd_delref(e);
   return e;
}
/*
NAME    {* bdd\_makeset *}
SECTION {* kernel *}
SHORT   {* builds a BDD variable set from an integer array *}
PROTO   {* BDD bdd_makeset(int *v, int n) *}
DESCR   {* Reads a set of variable numbers from the integer array {\tt v}
           which must hold exactly {\tt n} integers and then builds a BDD
	   representing the variable set.

	   The BDD variable set is represented as the conjunction of
	   all the variables in their positive form and may just as
	   well be made that way by the user. The user should keep a
	   reference to the returned BDD instead of building it every
	   time the set is needed. *}
ALSO    {* bdd\_scanset *}
RETURN {* A BDD variable set. *} */
BDD bdd_makeset(int *varset, int varnum)
{
   int v, res=1;
   
   for (v=varnum-1 ; v>=0 ; v--)
   {
      BDD tmp;
      bdd_addref(res);
      tmp = bdd_apply(res, bdd_ithvar(varset[v]), bddop_and);
      bdd_delref(res);
      res = tmp;
   }

   return res;
}
Exemple #14
0
CAMLprim value wrapper_bdd_bigapply(value clause, value op) {
    CAMLparam2(clause,op);
    CAMLlocal1(r);
    BDD x;
    if (clause == Val_emptylist) {
        caml_raise_constant(*caml_named_value("buddy_exn_EmptyList"));
    } else {
        BDD bdd = BDD_val(Field(clause, 0));
        clause = Field(clause, 1);
        while (clause != Val_emptylist) {
            x = BDD_val(Field(clause, 0));
            bdd = bdd_addref(bdd_apply(x,bdd,Int_val(op)));
            clause = Field(clause, 1);
        }
        _makebdd(&r, bdd);
    }
    CAMLreturn(r);
}
Exemple #15
0
/*
NAME    {* bdd\_makeset *}
SECTION {* kernel *}
SHORT   {* builds a BDD variable set from an integer array *}
PROTO   {* BDD bdd_makeset(int *v, int n) *}
DESCR   {* Reads a set of variable numbers from the integer array {\tt v}
           which must hold exactly {\tt n} integers and then builds a BDD
	   representing the variable set.

	   The BDD variable set is represented as the conjunction of
	   all the variables in their positive form and may just as
	   well be made that way by the user. The user should keep a
	   reference to the returned BDD instead of building it every
	   time the set is needed. *}
ALSO    {* bdd\_scanset *}
RETURN {* A BDD variable set. *} */
BDD bdd_makeset(int *varset, int varnum)
{
   int v, res=1;

   BUDDY_PROLOGUE;
   ADD_ARG2(T_INT_PTR,varset,varnum);
   ADD_ARG1(T_INT,varnum);
   
   for (v=varnum-1 ; v>=0 ; v--)
   {
      BDD tmp;
      bdd_addref(res);
      tmp = bdd_apply(res, bdd_ithvar(varset[v]), bddop_and);
      bdd_delref(res);
      res = tmp;
   }

   RETURN_BDD(res);
}
Exemple #16
0
int main(int argc,char **argv) {
   char ambiguous_treatment='A';
   char linebuff[1024];
   char *parseptr;
   PARSE_STATE ps;
   uint32_t low_code,high_code;
   int width,i,j,vi,vj;
   FILE *unicode_db;
   BDD x,y,child[8];
   BDD *queue;
   int queue_low,queue_high,queue_max;

   puts("/*\n"
	" * GENERATED CODE - DO NOT EDIT!\n"
	" * Edit mkwcw.c, which generates this, or the input to that\n"
	" * program, instead.  Distributions of IDSgrep will nonetheless\n"
	" * usually include a ready-made copy of this file because\n"
	" * compiling and running mkwcw.c requires a library and data\n"
	" * file that, although free, not everyone is expected to have.\n"
	" */\n\n"
	"#include \"_stdint.h\"\n"
       );
   
   if (argc>1)
     ambiguous_treatment=argv[1][0]&~32;
   
   bdd_init(1000000,15625);
   bdd_setcacheratio(64);
   bdd_setvarnum(32);
   bdd_gbc_hook(NULL);
   
   defined_codes=bddfalse;
   zero_codes=bddfalse;
   wide_codes=bddfalse;

   /* yes, unfortunately UnicodeData.txt and EastAsianWidth.txt are just
    * different enough to need separate parsers, at least if the parsers
    * are as stupid as I'd like these ones to be */
   
   if (argc>2) {
      unicode_db=fopen(argv[2],"rt");

      while (1) {
	 fgets(linebuff,sizeof(linebuff),unicode_db);
	 if (feof(unicode_db))
	   break;
	 
	 ps=psLOW;
	 linebuff[sizeof(linebuff)-1]='\0';
	 low_code=0;
	 width=-1;
	 
	 for (parseptr=linebuff;(*parseptr) && (ps!=psSTOP);parseptr++)
	   switch (ps) {
	      
	    case psLOW:
	      if ((*parseptr>='0') && (*parseptr<='9'))
		low_code=(low_code<<4)+(*parseptr-'0');
	      else if ((*parseptr>='a') && (*parseptr<='f'))
		low_code=(low_code<<4)+(*parseptr-'a'+10);
	      else if ((*parseptr>='A') && (*parseptr<='F'))
		low_code=(low_code<<4)+(*parseptr-'A'+10);
	      else if (*parseptr==';')
		 ps=psSEMI;
	      else if ((*parseptr==' ') || (*parseptr=='\t'))
		{ /* skip spaces and tabs */ }
	      else
		ps=psSTOP; /* this catches comment lines */
	      break;
	      
	    case psSEMI:
	      if (*parseptr==';')
		ps=psWIDTH;
	      break;
	      
	    case psWIDTH:
	      if (((parseptr[0]=='M') && ((parseptr[1]=='e') ||
					  (parseptr[1]=='n'))) ||
		  ((parseptr[0]=='C') && (parseptr[1]=='f')))
		width=0;
	      /* FALL THROUGH */
	      
	    default:
	      ps=psSTOP;
	      break;
	   }
	 
	 if (width==0)
	   set_range_width(low_code,low_code,0);
      }

      fclose(unicode_db);
   }
   
   while (1) {
      fgets(linebuff,sizeof(linebuff),stdin);
      if (feof(stdin))
	break;
      
      ps=psLOW;
      linebuff[sizeof(linebuff)-1]='\0';
      low_code=0;
      high_code=0;
      width=-1;

      for (parseptr=linebuff;(*parseptr) && (ps!=psSTOP);parseptr++)
	switch (ps) {

	 case psLOW:
	   if ((*parseptr>='0') && (*parseptr<='9'))
	     low_code=(low_code<<4)+(*parseptr-'0');
	   else if ((*parseptr>='a') && (*parseptr<='f'))
	     low_code=(low_code<<4)+(*parseptr-'a'+10);
	   else if ((*parseptr>='A') && (*parseptr<='F'))
	     low_code=(low_code<<4)+(*parseptr-'A'+10);
	   else if (*parseptr=='.')
	     ps=psHIGH;
	   else if (*parseptr==';') {
	      high_code=low_code;
	      ps=psWIDTH;
	   } else if ((*parseptr==' ') || (*parseptr=='\t'))
		{ /* skip spaces and tabs */ }
	   else
	     ps=psSTOP; /* this catches comment lines */
	   break;

	 case psHIGH:
	   if ((*parseptr>='0') && (*parseptr<='9'))
	     high_code=(high_code<<4)+(*parseptr-'0');
	   else if ((*parseptr>='a') && (*parseptr<='f'))
	     high_code=(high_code<<4)+(*parseptr-'a'+10);
	   else if ((*parseptr>='A') && (*parseptr<='F'))
	     high_code=(high_code<<4)+(*parseptr-'A'+10);
	   else if ((*parseptr=='.') || (*parseptr==' ') || (*parseptr=='\t'))
	     { /* skip spaces, tabs, and dots */ }
	   else if (*parseptr==';')
	     ps=psWIDTH;
	   else
	     ps=psSTOP;
	   break;
	   
	 case psWIDTH:
	   if (*parseptr=='A')
	     *parseptr=ambiguous_treatment;
	   switch (*parseptr) {
	    case 'F': /* full-width treated as wide */
	    case 'W': /* wide */
	      width=2;
	      break;
	      
	    case 'H': /* half-width treated as narrow */
	    case 'N': /* narrow or neutral */
	      width=1;
	      break;
	      
	    case '0': /* zero-width - should only appear in user database */
	      width=0;
	      break;
	      
	    default:
	      /* ignore all others */
	      break;
	   }
	   /* FALL THROUGH */
	   
	 default:
	   ps=psSTOP;
	   break;
	}
      
      if (width>=0)
	set_range_width(low_code,high_code,width);
   }
   
   printf("/* node counts before simplification: %d %d %d */\n",
	  bdd_nodecount(defined_codes),
	  bdd_nodecount(zero_codes),
	  bdd_nodecount(wide_codes));

   x=bdd_addref(bdd_simplify(wide_codes,defined_codes));
   bdd_delref(wide_codes);
   wide_codes=x;

   x=bdd_addref(bdd_apply(defined_codes,wide_codes,bddop_diff));
   bdd_delref(defined_codes);
   defined_codes=x;
   
   x=bdd_addref(bdd_simplify(zero_codes,defined_codes));
   bdd_delref(zero_codes);
   zero_codes=x;
   
   printf("/* node counts after simplification: %d %d %d */\n\n",
	  bdd_nodecount(defined_codes),
	  bdd_nodecount(zero_codes),
	  bdd_nodecount(wide_codes));

   bdd_varblockall();
   bdd_intaddvarblock(0,7,0);
   bdd_intaddvarblock(8,15,0);
   bdd_intaddvarblock(16,23,0);
   bdd_intaddvarblock(24,31,0);
   bdd_intaddvarblock(0,31,1);

   bdd_reorder_probe(&reordering_size_callback);
   
   puts("typedef struct _WIDTH_BBD_ENT {\n"
	"  int16_t child[8];\n"
	"  char byte,shift;\n"
	"} WIDTH_BDD_ENT;\n\n"
	"static WIDTH_BDD_ENT width_bdd[]={");

   queue=(BDD *)malloc(sizeof(BDD)*1000);
   queue_max=1000;
   queue_low=2;
   queue_high=4;
   queue[0]=bddfalse;
   queue[1]=bddtrue;
   queue[2]=wide_codes;
   queue[3]=zero_codes;
   
   while (queue_low<queue_high) {
      if (queue_high+8>queue_max) {
	 queue_max/=3;
	 queue_max*=4;
	 queue=(BDD *)realloc(queue,sizeof(BDD)*queue_max);
      }
      
      reorder_focus=queue[queue_low];
      bdd_reorder(BDD_REORDER_WIN2ITE);
      
      vj=bdd_var(queue[queue_low]);
      vi=(vj/8)*8;
      vj=((vj-vi+1)/3)*3-1;
      if (vj<0) vj=0;
      
      x=bdd_addref(bdd_restrict(queue[queue_low],bdd_nithvar(vi+vj)));
      y=bdd_addref(bdd_restrict(x,bdd_nithvar(vi+vj+1)));
      child[0]=bdd_addref(bdd_restrict(y,bdd_nithvar(vi+vj+2)));
      child[1]=bdd_addref(bdd_restrict(y,bdd_ithvar(vi+vj+2)));
      bdd_delref(y);
      y=bdd_addref(bdd_restrict(x,bdd_ithvar(vi+vj+1)));
      child[2]=bdd_addref(bdd_restrict(y,bdd_nithvar(vi+vj+2)));
      child[3]=bdd_addref(bdd_restrict(y,bdd_ithvar(vi+vj+2)));
      bdd_delref(y);
      bdd_delref(x);
      x=bdd_addref(bdd_restrict(queue[queue_low],bdd_ithvar(vi+vj)));
      y=bdd_addref(bdd_restrict(x,bdd_nithvar(vi+vj+1)));
      child[4]=bdd_addref(bdd_restrict(y,bdd_nithvar(vi+vj+2)));
      child[5]=bdd_addref(bdd_restrict(y,bdd_ithvar(vi+vj+2)));
      bdd_delref(y);
      y=bdd_addref(bdd_restrict(x,bdd_ithvar(vi+vj+1)));
      child[6]=bdd_addref(bdd_restrict(y,bdd_nithvar(vi+vj+2)));
      child[7]=bdd_addref(bdd_restrict(y,bdd_ithvar(vi+vj+2)));
      bdd_delref(y);
      bdd_delref(x);
      
      fputs("  {{",stdout);
      for (i=0;i<8;i++) {
	 queue[queue_high]=child[i];
	 for (j=0;queue[j]!=child[i];j++);
	 if (j==queue_high)
	   queue_high++;
	 else
	   bdd_delref(child[i]);
	 printf("%d",j-2);
	 if (i<7) putchar(',');
      }
      printf("},%d,%d},\n",vi/8,5-vj);
      
      queue_low++;
   }

   puts("};\n\n"
"int idsgrep_utf8cw(char *);\n"
"\n"
"#define WBS width_bdd[search]\n"
"\n"
"int idsgrep_utf8cw(char *cp) {\n"
"   int search;\n"
"\n"
"   for (search=0;search>=0;)\n"
"     search=WBS.child[(cp[WBS.byte]>>WBS.shift)&7];\n"
"   if (search==-1)\n"
"     return 2;\n"
"   for (search=1;search>=0;)\n"
"     search=WBS.child[(cp[WBS.byte]>>WBS.shift)&7];\n"
"   return ((-1)-search);\n"
"}\n");
   
   bdd_done();

   exit(0);
}
Exemple #17
0
/* ML type: bdd -> bdd -> int -> bdd */
EXTERNML value mlbdd_bdd_apply(value left, value right, value opr) /* ML */
{
  return mlbdd_make(bdd_apply(Bdd_val(left),Bdd_val(right), 
				Int_val(opr)));
}
Exemple #18
0
void create_bdds(TransitionSystem *model)
{
//	printf("%d\ttotal states before merge\n", initial_numstates);
//	merge_similar_parents(&PSEUDO_END);
//	merge_similar_children(model->pseudo_initial); //merging children spoiles the calculation of support
	model->states_size = assign_id_and_collect_labels(model, model->pseudo_initial);
//	printf("%d\ttotal states after merge\n", model->states_size);
//	printf("%d\tstates removed\n", initial_numstates - model->states_size);

	get_transitions(model, NULL, model->pseudo_initial);

	init_buddy(model->states_size);

	int state_vars = ceil_of_log2_of(model->states_size);
	int bdd_vars = state_vars * 2;
	bdd_setvarnum(bdd_vars);

	BDD unprimed2primed = bdd_addref(0);
	model->states_bdds = malloc(sizeof(int *) * model->states_size);
	model->states_primed_bdds = malloc(sizeof(int *) * model->states_size);
	model->all_states = bdd_addref(0);

	//encode states as binary functions
	for (int i = 1; i < model->states_size; i++) {
		BDD tmp = bdd_addref(1);
		BDD tmpp = bdd_addref(1);
		for (int j = 0; j < state_vars; j++) {
			int test = (i >> (state_vars - 1 - j)) & 1;
			if (test == 1) {
				tmp = f_bdd_and_with(tmp, bdd_ithvar(j));
				tmpp = f_bdd_and_with(tmpp, bdd_ithvar(j + state_vars));
			} else {
				tmp = f_bdd_and_with(tmp, bdd_nithvar(j));
				tmpp = f_bdd_and_with(tmpp, bdd_nithvar(j + state_vars));
			}
		}
		model->states_bdds[i] = bdd_addref(tmp);
		model->states_primed_bdds[i] = bdd_addref(tmpp);

		model->all_states = f_bdd_or_with(model->all_states, tmp);

		BDD tt = bdd_addref(bdd_and(tmp, tmpp));
		unprimed2primed = f_bdd_or_with(unprimed2primed, tt);
		bdd_delref(tt);
		bdd_delref(tmp);
		bdd_delref(tmpp);
	}
	model->pseudo_end = model->states_bdds[PSEUDO_END.id];
	//remove pseudo end
	BDD tmp = bdd_addref(model->all_states);
	bdd_delref(model->all_states);
	model->all_states = bdd_apply(tmp, model->pseudo_end, bddop_diff);
	bdd_delref(tmp);

	model->unprimed2primed = bdd_addref(unprimed2primed);
	bdd_delref(unprimed2primed);

	//create helper of unprimed and primed variables
	BDD unprimed_vars = bdd_addref(1);
	BDD primed_vars = bdd_addref(1);
	for (int i = 0; i < state_vars; i++) {
		unprimed_vars = f_bdd_and_with(unprimed_vars, bdd_ithvar(i));
		primed_vars = f_bdd_and_with(primed_vars, bdd_ithvar(i + state_vars));
	}
	model->unprimed_vars = unprimed_vars;
	model->primed_vars = primed_vars;

	//create function for transitions
	BDD transitions_bdd = bdd_addref(0);
	for (int i = 0; i < model->transition_size; i++)
	{
//		printf("(%d, %d), ", model->transitions[i]->src, model->transitions[i]->dest);
		BDD tt = bdd_addref(bdd_and(model->states_bdds[model->transitions[i]->src], model->states_primed_bdds[model->transitions[i]->dest]));
		transitions_bdd = f_bdd_or_with(transitions_bdd, tt);
		bdd_delref(tt);
	}
	//transition from end to end to complete Kripke structure
//	BDD tt = bdd_addref(bdd_and(model->states_bdds[PSEUDO_END.id], model->states_primed_bdds[PSEUDO_END.id]));
//	transitions_bdd = f_bdd_or_with(transitions_bdd, tt);
//	bdd_delref(tt);

	model->initial_states = 0;
	State *child;
//	printf("children %d\n", model->pseudo_initial->children_size);
	for (int i = 0; i < model->pseudo_initial->children_size; i++)
	{
		child = model->pseudo_initial->children[i];
		if (child == NULL)
			continue; // removed
		model->initial_states = f_bdd_or_with(model->initial_states, model->states_bdds[child->id]);
	}

	model->transitions_bdd = transitions_bdd;

	for (int i = 0; i < model->activities_size; i++)
	{
		Labels *l = model->labels[i];
		l->states_bdd = bdd_addref(0);
		for (int j = 0; j < l->states_size; j++)
		{
			l->states_bdd = f_bdd_or_with(l->states_bdd, model->states_bdds[l->states[j]]);
		}

	}

}
Exemple #19
0
bdd transitions(bdd* t, bdd* tp, bdd* h, bdd* hp, bdd* c, bdd* cp)
{
   int i;
   bdd P, E, T = bddfalse;
   bdd tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
   
   for(i=0; i<N; i++)
   {
      bdd_addref(T);

      tmp1 = bdd_addref( bdd_apply(c[i], cp[i], bddop_diff) );
      tmp2 = bdd_addref( bdd_apply(tp[i], t[i], bddop_diff) );
      tmp3 = bdd_addref( A(c, cp, i) );
      tmp4 = bdd_addref( A(t, tp, i) );
      tmp5 = bdd_addref( A(h, hp, i) );

      tmp6 = bdd_addref( bdd_apply(tmp1, tmp2, bddop_and) );
      bdd_delref(tmp1);
      bdd_delref(tmp2);

      tmp1 = bdd_addref( bdd_apply(tmp6, hp[i], bddop_and) );
      bdd_delref(tmp6);

      tmp2 = bdd_addref( bdd_apply(tmp1, tmp3, bddop_and) );
      bdd_delref(tmp1);
      bdd_delref(tmp3);

      tmp3 = bdd_addref( bdd_apply(tmp2, tmp4, bddop_and) );
      bdd_delref(tmp2);
      bdd_delref(tmp4);
      
      tmp1 = bdd_addref( bdd_apply(tmp3, tmp5, bddop_and) );
      bdd_delref(tmp3);
      bdd_delref(tmp5);

      
      tmp4 = bdd_addref( bdd_apply(h[i], hp[i], bddop_diff) );
      
      tmp5 = bdd_addref( bdd_apply(tmp4, cp[(i+1)%N], bddop_and) );
      bdd_delref(tmp4);

      tmp6 = bdd_addref( A(c, cp, (i+1)%N) );

      tmp2 = bdd_addref( bdd_apply(tmp5, tmp6, bddop_and) );
      bdd_delref(tmp5);
      bdd_delref(tmp6);

      tmp3 = bdd_addref( A(h, hp, i) );

      tmp4 = bdd_addref( bdd_apply(tmp2, tmp3, bddop_and) );
      bdd_delref(tmp2);
      bdd_delref(tmp3);

      tmp5 = bdd_addref( A(t, tp, N) );

      tmp6 = bdd_addref( bdd_apply(tmp4, tmp5, bddop_and) );
      bdd_delref(tmp4);
      bdd_delref(tmp5);

      P = bdd_addref( bdd_apply(tmp1, tmp6, bddop_or) );
      bdd_delref(tmp1);
      bdd_delref(tmp6);


      tmp1 = bdd_addref( bdd_apply(t[i], tp[i], bddop_diff) );

      tmp2 = bdd_addref( A(t, tp, i) );
      
      tmp3 = bdd_addref( bdd_apply(tmp1, tmp2, bddop_and) );
      bdd_delref(tmp1);
      bdd_delref(tmp2);

      tmp4 = bdd_addref( A(h, hp, N) );
      tmp5 = bdd_addref( A(c, cp, N) );

      tmp6 = bdd_addref( bdd_apply(tmp3, tmp4, bddop_and) );
      bdd_delref(tmp3);
      bdd_delref(tmp4);

      E = bdd_addref( bdd_apply(tmp6, tmp5, bddop_and) );
      bdd_delref(tmp6);
      bdd_delref(tmp5);
      

      tmp1 = bdd_addref( bdd_apply(P, E, bddop_or) );
      bdd_delref(P);
      bdd_delref(E);

      tmp2 = bdd_apply(T, tmp1, bddop_or);
      bdd_delref(T);
      T = tmp2;
   }

   return T;
}