Cardinality& Cardinality::operator+=(const Cardinality& c) { if (isUnknown()) { return *this; } else if (c.isUnknown()) { d_card = s_unknownCard; return *this; } if (c.isFinite() && isLargeFinite()) { return *this; } else if (isFinite() && c.isLargeFinite()) { d_card = s_largeFiniteCard; return *this; } if (isFinite() && c.isFinite()) { d_card += c.d_card - 1; return *this; } if (compare(c) == LESS) { return *this = c; } else { return *this; } Unreachable(); }
std::string PicklerPrivate::fromCaseString(uint32_t size) { std::stringstream ss; unsigned i; for(i = 0; i + 4 <= size; i += 4) { Block front = d_current.dequeue(); BlockBody body = front.d_body; ss << getCharBlockBody(body,0) << getCharBlockBody(body,1) << getCharBlockBody(body,2) << getCharBlockBody(body,3); } Assert(i == size - (size%4) ); if(size % 4 != 0) { Block front = d_current.dequeue(); BlockBody body = front.d_body; switch(size % 4) { case 1: ss << getCharBlockBody(body,0); break; case 2: ss << getCharBlockBody(body,0) << getCharBlockBody(body,1); break; case 3: ss << getCharBlockBody(body,0) << getCharBlockBody(body,1) << getCharBlockBody(body,2); break; default: Unreachable(); } } return ss.str(); }
/** Assigning multiplication of this cardinality with another. */ Cardinality& Cardinality::operator*=(const Cardinality& c) { if (isUnknown()) { return *this; } else if (c.isUnknown()) { d_card = s_unknownCard; return *this; } if (c.isFinite() && isLargeFinite()) { return *this; } else if (isFinite() && c.isLargeFinite()) { d_card = s_largeFiniteCard; return *this; } if (compare(0) == EQUAL || c.compare(0) == EQUAL) { return *this = 0; } else if (!isFinite() || !c.isFinite()) { if (compare(c) == LESS) { return *this = c; } else { return *this; } } else { d_card -= 1; d_card *= c.d_card - 1; d_card += 1; return *this; } Unreachable(); }
std::ostream& operator<<(std::ostream& out, TheoryOfMode m) throw() { switch(m) { case THEORY_OF_TYPE_BASED: return out << "THEORY_OF_TYPE_BASED"; case THEORY_OF_TERM_BASED: return out << "THEORY_OF_TERM_BASED"; default: return out << "TheoryOfMode!UNKNOWN"; } Unreachable(); }
void AttributeManager::deleteAttributes(const AttrIdVec& atids) { typedef std::map<uint64_t, std::vector< uint64_t> > AttrToVecMap; AttrToVecMap perTableIds; for(AttrIdVec::const_iterator it = atids.begin(), it_end = atids.end(); it != it_end; ++it) { const AttributeUniqueId& pair = *(*it); std::vector< uint64_t>& inTable = perTableIds[pair.getTableId()]; inTable.push_back(pair.getWithinTypeId()); } AttrToVecMap::iterator it = perTableIds.begin(), it_end = perTableIds.end(); for(; it != it_end; ++it) { Assert(((*it).first) <= LastAttrTable); AttrTableId tableId = (AttrTableId) ((*it).first); std::vector< uint64_t>& ids = (*it).second; std::sort(ids.begin(), ids.end()); switch(tableId) { case AttrTableBool: Unimplemented("delete attributes is unimplemented for bools"); break; case AttrTableUInt64: deleteAttributesFromTable(d_ints, ids); break; case AttrTableTNode: deleteAttributesFromTable(d_tnodes, ids); break; case AttrTableNode: deleteAttributesFromTable(d_nodes, ids); break; case AttrTableTypeNode: deleteAttributesFromTable(d_types, ids); break; case AttrTableString: deleteAttributesFromTable(d_strings, ids); break; case AttrTableCDBool: case AttrTableCDUInt64: case AttrTableCDTNode: case AttrTableCDNode: case AttrTableCDString: case AttrTableCDPointer: Unimplemented("CDAttributes cannot be deleted. Contact Tim/Morgan if this behavior is desired."); break; case LastAttrTable: default: Unreachable(); } } }
void ArithStaticLearner::iteMinMax(TNode n, NodeBuilder<>& learned){ Assert(n.getKind() == kind::ITE); Assert(n[0].getKind() != EQUAL); Assert(isRelationOperator(n[0].getKind())); TNode c = n[0]; Kind k = oldSimplifiedKind(c); TNode t = n[1]; TNode e = n[2]; TNode cleft = (c.getKind() == NOT) ? c[0][0] : c[0]; TNode cright = (c.getKind() == NOT) ? c[0][1] : c[1]; if((t == cright) && (e == cleft)){ TNode tmp = t; t = e; e = tmp; k = reverseRelationKind(k); } //(ite (< x y) x y) //(ite (x < y) x y) //(ite (x - y < 0) x y) // ---------------- // (ite (x - y < -c) ) if(t == cleft && e == cright){ // t == cleft && e == cright Assert( t == cleft ); Assert( e == cright ); switch(k){ case LT: // (ite (< x y) x y) case LEQ: { // (ite (<= x y) x y) Node nLeqX = NodeBuilder<2>(LEQ) << n << t; Node nLeqY = NodeBuilder<2>(LEQ) << n << e; Debug("arith::static") << n << "is a min =>" << nLeqX << nLeqY << endl; learned << nLeqX << nLeqY; ++(d_statistics.d_iteMinMaxApplications); break; } case GT: // (ite (> x y) x y) case GEQ: { // (ite (>= x y) x y) Node nGeqX = NodeBuilder<2>(GEQ) << n << t; Node nGeqY = NodeBuilder<2>(GEQ) << n << e; Debug("arith::static") << n << "is a max =>" << nGeqX << nGeqY << endl; learned << nGeqX << nGeqY; ++(d_statistics.d_iteMinMaxApplications); break; } default: Unreachable(); } } }
std::ostream& operator<<(std::ostream& os, Theory::Effort level){ switch(level){ case Theory::EFFORT_STANDARD: os << "EFFORT_STANDARD"; break; case Theory::EFFORT_FULL: os << "EFFORT_FULL"; break; case Theory::EFFORT_COMBINATION: os << "EFFORT_COMBINATION"; break; case Theory::EFFORT_LAST_CALL: os << "EFFORT_LAST_CALL"; break; default: Unreachable(); } return os; }/* ostream& operator<<(ostream&, Theory::Effort) */
ConstraintCP SimplexDecisionProcedure::generateConflictForBasic(ArithVar basic) const { Assert(d_tableau.isBasic(basic)); Assert(checkBasicForConflict(basic)); if(d_variables.cmpAssignmentLowerBound(basic) < 0){ Assert(d_linEq.nonbasicsAtUpperBounds(basic)); return d_linEq.generateConflictBelowLowerBound(basic, *d_conflictBuilder); }else if(d_variables.cmpAssignmentUpperBound(basic) > 0){ Assert(d_linEq.nonbasicsAtLowerBounds(basic)); return d_linEq.generateConflictAboveUpperBound(basic, *d_conflictBuilder); }else{ Unreachable(); return NullConstraint; } }
void PicklerPrivate::toCaseString(Kind k, const std::string& s) { d_current << mkConstantHeader(k, s.size()); unsigned size = s.size(); unsigned i; for(i = 0; i + 4 <= size; i += 4) { d_current << mkBlockBody4Chars(s[i + 0], s[i + 1],s[i + 2], s[i + 3]); } switch(size % 4) { case 0: break; case 1: d_current << mkBlockBody4Chars(s[i + 0], '\0','\0', '\0'); break; case 2: d_current << mkBlockBody4Chars(s[i + 0], s[i + 1], '\0', '\0'); break; case 3: d_current << mkBlockBody4Chars(s[i + 0], s[i + 1],s[i + 2], '\0'); break; default: Unreachable(); } }
Cardinality::CardinalityComparison Cardinality::compare(const Cardinality& c) const throw() { if(isUnknown() || c.isUnknown()) { return UNKNOWN; } else if(isLargeFinite()) { if(c.isLargeFinite()) { return UNKNOWN; } else if(c.isFinite()) { return GREATER; } else { Assert(c.isInfinite()); return LESS; } } else if(c.isLargeFinite()) { if(isLargeFinite()) { return UNKNOWN; } else if(isFinite()) { return LESS; } else { Assert(isInfinite()); return GREATER; } } else if(isInfinite()) { if(c.isFinite()) { return GREATER; } else { return d_card < c.d_card ? GREATER : (d_card == c.d_card ? EQUAL : LESS); } } else if(c.isInfinite()) { Assert(isFinite()); return LESS; } else { Assert(isFinite() && !isLargeFinite()); Assert(c.isFinite() && !c.isLargeFinite()); return d_card < c.d_card ? LESS : (d_card == c.d_card ? EQUAL : GREATER); } Unreachable(); }
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"); }
bool Relevancy::findSplitterRec(TNode node, SatValue desiredVal) { Trace("decision") << "findSplitterRec([" << node.getId() << "]" << node << ", " << desiredVal << ", .. )" << std::endl; ++d_expense; /* Handle NOT as a special case */ while (node.getKind() == kind::NOT) { desiredVal = invertValue(desiredVal); node = node[0]; } /* Avoid infinite loops */ if(d_visited.find(node) != d_visited.end()) { Debug("decision") << " node repeated. kind was " << node.getKind() << std::endl; Assert(false); Assert(node.getKind() == kind::ITE); return false; } /* Base case */ if(checkJustified(node)) { return false; } /** * If we have already explored the subtree for some desiredVal, we * skip this and continue exploring the rest */ if(d_polarityCache.find(node) == d_polarityCache.end()) { d_polarityCache[node] = desiredVal; } else { Assert(d_multipleBacktrace || options::decisionComputeRelevancy()); return true; } d_visited.insert(node); #if defined CVC4_ASSERTIONS || defined CVC4_TRACING // We don't always have a sat literal, so remember that. Will need // it for some assertions we make. bool litPresent = d_decisionEngine->hasSatLiteral(node); if(Trace.isOn("decision")) { if(!litPresent) { Trace("decision") << "no sat literal for this node" << std::endl; } } //Assert(litPresent); -- fails #endif // Get value of sat literal for the node, if there is one SatValue litVal = tryGetSatValue(node); /* You'd better know what you want */ Assert(desiredVal != SAT_VALUE_UNKNOWN, "expected known value"); /* Good luck, hope you can get what you want */ Assert(litVal == desiredVal || litVal == SAT_VALUE_UNKNOWN, "invariant violated"); /* What type of node is this */ Kind k = node.getKind(); theory::TheoryId tId = theory::kindToTheoryId(k); /* Some debugging stuff */ Trace("jh-findSplitterRec") << "kind = " << k << std::endl; Trace("jh-findSplitterRec") << "theoryId = " << tId << std::endl; Trace("jh-findSplitterRec") << "node = " << node << std::endl; Trace("jh-findSplitterRec") << "litVal = " << litVal << std::endl; /** * If not in theory of booleans, and not a "boolean" EQUAL (IFF), * then check if this is something to split-on. */ if(tId != theory::THEORY_BOOL // && !(k == kind::EQUAL && node[0].getType().isBoolean()) ) { // if node has embedded ites -- which currently happens iff it got // replaced during ite removal -- then try to resolve that first const IteList& l = getITEs(node); Debug("jh-ite") << " ite size = " << l.size() << std::endl; for(unsigned i = 0; i < l.size(); ++i) { Assert(l[i].getKind() == kind::ITE, "Expected ITE"); Debug("jh-ite") << " i = " << i << " l[i] = " << l[i] << std::endl; if(d_visited.find(node) != d_visited.end() ) continue; if(findSplitterRec(l[i], SAT_VALUE_TRUE)) { d_visited.erase(node); return true; } } Debug("jh-ite") << " ite done " << l.size() << std::endl; if(litVal != SAT_VALUE_UNKNOWN) { d_visited.erase(node); setJustified(node); return false; } else { /* if(not d_decisionEngine->hasSatLiteral(node)) throw GiveUpException(); */ Assert(d_decisionEngine->hasSatLiteral(node)); SatVariable v = d_decisionEngine->getSatLiteral(node).getSatVariable(); *d_curDecision = SatLiteral(v, desiredVal != SAT_VALUE_TRUE ); Trace("decision") << "decision " << *d_curDecision << std::endl; Trace("decision") << "Found something to split. Glad to be able to serve you." << std::endl; d_visited.erase(node); return true; } } bool ret = false; SatValue flipCaseVal = SAT_VALUE_FALSE; switch (k) { case kind::CONST_BOOLEAN: Assert(node.getConst<bool>() == false || desiredVal == SAT_VALUE_TRUE); Assert(node.getConst<bool>() == true || desiredVal == SAT_VALUE_FALSE); break; case kind::AND: if (desiredVal == SAT_VALUE_FALSE) ret = handleOrTrue(node, SAT_VALUE_FALSE); else ret = handleOrFalse(node, SAT_VALUE_TRUE); break; case kind::OR: if (desiredVal == SAT_VALUE_FALSE) ret = handleOrFalse(node, SAT_VALUE_FALSE); else ret = handleOrTrue(node, SAT_VALUE_TRUE); break; case kind::IMPLIES: Assert(node.getNumChildren() == 2, "Expected 2 fanins"); if (desiredVal == SAT_VALUE_FALSE) { ret = findSplitterRec(node[0], SAT_VALUE_TRUE); if(ret) break; ret = findSplitterRec(node[1], SAT_VALUE_FALSE); break; } else { if (tryGetSatValue(node[0]) != SAT_VALUE_TRUE) { ret = findSplitterRec(node[0], SAT_VALUE_FALSE); //if(!ret || !d_multipleBacktrace) break; } if (tryGetSatValue(node[1]) != SAT_VALUE_FALSE) { ret = findSplitterRec(node[1], SAT_VALUE_TRUE); break; } Assert(d_multipleBacktrace, "No controlling input found (3)"); } break; case kind::XOR: flipCaseVal = SAT_VALUE_TRUE; case kind::IFF: { SatValue val = tryGetSatValue(node[0]); if (val != SAT_VALUE_UNKNOWN) { ret = findSplitterRec(node[0], val); if (ret) break; if (desiredVal == flipCaseVal) val = invertValue(val); ret = findSplitterRec(node[1], val); } else { val = tryGetSatValue(node[1]); if (val == SAT_VALUE_UNKNOWN) val = SAT_VALUE_FALSE; if (desiredVal == flipCaseVal) val = invertValue(val); ret = findSplitterRec(node[0], val); if(ret) break; Assert(false, "Unable to find controlling input (4)"); } break; } case kind::ITE: ret = handleITE(node, desiredVal); break; default: Assert(false, "Unexpected Boolean operator"); break; }//end of switch(k) d_visited.erase(node); if(ret == false) { Assert(litPresent == false || litVal == desiredVal, "Output should be justified"); setJustified(node); } return ret; Unreachable(); }/* findRecSplit method */
void BVMinisatSatSolver::unregisterVar(SatLiteral lit) { // this should only be called when user context is implemented // in the BVSatSolver Unreachable(); }
SatValue CryptoMinisatSolver::solve(long unsigned int& resource) { // CMSat::SalverConf conf = d_solver->getConf(); Unreachable("Not sure how to set different limits for calls to solve in Cryptominisat"); return solve(); }
bool JustificationHeuristic::findSplitterRec(TNode node, SatValue desiredVal, SatLiteral* litDecision) { /** * Main idea * * Given a boolean formula "node", the goal is to try to make it * evaluate to "desiredVal" (true/false). for instance if "node" is a AND * formula we want to make it evaluate to true, we'd like one of the * children to be true. this is done recursively. */ Trace("jh-findSplitterRec") << "findSplitterRec(" << node << ", " << desiredVal << ", .. )" << std::endl; /* Handle NOT as a special case */ while (node.getKind() == kind::NOT) { desiredVal = invertValue(desiredVal); node = node[0]; } if(Debug.isOn("decision")) { if(checkJustified(node)) Debug("decision") << " justified, returning" << std::endl; } /* Base case */ if (checkJustified(node)) { return false; } #if defined CVC4_ASSERTIONS || defined CVC4_DEBUG // We don't always have a sat literal, so remember that. Will need // it for some assertions we make. bool litPresent = d_decisionEngine->hasSatLiteral(node); if(Debug.isOn("decision")) { if(!litPresent) { Debug("decision") << "no sat literal for this node" << std::endl; } } //Assert(litPresent); -- fails #endif // Get value of sat literal for the node, if there is one SatValue litVal = tryGetSatValue(node); /* You'd better know what you want */ Assert(desiredVal != SAT_VALUE_UNKNOWN, "expected known value"); /* Good luck, hope you can get what you want */ // if(not (litVal == desiredVal || litVal == SAT_VALUE_UNKNOWN)) { // Warning() << "WARNING: IMPORTANT: Please look into this. Sat solver is asking for a decision" << std::endl // << "when the assertion we are trying to justify is already unsat. OR there is a bug" << std::endl; // GiveUpException(); // } Assert(litVal == desiredVal || litVal == SAT_VALUE_UNKNOWN, "invariant violated"); /* What type of node is this */ Kind k = node.getKind(); theory::TheoryId tId = theory::kindToTheoryId(k); /* Some debugging stuff */ Debug("jh-findSplitterRec") << "kind = " << k << std::endl; Debug("jh-findSplitterRec") << "theoryId = " << tId << std::endl; Debug("jh-findSplitterRec") << "node = " << node << std::endl; Debug("jh-findSplitterRec") << "litVal = " << litVal << std::endl; /** * If not in theory of booleans, and not a "boolean" EQUAL (IFF), * then check if this is something to split-on. */ if(tId != theory::THEORY_BOOL // && !(k == kind::EQUAL && node[0].getType().isBoolean()) ) { // if node has embedded ites -- which currently happens iff it got // replaced during ite removal -- then try to resolve that first const IteList& l = getITEs(node); Trace("jh-ite") << " ite size = " << l.size() << std::endl; /*d_visited.insert(node);*/ for(IteList::const_iterator i = l.begin(); i != l.end(); ++i) { if(d_visited.find(i->first) == d_visited.end()) { d_visited.insert(i->first); Debug("jh-ite") << "jh-ite: adding visited " << i->first << std::endl; if(findSplitterRec(i->second, SAT_VALUE_TRUE, litDecision)) return true; Debug("jh-ite") << "jh-ite: removing visited " << i->first << std::endl; d_visited.erase(i->first); } else { Debug("jh-ite") << "jh-ite: already visited " << i->first << std::endl; } } if(litVal != SAT_VALUE_UNKNOWN) { setJustified(node); return false; } else { Assert(d_decisionEngine->hasSatLiteral(node)); /* if(not d_decisionEngine->hasSatLiteral(node)) throw GiveUpException(); */ Assert(d_decisionEngine->hasSatLiteral(node)); SatVariable v = d_decisionEngine->getSatLiteral(node).getSatVariable(); *litDecision = SatLiteral(v, desiredVal != SAT_VALUE_TRUE ); Trace("decision") << "decision " << *litDecision << std::endl; Trace("decision") << "Found something to split. Glad to be able to serve you." << std::endl; return true; } } SatValue valHard = SAT_VALUE_FALSE; switch (k) { case kind::CONST_BOOLEAN: Assert(node.getConst<bool>() == false || desiredVal == SAT_VALUE_TRUE); Assert(node.getConst<bool>() == true || desiredVal == SAT_VALUE_FALSE); setJustified(node); return false; case kind::AND: valHard = SAT_VALUE_TRUE; case kind::OR: if (desiredVal == valHard) { int n = node.getNumChildren(); for(int i = 0; i < n; ++i) { if (findSplitterRec(node[i], valHard, litDecision)) { return true; } } Assert(litPresent == false || litVal == valHard, "Output should be justified"); setJustified(node); return false; } else { SatValue valEasy = invertValue(valHard); int n = node.getNumChildren(); for(int i = 0; i < n; ++i) { Debug("jh-findSplitterRec") << " node[i] = " << node[i] << " " << tryGetSatValue(node[i]) << std::endl; if ( tryGetSatValue(node[i]) != valHard) { Debug("jh-findSplitterRec") << "hi"<< std::endl; if (findSplitterRec(node[i], valEasy, litDecision)) { return true; } Assert(litPresent == false || litVal == valEasy, "Output should be justified"); setJustified(node); return false; } } if(Debug.isOn("jh-findSplitterRec")) { Debug("jh-findSplitterRec") << " * ** " << std::endl; Debug("jh-findSplitterRec") << node.getKind() << " " << node << std::endl; for(unsigned i = 0; i < node.getNumChildren(); ++i) Debug("jh-findSplitterRec") << "child: " << tryGetSatValue(node[i]) << std::endl; Debug("jh-findSplitterRec") << "node: " << tryGetSatValue(node) << std::endl; } Assert(false, "No controlling input found (2)"); } break; case kind::IMPLIES: //throw GiveUpException(); Assert(node.getNumChildren() == 2, "Expected 2 fanins"); if (desiredVal == SAT_VALUE_FALSE) { if (findSplitterRec(node[0], SAT_VALUE_TRUE, litDecision)) { return true; } if (findSplitterRec(node[1], SAT_VALUE_FALSE, litDecision)) { return true; } Assert(litPresent == false || litVal == SAT_VALUE_FALSE, "Output should be justified"); setJustified(node); return false; } else { if (tryGetSatValue(node[0]) != SAT_VALUE_TRUE) { if (findSplitterRec(node[0], SAT_VALUE_FALSE, litDecision)) { return true; } Assert(litPresent == false || litVal == SAT_VALUE_TRUE, "Output should be justified"); setJustified(node); return false; } if (tryGetSatValue(node[1]) != SAT_VALUE_FALSE) { if (findSplitterRec(node[1], SAT_VALUE_TRUE, litDecision)) { return true; } Assert(litPresent == false || litVal == SAT_VALUE_TRUE, "Output should be justified"); setJustified(node); return false; } Assert(false, "No controlling input found (3)"); } break; case kind::IFF: //throw GiveUpException(); { SatValue val = tryGetSatValue(node[0]); if (val != SAT_VALUE_UNKNOWN) { if (findSplitterRec(node[0], val, litDecision)) { return true; } if (desiredVal == SAT_VALUE_FALSE) val = invertValue(val); if (findSplitterRec(node[1], val, litDecision)) { return true; } Assert(litPresent == false || litVal == desiredVal, "Output should be justified"); setJustified(node); return false; } else { val = tryGetSatValue(node[1]); if (val == SAT_VALUE_UNKNOWN) val = SAT_VALUE_FALSE; if (desiredVal == SAT_VALUE_FALSE) val = invertValue(val); if (findSplitterRec(node[0], val, litDecision)) { return true; } Assert(false, "Unable to find controlling input (4)"); } break; } case kind::XOR: //throw GiveUpException(); { SatValue val = tryGetSatValue(node[0]); if (val != SAT_VALUE_UNKNOWN) { if (findSplitterRec(node[0], val, litDecision)) { return true; } if (desiredVal == SAT_VALUE_TRUE) val = invertValue(val); if (findSplitterRec(node[1], val, litDecision)) { return true; } Assert(litPresent == false || litVal == desiredVal, "Output should be justified"); setJustified(node); return false; } else { SatValue val = tryGetSatValue(node[1]); if (val == SAT_VALUE_UNKNOWN) val = SAT_VALUE_FALSE; if (desiredVal == SAT_VALUE_TRUE) val = invertValue(val); if (findSplitterRec(node[0], val, litDecision)) { return true; } Assert(false, "Unable to find controlling input (5)"); } break; } case kind::ITE: { //[0]: if, [1]: then, [2]: else SatValue ifVal = tryGetSatValue(node[0]); if (ifVal == SAT_VALUE_UNKNOWN) { // are we better off trying false? if not, try true SatValue ifDesiredVal = (tryGetSatValue(node[2]) == desiredVal || tryGetSatValue(node[1]) == invertValue(desiredVal)) ? SAT_VALUE_FALSE : SAT_VALUE_TRUE; if(findSplitterRec(node[0], ifDesiredVal, litDecision)) { return true; } Assert(false, "No controlling input found (6)"); } else { // Try to justify 'if' if (findSplitterRec(node[0], ifVal, litDecision)) { return true; } // If that was successful, we need to go into only one of 'then' // or 'else' int ch = (ifVal == SAT_VALUE_TRUE) ? 1 : 2; int chVal = tryGetSatValue(node[ch]); if( (chVal == SAT_VALUE_UNKNOWN || chVal == desiredVal) && findSplitterRec(node[ch], desiredVal, litDecision) ) { return true; } } Assert(litPresent == false || litVal == desiredVal, "Output should be justified"); setJustified(node); return false; } default: Assert(false, "Unexpected Boolean operator"); break; }//end of switch(k) Unreachable(); }/* findRecSplit method */
/** Assigning exponentiation of this cardinality with another. */ Cardinality& Cardinality::operator^=(const Cardinality& c) { if (isUnknown()) { return *this; } else if (c.isUnknown()) { d_card = s_unknownCard; return *this; } if (c.isFinite() && isLargeFinite()) { return *this; } else if (isFinite() && c.isLargeFinite()) { d_card = s_largeFiniteCard; return *this; } if (c.compare(0) == EQUAL) { // (anything) ^ 0 == 1 d_card = 2; // remember, +1 for finite cardinalities return *this; } else if (compare(0) == EQUAL) { // 0 ^ (>= 1) == 0 return *this; } else if (compare(1) == EQUAL) { // 1 ^ (>= 1) == 1 return *this; } else if (c.compare(1) == EQUAL) { // (anything) ^ 1 == (that thing) return *this; } else if (isFinite() && c.isFinite()) { // finite ^ finite == finite try { // Note: can throw an assertion if c is too big for // exponentiation if (d_card - 1 >= 2 && c.d_card - 1 >= 64) { // don't bother, it's too large anyways d_card = s_largeFiniteCard; } else { d_card = (d_card - 1).pow(c.d_card.getUnsignedLong() - 1) + 1; } } catch (IllegalArgumentException&) { d_card = s_largeFiniteCard; } return *this; } else if (!isFinite() && c.isFinite()) { // inf ^ finite == inf return *this; } else { Assert(compare(2) != LESS && !c.isFinite(), "fall-through case not as expected:\n%s\n%s", this->toString().c_str(), c.toString().c_str()); // (>= 2) ^ beth_k == beth_(k+1) // unless the base is already > the exponent if (compare(c) == GREATER) { return *this; } d_card = c.d_card - 1; return *this; } Unreachable(); }
unsigned CryptoMinisatSolver::getAssertionLevel() const { Unreachable("No interface to get assertion level in Cryptominisat"); return -1; }
FloatingPoint Sampler::pickFpBiased(unsigned e, unsigned s) { // The biased generation of random FP values is inspired by // PyMPF [0]. // // [0] https://github.com/florianschanda/PyMPF Random& rnd = Random::getRandom(); BitVector zero(1); BitVector one(1, static_cast<unsigned int>(1)); BitVector sign(1); BitVector exp(e); BitVector sig(s - 1); if (rnd.pickWithProb(probSpecial)) { // Generate special values uint64_t type = rnd.pick(0, 12); switch (type) { // NaN // sign = 1, exp = 11...11, sig = 11...11 case 0: sign = one; exp = BitVector::mkOnes(e); sig = BitVector::mkOnes(s - 1); break; // +/- inf // sign = x, exp = 11...11, sig = 00...00 case 1: sign = one; // Intentional fall-through case 2: exp = BitVector::mkOnes(e); break; // +/- zero // sign = x, exp = 00...00, sig = 00...00 case 3: sign = one; // Intentional fall-through case 4: break; // +/- max subnormal // sign = x, exp = 00...00, sig = 11...11 case 5: sign = one; // Intentional fall-through case 6: sig = BitVector::mkOnes(s - 1); break; // +/- min subnormal // sign = x, exp = 00...00, sig = 00...01 case 7: sign = one; // Intentional fall-through case 8: sig = BitVector(s - 1, static_cast<unsigned int>(1)); break; // +/- max normal // sign = x, exp = 11...10, sig = 11...11 case 9: sign = one; // Intentional fall-through case 10: exp = BitVector::mkOnes(e) - BitVector(e, static_cast<unsigned int>(1)); sig = BitVector::mkOnes(s - 1); break; // +/- min normal // sign = x, exp = 00...01, sig = 00...00 case 11: sign = one; // Intentional fall-through case 12: exp = BitVector(e, static_cast<unsigned int>(1)); break; default: Unreachable(); } } else { // Generate normal and subnormal values // 50% chance of positive/negative sign if (rnd.pickWithProb(0.5)) { sign = one; } uint64_t pattern = rnd.pick(0, 5); switch (pattern) { case 0: // sign = x, exp = xx...x0, sig = 11...11 exp = pickBvUniform(e - 1).concat(zero); sig = BitVector::mkOnes(s - 1); break; case 1: // sign = x, exp = xx...x0, sig = 00...00 exp = pickBvUniform(e - 1).concat(zero); break; case 2: // sign = x, exp = 0x...x1, sig = 11...11 exp = zero.concat(pickBvUniform(e - 2).concat(one)); sig = BitVector::mkOnes(s - 1); break; case 3: // sign = x, exp = xx...x0, sig = xx...xx exp = pickBvUniform(e - 1).concat(zero); sig = pickBvUniform(s - 1); break; case 4: // sign = x, exp = 0x...x1, sig = xx...xx exp = zero.concat(pickBvUniform(e - 2).concat(one)); sig = pickBvUniform(s - 1); break; case 5: { // sign = x, exp = xx...xx0xx...xx, sig = xx...xx uint64_t lsbSize = rnd.pick(1, e - 2); uint64_t msbSize = e - lsbSize - 1; BitVector lsb = pickBvUniform(lsbSize); BitVector msb = pickBvUniform(msbSize); exp = msb.concat(zero.concat(lsb)); sig = pickBvUniform(s - 1); break; } default: Unreachable(); } } BitVector bv = sign.concat(exp.concat(sig)); return FloatingPoint(e, s, bv); }
void Smt1Printer::toStream(std::ostream& out, const Model& m, const Command* c) const throw() { // shouldn't be called; only the non-Command* version above should be Unreachable(); }
void BVMinisatSatSolver::renewVar(SatLiteral lit, int level) { // this should only be called when user context is implemented // in the BVSatSolver Unreachable(); }
std::string toLFSCKind(Kind kind) { switch(kind) { // core kinds case kind::OR : return "or"; case kind::AND: return "and"; case kind::XOR: return "xor"; case kind::EQUAL: return "="; case kind::IFF: return "iff"; case kind::IMPLIES: return "impl"; case kind::NOT: return "not"; // bit-vector kinds case kind::BITVECTOR_AND : return "bvand"; case kind::BITVECTOR_OR : return "bvor"; case kind::BITVECTOR_XOR : return "bvxor"; case kind::BITVECTOR_NAND : return "bvnand"; case kind::BITVECTOR_NOR : return "bvnor"; case kind::BITVECTOR_XNOR : return "bvxnor"; case kind::BITVECTOR_COMP : return "bvcomp"; case kind::BITVECTOR_MULT : return "bvmul"; case kind::BITVECTOR_PLUS : return "bvadd"; case kind::BITVECTOR_SUB : return "bvsub"; case kind::BITVECTOR_UDIV : case kind::BITVECTOR_UDIV_TOTAL : return "bvudiv"; case kind::BITVECTOR_UREM : case kind::BITVECTOR_UREM_TOTAL : return "bvurem"; case kind::BITVECTOR_SDIV : return "bvsdiv"; case kind::BITVECTOR_SREM : return "bvsrem"; case kind::BITVECTOR_SMOD : return "bvsmod"; case kind::BITVECTOR_SHL : return "bvshl"; case kind::BITVECTOR_LSHR : return "bvlshr"; case kind::BITVECTOR_ASHR : return "bvashr"; case kind::BITVECTOR_CONCAT : return "concat"; case kind::BITVECTOR_NEG : return "bvneg"; case kind::BITVECTOR_NOT : return "bvnot"; case kind::BITVECTOR_ROTATE_LEFT : return "rotate_left"; case kind::BITVECTOR_ROTATE_RIGHT : return "rotate_right"; case kind::BITVECTOR_ULT : return "bvult"; case kind::BITVECTOR_ULE : return "bvule"; case kind::BITVECTOR_UGT : return "bvugt"; case kind::BITVECTOR_UGE : return "bvuge"; case kind::BITVECTOR_SLT : return "bvslt"; case kind::BITVECTOR_SLE : return "bvsle"; case kind::BITVECTOR_SGT : return "bvsgt"; case kind::BITVECTOR_SGE : return "bvsge"; case kind::BITVECTOR_EXTRACT : return "extract"; case kind::BITVECTOR_REPEAT : return "repeat"; case kind::BITVECTOR_ZERO_EXTEND : return "zero_extend"; case kind::BITVECTOR_SIGN_EXTEND : return "sign_extend"; default: Unreachable(); } }
Node Rewriter::rewriteTo(theory::TheoryId theoryId, Node node) { #ifdef CVC4_ASSERTIONS bool isEquality = node.getKind() == kind::EQUAL && (!node[0].getType().isBoolean()); if(s_rewriteStack == NULL) { s_rewriteStack = new std::unordered_set<Node, NodeHashFunction>(); } #endif Trace("rewriter") << "Rewriter::rewriteTo(" << theoryId << "," << node << ")"<< std::endl; // Check if it's been cached already Node cached = getPostRewriteCache(theoryId, node); if (!cached.isNull()) { return cached; } // Put the node on the stack in order to start the "recursive" rewrite vector<RewriteStackElement> rewriteStack; rewriteStack.push_back(RewriteStackElement(node, theoryId)); ResourceManager* rm = NULL; bool hasSmtEngine = smt::smtEngineInScope(); if (hasSmtEngine) { rm = NodeManager::currentResourceManager(); } // Rewrite until the stack is empty for (;;){ if (hasSmtEngine && d_iterationCount % ResourceManager::getFrequencyCount() == 0) { rm->spendResource(options::rewriteStep()); d_iterationCount = 0; } // Get the top of the recursion stack RewriteStackElement& rewriteStackTop = rewriteStack.back(); Trace("rewriter") << "Rewriter::rewriting: " << (TheoryId) rewriteStackTop.theoryId << "," << rewriteStackTop.node << std::endl; // Before rewriting children we need to do a pre-rewrite of the node if (rewriteStackTop.nextChild == 0) { // Check if the pre-rewrite has already been done (it's in the cache) Node cached = Rewriter::getPreRewriteCache((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node); if (cached.isNull()) { // Rewrite until fix-point is reached for(;;) { // Perform the pre-rewrite RewriteResponse response = Rewriter::callPreRewrite((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node); // Put the rewritten node to the top of the stack rewriteStackTop.node = response.node; TheoryId newTheory = theoryOf(rewriteStackTop.node); // In the pre-rewrite, if changing theories, we just call the other theories pre-rewrite if (newTheory == (TheoryId) rewriteStackTop.theoryId && response.status == REWRITE_DONE) { break; } rewriteStackTop.theoryId = newTheory; } // Cache the rewrite Rewriter::setPreRewriteCache((TheoryId) rewriteStackTop.originalTheoryId, rewriteStackTop.original, rewriteStackTop.node); } // Otherwise we're have already been pre-rewritten (in pre-rewrite cache) else { // Continue with the cached version rewriteStackTop.node = cached; rewriteStackTop.theoryId = theoryOf(cached); } } rewriteStackTop.original =rewriteStackTop.node; // Now it's time to rewrite the children, check if this has already been done Node cached = Rewriter::getPostRewriteCache((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node); // If not, go through the children if(cached.isNull()) { // The child we need to rewrite unsigned child = rewriteStackTop.nextChild++; // To build the rewritten expression we set up the builder if(child == 0) { if (rewriteStackTop.node.getNumChildren() > 0) { // The children will add themselves to the builder once they're done rewriteStackTop.builder << rewriteStackTop.node.getKind(); kind::MetaKind metaKind = rewriteStackTop.node.getMetaKind(); if (metaKind == kind::metakind::PARAMETERIZED) { rewriteStackTop.builder << rewriteStackTop.node.getOperator(); } } } // Process the next child if(child < rewriteStackTop.node.getNumChildren()) { // The child node Node childNode = rewriteStackTop.node[child]; // Push the rewrite request to the stack (NOTE: rewriteStackTop might be a bad reference now) rewriteStack.push_back(RewriteStackElement(childNode, theoryOf(childNode))); // Go on with the rewriting continue; } // Incorporate the children if necessary if (rewriteStackTop.node.getNumChildren() > 0) { Node rewritten = rewriteStackTop.builder; rewriteStackTop.node = rewritten; rewriteStackTop.theoryId = theoryOf(rewriteStackTop.node); } // Done with all pre-rewriting, so let's do the post rewrite for(;;) { // Do the post-rewrite RewriteResponse response = Rewriter::callPostRewrite((TheoryId) rewriteStackTop.theoryId, rewriteStackTop.node); // We continue with the response we got TheoryId newTheoryId = theoryOf(response.node); if (newTheoryId != (TheoryId) rewriteStackTop.theoryId || response.status == REWRITE_AGAIN_FULL) { // In the post rewrite if we've changed theories, we must do a full rewrite Assert(response.node != rewriteStackTop.node); //TODO: this is not thread-safe - should make this assertion dependent on sequential build #ifdef CVC4_ASSERTIONS Assert(s_rewriteStack->find(response.node) == s_rewriteStack->end()); s_rewriteStack->insert(response.node); #endif Node rewritten = rewriteTo(newTheoryId, response.node); rewriteStackTop.node = rewritten; #ifdef CVC4_ASSERTIONS s_rewriteStack->erase(response.node); #endif break; } else if (response.status == REWRITE_DONE) { #ifdef CVC4_ASSERTIONS RewriteResponse r2 = Rewriter::callPostRewrite(newTheoryId, response.node); Assert(r2.node == response.node); #endif rewriteStackTop.node = response.node; break; } // Check for trivial rewrite loops of size 1 or 2 Assert(response.node != rewriteStackTop.node); Assert(Rewriter::callPostRewrite((TheoryId) rewriteStackTop.theoryId, response.node).node != rewriteStackTop.node); rewriteStackTop.node = response.node; } // We're done with the post rewrite, so we add to the cache Rewriter::setPostRewriteCache((TheoryId) rewriteStackTop.originalTheoryId, rewriteStackTop.original, rewriteStackTop.node); } else { // We were already in cache, so just remember it rewriteStackTop.node = cached; rewriteStackTop.theoryId = theoryOf(cached); } // If this is the last node, just return if (rewriteStack.size() == 1) { Assert(!isEquality || rewriteStackTop.node.getKind() == kind::EQUAL || rewriteStackTop.node.isConst()); return rewriteStackTop.node; } // We're done with this node, append it to the parent rewriteStack[rewriteStack.size() - 2].builder << rewriteStackTop.node; rewriteStack.pop_back(); } Unreachable(); }/* Rewriter::rewriteTo() */
TheoryId Theory::theoryOf(TheoryOfMode mode, TNode node) { TheoryId tid = THEORY_BUILTIN; switch(mode) { case THEORY_OF_TYPE_BASED: // Constants, variables, 0-ary constructors if (node.isVar() || node.isConst()) { tid = Theory::theoryOf(node.getType()); } else if (node.getKind() == kind::EQUAL) { // Equality is owned by the theory that owns the domain tid = Theory::theoryOf(node[0].getType()); } else { // Regular nodes are owned by the kind tid = kindToTheoryId(node.getKind()); } break; case THEORY_OF_TERM_BASED: // Variables if (node.isVar()) { if (Theory::theoryOf(node.getType()) != theory::THEORY_BOOL) { // We treat the variables as uninterpreted tid = s_uninterpretedSortOwner; } else { // Except for the Boolean ones, which we just ignore anyhow tid = theory::THEORY_BOOL; } } else if (node.isConst()) { // Constants go to the theory of the type tid = Theory::theoryOf(node.getType()); } else if (node.getKind() == kind::EQUAL) { // Equality // If one of them is an ITE, it's irelevant, since they will get replaced out anyhow if (node[0].getKind() == kind::ITE) { tid = Theory::theoryOf(node[0].getType()); } else if (node[1].getKind() == kind::ITE) { tid = Theory::theoryOf(node[1].getType()); } else { TNode l = node[0]; TNode r = node[1]; TypeNode ltype = l.getType(); TypeNode rtype = r.getType(); if( ltype != rtype ){ tid = Theory::theoryOf(l.getType()); }else { // If both sides belong to the same theory the choice is easy TheoryId T1 = Theory::theoryOf(l); TheoryId T2 = Theory::theoryOf(r); if (T1 == T2) { tid = T1; } else { TheoryId T3 = Theory::theoryOf(ltype); // This is a case of // * x*y = f(z) -> UF // * x = c -> UF // * f(x) = read(a, y) -> either UF or ARRAY // at least one of the theories has to be parametric, i.e. theory of the type is different // from the theory of the term if (T1 == T3) { tid = T2; } else if (T2 == T3) { tid = T1; } else { // If both are parametric, we take the smaller one (arbitrary) tid = T1 < T2 ? T1 : T2; } } } } } else { // Regular nodes are owned by the kind tid = kindToTheoryId(node.getKind()); } break; default: Unreachable(); } Trace("theory::internal") << "theoryOf(" << mode << ", " << node << ") -> " << tid << std::endl; return tid; }
//corresponds to Check() in dM06 //template <SimplexDecisionProcedure::PreferenceFunction pf> bool DualSimplexDecisionProcedure::searchForFeasibleSolution(uint32_t remainingIterations){ TimerStat::CodeTimer codeTimer(d_statistics.d_searchTime); Debug("arith") << "searchForFeasibleSolution" << endl; Assert(remainingIterations > 0); while(remainingIterations > 0 && !d_errorSet.focusEmpty()){ if(Debug.isOn("paranoid:check_tableau")){ d_linEq.debugCheckTableau(); } Assert(d_conflictVariables.empty()); ArithVar x_i = d_errorSet.topFocusVariable(); Debug("arith::update::select") << "selectSmallestInconsistentVar()=" << x_i << endl; if(x_i == ARITHVAR_SENTINEL){ Debug("arith::update") << "No inconsistent variables" << endl; return false; //sat } --remainingIterations; bool useVarOrderPivot = d_pivotsInRound.count(x_i) >= options::arithPivotThreshold(); if(!useVarOrderPivot){ d_pivotsInRound.add(x_i); } Debug("arith::update") << "pivots in rounds: " << d_pivotsInRound.count(x_i) << " use " << useVarOrderPivot << " threshold " << options::arithPivotThreshold() << endl; LinearEqualityModule::VarPreferenceFunction pf = useVarOrderPivot ? &LinearEqualityModule::minVarOrder : &LinearEqualityModule::minBoundAndColLength; //DeltaRational beta_i = d_variables.getAssignment(x_i); ArithVar x_j = ARITHVAR_SENTINEL; int32_t prevErrorSize CVC4_UNUSED = d_errorSet.errorSize(); if(d_variables.cmpAssignmentLowerBound(x_i) < 0 ){ x_j = d_linEq.selectSlackUpperBound(x_i, pf); if(x_j == ARITHVAR_SENTINEL ){ Unreachable(); // ++(d_statistics.d_statUpdateConflicts); // reportConflict(x_i); // ++(d_statistics.d_simplexConflicts); // Node conflict = d_linEq.generateConflictBelowLowerBound(x_i); //unsat // d_conflictVariable = x_i; // reportConflict(conflict); // return true; }else{ const DeltaRational& l_i = d_variables.getLowerBound(x_i); d_linEq.pivotAndUpdate(x_i, x_j, l_i); } }else if(d_variables.cmpAssignmentUpperBound(x_i) > 0){ x_j = d_linEq.selectSlackLowerBound(x_i, pf); if(x_j == ARITHVAR_SENTINEL ){ Unreachable(); // ++(d_statistics.d_statUpdateConflicts); // reportConflict(x_i); // ++(d_statistics.d_simplexConflicts); // Node conflict = d_linEq.generateConflictAboveUpperBound(x_i); //unsat // d_conflictVariable = x_i; // reportConflict(conflict); // return true; }else{ const DeltaRational& u_i = d_variables.getUpperBound(x_i); d_linEq.pivotAndUpdate(x_i, x_j, u_i); } } Assert(x_j != ARITHVAR_SENTINEL); bool conflict = processSignals(); int32_t currErrorSize CVC4_UNUSED = d_errorSet.errorSize(); d_pivots++; if(Debug.isOn("arith::dual")){ Debug("arith::dual") << "#" << d_pivots << " c" << conflict << " d" << (prevErrorSize - currErrorSize) << " f" << d_errorSet.inError(x_j) << " h" << d_conflictVariables.isMember(x_j) << " " << x_i << "->" << x_j << endl; } if(conflict){ return true; } } Assert(!d_errorSet.focusEmpty() || d_errorSet.errorEmpty()); Assert(remainingIterations == 0 || d_errorSet.focusEmpty()); Assert(d_errorSet.noSignals()); return false; }