public List <BitSet> getReachabilityForAllStates() { //std::vector<BitSet>* v=new std::vector<BitSet>; //v->resize(_state_to_scc.size()); List <BitSet> v = new List <BitSet>(); Ultility.resizeExact(v, _state_to_scc.Count); for (int i = 0; i < _state_to_scc.Count; ++i) { int scc = state2scc(i); BitSet reachable_sccs = _reachability[scc]; BitSet reachable_states = new BitSet(); //for (BitSetIterator it(reachable_sccs); it != BitSetIterator::end(reachable_sccs); ++it) for (int it = BitSetIterator.start(reachable_sccs); it != BitSetIterator.end(reachable_sccs); it = BitSetIterator.increment(reachable_sccs, it)) { // union with all states from the reachable scc reachable_states.Union(_sccs[it]); } v[i] = reachable_states; //std::cerr << "from "<<i<<": "<<reachable_states<<std::endl; } return(v); }
/** Calculate the SCCs*/ public void calculate(bool disjoint) { current_dfs_nr = 0; //_dfs_data.Clear(); // Ensure there are as many entries as there are graph-states //_dfs_data.resize(_graph.size()); //Ultility.resize(_dfs_data, _graph.size()); Ultility.resizeExact(_dfs_data, _graph.size()); scc_nr = 0; NBA_State start_state = _graph.getStartState(); if (start_state == null) { return; } if (!disjoint) { int start_idx = start_state.getName(); visit(start_idx); } else { // The Graph may be disjoint -> restart DFS on every not yet visited state for (int v = 0; v < _graph.size(); ++v) { if (_dfs_data[v] == null) //.get() { // not yet visited visit(v); } } } calculateDAG(); }
/** Calculate the Directed Acyclical Graph (DAG) */ public void calculateDAG() { //_result._dag.Clear(); //_result._dag.resize(_result.countSCCs()); Ultility.resizeExact(_result._dag, _result.countSCCs()); //_result._reachability.resize(_result.countSCCs()); Ultility.resizeExact(_result._reachability, _result.countSCCs()); List <int> in_degree = new List <int>(_result.countSCCs()); Ultility.resizeExact(in_degree, _result.countSCCs()); for (int scc = 0; scc < _result.countSCCs(); ++scc) { _result._reachability[scc] = new BitSet(); _result._dag[scc] = new BitSet(); BitSet states_in_scc = _result[scc]; //for (BitSetIterator it=BitSetIterator(states_in_scc); it!=BitSetIterator::end(states_in_scc); ++it) for (int it = BitSetIterator.start(states_in_scc); it != BitSetIterator.end(states_in_scc); it = BitSetIterator.increment(states_in_scc, it)) { int from_state = it; if (_labelMark == null) { //for (typename SuccessorAccess::successor_iterator succ_it=_successor_access.begin(_graph, from_state);succ_it!=_successor_access.end(_graph, from_state); ++succ_it) for (KeyValuePair <APElement, BitSet> it_set = _graph[from_state].edges_begin(); !_graph[from_state].edges_end(); it_set = _graph[from_state].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 to_state = succ_it; int to_scc = _result.state2scc(to_state); if (to_scc != scc) { // Only successor in the DAG if not the same scc if (!_result._dag[scc].get(to_scc)) { // This SCC is a new successor, increment in_degree in_degree[to_scc]++; _result._dag[scc].set(to_scc); } } // Reachability _result._reachability[scc].set(to_scc); } } } else { BitSet it_set = _graph[from_state].getEdge(_labelMark); //for (typename SuccessorAccess::successor_iterator succ_it=_successor_access.begin(_graph, from_state);succ_it!=_successor_access.end(_graph, from_state); ++succ_it) for (int succ_it = BitSetIterator.start(it_set); succ_it != BitSetIterator.end(it_set); succ_it = BitSetIterator.increment(it_set, succ_it)) { int to_state = succ_it; int to_scc = _result.state2scc(to_state); if (to_scc != scc) { // Only successor in the DAG if not the same scc if (!_result._dag[scc].get(to_scc)) { // This SCC is a new successor, increment in_degree in_degree[to_scc]++; _result._dag[scc].set(to_scc); } } // Reachability _result._reachability[scc].set(to_scc); } } } } bool progress = true; int cnt = 0; //_result._topological_order.Clear(); //_result._topological_order.resize(_result.countSCCs()); Ultility.resizeExact(_result._topological_order, _result.countSCCs()); List <int> sort = new List <int>(_result.countSCCs()); Ultility.resizeExact(sort, _result.countSCCs()); while (progress) { progress = false; for (int scc = 0; scc < _result.countSCCs(); ++scc) { if (in_degree[scc] == 0) { sort[scc] = cnt++; progress = true; in_degree[scc] = -1; //for (BitSetIterator it_neighbors= BitSetIterator(_result._dag[scc]); it_neighbors!=BitSetIterator::end(_result._dag[scc]); ++it_neighbors) for (int it_neighbors = BitSetIterator.start(_result._dag[scc]); it_neighbors != BitSetIterator.end(_result._dag[scc]); it_neighbors = BitSetIterator.increment(_result._dag[scc], it_neighbors)) { int scc_to = it_neighbors; in_degree[scc_to]--; } } } } for (int i = 0; i < _result.countSCCs(); i++) { _result._topological_order[sort[i]] = i; } // traverse SCCs in reverse topological order for (int i = _result.countSCCs(); i > 0; --i) { int cur_scc = _result._topological_order[i - 1]; BitSet reaches = _result._reachability[cur_scc]; //for (BitSetIterator it_neighbors= BitSetIterator(_result._dag[cur_scc]); it_neighbors!=BitSetIterator::end(_result._dag[cur_scc]);++it_neighbors) { for (int it_neighbors = BitSetIterator.start(_result._dag[cur_scc]); it_neighbors != BitSetIterator.end(_result._dag[cur_scc]); it_neighbors = BitSetIterator.increment(_result._dag[cur_scc], it_neighbors)) { int scc_to = it_neighbors; reaches.Union(_result._reachability[scc_to]); } } }