// ******************** FlopCpp ********************************************** // File: MP_set.hpp // $Id$ // Author: Tim Helge Hultberg (thh@mat.ua.pt) // Copyright (C) 2003 Tim Helge Hultberg // All Rights Reserved. // **************************************************************************** #ifndef _MP_set_hpp_ #define _MP_set_hpp_ #include #include using std::cout; using std::endl; #include using std::string; #include "MP_domain.hpp" #include "MP_index.hpp" #include "MP_utilities.hpp" namespace flopc { /** @brief Internal representation of a "set" @ingroup INTERNAL_USE @note FOR INTERNAL USE: This is not normally used directly by the calling code. */ class MP_set_base : public MP_index , public Named { public: MP_set_base() : Cyclic(false) {} virtual int size() const = 0; virtual operator MP_domain() const = 0; virtual MP_domain operator()(const MP_index_exp& i) const = 0; int check(int i) const { if ((i>=0) && (i=0) && (igetDomain(const_cast(this)); } /// @brief constructs an MP_domain from the MP_set. operator MP_domain() const { return new MP_domain_set(this,const_cast(this)); } /** @brief constructs a domain by subsetting this MP_set where the MP_boolean evaluates to 'true' */ MP_domain such_that(const MP_boolean& b) { return (MP_domain(new MP_domain_set(this,this))).such_that(b); } /** setter for 'cyclic' property @todo better explain the use of cyclic. */ void cyclic() { Cyclic = true; } /// getter for the cardinality of this MP_set. virtual int size() const { return cardinality; } int last() { return cardinality-1; } /// gets the distinct 'empty' MP_set. static MP_set &getEmpty(); private: static MP_set Empty; int cardinality; }; class MP_stage : public MP_set { public: MP_stage(int i = 0): MP_set(i) {} virtual int isStage() const { return 1; } }; template class MP_subset; /** @brief Internal representation of a "set" @ingroup INTERNAL_USE @note FOR INTERNAL USE: This is not normally used directly by the calling code. */ template class InsertFunctor : public Functor { public: InsertFunctor( MP_subset* s, vector i) : S(s), I(i) {} void operator()() const { vector elm(nbr); for (int i=0; ievaluate(); } S->insert(elm); } private: MP_subset* S; vector I; }; template class SubsetRef; /** @brief Internal representation of a "set" @ingroup INTERNAL_USE @note FOR INTERNAL USE: This is not normally used directly by the calling code. @note this is often implicitly created with many expressions which may subset a set. */ template class MP_subset : public MP_set { friend class MP_domain_subset; friend class SubsetRef; public: MP_subset(const MP_set& s1, const MP_set& s2=MP_set::getEmpty(), const MP_set& s3=MP_set::getEmpty(), const MP_set& s4=MP_set::getEmpty(), const MP_set& s5=MP_set::getEmpty()) { S = makeVector(&s1,&s2,&s3,&s4,&s5); } void display(const std::string& s = "") const { std::map, int>::const_iterator i; cout< s) : S(s) {} ~MP_subset() {} int operator()(int i1, int i2=0, int i3=0, int i4=0, int i5=0) { std::map, int>::const_iterator pos; pos = elements.find(makeVector(i1, i2, i3, i4, i5)); if (pos==elements.end()) { return outOfBound; } else { return pos->second; } } SubsetRef& operator()(const MP_index_exp& i1, const MP_index_exp& i2=MP_index::getEmpty(), const MP_index_exp& i3=MP_index::getEmpty(), const MP_index_exp& i4=MP_index::getEmpty(), const MP_index_exp& i5=MP_index::getEmpty()) { return *new SubsetRef(this,i1,i2,i3,i4,i5); } MP_domain& operator()(const SUBSETREF& s) { return MP_domain(s); } int evaluate(const vector& I) const { vector vi; for (int k=0; kevaluate(); vi.push_back(temp); } std::map, int>::const_iterator pos; pos = elements.find(vi); if (pos==elements.end()) { return outOfBound; } else { return pos->second; } } void insert(const vector &args) { bool isOk = true; for (int i=0; icheck(args[i]) == outOfBound ) { isOk = false; } } if (isOk == true) { std::map, int>::const_iterator pos; pos = elements.find(args); if (pos==elements.end()) { // insert if not existent const int v = elements.size(); elements[args] = v; } } } void insert(int i1, int i2=0, int i3=0, int i4=0, int i5=0) { insert(makeVector(i1, i2, i3, i4, i5)); } const InsertFunctor& insert(MP_index_exp i1, MP_index_exp i2=MP_index_exp::getEmpty(), MP_index_exp i3=MP_index_exp::getEmpty(), MP_index_exp i4=MP_index_exp::getEmpty(), MP_index_exp i5=MP_index_exp::getEmpty()) { return *new InsertFunctor(this,makeVector(i1, i2, i3, i4, i5)); } virtual int size() const { return elements.size(); } private: vector S; std::map, int> elements; }; /** @brief Internal representation of a "set" @ingroup INTERNAL_USE @note FOR INTERNAL USE: This is not normally used directly by the calling code. @note this is often implicitly created with many expressions which may subset a set. */ class SUBSETREF : public MP_index_base { public: virtual MP_index* getIndex() const { return 0; } virtual MP_domain getDomain(MP_set* s) const { return MP_domain::getEmpty(); } int evaluate() const { return 0; } }; /** @brief Internal representation of a "set" @ingroup INTERNAL_USE @note FOR INTERNAL USE: This is not normally used directly by the calling code. @note this is often implicitly created with many expressions which may subset a set. */ template class SubsetRef : public SUBSETREF { public: SubsetRef(MP_subset* s, const MP_index_exp& i1, const MP_index_exp& i2, const MP_index_exp& i3, const MP_index_exp& i4, const MP_index_exp& i5) : S(s),I1(i1),I2(i2),I3(i3),I4(i4),I5(i5) {} operator MP_domain() const { // MP_domain_base* base; // base = new MP_domain_subset(S, // makeVector(I1->getIndex(), I2->getIndex(), // I3->getIndex(), I4->getIndex(), // I5->getIndex()) ); // base->such_that(B); // return base; return new MP_domain_subset(S, makeVector(I1->getIndex(), I2->getIndex(), I3->getIndex(), I4->getIndex(), I5->getIndex()) ); } virtual MP_domain getDomain(MP_set* s) const { return new MP_domain_subset(S, makeVector(I1->getIndex(), I2->getIndex(), I3->getIndex(), I4->getIndex(), I5->getIndex()) ); } // const MP_domain& such_that(const MP_boolean& b) { // return MP_domain().such_that(b); // } SubsetRef& such_that(const MP_boolean& b) { B = b; return *this; } int evaluate() const { vector I = makeVector(I1,I2,I3,I4,I5); vector vi; for (int k=0; kevaluate(); vi.push_back(temp); } std::map, int>::const_iterator pos; pos = S->elements.find(vi); if (pos==S->elements.end()) { return outOfBound; } else { return pos->second; } } MP_index* getIndex() const { return S; } MP_boolean B; MP_subset* S; MP_index_exp I1,I2,I3,I4,I5; }; } // End of namespace flopc #endif