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 #include "search_simple.h"
00030 #include "theory_core.h"
00031 #include "typecheck_exception.h"
00032 #include "search_rules.h"
00033
00034 #include "decision_engine_dfs.h"
00035 #include "decision_engine_caching.h"
00036 #include "decision_engine_mbtf.h"
00037 #include "expr_transform.h"
00038 #include "command_line_flags.h"
00039
00040
00041 using namespace std;
00042 using namespace CVCL;
00043
00044
00045 Theorem SearchSimple::checkValidRec()
00046 {
00047 TRACE_MSG("search", "checkValidRec() {");
00048 if (d_core->inconsistent()) {
00049 TRACE("search", "checkValidRec => ", d_core->inconsistentThm(),
00050 " (context inconsistent) }");
00051 d_decisionEngine->goalSatisfied();
00052 return d_core->inconsistentThm();
00053 }
00054
00055 Theorem e = d_goal.get();
00056 bool workingOnGoal = true;
00057 if (d_goal.get().getExpr().isTrue()) {
00058 e = d_nonLiterals.get();
00059 workingOnGoal = false;
00060 }
00061
00062 Theorem simp = simplify(e);
00063 Expr rhs = simp.getExpr();
00064 if (rhs.hasFind()) {
00065 simp = d_commonRules->iffMP(simp, d_core->find(rhs));
00066 rhs = simp.getExpr();
00067 }
00068
00069 if (workingOnGoal) d_goal.set(simp);
00070 else d_nonLiterals.set(simp);
00071
00072 if (rhs.isFalse()) {
00073 TRACE("search", "checkValidRec => ", simp, " (rhs=false) }");
00074 d_decisionEngine->goalSatisfied();
00075 return simp;
00076 }
00077 else if (rhs.isTrue()) {
00078 if (workingOnGoal || !d_core->checkSATCore()) {
00079 Theorem res(checkValidRec());
00080 TRACE("search", "checkValidRec => ", res, "}");
00081
00082 return res;
00083 }
00084 TRACE("search", "checkValidRec => ", "Null (true)", "}");
00085 return Theorem();
00086 }
00087 Expr splitter = d_decisionEngine->findSplitter(rhs);
00088 DebugAssert(!splitter.isNull(), "Expected splitter");
00089 d_decisionEngine->pushDecision(splitter);
00090 Theorem thm1 = checkValidRec();
00091 if (thm1.isNull()) {
00092 TRACE("search", "checkValidRec => ", "Null (case 1 is true)", "}");
00093 return thm1;
00094 }
00095 d_decisionEngine->popDecision();
00096 d_decisionEngine->pushDecision(splitter, false);
00097 Theorem thm2 = checkValidRec();
00098 if (thm2.isNull()) {
00099 TRACE("search", "checkValidRec => ", "Null (case 2 is true)", "}");
00100 return thm2;
00101 }
00102 d_decisionEngine->popDecision();
00103 Theorem res(d_rules->caseSplit(splitter, thm1, thm2));
00104 TRACE("search", "checkValidRec => ", res, " (false) }");
00105 return res;
00106 }
00107
00108
00109 SearchSimple::SearchSimple(TheoryCore* core)
00110 : SearchImplBase(core),
00111 d_name("simple"),
00112 d_goal(core->getCM()->getCurrentContext()),
00113 d_nonLiterals(core->getCM()->getCurrentContext()),
00114 d_simplifiedThm(core->getCM()->getCurrentContext())
00115 {
00116 if (core->getFlags()["de"].getString() == "caching")
00117 d_decisionEngine = new DecisionEngineCaching(core, this);
00118 else if (core->getFlags()["de"].getString() == "mbtf")
00119 d_decisionEngine = new DecisionEngineMBTF(core, this);
00120 else
00121 d_decisionEngine = new DecisionEngineDFS(core, this);
00122
00123 d_goal.set(d_commonRules->trueTheorem());
00124 d_nonLiterals.set(d_commonRules->trueTheorem());
00125 }
00126
00127
00128 SearchSimple::~SearchSimple()
00129 {
00130 delete d_decisionEngine;
00131 }
00132
00133
00134 bool SearchSimple::checkValidMain(const Expr& e2)
00135 {
00136 Theorem res = checkValidRec();
00137
00138
00139 if (res.isNull()) {
00140 DebugAssert(d_goal.get().getExpr().isTrue(),
00141 "checkValid: Expected true goal");
00142 vector<Expr> a;
00143 d_goal.get().getLeafAssumptions(a);
00144 d_lastCounterExample.clear();
00145 for (vector<Expr>::iterator i=a.begin(), iend=a.end(); i != iend; ++i) {
00146 d_lastCounterExample[*i] = true;
00147 }
00148 }
00149
00150 bool r = processResult(res, e2);
00151
00152 if (r) {
00153 TRACE_MSG("search terse", "checkValid => true}");
00154 TRACE("search", "checkValid => true; theorem = ", d_lastValid, "}");
00155
00156 Theorem e_iff_e2(d_commonRules->iffContrapositive(d_simplifiedThm));
00157 d_lastValid =
00158 d_commonRules->iffMP(d_lastValid, d_commonRules->symmetryRule(e_iff_e2));
00159 d_core->getCM()->pop();
00160 }
00161 else {
00162 TRACE_MSG("search terse", "checkValid => false}");
00163 TRACE_MSG("search", "checkValid => false; }");
00164 }
00165 return r;
00166 }
00167
00168
00169 bool SearchSimple::checkValidInternal(const Expr& e)
00170 {
00171 DebugAssert(d_goal.get().getExpr().isTrue(),"checkValid: Expected true goal");
00172 DebugAssert(d_nonLiterals.get().getExpr().isTrue(),"checkValid: Expected true nonLiterals");
00173
00174 TRACE("search", "checkValid(", e, ") {");
00175 TRACE_MSG("search terse", "checkValid() {");
00176
00177 if (!e.getType().isBool()) {
00178 throw TypecheckException
00179 ("checking validity of a non-boolean expression:\n\n "
00180 + e.toString()
00181 + "\n\nwhich has the following type:\n\n "
00182 + e.getType().toString());
00183 }
00184
00185
00186 d_core->getCM()->push();
00187 d_bottomScope = scopeLevel();
00188
00189 d_simplifiedThm.set(d_core->getExprTrans()->preprocess(e.negate()));
00190 TRACE("search", "checkValid: simplifiedThm = ", d_simplifiedThm, "");
00191
00192 const Expr& not_e2 = d_simplifiedThm.get().getRHS();
00193 Expr e2 = not_e2.negate();
00194
00195
00196 TRACE_MSG("search terse", "checkValid: Asserting !e: ");
00197 TRACE("search", "checkValid: Asserting !e: ", not_e2, "");
00198 Theorem not_e2_thm;
00199 if(d_assumptions.count(not_e2) == 0) {
00200 not_e2_thm = newUserAssumption(not_e2);
00201 } else {
00202 not_e2_thm = d_assumptions[not_e2];
00203 }
00204 d_core->addFact(not_e2_thm);
00205 d_goal.set(not_e2_thm);
00206
00207 return checkValidMain(e2);
00208 }
00209
00210
00211 bool SearchSimple::restartInternal(const Expr& e)
00212 {
00213 TRACE("search", "restart(", e, ") {");
00214 TRACE_MSG("search terse", "restart() {");
00215
00216 if (!e.getType().isBool()) {
00217 throw TypecheckException
00218 ("argument to restart is a non-boolean expression:\n\n "
00219 + e.toString()
00220 + "\n\nwhich has the following type:\n\n "
00221 + e.getType().toString());
00222 }
00223
00224 if (d_bottomScope == 0) {
00225 throw Exception("Call to restart with no current query");
00226 }
00227 d_core->getCM()->popto(d_bottomScope);
00228
00229 Expr e2 = d_simplifiedThm.get().getRHS().negate();
00230
00231 TRACE_MSG("search terse", "restart: Asserting e: ");
00232 TRACE("search", "restart: Asserting e: ", e, "");
00233 if(d_assumptions.count(e) == 0) {
00234 d_core->addFact(newUserAssumption(e));
00235 }
00236
00237 return checkValidMain(e2);
00238 }
00239
00240
00241 void SearchSimple::addNonLiteralFact(const Theorem& thm)
00242 {
00243 d_nonLiterals.set(d_commonRules->andIntro(d_nonLiterals.get(), thm));
00244 }