summaryrefslogtreecommitdiff
path: root/src/theory/strings/eqc_info.cpp
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2020-02-26 10:17:30 -0600
committerGitHub <noreply@github.com>2020-02-26 10:17:30 -0600
commit9b09505bb2a8ed50622b9442700e7f98d010b955 (patch)
treecdc9b8fe22178cf96346b068eef3377067f92f59 /src/theory/strings/eqc_info.cpp
parentabd0048cdb6cf4d2ee0a096c9f7a63a1f7f1d9c8 (diff)
Move equivalence class info to its own file in strings (#3799)
Code move only, no updates to behavior or content of code in this PR.
Diffstat (limited to 'src/theory/strings/eqc_info.cpp')
-rw-r--r--src/theory/strings/eqc_info.cpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/theory/strings/eqc_info.cpp b/src/theory/strings/eqc_info.cpp
new file mode 100644
index 000000000..ab6d473bd
--- /dev/null
+++ b/src/theory/strings/eqc_info.cpp
@@ -0,0 +1,143 @@
+/********************* */
+/*! \file eqc_info.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andrew Reynolds
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2019 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Implementation of equivalence class info for the theory of strings
+ **/
+
+#include "theory/strings/eqc_info.h"
+
+#include "theory/strings/theory_strings_utils.h"
+
+using namespace std;
+using namespace CVC4::context;
+using namespace CVC4::kind;
+
+namespace CVC4 {
+namespace theory {
+namespace strings {
+
+EqcInfo::EqcInfo(context::Context* c)
+ : d_lengthTerm(c),
+ d_codeTerm(c),
+ d_cardinalityLemK(c),
+ d_normalizedLength(c),
+ d_prefixC(c),
+ d_suffixC(c)
+{
+}
+
+Node EqcInfo::addEndpointConst(Node t, Node c, bool isSuf)
+{
+ // check conflict
+ Node prev = isSuf ? d_suffixC : d_prefixC;
+ if (!prev.isNull())
+ {
+ Trace("strings-eager-pconf-debug") << "Check conflict " << prev << ", " << t
+ << " post=" << isSuf << std::endl;
+ Node prevC = utils::getConstantEndpoint(prev, isSuf);
+ Assert(!prevC.isNull());
+ Assert(prevC.getKind() == CONST_STRING);
+ if (c.isNull())
+ {
+ c = utils::getConstantEndpoint(t, isSuf);
+ Assert(!c.isNull());
+ }
+ Assert(c.getKind() == CONST_STRING);
+ bool conflict = false;
+ // if the constant prefixes are different
+ if (c != prevC)
+ {
+ // conflicts between constants should be handled by equality engine
+ Assert(!t.isConst() || !prev.isConst());
+ Trace("strings-eager-pconf-debug")
+ << "Check conflict constants " << prevC << ", " << c << std::endl;
+ const String& ps = prevC.getConst<String>();
+ const String& cs = c.getConst<String>();
+ unsigned pvs = ps.size();
+ unsigned cvs = cs.size();
+ if (pvs == cvs || (pvs > cvs && t.isConst())
+ || (cvs > pvs && prev.isConst()))
+ {
+ // If equal length, cannot be equal due to node check above.
+ // If one is fully constant and has less length than the other, then the
+ // other will not fit and we are in conflict.
+ conflict = true;
+ }
+ else
+ {
+ const String& larges = pvs > cvs ? ps : cs;
+ const String& smalls = pvs > cvs ? cs : ps;
+ if (isSuf)
+ {
+ conflict = !larges.hasSuffix(smalls);
+ }
+ else
+ {
+ conflict = !larges.hasPrefix(smalls);
+ }
+ }
+ if (!conflict && (pvs > cvs || prev.isConst()))
+ {
+ // current is subsumed, either shorter prefix or the other is a full
+ // constant
+ return Node::null();
+ }
+ }
+ else if (!t.isConst())
+ {
+ // current is subsumed since the other may be a full constant
+ return Node::null();
+ }
+ if (conflict)
+ {
+ Trace("strings-eager-pconf")
+ << "Conflict for " << prevC << ", " << c << std::endl;
+ std::vector<Node> ccs;
+ Node r[2];
+ for (unsigned i = 0; i < 2; i++)
+ {
+ Node tp = i == 0 ? t : prev;
+ if (tp.getKind() == STRING_IN_REGEXP)
+ {
+ ccs.push_back(tp);
+ r[i] = tp[0];
+ }
+ else
+ {
+ r[i] = tp;
+ }
+ }
+ if (r[0] != r[1])
+ {
+ ccs.push_back(r[0].eqNode(r[1]));
+ }
+ Assert(!ccs.empty());
+ Node ret =
+ ccs.size() == 1 ? ccs[0] : NodeManager::currentNM()->mkNode(AND, ccs);
+ Trace("strings-eager-pconf")
+ << "String: eager prefix conflict: " << ret << std::endl;
+ return ret;
+ }
+ }
+ if (isSuf)
+ {
+ d_suffixC = t;
+ }
+ else
+ {
+ d_prefixC = t;
+ }
+ return Node::null();
+}
+
+} // namespace strings
+} // namespace theory
+} // namespace CVC4
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback