Vaucanson  1.4.1
complete.hxx
1 // complete.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_COMPLETE_HXX
18 # define VCSN_ALGORITHMS_COMPLETE_HXX
19 
21 
22 # ifndef VCSN_NDEBUG
24 # endif // ! VCSN_NDEBUG
25 
26 # include <vaucanson/automata/concept/automata_base.hh>
27 # include <vaucanson/misc/usual_macros.hh>
28 
29 # include <list>
30 # include <set>
31 
32 namespace vcsn {
33 
34  /*--------------.
35  | complete_here |
36  `--------------*/
37 
38  template <typename A, typename AI>
39  void
41  {
42  // Note that this algorithm may be used on non-deterministic
43  // automata.
44  precondition(is_realtime(work));
45  BENCH_TASK_SCOPED("complete");
46  typedef Element<A, AI> automaton_t;
47  AUTOMATON_TYPES(automaton_t);
48  AUTOMATON_FREEMONOID_TYPES(automaton_t);
49 
50  hstate_t sink_state = work.add_state();
51  bool sink_needed = false;
52 
53  // If the sink states is the only state of the automaton, we want
54  // to keep it as an initial state. This is meant! The empty
55  // automaton is deterministic, but a complete deterministic
56  // automata has at least one state (it is then easier to
57  // complement it).
58  if (work.states().size() == 1)
59  {
60  sink_needed = true;
61  work.set_initial(sink_state);
62  }
63 
64  for_all_const_states(s, work)
65  for_all_const_letters(l, work.structure().series().monoid().alphabet())
66  {
67  bool empty = true;
68  for (delta_iterator t(work.value(), *s); ! t.done(); t.next())
69  {
70  monoid_elt_t w(work.series_of(*t).structure().monoid(), *l);
71  if (work.series_of(*t).get(w) != work.series().semiring().wzero_)
72  {
73  empty = false;
74  break;
75  }
76  }
77  if (empty)
78  {
79  sink_needed = true;
80  work.add_letter_transition(*s, sink_state, *l);
81  }
82  }
83 
84  if (!sink_needed)
85  work.del_state(sink_state);
86  }
87 
88  /*---------.
89  | complete |
90  `---------*/
91 
92  template <typename A, typename AI>
93  Element<A, AI>
95  {
96  Element<A, AI> res(e);
97  complete_here(res);
98  return res;
99  }
100 
101  /*------------.
102  | is_complete |
103  `------------*/
104 
105  template <typename A, typename AI>
106  bool
108  {
109  precondition(is_realtime(e));
110  BENCH_TASK_SCOPED("is_complete");
111  if (e.states().size() == 0)
112  return false;
113  typedef Element<A, AI> automaton_t;
114  AUTOMATON_TYPES(automaton_t);
115  AUTOMATON_FREEMONOID_TYPES(automaton_t);
116  const alphabet_t& alpha = e.structure().series().monoid().alphabet();
117  for_all_const_states(i, e)
118  {
119  for_all_const_letters(j, alpha)
120  {
121  bool empty = true;
122  for (delta_iterator t(e.value(), *i);
123  ! t.done() && empty;
124  t.next())
125  {
126  monoid_elt_t w(e.series_of(*t).structure().monoid(), *j);
127  if (e.series_of(*t).get(w) != e.series().semiring().wzero_)
128  {
129  empty = false;
130  break;
131  }
132  }
133 
134  if (empty)
135  return false;
136  }
137  }
138  return true;
139  }
140 
141 } // vcsn
142 
143 #endif // ! VCSN_ALGORITHMS_COMPLETE_HXX