The way we construct the model within the nonlinear extension makes using multiple subsolvers that contribute to the model potentially unsound. This PR prevent the coverings solver from being used if extended operators are present, unless --nl-cov-force is given.
Fixes #8515. Fixes #8516.
default = "false"
help = "whether to use the cylindrical algebraic coverings solver for non-linear arithmetic"
+[[option]]
+ name = "nlCovForce"
+ category = "expert"
+ long = "nl-cov-force"
+ type = "bool"
+ default = "false"
+ help = "forces using the cylindrical algebraic coverings solver, even in cases where it is possibly not safe to do so"
+
[[option]]
name = "nlCovVarElim"
category = "expert"
}
}
else if (logic.isQuantified() && logic.isTheoryEnabled(theory::THEORY_ARITH)
- && logic.areRealsUsed() && !logic.areIntegersUsed())
+ && logic.areRealsUsed() && !logic.areIntegersUsed()
+ && !logic.areTranscendentalsUsed())
{
if (!opts.arith.nlCov && !opts.arith.nlCovWasSetByUser)
{
throw LogicException(ss.str());
}
}
+ if (isTranscendentalKind(k) || k == Kind::IAND || k == Kind::POW2)
+ {
+ if (options().arith.nlCov && !options().arith.nlCovForce)
+ {
+ std::stringstream ss;
+ ss << "Term of kind " << printer::smt2::Smt2Printer::smtKindString(k)
+ << " is not compatible with using the coverings-based solver. If you know what you are doing, "
+ "you can try --nl-cov-force, but expect crashes or incorrect results.";
+ throw LogicException(ss.str());
+ }
+ }
}
void NonlinearExtension::processSideEffect(const NlLemma& se)
regress0/nl/issue8161-var-elim.smt2
regress0/nl/issue8226-ran-refinement.smt2
regress0/nl/issue8414-ran-rational.smt2
+ regress0/nl/issue8515-cov-iand.smt2
+ regress0/nl/issue8516-cov-sin.smt2
regress0/nl/lazard-spurious-root.smt2
regress0/nl/magnitude-wrong-1020-m.smt2
regress0/nl/mult-po.smt2
--- /dev/null
+; REQUIRES: poly
+; SCRUBBER: grep -o "Term of kind iand is not compatible"
+; EXPECT: Term of kind iand is not compatible
+; EXIT: 1
+(set-logic ALL)
+(set-option :nl-cov true)
+(set-option :check-models true)
+(declare-fun v () Int)
+(declare-fun a () Int)
+(declare-fun va () Int)
+(assert (and (= 1 (div 0 va)) (> 0 ((_ iand 1) v a))))
+(check-sat)
--- /dev/null
+; REQUIRES: poly
+; SCRUBBER: grep -o "Term of kind sin is not compatible"
+; EXPECT: Term of kind sin is not compatible
+; EXIT: 1
+(set-logic NRAT)
+(set-option :nl-cov true)
+(assert (exists ((r Real)) (distinct 0.0 (sin 1.0))))
+(check-sat)