00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_AUTOMATA_IMPLEMENTATION_GRAPH_HXX
00018 # define VCSN_AUTOMATA_IMPLEMENTATION_GRAPH_HXX
00019
00020 # include <fstream>
00021 # include <sstream>
00022
00023 # include <algorithm>
00024 # include <utility>
00025
00026 # include <vaucanson/automata/implementation/graph.hh>
00027 # include <vaucanson/misc/contract.hh>
00028 # include <vaucanson/misc/static.hh>
00029
00030 namespace vcsn
00031 {
00032
00033
00034
00035
00036
00037 template<typename EdgeLabel>
00038 edge_value<EdgeLabel>::edge_value(hstate_t h1, hstate_t h2,
00039 const EdgeLabel& l)
00040 : label(l),
00041 from(h1),
00042 to(h2)
00043 {}
00044
00045 inline
00046 state_value::state_value()
00047 {}
00048
00049
00050
00051
00052
00053
00054 # define TParam \
00055 template <class Kind, class WordValue, class WeightValue, \
00056 class SeriesValue, class Letter, class Tag, class Geometry>
00057
00058 # define GClass \
00059 Graph<Kind, WordValue, WeightValue, SeriesValue, Letter, Tag, Geometry>
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 TParam
00071 GClass::Graph()
00072 { }
00073
00074 TParam
00075 GClass::Graph (unsigned initial_number_of_state,
00076 unsigned reserve_number_of_edge)
00077 {
00078 states_.resize(initial_number_of_state);
00079 edges_.reserve(reserve_number_of_edge);
00080 }
00081
00082
00083
00084
00085
00086
00087 TParam
00088 typename GClass::states_t
00089 GClass::states() const
00090 {
00091 return states_t(hstate_t(0),
00092 hstate_t(states_.size()) - 1,
00093 removed_states_);
00094 }
00095
00096 TParam
00097 typename GClass::edges_t
00098 GClass::edges() const
00099 {
00100 return edges_t(hedge_t(0),
00101 hedge_t(edges_.size()) - 1,
00102 removed_edges_);
00103 }
00104
00105 TParam
00106 typename GClass::initial_support_t
00107 GClass::initial() const
00108 {
00109 return initial_support_t(initial_);
00110 }
00111
00112 TParam
00113 typename GClass::final_support_t
00114 GClass::final() const
00115 {
00116 return final_support_t(final_);
00117 }
00118
00119
00120
00121
00122
00123
00124 TParam
00125 bool
00126 GClass::has_state(hstate_t n) const
00127 {
00128 bool res = ((removed_states_.find(n) == removed_states_.end())
00129 && n >= 0
00130 && n < int(states_.size()));
00131 # ifndef VCSN_NDEBUG
00132 if (res == false)
00133 for (int i = 0; i < int(edges_.size()); ++i)
00134 if (removed_edges_.find(hedge_t(i)) == removed_edges_.end())
00135 postcondition(edges_[i].from != n
00136 && edges_[i].to != n);
00137 # endif // !VCSN_NDEBUG
00138 return res;
00139 }
00140
00141 TParam
00142 hstate_t
00143 GClass::add_state()
00144 {
00145 if (removed_states_.size() == 0)
00146 {
00147 states_.push_back(state_value_t());
00148 return states_.size() - 1;
00149 }
00150
00151 hstate_t n = *removed_states_.begin();
00152 removed_states_.erase(n);
00153 assertion(n < int(states_.size()));
00154
00155 states_[n].output_edges.clear();
00156 states_[n].input_edges.clear();
00157
00158 postcondition(has_state(n));
00159 return n;
00160 }
00161
00162 TParam
00163 void
00164 GClass::del_state(hstate_t n)
00165 {
00166 precondition (has_state(n));
00167
00168 const state_value_t& v = states_[n];
00169 state_value::edges_t::const_iterator e = v.output_edges.begin();
00170 state_value::edges_t::const_iterator end = v.output_edges.end();
00171 state_value::edges_t::const_iterator next = e;
00172
00173 for (; e != end; e = next)
00174 {
00175 ++next;
00176 this->del_edge(*e);
00177 }
00178
00179 e = v.input_edges.begin();
00180 end = v.input_edges.end();
00181 for (next = e; e != end; e = next)
00182 {
00183 ++next;
00184 this->del_edge(*e);
00185 }
00186
00187 removed_states_.insert(n);
00188 initial_.erase(n);
00189 final_.erase(n);
00190 postcondition(!has_state(n));
00191 }
00192
00193 TParam
00194 void
00195 GClass::set_initial(hstate_t n, const series_set_elt_value_t& v,
00196 const series_set_elt_value_t& z)
00197 {
00198 if (z == v)
00199 initial_.erase(n);
00200 else
00201 initial_[n] = v;
00202 }
00203
00204 TParam
00205 const typename GClass::series_set_elt_value_t&
00206 GClass::get_initial(hstate_t n, const series_set_elt_value_t& z) const
00207 {
00208 typename initial_t::const_iterator i = initial_.find(n);
00209 if (i == initial_.end())
00210 return z;
00211 return i->second;
00212 }
00213
00214 TParam
00215 void
00216 GClass::clear_initial()
00217 {
00218 return initial_.clear();
00219 }
00220
00221 TParam
00222 void
00223 GClass::set_final(hstate_t n, const series_set_elt_value_t& v,
00224 const series_set_elt_value_t& z)
00225 {
00226 if (v == z)
00227 final_.erase(n);
00228 else
00229 final_[n] = v;
00230 }
00231
00232 TParam
00233 const typename GClass::series_set_elt_value_t&
00234 GClass::get_final(hstate_t n, const series_set_elt_value_t& z) const
00235 {
00236 typename final_t::const_iterator i = final_.find(n);
00237 if (i == final_.end())
00238 return z;
00239 return i->second;
00240 }
00241
00242 TParam
00243 void
00244 GClass::clear_final()
00245 {
00246 return final_.clear();
00247 }
00248
00249
00250
00251
00252
00253
00254 TParam
00255 bool
00256 GClass::has_edge(hedge_t e) const
00257 {
00258 bool res = (removed_edges_.find(e) == removed_edges_.end()
00259 && (e < int(edges_.size())));
00260 # ifndef VCSN_NDEBUG
00261 if (res == false)
00262 for (int i = 0; i < int(states_.size()); ++i)
00263 if (removed_states_.find(hstate_t(i)) == removed_states_.end())
00264 postcondition(states_[i].output_edges.find(e) ==
00265 states_[i].output_edges.end());
00266 # endif // !VCSN_NDEBUG
00267 return res;
00268 }
00269
00270 TParam
00271 hedge_t
00272 GClass::add_edge(hstate_t n1, hstate_t n2,
00273 const label_t& v)
00274 {
00275 precondition(has_state(n1));
00276 precondition(has_state(n2));
00277 hedge_t e;
00278 if (removed_edges_.size() == 0)
00279 {
00280 edges_.push_back(edge_value_t(n1, n2, v));
00281 e = edges_.size() - 1;
00282 }
00283 else
00284 {
00285 e = *removed_edges_.begin();
00286 removed_edges_.erase(e);
00287 assertion(e < int(edges_.size()));
00288 edges_[e].from = n1;
00289 edges_[e].to = n2;
00290 edges_[e].label = v;
00291 }
00292 states_[n1].output_edges.insert(e);
00293 states_[n2].input_edges.insert(e);
00294
00295 postcondition(has_edge(e));
00296 return e;
00297 }
00298
00299 TParam
00300 void
00301 GClass::del_edge(hedge_t e)
00302 {
00303 if (!has_edge(e))
00304 return;
00305
00306 const edge_value_t& ev = edges_[e];
00307 states_[ev.from].output_edges.erase(e);
00308 states_[ev.to].input_edges.erase(e);
00309 removed_edges_.insert(e);
00310
00311 postcondition(!has_edge(e));
00312 }
00313
00314
00315 TParam
00316 hstate_t
00317 GClass::src_of(hedge_t e1) const
00318 {
00319 precondition(has_edge(e1));
00320 return edges_[e1].from;
00321 }
00322
00323 TParam
00324 hstate_t
00325 GClass::dst_of(hedge_t e2) const
00326 {
00327 precondition(has_edge(e2));
00328 return edges_[e2].to;
00329 }
00330
00331 TParam
00332 const typename GClass::label_t&
00333 GClass::label_of(hedge_t n) const
00334 {
00335 precondition(has_edge(n));
00336 return edges_[n];
00337 }
00338
00339 TParam
00340 void
00341 GClass::update(hedge_t e, label_t l)
00342 {
00343 precondition(has_edge(e));
00344 edges_[e].label = l;
00345 }
00346
00347
00349 TParam
00350 template <class S>
00351 bool
00352 GClass::exists(const AutomataBase<S>& s) const
00353 {
00354 typename WordValue::iterator it;
00355 typename label_t::const_iterator r;
00356 label_t l;
00357 WordValue w;
00358
00359 for (int i = 0; i < int(edges_.size()); ++i)
00360 {
00361 if (removed_edges_.find(hedge_t(i)) != removed_edges_.end())
00362 continue;
00363
00364
00365 if (!has_state(dst_of(hedge_t(i))) ||
00366 !has_state(src_of(hedge_t(i))))
00367 return false;
00368
00369
00370 l = label_of(hedge_t(i));
00371 for (r = l.begin(); r != l.end(); ++r)
00372 {
00373 w = r->first;
00374 for (it = w.begin(); it != w.end(); ++it)
00375 if (!s.series().monoid().alphabet().contains(*it))
00376 return false;
00377 }
00378 }
00379 return true;
00380 }
00381
00382
00383
00384
00385
00386
00387
00388 # define DEFINE_DELTA_FUNCTION(DeltaName, DKind, IO, WhatFromE) \
00389 TParam \
00390 template <class OutputIterator, class Query> \
00391 void \
00392 GClass::DeltaName(OutputIterator res, \
00393 hstate_t from, \
00394 const Query& query, \
00395 delta_kind::DKind) const \
00396 { \
00397 assertion(has_state(from)); \
00398 const std::set<hedge_t>& edges = states_[from].IO ## _edges; \
00399 for_all_const_(std::set<hedge_t>, e, edges) \
00400 if (query(*e)) \
00401 *res++ = WhatFromE; \
00402 } \
00403
00404 DEFINE_DELTA_FUNCTION (delta, edges, output, *e);
00405 DEFINE_DELTA_FUNCTION (delta, states, output, edges_[*e].to);
00406 DEFINE_DELTA_FUNCTION (rdelta, edges, input, *e);
00407 DEFINE_DELTA_FUNCTION (rdelta, states, input, edges_[*e].from);
00408
00409 # undef DEFINE_DELTA_FUNCTION
00410
00411
00412
00413
00414
00415 # define DEFINE_DELTAF_FUNCTION(DeltaName, DKind, IO, IsBool, Action) \
00416 TParam \
00417 template <typename Functor, class Query> \
00418 void \
00419 GClass::DeltaName(Functor& fun, \
00420 hstate_t from, \
00421 const Query& query, \
00422 delta_kind::DKind, \
00423 misc::IsBool ## _t) const \
00424 { \
00425 assertion(has_state(from)); \
00426 const std::set<hedge_t>& edges = states_[from].IO ## _edges; \
00427 for_all_const_(std::set<hedge_t>, e, edges) \
00428 if (query(*e)) \
00429 { Action; } \
00430 }
00431
00432 DEFINE_DELTAF_FUNCTION (deltaf, states, output, true,
00433 if (not fun(edges_[*e].to)) break);
00434 DEFINE_DELTAF_FUNCTION (deltaf, states, output, false, fun(edges_[*e].to));
00435 DEFINE_DELTAF_FUNCTION (deltaf, edges, output, true,
00436 if (not fun(*e)) break);
00437 DEFINE_DELTAF_FUNCTION (deltaf, edges, output, false, fun(*e));
00438
00439 DEFINE_DELTAF_FUNCTION (rdeltaf, states, input, true,
00440 if (not fun(edges_[*e].from)) break);
00441 DEFINE_DELTAF_FUNCTION (rdeltaf, states, input, false, fun(edges_[*e].from));
00442 DEFINE_DELTAF_FUNCTION (rdeltaf, edges, input, true,
00443 if (not fun(*e)) break);
00444 DEFINE_DELTAF_FUNCTION (rdeltaf, edges, input, false, fun(*e));
00445
00446 # undef DEFINE_DELTAF_FUNCTION
00447
00448
00449 namespace deltaf_helper {
00450 template <typename T, typename R, typename Arg>
00451 char is_returning_bool_helper (R (T::*) (Arg));
00452
00453 template <typename T, typename Arg>
00454 int is_returning_bool_helper (bool (T::*) (Arg));
00455
00456 # define is_returning_bool(T) \
00457 (sizeof (deltaf_helper::is_returning_bool_helper (T)) == sizeof (int))
00458 }
00459
00460 # define DEFINE_DELTAF_HELPER(DeltaName) \
00461 TParam \
00462 template <typename Functor, class Query, typename DKind> \
00463 void \
00464 GClass::DeltaName(Functor& fun, \
00465 hstate_t from, \
00466 const Query& query, \
00467 delta_kind::kind<DKind> k) const \
00468 { \
00469 DeltaName (fun, from, query, k, \
00470 BOOL_TO_TYPE (is_returning_bool (&Functor::operator ())) ()); \
00471 }
00472
00473 DEFINE_DELTAF_HELPER (deltaf);
00474 DEFINE_DELTAF_HELPER (rdeltaf);
00475
00476 # undef DEFINE_DELTAF_HELPER
00477 # undef is_returning_bool
00478
00479
00480
00481
00482
00483 TParam
00484 inline
00485 Tag& GClass::tag()
00486 {
00487 return tag_;
00488 }
00489
00490 TParam
00491 const Tag& GClass::tag() const
00492 {
00493 return tag_;
00494 }
00495
00496 template <class Kind, class WordValue, class WeightValue, class SerieValue,
00497 class Letter, class Tag, class Geometry, class I>
00498 Tag& op_tag(const AutomataBase<I>&,
00499 Graph<Kind, WordValue, WeightValue,
00500 SerieValue ,Letter, Tag, Geometry>& v)
00501 {
00502 return v.tag();
00503 }
00504
00505 template <class Kind, class WordValue, class WeightValue, class SerieValue,
00506 class Letter, class Tag, class Geometry, class I>
00507 const Tag& op_tag(const AutomataBase<I>&,
00508 const Graph<Kind, WordValue, WeightValue,
00509 SerieValue ,Letter, Tag, Geometry>& v)
00510 {
00511 return v.tag();
00512 }
00513
00514
00515
00516
00517
00518
00519 template <class Kind, class WordValue, class WeightValue, class SerieValue,
00520 class Letter, class Tag, class Geometry, class I>
00521 Geometry&
00522 op_geometry(const AutomataBase<I>&,
00523 Graph<Kind, WordValue, WeightValue,
00524 SerieValue, Letter, Tag, Geometry>& v)
00525 {
00526 return v.geometry();
00527 }
00528
00529 template <class Kind, class WordValue, class WeightValue, class SerieValue,
00530 class Letter, class Tag, class Geometry, class I>
00531 const Geometry&
00532 op_geometry(const AutomataBase<I>&,
00533 const Graph<Kind, WordValue, WeightValue,
00534 SerieValue, Letter, Tag, Geometry>& v)
00535 {
00536 return v.geometry();
00537 }
00538
00539
00540 TParam
00541 const Geometry&
00542 GClass::geometry() const
00543 {
00544 return geometry_;
00545 }
00546
00547 TParam
00548 Geometry&
00549 GClass::geometry()
00550 {
00551 return geometry_;
00552 }
00553
00554
00555
00556 # undef TParam
00557 # undef GClass
00558
00559 }
00560
00561 #endif // ! VCSN_AUTOMATA_IMPLEMENTATION_GRAPH_HXX