- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# determinize.hxx

    00001 // determinize.hxx: this file is part of the Vaucanson project.
    00002 //
    00003 // Vaucanson, a generic library for finite state machines.
    00004 //
    00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The
    00006 // Vaucanson Group.
    00007 //
    00008 // This program is free software; you can redistribute it and/or
    00009 // modify it under the terms of the GNU General Public License
    00010 // as published by the Free Software Foundation; either version 2
    00011 // of the License, or (at your option) any later version.
    00012 //
    00013 // The complete GNU General Public Licence Notice can be found as the
    00014 // `COPYING' file in the root directory.
    00015 //
    00016 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
    00017 //
    00018 #ifndef VCSN_ALGORITHMS_DETERMINIZE_HXX
    00019 # define VCSN_ALGORITHMS_DETERMINIZE_HXX
    00020
    00021 # include <map>
    00022 # include <set>
    00023 # include <queue>
    00024 # include <vaucanson/misc/usual_macros.hh>
    00025 # include <vaucanson/automata/concept/automata_base.hh>
    00026
    00027 # ifndef VCSN_NDEBUG
    00028 #  include <vaucanson/algorithms/realtime.hh>
    00029 # endif // ! VCSN_NDEBUG
    00030
    00031 namespace vcsn {
    00032
    00033   /*--------------------.
    00034   | subset_construction |
    00035   `--------------------*/
    00036   // preconditions :
    00037   //    - output has been initialized with good series set
    00038   //      (alphabet is well initialized) ;
    00039   //    - this algorithm is intended to work with realtime automaton
    00040   //      over |B<A*> => add concept checking.
    00041   //
    00042
    00043   template <typename A, typename input_t, typename output_t>
    00044   void
    00045   do_subset_construction(const AutomataBase<A>& ,
    00046                          output_t&              output,
    00047                          const input_t&         input,
    00048                          std::map<typename output_t::hstate_t,
    00049                           std::set<typename input_t::hstate_t> >& m =
    00050                          std::map<typename output_t::hstate_t,
    00051                           std::set<typename input_t::hstate_t> >())
    00052   {
    00053
    00054     /*--------.
    00055     | Typedef |
    00056     `--------*/
    00057
    00058     AUTOMATON_TYPES(input_t);
    00059     AUTOMATON_FREEMONOID_TYPES(input_t);
    00060     typedef typename std::set<typename input_t::hstate_t>    subset_t;
    00061     typedef typename std::map<subset_t, typename output_t::hstate_t>
    00062                                                              subset_set_t;
    00063     typedef std::pair<subset_t, typename output_t::hstate_t> subset_set_pair_t;
    00064     typedef std::vector<typename input_t::hstate_t>          delta_ret_t;
    00065
    00066
    00067     /*-----------------.
    00068     | Initialization.  |
    00069     `-----------------*/
    00070
    00071     typename output_t::hstate_t qi_hstate = output.add_state();
    00072     subset_t qi;
    00073     bool is_final = false;
    00074     for_all_const_initial_states(i, input)
    00075     {
    00076       qi.insert(*i);
    00077       is_final |= input.is_final(*i);
    00078     }
    00079     output.set_initial(qi_hstate);
    00080
    00081     if (is_final)
    00082       output.set_final(qi_hstate);
    00083
    00084     subset_set_t subset_set;
    00085     subset_set[qi] = qi_hstate;
    00086     m[qi_hstate] = qi;
    00087
    00088
    00089     /*------------.
    00090     | Main loop.  |
    00091     `------------*/
    00092
    00093     subset_t q;
    00094     const alphabet_t& alphabet(input.structure().series().monoid().alphabet());
    00095     delta_ret_t dst;
    00096     dst.reserve(input.states().size());
    00097     std::queue<subset_t> path;
    00098     path.push(qi);
    00099     while (!path.empty())
    00100     {
    00101       subset_t s = path.front();
    00102       typename input_t::hstate_t s_hstate = subset_set[s];
    00103       path.pop();
    00104
    00105       for_all_const_letters(e, alphabet)
    00106       {
    00107         q.clear ();
    00108         bool is_final = false;
    00109         for_all_const_ (subset_t, j, s)
    00110         {
    00111           for (delta_iterator t(input.value(), *j); ! t.done(); t.next())
    00112           {
    00113             monoid_elt_t w(input.series_of(*t).structure().monoid(), *e);
    00114             if (input.series_of(*t).get(w) != input.series().semiring().wzero_)
    00115             {
    00116               hstate_t s = input.dst_of(*t);
    00117               q.insert(s);
    00118               is_final |= input.is_final(s);
    00119             }
    00120           }
    00121         }
    00122         typename subset_set_t::const_iterator current = subset_set.find(q);
    00123         if (current == subset_set.end())
    00124         {
    00125           typename output_t::hstate_t qs = output.add_state();
    00126           current = (subset_set.insert(subset_set_pair_t(q, qs))).first;
    00127           m[qs] = q;
    00128
    00129           if (is_final)
    00130             output.set_final(current->second);
    00131           path.push(q);
    00132         }
    00133         output.add_letter_transition(s_hstate, (*current).second, *e);
    00134       }
    00135     }
    00136   }
    00137
    00138   template<typename A, typename AI>
    00139   Element<A, AI>
    00140   subset_construction(const Element<A, AI>& a)
    00141   {
    00142     Element<A, AI> res(a.structure());
    00143     do_subset_construction(res.structure(), res, a);
    00144     return res;
    00145   }
    00146
    00147   /*--------------.
    00148   | determinize.  |
    00149   `--------------*/
    00150   template <typename A, typename AI>
    00151   void
    00152   do_determinize(const AutomataBase<A>& a_set,
    00153                  Element<A, AI>&        output,
    00154                  const Element<A, AI>&  input,
    00155                  std::map<typename Element<A, AI>::hstate_t,
    00156                           std::set<typename Element<A, AI>::hstate_t> >& m)
    00157   {
    00158     BENCH_TASK_SCOPED("determinize");
    00159     precondition(is_realtime(input));
    00160     do_subset_construction(a_set, output, input, m);
    00161   }
    00162
    00163   template<typename A, typename AI>
    00164   Element<A, AI>
    00165   determinize(const Element<A, AI>& a,
    00166               std::map<typename Element<A, AI>::hstate_t,
    00167                 std::set<typename Element<A, AI>::hstate_t> >& m)
    00168   {
    00169     Element<A, AI> ret(a.structure());
    00170     do_determinize(ret.structure(), ret, a, m);
    00171     return ret;
    00172   }
    00173
    00174   template<typename A, typename AI>
    00175   Element<A, AI>
    00176   determinize(const Element<A, AI>& a)
    00177   {
    00178     std::map<typename Element<A, AI>::hstate_t,
    00179              std::set<typename Element<A, AI>::hstate_t> > m;
    00180     return determinize(a, m);
    00181   }
    00182
    00183 } // vcsn
    00184
    00185 #endif // ! VCSN_ALGORITHMS_DETERMINIZE_HXX