예제 #1
0
        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);
        }
예제 #2
0
        /** 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();
        }
예제 #3
0
        /** 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]);
                }
            }
        }