<< std::endl;
return RewriteResponse(REWRITE_DONE, in[0][selectorIndex]);
}else{
- if( options::dtRewriteErrorSel() ){
- Node gt;
- if( in.getType().isSort() ){
- TypeEnumerator te(in.getType());
- gt = *te;
- }else{
- gt = in.getType().mkGroundTerm();
- }
- TypeNode gtt = gt.getType();
- //Assert( gtt.isDatatype() || gtt.isParametricDatatype() );
- if( gtt.isDatatype() && !gtt.isInstantiatedDatatype() ){
- gt = NodeManager::currentNM()->mkNode(kind::APPLY_TYPE_ASCRIPTION,
- NodeManager::currentNM()->mkConst(AscriptionType(in.getType().toType())), gt);
- }
- Trace("datatypes-rewrite") << "DatatypesRewriter::postRewrite: "
- << "Rewrite trivial selector " << in
- << " to distinguished ground term "
- << in.getType().mkGroundTerm() << std::endl;
- return RewriteResponse(REWRITE_DONE,gt );
+ //typically should not be called
+ Node gt;
+ if( in.getType().isSort() ){
+ TypeEnumerator te(in.getType());
+ gt = *te;
+ }else{
+ gt = in.getType().mkGroundTerm();
}
+ TypeNode gtt = gt.getType();
+ //Assert( gtt.isDatatype() || gtt.isParametricDatatype() );
+ if( gtt.isDatatype() && !gtt.isInstantiatedDatatype() ){
+ gt = NodeManager::currentNM()->mkNode(kind::APPLY_TYPE_ASCRIPTION,
+ NodeManager::currentNM()->mkConst(AscriptionType(in.getType().toType())), gt);
+ }
+ Trace("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::TUPLE_SELECT &&
return RewriteResponse(REWRITE_DONE,
NodeManager::currentNM()->mkConst(true));
}
- if(in.getKind() == kind::EQUAL &&
- checkClash(in[0], in[1])) {
- Trace("datatypes-rewrite") << "Rewrite clashing equality " << in << " to false" << std::endl;
- return RewriteResponse(REWRITE_DONE,
- NodeManager::currentNM()->mkConst(false));
+ if(in.getKind() == kind::EQUAL ) {
+ std::vector< Node > rew;
+ if( checkClash(in[0], in[1], rew) ){
+ Trace("datatypes-rewrite") << "Rewrite clashing equality " << in << " to false" << std::endl;
+ return RewriteResponse(REWRITE_DONE,
+ NodeManager::currentNM()->mkConst(false));
+ }else if( rew.size()!=1 || rew[0]!=in ){
+ Node nn = rew.size()==0 ? NodeManager::currentNM()->mkConst( true ) :
+ ( rew.size()==1 ? rew[0] : NodeManager::currentNM()->mkNode( kind::AND, rew ) );
+ Trace("datatypes-rewrite") << "Rewrite equality to " << nn << std::endl;
+ return RewriteResponse(REWRITE_AGAIN_FULL, nn );
+ }
}
return RewriteResponse(REWRITE_DONE, in);
static inline void init() {}
static inline void shutdown() {}
- static bool checkClash( Node n1, Node n2 ) {
+ static bool checkClash( Node n1, Node n2, std::vector< Node >& rew ) {
if( (n1.getKind() == kind::APPLY_CONSTRUCTOR && n2.getKind() == kind::APPLY_CONSTRUCTOR) ||
(n1.getKind() == kind::TUPLE && n2.getKind() == kind::TUPLE) ||
(n1.getKind() == kind::RECORD && n2.getKind() == kind::RECORD) ) {
} else {
Assert( n1.getNumChildren() == n2.getNumChildren() );
for( int i=0; i<(int)n1.getNumChildren(); i++ ) {
- if( checkClash( n1[i], n2[i] ) ) {
+ if( checkClash( n1[i], n2[i], rew ) ) {
return true;
}
}
}
- }else if( !isTermDatatype( n1 ) ){
- //also check for clashes between non-datatypes
+ }else{
Node eq = NodeManager::currentNM()->mkNode( n1.getType().isBoolean() ? kind::IFF : kind::EQUAL, n1, n2 );
- eq = Rewriter::rewrite( eq );
- if( eq==NodeManager::currentNM()->mkConst(false) ){
- return true;
- }
+ rew.push_back( eq );
}
return false;
}
Node TheoryDatatypes::expandDefinition(LogicRequest &logicRequest, Node n) {
switch( n.getKind() ){
case kind::APPLY_SELECTOR: {
- Node selector = n.getOperator();
- Expr selectorExpr = selector.toExpr();
+ Node selector = n.getOperator();
+ Expr selectorExpr = selector.toExpr();
+ Node sel = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( selectorExpr ), n[0] );
+ if( options::dtRewriteErrorSel() ){
+ return sel;
+ }else{
size_t selectorIndex = Datatype::cindexOf(selectorExpr);
const Datatype& dt = Datatype::datatypeOf(selectorExpr);
const DatatypeConstructor& c = dt[selectorIndex];
Expr tester = c.getTester();
Node tst = NodeManager::currentNM()->mkNode( kind::APPLY_TESTER, Node::fromExpr( tester ), n[0] );
tst = Rewriter::rewrite( tst );
- Node sel = NodeManager::currentNM()->mkNode( kind::APPLY_SELECTOR_TOTAL, Node::fromExpr( selectorExpr ), n[0] );
Node n_ret;
if( tst==NodeManager::currentNM()->mkConst( true ) ){
n_ret = sel;
Trace("dt-expand") << "Expand def : " << n << " to " << n_ret << std::endl;
return n_ret;
}
+ }
break;
default:
return n;
Node boundVarList = NodeManager::currentNM()->mkNode(kind::BOUND_VAR_LIST, vars);
Node curr;
for( int i=(d_models[op]->d_cond.size()-1); i>=0; i--) {
- Node v = getRepresentative( d_models[op]->d_value[i] );
+ Node v = d_models[op]->d_value[i];
+ if( !hasTerm( v ) ){
+ //can happen when the model basis term does not exist in ground assignment
+ TypeNode tn = v.getType();
+ if( d_rep_set.d_type_reps.find( tn )!=d_rep_set.d_type_reps.end() && !d_rep_set.d_type_reps[ tn ].empty() ){
+ //see full_model_check.cpp line 366
+ v = d_rep_set.d_type_reps[tn][ d_rep_set.d_type_reps[tn].size()-1 ];
+ }else{
+ Assert( false );
+ }
+ }
+ v = getRepresentative( v );
if( curr.isNull() ){
curr = v;
}else{
if( !isStar(cond[j][1]) ){
children.push_back( NodeManager::currentNM()->mkNode( LT, vars[j], cond[j][1] ) );
}
- }else if ( !isStar(cond[j]) && //handle the case where there are 0 or 1 ground representatives of this type...
+ }else if ( !isStar(cond[j]) && //handle the case where there are 0 or 1 ground eqc of this type
d_rep_set.d_type_reps.find( tn )!=d_rep_set.d_type_reps.end() && d_rep_set.d_type_reps[ tn ].size()>1 ){
Node c = getUsedRepresentative( cond[j] );
children.push_back( NodeManager::currentNM()->mkNode( EQUAL, vars[j], c ) );