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

Generated on Thu Oct 9 20:22:34 2008 for Vaucanson by  doxygen 1.5.1