summaryrefslogtreecommitdiff
path: root/src/theory
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2020-05-19 15:38:05 -0500
committerGitHub <noreply@github.com>2020-05-19 15:38:05 -0500
commit6bb98062a5578d126db6a3e8cdca083881893b32 (patch)
tree6252c581945f90b786864eacc83344a0ed1ebfd0 /src/theory
parent02b88b7665df5a6b1a2bce231d7567efdcc4b20a (diff)
Use fresh variables when miniscoping (#4296)
Fixes #4288. When applying miniscoping, we previously were reusing variables across quantified formulas in the resulting conjunction. This ensures our miniscoping ensures fresh variables.
Diffstat (limited to 'src/theory')
-rw-r--r--src/theory/quantifiers/quantifiers_rewriter.cpp33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/theory/quantifiers/quantifiers_rewriter.cpp b/src/theory/quantifiers/quantifiers_rewriter.cpp
index 10c5741fe..df86922bc 100644
--- a/src/theory/quantifiers/quantifiers_rewriter.cpp
+++ b/src/theory/quantifiers/quantifiers_rewriter.cpp
@@ -1664,6 +1664,7 @@ Node QuantifiersRewriter::mkForall( std::vector< Node >& args, Node body, std::v
//computes miniscoping, also eliminates variables that do not occur free in body
Node QuantifiersRewriter::computeMiniscoping( std::vector< Node >& args, Node body, QAttributes& qa ){
+ NodeManager* nm = NodeManager::currentNM();
if( body.getKind()==FORALL ){
//combine prenex
std::vector< Node > newArgs;
@@ -1677,10 +1678,36 @@ Node QuantifiersRewriter::computeMiniscoping( std::vector< Node >& args, Node bo
// be applied first
if (options::miniscopeQuant() || options::aggressiveMiniscopeQuant())
{
- // break apart
+ // Break apart the quantifed formula
+ // forall x. P1 ^ ... ^ Pn ---> forall x. P1 ^ ... ^ forall x. Pn
NodeBuilder<> t(kind::AND);
- for( unsigned i=0; i<body.getNumChildren(); i++ ){
- t << computeMiniscoping( args, body[i], qa );
+ std::vector<Node> argsc;
+ for (unsigned i = 0, nchild = body.getNumChildren(); i < nchild; i++)
+ {
+ if (argsc.empty())
+ {
+ // If not done so, we must create fresh copy of args. This is to
+ // ensure that quantified formulas do not reuse variables.
+ for (const Node& v : args)
+ {
+ argsc.push_back(nm->mkBoundVar(v.getType()));
+ }
+ }
+ Node b = body[i];
+ Node bodyc =
+ b.substitute(args.begin(), args.end(), argsc.begin(), argsc.end());
+ if (b == bodyc)
+ {
+ // Did not contain variables in args, thus it is ground. Since we did
+ // not use them, we keep the variables argsc for the next child.
+ t << b;
+ }
+ else
+ {
+ t << computeMiniscoping(argsc, bodyc, qa);
+ // We used argsc, clear so we will construct a fresh copy above.
+ argsc.clear();
+ }
}
Node retVal = t;
return retVal;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback