Towards support for the strings standard. This adds support for str.is_digit and re.diff, which both can be eliminated eager during preprocessing.
{STRING_LEQ, CVC4::Kind::STRING_LEQ},
{STRING_PREFIX, CVC4::Kind::STRING_PREFIX},
{STRING_SUFFIX, CVC4::Kind::STRING_SUFFIX},
+ {STRING_IS_DIGIT, CVC4::Kind::STRING_IS_DIGIT},
{STRING_ITOS, CVC4::Kind::STRING_ITOS},
{STRING_STOI, CVC4::Kind::STRING_STOI},
{CONST_STRING, CVC4::Kind::CONST_STRING},
{REGEXP_CONCAT, CVC4::Kind::REGEXP_CONCAT},
{REGEXP_UNION, CVC4::Kind::REGEXP_UNION},
{REGEXP_INTER, CVC4::Kind::REGEXP_INTER},
+ {REGEXP_DIFF, CVC4::Kind::REGEXP_DIFF},
{REGEXP_STAR, CVC4::Kind::REGEXP_STAR},
{REGEXP_PLUS, CVC4::Kind::REGEXP_PLUS},
{REGEXP_OPT, CVC4::Kind::REGEXP_OPT},
{CVC4::Kind::STRING_LEQ, STRING_LEQ},
{CVC4::Kind::STRING_PREFIX, STRING_PREFIX},
{CVC4::Kind::STRING_SUFFIX, STRING_SUFFIX},
+ {CVC4::Kind::STRING_IS_DIGIT, STRING_IS_DIGIT},
{CVC4::Kind::STRING_ITOS, STRING_ITOS},
{CVC4::Kind::STRING_STOI, STRING_STOI},
{CVC4::Kind::CONST_STRING, CONST_STRING},
{CVC4::Kind::REGEXP_CONCAT, REGEXP_CONCAT},
{CVC4::Kind::REGEXP_UNION, REGEXP_UNION},
{CVC4::Kind::REGEXP_INTER, REGEXP_INTER},
+ {CVC4::Kind::REGEXP_DIFF, REGEXP_DIFF},
{CVC4::Kind::REGEXP_STAR, REGEXP_STAR},
{CVC4::Kind::REGEXP_PLUS, REGEXP_PLUS},
{CVC4::Kind::REGEXP_OPT, REGEXP_OPT},
* mkTerm(Kind kind, const std::vector<Term>& children)
*/
STRING_SUFFIX,
+ /**
+ * String is-digit.
+ * Returns true if string s is digit (it is one of "0", ..., "9").
+ * Parameters: 1
+ * -[1]: Term of sort String
+ * Create with:
+ * mkTerm(Kind kind, Term child1)
+ * mkTerm(Kind kind, const std::vector<Term>& children)
+ */
+ STRING_IS_DIGIT,
/**
* Integer to string.
* If the integer is negative this operator returns the empty string.
* mkTerm(Kind kind, const std::vector<Term>& children)
*/
REGEXP_INTER,
+ /**
+ * Regexp difference.
+ * Parameters: 2
+ * -[1]..[2]: Terms of Regexp sort
+ * Create with:
+ * mkTerm(Kind kind, Term child1, Term child2)
+ * mkTerm(Kind kind, const std::vector<Term>& children)
+ */
+ REGEXP_DIFF,
/**
* Regexp *.
* Parameters: 1
}
addOperator(kind::STRING_PREFIX, "str.prefixof" );
addOperator(kind::STRING_SUFFIX, "str.suffixof" );
+ addOperator(kind::STRING_IS_DIGIT, "str.is_digit" );
// at the moment, we only use this syntax for smt2.6.1
if (getLanguage() == language::input::LANG_SMTLIB_V2_6_1
|| getLanguage() == language::input::LANG_SYGUS_V2)
addOperator(kind::REGEXP_RANGE, "re.range");
addOperator(kind::REGEXP_LOOP, "re.loop");
addOperator(kind::REGEXP_COMPLEMENT, "re.comp");
+ addOperator(kind::REGEXP_DIFF, "re.diff");
addOperator(kind::STRING_LT, "str.<");
addOperator(kind::STRING_LEQ, "str.<=");
}
operator STRING_STRREPLALL 3 "string replace all"
operator STRING_PREFIX 2 "string prefixof"
operator STRING_SUFFIX 2 "string suffixof"
+operator STRING_IS_DIGIT 1 "string isdigit, returns true if argument is a string of length one that represents a digit"
operator STRING_ITOS 1 "integer to string"
operator STRING_STOI 1 "string to integer (total function)"
operator STRING_CODE 1 "string to code, returns the code of the first character of the string if it has length one, -1 otherwise"
operator REGEXP_CONCAT 2: "regexp concat"
operator REGEXP_UNION 2: "regexp union"
operator REGEXP_INTER 2: "regexp intersection"
+operator REGEXP_DIFF 2: "regexp difference"
operator REGEXP_STAR 1 "regexp *"
operator REGEXP_PLUS 1 "regexp +"
operator REGEXP_OPT 1 "regexp ?"
typerule REGEXP_CONCAT "SimpleTypeRuleVar<RRegExp, ARegExp>"
typerule REGEXP_UNION "SimpleTypeRuleVar<RRegExp, ARegExp>"
typerule REGEXP_INTER "SimpleTypeRuleVar<RRegExp, ARegExp>"
+typerule REGEXP_DIFF "SimpleTypeRuleVar<RRegExp, ARegExp>"
typerule REGEXP_STAR "SimpleTypeRule<RRegExp, ARegExp>"
typerule REGEXP_PLUS "SimpleTypeRule<RRegExp, ARegExp>"
typerule REGEXP_OPT "SimpleTypeRule<RRegExp, ARegExp>"
typerule STRING_STRREPLALL "SimpleTypeRule<RString, AString, AString, AString>"
typerule STRING_PREFIX "SimpleTypeRule<RBool, AString, AString>"
typerule STRING_SUFFIX "SimpleTypeRule<RBool, AString, AString>"
+typerule STRING_IS_DIGIT "SimpleTypeRule<RBool, AString>"
typerule STRING_ITOS "SimpleTypeRule<RString, AInteger>"
typerule STRING_STOI "SimpleTypeRule<RInteger, AString>"
typerule STRING_CODE "SimpleTypeRule<RInteger, AString>"
{
retNode = rewritePrefixSuffix(node);
}
+ else if (nk == STRING_IS_DIGIT)
+ {
+ // eliminate str.is_digit(s) ----> 48 <= str.to_code(s) <= 57
+ Node t = nm->mkNode(STRING_CODE, node[0]);
+ retNode = nm->mkNode(AND,
+ nm->mkNode(LEQ, nm->mkConst(Rational(48)), t),
+ nm->mkNode(LEQ, t, nm->mkConst(Rational(57))));
+ }
else if (nk == kind::STRING_ITOS)
{
if(node[0].isConst()) {
{
retNode = rewriteAndOrRegExp(node);
}
+ else if (nk == REGEXP_DIFF)
+ {
+ retNode = nm->mkNode(REGEXP_INTER, node[0],nm->mkNode(REGEXP_COMPLEMENT, node[1]));
+ }
else if (nk == REGEXP_STAR)
{
retNode = rewriteStarRegExp(node);
regress0/strings/idof-sem.smt2
regress0/strings/ilc-like.smt2
regress0/strings/indexof-sym-simp.smt2
+ regress0/strings/is_digit_simple.smt2
regress0/strings/issue1189.smt2
regress0/strings/issue2958.smt2
regress0/strings/issue3440.smt2
regress0/strings/parser-syms.cvc
regress0/strings/re.all.smt2
regress0/strings/re-syntax.smt2
+ regress0/strings/re_diff.smt2
regress0/strings/regexp-native-simple.cvc
regress0/strings/regexp_inclusion.smt2
regress0/strings/regexp_inclusion_reduction.smt2
--- /dev/null
+; COMMAND-LINE: --lang=smt2.6.1
+; EXPECT: sat
+(set-logic ALL)
+(set-info :status sat)
+
+(assert (str.is_digit "0"))
+(assert (str.is_digit "7"))
+(assert (not (str.is_digit "A")))
+(assert (not (str.is_digit "")))
+
+(check-sat)
--- /dev/null
+; COMMAND-LINE: --lang=smt2.6.1
+; EXPECT: unsat
+(set-logic ALL)
+(set-info :status unsat)
+(declare-fun x () String)
+(declare-fun y () String)
+
+(assert (str.in_re x (re.diff (re.* (str.to_re "A")) re.none)))
+(assert (or (not (str.in_re x (re.* (str.to_re "A")))) (str.in_re y (re.diff (re.* (str.to_re "B")) re.all))))
+
+(check-sat)