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 inequation coeffs*variables+constant<0 // in two's complement arithmetic DFA *build_DFA_ineq_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 *inequality, *temp; //int write1, overbits, label1, label2, co; int write1, label1, label2, co; preprocess(vars, coeffs, &constant, 1); //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 = max - min + 1; //overbits= ceil(log(states)/log(2)); states *= 2; //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); for (j = 0; j < transitions; j++) { co = count_ones(j, vars, coeffs); result = next_label + co; if (result >= 0) target = result / 2; else target = (result - 1) / 2; write1 = result & 1; label1 = next_label; label2 = target; while (label1 != label2) { label1 = label2; result = label1 + co; if (result >= 0) label2 = result / 2; else label2 = (result - 1) / 2; write1 = result & 1; } if (write1) { 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(count); 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 (i = count; i < states; i++) { dfaAllocExceptions(0); dfaStoreState(i); } //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); temp->ns -= states - count; inequality = dfaMinimize(temp); return inequality; }
//Constructs a DFA for the inequation coeffs*variables+constant<0 DFA *build_DFA_ineq_new(int vars, int *coeffs, int constant, int *indices) { int min, max, states, next_index, next_label, result, target, count; long i, transitions; unsigned long j; struct map_ent *map; char *statuces; DFA *inequality, *temp; preprocess(vars, coeffs, &constant, 1); //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 = max - min + 1; //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].i = -1; } map[constant].s = 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 = 0; count = 0; transitions = 1 << vars; //number of transitions from each state //Begin building dfaSetup(states + 1, vars, indices); dfaAllocExceptions(0); dfaStoreState(1); //count++; while (next_label < max + 1) { //there is a state to expand map[next_label].s = 2; dfaAllocExceptions(transitions); for (j = 0; j < transitions; j++) { result = next_label + count_ones(j, vars, coeffs); if (result >= 0) target = result / 2; else target = (result - 1) / 2; if (map[target].s == 0) { map[target].s = 1; next_index++; map[target].i = next_index; } dfaStoreException(map[target].i + 1, bintostr(j, vars)); } dfaStoreState(count); count++; for (next_label = min; (next_label <= max) && (map[next_label].i != count); next_label++) ; //find next state to expand } for (i = count; i <= states; i++) { dfaAllocExceptions(0); dfaStoreState(i); } //define accepting and rejecting states statuces = (char *) malloc(states + 2); for (i = 0; i <= count; i++) statuces[i] = '-'; for (; i <= states; i++) statuces[i] = '0'; for (i = min; i < 0; i++) if (map[i].s == 2) statuces[map[i].i + 1] = '+'; statuces[states + 1] = '\0'; temp = dfaBuild(statuces); temp->ns -= states - count; inequality = dfaMinimize(temp); return inequality; }
// 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 *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); }