summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorajreynol <andrew.j.reynolds@gmail.com>2017-05-09 17:16:06 -0500
committerajreynol <andrew.j.reynolds@gmail.com>2017-05-09 17:16:06 -0500
commit1ba6da827023f0980ad5a00772dd91665620d2a4 (patch)
tree9227e0e0d69d5fce9dfb8859c0e64d4ea98e61bf
parentf4b158635255affcafe52c7664fc5de4660c3f83 (diff)
Change str.replace for empty string.
-rw-r--r--src/theory/strings/theory_strings_rewriter.cpp75
-rw-r--r--test/regress/regress0/strings/Makefile.am3
-rw-r--r--test/regress/regress0/strings/repl-empty-sem.smt211
3 files changed, 53 insertions, 36 deletions
diff --git a/src/theory/strings/theory_strings_rewriter.cpp b/src/theory/strings/theory_strings_rewriter.cpp
index 2ee367cfc..6daaddcd7 100644
--- a/src/theory/strings/theory_strings_rewriter.cpp
+++ b/src/theory/strings/theory_strings_rewriter.cpp
@@ -1622,42 +1622,47 @@ Node TheoryStringsRewriter::rewriteReplace( Node node ) {
if( node[1]==node[2] ){
return node[0];
}else{
- std::vector< Node > children;
- getConcat( node[0], children );
- if( children[0].isConst() && node[1].isConst() ){
- CVC4::String s = children[0].getConst<String>();
- CVC4::String t = node[1].getConst<String>();
- std::size_t p = s.find(t);
- if( p != std::string::npos ) {
- Node retNode;
- if( node[2].isConst() ){
- CVC4::String r = node[2].getConst<String>();
- CVC4::String ret = s.replace(t, r);
- retNode = NodeManager::currentNM()->mkConst( ::CVC4::String(ret) );
- } else {
- CVC4::String s1 = s.substr(0, (int)p);
- CVC4::String s3 = s.substr((int)p + (int)t.size());
- Node ns1 = NodeManager::currentNM()->mkConst( ::CVC4::String(s1) );
- Node ns3 = NodeManager::currentNM()->mkConst( ::CVC4::String(s3) );
- retNode = NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, ns1, node[2], ns3 );
- }
- if( children.size()>1 ){
- children[0] = retNode;
- return mkConcat( kind::STRING_CONCAT, children );
- }else{
- return retNode;
- }
- }else{
- //could not find replacement string
- if( node[0].isConst() ){
- return node[0];
+ if( node[1].isConst() ){
+ if( node[1].getConst<String>().isEmptyString() ){
+ return node[0];
+ }
+ std::vector< Node > children;
+ getConcat( node[0], children );
+ if( children[0].isConst() ){
+ CVC4::String s = children[0].getConst<String>();
+ CVC4::String t = node[1].getConst<String>();
+ std::size_t p = s.find(t);
+ if( p != std::string::npos ) {
+ Node retNode;
+ if( node[2].isConst() ){
+ CVC4::String r = node[2].getConst<String>();
+ CVC4::String ret = s.replace(t, r);
+ retNode = NodeManager::currentNM()->mkConst( ::CVC4::String(ret) );
+ } else {
+ CVC4::String s1 = s.substr(0, (int)p);
+ CVC4::String s3 = s.substr((int)p + (int)t.size());
+ Node ns1 = NodeManager::currentNM()->mkConst( ::CVC4::String(s1) );
+ Node ns3 = NodeManager::currentNM()->mkConst( ::CVC4::String(s3) );
+ retNode = NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, ns1, node[2], ns3 );
+ }
+ if( children.size()>1 ){
+ children[0] = retNode;
+ return mkConcat( kind::STRING_CONCAT, children );
+ }else{
+ return retNode;
+ }
}else{
- //check for overlap, if none, we can remove the prefix
- if( s.overlap(t)==0 ){
- std::vector< Node > spl;
- spl.insert( spl.end(), children.begin()+1, children.end() );
- return NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, children[0],
- NodeManager::currentNM()->mkNode( kind::STRING_STRREPL, mkConcat( kind::STRING_CONCAT, spl ), node[1], node[2] ) );
+ //could not find replacement string
+ if( node[0].isConst() ){
+ return node[0];
+ }else{
+ //check for overlap, if none, we can remove the prefix
+ if( s.overlap(t)==0 ){
+ std::vector< Node > spl;
+ spl.insert( spl.end(), children.begin()+1, children.end() );
+ return NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, children[0],
+ NodeManager::currentNM()->mkNode( kind::STRING_STRREPL, mkConcat( kind::STRING_CONCAT, spl ), node[1], node[2] ) );
+ }
}
}
}
diff --git a/test/regress/regress0/strings/Makefile.am b/test/regress/regress0/strings/Makefile.am
index f4dc8ebf7..41c500170 100644
--- a/test/regress/regress0/strings/Makefile.am
+++ b/test/regress/regress0/strings/Makefile.am
@@ -86,7 +86,8 @@ TESTS = \
cmu-inc-nlpp-071516.smt2 \
strings-index-empty.smt2 \
bug768.smt2 \
- username_checker_min.smt2
+ username_checker_min.smt2 \
+ repl-empty-sem.smt2
FAILING_TESTS =
diff --git a/test/regress/regress0/strings/repl-empty-sem.smt2 b/test/regress/regress0/strings/repl-empty-sem.smt2
new file mode 100644
index 000000000..61f70bc23
--- /dev/null
+++ b/test/regress/regress0/strings/repl-empty-sem.smt2
@@ -0,0 +1,11 @@
+; COMMAND-LINE: --strings-exp
+; EXPECT: unsat
+(set-logic ALL)
+(set-info :status unsat)
+(declare-fun x () String)
+(declare-fun z () String)
+(assert (= (str.len z) 0))
+(assert (= (str.replace "ab" z "c") x))
+(declare-fun y () String)
+(assert (= x (str.++ "c" y)))
+(check-sat)
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback