#define __CVC4__THEORY__DATATYPES__DATATYPES_REWRITER_H
#include "theory/rewriter.h"
+#include "theory/datatypes/options.h"
namespace CVC4 {
namespace theory {
<< "Rewrite trivial selector " << in
<< std::endl;
return RewriteResponse(REWRITE_DONE, in[0][selectorIndex]);
- }
- /*
- Node gt = in.getType().mkGroundTerm();
- TypeNode gtt = gt.getType();
- //Assert( gtt.isDatatype() || gtt.isParametricDatatype() );
- if( !gtt.isInstantiatedDatatype() ){
- gt = NodeManager::currentNM()->mkNode(kind::APPLY_TYPE_ASCRIPTION,
- NodeManager::currentNM()->mkConst(AscriptionType(in.getType().toType())), gt);
+ }else{
+ if( options::dtRewriteErrorSel() ){
+ Node gt = in.getType().mkGroundTerm();
+ TypeNode gtt = gt.getType();
+ //Assert( gtt.isDatatype() || gtt.isParametricDatatype() );
+ if( !gtt.isInstantiatedDatatype() ){
+ gt = NodeManager::currentNM()->mkNode(kind::APPLY_TYPE_ASCRIPTION,
+ NodeManager::currentNM()->mkConst(AscriptionType(in.getType().toType())), gt);
+ }
+ Debug("datatypes-rewrite") << "DatatypesRewriter::postRewrite: "
+ << "Rewrite trivial selector " << in
+ << " to distinguished ground term "
+ << in.getType().mkGroundTerm() << std::endl;
+ return RewriteResponse(REWRITE_DONE,gt );
}
- Debug("datatypes-rewrite") << "DatatypesRewriter::postRewrite: "
- << "Rewrite trivial selector " << in
- << " to distinguished ground term "
- << in.getType().mkGroundTerm() << std::endl;
- return RewriteResponse(REWRITE_DONE,gt );
- */
+ }
}
if(in.getKind() == kind::EQUAL && in[0] == in[1]) {
d_infer_exp(c),
d_notify( *this ),
d_equalityEngine(d_notify, c, "theory::datatypes::TheoryDatatypes"),
+ d_selector_apps( c ),
d_labels( c ),
d_conflict( c, false ){
++eqcs_i;
}
flushPendingFacts();
- //if( !d_conflict ){
- // printModelDebug();
- //}
+ if( !d_conflict ){
+ if( options::dtRewriteErrorSel() ){
+ collapseSelectors();
+ flushPendingFacts();
+ }
+ }
+ if( !d_conflict ){
+ // printModelDebug();
+ }
}
if( Debug.isOn("datatypes") || Debug.isOn("datatypes-split") ) {
d_hasSeenCycle.set( d_hasSeenCycle.get() || result );
}
}else if( n.getKind() == APPLY_SELECTOR ){
- //we must also record which selectors exist
- Debug("datatypes") << " Found selector " << n << endl;
- if (n.getType().isBoolean()) {
- d_equalityEngine.addTriggerPredicate( n );
- }else{
- d_equalityEngine.addTerm( n );
- }
- Node rep = getRepresentative( n[0] );
- EqcInfo* eqc = getOrMakeEqcInfo( rep, true );
- if( !eqc->d_selectors ){
- eqc->d_selectors = true;
- instantiate( eqc, rep );
+ if( d_selector_apps.find( n )==d_selector_apps.end() ){
+ d_selector_apps[n] = false;
+ //we must also record which selectors exist
+ Debug("datatypes") << " Found selector " << n << endl;
+ if (n.getType().isBoolean()) {
+ d_equalityEngine.addTriggerPredicate( n );
+ }else{
+ d_equalityEngine.addTerm( n );
+ }
+ Node rep = getRepresentative( n[0] );
+ EqcInfo* eqc = getOrMakeEqcInfo( rep, true );
+ if( !eqc->d_selectors ){
+ eqc->d_selectors = true;
+ instantiate( eqc, rep );
+ }
}
}
}
//}
}
+void TheoryDatatypes::collapseSelectors(){
+ //must check incorrect applications of selectors
+ for( BoolMap::iterator it = d_selector_apps.begin(); it != d_selector_apps.end(); ++it ){
+ if( !(*it).second ){
+ Node n = (*it).first[0];
+ EqcInfo* ei = getOrMakeEqcInfo( n );
+ if( ei ){
+ if( !ei->d_constructor.get().isNull() ){
+ Node op = (*it).first.getOperator();
+ Node cons = ei->d_constructor;
+ Node sn = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR, op, cons );
+ Node s = Rewriter::rewrite( sn );
+ if( sn!=s ){
+ Node eq = s.eqNode( sn );
+ d_pending.push_back( eq );
+ d_pending_exp[ eq ] = NodeManager::currentNM()->mkConst( true );
+ Trace("datatypes-infer") << "DtInfer : " << eq << ", by rewrite" << std::endl;
+ d_infer.push_back( eq );
+ }
+ d_selector_apps[ (*it).first ] = true;
+ }
+ }
+ }
+ }
+}
+
void TheoryDatatypes::instantiate( EqcInfo* eqc, Node n ){
//add constructor to equivalence class if not done so already
if( hasLabel( eqc, n ) && !eqc->d_inst ){
eq::EqualityEngine d_equalityEngine;
/** information necessary for equivalence classes */
std::map< Node, EqcInfo* > d_eqc_info;
+ /** selector applications */
+ BoolMap d_selector_apps;
/** map from nodes to their instantiated equivalent for each constructor type */
std::map< Node, std::map< int, Node > > d_inst_map;
/** which instantiation lemmas we have sent */
void processNewTerm( Node n );
/** check instantiate */
void instantiate( EqcInfo* eqc, Node n );
+ /** collapse selectors */
+ void collapseSelectors();
/** must specify model
* This returns true when the datatypes theory is expected to specify the constructor
* type for all equivalence classes.