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 #ifndef DOXYGEN
00038 #include "variable.h"
00039 #endif
00040 
00041 #ifndef _cvcl__include__clause_h_
00042 #define _cvcl__include__clause_h_
00043 
00044 namespace CVCL {
00045 
00046   class Clause;
00047   class ClauseOwner;
00048   class TheoryCore;
00049 
00050   class ClauseValue {
00051     friend class Clause;
00052   private:
00053 
00054     int d_refcount;
00055 
00056     int d_refcountOwner;
00057     
00058     Theorem d_thm;
00059     
00060     int d_scope;
00061     
00062     
00063     std::vector<Literal> d_literals;
00064     
00065     ClauseValue(const ClauseValue& c); 
00066     ClauseValue& operator=(const ClauseValue& c) { return *this; }
00067     
00068     
00069     size_t d_wp[2];
00070     
00071     
00072     
00073     int d_dir[2];
00074     
00075     CDO<bool> d_sat;
00076     
00077     bool d_deleted;
00078     
00079     IF_DEBUG(std::string d_file; int d_line);
00080     
00081     
00082     ClauseValue(TheoryCore* core, VariableManager* vm,
00083                 const Theorem& clause, int scope);
00084   public:
00085     
00086     ~ClauseValue();
00087       
00088   }; 
00089 
00090 
00091   class Clause {
00092   private:
00093     friend class ClauseOwner;
00094 
00095     ClauseValue* d_clause;
00096 
00097     int& countOwner() {
00098       DebugAssert(d_clause != NULL, "");
00099       return d_clause->d_refcountOwner;
00100     }
00101   public:
00102     Clause(): d_clause(NULL) { }
00103     
00104     Clause(TheoryCore* core, VariableManager* vm, const Theorem& clause,
00105            int scope, const std::string& file = "", int line = 0)
00106       : d_clause(new ClauseValue(core, vm, clause, scope)) {
00107       d_clause->d_refcount++;
00108       IF_DEBUG(d_clause->d_file = file; d_clause->d_line=line);
00109     }
00110     
00111     Clause(const Clause& c): d_clause(c.d_clause) {
00112       if(d_clause != NULL) d_clause->d_refcount++;
00113     }
00114     
00115     ~Clause();
00116     
00117     Clause& operator=(const Clause& c);
00118 
00119     bool isNull() const { return d_clause == NULL; }
00120     
00121     size_t size() const {
00122       return (d_clause == NULL)? 0 : d_clause->d_literals.size();
00123     }
00124     
00125     const Theorem& getTheorem() const {
00126       DebugAssert(!isNull(), "Clause::getTheorem(): Null Clause");
00127       return d_clause->d_thm;
00128     }
00129     
00130     int getScope() const {
00131       if(isNull()) return 0;
00132       else return d_clause->d_scope;
00133     }
00134     
00135     const Literal& getLiteral(size_t i) const {
00136       DebugAssert(!isNull(), "Clause::getLiteral(): Null Clause");
00137       DebugAssert(i < size(), 
00138                   "Clause::getLiteral(" + int2string(i)
00139                   + "): i >= size = " + int2string(size()));
00140       return d_clause->d_literals[i];
00141     }
00142     
00143     const Literal& operator[](size_t i) const { return getLiteral(i); }
00144 
00145     
00146     const std::vector<Literal>& getLiterals() const {
00147       DebugAssert(!isNull(), "Clause::getLiterals(): Null Clause");
00148       return d_clause->d_literals;
00149     }
00150     
00151     size_t wp(int i) const {
00152       DebugAssert(!isNull(), "Clause::wp(i): Null Clause");
00153       DebugAssert(i==0 || i==1, 
00154                   "wp(i): Watch pointer index is out of bounds: i = "
00155                   + int2string(i));
00156       return d_clause->d_wp[i];
00157     }
00158     
00159     const Literal& watched(int i) const { return getLiteral(wp(i)); }
00160     
00161     size_t wp(int i, size_t l) const {
00162       DebugAssert(!isNull(), "Clause::wp(i,l): Null Clause");
00163       DebugAssert(i==0 || i==1, 
00164                   "wp(i,l): Watch pointer index is out of bounds: i = "
00165                   + int2string(i));
00166       DebugAssert(l < size(), "Clause::wp(i = " + int2string(i)
00167                   + ", l = " + int2string(l)
00168                   + "): l >= size() = " + int2string(size()));
00169       TRACE("clauses", " **clauses** UPDATE wp(idx="
00170             +int2string(i)+", l="+int2string(l),
00171             ")\n  clause #: ", id());
00172       d_clause->d_wp[i] = l;
00173       return l;
00174     }
00175     
00176     int dir(int i) const {
00177       DebugAssert(!isNull(), "Clause::dir(i): Null Clause");
00178       DebugAssert(i==0 || i==1, 
00179                   "dir(i): Watch pointer index is out of bounds: i = "
00180                   + int2string(i));
00181       return d_clause->d_dir[i];
00182     }
00183     
00184     int dir(int i, int d) const {
00185       DebugAssert(!isNull(), "Clause::dir(i,d): Null Clause");
00186       DebugAssert(i==0 || i==1, 
00187                   "dir(i="+int2string(i)+",d="+int2string(d)
00188                   +"): Watch pointer index is out of bounds");
00189       DebugAssert(d==1 || d==-1, "dir(i="+int2string(i)+",d="+int2string(d)
00190                   +"): Direction is out of bounds");
00191       d_clause->d_dir[i] = d;
00192       return d;
00193     }
00194 
00195     bool sat() const {
00196       DebugAssert(!isNull(), "Clause::sat()");
00197       return d_clause->d_sat;
00198     }
00199 
00200     bool sat(bool ignored) const {
00201       DebugAssert(!isNull(), "Clause::sat()");
00202       bool flag = false;
00203       if (!d_clause->d_sat) {
00204         for (size_t i = 0; !flag && i < d_clause->d_literals.size(); ++i)
00205           if (d_clause->d_literals[i].getValue() == 1)
00206             flag = true;
00207       }
00208       if (flag) {
00209         
00210         markSat();
00211       }
00212       return d_clause->d_sat;
00213     }
00214     
00215     void markSat() const {
00216       DebugAssert(!isNull(), "Clause::markSat()");
00217       d_clause->d_sat = true;
00218     }
00219     
00220     bool deleted() const {
00221       DebugAssert(!isNull(), "Clause::deleted()");
00222       return d_clause->d_deleted;
00223     }
00224     void markDeleted() const;
00225 
00226     
00227     size_t id() const { return (size_t) d_clause; }
00228 
00229     
00230     bool operator==(const Clause& c) const { return d_clause == c.d_clause; }
00231 
00232 
00233     int owners() const { return d_clause->d_refcountOwner; }
00234     
00235     
00236     std::string toString() const;
00237 
00238     friend std::ostream& operator<<(std::ostream& os, const Clause& c);
00239 
00240     IF_DEBUG(bool wpCheck() const);
00241     IF_DEBUG(const std::string& getFile() const { return d_clause->d_file; })
00242     IF_DEBUG(int getLine() const { return d_clause->d_line; })
00243 
00244   }; 
00245 
00246 
00247 
00248 
00249 
00250   class ClauseOwner {
00251     Clause d_clause;
00252 
00253     ClauseOwner() { }
00254   public:
00255 
00256     ClauseOwner(const Clause& c): d_clause(c) { d_clause.countOwner()++; }
00257 
00258     ClauseOwner(TheoryCore* core, VariableManager* vm, const Theorem& clause,
00259                 int scope): d_clause(core, vm, clause, scope) {
00260       d_clause.countOwner()++;
00261     }
00262 
00263     ClauseOwner(const ClauseOwner& c): d_clause(c.d_clause) {
00264       d_clause.countOwner()++;
00265     }
00266 
00267     ClauseOwner& operator=(const ClauseOwner& c) {
00268       if(&c == this) return *this; 
00269       DebugAssert(d_clause.countOwner() > 0, "in operator=");
00270       if(--(d_clause.countOwner()) == 0)
00271         d_clause.markDeleted();
00272       d_clause = c.d_clause;
00273       d_clause.countOwner()++;
00274       return *this;
00275     }
00276 
00277     ~ClauseOwner() {
00278       DebugAssert(d_clause.countOwner() > 0, "in ~ClauseOwner");
00279       if(--(d_clause.countOwner()) == 0) {
00280         d_clause.markDeleted();
00281       }
00282     }
00283 
00284     operator Clause& () { return d_clause; }
00285 
00286     operator const Clause& () const { return d_clause; }
00287   }; 
00288     
00289 
00290   
00291 
00292   
00293   
00294   class CompactClause {
00295   private:
00296     Clause d_clause;
00297   public:
00298     CompactClause(const Clause& c): d_clause(c) { }
00299     friend std::ostream& operator<<(std::ostream& os, const CompactClause& c);
00300     std::string toString() const;
00301   };
00302 
00303 } 
00304     
00305 #endif