Vaucanson  1.4.1
realtime.hxx
1 // realtime.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 Vaucanson Group.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // The complete GNU General Public Licence Notice can be found as the
13 // `COPYING' file in the root directory.
14 //
15 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
16 //
17 #ifndef VCSN_ALGORITHMS_REALTIME_HXX
18 # define VCSN_ALGORITHMS_REALTIME_HXX
19 
21 
25 
26 # include <vaucanson/automata/concept/automata_base.hh>
27 
28 # include <deque>
29 # include <set>
30 
31 namespace vcsn {
32 
33 
34  /*--------------------.
35  | do_realtime_words. |
36  `--------------------*/
37 
38  template <class Auto>
39  void do_realtime_words(Auto& a)
40  {
41  AUTOMATON_TYPES(Auto);
42  hstate_t s1;
43  semiring_elt_t s_ident = algebra::identity_as<semiring_elt_value_t>
44  ::of(a.structure().series().semiring());
45 
46  typedef std::vector<htransition_t> transition_vector_t;
47  transitions_t transitions = a.transitions();
48  transition_vector_t tmp_trans;
49  for_all_(transitions_t, e, transitions)
50  tmp_trans.push_back(*e);
51 
52  for_all(typename transition_vector_t, e, tmp_trans)
53  {
54  hstate_t start = a.src_of(*e);
55  hstate_t stop = a.dst_of(*e);
56  series_set_elt_t label = a.series_of(*e);
57 
58  assert(label.supp().begin() != label.supp().end());
59 
60  monoid_elt_t m1(a.structure().series().monoid(), *label.supp().begin());
61  monoid_elt_value_t w1 = m1.value();
62  unsigned int size = m1.length();
63 
64  if (size > 1)
65  {
66  monoid_elt_t m(a.structure().series().monoid());
67 
68  semiring_elt_t s = label.get(m1);
69  series_set_elt_t in_series(a.structure().series());
70  typename monoid_elt_t::iterator l = m1.begin();
71 
72  m = *l;
73 
74  in_series.assoc(m, s);
75 
76  s1 = a.add_state();
77  a.add_series_transition(start, s1, in_series);
78 
79  l++;
80  for (typename monoid_elt_t::iterator end = m1.begin() + (size - 1);
81  l != end; ++l)
82  {
83  m = *l;
84  hstate_t s0 = s1;
85  s1 = a.add_state();
86  series_set_elt_t series(a.structure().series());
87  series.assoc(m, s_ident);
88  a.add_series_transition(s0, s1, series);
89  }
90 
91  m = *l;
92 
93  series_set_elt_t out_series(a.structure().series());
94  out_series.assoc(m, s_ident);
95 
96  a.add_series_transition(s1, stop, out_series);
97  a.del_transition(*e);
98  }
99  }
100  }
101 
102 
103  template <class S, class T>
104  void realtime_words_here(Element<S, T>& res)
105  {
106  typedef Element<S, T> auto_t;
107  AUTOMATON_TYPES(auto_t);
108  typedef std::vector<hstate_t> state_vector_t;
109  typedef std::vector<htransition_t> transition_vector_t;
110  state_vector_t tmp;
111 
112  // perform cut-up.
113  cut_up_here(res);
114 
115  // Remove any labels from initial arrows.
116  tmp.reserve(res.initial().size());
117  for_all_const_initial_states(i, res)
118  tmp.push_back(*i);
119  for_all(typename state_vector_t, i, tmp)
120  {
121  series_set_elt_t l = res.get_initial(*i);
122  assert(l.supp().begin() != l.supp().end());
123  monoid_elt_t m(res.structure().series().monoid(), *l.supp().begin());
124  if (m.length() > 0)
125  {
126  hstate_t s = res.add_state();
127  res.add_series_transition(s, *i, l);
128  res.set_initial(s);
129  res.unset_initial(*i);
130  }
131  }
132  tmp.clear();
133 
134  // Remove any labels from final arrows.
135  tmp.reserve(res.final().size());
136  for_all_const_final_states(f, res)
137  tmp.push_back(*f);
138  for_all(typename state_vector_t, f, tmp)
139  {
140  series_set_elt_t l = res.get_final(*f);
141  assert(l.supp().begin() != l.supp().end());
142  monoid_elt_t m(res.structure().series().monoid(), *l.supp().begin());
143  if (m.length() > 0)
144  {
145  hstate_t s = res.add_state();
146  res.add_series_transition(*f, s, l);
147  res.set_final(s);
148  res.unset_final(*f);
149  }
150  }
151 
152  // Make the transitions realtime (now includes any former initial
153  // or final labels).
154  do_realtime_words(res);
155  }
156 
157 
158 
159  /*--------------.
160  | is_realtime. |
161  `--------------*/
162  template <class A, typename AI>
163  bool
164  do_is_realtime(const AutomataBase<A>&, const Element<A, AI>& a)
165  {
166  BENCH_TASK_SCOPED("is_realtime (automaton)");
167  typedef Element<A, AI> automaton_t;
168  AUTOMATON_TYPES(automaton_t);
169  for_all_const_initial_states(e, a)
170  {
171  series_set_elt_t l = a.get_initial(*e);
172  if (l.supp().size() > 1)
173  return false;
174  // We assume that an initial transition cannot be labeled by
175  // the empty series. In other words, l.supp().size() >= 1.
176  assertion(l.supp().size() == 1);
177  monoid_elt_t m(a.structure().series().monoid(), *l.supp().begin());
178  if (m.length() > 0)
179  return false;
180  }
181  for_all_const_final_states(e, a)
182  {
183  series_set_elt_t l = a.get_final(*e);
184  if (l.supp().size() > 1)
185  return false;
186  // We assume that a final transition cannot be labeled by
187  // the empty series. In other words, l.supp().size() >= 1.
188  assertion(l.supp().size() == 1);
189  monoid_elt_t m(a.structure().series().monoid(), *l.supp().begin());
190  if (m.length() > 0)
191  return false;
192  }
193  for_all_const_transitions(e, a)
194  if (!is_support_in_alphabet(a.series_of(*e)))
195  return false;
196  return true;
197  }
198 
199 
200  /*--------------.
201  | realtime_here. |
202  `--------------*/
203 
204  template<typename A, typename AI>
205  void
206  do_realtime_here(const AutomataBase<A>&,
207  Element<A, AI>& a,
208  misc::direction_type dir = misc::backward)
209  {
210  realtime_words_here(a);
211 
212  eps_removal_here(a, dir);
213 
214  // FIXME: This is not wanted. See #121.
215  if (dir == misc::forward)
217  else
218  accessible_here(a);
219  }
220 
221 
222  template<typename A, typename AI>
223  void
225  {
226  do_realtime_here(a.structure(), a, dir);
227  }
228 
229 
230  /*-----------.
231  | realtime. |
232  `-----------*/
233 
234  template<typename A, typename AI>
235  Element<A, AI>
236  do_realtime(const AutomataBase<A>& b,
237  const Element<A, AI>& a,
238  misc::direction_type dir = misc::backward)
239  {
240  Element<A, AI> ret(a);
241  do_realtime_here(b, ret, dir);
242  return ret;
243  }
244 
245  template<typename A, typename AI>
246  Element<A, AI>
248  {
249  return do_realtime(a.structure(), a, dir);
250  }
251 
252 
253 } // vcsn
254 
255 #endif // ! VCSN_ALGORITHMS_REALTIME_HXX