FLOPC++
MP_domain.hpp
Go to the documentation of this file.
1 // ******************** FlopCpp **********************************************
2 // File: MP_domain.hpp
3 // $Id$
4 // Author: Tim Helge Hultberg (thh@mat.ua.pt)
5 // Copyright (C) 2003 Tim Helge Hultberg
6 // All Rights Reserved.
7 // ****************************************************************************
8 #ifndef _MP_domain_hpp_
9 #define _MP_domain_hpp_
10 
11 #include <vector>
12 #include <map>
13 #include "MP_utilities.hpp"
14 #include "MP_boolean.hpp"
15 #include "MP_index.hpp"
16 
17 namespace flopc {
18 
19  class MP_set_base;
20  class MP_set;
21  class MP_index;
22 
23  template<int nbr> class MP_subset;
24 
30  class MP_domain_base : public Functor, public MP_index_base {
31  friend class MP_domain;
32  friend class Handle<MP_domain_base*>;
33  friend MP_domain operator*(const MP_domain& a, const MP_domain& b);
34  private:
35  int count;
36  public:
38  virtual ~MP_domain_base();
39 
40  virtual Functor* makeInsertFunctor() const;
41  virtual MP_index* getIndex() const = 0;
42  virtual const MP_set_base* getSet() const = 0;
43  void display()const;
44  virtual size_t size() const ;
45  const Functor* donext;
46  };
47 
61  class MP_domain : public Handle<MP_domain_base*> {
62  friend MP_domain operator*(const MP_domain& a, const MP_domain& b);
63 
64  friend class MP_constraint;
65  friend class MP_index_exp;
66  public:
70  MP_domain();
71  ~MP_domain();
76 
83  MP_domain such_that(const MP_boolean& b);
84 
89  void forall(const Functor* op) const;
90  void forall(const Functor& op) const;
92  size_t size() const;
94  static const MP_domain& getEmpty();
95  private:
96  std::vector<MP_boolean> condition;
98  static const MP_domain* Empty;
99  };
100 
111  class MP_domain_set : public MP_domain_base {
112  public:
114  MP_domain_set(const MP_set* s, MP_index* i);
116  void operator()() const;
120  int evaluate() const;
122  const MP_set_base* getSet() const;
124  MP_index* getIndex() const;
128  MP_domain getDomain(MP_set* s) const ;
129  ~MP_domain_set();
130  private:
131  const MP_set* S;
133  };
134 
135  template<int nbr> class MP_domain_subset;
136 
142  template<int nbr> class insertFunctor : public Functor {
143  public:
146  void operator()() const {
147  std::vector<int> elm(nbr);
148  for (int i=0; i<nbr; i++) {
149  elm[i] = D->I[i]->evaluate();
150  }
151  D->S->insert(elm);
152  }
153  private:
155  };
156 
167  template<int nbr> class MP_domain_subset : public MP_domain_base {
168  friend class insertFunctor<nbr>;
169  public:
171  const std::vector<MP_index*> &i) : S(s), I(i){}
172 
176  int evaluate() const {
177  return S->evaluate(I);
178  }
180  MP_set_base* getSet() const {
181  return S;
182  }
184  MP_index* getIndex() const {
185  return S;
186  }
191  return MP_domain(const_cast<MP_domain_subset<nbr>*>(this));
192  }
194  void operator()() const {
195  bool isBound[nbr];
196  bool allBound = true;
197  for (int j=0; j<nbr; j++) {
198  if (I[j]->isInstantiated() == true) {
199  isBound[j] = true;
200  } else {
201  isBound[j] = false;
202  allBound = false;
203  if (I[j]!=&MP_index::getEmpty()) {
204  I[j]->instantiate();
205  }
206  }
207  }
208  if (allBound == true) {
209  (*donext)();
210  } else {
211  std::map<std::vector<int>, int>::const_iterator i;
212  int counter = 0;
213  for (i = S->elements.begin(); i != S->elements.end(); i++) {
214  S->assign(counter);
215  counter++;
216  bool goOn = true;
217  for (int j=0; j<nbr; j++) {
218  if (isBound[j] == true) {
219  if (I[j]->evaluate() != i->first[j]) {
220  goOn = false;
221  break;
222  }
223  } else {
224  I[j]->assign(i->first[j]);
225  }
226  }
227  if (goOn == true) {
228  (*donext)();
229  }
230  }
231  }
232  for (int j=0; j<nbr; j++) {
233  if (isBound[j] == false) {
234  I[j]->assign(0);
235  I[j]->unInstantiate();
236  }
237  }
238  }
239 
242  return new insertFunctor<nbr>(
243  const_cast<MP_domain_subset<nbr>*>(this));
244  }
245  private:
247  std::vector<MP_index*> I;
248  };
249 
253  MP_domain operator*(const MP_domain& a, const MP_domain& b);
254 
255 } // End of namespace flopc
256 #endif