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,
00039 hstate_t h2,
00040 const EdgeLabel& l) :
00041 label(l),
00042 from(h1),
00043 to(h2)
00044 {}
00045
00046 inline
00047 state_value::state_value()
00048 {}
00049
00050
00051
00052
00053
00054
00055 # define TParam \
00056 template <class Kind, class WordValue, class WeightValue, \
00057 class SeriesValue, class Letter, class Tag, class Geometry>
00058
00059 # define GClass \
00060 Graph<Kind, WordValue, WeightValue, SeriesValue, Letter, Tag, Geometry>
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 TParam
00072 GClass::Graph()
00073 { }
00074
00075 TParam
00076 GClass::Graph
00077 (unsigned initial_number_of_state,
00078 unsigned reserve_number_of_edge)
00079 {
00080 states_.resize(initial_number_of_state);
00081 edges_.reserve(reserve_number_of_edge);
00082 }
00083
00084
00085
00086
00087
00088
00089 TParam
00090 typename GClass::states_t
00091 GClass::states() const
00092 {
00093 return states_t(hstate_t(0),
00094 hstate_t(states_.size()) - 1,
00095 removed_states_);
00096 }
00097
00098 TParam
00099 typename GClass::edges_t
00100 GClass::edges() const
00101 {
00102 return edges_t(hedge_t(0),
00103 hedge_t(edges_.size()) - 1,
00104 removed_edges_);
00105 }
00106
00107 TParam
00108 typename GClass::initial_support_t
00109 GClass::initial() const
00110 {
00111 return initial_support_t(initial_);
00112 }
00113
00114 TParam
00115 typename GClass::final_support_t
00116 GClass::final() const
00117 {
00118 return final_support_t(final_);
00119 }
00120
00121
00122
00123
00124
00125 TParam
00126 bool
00127 GClass::has_state(hstate_t n) const
00128 {
00129 bool res = ((removed_states_.find(n) == removed_states_.end())
00130 && n >= 0
00131 && n < int(states_.size()));
00132 # ifndef VCSN_NDEBUG
00133 if (res == false)
00134 for (int i = 0; i < int(edges_.size()); ++i)
00135 if (removed_edges_.find(hedge_t(i)) == removed_edges_.end())
00136 postcondition(edges_[i].from != n
00137 && edges_[i].to != n);
00138 # endif // !VCSN_NDEBUG
00139 return res;
00140 }
00141
00142 TParam
00143 hstate_t
00144 GClass::add_state()
00145 {
00146 if (removed_states_.size() == 0)
00147 {
00148 states_.push_back(state_value_t());
00149 return states_.size() - 1;
00150 }
00151
00152 hstate_t n = *removed_states_.begin();
00153 removed_states_.erase(n);
00154 assertion(n < int(states_.size()));
00155
00156 states_[n].output_edges.clear();
00157 states_[n].input_edges.clear();
00158
00159 postcondition(has_state(n));
00160 return n;
00161 }
00162
00163 TParam
00164 void
00165 GClass::del_state(hstate_t n)
00166 {
00167 precondition (has_state(n));
00168
00169 const state_value_t& v = states_[n];
00170 state_value::edges_t::const_iterator e = v.output_edges.begin();
00171 state_value::edges_t::const_iterator end = v.output_edges.end();
00172 state_value::edges_t::const_iterator next = e;
00173
00174 for (; e != end; e = next)
00175 {
00176 ++next;
00177 this->del_edge(*e);
00178 }
00179
00180 e = v.input_edges.begin();
00181 end = v.input_edges.end();
00182 for (next = e; e != end; e = next)
00183 {
00184 ++next;
00185 this->del_edge(*e);
00186 }
00187
00188 removed_states_.insert(n);
00189 initial_.erase(n);
00190 final_.erase(n);
00191 postcondition(!has_state(n));
00192 }
00193
00194 TParam
00195 void
00196 GClass::set_initial(hstate_t n, const series_set_elt_value_t& v,
00197 const series_set_elt_value_t& z)
00198 {
00199 if (z == v)
00200 initial_.erase(n);
00201 else
00202 initial_[n] = v;
00203 }
00204
00205 TParam
00206 const typename GClass::series_set_elt_value_t&
00207 GClass::get_initial(hstate_t n, const series_set_elt_value_t& z) const
00208 {
00209 typename initial_t::const_iterator i = initial_.find(n);
00210 if (i == initial_.end())
00211 return z;
00212 return i->second;
00213 }
00214
00215 TParam
00216 void
00217 GClass::clear_initial()
00218 {
00219 return initial_.clear();
00220 }
00221
00222 TParam
00223 void
00224 GClass::set_final(hstate_t n, const series_set_elt_value_t& v,
00225 const series_set_elt_value_t& z)
00226 {
00227 if (v == z)
00228 final_.erase(n);
00229 else
00230 final_[n] = v;
00231 }
00232
00233 TParam
00234 const typename GClass::series_set_elt_value_t&
00235 GClass::get_final(hstate_t n, const series_set_elt_value_t& z) const
00236 {
00237 typename final_t::const_iterator i = final_.find(n);
00238 if (i == final_.end())
00239 return z;
00240 return i->second;
00241 }
00242
00243 TParam
00244 void
00245 GClass::clear_final()
00246 {
00247 return final_.clear();
00248 }
00249
00250
00251
00252
00253
00254
00255 TParam
00256 bool
00257 GClass::has_edge(hedge_t e) const
00258 {
00259 bool res = (removed_edges_.find(e) == removed_edges_.end()
00260 && (e < int(edges_.size())));
00261 # ifndef VCSN_NDEBUG
00262 if (res == false)
00263 for (int i = 0; i < int(states_.size()); ++i)
00264 if (removed_states_.find(hstate_t(i)) == removed_states_.end())
00265 postcondition(states_[i].output_edges.find(e) ==
00266 states_[i].output_edges.end());
00267 # endif // !VCSN_NDEBUG
00268 return res;
00269 }
00270
00271 TParam
00272 hedge_t
00273 GClass::add_edge(hstate_t n1, hstate_t n2,
00274 const label_t& v)
00275 {
00276 precondition(has_state(n1));
00277 precondition(has_state(n2));
00278 hedge_t e;
00279 if (removed_edges_.size() == 0)
00280 {
00281 edges_.push_back(edge_value_t(n1, n2, v));
00282 e = edges_.size() - 1;
00283 }
00284 else
00285 {
00286 e = *removed_edges_.begin();
00287 removed_edges_.erase(e);
00288 assertion(e < int(edges_.size()));
00289 edges_[e].from = n1;
00290 edges_[e].to = n2;
00291 edges_[e].label = v;
00292 }
00293 states_[n1].output_edges.insert(e);
00294 states_[n2].input_edges.insert(e);
00295
00296 postcondition(has_edge(e));
00297 return e;
00298 }
00299
00300 TParam
00301 void
00302 GClass::del_edge(hedge_t e)
00303 {
00304 if (!has_edge(e))
00305 return;
00306
00307 const edge_value_t& ev = edges_[e];
00308 states_[ev.from].output_edges.erase(e);
00309 states_[ev.to].input_edges.erase(e);
00310 removed_edges_.insert(e);
00311
00312 postcondition(!has_edge(e));
00313 }
00314
00315
00316 TParam
00317 hstate_t
00318 GClass::src_of(hedge_t e1) const
00319 {
00320 precondition(has_edge(e1));
00321 return edges_[e1].from;
00322 }
00323
00324 TParam
00325 hstate_t
00326 GClass::dst_of(hedge_t e2) const
00327 {
00328 precondition(has_edge(e2));
00329 return edges_[e2].to;
00330 }
00331
00332 TParam
00333 const typename GClass::label_t&
00334 GClass::label_of(hedge_t n) const
00335 {
00336 precondition(has_edge(n));
00337 return edges_[n];
00338 }
00339
00340 TParam
00341 void
00342 GClass::update(hedge_t e, label_t l)
00343 {
00344 precondition(has_edge(e));
00345 edges_[e].label = l;
00346 }
00347
00348
00350 TParam
00351 template <class S>
00352 bool
00353 GClass::exists(const AutomataBase<S>& s) const
00354 {
00355 typename WordValue::iterator it;
00356 typename label_t::const_iterator r;
00357 label_t l;
00358 WordValue w;
00359
00360 for (int i = 0; i < int(edges_.size()); ++i)
00361 {
00362 if (removed_edges_.find(hedge_t(i)) != removed_edges_.end())
00363 continue;
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