summaryrefslogtreecommitdiff
path: root/src/theory/strings/skolem_cache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/theory/strings/skolem_cache.cpp')
-rw-r--r--src/theory/strings/skolem_cache.cpp108
1 files changed, 100 insertions, 8 deletions
diff --git a/src/theory/strings/skolem_cache.cpp b/src/theory/strings/skolem_cache.cpp
index b6604d6e0..276cb70d6 100644
--- a/src/theory/strings/skolem_cache.cpp
+++ b/src/theory/strings/skolem_cache.cpp
@@ -14,10 +14,13 @@
#include "theory/strings/skolem_cache.h"
+#include "options/strings_options.h"
#include "theory/rewriter.h"
#include "theory/strings/theory_strings_rewriter.h"
#include "util/rational.h"
+using namespace CVC4::kind;
+
namespace CVC4 {
namespace theory {
namespace strings {
@@ -42,6 +45,13 @@ Node SkolemCache::mkSkolemCached(Node a, SkolemId id, const char* c)
Node SkolemCache::mkTypedSkolemCached(
TypeNode tn, Node a, Node b, SkolemId id, const char* c)
{
+ if (!options::stringsCacheSkolems())
+ {
+ Node n = NodeManager::currentNM()->mkSkolem(c, tn, "string skolem");
+ d_allSkolems.insert(n);
+ return n;
+ }
+
a = a.isNull() ? a : Rewriter::rewrite(a);
b = b.isNull() ? b : Rewriter::rewrite(b);
@@ -87,26 +97,108 @@ bool SkolemCache::isSkolem(Node n) const
std::tuple<SkolemCache::SkolemId, Node, Node>
SkolemCache::normalizeStringSkolem(SkolemId id, Node a, Node b)
{
+ if (!options::stringsNormalizeSkolems())
+ {
+ return std::make_tuple(id, a, b);
+ }
+
Trace("skolem-cache") << "normalizeStringSkolem start: (" << id << ", " << a
<< ", " << b << ")" << std::endl;
- // SK_PURIFY(str.substr x 0 (str.indexof x y 0)) ---> SK_FIRST_CTN_PRE(x, y)
+ NodeManager* nm = NodeManager::currentNM();
+
+ if (id == SK_FIRST_CTN_POST)
+ {
+ // SK_FIRST_CTN_POST(x, y) --->
+ // SK_SUFFIX_REM(x, (+ (str.len SK_FIRST_CTN_PRE(x, y)) (str.len y)))
+ id = SK_SUFFIX_REM;
+ Node pre = mkSkolemCached(a, b, SK_FIRST_CTN_PRE, "pre");
+ b = Rewriter::rewrite(nm->mkNode(
+ PLUS, nm->mkNode(STRING_LENGTH, pre), nm->mkNode(STRING_LENGTH, b)));
+ }
+
+ if (id == SK_ID_C_SPT)
+ {
+ // SK_ID_C_SPT(x, y) ---> SK_SUFFIX_REM(x, (str.len y))
+ id = SK_SUFFIX_REM;
+ b = Rewriter::rewrite(nm->mkNode(STRING_LENGTH, b));
+ }
+ else if (id == SK_ID_VC_SPT)
+ {
+ // SK_ID_VC_SPT(x, y) ---> SK_SUFFIX_REM(x, 1)
+ id = SK_SUFFIX_REM;
+ b = nm->mkConst(Rational(1));
+ }
+ else if (id == SK_ID_VC_SPT_REV)
+ {
+ // SK_ID_VC_SPT_REV(x, y) ---> SK_PREFIX(x, (- (str.len x) 1))
+ id = SK_PREFIX;
+ b = Rewriter::rewrite(nm->mkNode(
+ MINUS, nm->mkNode(STRING_LENGTH, a), nm->mkConst(Rational(1))));
+ }
+ else if (id == SK_ID_DC_SPT)
+ {
+ // SK_ID_DC_SPT(x, y) ---> SK_PREFIX(x, 1)
+ id = SK_PREFIX;
+ b = nm->mkConst(Rational(1));
+ }
+ else if (id == SK_ID_DC_SPT_REM)
+ {
+ // SK_ID_DC_SPT_REM(x, y) ---> SK_SUFFIX_REM(x, 1)
+ id = SK_SUFFIX_REM;
+ b = nm->mkConst(Rational(1));
+ }
+ else if (id == SK_ID_DEQ_X)
+ {
+ // SK_ID_DEQ_X(x, y) ---> SK_PREFIX(y, (str.len x))
+ id = SK_PREFIX;
+ Node aOld = a;
+ a = b;
+ b = Rewriter::rewrite(nm->mkNode(STRING_LENGTH, aOld));
+ }
+ else if (id == SK_ID_DEQ_Y)
+ {
+ // SK_ID_DEQ_Y(x, y) ---> SK_PREFIX(x, (str.len y))
+ id = SK_PREFIX;
+ b = Rewriter::rewrite(nm->mkNode(STRING_LENGTH, b));
+ }
+
+ if (id == SK_SUFFIX_REM) {
+ //std::cout << "suffix" << a << " " << b << std::endl;
+ }
+
if (id == SK_PURIFY && a.getKind() == kind::STRING_SUBSTR)
{
Node s = a[0];
Node n = a[1];
Node m = a[2];
- if (m.getKind() == kind::STRING_STRIDOF && m[0] == s)
+
+ if (n == d_zero)
+ {
+ // SK_PURIFY((str.substr x 0 m)) ---> SK_PREFIX(x, m)
+ id = SK_PREFIX;
+ a = s;
+ b = m;
+ }
+ else if (TheoryStringsRewriter::checkEntailArith(
+ nm->mkNode(PLUS, n, m), nm->mkNode(STRING_LENGTH, s)))
{
- if (n == d_zero && m[2] == d_zero)
- {
- id = SK_FIRST_CTN_PRE;
- a = m[0];
- b = m[1];
- }
+ // SK_PURIFY((str.substr x n m)) ---> SK_SUFFIX_REM(x, n)
+ // if n + m >= (str.len x)
+ id = SK_SUFFIX_REM;
+ a = s;
+ b = n;
}
}
+ if (id == SK_PREFIX && b.getKind() == kind::STRING_STRIDOF && a == b[0]
+ && b[2] == d_zero)
+ {
+ // SK_PREFIX(x, (str.indexof x y 0)) ---> SK_FIRST_CTN_PRE(x, y)
+ id = SK_FIRST_CTN_PRE;
+ b = b[1];
+ }
+
if (id == SK_FIRST_CTN_PRE)
{
// SK_FIRST_CTN_PRE((str.substr x 0 n), y) ---> SK_FIRST_CTN_PRE(x, y)
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback