- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# freemonoid_product.hxx

    00001 // freemonoid_product.hxx: this file is part of the Vaucanson project.
    00002 //
    00003 // Vaucanson, a generic library for finite state machines.
    00004 //
    00005 // Copyright (C) 2004, 2005, 2008 The Vaucanson Group.
    00006 //
    00007 // This program is free software; you can redistribute it and/or
    00008 // modify it under the terms of the GNU General Public License
    00009 // as published by the Free Software Foundation; either version 2
    00010 // of the License, or (at your option) any later version.
    00011 //
    00012 // The complete GNU General Public Licence Notice can be found as the
    00013 // `COPYING' file in the root directory.
    00014 //
    00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
    00016 //
    00017 #ifndef VCSN_ALGEBRA_CONCEPT_FREEMONOID_PRODUCT_HXX
    00018 # define VCSN_ALGEBRA_CONCEPT_FREEMONOID_PRODUCT_HXX
    00019
    00020 # include <vaucanson/algebra/concept/freemonoid_product.hh>
    00021
    00022 namespace vcsn
    00023 {
    00024   namespace algebra
    00025   {
    00026     template <typename F, typename S>
    00027     MonoidRep<FreeMonoidProduct<F, S> >::MonoidRep() :
    00028         open_par("("),
    00029         sep(","),
    00030         close_par(")")
    00031     {}
    00032
    00033     template <typename Semiring, typename F, typename S>
    00034     void
    00035     SeriesRep<Semiring, FreeMonoidProduct<F, S> >::
    00036     disambiguate(const monoid_t& monoid, pointer_t& p)
    00037     {
    00038       // Pointer types.
    00039       typedef boost::shared_ptr<first_rep_t>            first_p_t;
    00040       typedef boost::shared_ptr<second_rep_t>           second_p_t;
    00041
    00042       first_p_t first_rep(new first_rep_t(p->first_representation()));
    00043       second_p_t second_rep(new second_rep_t(p->second_representation()));
    00044
    00045       // Backup old pointers.
    00046       first_p_t first_rep_orig = first_rep;
    00047       second_p_t second_rep_orig = second_rep;
    00048
    00049       // Real work done here.
    00050       first_rep->disambiguate(monoid.first_monoid(), first_rep);
    00051       second_rep->disambiguate(monoid.second_monoid(), second_rep);
    00052
    00053       // Copy on write.
    00054       if (first_rep_orig != first_rep || second_rep_orig != second_rep)
    00055       {
    00056         self_t new_rep(*p);
    00057         new_rep.first_representation() = *first_rep;
    00058         new_rep.second_representation() = *second_rep;
    00059         p = pointer_t(new self_t(new_rep));
    00060       }
    00061     }
    00062
    00063     template <typename Semiring, typename F, typename S>
    00064     SeriesRep<Semiring, F>&
    00065     SeriesRep<Semiring, FreeMonoidProduct<F, S> >::first_representation()
    00066     {
    00067       return first_representation_;
    00068     }
    00069
    00070     template <typename Semiring, typename F, typename S>
    00071     const SeriesRep<Semiring, F>&
    00072     SeriesRep<Semiring, FreeMonoidProduct<F, S> >::first_representation() const
    00073     {
    00074       return first_representation_;
    00075     }
    00076
    00077     template <typename Semiring, typename F, typename S>
    00078     SeriesRep<Semiring, S>&
    00079     SeriesRep<Semiring, FreeMonoidProduct<F, S> >::second_representation()
    00080     {
    00081       return second_representation_;
    00082     }
    00083
    00084     template <typename Semiring, typename F, typename S>
    00085     const SeriesRep<Semiring, S>&
    00086     SeriesRep<Semiring, FreeMonoidProduct<F, S> >::second_representation() const
    00087     {
    00088       return second_representation_;
    00089     }
    00090
    00091     template <typename F, typename S>
    00092     bool
    00093     operator==(boost::shared_ptr<MonoidRep<FreeMonoidProduct<F, S> > > lhs,
    00094                boost::shared_ptr<MonoidRep<FreeMonoidProduct<F, S> > > rhs)
    00095     {
    00096       // Type helpers.
    00097       typedef MonoidRepBase<MonoidRep, FreeMonoidProduct<F, S> >
    00098         monoid_rep_base_t;
    00099       typedef boost::shared_ptr<monoid_rep_base_t>      p_t;
    00100
    00101       return (lhs->open_par == rhs->open_par &&
    00102               lhs->sep == rhs->sep &&
    00103               lhs->close_par == rhs->close_par &&
    00104               static_cast<p_t>(lhs) == static_cast<p_t>(rhs));
    00105     }
    00106
    00107     template <typename Semiring, typename F, typename S>
    00108     bool
    00109     operator==(boost::shared_ptr<SeriesRep<Semiring, FreeMonoidProduct<F, S> > > lhs,
    00110                boost::shared_ptr<SeriesRep<Semiring, FreeMonoidProduct<F, S> > > rhs)
    00111     {
    00112       // Type helpers.
    00113       typedef SeriesRep<Semiring, F> first_rep_t;
    00114       typedef SeriesRep<Semiring, S> second_rep_t;
    00115       typedef SeriesRepBase<SeriesRep, Semiring, FreeMonoidProduct<F, S> >
    00116         series_rep_base_t;
    00117
    00118       // Pointer types.
    00119       typedef boost::shared_ptr<first_rep_t>            first_p_t;
    00120       typedef boost::shared_ptr<second_rep_t>           second_p_t;
    00121       typedef boost::shared_ptr<series_rep_base_t>      p_t;
    00122
    00123       // FIXME: we should provide operator== for the pointed to types.
    00124       first_p_t lhs_first(new first_rep_t());
    00125       second_p_t lhs_second(new second_rep_t());
    00126       first_p_t rhs_first(new first_rep_t());
    00127       second_p_t rhs_second(new second_rep_t());
    00128
    00129       *lhs_first = lhs->first_representation();
    00130       *lhs_second = lhs->second_representation();
    00131       *rhs_first = rhs->first_representation();
    00132       *rhs_second = rhs->second_representation();
    00133
    00134       return (lhs_first == rhs_first &&
    00135               lhs_second == rhs_second &&
    00136               static_cast<p_t>(lhs) == static_cast<p_t>(rhs));
    00137     }
    00138
    00139     /*------------------------.
    00140     | FreeMonoidProduct<F, S> |
    00141     `------------------------*/
    00142
    00143     // FIXME: This facility is a HACK. Explanations: when a high level
    00144     // structural element (a structure inheriting from Structure) is
    00145     // instantiated (say a series_set_t), the underlying monoid is only
    00146     // accessible via const methods.  Unfortunately it means that when a
    00147     // FreeMonoidProduct is instantiated (not as a non-const object) the
    00148     // shared_ptr holding the pointers to the first and second monoid
    00149     // representations can't be changed. And, because we originally planned to
    00150     // use singleton (see get_instance()) and other clever tricks, an FMP<F, S>
    00151     // with F == S will use the SAME representation for both the monoid.
    00152     // (simply put, changing the epsilon representation for the first monoid
    00153     // will pass on to the second one). A lot of work needs to be done to solve
    00154     // this problem elegantly but AFAIK it all revolves around improving the
    00155     // MonoidRepBase to be more like an alphabet (with dynamic data stored in
    00156     // some chosen implementation). As for now the implemented solution has the
    00157     // least impact on Vaucanson. It could have been done more compact but the
    00158     // choice was made to choose the code that most visibly explains why it is
    00159     // done.  We ensure _when creating the FMP_ that if the two representations
    00160     // match, we create a new one for the second monoid (the calculated
    00161     // representation build by the disambiguate function is used to initialize
    00162     // it). WARNING: it obviously defeat the purpose of the shared_ptr.
    00163     template <typename F, typename S>
    00164     void
    00165     split_monoid_(F&, S&)
    00166     {}
    00167
    00168     template <typename F>
    00169     void
    00170     split_monoid_(F& first_monoid, F& second_monoid)
    00171     {
    00172       if (first_monoid.representation().get() == second_monoid.representation().get())
    00173       {
    00174         typename F::monoid_rep_t second = *(second_monoid.representation());
    00175         second_monoid.set_representation(second);
    00176       }
    00177     }
    00178
    00179     template <class F, class S>
    00180     FreeMonoidProduct<F, S>::FreeMonoidProduct(const F& a, const S& b) :
    00181         first_monoid_(a), second_monoid_(b),
    00182         rep_(MonoidRepDefault<FreeMonoidProduct<F, S> >::get_instance())
    00183     {
    00184       split_monoid_(first_monoid_, second_monoid_);
    00185     }
    00186
    00187     template <class F, class S>
    00188     FreeMonoidProduct<F, S>::FreeMonoidProduct(const F& a, const S& b,
    00189                                                MonoidRep<FreeMonoidProduct<F, S> > mr) :
    00190         first_monoid_(a), second_monoid_(b),
    00191         rep_(boost::shared_ptr<MonoidRep<FreeMonoidProduct<F, S> > >(new MonoidRep<FreeMonoidProduct<F, S> >(mr)))
    00192     {
    00193       split_monoid_(first_monoid_, second_monoid_);
    00194     }
    00195
    00196     template <class F, class S>
    00197     FreeMonoidProduct<F, S>::FreeMonoidProduct(const FreeMonoidProduct& w) :
    00198       FreeMonoidProductBase<FreeMonoidProduct<F, S> >(w),
    00199       first_monoid_(w.first_monoid_),
    00200       second_monoid_(w.second_monoid_),
    00201       rep_(w.rep_)
    00202     {
    00203       split_monoid_(first_monoid_, second_monoid_);
    00204     }
    00205
    00206     template <class F, class S>
    00207     typename FreeMonoidProduct<F, S>::first_monoid_t&
    00208     FreeMonoidProduct<F, S>::first_monoid()
    00209     {
    00210       return first_monoid_;
    00211     }
    00212
    00213     template <class F, class S>
    00214     const typename FreeMonoidProduct<F, S>::first_monoid_t&
    00215     FreeMonoidProduct<F, S>::first_monoid() const
    00216     {
    00217       return first_monoid_;
    00218     }
    00219
    00220     template <class F, class S>
    00221     typename FreeMonoidProduct<F, S>::second_monoid_t&
    00222     FreeMonoidProduct<F, S>::second_monoid()
    00223     {
    00224       return second_monoid_;
    00225     }
    00226
    00227     template <class F, class S>
    00228     const typename FreeMonoidProduct<F, S>::second_monoid_t&
    00229     FreeMonoidProduct<F, S>::second_monoid() const
    00230     {
    00231       return second_monoid_;
    00232     }
    00233
    00234     template <typename F, typename S>
    00235     const boost::shared_ptr<MonoidRep<FreeMonoidProduct<F, S> > >
    00236     FreeMonoidProduct<F, S>::representation() const
    00237     {
    00238       return rep_;
    00239     }
    00240
    00241     template <typename F, typename S>
    00242     void
    00243     FreeMonoidProduct<F, S>::set_representation(MonoidRep<FreeMonoidProduct<F, S> > mr)
    00244     {
    00245       rep_ = boost::shared_ptr<MonoidRep<FreeMonoidProduct<F, S> > >(new MonoidRep<FreeMonoidProduct<F, S> > (mr));
    00246     }
    00247
    00248     template <typename F, typename S>
    00249     bool
    00250     operator==(const FreeMonoidProduct<F, S>& lhs,
    00251                const FreeMonoidProduct<F, S>& rhs)
    00252     {
    00253       return (lhs.first_monoid() == rhs.first_monoid() &&
    00254               lhs.second_monoid() == rhs.second_monoid() &&
    00255               lhs.representation() == rhs.representation());
    00256     }
    00257
    00258   } // ! algebra
    00259
    00260 } // ! vcsn
    00261
    00262 #endif // ! VCSN_ALGEBRA_CONCEPT_FREEMONOID_PRODUCT_HXX