diff options
author | yoni206 <yoni206@users.noreply.github.com> | 2020-07-28 10:44:55 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-28 12:44:55 -0500 |
commit | 7ad41fe71b9f7d206ee6d1c642bb7926bffea6c7 (patch) | |
tree | fc5d9cb07fbce3a28395eb30aabb6d6633724e02 /src/theory/strings/theory_strings.cpp | |
parent | e63544462eb850a27f7b416f2f0613efb96eef1d (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.cpp | 34 |
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(); } |