Uses new nested-qe utility for eliminating nested quantification before doing quantifier elimination.
Fixes CVC4/cvc4-wishues#26
Fixes #5484.
#include "expr/subs.h"
#include "smt/smt_solver.h"
+#include "theory/quantifiers/cegqi/nested_qe.h"
#include "theory/quantifiers/extended_rewrite.h"
#include "theory/rewriter.h"
#include "theory/theory_engine.h"
throw ModalException(
"Expecting a quantified formula as argument to get-qe.");
}
+ // do nested quantifier elimination if necessary
+ q = quantifiers::NestedQe::doNestedQe(q, true);
+ Trace("smt-qe") << "QuantElimSolver: after nested quantifier elimination : "
+ << q << std::endl;
NodeManager* nm = NodeManager::currentNM();
// tag the quantified formula with the quant-elim attribute
TypeNode t = nm->booleanType();
Node NestedQe::doNestedQe(Node q, bool keepTopLevel)
{
+ NodeManager* nm = NodeManager::currentNM();
+ Node qOrig = q;
+ bool inputExists = false;
+ if (q.getKind() == kind::EXISTS)
+ {
+ q = nm->mkNode(kind::FORALL, q[0], q[1].negate());
+ inputExists = true;
+ }
Assert(q.getKind() == kind::FORALL);
std::unordered_set<Node, NodeHashFunction> nqs;
if (!getNestedQuantification(q, nqs))
<< "...no nested quantification" << std::endl;
if (keepTopLevel)
{
- return q;
+ return qOrig;
}
// just do ordinary quantifier elimination
Node qqe = doQe(q);
// reconstruct the body
std::vector<Node> qargs;
qargs.push_back(q[0]);
- qargs.push_back(qeBody);
+ qargs.push_back(inputExists ? qeBody.negate() : qeBody);
if (q.getNumChildren() == 3)
{
qargs.push_back(q[2]);
}
- NodeManager* nm = NodeManager::currentNM();
- return nm->mkNode(kind::FORALL, qargs);
+ return nm->mkNode(inputExists ? kind::EXISTS : kind::FORALL, qargs);
}
Node NestedQe::doQe(Node q)
}
else if (computeOption == COMPUTE_PROCESS_TERMS)
{
- return options::elimExtArithQuant()
- || options::iteLiftQuant() != options::IteLiftQuantMode::NONE;
+ return is_std
+ && (options::elimExtArithQuant()
+ || options::iteLiftQuant() != options::IteLiftQuantMode::NONE);
}
else if (computeOption == COMPUTE_COND_SPLIT)
{
regress1/quantifiers/issue5469-aext.smt2
regress1/quantifiers/issue5470-aext.smt2
regress1/quantifiers/issue5471-aext.smt2
+ regress1/quantifiers/issue5484-qe.smt2
+ regress1/quantifiers/issue5484b-qe.smt2
regress1/quantifiers/issue993.smt2
regress1/quantifiers/javafe.ast.StmtVec.009.smt2
regress1/quantifiers/lia-witness-div-pp.smt2
--- /dev/null
+; SCRUBBER: sed 's/(.*)/()/g'
+; EXPECT: ()
+; EXIT: 0
+(set-logic LIA)
+(declare-fun v9 () Bool)
+(declare-fun v18 () Bool)
+(declare-fun i2 () Int)
+(declare-fun v31 () Bool)
+(get-qe (forall ((q23 Int) (q24 Int) (q25 Int) (q26 Int) (q27 Bool) (q28 Int) (q29 Int)) (xor (=> (not (not (distinct 83 407))) (> (- i2 31 722) 319)) (forall ((q23 Int) (q24 Int) (q25 Int) (q26 Int) (q27 Bool) (q28 Int) (q29 Int)) (not (not (not v9)))) v31 (> 665 (+ (mod 83 923) (div i2 850)) 319 (- 939 878)) v18)))
--- /dev/null
+; SCRUBBER: sed 's/(.*)/()/g'
+; EXPECT: ()
+; EXIT: 0
+(set-logic LIA)
+(declare-fun v0 () Bool)
+(declare-fun v1 () Bool)
+(declare-fun v2 () Bool)
+(declare-fun v3 () Bool)
+(declare-fun v4 () Bool)
+(declare-fun v7 () Bool)
+(declare-fun v8 () Bool)
+(declare-fun i6 () Int)
+(declare-fun i9 () Int)
+(declare-fun i11 () Int)
+(declare-fun i13 () Int)
+(declare-fun v9 () Bool)
+(declare-fun i16 () Int)
+(get-qe (forall ((q75 Bool)) (xor (< i9 52) (forall ((q75 Bool)) (not (and (< i16 37) q75 q75 v1))) v2 (and (distinct v4 v3 v4) v9 v9 (and v7 v0 (>= 24 56 i11 i6 7) v0 v8)) (= (+ (div i13 340) 268 i9) i13))))