00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #ifndef FUNCTION_H_JUN_26_2005
00067 #define FUNCTION_H_JUN_26_2005
00068
00069 #include <ext/hash_set>
00070 using namespace __gnu_cxx;
00071 #include "functiontemplate.h"
00072 #include "hash.h"
00073 #include "term.h"
00074
00075
00076
00077 class Function
00078 {
00079 public:
00080
00081 Function(const FunctionTemplate* const & ft)
00082 : template_(ft), terms_(new Array<Term*>), retConstId_(-1),
00083 intArrRep_(NULL), hashCode_(0), dirty_(true), parent_(NULL) {}
00084
00085
00086 Function(const FunctionTemplate* const & ft, Term* const & parent)
00087 : template_(ft), terms_(new Array<Term*>), retConstId_(-1),
00088 intArrRep_(NULL), hashCode_(0), dirty_(true), parent_(NULL) {}
00089
00090
00091 Function(const Function& f) { parent_ = NULL; copy(f); }
00092 Function(const Function& f, Term* const & parent) { parent_=parent; copy(f); }
00093
00094
00095 ~Function()
00096 {
00097 for (int i = 0; i < terms_->size(); i++)
00098 delete (*terms_)[i];
00099 delete terms_;
00100 if (intArrRep_) delete intArrRep_;
00101 }
00102
00103
00104
00105 void appendTerm(Term* const & term)
00106 {
00107 if (template_->getNumTerms() == terms_->size())
00108 {
00109 cout << "Error: In Function::appendTerm. Tried to add more terms than "
00110 << "the declared num of " << template_->getNumTerms() << endl;
00111 exit(-1);
00112 }
00113 terms_->append(term);
00114 setDirty();
00115 }
00116
00117
00118 int getNumTerms() const { return terms_->size(); }
00119
00120 const Term* getTerm(const int& idx) const { return (*terms_)[idx]; }
00121
00122 void setTemplate(FunctionTemplate* const & t) { template_ = t; }
00123
00124 const FunctionTemplate* getTemplate() const { return template_; }
00125
00126
00127 const char* getName() const { return template_->getName(); }
00128
00129 int getId() const { return template_->getId(); }
00130
00131
00132
00133 void setRetConstId(const int& constId) { retConstId_ = constId; setDirty();}
00134 int getRetConstId() const { return retConstId_; }
00135
00136 void setDirty();
00137 bool isDirty() const { return dirty_; }
00138
00139 void setParent(Term* const parent) { parent_ = parent; setDirty(); }
00140 Term* getParent() const { return parent_; }
00141
00142
00143
00144
00145
00146 const char* getTermTypeAsStr(const int& idx) const
00147 {
00148 if (idx >= template_->getNumTerms()) return NULL;
00149 return template_->getTermTypeAsStr(idx);
00150 }
00151
00152
00153 int getTermTypeAsInt(const int& idx) const
00154 {
00155 if (idx >= template_->getNumTerms()) return -1;
00156 return template_->getTermTypeAsInt(idx);
00157 }
00158
00159
00160 int getRetTypeId() const { return template_->getRetTypeId(); }
00161
00162
00163 const char* getRetTypeName() const { return template_->getRetTypeName(); }
00164
00165 bool same(const Function* const & f) const
00166 {
00167 if (this == f) return true;
00168
00169
00170 if (template_->getId() != f->getId()) return false;
00171 int numTerms = terms_->size();
00172 if (numTerms != f->getNumTerms()) return false;
00173 for (int i = 0; i < numTerms; i++)
00174 if ((*terms_)[i]->getId() != f->getTerm(i)->getId()) return false;
00175 return true;
00176 }
00177
00178
00179
00180 void appendIntArrRep(Array<int>& rep)
00181 {
00182 if (dirty_) computeAndStoreIntArrRep();
00183 rep.append(*intArrRep_);
00184 }
00185
00186
00187 size_t hashCode()
00188 {
00189 if (dirty_) computeAndStoreIntArrRep();
00190 return hashCode_;
00191 }
00192
00193
00194 bool same(Function* const & f)
00195 {
00196 if (this==f) return true;
00197 const Array<int>* fArr = f->getIntArrRep();
00198 const Array<int>* myArr = getIntArrRep();
00199 if (myArr->size() != fArr->size()) return false;
00200 const int* fItems = f->getIntArrRep()->getItems();
00201 const int* myItems = getIntArrRep()->getItems();
00202 return (memcmp(myItems, fItems, myArr->size()*sizeof(int))==0);
00203 }
00204
00205
00206 ostream& printAsInt(ostream& out) const
00207 {
00208 out << template_->getId() << "(";
00209 for (int i = 0; i < terms_->size(); i++)
00210 {
00211 (*terms_)[i]->printAsInt(out);
00212 out << ((i!=terms_->size()-1)?",":")");
00213 }
00214 return out;
00215 }
00216
00217
00218 ostream& printAsIntWithRetConstId(ostream& out) const
00219 {
00220 printAsInt(out);
00221 out << "=" << retConstId_ << endl;
00222 return out;
00223 }
00224
00225
00226 ostream& print(ostream& out, const Domain* const & domain) const
00227 {
00228 out << template_->getName() << "(";
00229 for (int i = 0; i < terms_->size(); i++)
00230 {
00231 (*terms_)[i]->print(out, domain);
00232 out << ((i!=terms_->size()-1)?",":")");
00233 }
00234 return out;
00235 }
00236
00237
00238 ostream&
00239 printWithRetConstName(ostream& out, const Domain* const & domain) const;
00240
00241
00242 private:
00243 void copy(const Function& f)
00244 {
00245 template_ = f.template_;
00246
00247 terms_ = new Array<Term*>;
00248 Array<Term*>* fterms = f.terms_;
00249 for (int i = 0; i < fterms->size(); i++)
00250 {
00251 Term* t = (*fterms)[i];
00252 terms_->append(new Term(*t, (void*)this, false));
00253 }
00254 dirty_ = f.dirty_;
00255
00256 if (!dirty_) { assert(noDirtyTerms()); }
00257
00258 retConstId_ = f.retConstId_;
00259
00260 if (f.intArrRep_) intArrRep_ = new Array<int>(*(f.intArrRep_));
00261 else intArrRep_ = NULL;
00262
00263 hashCode_ = f.hashCode_;
00264
00265 if (parent_) parent_->setDirty();
00266 }
00267
00268
00269 bool noDirtyTerms()
00270 {
00271 for (int i = 0; i < terms_->size(); i++)
00272 if ((*terms_)[i]->isDirty()) return false;
00273 return true;
00274 }
00275
00276
00277 const Array<int>* getIntArrRep()
00278 { if (dirty_) computeAndStoreIntArrRep(); return intArrRep_; }
00279
00280
00281 void computeAndStoreIntArrRep()
00282 {
00283
00284 dirty_ = false;
00285 if (intArrRep_ == NULL) intArrRep_ = new Array<int>;
00286 else intArrRep_->clear();
00287 intArrRep_->append(template_->getId());
00288
00289 int numTerms = terms_->size();
00290 for (int i = 0; i < numTerms; i++)
00291 (*terms_)[i]->appendIntArrRep(*intArrRep_);
00292
00293 intArrRep_->compress();
00294 hashCode_ = Hash::hash(*intArrRep_);
00295 }
00296
00297
00298 private:
00299 const FunctionTemplate* template_;
00300 Array<Term*>* terms_;
00301 int retConstId_;
00302 Array<int>* intArrRep_;
00303 size_t hashCode_;
00304 bool dirty_;
00305 Term* parent_;
00306 };
00307
00308 inline
00309 ostream& operator<<(ostream& out, const Function& f) {return f.printAsInt(out);}
00310
00311
00313
00314 class HashFunction
00315 {
00316 public:
00317 size_t operator()(Function* const & f) const { return f->hashCode(); }
00318 };
00319
00320
00321 class EqualFunction
00322 {
00323 public:
00324 bool operator()(const Function* const & f1, const Function* const & f2) const
00325 { return f1->same(f2); }
00326 };
00327
00328
00330
00331 typedef hash_set<Function*, HashFunction, EqualFunction> FunctionSet;
00332
00333
00334 #endif