// Computer terms appearing assertions and shared terms
d_external.computeRelevantTerms(terms);
+ // compute for each setterm elements that it contains
+ SettermElementsMap settermElementsMap;
+ TNode true_atom = NodeManager::currentNM()->mkConst<bool>(true);
+ TNode false_atom = NodeManager::currentNM()->mkConst<bool>(false);
+ for(eq::EqClassIterator it_eqclasses(true_atom, &d_equalityEngine);
+ ! it_eqclasses.isFinished() ; ++it_eqclasses) {
+ TNode n = (*it_eqclasses);
+ if(n.getKind() == kind::MEMBER) {
+ Assert(d_equalityEngine.areEqual(n, true_atom));
+ TNode x = d_equalityEngine.getRepresentative(n[0]);
+ TNode S = d_equalityEngine.getRepresentative(n[1]);
+ settermElementsMap[S].insert(x);
+ }
+ }
+
// Assert equalities and disequalities to the model
m->assertEqualityEngine(&d_equalityEngine, &terms);
- // Loop over all collect set-terms for which we generate models
+ // Loop over terms to collect set-terms for which we generate models
set<Node> settermsModEq;
- SettermElementsMap settermElementsMap;
BOOST_FOREACH(TNode term, terms) {
TNode n = term.getKind() == kind::NOT ? term[0] : term;
Debug("sets-model-details") << "[sets-model-details] > " << n << std::endl;
- if(n.getKind() == kind::EQUAL) {
- // nothing to do
- } else if(n.getKind() == kind::MEMBER) {
-
- TNode true_atom = NodeManager::currentNM()->mkConst<bool>(true);
-
- if(d_equalityEngine.areEqual(n, true_atom)) {
- TNode x = d_equalityEngine.getRepresentative(n[0]);
- TNode S = d_equalityEngine.getRepresentative(n[1]);
-
- settermElementsMap[S].insert(x);
- }
-
- } else if(n.getType().isSet()) {
-
+ if(n.getType().isSet()) {
n = d_equalityEngine.getRepresentative(n);
-
if( !n.isConst() ) {
settermsModEq.insert(n);
}
-
}
}
}
}
- // settermElementsMap processing
BOOST_FOREACH( SettermElementsMap::value_type &it, settermElementsMap ) {
BOOST_FOREACH( TNode element, it.second /* elements */ ) {
Debug("sets-model-details") << "[sets-model-details] > " <<
// static
RewriteResponse TheorySetsRewriter::postRewrite(TNode node) {
NodeManager* nm = NodeManager::currentNM();
+ Kind kind = node.getKind();
- switch(node.getKind()) {
+ switch(kind) {
case kind::MEMBER: {
if(!node[0].isConst() || !node[1].isConst())
// both are constants
bool isMember = checkConstantMembership(node[0], node[1]);
return RewriteResponse(REWRITE_DONE, nm->mkConst(isMember));
- }
+ }//kind::MEMBER
case kind::SUBSET: {
// rewrite (A subset-or-equal B) as (A union B = B)
return RewriteResponse(REWRITE_DONE, newNode);
}
break;
- }
+ }//kind::IFF
+
+ case kind::SETMINUS: {
+ if(node[0] == node[1]) {
+ Node newNode = nm->mkConst(EmptySet(nm->toType(node[0].getType())));
+ Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
+ return RewriteResponse(REWRITE_DONE, newNode);
+ } else if(node[0].getKind() == kind::EMPTYSET ||
+ node[1].getKind() == kind::EMPTYSET) {
+ Trace("sets-postrewrite") << "Sets::postRewrite returning " << node[0] << std::endl;
+ return RewriteResponse(REWRITE_DONE, node[0]);
+ } else if (node[0] > node[1]) {
+ Node newNode = nm->mkNode(node.getKind(), node[1], node[0]);
+ Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
+ return RewriteResponse(REWRITE_DONE, newNode);
+ }
+ break;
+ }//kind::INTERSECION
- case kind::UNION:
case kind::INTERSECTION: {
if(node[0] == node[1]) {
Trace("sets-postrewrite") << "Sets::postRewrite returning " << node[0] << std::endl;
return RewriteResponse(REWRITE_DONE, node[0]);
+ } else if(node[0].getKind() == kind::EMPTYSET) {
+ return RewriteResponse(REWRITE_DONE, node[0]);
+ } else if(node[1].getKind() == kind::EMPTYSET) {
+ return RewriteResponse(REWRITE_DONE, node[1]);
} else if (node[0] > node[1]) {
Node newNode = nm->mkNode(node.getKind(), node[1], node[0]);
Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
return RewriteResponse(REWRITE_DONE, newNode);
}
break;
- }
+ }//kind::INTERSECION
- default:
+ case kind::UNION: {
+ if(node[0] == node[1]) {
+ Trace("sets-postrewrite") << "Sets::postRewrite returning " << node[0] << std::endl;
+ return RewriteResponse(REWRITE_DONE, node[0]);
+ } else if(node[0].getKind() == kind::EMPTYSET) {
+ return RewriteResponse(REWRITE_DONE, node[1]);
+ } else if(node[1].getKind() == kind::EMPTYSET) {
+ return RewriteResponse(REWRITE_DONE, node[0]);
+ } else if (node[0] > node[1]) {
+ Node newNode = nm->mkNode(node.getKind(), node[1], node[0]);
+ Trace("sets-postrewrite") << "Sets::postRewrite returning " << newNode << std::endl;
+ return RewriteResponse(REWRITE_DONE, newNode);
+ }
break;
+ }//kind::UNION
+ default:
+ break;
}//switch(node.getKind())
// This default implementation