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