Example #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;
}
Example #2
0
BDD bits_range_bdd(uint32_t low_bits,uint32_t high_bits) {
   BDD rval,tail,newbdd;
   int i;
   uint32_t b;
   
   if (low_bits>0) {
      tail=bddtrue;
      for (i=31,b=1;i>=0;i--,b<<=1) {
	 if (low_bits&b)
	   newbdd=bdd_addref(bdd_and(bdd_ithvar(i),tail));
	 else
	   newbdd=bdd_addref(bdd_or(bdd_ithvar(i),tail));
	 bdd_delref(tail);
	 tail=newbdd;
      }
      rval=tail;
   } else
     rval=bddtrue;
   
   if (high_bits<UINT32_MAX) {
      tail=bddtrue;
      for (i=31,b=1;i>=0;i--,b<<=1) {
	 if (high_bits&b)
	   newbdd=bdd_addref(bdd_or(bdd_nithvar(i),tail));
	 else
	   newbdd=bdd_addref(bdd_and(bdd_nithvar(i),tail));
	 bdd_delref(tail);
	 tail=newbdd;
      }
      rval=bdd_addref(bdd_and(rval,tail));
      bdd_delref(tail);
   }
   
   return rval;
}
Example #3
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;
}
Example #4
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;
}
Example #5
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;
}
Example #6
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;
}
Example #7
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;
}
Example #8
0
File: muddy.c Project: Armael/HOL
/* Creation of a bdd makes a finalized pair (mlbdd_finalize, root) as
   described above. */
EXTERNML value mlbdd_make(BDD root) 
{
  value res;
  bdd_addref(root);
  res = mlbdd_alloc_final(2, &mlbdd_finalize);
  Bdd_val(res) = root;  /* Hopefully a BDD fits in a long */
  return res;
}
Example #9
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;
}
Example #10
0
void set_range_width(uint32_t low_code,uint32_t high_code,int width) {
   BDD x,y;

   /* sanity check */
   if (low_code>high_code)
     return;

   /* make a BDD for the range */
   x=code_range_bdd(low_code,high_code);
   
   /* if (in range) /\ (already defined) === true, we've been pre-empted */
   y=bdd_and(x,defined_codes); /* note no addref, we don't need it */
   if (y==x) {
      bdd_delref(x);
      return;
   }
   
   /* if (in range) /\ (already defined) !== false, must split */
   if (y!=bddfalse) {
      bdd_delref(x);
      set_range_width(low_code,(low_code+high_code)/2,width);
      set_range_width((low_code+high_code)/2+1,high_code,width);
      return;
   }
   
   y=bdd_addref(bdd_or(x,defined_codes));
   bdd_delref(defined_codes);
   defined_codes=y;
   
   if (width==0) {
      y=bdd_addref(bdd_or(x,zero_codes));
      bdd_delref(zero_codes);
      zero_codes=y;
   } else if (width==2) {
      y=bdd_addref(bdd_or(x,wide_codes));
      bdd_delref(wide_codes);
      wide_codes=y;
   }
   
   bdd_delref(x);
}
Example #11
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;
}
Example #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;
}
Example #13
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;
   
   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;
}
Example #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);
}
Example #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);
}
Example #16
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;
}
Example #17
0
double support(TransitionSystem *model, BDD result) {
	int count = 0;
	State *pi = model->pseudo_initial;
	State *child;
	int reals = 0;
	for(int i = 0; i < pi->children_size; i++) {
		child = pi->children[i];
		if (child == NULL)
			continue;
		BDD tt = bdd_addref(bdd_and(result, model->states_bdds[child->id]));

		if (tt == model->states_bdds[child->id])
			count += child->cardinality;

		bdd_delref(tt);
		reals += child->cardinality;
	}
	printf("%d\t%d\t", count, reals - count);
	return (double)count / reals;
}
Example #18
0
static void dup_level(int levToInsert, int val) {
	int n;
    for (n = 2; n < bddnodesize; n++) {
    	int lev, lo, hi, newLev;
        int n_low, n_high;
        int hash, r, r2, NEXT_r;
        if (LOW(n) == INVALID_BDD) continue;
        lev = LEVEL(n);
        if (lev != levToInsert || lev == bddvarnum-1) {
            continue;
        }
        lo = LOW(n);
        hi = HIGH(n);
        bdd_addref(n);
        n_low = bdd_makenode(levToInsert+1, val<=0 ? lo : 0, val<=0 ? 0 : lo);
        n_high = bdd_makenode(levToInsert+1, val==0 ? hi : 0, val==0 ? 0 : hi);
        bdd_delref(n);
        newLev = lev;
        SETLOW(n, n_low);
        SETHIGH(n, n_high);
        hash = NODEHASH(lev, lo, hi);
        r = HASH(hash);
        r2 = 0;
        while (r != n && r != 0) {
            r2 = r;
            r = NEXT(r);
        }
        NEXT_r = NEXT(r);
        if (r2 == 0) {
            SETHASH(hash, NEXT_r);
        } else {
            SETNEXT(r2, NEXT_r);
        }
        SETLEVEL(n, newLev);
        lo = LOW(n); hi = HIGH(n);
        hash = NODEHASH(newLev, lo, hi);
        r = HASH(hash);
        SETHASH(hash, n);
        SETNEXT(n, r);
    }
}
Example #19
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;
}
Example #20
0
/*
NAME    {* fdd\_overlapdomain *}
SECTION {* fdd *}
SHORT   {* combine two FDD blocks into one *}
PROTO   {* int fdd_overlapdomain(int v1, int v2) *}
DESCR   {* This function takes two FDD blocks and merges them into a new one,
           such that the new one is encoded using both sets of BDD variables.
	   If {\tt v1} is encoded using the BDD variables $a_1, \ldots,
	   a_n$ and has a domain of $[0,N_1]$, and {\tt v2} is encoded using
	   $b_1, \ldots, b_n$ and has a domain of $[0,N_2]$, then the result
	   will be encoded using the BDD variables $a_1, \ldots, a_n, b_1,
	   \ldots, b_n$ and have the domain $[0,N_1*N_2]$. The use of this
	   function may result in some strange output from
	   {\tt fdd\_printset}. *}
RETURN  {* The index of the finite domain block *}
ALSO    {* fdd\_extdomain *}
*/
int fdd_overlapdomain(int v1, int v2)
{
   Domain *d;
   int n;

   if (!bddrunning)
      return bdd_error(BDD_RUNNING);

   if (v1 < 0  ||  v1 >= fdvarnum  ||  v2 < 0  ||  v2 >= fdvarnum)
      return bdd_error(BDD_VAR);

   if (fdvarnum + 1 > fdvaralloc)
   {
      fdvaralloc += fdvaralloc;

      {
        Domain* tmp_ptr = (Domain*)realloc(domain, sizeof(Domain)*fdvaralloc);
        if (tmp_ptr == NULL)
          return bdd_error(BDD_MEMORY);
        domain = tmp_ptr;
      }
   }

   d = &domain[fdvarnum];
   d->realsize = domain[v1].realsize * domain[v2].realsize;
   d->binsize = domain[v1].binsize + domain[v2].binsize;
   d->ivar = (int *)malloc(sizeof(int)*d->binsize);

   for (n=0 ; n<domain[v1].binsize ; n++)
      d->ivar[n] = domain[v1].ivar[n];
   for (n=0 ; n<domain[v2].binsize ; n++)
      d->ivar[domain[v1].binsize+n] = domain[v2].ivar[n];

   d->var = bdd_makeset(d->ivar, d->binsize);
   bdd_addref(d->var);

   return fdvarnum++;
}
Example #21
0
static int bdd_loaddata(FILE *ifile)
{
   int key,var,low,high,root=0,n;
   
   for (n=0 ; n<lh_nodenum ; n++)
   {
      if (fscanf(ifile,"%d %d %d %d", &key, &var, &low, &high) != 4)
	 return bdd_error(BDD_FORMAT);

      if (low >= 2)
	 low = loadhash_get(low);
      if (high >= 2)
	 high = loadhash_get(high);

      if (low<0 || high<0 || var<0)
	 return bdd_error(BDD_FORMAT);

      root = bdd_addref( bdd_ite(bdd_ithvar(var), high, low) );

      loadhash_add(key, root);
   }

   return root;
}
Example #22
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);
}
Example #23
0
int main(int argc, char** argv)
{
   bdd *c, *cp, *h, *hp, *t, *tp;
   bdd I, T, R;
   int n;
   
   if(argc < 2)
   {
      printf("usage: %s N\n",argv[0]);
      printf("\tN  number of cyclers\n");
      exit(1);
   }
   
   N = atoi(argv[1]);
   if (N <= 0)
   {
      printf("The number of cyclers must more than zero\n");
      exit(2);
   }
   
   bdd_init(100000, 10000);
   bdd_setvarnum(N*6);
      
   c  = (bdd *)malloc(sizeof(bdd)*N);
   cp = (bdd *)malloc(sizeof(bdd)*N);
   t  = (bdd *)malloc(sizeof(bdd)*N);
   tp = (bdd *)malloc(sizeof(bdd)*N);
   h  = (bdd *)malloc(sizeof(bdd)*N);
   hp = (bdd *)malloc(sizeof(bdd)*N);
   
   normvar = (int *)malloc(sizeof(int)*N*3);
   primvar = (int *)malloc(sizeof(int)*N*3);
   
   for (n=0 ; n<N*3 ; n++)
   {
      normvar[n] = n*2;
      primvar[n] = n*2+1;
   }
   normvarset = bdd_addref( bdd_makeset(normvar, N*3) );
   pairs = bdd_newpair();
   bdd_setpairs(pairs, primvar, normvar, 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);
   }
   
   I = bdd_addref( initial_state(t,h,c) );
   T = bdd_addref( transitions(t,tp,h,hp,c,cp) );
   R = bdd_addref( reachable_states(I,T) );
   
   /*if(has_deadlocks(R,T))
     printf("Milner's Scheduler has deadlocks!\n"); */
   
   printf("SatCount R = %.0f\n", bdd_satcount(R));
   printf("Calc       = %.0f\n", (double)N*pow(2.0,1.0+N)*pow(2.0,3.0*N));
   
   bdd_done();
   
   return 0;
}
Example #24
0
int main (int argc, char** argv)
{
    int argi = init_sysCx (&argc, &argv);
    const int xdomsz = 4;
    int xdoms[3];

    int xfddidcs[3];
    bdd ybdds[3];
    bdd satbdd;
    int off;

    bdd a, b, c, d, e;

    if (argi < argc)  return 1;

    xdoms[0] = xdoms[1] = xdoms[2] = xdomsz;

    bdd_init (1000,100);
    push_losefn_sysCx (bdd_done);

    off = bdd_extvarnum (1);
    satbdd = bdd_ithvar (off);

    xfddidcs[0] = fdd_extdomain (xdoms, 3);
    xfddidcs[1] = xfddidcs[0] + 1;
    xfddidcs[2] = xfddidcs[1] + 1;

    off = bdd_extvarnum (3);
    printf ("y0:%d y1:%d y2:%d\n", off + 0, off + 1, off + 2);
    ybdds[0] = bdd_ithvar (off + 0);
    ybdds[1] = bdd_ithvar (off + 1);
    ybdds[2] = bdd_ithvar (off + 2);

    {
        int cnt = bdd_getnodenum ();
        printf ("Start with %d nodes!\n", cnt);
    }


    d = satbdd;
    {:for (i ; 3)
        a = fdd_equals (xfddidcs[i], xfddidcs[(i+1)%3]);
        a = bdd_addref (a);

        b = bdd_biimp (ybdds[i], ybdds[(i+1)%3]);
        b = bdd_addref (b);

        e = bdd_imp (a, b);
        e = bdd_addref (e);
        bdd_delref (a);
        bdd_delref (b);

        c = d;
        d = bdd_and (c, e);
        d = bdd_addref (d);
        bdd_delref (c);
        bdd_delref (e);
    }

#if 0
    a = bdd_satone (d);
    a = bdd_addref (a);

    fdd_printset (a);
    fputc ('\n', stdout);
    bdd_printset (a);
    fputc ('\n', stdout);
    bdd_delref (a);
#endif

    bdd_printtable (d);
    bdd_delref (d);
        /* fdd_clearall (); */

    {
        int cnt;
        bdd_gbc ();
        cnt = bdd_getnodenum ();
        printf ("Still have %d nodes!\n", cnt);
    }

    lose_sysCx ();
    return 0;
}
Example #25
0
BDD pre_exists(TransitionSystem *model, BDD p) {
	BDD pprime = bdd_addref(to_primed(model, p));
	BDD res = bdd_appex(model->transitions_bdd, pprime, bddop_and, model->primed_vars);
	bdd_delref(pprime);
	return res;
}
Example #26
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]]);
		}

	}

}
Example #27
0
void _makebdd(value* vptr, BDD x) {
    int used = bdd_nodecount(x);
    bdd_addref(x);
    *vptr = alloc_custom(&bddops, sizeof (BDD), used, wrapper_ocamlgc_max);
    BDD_val(*vptr) = x;
}
Example #28
0
/*
NAME    {* fdd\_extdomain *}
SECTION {* fdd *}
SHORT   {* adds another set of finite domain blocks *}
PROTO   {* int fdd_extdomain(int *dom, int num) *}
DESCR   {* Extends the set of finite domain blocks with the {\tt num}
           domains in
           {\tt dom}. Each entry in {\tt dom} defines the size of a new
	   finite domain which later on can be used for finite state machine
	   traversal and other operations on finte domains. Each domain
	   allocates $\log_2(|dom[i]|)$ BDD variables to be used later.
	   The ordering is interleaved for the domains defined in each
	   call to {\tt bdd\_extdomain}. This means that assuming domain
	   $D_0$ needs 2 BDD variables $x_1$ and $x_2$, and another domain
	   $D_1$ needs 4 BDD variables $y_1,y_2,y_3$ and $y_4$, then the
	   order will be $x_1,y_1,x_2,y_2,y_3,y_4$. The index of the first
	   domain in {\tt dom} is returned. The index of the other domains
	   are offset from this index with the same offset as in {\tt dom}.

	   The BDD variables needed to encode the domain are created for the
	   purpose and do not interfere with the BDD variables already in
	   use. *}
RETURN  {* The index of the first domain or a negative error code. *}
ALSO    {* fdd\_ithvar, fdd\_equals, fdd\_overlapdomain *}
*/
int fdd_extdomain(int *dom, int num)
{
   int offset = fdvarnum;
   int binoffset;
   int extravars = 0;
   int n, bn, more;

   if (!bddrunning)
      return bdd_error(BDD_RUNNING);

      /* Build domain table */
   if (domain == NULL)  /* First time */
   {
      fdvaralloc = num;
      if ((domain=(Domain*)malloc(sizeof(Domain)*num)) == NULL)
	 return bdd_error(BDD_MEMORY);
   }
   else  /* Allocated before */
   {
      if (fdvarnum + num > fdvaralloc)
      {
         fdvaralloc += (num > fdvaralloc) ? num : fdvaralloc;

         {
           Domain* tmp_ptr =
             (Domain*)realloc(domain, sizeof(Domain)*fdvaralloc);
           if (tmp_ptr == NULL)
             return bdd_error(BDD_MEMORY);
           domain = tmp_ptr;
         }
      }
   }

      /* Create bdd variable tables */
   for (n=0 ; n<num ; n++)
   {
      Domain_allocate(&domain[n+fdvarnum], dom[n]);
      extravars += domain[n+fdvarnum].binsize;
   }

   binoffset = firstbddvar;
   if (firstbddvar + extravars > bddvarnum)
      bdd_setvarnum(firstbddvar + extravars);

      /* Set correct variable sequence (interleaved) */
   for (bn=0,more=1 ; more ; bn++)
   {
      more = 0;

      for (n=0 ; n<num ; n++)
	 if (bn < domain[n+fdvarnum].binsize)
	 {
	    more = 1;
	    domain[n+fdvarnum].ivar[bn] = binoffset++;
	 }
   }

   for (n=0 ; n<num ; n++)
   {
      domain[n+fdvarnum].var = bdd_makeset(domain[n+fdvarnum].ivar,
					   domain[n+fdvarnum].binsize);
      bdd_addref(domain[n+fdvarnum].var);
   }

   fdvarnum += num;
   firstbddvar += extravars;

   return offset;
}
Example #29
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;
}
Example #30
0
BDD code_range_bdd(uint32_t low_code,uint32_t high_code) {
   BDD rval,subrange,srx;
   
   if (low_code<0x80)
     rval=bits_range_bdd((low_code<<24),
			 (high_code>=0x80?
			     0x7FFFFFFF:
			     high_code<<24));
   else
     rval=bddfalse;
   
   if ((low_code<0x800) && (high_code>=0x80)) {
      subrange=bits_range_bdd((low_code<0x80?
			       0xC2800000:
			       ((low_code& 0x3F)<<16)+
			       ((low_code&0x7C0)<<18)+
			       0xC0800000),
			      (high_code>=0x800?
				  0xDFBFFFFF:
				  ((high_code& 0x3F)<<16)+
				  ((high_code&0x7C0)<<18)+
				  0xC080FFFF));

      srx=bdd_addref(bdd_and(subrange,bdd_nithvar(9)));
      bdd_delref(subrange);
      subrange=bdd_addref(bdd_and(srx,bdd_ithvar(8)));
      bdd_delref(srx);
      srx=bdd_addref(bdd_or(rval,subrange));
      bdd_delref(rval);
      bdd_delref(subrange);
      rval=srx;
   }

   if ((low_code<0x10000) && (high_code>=0x800)) {
      subrange=bits_range_bdd((low_code<0x800?
			       0xE0A00000:
			       ((low_code&  0x3F)<<8)+
			       ((low_code& 0xFC0)<<10)+
			       ((low_code&0xF000)<<12)+
			       0xE0808000),
			      (high_code>=0x10000?
				  0xEFBFBFFF:
				  ((high_code&  0x3F)<<8)+
				  ((high_code& 0xFC0)<<10)+
				  ((high_code&0xF000)<<12)+
				  0xE08080FF));

      srx=bdd_addref(bdd_and(subrange,bdd_nithvar(17)));
      bdd_delref(subrange);
      subrange=bdd_addref(bdd_and(srx,bdd_ithvar(16)));
      bdd_delref(srx);
      srx=bdd_addref(bdd_and(subrange,bdd_nithvar(9)));
      bdd_delref(subrange);
      subrange=bdd_addref(bdd_and(srx,bdd_ithvar(8)));
      bdd_delref(srx);
      srx=bdd_addref(bdd_or(rval,subrange));
      bdd_delref(rval);
      bdd_delref(subrange);
      rval=srx;
   }

   if (high_code>=0x10000) {
      subrange=bits_range_bdd((low_code<0x10000?
			       0xF0900000:
			       (low_code&     0x3F)+
			       ((low_code&   0xFC0)<<2)+
			       ((low_code& 0x3F000)<<4)+
			       ((low_code&0x1C0000)<<6)+
			       0xF0808080),
			      (high_code&     0x3F)+
			      ((high_code&   0xFC0)<<2)+
			      ((high_code& 0x3F000)<<4)+
			      ((high_code&0x1C0000)<<6)+
			      0xF0808080);
      
      srx=bdd_addref(bdd_and(subrange,bdd_nithvar(25)));
      bdd_delref(subrange);
      subrange=bdd_addref(bdd_and(srx,bdd_ithvar(24)));
      bdd_delref(srx);
      srx=bdd_addref(bdd_and(subrange,bdd_nithvar(17)));
      bdd_delref(subrange);
      subrange=bdd_addref(bdd_and(srx,bdd_ithvar(16)));
      bdd_delref(srx);
      srx=bdd_addref(bdd_and(subrange,bdd_nithvar(9)));
      bdd_delref(subrange);
      subrange=bdd_addref(bdd_and(srx,bdd_ithvar(8)));
      bdd_delref(srx);
      srx=bdd_addref(bdd_or(rval,subrange));
      bdd_delref(rval);
      bdd_delref(subrange);
      rval=srx;
   }
   
   return rval;
}