diff options
author | Andrew Reynolds <andrew.j.reynolds@gmail.com> | 2021-04-12 16:55:44 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-12 21:55:44 +0000 |
commit | 76f495646c0e3a95f2474c5d746bc61ece18f89f (patch) | |
tree | 5390007f4be229dfb18e641f34b9d9df6a9dea92 /src/theory/quantifiers | |
parent | af398235ef9f3a909991fddbb71d43434d6cf3a1 (diff) |
Fix computation of whether a type is finite (#6312)
This PR generalizes TypeNode::isFinite / TypeNode::isInterpretedFinite with TypeNode::getCardinalityClass. It then uses this method to fix our computation of when a type should be treated as finite.
Fixes #4260, fixes #6100 (that benchmark now says unknown without an error).
Diffstat (limited to 'src/theory/quantifiers')
-rw-r--r-- | src/theory/quantifiers/fmf/bounded_integers.cpp | 4 | ||||
-rw-r--r-- | src/theory/quantifiers/fmf/model_engine.cpp | 2 | ||||
-rw-r--r-- | src/theory/quantifiers/quant_bound_inference.cpp | 8 | ||||
-rw-r--r-- | src/theory/quantifiers/quant_split.cpp | 5 | ||||
-rw-r--r-- | src/theory/quantifiers/sygus/sygus_enumerator.cpp | 6 |
5 files changed, 17 insertions, 8 deletions
diff --git a/src/theory/quantifiers/fmf/bounded_integers.cpp b/src/theory/quantifiers/fmf/bounded_integers.cpp index a4f4170fa..b0f6e63bf 100644 --- a/src/theory/quantifiers/fmf/bounded_integers.cpp +++ b/src/theory/quantifiers/fmf/bounded_integers.cpp @@ -357,7 +357,7 @@ void BoundedIntegers::checkOwnership(Node f) // supported for finite element types #1123). Regardless, this is // typically not a limitation since this variable can be bound in a // standard way below since its type is finite. - if (!v.getType().isInterpretedFinite()) + if (!d_qstate.isFiniteType(v.getType())) { setBoundedVar(f, v, BOUND_SET_MEMBER); setBoundVar = true; @@ -417,7 +417,7 @@ void BoundedIntegers::checkOwnership(Node f) for( unsigned i=0; i<f[0].getNumChildren(); i++) { if( d_bound_type[f].find( f[0][i] )==d_bound_type[f].end() ){ TypeNode tn = f[0][i].getType(); - if ((tn.isSort() && tn.isInterpretedFinite()) + if ((tn.isSort() && d_qstate.isFiniteType(tn)) || d_qreg.getQuantifiersBoundInference().mayComplete(tn)) { success = true; diff --git a/src/theory/quantifiers/fmf/model_engine.cpp b/src/theory/quantifiers/fmf/model_engine.cpp index e935ee694..585032dc4 100644 --- a/src/theory/quantifiers/fmf/model_engine.cpp +++ b/src/theory/quantifiers/fmf/model_engine.cpp @@ -133,7 +133,7 @@ void ModelEngine::registerQuantifier( Node f ){ for( unsigned i=0; i<f[0].getNumChildren(); i++ ){ TypeNode tn = f[0][i].getType(); if( !tn.isSort() ){ - if (!tn.isInterpretedFinite()) + if (!d_qstate.isFiniteType(tn)) { if( tn.isInteger() ){ if( !options::fmfBound() ){ diff --git a/src/theory/quantifiers/quant_bound_inference.cpp b/src/theory/quantifiers/quant_bound_inference.cpp index 7b184bf0d..1fbf53761 100644 --- a/src/theory/quantifiers/quant_bound_inference.cpp +++ b/src/theory/quantifiers/quant_bound_inference.cpp @@ -48,8 +48,14 @@ bool QuantifiersBoundInference::mayComplete(TypeNode tn) bool QuantifiersBoundInference::mayComplete(TypeNode tn, unsigned maxCard) { + if (!tn.isClosedEnumerable()) + { + return false; + } bool mc = false; - if (tn.isClosedEnumerable() && tn.isInterpretedFinite()) + // we cannot use FMF to complete interpreted types, thus we pass + // false for fmfEnabled here + if (isCardinalityClassFinite(tn.getCardinalityClass(), false)) { Cardinality c = tn.getCardinality(); if (!c.isLargeFinite()) diff --git a/src/theory/quantifiers/quant_split.cpp b/src/theory/quantifiers/quant_split.cpp index be384d1aa..cc2525b78 100644 --- a/src/theory/quantifiers/quant_split.cpp +++ b/src/theory/quantifiers/quant_split.cpp @@ -52,6 +52,7 @@ void QuantDSplit::checkOwnership(Node q) for( unsigned i=0; i<q[0].getNumChildren(); i++ ){ TypeNode tn = q[0][i].getType(); if( tn.isDatatype() ){ + bool isFinite = d_qstate.isFiniteType(tn); const DType& dt = tn.getDType(); if (dt.isRecursiveSingleton(tn)) { @@ -62,14 +63,14 @@ void QuantDSplit::checkOwnership(Node q) if (options::quantDynamicSplit() == options::QuantDSplitMode::AGG) { // split if it is a finite datatype - doSplit = dt.isInterpretedFinite(tn); + doSplit = isFinite; } else if (options::quantDynamicSplit() == options::QuantDSplitMode::DEFAULT) { if (!qbi.isFiniteBound(q, q[0][i])) { - if (dt.isInterpretedFinite(tn)) + if (isFinite) { // split if goes from being unhandled -> handled by finite // instantiation. An example is datatypes with uninterpreted sort diff --git a/src/theory/quantifiers/sygus/sygus_enumerator.cpp b/src/theory/quantifiers/sygus/sygus_enumerator.cpp index c0fb17dab..83a4276ab 100644 --- a/src/theory/quantifiers/sygus/sygus_enumerator.cpp +++ b/src/theory/quantifiers/sygus/sygus_enumerator.cpp @@ -773,8 +773,10 @@ bool SygusEnumerator::TermEnumMaster::incrementInternal() // have we run out of constructor classes for this size? if (d_ccCons.empty()) { - // check whether we should terminate - if (d_tn.isInterpretedFinite()) + // check whether we should terminate, which notice always treats + // uninterpreted sorts as infinite, since we do not put bounds on them + // in our enumeration. + if (isCardinalityClassFinite(d_tn.getCardinalityClass(), false)) { if (ncc == tc.getNumConstructorClasses()) { |