summaryrefslogtreecommitdiff
path: root/test/unit/node/node_algorithm_black.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit/node/node_algorithm_black.cpp')
-rw-r--r--test/unit/node/node_algorithm_black.cpp202
1 files changed, 202 insertions, 0 deletions
diff --git a/test/unit/node/node_algorithm_black.cpp b/test/unit/node/node_algorithm_black.cpp
new file mode 100644
index 000000000..bd243e0fd
--- /dev/null
+++ b/test/unit/node/node_algorithm_black.cpp
@@ -0,0 +1,202 @@
+/********************* */
+/*! \file node_algorithm_black.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Aina Niemetz, Yoni Zohar, Abdalrhman Mohamed
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ ** in the top-level source directory and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Black box testing of utility functions in node_algorithm.{h,cpp}
+ **
+ ** Black box testing of node_algorithm.{h,cpp}
+ **/
+
+#include <string>
+#include <vector>
+
+#include "base/output.h"
+#include "expr/node_algorithm.h"
+#include "expr/node_manager.h"
+#include "test_node.h"
+#include "theory/bv/theory_bv_utils.h"
+#include "util/integer.h"
+#include "util/rational.h"
+
+namespace CVC4 {
+
+using namespace expr;
+using namespace kind;
+
+namespace test {
+
+class TestNodeBlackNodeAlgorithm : public TestNode
+{
+};
+
+TEST_F(TestNodeBlackNodeAlgorithm, get_symbols1)
+{
+ // The only symbol in ~x (x is a boolean varible) should be x
+ Node x = d_nodeManager->mkSkolem("x", d_nodeManager->booleanType());
+ Node n = d_nodeManager->mkNode(NOT, x);
+ std::unordered_set<Node, NodeHashFunction> syms;
+ getSymbols(n, syms);
+ ASSERT_EQ(syms.size(), 1);
+ ASSERT_NE(syms.find(x), syms.end());
+}
+
+TEST_F(TestNodeBlackNodeAlgorithm, get_symbols2)
+{
+ // the only symbols in x=y ^ (exists var. var+var = x) are x and y, because
+ // "var" is bound.
+
+ // left conjunct
+ Node x = d_nodeManager->mkSkolem("x", d_nodeManager->integerType());
+ Node y = d_nodeManager->mkSkolem("y", d_nodeManager->integerType());
+ Node left = d_nodeManager->mkNode(EQUAL, x, y);
+
+ // right conjunct
+ Node var = d_nodeManager->mkBoundVar(*d_intTypeNode);
+ std::vector<Node> vars;
+ vars.push_back(var);
+ Node sum = d_nodeManager->mkNode(PLUS, var, var);
+ Node qeq = d_nodeManager->mkNode(EQUAL, x, sum);
+ Node bvl = d_nodeManager->mkNode(BOUND_VAR_LIST, vars);
+ Node right = d_nodeManager->mkNode(EXISTS, bvl, qeq);
+
+ // conjunction
+ Node res = d_nodeManager->mkNode(AND, left, right);
+
+ // symbols
+ std::unordered_set<Node, NodeHashFunction> syms;
+ getSymbols(res, syms);
+
+ // assertions
+ ASSERT_EQ(syms.size(), 2);
+ ASSERT_NE(syms.find(x), syms.end());
+ ASSERT_NE(syms.find(y), syms.end());
+ ASSERT_EQ(syms.find(var), syms.end());
+}
+
+TEST_F(TestNodeBlackNodeAlgorithm, get_operators_map)
+{
+ // map to store result
+ std::map<TypeNode, std::unordered_set<Node, NodeHashFunction> > result =
+ std::map<TypeNode, std::unordered_set<Node, NodeHashFunction> >();
+
+ // create test formula
+ Node x = d_nodeManager->mkSkolem("x", d_nodeManager->integerType());
+ Node plus = d_nodeManager->mkNode(PLUS, x, x);
+ Node mul = d_nodeManager->mkNode(MULT, x, x);
+ Node eq1 = d_nodeManager->mkNode(EQUAL, plus, mul);
+
+ Node y = d_nodeManager->mkSkolem("y", d_nodeManager->mkBitVectorType(4));
+ Node ext1 = theory::bv::utils::mkExtract(y, 1, 0);
+ Node ext2 = theory::bv::utils::mkExtract(y, 3, 2);
+ Node eq2 = d_nodeManager->mkNode(EQUAL, ext1, ext2);
+
+ Node formula = d_nodeManager->mkNode(AND, eq1, eq2);
+
+ // call function
+ expr::getOperatorsMap(formula, result);
+
+ // Verify result
+ // We should have only integer, bv and boolean as types
+ ASSERT_EQ(result.size(), 3);
+ ASSERT_NE(result.find(*d_intTypeNode), result.end());
+ ASSERT_NE(result.find(*d_boolTypeNode), result.end());
+ ASSERT_NE(result.find(*d_bvTypeNode), result.end());
+
+ // in integers, we should only have plus and mult as operators
+ ASSERT_EQ(result[*d_intTypeNode].size(), 2);
+ ASSERT_NE(result[*d_intTypeNode].find(d_nodeManager->operatorOf(PLUS)),
+ result[*d_intTypeNode].end());
+ ASSERT_NE(result[*d_intTypeNode].find(d_nodeManager->operatorOf(MULT)),
+ result[*d_intTypeNode].end());
+
+ // in booleans, we should only have "=" and "and" as an operator.
+ ASSERT_EQ(result[*d_boolTypeNode].size(), 2);
+ ASSERT_NE(result[*d_boolTypeNode].find(d_nodeManager->operatorOf(EQUAL)),
+ result[*d_boolTypeNode].end());
+ ASSERT_NE(result[*d_boolTypeNode].find(d_nodeManager->operatorOf(AND)),
+ result[*d_boolTypeNode].end());
+
+ // in bv, we should only have "extract" as an operator.
+ ASSERT_EQ(result[*d_boolTypeNode].size(), 2);
+ Node extractOp1 =
+ d_nodeManager->mkConst<BitVectorExtract>(BitVectorExtract(1, 0));
+ Node extractOp2 =
+ d_nodeManager->mkConst<BitVectorExtract>(BitVectorExtract(3, 2));
+ ASSERT_NE(result[*d_bvTypeNode].find(extractOp1),
+ result[*d_bvTypeNode].end());
+ ASSERT_NE(result[*d_bvTypeNode].find(extractOp2),
+ result[*d_bvTypeNode].end());
+}
+
+TEST_F(TestNodeBlackNodeAlgorithm, match)
+{
+ TypeNode integer = d_nodeManager->integerType();
+
+ Node one = d_nodeManager->mkConst(Rational(1));
+ Node two = d_nodeManager->mkConst(Rational(2));
+
+ Node x = d_nodeManager->mkBoundVar(integer);
+ Node a = d_nodeManager->mkSkolem("a", integer);
+
+ Node n1 = d_nodeManager->mkNode(MULT, two, x);
+ std::unordered_map<Node, Node, NodeHashFunction> subs;
+
+ // check reflexivity
+ ASSERT_TRUE(match(n1, n1, subs));
+ ASSERT_EQ(subs.size(), 0);
+
+ Node n2 = d_nodeManager->mkNode(MULT, two, a);
+ subs.clear();
+
+ // check instance
+ ASSERT_TRUE(match(n1, n2, subs));
+ ASSERT_EQ(subs.size(), 1);
+ ASSERT_EQ(subs[x], a);
+
+ // should return false for flipped arguments (match is not symmetric)
+ ASSERT_FALSE(match(n2, n1, subs));
+
+ n2 = d_nodeManager->mkNode(MULT, one, a);
+
+ // should return false since n2 is not an instance of n1
+ ASSERT_FALSE(match(n1, n2, subs));
+
+ n2 = d_nodeManager->mkNode(NONLINEAR_MULT, two, a);
+
+ // should return false for similar operators
+ ASSERT_FALSE(match(n1, n2, subs));
+
+ n2 = d_nodeManager->mkNode(MULT, two, a, one);
+
+ // should return false for different number of arguments
+ ASSERT_FALSE(match(n1, n2, subs));
+
+ n1 = x;
+ n2 = d_nodeManager->mkConst(true);
+
+ // should return false for different types
+ ASSERT_FALSE(match(n1, n2, subs));
+
+ n1 = d_nodeManager->mkNode(MULT, x, x);
+ n2 = d_nodeManager->mkNode(MULT, two, a);
+
+ // should return false for contradictory substitutions
+ ASSERT_FALSE(match(n1, n2, subs));
+
+ n2 = d_nodeManager->mkNode(MULT, a, a);
+ subs.clear();
+
+ // implementation: check if the cache works correctly
+ ASSERT_TRUE(match(n1, n2, subs));
+ ASSERT_EQ(subs.size(), 1);
+ ASSERT_EQ(subs[x], a);
+}
+} // namespace test
+} // namespace CVC4
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback