/** 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; }
/** * Move the bits set in acc to the places specified by mapping. */ private void move_acceptance_bits(BitSet acc, List<int> mapping) { int i = 0; while (i != -1) { int j = mapping[i]; // :: j is always <= i if (j > i) { throw new Exception("Wrong mapping in move_acceptance_bits"); } if (i == j) { // do nothing } else { // move bit from i->j //acc[j] = true; //acc[i] = false; acc.set(j); acc.clear(i); } //i=acc.nextSetBit(i+1); //i++; i = acc.nextSetBit(i + 1); } }
/** Calculate the BitSet for a state from the acceptance pairs, store * result in result. * @param state_index the state * @param acc the BitSetVector (either _L or _U) * @param result the Bitset where the results are stored, has to be clear * at the beginning! */ private void getBitSetForState(int state_index, List<BitSet> acc, BitSet result) { for (int i = 0; i < acc.Count; i++) { if (acc[i] != null) { if (acc[i].get(state_index)) { //result[i] = true; result.set(i); } } } }
/** Visit a state (perform DFS) */ public void visit(int v) { SCC_DFS_Data sdd = new SCC_DFS_Data(); sdd.dfs_nr = current_dfs_nr++; sdd.root_index = v; sdd.inComponent = false; _stack.Push(v); //todo: be careful of the following swap //_dfs_data[v].reset(sdd); //Ultility.swap(_dfs_data[v], sdd); _dfs_data[v] = sdd; //for (typename SuccessorAccess::successor_iterator succ_it=_successor_access.begin(_graph, v);succ_it!=_successor_access.end(_graph, v); ++succ_it) if(_labelMark == null) { for (KeyValuePair<APElement, BitSet> it_set = _graph[v].edges_begin(); !_graph[v].edges_end(); it_set = _graph[v].increment()) { for (int succ_it = BitSetIterator.start(it_set.Value); succ_it != BitSetIterator.end(it_set.Value); succ_it = BitSetIterator.increment(it_set.Value, succ_it)) { int w = succ_it; if (_dfs_data[w] == null) //.get() { // not yet visited visit(w); } SCC_DFS_Data sdd_w = _dfs_data[w]; //.get(); if (sdd_w.inComponent == false) { int dfs_nr_root_v = _dfs_data[sdd.root_index].dfs_nr; int dfs_nr_root_w = _dfs_data[sdd_w.root_index].dfs_nr; if (dfs_nr_root_v > dfs_nr_root_w) { sdd.root_index = sdd_w.root_index; } } } } } else { BitSet it_set = _graph[v].getEdge(_labelMark); for (int succ_it = BitSetIterator.start(it_set); succ_it != BitSetIterator.end(it_set); succ_it = BitSetIterator.increment(it_set, succ_it)) { int w = succ_it; if (_dfs_data[w] == null) //.get() { // not yet visited visit(w); } SCC_DFS_Data sdd_w = _dfs_data[w]; //.get(); if (sdd_w.inComponent == false) { int dfs_nr_root_v = _dfs_data[sdd.root_index].dfs_nr; int dfs_nr_root_w = _dfs_data[sdd_w.root_index].dfs_nr; if (dfs_nr_root_v > dfs_nr_root_w) { sdd.root_index = sdd_w.root_index; } } } } if (sdd.root_index == v) { BitSet set = new BitSet(); int w; do { //w=_stack.Peek(); //.top(); w = _stack.Pop(); set.set(w); _result.setState2SCC(w, scc_nr); SCC_DFS_Data sdd_w = _dfs_data[w];//.get(); sdd_w.inComponent = true; } while (w != v); scc_nr = _result.addSCC(set) + 1; } }
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; }