Node NaryBuilder::zeroArity(Kind k){ using namespace kind; NodeManager* nm = NodeManager::currentNM(); switch(k){ case AND: return nm->mkConst(true); case OR: return nm->mkConst(false); case PLUS: return nm->mkConst(Rational(0)); case MULT: return nm->mkConst(Rational(1)); default: return Node::null(); } }
// 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); }
Node InferBoundsResult::getLiteral() const{ const Rational& q = getValue().getNoninfinitesimalPart(); NodeManager* nm = NodeManager::currentNM(); Node qnode = nm->mkConst(q); Kind k; if(d_upperBound){ // x <= q + c*delta Assert(getValue().infinitesimalSgn() <= 0); k = boundIsRational() ? kind::LEQ : kind::LT; }else{ // x >= q + c*delta Assert(getValue().infinitesimalSgn() >= 0); k = boundIsRational() ? kind::GEQ : kind::GT; } Node atom = nm->mkNode(k, getTerm(), qnode); Node lit = Rewriter::rewrite(atom); return lit; }
PreprocessingPassResult SygusAbduct::applyInternal( AssertionPipeline* assertionsToPreprocess) { NodeManager* nm = NodeManager::currentNM(); Trace("sygus-abduct") << "Run sygus abduct..." << std::endl; Trace("sygus-abduct-debug") << "Collect symbols..." << std::endl; std::unordered_set<Node, NodeHashFunction> symset; std::vector<Node>& asserts = assertionsToPreprocess->ref(); // do we have any assumptions, e.g. via check-sat-assuming? bool usingAssumptions = (assertionsToPreprocess->getNumAssumptions() > 0); // The following is our set of "axioms". We construct this set only when the // usingAssumptions (above) is true. In this case, our input formula is // partitioned into Fa ^ Fc as described in the header of this class, where: // - The conjunction of assertions marked as assumptions are the negated // conjecture Fc, and // - The conjunction of all other assertions are the axioms Fa. std::vector<Node> axioms; for (size_t i = 0, size = asserts.size(); i < size; i++) { expr::getSymbols(asserts[i], symset); // if we are not an assumption, add it to the set of axioms if (usingAssumptions && i < assertionsToPreprocess->getAssumptionsStart()) { axioms.push_back(asserts[i]); } } Trace("sygus-abduct-debug") << "...finish, got " << symset.size() << " symbols." << std::endl; Trace("sygus-abduct-debug") << "Setup symbols..." << std::endl; std::vector<Node> syms; std::vector<Node> vars; std::vector<Node> varlist; std::vector<TypeNode> varlistTypes; for (const Node& s : symset) { TypeNode tn = s.getType(); if (tn.isFirstClass()) { std::stringstream ss; ss << s; Node var = nm->mkBoundVar(tn); syms.push_back(s); vars.push_back(var); Node vlv = nm->mkBoundVar(ss.str(), tn); varlist.push_back(vlv); varlistTypes.push_back(tn); } } Trace("sygus-abduct-debug") << "...finish" << std::endl; Trace("sygus-abduct-debug") << "Make abduction predicate..." << std::endl; // make the abduction predicate to synthesize TypeNode abdType = varlistTypes.empty() ? nm->booleanType() : nm->mkPredicateType(varlistTypes); Node abd = nm->mkBoundVar("A", abdType); Trace("sygus-abduct-debug") << "...finish" << std::endl; Trace("sygus-abduct-debug") << "Make abduction predicate app..." << std::endl; std::vector<Node> achildren; achildren.push_back(abd); achildren.insert(achildren.end(), vars.begin(), vars.end()); Node abdApp = vars.empty() ? abd : nm->mkNode(APPLY_UF, achildren); Trace("sygus-abduct-debug") << "...finish" << std::endl; Trace("sygus-abduct-debug") << "Set attributes..." << std::endl; // set the sygus bound variable list Node abvl = nm->mkNode(BOUND_VAR_LIST, varlist); abd.setAttribute(theory::SygusSynthFunVarListAttribute(), abvl); Trace("sygus-abduct-debug") << "...finish" << std::endl; Trace("sygus-abduct-debug") << "Make conjecture body..." << std::endl; Node input = asserts.size() == 1 ? asserts[0] : nm->mkNode(AND, asserts); input = input.substitute(syms.begin(), syms.end(), vars.begin(), vars.end()); // A(x) => ~input( x ) input = nm->mkNode(OR, abdApp.negate(), input.negate()); Trace("sygus-abduct-debug") << "...finish" << std::endl; Trace("sygus-abduct-debug") << "Make conjecture..." << std::endl; Node res = input.negate(); if (!vars.empty()) { Node bvl = nm->mkNode(BOUND_VAR_LIST, vars); // exists x. ~( A( x ) => ~input( x ) ) res = nm->mkNode(EXISTS, bvl, res); } // sygus attribute Node sygusVar = nm->mkSkolem("sygus", nm->booleanType()); theory::SygusAttribute ca; sygusVar.setAttribute(ca, true); Node instAttr = nm->mkNode(INST_ATTRIBUTE, sygusVar); std::vector<Node> iplc; iplc.push_back(instAttr); if (!axioms.empty()) { Node aconj = axioms.size() == 1 ? axioms[0] : nm->mkNode(AND, axioms); aconj = aconj.substitute(syms.begin(), syms.end(), vars.begin(), vars.end()); Trace("sygus-abduct") << "---> Assumptions: " << aconj << std::endl; Node sc = nm->mkNode(AND, aconj, abdApp); Node vbvl = nm->mkNode(BOUND_VAR_LIST, vars); sc = nm->mkNode(EXISTS, vbvl, sc); Node sygusScVar = nm->mkSkolem("sygus_sc", nm->booleanType()); sygusScVar.setAttribute(theory::SygusSideConditionAttribute(), sc); instAttr = nm->mkNode(INST_ATTRIBUTE, sygusScVar); // build in the side condition // exists x. A( x ) ^ input_axioms( x ) // as an additional annotation on the sygus conjecture. In other words, // the abducts A we procedure must be consistent with our axioms. iplc.push_back(instAttr); } Node instAttrList = nm->mkNode(INST_PATTERN_LIST, iplc); Node fbvl = nm->mkNode(BOUND_VAR_LIST, abd); // forall A. exists x. ~( A( x ) => ~input( x ) ) res = nm->mkNode(FORALL, fbvl, res, instAttrList); Trace("sygus-abduct-debug") << "...finish" << std::endl; res = theory::Rewriter::rewrite(res); Trace("sygus-abduct") << "Generate: " << res << std::endl; Node trueNode = nm->mkConst(true); assertionsToPreprocess->replace(0, res); for (size_t i = 1, size = assertionsToPreprocess->size(); i < size; ++i) { assertionsToPreprocess->replace(i, trueNode); } return PreprocessingPassResult::NO_CONFLICT; }
// 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); }