summaryrefslogtreecommitdiff
path: root/src/theory/quantifiers
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2021-05-21 16:27:19 -0500
committerGitHub <noreply@github.com>2021-05-21 21:27:19 +0000
commit8829c2cbb569296c188ef4285c7fe9568148f48a (patch)
tree5168211afd7f2d380b1d9ece36b3ec8e3ba24117 /src/theory/quantifiers
parent08218e74b729bd7da4d95ecd77bdd696a22bb687 (diff)
Fix and refactor relevant domain (#6528)
In a handcrafted case, one can make the body of quantified formula another quantified formula when special attributes are used. The relevant domain utility was not robust to this case, leading to instantiations with free variables. This fixes the issue and also updates its style to use a term context stack, which also avoids a tree traversal of the bodies of quantified formulas in this utility. Fixes #6476. The benchmark from that issue now times out.
Diffstat (limited to 'src/theory/quantifiers')
-rw-r--r--src/theory/quantifiers/relevant_domain.cpp65
-rw-r--r--src/theory/quantifiers/relevant_domain.h4
2 files changed, 56 insertions, 13 deletions
diff --git a/src/theory/quantifiers/relevant_domain.cpp b/src/theory/quantifiers/relevant_domain.cpp
index fab691061..7e2c0c909 100644
--- a/src/theory/quantifiers/relevant_domain.cpp
+++ b/src/theory/quantifiers/relevant_domain.cpp
@@ -15,6 +15,8 @@
#include "theory/quantifiers/relevant_domain.h"
+#include "expr/term_context.h"
+#include "expr/term_context_stack.h"
#include "theory/arith/arith_msum.h"
#include "theory/quantifiers/first_order_model.h"
#include "theory/quantifiers/quantifiers_registry.h"
@@ -119,7 +121,7 @@ void RelevantDomain::compute(){
Node q = fm->getAssertedQuantifier( i );
Node icf = d_qreg.getInstConstantBody(q);
Trace("rel-dom-debug") << "compute relevant domain for " << icf << std::endl;
- computeRelevantDomain( q, icf, true, true );
+ computeRelevantDomain(q);
}
Trace("rel-dom-debug") << "account for ground terms" << std::endl;
@@ -161,11 +163,58 @@ void RelevantDomain::compute(){
}
}
-void RelevantDomain::computeRelevantDomain( Node q, Node n, bool hasPol, bool pol ) {
+void RelevantDomain::computeRelevantDomain(Node q)
+{
+ Assert(q.getKind() == FORALL);
+ Node n = d_qreg.getInstConstantBody(q);
+ // we care about polarity in the traversal, so we use a polarity term context
+ PolarityTermContext tc;
+ TCtxStack ctx(&tc);
+ ctx.pushInitial(n);
+ std::unordered_set<std::pair<Node, uint32_t>,
+ PairHashFunction<Node, uint32_t, std::hash<Node> > >
+ visited;
+ std::pair<Node, uint32_t> curr;
+ Node node;
+ uint32_t nodeVal;
+ std::unordered_set<
+ std::pair<Node, uint32_t>,
+ PairHashFunction<Node, uint32_t, std::hash<Node> > >::const_iterator itc;
+ bool hasPol, pol;
+ while (!ctx.empty())
+ {
+ curr = ctx.getCurrent();
+ itc = visited.find(curr);
+ ctx.pop();
+ if (itc == visited.end())
+ {
+ visited.insert(curr);
+ node = curr.first;
+ // if not a quantified formula
+ if (!node.isClosure())
+ {
+ nodeVal = curr.second;
+ // get the polarity of the current term and process it
+ PolarityTermContext::getFlags(nodeVal, hasPol, pol);
+ computeRelevantDomainNode(q, node, hasPol, pol);
+ // traverse the children
+ ctx.pushChildren(node, nodeVal);
+ }
+ }
+ }
+}
+
+void RelevantDomain::computeRelevantDomainNode(Node q,
+ Node n,
+ bool hasPol,
+ bool pol)
+{
Trace("rel-dom-debug") << "Compute relevant domain " << n << "..." << std::endl;
Node op = d_treg.getTermDatabase()->getMatchOperator(n);
- for( unsigned i=0; i<n.getNumChildren(); i++ ){
- if( !op.isNull() ){
+ if (!op.isNull())
+ {
+ for (size_t i = 0, nchild = n.getNumChildren(); i < nchild; i++)
+ {
RDomain * rf = getRDomain( op, i );
if( n[i].getKind()==ITE ){
for( unsigned j=1; j<=2; j++ ){
@@ -175,14 +224,6 @@ void RelevantDomain::computeRelevantDomain( Node q, Node n, bool hasPol, bool po
computeRelevantDomainOpCh( rf, n[i] );
}
}
- // do not recurse under nested closures
- if (!n[i].isClosure())
- {
- bool newHasPol;
- bool newPol;
- QuantPhaseReq::getPolarity( n, i, hasPol, pol, newHasPol, newPol );
- computeRelevantDomain( q, n[i], newHasPol, newPol );
- }
}
if( ( ( n.getKind()==EQUAL && !n[0].getType().isBoolean() ) || n.getKind()==GEQ ) && TermUtil::hasInstConstAttr( n ) ){
diff --git a/src/theory/quantifiers/relevant_domain.h b/src/theory/quantifiers/relevant_domain.h
index 5581e932f..5643a4665 100644
--- a/src/theory/quantifiers/relevant_domain.h
+++ b/src/theory/quantifiers/relevant_domain.h
@@ -153,10 +153,12 @@ class RelevantDomain : public QuantifiersUtil
};
/** Cache of the effect of literals on the relevant domain */
std::map< bool, std::map< bool, std::map< Node, RDomainLit > > > d_rel_dom_lit;
+ /** Compute the relevant domain for quantified formula q. */
+ void computeRelevantDomain(Node q);
/** Compute the relevant domain for a subformula n of q,
* whose polarity is given by hasPol/pol.
*/
- void computeRelevantDomain(Node q, Node n, bool hasPol, bool pol);
+ void computeRelevantDomainNode(Node q, Node n, bool hasPol, bool pol);
/** Compute the relevant domain when the term n
* is in a position to be included in relevant domain rf.
*/
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback