コード例 #1
0
                /** Node visitor */
                public void visit(SafraTree tree, SafraTreeNode node)
                {
                    bool all_final = true;

                    //for (BitSetIterator it=BitSetIterator(node->getLabeling());it!=BitSetIterator::end(node->getLabeling());++it)
                    //BitSet label_this = node.getLabeling();
                    //for (int it = 0; it < label_this.Count; it++)
                    for (int it = BitSetIterator.start(node.getLabeling()); it != BitSetIterator.end(node.getLabeling()); it = BitSetIterator.increment(node.getLabeling(), it))
                    {
                        ////	if (!_nba_states_with_all_succ_final.get(*it)) {
                        if (!_nba_states_with_all_succ_final.get(it))
                        {
                            all_final = false;
                            break;
                        }
                    }

                    if (all_final)
                    {
                        // remove all children of node & set final flag
                        STVisitor_remove_subtree stv_remove = new STVisitor_remove_subtree(_tree_template);
                        tree.walkChildrenPostOrder(stv_remove, node);

                        node.setFinalFlag();

                        _success = true;
                    }
                }
コード例 #2
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);
        }
コード例 #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
        /** 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);
        }
コード例 #6
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);
        }
コード例 #7
0
        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);
        }
コード例 #8
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]);
                }
            }
        }
コード例 #9
0
        /** 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;
            }
        }
コード例 #10
0
        /**
         * Generate a new DRA from a coloring
         */
        DRA generateDRAfromColoring(DRA oldDRA, Coloring coloring, bool detailedStates)
        {
            DRA newDRA = oldDRA.createInstance(oldDRA.getAPSet()) as DRA;


            newDRA.acceptance().newAcceptancePairs(oldDRA.acceptance().size());

            for (int color = 0; color < coloring.countColors(); ++color)
            {
                newDRA.newState();
            }

            int old_start_state   = oldDRA.getStartState().getName();
            int start_state_color = coloring.state2color(old_start_state);

            newDRA.setStartState(newDRA.get(start_state_color));

            APSet apset = newDRA.getAPSet();

            for (int color = 0; color < coloring.countColors(); ++color)
            {
                DA_State new_state = newDRA.get(color);

                int old_state_representative = coloring.color2state(color);

                DA_State old_state = oldDRA[old_state_representative];

                if (detailedStates)
                {
                    BitSet old_states = coloring.color2states(color);

                    // create new description...
                    if (old_states.cardinality() == 1)
                    {
                        if (old_state.hasDescription())
                        {
                            new_state.setDescription(old_state.getDescription());
                        }
                    }
                    else
                    {
                        //std::ostringstream s;
                        //s << "<TABLE BORDER=\"1\" CELLBORDER=\"0\"><TR><TD>{</TD>";
                        StringBuilder s = new StringBuilder(@"<TABLE BORDER=\""1\"" CELLBORDER=\""0\""><TR><TD>{</TD>");

                        bool first = true;
                        for (int it = BitSetIterator.start(old_states); it != BitSetIterator.end(old_states); it = BitSetIterator.increment(old_states, it))
                        {
                            if (first)
                            {
                                first = false;
                            }
                            else
                            {
                                s.Append("<TD>,</TD>");
                            }

                            s.Append("<TD>");
                            if (!oldDRA[it].hasDescription())
                            {
                                s.Append(it);
                            }
                            else
                            {
                                s.Append(oldDRA[it].getDescription());
                            }
                            s.Append("</TD>");
                        }
                        s.Append("<TD>}</TD></TR></TABLE>");

                        new_state.setDescription(s.ToString());
                        ;
                    }
                }

                // Create appropriate acceptance conditions
                int old_state_index = old_state.getName();
                for (int i = 0; i < oldDRA.acceptance().size(); ++i)
                {
                    if (oldDRA.acceptance().isStateInAcceptance_L(i, old_state_index))
                    {
                        new_state.acceptance().addTo_L(i);
                    }

                    if (oldDRA.acceptance().isStateInAcceptance_U(i, old_state_index))
                    {
                        new_state.acceptance().addTo_U(i);
                    }
                }

                //for (APSet::element_iterator label=apset.all_elements_begin();label!=apset.all_elements_end();++label)
                for (int label = apset.all_elements_begin(); label != apset.all_elements_end(); ++label)
                {
                    DA_State old_to = old_state.edges().get(new APElement(label));

                    int to_color = coloring.state2color(old_to.getName());

                    new_state.edges().addEdge(new APElement(label), newDRA.get(to_color));
                }
            }

            return(newDRA);
        }