cvc5-cvc5-1.2.0.src.expr.oracle_caller.cpp Maven / Gradle / Ivy
The newest version!
/******************************************************************************
* Top contributors (to current version):
* Andrew Reynolds, Aina Niemetz
*
* This file is part of the cvc5 project.
*
* Copyright (c) 2009-2024 by the authors listed in the file AUTHORS
* in the top-level source directory and their institutional affiliations.
* All rights reserved. See the file COPYING in the top-level source
* directory for licensing information.
* ****************************************************************************
*
* Oracle caller
*/
#include "expr/oracle_caller.h"
#include "theory/quantifiers/quantifiers_attributes.h"
namespace cvc5::internal {
OracleCaller::OracleCaller(const Node& n)
: d_oracleNode(getOracleFor(n)),
d_oracle(NodeManager::currentNM()->getOracleFor(d_oracleNode))
{
Assert(!d_oracleNode.isNull());
}
bool OracleCaller::callOracle(const Node& fapp, std::vector& res)
{
std::map>::iterator it = d_cachedResults.find(fapp);
if (it != d_cachedResults.end())
{
Trace("oracle-calls") << "Using cached oracle result for " << fapp
<< std::endl;
res = it->second;
// don't bother setting runResult
return false;
}
Assert(fapp.getKind() == Kind::APPLY_UF);
Assert(getOracleFor(fapp.getOperator()) == d_oracleNode);
Trace("oracle-calls") << "Call oracle " << fapp << std::endl;
// get the input arguments from the application
std::vector args(fapp.begin(), fapp.end());
// run the oracle method
std::vector response = d_oracle.run(args);
Trace("oracle-calls") << "response node " << response << std::endl;
// cache the response
d_cachedResults[fapp] = response;
res = response;
return true;
}
bool OracleCaller::isOracleFunction(Node f)
{
return f.hasAttribute(theory::OracleInterfaceAttribute());
}
bool OracleCaller::isOracleFunctionApp(Node n)
{
if (n.getKind() == Kind::APPLY_UF)
{
return isOracleFunction(n.getOperator());
}
// possibly 0-ary
return isOracleFunction(n);
}
Node OracleCaller::getOracleFor(const Node& n)
{
// oracle functions have no children
if (n.isVar())
{
Assert(isOracleFunction(n));
Node o = n.getAttribute(theory::OracleInterfaceAttribute());
Assert(o.getKind() == Kind::ORACLE);
return o;
}
else if (n.getKind() == Kind::FORALL)
{
// oracle interfaces have children, and the attribute is stored in 2nd child
for (const Node& v : n[2][0])
{
if (v.getKind() == Kind::ORACLE)
{
return v;
}
}
}
Assert(false) << "Unexpected node for oracle " << n;
return Node::null();
}
const std::map>& OracleCaller::getCachedResults() const
{
return d_cachedResults;
}
} // namespace cvc5::internal