Vaucanson 1.4
|
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