MP_domain.hpp

Go to the documentation of this file.
00001 // ******************** FlopCpp **********************************************
00002 // File: MP_domain.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 #ifndef _MP_domain_hpp_
00009 #define _MP_domain_hpp_
00010 
00011 #include <vector>
00012 #include <map>
00013 #include "MP_utilities.hpp"
00014 #include "MP_boolean.hpp" 
00015 #include "MP_index.hpp" 
00016 
00017 namespace flopc {
00018 
00019 class MP_set_base;
00020 class MP_set;
00021 class MP_index;
00022 
00023 template<int nbr> class MP_subset;
00024 
00030 class MP_domain_base : public Functor, public MP_index_base {
00031     friend class MP_domain;
00032     friend class Handle<MP_domain_base*>;
00033     friend MP_domain operator*(const MP_domain& a, const MP_domain& b);
00034 private:
00035     int count;
00036 public:
00037     MP_domain_base();
00038         virtual ~MP_domain_base();
00039 
00040     virtual Functor* makeInsertFunctor() const;
00041     virtual MP_index* getIndex() const = 0;
00042     virtual const MP_set_base* getSet() const = 0;
00043     void display()const;
00044     virtual size_t size() const ;
00045     const Functor* donext;
00046 };
00047 
00061 class MP_domain : public Handle<MP_domain_base*> {
00062     friend MP_domain operator*(const MP_domain& a, const MP_domain& b);
00063     
00064     friend class MP_constraint;
00065     friend class MP_index_exp;
00066 public:
00070     MP_domain();
00071         ~MP_domain();
00075     MP_domain(MP_domain_base* r);
00076 
00083     MP_domain such_that(const MP_boolean& b);
00084 
00089     void Forall(const Functor* op) const;
00091     size_t size() const;
00093     static const MP_domain& getEmpty();
00094 private:
00095         std::vector<MP_boolean> condition;
00096     Handle<MP_domain_base*> last;
00097     static const MP_domain* Empty;
00098 };
00099 
00110 class MP_domain_set : public MP_domain_base {
00111 public:
00113     MP_domain_set(const MP_set* s, MP_index* i);
00115     void operator()() const;
00119     int evaluate() const;
00121     const MP_set_base* getSet() const;
00123     MP_index* getIndex() const;
00127     MP_domain getDomain(MP_set* s) const ;
00128     ~MP_domain_set();
00129 private:
00130     const MP_set* S;
00131      MP_index* I;
00132 };
00133 
00134 template<int nbr> class MP_domain_subset;
00135 
00141     template<int nbr> class insertFunctor : public Functor {
00142 public:
00143     insertFunctor(MP_domain_subset<nbr>* d) : D(d) {}
00145     void operator()() const { 
00146         std::vector<int> elm(nbr);
00147         for (int i=0; i<nbr; i++) {
00148             elm[i] = D->I[i]->evaluate();
00149         }
00150         D->S->insert(elm);
00151     }
00152 private:
00153     MP_domain_subset<nbr>* D;
00154 };
00155 
00166 template<int nbr> class MP_domain_subset : public MP_domain_base {
00167     friend class insertFunctor<nbr>;
00168 public:
00169     MP_domain_subset<nbr> (MP_subset<nbr>* s, 
00170                            const std::vector<MP_index*> &i) : S(s), I(i){}
00171 
00175     int evaluate() const {
00176         return S->evaluate(I);
00177     }
00179     MP_set_base* getSet() const {
00180         return S;
00181     }
00183     MP_index* getIndex() const {
00184         return S;
00185     }
00189     MP_domain getDomain(MP_set* s) const {
00190         return MP_domain(const_cast<MP_domain_subset<nbr>*>(this));
00191     }
00193     void operator()() const {
00194         bool isBound[nbr];
00195         bool allBound = true;
00196         for (int j=0; j<nbr; j++) {
00197             if (I[j]->isInstantiated() == true) {
00198                 isBound[j] = true;
00199             } else {
00200                 isBound[j] = false;
00201                 allBound = false;
00202                 if (I[j]!=&MP_index::getEmpty()) { 
00203                     I[j]->instantiate();
00204                 }
00205             }
00206         }
00207         if (allBound == true) {
00208             (*donext)(); 
00209         } else {
00210             std::map<std::vector<int>, int>::const_iterator i;
00211             int counter = 0;
00212             for (i = S->elements.begin(); i != S->elements.end(); i++) {
00213                 S->assign(counter);
00214                 counter++;
00215                 bool goOn = true;
00216                 for (int j=0; j<nbr; j++) {
00217                     if (isBound[j] == true) {
00218                         if (I[j]->evaluate() != i->first[j]) {
00219                             goOn = false;
00220                             break;
00221                         }
00222                     } else {
00223                         I[j]->assign(i->first[j]);
00224                     }
00225                 }
00226                 if (goOn == true) {
00227                     (*donext)();
00228                 }
00229             }
00230         }
00231         for (int j=0; j<nbr; j++) {
00232             if (isBound[j] == false) {
00233                 I[j]->assign(0);
00234                 I[j]->unInstantiate();
00235             }
00236         }
00237     }    
00238 
00240     Functor* makeInsertFunctor() const {
00241         return new insertFunctor<nbr>(
00242             const_cast<MP_domain_subset<nbr>*>(this));
00243     }
00244 private:
00245     MP_subset<nbr>* S;
00246     std::vector<MP_index*> I;
00247 };
00248 
00252 MP_domain operator*(const MP_domain& a, const MP_domain& b);
00253   
00254 }  // End of namespace flopc
00255 #endif

Generated on Sun Nov 6 03:14:50 2011 for FLOPC++ by  doxygen 1.4.7