Vaucanson  1.4.1
build_pattern.hxx
1 // build_pattern.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 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_INTERNAL_BUILD_PATTERN_HXX
18 # define VCSN_ALGORITHMS_INTERNAL_BUILD_PATTERN_HXX
19 
20 namespace vcsn
21 {
22  namespace algorithm_patterns
23  {
24 
25  // The ordered function called by maps
26  template <typename Self, typename Etiq>
27  bool
28  Comparator<Self, Etiq>::operator()(const Etiq& e1, const Etiq& e2) const
29  {
30  return Self::compare(e1, e2);
31  }
32 
33  /*-----------------------.
34  | IncAutomataConstructor |
35  `-----------------------*/
36 
37  // The constructor
38  template <typename Self, typename T_auto, typename Etiq>
39  IncAutomataConstructor<Self, T_auto, Etiq>::IncAutomataConstructor
40  (
41  const series_set_t& series, const Etiq& etiq
42  )
43  {
44  automata_set_t a_set(series);
45  auto_p = new T_auto(a_set);
46  unvisited = 0;
47  auto_p->set_initial(add_state(etiq));
48  current_state = states_map.end();
49  }
50 
51  // The constructor with list
52  template <typename Self, typename T_auto, typename Etiq>
53  IncAutomataConstructor<Self, T_auto, Etiq>::IncAutomataConstructor
54  (
55  const series_set_t& series, const std::list<Etiq>& listexp
56  )
57  {
58  automata_set_t a_set(series);
59  auto_p = new T_auto(a_set);
60  unvisited = 0;
61 
62  for (typename std::list<Etiq>::const_iterator it = listexp.begin();
63  it != listexp.end(); ++it)
64  auto_p->set_initial(add_state(*it));
65 
66  current_state = states_map.end();
67  }
68 
69 
70  // To get the result
71  template <typename Self, typename T_auto, typename Etiq>
72  T_auto*
74  {
75  return auto_p;
76  }
77 
78  // To run the algorithm
79  template <typename Self, typename T_auto, typename Etiq>
80  void
81  IncAutomataConstructor<Self, T_auto, Etiq>::run()
82  {
83  while (unvisited > 0)
84  {
85  for (current_state = states_map.begin();
86  current_state != states_map.end();
87  ++current_state)
88  {
89  if (!(current_state->second.second))
90  {
91  on_state_caller(current_state->first);
92  unvisited -= 1;
93  current_state->second.second = true;
94  }
95  }
96  }
97  }
98 
99  // Link current state to another, which can be created
100  template <typename Self, typename T_auto, typename Etiq>
101  void
102  IncAutomataConstructor<Self, T_auto, Etiq>::link_to
103  (
104  const Etiq& etiq, const letter_t& l
105  )
106  {
107  typename T_auto::hstate_t s;
108  iterator i = states_map.find(etiq);
109 
110  if (i == states_map.end())
111  s = add_state(etiq);
112  else
113  s = i->second.first;
114  auto_p->add_letter_transition(current_state->second.first, s, l);
115  }
116 
117  template <typename Self, typename T_auto, typename Etiq>
118  void
119  IncAutomataConstructor<Self, T_auto, Etiq>::link_to
120  (
121  const Etiq& etiq, const series_set_elt_t& el
122  )
123  {
124  typename T_auto::hstate_t s;
125  iterator i = states_map.find(etiq);
126 
127  if (i == states_map.end())
128  s = add_state(etiq);
129  else
130  s = i->second.first;
131  auto_p->add_series_transition(current_state->second.first, s, el);
132  }
133 
134  // A tool to add a state in the set and the automaton
135  template <typename Self, typename T_auto, typename Etiq>
136  typename T_auto::hstate_t
137  IncAutomataConstructor<Self, T_auto, Etiq>::add_state(const Etiq& etiq)
138  {
139  typename T_auto::hstate_t res = auto_p->add_state();
140  states_map[etiq] = std::pair<typename T_auto::hstate_t, bool>(res, false);
141  unvisited += 1;
142  return res;
143  }
144 
145  // To make the current state final
146  template <typename Self, typename T_auto, typename Etiq>
147  void
148  IncAutomataConstructor<Self, T_auto, Etiq>::set_final()
149  {
150  auto_p->set_final(current_state->second.first);
151  }
152 
153  // To make the current state final
154  template <typename Self, typename T_auto, typename Etiq>
155  void
156  IncAutomataConstructor<Self, T_auto, Etiq>::set_final
157  (const series_set_elt_t& el)
158  {
159  auto_p->set_final(current_state->second.first, el);
160  }
161 
162 
163  // The function called on each state :
164  // it just call the on_each_state function, which must be defined
165  // by user.
166  template <typename Self, typename T_auto, typename Etiq>
167  void
168  IncAutomataConstructor<Self, T_auto, Etiq>::on_state_caller(const Etiq& e)
169  {
170  static_cast<Self&>(*this).on_state(e);
171  }
172 
173  // The default function which will compare 2 Etiq
174  template <typename Self, typename T_auto, typename Etiq>
175  bool
176  IncAutomataConstructor<Self, T_auto, Etiq>::compare
177  (
178  const Etiq& e1, const Etiq& e2
179  )
180  {
181  return e1 < e2;
182  }
183 
184  /*------------------------.
185  | MathAutomataConstructor |
186  `------------------------*/
187 
188  // The constructor.
189  // It takes a container, which must contain the labels of states
190  template <typename Self, typename T_auto, typename Etiq>
191  template <typename Container>
192  MathAutomataConstructor<Self, T_auto, Etiq>::MathAutomataConstructor
193  (
194  const series_set_t& series, const Container container
195  )
196  {
197  typedef typename Container::iterator c_iterator;
198 
199  automata_set_t a_set(series);
200  auto_p = new T_auto(a_set);
201 
202  for (c_iterator i = container.begin(); i != container.end(); ++i)
203  states_map[*i] = auto_p->add_state();
204  }
205 
206  // The function used to get the result
207  template <typename Self, typename T_auto, typename Etiq>
208  T_auto*
210  {
211  return auto_p;
212  }
213 
214  // The building function.
215  // It calls the templated function link_to() in order to
216  // allow user not to declare the return type of delta()
217  // (That's why delta_caller() does not exist)
218  template <typename Self, typename T_auto, typename Etiq>
219  void
220  MathAutomataConstructor<Self, T_auto, Etiq>::run()
221  {
222  alphabet_t alpha = get()->series().monoid().alphabet();
223  for (iterator i = states_map.begin(); i != states_map.end(); ++i)
224  {
225  if (is_initial_caller(i->first))
226  auto_p->set_initial(i->second);
227  if (is_final_caller(i->first))
228  auto_p->set_final(i->second);
229  for (alphabet_iterator a = alpha.begin(); a != alpha.end(); ++a)
230  link_to(i->second, *a, static_cast<Self&>(*this).delta(i->first, *a));
231  }
232  }
233 
234  // The two following funtions just call the appropriate function
235  // of daughter class
236  template <typename Self, typename T_auto, typename Etiq>
237  bool
238  MathAutomataConstructor<Self, T_auto, Etiq>::is_initial_caller
239  (
240  const Etiq& e
241  ) const
242  {
243  return static_cast<const Self&>(*this).is_initial(e);
244  }
245 
246  template <typename Self, typename T_auto, typename Etiq>
247  bool
248  MathAutomataConstructor<Self, T_auto, Etiq>::is_final_caller
249  (
250  const Etiq& e
251  ) const
252  {
253  return static_cast<const Self&>(*this).is_final(e);
254  }
255 
256  // Function which build transitions between a state
257  // and a set of states
258  template <typename Self, typename T_auto, typename Etiq>
259  template <typename Container>
260  void
261  MathAutomataConstructor<Self, T_auto, Etiq>::link_to
262  (
263  const typename T_auto::hstate_t& state, const letter_t& letter, const Container container
264  )
265  {
266  typedef typename Container::iterator c_iterator;
267  for (c_iterator j = container.begin(); j != container.end(); ++j)
268  {
269  iterator tmp = states_map.find(*j);
270  if (tmp != states_map.end())
271  auto_p->add_letter_transition(state, tmp->second, letter);
272  }
273  }
274 
275  // The default function which will compare 2 Etiq
276  template <typename Self, typename T_auto, typename Etiq>
277  bool
278  MathAutomataConstructor<Self, T_auto, Etiq>::compare
279  (
280  const Etiq& e1, const Etiq& e2
281  )
282  {
283  return e1 < e2;
284  }
285 
286  }
287 }
288 
289 #endif // ! VCSN_ALGORITHMS_INTERNAL_BUILD_PATTERN_HXX