Vaucanson  1.4.1
determinize.hxx
1 // determinize.hxx: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The
6 // Vaucanson Group.
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License
10 // as published by the Free Software Foundation; either version 2
11 // of the License, or (at your option) any later version.
12 //
13 // The complete GNU General Public Licence Notice can be found as the
14 // `COPYING' file in the root directory.
15 //
16 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
17 //
18 #ifndef VCSN_ALGORITHMS_DETERMINIZE_HXX
19 # define VCSN_ALGORITHMS_DETERMINIZE_HXX
20 
21 # include <map>
22 # include <set>
23 # include <queue>
24 # include <vaucanson/misc/usual_macros.hh>
25 # include <vaucanson/automata/concept/automata_base.hh>
26 
27 # ifndef VCSN_NDEBUG
29 # endif // ! VCSN_NDEBUG
30 
31 namespace vcsn {
32 
33  /*--------------------.
34  | subset_construction |
35  `--------------------*/
36  // preconditions :
37  // - output has been initialized with good series set
38  // (alphabet is well initialized) ;
39  // - this algorithm is intended to work with realtime automaton
40  // over |B<A*> => add concept checking.
41  //
42 
43  template <typename A, typename input_t, typename output_t>
44  void
45  do_subset_construction(const AutomataBase<A>& ,
46  output_t& output,
47  const input_t& input,
48  std::map<typename output_t::hstate_t,
49  std::set<typename input_t::hstate_t> >& m =
50  std::map<typename output_t::hstate_t,
51  std::set<typename input_t::hstate_t> >())
52  {
53 
54  /*--------.
55  | Typedef |
56  `--------*/
57 
58  AUTOMATON_TYPES(input_t);
59  AUTOMATON_FREEMONOID_TYPES(input_t);
60  typedef typename std::set<typename input_t::hstate_t> subset_t;
61  typedef typename std::map<subset_t, typename output_t::hstate_t>
62  subset_set_t;
63  typedef std::pair<subset_t, typename output_t::hstate_t> subset_set_pair_t;
64  typedef std::vector<typename input_t::hstate_t> delta_ret_t;
65 
66 
67  /*-----------------.
68  | Initialization. |
69  `-----------------*/
70 
71  typename output_t::hstate_t qi_hstate = output.add_state();
72  subset_t qi;
73  bool is_final = false;
74  for_all_const_initial_states(i, input)
75  {
76  qi.insert(*i);
77  is_final |= input.is_final(*i);
78  }
79  output.set_initial(qi_hstate);
80 
81  if (is_final)
82  output.set_final(qi_hstate);
83 
84  subset_set_t subset_set;
85  subset_set[qi] = qi_hstate;
86  m[qi_hstate] = qi;
87 
88 
89  /*------------.
90  | Main loop. |
91  `------------*/
92 
93  subset_t q;
94  const alphabet_t& alphabet(input.structure().series().monoid().alphabet());
95  delta_ret_t dst;
96  dst.reserve(input.states().size());
97  std::queue<subset_t> path;
98  path.push(qi);
99  while (!path.empty())
100  {
101  subset_t s = path.front();
102  typename input_t::hstate_t s_hstate = subset_set[s];
103  path.pop();
104 
105  for_all_const_letters(e, alphabet)
106  {
107  q.clear ();
108  bool is_final = false;
109  for_all_const_ (subset_t, j, s)
110  {
111  for (delta_iterator t(input.value(), *j); ! t.done(); t.next())
112  {
113  monoid_elt_t w(input.series_of(*t).structure().monoid(), *e);
114  if (input.series_of(*t).get(w) != input.series().semiring().wzero_)
115  {
116  hstate_t s = input.dst_of(*t);
117  q.insert(s);
118  is_final |= input.is_final(s);
119  }
120  }
121  }
122  typename subset_set_t::const_iterator current = subset_set.find(q);
123  if (current == subset_set.end())
124  {
125  typename output_t::hstate_t qs = output.add_state();
126  current = (subset_set.insert(subset_set_pair_t(q, qs))).first;
127  m[qs] = q;
128 
129  if (is_final)
130  output.set_final(current->second);
131  path.push(q);
132  }
133  output.add_letter_transition(s_hstate, (*current).second, *e);
134  }
135  }
136  }
137 
138  template<typename A, typename AI>
139  Element<A, AI>
140  subset_construction(const Element<A, AI>& a)
141  {
142  Element<A, AI> res(a.structure());
143  do_subset_construction(res.structure(), res, a);
144  return res;
145  }
146 
147  /*--------------.
148  | determinize. |
149  `--------------*/
150  template <typename A, typename AI>
151  void
152  do_determinize(const AutomataBase<A>& a_set,
153  Element<A, AI>& output,
154  const Element<A, AI>& input,
155  std::map<typename Element<A, AI>::hstate_t,
156  std::set<typename Element<A, AI>::hstate_t> >& m)
157  {
158  BENCH_TASK_SCOPED("determinize");
159  precondition(is_realtime(input));
160  do_subset_construction(a_set, output, input, m);
161  }
162 
163  template<typename A, typename AI>
164  Element<A, AI>
166  std::map<typename Element<A, AI>::hstate_t,
167  std::set<typename Element<A, AI>::hstate_t> >& m)
168  {
169  Element<A, AI> ret(a.structure());
170  do_determinize(ret.structure(), ret, a, m);
171  return ret;
172  }
173 
174  template<typename A, typename AI>
175  Element<A, AI>
177  {
178  std::map<typename Element<A, AI>::hstate_t,
179  std::set<typename Element<A, AI>::hstate_t> > m;
180  return determinize(a, m);
181  }
182 
183 } // vcsn
184 
185 #endif // ! VCSN_ALGORITHMS_DETERMINIZE_HXX