souffle  2.0.2-371-g6315b36
ram_operation_equal_clone_test.cpp
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2020, The Souffle Developers. All rights reserved
4  * Licensed under the Universal Permissive License v 1.0 as shown at:
5  * - https://opensource.org/licenses/UPL
6  * - <souffle root>/licenses/SOUFFLE-UPL.txt
7  */
8 
9 /************************************************************************
10  *
11  * @file ram_operation_equal_clone_test.cpp
12  *
13  * Tests equal and clone function of Condition classes.
14  *
15  ***********************************************************************/
16 
17 #include "tests/test.h"
18 
19 #include "AggregateOp.h"
20 #include "RelationTag.h"
21 #include "ram/Aggregate.h"
22 #include "ram/Break.h"
23 #include "ram/Choice.h"
24 #include "ram/Condition.h"
25 #include "ram/Conjunction.h"
26 #include "ram/Constraint.h"
27 #include "ram/EmptinessCheck.h"
28 #include "ram/ExistenceCheck.h"
29 #include "ram/Expression.h"
30 #include "ram/Filter.h"
31 #include "ram/IndexAggregate.h"
32 #include "ram/IndexChoice.h"
33 #include "ram/IndexScan.h"
34 #include "ram/Negation.h"
35 #include "ram/Operation.h"
36 #include "ram/PackRecord.h"
37 #include "ram/ParallelChoice.h"
39 #include "ram/ParallelIndexScan.h"
40 #include "ram/ParallelScan.h"
41 #include "ram/Project.h"
42 #include "ram/Relation.h"
43 #include "ram/Scan.h"
44 #include "ram/SignedConstant.h"
45 #include "ram/SubroutineReturn.h"
46 #include "ram/True.h"
47 #include "ram/TupleElement.h"
48 #include "ram/UndefValue.h"
49 #include "ram/UnpackRecord.h"
51 #include <memory>
52 #include <string>
53 #include <utility>
54 #include <vector>
55 
56 namespace souffle::ram::test {
57 
58 TEST(RamScan, CloneAndEquals) {
59  Relation A("A", 1, 1, {"x"}, {"i"}, RelationRepresentation::DEFAULT);
60  // FOR t0 in A
61  // RETURN number(0)
62  VecOwn<Expression> a_return_args;
63  a_return_args.emplace_back(new SignedConstant(0));
64  auto a_return = mk<SubroutineReturn>(std::move(a_return_args));
65  Scan a("A", 0, std::move(a_return), "Scan test");
66 
67  VecOwn<Expression> b_return_args;
68  b_return_args.emplace_back(new SignedConstant(0));
69  auto b_return = mk<SubroutineReturn>(std::move(b_return_args));
70  Scan b("A", 0, std::move(b_return), "Scan test");
71 
72  EXPECT_EQ(a, b);
73  EXPECT_NE(&a, &b);
74 
75  Scan* c = a.clone();
76  EXPECT_EQ(a, *c);
77  EXPECT_NE(&a, c);
78  delete c;
79 }
80 
81 TEST(RamParallelScan, CloneAndEquals) {
82  Relation A("A", 1, 1, {"x"}, {"i"}, RelationRepresentation::DEFAULT);
83  // PARALLEL FOR t0 in A
84  // RETURN number(0)
85  VecOwn<Expression> a_return_args;
86  a_return_args.emplace_back(new SignedConstant(0));
87  auto a_return = mk<SubroutineReturn>(std::move(a_return_args));
88  ParallelScan a("A", 0, std::move(a_return), "ParallelScan test");
89 
90  VecOwn<Expression> b_return_args;
91  b_return_args.emplace_back(new SignedConstant(0));
92  auto b_return = mk<SubroutineReturn>(std::move(b_return_args));
93  ParallelScan b("A", 0, std::move(b_return), "ParallelScan test");
94 
95  EXPECT_EQ(a, b);
96  EXPECT_NE(&a, &b);
97 
98  ParallelScan* c = a.clone();
99  EXPECT_EQ(a, *c);
100  EXPECT_NE(&a, c);
101  delete c;
102 }
103 
104 TEST(RamIndexScan, CloneAndEquals) {
105  Relation edge("edge", 2, 1, {"x", "y"}, {"i", "i"}, RelationRepresentation::DEFAULT);
106  Relation vertex("vertex", 1, 1, {"x"}, {"i"}, RelationRepresentation::DEFAULT);
107  // get vertices contain self loop
108  // FOR t1 IN edge ON INDEX t1.x = t1.1 AND t1.y = ⊥
109  // PROJECT (t1.0) INTO vertex
110  VecOwn<Expression> a_project_args;
111  a_project_args.emplace_back(new TupleElement(1, 0));
112  auto a_project = mk<Project>("vertex", std::move(a_project_args));
113  RamPattern a_criteria;
114  a_criteria.first.emplace_back(new TupleElement(1, 1));
115  a_criteria.first.emplace_back(new UndefValue);
116  a_criteria.second.emplace_back(new TupleElement(1, 1));
117  a_criteria.second.emplace_back(new UndefValue);
118 
119  IndexScan a("edge", 1, std::move(a_criteria), std::move(a_project), "IndexScan test");
120 
121  VecOwn<Expression> b_project_args;
122  b_project_args.emplace_back(new TupleElement(1, 0));
123  auto b_project = mk<Project>("vertex", std::move(b_project_args));
124  RamPattern b_criteria;
125  b_criteria.first.emplace_back(new TupleElement(1, 1));
126  b_criteria.first.emplace_back(new UndefValue);
127  b_criteria.second.emplace_back(new TupleElement(1, 1));
128  b_criteria.second.emplace_back(new UndefValue);
129 
130  IndexScan b("edge", 1, std::move(b_criteria), std::move(b_project), "IndexScan test");
131  EXPECT_EQ(a, b);
132  EXPECT_NE(&a, &b);
133 
134  IndexScan* c = a.clone();
135  EXPECT_EQ(a, *c);
136  EXPECT_NE(&a, c);
137  delete c;
138 }
139 
140 TEST(RamParallelIndexScan, CloneAndEquals) {
141  Relation edge("edge", 2, 1, {"x", "y"}, {"i", "i"}, RelationRepresentation::DEFAULT);
142  Relation new_edge("new_edge", 2, 1, {"x", "y"}, {"i", "i"}, RelationRepresentation::DEFAULT);
143  // get edges direct to vertex 5
144  // PARALLEL FOR t1 IN edge ON INDEX t1.x = ⊥ AND t1.y = 5
145  // PROJECT (t1.0, t1.1) INTO new_edge
146  VecOwn<Expression> a_project_args;
147  a_project_args.emplace_back(new TupleElement(1, 0));
148  a_project_args.emplace_back(new TupleElement(1, 1));
149  auto a_project = mk<Project>("new_edge", std::move(a_project_args));
150  RamPattern a_criteria;
151  a_criteria.first.emplace_back(new UndefValue);
152  a_criteria.first.emplace_back(new SignedConstant(5));
153  a_criteria.second.emplace_back(new UndefValue);
154  a_criteria.second.emplace_back(new SignedConstant(5));
155 
156  ParallelIndexScan a("edge", 1, std::move(a_criteria), std::move(a_project), "ParallelIndexScan test");
157 
158  VecOwn<Expression> b_project_args;
159  b_project_args.emplace_back(new TupleElement(1, 0));
160  b_project_args.emplace_back(new TupleElement(1, 1));
161  auto b_project = mk<Project>("new_edge", std::move(b_project_args));
162  RamPattern b_criteria;
163  b_criteria.first.emplace_back(new UndefValue);
164  b_criteria.first.emplace_back(new SignedConstant(5));
165  b_criteria.second.emplace_back(new UndefValue);
166  b_criteria.second.emplace_back(new SignedConstant(5));
167 
168  ParallelIndexScan b("edge", 1, std::move(b_criteria), std::move(b_project), "ParallelIndexScan test");
169  EXPECT_EQ(a, b);
170  EXPECT_NE(&a, &b);
171 
172  ParallelIndexScan* c = a.clone();
173  EXPECT_EQ(a, *c);
174  EXPECT_NE(&a, c);
175  delete c;
176 }
177 
178 TEST(RamChoice, CloneAndEquals) {
179  Relation edge("edge", 2, 1, {"x", "y"}, {"i", "i"}, RelationRepresentation::DEFAULT);
180  // choose an edge not adjcent to vertex 5
181  // CHOICE t1 IN edge WHERE NOT t1.0 = 5 AND NOT t1.1 = 5
182  // RETURN (t1.0, t1.1)
183  VecOwn<Expression> a_return_args;
184  a_return_args.emplace_back(new TupleElement(1, 0));
185  a_return_args.emplace_back(new TupleElement(1, 1));
186  auto a_return = mk<SubroutineReturn>(std::move(a_return_args));
187  auto a_constraint1 =
188  mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 0), mk<SignedConstant>(5));
189  auto a_neg1 = mk<Negation>(std::move(a_constraint1));
190  auto a_constraint2 =
191  mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 1), mk<SignedConstant>(5));
192  auto a_neg2 = mk<Negation>(std::move(a_constraint2));
193  auto a_cond = mk<Conjunction>(std::move(a_neg1), std::move(a_neg2));
194  Choice a("edge", 1, std::move(a_cond), std::move(a_return), "Choice test");
195 
196  VecOwn<Expression> b_return_args;
197  b_return_args.emplace_back(new TupleElement(1, 0));
198  b_return_args.emplace_back(new TupleElement(1, 1));
199  auto b_return = mk<SubroutineReturn>(std::move(b_return_args));
200  auto b_constraint1 =
201  mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 0), mk<SignedConstant>(5));
202  auto b_neg1 = mk<Negation>(std::move(b_constraint1));
203  auto b_constraint2 =
204  mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 1), mk<SignedConstant>(5));
205  auto b_neg2 = mk<Negation>(std::move(b_constraint2));
206  auto b_cond = mk<Conjunction>(std::move(b_neg1), std::move(b_neg2));
207  Choice b("edge", 1, std::move(b_cond), std::move(b_return), "Choice test");
208 
209  EXPECT_EQ(a, b);
210  EXPECT_NE(&a, &b);
211 
212  Choice* c = a.clone();
213  EXPECT_EQ(a, *c);
214  EXPECT_NE(&a, c);
215  delete c;
216 }
217 
218 TEST(RamParallelChoice, CloneAndEquals) {
219  Relation edge("edge", 2, 1, {"x", "y"}, {"i", "i"}, RelationRepresentation::DEFAULT);
220  // parallel choose an edge not adjcent to vertex 5
221  // PARALLEL CHOICE t1 IN edge WHERE NOT t1.0 = 5 AND NOT t1.1 = 5
222  // RETURN (t1.0, t1.1)
223  VecOwn<Expression> a_return_args;
224  a_return_args.emplace_back(new TupleElement(1, 0));
225  a_return_args.emplace_back(new TupleElement(1, 1));
226  auto a_return = mk<SubroutineReturn>(std::move(a_return_args));
227  auto a_constraint1 =
228  mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 0), mk<SignedConstant>(5));
229  auto a_neg1 = mk<Negation>(std::move(a_constraint1));
230  auto a_constraint2 =
231  mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 1), mk<SignedConstant>(5));
232  auto a_neg2 = mk<Negation>(std::move(a_constraint2));
233  auto a_cond = mk<Conjunction>(std::move(a_neg1), std::move(a_neg2));
234  ParallelChoice a("edge", 1, std::move(a_cond), std::move(a_return), "ParallelChoice test");
235 
236  VecOwn<Expression> b_return_args;
237  b_return_args.emplace_back(new TupleElement(1, 0));
238  b_return_args.emplace_back(new TupleElement(1, 1));
239  auto b_return = mk<SubroutineReturn>(std::move(b_return_args));
240  auto b_constraint1 =
241  mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 0), mk<SignedConstant>(5));
242  auto b_neg1 = mk<Negation>(std::move(b_constraint1));
243  auto b_constraint2 =
244  mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 1), mk<SignedConstant>(5));
245  auto b_neg2 = mk<Negation>(std::move(b_constraint2));
246  auto b_cond = mk<Conjunction>(std::move(b_neg1), std::move(b_neg2));
247  ParallelChoice b("edge", 1, std::move(b_cond), std::move(b_return), "ParallelChoice test");
248 
249  EXPECT_EQ(a, b);
250  EXPECT_NE(&a, &b);
251 
252  ParallelChoice* c = a.clone();
253  EXPECT_EQ(a, *c);
254  EXPECT_NE(&a, c);
255  delete c;
256 }
257 
258 TEST(RamIndexChoice, CloneAndEquals) {
259  Relation edge("edge", 2, 1, {"x", "y"}, {"i", "i"}, RelationRepresentation::DEFAULT);
260  // FOR t1 IN edge ON INDEX t1.x = 5 AND t1.y = ⊥
261  // WHERE NOT t1.1 = 5
262  // RETURN (t1.0, t1.1)
263  VecOwn<Expression> a_return_args;
264  a_return_args.emplace_back(new TupleElement(1, 0));
265  a_return_args.emplace_back(new TupleElement(1, 1));
266  auto a_return = mk<SubroutineReturn>(std::move(a_return_args));
267  auto a_constraint = mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 1), mk<SignedConstant>(5));
268  auto a_neg = mk<Negation>(std::move(a_constraint));
269  RamPattern a_criteria;
270  a_criteria.first.emplace_back(new SignedConstant(5));
271  a_criteria.first.emplace_back(new UndefValue);
272  a_criteria.second.emplace_back(new SignedConstant(5));
273  a_criteria.second.emplace_back(new UndefValue);
274  IndexChoice a(
275  "edge", 1, std::move(a_neg), std::move(a_criteria), std::move(a_return), "IndexChoice test");
276 
277  VecOwn<Expression> b_return_args;
278  b_return_args.emplace_back(new TupleElement(1, 0));
279  b_return_args.emplace_back(new TupleElement(1, 1));
280  auto b_return = mk<SubroutineReturn>(std::move(b_return_args));
281  auto b_constraint = mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 1), mk<SignedConstant>(5));
282  auto b_neg = mk<Negation>(std::move(b_constraint));
283  RamPattern b_criteria;
284  b_criteria.first.emplace_back(new SignedConstant(5));
285  b_criteria.first.emplace_back(new UndefValue);
286  b_criteria.second.emplace_back(new SignedConstant(5));
287  b_criteria.second.emplace_back(new UndefValue);
288  IndexChoice b(
289  "edge", 1, std::move(b_neg), std::move(b_criteria), std::move(b_return), "IndexChoice test");
290  EXPECT_EQ(a, b);
291  EXPECT_NE(&a, &b);
292 
293  IndexChoice* c = a.clone();
294  EXPECT_EQ(a, *c);
295  EXPECT_NE(&a, c);
296  delete c;
297 }
298 
299 TEST(RamiParallelIndexChoice, CloneAndEquals) {
300  Relation edge("edge", 2, 1, {"x", "y"}, {"i", "i"}, RelationRepresentation::DEFAULT);
301  // PARALLEL FOR t1 IN edge ON INDEX t1.x = 5 AND t1.y = ⊥
302  // WHERE NOT t1.1 = 5
303  // RETURN (t1.0, t1.1)
304  VecOwn<Expression> a_return_args;
305  a_return_args.emplace_back(new TupleElement(1, 0));
306  a_return_args.emplace_back(new TupleElement(1, 1));
307  auto a_return = mk<SubroutineReturn>(std::move(a_return_args));
308  auto a_constraint = mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 1), mk<SignedConstant>(5));
309  auto a_neg = mk<Negation>(std::move(a_constraint));
310  RamPattern a_criteria;
311  a_criteria.first.emplace_back(new SignedConstant(5));
312  a_criteria.first.emplace_back(new UndefValue);
313  a_criteria.second.emplace_back(new SignedConstant(5));
314  a_criteria.second.emplace_back(new UndefValue);
316  "edge", 1, std::move(a_neg), std::move(a_criteria), std::move(a_return), "IndexChoice test");
317 
318  VecOwn<Expression> b_return_args;
319  b_return_args.emplace_back(new TupleElement(1, 0));
320  b_return_args.emplace_back(new TupleElement(1, 1));
321  auto b_return = mk<SubroutineReturn>(std::move(b_return_args));
322  auto b_constraint = mk<Constraint>(BinaryConstraintOp::EQ, mk<TupleElement>(1, 1), mk<SignedConstant>(5));
323  auto b_neg = mk<Negation>(std::move(b_constraint));
324  RamPattern b_criteria;
325  b_criteria.first.emplace_back(new SignedConstant(5));
326  b_criteria.first.emplace_back(new UndefValue);
327  b_criteria.second.emplace_back(new SignedConstant(5));
328  b_criteria.second.emplace_back(new UndefValue);
330  "edge", 1, std::move(b_neg), std::move(b_criteria), std::move(b_return), "IndexChoice test");
331  EXPECT_EQ(a, b);
332  EXPECT_NE(&a, &b);
333 
334  ParallelIndexChoice* c = a.clone();
335  EXPECT_EQ(a, *c);
336  EXPECT_NE(&a, c);
337  delete c;
338 }
339 
340 TEST(RamAggregate, CloneAndEquals) {
341  Relation edge("edge", 2, 1, {"x", "y"}, {"i", "i"}, RelationRepresentation::DEFAULT);
342  // t0.0 = COUNT FOR ALL t1 IN edge
343  // RETURN t0.0
344  VecOwn<Expression> a_return_args;
345  a_return_args.emplace_back(new TupleElement(0, 0));
346  auto a_return = mk<SubroutineReturn>(std::move(a_return_args));
347  Aggregate a(std::move(a_return), AggregateOp::COUNT, "edge", mk<TupleElement>(0, 0), mk<True>(), 1);
348 
349  VecOwn<Expression> b_return_args;
350  b_return_args.emplace_back(new TupleElement(0, 0));
351  auto b_return = mk<SubroutineReturn>(std::move(b_return_args));
352  Aggregate b(std::move(b_return), AggregateOp::COUNT, "edge", mk<TupleElement>(0, 0), mk<True>(), 1);
353  EXPECT_EQ(a, b);
354  EXPECT_NE(&a, &b);
355 
356  Aggregate* c = a.clone();
357  EXPECT_EQ(a, *c);
358  EXPECT_NE(&a, c);
359  delete c;
360 }
361 
362 TEST(RamIndexAggregate, CloneAndEquals) {
363  Relation sqrt("sqrt", 2, 1, {"nth", "value"}, {"i", "i"}, RelationRepresentation::DEFAULT);
364  // t0.0 = MIN t1.1 SEARCH t1 IN sqrt ON INDEX t1.0 = ⊥ AND t1.1 = ⊥
365  // WHERE t1.1 > 80
366  // RETURN t0.0
367  VecOwn<Expression> a_return_args;
368  a_return_args.emplace_back(new TupleElement(0, 0));
369  auto a_return = mk<SubroutineReturn>(std::move(a_return_args));
370  auto a_cond = mk<Constraint>(BinaryConstraintOp::GE, mk<TupleElement>(1, 1), mk<SignedConstant>(80));
371  RamPattern a_criteria;
372  a_criteria.first.emplace_back(new UndefValue);
373  a_criteria.first.emplace_back(new UndefValue);
374  a_criteria.second.emplace_back(new UndefValue);
375  a_criteria.second.emplace_back(new UndefValue);
376  IndexAggregate a(std::move(a_return), AggregateOp::MIN, "sqrt", mk<TupleElement>(1, 1), std::move(a_cond),
377  std::move(a_criteria), 1);
378 
379  VecOwn<Expression> b_return_args;
380  b_return_args.emplace_back(new TupleElement(0, 0));
381  auto b_return = mk<SubroutineReturn>(std::move(b_return_args));
382  auto b_cond = mk<Constraint>(BinaryConstraintOp::GE, mk<TupleElement>(1, 1), mk<SignedConstant>(80));
383  RamPattern b_criteria;
384  b_criteria.first.emplace_back(new UndefValue);
385  b_criteria.first.emplace_back(new UndefValue);
386  b_criteria.second.emplace_back(new UndefValue);
387  b_criteria.second.emplace_back(new UndefValue);
388  IndexAggregate b(std::move(b_return), AggregateOp::MIN, "sqrt", mk<TupleElement>(1, 1), std::move(b_cond),
389  std::move(b_criteria), 1);
390  EXPECT_EQ(a, b);
391  EXPECT_NE(&a, &b);
392 
393  IndexAggregate* c = a.clone();
394  EXPECT_EQ(a, *c);
395  EXPECT_NE(&a, c);
396  delete c;
397 }
398 
399 TEST(RamUnpackedRecord, CloneAndEquals) {
400  // UNPACK (t0.0, t0.2) INTO t1
401  // RETURN number(0)
402  VecOwn<Expression> a_return_args;
403  a_return_args.emplace_back(new SignedConstant(0));
404  auto a_return = mk<SubroutineReturn>(std::move(a_return_args));
405  VecOwn<Expression> a_record_args;
406  a_record_args.emplace_back(new TupleElement(0, 0));
407  a_record_args.emplace_back(new TupleElement(0, 2));
408  auto a_record = mk<PackRecord>(std::move(a_record_args));
409  UnpackRecord a(std::move(a_return), 1, std::move(a_record), 2);
410 
411  VecOwn<Expression> b_return_args;
412  b_return_args.emplace_back(new SignedConstant(0));
413  auto b_return = mk<SubroutineReturn>(std::move(b_return_args));
414  VecOwn<Expression> b_record_args;
415  b_record_args.emplace_back(new TupleElement(0, 0));
416  b_record_args.emplace_back(new TupleElement(0, 2));
417  auto b_record = mk<PackRecord>(std::move(b_record_args));
418  UnpackRecord b(std::move(b_return), 1, std::move(b_record), 2);
419  EXPECT_EQ(a, b);
420  EXPECT_NE(&a, &b);
421 
422  UnpackRecord* c = a.clone();
423  EXPECT_EQ(a, *c);
424  EXPECT_NE(&a, c);
425  delete c;
426 }
427 
428 TEST(RamFilter, CloneAndEquals) {
429  Relation A("A", 1, 1, {"a"}, {"i"}, RelationRepresentation::DEFAULT);
430  // IF (NOT t0.1 in A)
431  // RETURN number(0)
432  VecOwn<Expression> a_return_args;
433  a_return_args.emplace_back(new SignedConstant(0));
434  auto a_return = mk<SubroutineReturn>(std::move(a_return_args));
435  VecOwn<Expression> a_existence_check_args;
436  a_existence_check_args.emplace_back(new TupleElement(0, 1));
437  auto a_existence_check = mk<ExistenceCheck>("A", std::move(a_existence_check_args));
438  Filter a(mk<Negation>(std::move(a_existence_check)), std::move(a_return), "Filter test");
439 
440  VecOwn<Expression> b_return_args;
441  b_return_args.emplace_back(new SignedConstant(0));
442  auto b_return = mk<SubroutineReturn>(std::move(b_return_args));
443  VecOwn<Expression> b_existence_check_args;
444  b_existence_check_args.emplace_back(new TupleElement(0, 1));
445  auto b_existence_check = mk<ExistenceCheck>("A", std::move(b_existence_check_args));
446  Filter b(mk<Negation>(std::move(b_existence_check)), std::move(b_return), "Filter test");
447  EXPECT_EQ(a, b);
448  EXPECT_NE(&a, &b);
449 
450  Filter* c = a.clone();
451  EXPECT_EQ(a, *c);
452  EXPECT_NE(&a, c);
453  delete c;
454 }
455 
456 TEST(RamBreak, CloneAndEquals) {
457  Relation A("A", 1, 1, {"a"}, {"i"}, RelationRepresentation::DEFAULT);
458  // IF (A = ∅) BREAK
459  // RETURN number(0)
460  VecOwn<Expression> a_return_args;
461  a_return_args.emplace_back(new SignedConstant(0));
462  auto a_return = mk<SubroutineReturn>(std::move(a_return_args));
463  Break a(mk<EmptinessCheck>("A"), std::move(a_return), "Break test");
464 
465  VecOwn<Expression> b_return_args;
466  b_return_args.emplace_back(new SignedConstant(0));
467  auto b_return = mk<SubroutineReturn>(std::move(b_return_args));
468  Break b(mk<EmptinessCheck>("A"), std::move(b_return), "Break test");
469  EXPECT_EQ(a, b);
470  EXPECT_NE(&a, &b);
471 
472  Break* c = a.clone();
473  EXPECT_EQ(a, *c);
474  EXPECT_NE(&a, c);
475  delete c;
476 }
477 
478 TEST(RamProject, CloneAndEquals) {
479  Relation A("A", 2, 1, {"a", "b"}, {"i", "i"}, RelationRepresentation::DEFAULT);
480  // PROJECT (t0.1, t0.3) INTO A
481  VecOwn<Expression> a_args;
482  a_args.emplace_back(new TupleElement(0, 1));
483  a_args.emplace_back(new TupleElement(0, 3));
484  Project a("A", std::move(a_args));
485 
486  VecOwn<Expression> b_args;
487  b_args.emplace_back(new TupleElement(0, 1));
488  b_args.emplace_back(new TupleElement(0, 3));
489  Project b("A", std::move(b_args));
490  EXPECT_EQ(a, b);
491  EXPECT_NE(&a, &b);
492 
493  Project* c = a.clone();
494  EXPECT_EQ(a, *c);
495  EXPECT_NE(&a, c);
496  delete c;
497 }
498 
499 TEST(RamSubroutineReturn, CloneAndEquals) {
500  // RETURN (t0.1, t0.2)
501  VecOwn<Expression> a_args;
502  a_args.emplace_back(new TupleElement(0, 1));
503  a_args.emplace_back(new TupleElement(0, 2));
504  SubroutineReturn a(std::move(a_args));
505 
506  VecOwn<Expression> b_args;
507  b_args.emplace_back(new TupleElement(0, 1));
508  b_args.emplace_back(new TupleElement(0, 2));
509  SubroutineReturn b(std::move(b_args));
510  EXPECT_EQ(a, b);
511  EXPECT_NE(&a, &b);
512 
513  SubroutineReturn* c = a.clone();
514  EXPECT_EQ(a, *c);
515  EXPECT_NE(&a, c);
516  delete c;
517 
518  // RETURN (number(0))
519  VecOwn<Expression> d_args;
520  d_args.emplace_back(new SignedConstant(0));
521  SubroutineReturn d(std::move(d_args));
522 
523  VecOwn<Expression> e_args;
524  e_args.emplace_back(new SignedConstant(0));
525  SubroutineReturn e(std::move(e_args));
526  EXPECT_EQ(d, e);
527  EXPECT_NE(&d, &e);
528 
529  SubroutineReturn* f = d.clone();
530  EXPECT_EQ(d, *f);
531  EXPECT_NE(&d, f);
532  delete f;
533 }
534 } // namespace souffle::ram::test
Aggregate.h
souffle::ram::Break
Breaks out of the loop if a condition holds.
Definition: Break.h:49
souffle::ram::ParallelScan::clone
ParallelScan * clone() const override
Create a clone (i.e.
Definition: ParallelScan.h:57
souffle::AggregateOp::MIN
@ MIN
BinaryConstraintOps.h
PackRecord.h
souffle::ram::ParallelIndexScan
Search for tuples of a relation matching a criteria.
Definition: ParallelIndexScan.h:58
Constraint.h
souffle::ram::UnpackRecord
Record lookup.
Definition: UnpackRecord.h:51
Scan.h
Negation.h
AggregateOp.h
Project.h
souffle::ram::ParallelIndexScan::clone
ParallelIndexScan * clone() const override
Create a clone (i.e.
Definition: ParallelIndexScan.h:64
souffle::ram::ParallelIndexChoice
Use an index to find a tuple in a relation such that a given condition holds in parallel.
Definition: ParallelIndexChoice.h:59
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: test.h:191
e
l j a showGridBackground &&c b raw series this eventEmitter e
Definition: htmlJsChartistMin.h:15
ParallelChoice.h
souffle::BinaryConstraintOp::EQ
@ EQ
souffle::ram::SignedConstant
Represents a signed constant.
Definition: SignedConstant.h:40
Filter.h
EmptinessCheck.h
True.h
souffle::ram::Aggregate::clone
Aggregate * clone() const override
Create a clone (i.e.
Definition: Aggregate.h:67
souffle::ram::TupleElement
Access element from the current tuple in a tuple environment.
Definition: TupleElement.h:42
ParallelIndexScan.h
IndexAggregate.h
souffle::ram::Project::clone
Project * clone() const override
Create a clone (i.e.
Definition: Project.h:77
souffle::ram::Filter
Checks whether a given condition holds.
Definition: Filter.h:49
IndexScan.h
souffle::ram::Break::clone
Break * clone() const override
Create a clone (i.e.
Definition: Break.h:54
IndexChoice.h
souffle::ram::Project
Project a result into the target relation.
Definition: Project.h:50
souffle::ram::Choice::clone
Choice * clone() const override
Create a clone (i.e.
Definition: Choice.h:71
souffle::ram::UnpackRecord::clone
UnpackRecord * clone() const override
Create a clone (i.e.
Definition: UnpackRecord.h:75
Choice.h
RelationTag.h
souffle::ram::ParallelIndexChoice::clone
ParallelIndexChoice * clone() const override
Create a clone (i.e.
Definition: ParallelIndexChoice.h:66
souffle::ram::Relation
An abstract class for performing indexed operations.
Definition: Relation.h:40
Relation.h
souffle::BinaryConstraintOp::GE
@ GE
souffle::ram::Aggregate
Aggregation function applied on some relation.
Definition: Aggregate.h:53
ParallelIndexChoice.h
Condition.h
souffle::ram::ParallelChoice::clone
ParallelChoice * clone() const override
Create a clone (i.e.
Definition: ParallelChoice.h:57
souffle::ram::IndexChoice
Use an index to find a tuple in a relation such that a given condition holds.
Definition: IndexChoice.h:58
souffle::ram::IndexAggregate
Indexed aggregation on a relation. The index allows us to iterate over a restricted range.
Definition: IndexAggregate.h:51
ExistenceCheck.h
UnpackRecord.h
souffle::ram::ParallelScan
Iterate all tuples of a relation in parallel.
Definition: ParallelScan.h:52
test.h
ParallelScan.h
Break.h
souffle::ram::IndexChoice::clone
IndexChoice * clone() const override
Create a clone (i.e.
Definition: IndexChoice.h:85
EXPECT_NE
#define EXPECT_NE(a, b)
Definition: test.h:195
souffle::ram::Choice
Find a tuple in a relation such that a given condition holds.
Definition: Choice.h:59
souffle::ram::Scan
Iterate all tuples of a relation.
Definition: Scan.h:47
souffle::ram::IndexScan
Search for tuples of a relation matching a criteria.
Definition: IndexScan.h:52
souffle::ram::test::TEST
TEST(True, CloneAndEquals)
Definition: ram_condition_equal_clone_test.cpp:54
souffle::AggregateOp::COUNT
@ COUNT
souffle::ram::IndexScan::clone
IndexScan * clone() const override
Create a clone (i.e.
Definition: IndexScan.h:59
TupleElement.h
souffle::ram::Filter::clone
Filter * clone() const override
Create a clone (i.e.
Definition: Filter.h:54
b
l j a showGridBackground &&c b raw series this eventEmitter b
Definition: htmlJsChartistMin.h:15
Operation.h
souffle::RelationRepresentation::DEFAULT
@ DEFAULT
souffle::ram::RamPattern
std::pair< RamBound, RamBound > RamPattern
Definition: IndexOperation.h:42
souffle::ram::Scan::clone
Scan * clone() const override
Create a clone (i.e.
Definition: Scan.h:52
SignedConstant.h
d
else d
Definition: htmlJsChartistMin.h:15
souffle::ram::UndefValue
An undefined expression.
Definition: UndefValue.h:36
SubroutineReturn.h
Expression.h
UndefValue.h
souffle::ram::IndexAggregate::clone
IndexAggregate * clone() const override
Create a clone (i.e.
Definition: IndexAggregate.h:65
souffle::ram::SubroutineReturn
A statement for returning from a ram subroutine.
Definition: SubroutineReturn.h:46
souffle::VecOwn
std::vector< Own< A > > VecOwn
Definition: ContainerUtil.h:45
souffle::ram::test
Definition: ram_condition_equal_clone_test.cpp:46
souffle::ram::ParallelChoice
Find a tuple in a relation such that a given condition holds in parallel.
Definition: ParallelChoice.h:51
Conjunction.h