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
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()) {
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
00302
00303
00304
00305
00306
00307
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
00322
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 }
00355 #endif