Send external equalities from collapse selector as lemmas (#5346)
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Mon, 26 Oct 2020 17:18:26 +0000 (12:18 -0500)
committerGitHub <noreply@github.com>
Mon, 26 Oct 2020 17:18:26 +0000 (12:18 -0500)
In 20e58d4, a policy change was made for datatypes to keep more inferences as internal facts.

This leads to a crash (issue #5344) where the equality status of two BV terms is asked by TheoryDatatypes, where the TheoryBV was not informed of the term, as datatypes kept it internal.

This refines the policy further such that the collapse selector rule is processed as a lemma for terms of external type. The reason is that this rule may generate new terms of external type. Other rules like unification retain the internal fact policy, as they do not generate new terms.

Fixes #5344.

FYI @barrettcw

src/theory/datatypes/theory_datatypes.cpp
src/theory/theory.cpp

index 1b557b3cb9859e3bc6446f467c761721af9eb1f1..d60d8af328bfe88222087c5beddeccffabf31331 100644 (file)
@@ -1088,10 +1088,14 @@ void TheoryDatatypes::collapseSelector( Node s, Node c ) {
     {
       Node eq = s.eqNode(rrs);
       Node peq = c.eqNode(s[0]);
+      // Since collapsing selectors may generate new terms, we must send
+      // this out as a lemma if it is of an external type, or otherwise we
+      // may ask for the equality status of terms that only datatypes knows
+      // about, see issue #5344.
+      bool forceLemma = !s.getType().isDatatype();
       Trace("datatypes-infer") << "DtInfer : collapse sel";
-      //Trace("datatypes-infer") << ( wrong ? " wrong" : "");
       Trace("datatypes-infer") << " : " << eq << " by " << peq << std::endl;
-      d_im.addPendingInference(eq, peq, false, InferId::COLLAPSE_SEL);
+      d_im.addPendingInference(eq, peq, forceLemma, InferId::COLLAPSE_SEL);
     }
   }
 }
@@ -1845,6 +1849,7 @@ bool TheoryDatatypes::areDisequal( TNode a, TNode b ){
 }
 
 bool TheoryDatatypes::areCareDisequal( TNode x, TNode y ) {
+  Trace("datatypes-cg") << "areCareDisequal: " << x << " " << y << std::endl;
   Assert(d_equalityEngine->hasTerm(x));
   Assert(d_equalityEngine->hasTerm(y));
   if (d_equalityEngine->isTriggerTerm(x, THEORY_DATATYPES)
index 681f3bca1b0ee58fad4fd5ab758a6a3348316949..78fe6927f9a4a955abd08105d4a0216f3fc74d0a 100644 (file)
@@ -437,6 +437,7 @@ EqualityStatus Theory::getEqualityStatus(TNode a, TNode b)
   {
     return EQUALITY_UNKNOWN;
   }
+  Trace("sharing") << "Theory<" << getId() << ">::getEqualityStatus(" << a << ", " << b << ")" << std::endl;
   Assert(d_equalityEngine->hasTerm(a) && d_equalityEngine->hasTerm(b));
 
   // Check for equality (simplest)