Iterator substitutionsEnd,
std::unordered_map<TNode, TNode>& cache) const;
- /** Default constructor, makes a null expression. */
- NodeTemplate() : d_nv(&expr::NodeValue::null()) {}
+ /** Default constructor, makes a null expression.
+ *
+ * This constructor is `explicit` to avoid accidentially creating a null node
+ * from an empty braced-init-list.
+ */
+ explicit NodeTemplate() : d_nv(&expr::NodeValue::null()) {}
/**
* Conversion between nodes that are reference-counted and those that are
return kind::UNDEFINED_KIND;
}
+Node NodeManager::mkNode(Kind kind, std::initializer_list<TNode> children)
+{
+ NodeBuilder nb(this, kind);
+ nb.append(children.begin(), children.end());
+ return nb.constructNode();
+}
+
+Node NodeManager::mkNode(TNode opNode, std::initializer_list<TNode> children)
+{
+ NodeBuilder nb(this, operatorToKind(opNode));
+ if (opNode.getKind() != kind::BUILTIN)
+ {
+ nb << opNode;
+ }
+ nb.append(children.begin(), children.end());
+ return nb.constructNode();
+}
+
} // namespace cvc5
static Kind getKindForFunction(TNode fun);
// general expression-builders
+ //
+ /** Create a node with no child. */
+ Node mkNode(Kind kind);
/** Create a node with one child. */
Node mkNode(Kind kind, TNode child1);
/** Create a node with three children. */
Node mkNode(Kind kind, TNode child1, TNode child2, TNode child3);
- /** Create a node with four children. */
- Node mkNode(Kind kind, TNode child1, TNode child2, TNode child3,
- TNode child4);
-
- /** Create a node with five children. */
- Node mkNode(Kind kind, TNode child1, TNode child2, TNode child3,
- TNode child4, TNode child5);
-
/** Create a node with an arbitrary number of children. */
template <bool ref_count>
Node mkNode(Kind kind, const std::vector<NodeTemplate<ref_count> >& children);
+ /** Create a node using an initializer list.
+ *
+ * This function serves two purposes:
+ * - We can avoid creating a temporary vector in some cases, e.g., when we
+ * want to create a node with a fixed, large number of children
+ * - It makes sure that calls to `mkNode` that braced-init-lists work as
+ * expected, e.g., mkNode(REGEXP_EMPTY, {}) will call this overload instead
+ * of creating a node with a null node as a child.
+ */
+ Node mkNode(Kind kind, std::initializer_list<TNode> children);
+
/**
* Create an AND node with arbitrary number of children. This returns the
* true node if children is empty, or the single node in children if
/** Create a node with three children by operator. */
Node mkNode(TNode opNode, TNode child1, TNode child2, TNode child3);
- /** Create a node with four children by operator. */
- Node mkNode(TNode opNode, TNode child1, TNode child2, TNode child3,
- TNode child4);
-
- /** Create a node with five children by operator. */
- Node mkNode(TNode opNode, TNode child1, TNode child2, TNode child3,
- TNode child4, TNode child5);
-
/** Create a node by applying an operator to the children. */
template <bool ref_count>
Node mkNode(TNode opNode, const std::vector<NodeTemplate<ref_count> >& children);
+ /**
+ * Create a node by applying an operator to an arbitrary number of children.
+ *
+ * Analoguous to `mkNode(Kind, std::initializer_list<TNode>)`.
+ */
+ Node mkNode(TNode opNode, std::initializer_list<TNode> children);
+
Node mkBoundVar(const std::string& name, const TypeNode& type);
Node mkBoundVar(const TypeNode& type);
return kind::operatorToKind(n.d_nv);
}
+inline Node NodeManager::mkNode(Kind kind)
+{
+ NodeBuilder nb(this, kind);
+ return nb.constructNode();
+}
+
inline Node NodeManager::mkNode(Kind kind, TNode child1) {
NodeBuilder nb(this, kind);
nb << child1;
return nb.constructNode();
}
-inline Node NodeManager::mkNode(Kind kind, TNode child1, TNode child2,
- TNode child3, TNode child4) {
- NodeBuilder nb(this, kind);
- nb << child1 << child2 << child3 << child4;
- return nb.constructNode();
-}
-
-inline Node NodeManager::mkNode(Kind kind, TNode child1, TNode child2,
- TNode child3, TNode child4, TNode child5) {
- NodeBuilder nb(this, kind);
- nb << child1 << child2 << child3 << child4 << child5;
- return nb.constructNode();
-}
-
// N-ary version
template <bool ref_count>
inline Node NodeManager::mkNode(Kind kind,
return nb.constructNode();
}
-inline Node NodeManager::mkNode(TNode opNode, TNode child1, TNode child2,
- TNode child3, TNode child4) {
- NodeBuilder nb(this, operatorToKind(opNode));
- if(opNode.getKind() != kind::BUILTIN) {
- nb << opNode;
- }
- nb << child1 << child2 << child3 << child4;
- return nb.constructNode();
-}
-
-inline Node NodeManager::mkNode(TNode opNode, TNode child1, TNode child2,
- TNode child3, TNode child4, TNode child5) {
- NodeBuilder nb(this, operatorToKind(opNode));
- if(opNode.getKind() != kind::BUILTIN) {
- nb << opNode;
- }
- nb << child1 << child2 << child3 << child4 << child5;
- return nb.constructNode();
-}
-
// N-ary version for operators
template <bool ref_count>
inline Node NodeManager::mkNode(TNode opNode,
case kind::MULT:
case kind::NONLINEAR_MULT:
return mkRationalNode(1);
- default: Unreachable(); return {}; // silence warning
+ default: Unreachable(); return Node::null(); // silence warning
}
}
auto it = d_bounds.find(lhs);
if (it == d_bounds.end())
{
- return Bounds{};
+ return Bounds();
}
return it->second;
}
Assert(!isPreRewrite); // Likely redundant in pre-rewrite
if (node[1] > node[2]) {
- Node normal = NodeManager::currentNM()->mkNode(kind::FLOATINGPOINT_FMA,node[0],node[2],node[1],node[3]);
+ Node normal = NodeManager::currentNM()->mkNode(
+ kind::FLOATINGPOINT_FMA, {node[0], node[2], node[1], node[3]});
return RewriteResponse(REWRITE_DONE, normal);
} else {
return RewriteResponse(REWRITE_DONE, node);
sort REGEXP_TYPE \
Cardinality::INTEGERS \
well-founded \
- "NodeManager::currentNM()->mkNode(REGEXP_EMPTY, std::vector<Node>() )" \
+ "NodeManager::currentNM()->mkNode(REGEXP_EMPTY)" \
"util/string.h" \
"RegExp type"
d_regexp_opr(skc)
{
d_emptyString = NodeManager::currentNM()->mkConst(::cvc5::String(""));
- std::vector<Node> nvec;
- d_emptyRegexp = NodeManager::currentNM()->mkNode(REGEXP_EMPTY, nvec);
+ d_emptyRegexp = NodeManager::currentNM()->mkNode(REGEXP_EMPTY);
d_true = NodeManager::currentNM()->mkConst(true);
d_false = NodeManager::currentNM()->mkConst(false);
}
else if (c.getKind() == REGEXP_EMPTY)
{
// re.++( ..., empty, ... ) ---> empty
- std::vector<Node> nvec;
- Node ret = nm->mkNode(REGEXP_EMPTY, nvec);
+ Node ret = nm->mkNode(REGEXP_EMPTY);
return returnRewrite(node, ret, Rewrite::RE_CONCAT_EMPTY);
}
else
}
}
NodeManager* nm = NodeManager::currentNM();
- std::vector<Node> emptyVec;
// use inclusion tests
for (const Node& negMem : polRegExp[1])
{
Node retNode;
if (nk == REGEXP_INTER)
{
- retNode = nm->mkNode(kind::REGEXP_EMPTY, emptyVec);
+ retNode = nm->mkNode(kind::REGEXP_EMPTY);
}
else
{
- retNode = nm->mkNode(REGEXP_STAR, nm->mkNode(REGEXP_SIGMA, emptyVec));
+ retNode = nm->mkNode(REGEXP_STAR, nm->mkNode(REGEXP_SIGMA));
}
return returnRewrite(node, retNode, Rewrite::RE_ANDOR_INC_CONFLICT);
}
{
if (nk == REGEXP_INTER)
{
- retNode = nm->mkNode(REGEXP_STAR, nm->mkNode(REGEXP_SIGMA, emptyVec));
+ retNode = nm->mkNode(REGEXP_STAR, nm->mkNode(REGEXP_SIGMA));
}
else
{
- retNode = nm->mkNode(kind::REGEXP_EMPTY, emptyVec);
+ retNode = nm->mkNode(kind::REGEXP_EMPTY);
}
}
else
if (ch[0] > ch[1])
{
// re.range( "B", "A" ) ---> re.none
- std::vector<Node> emptyVec;
- Node retNode = nm->mkNode(REGEXP_EMPTY, emptyVec);
+ Node retNode = nm->mkNode(REGEXP_EMPTY);
return returnRewrite(node, retNode, Rewrite::RE_RANGE_EMPTY);
}
return node;
Assert(r.getType().isRegExp());
NodeManager* nm = NodeManager::currentNM();
- std::vector<Node> emptyVec;
- Node sigmaStar = nm->mkNode(REGEXP_STAR, nm->mkNode(REGEXP_SIGMA, emptyVec));
+ Node sigmaStar = nm->mkNode(REGEXP_STAR, nm->mkNode(REGEXP_SIGMA));
Node re = nm->mkNode(REGEXP_CONCAT, r, sigmaStar);
String s = n.getConst<String>();
// Length of the result is at most m
Node b14 = nm->mkNode(LEQ, nm->mkNode(STRING_LENGTH, skt), m);
- Node b1 = nm->mkNode(AND, b11, b12, b13, b14);
+ Node b1 = nm->mkNode(AND, {b11, b12, b13, b14});
Node b2 = skt.eqNode(emp);
Node lemma = nm->mkNode(ITE, cond, b1, b2);
nm->mkNode(ITE,
matchesEmpty,
res1,
- nm->mkNode(AND, splitX, firstMatch, k2Match, res2)),
+ nm->mkNode(AND, {splitX, firstMatch, k2Match, res2})),
k.eqNode(x)));
retNode = k;
}
Node fgx_eq_gy = d_nodeManager->mkNode(EQUAL, fgx, gy);
Node n = d_nodeManager->mkNode(
- OR, fffx_eq_x, fffx_eq_y, fx_eq_gx, x_eq_y, fgx_eq_gy);
+ OR, {fffx_eq_x, fffx_eq_y, fx_eq_gx, x_eq_y, fgx_eq_gy});
std::stringstream sstr;
sstr << Node::setdepth(-1) << Node::setlanguage(language::output::LANG_CVC);
ASSERT_EQ(n[2], z);
}
-TEST_F(TestNodeBlackNodeManager, mkNode_four_children)
+TEST_F(TestNodeBlackNodeManager, mkNode_init_list)
{
Node x1 = d_skolemManager->mkDummySkolem("x1", d_nodeManager->booleanType());
Node x2 = d_skolemManager->mkDummySkolem("x2", d_nodeManager->booleanType());
Node x3 = d_skolemManager->mkDummySkolem("x3", d_nodeManager->booleanType());
Node x4 = d_skolemManager->mkDummySkolem("x4", d_nodeManager->booleanType());
- Node n = d_nodeManager->mkNode(AND, x1, x2, x3, x4);
+ // Negate second argument to test the use of temporary nodes
+ Node n = d_nodeManager->mkNode(AND, {x1, x2.negate(), x3, x4});
ASSERT_EQ(n.getNumChildren(), 4u);
ASSERT_EQ(n.getKind(), AND);
ASSERT_EQ(n[0], x1);
- ASSERT_EQ(n[1], x2);
+ ASSERT_EQ(n[1], x2.negate());
ASSERT_EQ(n[2], x3);
ASSERT_EQ(n[3], x4);
}
-TEST_F(TestNodeBlackNodeManager, mkNode_five_children)
-{
- Node x1 = d_skolemManager->mkDummySkolem("x1", d_nodeManager->booleanType());
- Node x2 = d_skolemManager->mkDummySkolem("x2", d_nodeManager->booleanType());
- Node x3 = d_skolemManager->mkDummySkolem("x3", d_nodeManager->booleanType());
- Node x4 = d_skolemManager->mkDummySkolem("x4", d_nodeManager->booleanType());
- Node x5 = d_skolemManager->mkDummySkolem("x5", d_nodeManager->booleanType());
- Node n = d_nodeManager->mkNode(AND, x1, x2, x3, x4, x5);
- ASSERT_EQ(n.getNumChildren(), 5u);
- ASSERT_EQ(n.getKind(), AND);
- ASSERT_EQ(n[0], x1);
- ASSERT_EQ(n[1], x2);
- ASSERT_EQ(n[2], x3);
- ASSERT_EQ(n[3], x4);
- ASSERT_EQ(n[4], x5);
-}
-
TEST_F(TestNodeBlackNodeManager, mkNode_vector_of_node)
{
Node x1 = d_skolemManager->mkDummySkolem("x1", d_nodeManager->booleanType());
TEST_F(TestTheoryBlackRegexpOperation, basic)
{
- Node sigma = d_nodeManager->mkNode(REGEXP_SIGMA, std::vector<Node>{});
+ Node sigma = d_nodeManager->mkNode(REGEXP_SIGMA);
Node sigmaStar = d_nodeManager->mkNode(REGEXP_STAR, sigma);
Node a = d_nodeManager->mkNode(STRING_TO_REGEXP,
d_nodeManager->mkConst(String("a")));
TEST_F(TestTheoryBlackRegexpOperation, star_wildcards)
{
- Node sigma = d_nodeManager->mkNode(REGEXP_SIGMA, std::vector<Node>{});
+ Node sigma = d_nodeManager->mkNode(REGEXP_SIGMA);
Node sigmaStar = d_nodeManager->mkNode(REGEXP_STAR, sigma);
Node a = d_nodeManager->mkNode(STRING_TO_REGEXP,
d_nodeManager->mkConst(String("a")));
Node _abc_ = d_nodeManager->mkNode(REGEXP_CONCAT, sigmaStar, abc, sigmaStar);
Node _asc_ =
- d_nodeManager->mkNode(REGEXP_CONCAT, sigmaStar, a, sigma, c, sigmaStar);
+ d_nodeManager->mkNode(REGEXP_CONCAT, {sigmaStar, a, sigma, c, sigmaStar});
Node _sc_ = Rewriter::rewrite(
- d_nodeManager->mkNode(REGEXP_CONCAT, sigmaStar, sigma, c, sigmaStar));
+ d_nodeManager->mkNode(REGEXP_CONCAT, {sigmaStar, sigma, c, sigmaStar}));
Node _as_ = Rewriter::rewrite(
- d_nodeManager->mkNode(REGEXP_CONCAT, sigmaStar, a, sigma, sigmaStar));
+ d_nodeManager->mkNode(REGEXP_CONCAT, {sigmaStar, a, sigma, sigmaStar}));
Node _assc_ = d_nodeManager->mkNode(
REGEXP_CONCAT,
std::vector<Node>{sigmaStar, a, sigma, sigma, c, sigmaStar});
Node _csa_ =
- d_nodeManager->mkNode(REGEXP_CONCAT, sigmaStar, c, sigma, a, sigmaStar);
- Node _c_a_ = d_nodeManager->mkNode(
- REGEXP_CONCAT, sigmaStar, c, sigmaStar, a, sigmaStar);
+ d_nodeManager->mkNode(REGEXP_CONCAT, {sigmaStar, c, sigma, a, sigmaStar});
+ Node _c_a_ = d_nodeManager->mkNode(REGEXP_CONCAT,
+ {sigmaStar, c, sigmaStar, a, sigmaStar});
Node _s_s_ = Rewriter::rewrite(d_nodeManager->mkNode(
- REGEXP_CONCAT, sigmaStar, sigma, sigmaStar, sigma, sigmaStar));
+ REGEXP_CONCAT, {sigmaStar, sigma, sigmaStar, sigma, sigmaStar}));
Node _a_abc_ = Rewriter::rewrite(d_nodeManager->mkNode(
- REGEXP_CONCAT, sigmaStar, a, sigmaStar, abc, sigmaStar));
+ REGEXP_CONCAT, {sigmaStar, a, sigmaStar, abc, sigmaStar}));
includes(_asc_, _abc_);
doesNotInclude(_abc_, _asc_);
// (str.substr y 0 3))
Node z = d_nodeManager->mkNode(kind::STRING_SUBSTR, y, zero, three);
Node repl_e_x_z = d_nodeManager->mkNode(kind::STRING_STRREPL, empty, x, z);
- repl_a = d_nodeManager->mkNode(kind::STRING_CONCAT, y, repl_e_x_z, z, a, z);
- a_repl = d_nodeManager->mkNode(kind::STRING_CONCAT, y, z, repl_e_x_z, a, z);
+ repl_a = d_nodeManager->mkNode(kind::STRING_CONCAT, {y, repl_e_x_z, z, a, z});
+ a_repl = d_nodeManager->mkNode(kind::STRING_CONCAT, {y, z, repl_e_x_z, a, z});
sameNormalForm(repl_a, a_repl);
// Same normal form for:
d_nodeManager->mkNode(kind::STRING_CONCAT, x, x));
Node concat2 = d_nodeManager->mkNode(
kind::STRING_CONCAT,
- gh,
- x,
- d_nodeManager->mkNode(kind::STRING_STRREPL, x, gh, ij),
- ij);
+ {gh, x, d_nodeManager->mkNode(kind::STRING_STRREPL, x, gh, ij), ij});
Node res_concat1 = SequencesRewriter::lengthPreserveRewrite(concat1);
Node res_concat2 = SequencesRewriter::lengthPreserveRewrite(concat2);
ASSERT_EQ(res_concat1, res_concat2);
// (+ 2 (str.indexof (str.++ "A" x y) "A" 0))
Node lhs = d_nodeManager->mkNode(
kind::STRING_STRIDOF,
- d_nodeManager->mkNode(kind::STRING_CONCAT, b, c, a, x, y),
+ d_nodeManager->mkNode(kind::STRING_CONCAT, {b, c, a, x, y}),
a,
zero);
Node rhs = d_nodeManager->mkNode(
Node cat = d_nodeManager->mkNode(kind::STRING_CHARAT, x, n);
lhs = d_nodeManager->mkNode(kind::STRING_STRCTN, abc, cat);
rhs = d_nodeManager->mkNode(kind::OR,
- d_nodeManager->mkNode(kind::EQUAL, cat, empty),
- d_nodeManager->mkNode(kind::EQUAL, cat, a),
- d_nodeManager->mkNode(kind::EQUAL, cat, b),
- d_nodeManager->mkNode(kind::EQUAL, cat, c));
+ {d_nodeManager->mkNode(kind::EQUAL, cat, empty),
+ d_nodeManager->mkNode(kind::EQUAL, cat, a),
+ d_nodeManager->mkNode(kind::EQUAL, cat, b),
+ d_nodeManager->mkNode(kind::EQUAL, cat, c)});
sameNormalForm(lhs, rhs);
}
}
sameNormalForm(StringsEntail::inferEqsFromContains(empty, xy), empty_x_y);
// inferEqsFromContains(x, (str.++ x y)) returns false
- Node bxya = d_nodeManager->mkNode(kind::STRING_CONCAT, b, y, x, a);
+ Node bxya = d_nodeManager->mkNode(kind::STRING_CONCAT, {b, y, x, a});
sameNormalForm(StringsEntail::inferEqsFromContains(x, bxya), f);
// inferEqsFromContains(x, y) returns null
// (= (str.++ y w) (str.++ "A" z)))
Node lhs = d_nodeManager->mkNode(
kind::EQUAL,
- d_nodeManager->mkNode(kind::STRING_CONCAT, b, xrepl, z, y, w),
- d_nodeManager->mkNode(kind::STRING_CONCAT, z, x, ba, z));
+ d_nodeManager->mkNode(kind::STRING_CONCAT, {b, xrepl, z, y, w}),
+ d_nodeManager->mkNode(kind::STRING_CONCAT, {z, x, ba, z}));
Node rhs = d_nodeManager->mkNode(
kind::AND,
d_nodeManager->mkNode(
Node lhs = d_nodeManager->mkNode(
kind::STRING_IN_REGEXP,
x,
- d_nodeManager->mkNode(
- kind::REGEXP_CONCAT, sig_star, sig_star, re_abc, sig_star));
+ d_nodeManager->mkNode(kind::REGEXP_CONCAT,
+ {sig_star, sig_star, re_abc, sig_star}));
Node rhs = d_nodeManager->mkNode(kind::STRING_STRCTN, x, abc);
sameNormalForm(lhs, rhs);
}
out = d_nodeManager->mkNode(kind::OR, d_a, d_d, d_b);
test_nodes_equal(out, BooleanSimplification::simplifyClause(in));
- in = d_nodeManager->mkNode(kind::OR,
- d_fa,
- d_ga.orNode(d_c).notNode(),
- d_hfc,
- d_ac,
- d_d.andNode(d_b));
+ in = d_nodeManager->mkNode(
+ kind::OR,
+ {d_fa, d_ga.orNode(d_c).notNode(), d_hfc, d_ac, d_d.andNode(d_b)});
out = NodeBuilder(kind::OR) << d_fa << d_ga.orNode(d_c).notNode() << d_hfc
<< d_ac << d_d.andNode(d_b);
test_nodes_equal(out, BooleanSimplification::simplifyClause(in));
- in = d_nodeManager->mkNode(kind::OR,
- d_fa,
- d_ga.andNode(d_c).notNode(),
- d_hfc,
- d_ac,
- d_d.andNode(d_b));
+ in = d_nodeManager->mkNode(
+ kind::OR,
+ {d_fa, d_ga.andNode(d_c).notNode(), d_hfc, d_ac, d_d.andNode(d_b)});
out = NodeBuilder(kind::OR) << d_fa << d_ga.notNode() << d_c.notNode()
<< d_hfc << d_ac << d_d.andNode(d_b);
test_nodes_equal(out, BooleanSimplification::simplifyClause(in));
out = d_nodeManager->mkNode(kind::OR, d_a, d_ac.andNode(d_b));
test_nodes_equal(out, BooleanSimplification::simplifyHornClause(in));
- in =
- d_a.andNode(d_b).impNode(d_nodeManager->mkNode(kind::AND,
- d_fa,
- d_ga.orNode(d_c).notNode(),
- d_hfc.orNode(d_ac),
- d_d.andNode(d_b)));
+ in = d_a.andNode(d_b).impNode(
+ d_nodeManager->mkNode(kind::AND,
+ {d_fa,
+ d_ga.orNode(d_c).notNode(),
+ d_hfc.orNode(d_ac),
+ d_d.andNode(d_b)}));
out = d_nodeManager->mkNode(kind::OR,
d_a.notNode(),
d_b.notNode(),
d_nodeManager->mkNode(kind::AND,
- d_fa,
- d_ga.orNode(d_c).notNode(),
- d_hfc.orNode(d_ac),
- d_d.andNode(d_b)));
+ {d_fa,
+ d_ga.orNode(d_c).notNode(),
+ d_hfc.orNode(d_ac),
+ d_d.andNode(d_b)}));
test_nodes_equal(out, BooleanSimplification::simplifyHornClause(in));
in = d_a.andNode(d_b).impNode(
d_nodeManager->mkNode(kind::OR,
- d_fa,
- d_ga.orNode(d_c).notNode(),
- d_hfc.orNode(d_ac),
- d_d.andNode(d_b).notNode()));
+ {d_fa,
+ d_ga.orNode(d_c).notNode(),
+ d_hfc.orNode(d_ac),
+ d_d.andNode(d_b).notNode()}));
out = NodeBuilder(kind::OR)
<< d_a.notNode() << d_b.notNode() << d_fa << d_ga.orNode(d_c).notNode()
<< d_hfc << d_ac << d_d.notNode();
test_nodes_equal(out, BooleanSimplification::simplifyConflict(in));
in = d_nodeManager->mkNode(kind::AND,
- d_fa,
- d_ga.orNode(d_c).notNode(),
- d_fa,
- d_hfc.orNode(d_ac),
- d_d.andNode(d_b));
+ {d_fa,
+ d_ga.orNode(d_c).notNode(),
+ d_fa,
+ d_hfc.orNode(d_ac),
+ d_d.andNode(d_b)});
out = NodeBuilder(kind::AND) << d_fa << d_ga.notNode() << d_c.notNode()
<< d_hfc.orNode(d_ac) << d_d << d_b;
test_nodes_equal(out, BooleanSimplification::simplifyConflict(in));