- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# /home/coin/svn-release/Smi-0.93.1/FlopCpp/src/MP_set.hpp

Go to the documentation of this file.

    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 #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 //              Messenger &msgr = *MP_model::getCurrentModel()->getMessenger();
    00175 //              msgr.logMessage(5,s.c_str());
    00176 //              std::map<std::vector<int>, int>::const_iterator i;
    00177 //              for (i = elements.begin(); i != elements.end(); i++)
    00178 //              {
    00179 //                      std::stringstream ss;
    00180 //                      for (int j=0; j<nbr; j++)
    00181 //                      {
    00182 //                              ss<<(*i).first[j]<<"  ";
    00183 //                      }
    00184 //                      ss<<(*i).second<<std::ends;
    00185 //                      msgr.logMessage(5,ss.str().c_str());
    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()) {  // insert if not existent
    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 //              Messenger &msgr=*MP_model::getCurrentModel()->getMessenger();
    00306 //              msgr.logMessage(5,toString().c_str());
    00307         }
    00308
    00309         operator MP_domain() const {
    00310 //          MP_domain_base* base;
    00311 //          base = new MP_domain_subset<nbr>(S,
    00312 //              makeVector<nbr>(I1->getIndex(), I2->getIndex(),
    00313 //                              I3->getIndex(), I4->getIndex(),
    00314 //                              I5->getIndex()) );
    00315 //          base->such_that(B);
    00316 //          return base;
    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 } // End of namespace flopc
    00359 #endif