search_simple.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file search_simple.cpp
00004  * 
00005  * Author: Clark Barrett
00006  * 
00007  * Created: Sat Mar 29 21:59:36 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  */
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       //      d_decisionEngine->goalSatisfied();
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   // Set counter-example
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   // A successful query should leave the context unchanged
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   // Assert not_e2 if it's not already asserted
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 }

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