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; }
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_xor(a, b); bdd_fnprintdot("xor.dot", c); bdd_done(); }
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(); }
/* 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; }
/* 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); }
bool xo_equivalence_checker_bdd_programs_equivalent(const xo_program *prog1, const xo_program *prog2) { xo_register_set ro_set_1, ro_set_2; xo_program_analyze(prog1, NULL, &ro_set_1); xo_program_analyze(prog2, NULL, &ro_set_2); if(ro_set_1 != ro_set_2) return false; bdd_init(1000000, 100000); // TODO: good values? bdd_setvarnum(XO_NUM_REGISTERS*XO_NUM_BITS); bdd r[2][XO_NUM_REGISTERS][XO_NUM_BITS], f[2][XO_NUM_FLAGS]; int index = 0; for(int bi = 0; bi < XO_NUM_BITS; ++bi) for(int ri = 0; ri < XO_NUM_REGISTERS; ++ri) r[0][ri][bi] = r[1][ri][bi] = bdd_ithvar(index++); bdd_from_flag_set_(f[0], 0); bdd_from_flag_set_(f[1], 0); evaluate_program_(prog1, r[0], f[0]); evaluate_program_(prog2, r[1], f[1]); size_t ro_index = xo_register_set_first_live_index(ro_set_1); bool equiv = true; for(size_t i = 0; i < XO_NUM_BITS; ++i) { if(r[0][ro_index][i] != r[1][ro_index][i]) { equiv = false; break; } } bdd_done(); return equiv; }
/* 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; }
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; }
/* ML type: varnum -> bdd */ EXTERNML value mlbdd_bdd_ithvar(value i) /* ML */ { return mlbdd_make(bdd_ithvar(Int_val(i))); }
//================================================================== static bdd GET_PROP(spot::bdd_dict *d, const std::string & x, const void * t) { const spot::ltl::formula * f = ENV.require(x); bdd r = bdd_ithvar(d->register_proposition(f, t)); f->destroy(); return r; }
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; }
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]]); } } }
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; }
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); }
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; }