decision_engine.cpp

Go to the documentation of this file.
00001 /*****************************************************************************/
00002 /*!
00003  * \file decision_engine.cpp
00004  * \brief Decision Engine
00005  * 
00006  * Author: Clark Barrett
00007  * 
00008  * Created: Sun Jul 13 22:44:55 2003
00009  *
00010  * <hr>
00011  * Copyright (C) 2003 by the Board of Trustees of Leland Stanford
00012  * Junior University and by New York University. 
00013  *
00014  * License to use, copy, modify, sell and/or distribute this software
00015  * and its documentation for any purpose is hereby granted without
00016  * royalty, subject to the terms and conditions defined in the \ref
00017  * LICENSE file provided with this distribution.  In particular:
00018  *
00019  * - The above copyright notice and this permission notice must appear
00020  * in all copies of the software and related documentation.
00021  *
00022  * - THE SOFTWARE IS PROVIDED "AS-IS", WITHOUT ANY WARRANTIES,
00023  * EXPRESSED OR IMPLIED.  USE IT AT YOUR OWN RISK.
00024  * 
00025  * <hr>
00026  * 
00027  */
00028 /*****************************************************************************/
00029 
00030 
00031 #include "decision_engine.h"
00032 #include "theory_core.h"
00033 #include "search.h"
00034 
00035 
00036 using namespace std;
00037 using namespace CVCL;
00038 
00039 
00040 DecisionEngine::DecisionEngine(TheoryCore* core, SearchImplBase* se)
00041   : d_core(core), d_se(se),
00042     d_splitters(core->getCM()->getCurrentContext()),
00043     d_splitterCount(core->getStatistics().counter("splitters"))
00044 {
00045   IF_DEBUG(d_splitters.setName("CDList[SearchEngineDefault.d_splitters]");)
00046 }
00047 
00048 /*****************************************************************************/
00049 /*!
00050  * Function: DecisionEngine::findSplitterRec
00051  *
00052  * Author: Clark Barrett
00053  *
00054  * Created: Sun Jul 13 22:47:06 2003
00055  *
00056  * Search the expression e (depth-first) for an atomic formula.  Note that in
00057  * order to support the "simplify in-place" option, each sub-expression is
00058  * checked to see if it has a find pointer, and if it does, the find is
00059  * followed instead of continuing to recurse on the given expression.
00060  * \return a NULL expr if no atomic formula is found.
00061  */
00062 /*****************************************************************************/
00063 Expr DecisionEngine::findSplitterRec(const Expr& e)
00064 {
00065   Expr best;
00066 
00067   if(d_visited.count(e) > 0)
00068     return d_visited[e];
00069 
00070   if (e.isTrue() || e.isFalse() || e.isAtomic()
00071       || !d_se->isGoodSplitter(e)) {
00072     d_visited[e] = best;
00073     return best;
00074   }
00075 
00076   if (e.isAbsAtomicFormula()) {
00077     d_visited[e] = e;
00078     return e;
00079   }
00080 
00081   ExprMap<Expr>::iterator it = d_bestByExpr.find(e);
00082   if (it != d_bestByExpr.end()) {
00083     d_visited[e] = it->second;
00084     return it->second;
00085   }
00086 
00087   vector<int> order(e.arity());
00088   int i = 0;
00089 
00090   if (e.isITE())
00091   {
00092     order[i++] = 0;
00093     order[i++] = e.getHighestKid(); // always 1 or 2
00094     order[i++] = 3 - e.getHighestKid();
00095   }
00096 
00097   else
00098   {
00099     if (e.arity() > 0)
00100     {
00101       order[i++] = e.getHighestKid();
00102       for (int k = 0; k < e.arity(); ++k)
00103         if (k != e.getHighestKid())
00104           order[i++] = k;
00105     }
00106   }
00107 
00108   for (int k = 0; k < e.arity(); k++)
00109   {
00110     Expr splitter =
00111       findSplitterRec(d_core->findExpr(e[order[k]]));
00112     if (!splitter.isNull() && (best.isNull() || isBetter(splitter, best)))
00113       best = splitter;
00114   }
00115 
00116   d_bestByExpr[e] = best;
00117   d_visited[e] = best;
00118   return best;
00119 }
00120 
00121 
00122 /*****************************************************************************/
00123 /*!
00124  * Function: DecisionEngine::pushDecision
00125  *
00126  * Author: Clark Barrett
00127  *
00128  * Created: Sun Jul 13 22:55:16 2003
00129  *
00130  * \param splitter 
00131  * \param whichCase If true, increment the splitter count and assert the
00132  * splitter.  If false, do NOT increment the splitter count and assert the
00133  * negation of the splitter.  Defaults to true.
00134  */
00135 /*****************************************************************************/
00136 void DecisionEngine::pushDecision(Expr splitter, bool whichCase)
00137 {
00138   string stCase = whichCase ? "TRUE" : "FALSE";
00139   if (whichCase) d_splitterCount++;
00140   d_core->getCM()->push();
00141   TRACE("search trace", "Asserting splitter("+stCase+"): ", splitter, "");
00142   TRACE("search", "Asserting splitter("+stCase+"): ", splitter, "");
00143   d_splitters.push_back(splitter);
00144   if (!whichCase)
00145     splitter = splitter.negate();
00146   Theorem thm = d_se->newIntAssumption(splitter);
00147   d_core->addFact(thm);
00148   // Search engine needs to know what original facts it derived or
00149   // split on, so that we don't split on them twice.  addFact() may
00150   // simplify these facts before calling addLiteralFact() and lose
00151   // this information.  There is no reason to add non-literals though,
00152   // as we never split on them directly.
00153   if(thm.getExpr().isAbsLiteral())
00154     d_se->addLiteralFact(thm);
00155 }
00156 
00157 
00158 void DecisionEngine::popDecision()
00159 {
00160   d_core->getCM()->pop();
00161 }
00162 
00163 
00164 void DecisionEngine::popTo(int dl)
00165 {
00166   d_core->getCM()->popto(dl);
00167 }
00168 
00169 
00170 Expr DecisionEngine::lastSplitter()
00171 {
00172   return d_splitters.back();
00173 }

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