From: Andrew Reynolds Date: Fri, 25 Feb 2022 17:15:00 +0000 (-0600) Subject: Fix dropped bounds on PI (#8164) X-Git-Tag: cvc5-1.0.0~376 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=3428c0e156cdb3b079ae57bc8ba3805edb5d9c88;p=cvc5.git Fix dropped bounds on PI (#8164) Fixes #8162. In this example, we were failing to send the initial PI bound lemma, likely due to a conflict while this lemma was buffered. This makes the PI refinement utility more robust by explicitly checking based on the model whether we need to refine PI. --- diff --git a/src/theory/arith/nl/transcendental/transcendental_state.cpp b/src/theory/arith/nl/transcendental/transcendental_state.cpp index 3ef9834e7..3f003823c 100644 --- a/src/theory/arith/nl/transcendental/transcendental_state.cpp +++ b/src/theory/arith/nl/transcendental/transcendental_state.cpp @@ -133,9 +133,12 @@ void TranscendentalState::init(const std::vector& xts, } } // initialize pi if necessary - if (needPi && d_pi.isNull()) + if (needPi) { - mkPi(); + if (d_pi.isNull()) + { + mkPi(); + } getCurrentPiBounds(); } @@ -218,18 +221,28 @@ void TranscendentalState::mkPi() void TranscendentalState::getCurrentPiBounds() { - NodeManager* nm = NodeManager::currentNM(); - Node pi_lem = nm->mkNode(Kind::AND, - nm->mkNode(Kind::GEQ, d_pi, d_pi_bound[0]), - nm->mkNode(Kind::LEQ, d_pi, d_pi_bound[1])); - CDProof* proof = nullptr; - if (isProofEnabled()) + Assert(!d_pi.isNull()); + Node piv = d_model.computeAbstractModelValue(d_pi); + // If the current value of PI is not initialized, or not within bounds, add + // the lemma. Notice that this preempts the need to explicitly track which + // lemmas regarding the bound of PI have been added. + if (!piv.isConst() + || piv.getConst() < d_pi_bound[0].getConst() + || piv.getConst() > d_pi_bound[1].getConst()) { - proof = getProof(); - proof->addStep( - pi_lem, PfRule::ARITH_TRANS_PI, {}, {d_pi_bound[0], d_pi_bound[1]}); + NodeManager* nm = NodeManager::currentNM(); + Node pi_lem = nm->mkNode(Kind::AND, + nm->mkNode(Kind::GEQ, d_pi, d_pi_bound[0]), + nm->mkNode(Kind::LEQ, d_pi, d_pi_bound[1])); + CDProof* proof = nullptr; + if (isProofEnabled()) + { + proof = getProof(); + proof->addStep( + pi_lem, PfRule::ARITH_TRANS_PI, {}, {d_pi_bound[0], d_pi_bound[1]}); + } + d_im.addPendingLemma(pi_lem, InferenceId::ARITH_NL_T_PI_BOUND, proof); } - d_im.addPendingLemma(pi_lem, InferenceId::ARITH_NL_T_PI_BOUND, proof); } std::pair TranscendentalState::getClosestSecantPoints(TNode e, @@ -299,6 +312,8 @@ NlLemma TranscendentalState::mkSecantLemma(TNode lower, TNode splane, unsigned actual_d) { + Assert(lower.isConst() && upper.isConst()); + Assert(lower.getConst() < upper.getConst()); NodeManager* nm = NodeManager::currentNM(); // With respect to Figure 3, this is slightly different. // In particular, we chose b to be the model value of bounds[s], @@ -325,7 +340,9 @@ NlLemma TranscendentalState::mkSecantLemma(TNode lower, antec_n, nm->mkNode( convexity == Convexity::CONVEX ? Kind::LEQ : Kind::GEQ, tf, splane)); - Trace("nl-trans-lemma") << "*** Secant plane lemma : " << lem << std::endl; + Trace("nl-trans-lemma") << "*** Secant plane lemma : " << lem << ", value=" + << d_model.computeAbstractModelValue(lem) + << std::endl; Assert(d_model.computeAbstractModelValue(lem) == d_false); CDProof* proof = nullptr; if (isProofEnabled()) diff --git a/test/regress/CMakeLists.txt b/test/regress/CMakeLists.txt index 64e933ff9..e9c4e98a5 100644 --- a/test/regress/CMakeLists.txt +++ b/test/regress/CMakeLists.txt @@ -1913,6 +1913,7 @@ set(regress_1_tests regress1/nl/issue8016-iand-rewrite.smt2 regress1/nl/issue8052-iand-rewrite.smt2 regress1/nl/issue8118-elim-sin.smt2 + regress1/nl/issue8162-drop-pi-bound.smt2 regress1/nl/metitarski-1025.smt2 regress1/nl/metitarski-3-4.smt2 regress1/nl/metitarski_3_4_2e.smt2 diff --git a/test/regress/regress1/nl/issue8162-drop-pi-bound.smt2 b/test/regress/regress1/nl/issue8162-drop-pi-bound.smt2 new file mode 100644 index 000000000..23e6fa17d --- /dev/null +++ b/test/regress/regress1/nl/issue8162-drop-pi-bound.smt2 @@ -0,0 +1,8 @@ +; COMMAND-LINE: -q +; EXPECT: sat +(set-logic ALL) +(set-info :status sat) +(declare-fun v () Real) +(assert (xor (= 0 (/ v 0)) (distinct 1 (/ 0 0)))) +(assert (forall ((V Real)) (distinct 0 (sin 1.0)))) +(check-sat)