theorem.h

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file theorem.h
00004  * 
00005  * Author: Sergey Berezin
00006  * 
00007  * Created: Dec 10 00:37:49 GMT 2002
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  */
00027 /*****************************************************************************/
00028 // CLASS: Theorem
00029 //
00030 // AUTHOR: Sergey Berezin, 07/05/02
00031 //
00032 // Abstract:
00033 //
00034 // A class representing a proven fact in CVC.  It stores the theorem
00035 // as a CVC expression, and in the proof prodicing mode also its
00036 // proof.
00037 //
00038 // The idea is to allow only a few trusted classes to create values of
00039 // this class.  If all the critical computations in the decision
00040 // procedures are done through the use of Theorems, then soundness of
00041 // these decision procedures will rely only on the soundness of the
00042 // methods in the trusted classes (the inference rules).
00043 //
00044 // Thus, proof checking can effectively be done at run-time on the
00045 // fly.  Or the soundness may be potentially proven by static analysis
00046 // and many run-time checks can then be optimized away.
00047 //
00048 // This theorem.h file should be used by the decision procedures that
00049 // use Theorem.
00050 //
00051 ////////////////////////////////////////////////////////////////////////
00052 
00053 // expr.h Has to be included outside of #ifndef, since it sources us
00054 // recursively (read comments in expr_value.h).
00055 #ifndef _CVC_lite__expr_h_
00056 #include "expr.h"
00057 #endif
00058 
00059 #ifndef _CVC_lite__theorem_h_
00060 #define _CVC_lite__theorem_h_
00061 
00062 #include "proof.h"
00063 #include "assumptions.h"
00064 
00065 namespace CVCL {
00066 
00067   // Declare the data holding classes but hide the definitions
00068   class TheoremManager;
00069   class TheoremValue;
00070   class Assumptions;
00071 
00072   // Theorem is basically a wrapper around a pointer to a
00073   // TheoremValue, so that we can pass this class around by value.
00074   // All the constructors of this class are private, so do not inherit
00075   // from it and do not try to create a value directly.  Only
00076   // TheoremProducer can create new Theorem instances.
00077   //
00078   // Theorems, unlike expressions, are NOT made unique, and it is
00079   // possible to have the same theorem in different scopes with
00080   // different assumptions and proofs.  It is a deliberate feature,
00081   // since natural deduction sometimes requires proving the same
00082   // conclusion from different assumptions independently, e.g. in
00083   // disjunction elimination rule.
00084   class Theorem {
00085   private:
00086     // Make a theorem producing class our friend.  No definition is
00087     // exposed here.
00088     friend class TheoremProducer;
00089     // Also allow our 3-valued cousin to create us
00090     friend class Theorem3;
00091 
00092     TheoremValue *d_thm;
00093 
00094     //! Compare Theorems by their expressions.  Return -1, 0, or 1.
00095     friend int compare(const Theorem& t1, const Theorem& t2);
00096     //! Compare a Theorem with an Expr (as if Expr is a Theorem)
00097     friend int compare(const Theorem& t1, const Expr& e2);
00098     //! Compare Theorems by TheoremValue pointers.  Return -1, 0, or 1.
00099     friend int compareByPtr(const Theorem& t1, const Theorem& t2);
00100     //! Equality is w.r.t. compare()
00101     friend bool operator==(const Theorem& t1, const Theorem& t2) 
00102       { return (compare(t1, t2)==0); }
00103     //! Disequality is w.r.t. compare()
00104     friend bool operator!=(const Theorem& t1, const Theorem& t2)
00105       { return (compare(t1, t2) != 0); }
00106 
00107     //! Constructor for a new theorem 
00108     Theorem(TheoremManager* tm, const Expr &thm, const Assumptions& assump,
00109             const Proof& pf, bool isAssump = false, int scope = -1);
00110 
00111     //! Constructor for rewrite theorems.
00112     /*! These use a special efficient subclass of TheoremValue for
00113      * theorems which represent rewrites: A |- t = t' or A |- phi<=>phi'
00114      */
00115     Theorem(TheoremManager* tm, const Expr& lhs, const Expr& rhs,
00116             const Assumptions& assump, const Proof& pf, bool isAssump = false,
00117             int scope = -1);
00118 
00119     //! Constructor for a reflexivity theorem: |-t=t or |-phi<=>phi
00120     Theorem(TheoremManager* tm, const Expr& e, const Proof& pf);
00121 
00122     void recursivePrint(int& i) const;
00123     void getAssumptionsRec(std::set<Expr>& assumptions) const;
00124 
00125   public:
00126     // recusive function to print theorems and all assumptions recursively
00127     // important: this function will corrupt all flags!! so exercise 
00128     // caution when using in any graph traversals 
00129     // (probably more useful to call it only before a crash)
00130     void printDebug() const { 
00131       this->clearAllFlags();
00132       this->setCachedValue(0);
00133       this->setFlag();
00134       int i = 1; 
00135       recursivePrint(i); 
00136     }
00137 
00138     // Default constructor creates Null theorem to allow untrusted
00139     // code declare local vars without initialization (vector<Theorem>
00140     // may need that, for instance).
00141     Theorem(): d_thm(NULL) { }
00142     // Copy constructor
00143     Theorem(const Theorem &th);
00144     // Assignment operator
00145     Theorem& operator=(const Theorem &th);
00146 
00147     // Destructor
00148     virtual ~Theorem();
00149 
00150     bool isNull() const { return d_thm == NULL; }
00151 
00152     // True if theorem is of the form t=t' or phi iff phi'
00153     bool isRewrite() const;
00154     // True if theorem was created using assumpRule
00155     bool isAssump() const;
00156     
00157     // Return the theorem value as an Expr
00158     const Expr& getExpr() const;
00159     const Expr& getLHS() const;
00160     const Expr& getRHS() const;
00161 
00162     // Return the assumptions.
00163     // It's an error if called while running without assumptions.
00164     const Assumptions& getAssumptions() const;
00165     // Recurse to get actual assumptions
00166     void getLeafAssumptions(std::vector<Expr>& assumptions,
00167                             bool negate = false) const;
00168     const Assumptions& getAssumptionsRef() const;
00169     // This method returns a *clean copy* of the Assumptions.
00170     // It can be modified without any effect on the theorem.
00171     // It's an error if called while running without assumptions.
00172     Assumptions getAssumptionsCopy() const;
00173     // Return the proof of the theorem.  If running without proofs,
00174     // return the Null proof.
00175     const Proof& getProof() const;
00176     // Return the lowest scope level at which this theorem is valid.
00177     // Value -1 means no information is available.
00178     int getScope() const;
00179 
00180     // Test if we are running in a proof production mode and with assumptions
00181     bool withProof() const;
00182     bool withAssumptions() const;
00183 
00184     // Printing
00185     std::string toString() const;
00186 
00187     // For debugging
00188     void printx() const;
00189     void print() const;
00190 
00191     /*! \name Methods for Theorem Attributes
00192      *
00193      * Several attributes used in conflict analysis and assumptions
00194      * graph traversals.
00195      * @{
00196      */
00197     //! Check if the flag attribute is set
00198     bool isFlagged() const;
00199     //! Clear the flag attribute in all the theorems
00200     void clearAllFlags() const;
00201     //! Set the flag attribute
00202     void setFlag() const;
00203 
00204     //! Set the "expand" attribute
00205     void setExpandFlag(bool val) const;
00206     //! Check the "expand" attribute
00207     bool getExpandFlag() const;
00208     //! Set the "literal" attribute
00209     /*! The expression of this theorem will be added as a conflict
00210      * clause literal */
00211     void setLitFlag(bool val) const;
00212     //! Check the "literal" attribute
00213     /*! The expression of this theorem will be added as a conflict
00214      * clause literal */
00215     bool getLitFlag() const;
00216     //! Check if the theorem is a literal
00217     bool isAbsLiteral() const;
00218 
00219     bool refutes(const Expr& e) const
00220     {
00221       return
00222         (e.isNot() && e[0] == getExpr()) ||
00223         (getExpr().isNot() && getExpr()[0] == e);
00224     }
00225 
00226     bool proves(const Expr& e) const
00227     {
00228       return getExpr() == e;
00229     }
00230 
00231     bool matches(const Expr& e) const
00232     {
00233       return proves(e) || refutes(e);
00234     }
00235 
00236     void setCachedValue(int value) const;
00237     int getCachedValue() const;
00238     
00239     /*!@}*/ // End of Attribute methods
00240 
00241     //! Printing a theorem to a stream, calling it "name".
00242     std::ostream& print(std::ostream& os, const std::string& name) const;
00243     
00244     friend std::ostream& operator<<(std::ostream& os, const Theorem& t) {
00245       return t.print(os, "Theorem");
00246     }
00247   };  // End of Theorem
00248 
00249 
00250 /*****************************************************************************/
00251 /*!
00252  *\class Theorem3
00253  *\brief Theorem3
00254  *
00255  * Author: Sergey Berezin
00256  *
00257  * Created: Tue Nov  4 17:57:07 2003
00258  *
00259  * Implements the 3-valued theorem used for the user assertions and
00260  * the result of query.  It is simply a wrapper around class Theorem,
00261  * but has a different semantic meaning: the formula may have partial
00262  * functions and has the Kleene's 3-valued interpretation.  The fact
00263  * that a Theorem3 value is derived means that the TCCs for the
00264  * formula and all of its assumptions are valid in the current
00265  * context, and the proofs of TCCs contribute to the set of
00266  * assumptions.
00267  */
00268 /*****************************************************************************/
00269   class Theorem3 {
00270   private:
00271     // Make a theorem producing class our friend.  No definition is
00272     // exposed here.
00273     friend class TheoremProducer;
00274 
00275     Theorem d_thm;
00276 
00277     friend bool operator==(const Theorem3& t1, const Theorem3& t2) {
00278       return t1.d_thm == t2.d_thm;
00279     }
00280     friend bool operator!=(const Theorem3& t1, const Theorem3& t2) {
00281       return t1.d_thm != t2.d_thm;
00282     }
00283 
00284 
00285     // Private constructors for a new theorem 
00286     Theorem3(TheoremManager* tm, const Expr &thm, const Assumptions& assump,
00287              const Proof& pf, bool isAssump = false, int scope = -1)
00288       : d_thm(tm, thm, assump, pf, isAssump, scope) { }
00289 
00290     // Constructors for rewrite theorems.  These use a special efficient
00291     // subclass of TheoremValue for theorems which represent rewrites:
00292     // A |- t = t' or A |- phi iff phi'
00293     Theorem3(TheoremManager* tm, const Expr& lhs, const Expr& rhs,
00294              const Assumptions& assump, const Proof& pf)
00295       : d_thm(tm, lhs, rhs, assump, pf) { }
00296 
00297   public:
00298     // recusive function to print theorems and all assumptions recursively
00299     // important: this function will corrupt all flags!! so exercise 
00300     // caution when using in any graph traversals 
00301     // (probably more useful to call it only before a crash)
00302     void printDebug() const { d_thm.printDebug(); }
00303 
00304     // Default constructor creates Null theorem to allow untrusted
00305     // code declare local vars without initialization (vector<Theorem>
00306     // may need that, for instance).
00307     Theorem3() { }
00308 
00309     // Destructor
00310     virtual ~Theorem3() { }
00311 
00312     bool isNull() const { return d_thm.isNull(); }
00313 
00314     // True if theorem is of the form t=t' or phi iff phi'
00315     bool isRewrite() const { return d_thm.isRewrite(); }
00316     bool isAssump() const { return d_thm.isAssump(); }
00317     
00318     // Return the theorem value as an Expr
00319     const Expr& getExpr() const { return d_thm.getExpr(); }
00320     const Expr& getLHS() const { return d_thm.getLHS(); }
00321     const Expr& getRHS() const { return d_thm.getRHS(); }
00322 
00323     // Return the assumptions.
00324     // It's an error if called while running without assumptions.
00325     const Assumptions getAssumptions() const { return d_thm.getAssumptions(); }
00326     const Assumptions& getAssumptionsRef() const {
00327       return d_thm.getAssumptionsRef();
00328     }
00329     // This method returns a *clean copy* of the Assumptions.
00330     // It can be modified without any effect on the theorem.
00331     // It's an error if called while running without assumptions.
00332     Assumptions getAssumptionsCopy() const {
00333       return d_thm.getAssumptionsCopy();
00334     }
00335     // Return the proof of the theorem.  If running without proofs,
00336     // return the Null proof.
00337     const Proof& getProof() const { return d_thm.getProof(); }
00338 
00339     // Return the lowest scope level at which this theorem is valid.
00340     // Value -1 means no information is available.
00341     int getScope() const { return d_thm.getScope(); }
00342 
00343     // Test if we are running in a proof production mode and with assumptions
00344     bool withProof() const { return d_thm.withProof(); }
00345     bool withAssumptions() const { return d_thm.withAssumptions(); }
00346 
00347     // Printing
00348     std::string toString() const;
00349 
00350     // For debugging
00351     void printx() const { d_thm.printx(); }
00352     void print() const { d_thm.print(); }
00353 
00354     //! Check if the theorem is a literal
00355     bool isAbsLiteral() const { return d_thm.isAbsLiteral(); }
00356 
00357     friend std::ostream& operator<<(std::ostream& os, const Theorem3& t) {
00358       return t.d_thm.print(os, "Theorem3");
00359     }
00360   };  // End of Theorem3
00361 
00362   //! "Less" comparator for theorems by TheoremValue pointers
00363   class TheoremLess {
00364   public:
00365     bool operator()(const Theorem& t1, const Theorem& t2) const {
00366       return (compareByPtr(t1, t2) < 0);
00367     }
00368   };
00369   typedef std::map<Theorem,bool, TheoremLess> TheoremMap;
00370 
00371   inline std::string Theorem::toString() const {
00372     std::ostringstream ss;
00373     ss << (*this);
00374     return ss.str();
00375   }
00376 
00377   inline std::string Theorem3::toString() const {
00378     std::ostringstream ss;
00379     ss << (*this);
00380     return ss.str();
00381   }
00382 
00383   // Merge assumptions from different theorems
00384   inline Assumptions merge(const Theorem& t1, const Theorem& t2) {
00385     return Assumptions(t1, t2);
00386   }
00387   inline Assumptions merge(const Assumptions& a, const Theorem& t) {
00388     Assumptions a2 = a.copy();
00389     a2.add(t);
00390     return a2;
00391   }
00392   inline Assumptions merge(const Theorem& t, const Assumptions& a) {
00393     Assumptions a2 = a.copy();
00394     a2.add(t);
00395     return a2;
00396   }
00397   inline Assumptions merge(const std::vector<Theorem>& t) {
00398     return Assumptions(t);
00399   }
00400 
00401   inline bool operator<(const Theorem& t1, const Theorem& t2)
00402     { return compare(t1, t2) < 0; }
00403   inline bool operator<=(const Theorem& t1, const Theorem& t2)
00404     { return compare(t1, t2) <= 0; }
00405   inline bool operator>(const Theorem& t1, const Theorem& t2)
00406     { return compare(t1, t2) > 0; }
00407   inline bool operator>=(const Theorem& t1, const Theorem& t2)
00408     { return compare(t1, t2) >= 0; }
00409 
00410 }; // end of namespace CVCL
00411 
00412 #endif

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