#include "theory/strings/core_solver.h"
-#include "theory/strings/theory_strings_utils.h"
#include "options/strings_options.h"
#include "theory/strings/theory_strings_rewriter.h"
-
+#include "theory/strings/theory_strings_utils.h"
+#include "theory/strings/word.h"
using namespace std;
using namespace CVC4::context;
d_zero = NodeManager::currentNM()->mkConst( Rational( 0 ) );
d_one = NodeManager::currentNM()->mkConst( Rational( 1 ) );
d_neg_one = NodeManager::currentNM()->mkConst(Rational(-1));
- d_emptyString = NodeManager::currentNM()->mkConst( ::CVC4::String("") );
+ d_emptyString = Word::mkEmptyWord(CONST_STRING);
d_true = NodeManager::currentNM()->mkConst( true );
d_false = NodeManager::currentNM()->mkConst( false );
}
Assert(!d_state.areEqual(x, y));
std::vector<Node> lenExp;
- Node xLen = d_state.getLength(x, lenExp);
- Node yLen = d_state.getLength(y, lenExp);
+ Node xLenTerm = d_state.getLength(x, lenExp);
+ Node yLenTerm = d_state.getLength(y, lenExp);
- if (d_state.areEqual(xLen, yLen))
+ if (d_state.areEqual(xLenTerm, yLenTerm))
{
// `x` and `y` have the same length. We infer that the two components
// have to be the same.
Trace("strings-solve-debug")
<< "Simple Case 2 : string lengths are equal" << std::endl;
Node eq = x.eqNode(y);
- Node leneq = xLen.eqNode(yLen);
+ Node leneq = xLenTerm.eqNode(yLenTerm);
NormalForm::getExplanationForPrefixEq(nfi, nfj, index, index, lenExp);
lenExp.push_back(leneq);
d_im.sendInference(lenExp, eq, "N_Unify");
// Constants in both normal forms.
//
// E.g. "abc" ++ ... = "ab" ++ ...
- String c1 = x.getConst<String>();
- String c2 = y.getConst<String>();
+ size_t lenX = Word::getLength(x);
+ size_t lenY = Word::getLength(y);
Trace("strings-solve-debug")
<< "Simple Case 4 : Const Split : " << x << " vs " << y
<< " at index " << index << ", isRev = " << isRev << std::endl;
- size_t minLen = std::min(c1.size(), c2.size());
- bool isSameFix = isRev ? c1.rstrncmp(c2, minLen) : c1.strncmp(c2, minLen);
+ size_t minLen = std::min(lenX, lenY);
+ bool isSameFix =
+ isRev ? Word::rstrncmp(x, y, minLen) : Word::strncmp(x, y, minLen);
if (isSameFix)
{
// The shorter constant is a prefix/suffix of the longer constant. We
//
// E.g. "abc" ++ x' ++ ... = "ab" ++ y' ++ ... --->
// "c" ++ x' ++ ... = y' ++ ...
- bool c1Shorter = c1.size() < c2.size();
- NormalForm& nfl = c1Shorter ? nfj : nfi;
- const String& cl = c1Shorter ? c2 : c1;
- Node ns = c1Shorter ? x : y;
+ bool xShorter = lenX < lenY;
+ NormalForm& nfl = xShorter ? nfj : nfi;
+ Node cl = xShorter ? y : x;
+ Node ns = xShorter ? x : y;
Node remainderStr;
if (isRev)
{
- int newlen = cl.size() - minLen;
- remainderStr = nm->mkConst(cl.substr(0, newlen));
+ size_t newlen = std::max(lenX, lenY) - minLen;
+ remainderStr = Word::substr(cl, 0, newlen);
}
else
{
- remainderStr = nm->mkConst(cl.substr(minLen));
+ remainderStr = Word::substr(cl, minLen);
}
Trace("strings-solve-debug-test")
<< "Break normal form of " << cl << " into " << ns << ", "
info.d_j = nfj.d_base;
info.d_rev = isRev;
Assert(index < nfiv.size() - rproc && index < nfjv.size() - rproc);
- if (!d_state.areDisequal(xLen, yLen) && !d_state.areEqual(xLen, yLen)
+ if (!d_state.areDisequal(xLenTerm, yLenTerm) && !d_state.areEqual(xLenTerm, yLenTerm)
&& !x.isConst()
&& !y.isConst()) // AJR: remove the latter 2 conditions?
{
Trace("strings-solve-debug")
<< "Non-simple Case 1 : string lengths neither equal nor disequal"
<< std::endl;
- Node lenEq = nm->mkNode(EQUAL, xLen, yLen);
+ Node lenEq = nm->mkNode(EQUAL, xLenTerm, yLenTerm);
lenEq = Rewriter::rewrite(lenEq);
info.d_conc = nm->mkNode(OR, lenEq, lenEq.negate());
info.d_pending_phase[lenEq] = true;
// is a prefix/suffix of the other.
//
// E.g. x ++ ... = y ++ ... ---> (x = y ++ k) v (y = x ++ k)
- Assert(d_state.areDisequal(xLen, yLen));
+ Assert(d_state.areDisequal(xLenTerm, yLenTerm));
Assert(x.getKind() != CONST_STRING);
Assert(y.getKind() != CONST_STRING);
// do not infer constants are larger than variables
if (t.getKind() != CONST_STRING)
{
- Node lt1 = e == 0 ? xLen : yLen;
- Node lt2 = e == 0 ? yLen : xLen;
+ Node lt1 = e == 0 ? xLenTerm : yLenTerm;
+ Node lt2 = e == 0 ? yLenTerm : xLenTerm;
Node entLit = Rewriter::rewrite(nm->mkNode(GT, lt1, lt2));
std::pair<bool, Node> et = d_state.entailmentCheck(
options::TheoryOfMode::THEORY_OF_TYPE_BASED, entLit);
}
else
{
- Node ldeq = nm->mkNode(EQUAL, xLen, yLen).negate();
+ Node ldeq = nm->mkNode(EQUAL, xLenTerm, yLenTerm).negate();
info.d_ant.push_back(ldeq);
info.d_conc = nm->mkNode(OR, eq1, eq2);
info.d_id = INFER_SSPLIT_VAR;
{
Trace("strings-loop") << "Strings::Loop: Const Normal Breaking."
<< std::endl;
- CVC4::String s = t_yz.getConst<CVC4::String>();
- unsigned size = s.size();
+ unsigned size = Word::getLength(t_yz);
std::vector<Node> vconc;
for (unsigned len = 1; len <= size; len++)
{
- Node y = nm->mkConst(s.substr(0, len));
- Node z = nm->mkConst(s.substr(len, size - len));
+ Node y = Word::substr(t_yz, 0, len);
+ Node z = Word::substr(t_yz, len, size - len);
Node restr = s_zy;
Node cc;
if (r != d_emptyString)
return;
}else{
//split on first character
- CVC4::String str = const_k.getConst<String>();
- Node firstChar = str.size() == 1 ? const_k : NodeManager::currentNM()->mkConst( str.prefix( 1 ) );
+ Node firstChar = Word::getLength(const_k) == 1
+ ? const_k
+ : Word::prefix(const_k, 1);
if (d_state.areEqual(lnck, d_one))
{
if (d_state.areDisequal(firstChar, nconst_k))
if (!d_state.areEqual(i, j))
{
if( i.getKind()==kind::CONST_STRING && j.getKind()==kind::CONST_STRING ) {
- unsigned int len_short = i.getConst<String>().size() < j.getConst<String>().size() ? i.getConst<String>().size() : j.getConst<String>().size();
+ size_t lenI = Word::getLength(i);
+ size_t lenJ = Word::getLength(j);
+ unsigned int len_short = lenI < lenJ ? lenI : lenJ;
bool isSameFix = isRev ? i.getConst<String>().rstrncmp(j.getConst<String>(), len_short): i.getConst<String>().strncmp(j.getConst<String>(), len_short);
if( isSameFix ) {
//same prefix/suffix
//k is the index of the string that is shorter
- Node nk = i.getConst<String>().size() < j.getConst<String>().size() ? i : j;
- Node nl = i.getConst<String>().size() < j.getConst<String>().size() ? j : i;
+ Node nk = lenI < lenJ ? i : j;
+ Node nl = lenI < lenJ ? j : i;
Node remainderStr;
if( isRev ){
- int new_len = nl.getConst<String>().size() - len_short;
- remainderStr = NodeManager::currentNM()->mkConst( nl.getConst<String>().substr(0, new_len) );
+ int new_len = Word::getLength(nl) - len_short;
+ remainderStr = Word::substr(nl, 0, new_len);
Trace("strings-solve-debug-test") << "Rev. Break normal form of " << nl << " into " << nk << ", " << remainderStr << std::endl;
} else {
- remainderStr = NodeManager::currentNM()->mkConst( nl.getConst<String>().substr( len_short ) );
+ remainderStr = Word::substr(nl, len_short);
Trace("strings-solve-debug-test") << "Break normal form of " << nl << " into " << nk << ", " << remainderStr << std::endl;
}
- if( i.getConst<String>().size() < j.getConst<String>().size() ) {
+ if (lenI < lenJ)
+ {
nfj.insert( nfj.begin() + index + 1, remainderStr );
nfj[index] = nfi[index];
- } else {
+ }
+ else
+ {
nfi.insert( nfi.begin() + index + 1, remainderStr );
nfi[index] = nfj[index];
}
#include "options/strings_options.h"
#include "theory/strings/theory_strings_rewriter.h"
#include "theory/strings/theory_strings_utils.h"
+#include "theory/strings/word.h"
using namespace CVC4;
using namespace CVC4::kind;
namespace strings {
RegExpOpr::RegExpOpr()
- : d_emptyString(NodeManager::currentNM()->mkConst(::CVC4::String(""))),
- d_true(NodeManager::currentNM()->mkConst(true)),
+ : d_true(NodeManager::currentNM()->mkConst(true)),
d_false(NodeManager::currentNM()->mkConst(false)),
- d_emptySingleton(NodeManager::currentNM()->mkNode(kind::STRING_TO_REGEXP,
- d_emptyString)),
d_emptyRegexp(NodeManager::currentNM()->mkNode(kind::REGEXP_EMPTY,
std::vector<Node>{})),
d_zero(NodeManager::currentNM()->mkConst(::CVC4::Rational(0))),
std::vector<Node>{})),
d_sigma_star(NodeManager::currentNM()->mkNode(kind::REGEXP_STAR, d_sigma))
{
+ d_emptyString = Word::mkEmptyWord(CONST_STRING);
+
+ d_emptySingleton =
+ NodeManager::currentNM()->mkNode(STRING_TO_REGEXP, d_emptyString);
d_lastchar = utils::getAlphabetCardinality() - 1;
}
int ret = 1;
retNode = d_emptyRegexp;
+ NodeManager* nm = NodeManager::currentNM();
PairNodeStr dv = std::make_pair( r, c );
if( d_deriv_cache.find( dv ) != d_deriv_cache.end() ) {
if(tmp == d_emptyString) {
ret = 2;
} else {
- if (tmp.getConst<CVC4::String>().front() == c.front())
+ if (tmp.getConst<String>().front() == c.front())
{
- retNode = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP,
- tmp.getConst< CVC4::String >().size() == 1 ? d_emptyString : NodeManager::currentNM()->mkConst( tmp.getConst< CVC4::String >().substr(1) ) );
+ retNode =
+ nm->mkNode(STRING_TO_REGEXP,
+ Word::getLength(tmp) == 1 ? d_emptyString
+ : Word::substr(tmp, 1));
} else {
ret = 2;
}
if(tmp.getKind() == kind::STRING_CONCAT) {
Node t2 = tmp[0];
if(t2.isConst()) {
- if (t2.getConst<CVC4::String>().front() == c.front())
+ if (t2.getConst<String>().front() == c.front())
{
- Node n = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP,
- tmp.getConst< CVC4::String >().size() == 1 ? d_emptyString : NodeManager::currentNM()->mkConst( tmp.getConst< CVC4::String >().substr(1) ) );
+ Node n = nm->mkNode(STRING_TO_REGEXP,
+ Word::getLength(tmp) == 1
+ ? d_emptyString
+ : Word::substr(tmp, 1));
std::vector< Node > vec_nodes;
vec_nodes.push_back(n);
for(unsigned i=1; i<tmp.getNumChildren(); i++) {
Trace("regexp-derive") << "RegExp-derive starts with /" << mkString( r ) << "/, c=" << c << std::endl;
Node retNode = d_emptyRegexp;
PairNodeStr dv = std::make_pair( r, c );
+ NodeManager* nm = NodeManager::currentNM();
if( d_dv_cache.find( dv ) != d_dv_cache.end() ) {
retNode = d_dv_cache[dv];
} else if( c.isEmptyString() ){
if(r[0] == d_emptyString) {
retNode = d_emptyRegexp;
} else {
- if (r[0].getConst<CVC4::String>().front() == c.front())
+ if (r[0].getConst<String>().front() == c.front())
{
- retNode = NodeManager::currentNM()->mkNode( kind::STRING_TO_REGEXP,
- r[0].getConst< CVC4::String >().size() == 1 ? d_emptyString : NodeManager::currentNM()->mkConst( r[0].getConst< CVC4::String >().substr(1) ) );
+ retNode = nm->mkNode(STRING_TO_REGEXP,
+ Word::getLength(r[0]) == 1
+ ? d_emptyString
+ : Word::substr(r[0], 1));
} else {
retNode = d_emptyRegexp;
}
case kind::STRING_TO_REGEXP: {
Node st = Rewriter::rewrite(r[0]);
if(st.isConst()) {
- CVC4::String s = st.getConst< CVC4::String >();
+ String s = st.getConst<String>();
if(s.size() != 0) {
unsigned sc = s.front();
sc = String::convertUnsignedIntToCode(sc);
else if (st.getKind() == kind::STRING_CONCAT)
{
if(st[0].isConst()) {
- CVC4::String s = st[0].getConst<CVC4::String>();
+ String s = st[0].getConst<String>();
unsigned sc = s.front();
sc = String::convertUnsignedIntToCode(sc);
cset.insert(sc);
//printing
std::string RegExpOpr::niceChar(Node r) {
if(r.isConst()) {
- std::string s = r.getConst<CVC4::String>().toString() ;
+ std::string s = r.getConst<String>().toString();
return s == "." ? "\\." : s;
} else {
std::string ss = "$" + r.toString();