Vaucanson 1.4
|
00001 // complete.hxx: this file is part of the Vaucanson project. 00002 // 00003 // Vaucanson, a generic library for finite state machines. 00004 // 00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The Vaucanson Group. 00006 // 00007 // This program is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU General Public License 00009 // as published by the Free Software Foundation; either version 2 00010 // of the License, or (at your option) any later version. 00011 // 00012 // The complete GNU General Public Licence Notice can be found as the 00013 // `COPYING' file in the root directory. 00014 // 00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file. 00016 // 00017 #ifndef VCSN_ALGORITHMS_COMPLETE_HXX 00018 # define VCSN_ALGORITHMS_COMPLETE_HXX 00019 00020 # include <vaucanson/algorithms/complete.hh> 00021 00022 # ifndef VCSN_NDEBUG 00023 # include <vaucanson/algorithms/realtime.hh> 00024 # endif // ! VCSN_NDEBUG 00025 00026 # include <vaucanson/automata/concept/automata_base.hh> 00027 # include <vaucanson/misc/usual_macros.hh> 00028 00029 # include <list> 00030 # include <set> 00031 00032 namespace vcsn { 00033 00034 /*--------------. 00035 | complete_here | 00036 `--------------*/ 00037 00038 template <typename A, typename AI> 00039 void 00040 complete_here(Element<A, AI>& work) 00041 { 00042 // Note that this algorithm may be used on non-deterministic 00043 // automata. 00044 precondition(is_realtime(work)); 00045 BENCH_TASK_SCOPED("complete"); 00046 typedef Element<A, AI> automaton_t; 00047 AUTOMATON_TYPES(automaton_t); 00048 AUTOMATON_FREEMONOID_TYPES(automaton_t); 00049 00050 hstate_t sink_state = work.add_state(); 00051 bool sink_needed = false; 00052 00053 // If the sink states is the only state of the automaton, we want 00054 // to keep it as an initial state. This is meant! The empty 00055 // automaton is deterministic, but a complete deterministic 00056 // automata has at least one state (it is then easier to 00057 // complement it). 00058 if (work.states().size() == 1) 00059 { 00060 sink_needed = true; 00061 work.set_initial(sink_state); 00062 } 00063 00064 for_all_const_states(s, work) 00065 for_all_const_letters(l, work.structure().series().monoid().alphabet()) 00066 { 00067 bool empty = true; 00068 for (delta_iterator t(work.value(), *s); ! t.done(); t.next()) 00069 { 00070 monoid_elt_t w(work.series_of(*t).structure().monoid(), *l); 00071 if (work.series_of(*t).get(w) != work.series().semiring().wzero_) 00072 { 00073 empty = false; 00074 break; 00075 } 00076 } 00077 if (empty) 00078 { 00079 sink_needed = true; 00080 work.add_letter_transition(*s, sink_state, *l); 00081 } 00082 } 00083 00084 if (!sink_needed) 00085 work.del_state(sink_state); 00086 } 00087 00088 /*---------. 00089 | complete | 00090 `---------*/ 00091 00092 template <typename A, typename AI> 00093 Element<A, AI> 00094 complete(const Element<A, AI>& e) 00095 { 00096 Element<A, AI> res(e); 00097 complete_here(res); 00098 return res; 00099 } 00100 00101 /*------------. 00102 | is_complete | 00103 `------------*/ 00104 00105 template <typename A, typename AI> 00106 bool 00107 is_complete(const Element<A, AI>& e) 00108 { 00109 precondition(is_realtime(e)); 00110 BENCH_TASK_SCOPED("is_complete"); 00111 if (e.states().size() == 0) 00112 return false; 00113 typedef Element<A, AI> automaton_t; 00114 AUTOMATON_TYPES(automaton_t); 00115 AUTOMATON_FREEMONOID_TYPES(automaton_t); 00116 const alphabet_t& alpha = e.structure().series().monoid().alphabet(); 00117 for_all_const_states(i, e) 00118 { 00119 for_all_const_letters(j, alpha) 00120 { 00121 bool empty = true; 00122 for (delta_iterator t(e.value(), *i); 00123 ! t.done() && empty; 00124 t.next()) 00125 { 00126 monoid_elt_t w(e.series_of(*t).structure().monoid(), *j); 00127 if (e.series_of(*t).get(w) != e.series().semiring().wzero_) 00128 { 00129 empty = false; 00130 break; 00131 } 00132 } 00133 00134 if (empty) 00135 return false; 00136 } 00137 } 00138 return true; 00139 } 00140 00141 } // vcsn 00142 00143 #endif // ! VCSN_ALGORITHMS_COMPLETE_HXX