00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGORITHMS_IS_SYNCHRONISABLE_HXX
00018 # define VCSN_ALGORITHMS_IS_SYNCHRONISABLE_HXX
00019
00020 # include <vaucanson/algorithms/is_synchronisable.hh>
00021
00022 # include <vaucanson/automata/concept/automata_base.hh>
00023 # include <vaucanson/algebra/concept/freemonoid_product.hh>
00024 # include <vaucanson/misc/usual_macros.hh>
00025
00026 # include <vaucanson/tools/dot_display.hh>
00027 # include <vaucanson/tools/dot_dump.hh>
00028
00029 # include <map>
00030 # include <set>
00031 # include <list>
00032 # include <utility>
00033 # include <queue>
00034 # include <iostream>
00035 # include <stdlib.h>
00036
00037 namespace vcsn
00038 {
00039
00040 template <typename Trans>
00041 int
00042 length_discrepancy (const htransition_t& l, const Trans& trans)
00043 {
00044 AUTOMATON_TYPES(Trans);
00045
00046 monoid_elt_t label = trans.word_of (l);
00047 int res = label.value ().first.length () - label.value ().second.length ();
00048 return res;
00049 }
00050
00051
00052 template <typename Trans>
00053 class IsBoundedLag
00054 {
00055 AUTOMATON_TYPES(Trans);
00056 typedef enum { WHITE, GRAY, BLACK } color_t;
00057 typedef std::map<hstate_t, color_t> visited_t;
00058 typedef std::map<hstate_t, std::pair<hstate_t, htransition_t> > father_t;
00059
00060 private:
00061 const automaton_t& trans_;
00062
00067 visited_t visited_;
00068
00070 father_t father_of_;
00071
00072 public:
00073
00074 IsBoundedLag(const automaton_t& t)
00075 : trans_(t)
00076 {
00077 for_all_states(s, trans_)
00078 visited_[*s] = WHITE;
00079 }
00080
00081 bool operator() ()
00082 {
00083 bool is_synch = true;
00084
00085 for_all_states(s, trans_)
00086 if (visited_[*s] == WHITE &&
00087 !(is_synch = dispatch_bounded_lag (*s)))
00088 break;
00089 return is_synch;
00090 }
00091
00092 bool
00093 dispatch_bounded_lag (const hstate_t s)
00094 {
00095 std::list<htransition_t> delta_ret;
00096
00097 visited_[s] = GRAY;
00098 trans_.deltac (delta_ret, s, delta_kind::transitions());
00099 for_all_const(std::list<htransition_t>, e, delta_ret)
00100 {
00101 hstate_t r = trans_.dst_of (*e);
00102 if (visited_[r] == WHITE)
00103 {
00104 father_of_[r] = std::make_pair (s, *e);
00105 if (!dispatch_bounded_lag (r))
00106 return false;
00107 }
00108 else if (visited_[r] == GRAY)
00109 {
00110
00111
00112 int res = length_discrepancy (*e, trans_);
00113 if (s != r)
00114 {
00115 hstate_t p = father_of_[s].first;
00116 hstate_t f = s;
00117 htransition_t l = father_of_[s].second;
00118 while (p != r)
00119 {
00120 res += length_discrepancy (l, trans_);
00121 f = p;
00122 p = father_of_[p].first;
00123 l = father_of_[p].second;
00124 }
00125 res += length_discrepancy (l, trans_);
00126 }
00127 std::cerr << "bounded_lag: circuit detected" << std::endl;
00128 if (res != 0)
00129 return false;
00130 }
00131 }
00132 visited_[s] = BLACK;
00133 return true;
00134 }
00135 };
00136
00137 template <typename T_, typename M1, typename M2, typename Trans>
00138 bool
00139 do_is_bounded_lag(const AutomataBase<T_>&,
00140 const algebra::FreeMonoidProduct<M1, M2>&,
00141 const Trans& t)
00142 {
00143 IsBoundedLag<Trans> is_bounded(t);
00144
00145 return is_bounded();
00146 }
00147
00148 template <typename S, typename T>
00149 bool
00150 is_bounded_lag (const Element<S, T>& t)
00151 {
00152 return do_is_bounded_lag (t.structure(), t.structure().series().monoid(), t);
00153 }
00154
00155 typedef std::pair<hstate_t, int> valued_state_t;
00156 typedef std::map<valued_state_t, hstate_t> conv_t;
00157
00158
00159
00160
00161
00162 template <typename Trans>
00163 class Ranker
00164 {
00165 public:
00166 AUTOMATON_TYPES(Trans);
00167 typedef std::map<hstate_t, int> rank_t;
00168
00169 void
00170 operator() (const automaton_t& t, rank_t& rank, automaton_t& B)
00171 {
00172 std::stack<valued_state_t> to_treat;
00173 conv_t conv;
00174
00175
00176
00177
00178 for_all_initial_states(s, t)
00179 {
00180 hstate_t p;
00181 valued_state_t vp;
00182 p = B.add_state ();
00183 B.set_initial (p);
00184 if (t.is_final (*s))
00185 B.set_final (p, t.get_final (*s));
00186 vp = std::make_pair (*s, 0);
00187 rank[p] = 0;
00188 to_treat.push (vp);
00189 conv[vp] = p;
00190 }
00191
00192 valued_state_t s;
00193 std::list<htransition_t> delta_ret;
00194 while (!to_treat.empty ())
00195 {
00196 s = to_treat.top ();
00197 to_treat.pop ();
00198 delta_ret.clear ();
00199
00200
00201
00202 t.deltac (delta_ret, s.first, delta_kind::transitions());
00203 for (std::list<htransition_t>::iterator e = delta_ret.begin ();
00204 e != delta_ret.end (); ++e)
00205 {
00206 hstate_t r = t.dst_of (*e);
00207 int lag = s.second + length_discrepancy (*e, t);
00208 valued_state_t vr = std::make_pair (r, lag);
00209 conv_t::iterator b;
00210 b = conv.find (vr);
00211
00212
00213 if (b == conv.end ())
00214 {
00215 hstate_t p = B.add_state ();
00216 if (t.is_final (vr.first))
00217 B.set_final (p, t.get_final (vr.first));
00218 conv[vr] = p;
00219 rank[p] = lag;
00220 B.add_transition(conv[s], p, t.label_of (*e));
00221 to_treat.push (vr);
00222 }
00223 else
00224 B.add_transition (conv[s], b->second, t.label_of (*e));
00225 }
00226 }
00227 }
00228 };
00229
00230 namespace synchronise_internal
00231 {
00232
00233 template <typename Trans>
00234 void split_transition (Trans& t,
00235 hstate_t src,
00236 hstate_t dst,
00237 const typename Trans::monoid_elt_t::first_monoid_elt_t::value_t& left,
00238 const typename Trans::monoid_elt_t::second_monoid_elt_t::value_t& right)
00239 {
00240 AUTOMATON_TYPES(Trans);
00241
00242 monoid_elt_t mon (t.structure().series().monoid());
00243 semiring_elt_t weight (t.structure().series().semiring());
00244 weight = true;
00245
00246 monoid_elt_value_t v1(left, right);
00247 mon = v1;
00248
00249 series_set_elt_t s1 (t.structure().series());
00250 s1.assoc(mon, weight);
00251 t.add_series_transition (src, dst, s1);
00252 }
00253 }
00254
00255
00256 template <typename Trans>
00257 void
00258 split_transitions (Trans& t, typename Ranker<Trans>::rank_t& rank)
00259 {
00260 AUTOMATON_TYPES(Trans);
00261
00262 AUTOMATON_FREEMONOIDPRODUCT_TYPES(Trans);
00263
00264 first_monoid_elt_t fm_empty =
00265 algebra::identity_as<first_monoid_elt_value_t>::of
00266 (t.structure().series().monoid().first_monoid());
00267
00268 second_monoid_elt_t sm_empty =
00269 algebra::identity_as<second_monoid_elt_value_t>::of
00270 (t.structure().series().monoid().second_monoid());
00271 for_all_transitions(e, t)
00272 {
00273 hstate_t src = t.src_of (*e);
00274 hstate_t dst = t.dst_of (*e);
00275
00276 if ((rank[src] > 0 && rank[dst] < 0) ||
00277 (rank[src] < 0 && rank[dst] > 0))
00278 {
00279 hstate_t zero_state = t.add_state ();
00280 rank[zero_state] = 0;
00281 monoid_elt_t m(t.structure().series().monoid());
00282 m = t.word_of (*e);
00283 int delta = abs (rank[src] - rank[dst]);
00284
00285 if (rank[src] > 0 && rank[dst] < 0)
00286 {
00287 synchronise_internal::split_transition
00288 (t,
00289 src,
00290 zero_state,
00291 m.value().first,
00292 second_monoid_elt_value_t(m.value().second.c_str(), delta));
00293
00294 synchronise_internal::split_transition
00295 (t,
00296 zero_state,
00297 dst,
00298 fm_empty.value(),
00299 second_monoid_elt_value_t(m.value().second, delta,
00300 m.value().second.length() - delta));
00301 }
00302 else
00303 {
00304 synchronise_internal::split_transition
00305 (t,
00306 src,
00307 zero_state,
00308 first_monoid_elt_value_t(m.value().first.c_str(), delta),
00309 m.value().second);
00310
00311 synchronise_internal::split_transition
00312 (t,
00313 zero_state,
00314 dst,
00315 first_monoid_elt_value_t(m.value().first, delta,
00316 m.value().first.length() - delta),
00317 sm_empty.value());
00318 }
00319 t.del_transition (*e);
00320 }
00321 }
00322 }
00323
00324
00325 template <typename Trans>
00326 class Synchroniser
00327 {
00328 public:
00329 AUTOMATON_TYPES(Trans);
00330 AUTOMATON_FREEMONOIDPRODUCT_TYPES(automaton_t);
00331
00332 typedef typename Ranker<Trans>::rank_t rank_t;
00333 typedef std::map<std::string, hstate_t> prefix_map_t;
00334
00335 Synchroniser(automaton_t& t, rank_t& rank)
00336 : t_(t), rank_(rank)
00337 {}
00338
00339 void operator() ()
00340 {
00341 AUTOMATON_TYPES(Trans);
00342
00343 hstate_t s;
00344 std::set<hstate_t> done;
00345
00346 while (choose_state(s))
00347 {
00348 std::cerr << s << std::endl;
00349
00350 make_circulation (s);
00351
00352 rank_.erase (s);
00353 t_.del_state (s);
00354 }
00355 }
00356
00357 private:
00358
00359 void
00360 remove_pref_from_transition (const htransition_t& e,
00361 const std::string& pref,
00362 prefix_map_t& p2s)
00363 {
00364 monoid_elt_t mon(t_.structure().series().monoid());
00365 semiring_elt_t weight (t_.structure().series().semiring());
00366
00367 std::string output;
00368 if (rank_[t_.src_of (e)] > 0)
00369 {
00370 output = t_.word_of (e).value().second;
00371 monoid_elt_value_t v1(t_.word_of (e).value ().first,
00372 std::string(output, pref.length (), output.length () - pref.length ()));
00373 mon = v1;
00374 }
00375 else
00376 {
00377 output = t_.word_of (e).value().first;
00378 monoid_elt_value_t v1(std::string(output, pref.length (), output.length () - pref.length ()),
00379 t_.word_of (e).value ().second);
00380 mon = v1;
00381 }
00382
00383 weight = true;
00384 series_set_elt_t s (t_.structure().series());
00385 s.assoc(mon, weight);
00386 t_.add_series_transition(p2s[pref], t_.dst_of (e), s);
00387 }
00388
00389 void
00390 append_pref_to_transition (const htransition_t& e,
00391 const std::string& pref,
00392 hstate_t src,
00393 hstate_t dst,
00394 std::string rpref = std::string(""))
00395 {
00396 monoid_elt_t mon(t_.structure().series().monoid());
00397 semiring_elt_t weight (t_.structure().series().semiring());
00398
00399 monoid_elt_value_t v1;
00400
00401 if (rank_[t_.dst_of (e)] > 0)
00402 v1.first = t_.word_of (e).value().first;
00403 else
00404 v1.second = t_.word_of (e).value().second;
00405
00406 if (t_.src_of (e) != t_.dst_of (e))
00407 {
00408 if (rank_[t_.dst_of (e)] > 0)
00409 v1.second = t_.word_of (e).value().second + pref;
00410 else
00411 v1.first = t_.word_of (e).value().first + pref;
00412 }
00413 else
00414 {
00415
00416 if (rank_[t_.dst_of (e)] > 0)
00417 {
00418 std::string output = t_.word_of (e).value().second;
00419 v1.second = std::string (output, rpref.length(), output.length() - rpref.length()) + pref;
00420 }
00421 else
00422 {
00423 std::string output = t_.word_of (e).value().first;
00424 v1.first = std::string (output, rpref.length(), output.length() - rpref.length()) + pref;
00425 }
00426 }
00427 mon = v1;
00428 weight = true;
00429 series_set_elt_t s (t_.structure().series());
00430 s.assoc(mon, weight);
00431 t_.add_series_transition(src, dst, s);
00432 }
00433
00434
00435 void
00436 remove_pref_from_final(hstate_t s,
00437 prefix_map_t& p2s,
00438 std::set<hstate_t>& done)
00439 {
00440 typename series_set_elt_t::support_t::iterator i =
00441 t_.get_final(s).supp().begin();
00442 monoid_elt_t m(t_.structure().series().monoid());
00443 m = *i;
00444
00445 std::string pref;
00446 if (rank_[s] > 0)
00447 pref = std::string(m.value().second.c_str(), rank_[s]);
00448 else
00449 pref = std::string(m.value().first.c_str(), rank_[s]);
00450
00451 p2s[pref] = t_.add_state ();
00452 rank_[p2s[pref]] = rank_[s];
00453
00454 monoid_elt_t mon(t_.structure().series().monoid());
00455 semiring_elt_t weight (t_.structure().series().semiring());
00456
00457 if (rank_[s] > 0)
00458 {
00459 second_monoid_elt_value_t output = m.value().second;
00460 monoid_elt_value_t v1
00461 (m.value().first,
00462 std::string(output, pref.length (), output.length () - pref.length ()));
00463 mon = v1;
00464 }
00465 else
00466 {
00467 first_monoid_elt_value_t output = m.value().first;
00468 monoid_elt_value_t v1(
00469 first_monoid_elt_value_t(output, pref.length (),
00470 output.length () - pref.length ()),
00471 m.value().second);
00472 mon = v1;
00473 }
00474
00475 weight = true;
00476 series_set_elt_t s1(t_.structure().series());
00477 s1.assoc(mon, weight);
00478 t_.set_final(p2s[pref], s1);
00479 done.insert(p2s[pref]);
00480 }
00481
00482 void
00483 make_circulation (hstate_t s)
00484 {
00485
00486 prefix_map_t p2s;
00487
00488 std::set<hstate_t> done;
00489 std::list<htransition_t> delta_ret;
00490
00491
00492 if (t_.is_final(s))
00493 remove_pref_from_final(s, p2s, done);
00494 delta_ret.clear();
00495
00496
00497 t_.deltac (delta_ret, s, delta_kind::transitions());
00498 for_all_const(std::list<htransition_t>, e, delta_ret)
00499 {
00500 std::string proj;
00501 if (rank_[s] > 0)
00502 proj = t_.word_of(*e).value().second;
00503 else
00504 proj = t_.word_of(*e).value().first;
00505 std::string pref(proj.c_str(), abs(rank_[s]));
00506 if (p2s.find (pref) == p2s.end ())
00507 {
00508 p2s[pref] = t_.add_state ();
00509 rank_[p2s[pref]] = rank_[s];
00510 }
00511 if (t_.dst_of (*e) != t_.src_of (*e))
00512 remove_pref_from_transition(*e, pref, p2s);
00513 }
00514 delta_ret.clear ();
00515
00516
00517
00518
00519 t_.rdeltac (delta_ret, s, delta_kind::transitions());
00520 for_all_const(std::list<htransition_t>, e, delta_ret)
00521 {
00522 hstate_t src = t_.src_of (*e);
00523 if (src != s)
00524 {
00525 for (prefix_map_t::iterator s1 = p2s.begin ();
00526 s1 != p2s.end (); ++s1)
00527 append_pref_to_transition(*e, s1->first, src, s1->second);
00528 }
00529 else
00530 {
00531
00532 std::string pref(t_.word_of (*e).value().second.c_str(), rank_[s]);
00533 for (prefix_map_t::iterator s1 = p2s.begin ();
00534 s1 != p2s.end (); ++s1)
00535 append_pref_to_transition(*e, s1->first, p2s[pref], s1->second, pref);
00536 }
00537 }
00538
00539
00540 }
00541
00542 bool
00543 choose_state (hstate_t& selected)
00544 {
00545 typedef std::vector<htransition_t> delta_ret_t;
00546
00547 delta_ret_t delta_ret;
00548 bool find = true;
00549
00550 for_all_states(s, t_)
00551 {
00552 if (rank_[*s] == 0)
00553 continue;
00554
00555
00556
00557 bool all_equal = true;
00558 delta_ret.clear ();
00559 t_.deltac (delta_ret, *s, delta_kind::transitions());
00560 for (delta_ret_t::iterator e = delta_ret.begin();
00561 e != delta_ret.end() && all_equal; ++e)
00562 {
00563 monoid_elt_t m(t_.structure().series().monoid());
00564 m = t_.word_of (*e);
00565 if (m.value().first.length() != m.value().second.length())
00566 all_equal = false;
00567 }
00568
00569
00570
00571 if (all_equal)
00572 continue;
00573
00574
00575 if (t_.is_final (*s))
00576 {
00577 typename series_set_elt_t::support_t::iterator i = t_.get_final(*s).supp().begin();
00578 monoid_elt_t m(t_.structure().series().monoid());
00579 m = *i;
00580 if (rank_[*s] > 0)
00581 {
00582 if ((int)m.value().second.length() < rank_[*s])
00583 continue;
00584 }
00585 else
00586 {
00587 if ((int)m.value().first.length() < -rank_[*s])
00588 continue;
00589 }
00590 }
00591
00592 t_.deltac (delta_ret, *s, delta_kind::transitions());
00593
00594
00595 if (rank_[*s] > 0)
00596 {
00597 for_all_(delta_ret_t, e, delta_ret)
00598 {
00599 monoid_elt_t m(t_.structure().series().monoid());
00600 m = t_.word_of (*e);
00601 if ((int)m.value().second.length() < rank_[*s])
00602 {
00603 find = false;
00604 break;
00605 }
00606 }
00607 }
00608 else
00609 {
00610 for_all_(delta_ret_t, e, delta_ret)
00611 {
00612 monoid_elt_t m(t_.structure().series().monoid());
00613 m = t_.word_of (*e);
00614 if ((int)m.value().first.length() < -rank_[*s])
00615 {
00616 find = false;
00617 break;
00618 }
00619 }
00620 }
00621
00622 if (!find)
00623 {
00624 find = true;
00625 continue;
00626 }
00627 selected = *s;
00628 return true;
00629 }
00630 return false;
00631 }
00632
00633 automaton_t& t_;
00634 rank_t rank_;
00635 };
00636
00637 template <typename S, typename T, typename M1, typename M2>
00638 void
00639 do_synchronise (SELECTOR(AutomataBase<S>),
00640 SELECTOR2(algebra::FreeMonoidProduct<M1, M2>),
00641 const Element<S, T>& t,
00642 Element<S, T>& B)
00643 {
00644 typedef Element<S, T> trans_t;
00645 AUTOMATON_TYPES(trans_t);
00646
00647 typename Ranker<trans_t>::rank_t rank;
00648 Ranker<trans_t> compute_rank;
00649
00650 compute_rank (t, rank, B);
00651
00652
00653 split_transitions (B, rank);
00654
00655
00656
00657
00658
00659
00660 Synchroniser<trans_t> sync(B, rank);
00661 sync();
00662 }
00663
00664 template <typename S, typename T>
00665 Element<S, T>
00666 synchronise (const Element<S, T>& t)
00667 {
00668 typedef Element<S, T> trans_t;
00669
00670 typedef typename trans_t::set_t trans_set_t;
00671 typedef typename trans_set_t::series_set_t series_set_t;
00672
00673 trans_set_t aset(series_set_t(t.structure().series().semiring(),
00674 t.structure().series().monoid()));
00675 trans_t res(aset);
00676
00677 do_synchronise(t.structure(), t.structure().series().monoid(),
00678 t, res);
00679 return res;
00680 }
00681
00682 }
00683
00684 #endif // ! VCSN_ALGORITHMS_IS_SYNCHRONISABLE_HXX