This PR adds a new InferenceId member to the TheoryInference class.
All classes derived from TheoryInference are adapted accordingly.
LemmaProperty p,
ProofGenerator* pg,
InferenceId inf = InferenceId::UNKNOWN)
- : SimpleTheoryLemma(n, p, pg), d_inference(inf)
+ : SimpleTheoryLemma(inf, n, p, pg)
{
}
virtual ~ArithLemma() {}
-
- /** The inference id for the lemma */
- InferenceId d_inference;
};
/**
* Writes an arithmetic lemma to a stream.
void InferenceManager::addPendingArithLemma(std::unique_ptr<ArithLemma> lemma,
bool isWaiting)
{
- Trace("arith::infman") << "Add " << lemma->d_inference << " " << lemma->d_node
+ Trace("arith::infman") << "Add " << lemma->getId() << " " << lemma->d_node
<< (isWaiting ? " as waiting" : "") << std::endl;
if (hasCachedLemma(lemma->d_node, lemma->d_property))
{
for (auto& lem : d_waitingLem)
{
Trace("arith::infman") << "Flush waiting lemma to pending: "
- << lem->d_inference << " " << lem->d_node
+ << lem->getId() << " " << lem->d_node
<< std::endl;
d_pendingLem.emplace_back(std::move(lem));
}
{
for (const NlLemma& nlem : out)
{
- Trace("nl-ext-lemma") << "NonlinearExtension::Lemma : " << nlem.d_inference
+ Trace("nl-ext-lemma") << "NonlinearExtension::Lemma : " << nlem.getId()
<< " : " << nlem.d_node << std::endl;
d_im.addPendingArithLemma(nlem);
- d_stats.d_inferences << nlem.d_inference;
+ d_stats.d_inferences << nlem.getId();
}
}
namespace theory {
namespace bags {
-InferInfo::InferInfo() : d_id(InferenceId::UNKNOWN) {}
+InferInfo::InferInfo(InferenceId id) : TheoryInference(id) {}
bool InferInfo::process(TheoryInferenceManager* im, bool asLemma)
{
std::ostream& operator<<(std::ostream& out, const InferInfo& ii)
{
- out << "(infer :id " << ii.d_id << std::endl;
+ out << "(infer :id " << ii.getId() << std::endl;
out << ":conclusion " << ii.d_conclusion << std::endl;
if (!ii.d_premises.empty())
{
class InferInfo : public TheoryInference
{
public:
- InferInfo();
+ InferInfo(InferenceId id);
~InferInfo() {}
/** Process this inference */
bool process(TheoryInferenceManager* im, bool asLemma) override;
- /** The inference identifier */
- InferenceId d_id;
/** The conclusion */
Node d_conclusion;
/**
Assert(n.getType().isBag());
Assert(e.getType() == n.getType().getBagElementType());
- InferInfo inferInfo;
- inferInfo.d_id = InferenceId::BAG_NON_NEGATIVE_COUNT;
+ InferInfo inferInfo(InferenceId::BAG_NON_NEGATIVE_COUNT);
Node count = d_nm->mkNode(kind::BAG_COUNT, e, n);
Node gte = d_nm->mkNode(kind::GEQ, count, d_zero);
Assert(n.getKind() == kind::MK_BAG);
Assert(e.getType() == n.getType().getBagElementType());
- InferInfo inferInfo;
- Node skolem = getSkolem(n, inferInfo);
- Node count = getMultiplicityTerm(e, skolem);
if (n[0] == e)
{
// TODO issue #78: refactor this with BagRewriter
// (=> true (= (bag.count e (bag e c)) c))
- inferInfo.d_id = InferenceId::BAG_MK_BAG_SAME_ELEMENT;
+ InferInfo inferInfo(InferenceId::BAG_MK_BAG_SAME_ELEMENT);
+ Node skolem = getSkolem(n, inferInfo);
+ Node count = getMultiplicityTerm(e, skolem);
inferInfo.d_conclusion = count.eqNode(n[1]);
+ return inferInfo;
}
else
{
// (=>
// true
// (= (bag.count e (bag x c)) (ite (= e x) c 0)))
- inferInfo.d_id = InferenceId::BAG_MK_BAG;
+ InferInfo inferInfo(InferenceId::BAG_MK_BAG);
+ Node skolem = getSkolem(n, inferInfo);
+ Node count = getMultiplicityTerm(e, skolem);
Node same = d_nm->mkNode(kind::EQUAL, n[0], e);
Node ite = d_nm->mkNode(kind::ITE, same, n[1], d_zero);
Node equal = count.eqNode(ite);
inferInfo.d_conclusion = equal;
+ return inferInfo;
}
- return inferInfo;
}
struct BagsDeqAttributeId
Node A = n[0];
Node B = n[1];
- InferInfo inferInfo;
- inferInfo.d_id = InferenceId::BAG_DISEQUALITY;
+ InferInfo inferInfo(InferenceId::BAG_DISEQUALITY);
TypeNode elementType = A.getType().getBagElementType();
BoundVarManager* bvm = d_nm->getBoundVarManager();
Assert(n.getKind() == kind::EMPTYBAG);
Assert(e.getType() == n.getType().getBagElementType());
- InferInfo inferInfo;
+ InferInfo inferInfo(InferenceId::BAG_EMPTY);
Node skolem = getSkolem(n, inferInfo);
- inferInfo.d_id = InferenceId::BAG_EMPTY;
Node count = getMultiplicityTerm(e, skolem);
Node equal = count.eqNode(d_zero);
Node A = n[0];
Node B = n[1];
- InferInfo inferInfo;
- inferInfo.d_id = InferenceId::BAG_UNION_DISJOINT;
+ InferInfo inferInfo(InferenceId::BAG_UNION_DISJOINT);
Node countA = getMultiplicityTerm(e, A);
Node countB = getMultiplicityTerm(e, B);
Node A = n[0];
Node B = n[1];
- InferInfo inferInfo;
- inferInfo.d_id = InferenceId::BAG_UNION_MAX;
+ InferInfo inferInfo(InferenceId::BAG_UNION_MAX);
Node countA = getMultiplicityTerm(e, A);
Node countB = getMultiplicityTerm(e, B);
Node A = n[0];
Node B = n[1];
- InferInfo inferInfo;
- inferInfo.d_id = InferenceId::BAG_INTERSECTION_MIN;
+ InferInfo inferInfo(InferenceId::BAG_INTERSECTION_MIN);
Node countA = getMultiplicityTerm(e, A);
Node countB = getMultiplicityTerm(e, B);
Node A = n[0];
Node B = n[1];
- InferInfo inferInfo;
- inferInfo.d_id = InferenceId::BAG_DIFFERENCE_SUBTRACT;
+ InferInfo inferInfo(InferenceId::BAG_DIFFERENCE_SUBTRACT);
Node countA = getMultiplicityTerm(e, A);
Node countB = getMultiplicityTerm(e, B);
Node A = n[0];
Node B = n[1];
- InferInfo inferInfo;
- inferInfo.d_id = InferenceId::BAG_DIFFERENCE_REMOVE;
+ InferInfo inferInfo(InferenceId::BAG_DIFFERENCE_REMOVE);
Node countA = getMultiplicityTerm(e, A);
Node countB = getMultiplicityTerm(e, B);
Assert(e.getType() == n[0].getType().getBagElementType());
Node A = n[0];
- InferInfo inferInfo;
- inferInfo.d_id = InferenceId::BAG_DUPLICATE_REMOVAL;
+ InferInfo inferInfo(InferenceId::BAG_DUPLICATE_REMOVAL);
Node countA = getMultiplicityTerm(e, A);
Node skolem = getSkolem(n, inferInfo);
// now go back and convert it to proof steps and add to proof
std::shared_ptr<DatatypesInference> di = (*it).second;
// run the conversion
- convert(di->getInferId(), di->d_conc, di->d_exp, &pf);
+ convert(di->getId(), di->d_conc, di->d_exp, &pf);
return pf.getProofFor(fact);
}
Node conc,
Node exp,
InferenceId i)
- : SimpleTheoryInternalFact(conc, exp, nullptr), d_im(im), d_id(i)
+ : SimpleTheoryInternalFact(i, conc, exp, nullptr), d_im(im)
{
// false is not a valid explanation
Assert(d_exp.isNull() || !d_exp.isConst() || d_exp.getConst<bool>());
// sent as a lemma in addPendingInference below.
if (asLemma || mustCommunicateFact(d_conc, d_exp))
{
- return d_im->processDtLemma(d_conc, d_exp, d_id);
+ return d_im->processDtLemma(d_conc, d_exp, getId());
}
- return d_im->processDtFact(d_conc, d_exp, d_id);
+ return d_im->processDtFact(d_conc, d_exp, getId());
}
-InferenceId DatatypesInference::getInferId() const { return d_id; }
-
} // namespace datatypes
} // namespace theory
} // namespace CVC4
* above method.
*/
bool process(TheoryInferenceManager* im, bool asLemma) override;
- /** Get the inference identifier */
- InferenceId getInferId() const;
private:
/** Pointer to the inference manager */
InferenceManager* d_im;
- /** The inference */
- InferenceId d_id;
};
} // namespace datatypes
}
}
// make the simple theory lemma
- d_pendingLem.emplace_back(new SimpleTheoryLemma(lem, p, pg));
+ d_pendingLem.emplace_back(new SimpleTheoryLemma(InferenceId::UNKNOWN, lem, p, pg));
return true;
}
{
// make a simple theory internal fact
Assert(conc.getKind() != AND && conc.getKind() != OR);
- d_pendingFact.emplace_back(new SimpleTheoryInternalFact(conc, exp, pg));
+ d_pendingFact.emplace_back(new SimpleTheoryInternalFact(InferenceId::UNKNOWN, conc, exp, pg));
}
void InferenceManagerBuffered::addPendingFact(
namespace theory {
namespace strings {
-CoreInferInfo::CoreInferInfo() : d_index(0), d_rev(false) {}
+CoreInferInfo::CoreInferInfo(InferenceId id) : d_infer(id), d_index(0), d_rev(false) {}
CoreSolver::CoreSolver(SolverState& s,
InferenceManager& im,
InferInfo& ii = ipii.d_infer;
Trace("strings-solve") << "#" << i << ": From " << ipii.d_i << " / "
<< ipii.d_j << " (rev=" << ipii.d_rev << ") : ";
- Trace("strings-solve") << ii.d_conc << " by " << ii.d_id << std::endl;
- if (!set_use_index || ii.d_id < min_id
- || (ii.d_id == min_id && ipii.d_index > max_index))
+ Trace("strings-solve") << ii.d_conc << " by " << ii.getId() << std::endl;
+ if (!set_use_index || ii.getId() < min_id
+ || (ii.getId() == min_id && ipii.d_index > max_index))
{
- min_id = ii.d_id;
+ min_id = ii.getId();
max_index = ipii.d_index;
use_index = i;
set_use_index = true;
}
// The candidate inference "info"
- CoreInferInfo info;
+ CoreInferInfo info(InferenceId::UNKNOWN);
InferInfo& iinfo = info.d_infer;
info.d_index = index;
// for debugging
Node lenEq = nm->mkNode(EQUAL, xLenTerm, yLenTerm);
lenEq = Rewriter::rewrite(lenEq);
iinfo.d_conc = nm->mkNode(OR, lenEq, lenEq.negate());
- iinfo.d_id = InferenceId::STRINGS_LEN_SPLIT;
+ iinfo.setId(InferenceId::STRINGS_LEN_SPLIT);
info.d_pendingPhase[lenEq] = true;
pinfer.push_back(info);
break;
// inferred
iinfo.d_conc = nm->mkNode(
AND, p.eqNode(nc), !eq.getConst<bool>() ? pEq.negate() : pEq);
- iinfo.d_id = InferenceId::STRINGS_INFER_EMP;
+ iinfo.setId(InferenceId::STRINGS_INFER_EMP);
}
else
{
iinfo.d_conc = nm->mkNode(OR, eq, eq.negate());
- iinfo.d_id = InferenceId::STRINGS_LEN_SPLIT_EMP;
+ iinfo.setId(InferenceId::STRINGS_LEN_SPLIT_EMP);
}
pinfer.push_back(info);
break;
xcv, stra, PfRule::CONCAT_CPROP, isRev, skc, newSkolems);
Assert(newSkolems.size() == 1);
iinfo.d_skolems[LENGTH_SPLIT].push_back(newSkolems[0]);
- iinfo.d_id = InferenceId::STRINGS_SSPLIT_CST_PROP;
+ iinfo.setId(InferenceId::STRINGS_SSPLIT_CST_PROP);
iinfo.d_idRev = isRev;
pinfer.push_back(info);
break;
iinfo.d_premises.push_back(expNonEmpty);
Assert(newSkolems.size() == 1);
iinfo.d_skolems[LENGTH_SPLIT].push_back(newSkolems[0]);
- iinfo.d_id = InferenceId::STRINGS_SSPLIT_CST;
+ iinfo.setId(InferenceId::STRINGS_SSPLIT_CST);
iinfo.d_idRev = isRev;
pinfer.push_back(info);
break;
// make the conclusion
if (lentTestSuccess == -1)
{
- iinfo.d_id = InferenceId::STRINGS_SSPLIT_VAR;
+ iinfo.setId(InferenceId::STRINGS_SSPLIT_VAR);
iinfo.d_conc =
getConclusion(x, y, PfRule::CONCAT_SPLIT, isRev, skc, newSkolems);
if (options::stringUnifiedVSpt() && !options::stringLenConc())
}
else if (lentTestSuccess == 0)
{
- iinfo.d_id = InferenceId::STRINGS_SSPLIT_VAR_PROP;
+ iinfo.setId(InferenceId::STRINGS_SSPLIT_VAR_PROP);
iinfo.d_conc =
getConclusion(x, y, PfRule::CONCAT_LPROP, isRev, skc, newSkolems);
}
else
{
Assert(lentTestSuccess == 1);
- iinfo.d_id = InferenceId::STRINGS_SSPLIT_VAR_PROP;
+ iinfo.setId(InferenceId::STRINGS_SSPLIT_VAR_PROP);
iinfo.d_conc =
getConclusion(y, x, PfRule::CONCAT_LPROP, isRev, skc, newSkolems);
}
iinfo.d_premises.clear();
// try to make t equal to empty to avoid loop
iinfo.d_conc = nm->mkNode(kind::OR, split_eq, split_eq.negate());
- iinfo.d_id = InferenceId::STRINGS_LEN_SPLIT_EMP;
+ iinfo.setId(InferenceId::STRINGS_LEN_SPLIT_EMP);
return ProcessLoopResult::INFERENCE;
}
else
// we will be done
iinfo.d_conc = conc;
- iinfo.d_id = InferenceId::STRINGS_FLOOP;
+ iinfo.setId(InferenceId::STRINGS_FLOOP);
info.d_nfPair[0] = nfi.d_base;
info.d_nfPair[1] = nfj.d_base;
return ProcessLoopResult::INFERENCE;
class CoreInferInfo
{
public:
- CoreInferInfo();
+ CoreInferInfo(InferenceId id);
~CoreInferInfo() {}
/** The infer info of this class */
InferInfo d_infer;
namespace theory {
namespace strings {
-InferInfo::InferInfo() : d_sim(nullptr), d_id(InferenceId::UNKNOWN), d_idRev(false)
+InferInfo::InferInfo(InferenceId id): TheoryInference(id), d_sim(nullptr), d_idRev(false)
{
}
std::ostream& operator<<(std::ostream& out, const InferInfo& ii)
{
- out << "(infer " << ii.d_id << " " << ii.d_conc;
+ out << "(infer " << ii.getId() << " " << ii.d_conc;
if (ii.d_idRev)
{
out << " :rev";
class InferInfo : public TheoryInference
{
public:
- InferInfo();
+ InferInfo(InferenceId id);
~InferInfo() {}
/** Process this inference */
bool process(TheoryInferenceManager* im, bool asLemma) override;
/** Pointer to the class used for processing this info */
InferenceManager* d_sim;
- /** The inference identifier */
- InferenceId d_id;
/** Whether it is the reverse form of the above id */
bool d_idRev;
/** The conclusion */
TheoryProofStepBuffer psb(d_pnm->getChecker());
std::shared_ptr<InferInfo> ii = (*it).second;
// run the conversion
- convert(ii->d_id, ii->d_idRev, ii->d_conc, ii->d_premises, ps, psb, useBuffer);
+ convert(ii->getId(), ii->d_idRev, ii->d_conc, ii->d_premises, ps, psb, useBuffer);
// make the proof based on the step or the buffer
if (useBuffer)
{
return false;
}
// wrap in infer info and send below
- InferInfo ii;
- ii.d_id = infer;
+ InferInfo ii(infer);
ii.d_idRev = isRev;
ii.d_conc = eq;
ii.d_premises = exp;
{
Trace("strings-infer-debug") << "...as conflict" << std::endl;
Trace("strings-lemma") << "Strings::Conflict: " << ii.d_premises << " by "
- << ii.d_id << std::endl;
- Trace("strings-conflict") << "CONFLICT: inference conflict " << ii.d_premises << " by " << ii.d_id << std::endl;
+ << ii.getId() << std::endl;
+ Trace("strings-conflict") << "CONFLICT: inference conflict " << ii.d_premises << " by " << ii.getId() << std::endl;
++(d_statistics.d_conflictsInfer);
// process the conflict immediately
processConflict(ii);
if (unproc.empty())
{
Node eqs = ii.d_conc;
- InferInfo iiSubsLem;
- iiSubsLem.d_sim = this;
// keep the same id for now, since we are transforming the form of the
// inference, not the root reason.
- iiSubsLem.d_id = ii.d_id;
+ InferInfo iiSubsLem(ii.getId());
+ iiSubsLem.d_sim = this;
iiSubsLem.d_conc = eqs;
if (Trace.isOn("strings-lemma-debug"))
{
return false;
}
NodeManager* nm = NodeManager::currentNM();
- InferInfo iiSplit;
+ InferInfo iiSplit(infer);
iiSplit.d_sim = this;
- iiSplit.d_id = infer;
iiSplit.d_conc = nm->mkNode(OR, eq, nm->mkNode(NOT, eq));
eq = Rewriter::rewrite(eq);
addPendingPhaseRequirement(eq, preq);
{
Assert(!d_state.isInConflict());
// setup the fact to reproduce the proof in the call below
- d_statistics.d_inferences << ii.d_id;
+ d_statistics.d_inferences << ii.getId();
if (d_ipc != nullptr)
{
d_ipc->notifyFact(ii);
TrustNode tconf = mkConflictExp(ii.d_premises, d_ipc.get());
Assert(tconf.getKind() == TrustNodeKind::CONFLICT);
Trace("strings-assert") << "(assert (not " << tconf.getNode()
- << ")) ; conflict " << ii.d_id << std::endl;
+ << ")) ; conflict " << ii.getId() << std::endl;
// send the trusted conflict
trustedConflict(tconf);
}
facts.push_back(ii.d_conc);
}
Trace("strings-assert") << "(assert (=> " << ii.getPremises() << " "
- << ii.d_conc << ")) ; fact " << ii.d_id << std::endl;
+ << ii.d_conc << ")) ; fact " << ii.getId() << std::endl;
Trace("strings-lemma") << "Strings::Fact: " << ii.d_conc << " from "
- << ii.getPremises() << " by " << ii.d_id
+ << ii.getPremises() << " by " << ii.getId()
<< std::endl;
std::vector<Node> exp;
for (const Node& ec : ii.d_premises)
for (const Node& fact : facts)
{
ii.d_conc = fact;
- d_statistics.d_inferences << ii.d_id;
+ d_statistics.d_inferences << ii.getId();
bool polarity = fact.getKind() != NOT;
TNode atom = polarity ? fact : fact[0];
bool curRet = false;
}
// ensure that the proof generator is ready to explain the final conclusion
// of the lemma (ii.d_conc).
- d_statistics.d_inferences << ii.d_id;
+ d_statistics.d_inferences << ii.getId();
if (d_ipc != nullptr)
{
d_ipc->notifyFact(ii);
}
}
LemmaProperty p = LemmaProperty::NONE;
- if (ii.d_id == InferenceId::STRINGS_REDUCTION)
+ if (ii.getId() == InferenceId::STRINGS_REDUCTION)
{
p |= LemmaProperty::NEEDS_JUSTIFY;
}
Trace("strings-assert") << "(assert " << tlem.getNode() << ") ; lemma "
- << ii.d_id << std::endl;
+ << ii.getId() << std::endl;
Trace("strings-lemma") << "Strings::Lemma: " << tlem.getNode() << " by "
- << ii.d_id << std::endl;
+ << ii.getId() << std::endl;
++(d_statistics.d_lemmasInfer);
// call the trusted lemma, without caching
SolverState::SolverState(context::Context* c,
context::UserContext* u,
Valuation& v)
- : TheoryState(c, u, v), d_eeDisequalities(c), d_pendingConflictSet(c, false)
+ : TheoryState(c, u, v), d_eeDisequalities(c), d_pendingConflictSet(c, false), d_pendingConflict(InferenceId::UNKNOWN)
{
d_zero = NodeManager::currentNM()->mkConst(Rational(0));
d_false = NodeManager::currentNM()->mkConst(false);
{
return;
}
- InferInfo iiPrefixConf;
- iiPrefixConf.d_id = InferenceId::STRINGS_PREFIX_CONFLICT;
+ InferInfo iiPrefixConf(InferenceId::STRINGS_PREFIX_CONFLICT);
iiPrefixConf.d_conc = d_false;
utils::flattenOp(AND, conf, iiPrefixConf.d_premises);
setPendingConflict(iiPrefixConf);
// process pending conflicts due to reasoning about endpoints
if (!d_state.isInConflict() && d_state.hasPendingConflict())
{
- InferInfo iiPendingConf;
+ InferInfo iiPendingConf(InferenceId::UNKNOWN);
d_state.getPendingConflict(iiPendingConf);
Trace("strings-pending")
<< "Process pending conflict " << iiPendingConf.d_premises << std::endl;
namespace CVC4 {
namespace theory {
-SimpleTheoryLemma::SimpleTheoryLemma(Node n,
+SimpleTheoryLemma::SimpleTheoryLemma(InferenceId id,
+ Node n,
LemmaProperty p,
ProofGenerator* pg)
- : d_node(n), d_property(p), d_pg(pg)
+ : TheoryInference(id), d_node(n), d_property(p), d_pg(pg)
{
}
return im->trustedLemma(TrustNode::mkTrustLemma(d_node, d_pg), d_property);
}
-SimpleTheoryInternalFact::SimpleTheoryInternalFact(Node conc,
+SimpleTheoryInternalFact::SimpleTheoryInternalFact(InferenceId id,
+ Node conc,
Node exp,
ProofGenerator* pg)
- : d_conc(conc), d_exp(exp), d_pg(pg)
+ : TheoryInference(id), d_conc(conc), d_exp(exp), d_pg(pg)
{
}
#define CVC4__THEORY__THEORY_INFERENCE_H
#include "expr/node.h"
+#include "theory/inference_id.h"
#include "theory/output_channel.h"
namespace CVC4 {
class TheoryInference
{
public:
+ TheoryInference(InferenceId id) : d_id(id) {}
virtual ~TheoryInference() {}
/**
* Called by the provided inference manager to process this inference. This
* lemma that was already cached by im and hence was discarded.
*/
virtual bool process(TheoryInferenceManager* im, bool asLemma) = 0;
+
+ /** Get the InferenceId of this theory inference. */
+ InferenceId getId() const { return d_id; }
+ /** Set the InferenceId of this theory inference. */
+ void setId(InferenceId id) { d_id = id; }
+
+ private:
+ InferenceId d_id;
};
/**
class SimpleTheoryLemma : public TheoryInference
{
public:
- SimpleTheoryLemma(Node n, LemmaProperty p, ProofGenerator* pg);
+ SimpleTheoryLemma(InferenceId id, Node n, LemmaProperty p, ProofGenerator* pg);
virtual ~SimpleTheoryLemma() {}
/**
* Send the lemma using inference manager im, return true if the lemma was
class SimpleTheoryInternalFact : public TheoryInference
{
public:
- SimpleTheoryInternalFact(Node conc, Node exp, ProofGenerator* pg);
+ SimpleTheoryInternalFact(InferenceId id, Node conc, Node exp, ProofGenerator* pg);
virtual ~SimpleTheoryInternalFact() {}
/**
* Send the lemma using inference manager im, return true if the lemma was
#include "context/cdhashset.h"
#include "expr/node.h"
+#include "theory/inference_id.h"
#include "theory/output_channel.h"
#include "theory/theory_state.h"
#include "theory/trust_node.h"