Node CVC4::theory::bv::mergeExplanations(const std::vector<Node>& expls) { TNodeSet literals; for (unsigned i = 0; i < expls.size(); ++i) { TNode expl = expls[i]; Assert (expl.getType().isBoolean()); if (expl.getKind() == kind::AND) { for (unsigned i = 0; i < expl.getNumChildren(); ++i) { TNode child = expl[i]; if (child == utils::mkTrue()) continue; literals.insert(child); } } else if (expl != utils::mkTrue()) { literals.insert(expl); } } if (literals.size() == 0) return utils::mkTrue(); if (literals.size() == 1) return *literals.begin(); NodeBuilder<> nb(kind::AND); for (TNodeSet::const_iterator it = literals.begin(); it!= literals.end(); ++it) { nb << *it; } return nb; }
unsigned QuickXPlain::selectUnsatCore(unsigned low, unsigned high, std::vector<TNode>& conflict) { Assert(!d_solver->getConflict().isNull() && d_solver->inConflict()); Node query_confl = d_solver->getConflict(); // conflict wasn't actually minimized if (query_confl.getNumChildren() == high - low + 1) { return high; } TNodeSet nodes; for (unsigned i = low; i <= high; i++) { nodes.insert(conflict[i]); } unsigned write = low; for (unsigned i = 0; i < query_confl.getNumChildren(); ++i) { TNode current = query_confl[i]; // the conflict can have nodes in lower decision levels if (nodes.find(current) != nodes.end()) { conflict[write++] = current; nodes.erase(nodes.find(current)); } } // if all of the nodes in the conflict were on a lower level if (write == low) { return low; } Assert (write != 0); unsigned new_high = write - 1; for (TNodeSet::const_iterator it = nodes.begin(); it != nodes.end(); ++it) { conflict[write++] = *it; } Assert (write -1 == high); Assert (new_high <= high); return new_high; }
ControlNode* GraphLinker::optimizePhi(PhiNode* phi) { TNodeSet incomingValues; const PhiNode::TIncomingList& incomings = phi->getIncomingList(); assert(incomings.size() > 1); // Phi should have at least two incoming edges for (size_t index = 0; index < incomings.size(); index++) incomingValues.insert(incomings[index].node); assert(incomingValues.size()); if (traces_enabled) std::printf("GraphLinker::optimizePhi : phi node %u has %u unique incoming values\n", phi->getIndex(), incomingValues.size()); if (incomingValues.size() > 1) return phi; // Phi is ok, no need to optimize. Leave everything as is. // It seem that phi node is redundant becasue all of it's incomings link to the same value. // This may happen in a diamond-shaped reference diagram if incoming value stored in the top // domain and consumed in the bottom one. Left and right domains are not affected. // We may safely remove the phi because incoming value dominates it's consumer. if (traces_enabled) std::printf("GraphLinker::optimizePhi : phi node %u is redundant and may be removed\n", phi->getIndex()); // This is the real value that should be returned ControlNode* const value = *incomingValues.begin(); // Unlink and erase phi value->removeConsumer(phi); value->removeEdge(phi); m_graph->eraseNode(phi); return value; }