d_sigma_star = NodeManager::currentNM()->mkNode( kind::REGEXP_STAR, d_sigma );\r
}\r
\r
+int RegExpOpr::gcd ( int a, int b ) {\r
+ int c;\r
+ while ( a != 0 ) {\r
+ c = a; a = b%a; b = c;\r
+ }\r
+ return b;\r
+}\r
+\r
bool RegExpOpr::checkConstRegExp( Node r ) {\r
Trace("strings-regexp-cstre") << "RegExp-CheckConstRegExp starts with " << mkString( r ) << std::endl;\r
bool ret = true;\r
return retNode;\r
}\r
\r
+//TODO:\r
+bool RegExpOpr::guessLength( Node r, int &co ) {\r
+ int k = r.getKind();\r
+ switch( k ) {\r
+ case kind::STRING_TO_REGEXP:\r
+ {\r
+ if(r[0].isConst()) {\r
+ co += r[0].getConst< CVC4::String >().size();\r
+ return true;\r
+ } else {\r
+ return false;\r
+ }\r
+ }\r
+ break;\r
+ case kind::REGEXP_CONCAT:\r
+ {\r
+ for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
+ if(!guessLength( r[i], co)) {\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ break;\r
+ case kind::REGEXP_OR:\r
+ {\r
+ int g_co;\r
+ for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
+ int cop = 0;\r
+ if(!guessLength( r[i], cop)) {\r
+ return false;\r
+ }\r
+ if(i == 0) {\r
+ g_co = cop;\r
+ } else {\r
+ g_co = gcd(g_co, cop);\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ break;\r
+ case kind::REGEXP_INTER:\r
+ {\r
+ int g_co;\r
+ for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
+ int cop = 0;\r
+ if(!guessLength( r[i], cop)) {\r
+ return false;\r
+ }\r
+ if(i == 0) {\r
+ g_co = cop;\r
+ } else {\r
+ g_co = gcd(g_co, cop);\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+ break;\r
+ case kind::REGEXP_STAR:\r
+ {\r
+ co = 0;\r
+ return true;\r
+ }\r
+ break;\r
+ default:\r
+ Trace("strings-error") << "Unsupported term: " << mkString( r ) << " in membership of RegExp." << std::endl;\r
+ return false;\r
+ }\r
+}\r
+\r
void RegExpOpr::firstChar( Node r ) {\r
Trace("strings-regexp-firstchar") << "Head characters: ";\r
for(char ch = d_char_start; ch <= d_char_end; ++ch) {\r
//void simplifyRegExp( Node s, Node r, std::vector< Node > &ret, std::vector< Node > &nn );\r
//Node simplify( Node t, std::vector< Node > &new_nodes );\r
std::string niceChar( Node r );\r
+ int gcd ( int a, int b );\r
+\r
public:\r
RegExpOpr();\r
bool checkConstRegExp( Node r );\r
Node complement( Node r );\r
int delta( Node r );\r
Node derivativeSingle( Node r, CVC4::String c );\r
+ bool guessLength( Node r, int &co );\r
void firstChar( Node r );\r
bool follow( Node r, CVC4::String c, std::vector< char > &vec_chars );\r
std::string mkString( Node r );\r
d_false = NodeManager::currentNM()->mkConst( false );
d_regexp_incomplete = false;
+ d_opt_regexp_gcd = true;
}
TheoryStrings::~TheoryStrings() {
return false;
}
-int TheoryStrings::gcd ( int a, int b ) {
- int c;
- while ( a != 0 ) {
- c = a; a = b%a; b = c;
- }
- return b;
-}
-
void TheoryStrings::getEquivalenceClasses( std::vector< Node >& eqcs ) {
eq::EqClassesIterator eqcs_i = eq::EqClassesIterator( &d_equalityEngine );
while( !eqcs_i.isFinished() ) {
Node r = atom[1];
Assert( r.getKind()==kind::REGEXP_STAR );
if( !areEqual( x, d_emptyString ) ) {
+ /*if(d_opt_regexp_gcd) {
+ if(d_membership_length.find(atom) == d_membership_length.end()) {
+ addedLemma = addMembershipLength(atom);
+ d_membership_length[atom] = true;
+ } else {
+ Trace("strings-regexp") << "Membership length is already added." << std::endl;
+ }
+ }*/
bool flag = true;
if( d_reg_exp_deriv.find(atom)==d_reg_exp_deriv.end() ) {
if(splitRegExp( x, r, atom )) {
Trace("strings-regexp-derivative") << "... is processed by deriv." << std::endl;
}
if( flag && d_reg_exp_unroll.find(atom)==d_reg_exp_unroll.end() ) {
- if( unrollStar( atom ) ) {
- addedLemma = true;
- } else {
- Trace("strings-regexp") << "RegExp is incomplete due to " << assertion << ", depth = " << d_regexp_unroll_depth << std::endl;
- is_unk = true;
- }
+ if( unrollStar( atom ) ) {
+ addedLemma = true;
+ } else {
+ Trace("strings-regexp") << "RegExp is incomplete due to " << assertion << ", depth = " << d_regexp_unroll_depth << std::endl;
+ is_unk = true;
+ }
} else {
Trace("strings-regexp") << "...is already unrolled or splitted." << std::endl;
}
}
}
+bool TheoryStrings::addMembershipLength(Node atom) {
+ Node x = atom[0];
+ Node r = atom[1];
+
+ /*std::vector< int > co;
+ co.push_back(0);
+ for(unsigned int k=0; k<lts.size(); ++k) {
+ if(lts[k].isConst() && lts[k].getType().isInteger()) {
+ int len = lts[k].getConst<Rational>().getNumerator().toUnsignedInt();
+ co[0] += cols[k].size() * len;
+ } else {
+ co.push_back( cols[k].size() );
+ }
+ }
+ int g_co = co[0];
+ for(unsigned k=1; k<co.size(); ++k) {
+ g_co = gcd(g_co, co[k]);
+ }*/
+ return false;
+}
+
bool TheoryStrings::splitRegExp( Node x, Node r, Node ant ) {
// TODO cstr in vre
Assert(x != d_emptyString);
Node d_zero;
// Options
bool d_opt_fmf;
+ bool d_opt_regexp_gcd;
// Helper functions
Node getRepresentative( Node t );
bool hasTerm( Node a );
bool checkCardinality();
bool checkInductiveEquations();
bool checkMemberships();
- int gcd(int a, int b);
public:
void preRegisterTerm(TNode n);
bool d_regexp_incomplete;
int d_regexp_unroll_depth;
int d_regexp_max_depth;
+ // membership length
+ std::map< Node, bool > d_membership_length;
// regular expression derivative
std::map< Node, bool > d_reg_exp_deriv;
// regular expression operations
CVC4::String getHeadConst( Node x );
bool splitRegExp( Node x, Node r, Node ant );
+ bool addMembershipLength(Node atom);
// Finite Model Finding