00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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
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
00091
00092
00093
00094
00095
00096
00097
00098
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
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
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
00171
00172
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;
00184 ExprMap<bool> visited;
00185
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
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 }