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
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 if (!has_state(n))
00168 return;
00169
00170 const state_value_t& v = states_[n];
00171 state_value::edges_t::const_iterator e = v.output_edges.begin();
00172 state_value::edges_t::const_iterator end = v.output_edges.end();
00173 state_value::edges_t::const_iterator next = e;
00174
00175 for (; e != end; e = next)
00176 {
00177 ++next;
00178 this->del_edge(*e);
00179 }
00180
00181 e = v.input_edges.begin();
00182 end = v.input_edges.end();
00183 for (next = e; e != end; e = next)
00184 {
00185 ++next;
00186 this->del_edge(*e);
00187 }
00188
00189 removed_states_.insert(n);
00190 initial_.erase(n);
00191 final_.erase(n);
00192 postcondition(!has_state(n));
00193 }
00194
00195 TParam
00196 void
00197 GClass::set_initial(hstate_t n, const series_set_elt_value_t& v,
00198 const series_set_elt_value_t& z)
00199 {
00200 if (z == v)
00201 initial_.erase(n);
00202 else
00203 initial_[n] = v;
00204 }
00205
00206 TParam
00207 const typename GClass::series_set_elt_value_t&
00208 GClass::get_initial(hstate_t n, const series_set_elt_value_t& z) const
00209 {
00210 typename initial_t::const_iterator i = initial_.find(n);
00211 if (i == initial_.end())
00212 return z;
00213 return i->second;
00214 }
00215
00216 TParam
00217 void
00218 GClass::clear_initial()
00219 {
00220 return initial_.clear();
00221 }
00222
00223 TParam
00224 void
00225 GClass::set_final(hstate_t n, const series_set_elt_value_t& v,
00226 const series_set_elt_value_t& z)
00227 {
00228 if (v == z)
00229 final_.erase(n);
00230 else
00231 final_[n] = v;
00232 }
00233
00234 TParam
00235 const typename GClass::series_set_elt_value_t&
00236 GClass::get_final(hstate_t n, const series_set_elt_value_t& z) const
00237 {
00238 typename final_t::const_iterator i = final_.find(n);
00239 if (i == final_.end())
00240 return z;
00241 return i->second;
00242 }
00243
00244 TParam
00245 void
00246 GClass::clear_final()
00247 {
00248 return final_.clear();
00249 }
00250
00251
00252
00253
00254
00255
00256 TParam
00257 bool
00258 GClass::has_edge(hedge_t e) const
00259 {
00260 bool res = (removed_edges_.find(e) == removed_edges_.end()
00261 && (e < int(edges_.size())));
00262 # ifndef VCSN_NDEBUG
00263 if (res == false)
00264 for (int i = 0; i < int(states_.size()); ++i)
00265 if (removed_states_.find(hstate_t(i)) == removed_states_.end())
00266 postcondition(states_[i].output_edges.find(e) ==
00267 states_[i].output_edges.end());
00268 # endif // !VCSN_NDEBUG
00269 return res;
00270 }
00271
00272 TParam
00273 hedge_t
00274 GClass::add_edge(hstate_t n1, hstate_t n2,
00275 const label_t& v)
00276 {
00277 precondition(has_state(n1));
00278 precondition(has_state(n2));
00279 hedge_t e;
00280 if (removed_edges_.size() == 0)
00281 {
00282 edges_.push_back(edge_value_t(n1, n2, v));
00283 e = edges_.size() - 1;
00284 }
00285 else
00286 {
00287 e = *removed_edges_.begin();
00288 removed_edges_.erase(e);
00289 assertion(e < int(edges_.size()));
00290 edges_[e].from = n1;
00291 edges_[e].to = n2;
00292 edges_[e].label = v;
00293 }
00294 states_[n1].output_edges.insert(e);
00295 states_[n2].input_edges.insert(e);
00296
00297 postcondition(has_edge(e));
00298 return e;
00299 }
00300
00301 TParam
00302 void
00303 GClass::del_edge(hedge_t e)
00304 {
00305 if (!has_edge(e))
00306 return;
00307
00308 const edge_value_t& ev = edges_[e];
00309 states_[ev.from].output_edges.erase(e);
00310 states_[ev.to].input_edges.erase(e);
00311 removed_edges_.insert(e);
00312
00313 postcondition(!has_edge(e));
00314 }
00315
00316
00317 TParam
00318 hstate_t
00319 GClass::src_of(hedge_t e1) const
00320 {
00321 precondition(has_edge(e1));
00322 return edges_[e1].from;
00323 }
00324
00325 TParam
00326 hstate_t
00327 GClass::dst_of(hedge_t e2) const
00328 {
00329 precondition(has_edge(e2));
00330 return edges_[e2].to;
00331 }
00332
00333 TParam
00334 const typename GClass::label_t&
00335 GClass::label_of(hedge_t n) const
00336 {
00337 precondition(has_edge(n));
00338 return edges_[n];
00339 }
00340
00341 TParam
00342 void
00343 GClass::update(hedge_t e, label_t l)
00344 {
00345 precondition(has_edge(e));
00346 edges_[e].label = l;
00347 }
00348
00349
00351 TParam
00352 template <class S>
00353 bool
00354 GClass::exists(const AutomataBase<S>& s) const
00355 {
00356 typename WordValue::iterator it;
00357 typename label_t::const_iterator r;
00358 label_t l;
00359 WordValue w;
00360
00361 for (int i = 0; i < int(edges_.size()); ++i)
00362 {
00363 if (removed_edges_.find(hedge_t(i)) != removed_edges_.end())
00364 continue;
00365
00366 if (!has_state(dst_of(hedge_t(i))) ||
00367 !has_state(src_of(hedge_t(i))))
00368 return false;
00369
00370
00371 l = label_of(hedge_t(i));
00372 for (r = l.begin(); r != l.end(); ++r)
00373 {
00374 w = r->first;
00375 for (it = w.begin(); it != w.end(); ++it)
00376 if (!s.series().monoid().alphabet().contains(*it))
00377 return false;
00378 }
00379 }
00380 return true;
00381 }
00382
00383
00384
00385
00386
00387 TParam
00388 template <class OutputIterator, class Query>
00389 void
00390 GClass::delta(OutputIterator res,
00391 hstate_t from,
00392 const Query& q,
00393 delta_kind::edges) const
00394 {
00395 assertion(has_state(from));
00396 const std::set<hedge_t>& edges = states_[from].output_edges;
00397 for_each_const_(std::set<hedge_t>, e, edges)
00398 if (q(*e))
00399 *res++ = *e;
00400 }
00401
00402 TParam
00403 template <class OutputIterator, class Query>
00404 void
00405 GClass::delta(OutputIterator res,
00406 hstate_t from,
00407 const Query& query,
00408 delta_kind::states) const
00409 {
00410 assertion(has_state(from));
00411 const std::set<hedge_t>& edges = states_[from].output_edges;
00412 for_each_const_(std::set<hedge_t>, e, edges)
00413 if (query(*e))
00414 *res++ = edges_[*e].to;
00415 }
00416
00417 TParam
00418 template <class OutputIterator, class Query>
00419 void
00420 GClass::rdelta(OutputIterator res,
00421 hstate_t from,
00422 const Query& q,
00423 delta_kind::edges) const
00424 {
00425 assertion(has_state(from));
00426 const std::set<hedge_t>& edges = states_[from].input_edges;
00427 for_each_const_(std::set<hedge_t>, e, edges)
00428 if (q(*e))
00429 *res++ = *e;
00430 }
00431
00432 TParam
00433 template <class OutputIterator, class Query>
00434 void
00435 GClass::rdelta(OutputIterator res,
00436 hstate_t from,
00437 const Query& q,
00438 delta_kind::states) const
00439 {
00440 assertion(has_state(from));
00441 const state_value_t::edges_t& edges =
00442 states_[from].input_edges;
00443 for_each_const_(std::set<hedge_t>, e, edges)
00444 if (q(*e))
00445 *res++ = edges_[*e].from;
00446 }
00447
00448 template <class S,
00449 class Kind,
00450 class WordValue,
00451 class WeightValue,
00452 class SeriesValue,
00453 class Letter,
00454 class Tag,
00455 class Geometry,
00456 typename OutputIterator,
00457 typename L>
00458 void op_rdelta(const AutomataBase<S>&,
00459 const GClass& v,
00460 OutputIterator res,
00461 hstate_t from,
00462 const L& query,
00463 delta_kind::states k)
00464 {
00465 v.rdelta(res, from, query, k);
00466 }
00467
00468 template <class S, class WordValue, class WeightValue, class SeriesValue,
00469 class Letter, class Tag, class Geometry,
00470 typename OutputIterator, typename L>
00471 void op_letter_delta(const AutomataBase<S>&,
00472 const Graph<labels_are_letters,
00473 WordValue, WeightValue,
00474 SeriesValue, Letter, Tag, Geometry>& v,
00475 OutputIterator res,
00476 hstate_t from,
00477 const L& letter,
00478 delta_kind::states)
00479 {
00480 typedef typename state_value::edges_t edges_t;
00481 const edges_t& edges = v.states_[from].output_edges;
00482 for_each_const_(edges_t, e, edges)
00483 if (v.edges_[*e].label == letter)
00484 *res++ = v.edges_[*e].to;
00485 }
00486
00487
00488
00489
00490
00491
00492 TParam
00493 inline
00494 Tag& GClass::tag()
00495 {
00496 return tag_;
00497 }
00498
00499 TParam
00500 const Tag& GClass::tag() const
00501 {
00502 return tag_;
00503 }
00504
00505 template <class Kind, class WordValue, class WeightValue, class SerieValue,
00506 class Letter, class Tag, class Geometry, class I>
00507 Tag& op_tag(const AutomataBase<I>&,
00508 Graph<Kind, WordValue, WeightValue,
00509 SerieValue ,Letter, Tag, Geometry>& v)
00510 {
00511 return v.tag();
00512 }
00513
00514 template <class Kind, class WordValue, class WeightValue, class SerieValue,
00515 class Letter, class Tag, class Geometry, class I>
00516 const Tag& op_tag(const AutomataBase<I>&,
00517 const Graph<Kind, WordValue, WeightValue,
00518 SerieValue ,Letter, Tag, Geometry>& v)
00519 {
00520 return v.tag();
00521 }
00522
00523
00524
00525
00526
00527
00528 template <class Kind, class WordValue, class WeightValue, class SerieValue,
00529 class Letter, class Tag, class Geometry, class I>
00530 Geometry&
00531 op_geometry(const AutomataBase<I>&,
00532 Graph<Kind, WordValue, WeightValue,
00533 SerieValue, Letter, Tag, Geometry>& v)
00534 {
00535 return v.geometry();
00536 }
00537
00538 template <class Kind, class WordValue, class WeightValue, class SerieValue,
00539 class Letter, class Tag, class Geometry, class I>
00540 const Geometry&
00541 op_geometry(const AutomataBase<I>&,
00542 const Graph<Kind, WordValue, WeightValue,
00543 SerieValue, Letter, Tag, Geometry>& v)
00544 {
00545 return v.geometry();
00546 }
00547
00548
00549 TParam
00550 const Geometry&
00551 GClass::geometry() const
00552 {
00553 return geometry_;
00554 }
00555
00556 TParam
00557 Geometry&
00558 GClass::geometry()
00559 {
00560 return geometry_;
00561 }
00562
00563
00564
00565 #undef TParam
00566 #undef GClass
00567
00568 }
00569
00570 #endif // ! VCSN_AUTOMATA_IMPLEMENTATION_GRAPH_HXX