summaryrefslogtreecommitdiff
path: root/src/smt/smt_engine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/smt/smt_engine.cpp')
-rw-r--r--src/smt/smt_engine.cpp195
1 files changed, 148 insertions, 47 deletions
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index 68b7e2251..d035f88c1 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -4,7 +4,7 @@
** Top contributors (to current version):
** Morgan Deters, Andrew Reynolds, Tim King
** This file is part of the CVC4 project.
- ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS
+ ** Copyright (c) 2009-2019 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.\endverbatim
@@ -111,6 +111,10 @@
#include "util/random.h"
#include "util/resource_manager.h"
+#if (IS_LFSC_BUILD && IS_PROOFS_BUILD)
+#include "lfscc.h"
+#endif
+
using namespace std;
using namespace CVC4;
using namespace CVC4::smt;
@@ -120,6 +124,11 @@ using namespace CVC4::context;
using namespace CVC4::theory;
namespace CVC4 {
+
+namespace proof {
+extern const char* const plf_signatures;
+} // namespace proof
+
namespace smt {
struct DeleteCommandFunction : public std::unary_function<const Command*, void>
@@ -178,10 +187,12 @@ struct SmtEngineStatistics {
IntStat d_numAssertionsPre;
/** Num of assertions after ite removal */
IntStat d_numAssertionsPost;
+ /** Size of all proofs generated */
+ IntStat d_proofsSize;
/** time spent in checkModel() */
TimerStat d_checkModelTime;
- /** time spent in checkProof() */
- TimerStat d_checkProofTime;
+ /** time spent checking the proof with LFSC */
+ TimerStat d_lfscCheckProofTime;
/** time spent in checkUnsatCore() */
TimerStat d_checkUnsatCoreTime;
/** time spent in PropEngine::checkSat() */
@@ -196,28 +207,30 @@ struct SmtEngineStatistics {
/** Number of resource units spent. */
ReferenceStat<uint64_t> d_resourceUnitsUsed;
- SmtEngineStatistics() :
- d_definitionExpansionTime("smt::SmtEngine::definitionExpansionTime"),
- d_numConstantProps("smt::SmtEngine::numConstantProps", 0),
- d_cnfConversionTime("smt::SmtEngine::cnfConversionTime"),
- d_numAssertionsPre("smt::SmtEngine::numAssertionsPreITERemoval", 0),
- d_numAssertionsPost("smt::SmtEngine::numAssertionsPostITERemoval", 0),
- d_checkModelTime("smt::SmtEngine::checkModelTime"),
- d_checkProofTime("smt::SmtEngine::checkProofTime"),
- d_checkUnsatCoreTime("smt::SmtEngine::checkUnsatCoreTime"),
- d_solveTime("smt::SmtEngine::solveTime"),
- d_pushPopTime("smt::SmtEngine::pushPopTime"),
- d_processAssertionsTime("smt::SmtEngine::processAssertionsTime"),
- d_simplifiedToFalse("smt::SmtEngine::simplifiedToFalse", 0),
- d_resourceUnitsUsed("smt::SmtEngine::resourceUnitsUsed")
- {
+ SmtEngineStatistics()
+ : d_definitionExpansionTime("smt::SmtEngine::definitionExpansionTime"),
+ d_numConstantProps("smt::SmtEngine::numConstantProps", 0),
+ d_cnfConversionTime("smt::SmtEngine::cnfConversionTime"),
+ d_numAssertionsPre("smt::SmtEngine::numAssertionsPreITERemoval", 0),
+ d_numAssertionsPost("smt::SmtEngine::numAssertionsPostITERemoval", 0),
+ d_proofsSize("smt::SmtEngine::proofsSize", 0),
+ d_checkModelTime("smt::SmtEngine::checkModelTime"),
+ d_lfscCheckProofTime("smt::SmtEngine::lfscCheckProofTime"),
+ d_checkUnsatCoreTime("smt::SmtEngine::checkUnsatCoreTime"),
+ d_solveTime("smt::SmtEngine::solveTime"),
+ d_pushPopTime("smt::SmtEngine::pushPopTime"),
+ d_processAssertionsTime("smt::SmtEngine::processAssertionsTime"),
+ d_simplifiedToFalse("smt::SmtEngine::simplifiedToFalse", 0),
+ d_resourceUnitsUsed("smt::SmtEngine::resourceUnitsUsed")
+ {
smtStatisticsRegistry()->registerStat(&d_definitionExpansionTime);
smtStatisticsRegistry()->registerStat(&d_numConstantProps);
smtStatisticsRegistry()->registerStat(&d_cnfConversionTime);
smtStatisticsRegistry()->registerStat(&d_numAssertionsPre);
smtStatisticsRegistry()->registerStat(&d_numAssertionsPost);
+ smtStatisticsRegistry()->registerStat(&d_proofsSize);
smtStatisticsRegistry()->registerStat(&d_checkModelTime);
- smtStatisticsRegistry()->registerStat(&d_checkProofTime);
+ smtStatisticsRegistry()->registerStat(&d_lfscCheckProofTime);
smtStatisticsRegistry()->registerStat(&d_checkUnsatCoreTime);
smtStatisticsRegistry()->registerStat(&d_solveTime);
smtStatisticsRegistry()->registerStat(&d_pushPopTime);
@@ -232,8 +245,9 @@ struct SmtEngineStatistics {
smtStatisticsRegistry()->unregisterStat(&d_cnfConversionTime);
smtStatisticsRegistry()->unregisterStat(&d_numAssertionsPre);
smtStatisticsRegistry()->unregisterStat(&d_numAssertionsPost);
+ smtStatisticsRegistry()->unregisterStat(&d_proofsSize);
smtStatisticsRegistry()->unregisterStat(&d_checkModelTime);
- smtStatisticsRegistry()->unregisterStat(&d_checkProofTime);
+ smtStatisticsRegistry()->unregisterStat(&d_lfscCheckProofTime);
smtStatisticsRegistry()->unregisterStat(&d_checkUnsatCoreTime);
smtStatisticsRegistry()->unregisterStat(&d_solveTime);
smtStatisticsRegistry()->unregisterStat(&d_pushPopTime);
@@ -865,6 +879,7 @@ SmtEngine::SmtEngine(ExprManager* em)
d_defineCommands(),
d_logic(),
d_originalOptions(),
+ d_isInternalSubsolver(false),
d_pendingPops(0),
d_fullyInited(false),
d_problemExtended(false),
@@ -1195,6 +1210,12 @@ void SmtEngine::setDefaults() {
if(options::forceLogicString.wasSetByUser()) {
d_logic = LogicInfo(options::forceLogicString());
}else if (options::solveIntAsBV() > 0) {
+ if (!(d_logic <= LogicInfo("QF_NIA")))
+ {
+ throw OptionException(
+ "--solve-int-as-bv=X only supported for pure integer logics (QF_NIA, "
+ "QF_LIA, QF_IDL)");
+ }
d_logic = LogicInfo("QF_BV");
}else if (d_logic.getLogicString() == "QF_NRA" && options::solveRealAsInt()) {
d_logic = LogicInfo("QF_NIA");
@@ -1244,16 +1265,20 @@ void SmtEngine::setDefaults() {
}
// sygus inference may require datatypes
- if (options::sygusInference() || options::sygusRewSynthInput())
+ if (!d_isInternalSubsolver)
{
- d_logic = d_logic.getUnlockedCopy();
- // sygus requires arithmetic, datatypes and quantifiers
- d_logic.enableTheory(THEORY_ARITH);
- d_logic.enableTheory(THEORY_DATATYPES);
- d_logic.enableTheory(THEORY_QUANTIFIERS);
- d_logic.lock();
- // since we are trying to recast as sygus, we assume the input is sygus
- is_sygus = true;
+ if (options::sygusInference() || options::sygusRewSynthInput()
+ || options::sygusAbduct())
+ {
+ d_logic = d_logic.getUnlockedCopy();
+ // sygus requires arithmetic, datatypes and quantifiers
+ d_logic.enableTheory(THEORY_ARITH);
+ d_logic.enableTheory(THEORY_DATATYPES);
+ d_logic.enableTheory(THEORY_QUANTIFIERS);
+ d_logic.lock();
+ // since we are trying to recast as sygus, we assume the input is sygus
+ is_sygus = true;
+ }
}
if ((options::checkModels() || options::checkSynthSol()
@@ -1938,8 +1963,16 @@ void SmtEngine::setDefaults() {
options::sygusExtRew.set(false);
}
}
+ if (options::sygusAbduct())
+ {
+ // if doing abduction, we should filter strong solutions
+ if (!options::sygusFilterSolMode.wasSetByUser())
+ {
+ options::sygusFilterSolMode.set(quantifiers::SYGUS_FILTER_SOL_STRONG);
+ }
+ }
if (options::sygusRewSynth() || options::sygusRewVerify()
- || options::sygusQueryGen())
+ || options::sygusQueryGen() || options::sygusAbduct())
{
// rewrite rule synthesis implies that sygus stream must be true
options::sygusStream.set(true);
@@ -1947,8 +1980,9 @@ void SmtEngine::setDefaults() {
if (options::sygusStream())
{
// Streaming is incompatible with techniques that focus the search towards
- // finding a single solution. This currently includes the PBE solver and
- // static template inference for invariant synthesis.
+ // finding a single solution. This currently includes the PBE solver,
+ // static template inference for invariant synthesis, and single
+ // invocation techniques.
if (!options::sygusUnifPbe.wasSetByUser())
{
options::sygusUnifPbe.set(false);
@@ -1962,6 +1996,10 @@ void SmtEngine::setDefaults() {
{
options::sygusInvTemplMode.set(quantifiers::SYGUS_INV_TEMPL_MODE_NONE);
}
+ if (!options::cegqiSingleInvMode.wasSetByUser())
+ {
+ options::cegqiSingleInvMode.set(quantifiers::CEGQI_SI_MODE_NONE);
+ }
}
//do not allow partial functions
if( !options::bitvectorDivByZeroConst.wasSetByUser() ){
@@ -2262,11 +2300,13 @@ void SmtEngine::setDefaults() {
"--sygus-expr-miner-check-timeout=N requires "
"--sygus-expr-miner-check-use-export");
}
- if (options::sygusRewSynthInput())
+ if (options::sygusRewSynthInput() || options::sygusAbduct())
{
- throw OptionException(
- "--sygus-rr-synth-input requires "
- "--sygus-expr-miner-check-use-export");
+ std::stringstream ss;
+ ss << (options::sygusRewSynthInput() ? "--sygus-rr-synth-input"
+ : "--sygus-abduct");
+ ss << "requires --sygus-expr-miner-check-use-export";
+ throw OptionException(ss.str());
}
}
@@ -3294,10 +3334,6 @@ void SmtEnginePrivate::processAssertions() {
d_smt.d_fmfRecFunctionsDefined->push_back( f );
}
}
- if (options::sygusInference())
- {
- d_passes["sygus-infer"]->apply(&d_assertions);
- }
}
if( options::sortInference() || options::ufssFairnessMonotone() ){
@@ -3308,10 +3344,22 @@ void SmtEnginePrivate::processAssertions() {
d_passes["pseudo-boolean-processor"]->apply(&d_assertions);
}
- if (options::sygusRewSynthInput())
+ // rephrasing normal inputs as sygus problems
+ if (!d_smt.d_isInternalSubsolver)
{
- // do candidate rewrite rule synthesis
- d_passes["synth-rr"]->apply(&d_assertions);
+ if (options::sygusInference())
+ {
+ d_passes["sygus-infer"]->apply(&d_assertions);
+ }
+ else if (options::sygusAbduct())
+ {
+ d_passes["sygus-abduct"]->apply(&d_assertions);
+ }
+ else if (options::sygusRewSynthInput())
+ {
+ // do candidate rewrite rule synthesis
+ d_passes["synth-rr"]->apply(&d_assertions);
+ }
}
Trace("smt-proc") << "SmtEnginePrivate::processAssertions() : pre-simplify" << endl;
@@ -3545,8 +3593,10 @@ Result SmtEngine::checkSat(const vector<Expr>& assumptions, bool inUnsatCore)
Result SmtEngine::query(const Expr& assumption, bool inUnsatCore)
{
- Assert(!assumption.isNull());
- return checkSatisfiability(assumption, inUnsatCore, true);
+ return checkSatisfiability(
+ assumption.isNull() ? std::vector<Expr>() : std::vector<Expr>{assumption},
+ inUnsatCore,
+ true);
}
Result SmtEngine::query(const vector<Expr>& assumptions, bool inUnsatCore)
@@ -3559,7 +3609,7 @@ Result SmtEngine::checkSatisfiability(const Expr& expr,
bool isQuery)
{
return checkSatisfiability(
- expr.isNull() ? vector<Expr>() : vector<Expr>{expr},
+ expr.isNull() ? std::vector<Expr>() : std::vector<Expr>{expr},
inUnsatCore,
isQuery);
}
@@ -3712,7 +3762,6 @@ Result SmtEngine::checkSatisfiability(const vector<Expr>& assumptions,
// Check that UNSAT results generate a proof correctly.
if(options::checkProofs()) {
if(r.asSatisfiabilityResult().isSat() == Result::UNSAT) {
- TimerStat::CodeTimer checkProofTimer(d_stats->d_checkProofTime);
checkProof();
}
}
@@ -4367,6 +4416,57 @@ Expr SmtEngine::getSepHeapExpr() { return getSepHeapAndNilExpr().first; }
Expr SmtEngine::getSepNilExpr() { return getSepHeapAndNilExpr().second; }
+void SmtEngine::checkProof()
+{
+#if (IS_LFSC_BUILD && IS_PROOFS_BUILD)
+
+ Chat() << "generating proof..." << endl;
+
+ const Proof& pf = getProof();
+
+ Chat() << "checking proof..." << endl;
+
+ std::string logicString = d_logic.getLogicString();
+
+ if (!(
+ // Pure logics
+ logicString == "QF_UF" || logicString == "QF_AX"
+ || logicString == "QF_BV" ||
+ // Non-pure logics
+ logicString == "QF_AUF" || logicString == "QF_UFBV"
+ || logicString == "QF_ABV" || logicString == "QF_AUFBV"))
+ {
+ // This logic is not yet supported
+ Notice() << "Notice: no proof-checking for " << logicString << " proofs yet"
+ << endl;
+ return;
+ }
+
+ std::stringstream pfStream;
+
+ pfStream << proof::plf_signatures << endl;
+ int64_t sizeBeforeProof = static_cast<int64_t>(pfStream.tellp());
+
+ pf.toStream(pfStream);
+ d_stats->d_proofsSize +=
+ static_cast<int64_t>(pfStream.tellp()) - sizeBeforeProof;
+
+ {
+ TimerStat::CodeTimer checkProofTimer(d_stats->d_lfscCheckProofTime);
+ lfscc_init();
+ lfscc_check_file(pfStream, false, false, false, false, false, false, false);
+ }
+ // FIXME: we should actually call lfscc_cleanup here, but lfscc_cleanup
+ // segfaults on regress0/bv/core/bitvec7.smt
+ // lfscc_cleanup();
+
+#else /* (IS_LFSC_BUILD && IS_PROOFS_BUILD) */
+ Unreachable(
+ "This version of CVC4 was built without proof support; cannot check "
+ "proofs.");
+#endif /* (IS_LFSC_BUILD && IS_PROOFS_BUILD) */
+}
+
UnsatCore SmtEngine::getUnsatCoreInternal()
{
#if IS_PROOFS_BUILD
@@ -5225,6 +5325,7 @@ void SmtEngine::setOption(const std::string& key, const CVC4::SExpr& value)
nodeManagerOptions.setOption(key, optionarg);
}
+void SmtEngine::setIsInternalSubsolver() { d_isInternalSubsolver = true; }
CVC4::SExpr SmtEngine::getOption(const std::string& key) const
{
NodeManagerScope nms(d_nodeManager);
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback