<< "Iterate through " << propagator->getLearnedLiterals().size()
<< " learned literals." << std::endl;
// No conflict, go through the literals and solve them
+ NodeManager* nm = NodeManager::currentNM();
context::Context* u = userContext();
Rewriter* rw = d_env.getRewriter();
TrustSubstitutionMap& ttls = d_preprocContext->getTopLevelSubstitutions();
Trace("non-clausal-simplify")
<< "conflict with " << learned_literals[i].getNode() << std::endl;
assertionsToPreprocess->clear();
- Node n = NodeManager::currentNM()->mkConst<bool>(false);
+ Node n = nm->mkConst<bool>(false);
assertionsToPreprocess->push_back(n, false, false, d_llpg.get());
return PreprocessingPassResult::CONFLICT;
}
Trace("non-clausal-simplify")
<< "conflict while solving " << learnedLiteral << std::endl;
assertionsToPreprocess->clear();
- Node n = NodeManager::currentNM()->mkConst<bool>(false);
+ Node n = nm->mkConst<bool>(false);
assertionsToPreprocess->push_back(n);
return PreprocessingPassResult::CONFLICT;
}
default:
+ TNode t;
+ TNode c;
if (learnedLiteral.getKind() == kind::EQUAL
&& (learnedLiteral[0].isConst() || learnedLiteral[1].isConst()))
{
// constant propagation
- TNode t;
- TNode c;
if (learnedLiteral[0].isConst())
{
t = learnedLiteral[1];
t = learnedLiteral[0];
c = learnedLiteral[1];
}
+ }
+ else if (options().smt.simplificationBoolConstProp)
+ {
+ // From non-equalities, learn the Boolean equality. Notice that
+ // the equality case above is strictly more powerful that this, since
+ // e.g. (= t c) * { t -> c } also simplifies to true.
+ bool pol = learnedLiteral.getKind() != kind::NOT;
+ c = nm->mkConst(pol);
+ t = pol ? learnedLiteral : learnedLiteral[0];
+ }
+ if (!t.isNull())
+ {
Assert(!t.isConst());
Assert(rewrite(cps.apply(t)) == t);
Assert(top_level_substs.apply(t) == t);
}
else
{
- // Keep the literal
+ // Keep the learned literal
learned_literals[j++] = learned_literals[i];
}
// Its a literal that could not be processed as a substitution or
if (!learnedLitsToConjoin.empty())
{
size_t replIndex = assertionsToPreprocess->getRealAssertionsEnd() - 1;
- Node newConj = NodeManager::currentNM()->mkAnd(learnedLitsToConjoin);
+ Node newConj = nm->mkAnd(learnedLitsToConjoin);
Trace("non-clausal-simplify")
<< "non-clausal simplification, reassert: " << newConj << std::endl;
ProofGenerator* pg = nullptr;
throw OptionException(ss.str());
}
}
+ // check if we have separation logic heap types
+ if (d_env.hasSepHeap())
+ {
+ std::stringstream reasonNoSepLogic;
+ if (incompatibleWithSeparationLogic(opts, reasonNoSepLogic))
+ {
+ std::stringstream ss;
+ ss << reasonNoSepLogic.str()
+ << " not supported when using separation logic.";
+ throw OptionException(ss.str());
+ }
+ }
}
void SetDefaults::setDefaultsPost(const LogicInfo& logic, Options& opts) const
return false;
}
+bool SetDefaults::incompatibleWithSeparationLogic(Options& opts,
+ std::ostream& reason) const
+{
+ if (options().smt.simplificationBoolConstProp)
+ {
+ // Spatial formulas in separation logic have a semantics that depends on
+ // their position in the AST (e.g. their nesting beneath separation
+ // conjunctions). Thus, we cannot apply BCP as a substitution for spatial
+ // predicates to the input formula. We disable this option altogether to
+ // ensure this is the case
+ notifyModifyOption("simplification-bcp", "false", "separation logic");
+ options().smt.simplificationBoolConstProp = false;
+ }
+ return false;
+}
+
void SetDefaults::widenLogic(LogicInfo& logic, const Options& opts) const
{
bool needsUf = false;
* The output stream reason is similar to above.
*/
bool incompatibleWithQuantifiers(Options& opts, std::ostream& reason) const;
+ /**
+ * Check if incompatible with separation logic. Notice this method may
+ * modify the options to ensure that we are compatible with separation logic.
+ * The output stream reason is similar to above.
+ */
+ bool incompatibleWithSeparationLogic(Options& opts,
+ std::ostream& reason) const;
//------------------------- options setting, prior finalization of logic
/**
* Set defaults pre, which sets all options prior to finalizing the logic.