FLOPC++
|
00001 // ******************** FlopCpp ********************************************** 00002 // File: MP_set.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 00009 #ifndef _MP_set_hpp_ 00010 #define _MP_set_hpp_ 00011 00012 #include <iostream> 00013 #include <sstream> 00014 using std::cout; 00015 using std::endl; 00016 00017 #include <string> 00018 using std::string; 00019 00020 #include "MP_domain.hpp" 00021 #include "MP_index.hpp" 00022 #include "MP_utilities.hpp" 00023 00024 namespace flopc { 00025 00030 class MP_set_base : public MP_index , public Named { 00031 public: 00032 MP_set_base() : Cyclic(false) {} 00033 00034 virtual int size() const = 0; 00035 virtual operator MP_domain() const = 0; 00036 virtual MP_domain operator()(const MP_index_exp& i) const = 0; 00037 00038 int check(int i) const { 00039 if ((i>=0) && (i<size())) { 00040 return i; 00041 } else { 00042 if (Cyclic == true) { 00043 return mod(i,size()); 00044 } else { 00045 return outOfBound; 00046 } 00047 } 00048 } 00049 int checkStage(int i) const { 00050 if ((i>=0) && (i<size())) { 00051 return i*isStage(); 00052 } else { 00053 if (Cyclic == true) { 00054 return mod(i,size())*isStage(); 00055 } else { 00056 return outOfBound; 00057 } 00058 } 00059 } 00061 virtual int isStage() const { 00062 return 0; 00063 } 00064 00065 bool Cyclic; 00066 }; 00067 00068 00079 class MP_set : public MP_set_base { 00080 public: 00082 MP_set(int i = 0): cardinality(i) {} 00087 MP_domain operator()(const MP_index_exp& i) const { 00088 return i->getDomain(const_cast<MP_set*>(this)); 00089 } 00091 operator MP_domain() const { 00092 return new MP_domain_set(this,const_cast<MP_set*>(this)); 00093 } 00097 MP_domain such_that(const MP_boolean& b) { 00098 return (MP_domain(new MP_domain_set(this,this))).such_that(b); 00099 } 00103 void cyclic() { 00104 Cyclic = true; 00105 } 00107 virtual int size() const { 00108 return cardinality; 00109 } 00110 int last() { 00111 return cardinality-1; 00112 } 00114 static MP_set &getEmpty(); 00115 private: 00116 static MP_set Empty; 00117 int cardinality; 00118 }; 00119 00120 class MP_stage : public MP_set { 00121 public: 00122 MP_stage(int i = 0): MP_set(i) {} 00123 virtual int isStage() const { 00124 return 1; 00125 } 00126 }; 00127 00128 template <int nbr> class MP_subset; 00129 00135 template<int nbr> class InsertFunctor : public Functor { 00136 public: 00137 InsertFunctor( MP_subset<nbr>* s, vector<MP_index_exp> i) 00138 : S(s), I(i) {} 00139 void operator()() const { 00140 vector<int> elm(nbr); 00141 for (int i=0; i<nbr; i++) { 00142 elm[i] = I[i]->evaluate(); 00143 } 00144 S->insert(elm); 00145 } 00146 private: 00147 MP_subset<nbr>* S; 00148 vector<MP_index_exp> I; 00149 }; 00150 00151 template <int nbr> class SubsetRef; 00152 00161 template <int nbr> 00162 class MP_subset : public MP_set { 00163 friend class MP_domain_subset<nbr>; 00164 friend class SubsetRef<nbr>; 00165 public: 00166 MP_subset(const MP_set& s1, 00167 const MP_set& s2=MP_set::getEmpty(), 00168 const MP_set& s3=MP_set::getEmpty(), 00169 const MP_set& s4=MP_set::getEmpty(), 00170 const MP_set& s5=MP_set::getEmpty()) { 00171 S = makeVector<nbr,const MP_set*>(&s1,&s2,&s3,&s4,&s5); 00172 } 00173 00174 void display(const std::string& s = "") const { 00175 std::map<std::vector<int>, int>::const_iterator i; 00176 cout<<s<<endl; 00177 for (i = elements.begin(); i != elements.end(); i++) { 00178 for (int j=0; j<nbr; j++) { 00179 cout<<(*i).first[j]<<" "; 00180 } 00181 cout<<endl; 00182 } 00183 } 00184 00185 MP_subset(vector<const MP_set*> s) : S(s) {} 00186 00187 ~MP_subset() {} 00188 00189 int operator()(int i1, int i2=0, int i3=0, int i4=0, int i5=0) { 00190 std::map<vector<int>, int>::const_iterator pos; 00191 pos = elements.find(makeVector<nbr>(i1, i2, i3, i4, i5)); 00192 if (pos==elements.end()) { 00193 return outOfBound; 00194 } else { 00195 return pos->second; 00196 } 00197 } 00198 00199 SubsetRef<nbr>& operator()(const MP_index_exp& i1, 00200 const MP_index_exp& i2=MP_index::getEmpty(), 00201 const MP_index_exp& i3=MP_index::getEmpty(), 00202 const MP_index_exp& i4=MP_index::getEmpty(), 00203 const MP_index_exp& i5=MP_index::getEmpty()) { 00204 return *new SubsetRef<nbr>(this,i1,i2,i3,i4,i5); 00205 } 00206 00207 MP_domain& operator()(const SUBSETREF& s) { 00208 return MP_domain(s); 00209 } 00210 00211 int evaluate(const vector<MP_index*>& I) const { 00212 vector<int> vi; 00213 for (int k=0; k<nbr; k++) { 00214 int temp = I[k]->evaluate(); 00215 vi.push_back(temp); 00216 } 00217 std::map<vector<int>, int>::const_iterator pos; 00218 pos = elements.find(vi); 00219 if (pos==elements.end()) { 00220 return outOfBound; 00221 } else { 00222 return pos->second; 00223 } 00224 } 00225 00226 void insert(const vector<int> &args) { 00227 bool isOk = true; 00228 for (int i=0; i<nbr; i++) { 00229 if ( S[i]->check(args[i]) == outOfBound ) { 00230 isOk = false; 00231 } 00232 } 00233 if (isOk == true) { 00234 std::map<vector<int>, int>::const_iterator pos; 00235 pos = elements.find(args); 00236 if (pos==elements.end()) { // insert if not existent 00237 const int v = elements.size(); 00238 elements[args] = v; 00239 } 00240 } 00241 } 00242 void insert(int i1, int i2=0, int i3=0, int i4=0, int i5=0) { 00243 insert(makeVector<nbr>(i1, i2, i3, i4, i5)); 00244 } 00245 const InsertFunctor<nbr>& insert(MP_index_exp i1, 00246 MP_index_exp i2=MP_index_exp::getEmpty(), 00247 MP_index_exp i3=MP_index_exp::getEmpty(), 00248 MP_index_exp i4=MP_index_exp::getEmpty(), 00249 MP_index_exp i5=MP_index_exp::getEmpty()) { 00250 return *new InsertFunctor<nbr>(this,makeVector<nbr>(i1, i2, i3, i4, i5)); 00251 } 00252 virtual int size() const { 00253 return elements.size(); 00254 } 00255 00256 private: 00257 vector<const MP_set*> S; 00258 std::map<std::vector<int>, int> elements; 00259 }; 00260 00269 class SUBSETREF : public MP_index_base { 00270 public: 00271 virtual MP_index* getIndex() const { 00272 return 0; 00273 } 00274 virtual MP_domain getDomain(MP_set* s) const { 00275 return MP_domain::getEmpty(); 00276 } 00277 int evaluate() const { 00278 return 0; 00279 } 00280 }; 00281 00289 template <int nbr> 00290 class SubsetRef : public SUBSETREF { 00291 public: 00292 SubsetRef(MP_subset<nbr>* s, 00293 const MP_index_exp& i1, 00294 const MP_index_exp& i2, 00295 const MP_index_exp& i3, 00296 const MP_index_exp& i4, 00297 const MP_index_exp& i5) : 00298 S(s),I1(i1),I2(i2),I3(i3),I4(i4),I5(i5) {} 00299 00300 operator MP_domain() const { 00301 // MP_domain_base* base; 00302 // base = new MP_domain_subset<nbr>(S, 00303 // makeVector<nbr>(I1->getIndex(), I2->getIndex(), 00304 // I3->getIndex(), I4->getIndex(), 00305 // I5->getIndex()) ); 00306 // base->such_that(B); 00307 // return base; 00308 return new MP_domain_subset<nbr>(S, 00309 makeVector<nbr>(I1->getIndex(), I2->getIndex(), 00310 I3->getIndex(), I4->getIndex(), 00311 I5->getIndex()) ); 00312 } 00313 00314 virtual MP_domain getDomain(MP_set* s) const { 00315 return new MP_domain_subset<nbr>(S, 00316 makeVector<nbr>(I1->getIndex(), I2->getIndex(), 00317 I3->getIndex(), I4->getIndex(), 00318 I5->getIndex()) ); 00319 } 00320 00321 // const MP_domain& such_that(const MP_boolean& b) { 00322 // return MP_domain().such_that(b); 00323 // } 00324 00325 SubsetRef& such_that(const MP_boolean& b) { 00326 B = b; 00327 return *this; 00328 } 00329 00330 int evaluate() const { 00331 vector<MP_index_exp> I = makeVector<nbr>(I1,I2,I3,I4,I5); 00332 vector<int> vi; 00333 for (int k=0; k<nbr; k++) { 00334 int temp = I[k]->evaluate(); 00335 vi.push_back(temp); 00336 } 00337 std::map<vector<int>, int>::const_iterator pos; 00338 pos = S->elements.find(vi); 00339 if (pos==S->elements.end()) { 00340 return outOfBound; 00341 } else { 00342 return pos->second; 00343 } 00344 00345 } 00346 MP_index* getIndex() const { 00347 return S; 00348 } 00349 MP_boolean B; 00350 MP_subset<nbr>* S; 00351 MP_index_exp I1,I2,I3,I4,I5; 00352 }; 00353 00354 } // End of namespace flopc 00355 #endif