Vaucanson  1.4.1
sub_normalize.hxx
Go to the documentation of this file.
1 // sub_normalize.hxx: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2005, 2006, 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_SUB_NORMALIZE_HXX
18 # define VCSN_ALGORITHMS_SUB_NORMALIZE_HXX
19 
29 namespace vcsn {
30 
31  /*------------------.
32  | is_sub_normalized |
33  `------------------*/
34 
35  template <class M1, class M2, class Auto>
36  bool do_is_sub_normalized(const algebra::FreeMonoidProduct<M1, M2>&,
37  const Auto& a)
38  {
39  BENCH_TASK_SCOPED("is_sub_normalized");
40  AUTOMATON_TYPES(Auto);
41  typedef typename series_set_elt_t::support_t support_t;
42 
43  for_all_const_initial_states(i, a)
44  {
45  series_set_elt_t label = a.get_initial(*i);
46  for (typename support_t::const_iterator it = label.supp().begin();
47  it != label.supp().end(); ++it)
48  if ((*it).first.size() > 1 || (*it).second.size() > 1)
49  return false;
50  }
51 
52  for_all_const_final_states(f, a)
53  {
54  series_set_elt_t label = a.get_final(*f);
55  for (typename support_t::const_iterator it = label.supp().begin();
56  it != label.supp().end(); ++it)
57  if ((*it).first.size() > 1 || (*it).second.size() > 1)
58  return false;
59  }
60 
61  for_all_const_transitions(e, a)
62  {
63  series_set_elt_t label = a.series_of(*e);
64  for (typename support_t::const_iterator it = label.supp().begin();
65  it != label.supp().end(); ++it)
66  if ((*it).first.size() > 1 || (*it).second.size() > 1)
67  return false;
68  }
69 
70  return true;
71  }
72 
73 
74  /*--------------.
75  | sub_normalize |
76  `--------------*/
77 
78  template <class Auto, class Label>
79  int do_sub_normalize_transition(Auto& a,
80  typename Auto::hstate_t start,
81  typename Auto::hstate_t stop,
82  const Label& label, bool initial, bool final)
83  {
84  BENCH_TASK_SCOPED("sub_normalize_transition");
85  AUTOMATON_TYPES(Auto);
86  hstate_t s0;
87  hstate_t s1;
88  typedef typename monoid_elt_t::first_monoid_elt_t first_monoid_elt_t;
89  typedef typename monoid_elt_t::second_monoid_elt_t
90  second_monoid_elt_t;
91  typedef typename monoid_elt_t::first_monoid_elt_value_t
92  first_monoid_elt_value_t;
93  typedef typename monoid_elt_t::second_monoid_elt_value_t
94  second_monoid_elt_value_t;
95 
96  first_monoid_elt_value_t m1_ident =
97  algebra::identity_as<first_monoid_elt_value_t>
98  ::of(a.structure().series().monoid().first_monoid()).value();
99  second_monoid_elt_value_t m2_ident =
100  algebra::identity_as<second_monoid_elt_value_t>
101  ::of(a.structure().series().monoid().second_monoid()).value();
102 
103  semiring_elt_t s_ident =
104  algebra::identity_as<semiring_elt_value_t>
105  ::of(a.structure().series().semiring());
106 
107 
108  monoid_elt_t m1(a.structure().series().monoid(),
109  *(label.supp().begin()));
110  first_monoid_elt_value_t w1 = m1.value().first;
111  second_monoid_elt_value_t w2 = m1.value().second;
112 
113  int size1 = w1.size();
114  int size2 = w2.size();
115  int cpt1 = 0;
116  int cpt2 = 0;
117 
118  unsigned int size = std::max(w1.size(), w2.size());
119 
120  if (size > 1)
121  {
122  monoid_elt_t m(a.structure().series().monoid());
123 
124  semiring_elt_t s = label.get(m1);
125  series_set_elt_t in_series(a.structure().series());
126 
127  m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
128  cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
129 
130  in_series.assoc(m, s);
131 
132  if (initial)
133  {
134  s0 = a.add_state();
135  a.set_initial(s0, in_series);
136  a.unset_initial(stop);
137  s1 = s0;
138  }
139  else
140  {
141  s0 = start;
142  s1 = a.add_state();
143  a.add_series_transition(s0, s1, in_series);
144  }
145 
146  for (unsigned int i = 1; i < size - 1; ++i)
147  {
148  m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
149  cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
150  s0 = s1;
151  s1 = a.add_state();
152  series_set_elt_t series(a.structure().series());
153  series.assoc(m, s_ident);
154  a.add_series_transition(s0, s1, series);
155  }
156 
157  m = std::make_pair(cpt1 < size1 ? w1.substr(cpt1++, 1) : m1_ident,
158  cpt2 < size2 ? w2.substr(cpt2++, 1) : m2_ident);
159 
160  series_set_elt_t out_series(a.structure().series());
161  out_series.assoc(m, s_ident);
162 
163  if (final)
164  {
165  a.unset_final(start);
166  a.set_final(s1, out_series);
167  }
168  else
169  a.add_series_transition(s1, stop, out_series);
170 
171  return 1;
172  }
173 
174  return 0;
175  }
176 
177 
178 
179  template <class M1, class M2, class Auto, class Ret>
180  void do_sub_normalize(const algebra::FreeMonoidProduct<M1, M2>&,
181  const Auto& a,
182  Ret& res)
183  {
184  BENCH_TASK_SCOPED("sub_normalize");
185  AUTOMATON_TYPES(Ret);
186  typedef std::vector<hstate_t> vector_t;
187 
188  auto_copy(res, cut_up(a));
189 
190  transitions_t transitions = res.transitions();
191  vector_t i_states; i_states.reserve(res.initial().size());
192  vector_t f_states; f_states.reserve(res.final().size());
193 
194  for_all_const_initial_states(f, res)
195  i_states.push_back(*f);
196  for_all_const_final_states(i, res)
197  f_states.push_back(*i);
198 
199  for_all_(vector_t, i, i_states)
200  do_sub_normalize_transition(res, hstate_t(), *i,
201  res.get_initial(*i), true, false);
202 
203  for_all_(vector_t, f, f_states)
204  do_sub_normalize_transition(res, *f, hstate_t(),
205  res.get_final(*f), false, true);
206 
207  for_all_(transitions_t, e, transitions)
208  if (do_sub_normalize_transition(res, res.src_of(*e), res.dst_of(*e),
209  res.series_of(*e), false, false))
210  res.del_transition(*e);
211  }
212 
213 
214  /*---------.
215  | Wrappers |
216  `---------*/
217 
218  template <class S, class T>
219  Element<S, T>
220  sub_normalize(const Element<S, T>& a)
221  {
222  Element<S, T> res(a.structure());
223  do_sub_normalize(a.structure().series().monoid(), a, res);
224 
225  return res;
226  }
227 
228 
229  template <class S, class T>
230  void
231  sub_normalize(const Element<S, T>& a, Element<S, T>& res)
232  {
233  do_sub_normalize(a.structure().series().monoid(), a, res);
234  }
235 
236  template <class S, class T>
237  void
239  {
240  do_sub_normalize (a.structure().series().monoid(), a, a);
241  }
242 
243  template <class S, class T>
245  {
246  return do_is_sub_normalized(a.structure().series().monoid(), a);
247  }
248 
249 } // ! vcsn
250 
251 #endif // ! VCSN_ALGORITHMS_SUB_NORMALIZE_HXX