/* ---- This file is part of SECONDO. Copyright (C) 2004, University in Hagen, Department of Computer Science, Database Systems for New Applications. SECONDO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. SECONDO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SECONDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---- //[title] [\title{TopRelAlgebra}\author{Thomas Behr}\maketitle] //[toc] [\tableofcontents] //[x] [\ensuremath{\times}] //[abstract] [\abstract] //[&] [\&] //paragraph [21] verb: [\begin{verbatim}] [\end{verbatim}] //[|] [$\mid$] //[\f] [\newpage] //[=>] [\ensuremath{\Rightarrow}] //[<=>] [\ensuremath{\Leftrightarrow}] \setcounter{tocdepth}{2} \setcounter{secnumdepth}{2} [title] [toc] [abstract] This algebra provides three data types, namely int9m, cluster, and predicategroup. The int9m type represents the 9 intersection matrix of Egenhofer's 9 intersection model. This means an instance of type int9m is a 3 [x] 3 matrix containing only boolean values. To learn more about this model, read the original paper ''A formal definition of Binary Topological Relationships'' of M.J. Egenhofer. A cluster describes a set of such matrices. Therewith we can describe a predicate ''inside'' containing a defined set of matrizes. Beside the matrices, each cluster contains a name for identification. A predicate cluster is a set of pairwise disjoint clusters. This can be used for modelling a complete set of topological predicates. */ /* 1 The Header File 2.0 Some needed includes */ #ifndef TOPREL_H #define TOPREL_H #include #include #include #include #include "NestedList.h" #include "Attribute.h" #include "StandardTypes.h" #include "../Tools/Flob/DbArray.h" #include "../Tools/Flob/Flob.h" #include "Algebras/Rectangle/RectangleAlgebra.h" #include "ListUtils.h" /* 2.1 Symbolic names for the matrix positions The following rows define some contants used in this algebra. The meaning of the letters is the following: * I the interior of the object * B the boundary of the object * E the exterior of the object Furthermore, the position of the letter describes the position of the object. For example, for two objects A and B respectively, IE designates the unemptyness of the intersection between the interior of A and the exterior of B. */ static const unsigned short II = 256; static const unsigned short IB = 128; static const unsigned short IE = 64; static const unsigned short BI = 32; static const unsigned short BB = 16; static const unsigned short BE = 8; static const unsigned short EI = 4; static const unsigned short EB = 2; static const unsigned short EE = 1; const unsigned char* getEmptyBlock(); const unsigned char* getFullBlock(); /* 2.1 The Data Type ~Int9M~ This type is the implementation of the well know 9-intersections-matrix developed by M. Egenhofer. The type is just a implementation of a bitvector with 9 elements representing the 9 entries in the matrix. */ namespace toprel { class Int9M: public Attribute{ public: /* 2.1.1 The Standard Constructor This constructor should never be called directly. It is used in a non-standard-way in a cast function. */ Int9M(){}; /* 2.1.2 Constructor This constructor takes the matrix number and create a matrix from it. The matrix number is the number resulting from the bitrepresentation of the matrix. For this reason, 512 possible matrices exist. A wrong value for the matrix number leads not to an error, the number is just corrected to tak the last 9 bits. */ Int9M(const short number): Attribute(true){ value = number & 511; } /* 2.1.3 Copy Constructor */ Int9M(const Int9M& source):Attribute(source.IsDefined()){ Equalize(source); } /* 2.1.4 Assignement Operator */ Int9M& operator=(const Int9M& arg){ Equalize(arg); return (*this); } /* 2.1.4 Constructor In this constructor, all matrix entries can be explicitely set. */ Int9M(const bool II, const bool IB, const bool IE, const bool BI, const bool BB, const bool BE, const bool EI, const bool EB, const bool EE); /* 2.1.5 Destructor */ ~Int9M(){}; /* 2.1.6 The ~GetNumber~ function This function returns the matrix number of this int9m instance. */ int GetNumber()const{ return (value & 511);} /* 2.1.7 SetValue Sets the matrix number directly. When the given value is outside the valid range, only the significant bits are used to set the value. */ void SetValue(const short value){ this->value = value&511; SetDefined(true); } /* 2.1.7 ~Invert~ The invert function changes the value of each entry in the matrix to its converse. */ void Invert(){ value = value ^ 511; } /* 2.1.8 ~Union~ This function realizes an elementwise ''or'' of the matrix entries. */ void Union(Int9M* arg){ value |= arg->value; SetDefined(IsDefined() && arg->IsDefined()); } /* 2.1.9 ~Intersection~ The ~Intersection~ Functions computes a elementwise ''and'' of both matrices. */ void Intersection(Int9M* arg){ value &= arg->value; SetDefined(IsDefined() && arg->IsDefined()); } /* 2.1.10 ~SetToNumber~ This function changes the matrix to this one of the given number. */ void SetToNumber(unsigned short number){ value = number & 511; SetDefined(true); } /* 2.1.10 ~Fill~ This function sets all possible intersections within this matrix to be __true__. After calling this function this Int9M instance is also defined. */ void Fill(){ value = 511; SetDefined(true); } /* 2.1.10 ~IsFull~ This function checks whether all intersections are set to be non-empty. For an undefined isnatnce the result will be __false__. */ bool IsFull(){ return IsDefined() && (value==511); } /* 2.1.10 ~IsEmpty~ This function checks if all matrix entries are set to be empty. */ bool IsEmpty(){ return IsDefined() && (value==0); } /* 2.1.11 Set Function This function sets all matrix entries to the given values. */ void Set( const bool II, const bool IB, const bool IE, const bool BI, const bool BB, const bool BE, const bool EI, const bool EB, const bool EE); /* 2.1.12 Further Set functions The next nine functions can be used to set a single entry in the matrix to a specified value. */ void SetII(const bool v){ if(v) value = value | II; else value = value & (511 - II); } void SetIB(const bool v){ if(v) value = value | IB; else value = value & (511 - IB); } void SetIE(const bool v){ if(v) value = value | IE; else value = value & (511 - IE); } void SetBI(const bool v){ if(v) value = value | BI; else value = value & (511 - BI); } void SetBB(const bool v){ if(v) value = value | BB; else value = value & (511 - BB); } void SetBE(const bool v){ if(v) value = value | BE; else value = value & (511 - BE); } void SetEI(const bool v){ if(v) value = value | EI; else value = value & (511 - EI); } void SetEB(const bool v){ if(v) value = value | EB; else value = value & (511 - EB); } void SetEE(const bool v){ if(v) value = value | EE; else value = value & (511 - EE); } /* 2.1.13 Get Functions Aided by the next nine functions, the matrix entries of this matrix can be received. */ bool GetII()const {return II & value; } bool GetIB()const {return IB & value; } bool GetIE()const {return IE & value; } bool GetBI()const {return BI & value; } bool GetBB()const {return BB & value; } bool GetBE()const {return BE & value; } bool GetEI()const {return EI & value; } bool GetEB()const {return EB & value; } bool GetEE()const {return EE & value; } /* 2.1.14 Transpose This function computes the transpose of this matrix. This can be used to detect symmetries between matrices. */ void Transpose(); /* 2.1.15 Destroy This function is needed for using this class as an Attribute. */ void Destroy(); /* 2.1.16 ToListExpr This function computes the ListRepresentation of this matrix. The ListRepresentation is a list containing 9 boolean elements describing the value of the matrix entries. */ ListExpr ToListExpr(const ListExpr typeInfo)const ; /* 2.1.17 ReadFrom Function This function reads the value of this matrix from LE. If LE don't represent a valid representation of a 9 intersection matrix, the value of this matrix remains unchanged and the result is false. Otherwise, the value is changed corresponding to the nested list representation and the return value is true. Allowed formats are: * a single int atom holding a value between 0 and 511 representing a matrix number * a list consisting of nine boolean values representing the matrix entries. */ bool ReadFrom(const ListExpr LE, const ListExpr typeInfo); /* 2.1.18 Equalize functions When calling one of the next functions, the values of this matrix are taken from the argument. */ void Equalize(const Int9M& value); void Equalize(const Int9M* value); /* 2.1.19 ToString function This function returns a string representation of this matrix. */ std::string ToString() const; /* 2.1.19 Further functions The following functions are needed for using this type as an attribute type within secondo relations. */ int Compare(const Attribute* arg) const; bool Adjacent(const Attribute*) const {return false;} size_t HashValue() const; void CopyFrom(const Attribute* arg); Int9M* Clone() const; size_t Sizeof() const { return sizeof(*this); } /* 2.1.20 Print function */ virtual std::ostream& Print( std::ostream& os ) const; /* 2.1.21 CompareTo function */ int CompareTo(const Int9M& M2) const{ if(!IsDefined() && !M2.IsDefined()){ return 0; } if(!IsDefined()) return -1; if(!M2.IsDefined()) return 1; if(value>M2.value) return 1; if(value DATA", BasicType(), "(ii ib ie bi bb be ei eb ee)", "(TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE)"); } static bool CheckKind(ListExpr type, ListExpr& errorInfo){ return nl->IsEqual(type,BasicType()); } private: // we use the appropriate bits of this value for the different // entries in the matrix uint16_t value; }; /* 2.2 The Type Cluster A cluster is a set of 9-intersection matrices implemented by the Int9M type. Because only 512 of such matrices exist, we can realize this type by a bitvector containing 512 elements. A "1" of a specific position means that the matrix with the appropriate number is contained in this cluster. */ class Cluster: public Attribute{ public: /* 2.2.1 Constructor This standard constructor should only be used in the cast function. */ Cluster(){} Cluster(int dummy) : Attribute(true), boxchecks(0), boxchecksT(0), boxchecksok(false){ memcpy(BitVector,getEmptyBlock(),64); memcpy(BitVectorT,getEmptyBlock(),64); memset(name,'\0',MAX_STRINGSIZE + 1); strcpy(name,"empty"); updateBoxChecks(); } /* 2.2.2 Constructor This constructor creates an empty cluster. The argument is only used for making this constructor different to the standard constructor and is ignored. */ Cluster(const bool all, const bool updateBC = true) : Attribute(true), boxchecks(0), boxchecksT(0), boxchecksok(false) { //for(int i=0;i<64;i++) // BitVector[i]=0; memset(name,'\0',MAX_STRINGSIZE + 1 ); if(all){ memset(BitVector,(unsigned char) 255, 64); memset(BitVectorT,(unsigned char) 255, 64); strcpy(name,"empty"); } else { memset(BitVector,(unsigned char) 0, 64); memset(BitVectorT,(unsigned char) 0, 64); strcpy(name,"complete"); } if(updateBC){ updateBoxChecks(); } else { boxchecksok = false; boxchecks=false; boxchecksT = false; } } /* 2.2.3 Copy Constructor */ Cluster(const Cluster& source) : Attribute(true){ Equalize(source); } Cluster(const Cluster* source): Attribute(true){ Equalize(source); } /* 2.2.3 Destructor */ ~Cluster(){} /* 2.2.4 SetName This function sets a new name for this cluster. */ void SetName(const STRING_T* newname){ strcpy(name,(char*)newname); } void SetName(const std::string& newname){ std::string s; if(newname.length()>MAX_STRINGSIZE){ s = newname.substr(0,MAX_STRINGSIZE); } else { s = newname; } strcpy(name,s.c_str()); } /* 2.2.5 Transpose This function transposes all contained matrices in this cluster. This can be used for easy defining of symmetrical clusters, e.g. Contains.Transpose().SetName("CoveredBy"); */ void Transpose(const bool updateBC = true); /* 2.2.6 Disjoint This function checks whether this cluster and the argument has no common matrices. */ bool Disjoint(const Cluster* C2) const{ for(int i=0;i<64;i++) if(BitVector[i] & C2->BitVector[i]) return false; return true; } /* 2.2.7 Contains This function checks whether all matrices contained in the argument are also contained in this cluster. Note that for equal clusters the result will be true. */ bool Contains(const Cluster* C2)const{ for(int i=0;i<64;i++) if((BitVector[i] | C2->BitVector[i]) > BitVector[i]) return false; return true; } /* 2.2.8 Contains This function checks whether the argument is part of this cluster. */ bool Contains(const Int9M M) const; /* 2.2.9 Union This implements the familiar union function for the matrix sets. */ void Union(const Cluster* C2, const bool updateBC=true){ for(int i=0;i<64;i++){ BitVector[i] |= C2->BitVector[i]; BitVectorT[i] |= C2->BitVectorT[i]; } if(updateBC){ updateBoxChecks(); } } /* 2.2.10 Intersection This function computes the intersection of this cluster and the argument. */ void Intersection(const Cluster* C2, const bool updateBC = true){ for(int i=0;i<64;i++){ BitVector[i] &= C2->BitVector[i]; BitVectorT[i] &= C2->BitVectorT[i]; } if(updateBC){ updateBoxChecks(); } } /* 2.2.10 Intersects A call of this function yields true if this cluster and C2 have common elements. */ bool Intersects(const Cluster* C2) const{ for(int i=0;i<64;i++){ if( BitVector[i] & C2->BitVector[i]){ return true; } } return false; } /* 2.2.11 Minus ~Minus~ removes all matrices contained in C2 from this cluster. */ void Minus(const Cluster* C2, const bool updateBC = true){ for(int i=0;i<64;i++){ BitVector[i] = (BitVector[i] & ( ~(C2->BitVector[i]))); BitVectorT[i] = (BitVectorT[i] & ( ~(C2->BitVectorT[i]))); } if(updateBC){ updateBoxChecks(); } } /* 2.2.12 Invert The ~Invert~ function changes this cluster containing all possible matrices minus the matrices conatained originally in it. */ void Invert(const bool updateBC = true){ for(int i=0;i<64;i++){ BitVector[i] ^= 255; BitVectorT[i] ^= 255; } if(updateBC){ updateBoxChecks(); } } /* 2.2.13 MakeEmpty This function removes all matrices from this cluster. */ void MakeEmpty(const bool updateBC = true){ //for(int i=0;i<64;i++) // BitVector[i] = 0; memcpy(BitVector,getEmptyBlock(),64); memcpy(BitVectorT,getEmptyBlock(),64); if(updateBC) { updateBoxChecks(); } } /* 2.2.14 MakeFull The MakeFull function changes this cluster to contain all 512 possible matrices. */ void MakeFull(const bool updateBC = true){ //for(int i=0;i<64;i++) // BitVector[i] = 255; memcpy(BitVector,getFullBlock(),64); memcpy(BitVectorT,getFullBlock(),64); if(updateBC){ updateBoxChecks(); } } /* 2.2.15 IsEmpty This function checks whether this cluster is empty. */ bool IsEmpty() const{ return (memcmp(BitVector,getEmptyBlock(),64)==0); } /* 2.2.16 IsComplete This function returns true if this cluster contains all 512 possible matrices. */ bool IsComplete() const{ return (memcmp(BitVector,getFullBlock(),64)==0); } /* 2.2.15 Size The Size function counts the matrices contained in this cluster. */ unsigned int Size()const{ unsigned int c=0; for(int i=0; i< 64 ; i++){ for(unsigned int pos=1; pos<256;pos = 2*pos){ if(BitVector[i] & pos & 255) c++; } } return c; } /* 2.5.16 ToListExpr This function returns the nested list representation of this cluster. The format of the nested list is a list contaning a string representing the name of the cluster followed by a set of matrix numbers. */ ListExpr ToListExpr(const ListExpr typeInfo)const; /* 2.5.17 ReadFrom This function reads the value of this cluster from the nested list given as argument. If the nested list don't represent a valid cluster, this cluster is not changed and the result will be false. Otherwise the cluster takes its value from the nested list and true is returned. Allowed formats are: 1) (Name $n_1$ ... $n_n$) Where name is a string representing the name of this matrix and $n_1$ .. $n_n$ are the numbers of the contained matrices. 2) (Name (...) (...) (...)) Where Name is as before and the next elements are valid representations of the contained matrices. 3) (Name Conditions) This can be used for defining a cluster of a logical level. The name describes the name of this cluster and Condition is a string (or a text) describing the cluster. In the conditions, boolean constants (true,false), boolean operators (and, or, not, [=>] [<=>] ) and variables (ii, ib, ie, bi, bb, be, ei, eb, ee) representing the matrix entries are allowed. All matrices fulfilling the condition will be element of this cluster. For example, we can define a contains cluster by the following command: [21] let contains = [const cluster value ("contains" ii and ie and not ei and not bb )] Instead of writing ''and'', ''or'', ''not'', we can also use the abbreviations ''[&]'', ''[|]'', ''!''. */ bool ReadFrom(const ListExpr LE,const ListExpr); /* 2.2.15 Equalize functions If one of these functions is called, the value of this cluster is taken from the argument. */ void Equalize(const Cluster& value); void Equalize(const Cluster* value); /* 2.2.16 ToString function */ std::string ToString() const; /* 2.2.16 Compare Function This function compares this with the argument. */ int CompareTo(const Cluster* C2) const; /* 2.2.17 Functions supporting the attribute property of this class The following functions are required to make it possible that a cluster acts as an attribute type within relations. */ int Compare(const Attribute* arg) const{ return CompareTo((Cluster*) arg); } /* returns false in each case */ bool Adjacent(const Attribute*) const; /* computes a hashvalue for this cluster */ size_t HashValue() const; /* reads the value of this cluster from arg */ void CopyFrom(const Attribute* arg); /* returns a copy of this cluster */ Cluster* Clone() const; size_t Sizeof() const { return sizeof(*this); } /* 2.2.18 ValueAt This function returns true iff the matrix with number pos is part of this cluster. */ bool ValueAt(const int pos) const; /* 2.2.19 SetValueAt This function sets the containment of the matrix with number pos to the given value. */ void SetValueAt(const int pos,const bool value, const bool updateBC=true); /* 2.2.20 GetName This function returns the name of this cluster. */ void GetName(STRING_T& res) const { if(IsDefined()){ strcpy(res, name); } else { strcpy(res, "undefined"); } } /* 2.2.21 GetName Return the name of this cluster as a string. */ std::string GetName() const{ STRING_T s; GetName(s); std::string res(s); return res; } /* 2.2.21 Restrict This functions changes a cluster in this way that it will contain only such matrices which are part of the original cluster and fulfill the condition given as the argument. If the given string does not represent a valid formula, the result will be false and the cluster is not changed. */ bool Restrict(std::string condition, const bool updateBC = true); virtual void Restrict(const std::vector >& interval){ Attribute::Restrict(interval); } /* 2.2.22 Relax This function extends the cluster to all matrices which are already part of the cluster or fulfill the given condition. The return value represents the correctness of the formula describing the condition. */ bool Relax(std::string condition, const bool updateBC = true); /* 2.2.23 Restrict This version of restrict, removes all matrixes from the cluster where at the position given by the first parameter is a different value to the second parameter. This result of this function is the same as an intersection with a cluster containing all matrices with the pecified value at the given position - but this version is faster. */ void Restrict(const int pos, const bool value, const bool updateBC = true); /* 2.2.24 Restrict Removes all matrices from this cluster whith different entries than the Int9M value provided as the first argument at the positions specified by the boolean parameter. */ void Restrict(const Int9M& m, const bool value, const bool updateBC=true); /* 2.2.25 IsExtension This function checks whether all extensions of __m__, i.e. all matrices which can derived from __m__ by setting additional intersections are part of this cluster. */ bool isExtension(const Int9M& m) const; /* 2.2.26 CheckBoxes This function works as prefilter for bounding box and empty checks. The function has the follwing return values: * 1 : from the arguments we can derive that the cluster will contain the 9 intersection matrix * 2 : from the arguments we can derive that the cluster will not contain the 9 intersection matrix * 3 : from the arguments we cannot derive a result */ int checkBoxes( const Rectangle<2>& box1, const bool empty1, const Rectangle<2>& box2, const bool empty2) const; /* 2.2.21 Operators The following operators can be used for easy comparisons between clusters. */ bool operator<(const Cluster C2)const; bool operator==(const Cluster& C2)const; bool operator!=(const Cluster& C2) const{ return !operator==(C2); } bool operator>(const Cluster C2)const; Cluster& operator=(const Cluster& arg){ Equalize(arg); return (*this); } void updateBoxChecks(); static const std::string BasicType(){ return "cluster"; } static const bool checkType(const ListExpr type){ return listutils::isSymbol(type, BasicType()); } static ListExpr Property(){ return gentc::GenProperty("-> DATA", BasicType(), "(\"name \" (m1, m2 , ...))", "(\"bothempty\" (1))"); } static bool CheckKind(ListExpr type, ListExpr& errorInfo){ return nl->IsEqual(type,BasicType()); } private: unsigned char BitVector[64]; // the set of matrices unsigned char BitVectorT[64]; // set of transposed matrices STRING_T name; int boxchecks; // coded information about this cluster int boxchecksT; // information baout the transposed array bool boxchecksok; void SetValueAt(const int pos, const bool value, unsigned char bitvector[], unsigned char bitvectorT[]) const; static void Transpose(unsigned char Source[64], unsigned char Target[64]); static bool ValueAt(const int pos, const unsigned char BitVector[64]); static void updateBoxChecks(const unsigned char bitvector[], int& boxchecks); }; /* 2.3 The Type PredicateGroup A PredicateGroup is a set of disjoint clusters. Aided by this type we can decide, what the cluster for a given 9Int-Matrix is. A predicategroup contains an additional cluster with the name 'unspecified' containing all matrices not included in the other clusters. For this reason, no cluster with the name 'unspecified' can be included manually. */ class PredicateGroup: public Attribute{ public: /* 2.3.1 The Standardconstructor */ PredicateGroup(){} /* 2.3.2 Constructor This constructor creates an empty predicate group with the given capacity for clusters. In this context, 'empty' means, that this predicate group contains a single cluster named ''unspecified'' containing all 512 9-intersection matrices. */ PredicateGroup(int size); /* 2.3.3 Copy Constructor */ PredicateGroup(const PredicateGroup& source): Attribute(source.IsDefined()), theClusters(source.Size()-1){ Equalize(source); } /* 2.3.4 Assignment Operator */ PredicateGroup& operator=(const PredicateGroup& source){ Equalize(source); return (*this); } /* 2.3.3. Destructor This destructor destroys the contained FLOB if canDelete is set to true. */ ~PredicateGroup(){ if(canDelete){ theClusters.Destroy(); } } /* 2.3.4 Equalize functions When one of the next functions is called, the value of this predicate cluster will be the same like this one of the argument. */ void Equalize(const PredicateGroup* PC); void Equalize(const PredicateGroup& PC){ Equalize(&PC); } /* 2.3.4 Check for equality */ bool operator==(const PredicateGroup& p2) const; bool operator!=(const PredicateGroup& p2) const{ return !operator==(p2); } /* 2.3.5 ToString */ std::string ToString() const; /* 2.3.4 Functions for acting as an attribute type */ size_t HashValue() const{ return unSpecified.HashValue(); } void CopyFrom(const Attribute* right){ Equalize((PredicateGroup*) right); } int Compare(const Attribute * arg) const; bool Adjacent(const Attribute * arg) const{ return false; } PredicateGroup* Clone() const{ PredicateGroup* res = new PredicateGroup(1); res->Equalize(this); return res; } size_t Sizeof() const{ return sizeof(*this); } int NumOfFLOBs() const{ return 1; } virtual Flob* GetFLOB( const int i ){ assert(i==0); return &theClusters; } /* 2.3.5 The Size function This function returns the number of contained clusters. Note that the unspecified cluster is also counted by this function. */ unsigned int Size() const{ return theClusters.Size()+1; } /* 2.3.6 The ~IsComplete~ function This function returns true if all possible matrices are contained in named clusters. */ bool IsComplete()const { return unSpecified.IsEmpty(); } /* 2.3.6 The ~IsEmpty~ function This function returns true if no cluster is contained in this predicategroup. */ bool IsEmpty(){ return unSpecified.IsComplete(); } /* 2.3.7 GetUnspecified This function returns the cluster representing all non-covered matrices. */ Cluster GetUnspecified(){ return unSpecified; } /* 2.3.6 ToListExpr This function computes the nested list representaton of this predicate cluster. */ ListExpr ToListExpr(const ListExpr typeInfo); /* 2.3.7 ReadFrom This function reads the value of this predicate group from it's nested list representation. If the list don't represent a valid value, false is returned. Otherwise, this value is changed and the result is true. A predicate group representation is just a set of clusters. All contained clusters must be disjoint. This means all cluster names must be different and the matrix sets can't have any common matrices. */ bool ReadFrom(const ListExpr instance, const ListExpr typeInfo); /* 2.3.8 MakeEmpty The ~MakeEmpty~ function removes all clusters from this cluster predicate. Only the ''unspecified'' cluster will remain in this cluster predicate. This cluster will contain all 512 possible matrices. */ void MakeEmpty(){ unSpecified.MakeFull(); theClusters.clean(); SetDefined(true); sorted=true; } /* 2.3.9 Add This function add a cluster to this cluster predicate. The new cluster can't have any common matrix with an existing cluster and the name must be different to all names of contained clusters. */ bool Add(Cluster* C); /* 2.3.9 AddWithPriority This function add a cluster to this cluster predicate. Existing clusters will have a higher priority as the new cluster C. This means, that all matrices contained in present clusters are removed from C before inserting it. */ bool AddWithPriority(const Cluster * C); /* 2.3.10 GetNameOf This function searchs for the cluster containing the given matrix and returns its name. The search is realized by scanning the whole FLOB. For this reason, this function has linear runtime. This is acceptable because at most 512 non-overlapping clusters can exist within a single predicategroup. Note that this function creates a new STRING object. The caller of this function has to destroy this object to avoid memory holes. */ void GetNameOf(Int9M* Matrix, STRING_T& res) { if(unSpecified.Contains(*Matrix)){ unSpecified.GetName(res); return; } int s = theClusters.Size(); Cluster C; for(int i=0;i DATA", BasicType(), "(c1 c2 c2)", "(....)"); } static bool CheckKind(ListExpr type, ListExpr& errorInfo){ return nl->IsEqual(type,BasicType()); } void Destroy(){ canDelete = true; } std::vector getNames() const{ std::vector res; res.push_back(unSpecified.GetName()); Cluster c; for(int i=0;i= 0); if(index == 0){ result.Equalize(unSpecified); return; } int index2 = index -1; assert(index2 < theClusters.Size()); theClusters.Get(index2, result); } private: mutable DbArray theClusters; bool canDelete; mutable bool sorted; Cluster unSpecified; // Cluster containing all non-used matrices }; } // namespace toprel std::ostream& operator<<(std::ostream& o, const toprel::Int9M& p); std::ostream& operator<<(std::ostream& o, const toprel::Cluster& c); std::ostream& operator<<(std::ostream& o, const toprel::PredicateGroup& p); #endif