There was a bug in CEGQI's needModel method which could say that it doesnt need a model built when there are no active quantifiers. However, computing active quantifiers is not done in QuantifiersEngine::check until after this method is called, meaning it was using stale data on whether a quantifier was active or not. This could lead to the use of bogus models in CEGQI in incremental mode in some corner cases, leading to the assertion failure in #5019.
Fixes #5019.
QuantifiersModule::QEffort InstStrategyCegqi::needsModel(Theory::Effort e)
{
- for( unsigned i=0; i<d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){
+ size_t nquant = d_quantEngine->getModel()->getNumAssertedQuantifiers();
+ for (size_t i = 0; i < nquant; i++)
+ {
Node q = d_quantEngine->getModel()->getAssertedQuantifier( i );
- if( doCbqi( q ) && d_quantEngine->getModel()->isQuantifierActive( q ) ){
+ if (doCbqi(q))
+ {
return QEFFORT_STANDARD;
}
}
}
}
-unsigned FirstOrderModel::getNumAssertedQuantifiers() {
+size_t FirstOrderModel::getNumAssertedQuantifiers() const
+{
return d_forall_asserts.size();
}
/** assert quantifier */
void assertQuantifier( Node n );
/** get number of asserted quantifiers */
- unsigned getNumAssertedQuantifiers();
+ size_t getNumAssertedQuantifiers() const;
/** get asserted quantifier */
Node getAssertedQuantifier( unsigned i, bool ordered = false );
/** initialize model for term */
regress1/quantifiers/issue4290-cegqi-r.smt2
regress1/quantifiers/issue4620-erq-witness-unsound.smt2
regress1/quantifiers/issue4685-wrewrite.smt2
+ regress1/quantifiers/issue5019-cegqi-i.smt2
regress1/quantifiers/issue993.smt2
regress1/quantifiers/javafe.ast.StmtVec.009.smt2
regress1/quantifiers/lra-vts-inf.smt2
--- /dev/null
+; COMMAND-LINE: --incremental
+; EXPECT: sat
+; EXPECT: sat
+(set-logic BV)
+(declare-const v4 Bool)
+(assert (forall ((q0 Bool) (q1 Bool)) (xor true true q1 v4 q1 true true true true true true)))
+(push 1)
+(check-sat)
+(pop 1)
+(check-sat)