/** Check for partial stutter insensitiveness using * the nba and the complement nba */ public void checkNBAs(NBA nba, NBA nba_complement) { APSet apset = nba.getAPSet_cp(); bool nba_is_smaller = (nba.size() < nba_complement.size()); //if (_printInfo) { // std::cerr << "Checking for insensitiveness" << std::endl; //} bool one_insensitive = false; bool all_insensitive = true; //for (APSet::element_iterator it=apset->all_elements_begin(); it!=apset->all_elements_end();++it) for (int it = apset.all_elements_begin(); it != apset.all_elements_end(); ++it) { APElement elem = new APElement(it); if (_partiallyInsensitive.get(it)) { // don't recheck something we already now is stutter insensitive one_insensitive = true; continue; } // if (_printInfo) { //std::cerr << "Checking " << elem.toString(*apset) << ": "; //std::cerr.flush(); // } bool insensitive; if (nba_is_smaller) { insensitive = is_stutter_insensitive(nba, nba_complement, elem); } else { insensitive = is_stutter_insensitive(nba_complement, nba, elem); } if (insensitive) { _partiallyInsensitive.set(it); one_insensitive = true; //if (_printInfo) { // std::cerr << "+" << std::endl; //} } else { all_insensitive = false; //if (_printInfo) { // std::cerr << "-" << std::endl; //} } } _hasCheckedNBAs = true; _partiallyStutterInsensitive = one_insensitive; }
/** * Convert an NBA to a DRA using Safra's algorithm. * If limit is specified (>0), the conversion is * aborted with LimitReachedException when the number of * states exceeds the limit. * @param nba the formula * @param limit a limit on the number of states (0 for no limit) * @param detailedStates save detailed interal information (Safra trees) * in the generated states * @param stutter_information Information about the symbols that can be stuttered * @return a shared_ptr to the created DRA */ public DRA nba2dra(NBA nba, int limit, bool detailedStates, StutterSensitivenessInformation stutter_information) { DRA dra = new DRA(nba.getAPSet_cp()); NBA2DRA nba2dra = new NBA2DRA(_safra_opt, detailedStates, stutter_information); try { nba2dra.convert(nba, dra, limit); } catch (LimitReachedException e) { //dra.reset(); // rethrow to notify caller //throw; } return dra; }
/** * Convert an NBA to a DRA using Safra's algorithm. * If limit is specified (>0), the conversion is * aborted with LimitReachedException when the number of * states exceeds the limit. * @param nba the formula * @param limit a limit on the number of states (0 for no limit) * @param detailedStates save detailed interal information (Safra trees) * in the generated states * @param stutter_information Information about the symbols that can be stuttered * @return a shared_ptr to the created DRA */ public DRA nba2dra(NBA nba, int limit, bool detailedStates, StutterSensitivenessInformation stutter_information) { DRA dra = new DRA(nba.getAPSet_cp()); NBA2DRA nba2dra = new NBA2DRA(_safra_opt, detailedStates, stutter_information); try { nba2dra.convert(nba, dra, limit); } catch (LimitReachedException e) { //dra.reset(); // rethrow to notify caller //throw; } return(dra); }
/** Calculate the stutter closure for the NBA, for all symbols. * @param nba the NBA */ public static NBA stutter_closure(NBA nba) { APSet apset = nba.getAPSet_cp(); NBA nba_result_ptr = new NBA(apset); NBA result = nba_result_ptr; int element_count = apset.powersetSize(); Debug.Assert(nba.getStartState() != null); int start_state = nba.getStartState().getName(); for (int i = 0; i < nba.size(); i++) { int st = result.nba_i_newState(); Debug.Assert(st == i); if (st == start_state) { result.setStartState(result[st]); } if (nba[st].isFinal()) { result[st].setFinal(true); } } for (int i = 0; i < nba.size(); i++) { for (int j = 0; j < element_count; j++) { int st = result.nba_i_newState(); Debug.Assert(st == nba.size() + (i*element_count) + j); result[st].addEdge(new APElement(j), result[i]); result[st].addEdge(new APElement(j), result[st]); } } List<List<BitSet>> reachable = new List<List<BitSet>>(); //reachable.resize(element_count); Ultility.resize(reachable, element_count); for (int j = 0; j < element_count; j++) { //NBAEdgeSuccessors edge_successor = new NBAEdgeSuccessors(new APElement(j)); SCCs scc = new SCCs(); GraphAlgorithms.calculateSCCs(nba, scc, true, new APElement(j)); //,edge_successor reachable[j] = scc.getReachabilityForAllStates(); #if VERBOSE std::cerr << "SCCs for " << APElement(j).toString(*apset) << std::endl; std::cerr << scc << std::endl; std::cerr << " Reachability: "<< std::endl; std::vector<BitSet>& reach=*reachable[j]; for (unsigned int t=0; t < reach.size(); t++) { std::cerr << t << " -> " << reach[t] << std::endl; } std::cerr << " ---\n"; #endif } for (int i = 0; i < nba.size(); i++) { NBA_State from = result[i]; for (int j = 0; j < element_count; j++) { BitSet result_to = new BitSet(); BitSet to = nba[i].getEdge(new APElement(j)); //for (BitSetIterator it=BitSetIterator(*to);it!=BitSetIterator::end(*to);++it) for (int it = BitSetIterator.start(to); it != BitSetIterator.end(to); it = BitSetIterator.increment(to, it)) { int to_state = it; // We can go directly to the original state result_to.set(to_state); // We can also go to the corresponding stutter state instead int stutter_state = nba.size() + (to_state*element_count) + j; result_to.set(stutter_state); // ... and then we can go directly to all the states that are j-reachable from to result_to.Union(reachable[j][to_state]); } from.getEdge(new APElement(j)).Assign(result_to); } } //for (int i=0; i<reachable.size(); ++i) { // delete reachable[i]; // } return nba_result_ptr; }
/** Calculate the stutter closure for the NBA, for a certain symbol. * @param nba the NBA * @param label the symbol for which to perform the stutter closure */ public static NBA stutter_closure(NBA nba, APElement label) { APSet apset = nba.getAPSet_cp(); NBA nba_result_ptr = new NBA(apset); NBA result = nba_result_ptr; int element_count = apset.powersetSize(); Debug.Assert(nba.getStartState() != null); int start_state = nba.getStartState().getName(); for (int i = 0; i < nba.size(); i++) { int st = result.nba_i_newState(); Debug.Assert(st == i); if (st == start_state) { result.setStartState(result[st]); } if (nba[st].isFinal()) { result[st].setFinal(true); } } for (int i = 0; i < nba.size(); i++) { int st = result.nba_i_newState(); Debug.Assert(st == nba.size() + i); result[st].addEdge(label, result[i]); result[st].addEdge(label, result[st]); } //List<BitSet> reachable = null; //NBAEdgeSuccessors edge_successor = new NBAEdgeSuccessors(label); SCCs scc = new SCCs(); GraphAlgorithms.calculateSCCs(nba, scc, true, label); //,edge_successor List<BitSet> reachable = scc.getReachabilityForAllStates(); // std::cerr << "SCCs for " << label.toString(*apset) << std::endl; // std::cerr << scc << std::endl; // std::cerr << " Reachability: "<< std::endl; // for (unsigned int t=0; t < reachable->size(); t++) { // std::cerr << t << " -> " << (*reachable)[t] << std::endl; // } // std::cerr << " ---\n"; for (int i = 0; i < nba.size(); i++) { NBA_State from = result[i]; for (int j = 0; j < element_count; j++) { BitSet result_to = new BitSet(); BitSet to = nba[i].getEdge(new APElement(j)); if (j != label.bitset) { result_to = to; } else { //for (BitSetIterator it=BitSetIterator(*to);it!=BitSetIterator::end(*to);++it) for (int it = BitSetIterator.start(to); it != BitSetIterator.end(to); it = BitSetIterator.increment(to, it)) { int to_state = it; // We can go directly to the original state result_to.set(to_state); // We can also go to the corresponding stutter state instead int stutter_state = nba.size() + to_state; result_to.set(stutter_state); // ... and then we can go directly to all the states that are j-reachable from to result_to.Union(reachable[to_state]); } } from.getEdge(new APElement(j)).Assign(result_to); } } //delete reachable; return nba_result_ptr; }
/** Calculate the stutter closure for the NBA, for a certain symbol. * @param nba the NBA * @param label the symbol for which to perform the stutter closure */ public static NBA stutter_closure(NBA nba, APElement label) { APSet apset = nba.getAPSet_cp(); NBA nba_result_ptr = new NBA(apset); NBA result = nba_result_ptr; int element_count = apset.powersetSize(); Debug.Assert(nba.getStartState() != null); int start_state = nba.getStartState().getName(); for (int i = 0; i < nba.size(); i++) { int st = result.nba_i_newState(); Debug.Assert(st == i); if (st == start_state) { result.setStartState(result[st]); } if (nba[st].isFinal()) { result[st].setFinal(true); } } for (int i = 0; i < nba.size(); i++) { int st = result.nba_i_newState(); Debug.Assert(st == nba.size() + i); result[st].addEdge(label, result[i]); result[st].addEdge(label, result[st]); } //List<BitSet> reachable = null; //NBAEdgeSuccessors edge_successor = new NBAEdgeSuccessors(label); SCCs scc = new SCCs(); GraphAlgorithms.calculateSCCs(nba, scc, true, label); //,edge_successor List <BitSet> reachable = scc.getReachabilityForAllStates(); // std::cerr << "SCCs for " << label.toString(*apset) << std::endl; // std::cerr << scc << std::endl; // std::cerr << " Reachability: "<< std::endl; // for (unsigned int t=0; t < reachable->size(); t++) { // std::cerr << t << " -> " << (*reachable)[t] << std::endl; // } // std::cerr << " ---\n"; for (int i = 0; i < nba.size(); i++) { NBA_State from = result[i]; for (int j = 0; j < element_count; j++) { BitSet result_to = new BitSet(); BitSet to = nba[i].getEdge(new APElement(j)); if (j != label.bitset) { result_to = to; } else { //for (BitSetIterator it=BitSetIterator(*to);it!=BitSetIterator::end(*to);++it) for (int it = BitSetIterator.start(to); it != BitSetIterator.end(to); it = BitSetIterator.increment(to, it)) { int to_state = it; // We can go directly to the original state result_to.set(to_state); // We can also go to the corresponding stutter state instead int stutter_state = nba.size() + to_state; result_to.set(stutter_state); // ... and then we can go directly to all the states that are j-reachable from to result_to.Union(reachable[to_state]); } } from.getEdge(new APElement(j)).Assign(result_to); } } //delete reachable; return(nba_result_ptr); }
/** Calculate the stutter closure for the NBA, for all symbols. * @param nba the NBA */ public static NBA stutter_closure(NBA nba) { APSet apset = nba.getAPSet_cp(); NBA nba_result_ptr = new NBA(apset); NBA result = nba_result_ptr; int element_count = apset.powersetSize(); Debug.Assert(nba.getStartState() != null); int start_state = nba.getStartState().getName(); for (int i = 0; i < nba.size(); i++) { int st = result.nba_i_newState(); Debug.Assert(st == i); if (st == start_state) { result.setStartState(result[st]); } if (nba[st].isFinal()) { result[st].setFinal(true); } } for (int i = 0; i < nba.size(); i++) { for (int j = 0; j < element_count; j++) { int st = result.nba_i_newState(); Debug.Assert(st == nba.size() + (i * element_count) + j); result[st].addEdge(new APElement(j), result[i]); result[st].addEdge(new APElement(j), result[st]); } } List <List <BitSet> > reachable = new List <List <BitSet> >(); //reachable.resize(element_count); Ultility.resize(reachable, element_count); for (int j = 0; j < element_count; j++) { //NBAEdgeSuccessors edge_successor = new NBAEdgeSuccessors(new APElement(j)); SCCs scc = new SCCs(); GraphAlgorithms.calculateSCCs(nba, scc, true, new APElement(j)); //,edge_successor reachable[j] = scc.getReachabilityForAllStates(); #if VERBOSE std::cerr << "SCCs for " << APElement(j).toString(*apset) << std::endl; std::cerr << scc << std::endl; std::cerr << " Reachability: " << std::endl; std::vector <BitSet>& reach = *reachable[j]; for (unsigned int t = 0; t < reach.size(); t++) { std::cerr << t << " -> " << reach[t] << std::endl; } std::cerr << " ---\n"; #endif } for (int i = 0; i < nba.size(); i++) { NBA_State from = result[i]; for (int j = 0; j < element_count; j++) { BitSet result_to = new BitSet(); BitSet to = nba[i].getEdge(new APElement(j)); //for (BitSetIterator it=BitSetIterator(*to);it!=BitSetIterator::end(*to);++it) for (int it = BitSetIterator.start(to); it != BitSetIterator.end(to); it = BitSetIterator.increment(to, it)) { int to_state = it; // We can go directly to the original state result_to.set(to_state); // We can also go to the corresponding stutter state instead int stutter_state = nba.size() + (to_state * element_count) + j; result_to.set(stutter_state); // ... and then we can go directly to all the states that are j-reachable from to result_to.Union(reachable[j][to_state]); } from.getEdge(new APElement(j)).Assign(result_to); } } //for (int i=0; i<reachable.size(); ++i) { // delete reachable[i]; // } return(nba_result_ptr); }
public static NBA product_automaton(NBA nba_1, NBA nba_2) { Debug.Assert(nba_1.getAPSet() == nba_2.getAPSet()); NBA product_nba = new NBA(nba_1.getAPSet_cp()); APSet apset = nba_1.getAPSet(); Debug.Assert(apset == nba_2.getAPSet()); for (int s_1 = 0; s_1 < nba_1.size(); s_1++) { for (int s_2 = 0; s_2 < nba_2.size(); s_2++) { for (int copy = 0; copy < 2; copy++) { int s_r = product_nba.nba_i_newState(); Debug.Assert(s_r == (s_1 * nba_2.size() + s_2) * 2 + copy); int to_copy = copy; if (copy == 0 && nba_1[s_1].isFinal()) { to_copy = 1; } if (copy == 1 && nba_2[s_2].isFinal()) { product_nba[s_r].setFinal(true); to_copy = 0; } //for (typename APSet::element_iterator it=apset.all_elements_begin();it!=apset.all_elements_end();++it) for (int it = apset.all_elements_begin(); it != apset.all_elements_end(); it++) { APElement label = new APElement(it); BitSet to_s1 = nba_1[s_1].getEdge(label); BitSet to_s2 = nba_2[s_2].getEdge(label); BitSet to_set = new BitSet(); //for (BitSetIterator it_e_1 = BitSetIterator(*to_s1); it_e_1 != BitSetIterator::end(*to_s1); ++it_e_1) //for (int it_e_1 = 0; it_e_1 != to_s1.bitset.Count; ++it_e_1) for (int it_e_1 = BitSetIterator.start(to_s1); it_e_1 != BitSetIterator.end(to_s1); it_e_1 = BitSetIterator.increment(to_s1, it_e_1)) { //for (BitSetIterator it_e_2 = BitSetIterator(*to_s2); it_e_2 != BitSetIterator::end(*to_s2); ++it_e_2) //for (int it_e_2 = 0; it_e_2 != to_s2.bitset.Count; ++it_e_2) for (int it_e_2 = BitSetIterator.start(to_s2); it_e_2 != BitSetIterator.end(to_s2); it_e_2 = BitSetIterator.increment(to_s2, it_e_2)) { int to = it_e_1 * nba_2.size() + it_e_2 * 2 + to_copy; to_set.set(to); } } product_nba[s_r].getEdge(label).Assign(to_set); } } } } int start_1 = nba_1.getStartState().getName(); int start_2 = nba_2.getStartState().getName(); product_nba.setStartState(product_nba[start_1 * nba_2.size() + start_2]); return(product_nba); }
public static NBA product_automaton(NBA nba_1, NBA nba_2) { Debug.Assert(nba_1.getAPSet() == nba_2.getAPSet()); NBA product_nba = new NBA(nba_1.getAPSet_cp()); APSet apset = nba_1.getAPSet(); Debug.Assert(apset == nba_2.getAPSet()); for (int s_1 = 0; s_1 < nba_1.size(); s_1++) { for (int s_2 = 0; s_2 < nba_2.size(); s_2++) { for (int copy = 0; copy < 2; copy++) { int s_r = product_nba.nba_i_newState(); Debug.Assert(s_r == (s_1 * nba_2.size() + s_2) * 2 + copy); int to_copy = copy; if (copy == 0 && nba_1[s_1].isFinal()) { to_copy = 1; } if (copy == 1 && nba_2[s_2].isFinal()) { product_nba[s_r].setFinal(true); to_copy = 0; } //for (typename APSet::element_iterator it=apset.all_elements_begin();it!=apset.all_elements_end();++it) for (int it = apset.all_elements_begin(); it != apset.all_elements_end(); it++) { APElement label = new APElement(it); BitSet to_s1 = nba_1[s_1].getEdge(label); BitSet to_s2 = nba_2[s_2].getEdge(label); BitSet to_set = new BitSet(); //for (BitSetIterator it_e_1 = BitSetIterator(*to_s1); it_e_1 != BitSetIterator::end(*to_s1); ++it_e_1) //for (int it_e_1 = 0; it_e_1 != to_s1.bitset.Count; ++it_e_1) for (int it_e_1 = BitSetIterator.start(to_s1); it_e_1 != BitSetIterator.end(to_s1); it_e_1 = BitSetIterator.increment(to_s1, it_e_1)) { //for (BitSetIterator it_e_2 = BitSetIterator(*to_s2); it_e_2 != BitSetIterator::end(*to_s2); ++it_e_2) //for (int it_e_2 = 0; it_e_2 != to_s2.bitset.Count; ++it_e_2) for (int it_e_2 = BitSetIterator.start(to_s2); it_e_2 != BitSetIterator.end(to_s2); it_e_2 = BitSetIterator.increment(to_s2, it_e_2)) { int to = it_e_1 * nba_2.size() + it_e_2 * 2 + to_copy; to_set.set(to); } } product_nba[s_r].getEdge(label).Assign(to_set); } } } } int start_1 = nba_1.getStartState().getName(); int start_2 = nba_2.getStartState().getName(); product_nba.setStartState(product_nba[start_1 * nba_2.size() + start_2]); return product_nba; }