Vaucanson  1.4.1
freemonoid_product.hxx
1 // freemonoid_product.hxx: this file is part of the Vaucanson project.
2 //
3 // Vaucanson, a generic library for finite state machines.
4 //
5 // Copyright (C) 2004, 2005, 2008 The Vaucanson Group.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // The complete GNU General Public Licence Notice can be found as the
13 // `COPYING' file in the root directory.
14 //
15 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
16 //
17 #ifndef VCSN_ALGEBRA_CONCEPT_FREEMONOID_PRODUCT_HXX
18 # define VCSN_ALGEBRA_CONCEPT_FREEMONOID_PRODUCT_HXX
19 
20 # include <vaucanson/algebra/concept/freemonoid_product.hh>
21 
22 namespace vcsn
23 {
24  namespace algebra
25  {
26  template <typename F, typename S>
27  MonoidRep<FreeMonoidProduct<F, S> >::MonoidRep() :
28  open_par("("),
29  sep(","),
30  close_par(")")
31  {}
32 
33  template <typename Semiring, typename F, typename S>
34  void
35  SeriesRep<Semiring, FreeMonoidProduct<F, S> >::
36  disambiguate(const monoid_t& monoid, pointer_t& p)
37  {
38  // Pointer types.
39  typedef boost::shared_ptr<first_rep_t> first_p_t;
40  typedef boost::shared_ptr<second_rep_t> second_p_t;
41 
42  first_p_t first_rep(new first_rep_t(p->first_representation()));
43  second_p_t second_rep(new second_rep_t(p->second_representation()));
44 
45  // Backup old pointers.
46  first_p_t first_rep_orig = first_rep;
47  second_p_t second_rep_orig = second_rep;
48 
49  // Real work done here.
50  first_rep->disambiguate(monoid.first_monoid(), first_rep);
51  second_rep->disambiguate(monoid.second_monoid(), second_rep);
52 
53  // Copy on write.
54  if (first_rep_orig != first_rep || second_rep_orig != second_rep)
55  {
56  self_t new_rep(*p);
57  new_rep.first_representation() = *first_rep;
58  new_rep.second_representation() = *second_rep;
59  p = pointer_t(new self_t(new_rep));
60  }
61  }
62 
63  template <typename Semiring, typename F, typename S>
64  SeriesRep<Semiring, F>&
65  SeriesRep<Semiring, FreeMonoidProduct<F, S> >::first_representation()
66  {
67  return first_representation_;
68  }
69 
70  template <typename Semiring, typename F, typename S>
71  const SeriesRep<Semiring, F>&
72  SeriesRep<Semiring, FreeMonoidProduct<F, S> >::first_representation() const
73  {
74  return first_representation_;
75  }
76 
77  template <typename Semiring, typename F, typename S>
78  SeriesRep<Semiring, S>&
79  SeriesRep<Semiring, FreeMonoidProduct<F, S> >::second_representation()
80  {
81  return second_representation_;
82  }
83 
84  template <typename Semiring, typename F, typename S>
85  const SeriesRep<Semiring, S>&
86  SeriesRep<Semiring, FreeMonoidProduct<F, S> >::second_representation() const
87  {
88  return second_representation_;
89  }
90 
91  template <typename F, typename S>
92  bool
93  operator==(boost::shared_ptr<MonoidRep<FreeMonoidProduct<F, S> > > lhs,
94  boost::shared_ptr<MonoidRep<FreeMonoidProduct<F, S> > > rhs)
95  {
96  // Type helpers.
97  typedef MonoidRepBase<MonoidRep, FreeMonoidProduct<F, S> >
98  monoid_rep_base_t;
99  typedef boost::shared_ptr<monoid_rep_base_t> p_t;
100 
101  return (lhs->open_par == rhs->open_par &&
102  lhs->sep == rhs->sep &&
103  lhs->close_par == rhs->close_par &&
104  static_cast<p_t>(lhs) == static_cast<p_t>(rhs));
105  }
106 
107  template <typename Semiring, typename F, typename S>
108  bool
109  operator==(boost::shared_ptr<SeriesRep<Semiring, FreeMonoidProduct<F, S> > > lhs,
110  boost::shared_ptr<SeriesRep<Semiring, FreeMonoidProduct<F, S> > > rhs)
111  {
112  // Type helpers.
113  typedef SeriesRep<Semiring, F> first_rep_t;
114  typedef SeriesRep<Semiring, S> second_rep_t;
115  typedef SeriesRepBase<SeriesRep, Semiring, FreeMonoidProduct<F, S> >
116  series_rep_base_t;
117 
118  // Pointer types.
119  typedef boost::shared_ptr<first_rep_t> first_p_t;
120  typedef boost::shared_ptr<second_rep_t> second_p_t;
121  typedef boost::shared_ptr<series_rep_base_t> p_t;
122 
123  // FIXME: we should provide operator== for the pointed to types.
124  first_p_t lhs_first(new first_rep_t());
125  second_p_t lhs_second(new second_rep_t());
126  first_p_t rhs_first(new first_rep_t());
127  second_p_t rhs_second(new second_rep_t());
128 
129  *lhs_first = lhs->first_representation();
130  *lhs_second = lhs->second_representation();
131  *rhs_first = rhs->first_representation();
132  *rhs_second = rhs->second_representation();
133 
134  return (lhs_first == rhs_first &&
135  lhs_second == rhs_second &&
136  static_cast<p_t>(lhs) == static_cast<p_t>(rhs));
137  }
138 
139  /*------------------------.
140  | FreeMonoidProduct<F, S> |
141  `------------------------*/
142 
143  // FIXME: This facility is a HACK. Explanations: when a high level
144  // structural element (a structure inheriting from Structure) is
145  // instantiated (say a series_set_t), the underlying monoid is only
146  // accessible via const methods. Unfortunately it means that when a
147  // FreeMonoidProduct is instantiated (not as a non-const object) the
148  // shared_ptr holding the pointers to the first and second monoid
149  // representations can't be changed. And, because we originally planned to
150  // use singleton (see get_instance()) and other clever tricks, an FMP<F, S>
151  // with F == S will use the SAME representation for both the monoid.
152  // (simply put, changing the epsilon representation for the first monoid
153  // will pass on to the second one). A lot of work needs to be done to solve
154  // this problem elegantly but AFAIK it all revolves around improving the
155  // MonoidRepBase to be more like an alphabet (with dynamic data stored in
156  // some chosen implementation). As for now the implemented solution has the
157  // least impact on Vaucanson. It could have been done more compact but the
158  // choice was made to choose the code that most visibly explains why it is
159  // done. We ensure _when creating the FMP_ that if the two representations
160  // match, we create a new one for the second monoid (the calculated
161  // representation build by the disambiguate function is used to initialize
162  // it). WARNING: it obviously defeat the purpose of the shared_ptr.
163  template <typename F, typename S>
164  void
165  split_monoid_(F&, S&)
166  {}
167 
168  template <typename F>
169  void
170  split_monoid_(F& first_monoid, F& second_monoid)
171  {
172  if (first_monoid.representation().get() == second_monoid.representation().get())
173  {
174  typename F::monoid_rep_t second = *(second_monoid.representation());
175  second_monoid.set_representation(second);
176  }
177  }
178 
179  template <class F, class S>
181  first_monoid_(a), second_monoid_(b),
182  rep_(MonoidRepDefault<FreeMonoidProduct<F, S> >::get_instance())
183  {
184  split_monoid_(first_monoid_, second_monoid_);
185  }
186 
187  template <class F, class S>
188  FreeMonoidProduct<F, S>::FreeMonoidProduct(const F& a, const S& b,
189  MonoidRep<FreeMonoidProduct<F, S> > mr) :
190  first_monoid_(a), second_monoid_(b),
191  rep_(boost::shared_ptr<MonoidRep<FreeMonoidProduct<F, S> > >(new MonoidRep<FreeMonoidProduct<F, S> >(mr)))
192  {
193  split_monoid_(first_monoid_, second_monoid_);
194  }
195 
196  template <class F, class S>
199  first_monoid_(w.first_monoid_),
200  second_monoid_(w.second_monoid_),
201  rep_(w.rep_)
202  {
203  split_monoid_(first_monoid_, second_monoid_);
204  }
205 
206  template <class F, class S>
209  {
210  return first_monoid_;
211  }
212 
213  template <class F, class S>
216  {
217  return first_monoid_;
218  }
219 
220  template <class F, class S>
223  {
224  return second_monoid_;
225  }
226 
227  template <class F, class S>
230  {
231  return second_monoid_;
232  }
233 
234  template <typename F, typename S>
235  const boost::shared_ptr<MonoidRep<FreeMonoidProduct<F, S> > >
237  {
238  return rep_;
239  }
240 
241  template <typename F, typename S>
242  void
244  {
245  rep_ = boost::shared_ptr<MonoidRep<FreeMonoidProduct<F, S> > >(new MonoidRep<FreeMonoidProduct<F, S> > (mr));
246  }
247 
248  template <typename F, typename S>
249  bool
250  operator==(const FreeMonoidProduct<F, S>& lhs,
251  const FreeMonoidProduct<F, S>& rhs)
252  {
253  return (lhs.first_monoid() == rhs.first_monoid() &&
254  lhs.second_monoid() == rhs.second_monoid() &&
255  lhs.representation() == rhs.representation());
256  }
257 
258  } // ! algebra
259 
260 } // ! vcsn
261 
262 #endif // ! VCSN_ALGEBRA_CONCEPT_FREEMONOID_PRODUCT_HXX