00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_UNIVERSAL_HXX
00018 # define VCSN_ALGORITHMS_UNIVERSAL_HXX
00019
00020
00021 # include <map>
00022 # include <set>
00023
00024 # include <vaucanson/boolean_automaton.hh>
00025 # include <vaucanson/algorithms/determinize.hh>
00026 # include <vaucanson/algorithms/transpose.hh>
00027 # include <vaucanson/algorithms/complete.hh>
00028
00029 # include <vaucanson/misc/usual_macros.hh>
00030
00031 namespace vcsn {
00032
00033 namespace universal_internal {
00034
00035
00036 template<typename Set>
00037 Set intersection_structure(const Set& set1, const Set& set2)
00038 {
00039 Set tmp;
00040 std::insert_iterator<Set> i(tmp, tmp.begin());
00041 std::set_intersection(set1.begin(), set1.end(),
00042 set2.begin(), set2.end(),
00043 i);
00044 return tmp;
00045 }
00046
00047
00048 template<typename Set>
00049 std::set<Set> intersection_closure(const std::set<Set>& s)
00050 {
00051 std::set<Set> tmp = s;
00052 std::set<Set> ret = s;
00053
00054 do {
00055 std::swap(ret, tmp);
00056 for_all_const_(std::set<Set>, s1, tmp)
00057 for_all_const_(std::set<Set>, s2, tmp)
00058 ret.insert(intersection_structure(*s1, *s2));
00059 } while (ret.size() != tmp.size());
00060 return ret;
00061 }
00062
00063
00064 template<typename K, typename V>
00065 std::set<V> image(const std::map<K,V>& m)
00066 {
00067 std::set<V> ret;
00068 for(typename std::map<K,V>::const_iterator a=m.begin(); a!= m.end(); ++a)
00069 ret.insert(a->second);
00070 return ret;
00071 }
00072
00073
00074 template <class Container1, class Container2>
00075 bool includes(const Container1& set1, const Container2& set2)
00076 {
00077 return std::includes(set2.begin(), set2.end(),
00078 set1.begin(), set1.end());
00079 }
00080 }
00081
00082
00083
00084 template<typename A, typename AI>
00085 void do_universal(const AutomataBase<A>&,
00086 const Element<A,AI>& a,
00087 Element<A,AI>& u)
00088 {
00089 typedef Element<A, AI> Auto;
00090 AUTOMATON_TYPES(Auto);
00091 AUTOMATON_FREEMONOID_TYPES(Auto);
00092
00093 typedef std::set<std::set<hstate_t> > pstate_t;
00094 typedef std::set<hstate_t> state_set_t;
00095 typedef std::map<hstate_t, state_set_t> map_t;
00096
00097 using namespace universal_internal;
00098
00099 Auto automaton(a);
00100
00101 if(!is_deterministic(automaton))
00102 automaton = determinize(automaton);
00103 if(!is_complete(automaton))
00104 automaton = complete(automaton);
00105
00106
00107
00108 hstate_t i = *automaton.initial().begin();
00109
00110
00111
00112 map_t origin;
00113 Auto transposed = transpose(automaton);
00114 Auto co_det = determinize(transposed, origin);
00115
00116
00117
00118
00119 pstate_t transp_states = image(origin);
00120
00121
00122 pstate_t univers_states(intersection_closure(transp_states));
00123
00124
00125 map_t subset_label;
00126
00127
00128 for_all_const_(pstate_t, s, univers_states)
00129 if (s->size() != 0)
00130 {
00131 hstate_t new_s = u.add_state();
00132 subset_label[new_s] = *s;
00133
00134 if (s->find(i) != s->end())
00135 u.set_initial(new_s);
00136
00137 if (includes(*s, automaton.final()))
00138 u.set_final(new_s);
00139 }
00140
00141
00142 for_all_states(x, u)
00143 for_all_states(y, u)
00144 for_all_letters(a, u.series().monoid().alphabet())
00145 {
00146 bool cont = false;
00147 std::set<hstate_t> delta_ret;
00148 for_all_const_(state_set_t, s, subset_label[*x])
00149 {
00150 bool empty = true;
00151
00152
00153 for (typename automaton_t::delta_iterator dst(automaton.value(), *s);
00154 ! dst.done(); dst.next())
00155 {
00156 monoid_elt_t w(automaton.series_of(*dst).structure().monoid(), *a);
00157 if (automaton.series_of(*dst).get(w)
00158 != automaton.series().semiring().wzero_)
00159 {
00160 empty = false;
00161 delta_ret.insert(automaton.dst_of(*dst));
00162 }
00163 }
00164 if (empty)
00165 {
00166 cont = true;
00167 break;
00168 }
00169 }
00170
00171 if (cont)
00172 continue;
00173
00174 if (includes(delta_ret, subset_label[*y]))
00175 u.add_letter_transition(*x, *y, *a);
00176 }
00177 }
00178
00179 template<typename A, typename AI>
00180 Element<A, AI>
00181 universal(const Element<A, AI>& a)
00182 {
00183 precondition(is_realtime(a));
00184
00185 Element<A, AI> ret(a.structure());
00186 do_universal(a.structure(), a, ret);
00187 return ret;
00188 }
00189
00190 }
00191 #endif // !VCSN_ALGORITHMS_UNIVERSAL_HXX