-/********************* */\r
-/*! \file theory_strings_preprocess.cpp\r
- ** \verbatim\r
- ** Original author: Tianyi Liang\r
- ** Major contributors: Tianyi Liang, Andrew Reynolds\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 prototype.\r
- ** Copyright (c) 2013-2013 New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief Strings Preprocess\r
- **\r
- ** Strings Preprocess.\r
- **/\r
-\r
-#include "theory/strings/theory_strings_preprocess.h"\r
-#include "expr/kind.h"\r
-\r
-namespace CVC4 {\r
-namespace theory {\r
-namespace strings {\r
-\r
-void StringsPreprocess::simplifyRegExp( Node s, Node r, std::vector< Node > &ret ) {\r
- int k = r.getKind();\r
- switch( k ) {\r
- case kind::STRING_TO_REGEXP:\r
- {\r
- Node eq = NodeManager::currentNM()->mkNode( kind::EQUAL, s, r[0] );\r
- ret.push_back( eq );\r
- }\r
- break;\r
- case kind::REGEXP_CONCAT:\r
- {\r
- std::vector< Node > cc;\r
- for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
- Node sk = NodeManager::currentNM()->mkSkolem( "recsym_$$", s.getType(), "created for regular expression concat" );\r
- simplifyRegExp( sk, r[i], ret );\r
- cc.push_back( sk );\r
- }\r
- Node cc_eq = NodeManager::currentNM()->mkNode( kind::EQUAL, s, \r
- NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, cc ) );\r
- ret.push_back( cc_eq );\r
- }\r
- break;\r
- case kind::REGEXP_OR:\r
- {\r
- std::vector< Node > c_or;\r
- for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
- simplifyRegExp( s, r[i], c_or );\r
- }\r
- Node eq = NodeManager::currentNM()->mkNode( kind::OR, c_or );\r
- ret.push_back( eq );\r
- }\r
- break;\r
- case kind::REGEXP_INTER:\r
- for(unsigned i=0; i<r.getNumChildren(); ++i) {\r
- simplifyRegExp( s, r[i], ret );\r
- }\r
- break;\r
- case kind::REGEXP_STAR:\r
- {\r
- Node sk = NodeManager::currentNM()->mkSkolem( "ressym_$$", s.getType(), "created for regular expression star" );\r
- Node eq = NodeManager::currentNM()->mkNode( kind::EQUAL,\r
- NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, sk, s ),\r
- NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, s, sk ));\r
- ret.push_back( eq );\r
- simplifyRegExp( sk, r[0], ret );\r
- }\r
- break;\r
- case kind::REGEXP_OPT:\r
- {\r
- Node eq_empty = NodeManager::currentNM()->mkNode( kind::EQUAL, s, NodeManager::currentNM()->mkConst( ::CVC4::String("") ) );\r
- std::vector< Node > rr;\r
- simplifyRegExp( s, r[0], rr );\r
- Node nrr = rr.size()==1 ? rr[0] : NodeManager::currentNM()->mkNode( kind::AND, rr );\r
- ret.push_back( NodeManager::currentNM()->mkNode( kind::OR, eq_empty, nrr) );\r
- }\r
- break;\r
- default:\r
- //TODO:case kind::REGEXP_PLUS:\r
- //TODO: special sym: sigma, none, all\r
- break;\r
- }\r
-}\r
-\r
-Node StringsPreprocess::simplify( Node t ) {\r
- if( t.getKind() == kind::STRING_IN_REGEXP ){\r
- // t0 in t1\r
- //rewrite it\r
- std::vector< Node > ret;\r
- simplifyRegExp( t[0], t[1], ret );\r
-\r
- return ret.size() == 1 ? ret[0] : NodeManager::currentNM()->mkNode( kind::AND, ret );\r
- }else if( t.getNumChildren()>0 ){\r
- std::vector< Node > cc;\r
- if (t.getMetaKind() == kind::metakind::PARAMETERIZED) {\r
- cc.push_back(t.getOperator());\r
- }\r
- bool changed = false;\r
- for( unsigned i=0; i<t.getNumChildren(); i++ ){\r
- Node tn = simplify( t[i] );\r
- cc.push_back( tn );\r
- changed = changed || tn!=t[i];\r
- }\r
- return changed ? NodeManager::currentNM()->mkNode( t.getKind(), cc ) : t;\r
- }else{\r
- return t;\r
- }\r
-}\r
-\r
-void StringsPreprocess::simplify(std::vector< Node > &vec_node) {\r
- for( unsigned i=0; i<vec_node.size(); i++ ){\r
- vec_node[i] = simplify( vec_node[i] );\r
- }\r
-}\r
-\r
-}/* CVC4::theory::strings namespace */\r
-}/* CVC4::theory namespace */\r
-}/* CVC4 namespace */\r
+/********************* */
+/*! \file theory_strings_preprocess.cpp
+ ** \verbatim
+ ** Original author: Tianyi Liang
+ ** Major contributors: Tianyi Liang, Andrew Reynolds
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2013-2013 New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Strings Preprocess
+ **
+ ** Strings Preprocess.
+ **/
+
+#include "theory/strings/theory_strings_preprocess.h"
+#include "expr/kind.h"
+
+namespace CVC4 {
+namespace theory {
+namespace strings {
+
+void StringsPreprocess::simplifyRegExp( Node s, Node r, std::vector< Node > &ret ) {
+ int k = r.getKind();
+ switch( k ) {
+ case kind::STRING_TO_REGEXP:
+ {
+ Node eq = NodeManager::currentNM()->mkNode( kind::EQUAL, s, r[0] );
+ ret.push_back( eq );
+ }
+ break;
+ case kind::REGEXP_CONCAT:
+ {
+ std::vector< Node > cc;
+ for(unsigned i=0; i<r.getNumChildren(); ++i) {
+ Node sk = NodeManager::currentNM()->mkSkolem( "recsym_$$", s.getType(), "created for regular expression concat" );
+ simplifyRegExp( sk, r[i], ret );
+ cc.push_back( sk );
+ }
+ Node cc_eq = NodeManager::currentNM()->mkNode( kind::EQUAL, s,
+ NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, cc ) );
+ ret.push_back( cc_eq );
+ }
+ break;
+ case kind::REGEXP_OR:
+ {
+ std::vector< Node > c_or;
+ for(unsigned i=0; i<r.getNumChildren(); ++i) {
+ simplifyRegExp( s, r[i], c_or );
+ }
+ Node eq = NodeManager::currentNM()->mkNode( kind::OR, c_or );
+ ret.push_back( eq );
+ }
+ break;
+ case kind::REGEXP_INTER:
+ for(unsigned i=0; i<r.getNumChildren(); ++i) {
+ simplifyRegExp( s, r[i], ret );
+ }
+ break;
+ case kind::REGEXP_STAR:
+ {
+ Node sk = NodeManager::currentNM()->mkSkolem( "ressym_$$", s.getType(), "created for regular expression star" );
+ Node eq = NodeManager::currentNM()->mkNode( kind::EQUAL,
+ NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, sk, s ),
+ NodeManager::currentNM()->mkNode( kind::STRING_CONCAT, s, sk ));
+ ret.push_back( eq );
+ simplifyRegExp( sk, r[0], ret );
+ }
+ break;
+ case kind::REGEXP_OPT:
+ {
+ Node eq_empty = NodeManager::currentNM()->mkNode( kind::EQUAL, s, NodeManager::currentNM()->mkConst( ::CVC4::String("") ) );
+ std::vector< Node > rr;
+ simplifyRegExp( s, r[0], rr );
+ Node nrr = rr.size()==1 ? rr[0] : NodeManager::currentNM()->mkNode( kind::AND, rr );
+ ret.push_back( NodeManager::currentNM()->mkNode( kind::OR, eq_empty, nrr) );
+ }
+ break;
+ default:
+ //TODO:case kind::REGEXP_PLUS:
+ //TODO: special sym: sigma, none, all
+ break;
+ }
+}
+
+Node StringsPreprocess::simplify( Node t ) {
+ std::hash_map<TNode, Node, TNodeHashFunction>::const_iterator i = d_cache.find(t);
+ if(i != d_cache.end()) {
+ return (*i).second.isNull() ? t : (*i).second;
+ }
+
+ if( t.getKind() == kind::STRING_IN_REGEXP ){
+ // t0 in t1
+ //rewrite it
+ std::vector< Node > ret;
+ simplifyRegExp( t[0], t[1], ret );
+
+ Node n = ret.size() == 1 ? ret[0] : NodeManager::currentNM()->mkNode( kind::AND, ret );
+ d_cache[t] = (t == n) ? Node::null() : n;
+ return n;
+ }else if( t.getNumChildren()>0 ){
+ std::vector< Node > cc;
+ if (t.getMetaKind() == kind::metakind::PARAMETERIZED) {
+ cc.push_back(t.getOperator());
+ }
+ bool changed = false;
+ for( unsigned i=0; i<t.getNumChildren(); i++ ){
+ Node tn = simplify( t[i] );
+ cc.push_back( tn );
+ changed = changed || tn!=t[i];
+ }
+ if(changed) {
+ Node n = NodeManager::currentNM()->mkNode( t.getKind(), cc );
+ d_cache[t] = n;
+ return n;
+ } else {
+ d_cache[t] = Node::null();
+ return t;
+ }
+ }else{
+ d_cache[t] = Node::null();
+ return t;
+ }
+}
+
+void StringsPreprocess::simplify(std::vector< Node > &vec_node) {
+ for( unsigned i=0; i<vec_node.size(); i++ ){
+ vec_node[i] = simplify( vec_node[i] );
+ }
+}
+
+}/* CVC4::theory::strings namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
-/********************* */\r
-/*! \file theory_strings_preprocess.h\r
- ** \verbatim\r
- ** Original author: Tianyi Liang\r
- ** Major contributors: Tianyi Liang, Andrew Reynolds\r
- ** Minor contributors (to current version): none\r
- ** This file is part of the CVC4 prototype.\r
- ** Copyright (c) 2013-2013 New York University and The University of Iowa\r
- ** See the file COPYING in the top-level source directory for licensing\r
- ** information.\endverbatim\r
- **\r
- ** \brief Strings Preprocess\r
- **\r
- ** Strings Preprocess.\r
- **/\r
-\r
-#include "cvc4_private.h"\r
-\r
-#ifndef __CVC4__THEORY__STRINGS__PREPROCESS_H\r
-#define __CVC4__THEORY__STRINGS__PREPROCESS_H\r
-\r
-#include <vector>\r
-#include "theory/theory.h"\r
-\r
-namespace CVC4 {\r
-namespace theory {\r
-namespace strings {\r
-\r
-class StringsPreprocess {\r
-private:\r
- void simplifyRegExp( Node s, Node r, std::vector< Node > &ret );\r
- Node simplify( Node t );\r
-public:\r
-void simplify(std::vector< Node > &vec_node);\r
-};\r
-\r
-}/* CVC4::theory::strings namespace */\r
-}/* CVC4::theory namespace */\r
-}/* CVC4 namespace */\r
-\r
-#endif /* __CVC4__THEORY__STRINGS__PREPROCESS_H */\r
+/********************* */
+/*! \file theory_strings_preprocess.h
+ ** \verbatim
+ ** Original author: Tianyi Liang
+ ** Major contributors: Tianyi Liang, Andrew Reynolds
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2013-2013 New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Strings Preprocess
+ **
+ ** Strings Preprocess.
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__THEORY__STRINGS__PREPROCESS_H
+#define __CVC4__THEORY__STRINGS__PREPROCESS_H
+
+#include <vector>
+#include "util/hash.h"
+#include "theory/theory.h"
+
+namespace CVC4 {
+namespace theory {
+namespace strings {
+
+class StringsPreprocess {
+ // NOTE: this class is NOT context-dependent
+ std::hash_map<TNode, Node, TNodeHashFunction> d_cache;
+private:
+ void simplifyRegExp( Node s, Node r, std::vector< Node > &ret );
+ Node simplify( Node t );
+public:
+void simplify(std::vector< Node > &vec_node);
+};
+
+}/* CVC4::theory::strings namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
+
+#endif /* __CVC4__THEORY__STRINGS__PREPROCESS_H */