00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_HXX
00018 # define VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_HXX
00019
00020 # include <utility>
00021 # include <vaucanson/algebra/implementation/series/series.hh>
00022 # include <vaucanson/algebra/implementation/series/rat/exp.hh>
00023 # include <vaucanson/algebra/implementation/series/rat/random_visitor.hh>
00024 # include <vaucanson/misc/usual_macros.hh>
00025
00026 # include <vaucanson/algebra/implementation/series/krat_exp_is_finite_app.hxx>
00027 # include <vaucanson/algebra/implementation/series/krat_exp_support.hxx>
00028 # include <vaucanson/algebra/implementation/series/krat_exp_transpose.hxx>
00029
00030 # include <vaucanson/algorithms/eval.hh>
00031 # include <vaucanson/algorithms/standard_of.hh>
00032
00033 # include <vaucanson/algebra/implementation/series/polynoms.hh>
00034 # include <vaucanson/automata/concept/automata.hh>
00035 # include <vaucanson/automata/implementation/graph.hh>
00036
00037 # include <vaucanson/misc/contract.hh>
00038
00039
00040 namespace vcsn {
00041
00058 namespace algebra {
00059
00060 template<typename W, typename M, typename Tm, typename Tw>
00061 bool op_contains(const algebra::Series<W, M>&, const rat::exp<Tm, Tw>&)
00062 {
00063 pure_service_call ("default version of op_contains(Series<W,M>, exp<Tm,Tw>)");
00064 return true;
00065 }
00066
00067 template<typename W, typename M, typename Tm, typename Tw>
00068 bool op_is_finite_app(const algebra::Series<W, M>&,
00069 const rat::exp<Tm, Tw>& m)
00070 {
00071 vcsn::IsFiniteAppMatcher<algebra::Series<W, M>,
00072 vcsn::rat::exp<Tm, Tw>,
00073 algebra::DispatchFunction<vcsn::rat::exp<Tm, Tw> > > matcher;
00074 return matcher.match(m);
00075 }
00076
00077 template<typename W, typename M, typename Tm, typename Tw>
00078 typename algebra::series_traits<rat::exp<Tm, Tw> >::support_t
00079 op_support(const algebra::Series<W, M>& s, const rat::exp<Tm, Tw>& m)
00080 {
00081 vcsn::SupportMatcher<algebra::Series<W, M>, rat::exp<Tm, Tw>,
00082 algebra::DispatchFunction<rat::exp<Tm, Tw> > > matcher(s);
00083 matcher.match(m);
00084 return matcher.get();
00085 }
00086
00087 template <typename W, typename M, typename Tm, typename Tw>
00088 Tm op_choose_from_supp(const algebra::Series<W, M>&,
00089 const rat::exp<Tm, Tw>& m)
00090 {
00091 rat::RandomVisitor<Tm, Tw> v;
00092 m.accept(v);
00093 return v.get();
00094 }
00095
00096 template<typename W, typename M, typename Tm, typename Tw>
00097 const rat::exp<Tm, Tw>& identity_value(SELECTOR2(algebra::Series<W, M>),
00098 SELECTOR2(rat::exp<Tm, Tw>))
00099 {
00100 static const rat::exp<Tm, Tw> instance = rat::exp<Tm, Tw>::one();
00101 return instance;
00102 }
00103
00104 template<typename W, typename M, typename Tm, typename Tw>
00105 const rat::exp<Tm, Tw>& zero_value(SELECTOR2(algebra::Series<W, M>),
00106 SELECTOR2(rat::exp<Tm, Tw>))
00107 {
00108 static const rat::exp<Tm, Tw> instance = rat::exp<Tm, Tw>::zero();
00109 return instance;
00110 }
00111
00112 template <typename W, typename M, typename Tm, typename Tw>
00113 void op_in_transpose(const algebra::Series<W, M>& s,
00114 rat::exp<Tm, Tw>& exp)
00115 {
00116 Element<algebra::Series<W, M>,
00117 rat::exp<Tm, Tw> > elt(s, exp);
00118
00119 vcsn::algebra::KRatExpTranspose<
00120 algebra::Series<W, M>,
00121 rat::exp<Tm, Tw>,
00122 algebra::DispatchFunction<vcsn::rat::exp<Tm, Tw> >
00123 > matcher(elt);
00124
00125 elt = matcher.match(exp);
00126 exp = elt.value();
00127 }
00128
00129
00130 template<typename W, typename M, typename Tm, typename Tw>
00131 void op_in_add(const algebra::Series<W, M>&,
00132 rat::exp<Tm, Tw>& dst,
00133 const rat::exp<Tm, Tw>& arg)
00134 {
00135
00136 if (arg.base()->what() == rat::Node<Tm, Tw>::zero)
00137 return ;
00138
00139
00140 if (dst.base()->what() == rat::Node<Tm, Tw>::zero)
00141 {
00142 delete dst.base();
00143 dst.base() = arg.base()->clone();
00144 return;
00145 }
00146
00147 dst.base() = new rat::Sum<Tm, Tw>(dst.base(), arg.base()->clone());
00148 }
00149
00150 template<typename W, typename M, typename Tm, typename Tw>
00151 rat::exp<Tm, Tw> op_add(const algebra::Series<W, M>& s,
00152 const rat::exp<Tm, Tw>& a,
00153 const rat::exp<Tm, Tw>& b)
00154 {
00155 rat::exp<Tm, Tw> ret(a);
00156 op_in_add(s, ret, b);
00157 return ret;
00158 }
00159
00160 template<typename W, typename M, typename Tm, typename Tw>
00161 void op_in_mul(const algebra::Series<W, M>& s,
00162 rat::exp<Tm, Tw>& dst,
00163 const rat::exp<Tm, Tw>& arg)
00164 {
00165 typedef rat::Node<Tm, Tw> node_t;
00166 typedef typename rat::Node<Tm, Tw>::type type;
00167 typedef rat::One<Tm, Tw> n_one_t;
00168 typedef rat::Constant<Tm, Tw> n_const_t;
00169 typedef rat::Zero<Tm, Tw> n_zero_t;
00170 typedef rat::Star<Tm, Tw> n_star_t;
00171 typedef rat::LeftWeighted<Tm, Tw> n_lweight_t;
00172 typedef rat::RightWeighted<Tm, Tw> n_rweight_t;
00173 typedef rat::Sum<Tm, Tw> n_sum_t;
00174 typedef rat::Product<Tm, Tw> n_prod_t;
00175
00176 type this_type = dst.base()->what();
00177 type arg_type = arg.base()->what();
00178
00179
00180 if (this_type == node_t::zero)
00181 return;
00182
00183
00184 if (arg_type == node_t::zero)
00185 {
00186 delete dst.base();
00187 dst.base() = new n_zero_t;
00188 return;
00189 }
00190
00191
00192 if (this_type == node_t::one)
00193 {
00194 delete dst.base();
00195 dst.base() = arg.base()->clone();
00196 return;
00197 }
00198
00199
00200 if (arg_type == node_t::one)
00201 {
00202 return;
00203 }
00204
00205
00206 if (arg_type == node_t::lweight)
00207 {
00208 n_lweight_t *p = dynamic_cast<n_lweight_t*>(arg.base());
00209 if (p->child_->what() == node_t::one)
00210 {
00211 op_in_mul(s, s.semiring(), dst, p->weight_);
00212 return;
00213 }
00214 }
00215
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 if (this_type == node_t::lweight)
00244 {
00245 n_lweight_t *p = dynamic_cast<n_lweight_t*>(dst.base());
00246 if (p->child_->what() == node_t::one)
00247 {
00248 dst = op_mul(s.semiring(), s, p->weight_, arg);
00249 return;
00250 }
00251 }
00252
00253
00254 dst.base() = new n_prod_t(dst.base(), arg.base()->clone());
00255 return;
00256 }
00257
00258 template<typename W, typename M, typename Tm, typename Tw>
00259 rat::exp<Tm, Tw> op_mul(const algebra::Series<W, M>& s,
00260 const rat::exp<Tm, Tw>& a,
00261 const rat::exp<Tm, Tw>& b)
00262 {
00263 rat::exp<Tm, Tw> ret(a);
00264 op_in_mul(s, ret, b);
00265 return ret;
00266 }
00267
00268
00269
00270
00271
00272
00273 template<typename Tm, typename Tw, typename M, typename W>
00274 rat::exp<Tm, Tw> op_convert(SELECTOR2(algebra::Series<M, W>),
00275 SELECTOR2(rat::exp<Tm, Tw>),
00276 const Tm& m_value)
00277 {
00278 return new rat::Constant<Tm, Tw>(m_value);
00279 }
00280
00281 template<typename Tm, typename Tw, typename M, typename W>
00282 rat::exp<Tm, Tw> op_convert(SELECTOR2(algebra::Series<M, W>),
00283 SELECTOR2(rat::exp<Tm, Tw>),
00284 char m_value)
00285 {
00286 const char str[] = {m_value, '\0'};
00287 return new rat::Constant<Tm, Tw>(str);
00288 }
00289
00290 template<typename Tm, typename Tw, typename W, typename M, typename oTm>
00291 rat::exp<Tm, Tw> op_convert(SELECTOR2(algebra::Series<W, M>) s,
00292 SELECTOR2(rat::exp<Tm, Tw>),
00293 SELECTOR(M),
00294 const oTm& m_value)
00295 {
00296
00297
00298 if (m_value == identity_value(SELECT(M), SELECT(oTm)))
00299 return rat::exp<Tm, Tw>::one();
00300 return rat::exp<Tm, Tw>::constant(op_convert(s.monoid(), SELECT(Tm),
00301 m_value));
00302 }
00303
00304 template<typename Tm, typename Tw, typename W, typename M, typename oTw>
00305 rat::exp<Tm, Tw> op_convert(SELECTOR2(algebra::Series<W, M>),
00306 SELECTOR2(rat::exp<Tm, Tw>),
00307 SELECTOR(W),
00308 const oTw& w_value)
00309 {
00310 if (w_value == identity_value(SELECT(W), SELECT(oTw)))
00311 return rat::exp<Tm, Tw>::one();
00312 if (w_value == zero_value(SELECT(W), SELECT(oTw)))
00313 return rat::exp<Tm, Tw>::zero();
00314 rat::exp<Tm, Tw> ret = rat::exp<Tm, Tw>::one();
00315 ret.base() = new rat::LeftWeighted<Tm, Tw>
00316 (op_convert(SELECT(W), SELECT(Tw),
00317 w_value), ret.base());
00318 return ret;
00319 }
00320
00321 template<typename W, typename M, typename Tm, typename Tw, typename oTm>
00322 void op_assign(const algebra::Series<W, M>&,
00323 const M&,
00324 rat::exp<Tm, Tw>& dst,
00325 const oTm& src)
00326 {
00327
00328
00329 if (src == identity_value(SELECT(M), SELECT(oTm)))
00330 dst = rat::exp<Tm, Tw>::one();
00331 else
00332 dst = rat::exp<Tm, Tw>::constant(src);
00333 }
00334
00335 template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00336 void op_assign(const algebra::Series<W, M>&,
00337 const W& semiring,
00338 rat::exp<Tm, Tw>& dst,
00339 const oTw& src)
00340 {
00341 dst = op_convert
00342 (SELECT2(algebra::Series<W, M>), SELECT2(rat::exp<Tm, Tw>), SELECT(W), src);
00343 }
00344
00345
00346
00347
00348
00349 template<typename W, typename M, typename Tm, typename Tw>
00350 bool op_starable(const algebra::Series<W, M>&,
00351 const rat::exp<Tm, Tw>&)
00352 {
00353 return true;
00354 }
00355
00356 template<typename W, typename M, typename Tm, typename Tw>
00357 void op_in_star(const algebra::Series<W, M>&,
00358 rat::exp<Tm, Tw>& dst)
00359 {
00360 if (dst.base()->what() == rat::Node<Tm, Tw>::zero)
00361 dst = rat::exp<Tm, Tw>::one();
00362 else
00363 dst.base() = new rat::Star<Tm, Tw>(dst.base());
00364 }
00365
00366 template<typename W, typename M, typename Tm, typename Tw>
00367 rat::exp<Tm, Tw>
00368 op_star(const algebra::Series<W, M>&,
00369 const rat::exp<Tm, Tw>& src)
00370 {
00371 if (src.base()->what() == rat::Node<Tm, Tw>::zero)
00372 return rat::exp<Tm, Tw>::one();
00373 rat::exp<Tm, Tw> ret(src);
00374 ret.base() = new rat::Star<Tm, Tw>(ret.base());
00375 return ret;
00376 }
00377
00378
00379
00380
00381
00382
00383 template<typename W, typename M, typename Tm, typename Tw, typename oTm>
00384 void op_in_add(const algebra::Series<W, M>& s,
00385 const M& monoid,
00386 rat::exp<Tm, Tw>& dst,
00387 const oTm& src)
00388 {
00389 op_in_add(s, dst, op_convert(SELECT2(algebra::Series<W, M>),
00390 SELECT2(rat::exp<Tm, Tw>),
00391 SELECT(M),
00392 src));
00393 }
00394
00395 template<typename W, typename M, typename Tm, typename Tw, typename oTm>
00396 rat::exp<Tm, Tw> op_add(const algebra::Series<W, M>& s,
00397 const M& monoid,
00398 const rat::exp<Tm, Tw>& a,
00399 const oTm& b)
00400 {
00401 rat::exp<Tm, Tw> ret(a);
00402 op_in_add(s, monoid, ret, b);
00403 return ret;
00404 }
00405
00406 template<typename M, typename W, typename oTm, typename Tm, typename Tw>
00407 rat::exp<Tm, Tw> op_add(const M& monoid,
00408 const algebra::Series<W, M>& s,
00409 const oTm& a,
00410 const rat::exp<Tm, Tw>& b)
00411 {
00412 rat::exp<Tm, Tw> ret(b);
00413 op_in_add(s, monoid, ret, a);
00414 return ret;
00415 }
00416
00417
00418
00419
00420
00421 template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00422 void op_in_add(const algebra::Series<W, M>& s,
00423 const W& semiring,
00424 rat::exp<Tm, Tw>& dst,
00425 const oTw& src)
00426 {
00427 precondition(& s.semiring() == & semiring);
00428 op_in_add(s, dst, op_convert(SELECT2(algebra::Series<W, M>),
00429 SELECT2(rat::exp<Tm, Tw>),
00430 SELECT(W),
00431 src));
00432 }
00433
00434 template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00435 rat::exp<Tm, Tw> op_add(const algebra::Series<W, M>& s,
00436 const W& semiring,
00437 const rat::exp<Tm, Tw>& a,
00438 const oTw& b)
00439 {
00440 rat::exp<Tm, Tw> ret(a);
00441 op_in_add(s, semiring, ret, b);
00442 return ret;
00443 }
00444
00445 template<typename W, typename M, typename oTw, typename Tm, typename Tw>
00446 rat::exp<Tm, Tw> op_add(const W& semiring,
00447 const algebra::Series<W, M>& s,
00448 const oTw& a,
00449 const rat::exp<Tm, Tw>& b)
00450 {
00451 rat::exp<Tm, Tw> ret(b);
00452 op_in_add(s, semiring, ret, a);
00453 return ret;
00454 }
00455
00456
00457
00458
00459
00460 template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00461 void op_in_mul(const algebra::Series<W, M>& s,
00462 const W& semiring,
00463 rat::exp<Tm, Tw>& ret,
00464 const oTw& w)
00465 {
00466 precondition(& s.semiring() == & semiring);
00467 (void) s; (void) semiring;
00468
00469 typedef rat::Node<Tm, Tw> node_t;
00470 typedef typename rat::Node<Tm, Tw>::type type;
00471 typedef rat::One<Tm, Tw> n_one_t;
00472 typedef rat::Constant<Tm, Tw> n_const_t;
00473 typedef rat::Zero<Tm, Tw> n_zero_t;
00474 typedef rat::Star<Tm, Tw> n_star_t;
00475 typedef rat::LeftWeighted<Tm, Tw> n_lweight_t;
00476 typedef rat::RightWeighted<Tm, Tw> n_rweight_t;
00477 typedef rat::Sum<Tm, Tw> n_sum_t;
00478 typedef rat::Product<Tm, Tw> n_prod_t;
00479
00480 type this_type = ret.base()->what();
00481
00482
00483 if (this_type == node_t::zero)
00484 return;
00485
00486
00487 if (w == identity_value(SELECT(W), SELECT(oTw)))
00488 return;
00489
00490
00491 if (w == zero_value(SELECT(W), SELECT(oTw)))
00492 {
00493 delete ret.base();
00494 ret.base() = new n_zero_t;
00495 return;
00496 }
00497
00498
00499 if (this_type == node_t::one)
00500 {
00501 ret.base() = new n_lweight_t
00502 (op_convert(SELECT(W), SELECT(Tw), w), ret.base());
00503 return;
00504 }
00505
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535 ret.base() =
00536 new n_rweight_t(op_convert(SELECT(W), SELECT(Tw), w), ret.base());
00537 return;
00538 }
00539
00540 template<typename W, typename M, typename Tm, typename Tw, typename oTw>
00541 rat::exp<Tm, Tw> op_mul(const algebra::Series<W, M>& s,
00542 const W& semiring,
00543 const rat::exp<Tm, Tw>& a,
00544 const oTw& w)
00545 {
00546 rat::exp<Tm, Tw> ret(a);
00547 op_in_mul(s, semiring, ret, w);
00548 return ret;
00549 }
00550
00551 template<typename W, typename M, typename oTw, typename Tm, typename Tw>
00552 rat::exp<Tm, Tw> op_mul(const W& semiring,
00553 const algebra::Series<W, M>& s,
00554 const oTw& w,
00555 const rat::exp<Tm, Tw>& b)
00556 {
00557 precondition(& s.semiring() == & semiring);
00558 (void) s; (void) semiring;
00559
00560 typedef rat::Node<Tm, Tw> node_t;
00561 typedef typename rat::Node<Tm, Tw>::type type;
00562 typedef rat::One<Tm, Tw> n_one_t;
00563 typedef rat::Constant<Tm, Tw> n_const_t;
00564 typedef rat::Zero<Tm, Tw> n_zero_t;
00565 typedef rat::Star<Tm, Tw> n_star_t;
00566 typedef rat::LeftWeighted<Tm, Tw> n_lweight_t;
00567 typedef rat::RightWeighted<Tm, Tw> n_rweight_t;
00568 typedef rat::Sum<Tm, Tw> n_sum_t;
00569 typedef rat::Product<Tm, Tw> n_prod_t;
00570
00571 rat::exp<Tm, Tw> ret(b);
00572
00573 type this_type = ret.base()->what();
00574
00575
00576 if (this_type == node_t::zero)
00577 return ret;
00578
00579
00580
00581
00582 if (w == zero_value(SELECT(W), SELECT(oTw)))
00583 { return rat::exp<Tm, Tw>::zero(); }
00584
00585
00586 if (w == identity_value(SELECT(W), SELECT(oTw)))
00587 return ret;
00588
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 ret.base() = new n_lweight_t(w, ret.base());
00612 return ret;
00613 }
00614
00615 template<typename W, typename M, typename Tm, typename Tw, typename oTm>
00616 Tw op_series_get(const algebra::Series<W, M>& s,
00617 const rat::exp<Tm, Tw>& p,
00618 const oTm& m)
00619 {
00620 typedef typename algebra::Series<W,M> series_set_t;
00621 typedef typename algebra::polynom<Tm, Tw> series_set_elt_value_t;
00622 typedef typename rat::exp<Tm, Tw> exp_t;
00623 typedef Graph
00624 <
00625 labels_are_series,
00626 Tm,
00627 Tw,
00628 series_set_elt_value_t,
00629 Tm,
00630 NoTag,
00631 NoTag
00632 >
00633 automaton_impl_t;
00634 typedef Element<Automata<series_set_t>, automaton_impl_t> automaton_t;
00635
00636 typename automaton_t::set_t automata (s);
00637 automaton_t a (automata);
00638 standard_of(a, p);
00639 return eval(a, m).value();
00640 }
00641
00642 template<typename W, typename M, typename Tm, typename Tw,
00643 typename oTm, typename oTw>
00644 void op_series_set(const algebra::Series<W, M>& s,
00645 rat::exp<Tm, Tw>& p,
00646 const oTm& m,
00647 const oTw& w)
00648 {
00649 if ((m == algebra::identity_as<oTm>::of(s.monoid())) &&
00650 (w == algebra::identity_as<oTw>::of(s.semiring())) &&
00651 (p == algebra::zero_as<rat::exp<Tm, Tw> >::of(s)))
00652 {
00653 p = algebra::identity_as<rat::exp<Tm, Tw> >::of(s).value();
00654 return ;
00655 }
00656
00657 rat::exp<Tm, Tw> ret =
00658 rat::exp<Tm, Tw>::constant(op_convert(s.monoid(),
00659 SELECT(Tm),
00660 m));
00661 op_in_add(s, p, op_mul(s.semiring(), s, w, ret));
00662 }
00663
00664
00665 }
00666
00667
00668
00669
00670
00671
00672 template <typename W, typename M, typename Tm, typename Tw>
00673 void
00674 MetaElement<algebra::Series<W, M>, rat::exp<Tm, Tw> >::accept
00675 (const rat::ConstNodeVisitor<Tm, Tw>& v) const
00676 {
00677 this->value().accept(v);
00678 }
00679
00680 template <typename W, typename M, typename Tm, typename Tw>
00681 size_t
00682 MetaElement<algebra::Series<W, M>, rat::exp<Tm, Tw> >::depth() const
00683 {
00684 return this->value().depth();
00685 }
00686
00687 namespace algebra {
00688
00689 template <class W, class M, class Tm, class Tw>
00690 Element<algebra::Series<W,M>, rat::exp<Tm,Tw> >
00691 op_choose(const algebra::Series<W,M>& s,
00692 SELECTOR2(rat::exp<Tm,Tw>))
00693 {
00694 Element<algebra::Series<W,M>, rat::exp<Tm, Tw> > e(s);
00695
00696 unsigned nb = RAND___(10);
00697 while (nb != 0)
00698 {
00699 --nb;
00700 unsigned t = RAND___(3);
00701 switch (t)
00702 {
00703
00704 case 0 :
00705 {
00706 e = e.star();
00707 continue;
00708 }
00709
00710 case 1 :
00711 {
00712 Element<algebra::Series<W,M>, rat::exp<Tm,Tw> >
00713 ep(s, s.monoid().choose(SELECT(Tm)));
00714 ep = ep * s.semiring().choose(SELECT(Tw));
00715 unsigned t = RAND___(2);
00716 if (t < 1)
00717 e = e + ep;
00718 else
00719 e = ep + e;
00720 continue;
00721 }
00722
00723 case 2 :
00724 {
00725 Element<algebra::Series<W,M>, rat::exp<Tm,Tw> >
00726 ep(s, s.monoid().choose(SELECT(Tm)));
00727 ep = ep * s.semiring().choose(SELECT(Tw));
00728 unsigned t = RAND___(2);
00729 if (t < 1)
00730 e = e * ep;
00731 else
00732 e = ep * e;
00733 continue;
00734 }
00735 }
00736 }
00737 return Element<algebra::Series<W,M>, rat::exp<Tm,Tw> >(s, e);
00738 }
00739
00740 }
00741
00742 }
00743
00744 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_SERIES_KRAT_HXX