Towards theory of sequences.
{
slv = getVarElimLitBv(lit, args, var);
}
- else if (tt.isString())
+ else if (tt.isStringLike())
{
slv = getVarElimLitString(lit, args, var);
}
#include "theory/quantifiers/sygus/term_database_sygus.h"
#include "theory/quantifiers/term_util.h"
#include "theory/quantifiers_engine.h"
+#include "theory/strings/word.h"
using namespace CVC4::kind;
ops.push_back(nm->mkConst(true));
ops.push_back(nm->mkConst(false));
}
- else if (type.isString())
+ else if (type.isStringLike())
{
- ops.push_back(nm->mkConst(String("")));
- // dummy character "A"
- ops.push_back(nm->mkConst(String("A")));
+ ops.push_back(strings::Word::mkEmptyWord(type));
+ if (type.isString())
+ {
+ // Dummy character "A". This is not necessary for sequences which
+ // have the generic constructor seq.unit.
+ ops.push_back(nm->mkConst(String("A")));
+ }
}
else if (type.isArray() || type.isSet())
{
{
collectSygusGrammarTypesFor(range.getSetElementType(), types);
}
- else if (range.isString() )
+ else if (range.isStringLike())
{
// theory of strings shares the integer type
TypeNode intType = NodeManager::currentNM()->integerType();
#include "theory/quantifiers/term_database.h"
#include "theory/quantifiers/term_enumeration.h"
#include "theory/quantifiers_engine.h"
+#include "theory/strings/word.h"
#include "theory/theory_engine.h"
using namespace std;
n = NodeManager::currentNM()->mkConst(false);
}
}
- else if (tn.isString())
+ else if (tn.isStringLike())
{
if (val == 0)
{
- n = NodeManager::currentNM()->mkConst(::CVC4::String(""));
+ n = strings::Word::mkEmptyWord(tn);
}
}
return n;
while( !eqc_i.isFinished() ){
Node n = (*eqc_i);
if( !d_bsolver.isCongruent(n) ){
- if (n.getKind() == CONST_STRING || n.getKind() == STRING_CONCAT)
+ if (n.isConst() || n.getKind() == STRING_CONCAT)
{
Trace("strings-process-debug") << "Get Normal Form : Process term " << n << " in eqc " << eqc << std::endl;
NormalForm nf_curr;
- if (n.getKind() == CONST_STRING)
+ if (n.isConst())
{
nf_curr.init(n);
}
}
//if not equal to self
std::vector<Node>& currv = nf_curr.d_nf;
- if (currv.size() > 1
- || (currv.size() == 1 && currv[0].getKind() == CONST_STRING))
+ if (currv.size() > 1 || (currv.size() == 1 && currv[0].isConst()))
{
// if in a build with assertions, check that normal form is acyclic
if (Configuration::isAssertionBuild())
d_im.sendInference(lenExp, eq, Inference::N_UNIFY);
break;
}
- else if ((x.getKind() != CONST_STRING && index == nfiv.size() - rproc - 1)
- || (y.getKind() != CONST_STRING
- && index == nfjv.size() - rproc - 1))
+ else if ((!x.isConst() && index == nfiv.size() - rproc - 1)
+ || (!y.isConst() && index == nfjv.size() - rproc - 1))
{
// We have reached the last component in one of the normal forms and it
// is not a constant. Thus, the last component must be equal to the
NormalForm& nfnc = x.isConst() ? nfj : nfi;
const std::vector<Node>& nfncv = nfnc.d_nf;
Node nc = nfncv[index];
- Assert(nc.getKind() != CONST_STRING) << "Other string is not constant.";
+ Assert(!nc.isConst()) << "Other string is not constant.";
Assert(nc.getKind() != STRING_CONCAT) << "Other string is not CONCAT.";
if (!ee->areDisequal(nc, d_emptyString, true))
{
//
// E.g. x ++ ... = y ++ ... ---> (x = y ++ k) v (y = x ++ k)
Assert(d_state.areDisequal(xLenTerm, yLenTerm));
- Assert(x.getKind() != CONST_STRING);
- Assert(y.getKind() != CONST_STRING);
+ Assert(!x.isConst());
+ Assert(!y.isConst());
int32_t lentTestSuccess = -1;
Node lentTestExp;
{
Node t = e == 0 ? x : y;
// do not infer constants are larger than variables
- if (t.getKind() != CONST_STRING)
+ if (!t.isConst())
{
Node lt1 = e == 0 ? xLenTerm : yLenTerm;
Node lt2 = e == 0 ? yLenTerm : xLenTerm;
Trace("strings-solve-debug") << "...Processing(DEQ) " << i << " " << j << std::endl;
if (!d_state.areEqual(i, j))
{
- Assert(i.getKind() != kind::CONST_STRING
- || j.getKind() != kind::CONST_STRING);
+ Assert(!i.isConst() || !j.isConst());
std::vector< Node > lexp;
Node li = d_state.getLength(i, lexp);
Node lj = d_state.getLength(j, lexp);
if (d_state.areDisequal(li, lj))
{
- if( i.getKind()==kind::CONST_STRING || j.getKind()==kind::CONST_STRING ){
+ if (i.isConst() || j.isConst())
+ {
//check if empty
- Node const_k = i.getKind() == kind::CONST_STRING ? i : j;
- Node nconst_k = i.getKind() == kind::CONST_STRING ? j : i;
- Node lnck = i.getKind() == kind::CONST_STRING ? lj : li;
+ Node const_k = i.isConst() ? i : j;
+ Node nconst_k = i.isConst() ? j : i;
+ Node lnck = i.isConst() ? lj : li;
if( !ee->areDisequal( nconst_k, d_emptyString, true ) ){
Node eq = nconst_k.eqNode( d_emptyString );
Node conc = NodeManager::currentNM()->mkNode( kind::OR, eq, eq.negate() );
Trace("strings-solve-debug") << "...Processing(QED) " << i << " " << j << std::endl;
if (!d_state.areEqual(i, j))
{
- if( i.getKind()==kind::CONST_STRING && j.getKind()==kind::CONST_STRING ) {
+ if (i.isConst() && j.isConst())
+ {
size_t lenI = Word::getLength(i);
size_t lenJ = Word::getLength(j);
unsigned int len_short = lenI < lenJ ? lenI : lenJ;
<< " post=" << isSuf << std::endl;
Node prevC = utils::getConstantEndpoint(prev, isSuf);
Assert(!prevC.isNull());
- Assert(prevC.getKind() == CONST_STRING);
+ Assert(prevC.isConst());
if (c.isNull())
{
c = utils::getConstantEndpoint(t, isSuf);
Assert(!c.isNull());
}
- Assert(c.getKind() == CONST_STRING);
+ Assert(c.isConst());
bool conflict = false;
// if the constant prefixes are different
if (c != prevC)
{
return c;
}
- else if (effort >= 1 && n.getType().isString())
+ else if (effort >= 1 && n.getType().isStringLike())
{
Assert(effort < 3);
// normal forms
#include "theory/rewriter.h"
#include "theory/strings/theory_strings.h"
#include "theory/strings/theory_strings_utils.h"
+#include "theory/strings/word.h"
using namespace std;
using namespace CVC4::context;
void InferenceManager::registerLength(Node n)
{
+ Assert(n.getType().isStringLike());
NodeManager* nm = NodeManager::currentNM();
// register length information:
// for variables, split on empty vs positive length
// for concat/const/replace, introduce proxy var and state length relation
Node lsum;
- if (n.getKind() != STRING_CONCAT && n.getKind() != CONST_STRING)
+ if (n.getKind() != STRING_CONCAT && !n.isConst())
{
Node lsumb = nm->mkNode(STRING_LENGTH, n);
lsum = Rewriter::rewrite(lsumb);
lsum = nm->mkNode(PLUS, nodeVec);
lsum = Rewriter::rewrite(lsum);
}
- else if (n.getKind() == CONST_STRING)
+ else if (n.isConst())
{
- lsum = nm->mkConst(Rational(n.getConst<String>().size()));
+ lsum = nm->mkConst(Rational(Word::getLength(n)));
}
Assert(!lsum.isNull());
d_proxyVarToLength[sk] = lsum;
void NormalForm::init(Node base)
{
- Assert(base.getType().isString());
+ Assert(base.getType().isStringLike());
Assert(base.getKind() != STRING_CONCAT);
d_base = base;
d_nf.clear();
{
return rewriteArithEqualityExt(node);
}
- if (node[0].getType().isString())
+ if (node[0].getType().isStringLike())
{
return rewriteStrEqualityExt(node);
}
Node SequencesRewriter::rewriteStrEqualityExt(Node node)
{
- Assert(node.getKind() == EQUAL && node[0].getType().isString());
+ Assert(node.getKind() == EQUAL && node[0].getType().isStringLike());
TypeNode stype = node[0].getType();
NodeManager* nm = NodeManager::currentNM();
ei->d_codeTerm = t[0];
}
}
- else if (k == CONST_STRING)
+ else if (t.isConst())
{
EqcInfo* ei = getOrMakeEqcInfo(t);
ei->d_prefixC = t;
void StringsFmf::preRegisterTerm(TNode n)
{
- if (!n.getType().isString())
+ if (!n.getType().isStringLike())
{
return;
}
Trace("strings-eqc") << (t==0 ? "STRINGS:" : "OTHER:") << std::endl;
while( !eqcs2_i.isFinished() ){
Node eqc = (*eqcs2_i);
- bool print = (t==0 && eqc.getType().isString() ) || (t==1 && !eqc.getType().isString() );
+ bool print = (t == 0 && eqc.getType().isStringLike())
+ || (t == 1 && !eqc.getType().isStringLike());
if (print) {
eq::EqClassIterator eqc2_i = eq::EqClassIterator( eqc, &d_equalityEngine );
Trace("strings-eqc") << "Eqc( " << eqc << " ) : { ";
if( atom.getKind()==kind::EQUAL ){
Trace("strings-pending-debug") << " Register term" << std::endl;
for( unsigned j=0; j<2; j++ ) {
- if( !d_equalityEngine.hasTerm( atom[j] ) && atom[j].getType().isString() ) {
+ if (!d_equalityEngine.hasTerm(atom[j])
+ && atom[j].getType().isStringLike())
+ {
registerTerm( atom[j], 0 );
}
}
{
TypeNode tn = n.getType();
bool do_register = true;
- if (!tn.isString())
+ if (!tn.isStringLike())
{
if (options::stringEagerLen())
{
NodeManager* nm = NodeManager::currentNM();
Debug("strings-register") << "TheoryStrings::registerTerm() " << n
<< ", effort = " << effort << std::endl;
- if (tn.isString())
+ if (tn.isStringLike())
{
// register length information:
// for variables, split on empty vs positive length
if (!t.isString()) {
throw TypeCheckingExceptionPrivate(n, "expecting a string term in regexp range");
}
- if( (*it).getKind() != kind::CONST_STRING ) {
+ if (!(*it).isConst())
+ {
throw TypeCheckingExceptionPrivate(n, "expecting a constant string term in regexp range");
}
if( (*it).getConst<String>().size() != 1 ) {