Towards eliminating arithmetic subtyping.
}
}
-// Node explainSet(const set<ConstraintP>& inp){
-// Assert(!inp.empty());
-// NodeBuilder nb(kind::AND);
-// set<ConstraintP>::const_iterator iter, end;
-// for(iter = inp.begin(), end = inp.end(); iter != end; ++iter){
-// const ConstraintP c = *iter;
-// Assert(c != NullConstraint);
-// c->explainForConflict(nb);
-// }
-// Node ret = safeConstructNary(nb);
-// Node rew = rewrite(ret);
-// if(rew.getNumChildren() < ret.getNumChildren()){
-// //Debug("approx::") << "explainSet " << ret << " " << rew << endl;
-// }
-// return rew;
-// }
-
DeltaRational sumConstraints(const DenseMap<Rational>& xs, const DenseMap<ConstraintP>& cs, bool* anyinf){
if(anyinf != NULL){
*anyinf = false;
switch(n.getKind()){
case ITE:{
Node c = n[0], t = n[1], e = n[2];
- if (n.getType().isRealOrInt())
+ TypeNode tn = n.getType();
+ if (tn.isRealOrInt())
{
Node rc = reduceVariablesInItes(c);
Node rt = reduceVariablesInItes(t);
Node ve = d_varParts[e];
Node vpite = (vt == ve) ? vt : Node::null();
+ NodeManager* nm = NodeManager::currentNM();
if(vpite.isNull()){
Node rite = rc.iteNode(rt, re);
// do not apply
d_reduceVar[n] = rite;
- d_constants[n] = mkRationalNode(Rational(0));
+ d_constants[n] = nm->mkConstRealOrInt(tn, Rational(0));
d_varParts[n] = rite; // treat the ite as a variable
return rite;
}else{
- NodeManager* nm = NodeManager::currentNM();
Node constantite = rc.iteNode(d_constants[t], d_constants[e]);
Node sum = nm->mkNode(kind::PLUS, vpite, constantite);
d_reduceVar[n] = sum;
}
}break;
default:
- if (n.getType().isRealOrInt() && Polynomial::isMember(n))
+ {
+ TypeNode tn = n.getType();
+ if (tn.isRealOrInt() && Polynomial::isMember(n))
{
Node newn = Node::null();
if(!d_contains.containsTermITE(n)){
}else{
newn = n;
}
-
+ NodeManager* nm = NodeManager::currentNM();
Polynomial p = Polynomial::parsePolynomial(newn);
if(p.isConstant()){
d_constants[n] = newn;
- d_varParts[n] = mkRationalNode(Rational(0));
+ d_varParts[n] = nm->mkConstRealOrInt(tn, Rational(0));
// don't bother adding to d_reduceVar
return newn;
}else if(!p.containsConstant()){
- d_constants[n] = mkRationalNode(Rational(0));
+ d_constants[n] = nm->mkConstRealOrInt(tn, Rational(0));
d_varParts[n] = newn;
d_reduceVar[n] = p.getNode();
return p.getNode();
return n;
}
}
+ }
break;
}
Unreachable();
Node ArithIteUtils::reduceIteConstantIteByGCD_rec(Node n, const Rational& q){
if(n.isConst()){
- Assert(n.getKind() == kind::CONST_RATIONAL);
- return mkRationalNode(n.getConst<Rational>() * q);
+ Assert(n.getType().isRealOrInt());
+ return NodeManager::currentNM()->mkConstRealOrInt(
+ n.getType(), n.getConst<Rational>() * q);
}else{
Assert(n.getKind() == kind::ITE);
Assert(n.getType().isInteger());
Assert(n.getKind() == kind::ITE);
Assert(n.getType().isRealOrInt());
const Integer& gcd = gcdIte(n);
+ NodeManager* nm = NodeManager::currentNM();
if(gcd.isOne()){
Node newIte = reduceConstantIteByGCD(n[0]).iteNode(n[1],n[2]);
d_reduceGcd[n] = newIte;
return newIte;
}else if(gcd.isZero()){
- Node zeroNode = mkRationalNode(Rational(0));
+ Node zeroNode = nm->mkConstRealOrInt(n.getType(), Rational(0));
d_reduceGcd[n] = zeroNode;
return zeroNode;
}else{
Rational divBy(Integer(1), gcd);
Node redite = reduceIteConstantIteByGCD_rec(n, divBy);
- Node gcdNode = mkRationalNode(Rational(gcd));
- Node multIte = NodeManager::currentNM()->mkNode(kind::MULT, gcdNode, redite);
+ Node gcdNode = nm->mkConstRealOrInt(n.getType(), Rational(gcd));
+ Node multIte = nm->mkNode(kind::MULT, gcdNode, redite);
d_reduceGcd[n] = multIte;
return multIte;
}
const Rational& exp = t[1].getConst<Rational>();
TNode base = t[0];
if(exp.sgn() == 0){
- return RewriteResponse(REWRITE_DONE, mkRationalNode(Rational(1)));
+ return RewriteResponse(REWRITE_DONE,
+ NodeManager::currentNM()->mkConstRealOrInt(
+ t.getType(), Rational(1)));
}else if(exp.sgn() > 0 && exp.isIntegral()){
cvc5::Rational r(expr::NodeValue::MAX_CHILDREN);
if (exp <= r)
Rational r = pi_factor.getConst<Rational>();
Rational r_abs = r.abs();
Rational rone = Rational(1);
- Node ntwo = mkRationalNode(Rational(2));
+ Node ntwo = nm->mkConstInt(Rational(2));
if (r_abs > rone)
{
//add/substract 2*pi beyond scope
if (k == kind::INTS_MODULUS_TOTAL)
{
// (mod x 1) --> 0
- return returnRewrite(t, mkRationalNode(0), Rewrite::MOD_BY_ONE);
+ return returnRewrite(t, nm->mkConstInt(0), Rewrite::MOD_BY_ONE);
}
Assert(k == kind::INTS_DIVISION_TOTAL);
// (div x 1) --> x
CDNodeToMinMaxMap::const_iterator minFind = d_minMap.find(n);
if (minFind == d_minMap.end() || (*minFind).second < min) {
d_minMap.insert(n, min);
- Node nGeqMin;
- if (min.getInfinitesimalPart() == 0) {
- nGeqMin = NodeBuilder(kind::GEQ)
- << n << mkRationalNode(min.getNoninfinitesimalPart());
- } else {
- nGeqMin = NodeBuilder(kind::GT)
- << n << mkRationalNode(min.getNoninfinitesimalPart());
- }
+ NodeManager* nm = NodeManager::currentNM();
+ Node nGeqMin = nm->mkNode(
+ min.getInfinitesimalPart() == 0 ? kind::GEQ : kind::GT,
+ n,
+ nm->mkConstRealOrInt(n.getType(), min.getNoninfinitesimalPart()));
learned << nGeqMin;
Debug("arith::static") << n << " iteConstant" << nGeqMin << endl;
++(d_statistics.d_iteConstantApplications);
CDNodeToMinMaxMap::const_iterator maxFind = d_maxMap.find(n);
if (maxFind == d_maxMap.end() || (*maxFind).second > max) {
d_maxMap.insert(n, max);
- Node nLeqMax;
- if (max.getInfinitesimalPart() == 0) {
- nLeqMax = NodeBuilder(kind::LEQ)
- << n << mkRationalNode(max.getNoninfinitesimalPart());
- } else {
- nLeqMax = NodeBuilder(kind::LT)
- << n << mkRationalNode(max.getNoninfinitesimalPart());
- }
+ NodeManager* nm = NodeManager::currentNM();
+ Node nLeqMax = nm->mkNode(
+ max.getInfinitesimalPart() == 0 ? kind::LEQ : kind::LT,
+ n,
+ nm->mkConstRealOrInt(n.getType(), max.getNoninfinitesimalPart()));
learned << nLeqMax;
Debug("arith::static") << n << " iteConstant" << nLeqMax << endl;
++(d_statistics.d_iteConstantApplications);
}
// Returns an node that is the identity of a select few kinds.
-inline Node getIdentity(Kind k){
- switch(k){
- case kind::AND:
- return mkBoolNode(true);
- case kind::PLUS:
- return mkRationalNode(0);
- case kind::MULT:
- case kind::NONLINEAR_MULT:
- return mkRationalNode(1);
- default: Unreachable(); return Node::null(); // silence warning
+inline Node getIdentityType(const TypeNode& tn, Kind k)
+{
+ switch (k)
+ {
+ case kind::PLUS: return NodeManager::currentNM()->mkConstRealOrInt(tn, 0);
+ case kind::MULT:
+ case kind::NONLINEAR_MULT:
+ return NodeManager::currentNM()->mkConstRealOrInt(tn, 1);
+ default: Unreachable(); return Node::null(); // silence warning
}
}
-inline Node safeConstructNary(NodeBuilder& nb)
+inline Node mkAndFromBuilder(NodeBuilder& nb)
{
+ Assert(nb.getKind() == kind::AND);
switch (nb.getNumChildren()) {
- case 0:
- return getIdentity(nb.getKind());
+ case 0: return mkBoolNode(true);
case 1:
return nb[0];
default:
}
}
-inline Node safeConstructNary(Kind k, const std::vector<Node>& children) {
- switch (children.size()) {
- case 0:
- return getIdentity(k);
- case 1:
- return children[0];
- default:
- return NodeManager::currentNM()->mkNode(k, children);
+inline Node safeConstructNaryType(const TypeNode& tn,
+ Kind k,
+ const std::vector<Node>& children)
+{
+ switch (children.size())
+ {
+ case 0: return getIdentityType(tn, k);
+ case 1: return children[0];
+ default: return NodeManager::currentNM()->mkNode(k, children);
}
}
// when n is 0 or not. Useful for division by 0 logic.
// (ite (= n 0) (= q if_zero) (= q not_zero))
inline Node mkOnZeroIte(Node n, Node q, Node if_zero, Node not_zero) {
- Node zero = mkRationalNode(0);
+ Node zero = NodeManager::currentNM()->mkConstRealOrInt(n.getType(), 0);
return n.eqNode(zero).iteNode(q.eqNode(if_zero), q.eqNode(not_zero));
}
NodeBuilder reasonBuilder(Kind::AND);
auto pfLb = lb->externalExplainByAssertions(reasonBuilder);
auto pfUb = ub->externalExplainByAssertions(reasonBuilder);
- Node reason = safeConstructNary(reasonBuilder);
+ Node reason = mkAndFromBuilder(reasonBuilder);
std::shared_ptr<ProofNode> pf{};
if (isProofEnabled())
{
pf = d_pnm->mkNode(
PfRule::MACRO_SR_PRED_TRANSFORM, {pf}, {d_watchedEqualities[s]});
}
- Node reason = safeConstructNary(nb);
+ Node reason = mkAndFromBuilder(nb);
d_keepAlive.push_back(reason);
assertionToEqualityEngine(true, s, reason, pf);
pf->printDebug(Debug("arith::cong::notzero"));
Debug("arith::cong::notzero") << std::endl;
}
- Node reason = safeConstructNary(nb);
+ Node reason = mkAndFromBuilder(nb);
if (isProofEnabled())
{
if (c->getType() == ConstraintType::Disequality)
ArithVar x = c->getVariable();
Node xAsNode = d_avariables.asNode(x);
- Node asRational = mkRationalNode(c->getValue().getNoninfinitesimalPart());
+ NodeManager* nm = NodeManager::currentNM();
+ Node asRational = nm->mkConstRealOrInt(
+ xAsNode.getType(), c->getValue().getNoninfinitesimalPart());
// No guarentee this is in normal form!
// Note though, that it happens to be in proof normal form!
NodeBuilder nb(Kind::AND);
auto pf = c->externalExplainByAssertions(nb);
- Node reason = safeConstructNary(nb);
+ Node reason = mkAndFromBuilder(nb);
d_keepAlive.push_back(reason);
Trace("arith-ee") << "Assert equalsConstant " << eq << ", reason " << reason << std::endl;
NodeBuilder nb(Kind::AND);
auto pfLb = lb->externalExplainByAssertions(nb);
auto pfUb = ub->externalExplainByAssertions(nb);
- Node reason = safeConstructNary(nb);
+ Node reason = mkAndFromBuilder(nb);
Node xAsNode = d_avariables.asNode(x);
- Node asRational = mkRationalNode(lb->getValue().getNoninfinitesimalPart());
+ NodeManager* nm = NodeManager::currentNM();
+ Node asRational = nm->mkConstRealOrInt(
+ xAsNode.getType(), lb->getValue().getNoninfinitesimalPart());
// No guarentee this is in normal form!
// Note though, that it happens to be in proof normal form!
{
NodeBuilder nb(kind::AND);
auto pfFromAssumptions = externalExplain(nb, AssertionOrderSentinel);
- Node exp = safeConstructNary(nb);
+ Node exp = mkAndFromBuilder(nb);
if (d_database->isProofEnabled())
{
std::vector<Node> assumptions;
}
auto pf = d_database->d_pnm->mkScope(pfFromAssumptions, assumptions);
return d_database->d_pfGen->mkTrustedPropagation(
- getLiteral(), safeConstructNary(Kind::AND, assumptions), pf);
+ getLiteral(), NodeManager::currentNM()->mkAnd(assumptions), pf);
}
return TrustNode::mkTrustPropExp(getLiteral(), exp);
}
Assert(!isInternalAssumption());
NodeBuilder nb(Kind::AND);
auto pfFromAssumptions = externalExplain(nb, d_assertionOrder);
- Node n = safeConstructNary(nb);
+ Node n = mkAndFromBuilder(nb);
if (d_database->isProofEnabled())
{
std::vector<Node> assumptions;
}
auto pf = d_database->d_pnm->mkScope(pfFromAssumptions, assumptions);
return d_database->d_pfGen->mkTrustedPropagation(
- lit, safeConstructNary(Kind::AND, assumptions), pf);
+ lit, NodeManager::currentNM()->mkAnd(assumptions), pf);
}
else
{
auto pf1 = externalExplainByAssertions(nb);
auto not2 = getNegation()->getProofLiteral().negate();
auto pf2 = getNegation()->externalExplainByAssertions(nb);
- Node n = safeConstructNary(nb);
+ Node n = mkAndFromBuilder(nb);
if (d_database->isProofEnabled())
{
auto pfNot2 = d_database->d_pnm->mkNode(
}
auto confPf = d_database->d_pnm->mkScope(bot, lits);
return d_database->d_pfGen->mkTrustNode(
- safeConstructNary(Kind::AND, lits), confPf, true);
+ NodeManager::currentNM()->mkAnd(lits), confPf, true);
}
else
{
ConstraintCP v_i = *i;
v_i->externalExplain(nb, order);
}
- return safeConstructNary(nb);
+ return mkAndFromBuilder(nb);
}
std::shared_ptr<ProofNode> Constraint::externalExplain(
d_m_contain_parent[a].push_back(b);
d_m_contain_children[b].push_back(a);
- Node mult_term = safeConstructNary(MULT, diff_children);
- Node nlmult_term = safeConstructNary(NONLINEAR_MULT, diff_children);
+ // currently use real type here
+ TypeNode tn = NodeManager::currentNM()->realType();
+ Node mult_term = safeConstructNaryType(tn, MULT, diff_children);
+ Node nlmult_term = safeConstructNaryType(tn, NONLINEAR_MULT, diff_children);
d_m_contain_mult[a][b] = mult_term;
d_m_contain_umult[a][b] = nlmult_term;
Trace("nl-ext-mindex") << "..." << a << " is a subset of " << b
<< "......rem, now " << inc << " factors of " << v << std::endl;
children.insert(children.end(), inc, v);
}
- Node ret = safeConstructNary(MULT, children);
+ Node ret = safeConstructNaryType(n.getType(), MULT, children);
Trace("nl-ext-mono-factor") << "...return : " << ret << std::endl;
return ret;
}
size_t getComplexity() const;
};/* class Variable */
-
class Constant : public NodeWrapper {
public:
Constant(Node n) : NodeWrapper(n) { Assert(isMember(getNode())); }
}
}
Assert(negPos < neg.size());
-
- // Assert(dnconf.getKind() == kind::AND);
- // Assert(upconf.getKind() == kind::AND);
- // Assert(dnpos < dnconf.getNumChildren());
- // Assert(uppos < upconf.getNumChildren());
- // Assert(equalUpToNegation(dnconf[dnpos], upconf[uppos]));
-
- // NodeBuilder nb(kind::AND);
- // dropPosition(nb, dnconf, dnpos);
- // dropPosition(nb, upconf, uppos);
- // return safeConstructNary(nb);
}
TheoryArithPrivate::ModelException::ModelException(TNode n, const char* msg)
const DeltaRational drv = getDeltaValue(term);
const Rational& delta = d_partialModel.getDelta();
const Rational qmodel = drv.substituteDelta( delta );
- return mkRationalNode( qmodel );
+ return NodeManager::currentNM()->mkConstRealOrInt(term.getType(), qmodel);
} catch (DeltaRationalException& dr) {
return Node::null();
} catch (ModelException& me) {
Assert(k == kind::LEQ || k == kind::GEQ);
- Node comparison = NodeManager::currentNM()->mkNode(k, sum, mkRationalNode(rhs));
+ NodeManager* nm = NodeManager::currentNM();
+ Node comparison =
+ nm->mkNode(k, sum, nm->mkConstRealOrInt(sum.getType(), rhs));
Node rewritten = rewrite(comparison);
if(!(Comparison::isNormalAtom(rewritten))){
return make_pair(NullConstraint, added);
return replayGetConstraint(lhs, k, rhs, ci.getKlass() == BranchCutKlass);
}
-// Node denseVectorToLiteral(const ArithVariables& vars, const DenseVector& dv,
-// Kind k){
-// NodeManager* nm = NodeManager::currentNM();
-// Node sumLhs = toSumNode(vars, dv.lhs);
-// Node ineq = nm->mkNode(k, sumLhs, mkRationalNode(dv.rhs) );
-// Node lit = rewrite(ineq);
-// return lit;
-// }
-
Node toSumNode(const ArithVariables& vars, const DenseMap<Rational>& sum){
Debug("arith::toSumNode") << "toSumNode() begin" << endl;
- NodeBuilder nb(kind::PLUS);
NodeManager* nm = NodeManager::currentNM();
DenseMap<Rational>::const_iterator iter, end;
iter = sum.begin(), end = sum.end();
+ std::vector<Node> children;
for(; iter != end; ++iter){
ArithVar x = *iter;
if(!vars.hasNode(x)){ return Node::null(); }
const Rational& q = sum[x];
Node mult = nm->mkNode(kind::MULT, mkRationalNode(q), xNode);
Debug("arith::toSumNode") << "toSumNode() " << x << " " << mult << endl;
- nb << mult;
+ children.push_back(mult);
}
Debug("arith::toSumNode") << "toSumNode() end" << endl;
- return safeConstructNary(nb);
+ if (children.empty())
+ {
+ // NOTE: real type assumed here
+ return nm->mkConstReal(Rational(0));
+ }
+ else if (children.size() == 1)
+ {
+ return children[0];
+ }
+ return nm->mkNode(kind::PLUS, children);
}
ConstraintCP TheoryArithPrivate::vectorToIntHoleConflict(const ConstraintCPVec& conflict){
}
Rational fl(maybe_value.value().floor());
NodeManager* nm = NodeManager::currentNM();
- Node leq = nm->mkNode(kind::LEQ, n, mkRationalNode(fl));
+ Node leq =
+ nm->mkNode(kind::LEQ, n, nm->mkConstRealOrInt(n.getType(), fl));
Node norm = rewrite(leq);
return norm;
}
const DenseMap<Rational>& lhs = ci.getReconstruction().lhs;
Node sum = toSumNode(d_partialModel, lhs);
if(!sum.isNull()){
+ NodeManager* nm = NodeManager::currentNM();
Kind k = ci.getKind();
Assert(k == kind::LEQ || k == kind::GEQ);
- Node rhs = mkRationalNode(ci.getReconstruction().rhs);
-
- NodeManager* nm = NodeManager::currentNM();
+ Node rhs = nm->mkConstRealOrInt(sum.getType(), ci.getReconstruction().rhs);
Node ineq = nm->mkNode(k, sum, rhs);
return rewrite(ineq);
}
}
}
+ NodeManager* nm = NodeManager::currentNM();
while(d_congruenceManager.hasMorePropagations()){
TNode toProp = d_congruenceManager.getNextPropagation();
Node notNormalized = normalized.negate();
std::vector<Node> ants(exp.getNode().begin(), exp.getNode().end());
ants.push_back(notNormalized);
- Node lp = safeConstructNary(kind::AND, ants);
+ Node lp = nm->mkAnd(ants);
Debug("arith::prop") << "propagate conflict" << lp << endl;
if (proofsEnabled())
{
// TODO:
// This is not very good for user push/pop....
// Revisit when implementing push/pop
+ NodeManager* nm = NodeManager::currentNM();
for(var_iterator vi = var_begin(), vend = var_end(); vi != vend; ++vi){
ArithVar v = *vi;
const DeltaRational& mod = d_partialModel.getAssignment(v);
Rational qmodel = mod.substituteDelta(delta);
- Node qNode = mkRationalNode(qmodel);
+ Node qNode = nm->mkConstRealOrInt(term.getType(), qmodel);
Debug("arith::collectModelInfo") << "m->assertEquality(" << term << ", " << qmodel << ", true)" << endl;
// Add to the map
arithModel[term] = qNode;