00001 /*****************************************************************************/ 00002 /*! 00003 * \file common_proof_rules.h 00004 * 00005 * Author: Sergey Berezin 00006 * 00007 * Created: Dec 11 18:15:37 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: CommonProofRules 00029 // 00030 // AUTHOR: Sergey Berezin, 12/09/2002 00031 // 00032 // Description: Commonly used proof rules (reflexivity, symmetry, 00033 // transitivity, substitutivity, etc.). 00034 // 00035 // Normally, proof rule interfaces belong to their decision 00036 // procedures. However, in the case of equational logic, the rules 00037 // are so useful, that even some basic classes like Transformer use 00038 // these rules under the hood. Therefore, it is made public, and its 00039 // implementation is provided by the 'theorem' module. 00040 /////////////////////////////////////////////////////////////////////////////// 00041 00042 #ifndef _CVC_lite__common_proof_rules_h_ 00043 #define _CVC_lite__common_proof_rules_h_ 00044 00045 #include <vector> 00046 00047 namespace CVCL { 00048 00049 class Theorem; 00050 class Theorem3; 00051 class Expr; 00052 class Op; 00053 00054 class CommonProofRules { 00055 public: 00056 //! Destructor 00057 virtual ~CommonProofRules() { } 00058 00059 // ==> u:a |- a 00060 //! \f[\frac{}{a\vdash a}\f] 00061 virtual Theorem assumpRule(const Expr& a, int scope = -1) = 0; 00062 00063 // ==> a == a or ==> a IFF a 00064 //! \f[\frac{}{a = a}\quad or \quad\frac{}{a \Leftrightarrow a}\f] 00065 virtual Theorem reflexivityRule(const Expr& a) = 0; 00066 00067 //! ==> (a == a) IFF TRUE 00068 virtual Theorem rewriteReflexivity(const Expr& a_eq_a) = 0; 00069 00070 // a1 == a2 ==> a2 == a1 (same for IFF) 00071 //! \f[\frac{a_1=a_2}{a_2=a_1}\f] (same for IFF) 00072 virtual Theorem symmetryRule(const Theorem& a1_eq_a2) = 0; 00073 00074 // ==> (a1 == a2) IFF (a2 == a1) 00075 //! \f[\frac{}{(a_1=a_2)\Leftrightarrow (a_2=a_1)}\f] 00076 virtual Theorem rewriteUsingSymmetry(const Expr& a1_eq_a2) = 0; 00077 00078 // (a1 == a2) & (a2 == a3) ==> (a1 == a3) [same for IFF] 00079 //! \f[\frac{a_1=a_2\quad a_2=a_3}{a_1=a_3}\f] (same for IFF) 00080 virtual Theorem transitivityRule(const Theorem& a1_eq_a2, 00081 const Theorem& a2_eq_a3) = 0; 00082 00083 // (c_1 == d_1) & ... & (c_n == d_n) 00084 // ==> op(c_1,...,c_n) == op(d_1,...,d_n) 00085 /*! @brief 00086 \f[\frac{(c_1=d_1)\wedge\ldots\wedge(c_n=d_n)} 00087 {op(c_1,\ldots,c_n)=op(d_1,\ldots,d_n)}\f] 00088 */ 00089 virtual Theorem substitutivityRule(const Op& op, 00090 const std::vector<Theorem>& thms) = 0; 00091 00092 // (c_1 == d_1) & ... & (c_n == d_n) 00093 // ==> op(c_1,...,c_n) == op(d_1,...,d_n) 00094 /*! @brief 00095 \f[\frac{(c_1=d_1)\wedge\ldots\wedge(c_n=d_n)} 00096 {op(c_1,\ldots,c_n)=op(d_1,\ldots,d_n)}\f] 00097 except that only those arguments are given that \f$c_i\not=d_i\f$. 00098 \param e is the original expression \f$op(c_1,\ldots,c_n)\f$. 00099 \param changed is the vector of indices of changed kids 00100 \param thms are the theorems \f$c_i=d_i\f$ for the changed kids. 00101 */ 00102 virtual Theorem substitutivityRule(const Expr& e, 00103 const std::vector<unsigned>& changed, 00104 const std::vector<Theorem>& thms) = 0; 00105 00106 // |- e, |- !e ==> |- FALSE 00107 /*! @brief 00108 \f[\frac{\Gamma_1\vdash e\quad\Gamma_2\vdash \neg e} 00109 {\Gamma_1\cup\Gamma_2\vdash \mathrm{FALSE}} 00110 \f] 00111 */ 00112 virtual Theorem contradictionRule(const Theorem& e, 00113 const Theorem& not_e) = 0; 00114 00115 // e ==> e IFF TRUE 00116 //! \f[\frac{\Gamma\vdash e}{\Gamma\vdash e\Leftrightarrow\mathrm{TRUE}}\f] 00117 virtual Theorem iffTrue(const Theorem& e) = 0; 00118 00119 // e ==> !e IFF FALSE 00120 //! \f[\frac{\Gamma\vdash e}{\Gamma\vdash\neg e\Leftrightarrow\mathrm{FALSE}}\f] 00121 virtual Theorem iffNotFalse(const Theorem& e) = 0; 00122 00123 // e IFF TRUE ==> e 00124 //! \f[\frac{\Gamma\vdash e\Leftrightarrow\mathrm{TRUE}}{\Gamma\vdash e}\f] 00125 virtual Theorem iffTrueElim(const Theorem& e) = 0; 00126 00127 // e IFF FALSE ==> !e 00128 //! \f[\frac{\Gamma\vdash e\Leftrightarrow\mathrm{FALSE}}{\Gamma\vdash\neg e}\f] 00129 virtual Theorem iffFalseElim(const Theorem& e) = 0; 00130 00131 //! e1 <=> e2 ==> ~e1 <=> ~e2 00132 /*! \f[\frac{\Gamma\vdash e_1\Leftrightarrow e_2} 00133 * {\Gamma\vdash\sim e_1\Leftrightarrow\sim e_2}\f] 00134 * Where ~e is the <em>inverse</em> of e (that is, ~(!e') = e'). 00135 */ 00136 virtual Theorem iffContrapositive(const Theorem& thm) = 0; 00137 00138 // !!e ==> e 00139 //! \f[\frac{\Gamma\vdash\neg\neg e}{\Gamma\vdash e}\f] 00140 virtual Theorem notNotElim(const Theorem& not_not_e) = 0; 00141 00142 // e1 AND (e1 IFF e2) ==> e2 00143 /*! @brief 00144 \f[\frac{\Gamma_1\vdash e_1\quad \Gamma_2\vdash(e_1\Leftrightarrow e_2)} 00145 {\Gamma_1\cup\Gamma_2\vdash e_2} 00146 \f] 00147 */ 00148 virtual Theorem iffMP(const Theorem& e1, const Theorem& e1_iff_e2) = 0; 00149 00150 // e1 AND (e1 IMPLIES e2) ==> e2 00151 /*! @brief 00152 \f[\frac{\Gamma_1\vdash e_1\quad \Gamma_2\vdash(e_1\Rightarrow e_2)} 00153 {\Gamma_1\cup\Gamma_2\vdash e_2} 00154 \f] 00155 */ 00156 virtual Theorem implMP(const Theorem& e1, const Theorem& e1_impl_e2) = 0; 00157 00158 // AND(e_1,...e_n) ==> e_i 00159 //! \f[\frac{\vdash e_1\wedge\cdots\wedge e_n}{\vdash e_i}\f] 00160 virtual Theorem andElim(const Theorem& e, int i) = 0; 00161 00162 // e1, e2 ==> AND(e1, e2) 00163 /*! @brief 00164 \f[\frac{\Gamma_1\vdash e_1\quad \Gamma_2\vdash e_2} 00165 {\Gamma_1\cup\Gamma_2\vdash e_1\wedge e_2} 00166 \f] 00167 */ 00168 virtual Theorem andIntro(const Theorem& e1, const Theorem& e2) = 0; 00169 00170 // e1, ..., en ==> AND(e1, ..., en) 00171 /*! @brief 00172 \f[\frac{\Gamma_1\vdash e_1\quad \cdots \quad\Gamma_n\vdash e_n} 00173 {\bigcup_{i=1}^n\Gamma_i\vdash \bigwedge_{i=1}^n e_i} 00174 \f] 00175 */ 00176 virtual Theorem andIntro(const std::vector<Theorem>& es) = 0; 00177 00178 // G,a1,...,an |- phi 00179 // ------------------------------------------------- 00180 // G |- (a1 & ... & an) -> phi 00181 /*! 00182 * @brief Implication introduction rule: 00183 * \f[\frac{\Gamma,\,\alpha_1\,\ldots,\,\alpha_n\vdash\phi} 00184 * {\Gamma\vdash(\bigwedge_{i=1}^n\alpha_i)\to\phi}\f] 00185 * 00186 * \param phi is the formula \f$\phi\f$ 00187 * \param assump is the vector of assumptions \f$\alpha_1\ldots\alpha_n\f$ 00188 */ 00189 virtual Theorem implIntro(const Theorem& phi, 00190 const std::vector<Expr>& assump) = 0; 00191 00192 //! e1 => e2 ==> ~e2 => ~e1 00193 /*! \f[\frac{\Gamma\vdash e_1\Rightarrow e_2} 00194 * {\Gamma\vdash\sim e_2\Rightarrow\sim e_1}\f] 00195 * Where ~e is the <em>inverse</em> of e (that is, ~(!e') = e'). 00196 */ 00197 virtual Theorem implContrapositive(const Theorem& thm) = 0; 00198 00199 // NOT e ==> e IFF FALSE 00200 //! \f[\frac{\vdash\neg e}{\vdash e\Leftrightarrow\mathrm{FALSE}}\f] 00201 virtual Theorem notToIff(const Theorem& not_e) = 0; 00202 00203 //! ==> (e1 <=> e2) <=> [simplified expr] 00204 /*! Rewrite formulas like FALSE/TRUE <=> e, e <=> NOT e, etc. */ 00205 virtual Theorem rewriteIff(const Expr& e) = 0; 00206 00207 // AND and OR rewrites check for TRUE and FALSE arguments and 00208 // remove them or collapse the entire expression to TRUE and FALSE 00209 // appropriately 00210 00211 //! ==> AND(e1,e2) IFF [simplified expr] 00212 virtual Theorem rewriteAnd(const Expr& e) = 0; 00213 00214 //! ==> OR(e1,...,en) IFF [simplified expr] 00215 virtual Theorem rewriteOr(const Expr& e) = 0; 00216 00217 //! ==> NOT TRUE IFF FALSE 00218 virtual Theorem rewriteNotTrue(const Expr& e) = 0; 00219 00220 //! ==> NOT FALSE IFF TRUE 00221 virtual Theorem rewriteNotFalse(const Expr& e) = 0; 00222 00223 //! ==> NOT NOT e IFF e, takes !!e 00224 virtual Theorem rewriteNotNot(const Expr& e) = 0; 00225 00226 //! ==> NOT FORALL (vars): e IFF EXISTS (vars) NOT e 00227 virtual Theorem rewriteNotForall(const Expr& forallExpr) = 0; 00228 00229 //! ==> NOT EXISTS (vars): e IFF FORALL (vars) NOT e 00230 virtual Theorem rewriteNotExists(const Expr& existsExpr) = 0; 00231 00232 //From expr EXISTS(x1: t1, ..., xn: tn) phi(x1,...,cn) 00233 //we create phi(c1,...,cn) where ci is a skolem constant 00234 //defined by the original expression and the index i. 00235 virtual Expr skolemize(const Expr& e) = 0; 00236 00237 /*! skolem rewrite rule: Introduces axiom |- Exists(x) phi(x) <=> phi(c) 00238 * where c is a constant defined by the expression Exists(x) phi(x) 00239 */ 00240 virtual Theorem skolemizeRewrite(const Expr& e) = 0; 00241 00242 //! Special version of skolemizeRewrite for "EXISTS x. t = x" 00243 virtual Theorem skolemizeRewriteVar(const Expr& e) = 0; 00244 00245 //! |- EXISTS x. e = x 00246 virtual Theorem varIntroRule(const Expr& e) = 0; 00247 00248 /*! @brief If thm is (EXISTS x: phi(x)), create the Skolemized version 00249 and add it to the database. Otherwise returns just thm. */ 00250 /*! 00251 * \param thm is the Theorem(EXISTS x: phi(x)) 00252 */ 00253 virtual Theorem skolemize(const Theorem& thm) = 0; 00254 00255 //! Retrun a theorem "|- e = v" for a new Skolem constant v 00256 /*! 00257 * This is equivalent to skolemize(d_core->varIntroRule(e)), only more 00258 * efficient. 00259 */ 00260 virtual Theorem varIntroSkolem(const Expr& e) = 0; 00261 00262 // Derived rules 00263 00264 //! ==> TRUE 00265 virtual Theorem trueTheorem() = 0; 00266 00267 //! AND(e1,e2) ==> [simplified expr] 00268 virtual Theorem rewriteAnd(const Theorem& e) = 0; 00269 00270 //! OR(e1,...,en) ==> [simplified expr] 00271 virtual Theorem rewriteOr(const Theorem& e) = 0; 00272 00273 // TODO: do we really need this? 00274 virtual std::vector<Theorem>& getSkolemAxioms() = 0; 00275 00276 //TODO: do we need this? 00277 virtual void clearSkolemAxioms() = 0; 00278 00279 }; // end of class CommonProofRules 00280 00281 } // end of namespace CVCL 00282 00283 #endif