}
}
+Node arithSubstitute(Node n, std::vector<Node>& vars, std::vector<Node>& subs)
+{
+ Assert(vars.size() == subs.size());
+ NodeManager* nm = NodeManager::currentNM();
+ std::unordered_map<TNode, Node, TNodeHashFunction> visited;
+ std::unordered_map<TNode, Node, TNodeHashFunction>::iterator it;
+ std::vector<Node>::iterator itv;
+ std::vector<TNode> visit;
+ TNode cur;
+ Kind ck;
+ visit.push_back(n);
+ do
+ {
+ cur = visit.back();
+ visit.pop_back();
+ it = visited.find(cur);
+
+ if (it == visited.end())
+ {
+ visited[cur] = Node::null();
+ ck = cur.getKind();
+ itv = std::find(vars.begin(), vars.end(), cur);
+ if (itv != vars.end())
+ {
+ visited[cur] = subs[std::distance(vars.begin(), itv)];
+ }
+ else if (cur.getNumChildren() == 0)
+ {
+ visited[cur] = cur;
+ }
+ else
+ {
+ TheoryId ctid = theory::kindToTheoryId(ck);
+ if (ctid != THEORY_ARITH && ctid != THEORY_BOOL
+ && ctid != THEORY_BUILTIN)
+ {
+ // do not traverse beneath applications that belong to another theory
+ visited[cur] = cur;
+ }
+ else
+ {
+ visit.push_back(cur);
+ for (const Node& cn : cur)
+ {
+ visit.push_back(cn);
+ }
+ }
+ }
+ }
+ else if (it->second.isNull())
+ {
+ Node ret = cur;
+ bool childChanged = false;
+ std::vector<Node> children;
+ if (cur.getMetaKind() == kind::metakind::PARAMETERIZED)
+ {
+ children.push_back(cur.getOperator());
+ }
+ for (const Node& cn : cur)
+ {
+ it = visited.find(cn);
+ Assert(it != visited.end());
+ Assert(!it->second.isNull());
+ childChanged = childChanged || cn != it->second;
+ children.push_back(it->second);
+ }
+ if (childChanged)
+ {
+ ret = nm->mkNode(cur.getKind(), children);
+ }
+ visited[cur] = ret;
+ }
+ } while (!visit.empty());
+ Assert(visited.find(n) != visited.end());
+ Assert(!visited.find(n)->second.isNull());
+ return visited[n];
+}
+
} // namespace arith
} // namespace theory
} // namespace CVC4
/** print rational approximation of cr with precision prec on trace c */
void printRationalApprox(const char* c, Node cr, unsigned prec = 5);
+/** Arithmetic substitute
+ *
+ * This computes the substitution n { vars -> subs }, but with the caveat
+ * that subterms of n that belong to a theory other than arithmetic are
+ * not traversed. In other words, terms that belong to other theories are
+ * treated as atomic variables. For example:
+ * (5*f(x) + 7*x ){ x -> 3 } returns 5*f(x) + 7*3.
+ */
+Node arithSubstitute(Node n, std::vector<Node>& vars, std::vector<Node>& subs);
+
}/* CVC4::theory::arith namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
// apply the substitution to a
if (!d_check_model_vars.empty())
{
- av = av.substitute(d_check_model_vars.begin(),
- d_check_model_vars.end(),
- d_check_model_subs.begin(),
- d_check_model_subs.end());
+ av = arithSubstitute(av, d_check_model_vars, d_check_model_subs);
av = Rewriter::rewrite(av);
}
// simple check literal
return false;
}
}
+ std::vector<Node> varsTmp;
+ varsTmp.push_back(v);
+ std::vector<Node> subsTmp;
+ subsTmp.push_back(s);
for (unsigned i = 0, size = d_check_model_subs.size(); i < size; i++)
{
Node ms = d_check_model_subs[i];
- Node mss = ms.substitute(v, s);
+ Node mss = arithSubstitute(ms, varsTmp, subsTmp);
if (mss != ms)
{
mss = Rewriter::rewrite(mss);
Node seq = eq;
if (!d_check_model_vars.empty())
{
- seq = eq.substitute(d_check_model_vars.begin(),
- d_check_model_vars.end(),
- d_check_model_subs.begin(),
- d_check_model_subs.end());
+ seq = arithSubstitute(eq, d_check_model_vars, d_check_model_subs);
seq = Rewriter::rewrite(seq);
if (seq.isConst())
{
for (unsigned r = 0; r < 2; r++)
{
qsubs.push_back(boundn[r]);
- Node ts = t.substitute(
- qvars.begin(), qvars.end(), qsubs.begin(), qsubs.end());
+ Node ts = arithSubstitute(t, qvars, qsubs);
tcmpn[r] = Rewriter::rewrite(ts);
qsubs.pop_back();
}
Node pa = a;
if (!pvars.empty())
{
- pa =
- pa.substitute(pvars.begin(), pvars.end(), psubs.begin(), psubs.end());
+ pa = arithSubstitute(pa, pvars, psubs);
pa = Rewriter::rewrite(pa);
}
if (!pa.isConst() || !pa.getConst<bool>())
regress1/nl/exp1-lb.smt2
regress1/nl/exp_monotone.smt2
regress1/nl/factor_agg_s.smt2
+ regress1/nl/issue3307.smt2
regress1/nl/issue3441.smt2
regress1/nl/metitarski-1025.smt2
regress1/nl/metitarski-3-4.smt2
--- /dev/null
+; COMMAND-LINE: --no-check-models
+; EXPECT: sat
+(set-logic NRA)
+(set-info :status sat)
+(declare-fun a () Real)
+(declare-fun b () Real)
+(assert
+ (and
+ (> b 1)
+ (< a 0)
+ (>= (/ 0 (+ (* a b) (/ (- a) 0))) a)
+ )
+ )
+(check-sat)