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