From 728b73212dad6a7ec0e2a6a97761f8bbaabee914 Mon Sep 17 00:00:00 2001 From: Andrew Reynolds Date: Thu, 30 Jul 2020 19:35:22 -0500 Subject: [PATCH] Standardize explanations in arrays (#4804) Some internal inferences had a non-standard way of providing (disjunctive) reasons and a custom way of explaining them. This PR simplifies the array solver so that its explanations are analogous to the other equality engine based theory solvers (strings, datatypes, sets, ...). This is done in preparation for the incorporation of the proof equality engine in arrays, which follows a standard design for reasons/explanations. The performance impact on QF arrays is negligible --- src/theory/arrays/theory_arrays.cpp | 53 ++++++++++++----------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/src/theory/arrays/theory_arrays.cpp b/src/theory/arrays/theory_arrays.cpp index 27e49d2ce..245da617b 100644 --- a/src/theory/arrays/theory_arrays.cpp +++ b/src/theory/arrays/theory_arrays.cpp @@ -431,16 +431,22 @@ void TheoryArrays::explain(TNode literal, std::vector& assumptions, } else { d_equalityEngine.explainPredicate(atom, polarity, assumptions, proof); } - if(proof){ - Debug("pf::array") << " Proof is : " << std::endl; - proof->debug_print("pf::array"); - } + if (Debug.isOn("pf::array")) + { + if (proof) + { + Debug("pf::array") << " Proof is : " << std::endl; + proof->debug_print("pf::array"); + } - Debug("pf::array") << "Array: explain( " << literal << " ):" << std::endl << "\t"; - for (unsigned i = 0; i < assumptions.size(); ++i) { - Debug("pf::array") << assumptions[i] << " "; + Debug("pf::array") << "Array: explain( " << literal << " ):" << std::endl + << "\t"; + for (unsigned i = 0; i < assumptions.size(); ++i) + { + Debug("pf::array") << assumptions[i] << " "; + } + Debug("pf::array") << std::endl; } - Debug("pf::array") << std::endl; } TNode TheoryArrays::weakEquivGetRep(TNode node) { @@ -1526,10 +1532,12 @@ void TheoryArrays::check(Effort e) { Node TheoryArrays::mkAnd(std::vector& conjunctions, bool invert, unsigned startIndex) { - Assert(conjunctions.size() > 0); + if (conjunctions.empty()) + { + return invert ? d_false : d_true; + } std::set all; - std::set explained; unsigned i = startIndex; TNode t; @@ -1546,23 +1554,6 @@ Node TheoryArrays::mkAnd(std::vector& conjunctions, bool invert, unsigned all.insert(*child_it); } } - else if (t.getKind() == kind::OR) { - // Expand explanation resulting from propagating a ROW or EXT lemma - if ((explained.find(t) == explained.end())) { - if (t[1].getKind() == kind::EQUAL) { - // ROW lemma - d_equalityEngine.explainEquality(t[1][0], t[1][1], false, conjunctions); - explained.insert(t); - } else { - // EXT lemma - Assert(t[1].getKind() == kind::NOT - && t[1][0].getKind() == kind::EQUAL); - Assert(t[0].getKind() == kind::EQUAL); - all.insert(t[0].notNode()); - explained.insert(t); - } - } - } else { all.insert(t); } @@ -1930,8 +1921,8 @@ void TheoryArrays::propagate(RowLemmaType lem) if (d_equalityEngine.areDisequal(i,j,true) && (bothExist || prop > 1)) { Trace("arrays-lem") << spaces(getSatContext()->getLevel()) <<"Arrays::queueRowLemma: propagating aj = bj ("<mkNode(kind::OR, aj_eq_bj, i_eq_j); + Node reason = + (i.isConst() && j.isConst()) ? d_true : i.eqNode(j).notNode(); d_permRef.push_back(reason); if (!ajExists) { preRegisterTermInternal(aj); @@ -1945,9 +1936,9 @@ void TheoryArrays::propagate(RowLemmaType lem) } if (bothExist && d_equalityEngine.areDisequal(aj,bj,true)) { Trace("arrays-lem") << spaces(getSatContext()->getLevel()) <<"Arrays::queueRowLemma: propagating i = j ("<mkNode(kind::OR, i_eq_j, aj_eq_bj); d_permRef.push_back(reason); d_equalityEngine.assertEquality(i_eq_j, true, reason, d_reasonRow); ++d_numProp; -- 2.30.2