quant_theorem_producer.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file quant_theorem_producer.cpp
00004  * 
00005  * Author: Daniel Wichs
00006  * 
00007  * Created: Jul 07 22:22:38 GMT 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  * CLASS: QuantProofRules
00027  * 
00028  * 
00029  * Description: TRUSTED implementation of arithmetic proof rules.
00030  * 
00031  */
00032 /*****************************************************************************/
00033 
00034 // This code is trusted
00035 #define _CVCL_TRUSTED_
00036 
00037 
00038 #include "quant_theorem_producer.h"
00039 #include "theory_quant.h"
00040 #include "theory_core.h"
00041 
00042 
00043 using namespace std;
00044 using namespace CVCL;
00045 
00046 
00047 QuantProofRules* TheoryQuant::createProofRules() {
00048   return new QuantTheoremProducer(theoryCore()->getTM(), this);
00049 }
00050   
00051 
00052 #define CLASS_NAME "CVCL::QuantTheoremProducer"
00053 
00054 
00055 //! ==> NOT FORALL (vars): e  IFF EXISTS (vars) NOT e
00056 Theorem
00057 QuantTheoremProducer::rewriteNotForall(const Expr& e) {
00058   if(CHECK_PROOFS) {
00059     CHECK_SOUND(e.isNot() && e[0].isForall(),
00060                 "rewriteNotForall: expr must be NOT FORALL:\n"
00061                 +e.toString());
00062   }
00063   Assumptions a;
00064   Proof pf;
00065   if(withProof())
00066     pf = newPf("rewrite_not_forall", e);
00067   return newRWTheorem(e, e.getEM()->newClosureExpr(EXISTS, e[0].getVars(),
00068                                                    !e[0].getBody()),
00069                       a, pf);
00070 }
00071 
00072 
00073 //! ==> NOT EXISTS (vars): e  IFF FORALL (vars) NOT e
00074 Theorem
00075 QuantTheoremProducer::rewriteNotExists(const Expr& e) {
00076   if(CHECK_PROOFS) {
00077     CHECK_SOUND(e.isNot() && e[0].isExists(),
00078                 "rewriteNotExists: expr must be NOT FORALL:\n"
00079                 +e.toString());
00080   }
00081   Assumptions a;
00082   Proof pf;
00083   if(withProof())
00084     pf = newPf("rewrite_not_exists", e);
00085   return newRWTheorem(e, e.getEM()->newClosureExpr(FORALL, e[0].getVars(),
00086                                                    !e[0].getBody()),
00087                       a, pf);
00088 }
00089 
00090 //! Instantiate a  universally quantified formula
00091 /*! From T|-FORALL(var): e generate T|-psi => e' where e' is obtained
00092  * from e by instantiating bound variables with terms in
00093  * vector<Expr>& terms.  The vector of terms should be the same
00094  * size as the vector of bound variables in e. Also elements in
00095  * each position i need to have matching base types. psi is the conjunction of 
00096  * subtype predicates for the bound variables of the quanitfied expression.
00097  * \param t1 is the quantifier (a Theorem)
00098  * \param terms are the terms to instantiate.
00099  */
00100 Theorem QuantTheoremProducer::universalInst(const Theorem& t1, const
00101                                             vector<Expr>& terms)
00102 {
00103 
00104   Expr e = t1.getExpr();
00105   const vector<Expr>& boundVars = e.getVars();
00106   if(CHECK_PROOFS) {
00107     CHECK_SOUND(boundVars.size() == terms.size(), 
00108                 "Universal instantiation: size of terms array does "
00109                 "not match quanitfied variables array size");
00110     CHECK_SOUND(e.isForall(),
00111                 "universal instantiation: expr must be FORALL:\n"
00112                 +e.toString());
00113     for(unsigned int i=0; i<terms.size(); i++)
00114       CHECK_SOUND(d_theoryQuant->getBaseType(boundVars[i]) ==
00115                   d_theoryQuant->getBaseType(terms[i]),
00116               "Universal instantiation: type mismatch");
00117 
00118   }
00119 
00120   //build up a conjunction of type predicates for expression
00121   Expr tr = e.getEM()->trueExpr();
00122   Expr typePred = tr;
00123   for(unsigned int i=0; i<terms.size(); i++) {
00124     Expr p = d_theoryQuant->getTypePred(boundVars[i].getType(),terms[i]);
00125     if(p!=tr) {
00126       if(typePred==tr)
00127         typePred = p;
00128       else
00129         typePred = typePred.andExpr(p);
00130     }
00131   }
00132   Assumptions a;
00133   Proof pf;
00134   if(withAssumptions())
00135     a = t1.getAssumptionsCopy();
00136   if(withProof()) {
00137     vector<Proof> pfs;
00138     vector<Expr> es;
00139     pfs.push_back(t1.getProof());
00140     es.push_back(e);
00141     es.insert(es.end(), terms.begin(), terms.end());
00142     pf= newPf("universal_elimination", es, pfs);
00143   }
00144    Expr inst = e.getBody().substExpr(e.getVars(), terms);
00145    Expr imp;
00146    if(typePred == tr)
00147      imp = inst;
00148    else
00149      imp = typePred.impExpr(inst); 
00150    return(newTheorem(imp, a, pf));
00151 }
00152 
00153 //! find all bound variables in e and maps them to true in boundVars
00154 void QuantTheoremProducer::recFindBoundVars(const Expr& e, 
00155                            ExprMap<bool> & boundVars, ExprMap<bool> &visited) 
00156 {
00157   if(visited.count(e)>0)
00158     return;
00159   else
00160     visited[e] = true;
00161   if(e.getKind() == BOUND_VAR)
00162     boundVars[e] = true;
00163   if(e.getKind() == EXISTS || e.getKind() == FORALL)
00164     recFindBoundVars(e.getBody(), boundVars, visited);
00165   for(Expr::iterator it = e.begin(); it!=e.end(); ++it)
00166     recFindBoundVars(*it, boundVars, visited);
00167   
00168 }
00169 
00170 /*! @brief From T|- QUANTIFIER (vars): e we get T|-QUANTIFIER(vars') e
00171  * where vars' is obtained from vars by removing all bound variables
00172  *  not used in e. If vars' is empty the produced theorem is just T|-e
00173  */
00174 Theorem QuantTheoremProducer::boundVarElim(const Theorem& t1)
00175 {
00176   const Expr e=t1.getExpr();
00177   const Expr body = e.getBody();
00178   if(CHECK_PROOFS) {
00179       CHECK_SOUND(e.isForall() || e.isExists(),
00180                 "bound var elimination: "
00181                 +e.toString());
00182   }
00183   ExprMap<bool> boundVars; //a mapping of bound variables in the body to true
00184   ExprMap<bool> visited; //to make sure expressions aren't traversed
00185                           //multiple times
00186   recFindBoundVars(body, boundVars, visited);
00187   vector<Expr> quantVars;
00188   const vector<Expr>& origVars = e.getVars();
00189   for(vector<Expr>::const_iterator it = origVars.begin(), 
00190         iend=origVars.end(); it!=iend; ++it)
00191     {
00192     if(boundVars.count(*it) > 0)
00193       quantVars.push_back(*it);
00194     }
00195 
00196   // If all variables are used, just return the original theorem
00197   if(quantVars.size() == origVars.size())
00198     return t1;
00199 
00200   Assumptions a;
00201   Proof pf;
00202   if(withAssumptions())
00203     a = t1.getAssumptionsCopy();
00204   if(withProof()) {
00205     vector<Expr> es;
00206     vector<Proof> pfs;
00207     es.push_back(e);
00208     es.insert(es.end(), quantVars.begin(), quantVars.end());
00209     pfs.push_back(t1.getProof());
00210     pf= newPf("bound_variable_elimination", es, pfs);
00211   }
00212   if(quantVars.size() == 0)
00213     return(newTheorem(e.getBody(), a, pf));
00214   
00215   Expr newQuantExpr;
00216   if(e.isForall())
00217     newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(FORALL, quantVars, body);
00218   else
00219     newQuantExpr = d_theoryQuant->getEM()->newClosureExpr(EXISTS, quantVars, body);
00220 
00221   return(newTheorem(newQuantExpr, a, pf));
00222 }

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