summaryrefslogtreecommitdiff
path: root/src/theory/strings
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2021-03-21 09:01:04 -0500
committerGitHub <noreply@github.com>2021-03-21 14:01:04 +0000
commitc0d4ac3d307b13c24471da5af2f916569a7f52b9 (patch)
treebc458edc2a59fd3877e7952beb52d27997a15c8b /src/theory/strings
parent09097cd3b9cd3233b938ace34f3513a16ac17f80 (diff)
Simplify strings term registration (#6174)
String terms may enter into the equality engine without appearing in assertions, due to eager context-dependent simplification internal to the equality engine (--strings-eager-eval). In rare cases, we did not catch when a new string constant appeared in the equality engine, meaning it would not be marked as relevant leading to bogus models in incremental mode. This makes it so that proxy variables are stored in a user-context dependent manner, which impacts when terms marked as having a proxy variable are registered. The PR also simplifies our policies for when string terms are registered slightly. Fixes #6072.
Diffstat (limited to 'src/theory/strings')
-rw-r--r--src/theory/strings/term_registry.cpp20
-rw-r--r--src/theory/strings/term_registry.h2
-rw-r--r--src/theory/strings/theory_strings.cpp12
3 files changed, 17 insertions, 17 deletions
diff --git a/src/theory/strings/term_registry.cpp b/src/theory/strings/term_registry.cpp
index 9497b9661..f24fe12e5 100644
--- a/src/theory/strings/term_registry.cpp
+++ b/src/theory/strings/term_registry.cpp
@@ -49,6 +49,7 @@ TermRegistry::TermRegistry(SolverState& s,
d_preregisteredTerms(s.getSatContext()),
d_registeredTerms(s.getUserContext()),
d_registeredTypes(s.getUserContext()),
+ d_proxyVar(s.getUserContext()),
d_lengthLemmaTermsCache(s.getUserContext()),
d_epg(pnm ? new EagerProofGenerator(
pnm,
@@ -246,8 +247,15 @@ void TermRegistry::preRegisterTerm(TNode n)
void TermRegistry::registerTerm(Node n, int effort)
{
- TypeNode tn = n.getType();
+ Trace("strings-register") << "TheoryStrings::registerTerm() " << n
+ << ", effort = " << effort << std::endl;
+ if (d_registeredTerms.find(n) != d_registeredTerms.end())
+ {
+ Trace("strings-register") << "...already registered" << std::endl;
+ return;
+ }
bool do_register = true;
+ TypeNode tn = n.getType();
if (!tn.isStringLike())
{
if (options::stringEagerLen())
@@ -261,17 +269,13 @@ void TermRegistry::registerTerm(Node n, int effort)
}
if (!do_register)
{
+ Trace("strings-register") << "...do not register" << std::endl;
return;
}
- if (d_registeredTerms.find(n) != d_registeredTerms.end())
- {
- return;
- }
+ Trace("strings-register") << "...register" << std::endl;
d_registeredTerms.insert(n);
// ensure the type is registered
registerType(tn);
- Debug("strings-register") << "TheoryStrings::registerTerm() " << n
- << ", effort = " << effort << std::endl;
TrustNode regTermLem;
if (tn.isStringLike())
{
@@ -555,7 +559,7 @@ Node TermRegistry::getSymbolicDefinition(Node n, std::vector<Node>& exp) const
Node TermRegistry::getProxyVariableFor(Node n) const
{
- std::map<Node, Node>::const_iterator it = d_proxyVar.find(n);
+ NodeNodeMap::const_iterator it = d_proxyVar.find(n);
if (it != d_proxyVar.end())
{
return (*it).second;
diff --git a/src/theory/strings/term_registry.h b/src/theory/strings/term_registry.h
index a3d1d1e0e..cb1b50816 100644
--- a/src/theory/strings/term_registry.h
+++ b/src/theory/strings/term_registry.h
@@ -237,7 +237,7 @@ class TermRegistry
* which rewrites to 3 = 3.
* In the above example, we store "ABC" -> v_{"ABC"} in this map.
*/
- std::map<Node, Node> d_proxyVar;
+ NodeNodeMap d_proxyVar;
/**
* Map from proxy variables to their normalized length. In the above example,
* we store "ABC" -> 3.
diff --git a/src/theory/strings/theory_strings.cpp b/src/theory/strings/theory_strings.cpp
index b92cdaf5b..204b938fa 100644
--- a/src/theory/strings/theory_strings.cpp
+++ b/src/theory/strings/theory_strings.cpp
@@ -583,16 +583,12 @@ bool TheoryStrings::preNotifyFact(
// this is only required for internal facts, others are already registered
if (isInternal && atom.getKind() == EQUAL)
{
- // we must ensure these terms are registered
+ // We must ensure these terms are registered. We register eagerly here for
+ // performance reasons. Alternatively, terms could be registered at full
+ // effort in e.g. BaseSolver::init.
for (const Node& t : atom)
{
- // terms in the equality engine are already registered, hence skip
- // currently done for only string-like terms, but this could potentially
- // be avoided.
- if (!d_equalityEngine->hasTerm(t) && t.getType().isStringLike())
- {
- d_termReg.registerTerm(t, 0);
- }
+ d_termReg.registerTerm(t, 0);
}
}
return false;
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback