diff options
Diffstat (limited to 'src/smt/smt_engine.cpp')
-rw-r--r-- | src/smt/smt_engine.cpp | 195 |
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); |