summaryrefslogtreecommitdiff
path: root/src/theory/strings/theory_strings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/theory/strings/theory_strings.cpp')
-rw-r--r--src/theory/strings/theory_strings.cpp53
1 files changed, 34 insertions, 19 deletions
diff --git a/src/theory/strings/theory_strings.cpp b/src/theory/strings/theory_strings.cpp
index b77a616b3..3da652457 100644
--- a/src/theory/strings/theory_strings.cpp
+++ b/src/theory/strings/theory_strings.cpp
@@ -124,6 +124,7 @@ TheoryStrings::TheoryStrings(context::Context* c,
getExtTheory()->addFunctionKind(kind::STRING_STRREPL);
getExtTheory()->addFunctionKind(kind::STRING_STRCTN);
getExtTheory()->addFunctionKind(kind::STRING_IN_REGEXP);
+ getExtTheory()->addFunctionKind(kind::STRING_LEQ);
getExtTheory()->addFunctionKind(kind::STRING_CODE);
// The kinds we are treating as function application in congruence
@@ -133,6 +134,7 @@ TheoryStrings::TheoryStrings(context::Context* c,
d_equalityEngine.addFunctionKind(kind::STRING_CODE);
if( options::stringLazyPreproc() ){
d_equalityEngine.addFunctionKind(kind::STRING_STRCTN);
+ d_equalityEngine.addFunctionKind(kind::STRING_LEQ);
d_equalityEngine.addFunctionKind(kind::STRING_SUBSTR);
d_equalityEngine.addFunctionKind(kind::STRING_ITOS);
d_equalityEngine.addFunctionKind(kind::STRING_STOI);
@@ -142,6 +144,7 @@ TheoryStrings::TheoryStrings(context::Context* c,
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("") );
std::vector< Node > nvec;
d_emptyRegexp = NodeManager::currentNM()->mkNode( kind::REGEXP_EMPTY, nvec );
@@ -436,7 +439,8 @@ int TheoryStrings::getReduction( int effort, Node n, Node& nr ) {
Assert(k == STRING_SUBSTR || k == STRING_STRCTN || k == STRING_STRIDOF
|| k == STRING_ITOS
|| k == STRING_STOI
- || k == STRING_STRREPL);
+ || k == STRING_STRREPL
+ || k == STRING_LEQ);
std::vector< Node > new_nodes;
Node res = d_preproc.simplify( n, new_nodes );
Assert( res!=n );
@@ -547,8 +551,9 @@ bool TheoryStrings::collectModelInfo(TheoryModel* m)
Assert(d_normal_forms.find(eqc) != d_normal_forms.end());
if (d_normal_forms[eqc].size() == 1)
{
- // does it have a code?
- if (d_has_str_code)
+ // does it have a code and the length of these equivalence classes are
+ // one?
+ if (d_has_str_code && lts_values[i] == d_one)
{
EqcInfo* eip = getOrMakeEqcInfo(eqc, false);
if (eip && !eip->d_code_term.get().isNull())
@@ -563,7 +568,7 @@ bool TheoryStrings::collectModelInfo(TheoryModel* m)
vec.push_back(String::convertCodeToUnsignedInt(cvalue));
Node mv = nm->mkConst(String(vec));
pure_eq_assign[eqc] = mv;
- m->getEqualityEngine()->addTerm( mv );
+ m->getEqualityEngine()->addTerm(mv);
}
}
pure_eq.push_back(eqc);
@@ -579,7 +584,8 @@ bool TheoryStrings::collectModelInfo(TheoryModel* m)
//assign a new length if necessary
if( !pure_eq.empty() ){
if( lts_values[i].isNull() ){
- unsigned lvalue = 0;
+ // start with length two (other lengths have special precendence)
+ unsigned lvalue = 2;
while( values_used.find( lvalue )!=values_used.end() ){
lvalue++;
}
@@ -671,16 +677,22 @@ void TheoryStrings::preRegisterTerm(TNode n) {
if( d_pregistered_terms_cache.find(n) == d_pregistered_terms_cache.end() ) {
d_pregistered_terms_cache.insert(n);
//check for logic exceptions
+ Kind k = n.getKind();
if( !options::stringExp() ){
- if( n.getKind()==kind::STRING_STRIDOF ||
- n.getKind() == kind::STRING_ITOS || n.getKind() == kind::STRING_STOI ||
- n.getKind() == kind::STRING_STRREPL || n.getKind() == kind::STRING_STRCTN ){
+ if (k == kind::STRING_STRIDOF || k == kind::STRING_ITOS
+ || k == kind::STRING_STOI
+ || k == kind::STRING_STRREPL
+ || k == kind::STRING_STRCTN
+ || k == STRING_LEQ)
+ {
std::stringstream ss;
- ss << "Term of kind " << n.getKind() << " not supported in default mode, try --strings-exp";
+ ss << "Term of kind " << k
+ << " not supported in default mode, try --strings-exp";
throw LogicException(ss.str());
}
}
- switch( n.getKind() ) {
+ switch (k)
+ {
case kind::EQUAL: {
d_equalityEngine.addTriggerEquality(n);
break;
@@ -702,7 +714,7 @@ void TheoryStrings::preRegisterTerm(TNode n) {
// not belong to this theory.
if (options::stringFMF()
&& (n.isVar() ? d_all_skolems.find(n) == d_all_skolems.end()
- : kindToTheoryId(n.getKind()) != THEORY_STRINGS))
+ : kindToTheoryId(k) != THEORY_STRINGS))
{
d_input_vars.insert(n);
}
@@ -720,7 +732,9 @@ void TheoryStrings::preRegisterTerm(TNode n) {
}
}
//concat terms do not contribute to theory combination? TODO: verify
- if( n.hasOperator() && kindToTheoryId( n.getKind() )==THEORY_STRINGS && n.getKind()!=kind::STRING_CONCAT ){
+ if (n.hasOperator() && kindToTheoryId(k) == THEORY_STRINGS
+ && k != kind::STRING_CONCAT)
+ {
d_functionsTerms.push_back( n );
}
}
@@ -2218,13 +2232,15 @@ void TheoryStrings::checkNormalForms(){
cmps.pop_back();
for (const Node& c2 : cmps)
{
- Trace("strings-code-debug") << "Compare codes : " << c1 << " " << c2
- << std::endl;
- if (!areDisequal(c1, c2))
+ Trace("strings-code-debug")
+ << "Compare codes : " << c1 << " " << c2 << std::endl;
+ if (!areDisequal(c1, c2) && !areEqual(c1, d_neg_one))
{
+ Node eq_no = c1.eqNode(d_neg_one);
+ Node deq = c1.eqNode(c2).negate();
Node eqn = c1[0].eqNode(c2[0]);
- Node eq = c1.eqNode(c2);
- Node inj_lem = nm->mkNode(kind::OR, eq.negate(), eqn);
+ // str.code(x)==-1 V str.code(x)!=str.code(y) V x==y
+ Node inj_lem = nm->mkNode(kind::OR, eq_no, deq, eqn);
sendInference(d_empty_vec, inj_lem, "Code_Inj");
}
}
@@ -3520,9 +3536,8 @@ void TheoryStrings::registerTerm( Node n, int effort ) {
d_has_str_code = true;
NodeManager* nm = NodeManager::currentNM();
// ite( str.len(s)==1, 0 <= str.code(s) < num_codes, str.code(s)=-1 )
- Node neg_one = nm->mkConst(Rational(-1));
Node code_len = mkLength(n[0]).eqNode(d_one);
- Node code_eq_neg1 = n.eqNode(nm->mkConst(Rational(-1)));
+ Node code_eq_neg1 = n.eqNode(d_neg_one);
Node code_range = nm->mkNode(
kind::AND,
nm->mkNode(kind::GEQ, n, d_zero),
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback