// static RewriteResponse TheorySetsRewriter::preRewrite(TNode node) { NodeManager* nm = NodeManager::currentNM(); // do nothing if(node.getKind() == kind::EQUAL && node[0] == node[1]) return RewriteResponse(REWRITE_DONE, nm->mkConst(true)); // Further optimization, if constants but differing ones return RewriteResponse(REWRITE_DONE, node); }
RewriteResponse TheorySepRewriter::postRewrite(TNode node) { Trace("sep-postrewrite") << "Sep::postRewrite start " << node << std::endl; Node retNode = node; switch (node.getKind()) { case kind::SEP_LABEL: { if( node[0].getKind()==kind::SEP_PTO ){ Node s = NodeManager::currentNM()->mkNode( kind::SINGLETON, node[0][0] ); if( node[1]!=s ){ Node c1 = node[1].eqNode( s ); Node c2 = NodeManager::currentNM()->mkNode( kind::SEP_LABEL, NodeManager::currentNM()->mkNode( kind::SEP_PTO, node[0][0], node[0][1] ), s ); retNode = NodeManager::currentNM()->mkNode( kind::AND, c1, c2 ); } } if( node[0].getKind()==kind::SEP_EMP ){ retNode = node[1].eqNode( NodeManager::currentNM()->mkConst(EmptySet(node[1].getType().toType())) ); } break; } case kind::SEP_PTO: { break; } case kind::SEP_STAR: { //flatten std::vector< Node > s_children; std::vector< Node > ns_children; getStarChildren( node, s_children, ns_children ); if( !s_children.empty() ){ Node schild; if( s_children.size()==1 ) { schild = s_children[0]; }else{ schild = NodeManager::currentNM()->mkNode( kind::SEP_STAR, s_children ); } ns_children.push_back( schild ); } Assert( !ns_children.empty() ); if( ns_children.size()==1 ){ retNode = ns_children[0]; }else{ retNode = NodeManager::currentNM()->mkNode( kind::AND, ns_children ); } break; } case kind::EQUAL: case kind::IFF: { if(node[0] == node[1]) { return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst(true)); } else if (node[0].isConst() && node[1].isConst()) { return RewriteResponse(REWRITE_DONE, NodeManager::currentNM()->mkConst(false)); } if (node[0] > node[1]) { Node newNode = NodeManager::currentNM()->mkNode(node.getKind(), node[1], node[0]); return RewriteResponse(REWRITE_DONE, newNode); } break; } default: break; } if( node!=retNode ){ Trace("sep-rewrite") << "Sep::rewrite : " << node << " -> " << retNode << std::endl; } return RewriteResponse(node==retNode ? REWRITE_DONE : REWRITE_AGAIN_FULL, retNode); }
// static RewriteResponse TheorySetsRewriter::postRewrite(TNode node) { NodeManager* nm = NodeManager::currentNM(); switch(node.getKind()) { case kind::IN: { if(!node[0].isConst() || !node[1].isConst()) break; // both are constants bool isMember = checkConstantMembership(node[0], node[1]); return RewriteResponse(REWRITE_DONE, nm->mkConst(isMember)); } case kind::SUBSET: { // rewrite (A subset-or-equal B) as (A union B = B) TNode A = node[0]; TNode B = node[1]; return RewriteResponse(REWRITE_AGAIN, nm->mkNode(kind::EQUAL, nm->mkNode(kind::UNION, A, B), B) ); }//kind::SUBSET case kind::EQUAL: case kind::IFF: { //rewrite: t = t with true (t term) //rewrite: c = c' with c different from c' false (c, c' constants) //otherwise: sort them if(node[0] == node[1]) { Trace("sets-postrewrite") << "Sets::postRewrite returning true" << std::endl; return RewriteResponse(REWRITE_DONE, nm->mkConst(true)); } else if (node[0].isConst() && node[1].isConst()) { Trace("sets-postrewrite") << "Sets::postRewrite returning false" << std::endl; return RewriteResponse(REWRITE_DONE, nm->mkConst(false)); } 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; } 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] > 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; } default: break; }//switch(node.getKind()) // This default implementation return RewriteResponse(REWRITE_DONE, node); }