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 flopc::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 Fri May 16 00:25:12 2008 for FLOPC++ by  doxygen 1.4.7