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; 00091 size_t size() const; 00093 static const MP_domain& getEmpty(); 00094 private: 00095 std::vector<MP_boolean> condition; 00096 Handle<MP_domain_base*> last; 00097 static const MP_domain* Empty; 00098 }; 00099 00110 class MP_domain_set : public MP_domain_base { 00111 public: 00113 MP_domain_set(const MP_set* s, MP_index* i); 00115 void operator()() const; 00119 int evaluate() const; 00121 const MP_set_base* getSet() const; 00123 MP_index* getIndex() const; 00127 MP_domain getDomain(MP_set* s) const ; 00128 ~MP_domain_set(); 00129 private: 00130 const MP_set* S; 00131 MP_index* I; 00132 }; 00133 00134 template<int nbr> class MP_domain_subset; 00135 00141 template<int nbr> class insertFunctor : public Functor { 00142 public: 00143 insertFunctor(MP_domain_subset<nbr>* d) : D(d) {} 00145 void operator()() const { 00146 std::vector<int> elm(nbr); 00147 for (int i=0; i<nbr; i++) { 00148 elm[i] = D->I[i]->evaluate(); 00149 } 00150 D->S->insert(elm); 00151 } 00152 private: 00153 MP_domain_subset<nbr>* D; 00154 }; 00155 00166 template<int nbr> class MP_domain_subset : public MP_domain_base { 00167 friend class insertFunctor<nbr>; 00168 public: 00169 MP_domain_subset<nbr> (MP_subset<nbr>* s, 00170 const std::vector<MP_index*> &i) : S(s), I(i){} 00171 00175 int evaluate() const { 00176 return S->evaluate(I); 00177 } 00179 MP_set_base* getSet() const { 00180 return S; 00181 } 00183 MP_index* getIndex() const { 00184 return S; 00185 } 00189 MP_domain getDomain(MP_set* s) const { 00190 return MP_domain(const_cast<MP_domain_subset<nbr>*>(this)); 00191 } 00193 void operator()() const { 00194 bool isBound[nbr]; 00195 bool allBound = true; 00196 for (int j=0; j<nbr; j++) { 00197 if (I[j]->isInstantiated() == true) { 00198 isBound[j] = true; 00199 } else { 00200 isBound[j] = false; 00201 allBound = false; 00202 if (I[j]!=&MP_index::getEmpty()) { 00203 I[j]->instantiate(); 00204 } 00205 } 00206 } 00207 if (allBound == true) { 00208 (*donext)(); 00209 } else { 00210 std::map<std::vector<int>, int>::const_iterator i; 00211 int counter = 0; 00212 for (i = S->elements.begin(); i != S->elements.end(); i++) { 00213 S->assign(counter); 00214 counter++; 00215 bool goOn = true; 00216 for (int j=0; j<nbr; j++) { 00217 if (isBound[j] == true) { 00218 if (I[j]->evaluate() != i->first[j]) { 00219 goOn = false; 00220 break; 00221 } 00222 } else { 00223 I[j]->assign(i->first[j]); 00224 } 00225 } 00226 if (goOn == true) { 00227 (*donext)(); 00228 } 00229 } 00230 } 00231 for (int j=0; j<nbr; j++) { 00232 if (isBound[j] == false) { 00233 I[j]->assign(0); 00234 I[j]->unInstantiate(); 00235 } 00236 } 00237 } 00238 00240 Functor* makeInsertFunctor() const { 00241 return new insertFunctor<nbr>( 00242 const_cast<MP_domain_subset<nbr>*>(this)); 00243 } 00244 private: 00245 MP_subset<nbr>* S; 00246 std::vector<MP_index*> I; 00247 }; 00248 00252 MP_domain operator*(const MP_domain& a, const MP_domain& b); 00253 00254 } // End of namespace flopc 00255 #endif