From: Andrew Reynolds Date: Fri, 31 Jul 2020 00:35:22 +0000 (-0500) Subject: Standardize explanations in arrays (#4804) X-Git-Tag: cvc5-1.0.0~3064 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=728b73212dad6a7ec0e2a6a97761f8bbaabee914;p=cvc5.git 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 --- 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;