TimeType MonaAutomataDotWalker::_constructAutomaton(ASTForm* form) { DFA *monaAutomaton = nullptr; try { DFA *temp = nullptr; size_t monaStates = 0, minimizedStates = 0; toMonaAutomaton(form, monaAutomaton, false); assert(monaAutomaton != nullptr); monaStates = monaAutomaton->ns; temp = dfaCopy(monaAutomaton); dfaUnrestrict(temp); monaAutomaton = dfaMinimize(temp); minimizedStates = monaAutomaton->ns; // Clean up dfaFree(monaAutomaton); monaAutomaton = nullptr; /*dfaFree(temp); temp = nullptr;*/ return std::make_pair(minimizedStates, monaStates); } catch (std::exception &e) { if(monaAutomaton != nullptr) { dfaFree(monaAutomaton); } return std::make_pair(0, 0); } }
DFA *dfa_Prefix(DFA *M, int c1, int c2, int var, int* indices) //Output M' so that L(M')={w| w'\in \Sigma*, ww' \in L(M), c_1 <= |w|<=c_2 } { int i, sink; DFA *M1 = dfaSigmaC1toC2(c1, c2, var, indices); DFA *M2 = dfaCopy(M); //dfaPrintVerbose(M2); sink = find_sink(M); for(i=0; i<M2->ns; i++){ if(i!= sink) M2->f[i]=1; } //dfaPrintVerbose(M2); DFA *result = dfa_intersect(M2, M1); //dfaPrintVerbose(result); dfaFree(M1); dfaFree(M2); return dfaMinimize(result); }//end of prefix
// Constructs a DFA for the equation coeffs*variables+constant=0 // in two's complement arithmetic DFA *build_DFA_eq_2sc(int vars, int *coeffs, int constant, int *indices) { int min, max, states, next_index, next_label, result, target, count; long i; unsigned long j, transitions; struct map_ent *map; char *statuces; DFA *equality, *temp; if (preprocess(vars, coeffs, &constant, 0)) return dfaFalse(); //initialization min = 0; max = 0; for (i = 0; i < vars; i++) if (coeffs[i] > 0) max += coeffs[i]; else min += coeffs[i]; if (constant > max) max = constant; else if (constant < min) min = constant; states = 2 * max - 2 * min + 3; //This array maps state labels (carries) to state indices map = (struct map_ent *) malloc(states * sizeof(struct map_ent)) - min; for (i = min; i < max + 1; i++) { map[i].s = 0; map[i].sr = 0; map[i].i = -1; map[i].ir = -1; } map[constant].sr = 1; //the first state to be expanded next_index = 0; //the next available state index next_label = constant; //the next available state label map[constant].i = -1; map[constant].ir = 0; count = 0; transitions = 1 << vars; //number of transitions from each state //Begin building dfaSetup(states, vars, indices); while (next_label < max + 1) { //there is a state to expand (excuding sink) if (map[next_label].i == count) map[next_label].s = 2; else map[next_label].sr = 2; dfaAllocExceptions(transitions / 2); for (j = 0; j < transitions; j++) { result = next_label + count_ones(j, vars, coeffs); if (!(result & 1)) { target = result / 2; if (target == next_label) { if (map[target].s == 0) { map[target].s = 1; next_index++; map[target].i = next_index; } dfaStoreException(map[target].i, bintostr(j, vars)); } else { if (map[target].sr == 0) { map[target].sr = 1; next_index++; map[target].ir = next_index; } dfaStoreException(map[target].ir, bintostr(j, vars)); } } } dfaStoreState(states - 1); count++; for (next_label = min; (next_label <= max) && (map[next_label].i != count) && (map[next_label].ir != count); next_label++) ; //find next state to expand } for (; count < states; count++) { dfaAllocExceptions(0); dfaStoreState(states - 1); } //define accepting and rejecting states statuces = (char *) malloc(states + 1); for (i = 0; i < states; i++) statuces[i] = '-'; for (next_label = min; next_label <= max; next_label++) if (map[next_label].s == 2) statuces[map[next_label].i] = '+'; statuces[states] = '\0'; temp = dfaBuild(statuces); equality = dfaMinimize(temp); dfaFree(temp); return equality; }
DFA *dfaImport(char* filename, char ***vars, int **orders) { int i, numvars, bdd_nodes, ns, s; FILE *file; DFA *a; char ts[100]; int ti; fprintf(stderr, "IN dfaImport\n"); fflush(stderr); /* Read file */ if ((file = fopen(filename, "r")) == 0) return NULL; /* * BD: we should check the return value of every call to fscanf. */ if (fscanf(file, "MONA DFA\n" "number of variables: %u\n" "variables: ", &numvars) != 1) { return NULL; } /* * BD: allocate vars and order arrays here if needed. * Also initialize a and table to NULL in case we need to clean up. */ a = NULL; table = NULL; if (vars) { *vars = (char **) mem_alloc(sizeof(char *) * (numvars + 1)); // BD: initialize all to NULL so that we can release memory // in case of a read or format error. // (*vars)[numvars] = 0; for (i=0; i<= numvars; i++) { (*vars)[i] = NULL; } } if (orders) { *orders = (int *) mem_alloc(sizeof(int) * numvars); } if (vars) { for (i = 0; i < numvars; i++) { (*vars)[i] = (char *) mem_alloc(100); if (fscanf(file, " %s ", (*vars)[i]) != 1) { goto cleanup; } } } else { for (i = 0; i < numvars; i++) { if (fscanf(file, " %s ", ts) != 1) { goto cleanup; } } } if (fscanf(file, "orders: ") != 0) { goto cleanup; } if (orders) { for (i = 0; i < numvars; i++) if (fscanf(file, " %d ", &((*orders)[i])) != 1) { goto cleanup; } } else { for (i = 0; i < numvars; i++) { if (fscanf(file, " %d ", &ti) != 1) { goto cleanup; } } } if (fscanf(file, "states: %u\n" "initial: %u\n" "bdd nodes: %u\n" "final:", &ns, &s, &bdd_nodes) != 3) { goto cleanup; } a = dfaMake(ns); a->s = s; for (i = 0; i<a->ns; i++) { if (fscanf(file, " %d", &a->f[i]) != 1) { goto cleanup; } } if (fscanf(file, "\nbehaviour:") != 0) { goto cleanup; } for (i = 0; i < a->ns; i++) { if (fscanf(file, " %u", &a->q[i]) != 1) { goto cleanup; } } if (fscanf(file, "\nbdd:\n") != 0) { goto cleanup; } table = (BddNode *) mem_alloc(sizeof(BddNode)*bdd_nodes); for (i = 0; i < bdd_nodes; i++) { table[i].p = -1; if (fscanf(file, "%i %u %u\n", &table[i].idx, &table[i].lo, &table[i].hi) != 3) { goto cleanup; } } if (fgetc(file) != 'e' || fgetc(file) != 'n' || fgetc(file) != 'd') { goto cleanup; } fclose(file); /* fill bdd-manager */ import_bddm = a->bddm; for (i = 0; i < a->ns; i++) a->q[i] = make_node(a->q[i]); mem_free(table); return a; cleanup: fclose(file); if (table != NULL) { mem_free(table); } if (a != NULL) { dfaFree(a); } if (orders) { mem_free(*orders); } if (vars) { i = 0; while ((*vars)[i] != NULL) { mem_free((*vars)[i]); i ++; } mem_free(*vars); } return NULL; }
DFA *dfaSigmaC1toC2(int c1, int c2, int var, int* indices){ int i, n; char *statuces; DFA *result=NULL; if(c2<=-1){ //accept everything after c1 steps n=c1+1; statuces=(char *)malloc((n+1)*sizeof(char)); dfaSetup(n,var,indices); //the 0 to c1-1 states(unaccepted) for( i=0; i<c1; i++){ dfaAllocExceptions(0); dfaStoreState(i+1); statuces[i]='-'; } //the c1 state dfaAllocExceptions(0); dfaStoreState(i); statuces[i]='+'; //i==c1 statuces[n]='\0'; //n==c1+1 }else if(c1<=-1){ n=c2+2; //add one sink state statuces=(char *)malloc((n+1)*sizeof(char)); dfaSetup(n,var,indices); //the 0 to c2 states(accepted) for( i=0; i<=c2; i++){ dfaAllocExceptions(0); dfaStoreState(i+1); statuces[i]='+'; } //the c1 state dfaAllocExceptions(0); dfaStoreState(i); statuces[i]='-'; //i==c2 statuces[n]='\0'; //n==c1+1 }else { assert(c2>=c1); n=c2+2; //add one sink state statuces=(char *)malloc((n+1)*sizeof(char)); dfaSetup(n,var,indices); //the 0 to c2 states(accepted) for( i=0; i<=c2; i++){ dfaAllocExceptions(0); dfaStoreState(i+1); if(i>=c1) statuces[i]='+'; else statuces[i]='-'; } //the c1 state dfaAllocExceptions(0); dfaStoreState(i); statuces[i]='-'; //i==c2 statuces[n]='\0'; //n==c1+1 } result=dfaBuild(statuces); //dfaPrintVerbose(result); free(statuces); if(c1==0) result->f[result->s]=1; DFA *tmp = dfaMinimize(result); dfaFree(result); return tmp; }
DFA *dfa_Suffix(DFA *M, int c1, int c2, int var, int *oldindices) { DFA *result = NULL; DFA *tmpM = NULL; int aux=0; struct int_list_type *states=NULL; struct int_type *tmpState=NULL; int maxCount = 0; int *indices = oldindices; //indices is updated if you need to add auxiliary bits paths state_paths, pp; trace_descr tp; int i, j, z, k; char *exeps; int *to_states; long max_exeps; char *statuces; int len=var; int sink; char *auxbit=NULL; // char *apath =bintostr(a, var); states = reachable_states_bounded_steps(M, c1, c2); maxCount = states->count; if(maxCount>0){ //Need auxiliary bits when there exist some outgoing edges aux = get_hsig(maxCount); if(_FANG_DFA_DEBUG) printf("\n There are %d reachable states, need to add %d auxiliary bits\n", maxCount, aux); auxbit = (char *) malloc(aux*sizeof(char)); len = var+aux; // extra aux bits indices = allocateArbitraryIndex(len); } max_exeps=1<<len; //maybe exponential sink=find_sink(M); assert(sink >-1); //pairs[i] is the list of all reachable states by \sharp1 \bar \sharp0 from i dfaSetup(M->ns+1, len, indices); //add one new initial state exeps=(char *)malloc(max_exeps*(len+1)*sizeof(char)); //plus 1 for \0 end of the string to_states=(int *)malloc(max_exeps*sizeof(int)); statuces=(char *)malloc((M->ns+2)*sizeof(char)); //printf("Before Replace Char\n"); //dfaPrintVerbose(M); k=0; //setup for the initial state tmpState = states->head; for (z=1; z<=states->count; z++) { state_paths = pp = make_paths(M->bddm, M->q[tmpState->value]); while (pp) { if(pp->to!=sink){ to_states[k]=pp->to+1; //insert itself as the initial state for (j = 0; j < var; j++) { //the following for loop can be avoided if the indices are in order for (tp = pp->trace; tp && (tp->index != indices[j]); tp =tp->next); if (tp) { if (tp->value) exeps[k*(len+1)+j]='1'; else exeps[k*(len+1)+j]='0'; }else{ exeps[k*(len+1)+j]='X'; } } set_bitvalue(auxbit, aux, z); // aux = 3, z=4, auxbit 001 for (j = var; j < len; j++) { //set to xxxxxxxx100 exeps[k*(len+1)+j]=auxbit[len-j-1]; } exeps[k*(len+1)+len]='\0'; k++; } pp = pp->next; }//end while kill_paths(state_paths); tmpState = tmpState->next; } //end for dfaAllocExceptions(k); for(k--;k>=0;k--) dfaStoreException(to_states[k],exeps+k*(len+1)); dfaStoreState(sink+1); if(check_accept(M, states)) statuces[0]='+'; else statuces[0]='0'; //for the rest of states (shift one state) for (i = 0; i < M->ns; i++) { state_paths = pp = make_paths(M->bddm, M->q[i]); k=0; while (pp) { if(pp->to!=sink){ for (tp = pp->trace; tp && (tp->index != indices[var]); tp =tp->next); //find the bar value if (!tp || !(tp->value)) { to_states[k]=pp->to+1; for (j = 0; j < var; j++) { //the following for loop can be avoided if the indices are in order for (tp = pp->trace; tp && (tp->index != indices[j]); tp =tp->next); if (tp) { if (tp->value) exeps[k*(len+1)+j]='1'; else exeps[k*(len+1)+j]='0'; } else exeps[k*(len+1)+j]='X'; } for (j = var; j < len; j++) { exeps[k*(len+1)+j]='0'; } exeps[k*(len+1)+len]='\0'; k++; } } pp = pp->next; }//end while dfaAllocExceptions(k); for(k--;k>=0;k--) dfaStoreException(to_states[k],exeps+k*(len+1)); dfaStoreState(sink+1); if(M->f[i]==1) statuces[i+1]='+'; else if(M->f[i]==-1) statuces[i+1]='-'; else statuces[i+1]='0'; kill_paths(state_paths); } statuces[M->ns+1]='\0'; result=dfaBuild(statuces); // dfaPrintVerbose(result); for(i=0; i<aux; i++){ j=len-i-1; tmpM =dfaProject(result, (unsigned) j); dfaFree(result); result = dfaMinimize(tmpM); dfaFree(tmpM); // printf("\n After projecting away %d bits", j); // dfaPrintVerbose(result); } free(exeps); //printf("FREE ToState\n"); free(to_states); //printf("FREE STATUCES\n"); free(statuces); if(maxCount>0) free(auxbit); free_ilt(states); return dfaMinimize(result); }
int main(int argc, char *argv[]) { char **vars; int *orders; DFA *a; char *example; unsigned indices[1]; unsigned index; int i; if (argc != 3) { printf("usage: %s <dfa-file> <variable-name>\n", argv[0]); exit(-1); } /* initialize the BDD package */ bdd_init(); /* import the automaton */ a = dfaImport(argv[1], &vars, &orders); if (!a) { printf("error: unable to import '%s'\n", argv[1]); exit(-1); } /* find the index */ for (index = 0; vars[index]; index++) if (strcmp(vars[index], argv[2]) == 0) break; if (!vars[index]) { printf("error: '%s' not found in '%s'\n", argv[2], argv[1]); exit(-1); } /* 'dfaMakeExample' finds a string leading from the initial state to a nearest accepting state, this string represents a binary encoded number for each free variable */ indices[0] = index; example = dfaMakeExample(a, 1, 1, indices); /* print the result */ if (!example) printf("relation is unsatisfiable!\n"); else { printf("satisfying example:\n" "%s = %d\n", argv[2], decode_example(example, 0, 1)); mem_free(example); } /* clean up */ dfaFree(a); for (i = 0; vars[i]; i++) mem_free(vars[i]); mem_free(vars); mem_free(orders); return 0; }