Fixes the nightlies due to ensuring that a unit test fails in production (it was failing only in debug).
Fixes #8127.
int main()
{
Solver slv;
- Term helloworld = slv.mkVar(slv.getBooleanSort(), "Hello World!");
+ Term helloworld = slv.mkConst(slv.getBooleanSort(), "Hello World!");
std::cout << helloworld << " is " << slv.checkEntailed(helloworld)
<< std::endl;
return 0;
{
try (Solver slv = new Solver())
{
- Term helloworld = slv.mkVar(slv.getBooleanSort(), "Hello World!");
+ Term helloworld = slv.mkConst(slv.getBooleanSort(), "Hello World!");
System.out.println(helloworld + " is " + slv.checkEntailed(helloworld));
}
#include "expr/sequence.h"
#include "expr/type_node.h"
#include "options/base_options.h"
+#include "options/expr_options.h"
#include "options/main_options.h"
#include "options/option_exception.h"
#include "options/options.h"
return true;
}
+void Solver::ensureWellFormedTerm(const Term& t) const
+{
+ // only check if option is set
+ if (d_slv->getOptions().expr.wellFormedChecking)
+ {
+ bool wasShadow = false;
+ if (expr::hasFreeOrShadowedVar(*t.d_node, wasShadow))
+ {
+ std::stringstream se;
+ se << "Cannot process term with " << (wasShadow ? "shadowed" : "free")
+ << " variable";
+ throw CVC5ApiException(se.str().c_str());
+ }
+ }
+}
+
+void Solver::ensureWellFormedTerms(const std::vector<Term>& ts) const
+{
+ // only check if option is set
+ if (d_slv->getOptions().expr.wellFormedChecking)
+ {
+ for (const Term& t : ts)
+ {
+ ensureWellFormedTerm(t);
+ }
+ }
+}
+
void Solver::resetStatistics()
{
if constexpr (configuration::isStatisticsBuild())
<< "Cannot make multiple queries unless incremental solving is enabled "
"(try --incremental)";
CVC5_API_SOLVER_CHECK_TERM(term);
+ ensureWellFormedTerm(term);
//////// all checks before this line
return d_slv->checkEntailed(*term.d_node);
////////
<< "Cannot make multiple queries unless incremental solving is enabled "
"(try --incremental)";
CVC5_API_SOLVER_CHECK_TERMS(terms);
+ ensureWellFormedTerms(terms);
//////// all checks before this line
return d_slv->checkEntailed(Term::termVectorToNodes(terms));
////////
CVC5_API_TRY_CATCH_BEGIN;
CVC5_API_SOLVER_CHECK_TERM(term);
CVC5_API_SOLVER_CHECK_TERM_WITH_SORT(term, getBooleanSort());
+ ensureWellFormedTerm(term);
//////// all checks before this line
d_slv->assertFormula(*term.d_node);
////////
<< "Cannot make multiple queries unless incremental solving is enabled "
"(try --incremental)";
CVC5_API_SOLVER_CHECK_TERM_WITH_SORT(assumption, getBooleanSort());
+ ensureWellFormedTerm(assumption);
//////// all checks before this line
return d_slv->checkSat(*assumption.d_node);
////////
<< "Cannot make multiple queries unless incremental solving is enabled "
"(try --incremental)";
CVC5_API_SOLVER_CHECK_TERMS_WITH_SORT(assumptions, getBooleanSort());
+ ensureWellFormedTerms(assumptions);
//////// all checks before this line
for (const Term& term : assumptions)
{
CVC5_API_RECOVERABLE_CHECK(!term.getSort().isDatatype()
|| term.getSort().getDatatype().isWellFounded())
<< "Cannot get value of a term of non-well-founded datatype sort.";
+ ensureWellFormedTerm(term);
//////// all checks before this line
return getValueHelper(term);
////////
<< "Cannot get value of a term of non-well-founded datatype sort.";
}
CVC5_API_SOLVER_CHECK_TERMS(terms);
+ ensureWellFormedTerms(terms);
//////// all checks before this line
std::vector<Term> res;
CVC5_API_ARG_SIZE_CHECK_EXPECTED(!terms.empty(), terms)
<< "a non-empty set of terms";
CVC5_API_SOLVER_CHECK_TERMS(terms);
+ ensureWellFormedTerms(terms);
//////// all checks before this line
d_slv->blockModelValues(Term::termVectorToNodes(terms));
////////
/** Check whether string s is a valid decimal integer. */
bool isValidInteger(const std::string& s) const;
+ /**
+ * Check that the given term is a valid closed term, which can be used as an
+ * argument to, e.g., assert, get-value, block-model-values, etc.
+ *
+ * @param t The term to check
+ */
+ void ensureWellFormedTerm(const Term& t) const;
+ /** Vector version of above. */
+ void ensureWellFormedTerms(const std::vector<Term>& ts) const;
+
/** Increment the term stats counter. */
void increment_term_stats(Kind kind) const;
/** Increment the vars stats (if 'is_var') or consts stats counter. */
{
solver->setOption("incremental", "false");
}
+ // we don't need to check that terms passed to API methods are well
+ // formed, since this should be an invariant of the parser
+ if (!solver->getOptionInfo("wf-checking").setByUser)
+ {
+ solver->setOption("wf-checking", "false");
+ }
ParserBuilder parserBuilder(
pExecutor->getSolver(), pExecutor->getSymbolManager(), true);
type = "bool"
default = "DO_SEMANTIC_CHECKS_BY_DEFAULT"
help = "type check expressions"
+
+[[option]]
+ name = "wellFormedChecking"
+ category = "regular"
+ long = "wf-checking"
+ type = "bool"
+ default = "true"
+ help = "check that terms passed to API methods are well formed (default false for text interface)"
Result SolverEngine::checkSat(const Node& assumption)
{
+ ensureWellFormedTerm(assumption, "checkSat");
std::vector<Node> assump;
if (!assumption.isNull())
{
Result SolverEngine::checkSat(const std::vector<Node>& assumptions)
{
+ ensureWellFormedTerms(assumptions, "checkSat");
return checkSatInternal(assumptions, false);
}
Result SolverEngine::checkEntailed(const Node& node)
{
+ ensureWellFormedTerm(node, "checkEntailed");
return checkSatInternal(
node.isNull() ? std::vector<Node>() : std::vector<Node>{node},
true)
Result SolverEngine::checkEntailed(const std::vector<Node>& nodes)
{
+ ensureWellFormedTerms(nodes, "checkEntailed");
return checkSatInternal(nodes, true).asEntailmentResult();
}
SolverEngineScope smts(this);
finishInit();
d_state->doPendingPops();
+ ensureWellFormedTerm(formula, "assertFormula");
+ return assertFormulaInternal(formula);
+}
+Result SolverEngine::assertFormulaInternal(const Node& formula)
+{
// as an optimization we do not check whether formula is well-formed here, and
// defer this check for certain cases within the assertions module.
Trace("smt") << "SolverEngine::assertFormula(" << formula << ")" << endl;
d_asserts->assertFormula(n);
return quickCheck().asEntailmentResult();
-} /* SolverEngine::assertFormula() */
+}
/*
--------------------------------------------------------------------------
Node eblocker = mb.getModelBlocker(
eassertsProc, m, d_env->getOptions().smt.blockModelsMode);
Trace("smt") << "Block formula: " << eblocker << std::endl;
- return assertFormula(eblocker);
+ return assertFormulaInternal(eblocker);
}
Result SolverEngine::blockModelValues(const std::vector<Node>& exprs)
ModelBlocker mb(*d_env.get());
Node eblocker = mb.getModelBlocker(
eassertsProc, m, options::BlockModelsMode::VALUES, exprs);
- return assertFormula(eblocker);
+ return assertFormulaInternal(eblocker);
}
std::pair<Node, Node> SolverEngine::getSepHeapAndNilExpr(void)
void SolverEngine::ensureWellFormedTerm(const Node& n,
const std::string& src) const
{
- bool wasShadow = false;
- if (expr::hasFreeOrShadowedVar(n, wasShadow))
+ if (Configuration::isAssertionBuild())
+ {
+ bool wasShadow = false;
+ if (expr::hasFreeOrShadowedVar(n, wasShadow))
+ {
+ std::string varType(wasShadow ? "shadowed" : "free");
+ std::stringstream se;
+ se << "Cannot process term with " << varType << " variable in " << src
+ << ".";
+ throw ModalException(se.str().c_str());
+ }
+ }
+}
+
+void SolverEngine::ensureWellFormedTerms(const std::vector<Node>& ns,
+ const std::string& src) const
+{
+ if (Configuration::isAssertionBuild())
{
- std::string varType(wasShadow ? "shadowed" : "free");
- std::stringstream se;
- se << "Cannot process term with " << varType << " variable in " << src
- << ".";
- throw ModalException(se.str().c_str());
+ for (const Node& n : ns)
+ {
+ ensureWellFormedTerm(n, src);
+ }
}
}
*/
UnsatCore getUnsatCoreInternal();
+ /** Internal version of assertFormula */
+ Result assertFormulaInternal(const Node& formula);
+
/**
* Check that a generated proof checks. This method is the same as printProof,
* but does not print the proof. Like that method, it should be called
* this check fails.
*/
void ensureWellFormedTerm(const Node& n, const std::string& src) const;
+ /** Vector version of above. */
+ void ensureWellFormedTerms(const std::vector<Node>& ns,
+ const std::string& src) const;
/* Members -------------------------------------------------------------- */
ASSERT_FALSE(res_null.isNotEntailed());
ASSERT_FALSE(res_null.isEntailmentUnknown());
Sort u_sort = d_solver.mkUninterpretedSort("u");
- Term x = d_solver.mkVar(u_sort, "x");
+ Term x = d_solver.mkConst(u_sort, "x");
d_solver.assertFormula(x.eqTerm(x));
cvc5::api::Result res = d_solver.checkSat();
ASSERT_FALSE(res.isNull());
TEST_F(TestApiBlackResult, eq)
{
Sort u_sort = d_solver.mkUninterpretedSort("u");
- Term x = d_solver.mkVar(u_sort, "x");
+ Term x = d_solver.mkConst(u_sort, "x");
d_solver.assertFormula(x.eqTerm(x));
cvc5::api::Result res;
cvc5::api::Result res2 = d_solver.checkSat();
TEST_F(TestApiBlackResult, isSat)
{
Sort u_sort = d_solver.mkUninterpretedSort("u");
- Term x = d_solver.mkVar(u_sort, "x");
+ Term x = d_solver.mkConst(u_sort, "x");
d_solver.assertFormula(x.eqTerm(x));
cvc5::api::Result res = d_solver.checkSat();
ASSERT_TRUE(res.isSat());
TEST_F(TestApiBlackResult, isUnsat)
{
Sort u_sort = d_solver.mkUninterpretedSort("u");
- Term x = d_solver.mkVar(u_sort, "x");
+ Term x = d_solver.mkConst(u_sort, "x");
d_solver.assertFormula(x.eqTerm(x).notTerm());
cvc5::api::Result res = d_solver.checkSat();
ASSERT_TRUE(res.isUnsat());
d_solver.setOption("incremental", "false");
d_solver.setOption("solve-int-as-bv", "32");
Sort int_sort = d_solver.getIntegerSort();
- Term x = d_solver.mkVar(int_sort, "x");
+ Term x = d_solver.mkConst(int_sort, "x");
d_solver.assertFormula(x.eqTerm(x).notTerm());
cvc5::api::Result res = d_solver.checkSat();
ASSERT_FALSE(res.isSat());
d_solver.setOption("incremental", "false");
d_solver.setOption("solve-int-as-bv", "32");
Sort int_sort = d_solver.getIntegerSort();
- Term x = d_solver.mkVar(int_sort, "x");
+ Term x = d_solver.mkConst(int_sort, "x");
d_solver.assertFormula(x.eqTerm(x).notTerm());
cvc5::api::Result res = d_solver.checkEntailed(x.eqTerm(x));
ASSERT_FALSE(res.isEntailed());
Term t1040 = slv.defineFun("_f45", {t1014}, t1039.getSort(), t1039);
Term t1072 = slv.mkTerm(Kind::APPLY_UF, {t1040, t510});
Term t1073 = slv.mkTerm(Kind::APPLY_UF, {t73, t1072});
- ASSERT_NO_THROW(slv.checkSatAssuming({t1073, t510}));
+ // the query has free variables, and should throw an exception
+ ASSERT_THROW(slv.checkSatAssuming({t1073, t510}), CVC5ApiException);
}
TEST_F(TestApiBlackSolver, proj_issue436)
assertFalse(res_null.isNotEntailed());
assertFalse(res_null.isEntailmentUnknown());
Sort u_sort = d_solver.mkUninterpretedSort("u");
- Term x = d_solver.mkVar(u_sort, "x");
+ Term x = d_solver.mkConst(u_sort, "x");
d_solver.assertFormula(x.eqTerm(x));
Result res = d_solver.checkSat();
assertFalse(res.isNull());
@Test void eq()
{
Sort u_sort = d_solver.mkUninterpretedSort("u");
- Term x = d_solver.mkVar(u_sort, "x");
+ Term x = d_solver.mkConst(u_sort, "x");
d_solver.assertFormula(x.eqTerm(x));
Result res;
Result res2 = d_solver.checkSat();
@Test void isSat()
{
Sort u_sort = d_solver.mkUninterpretedSort("u");
- Term x = d_solver.mkVar(u_sort, "x");
+ Term x = d_solver.mkConst(u_sort, "x");
d_solver.assertFormula(x.eqTerm(x));
Result res = d_solver.checkSat();
assertTrue(res.isSat());
@Test void isUnsat()
{
Sort u_sort = d_solver.mkUninterpretedSort("u");
- Term x = d_solver.mkVar(u_sort, "x");
+ Term x = d_solver.mkConst(u_sort, "x");
d_solver.assertFormula(x.eqTerm(x).notTerm());
Result res = d_solver.checkSat();
assertTrue(res.isUnsat());
d_solver.setOption("incremental", "false");
d_solver.setOption("solve-int-as-bv", "32");
Sort int_sort = d_solver.getIntegerSort();
- Term x = d_solver.mkVar(int_sort, "x");
+ Term x = d_solver.mkConst(int_sort, "x");
d_solver.assertFormula(x.eqTerm(x).notTerm());
Result res = d_solver.checkSat();
assertFalse(res.isSat());
d_solver.setOption("incremental", "false");
d_solver.setOption("solve-int-as-bv", "32");
Sort int_sort = d_solver.getIntegerSort();
- Term x = d_solver.mkVar(int_sort, "x");
+ Term x = d_solver.mkConst(int_sort, "x");
d_solver.assertFormula(x.eqTerm(x).notTerm());
Result res = d_solver.checkEntailed(x.eqTerm(x));
assertFalse(res.isEntailed());
assert not res_null.isNotEntailed()
assert not res_null.isEntailmentUnknown()
u_sort = solver.mkUninterpretedSort("u")
- x = solver.mkVar(u_sort, "x")
+ x = solver.mkConst(u_sort, "x")
solver.assertFormula(x.eqTerm(x))
res = solver.checkSat()
assert not res.isNull()
def test_eq(solver):
u_sort = solver.mkUninterpretedSort("u")
- x = solver.mkVar(u_sort, "x")
+ x = solver.mkConst(u_sort, "x")
solver.assertFormula(x.eqTerm(x))
res2 = solver.checkSat()
res3 = solver.checkSat()
def test_is_sat(solver):
u_sort = solver.mkUninterpretedSort("u")
- x = solver.mkVar(u_sort, "x")
+ x = solver.mkConst(u_sort, "x")
solver.assertFormula(x.eqTerm(x))
res = solver.checkSat()
assert res.isSat()
def test_is_unsat(solver):
u_sort = solver.mkUninterpretedSort("u")
- x = solver.mkVar(u_sort, "x")
+ x = solver.mkConst(u_sort, "x")
solver.assertFormula(x.eqTerm(x).notTerm())
res = solver.checkSat()
assert res.isUnsat()
solver.setOption("incremental", "false")
solver.setOption("solve-int-as-bv", "32")
int_sort = solver.getIntegerSort()
- x = solver.mkVar(int_sort, "x")
+ x = solver.mkConst(int_sort, "x")
solver.assertFormula(x.eqTerm(x).notTerm())
res = solver.checkSat()
assert not res.isSat()
solver.setOption("incremental", "false")
solver.setOption("solve-int-as-bv", "32")
int_sort = solver.getIntegerSort()
- x = solver.mkVar(int_sort, "x")
+ x = solver.mkConst(int_sort, "x")
solver.assertFormula(x.eqTerm(x).notTerm())
res = solver.checkEntailed(x.eqTerm(x))
assert not res.isEntailed()