variable.h

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file variable.h
00004  * 
00005  * Author: Sergey Berezin
00006  * 
00007  * Created: Fri Apr 25 11:52:17 2003
00008  *
00009  * <hr>
00010  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00011  * Junior University and by New York University. 
00012  *
00013  * License to use, copy, modify, sell and/or distribute this software
00014  * and its documentation for any purpose is hereby granted without
00015  * royalty, subject to the terms and conditions defined in the \ref
00016  * LICENSE file provided with this distribution.  In particular:
00017  *
00018  * - The above copyright notice and this permission notice must appear
00019  * in all copies of the software and related documentation.
00020  *
00021  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00022  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00023  * 
00024  * <hr>
00025  * 
00026  * A data structure representing a variable in the search engine.  It
00027  * is a smart pointer with a uniquifying mechanism similar to Expr,
00028  * and a variable is uniquely determined by its expression.  It can be
00029  * thought of as an Expr with additional attributes, but the type is
00030  * different, so it will not be confused with other Exprs.
00031  */
00032 /*****************************************************************************/
00033 
00034 #ifndef _CVC_lite__variable_h_
00035 #define _CVC_lite__variable_h_
00036 
00037 #include "expr.h"
00038 
00039 namespace CVCL {
00040 
00041   class VariableManager;
00042   class VariableValue;
00043   class Clause;
00044   class SearchEngineRules;
00045 
00046   // The main "smart pointer" class
00047   class Variable {
00048   private:
00049     VariableValue* d_val;
00050     // Private methods
00051     Theorem deriveThmRec(bool checkAssump) const;
00052   public:
00053     // Default constructor
00054     Variable(): d_val(NULL) { }
00055     // Constructor from an Expr; if such variable already exists, it
00056     // will be found and used.
00057     Variable(VariableManager* vm, const Expr& e);
00058     // Copy constructor
00059     Variable(const Variable& l);
00060     // Destructor
00061     ~Variable();
00062     // Assignment
00063     Variable& operator=(const Variable& l);
00064 
00065     bool isNull() const { return d_val == NULL; }
00066 
00067     // Accessors
00068 
00069     // Expr is the only constant attribute of a variable; other
00070     // attributes can be changed.
00071     const Expr& getExpr() const;
00072     // The Expr of the inverse of the variable.  This function is
00073     // caching, so !e is only constructed once.
00074     const Expr& getNegExpr() const;
00075     
00076     // IMPORTANT: Value can be -1 (false), 1 (true), or 0 (unresolved)
00077     int getValue() const;
00078     // If the value is set, scope level and either a theorem or
00079     // an antecedent clause must be defined
00080     int getScope() const;
00081     const Theorem& getTheorem() const;
00082     const Clause& getAntecedent() const;
00083     // Index of this variable in the antecedent clause; if it is -1,
00084     // the variable is FALSE, and that clause caused the contradiction
00085     int getAntecedentIdx() const;
00086     // Theorem of the form l |- l produced by the 'assump' rule, if
00087     // this variable is a splitter, or a new intermediate assumption
00088     // is generated for it.
00089     const Theorem& getAssumpThm() const;
00090     // Setting the attributes: it can be either derived from the
00091     // antecedent clause, or by a theorem.  The scope level is set to
00092     // the current scope.
00093     void setValue(int val, const Clause& c, int idx);
00094     // The theorem's expr must be the same as the variable's expr or
00095     // its negation, and the scope is the lowest scope where all
00096     // assumptions of the theorem are true
00097     void setValue(const Theorem& thm);
00098     void setValue(const Theorem& thm, int scope);
00099     
00100     void setAssumpThm(const Theorem& a, int scope);
00101     // Derive the theorem for either the variable or its negation.  If
00102     // the value is set by a theorem, that theorem is returned;
00103     // otherwise a unit propagation rule is applied to the antecedent
00104     // clause.
00105     Theorem deriveTheorem() const;
00106 
00107     // Accessing Chaff counters (read and modified by reference)
00108     unsigned& count(bool neg);
00109     unsigned& countPrev(bool neg);
00110     int& score(bool neg);
00111     bool& added(bool neg);
00112     // Read-only versions
00113     unsigned count(bool neg) const;
00114     unsigned countPrev(bool neg) const;
00115     int score(bool neg) const;
00116     bool added(bool neg) const;
00117     // Watch pointer access
00118     std::vector<std::pair<Clause, int> >& wp(bool neg) const;
00119     // Friend methods
00120     friend bool operator==(const Variable& l1, const Variable& l2) {
00121       return l1.d_val == l2.d_val;
00122     }
00123     // Printing
00124     friend std::ostream& operator<<(std::ostream& os, const Variable& l);
00125     std::string toString() const;
00126   }; // end of class Variable
00127 
00128   class Literal {
00129   private:
00130     Variable d_var;
00131     bool d_negative;
00132   public:
00133     // Constructors: from a variable
00134     Literal(const Variable& v, bool positive = true)
00135       : d_var(v), d_negative(!positive) { }
00136     // Default constructor
00137     Literal(): d_negative(false) { }
00138     // from Expr: if e == !e', construct negative literal of e',
00139     // otherwise positive of e
00140     Literal(VariableManager* vm, const Expr& e)
00141       : d_var(vm, (e.isNot())? e[0] : e), d_negative(e.isNot()) { }
00142     Variable& getVar() { return d_var; }
00143     const Variable& getVar() const { return d_var; }
00144     bool isPositive() const { return !d_negative; }
00145     bool isNegative() const { return d_negative; }
00146     bool isNull() const { return d_var.isNull(); }
00147     // Return var or !var
00148     const Expr& getExpr() const {
00149       if(d_negative) return d_var.getNegExpr();
00150       else return d_var.getExpr();
00151     }
00152     int getValue() const {
00153       if(d_negative) return -(d_var.getValue());
00154       else return d_var.getValue();
00155     }
00156     int getScope() const { return getVar().getScope(); }
00157     // Set the value of the literal
00158 //     void setValue(int val, const Clause& c, int idx) {
00159 //       d_var.setValue(d_negative? -val : val, c, idx);
00160 //     }
00161     void setValue(const Theorem& thm) {
00162       d_var.setValue(thm, thm.getScope());
00163     }
00164     void setValue(const Theorem& thm, int scope) {
00165       d_var.setValue(thm, scope);
00166     }
00167     const Theorem& getTheorem() const { return d_var.getTheorem(); }
00168 //     const Clause& getAntecedent() const { return d_var.getAntecedent(); }
00169 //     int getAntecedentIdx() const { return d_var.getAntecedentIdx(); }
00170     // Defined when the literal has a value.  Derives a theorem
00171     // proving either this literal or its inverse.
00172     Theorem deriveTheorem() const { return d_var.deriveTheorem(); }
00173     // Accessing Chaff counters (read and modified by reference)
00174     unsigned& count() { return d_var.count(d_negative); }
00175     unsigned& countPrev() { return d_var.countPrev(d_negative); }
00176     int& score() { return d_var.score(d_negative); }
00177     bool& added() { return d_var.added(d_negative); }
00178     // Read-only versions
00179     unsigned count() const { return d_var.count(d_negative); }
00180     unsigned countPrev() const { return d_var.countPrev(d_negative); }
00181     int score() const { return d_var.score(d_negative); }
00182     bool added() const { return d_var.added(d_negative); }
00183     // Watch pointer access
00184     std::vector<std::pair<Clause, int> >& wp() const
00185       { return d_var.wp(d_negative); }
00186     // Printing
00187     friend std::ostream& operator<<(std::ostream& os, const Literal& l);
00188     std::string toString() const;
00189     // Equality
00190     friend bool operator==(const Literal& l1, const Literal& l2) {
00191       return (l1.d_negative == l2.d_negative && l1.d_var==l1.d_var);
00192     }
00193   }; // end of class Literal
00194 
00195   // Non-member methods: negation of Variable and Literal
00196   inline Literal operator!(const Variable& v) {
00197     return Literal(v, false);
00198   }
00199 
00200   inline Literal operator!(const Literal& l) {
00201     return Literal(l.getVar(), l.isNegative());
00202   }
00203 
00204   std::ostream& operator<<(std::ostream& os, const Literal& l);
00205 
00206 } // end of namespace CVCL
00207 
00208 // Clause uses class Variable, have to include it here
00209 #include "clause.h"
00210 
00211 namespace CVCL {
00212 
00213   // The value holding class
00214   class VariableValue {
00215     friend class Variable;
00216     friend class VariableManager;
00217   private:
00218     VariableManager* d_vm;
00219     int d_refcount;
00220 
00221     Expr d_expr;
00222     // The inverse expression (initally Null)
00223     Expr d_neg;
00224 
00225     // Non-backtracking attributes (Chaff counters)
00226 
00227     // For positive instances
00228     unsigned d_count;
00229     unsigned d_countPrev;
00230     int d_score;
00231     // For negative instances
00232     unsigned d_negCount;
00233     unsigned d_negCountPrev;
00234     int d_negScore;
00235     // Whether the corresponding literal is in the list of active literals
00236     bool d_added;
00237     bool d_negAdded;
00238     // Watch pointer lists
00239     std::vector<std::pair<Clause, int> > d_wp;
00240     std::vector<std::pair<Clause, int> > d_negwp;
00241 
00242     // Backtracking attributes
00243 
00244     // Value of the variable: -1 (false), 1 (true), 0 (unresolved)
00245     CDO<int>* d_val;
00246     CDO<int>* d_scope; // Scope level where the variable is assigned
00247     // Theorem of the form (d_expr) or (!d_expr), reflecting d_val
00248     CDO<Theorem>* d_thm;
00249     CDO<Clause>* d_ante; // Antecedent clause and index of the variable
00250     CDO<int>* d_anteIdx;
00251     CDO<Theorem>* d_assump; // Theorem generated by assump rule, if any
00252     // Constructor is private; only class Variable can create it
00253     VariableValue(VariableManager* vm, const Expr& e)
00254       : d_vm(vm), d_refcount(0), d_expr(e),
00255       d_count(0), d_countPrev(0), d_score(0),
00256       d_negCount(0), d_negCountPrev(0), d_negScore(0),
00257       d_added(false), d_negAdded(false),
00258       d_val(NULL), d_scope(NULL), d_thm(NULL),
00259       d_ante(NULL), d_anteIdx(NULL), d_assump(NULL) { }
00260   public:
00261     ~VariableValue();
00262     // Accessor methods
00263     const Expr& getExpr() const { return d_expr; }
00264 
00265     const Expr& getNegExpr() const {
00266       if(d_neg.isNull()) {
00267         const_cast<VariableValue*>(this)->d_neg
00268           = d_expr.negate();
00269       }
00270       return d_neg;
00271     }
00272 
00273     int getValue() const {
00274       if(d_val==NULL) return 0;
00275       else return d_val->get();
00276     }
00277     
00278     int getScope() const {
00279       if(d_scope==NULL) return 0;
00280       else return d_scope->get();
00281     }
00282 
00283     const Theorem& getTheorem() const {
00284       static Theorem null;
00285       if(d_thm==NULL) return null;
00286       else return d_thm->get();
00287     }
00288 
00289     const Clause& getAntecedent() const {
00290       static Clause null;
00291       if(d_ante==NULL) return null;
00292       else return d_ante->get();
00293     }
00294 
00295     int getAntecedentIdx() const {
00296       if(d_anteIdx==NULL) return 0;
00297       else return d_anteIdx->get();
00298     }
00299     
00300     const Theorem& getAssumpThm() const {
00301       static Theorem null;
00302       if(d_assump==NULL) return null;
00303       else return d_assump->get();
00304     }
00305 
00306     // Setting the attributes: it can be either derived from the
00307     // antecedent clause, or by a theorem
00308     void setValue(int val, const Clause& c, int idx);
00309     // The theorem's expr must be the same as the variable's expr or
00310     // its negation
00311     void setValue(const Theorem& thm, int scope);
00312 
00313     void setAssumpThm(const Theorem& a, int scope);
00314 
00315     // Chaff counters: read and modified by reference
00316     unsigned& count(bool neg) {
00317       if(neg) return d_negCount;
00318       else return d_count;
00319     }
00320     unsigned& countPrev(bool neg) {
00321       if(neg) return d_negCountPrev;
00322       else return d_countPrev;
00323     }
00324     int& score(bool neg) {
00325       if(neg) return d_negScore;
00326       else return d_score;
00327     }
00328     bool& added(bool neg) {
00329       if(neg) return d_negAdded;
00330       else return d_added;
00331     }
00332 
00333     // Memory management
00334     void* operator new(size_t size, MemoryManager* mm) {
00335       return mm->newData(size);
00336     }
00337     void operator delete(void*) { }
00338 
00339     // friend methods
00340     friend std::ostream& operator<<(std::ostream& os, const VariableValue& v);
00341     friend bool operator==(const VariableValue& v1, const VariableValue& v2) {
00342       return v1.d_expr == v2.d_expr;
00343     }
00344   }; // end of class VariableValue
00345 
00346     // Accessing Chaff counters (read and modified by reference)
00347   inline unsigned& Variable::count(bool neg) { return d_val->count(neg); }
00348   inline unsigned& Variable::countPrev(bool neg)
00349     { return d_val->countPrev(neg); }
00350   inline int& Variable::score(bool neg) { return d_val->score(neg); }
00351   inline bool& Variable::added(bool neg) { return d_val->added(neg); }
00352 
00353   inline unsigned Variable::count(bool neg) const { return d_val->count(neg); }
00354   inline unsigned Variable::countPrev(bool neg) const
00355     { return d_val->countPrev(neg); }
00356   inline int Variable::score(bool neg) const { return d_val->score(neg); }
00357   inline bool Variable::added(bool neg) const { return d_val->added(neg); }
00358 
00359   inline std::vector<std::pair<Clause, int> >& Variable::wp(bool neg) const {
00360     if(neg) return d_val->d_negwp;
00361     else return d_val->d_wp;
00362   }
00363 
00364 
00365   class VariableManagerNotifyObj;
00366 
00367   // The manager class
00368   class VariableManager {
00369     friend class Variable;
00370     friend class VariableValue;
00371   private:
00372     ContextManager* d_cm;
00373     MemoryManager* d_mm;
00374     SearchEngineRules* d_rules;
00375     VariableManagerNotifyObj* d_notifyObj;
00376     //! Disable the garbage collection
00377     /*! Normally, it's set in the destructor, so that we can delete
00378      * all remaining variables without GC getting in the way
00379      */
00380     bool d_disableGC;
00381     //! Postpone garbage collection
00382     bool d_postponeGC;
00383     //! Vector of variables to be deleted (postponed during pop())
00384     std::vector<VariableValue*> d_deleted;
00385     
00386     // Hash only by the Expr
00387     class HashLV {
00388     public:
00389       size_t operator()(VariableValue* v) const { return v->getExpr().hash(); }
00390     };
00391     class EqLV {
00392     public:
00393       bool operator()(const VariableValue* lv1, const VariableValue* lv2) const
00394         { return lv1->getExpr() == lv2->getExpr(); }
00395     };
00396 
00397     // Hash set for existing variables
00398     typedef std::hash_set<VariableValue*, HashLV, EqLV> VariableValueSet;
00399     VariableValueSet d_varSet;
00400     
00401     // Creating unique VariableValue
00402     VariableValue* newVariableValue(const Expr& e);
00403 
00404   public:
00405     // Constructor.  mmFlag indicates which memory manager to use.
00406     VariableManager(ContextManager* cm, SearchEngineRules* rules,
00407                     const std::string& mmFlag);
00408     // Destructor
00409     ~VariableManager();
00410 
00411     //! Garbage collect VariableValue pointer
00412     void gc(VariableValue* v);
00413     //! Postpone garbage collection
00414     void postponeGC() { d_postponeGC = true; }
00415     //! Resume garbage collection
00416     void resumeGC();
00417     // Accessors
00418     ContextManager* getCM() const { return d_cm; }
00419     SearchEngineRules* getRules() const { return d_rules; }
00420 
00421   }; // end of class VariableManager
00422 
00423 /*****************************************************************************/
00424 /*!
00425  *\class VariableManagerNotifyObj
00426  *\brief Notifies VariableManager before and after each pop()
00427  *
00428  * Author: Sergey Berezin
00429  *
00430  * Created: Tue Mar  1 13:52:28 2005
00431  *
00432  * Disables the deletion of VariableValue objects during context
00433  * restoration (backtracking).  This solves the problem of circular
00434  * dependencies (e.g. a Variable pointing to its antecedent Clause).
00435  */
00436 /*****************************************************************************/
00437   class VariableManagerNotifyObj: public ContextNotifyObj {
00438     VariableManager* d_vm;
00439   public:
00440     //! Constructor
00441   VariableManagerNotifyObj(VariableManager* vm, Context* cxt)
00442     : ContextNotifyObj(cxt), d_vm(vm) { }
00443     
00444     void notifyPre(void) { d_vm->postponeGC(); }
00445     void notify(void) { d_vm->resumeGC(); }
00446   };
00447 
00448 
00449 } // end of namespace CVCL
00450 #endif

Generated on Thu Apr 13 16:57:36 2006 for CVC Lite by  doxygen 1.4.4