Node ModelPostprocessor::rewriteAs(TNode n, TypeNode asType) { if(n.getType().isSubtypeOf(asType)) { // good to go, we have the right type return n; } if(!n.isConst()) { // we don't handle non-const right now return n; } if(asType.isBoolean()) { if(n.getType().isBitVector(1u)) { // type mismatch: should only happen for Boolean-term conversion under // datatype constructor applications; rewrite from BV(1) back to Boolean bool tf = (n.getConst<BitVector>().getValue() == 1); return NodeManager::currentNM()->mkConst(tf); } if(n.getType().isDatatype() && n.getType().hasAttribute(BooleanTermAttr())) { // type mismatch: should only happen for Boolean-term conversion under // datatype constructor applications; rewrite from datatype back to Boolean Assert(n.getKind() == kind::APPLY_CONSTRUCTOR); Assert(n.getNumChildren() == 0); // we assume (by construction) false is first; see boolean_terms.cpp bool tf = (Datatype::indexOf(n.getOperator().toExpr()) == 1); Debug("boolean-terms") << "+++ rewriteAs " << n << " : " << asType << " ==> " << tf << endl; return NodeManager::currentNM()->mkConst(tf); } } if(n.getType().isBoolean()) { bool tf = n.getConst<bool>(); if(asType.isBitVector(1u)) { return NodeManager::currentNM()->mkConst(BitVector(1u, tf ? 1u : 0u)); } if(asType.isDatatype() && asType.hasAttribute(BooleanTermAttr())) { const Datatype& asDatatype = asType.getConst<Datatype>(); return NodeManager::currentNM()->mkNode(kind::APPLY_CONSTRUCTOR, (tf ? asDatatype[0] : asDatatype[1]).getConstructor()); } } if(n.getType().isRecord() && asType.isRecord()) { Debug("boolean-terms") << "+++ got a record - rewriteAs " << n << " : " << asType << endl; const Record& rec CVC4_UNUSED = n.getType().getConst<Record>(); const Record& asRec = asType.getConst<Record>(); Assert(rec.getNumFields() == asRec.getNumFields()); Assert(n.getNumChildren() == asRec.getNumFields()); NodeBuilder<> b(n.getKind()); b << asType; for(size_t i = 0; i < n.getNumChildren(); ++i) { b << rewriteAs(n[i], TypeNode::fromType(asRec[i].second)); } Node out = b; Debug("boolean-terms") << "+++ returning record " << out << endl; return out; }
Kind SymmetryBreaker::getOrderKind(Node node) { TypeNode tn = node.getType(); if (tn.isBoolean()) { return IMPLIES; } else if (tn.isReal()) { return LEQ; } else if (tn.isBitVector()) { return BITVECTOR_ULE; } if (tn.isFirstClass()) { return EQUAL; } return UNDEFINED_KIND; }
Node removeToFPGeneric (TNode node) { Assert(node.getKind() == kind::FLOATINGPOINT_TO_FP_GENERIC); FloatingPointToFPGeneric info = node.getOperator().getConst<FloatingPointToFPGeneric>(); size_t children = node.getNumChildren(); Node op; if (children == 1) { op = NodeManager::currentNM()->mkConst(FloatingPointToFPIEEEBitVector(info.t.exponent(), info.t.significand())); return NodeManager::currentNM()->mkNode(op, node[0]); } else { Assert(children == 2); Assert(node[0].getType().isRoundingMode()); TypeNode t = node[1].getType(); if (t.isFloatingPoint()) { op = NodeManager::currentNM()->mkConst(FloatingPointToFPFloatingPoint(info.t.exponent(), info.t.significand())); } else if (t.isReal()) { op = NodeManager::currentNM()->mkConst(FloatingPointToFPReal(info.t.exponent(), info.t.significand())); } else if (t.isBitVector()) { op = NodeManager::currentNM()->mkConst(FloatingPointToFPSignedBitVector(info.t.exponent(), info.t.significand())); } else { throw TypeCheckingExceptionPrivate(node, "cannot rewrite to_fp generic due to incorrect type of second argument"); } return NodeManager::currentNM()->mkNode(op, node[0], node[1]); } Unreachable("to_fp generic not rewritten"); }
void CoreSolver::buildModel() { Debug("bv-core") << "CoreSolver::buildModel() \n"; d_modelValues.clear(); TNodeSet constants; TNodeSet constants_in_eq_engine; // collect constants in equality engine eq::EqClassesIterator eqcs_i = eq::EqClassesIterator(&d_equalityEngine); while (!eqcs_i.isFinished()) { TNode repr = *eqcs_i; if (repr.getKind() == kind::CONST_BITVECTOR) { // must check if it's just the constant eq::EqClassIterator it(repr, &d_equalityEngine); if (!(++it).isFinished() || true) { constants.insert(repr); constants_in_eq_engine.insert(repr); } } ++eqcs_i; } // build repr to value map eqcs_i = eq::EqClassesIterator(&d_equalityEngine); while (!eqcs_i.isFinished()) { TNode repr = *eqcs_i; ++eqcs_i; if (repr.getKind() != kind::VARIABLE && repr.getKind() != kind::SKOLEM && repr.getKind() != kind::CONST_BITVECTOR && !d_bv->isSharedTerm(repr)) { continue; } TypeNode type = repr.getType(); if (type.isBitVector() && repr.getKind()!= kind::CONST_BITVECTOR) { Debug("bv-core-model") << " processing " << repr <<"\n"; // we need to assign a value for it TypeEnumerator te(type); Node val; do { val = *te; ++te; // Debug("bv-core-model") << " trying value " << val << "\n"; // Debug("bv-core-model") << " is in set? " << constants.count(val) << "\n"; // Debug("bv-core-model") << " enumerator done? " << te.isFinished() << "\n"; } while (constants.count(val) != 0 && !(te.isFinished())); if (te.isFinished() && constants.count(val) != 0) { // if we cannot enumerate anymore values we just return the lemma stating that // at least two of the representatives are equal. std::vector<TNode> representatives; representatives.push_back(repr); for (TNodeSet::const_iterator it = constants_in_eq_engine.begin(); it != constants_in_eq_engine.end(); ++it) { TNode constant = *it; if (utils::getSize(constant) == utils::getSize(repr)) { representatives.push_back(constant); } } for (ModelValue::const_iterator it = d_modelValues.begin(); it != d_modelValues.end(); ++it) { representatives.push_back(it->first); } std::vector<Node> equalities; for (unsigned i = 0; i < representatives.size(); ++i) { for (unsigned j = i + 1; j < representatives.size(); ++j) { TNode a = representatives[i]; TNode b = representatives[j]; if (a.getKind() == kind::CONST_BITVECTOR && b.getKind() == kind::CONST_BITVECTOR) { Assert (a != b); continue; } if (utils::getSize(a) == utils::getSize(b)) { equalities.push_back(utils::mkNode(kind::EQUAL, a, b)); } } } // better off letting the SAT solver split on values if (equalities.size() > d_lemmaThreshold) { d_isComplete = false; return; } Node lemma = utils::mkOr(equalities); d_bv->lemma(lemma); Debug("bv-core") << " lemma: " << lemma << "\n"; return; } Debug("bv-core-model") << " " << repr << " => " << val <<"\n" ; constants.insert(val); d_modelValues[repr] = val; } } }