summaryrefslogtreecommitdiff
path: root/src/expr
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2020-05-19 21:48:01 -0500
committerGitHub <noreply@github.com>2020-05-19 21:48:01 -0500
commitaf874a5c7a2ff134da0d4c20d06a0626d3e36d9b (patch)
tree16ad9de2b0c5753d2cd4cd3fcdd43bf8fbd55a71 /src/expr
parent9712a20e6585728c7d0453e64e1e3b06a7d37b7f (diff)
Do not eliminate variables that are equal to unevaluatable terms (#4267)
When we eliminate a variable x -> v during simplification, it may be the case that v contains "unevaluated" operators like forall, choice, etc. Thus, we do not produce correct models for such inputs unless simplification is disabled. This PR ensures we only eliminate variables when v contains only evaluated operators. Additionally, the kinds registered as unevaluated were slightly modified so that when we are in a logic like QF_LIA, there are no registered unevaluated operators, hence the check above is unnecessary. This is to minimize the performance impact of this change. Fixes #4500.
Diffstat (limited to 'src/expr')
-rw-r--r--src/expr/node_algorithm.cpp28
-rw-r--r--src/expr/node_algorithm.h8
2 files changed, 36 insertions, 0 deletions
diff --git a/src/expr/node_algorithm.cpp b/src/expr/node_algorithm.cpp
index 0c572f615..44430f072 100644
--- a/src/expr/node_algorithm.cpp
+++ b/src/expr/node_algorithm.cpp
@@ -155,6 +155,34 @@ bool hasSubtermKind(Kind k, Node n)
return false;
}
+bool hasSubtermKinds(const std::unordered_set<Kind, kind::KindHashFunction>& ks,
+ Node n)
+{
+ if (ks.empty())
+ {
+ return false;
+ }
+ std::unordered_set<TNode, TNodeHashFunction> visited;
+ std::vector<TNode> visit;
+ TNode cur;
+ visit.push_back(n);
+ do
+ {
+ cur = visit.back();
+ visit.pop_back();
+ if (visited.find(cur) == visited.end())
+ {
+ if (ks.find(cur.getKind()) != ks.end())
+ {
+ return true;
+ }
+ visited.insert(cur);
+ visit.insert(visit.end(), cur.begin(), cur.end());
+ }
+ } while (!visit.empty());
+ return false;
+}
+
bool hasSubterm(TNode n, const std::vector<Node>& t, bool strict)
{
if (t.empty())
diff --git a/src/expr/node_algorithm.h b/src/expr/node_algorithm.h
index 5e042d591..894dce7c6 100644
--- a/src/expr/node_algorithm.h
+++ b/src/expr/node_algorithm.h
@@ -52,6 +52,14 @@ bool hasSubtermMulti(TNode n, TNode t);
bool hasSubtermKind(Kind k, Node n);
/**
+ * @param ks The kinds of node to check
+ * @param n The node to search in.
+ * @return true iff there is a term in n that has any kind ks
+ */
+bool hasSubtermKinds(const std::unordered_set<Kind, kind::KindHashFunction>& ks,
+ Node n);
+
+/**
* Check if the node n has a subterm that occurs in t.
* @param n The node to search in
* @param t The set of subterms to search for
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback