/*****************************************************************************/
/*!
* \file decision_engine.cpp
* \brief Decision Engine
*
* Author: Clark Barrett
*
* Created: Sun Jul 13 22:44:55 2003
*
* <hr>
*
* License to use, copy, modify, sell and/or distribute this software
* and its documentation for any purpose is hereby granted without
* royalty, subject to the terms and conditions defined in the \ref
* LICENSE file provided with this distribution.
*
* <hr>
*
*/
/*****************************************************************************/
#include "decision_engine.h"
#include "theory_core.h"
#include "search.h"
using namespace std;
using namespace CVC3;
DecisionEngine::DecisionEngine(TheoryCore* core, SearchImplBase* se)
: d_core(core), d_se(se),
d_splitters(core->getCM()->getCurrentContext()),
d_splitterCount(core->getStatistics().counter("splitters"))
{
IF_DEBUG(d_splitters.setName("CDList[SearchEngineDefault.d_splitters]");)
}
/*****************************************************************************/
/*!
* Function: DecisionEngine::findSplitterRec
*
* Author: Clark Barrett
*
* Created: Sun Jul 13 22:47:06 2003
*
* Search the expression e (depth-first) for an atomic formula. Note that in
* order to support the "simplify in-place" option, each sub-expression is
* checked to see if it has a find pointer, and if it does, the find is
* followed instead of continuing to recurse on the given expression.
* \return a NULL expr if no atomic formula is found.
*/
/*****************************************************************************/
Expr DecisionEngine::findSplitterRec(const Expr& e)
{
Expr best;
if(d_visited.count(e) > 0)
return d_visited[e];
if (e.isTrue() || e.isFalse() || e.isAtomic()
|| !d_se->isGoodSplitter(e)) {
d_visited[e] = best;
return best;
}
if (e.isAbsAtomicFormula()) {
d_visited[e] = e;
return e;
}
ExprMap<Expr>::iterator it = d_bestByExpr.find(e);
if (it != d_bestByExpr.end()) {
d_visited[e] = it->second;
return it->second;
}
vector<int> order(e.arity());
int i = 0;
if (e.isITE())
{
order[i++] = 0;
order[i++] = 1;//e.getHighestKid(); // always 1 or 2
order[i++] = 2;//3 - e.getHighestKid();
}
else
{
if (e.arity() > 0)
{
order[i++] = 0;//e.getHighestKid();
for (int k = 0; k < e.arity(); ++k)
if (k != 0)//e.getHighestKid())
order[i++] = k;
}
}
for (int k = 0; k < e.arity(); k++)
{
Expr splitter =
findSplitterRec(d_core->findExpr(e[order[k]]));
if (!splitter.isNull() && (best.isNull() || isBetter(splitter, best)))
best = splitter;
}
d_bestByExpr[e] = best;
d_visited[e] = best;
return best;
}
/*****************************************************************************/
/*!
* Function: DecisionEngine::pushDecision
*
* Author: Clark Barrett
*
* Created: Sun Jul 13 22:55:16 2003
*
* \param splitter
* \param whichCase If true, increment the splitter count and assert the
* splitter. If false, do NOT increment the splitter count and assert the
* negation of the splitter. Defaults to true.
*/
/*****************************************************************************/
void DecisionEngine::pushDecision(Expr splitter, bool whichCase)
{
string stCase = whichCase ? "TRUE" : "FALSE";
if (whichCase) d_splitterCount++;
d_core->getCM()->push();
TRACE("search trace", "Asserting splitter("+stCase+"): ", splitter, "");
TRACE("search", "Asserting splitter("+stCase+"): ", splitter, "");
d_splitters.push_back(splitter);
if (!whichCase)
splitter = splitter.negate();
Theorem thm = d_se->newIntAssumption(splitter);
d_core->addFact(thm);
// Search engine needs to know what original facts it derived or
// split on, so that we don't split on them twice. addFact() may
// simplify these facts before calling addLiteralFact() and lose
// this information. There is no reason to add non-literals though,
// as we never split on them directly.
if(thm.getExpr().isAbsLiteral())
d_se->addLiteralFact(thm);
}
void DecisionEngine::popDecision()
{
d_core->getCM()->pop();
TRACE("search trace", "Pop: scope level =", d_core->getCM()->scopeLevel(), "");
}
void DecisionEngine::popTo(int dl)
{
d_core->getCM()->popto(dl);
TRACE("search trace", "Popto: scope level =", d_core->getCM()->scopeLevel(), "");
}
Expr DecisionEngine::lastSplitter()
{
return d_splitters.back();
}
syntax highlighted by Code2HTML, v. 0.9.1