Ejemplo n.º 1
0
 /** Get the SCCs for the NBA
  * @return the SCCs
  */
 public SCCs getSCCs()
 {
     if (_sccs == null)
     {
         _sccs = new SCCs();
         GraphAlgorithms.calculateSCCs(_nba, _sccs, false, null);
     }
     return(_sccs);
 }
Ejemplo n.º 2
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;
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        /** Constructor */
        public SCC_DFS(NBA graph, SCCs result, APElement label)  //
        {
            _graph  = graph;
            _result = result;
            //_successor_access = successor_access;
            _labelMark = label;

            /** The DFS stack */
            _stack = new Stack <int>();

            /** The SCC_DFS_Data for every state (state index -> DFS_DATA) */
            _dfs_data = new List <SCC_DFS_Data>();
        }
Ejemplo n.º 4
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;
                        }
                    }
                }
            }
        }
Ejemplo n.º 5
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;
                        }
                    }
                }
            }
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
        /** 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;
        }
Ejemplo n.º 8
0
        /** 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;
        }
Ejemplo n.º 9
0
        /** 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);
        }
Ejemplo n.º 10
0
        /** 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);
        }
Ejemplo n.º 11
0
 //, SuccessorAccess& successor_access
 /** Calculate the SCCs for Graph graph and save in result. */
 public static void calculateSCCs(NBA graph, SCCs result, bool disjoint, APElement label)
 {
     SCC_DFS scc_dfs = new SCC_DFS(graph, result, label);
     scc_dfs.calculate(disjoint);
 }
Ejemplo n.º 12
0
 /** Calculate the SCCs for Graph graph and save in result. */
 //public static void calculateSCCs(NBA graph, SCCs result)
 //{
 //    calculateSCCs(graph, result, false);
 //}
 /** Calculate the SCCs for Graph graph and save in result. */
 public static void calculateSCCs(NBA graph, SCCs result, bool disjoint, APElement label)
 {
     // =false, SuccessorAccess successor_access=SuccessorAccess()
     SCC_DFS.calculateSCCs(graph, result, disjoint, label); //, successor_access
 }
Ejemplo n.º 13
0
        //
        /** Constructor */
        public SCC_DFS(NBA graph, SCCs result, APElement label)
        {
            _graph = graph;
            _result = result;
            //_successor_access = successor_access;
            _labelMark = label;

            /** The DFS stack */
            _stack = new Stack<int>();

            /** The SCC_DFS_Data for every state (state index -> DFS_DATA) */
            _dfs_data = new List<SCC_DFS_Data>();
        }
Ejemplo n.º 14
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;
                        }
                    }
                }
            }
        }
Ejemplo n.º 15
0
        /** Calculate the SCCs for Graph graph and save in result. */
        public static void calculateSCCs(NBA graph, SCCs result, bool disjoint, APElement label) //, SuccessorAccess& successor_access
        {
            SCC_DFS scc_dfs = new SCC_DFS(graph, result, label);

            scc_dfs.calculate(disjoint);
        }
Ejemplo n.º 16
0
        /** Calculate the SCCs for Graph graph and save in result. */
        //public static void calculateSCCs(NBA graph, SCCs result)
        //{
        //    calculateSCCs(graph, result, false);
        //}

        /** Calculate the SCCs for Graph graph and save in result. */
        public static void calculateSCCs(NBA graph, SCCs result, bool disjoint, APElement label)
        {                                                          // =false, SuccessorAccess successor_access=SuccessorAccess()
            SCC_DFS.calculateSCCs(graph, result, disjoint, label); //, successor_access
        }