00001 // ******************** FlopCpp ********************************************** 00002 // File: MP_domain.hpp 00003 // $Id$ 00004 // Author: Tim Helge Hultberg (thh@mat.ua.pt) 00005 // Copyright (C) 2003 Tim Helge Hultberg 00006 // All Rights Reserved. 00007 // **************************************************************************** 00008 #ifndef _MP_domain_hpp_ 00009 #define _MP_domain_hpp_ 00010 00011 #include <vector> 00012 #include <map> 00013 #include "MP_utilities.hpp" 00014 #include "MP_boolean.hpp" 00015 #include "MP_index.hpp" 00016 00017 namespace flopc { 00018 00019 class MP_set_base; 00020 class MP_set; 00021 class MP_index; 00022 00023 template<int nbr> class MP_subset; 00024 00030 class MP_domain_base : public Functor, public MP_index_base { 00031 friend class MP_domain; 00032 friend class Handle<MP_domain_base*>; 00033 friend MP_domain operator*(const MP_domain& a, const MP_domain& b); 00034 private: 00035 int count; 00036 public: 00037 MP_domain_base(); 00038 virtual ~MP_domain_base(); 00039 00040 virtual Functor* makeInsertFunctor() const; 00041 virtual MP_index* getIndex() const = 0; 00042 virtual const MP_set_base* getSet() const = 0; 00043 void display()const; 00044 virtual size_t size() const ; 00045 const Functor* donext; 00046 }; 00047 00061 class MP_domain : public Handle<MP_domain_base*> { 00062 friend MP_domain operator*(const MP_domain& a, const MP_domain& b); 00063 00064 friend class MP_constraint; 00065 friend class MP_index_exp; 00066 public: 00070 MP_domain(); 00071 ~MP_domain(); 00075 MP_domain(MP_domain_base* r); 00076 00083 MP_domain such_that(const MP_boolean& b); 00084 00089 void forall(const Functor* op) const; 00090 void forall(const Functor& op) const; 00092 size_t size() const; 00094 static const MP_domain& getEmpty(); 00095 private: 00096 std::vector<MP_boolean> condition; 00097 Handle<MP_domain_base*> last; 00098 static const MP_domain* Empty; 00099 }; 00100 00111 class MP_domain_set : public MP_domain_base { 00112 public: 00114 MP_domain_set(const MP_set* s, MP_index* i); 00116 void operator()() const; 00120 int evaluate() const; 00122 const MP_set_base* getSet() const; 00124 MP_index* getIndex() const; 00128 MP_domain getDomain(MP_set* s) const ; 00129 ~MP_domain_set(); 00130 private: 00131 const MP_set* S; 00132 MP_index* I; 00133 }; 00134 00135 template<int nbr> class MP_domain_subset; 00136 00142 template<int nbr> class insertFunctor : public Functor { 00143 public: 00144 insertFunctor(MP_domain_subset<nbr>* d) : D(d) {} 00146 void operator()() const { 00147 std::vector<int> elm(nbr); 00148 for (int i=0; i<nbr; i++) { 00149 elm[i] = D->I[i]->evaluate(); 00150 } 00151 D->S->insert(elm); 00152 } 00153 private: 00154 MP_domain_subset<nbr>* D; 00155 }; 00156 00167 template<int nbr> class MP_domain_subset : public MP_domain_base { 00168 friend class insertFunctor<nbr>; 00169 public: 00170 MP_domain_subset<nbr> (MP_subset<nbr>* s, 00171 const std::vector<MP_index*> &i) : S(s), I(i){} 00172 00176 int evaluate() const { 00177 return S->evaluate(I); 00178 } 00180 MP_set_base* getSet() const { 00181 return S; 00182 } 00184 MP_index* getIndex() const { 00185 return S; 00186 } 00190 MP_domain getDomain(MP_set* s) const { 00191 return MP_domain(const_cast<MP_domain_subset<nbr>*>(this)); 00192 } 00194 void operator()() const { 00195 bool isBound[nbr]; 00196 bool allBound = true; 00197 for (int j=0; j<nbr; j++) { 00198 if (I[j]->isInstantiated() == true) { 00199 isBound[j] = true; 00200 } else { 00201 isBound[j] = false; 00202 allBound = false; 00203 if (I[j]!=&MP_index::getEmpty()) { 00204 I[j]->instantiate(); 00205 } 00206 } 00207 } 00208 if (allBound == true) { 00209 (*donext)(); 00210 } else { 00211 std::map<std::vector<int>, int>::const_iterator i; 00212 int counter = 0; 00213 for (i = S->elements.begin(); i != S->elements.end(); i++) { 00214 S->assign(counter); 00215 counter++; 00216 bool goOn = true; 00217 for (int j=0; j<nbr; j++) { 00218 if (isBound[j] == true) { 00219 if (I[j]->evaluate() != i->first[j]) { 00220 goOn = false; 00221 break; 00222 } 00223 } else { 00224 I[j]->assign(i->first[j]); 00225 } 00226 } 00227 if (goOn == true) { 00228 (*donext)(); 00229 } 00230 } 00231 } 00232 for (int j=0; j<nbr; j++) { 00233 if (isBound[j] == false) { 00234 I[j]->assign(0); 00235 I[j]->unInstantiate(); 00236 } 00237 } 00238 } 00239 00241 Functor* makeInsertFunctor() const { 00242 return new insertFunctor<nbr>( 00243 const_cast<MP_domain_subset<nbr>*>(this)); 00244 } 00245 private: 00246 MP_subset<nbr>* S; 00247 std::vector<MP_index*> I; 00248 }; 00249 00253 MP_domain operator*(const MP_domain& a, const MP_domain& b); 00254 00255 } // End of namespace flopc 00256 #endif