Пример #1
0
        /**
         * Calculate the set of states that are accepting and have a true self loop.
         */
        public void calculateAcceptingTrueLoops()
        {
            _accepting_true_loops = new BitSet();
            //BitSet isAcceptingTrueLoop= *_accepting_true_loops;
            BitSet isAcceptingTrueLoop = _accepting_true_loops;////////changed
            SCCs   sccs = getSCCs();

            for (int scc = 0; scc < sccs.countSCCs(); ++scc)
            {
                if (sccs[scc].cardinality() == 1)
                {
                    int       state_id = sccs[scc].nextSetBit(0);
                    NBA_State state    = _nba[state_id];

                    if (!state.isFinal())
                    {
                        // not final, consider next
                        continue;
                    }

                    if (!sccs.successors(scc).isEmpty())//////////note here
                    {
                        // there are edges leaving this state, consider next
                        continue;
                    }

                    bool no_empty_to = true;
                    if (sccs.stateIsReachable(state_id, state_id))
                    {
                        // state has at least one self-loop
                        // we have to check that there is no edge with empty To

                        //for (typename NBA_t::edge_iterator eit=state->edges_begin(); eit!=state->edges_end(); ++eit)
                        //BitSet[] edges = state._edge_manager._container._storage;

                        //foreach (BitSet eit in edges)
                        for (KeyValuePair <APElement, BitSet> eit = state.edges_begin(); !state.edges_end(); eit = state.increment())
                        {
                            BitSet edge = eit.Value;
                            if (edge.isEmpty())
                            {
                                // not all edges lead back to the state...
                                no_empty_to = false;
                                break;
                            }
                        }

                        if (no_empty_to)
                        {
                            // When we are here the state is a final true loop
                            isAcceptingTrueLoop.set(state_id);
                            //	  std::cerr << "True Loop: " << state_id << std::endl;
                        }
                    }
                }
            }
        }
Пример #2
0
        /**
         * Remove states from the set of accepting (final) states when this is redundant.
         * @param sccs the SCCs of the NBA
         */
        public void removeRedundantFinalStates(SCCs sccs)
        {
            for (int scc = 0; scc < sccs.countSCCs(); ++scc)
            {
                if (sccs[scc].cardinality() == 1)
                {
                    int       state_id = sccs[scc].nextSetBit(0);
                    NBA_State state    = this[state_id];

                    if (state.isFinal())
                    {
                        if (!sccs.stateIsReachable(state_id, state_id))
                        {
                            // The state is final and has no self-loop
                            //  -> the final flag is redundant
                            state.setFinal(false);
                            //	  std::cerr << "Removing final flag for " << state_id << std::endl;
                        }
                    }
                }
            }
        }
Пример #3
0
        /**
         * Calculates BitSet which specifies which states in the NBA
         * only have accepting successors.
         */
        public void calculateStatesWithAllSuccAccepting()
        {
            _allSuccAccepting = new BitSet();
            BitSet result = _allSuccAccepting;
            SCCs   sccs   = getSCCs();

            List <bool> scc_all_final = new List <bool>();

            Ultility.resize(scc_all_final, sccs.countSCCs());

            for (int i = 0; i < scc_all_final.Count; i++)
            {
                scc_all_final[i] = false;
            }

            for (int i = sccs.countSCCs(); i > 0; --i)
            {
                // go backward in topological order...
                int scc = (sccs.topologicalOrder())[i - 1];

                BitSet states_in_scc = sccs[scc];

                // check to see if all states in this SCC are final
                scc_all_final[scc] = true;
                //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))
                {
                    if (!_nba[it].isFinal())
                    {
                        scc_all_final[scc] = false;
                        break;
                    }
                }


                bool might_be_final = false;
                if (scc_all_final[scc] == false)
                {
                    if (states_in_scc.length() == 1)
                    {
                        // there is only one state in this scc ...
                        int state = states_in_scc.nextSetBit(0);

                        if (sccs.stateIsReachable(state, state) == false)
                        {
                            // ... and it doesn't loop to itself
                            might_be_final = true;
                        }
                    }
                }

                if (scc_all_final[scc] == true || might_be_final)
                {
                    // Check to see if all successors are final...
                    bool   all_successors_are_final = true;
                    BitSet scc_succ = sccs.successors(scc);

                    //for (BitSetIterator it=BitSetIterator(scc_succ); it!=BitSetIterator::end(scc_succ); ++it) {
                    for (int it = BitSetIterator.start(scc_succ); it != BitSetIterator.end(scc_succ); it = BitSetIterator.increment(scc_succ, it))
                    {
                        if (!scc_all_final[it])
                        {
                            all_successors_are_final = false;
                            break;
                        }
                    }

                    if (all_successors_are_final)
                    {
                        // Add all states in this SCC to the result-set
                        result.Or(states_in_scc);

                        if (might_be_final)
                        {
                            scc_all_final[scc] = true;
                        }
                    }
                }
            }
        }
Пример #4
0
        /** Check if the NBA is empty.
         * @return true iff the NBA has no accepting run.
         */
        public bool emptinessCheck()
        {
            SCCs sccs = getSCCs();

#if VERBOSE
            std::cerr << sccs << "\n";

            std::cerr << " Reachability: " << std::endl;
            std::vector <BitSet> *reachable = sccs.getReachabilityForAllStates();
            for (unsigned int t = 0; t < reachable->size(); t++)
            {
                std::cerr << t << " -> " << (*reachable)[t] << std::endl;
            }
            delete reachable;
#endif

            for (int scc = 0; scc < sccs.countSCCs(); ++scc)
            {
                BitSet states_in_scc = sccs[scc];

                // check to see if there is an accepting state in this 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 state = it;

#if VERBOSE
                    std::cerr << "Considering state " << state << std::endl;
#endif
                    if (_nba[state].isFinal())
                    {
                        // check to see if this SCC is a trivial SCC (can't reach itself)

#if VERBOSE
                        std::cerr << " +final";
                        std::cerr << " " << states_in_scc.cardinality();
#endif

                        if (states_in_scc.cardinality() == 1)
                        {
                            // there is only one state in this scc ...

#if VERBOSE
                            std::cerr << " +single";
#endif

                            if (sccs.stateIsReachable(state, state) == false)
                            {
                                // ... and it doesn't loop to itself
                                // -> can not guarantee accepting run

#if VERBOSE
                                std::cerr << " -no_loop" << std::endl;
#endif
                                continue;
                            }
                        }

                        // if we are here, the SCC has more than 1 state or
                        // exactly one self-looping state
                        //  -> accepting run

#if VERBOSE
                        std::cerr << "+acc" << std::endl;
#endif

                        // check that SCC can be reached from initial state
                        Debug.Assert(_nba.getStartState() != null);
                        if (sccs.stateIsReachable(_nba.getStartState().getName(), state))
                        {
#if VERBOSE
                            std::cerr << "Found accepting state = " << state << std::endl;
#endif
                            return(false);
                        }
#if VERBOSE
                        std::cerr << "Not reachable!" << std::endl;
#endif
                        continue;
                    }
                }
            }
            return(true);
        }
Пример #5
0
        /**
         * Remove states from the set of accepting (final) states when this is redundant.
         * @param sccs the SCCs of the NBA
         */
        public void removeRedundantFinalStates(SCCs sccs)
        {
            for (int scc = 0; scc < sccs.countSCCs(); ++scc)
            {
                if (sccs[scc].cardinality() == 1)
                {
                    int state_id = sccs[scc].nextSetBit(0);
                    NBA_State state = this[state_id];

                    if (state.isFinal())
                    {
                        if (!sccs.stateIsReachable(state_id, state_id))
                        {
                            // The state is final and has no self-loop
                            //  -> the final flag is redundant
                            state.setFinal(false);
                            //	  std::cerr << "Removing final flag for " << state_id << std::endl;
                        }
                    }
                }
            }
        }
Пример #6
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]);
                }
            }
        }