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; }
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; }
/* 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; }
/* * 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; }
/* 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; }
/* * 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; }
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; }
/* 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; }
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(); }
/* 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; }
/* 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; }
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); }
/* 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); }
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); }
/* 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))); }
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]]); } } }
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; }