Belle II Software  release-08-01-10
cutNodes.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include <functional>
9 #include <iostream>
10 #include <cmath>
11 #include <boost/python.hpp>
12 #include <framework/utilities/CutNodes.h>
13 #include <framework/utilities/TestHelpers.h>
14 #include <analysis/VariableManager/Manager.h>
15 #include <framework/utilities/Conversion.h>
16 #include <gtest/gtest.h>
17 
18 
19 using namespace Belle2;
20 namespace {
21  namespace py = boost::python;
22  using VarVariant = Belle2::Variable::Manager::VarVariant;
24  struct MockObjectType {
26  explicit MockObjectType(const double& d) : m_value{d} {}
27  explicit MockObjectType(const int& i) : m_value{i} {}
28  explicit MockObjectType(const bool& b) : m_value{b} {}
29  VarVariant m_value;
30  };
32  std::function<VarVariant(const MockObjectType*)> mockMetaVariable(const std::vector<std::string>& arguments);
33 
39  class MockVariableType {
40  public:
42  VarVariant function(const MockObjectType* object) const
43  {
44  return m_function(object);
45  }
46  explicit MockVariableType(const std::string& name) : m_name{name}
47  {
48  m_function = [](const MockObjectType * object) -> VarVariant {
49  if (object != nullptr)
50  {
51  return object->m_value;
52  } else
53  {
54  return std::numeric_limits<double>::quiet_NaN();
55  }
56  };
57  }
58 
59  MockVariableType(const std::string& name, std::function<VarVariant(const MockObjectType*)> function) : m_name{name}, m_function{function}
60  {}
61 
63  std::string m_name;
64  std::function<VarVariant(const MockObjectType*)> m_function;
65  };
66 
71  class MockVariableManager {
72  public:
74  using Object = MockObjectType;
76  using Var = MockVariableType;
78  using VarVariant = Belle2::Variable::Manager::VarVariant;
79 
81  static MockVariableManager& Instance()
82  {
83  static MockVariableManager instance;
84  return instance;
85  }
86 
88  Var* getVariable(const std::string& name)
89  {
90  if (name == "mocking_variable") {
91  return &m_mocking_variable;
92  } else {
93  return nullptr;
94  }
95  }
96 
97  Var* getVariable(const std::string& functionName, const std::vector<std::string>& functionArguments)
98  {
99  auto function = mockMetaVariable(functionArguments);
100  m_mocking_metavariable = MockVariableType(functionName, function);
101  return &m_mocking_metavariable;
102  }
103 
105  Var m_mocking_variable{"mocking_variable"};
106  Var m_mocking_metavariable{""};
107  };
108 
109 
110 // Mock sum metavariable
111  std::function<VarVariant(const MockObjectType*)> mockMetaVariable(const std::vector<std::string>& arguments)
112  {
113  const MockVariableType* var = MockVariableManager::Instance().getVariable(arguments[0]);
114  if (var == nullptr) {
115  throw std::runtime_error("Variable could not be found.");
116  }
117  auto func = [var, arguments](const MockObjectType * object) -> VarVariant {
118  double sum = 0.0;
119  if (std::holds_alternative<int>(var->function(object)))
120  {
121  sum += std::get<int>(var->function(object));
122  } else if (std::holds_alternative<double>(var->function(object)))
123  {
124  sum += std::get<double>(var->function(object));
125  } else
126  {
127  sum += std::get<bool>(var->function(object));
128  }
129  for (size_t i = 1; i < arguments.size(); i++)
130  {
131  sum += Belle2::convertString<double>(arguments[i]);
132  }
133  return sum;
134  };
135  return func;
136  }
137 
141  TEST(CutNodesTest, TupleLength)
142  {
143  Py_Initialize();
144  py::tuple tuple = py::tuple();
145  EXPECT_B2FATAL(NodeFactory::compile_boolean_node<MockVariableManager>(tuple));
146  EXPECT_B2FATAL(NodeFactory::compile_expression_node<MockVariableManager>(tuple));
147 
148  tuple = py::make_tuple(static_cast<int>(NodeType::UnaryBooleanNode));
149  EXPECT_B2FATAL(NodeFactory::compile_boolean_node<MockVariableManager>(tuple));
150 
151  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryBooleanNode));
152  EXPECT_B2FATAL(NodeFactory::compile_boolean_node<MockVariableManager>(tuple));
153 
154  tuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode));
155  EXPECT_B2FATAL(NodeFactory::compile_boolean_node<MockVariableManager>(tuple));
156 
157  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode));
158  EXPECT_B2FATAL(NodeFactory::compile_boolean_node<MockVariableManager>(tuple));
159 
160  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode));
161  EXPECT_B2FATAL(NodeFactory::compile_boolean_node<MockVariableManager>(tuple));
162 
163  tuple = py::make_tuple(static_cast<int>(NodeType::UnaryExpressionNode));
164  EXPECT_B2FATAL(NodeFactory::compile_expression_node<MockVariableManager>(tuple));
165 
166  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode));
167  EXPECT_B2FATAL(NodeFactory::compile_expression_node<MockVariableManager>(tuple));
168 
169  tuple = py::make_tuple(static_cast<int>(NodeType::BooleanNode));
170  EXPECT_B2FATAL(NodeFactory::compile_expression_node<MockVariableManager>(tuple));
171 
172  tuple = py::make_tuple(static_cast<int>(NodeType::IntegerNode));
173  EXPECT_B2FATAL(NodeFactory::compile_expression_node<MockVariableManager>(tuple));
174 
175  tuple = py::make_tuple(static_cast<int>(NodeType::DoubleNode));
176  EXPECT_B2FATAL(NodeFactory::compile_expression_node<MockVariableManager>(tuple));
177 
178  tuple = py::make_tuple(static_cast<int>(NodeType::IdentifierNode));
179  EXPECT_B2FATAL(NodeFactory::compile_expression_node<MockVariableManager>(tuple));
180 
181  tuple = py::make_tuple(static_cast<int>(NodeType::FunctionNode));
182  EXPECT_B2FATAL(NodeFactory::compile_expression_node<MockVariableManager>(tuple));
183 
184  }
185 
186 
188  TEST(CutNodesTest, unaryBooleanNode)
189  {
190  Py_Initialize();
191  // Create two BooleanNode tuples with values true and false.
192  const py::tuple booleanTuple_true = py::make_tuple(static_cast<int>(NodeType::BooleanNode), true);
193  const py::tuple booleanTuple_false = py::make_tuple(static_cast<int>(NodeType::BooleanNode), false);
194  // Compile BooleanNodes and check evaluation
195  auto booleanNode_true = NodeFactory::compile_expression_node<MockVariableManager>(booleanTuple_true);
196  auto booleanNode_false = NodeFactory::compile_expression_node<MockVariableManager>(booleanTuple_false);
197  EXPECT_TRUE(std::get<bool>(booleanNode_true->evaluate(nullptr)));
198  EXPECT_FALSE(std::get<bool>(booleanNode_false->evaluate(nullptr)));
199 
200  // Create two UnaryRelationalNodes tuples with each BooleanNode tuple as child.
201  const py::tuple uRelTuple_true = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), booleanTuple_true);
202  const py::tuple uRelTuple_false = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), booleanTuple_false);
203  // Compile UnaryExpressionNodes and check evaluation
204  auto uRelNode_true = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple_true);
205  auto uRelNode_false = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple_false);
206  EXPECT_TRUE(uRelNode_true->check(nullptr));
207  EXPECT_FALSE(uRelNode_false->check(nullptr));
208 
209  // Create all tuple combinations of true/false children and flags
210  // True child
211  const py::tuple uBoolTuple_true = py::make_tuple(static_cast<int>(NodeType::UnaryBooleanNode), uRelTuple_true, false, false);
212  const py::tuple uBoolTuple_true_brack = py::make_tuple(static_cast<int>(NodeType::UnaryBooleanNode), uRelTuple_true, false, true);
213  const py::tuple uBoolTuple_true_neg = py::make_tuple(static_cast<int>(NodeType::UnaryBooleanNode), uRelTuple_true, true, false);
214  const py::tuple uBoolTuple_true_neg_brack = py::make_tuple(static_cast<int>(NodeType::UnaryBooleanNode), uRelTuple_true, true,
215  true);
216 
217  auto uBoolNode_true = NodeFactory::compile_boolean_node<MockVariableManager>(uBoolTuple_true);
218  EXPECT_TRUE(uBoolNode_true->check(nullptr));
219  EXPECT_EQ(uBoolNode_true->decompile(), "true");
220 
221  auto uBoolNode_true_brack = NodeFactory::compile_boolean_node<MockVariableManager>(uBoolTuple_true_brack);
222  EXPECT_TRUE(uBoolNode_true_brack->check(nullptr));
223  EXPECT_EQ(uBoolNode_true_brack->decompile(), "[true]");
224 
225  auto uBoolNode_true_neg = NodeFactory::compile_boolean_node<MockVariableManager>(uBoolTuple_true_neg);
226  EXPECT_FALSE(uBoolNode_true_neg->check(nullptr));
227  EXPECT_EQ(uBoolNode_true_neg->decompile(), "not true");
228 
229  auto uBoolNode_true_neg_brack = NodeFactory::compile_boolean_node<MockVariableManager>(uBoolTuple_true_neg_brack);
230  EXPECT_FALSE(uBoolNode_true_neg_brack->check(nullptr));
231  EXPECT_EQ(uBoolNode_true_neg_brack->decompile(), "not [true]");
232 
233  // False child
234  const py::tuple uBoolTuple_false = py::make_tuple(static_cast<int>(NodeType::UnaryBooleanNode), uRelTuple_false, false, false);
235  const py::tuple uBoolTuple_false_brack = py::make_tuple(static_cast<int>(NodeType::UnaryBooleanNode), uRelTuple_false, false, true);
236  const py::tuple uBoolTuple_false_neg = py::make_tuple(static_cast<int>(NodeType::UnaryBooleanNode), uRelTuple_false, true, false);
237  const py::tuple uBoolTuple_false_neg_brack = py::make_tuple(static_cast<int>(NodeType::UnaryBooleanNode), uRelTuple_false, true,
238  true);
239 
240  auto uBoolNode_false = NodeFactory::compile_boolean_node<MockVariableManager>(uBoolTuple_false);
241  EXPECT_FALSE(uBoolNode_false->check(nullptr));
242  EXPECT_EQ(uBoolNode_false->decompile(), "false");
243 
244  auto uBoolNode_false_brack = NodeFactory::compile_boolean_node<MockVariableManager>(uBoolTuple_false_brack);
245  EXPECT_FALSE(uBoolNode_false_brack->check(nullptr));
246  EXPECT_EQ(uBoolNode_false_brack->decompile(), "[false]");
247 
248  auto uBoolNode_false_neg = NodeFactory::compile_boolean_node<MockVariableManager>(uBoolTuple_false_neg);
249  EXPECT_TRUE(uBoolNode_false_neg->check(nullptr));
250  EXPECT_EQ(uBoolNode_false_neg->decompile(), "not false");
251 
252  auto uBoolNode_false_neg_brack = NodeFactory::compile_boolean_node<MockVariableManager>(uBoolTuple_false_neg_brack);
253  EXPECT_TRUE(uBoolNode_false_neg_brack->check(nullptr));
254  EXPECT_EQ(uBoolNode_false_neg_brack->decompile(), "not [false]");
255 
256  }
258  TEST(CutNodesTest, binaryBooleanNode)
259  {
260  // Create two BooleanNode tuples with values true and false.
261  const py::tuple booleanTuple_true = py::make_tuple(static_cast<int>(NodeType::BooleanNode), true);
262  const py::tuple booleanTuple_false = py::make_tuple(static_cast<int>(NodeType::BooleanNode), false);
263 
264  // Create two UnaryRelationalNodes tuples with each BooleanNode tuple as child.
265  const py::tuple uRelTuple_true = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), booleanTuple_true);
266  const py::tuple uRelTuple_false = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), booleanTuple_false);
267 
268  // Create all tuple combinations of children and BooleanOperators
269  const py::tuple binBoolTuple_AND_true_true = py::make_tuple(static_cast<int>(NodeType::BinaryBooleanNode), uRelTuple_true,
270  uRelTuple_true, static_cast<int>(BooleanOperator::AND));
271  const py::tuple binBoolTuple_AND_false_true = py::make_tuple(static_cast<int>(NodeType::BinaryBooleanNode), uRelTuple_false,
272  uRelTuple_true, static_cast<int>(BooleanOperator::AND));
273  const py::tuple binBoolTuple_AND_true_false = py::make_tuple(static_cast<int>(NodeType::BinaryBooleanNode), uRelTuple_true,
274  uRelTuple_false, static_cast<int>(BooleanOperator::AND));
275  const py::tuple binBoolTuple_AND_false_false = py::make_tuple(static_cast<int>(NodeType::BinaryBooleanNode), uRelTuple_false,
276  uRelTuple_false, static_cast<int>(BooleanOperator::AND));
277 
278  const py::tuple binBoolTuple_OR_true_true = py::make_tuple(static_cast<int>(NodeType::BinaryBooleanNode), uRelTuple_true,
279  uRelTuple_true, static_cast<int>(BooleanOperator::OR));
280  const py::tuple binBoolTuple_OR_false_true = py::make_tuple(static_cast<int>(NodeType::BinaryBooleanNode), uRelTuple_false,
281  uRelTuple_true, static_cast<int>(BooleanOperator::OR));
282  const py::tuple binBoolTuple_OR_true_false = py::make_tuple(static_cast<int>(NodeType::BinaryBooleanNode), uRelTuple_true,
283  uRelTuple_false, static_cast<int>(BooleanOperator::OR));
284  const py::tuple binBoolTuple_OR_false_false = py::make_tuple(static_cast<int>(NodeType::BinaryBooleanNode), uRelTuple_false,
285  uRelTuple_false, static_cast<int>(BooleanOperator::OR));
286 
287 
288  auto binBoolNode_AND_true_true = NodeFactory::compile_boolean_node<MockVariableManager>(binBoolTuple_AND_true_true);
289  auto binBoolNode_AND_false_true = NodeFactory::compile_boolean_node<MockVariableManager>(binBoolTuple_AND_false_true);
290  auto binBoolNode_AND_true_false = NodeFactory::compile_boolean_node<MockVariableManager>(binBoolTuple_AND_true_false);
291  auto binBoolNode_AND_false_false = NodeFactory::compile_boolean_node<MockVariableManager>(binBoolTuple_AND_false_false);
292 
293  auto binBoolNode_OR_true_true = NodeFactory::compile_boolean_node<MockVariableManager>(binBoolTuple_OR_true_true);
294  auto binBoolNode_OR_false_true = NodeFactory::compile_boolean_node<MockVariableManager>(binBoolTuple_OR_false_true);
295  auto binBoolNode_OR_true_false = NodeFactory::compile_boolean_node<MockVariableManager>(binBoolTuple_OR_true_false);
296  auto binBoolNode_OR_false_false = NodeFactory::compile_boolean_node<MockVariableManager>(binBoolTuple_OR_false_false);
297 
298  EXPECT_TRUE(binBoolNode_AND_true_true->check(nullptr));
299  EXPECT_FALSE(binBoolNode_AND_false_true->check(nullptr));
300  EXPECT_FALSE(binBoolNode_AND_true_false->check(nullptr));
301  EXPECT_FALSE(binBoolNode_AND_false_false->check(nullptr));
302 
303  EXPECT_TRUE(binBoolNode_OR_true_true->check(nullptr));
304  EXPECT_TRUE(binBoolNode_OR_false_true->check(nullptr));
305  EXPECT_TRUE(binBoolNode_OR_true_false->check(nullptr));
306  EXPECT_FALSE(binBoolNode_OR_false_false->check(nullptr));
307 
308  }
310  TEST(CutNodesTest, unaryRelationalNode)
311  {
312  Py_Initialize();
313  // Get main module
314  py::object main = py::import("__main__");
315  py::object pyfloat = main.attr("__builtins__").attr("float");
316 
317  // Test IntegerNode
318  py::tuple tuple = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 1337);
319  py::tuple uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
320  auto node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
321  EXPECT_TRUE(node->check(nullptr));
322 
323  tuple = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 0);
324  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
325  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
326  EXPECT_FALSE(node->check(nullptr));
327 
328  tuple = py::make_tuple(static_cast<int>(NodeType::IntegerNode), -0);
329  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
330  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
331  EXPECT_FALSE(node->check(nullptr));
332 
333  tuple = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 1);
334  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
335  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
336  EXPECT_TRUE(node->check(nullptr));
337 
338  tuple = py::make_tuple(static_cast<int>(NodeType::IntegerNode), -1);
339  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
340  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
341  EXPECT_TRUE(node->check(nullptr));
342 
343  // Test DoubleNode
344  tuple = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 0.0);
345  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
346  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
347  EXPECT_FALSE(node->check(nullptr));
348 
349  tuple = py::make_tuple(static_cast<int>(NodeType::DoubleNode), -0.0);
350  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
351  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
352  EXPECT_FALSE(node->check(nullptr));
353 
354  tuple = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 1.0);
355  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
356  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
357  EXPECT_TRUE(node->check(nullptr));
358 
359  tuple = py::make_tuple(static_cast<int>(NodeType::DoubleNode), -1.0);
360  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
361  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
362  EXPECT_TRUE(node->check(nullptr));
363 
364  tuple = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 1.1);
365  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
366  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
367  EXPECT_TRUE(node->check(nullptr));
368 
369  tuple = py::make_tuple(static_cast<int>(NodeType::DoubleNode), -1.1);
370  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
371  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
372  EXPECT_TRUE(node->check(nullptr));
373 
374  tuple = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("nan"));
375  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
376  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
377  EXPECT_FALSE(node->check(nullptr));
378 
379  tuple = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("inf"));
380  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
381  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
382  EXPECT_TRUE(node->check(nullptr));
383 
384 
385  tuple = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("-inf"));
386  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
387  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
388  EXPECT_TRUE(node->check(nullptr));
389 
390  // Test BooleanNodes
391  tuple = py::make_tuple(static_cast<int>(NodeType::BooleanNode), true);
392  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
393  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
394  EXPECT_TRUE(node->check(nullptr));
395 
396  tuple = py::make_tuple(static_cast<int>(NodeType::BooleanNode), false);
397  uRelTuple = py::make_tuple(static_cast<int>(NodeType::UnaryRelationalNode), tuple);
398  node = NodeFactory::compile_boolean_node<MockVariableManager>(uRelTuple);
399  EXPECT_FALSE(node->check(nullptr));
400 
401  }
403  TEST(CutNodesTest, binaryRelationalNode)
404  {
405  Py_Initialize();
406  // Get main module
407  py::object main = py::import("__main__");
408  py::object pyfloat = main.attr("__builtins__").attr("float");
409 
410  py::tuple child1 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 1337);
411  py::tuple child2 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 1337);
412  py::tuple bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
413  static_cast<int>(ComparisonOperator::EQUALEQUAL));
414  auto node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
415  EXPECT_TRUE(node->check(nullptr));
416 
417  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 1337.0);
418  child2 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 1337);
419  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
420  static_cast<int>(ComparisonOperator::EQUALEQUAL));
421  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
422  EXPECT_TRUE(node->check(nullptr));
423 
424  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child2, child1,
425  static_cast<int>(ComparisonOperator::EQUALEQUAL));
426  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
427  EXPECT_TRUE(node->check(nullptr));
428 
429  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 1337.0);
430  child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 1337.0);
431  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
432  static_cast<int>(ComparisonOperator::EQUALEQUAL));
433  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
434  EXPECT_TRUE(node->check(nullptr));
435 
436  // NaN with NaN comparisons
437  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("nan"));
438  child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("nan"));
439  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
440  static_cast<int>(ComparisonOperator::EQUALEQUAL));
441  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
442  EXPECT_TRUE(node->check(nullptr));
443 
444  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
445  static_cast<int>(ComparisonOperator::GREATEREQUAL));
446  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
447  EXPECT_FALSE(node->check(nullptr));
448 
449  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
450  static_cast<int>(ComparisonOperator::LESSEQUAL));
451  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
452  EXPECT_FALSE(node->check(nullptr));
453 
454  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
455  static_cast<int>(ComparisonOperator::GREATER));
456  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
457  EXPECT_FALSE(node->check(nullptr));
458 
459  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
460  static_cast<int>(ComparisonOperator::LESS));
461  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
462  EXPECT_FALSE(node->check(nullptr));
463 
464  // NaN != NaN yields true
465  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
466  static_cast<int>(ComparisonOperator::NOTEQUAL));
467  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
468  EXPECT_FALSE(node->check(nullptr));
469 
470  // Compare nan with a numerical value
471  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("nan"));
472  child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 0.0);
473  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
474  static_cast<int>(ComparisonOperator::EQUALEQUAL));
475  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
476  EXPECT_FALSE(node->check(nullptr));
477 
478  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
479  static_cast<int>(ComparisonOperator::GREATEREQUAL));
480  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
481  EXPECT_FALSE(node->check(nullptr));
482 
483  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
484  static_cast<int>(ComparisonOperator::LESSEQUAL));
485  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
486  EXPECT_FALSE(node->check(nullptr));
487 
488  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
489  static_cast<int>(ComparisonOperator::GREATER));
490  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
491  EXPECT_FALSE(node->check(nullptr));
492 
493  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
494  static_cast<int>(ComparisonOperator::LESS));
495  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
496  EXPECT_FALSE(node->check(nullptr));
497 
498  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
499  static_cast<int>(ComparisonOperator::NOTEQUAL));
500  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
501  EXPECT_TRUE(node->check(nullptr));
502 
503  // Compare nan with -inf
504  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("nan"));
505  child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("inf"));
506  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
507  static_cast<int>(ComparisonOperator::EQUALEQUAL));
508  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
509  EXPECT_FALSE(node->check(nullptr));
510 
511  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
512  static_cast<int>(ComparisonOperator::GREATEREQUAL));
513  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
514  EXPECT_FALSE(node->check(nullptr));
515 
516  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
517  static_cast<int>(ComparisonOperator::LESSEQUAL));
518  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
519  EXPECT_FALSE(node->check(nullptr));
520 
521  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
522  static_cast<int>(ComparisonOperator::GREATER));
523  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
524  EXPECT_FALSE(node->check(nullptr));
525 
526  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
527  static_cast<int>(ComparisonOperator::LESS));
528  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
529  EXPECT_FALSE(node->check(nullptr));
530 
531  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
532  static_cast<int>(ComparisonOperator::NOTEQUAL));
533  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
534  EXPECT_TRUE(node->check(nullptr));
535 
536  // Compare nan with -inf
537  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("nan"));
538  child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("-inf"));
539  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
540  static_cast<int>(ComparisonOperator::EQUALEQUAL));
541  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
542  EXPECT_FALSE(node->check(nullptr));
543 
544  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
545  static_cast<int>(ComparisonOperator::GREATEREQUAL));
546  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
547  EXPECT_FALSE(node->check(nullptr));
548 
549  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
550  static_cast<int>(ComparisonOperator::LESSEQUAL));
551  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
552  EXPECT_FALSE(node->check(nullptr));
553 
554  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
555  static_cast<int>(ComparisonOperator::GREATER));
556  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
557  EXPECT_FALSE(node->check(nullptr));
558 
559  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
560  static_cast<int>(ComparisonOperator::LESS));
561  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
562  EXPECT_FALSE(node->check(nullptr));
563 
564  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
565  static_cast<int>(ComparisonOperator::NOTEQUAL));
566  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
567  EXPECT_TRUE(node->check(nullptr));
568 
569  // Compare inf with numerical value
570  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("inf"));
571  child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 0.0);
572  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
573  static_cast<int>(ComparisonOperator::EQUALEQUAL));
574  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
575  EXPECT_FALSE(node->check(nullptr));
576 
577  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
578  static_cast<int>(ComparisonOperator::GREATEREQUAL));
579  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
580  EXPECT_TRUE(node->check(nullptr));
581 
582  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
583  static_cast<int>(ComparisonOperator::LESSEQUAL));
584  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
585  EXPECT_FALSE(node->check(nullptr));
586 
587  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
588  static_cast<int>(ComparisonOperator::GREATER));
589  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
590  EXPECT_TRUE(node->check(nullptr));
591 
592  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
593  static_cast<int>(ComparisonOperator::LESS));
594  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
595  EXPECT_FALSE(node->check(nullptr));
596 
597  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
598  static_cast<int>(ComparisonOperator::NOTEQUAL));
599  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
600  EXPECT_TRUE(node->check(nullptr));
601 
602  // Compare inf with inf
603  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("inf"));
604  child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("inf"));
605  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
606  static_cast<int>(ComparisonOperator::EQUALEQUAL));
607  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
608  EXPECT_TRUE(node->check(nullptr));
609 
610  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
611  static_cast<int>(ComparisonOperator::GREATEREQUAL));
612  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
613  EXPECT_TRUE(node->check(nullptr));
614 
615  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
616  static_cast<int>(ComparisonOperator::LESSEQUAL));
617  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
618  EXPECT_TRUE(node->check(nullptr));
619 
620  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
621  static_cast<int>(ComparisonOperator::GREATER));
622  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
623  EXPECT_FALSE(node->check(nullptr));
624 
625  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
626  static_cast<int>(ComparisonOperator::LESS));
627  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
628  EXPECT_FALSE(node->check(nullptr));
629 
630  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
631  static_cast<int>(ComparisonOperator::NOTEQUAL));
632  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
633  EXPECT_FALSE(node->check(nullptr));
634 
635  // Compare inf with -inf
636  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("inf"));
637  child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("-inf"));
638  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
639  static_cast<int>(ComparisonOperator::EQUALEQUAL));
640  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
641  EXPECT_FALSE(node->check(nullptr));
642 
643  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
644  static_cast<int>(ComparisonOperator::GREATEREQUAL));
645  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
646  EXPECT_TRUE(node->check(nullptr));
647 
648  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
649  static_cast<int>(ComparisonOperator::LESSEQUAL));
650  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
651  EXPECT_FALSE(node->check(nullptr));
652 
653  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
654  static_cast<int>(ComparisonOperator::GREATER));
655  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
656  EXPECT_TRUE(node->check(nullptr));
657 
658  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
659  static_cast<int>(ComparisonOperator::LESS));
660  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
661  EXPECT_FALSE(node->check(nullptr));
662 
663  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
664  static_cast<int>(ComparisonOperator::NOTEQUAL));
665  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
666  EXPECT_TRUE(node->check(nullptr));
667 
668  // Check double precision
669  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 3.141592653589793);
670  child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 3.141592653589792);
671  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
672  static_cast<int>(ComparisonOperator::EQUALEQUAL));
673  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
674  EXPECT_FALSE(node->check(nullptr));
675 
676  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
677  static_cast<int>(ComparisonOperator::GREATEREQUAL));
678  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
679  EXPECT_TRUE(node->check(nullptr));
680 
681  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
682  static_cast<int>(ComparisonOperator::LESSEQUAL));
683  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
684  EXPECT_FALSE(node->check(nullptr));
685 
686  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
687  static_cast<int>(ComparisonOperator::GREATER));
688  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
689  EXPECT_TRUE(node->check(nullptr));
690 
691  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
692  static_cast<int>(ComparisonOperator::LESS));
693  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
694  EXPECT_FALSE(node->check(nullptr));
695 
696  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
697  static_cast<int>(ComparisonOperator::NOTEQUAL));
698  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
699  EXPECT_TRUE(node->check(nullptr));
700 
701  // Check almost equal doubles
702  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 3.1415926535897931234567890);
703  child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 3.1415926535897931234567891);
704  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
705  static_cast<int>(ComparisonOperator::EQUALEQUAL));
706  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
707  EXPECT_TRUE(node->check(nullptr));
708 
709  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
710  static_cast<int>(ComparisonOperator::GREATEREQUAL));
711  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
712  EXPECT_TRUE(node->check(nullptr));
713 
714  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
715  static_cast<int>(ComparisonOperator::LESSEQUAL));
716  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
717  EXPECT_TRUE(node->check(nullptr));
718 
719  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
720  static_cast<int>(ComparisonOperator::GREATER));
721  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
722  EXPECT_FALSE(node->check(nullptr));
723 
724  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
725  static_cast<int>(ComparisonOperator::LESS));
726  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
727  EXPECT_FALSE(node->check(nullptr));
728 
729  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
730  static_cast<int>(ComparisonOperator::NOTEQUAL));
731  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
732  EXPECT_FALSE(node->check(nullptr));
733 
734  // Check almost equal comparison for doubles and integers
735  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 3.0000000000000000000000001);
736  child2 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 3);
737  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
738  static_cast<int>(ComparisonOperator::EQUALEQUAL));
739  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
740  EXPECT_TRUE(node->check(nullptr));
741 
742  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
743  static_cast<int>(ComparisonOperator::GREATEREQUAL));
744  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
745  EXPECT_TRUE(node->check(nullptr));
746 
747  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
748  static_cast<int>(ComparisonOperator::LESSEQUAL));
749  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
750  EXPECT_TRUE(node->check(nullptr));
751 
752  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
753  static_cast<int>(ComparisonOperator::GREATER));
754  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
755  EXPECT_FALSE(node->check(nullptr));
756 
757  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
758  static_cast<int>(ComparisonOperator::LESS));
759  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
760  EXPECT_FALSE(node->check(nullptr));
761 
762  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
763  static_cast<int>(ComparisonOperator::NOTEQUAL));
764  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
765  EXPECT_FALSE(node->check(nullptr));
766 
767  // Note: almostEqualDouble does not work if one input is exactely 0.0
768  // and the other input is almost equal to 0.0
769  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 0.0);
770  child2 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 0);
771  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
772  static_cast<int>(ComparisonOperator::EQUALEQUAL));
773  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
774  EXPECT_TRUE(node->check(nullptr));
775 
776  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
777  static_cast<int>(ComparisonOperator::GREATEREQUAL));
778  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
779  EXPECT_TRUE(node->check(nullptr));
780 
781  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
782  static_cast<int>(ComparisonOperator::LESSEQUAL));
783  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
784  EXPECT_TRUE(node->check(nullptr));
785 
786  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
787  static_cast<int>(ComparisonOperator::GREATER));
788  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
789  EXPECT_FALSE(node->check(nullptr));
790 
791  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
792  static_cast<int>(ComparisonOperator::LESS));
793  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
794  EXPECT_FALSE(node->check(nullptr));
795 
796  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
797  static_cast<int>(ComparisonOperator::NOTEQUAL));
798  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
799  EXPECT_FALSE(node->check(nullptr));
800 
801  // Check double and int that are not almost equal but notequal 0.0
802  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 3.00000000000001);
803  child2 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 3);
804  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
805  static_cast<int>(ComparisonOperator::EQUALEQUAL));
806  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
807  EXPECT_FALSE(node->check(nullptr));
808 
809  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
810  static_cast<int>(ComparisonOperator::GREATEREQUAL));
811  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
812  EXPECT_TRUE(node->check(nullptr));
813 
814  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
815  static_cast<int>(ComparisonOperator::LESSEQUAL));
816  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
817  EXPECT_FALSE(node->check(nullptr));
818 
819  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
820  static_cast<int>(ComparisonOperator::GREATER));
821  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
822  EXPECT_TRUE(node->check(nullptr));
823 
824  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
825  static_cast<int>(ComparisonOperator::LESS));
826  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
827  EXPECT_FALSE(node->check(nullptr));
828 
829  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
830  static_cast<int>(ComparisonOperator::NOTEQUAL));
831  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
832  EXPECT_TRUE(node->check(nullptr));
833 
834  // Check almost equal comparison for double and bool
835  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 1.0000000000000001);
836  child2 = py::make_tuple(static_cast<int>(NodeType::BooleanNode), true);
837  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
838  static_cast<int>(ComparisonOperator::EQUALEQUAL));
839  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
840  // Uses almostEqualDouble and should evaluate to true
841  EXPECT_TRUE(node->check(nullptr));
842 
843  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
844  static_cast<int>(ComparisonOperator::GREATEREQUAL));
845  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
846  EXPECT_TRUE(node->check(nullptr));
847 
848  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
849  static_cast<int>(ComparisonOperator::LESSEQUAL));
850  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
851  EXPECT_TRUE(node->check(nullptr));
852 
853  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
854  static_cast<int>(ComparisonOperator::GREATER));
855  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
856  EXPECT_FALSE(node->check(nullptr));
857 
858  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
859  static_cast<int>(ComparisonOperator::LESS));
860  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
861  EXPECT_FALSE(node->check(nullptr));
862 
863  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
864  static_cast<int>(ComparisonOperator::NOTEQUAL));
865  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
866  // Uses almostEqualDouble and should evaluate to false
867  EXPECT_FALSE(node->check(nullptr));
868 
869  // Note: almostEqualDouble does not work if one input is exactely 0.0
870  // and the other input is almost equal to 0.0
871  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 0.0);
872  child2 = py::make_tuple(static_cast<int>(NodeType::BooleanNode), false);
873  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
874  static_cast<int>(ComparisonOperator::EQUALEQUAL));
875  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
876  EXPECT_TRUE(node->check(nullptr));
877 
878  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
879  static_cast<int>(ComparisonOperator::GREATEREQUAL));
880  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
881  EXPECT_TRUE(node->check(nullptr));
882 
883  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
884  static_cast<int>(ComparisonOperator::LESSEQUAL));
885  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
886  EXPECT_TRUE(node->check(nullptr));
887 
888  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
889  static_cast<int>(ComparisonOperator::GREATER));
890  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
891  EXPECT_FALSE(node->check(nullptr));
892 
893  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
894  static_cast<int>(ComparisonOperator::LESS));
895  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
896  EXPECT_FALSE(node->check(nullptr));
897 
898  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
899  static_cast<int>(ComparisonOperator::NOTEQUAL));
900  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
901  EXPECT_FALSE(node->check(nullptr));
902 
903 
904  // Check double and bool that are not almost equal
905  child1 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 1.00000000000001);
906  child2 = py::make_tuple(static_cast<int>(NodeType::BooleanNode), true);
907  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
908  static_cast<int>(ComparisonOperator::EQUALEQUAL));
909  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
910  EXPECT_FALSE(node->check(nullptr));
911 
912  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
913  static_cast<int>(ComparisonOperator::GREATEREQUAL));
914  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
915  EXPECT_TRUE(node->check(nullptr));
916 
917  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
918  static_cast<int>(ComparisonOperator::LESSEQUAL));
919  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
920  EXPECT_FALSE(node->check(nullptr));
921 
922  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
923  static_cast<int>(ComparisonOperator::GREATER));
924  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
925  EXPECT_TRUE(node->check(nullptr));
926 
927  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
928  static_cast<int>(ComparisonOperator::LESS));
929  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
930  EXPECT_FALSE(node->check(nullptr));
931 
932  bRelTuple = py::make_tuple(static_cast<int>(NodeType::BinaryRelationalNode), child1, child2,
933  static_cast<int>(ComparisonOperator::NOTEQUAL));
934  node = NodeFactory::compile_boolean_node<MockVariableManager>(bRelTuple);
935  EXPECT_TRUE(node->check(nullptr));
936 
937  }
939  TEST(CutNodesTest, ternaryRelationalNode)
940  {
941  Py_Initialize();
942  // Get main module
943  py::object main = py::import("__main__");
944  py::object pyfloat = main.attr("__builtins__").attr("float");
945 
946  auto child1 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 1);
947  auto child2 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 2);
948  auto child3 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 3);
949  auto tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child2, child3,
950  static_cast<int>(ComparisonOperator::LESS), static_cast<int>(ComparisonOperator::LESS));
951 
952  auto node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
953  EXPECT_TRUE(node->check(nullptr));
954  EXPECT_EQ(node->decompile(), "1 < 2 < 3");
955 
956  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child1, child1,
957  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::EQUALEQUAL));
958  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
959  EXPECT_TRUE(node->check(nullptr));
960  EXPECT_EQ(node->decompile(), "1 == 1 == 1");
961 
962 
963  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child1, child1,
964  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::LESSEQUAL));
965  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
966  EXPECT_TRUE(node->check(nullptr));
967  EXPECT_EQ(node->decompile(), "1 == 1 <= 1");
968 
969 
970  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child1, child2,
971  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::LESSEQUAL));
972  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
973  EXPECT_TRUE(node->check(nullptr));
974  EXPECT_EQ(node->decompile(), "1 == 1 <= 2");
975 
976 
977  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child1, child2,
978  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::LESS));
979  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
980  EXPECT_TRUE(node->check(nullptr));
981  EXPECT_EQ(node->decompile(), "1 == 1 < 2");
982 
983  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child1, child2,
984  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::NOTEQUAL));
985  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
986  EXPECT_TRUE(node->check(nullptr));
987  EXPECT_EQ(node->decompile(), "1 == 1 != 2");
988 
989  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child1, child1,
990  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::GREATEREQUAL));
991  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
992  EXPECT_TRUE(node->check(nullptr));
993  EXPECT_EQ(node->decompile(), "1 == 1 >= 1");
994 
995  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child1, child2,
996  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::GREATER));
997  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
998  EXPECT_FALSE(node->check(nullptr));
999  EXPECT_EQ(node->decompile(), "1 == 1 > 2");
1000 
1001  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child1, child1,
1002  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::NOTEQUAL));
1003  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1004  EXPECT_FALSE(node->check(nullptr));
1005  EXPECT_EQ(node->decompile(), "1 == 1 != 1");
1006 
1007 
1008  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child1, child2,
1009  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::LESSEQUAL));
1010  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1011  EXPECT_TRUE(node->check(nullptr));
1012  EXPECT_EQ(node->decompile(), "1 == 1 <= 2");
1013 
1014  // Create new double tuple
1015  child3 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 3.141);
1016 
1017  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child1, child3,
1018  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::LESSEQUAL));
1019  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1020  EXPECT_TRUE(node->check(nullptr));
1021  EXPECT_EQ(node->decompile(), "1 == 1 <= 3.141");
1022 
1023  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child1, child3, child3,
1024  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::LESSEQUAL));
1025  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1026  EXPECT_FALSE(node->check(nullptr));
1027  EXPECT_EQ(node->decompile(), "1 == 3.141 <= 3.141");
1028 
1029 
1030  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child3,
1031  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::LESSEQUAL));
1032  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1033  EXPECT_TRUE(node->check(nullptr));
1034  EXPECT_EQ(node->decompile(), "3.141 == 3.141 <= 3.141");
1035 
1036 
1037  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child3,
1038  static_cast<int>(ComparisonOperator::NOTEQUAL), static_cast<int>(ComparisonOperator::LESSEQUAL));
1039  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1040  EXPECT_FALSE(node->check(nullptr));
1041  EXPECT_EQ(node->decompile(), "3.141 != 3.141 <= 3.141");
1042 
1043  child3 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("nan"));
1044 
1045  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child3,
1046  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::EQUALEQUAL));
1047  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1048  EXPECT_TRUE(node->check(nullptr));
1049  EXPECT_EQ(node->decompile(), "nan == nan == nan");
1050 
1051  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child2,
1052  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::EQUALEQUAL));
1053  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1054  EXPECT_FALSE(node->check(nullptr));
1055  EXPECT_EQ(node->decompile(), "nan == nan == 2");
1056 
1057 
1058  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child2,
1059  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::NOTEQUAL));
1060  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1061  EXPECT_TRUE(node->check(nullptr));
1062  EXPECT_EQ(node->decompile(), "nan == nan != 2");
1063 
1064  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child3,
1065  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::NOTEQUAL));
1066  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1067  EXPECT_FALSE(node->check(nullptr));
1068  EXPECT_EQ(node->decompile(), "nan == nan != nan");
1069 
1070  child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), pyfloat("inf"));
1071 
1072  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child2,
1073  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::NOTEQUAL));
1074  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1075  EXPECT_TRUE(node->check(nullptr));
1076  EXPECT_EQ(node->decompile(), "nan == nan != inf");
1077 
1078 
1079  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child2,
1080  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::EQUALEQUAL));
1081  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1082  EXPECT_FALSE(node->check(nullptr));
1083  EXPECT_EQ(node->decompile(), "nan == nan == inf");
1084 
1085  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child2,
1086  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::LESS));
1087  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1088  EXPECT_FALSE(node->check(nullptr));
1089  EXPECT_EQ(node->decompile(), "nan == nan < inf");
1090 
1091  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child2,
1092  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::LESSEQUAL));
1093  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1094  EXPECT_FALSE(node->check(nullptr));
1095  EXPECT_EQ(node->decompile(), "nan == nan <= inf");
1096 
1097  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child2,
1098  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::GREATER));
1099  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1100  EXPECT_FALSE(node->check(nullptr));
1101  EXPECT_EQ(node->decompile(), "nan == nan > inf");
1102 
1103  tuple = py::make_tuple(static_cast<int>(NodeType::TernaryRelationalNode), child3, child3, child2,
1104  static_cast<int>(ComparisonOperator::EQUALEQUAL), static_cast<int>(ComparisonOperator::GREATEREQUAL));
1105  node = NodeFactory::compile_boolean_node<MockVariableManager>(tuple);
1106  EXPECT_FALSE(node->check(nullptr));
1107  EXPECT_EQ(node->decompile(), "nan == nan >= inf");
1108 
1109  }
1111  TEST(CutNodesTest, unaryExpressionNode)
1112  {
1113  Py_Initialize();
1114  auto child1 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 1);
1115  auto tuple = py::make_tuple(static_cast<int>(NodeType::UnaryExpressionNode), child1, false, false);
1116  auto node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1117  EXPECT_EQ(std::get<int>(node->evaluate(nullptr)), 1);
1118 
1119  // Check docompiling
1120  EXPECT_EQ(node->decompile(), "1");
1121 
1122  tuple = py::make_tuple(static_cast<int>(NodeType::UnaryExpressionNode), child1, true, false);
1123  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1124  EXPECT_EQ(std::get<int>(node->evaluate(nullptr)), -1);
1125 
1126  // Check docompiling
1127  EXPECT_EQ(node->decompile(), "-1");
1128 
1129  tuple = py::make_tuple(static_cast<int>(NodeType::UnaryExpressionNode), child1, true, true);
1130  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1131  EXPECT_EQ(std::get<int>(node->evaluate(nullptr)), -1);
1132 
1133  // Check docompiling
1134  EXPECT_EQ(node->decompile(), "-( 1 )");
1135 
1136  tuple = py::make_tuple(static_cast<int>(NodeType::UnaryExpressionNode), child1, false, true);
1137  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1138  EXPECT_EQ(std::get<int>(node->evaluate(nullptr)), 1);
1139 
1140  // Check docompiling
1141  EXPECT_EQ(node->decompile(), "( 1 )");
1142 
1143  }
1145  TEST(CutNodesTest, binaryExpressionNode)
1146  {
1147  Py_Initialize();
1148  auto child1 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 1);
1149  auto child2 = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 2.5);
1150  auto tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child1, child1,
1151  static_cast<int>(ArithmeticOperation::PLUS));
1152  auto node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1153  EXPECT_EQ(std::get<int>(node->evaluate(nullptr)), 2);
1154 
1155  // Check docompiling
1156  EXPECT_EQ(node->decompile(), "1 + 1");
1157 
1158  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child1, child2,
1159  static_cast<int>(ArithmeticOperation::PLUS));
1160  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1161  EXPECT_EQ(std::get<double>(node->evaluate(nullptr)), 3.5);
1162  EXPECT_EQ(node->decompile(), "1 + 2.5");
1163 
1164  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child1, child2,
1165  static_cast<int>(ArithmeticOperation::MINUS));
1166  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1167  EXPECT_EQ(std::get<double>(node->evaluate(nullptr)), -1.5);
1168  EXPECT_EQ(node->decompile(), "1 - 2.5");
1169 
1170 
1171  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child1, child2,
1172  static_cast<int>(ArithmeticOperation::PRODUCT));
1173  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1174  EXPECT_EQ(std::get<double>(node->evaluate(nullptr)), 2.5);
1175  EXPECT_EQ(node->decompile(), "1 * 2.5");
1176 
1177 
1178  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child1, child2,
1179  static_cast<int>(ArithmeticOperation::DIVISION));
1180  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1181  EXPECT_EQ(std::get<double>(node->evaluate(nullptr)), 0.4);
1182  EXPECT_EQ(node->decompile(), "1 / 2.5");
1183 
1184 
1185  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child1, child1,
1186  static_cast<int>(ArithmeticOperation::POWER));
1187  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1188  EXPECT_EQ(std::get<double>(node->evaluate(nullptr)), 1.0);
1189  EXPECT_EQ(node->decompile(), "1 ** 1");
1190 
1191  child1 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 2);
1192  child2 = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 3);
1193 
1194  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child1, child2,
1195  static_cast<int>(ArithmeticOperation::POWER));
1196  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1197  EXPECT_EQ(std::get<double>(node->evaluate(nullptr)), 8.0);
1198  EXPECT_EQ(node->decompile(), "2 ** 3");
1199 
1200  child2 = py::make_tuple(static_cast<int>(NodeType::IdentifierNode), "mocking_variable");
1201  MockObjectType part{10};
1202  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child1, child2,
1203  static_cast<int>(ArithmeticOperation::POWER));
1204  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1205  EXPECT_EQ(std::get<double>(node->evaluate(&part)), 1024);
1206  EXPECT_EQ(node->decompile(), "2 ** mocking_variable");
1207 
1208 
1209  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child2, child2,
1210  static_cast<int>(ArithmeticOperation::PLUS));
1211  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1212  EXPECT_EQ(std::get<int>(node->evaluate(&part)), 20);
1213  EXPECT_EQ(node->decompile(), "mocking_variable + mocking_variable");
1214 
1215  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child2, child2,
1216  static_cast<int>(ArithmeticOperation::MINUS));
1217  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1218  EXPECT_EQ(std::get<int>(node->evaluate(&part)), 0);
1219  EXPECT_EQ(node->decompile(), "mocking_variable - mocking_variable");
1220 
1221  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child2, child2,
1222  static_cast<int>(ArithmeticOperation::PRODUCT));
1223  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1224  EXPECT_EQ(std::get<int>(node->evaluate(&part)), 100);
1225  EXPECT_EQ(node->decompile(), "mocking_variable * mocking_variable");
1226 
1227 
1228  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child2, child2,
1229  static_cast<int>(ArithmeticOperation::DIVISION));
1230  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1231  EXPECT_EQ(std::get<double>(node->evaluate(&part)), 1);
1232  EXPECT_EQ(node->decompile(), "mocking_variable / mocking_variable");
1233 
1234 
1235  part = MockObjectType{20};
1236  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child1, child2,
1237  static_cast<int>(ArithmeticOperation::DIVISION));
1238  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1239  EXPECT_EQ(std::get<double>(node->evaluate(&part)), 0.1);
1240  EXPECT_EQ(node->decompile(), "2 / mocking_variable");
1241 
1242  part = MockObjectType{0.1};
1243  tuple = py::make_tuple(static_cast<int>(NodeType::BinaryExpressionNode), child2, child1,
1244  static_cast<int>(ArithmeticOperation::DIVISION));
1245  node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1246  EXPECT_EQ(std::get<double>(node->evaluate(&part)), 0.05);
1247  EXPECT_EQ(node->decompile(), "mocking_variable / 2");
1248 
1249 
1250  }
1252  TEST(CutNodesTest, identifierNode)
1253  {
1254  Py_Initialize();
1255  MockObjectType part{4.2};
1256  auto tuple = py::make_tuple(static_cast<int>(NodeType::IdentifierNode), "mocking_variable");
1257  auto node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1258  EXPECT_EQ(std::get<double>(node->evaluate(&part)), 4.2);
1259 
1260  tuple = py::make_tuple(static_cast<int>(NodeType::IdentifierNode), "THISDOESNOTEXIST");
1261  EXPECT_THROW(NodeFactory::compile_expression_node<MockVariableManager>(tuple), std::runtime_error);
1262 
1263  // Check nested runtime_error
1264  tuple = py::make_tuple(static_cast<int>(NodeType::UnaryExpressionNode), tuple, false, false);
1265  EXPECT_THROW(NodeFactory::compile_expression_node<MockVariableManager>(tuple), std::runtime_error);
1266 
1267  }
1269  TEST(CutNodesTest, functionNode)
1270  {
1271  Py_Initialize();
1272  MockObjectType part{4};
1273  auto tuple = py::make_tuple(
1274  static_cast<int>(NodeType::FunctionNode),
1275  "sum",
1276  "mocking_variable, 2, 1"
1277  );
1278  auto node = NodeFactory::compile_expression_node<MockVariableManager>(tuple);
1279  EXPECT_EQ(std::get<double>(node->evaluate(&part)), 7);
1280  EXPECT_EQ(node->decompile(), "sum(mocking_variable, 2, 1)");
1281  part = MockObjectType{4.2};
1282  EXPECT_EQ(std::get<double>(node->evaluate(&part)), 7.2);
1283  part = MockObjectType{false};
1284  EXPECT_EQ(std::get<double>(node->evaluate(&part)), 3.0);
1285  part = MockObjectType{true};
1286  EXPECT_EQ(std::get<double>(node->evaluate(&part)), 4.0);
1287 
1288  }
1290  TEST(CutNodesTest, integerNode)
1291  {
1292  Py_Initialize();
1293  // Get main module
1294  py::object main = py::import("__main__");
1295 
1296  // Create IntegerNode tuples.
1297  const py::tuple iTuple_val = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 1337);
1298  const py::tuple iTuple_val_neg = py::make_tuple(static_cast<int>(NodeType::IntegerNode), -1337);
1299  const py::tuple iTuple_val_zero = py::make_tuple(static_cast<int>(NodeType::IntegerNode), 0);
1300 
1301  // Check overflow management
1302  const py::tuple iTuple_max = py::make_tuple(static_cast<int>(NodeType::IntegerNode),
1303  main.attr("__builtins__").attr("int")("2147483647"));
1304  const py::tuple iTuple_min = py::make_tuple(static_cast<int>(NodeType::IntegerNode),
1305  main.attr("__builtins__").attr("int")("-2147483648"));
1306  const py::tuple iTuple_pos_overflow = py::make_tuple(static_cast<int>(NodeType::IntegerNode),
1307  main.attr("__builtins__").attr("int")("2147483648"));
1308  const py::tuple iTuple_neg_overflow = py::make_tuple(static_cast<int>(NodeType::IntegerNode),
1309  main.attr("__builtins__").attr("int")("-2147483649"));
1310 
1311  // Compile IntegerNodes and check evaluation
1312  auto iNode_val = NodeFactory::compile_expression_node<MockVariableManager>(iTuple_val);
1313  auto iNode_val_neg = NodeFactory::compile_expression_node<MockVariableManager>(iTuple_val_neg);
1314  auto iNode_val_zero = NodeFactory::compile_expression_node<MockVariableManager>(iTuple_val_zero);
1315  // Compile overflow management
1316  auto iNode_max = NodeFactory::compile_expression_node<MockVariableManager>(iTuple_max);
1317  auto iNode_min = NodeFactory::compile_expression_node<MockVariableManager>(iTuple_min);
1318  auto iNode_pos_overflow = NodeFactory::compile_expression_node<MockVariableManager>(iTuple_pos_overflow);
1319  auto iNode_neg_overflow = NodeFactory::compile_expression_node<MockVariableManager>(iTuple_neg_overflow);
1320 
1321  // test evaluation
1322  EXPECT_EQ(std::get<int>(iNode_val->evaluate(nullptr)), 1337);
1323  EXPECT_EQ(std::get<int>(iNode_val_neg->evaluate(nullptr)), -1337);
1324  EXPECT_EQ(std::get<int>(iNode_val_zero->evaluate(nullptr)), 0);
1325  EXPECT_EQ(std::get<int>(iNode_max->evaluate(nullptr)), 2147483647);
1326  EXPECT_EQ(std::get<int>(iNode_min->evaluate(nullptr)), -2147483648);
1327  // test overflowing node evaluation (returned as double)
1328  EXPECT_EQ(std::get<double>(iNode_pos_overflow->evaluate(nullptr)), 2147483648.);
1329  EXPECT_EQ(std::get<double>(iNode_neg_overflow->evaluate(nullptr)), -2147483649.);
1330 
1331  // test decompiling
1332  EXPECT_EQ(iNode_val->decompile(), "1337");
1333  EXPECT_EQ(iNode_val_neg->decompile(), "-1337");
1334  EXPECT_EQ(iNode_val_zero->decompile(), "0");
1335  EXPECT_EQ(iNode_max->decompile(), "2147483647");
1336  EXPECT_EQ(iNode_min->decompile(), "-2147483648");
1337  // test overflowing node decompiling
1338  EXPECT_EQ(iNode_pos_overflow->decompile(), "2.14748e+09");
1339  EXPECT_EQ(iNode_neg_overflow->decompile(), "-2.14748e+09");
1340  }
1342  TEST(CutNodesTest, booleanNode)
1343  {
1344  Py_Initialize();
1345  // Create two BooleanNode tuples with values true and false.
1346  const py::tuple booleanTuple_true = py::make_tuple(static_cast<int>(NodeType::BooleanNode), true);
1347  const py::tuple booleanTuple_false = py::make_tuple(static_cast<int>(NodeType::BooleanNode), false);
1348  // Compile BooleanNodes and check evaluation
1349  auto booleanNode_true = NodeFactory::compile_expression_node<MockVariableManager>(booleanTuple_true);
1350  auto booleanNode_false = NodeFactory::compile_expression_node<MockVariableManager>(booleanTuple_false);
1351  // test evaluation
1352  EXPECT_TRUE(std::get<bool>(booleanNode_true->evaluate(nullptr)));
1353  EXPECT_FALSE(std::get<bool>(booleanNode_false->evaluate(nullptr)));
1354  // test decompiling
1355  EXPECT_EQ(booleanNode_true->decompile(), "true");
1356  EXPECT_EQ(booleanNode_false->decompile(), "false");
1357  }
1359  TEST(CutNodesTest, doubleNode)
1360  {
1361  Py_Initialize();
1362  // Get main module
1363  py::object main = py::import("__main__");
1364 
1365  // Value tuples
1366  const py::tuple tuple_val = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 3.141);
1367  const py::tuple tuple_val_neg = py::make_tuple(static_cast<int>(NodeType::DoubleNode), -3.141);
1368  const py::tuple tuple_val_zero = py::make_tuple(static_cast<int>(NodeType::DoubleNode), 0.0);
1369  // Infinity tuples
1370  const py::tuple tuple_inf = py::make_tuple(static_cast<int>(NodeType::DoubleNode), main.attr("__builtins__").attr("float")("inf"));
1371  const py::tuple tuple_neg_inf = py::make_tuple(static_cast<int>(NodeType::DoubleNode),
1372  main.attr("__builtins__").attr("float")("-inf"));
1373  // nan tuple
1374  const py::tuple tuple_nan = py::make_tuple(static_cast<int>(NodeType::DoubleNode), main.attr("__builtins__").attr("float")("nan"));
1375 
1376  // Value nodes
1377  auto doubleNode_val = NodeFactory::compile_expression_node<MockVariableManager>(tuple_val);
1378  auto doubleNode_val_neg = NodeFactory::compile_expression_node<MockVariableManager>(tuple_val_neg);
1379  auto doubleNode_val_zero = NodeFactory::compile_expression_node<MockVariableManager>(tuple_val_zero);
1380 
1381  // Infinity nodes
1382  auto doubleNode_inf = NodeFactory::compile_expression_node<MockVariableManager>(tuple_inf);
1383  auto doubleNode_neg_inf = NodeFactory::compile_expression_node<MockVariableManager>(tuple_neg_inf);
1384  // NaN nodes
1385  auto doubleNode_nan = NodeFactory::compile_expression_node<MockVariableManager>(tuple_nan);
1386 
1387  // test value evaluation
1388  EXPECT_EQ(std::get<double>(doubleNode_val->evaluate(nullptr)), 3.141);
1389  EXPECT_EQ(std::get<double>(doubleNode_val_neg->evaluate(nullptr)), -3.141);
1390  EXPECT_EQ(std::get<double>(doubleNode_val_zero->evaluate(nullptr)), 0);
1391 
1392  // test infinity evaluation
1393  EXPECT_EQ(std::get<double>(doubleNode_inf->evaluate(nullptr)), std::numeric_limits<double>::infinity());
1394  EXPECT_EQ(std::get<double>(doubleNode_neg_inf->evaluate(nullptr)), -1 * std::numeric_limits<double>::infinity());
1395 
1396  // test NaN evaluation
1397  EXPECT_TRUE(std::isnan(std::get<double>(doubleNode_nan->evaluate(nullptr))));
1398 
1399  // test value decompiling
1400  EXPECT_EQ(doubleNode_val->decompile(), "3.141");
1401  EXPECT_EQ(doubleNode_val_neg->decompile(), "-3.141");
1402  EXPECT_EQ(doubleNode_val_zero->decompile(), "0");
1403  // test infinity decompiling
1404  EXPECT_EQ(doubleNode_inf->decompile(), "inf");
1405  EXPECT_EQ(doubleNode_neg_inf->decompile(), "-inf");
1406  // test nan decompiling
1407  EXPECT_EQ(doubleNode_nan->decompile(), "nan");
1408  }
1409 } // namespace
std::variant< double, int, bool > VarVariant
NOTE: the python interface is documented manually in analysis/doc/Variables.rst (because we use ROOT ...
Definition: Manager.h:111
TEST(TestgetDetectorRegion, TestgetDetectorRegion)
Test Constructors.
Abstract base class for different kinds of events.
int main(int argc, char **argv)
Run all tests.
Definition: test_main.cc:91