void CardSolver::checkCardinalityGraph()
{
- for (const auto& pair : d_state.getCardinalityTerms())
+ const std::map<Node, Node>& cardinalityTerms = d_state.getCardinalityTerms();
+ for (const auto& pair : cardinalityTerms)
{
Trace("bags-card") << "CardSolver::checkCardinalityGraph cardTerm: " << pair
<< std::endl;
case BAG_DIFFERENCE_REMOVE: checkDifferenceRemove(pair, n); break;
default: break;
}
+ if (d_im.hasSentLemma())
+ {
+ // exit with each new pending lemma
+ return;
+ }
it++;
}
// if the bag is a leaf in the graph, then we reduce its cardinality
checkLeafBag(pair, bag);
- }
-
- for (const auto& pair : d_state.getCardinalityTerms())
- {
+ // cardinality term is non-negative
InferInfo i = d_ig.nonNegativeCardinality(pair.second);
d_im.lemmaTheoryInference(&i);
}
* This map needs to cleared before each full effort check.
*/
std::map<Node, std::set<std::set<Node>>> d_cardGraph;
-
/** Commonly used constants */
Node d_true;
Node d_false;
*/
#include "theory/bags/infer_info.h"
-#include "theory/inference_manager_buffered.h"
+
#include "theory/bags/inference_manager.h"
+#include "theory/inference_manager_buffered.h"
namespace cvc5 {
namespace theory {
TrustNode InferInfo::processLemma(LemmaProperty& p)
{
- NodeManager* nm = NodeManager::currentNM();
- Node pnode = nm->mkAnd(d_premises);
- Node lemma = nm->mkNode(kind::IMPLIES, pnode, d_conclusion);
+ Node lemma = getLemma();
+
+ Trace("bags::InferInfo::process") << (*this) << std::endl;
+ d_im->addPendingLemma(lemma, getId());
+ return TrustNode::mkTrustLemma(lemma, nullptr);
+}
+Node InferInfo::getLemma() const
+{
+ NodeManager* nm = NodeManager::currentNM();
+ std::vector<Node> nodes;
+ Node premises = nm->mkAnd(d_premises);
+ Node lemma = nm->mkNode(kind::IMPLIES, premises, d_conclusion);
+ nodes.push_back(lemma);
// send lemmas corresponding to the skolems introduced
for (const auto& pair : d_skolems)
{
Node n = pair.first.eqNode(pair.second);
- d_im->addPendingLemma(n, InferenceId::BAGS_SKOLEM);
+ nodes.push_back(n);
}
-
- Trace("bags::InferInfo::process") << (*this) << std::endl;
- d_im->addPendingLemma(lemma, getId());
- return TrustNode::mkTrustLemma(lemma, nullptr);
+ if (nodes.size() == 1)
+ {
+ return lemma;
+ }
+ return nm->mkNode(kind::AND, nodes);
}
bool InferInfo::isTrivial() const
* engine with no new external premises (d_noExplain).
*/
bool isFact() const;
+ /**
+ * @return the lemma for this InferInfo.
+ */
+ Node getLemma() const;
};
/**
Assert(n.getKind() == BAG_CARD);
Node bag = d_state->getRepresentative(n[0]);
Node cardTerm = d_nm->mkNode(BAG_CARD, bag);
- Node skolem = registerAndAssertSkolemLemma(cardTerm, "bag.card");
+ Node skolem = registerAndAssertSkolemLemma(cardTerm, "bagCard");
d_state->registerCardinalityTerm(cardTerm, skolem);
Node premise = n[0].eqNode(bag);
Node conclusion = skolem.eqNode(n);
InferInfo inferInfo(d_im, InferenceId::BAGS_CARD_EMPTY);
Node premise = pair.first[0].eqNode(n);
Node conclusion = pair.second.eqNode(d_zero);
- inferInfo.d_conclusion = premise.notNode().orNode(conclusion);
+ inferInfo.d_conclusion = premise.eqNode(conclusion);
return inferInfo;
}
Node unionDisjoints = child;
Node card = d_nm->mkNode(BAG_CARD, child);
std::vector<Node> lemmas;
- registerCardinalityTerm(card);
- Node sum = d_state->getCardinalitySkolem(card);
+ Node sum = registerAndAssertSkolemLemma(card, "bagCard");
++it;
while (it != children.end())
{
unionDisjoints =
d_nm->mkNode(kind::BAG_UNION_DISJOINT, unionDisjoints, child);
card = d_nm->mkNode(BAG_CARD, child);
- registerCardinalityTerm(card);
- Node skolem = d_state->getCardinalitySkolem(card);
+ Node skolem = registerAndAssertSkolemLemma(card, "bagCard");
sum = d_nm->mkNode(ADD, sum, skolem);
++it;
}
Node parentCard = d_nm->mkNode(BAG_CARD, parent);
- registerCardinalityTerm(parentCard);
- Node parentSkolem = d_state->getCardinalitySkolem(parentCard);
+ Node parentSkolem = registerAndAssertSkolemLemma(parentCard, "bagCard");
Node bags = parent.eqNode(unionDisjoints);
lemmas.push_back(bags);
* @param cardTerm a term of the form (bag.card A) where A has type (Bag E)
* @param n is (as bag.empty (Bag E))
* @return an inference that represents the following implication
- * (=> (= A (as bag.empty (Bag E)))
+ * (= (= A (as bag.empty (Bag E)))
* (= (bag.card A) 0))
*/
InferInfo cardEmpty(const std::pair<Node, Node>& pair, Node n);
regress1/bags/product1.smt2
regress1/bags/product2.smt2
regress1/bags/product3.smt2
+ regress1/bags/proj-issue497.smt2
regress1/bags/subbag1.smt2
regress1/bags/subbag2.smt2
regress1/bags/union_disjoint.smt2
--- /dev/null
+(set-logic ALL)
+(set-info :status sat)
+(set-option :fmf-bound true)
+(declare-const x (Bag Bool))
+(declare-const x5 (Bag Bool))
+(check-sat-assuming ((= 0 (bag.card (bag.inter_min x5 (bag.inter_min x5 x))))))