summaryrefslogtreecommitdiff
path: root/src/theory/strings/theory_strings.cpp
diff options
context:
space:
mode:
authoryoni206 <yoni206@users.noreply.github.com>2020-07-28 10:44:55 -0700
committerGitHub <noreply@github.com>2020-07-28 12:44:55 -0500
commit7ad41fe71b9f7d206ee6d1c642bb7926bffea6c7 (patch)
treefc5d9cb07fbce3a28395eb30aabb6d6633724e02 /src/theory/strings/theory_strings.cpp
parente63544462eb850a27f7b416f2f0613efb96eef1d (diff)
Supporting seq.nth (#4723)
This PR adds support for seq.nth operator by eliminating it during expandDefinitions, based on sub-sequences. Tests that use this operator are also included.
Diffstat (limited to 'src/theory/strings/theory_strings.cpp')
-rw-r--r--src/theory/strings/theory_strings.cpp34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/theory/strings/theory_strings.cpp b/src/theory/strings/theory_strings.cpp
index 1fffd9638..84fd08e7c 100644
--- a/src/theory/strings/theory_strings.cpp
+++ b/src/theory/strings/theory_strings.cpp
@@ -594,6 +594,40 @@ TrustNode TheoryStrings::expandDefinition(Node node)
return TrustNode::mkTrustRewrite(node, ret, nullptr);
}
+ if (node.getKind() == SEQ_NTH)
+ {
+ // str.nth(s,i) --->
+ // ite(0<=i<=len(s), witness k. 0<=i<=len(s)->unit(k) = seq.at(s,i),
+ // uf(s,i))
+ NodeManager* nm = NodeManager::currentNM();
+ Node s = node[0];
+ Node i = node[1];
+ Node len = nm->mkNode(STRING_LENGTH, s);
+ Node cond =
+ nm->mkNode(AND, nm->mkNode(LEQ, d_zero, i), nm->mkNode(LT, i, len));
+ TypeNode elemType = s.getType().getSequenceElementType();
+ Node k = nm->mkBoundVar(elemType);
+ Node bvl = nm->mkNode(BOUND_VAR_LIST, k);
+ std::vector<TypeNode> argTypes;
+ argTypes.push_back(s.getType());
+ argTypes.push_back(nm->integerType());
+ TypeNode ufType = nm->mkFunctionType(argTypes, elemType);
+ SkolemCache* sc = d_termReg.getSkolemCache();
+ Node uf = sc->mkTypedSkolemCached(
+ ufType, Node::null(), Node::null(), SkolemCache::SK_NTH, "Uf");
+ Node ret = nm->mkNode(
+ ITE,
+ cond,
+ nm->mkNode(WITNESS,
+ bvl,
+ nm->mkNode(IMPLIES,
+ cond,
+ nm->mkNode(SEQ_UNIT, k)
+ .eqNode(nm->mkNode(STRING_CHARAT, s, i)))),
+ nm->mkNode(APPLY_UF, uf, s, i));
+ return TrustNode::mkTrustRewrite(node, ret, nullptr);
+ }
+
return TrustNode::null();
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback