theorem_producer.h

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file theorem_producer.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_Producer
00029 //
00030 // AUTHOR: Sergey Berezin, 07/05/02
00031 //
00032 // Abstract:
00033 //
00034 // This class is the only one that can create new Theorem classes.
00035 //
00036 // Only TRUSTED code can use it; a symbol _CVCL_TRUSTED_ must be
00037 // defined in *.cpp file before including this one; otherwise you'll
00038 // get a compiler warning.  Custom header files (*.h) which include
00039 // this file should NOT define _CVCL_TRUSTED_.  This practice enforces
00040 // the programmer to be aware of which part of his/her code is
00041 // trusted.
00042 // 
00043 // It defines a protected NON-virtual method newTheorem() so that any
00044 // subclass can create a new Theorem.  This means that no untrusted
00045 // decision procedure's code should see this interface.
00046 // Unfortunately, this has to be a coding policy rather than something
00047 // we can enforce by C++ class structure.
00048 // 
00049 // The intended use of this class is to make a subclass and define new
00050 // methods corresponding to proof rules (they take theorems and
00051 // generate new theorems).  Each decision procedure should have such a
00052 // subclass for its trusted core.  Each new proof rule must be sound;
00053 // that is, each new theorem that it generates must logically follow
00054 // from the theorems in the arguments, or the new theorem must be a
00055 // tautology.
00056 // 
00057 // Each such subclass must also inherit from a decision
00058 // procedure-specific abstract interface which declares the new
00059 // methods (other than newTheorem). The decision procedure should only
00060 // use the new abstract interface.  Thus, the DP will not even see
00061 // newTheorem() method.
00062 //
00063 // This way the untrusted part of the code will not be able to create
00064 // an unsound theorem.
00065 //
00066 // Proof rules may expect theorems in the arguments be of a certain
00067 // form; if the expectations are not met, the right thing to do is to
00068 // fail in DebugAssert with the appropriate message.  In other words,
00069 // it is a coding bug to pass wrong theorems to the wrong rules.
00070 //
00071 // It is also a bug if a wrong theorem is passed but not detected by
00072 // the proof rule, unless such checks are explicitly turned off
00073 // globally for efficiency.
00074 ////////////////////////////////////////////////////////////////////////
00075 
00076 #ifndef _CVCL_TRUSTED_
00077 #warning "This file should be included only by TRUSTED code.  Define _CVCL_TRUSTED_ before including this file."
00078 #endif
00079 
00080 #ifndef _CVC_lite__theorem_producer_h_
00081 #define _CVC_lite__theorem_producer_h_
00082 
00083 #include "theorem.h"
00084 #include "theorem_manager.h"
00085 #include "exception.h"
00086 
00087 // Macro to check for soundness.  It should only be executed within a
00088 // TheoremProducer class, and only if the -check-proofs option is set.
00089 // When its 'cond' is violated, it will call a function which will
00090 // eventually throw a soundness exception.
00091 #define CHECK_SOUND(cond, msg) if(!(cond)) \
00092  soundError(__FILE__, __LINE__, #cond, msg)
00093 
00094 // Flag whether to check soundness or not
00095 #define CHECK_PROOFS *d_checkProofs
00096 
00097 namespace CVCL {
00098 
00099   class TheoremProducer {
00100 
00101   protected:
00102     TheoremManager* d_tm;
00103     ExprManager* d_em;
00104 
00105     // Command-line option whether to check for soundness
00106     const bool* d_checkProofs;
00107     // Operator for creating proof terms
00108     Op d_pfOp;
00109     // Expr for filling in "condition" arguments in flea proofs
00110     Expr d_hole;
00111 
00112     // Make it possible for the subclasses to create theorems directly.
00113 
00114     //! Create a new theorem.  See also newRWTheorem() and newReflTheorem()
00115     Theorem newTheorem(const Expr& thm,
00116                        const Assumptions& assump,
00117                        const Proof& pf) {
00118       IF_DEBUG(if(!thm.isEq() && !thm.isIff()) {
00119         TRACE("newTheorem", "newTheorem(", thm, ")");
00120         debugger.counter("newTheorem() called on equality")++;
00121       });
00122       return Theorem(d_tm, thm, assump, pf);
00123     }
00124 
00125     //! Create a rewrite theorem: lhs = rhs
00126     Theorem newRWTheorem(const Expr& lhs, const Expr& rhs,
00127                          const Assumptions& assump,
00128                          const Proof& pf) {
00129       return Theorem(d_tm, lhs, rhs, assump, pf);
00130     }
00131 
00132     //! Create a reflexivity theorem
00133     Theorem newReflTheorem(const Expr& e, const Proof& pf) {
00134       return Theorem(d_tm, e, pf);
00135     }
00136 
00137     Theorem newAssumption(const Expr& thm, const Proof& pf, int scope = -1) {
00138       return Theorem(d_tm, thm, Assumptions(), pf, true, scope);
00139     }
00140 
00141     Theorem3 newTheorem3(const Expr& thm,
00142                          const Assumptions& assump,
00143                          const Proof& pf) {
00144       IF_DEBUG(if(!thm.isEq() && !thm.isIff()) {
00145         TRACE("newTheorem", "newTheorem3(", thm, ")");
00146         debugger.counter("newTheorem3() called on equality")++;
00147       });
00148       return Theorem3(d_tm, thm, assump, pf);
00149     }
00150 
00151     Theorem3 newRWTheorem3(const Expr& lhs, const Expr& rhs,
00152                            const Assumptions& assump,
00153                            const Proof& pf) {
00154       return Theorem3(d_tm, lhs, rhs, assump, pf);
00155     }
00156 
00157     void soundError(const std::string& file, int line,
00158                     const std::string& cond, const std::string& msg)
00159       throw(Exception);
00160 
00161   public:
00162     // Constructor
00163     TheoremProducer(TheoremManager *tm);
00164     // Destructor
00165     virtual ~TheoremProducer() { }
00166 
00167     //! Testing whether to generate proofs
00168     bool withProof() { return d_tm->withProof(); }
00169 
00170     //! Testing whether to generate assumptions
00171     bool withAssumptions() { return d_tm->withAssumptions(); }
00172 
00173     //! Create a new proof label (bound variable) for an assumption (formula)
00174     Proof newLabel(const Expr& e);
00175     
00176     //////////////////////////////////////////////////////////////////
00177     // Functions to create proof terms
00178     //////////////////////////////////////////////////////////////////
00179 
00180     // Apply a rule named 'name' to its arguments, Proofs or Exprs
00181     Proof newPf(const std::string& name);
00182     Proof newPf(const std::string& name, const Expr& e);
00183     Proof newPf(const std::string& name, const Proof& pf);              
00184     Proof newPf(const std::string& name, const Expr& e1, const Expr& e2);
00185     Proof newPf(const std::string& name, const Expr& e, const Proof& pf);
00186     Proof newPf(const std::string& name, const Expr& e1,
00187                 const Expr& e2, const Expr& e3);
00188     Proof newPf(const std::string& name, const Expr& e1,
00189                 const Expr& e2, const Proof& pf);
00190 
00191     // Methods with iterators.
00192 
00193     // Iterators are preferred to vectors, since they are often
00194     // efficient
00195 
00196     Proof newPf(const std::string& name,
00197                 Expr::iterator begin, const Expr::iterator &end);
00198     Proof newPf(const std::string& name, const Expr& e,
00199                 Expr::iterator begin, const Expr::iterator &end);
00200     Proof newPf(const std::string& name,
00201                 Expr::iterator begin, const Expr::iterator &end,
00202                 const std::vector<Proof>& pfs);
00203 
00204     // Methods with vectors.
00205     Proof newPf(const std::string& name, const std::vector<Expr>& args);
00206     Proof newPf(const std::string& name, const Expr& e,
00207                 const std::vector<Expr>& args);
00208     Proof newPf(const std::string& name, const Expr& e,
00209                 const std::vector<Proof>& pfs);
00210     Proof newPf(const std::string& name, const Expr& e1, const Expr& e2,
00211                 const std::vector<Proof>& pfs);
00212     Proof newPf(const std::string& name, const std::vector<Proof>& pfs);
00213     Proof newPf(const std::string& name, const std::vector<Expr>& args,
00214                 const Proof& pf);
00215     Proof newPf(const std::string& name, const std::vector<Expr>& args,
00216                 const std::vector<Proof>& pfs);
00217 
00218     //! Creating LAMBDA-abstraction (LAMBDA label formula proof)
00219     /*! The label must be a variable with a formula as a type, and
00220      * matching the given "frm". */
00221     Proof newPf(const Proof& label, const Expr& frm, const Proof& pf);
00222 
00223     //! Creating LAMBDA-abstraction (LAMBDA label proof).
00224     /*! The label must be a variable with a formula as a type. */
00225     Proof newPf(const Proof& label, const Proof& pf);
00226 
00227     /*! @brief Similarly, multi-argument lambda-abstractions: 
00228      * (LAMBDA (u1,...,un): (f1,...,fn). pf) */
00229     Proof newPf(const std::vector<Proof>& labels,
00230                 const std::vector<Expr>& frms,
00231                 const Proof& pf);
00232 
00233     Proof newPf(const std::vector<Proof>& labels,
00234                 const Proof& pf);
00235 
00236   }; // end of Theorem_Producer class
00237 
00238 };  // end of namespace CVCL
00239 #endif

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