aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query/src/test/java
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2024-03-07 22:10:42 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2024-04-07 14:55:46 +0200
commit16a9b534adec2c53b50f92a43c1623918b1c59c0 (patch)
tree690b299a2ca31e302ddad219a7aa94bcf86d5d0b /subprojects/store-query/src/test/java
parentfix(frontend): * operator highlighting (diff)
downloadrefinery-16a9b534adec2c53b50f92a43c1623918b1c59c0.tar.gz
refinery-16a9b534adec2c53b50f92a43c1623918b1c59c0.tar.zst
refinery-16a9b534adec2c53b50f92a43c1623918b1c59c0.zip
refactor: move terms and DNF into logic subproject
Diffstat (limited to 'subprojects/store-query/src/test/java')
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderLiteralEliminationTest.java259
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderVariableUnificationTest.java325
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java157
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/HashCodeTest.java67
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java113
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java251
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java89
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/literal/CallLiteralTest.java94
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/DuplicateDnfRemoverTest.java164
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java228
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/term/TermSubstitutionTest.java97
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/term/bool/BoolTermsEvaluateTest.java75
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/term/int_/IntTermsEvaluateTest.java259
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/term/real/RealTermEvaluateTest.java238
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorStreamTest.java56
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorTest.java80
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityTermsEvaluateTest.java104
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToRawTest.java159
-rw-r--r--subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java127
19 files changed, 0 insertions, 2942 deletions
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderLiteralEliminationTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderLiteralEliminationTest.java
deleted file mode 100644
index 6a2dc0c7..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderLiteralEliminationTest.java
+++ /dev/null
@@ -1,259 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.dnf;
7
8import org.junit.jupiter.api.Test;
9import org.junit.jupiter.params.ParameterizedTest;
10import org.junit.jupiter.params.provider.CsvSource;
11import tools.refinery.store.query.literal.BooleanLiteral;
12import tools.refinery.store.query.term.NodeVariable;
13import tools.refinery.store.query.term.ParameterDirection;
14import tools.refinery.store.query.term.Variable;
15import tools.refinery.store.query.term.bool.BoolTerms;
16import tools.refinery.store.query.view.KeyOnlyView;
17import tools.refinery.store.query.view.SymbolView;
18import tools.refinery.store.representation.Symbol;
19
20import java.util.List;
21
22import static org.hamcrest.MatcherAssert.assertThat;
23import static tools.refinery.store.query.literal.Literals.check;
24import static tools.refinery.store.query.literal.Literals.not;
25import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo;
26
27class DnfBuilderLiteralEliminationTest {
28 private final Symbol<Boolean> friend = Symbol.of("friend", 2);
29 private final SymbolView<Boolean> friendView = new KeyOnlyView<>(friend);
30 private final NodeVariable p = Variable.of("p");
31 private final NodeVariable q = Variable.of("q");
32 private final Dnf trueDnf = Dnf.builder().parameter(p, ParameterDirection.IN).clause().build();
33 private final Dnf falseDnf = Dnf.builder().parameter(p).build();
34
35 @Test
36 void eliminateTrueTest() {
37 var actual = Dnf.builder()
38 .parameters(p, q)
39 .clause(BooleanLiteral.TRUE, friendView.call(p, q))
40 .build();
41 var expected = Dnf.builder().parameters(p, q).clause(friendView.call(p, q)).build();
42
43 assertThat(actual, structurallyEqualTo(expected));
44 }
45
46 @Test
47 void eliminateTrueAssumptionTest() {
48 var actual = Dnf.builder()
49 .parameters(p, q)
50 .clause(check(BoolTerms.constant(true)), friendView.call(p, q))
51 .build();
52 var expected = Dnf.builder().parameters(p, q).clause(friendView.call(p, q)).build();
53
54 assertThat(actual, structurallyEqualTo(expected));
55 }
56
57 @Test
58 void eliminateFalseTest() {
59 var actual = Dnf.builder()
60 .parameters(p, q)
61 .clause(friendView.call(p, q))
62 .clause(friendView.call(q, p), BooleanLiteral.FALSE)
63 .build();
64 var expected = Dnf.builder().parameters(p, q).clause(friendView.call(p, q)).build();
65
66 assertThat(actual, structurallyEqualTo(expected));
67 }
68
69 @ParameterizedTest
70 @CsvSource(value = {
71 "false",
72 "null"
73 }, nullValues = "null")
74 void eliminateFalseAssumptionTest(Boolean value) {
75 var actual = Dnf.builder()
76 .parameters(p, q)
77 .clause(friendView.call(p, q))
78 .clause(friendView.call(q, p), check(BoolTerms.constant(value)))
79 .build();
80 var expected = Dnf.builder().parameters(p, q).clause(friendView.call(p, q)).build();
81
82 assertThat(actual, structurallyEqualTo(expected));
83 }
84
85 @Test
86 void alwaysTrueTest() {
87 var actual = Dnf.builder()
88 .parameters(List.of(p, q), ParameterDirection.IN)
89 .clause(friendView.call(p, q))
90 .clause(BooleanLiteral.TRUE)
91 .build();
92 var expected = Dnf.builder().parameters(List.of(p, q), ParameterDirection.IN).clause().build();
93
94 assertThat(actual, structurallyEqualTo(expected));
95 }
96
97 @Test
98 void alwaysFalseTest() {
99 var actual = Dnf.builder()
100 .parameters(p, q)
101 .clause(friendView.call(p, q), BooleanLiteral.FALSE)
102 .build();
103 var expected = Dnf.builder().parameters(p, q).build();
104
105 assertThat(actual, structurallyEqualTo(expected));
106 }
107
108 @Test
109 void eliminateTrueDnfTest() {
110 var actual = Dnf.builder()
111 .parameters(p, q)
112 .clause(trueDnf.call(q), friendView.call(p, q))
113 .build();
114 var expected = Dnf.builder().parameters(p, q).clause(friendView.call(p, q)).build();
115
116 assertThat(actual, structurallyEqualTo(expected));
117 }
118
119 @Test
120 void eliminateFalseDnfTest() {
121 var actual = Dnf.builder()
122 .parameters(p, q)
123 .clause(friendView.call(p, q))
124 .clause(friendView.call(q, p), falseDnf.call(q))
125 .build();
126 var expected = Dnf.builder().parameters(p, q).clause(friendView.call(p, q)).build();
127
128 assertThat(actual, structurallyEqualTo(expected));
129 }
130
131 @Test
132 void alwaysTrueDnfTest() {
133 var actual = Dnf.builder()
134 .parameters(List.of(p, q), ParameterDirection.IN)
135 .clause(friendView.call(p, q))
136 .clause(trueDnf.call(q))
137 .build();
138 var expected = Dnf.builder().parameters(List.of(p, q), ParameterDirection.IN).clause().build();
139
140 assertThat(actual, structurallyEqualTo(expected));
141 }
142
143 @Test
144 void alwaysFalseDnfTest() {
145 var actual = Dnf.builder()
146 .parameters(p, q)
147 .clause(friendView.call(p, q), falseDnf.call(q))
148 .build();
149 var expected = Dnf.builder().parameters(p, q).build();
150
151 assertThat(actual, structurallyEqualTo(expected));
152 }
153
154 @Test
155 void eliminateNotFalseDnfTest() {
156 var actual = Dnf.builder()
157 .parameters(p, q)
158 .clause(not(falseDnf.call(q)), friendView.call(p, q))
159 .build();
160 var expected = Dnf.builder().parameters(p, q).clause(friendView.call(p, q)).build();
161
162 assertThat(actual, structurallyEqualTo(expected));
163 }
164
165 @Test
166 void eliminateNotTrueDnfTest() {
167 var actual = Dnf.builder()
168 .parameters(p, q)
169 .clause(friendView.call(p, q))
170 .clause(friendView.call(q, p), not(trueDnf.call(q)))
171 .build();
172 var expected = Dnf.builder().parameters(p, q).clause(friendView.call(p, q)).build();
173
174 assertThat(actual, structurallyEqualTo(expected));
175 }
176
177 @Test
178 void alwaysNotFalseDnfTest() {
179 var actual = Dnf.builder()
180 .parameters(List.of(p, q), ParameterDirection.IN)
181 .clause(friendView.call(p, q))
182 .clause(not(falseDnf.call(q)))
183 .build();
184 var expected = Dnf.builder().parameters(List.of(p, q), ParameterDirection.IN).clause().build();
185
186 assertThat(actual, structurallyEqualTo(expected));
187 }
188
189 @Test
190 void alwaysNotTrueDnfTest() {
191 var actual = Dnf.builder()
192 .parameters(p, q)
193 .clause(friendView.call(p, q), not(trueDnf.call(q)))
194 .build();
195 var expected = Dnf.builder().parameters(p, q).build();
196
197 assertThat(actual, structurallyEqualTo(expected));
198 }
199
200 @Test
201 void removeDuplicateTest() {
202 var actual = Dnf.of(builder -> builder.clause((p, q) -> List.of(
203 friendView.call(p, q),
204 friendView.call(p, q)
205 )));
206 var expected = Dnf.of(builder -> builder.clause((p, q) -> List.of(friendView.call(p, q))));
207
208 assertThat(actual, structurallyEqualTo(expected));
209 }
210
211 @Test
212 void removeContradictoryTest() {
213 var actual = Dnf.of(builder -> builder.clause((p, q) -> List.of(
214 friendView.call(p, q),
215 not(friendView.call(p, q))
216 )));
217 var expected = Dnf.builder().build();
218
219 assertThat(actual, structurallyEqualTo(expected));
220 }
221
222 @Test
223 void removeContradictoryUniversalTest() {
224 var actual = Dnf.of(builder -> builder.clause((p, q) -> List.of(
225 friendView.call(q, q),
226 friendView.call(p, q),
227 not(friendView.call(p, Variable.of()))
228 )));
229 var expected = Dnf.builder().build();
230
231 assertThat(actual, structurallyEqualTo(expected));
232 }
233
234 @Test
235 void removeContradictoryExistentialUniversalTest() {
236 var actual = Dnf.of(builder -> builder.clause((p) -> List.of(
237 friendView.call(p, Variable.of()),
238 not(friendView.call(p, Variable.of()))
239 )));
240 var expected = Dnf.builder().build();
241
242 assertThat(actual, structurallyEqualTo(expected));
243 }
244
245 @Test
246 void removeContradictoryUniversalParameterTest() {
247 var actual = Dnf.of(builder -> {
248 var p = builder.parameter("p");
249 builder.clause((q) -> List.of(
250 friendView.call(q, q),
251 friendView.call(p, q),
252 not(friendView.call(p, Variable.of()))
253 ));
254 });
255 var expected = Dnf.builder().parameter(p).build();
256
257 assertThat(actual, structurallyEqualTo(expected));
258 }
259}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderVariableUnificationTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderVariableUnificationTest.java
deleted file mode 100644
index fc40c7b3..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfBuilderVariableUnificationTest.java
+++ /dev/null
@@ -1,325 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.dnf;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.term.ParameterDirection;
10import tools.refinery.store.query.term.Variable;
11import tools.refinery.store.query.view.KeyOnlyView;
12import tools.refinery.store.query.view.SymbolView;
13import tools.refinery.store.representation.Symbol;
14
15import java.util.List;
16
17import static org.hamcrest.MatcherAssert.assertThat;
18import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo;
19
20class DnfBuilderVariableUnificationTest {
21 private final Symbol<Boolean> friend = Symbol.of("friend", 2);
22 private final Symbol<Boolean> children = Symbol.of("children", 2);
23 private final SymbolView<Boolean> friendView = new KeyOnlyView<>(friend);
24 private final SymbolView<Boolean> childrenView = new KeyOnlyView<>(children);
25
26 @Test
27 void equalToParameterTest() {
28 var actual = Dnf.of(builder -> {
29 var p = builder.parameter("p");
30 builder.clause(q -> List.of(
31 friendView.call(p, q),
32 p.isEquivalent(q)
33 ));
34 });
35
36 var expectedP = Variable.of("p");
37 assertThat(actual, structurallyEqualTo(
38 List.of(new SymbolicParameter(expectedP, ParameterDirection.OUT)),
39 List.of(
40 List.of(friendView.call(expectedP, expectedP))
41 )
42 ));
43 }
44
45 @Test
46 void equalToParameterReverseTest() {
47 var actual = Dnf.of(builder -> {
48 var p = builder.parameter("p");
49 builder.clause(q -> List.of(
50 friendView.call(p, q),
51 q.isEquivalent(p)
52 ));
53 });
54
55 var expectedP = Variable.of("p");
56 assertThat(actual, structurallyEqualTo(
57 List.of(new SymbolicParameter(expectedP, ParameterDirection.OUT)),
58 List.of(
59 List.of(friendView.call(expectedP, expectedP))
60 )
61 ));
62 }
63
64 @Test
65 void equalQuantifiedTest() {
66 var actual = Dnf.of(builder -> builder.clause((p, q) -> List.of(
67 friendView.call(p, q),
68 p.isEquivalent(q)
69 )));
70
71 var expectedP = Variable.of("p");
72 assertThat(actual, structurallyEqualTo(
73 List.of(),
74 List.of(
75 List.of(friendView.call(expectedP, expectedP))
76 )
77 ));
78 }
79
80 @Test
81 void equalQuantifiedTransitiveTest() {
82 var actual = Dnf.of(builder -> builder.clause((p, q, r) -> List.of(
83 friendView.call(p, q),
84 p.isEquivalent(q),
85 childrenView.call(p, r),
86 q.isEquivalent(r)
87 )));
88
89 var expectedP = Variable.of("p");
90 assertThat(actual, structurallyEqualTo(
91 List.of(),
92 List.of(
93 List.of(friendView.call(expectedP, expectedP), childrenView.call(expectedP, expectedP))
94 )
95 ));
96 }
97
98 @Test
99 void equalQuantifiedTransitiveRemoveDuplicateTest() {
100 var actual = Dnf.of(builder -> builder.clause((p, q, r) -> List.of(
101 friendView.call(p, q),
102 p.isEquivalent(q),
103 friendView.call(p, r),
104 q.isEquivalent(r)
105 )));
106
107 var expectedP = Variable.of("p");
108 assertThat(actual, structurallyEqualTo(
109 List.of(),
110 List.of(
111 List.of(friendView.call(expectedP, expectedP))
112 )
113 ));
114 }
115
116 @Test
117 void parametersEqualTest() {
118 var actual = Dnf.of(builder -> {
119 var p = builder.parameter("p");
120 var q = builder.parameter("q");
121 builder.clause(
122 friendView.call(p, q),
123 p.isEquivalent(q)
124 );
125 });
126
127 var expectedP = Variable.of("p");
128 var expectedQ = Variable.of("q");
129 assertThat(actual, structurallyEqualTo(
130 List.of(
131 new SymbolicParameter(expectedP, ParameterDirection.OUT),
132 new SymbolicParameter(expectedQ, ParameterDirection.OUT)
133 ),
134 List.of(
135 List.of(friendView.call(expectedP, expectedP), expectedQ.isEquivalent(expectedP))
136 )
137 ));
138 }
139
140 @Test
141 void parametersEqualTransitiveTest() {
142 var actual = Dnf.of(builder -> {
143 var p = builder.parameter("p");
144 var q = builder.parameter("q");
145 var r = builder.parameter("r");
146 builder.clause(
147 friendView.call(p, q),
148 childrenView.call(p, r),
149 p.isEquivalent(q),
150 r.isEquivalent(q)
151 );
152 });
153
154 var expectedP = Variable.of("p");
155 var expectedQ = Variable.of("q");
156 var expectedR = Variable.of("r");
157 assertThat(actual, structurallyEqualTo(
158 List.of(
159 new SymbolicParameter(expectedP, ParameterDirection.OUT),
160 new SymbolicParameter(expectedQ, ParameterDirection.OUT),
161 new SymbolicParameter(expectedR, ParameterDirection.OUT)
162 ),
163 List.of(
164 List.of(
165 friendView.call(expectedP, expectedP),
166 expectedQ.isEquivalent(expectedP),
167 expectedR.isEquivalent(expectedP),
168 childrenView.call(expectedP, expectedP)
169 )
170 )
171 ));
172 }
173
174 @Test
175 void parameterAndQuantifiedEqualsTest() {
176 var actual = Dnf.of(builder -> {
177 var p = builder.parameter("p");
178 var q = builder.parameter("q");
179 builder.clause((r) -> List.of(
180 friendView.call(p, r),
181 p.isEquivalent(r),
182 childrenView.call(q, r),
183 q.isEquivalent(r)
184 ));
185 });
186
187
188 var expectedP = Variable.of("p");
189 var expectedQ = Variable.of("q");
190 assertThat(actual, structurallyEqualTo(
191 List.of(
192 new SymbolicParameter(expectedP, ParameterDirection.OUT),
193 new SymbolicParameter(expectedQ, ParameterDirection.OUT)
194 ),
195 List.of(
196 List.of(
197 friendView.call(expectedP, expectedP),
198 expectedQ.isEquivalent(expectedP),
199 childrenView.call(expectedP, expectedP)
200 )
201 )
202 ));
203 }
204
205 @Test
206 void parameterAndQuantifiedEqualsReverseFirstTest() {
207 var actual = Dnf.of(builder -> {
208 var p = builder.parameter("p");
209 var q = builder.parameter("q");
210 builder.clause((r) -> List.of(
211 friendView.call(p, r),
212 r.isEquivalent(p),
213 childrenView.call(q, r),
214 q.isEquivalent(r)
215 ));
216 });
217
218 var expectedP = Variable.of("p");
219 var expectedQ = Variable.of("q");
220 assertThat(actual, structurallyEqualTo(
221 List.of(
222 new SymbolicParameter(expectedP, ParameterDirection.OUT),
223 new SymbolicParameter(expectedQ, ParameterDirection.OUT)
224 ),
225 List.of(
226 List.of(
227 friendView.call(expectedP, expectedP),
228 expectedQ.isEquivalent(expectedP),
229 childrenView.call(expectedP, expectedP)
230 )
231 )
232 ));
233 }
234
235 @Test
236 void parameterAndQuantifiedEqualsReverseSecondTest() {
237 var actual = Dnf.of(builder -> {
238 var p = builder.parameter("p");
239 var q = builder.parameter("q");
240 builder.clause((r) -> List.of(
241 friendView.call(p, r),
242 p.isEquivalent(r),
243 childrenView.call(q, r),
244 r.isEquivalent(q)
245 ));
246 });
247
248 var expectedP = Variable.of("p");
249 var expectedQ = Variable.of("q");
250 assertThat(actual, structurallyEqualTo(
251 List.of(
252 new SymbolicParameter(expectedP, ParameterDirection.OUT),
253 new SymbolicParameter(expectedQ, ParameterDirection.OUT)
254 ),
255 List.of(
256 List.of(
257 friendView.call(expectedP, expectedP),
258 expectedQ.isEquivalent(expectedP),
259 childrenView.call(expectedP, expectedP)
260 )
261 )
262 ));
263 }
264
265 @Test
266 void parameterAndQuantifiedEqualsReverseBoth() {
267 var actual = Dnf.of(builder -> {
268 var p = builder.parameter("p");
269 var q = builder.parameter("q");
270 builder.clause((r) -> List.of(
271 friendView.call(p, r),
272 p.isEquivalent(r),
273 childrenView.call(q, r),
274 r.isEquivalent(q)
275 ));
276 });
277
278 var expectedP = Variable.of("p");
279 var expectedQ = Variable.of("q");
280 assertThat(actual, structurallyEqualTo(
281 List.of(
282 new SymbolicParameter(expectedP, ParameterDirection.OUT),
283 new SymbolicParameter(expectedQ, ParameterDirection.OUT)
284 ),
285 List.of(
286 List.of(
287 friendView.call(expectedP, expectedP),
288 expectedQ.isEquivalent(expectedP),
289 childrenView.call(expectedP, expectedP)
290 )
291 )
292 ));
293 }
294
295 @Test
296 void parameterAndTwoQuantifiedEqualsTest() {
297 var actual = Dnf.of(builder -> {
298 var p = builder.parameter("p");
299 var q = builder.parameter("q");
300 builder.clause((r, s) -> List.of(
301 r.isEquivalent(s),
302 friendView.call(p, r),
303 p.isEquivalent(r),
304 childrenView.call(q, s),
305 q.isEquivalent(s)
306 ));
307 });
308
309 var expectedP = Variable.of("p");
310 var expectedQ = Variable.of("q");
311 assertThat(actual, structurallyEqualTo(
312 List.of(
313 new SymbolicParameter(expectedP, ParameterDirection.OUT),
314 new SymbolicParameter(expectedQ, ParameterDirection.OUT)
315 ),
316 List.of(
317 List.of(
318 friendView.call(expectedP, expectedP),
319 expectedQ.isEquivalent(expectedP),
320 childrenView.call(expectedP, expectedP)
321 )
322 )
323 ));
324 }
325}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java
deleted file mode 100644
index 12cfaa4e..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/DnfToDefinitionStringTest.java
+++ /dev/null
@@ -1,157 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.dnf;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.term.NodeVariable;
10import tools.refinery.store.query.term.ParameterDirection;
11import tools.refinery.store.query.term.Variable;
12import tools.refinery.store.query.view.AnySymbolView;
13import tools.refinery.store.query.view.KeyOnlyView;
14import tools.refinery.store.representation.Symbol;
15
16import static org.hamcrest.MatcherAssert.assertThat;
17import static org.hamcrest.Matchers.is;
18import static tools.refinery.store.query.literal.Literals.not;
19
20class DnfToDefinitionStringTest {
21 private static final Symbol<Boolean> person = Symbol.of("person", 1);
22 private static final Symbol<Boolean> friend = Symbol.of("friend", 2);
23 private static final AnySymbolView personView = new KeyOnlyView<>(person);
24 private static final AnySymbolView friendView = new KeyOnlyView<>(friend);
25 private static final NodeVariable p = Variable.of("p");
26 private static final NodeVariable q = Variable.of("q");
27
28 @Test
29 void noClausesTest() {
30 var dnf = Dnf.builder("Example").parameter(p).build();
31
32 assertThat(dnf.toDefinitionString(), is("""
33 pred Example(p) <->
34 <no clauses>.
35 """));
36 }
37
38 @Test
39 void noParametersTest() {
40 var dnf = Dnf.builder("Example").build();
41
42 assertThat(dnf.toDefinitionString(), is("""
43 pred Example() <->
44 <no clauses>.
45 """));
46 }
47
48 @Test
49 void emptyClauseTest() {
50 var dnf = Dnf.builder("Example").parameter(p, ParameterDirection.IN).clause().build();
51
52 assertThat(dnf.toDefinitionString(), is("""
53 pred Example(in p) <->
54 <empty>.
55 """));
56 }
57
58 @Test
59 void relationViewPositiveTest() {
60 var dnf = Dnf.builder("Example").parameter(p).clause(friendView.call(p, q)).build();
61
62 assertThat(dnf.toDefinitionString(), is("""
63 pred Example(p) <->
64 @RelationView("key") friend(p, q).
65 """));
66 }
67
68 @Test
69 void relationViewNegativeTest() {
70 var dnf = Dnf.builder("Example")
71 .parameter(p, ParameterDirection.IN)
72 .clause(not(friendView.call(p, q)))
73 .build();
74
75 assertThat(dnf.toDefinitionString(), is("""
76 pred Example(in p) <->
77 !(@RelationView("key") friend(p, q)).
78 """));
79 }
80
81 @Test
82 void relationViewTransitiveTest() {
83 var dnf = Dnf.builder("Example").parameter(p).clause(friendView.callTransitive(p, q)).build();
84
85 assertThat(dnf.toDefinitionString(), is("""
86 pred Example(p) <->
87 @RelationView("key") friend+(p, q).
88 """));
89 }
90
91 @Test
92 void multipleParametersTest() {
93 var dnf = Dnf.builder("Example").parameters(p, q).clause(friendView.call(p, q)).build();
94
95 assertThat(dnf.toDefinitionString(), is("""
96 pred Example(p, q) <->
97 @RelationView("key") friend(p, q).
98 """));
99 }
100
101 @Test
102 void multipleLiteralsTest() {
103 var dnf = Dnf.builder("Example")
104 .parameter(p)
105 .clause(
106 personView.call(p),
107 personView.call(q),
108 friendView.call(p, q)
109 )
110 .build();
111
112 assertThat(dnf.toDefinitionString(), is("""
113 pred Example(p) <->
114 @RelationView("key") person(p),
115 @RelationView("key") person(q),
116 @RelationView("key") friend(p, q).
117 """));
118 }
119
120 @Test
121 void multipleClausesTest() {
122 var dnf = Dnf.builder("Example")
123 .parameter(p)
124 .clause(friendView.call(p, q))
125 .clause(friendView.call(q, p))
126 .build();
127
128 assertThat(dnf.toDefinitionString(), is("""
129 pred Example(p) <->
130 @RelationView("key") friend(p, q)
131 ;
132 @RelationView("key") friend(q, p).
133 """));
134 }
135
136 @Test
137 void dnfTest() {
138 var r = Variable.of("r");
139 var s = Variable.of("s");
140 var called = Dnf.builder("Called").parameters(r, s).clause(friendView.call(r, s)).build();
141 var dnf = Dnf.builder("Example")
142 .parameter(p)
143 .clause(
144 personView.call(p),
145 personView.call(q),
146 not(called.call(p, q))
147 )
148 .build();
149
150 assertThat(dnf.toDefinitionString(), is("""
151 pred Example(p) <->
152 @RelationView("key") person(p),
153 @RelationView("key") person(q),
154 !(@Dnf Called(p, q)).
155 """));
156 }
157}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/HashCodeTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/HashCodeTest.java
deleted file mode 100644
index 0c8eaeed..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/HashCodeTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.dnf;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.term.NodeVariable;
10import tools.refinery.store.query.term.Variable;
11import tools.refinery.store.query.view.AnySymbolView;
12import tools.refinery.store.query.view.KeyOnlyView;
13import tools.refinery.store.representation.Symbol;
14
15import static org.hamcrest.MatcherAssert.assertThat;
16import static org.hamcrest.Matchers.is;
17import static org.hamcrest.Matchers.not;
18
19class HashCodeTest {
20 private static final Symbol<Boolean> person = Symbol.of("Person", 1);
21 private static final Symbol<Boolean> friend = Symbol.of("friend", 2);
22 private static final AnySymbolView personView = new KeyOnlyView<>(person);
23 private static final AnySymbolView friendView = new KeyOnlyView<>(friend);
24 private static final NodeVariable p = Variable.of("p");
25 private static final NodeVariable q = Variable.of("q");
26
27 @Test
28 void flatEqualsTest() {
29 var expected = Dnf.builder("Expected").parameters(q).clause(personView.call(q)).build();
30 var actual = Dnf.builder("Actual").parameters(p).clause(personView.call(p)).build();
31
32 assertThat(actual.hashCodeWithSubstitution(), is(expected.hashCodeWithSubstitution()));
33 }
34
35 @Test
36 void flatNotEqualsTest() {
37 var expected = Dnf.builder("Expected").parameters(q).clause(friendView.call(q, q)).build();
38 var actual = Dnf.builder("Actual").parameters(p).clause(friendView.call(p, q)).build();
39
40 assertThat(actual.hashCodeWithSubstitution(), not(expected.hashCodeWithSubstitution()));
41 }
42
43 @Test
44 void deepEqualsTest() {
45 var expected2 = Dnf.builder("Expected2").parameters(p).clause(personView.call(p)).build();
46 var expected = Dnf.builder("Expected").parameters(q).clause(
47 expected2.call(q)
48 ).build();
49 var actual = Dnf.builder("Actual").parameters(q).clause(
50 expected2.call(q)
51 ).build();
52
53 assertThat(actual.hashCodeWithSubstitution(), is(expected.hashCodeWithSubstitution()));
54 }
55
56 @Test
57 void deepNotEqualsTest() {
58 var expected = Dnf.builder("Expected").parameters(q).clause(
59 Dnf.builder("Expected2").parameters(p).clause(personView.call(p)).build().call(q)
60 ).build();
61 var actual = Dnf.builder("Actual").parameters(q).clause(
62 Dnf.builder("Actual2").parameters(p).clause(personView.call(p)).build().call(q)
63 ).build();
64
65 assertThat(actual.hashCodeWithSubstitution(), not(expected.hashCodeWithSubstitution()));
66 }
67}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java
deleted file mode 100644
index 854bd469..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/TopologicalSortTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.dnf;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.InvalidQueryException;
10import tools.refinery.store.query.term.NodeVariable;
11import tools.refinery.store.query.term.ParameterDirection;
12import tools.refinery.store.query.term.Variable;
13import tools.refinery.store.query.view.AnySymbolView;
14import tools.refinery.store.query.view.KeyOnlyView;
15import tools.refinery.store.representation.Symbol;
16
17import java.util.List;
18
19import static org.hamcrest.MatcherAssert.assertThat;
20import static org.junit.jupiter.api.Assertions.assertThrows;
21import static tools.refinery.store.query.literal.Literals.not;
22import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo;
23
24class TopologicalSortTest {
25 private static final Symbol<Boolean> friend = Symbol.of("friend", 2);
26 private static final AnySymbolView friendView = new KeyOnlyView<>(friend);
27 private static final Dnf example = Dnf.of("example", builder -> {
28 var a = builder.parameter("a", ParameterDirection.IN);
29 var b = builder.parameter("b", ParameterDirection.IN);
30 var c = builder.parameter("c", ParameterDirection.OUT);
31 var d = builder.parameter("d", ParameterDirection.OUT);
32 builder.clause(
33 friendView.call(a, b),
34 friendView.call(b, c),
35 friendView.call(c, d)
36 );
37 });
38 private static final NodeVariable p = Variable.of("p");
39 private static final NodeVariable q = Variable.of("q");
40 private static final NodeVariable r = Variable.of("r");
41 private static final NodeVariable s = Variable.of("s");
42 private static final NodeVariable t = Variable.of("t");
43
44 @Test
45 void topologicalSortTest() {
46 var actual = Dnf.builder("Actual")
47 .parameter(p, ParameterDirection.IN)
48 .parameter(q, ParameterDirection.OUT)
49 .clause(
50 not(friendView.call(p, q)),
51 example.call(p, q, r, s),
52 example.call(r, t, q, s),
53 friendView.call(r, t)
54 )
55 .build();
56
57 assertThat(actual, structurallyEqualTo(
58 List.of(
59 new SymbolicParameter(p, ParameterDirection.IN),
60 new SymbolicParameter(q, ParameterDirection.OUT)
61 ),
62 List.of(
63 List.of(
64 friendView.call(r, t),
65 example.call(r, t, q, s),
66 not(friendView.call(p, q)),
67 example.call(p, q, r, s)
68 )
69 )
70 ));
71 }
72
73 @Test
74 void missingInputTest() {
75 var builder = Dnf.builder("Actual")
76 .parameter(p, ParameterDirection.OUT)
77 .parameter(q, ParameterDirection.OUT)
78 .clause(
79 not(friendView.call(p, q)),
80 example.call(p, q, r, s),
81 example.call(r, t, q, s),
82 friendView.call(r, t)
83 );
84 assertThrows(InvalidQueryException.class, builder::build);
85 }
86
87 @Test
88 void missingVariableTest() {
89 var builder = Dnf.builder("Actual")
90 .parameter(p, ParameterDirection.IN)
91 .parameter(q, ParameterDirection.OUT)
92 .clause(
93 not(friendView.call(p, q)),
94 example.call(p, q, r, s),
95 example.call(r, t, q, s)
96 );
97 assertThrows(InvalidQueryException.class, builder::build);
98 }
99
100 @Test
101 void circularDependencyTest() {
102 var builder = Dnf.builder("Actual")
103 .parameter(p, ParameterDirection.IN)
104 .parameter(q, ParameterDirection.OUT)
105 .clause(
106 not(friendView.call(p, q)),
107 example.call(p, q, r, s),
108 example.call(r, t, q, s),
109 example.call(p, q, r, t)
110 );
111 assertThrows(InvalidQueryException.class, builder::build);
112 }
113}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java
deleted file mode 100644
index fc3f5d48..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/dnf/VariableDirectionTest.java
+++ /dev/null
@@ -1,251 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.dnf;
7
8import org.junit.jupiter.params.ParameterizedTest;
9import org.junit.jupiter.params.provider.Arguments;
10import org.junit.jupiter.params.provider.MethodSource;
11import tools.refinery.store.query.literal.BooleanLiteral;
12import tools.refinery.store.query.literal.Literal;
13import tools.refinery.store.query.term.DataVariable;
14import tools.refinery.store.query.term.NodeVariable;
15import tools.refinery.store.query.term.ParameterDirection;
16import tools.refinery.store.query.term.Variable;
17import tools.refinery.store.query.view.AnySymbolView;
18import tools.refinery.store.query.view.FunctionView;
19import tools.refinery.store.query.view.KeyOnlyView;
20import tools.refinery.store.representation.Symbol;
21
22import java.util.ArrayList;
23import java.util.List;
24import java.util.stream.Stream;
25
26import static org.hamcrest.MatcherAssert.assertThat;
27import static org.hamcrest.Matchers.hasItem;
28import static org.hamcrest.Matchers.not;
29import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
30import static org.junit.jupiter.api.Assertions.assertThrows;
31import static tools.refinery.store.query.literal.Literals.not;
32import static tools.refinery.store.query.term.int_.IntTerms.INT_SUM;
33
34class VariableDirectionTest {
35 private static final Symbol<Boolean> person = Symbol.of("Person", 1);
36 private static final Symbol<Boolean> friend = Symbol.of("friend", 2);
37 private static final Symbol<Integer> age = Symbol.of("age", 1, Integer.class);
38 private static final AnySymbolView personView = new KeyOnlyView<>(person);
39 private static final AnySymbolView friendView = new KeyOnlyView<>(friend);
40 private static final FunctionView<Integer> ageView = new FunctionView<>(age);
41 private static final NodeVariable p = Variable.of("p");
42 private static final NodeVariable q = Variable.of("q");
43 private static final DataVariable<Integer> x = Variable.of("x", Integer.class);
44 private static final DataVariable<Integer> y = Variable.of("y", Integer.class);
45 private static final DataVariable<Integer> z = Variable.of("z", Integer.class);
46
47 @ParameterizedTest
48 @MethodSource("clausesWithVariableInput")
49 void unboundOutVariableTest(List<? extends Literal> clause) {
50 var builder = Dnf.builder().parameter(p, ParameterDirection.OUT).clause(clause);
51 assertThrows(InvalidClauseException.class, builder::build);
52 }
53
54 @ParameterizedTest
55 @MethodSource("clausesWithVariableInput")
56 void unboundInVariableTest(List<? extends Literal> clause) {
57 var builder = Dnf.builder().parameter(p, ParameterDirection.IN).clause(clause);
58 var dnf = assertDoesNotThrow(builder::build);
59 var clauses = dnf.getClauses();
60 if (clauses.size() > 0) {
61 assertThat(clauses.get(0).positiveVariables(), hasItem(p));
62 }
63 }
64
65 @ParameterizedTest
66 @MethodSource("clausesWithVariableInput")
67 void boundPrivateVariableTest(List<? extends Literal> clause) {
68 var clauseWithBinding = new ArrayList<Literal>(clause);
69 clauseWithBinding.add(personView.call(p));
70 var builder = Dnf.builder().clause(clauseWithBinding);
71 var dnf = assertDoesNotThrow(builder::build);
72 var clauses = dnf.getClauses();
73 if (clauses.size() > 0) {
74 assertThat(clauses.get(0).positiveVariables(), hasItem(p));
75 }
76 }
77
78 static Stream<Arguments> clausesWithVariableInput() {
79 return Stream.concat(
80 clausesNotBindingVariable(),
81 literalToClauseArgumentStream(literalsWithRequiredVariableInput())
82 );
83 }
84
85 @ParameterizedTest
86 @MethodSource("clausesNotBindingVariable")
87 void unboundPrivateVariableTest(List<? extends Literal> clause) {
88 var builder = Dnf.builder().clause(clause);
89 var dnf = assertDoesNotThrow(builder::build);
90 var clauses = dnf.getClauses();
91 if (clauses.size() > 0) {
92 assertThat(clauses.get(0).positiveVariables(), not(hasItem(p)));
93 }
94 }
95
96 @ParameterizedTest
97 @MethodSource("clausesNotBindingVariable")
98 void unboundByEquivalencePrivateVariableTest(List<? extends Literal> clause) {
99 var r = Variable.of("r");
100 var clauseWithEquivalence = new ArrayList<Literal>(clause);
101 clauseWithEquivalence.add(r.isEquivalent(p));
102 var builder = Dnf.builder().clause(clauseWithEquivalence);
103 assertThrows(InvalidClauseException.class, builder::build);
104 }
105
106 static Stream<Arguments> clausesNotBindingVariable() {
107 return Stream.concat(
108 Stream.of(
109 Arguments.of(List.of()),
110 Arguments.of(List.of(BooleanLiteral.TRUE)),
111 Arguments.of(List.of(BooleanLiteral.FALSE))
112 ),
113 literalToClauseArgumentStream(literalsWithPrivateVariable())
114 );
115 }
116
117 @ParameterizedTest
118 @MethodSource("literalsWithPrivateVariable")
119 void unboundTwicePrivateVariableTest(Literal literal) {
120 var builder = Dnf.builder().clause(not(personView.call(p)), literal);
121 assertThrows(InvalidClauseException.class, builder::build);
122 }
123
124 @ParameterizedTest
125 @MethodSource("literalsWithPrivateVariable")
126 void unboundTwiceByEquivalencePrivateVariableTest(Literal literal) {
127 var r = Variable.of("r");
128 var builder = Dnf.builder().clause(not(personView.call(r)), r.isEquivalent(p), literal);
129 assertThrows(InvalidClauseException.class, builder::build);
130 }
131
132 static Stream<Arguments> literalsWithPrivateVariable() {
133 var dnfWithOutput = Dnf.builder("WithOutput")
134 .parameter(p, ParameterDirection.OUT)
135 .parameter(q, ParameterDirection.OUT)
136 .clause(friendView.call(p, q))
137 .build();
138 var dnfWithOutputToAggregate = Dnf.builder("WithOutputToAggregate")
139 .parameter(p, ParameterDirection.OUT)
140 .parameter(q, ParameterDirection.OUT)
141 .parameter(x, ParameterDirection.OUT)
142 .clause(
143 friendView.call(p, q),
144 ageView.call(q, x)
145 )
146 .build();
147
148 return Stream.of(
149 Arguments.of(not(friendView.call(p, q))),
150 Arguments.of(y.assign(friendView.count(p, q))),
151 Arguments.of(y.assign(ageView.aggregate(INT_SUM, p))),
152 Arguments.of(not(dnfWithOutput.call(p, q))),
153 Arguments.of(y.assign(dnfWithOutput.count(p, q))),
154 Arguments.of(y.assign(dnfWithOutputToAggregate.aggregateBy(z, INT_SUM, p, q, z)))
155 );
156 }
157
158 @ParameterizedTest
159 @MethodSource("literalsWithRequiredVariableInput")
160 void unboundPrivateVariableTest(Literal literal) {
161 var builder = Dnf.builder().clause(literal);
162 assertThrows(InvalidClauseException.class, builder::build);
163 }
164
165 @ParameterizedTest
166 @MethodSource("literalsWithRequiredVariableInput")
167 void boundPrivateVariableInputTest(Literal literal) {
168 var builder = Dnf.builder().clause(personView.call(p), literal);
169 var dnf = assertDoesNotThrow(builder::build);
170 assertThat(dnf.getClauses().get(0).positiveVariables(), hasItem(p));
171 }
172
173 static Stream<Arguments> literalsWithRequiredVariableInput() {
174 var dnfWithInput = Dnf.builder("WithInput")
175 .parameter(p, ParameterDirection.IN)
176 .parameter(q, ParameterDirection.OUT)
177 .clause(friendView.call(p, q)).build();
178 var dnfWithInputToAggregate = Dnf.builder("WithInputToAggregate")
179 .parameter(p, ParameterDirection.IN)
180 .parameter(q, ParameterDirection.OUT)
181 .parameter(x, ParameterDirection.OUT)
182 .clause(
183 friendView.call(p, q),
184 ageView.call(q, x)
185 ).build();
186
187 return Stream.of(
188 Arguments.of(dnfWithInput.call(p, q)),
189 Arguments.of(dnfWithInput.call(p, p)),
190 Arguments.of(not(dnfWithInput.call(p, q))),
191 Arguments.of(not(dnfWithInput.call(p, p))),
192 Arguments.of(y.assign(dnfWithInput.count(p, q))),
193 Arguments.of(y.assign(dnfWithInput.count(p, p))),
194 Arguments.of(y.assign(dnfWithInputToAggregate.aggregateBy(z, INT_SUM, p, q, z))),
195 Arguments.of(y.assign(dnfWithInputToAggregate.aggregateBy(z, INT_SUM, p, p, z)))
196 );
197 }
198
199 @ParameterizedTest
200 @MethodSource("literalsWithVariableOutput")
201 void boundParameterTest(Literal literal) {
202 var builder = Dnf.builder().parameter(p, ParameterDirection.OUT).clause(literal);
203 var dnf = assertDoesNotThrow(builder::build);
204 assertThat(dnf.getClauses().get(0).positiveVariables(), hasItem(p));
205 }
206
207 @ParameterizedTest
208 @MethodSource("literalsWithVariableOutput")
209 void boundTwiceParameterTest(Literal literal) {
210 var builder = Dnf.builder().parameter(p, ParameterDirection.IN).clause(literal);
211 var dnf = assertDoesNotThrow(builder::build);
212 assertThat(dnf.getClauses().get(0).positiveVariables(), hasItem(p));
213 }
214
215 @ParameterizedTest
216 @MethodSource("literalsWithVariableOutput")
217 void boundPrivateVariableOutputTest(Literal literal) {
218 var dnfWithInput = Dnf.builder("WithInput")
219 .parameter(p, ParameterDirection.IN)
220 .clause(personView.call(p))
221 .build();
222 var builder = Dnf.builder().clause(dnfWithInput.call(p), literal);
223 var dnf = assertDoesNotThrow(builder::build);
224 assertThat(dnf.getClauses().get(0).positiveVariables(), hasItem(p));
225 }
226
227 @ParameterizedTest
228 @MethodSource("literalsWithVariableOutput")
229 void boundTwicePrivateVariableOutputTest(Literal literal) {
230 var builder = Dnf.builder().clause(personView.call(p), literal);
231 var dnf = assertDoesNotThrow(builder::build);
232 assertThat(dnf.getClauses().get(0).positiveVariables(), hasItem(p));
233 }
234
235 static Stream<Arguments> literalsWithVariableOutput() {
236 var dnfWithOutput = Dnf.builder("WithOutput")
237 .parameter(p, ParameterDirection.OUT)
238 .parameter(q, ParameterDirection.OUT)
239 .clause(friendView.call(p, q))
240 .build();
241
242 return Stream.of(
243 Arguments.of(friendView.call(p, q)),
244 Arguments.of(dnfWithOutput.call(p, q))
245 );
246 }
247
248 private static Stream<Arguments> literalToClauseArgumentStream(Stream<Arguments> literalArgumentsStream) {
249 return literalArgumentsStream.map(arguments -> Arguments.of(List.of(arguments.get()[0])));
250 }
251}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java
deleted file mode 100644
index ddd57e96..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/AggregationLiteralTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.literal;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.Constraint;
10import tools.refinery.store.query.InvalidQueryException;
11import tools.refinery.store.query.dnf.Dnf;
12import tools.refinery.store.query.dnf.InvalidClauseException;
13import tools.refinery.store.query.term.*;
14
15import java.util.List;
16import java.util.Set;
17
18import static org.hamcrest.MatcherAssert.assertThat;
19import static org.hamcrest.Matchers.*;
20import static org.junit.jupiter.api.Assertions.assertAll;
21import static org.junit.jupiter.api.Assertions.assertThrows;
22import static tools.refinery.store.query.literal.Literals.not;
23import static tools.refinery.store.query.term.int_.IntTerms.INT_SUM;
24import static tools.refinery.store.query.term.int_.IntTerms.constant;
25
26class AggregationLiteralTest {
27 private static final NodeVariable p = Variable.of("p");
28 private static final DataVariable<Integer> x = Variable.of("x", Integer.class);
29 private static final DataVariable<Integer> y = Variable.of("y", Integer.class);
30 private static final DataVariable<Integer> z = Variable.of("z", Integer.class);
31 private static final Constraint fakeConstraint = new Constraint() {
32 @Override
33 public String name() {
34 return getClass().getName();
35 }
36
37 @Override
38 public List<Parameter> getParameters() {
39 return List.of(
40 new Parameter(null, ParameterDirection.OUT),
41 new Parameter(Integer.class, ParameterDirection.OUT)
42 );
43 }
44 };
45
46 @Test
47 void parameterDirectionTest() {
48 var literal = x.assign(fakeConstraint.aggregateBy(y, INT_SUM, p, y));
49 assertAll(
50 () -> assertThat(literal.getOutputVariables(), containsInAnyOrder(x)),
51 () -> assertThat(literal.getInputVariables(Set.of()), empty()),
52 () -> assertThat(literal.getInputVariables(Set.of(p)), containsInAnyOrder(p)),
53 () -> assertThat(literal.getPrivateVariables(Set.of()), containsInAnyOrder(p, y)),
54 () -> assertThat(literal.getPrivateVariables(Set.of(p)), containsInAnyOrder(y))
55 );
56 }
57
58 @Test
59 void missingAggregationVariableTest() {
60 var aggregation = fakeConstraint.aggregateBy(y, INT_SUM, p, z);
61 assertThrows(InvalidQueryException.class, () -> x.assign(aggregation));
62 }
63
64 @Test
65 void circularAggregationVariableTest() {
66 var aggregation = fakeConstraint.aggregateBy(x, INT_SUM, p, x);
67 assertThrows(InvalidQueryException.class, () -> x.assign(aggregation));
68 }
69
70 @Test
71 void unboundTwiceVariableTest() {
72 var builder = Dnf.builder()
73 .clause(
74 not(fakeConstraint.call(p, y)),
75 x.assign(fakeConstraint.aggregateBy(y, INT_SUM, p, y))
76 );
77 assertThrows(InvalidClauseException.class, builder::build);
78 }
79
80 @Test
81 void unboundBoundVariableTest() {
82 var builder = Dnf.builder()
83 .clause(
84 y.assign(constant(27)),
85 x.assign(fakeConstraint.aggregateBy(y, INT_SUM, p, y))
86 );
87 assertThrows(InvalidClauseException.class, builder::build);
88 }
89}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/CallLiteralTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/CallLiteralTest.java
deleted file mode 100644
index a01c6586..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/literal/CallLiteralTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.literal;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.Constraint;
10import tools.refinery.store.query.term.NodeVariable;
11import tools.refinery.store.query.term.Parameter;
12import tools.refinery.store.query.term.ParameterDirection;
13import tools.refinery.store.query.term.Variable;
14
15import java.util.List;
16import java.util.Set;
17
18import static org.hamcrest.MatcherAssert.assertThat;
19import static org.hamcrest.Matchers.containsInAnyOrder;
20import static org.hamcrest.Matchers.empty;
21import static org.junit.jupiter.api.Assertions.assertAll;
22import static tools.refinery.store.query.literal.Literals.not;
23
24class CallLiteralTest {
25 private static final NodeVariable p = Variable.of("p");
26 private static final NodeVariable q = Variable.of("q");
27 private static final NodeVariable r = Variable.of("r");
28 private static final NodeVariable s = Variable.of("s");
29
30 private static final Constraint fakeConstraint = new Constraint() {
31 @Override
32 public String name() {
33 return getClass().getName();
34 }
35
36 @Override
37 public List<Parameter> getParameters() {
38 return List.of(
39 new Parameter(null, ParameterDirection.IN),
40 new Parameter(null, ParameterDirection.IN),
41 new Parameter(null, ParameterDirection.OUT),
42 new Parameter(null, ParameterDirection.OUT)
43 );
44 }
45 };
46
47 @Test
48 void notRepeatedPositiveDirectionTest() {
49 var literal = fakeConstraint.call(p, q, r, s);
50 assertAll(
51 () -> assertThat(literal.getOutputVariables(), containsInAnyOrder(r, s)),
52 () -> assertThat(literal.getInputVariables(Set.of()), containsInAnyOrder(p, q)),
53 () -> assertThat(literal.getInputVariables(Set.of(p, q, r)), containsInAnyOrder(p, q)),
54 () -> assertThat(literal.getPrivateVariables(Set.of()), empty()),
55 () -> assertThat(literal.getPrivateVariables(Set.of(p, q, r)), empty())
56 );
57 }
58
59 @Test
60 void notRepeatedNegativeDirectionTest() {
61 var literal = not(fakeConstraint.call(p, q, r, s));
62 assertAll(
63 () -> assertThat(literal.getOutputVariables(), empty()),
64 () -> assertThat(literal.getInputVariables(Set.of()), containsInAnyOrder(p, q)),
65 () -> assertThat(literal.getInputVariables(Set.of(p, q, r)), containsInAnyOrder(p, q, r)),
66 () -> assertThat(literal.getPrivateVariables(Set.of()), containsInAnyOrder(r, s)),
67 () -> assertThat(literal.getPrivateVariables(Set.of(p, q, r)), containsInAnyOrder(s))
68 );
69 }
70
71 @Test
72 void repeatedPositiveDirectionTest() {
73 var literal = fakeConstraint.call(p, p, q, q);
74 assertAll(
75 () -> assertThat(literal.getOutputVariables(), containsInAnyOrder(q)),
76 () -> assertThat(literal.getInputVariables(Set.of()), containsInAnyOrder(p)),
77 () -> assertThat(literal.getInputVariables(Set.of(p, q)), containsInAnyOrder(p)),
78 () -> assertThat(literal.getPrivateVariables(Set.of()), empty()),
79 () -> assertThat(literal.getPrivateVariables(Set.of(p, q)), empty())
80 );
81 }
82
83 @Test
84 void repeatedNegativeDirectionTest() {
85 var literal = not(fakeConstraint.call(p, p, q, q));
86 assertAll(
87 () -> assertThat(literal.getOutputVariables(), empty()),
88 () -> assertThat(literal.getInputVariables(Set.of()), containsInAnyOrder(p)),
89 () -> assertThat(literal.getInputVariables(Set.of(p, q)), containsInAnyOrder(p, q)),
90 () -> assertThat(literal.getPrivateVariables(Set.of()), containsInAnyOrder(q)),
91 () -> assertThat(literal.getPrivateVariables(Set.of(p, q)), empty())
92 );
93 }
94}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/DuplicateDnfRemoverTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/DuplicateDnfRemoverTest.java
deleted file mode 100644
index ebb24ab5..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/DuplicateDnfRemoverTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.rewriter;
7
8import org.junit.jupiter.api.BeforeEach;
9import org.junit.jupiter.api.Test;
10import tools.refinery.store.query.dnf.Query;
11import tools.refinery.store.query.literal.AbstractCallLiteral;
12import tools.refinery.store.query.literal.Reduction;
13import tools.refinery.store.query.term.Variable;
14import tools.refinery.store.query.view.AnySymbolView;
15import tools.refinery.store.query.view.KeyOnlyView;
16import tools.refinery.store.representation.Symbol;
17
18import java.util.List;
19
20import static org.hamcrest.MatcherAssert.assertThat;
21import static org.hamcrest.Matchers.is;
22import static org.hamcrest.Matchers.not;
23import static tools.refinery.store.query.literal.Literals.not;
24
25class DuplicateDnfRemoverTest {
26 private final static Symbol<Boolean> friend = Symbol.of("friend", 2);
27 private final static AnySymbolView friendView = new KeyOnlyView<>(friend);
28
29 private DuplicateDnfRemover sut;
30
31 @BeforeEach
32 void beforeEach() {
33 sut = new DuplicateDnfRemover();
34 }
35
36 @Test
37 void removeDuplicateSimpleTest() {
38 var one = Query.of("One", (builder, x, y) -> builder.clause(
39 friendView.call(x, y),
40 friendView.call(y, x)
41 ));
42 var two = Query.of("Two", (builder, x, y) -> builder.clause(
43 friendView.call(x, y),
44 friendView.call(y, x)
45 ));
46
47 var oneResult = sut.rewrite(one);
48 var twoResult = sut.rewrite(two);
49
50 assertThat(oneResult, is(twoResult));
51 assertThat(one, is(oneResult));
52 }
53
54 @Test
55 void notDuplicateSimpleTest() {
56 var one = Query.of("One", (builder, x, y) -> builder.clause(
57 friendView.call(x, y),
58 friendView.call(y, x)
59 ));
60 var two = Query.of("Two", (builder, x, y) -> builder.clause((z) -> List.of(
61 friendView.call(x, y),
62 friendView.call(y, z)
63 )));
64
65 var oneResult = sut.rewrite(one);
66 var twoResult = sut.rewrite(two);
67
68 assertThat(one, is(oneResult));
69 assertThat(two, is(twoResult));
70 }
71
72 @Test
73 void removeDuplicateRecursiveTest() {
74 var oneSubQuery = Query.of("OneSubQuery", (builder, x, y) -> builder.clause(
75 friendView.call(x, y),
76 friendView.call(y, x)
77 ));
78 var one = Query.of("One", (builder, x) -> builder.clause(
79 oneSubQuery.call(x, Variable.of())
80 ));
81 var twoSubQuery = Query.of("TwoSubQuery", (builder, x, y) -> builder.clause(
82 friendView.call(x, y),
83 friendView.call(y, x)
84 ));
85 var two = Query.of("Two", (builder, x) -> builder.clause(
86 twoSubQuery.call(x, Variable.of())
87 ));
88
89 var oneResult = sut.rewrite(one);
90 var twoResult = sut.rewrite(two);
91
92 assertThat(oneResult, is(twoResult));
93 assertThat(one, is(oneResult));
94 }
95
96 @Test
97 void notDuplicateRecursiveTest() {
98 var oneSubQuery = Query.of("OneSubQuery", (builder, x, y) -> builder.clause(
99 friendView.call(x, y),
100 friendView.call(y, x)
101 ));
102 var one = Query.of("One", (builder, x) -> builder.clause(
103 oneSubQuery.call(x, Variable.of())
104 ));
105 var twoSubQuery = Query.of("TwoSubQuery", (builder, x, y) -> builder.clause(
106 friendView.call(x, y),
107 friendView.call(y, x)
108 ));
109 var two = Query.of("Two", (builder, x) -> builder.clause(
110 twoSubQuery.call(Variable.of(), x)
111 ));
112
113 var oneResult = sut.rewrite(one);
114 var twoResult = sut.rewrite(two);
115
116 assertThat(one, is(oneResult));
117 assertThat(oneResult, is(not(twoResult)));
118
119 var oneCall = (AbstractCallLiteral) oneResult.getDnf().getClauses().get(0).literals().get(0);
120 var twoCall = (AbstractCallLiteral) twoResult.getDnf().getClauses().get(0).literals().get(0);
121
122 assertThat(oneCall.getTarget(), is(twoCall.getTarget()));
123 }
124
125 @Test
126 void removeContradictionTest() {
127 var oneSubQuery = Query.of("OneSubQuery", (builder, x, y) -> builder.clause(
128 friendView.call(x, y),
129 friendView.call(y, x)
130 ));
131 var twoSubQuery = Query.of("TwoSubQuery", (builder, x, y) -> builder.clause(
132 friendView.call(x, y),
133 friendView.call(y, x)
134 ));
135 var query = Query.of("Contradiction", (builder, x, y) -> builder.clause(
136 oneSubQuery.call(x, y),
137 not(twoSubQuery.call(x, y))
138 ));
139
140 var result = sut.rewrite(query);
141
142 assertThat(result.getDnf().getReduction(), is(Reduction.ALWAYS_FALSE));
143 }
144
145 @Test
146 void removeQuantifiedContradictionTest() {
147 var oneSubQuery = Query.of("OneSubQuery", (builder, x, y) -> builder.clause(
148 friendView.call(x, y),
149 friendView.call(y, x)
150 ));
151 var twoSubQuery = Query.of("TwoSubQuery", (builder, x, y) -> builder.clause(
152 friendView.call(x, y),
153 friendView.call(y, x)
154 ));
155 var query = Query.of("Contradiction", (builder, x) -> builder.clause(
156 oneSubQuery.call(x, Variable.of()),
157 not(twoSubQuery.call(x, Variable.of()))
158 ));
159
160 var result = sut.rewrite(query);
161
162 assertThat(result.getDnf().getReduction(), is(Reduction.ALWAYS_FALSE));
163 }
164}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java
deleted file mode 100644
index ef0077e4..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/rewriter/InputParameterResolverTest.java
+++ /dev/null
@@ -1,228 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.rewriter;
7
8import org.junit.jupiter.api.BeforeEach;
9import org.junit.jupiter.api.Test;
10import tools.refinery.store.query.dnf.Dnf;
11import tools.refinery.store.query.dnf.Query;
12import tools.refinery.store.query.term.ParameterDirection;
13import tools.refinery.store.query.term.Variable;
14import tools.refinery.store.query.view.AnySymbolView;
15import tools.refinery.store.query.view.KeyOnlyView;
16import tools.refinery.store.representation.Symbol;
17
18import java.util.List;
19
20import static org.hamcrest.MatcherAssert.assertThat;
21import static org.hamcrest.Matchers.is;
22import static tools.refinery.store.query.literal.Literals.not;
23import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo;
24
25class InputParameterResolverTest {
26 private final static Symbol<Boolean> person = Symbol.of("Person", 1);
27 private final static Symbol<Boolean> friend = Symbol.of("friend", 2);
28 private final static AnySymbolView personView = new KeyOnlyView<>(person);
29 private final static AnySymbolView friendView = new KeyOnlyView<>(friend);
30
31 private InputParameterResolver sut;
32
33 @BeforeEach
34 void beforeEach() {
35 sut = new InputParameterResolver();
36 }
37
38 @Test
39 void inlineSingleClauseTest() {
40 var dnf = Dnf.of("SubQuery", builder -> {
41 var x = builder.parameter("x", ParameterDirection.OUT);
42 builder.clause(friendView.call(x, Variable.of()));
43 });
44 var query = Query.of("Actual", (builder, x) -> builder.clause(
45 dnf.call(x),
46 personView.call(x)
47 ));
48
49 var actual = sut.rewrite(query);
50
51 var expected = Query.of("Expected", (builder, x) -> builder.clause(
52 friendView.call(x, Variable.of()),
53 personView.call(x)
54 ));
55
56 assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf()));
57 }
58
59 @Test
60 void inlineSingleClauseWIthInputTest() {
61 var dnf = Dnf.of("SubQuery", builder -> {
62 var x = builder.parameter("x", ParameterDirection.IN);
63 builder.clause(not(friendView.call(x, Variable.of())));
64 });
65 var query = Query.of("Actual", (builder, x) -> builder.clause(
66 dnf.call(x),
67 personView.call(x)
68 ));
69
70 var actual = sut.rewrite(query);
71
72 var expected = Query.of("Expected", (builder, x) -> builder.clause(
73 personView.call(x),
74 not(friendView.call(x, Variable.of()))
75 ));
76
77 assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf()));
78 }
79
80 @Test
81 void singleLiteralDemandSetTest() {
82 var dnf = Dnf.of("SubQuery", builder -> {
83 var x = builder.parameter("x", ParameterDirection.IN);
84 builder.clause(not(friendView.call(x, Variable.of())));
85 builder.clause(not(friendView.call(Variable.of(), x)));
86 });
87 var query = Query.of("Actual", (builder, x) -> builder.clause(
88 dnf.call(x),
89 personView.call(x)
90 ));
91
92 var actual = sut.rewrite(query);
93
94 var expectedSubQuery = Dnf.of("ExpectedSubQuery", builder -> {
95 var x = builder.parameter("x", ParameterDirection.OUT);
96 builder.clause(
97 personView.call(x),
98 not(friendView.call(x, Variable.of()))
99 );
100 builder.clause(
101 personView.call(x),
102 not(friendView.call(Variable.of(), x))
103 );
104 });
105 var expected = Query.of("Expected", (builder, x) -> builder.clause(
106 personView.call(x),
107 expectedSubQuery.call(x)
108 ));
109
110 assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf()));
111 }
112
113 @Test
114 void multipleLiteralDemandSetTest() {
115 var dnf = Dnf.of("SubQuery", builder -> {
116 var x = builder.parameter("x", ParameterDirection.IN);
117 var y = builder.parameter("y", ParameterDirection.IN);
118 builder.clause(not(friendView.call(x, y)));
119 builder.clause(not(friendView.call(y, x)));
120 });
121 var query = Query.of("Actual", (builder, p1) -> builder.clause(p2 -> List.of(
122 not(dnf.call(p1, p2)),
123 personView.call(p1),
124 personView.call(p2)
125 )));
126
127 var actual = sut.rewrite(query);
128
129 var context = Dnf.of("Context", builder -> {
130 var x = builder.parameter("x", ParameterDirection.OUT);
131 var y = builder.parameter("y", ParameterDirection.OUT);
132 builder.clause(
133 personView.call(x),
134 personView.call(y)
135 );
136 });
137 var expectedSubQuery = Dnf.of("ExpectedSubQuery", builder -> {
138 var x = builder.parameter("x", ParameterDirection.OUT);
139 var y = builder.parameter("x", ParameterDirection.OUT);
140 builder.clause(
141 context.call(x, y),
142 not(friendView.call(x, y))
143 );
144 builder.clause(
145 context.call(x, y),
146 not(friendView.call(y, x))
147 );
148 });
149 var expected = Query.of("Expected", (builder, p1) -> builder.clause(p2 -> List.of(
150 context.call(p1, p2),
151 not(expectedSubQuery.call(p1, p2))
152 )));
153
154 assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf()));
155 }
156
157 @Test
158 void multipleParameterDemandSetTest() {
159 var dnf = Dnf.of("SubQuery", builder -> {
160 var x = builder.parameter("x", ParameterDirection.IN);
161 var y = builder.parameter("y", ParameterDirection.IN);
162 builder.clause(not(friendView.call(x, y)));
163 builder.clause(not(friendView.call(y, x)));
164 });
165 var query = Query.of("Actual", (builder, p1) -> builder.clause(
166 not(dnf.call(p1, p1)),
167 personView.call(p1)
168 ));
169
170 var actual = sut.rewrite(query);
171
172 var expectedSubQuery = Dnf.of("ExpectedSubQuery", builder -> {
173 var x = builder.parameter("x", ParameterDirection.OUT);
174 var y = builder.parameter("y", ParameterDirection.OUT);
175 builder.clause(
176 y.isEquivalent(x),
177 personView.call(x),
178 not(friendView.call(x, x))
179 );
180 });
181 var expected = Query.of("Expected", (builder, p1) -> builder.clause(
182 personView.call(p1),
183 not(expectedSubQuery.call(p1, p1))
184 ));
185
186 assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf()));
187 }
188
189 @Test
190 void eliminateDoubleNegationTest() {
191 var dnf = Dnf.of("SubQuery", builder -> {
192 var x = builder.parameter("x", ParameterDirection.IN);
193 builder.clause(not(friendView.call(x, Variable.of())));
194 });
195 var query = Query.of("Actual", (builder, p1) -> builder.clause(
196 personView.call(p1),
197 not(dnf.call(p1))
198 ));
199
200 var actual = sut.rewrite(query);
201
202 var expected = Query.of("Actual", (builder, p1) -> builder.clause(
203 personView.call(p1),
204 friendView.call(p1, Variable.of())
205 ));
206
207 assertThat(actual.getDnf(), structurallyEqualTo(expected.getDnf()));
208 }
209
210 @Test
211 void identityWhenNoWorkToDoTest() {
212 var dnf = Dnf.of("SubQuery", builder -> {
213 var x = builder.parameter("x", ParameterDirection.OUT);
214 builder.clause(
215 personView.call(x),
216 not(friendView.call(x, Variable.of()))
217 );
218 });
219 var query = Query.of("Actual", (builder, p1) -> builder.clause(
220 personView.call(p1),
221 not(dnf.call(p1))
222 ));
223
224 var actual = sut.rewrite(query);
225
226 assertThat(actual, is(query));
227 }
228}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/TermSubstitutionTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/term/TermSubstitutionTest.java
deleted file mode 100644
index 1fae2492..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/TermSubstitutionTest.java
+++ /dev/null
@@ -1,97 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.term;
7
8import org.junit.jupiter.api.Assertions;
9import org.junit.jupiter.params.ParameterizedTest;
10import org.junit.jupiter.params.provider.Arguments;
11import org.junit.jupiter.params.provider.MethodSource;
12import tools.refinery.store.query.equality.DnfEqualityChecker;
13import tools.refinery.store.query.equality.SubstitutingLiteralEqualityHelper;
14import tools.refinery.store.query.substitution.Substitution;
15import tools.refinery.store.query.term.bool.BoolTerms;
16import tools.refinery.store.query.term.int_.IntTerms;
17import tools.refinery.store.query.term.real.RealTerms;
18import tools.refinery.store.query.term.uppercardinality.UpperCardinalityTerms;
19import tools.refinery.store.representation.cardinality.UpperCardinality;
20
21import java.util.List;
22import java.util.stream.Stream;
23
24class TermSubstitutionTest {
25 private final static DataVariable<Integer> intA = Variable.of("intA", Integer.class);
26 private final static DataVariable<Integer> intB = Variable.of("intB", Integer.class);
27 private final static DataVariable<Double> realA = Variable.of("realA", Double.class);
28 private final static DataVariable<Double> realB = Variable.of("realB", Double.class);
29 private final static DataVariable<Boolean> boolA = Variable.of("boolA", Boolean.class);
30 private final static DataVariable<Boolean> boolB = Variable.of("boolB", Boolean.class);
31 private final static DataVariable<UpperCardinality> upperCardinalityA = Variable.of("upperCardinalityA",
32 UpperCardinality.class);
33 private final static DataVariable<UpperCardinality> upperCardinalityB = Variable.of("upperCardinalityB",
34 UpperCardinality.class);
35 private final static Substitution substitution = Substitution.builder()
36 .put(intA, intB)
37 .put(intB, intA)
38 .put(realA, realB)
39 .put(realB, realA)
40 .put(boolA, boolB)
41 .put(boolB, boolA)
42 .put(upperCardinalityA, upperCardinalityB)
43 .put(upperCardinalityB, upperCardinalityA)
44 .build();
45
46 @ParameterizedTest
47 @MethodSource
48 void substitutionTest(AnyTerm term) {
49 var substitutedTerm1 = term.substitute(substitution);
50 Assertions.assertNotEquals(term, substitutedTerm1, "Original term is not equal to substituted term");
51 var helper = new SubstitutingLiteralEqualityHelper(DnfEqualityChecker.DEFAULT, List.of(), List.of());
52 Assertions.assertTrue(term.equalsWithSubstitution(helper, substitutedTerm1), "Terms are equal by helper");
53 // The {@link #substitution} is its own inverse.
54 var substitutedTerm2 = substitutedTerm1.substitute(substitution);
55 Assertions.assertEquals(term, substitutedTerm2, "Original term is not equal to back-substituted term");
56 }
57
58 static Stream<Arguments> substitutionTest() {
59 return Stream.of(
60 Arguments.of(IntTerms.plus(intA)),
61 Arguments.of(IntTerms.minus(intA)),
62 Arguments.of(IntTerms.add(intA, intB)),
63 Arguments.of(IntTerms.sub(intA, intB)),
64 Arguments.of(IntTerms.mul(intA, intB)),
65 Arguments.of(IntTerms.div(intA, intB)),
66 Arguments.of(IntTerms.pow(intA, intB)),
67 Arguments.of(IntTerms.min(intA, intB)),
68 Arguments.of(IntTerms.max(intA, intB)),
69 Arguments.of(IntTerms.eq(intA, intB)),
70 Arguments.of(IntTerms.notEq(intA, intB)),
71 Arguments.of(IntTerms.less(intA, intB)),
72 Arguments.of(IntTerms.lessEq(intA, intB)),
73 Arguments.of(IntTerms.greater(intA, intB)),
74 Arguments.of(IntTerms.greaterEq(intA, intB)),
75 Arguments.of(IntTerms.asInt(realA)),
76 Arguments.of(RealTerms.plus(realA)),
77 Arguments.of(RealTerms.minus(realA)),
78 Arguments.of(RealTerms.add(realA, realB)),
79 Arguments.of(RealTerms.sub(realA, realB)),
80 Arguments.of(RealTerms.mul(realA, realB)),
81 Arguments.of(RealTerms.div(realA, realB)),
82 Arguments.of(RealTerms.pow(realA, realB)),
83 Arguments.of(RealTerms.min(realA, realB)),
84 Arguments.of(RealTerms.max(realA, realB)),
85 Arguments.of(RealTerms.asReal(intA)),
86 Arguments.of(BoolTerms.not(boolA)),
87 Arguments.of(BoolTerms.and(boolA, boolB)),
88 Arguments.of(BoolTerms.or(boolA, boolB)),
89 Arguments.of(BoolTerms.xor(boolA, boolB)),
90 Arguments.of(RealTerms.eq(realA, realB)),
91 Arguments.of(UpperCardinalityTerms.add(upperCardinalityA, upperCardinalityB)),
92 Arguments.of(UpperCardinalityTerms.mul(upperCardinalityA, upperCardinalityB)),
93 Arguments.of(UpperCardinalityTerms.min(upperCardinalityA, upperCardinalityB)),
94 Arguments.of(UpperCardinalityTerms.max(upperCardinalityA, upperCardinalityB))
95 );
96 }
97}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/bool/BoolTermsEvaluateTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/term/bool/BoolTermsEvaluateTest.java
deleted file mode 100644
index beff705e..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/bool/BoolTermsEvaluateTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.term.bool;
7
8import org.junit.jupiter.params.ParameterizedTest;
9import org.junit.jupiter.params.provider.CsvSource;
10import tools.refinery.store.query.valuation.Valuation;
11
12import static org.hamcrest.MatcherAssert.assertThat;
13import static org.hamcrest.Matchers.is;
14
15class BoolTermsEvaluateTest {
16 @ParameterizedTest(name = "!{0} == {1}")
17 @CsvSource(value = {
18 "false, true",
19 "true, false",
20 "null, null"
21 }, nullValues = "null")
22 void notTest(Boolean a, Boolean result) {
23 var term = BoolTerms.not(BoolTerms.constant(a));
24 assertThat(term.getType(), is(Boolean.class));
25 assertThat(term.evaluate(Valuation.empty()), is(result));
26 }
27
28 @ParameterizedTest(name = "{0} && {1} == {2}")
29 @CsvSource(value = {
30 "false, false, false",
31 "false, true, false",
32 "true, false, false",
33 "true, true, true",
34 "false, null, null",
35 "null, false, null",
36 "null, null, null"
37 }, nullValues = "null")
38 void andTest(Boolean a, Boolean b, Boolean result) {
39 var term = BoolTerms.and(BoolTerms.constant(a), BoolTerms.constant(b));
40 assertThat(term.getType(), is(Boolean.class));
41 assertThat(term.evaluate(Valuation.empty()), is(result));
42 }
43
44 @ParameterizedTest(name = "{0} || {1} == {2}")
45 @CsvSource(value = {
46 "false, false, false",
47 "false, true, true",
48 "true, false, true",
49 "true, true, true",
50 "true, null, null",
51 "null, true, null",
52 "null, null, null"
53 }, nullValues = "null")
54 void orTest(Boolean a, Boolean b, Boolean result) {
55 var term = BoolTerms.or(BoolTerms.constant(a), BoolTerms.constant(b));
56 assertThat(term.getType(), is(Boolean.class));
57 assertThat(term.evaluate(Valuation.empty()), is(result));
58 }
59
60 @ParameterizedTest(name = "{0} ^^ {1} == {2}")
61 @CsvSource(value = {
62 "false, false, false",
63 "false, true, true",
64 "true, false, true",
65 "true, true, false",
66 "false, null, null",
67 "null, false, null",
68 "null, null, null"
69 }, nullValues = "null")
70 void xorTest(Boolean a, Boolean b, Boolean result) {
71 var term = BoolTerms.xor(BoolTerms.constant(a), BoolTerms.constant(b));
72 assertThat(term.getType(), is(Boolean.class));
73 assertThat(term.evaluate(Valuation.empty()), is(result));
74 }
75}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/int_/IntTermsEvaluateTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/term/int_/IntTermsEvaluateTest.java
deleted file mode 100644
index abe50d75..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/int_/IntTermsEvaluateTest.java
+++ /dev/null
@@ -1,259 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.term.int_;
7
8import org.junit.jupiter.params.ParameterizedTest;
9import org.junit.jupiter.params.provider.Arguments;
10import org.junit.jupiter.params.provider.CsvSource;
11import org.junit.jupiter.params.provider.MethodSource;
12import tools.refinery.store.query.term.real.RealTerms;
13import tools.refinery.store.query.valuation.Valuation;
14
15import java.util.stream.Stream;
16
17import static org.hamcrest.Matchers.is;
18import static org.hamcrest.MatcherAssert.assertThat;
19
20class IntTermsEvaluateTest {
21 @ParameterizedTest(name = "+{0} == {1}")
22 @CsvSource(value = {
23 "2, 2",
24 "null, null"
25 }, nullValues = "null")
26 void plusTest(Integer a, Integer result) {
27 var term = IntTerms.plus(IntTerms.constant(a));
28 assertThat(term.getType(), is(Integer.class));
29 assertThat(term.evaluate(Valuation.empty()), is(result));
30 }
31
32 @ParameterizedTest(name = "-{0} == {1}")
33 @CsvSource(value = {
34 "2, -2",
35 "null, null"
36 }, nullValues = "null")
37 void minusTest(Integer a, Integer result) {
38 var term = IntTerms.minus(IntTerms.constant(a));
39 assertThat(term.getType(), is(Integer.class));
40 assertThat(term.evaluate(Valuation.empty()), is(result));
41 }
42
43 @ParameterizedTest(name = "{0} + {1} == {2}")
44 @CsvSource(value = {
45 "1, 2, 3",
46 "null, 2, null",
47 "1, null, null",
48 "null, null, null"
49 }, nullValues = "null")
50 void addTest(Integer a, Integer b, Integer result) {
51 var term = IntTerms.add(IntTerms.constant(a), IntTerms.constant(b));
52 assertThat(term.getType(), is(Integer.class));
53 assertThat(term.evaluate(Valuation.empty()), is(result));
54 }
55
56 @ParameterizedTest(name = "{0} - {1} == {2}")
57 @CsvSource(value = {
58 "1, 3, -2",
59 "null, 3, null",
60 "1, null, null",
61 "null, null, null"
62 }, nullValues = "null")
63 void subTest(Integer a, Integer b, Integer result) {
64 var term = IntTerms.sub(IntTerms.constant(a), IntTerms.constant(b));
65 assertThat(term.getType(), is(Integer.class));
66 assertThat(term.evaluate(Valuation.empty()), is(result));
67 }
68
69 @ParameterizedTest(name = "{0} * {1} == {2}")
70 @CsvSource(value = {
71 "2, 3, 6",
72 "null, 3, null",
73 "2, null, null",
74 "null, null, null"
75 }, nullValues = "null")
76 void mulTest(Integer a, Integer b, Integer result) {
77 var term = IntTerms.mul(IntTerms.constant(a), IntTerms.constant(b));
78 assertThat(term.getType(), is(Integer.class));
79 assertThat(term.evaluate(Valuation.empty()), is(result));
80 }
81
82 @ParameterizedTest(name = "{0} * {1} == {2}")
83 @CsvSource(value = {
84 "6, 3, 2",
85 "7, 3, 2",
86 "6, 0, null",
87 "null, 3, null",
88 "6, null, null",
89 "null, null, null"
90 }, nullValues = "null")
91 void divTest(Integer a, Integer b, Integer result) {
92 var term = IntTerms.div(IntTerms.constant(a), IntTerms.constant(b));
93 assertThat(term.getType(), is(Integer.class));
94 assertThat(term.evaluate(Valuation.empty()), is(result));
95 }
96
97 @ParameterizedTest(name = "{0} ** {1} == {2}")
98 @CsvSource(value = {
99 "1, 0, 1",
100 "1, 3, 1",
101 "1, -3, null",
102 "2, 0, 1",
103 "2, 2, 4",
104 "2, 3, 8",
105 "2, 4, 16",
106 "2, 5, 32",
107 "2, 6, 64",
108 "2, -3, null",
109 "null, 3, null",
110 "2, null, null",
111 "null, null, null"
112 }, nullValues = "null")
113 void powTest(Integer a, Integer b, Integer result) {
114 var term = IntTerms.pow(IntTerms.constant(a), IntTerms.constant(b));
115 assertThat(term.getType(), is(Integer.class));
116 assertThat(term.evaluate(Valuation.empty()), is(result));
117 }
118
119 @ParameterizedTest(name = "min({0}, {1}) == {2}")
120 @CsvSource(value = {
121 "1, 2, 1",
122 "2, 1, 1",
123 "null, 2, null",
124 "1, null, null",
125 "null, null, null"
126 }, nullValues = "null")
127 void minTest(Integer a, Integer b, Integer result) {
128 var term = IntTerms.min(IntTerms.constant(a), IntTerms.constant(b));
129 assertThat(term.getType(), is(Integer.class));
130 assertThat(term.evaluate(Valuation.empty()), is(result));
131 }
132
133 @ParameterizedTest(name = "max({0}, {1}) == {2}")
134 @CsvSource(value = {
135 "1, 2, 2",
136 "2, 1, 2",
137 "null, 2, null",
138 "1, null, null",
139 "null, null, null"
140 }, nullValues = "null")
141 void maxTest(Integer a, Integer b, Integer result) {
142 var term = IntTerms.max(IntTerms.constant(a), IntTerms.constant(b));
143 assertThat(term.getType(), is(Integer.class));
144 assertThat(term.evaluate(Valuation.empty()), is(result));
145 }
146
147 @ParameterizedTest(name = "({0} == {1}) == {2}")
148 @CsvSource(value = {
149 "1, 1, true",
150 "1, 2, false",
151 "null, 1, null",
152 "1, null, null",
153 "null, null, null"
154 }, nullValues = "null")
155 void eqTest(Integer a, Integer b, Boolean result) {
156 var term = IntTerms.eq(IntTerms.constant(a), IntTerms.constant(b));
157 assertThat(term.getType(), is(Boolean.class));
158 assertThat(term.evaluate(Valuation.empty()), is(result));
159 }
160
161 @ParameterizedTest(name = "({0} != {1}) == {2}")
162 @CsvSource(value = {
163 "1, 1, false",
164 "1, 2, true",
165 "null, 1, null",
166 "1, null, null",
167 "null, null, null"
168 }, nullValues = "null")
169 void notEqTest(Integer a, Integer b, Boolean result) {
170 var term = IntTerms.notEq(IntTerms.constant(a), IntTerms.constant(b));
171 assertThat(term.getType(), is(Boolean.class));
172 assertThat(term.evaluate(Valuation.empty()), is(result));
173 }
174
175 @ParameterizedTest(name = "({0} < {1}) == {2}")
176 @CsvSource(value = {
177 "1, -2, false",
178 "1, 1, false",
179 "1, 2, true",
180 "null, 1, null",
181 "1, null, null",
182 "null, null, null"
183 }, nullValues = "null")
184 void lessTest(Integer a, Integer b, Boolean result) {
185 var term = IntTerms.less(IntTerms.constant(a), IntTerms.constant(b));
186 assertThat(term.getType(), is(Boolean.class));
187 assertThat(term.evaluate(Valuation.empty()), is(result));
188 }
189
190 @ParameterizedTest(name = "({0} <= {1}) == {2}")
191 @CsvSource(value = {
192 "1, -2, false",
193 "1, 1, true",
194 "1, 2, true",
195 "null, 1, null",
196 "1, null, null",
197 "null, null, null"
198 }, nullValues = "null")
199 void lessEqTest(Integer a, Integer b, Boolean result) {
200 var term = IntTerms.lessEq(IntTerms.constant(a), IntTerms.constant(b));
201 assertThat(term.getType(), is(Boolean.class));
202 assertThat(term.evaluate(Valuation.empty()), is(result));
203 }
204
205 @ParameterizedTest(name = "({0} > {1}) == {2}")
206 @CsvSource(value = {
207 "1, -2, true",
208 "1, 1, false",
209 "1, 2, false",
210 "null, 1, null",
211 "1, null, null",
212 "null, null, null"
213 }, nullValues = "null")
214 void greaterTest(Integer a, Integer b, Boolean result) {
215 var term = IntTerms.greater(IntTerms.constant(a), IntTerms.constant(b));
216 assertThat(term.getType(), is(Boolean.class));
217 assertThat(term.evaluate(Valuation.empty()), is(result));
218 }
219
220 @ParameterizedTest(name = "({0} >= {1}) == {2}")
221 @CsvSource(value = {
222 "1, -2, true",
223 "1, 1, true",
224 "1, 2, false",
225 "null, 1, null",
226 "1, null, null",
227 "null, null, null"
228 }, nullValues = "null")
229 void greaterEqTest(Integer a, Integer b, Boolean result) {
230 var term = IntTerms.greaterEq(IntTerms.constant(a), IntTerms.constant(b));
231 assertThat(term.getType(), is(Boolean.class));
232 assertThat(term.evaluate(Valuation.empty()), is(result));
233 }
234
235 @ParameterizedTest(name = "{0} as int == {1}")
236 @MethodSource
237 void asIntTest(Double a, Integer result) {
238 var term = IntTerms.asInt(RealTerms.constant(a));
239 assertThat(term.getType(), is(Integer.class));
240 assertThat(term.evaluate(Valuation.empty()), is(result));
241 }
242
243 static Stream<Arguments> asIntTest() {
244 return Stream.of(
245 Arguments.of(2.0, 2),
246 Arguments.of(2.1, 2),
247 Arguments.of(2.9, 2),
248 Arguments.of(-2.0, -2),
249 Arguments.of(-2.1, -2),
250 Arguments.of(-2.9, -2),
251 Arguments.of(0.0, 0),
252 Arguments.of(-0.0, 0),
253 Arguments.of(Double.POSITIVE_INFINITY, Integer.MAX_VALUE),
254 Arguments.of(Double.NEGATIVE_INFINITY, Integer.MIN_VALUE),
255 Arguments.of(Double.NaN, null),
256 Arguments.of(null, null)
257 );
258 }
259}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/real/RealTermEvaluateTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/term/real/RealTermEvaluateTest.java
deleted file mode 100644
index 6a8eebf1..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/real/RealTermEvaluateTest.java
+++ /dev/null
@@ -1,238 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.term.real;
7
8import org.hamcrest.Matcher;
9import org.junit.jupiter.params.ParameterizedTest;
10import org.junit.jupiter.params.provider.CsvSource;
11import tools.refinery.store.query.term.int_.IntTerms;
12import tools.refinery.store.query.valuation.Valuation;
13
14import static org.hamcrest.MatcherAssert.assertThat;
15import static org.hamcrest.Matchers.*;
16
17class RealTermEvaluateTest {
18 public static final double TOLERANCE = 1e-6;
19
20 private static Matcher<Double> closeToOrNull(Double expected) {
21 return expected == null ? nullValue(Double.class) : closeTo(expected, TOLERANCE);
22 }
23
24 @ParameterizedTest(name = "+{0} == {1}")
25 @CsvSource(value = {
26 "2.5, 2.5",
27 "null, null"
28 }, nullValues = "null")
29 void plusTest(Double a, Double result) {
30 var term = RealTerms.plus(RealTerms.constant(a));
31 assertThat(term.getType(), is(Double.class));
32 assertThat(term.evaluate(Valuation.empty()), closeToOrNull(result));
33 }
34
35 @ParameterizedTest(name = "-{0} == {1}")
36 @CsvSource(value = {
37 "2.5, -2.5",
38 "null, null"
39 }, nullValues = "null")
40 void minusTest(Double a, Double result) {
41 var term = RealTerms.minus(RealTerms.constant(a));
42 assertThat(term.getType(), is(Double.class));
43 assertThat(term.evaluate(Valuation.empty()), closeToOrNull(result));
44 }
45
46 @ParameterizedTest(name = "{0} + {1} == {2}")
47 @CsvSource(value = {
48 "1.2, 2.3, 3.5",
49 "null, 2.3, null",
50 "1.2, null, null",
51 "null, null, null"
52 }, nullValues = "null")
53 void addTest(Double a, Double b, Double result) {
54 var term = RealTerms.add(RealTerms.constant(a), RealTerms.constant(b));
55 assertThat(term.getType(), is(Double.class));
56 assertThat(term.evaluate(Valuation.empty()), closeToOrNull(result));
57 }
58
59 @ParameterizedTest(name = "{0} - {1} == {2}")
60 @CsvSource(value = {
61 "1.2, 3.4, -2.2",
62 "null, 3.4, null",
63 "1.2, null, null",
64 "null, null, null"
65 }, nullValues = "null")
66 void subTest(Double a, Double b, Double result) {
67 var term = RealTerms.sub(RealTerms.constant(a), RealTerms.constant(b));
68 assertThat(term.getType(), is(Double.class));
69 assertThat(term.evaluate(Valuation.empty()), closeToOrNull(result));
70 }
71
72 @ParameterizedTest(name = "{0} * {1} == {2}")
73 @CsvSource(value = {
74 "2.3, 3.4, 7.82",
75 "null, 3.4, null",
76 "2.3, null, null",
77 "null, null, null"
78 }, nullValues = "null")
79 void mulTest(Double a, Double b, Double result) {
80 var term = RealTerms.mul(RealTerms.constant(a), RealTerms.constant(b));
81 assertThat(term.getType(), is(Double.class));
82 assertThat(term.evaluate(Valuation.empty()), closeToOrNull(result));
83 }
84
85 @ParameterizedTest(name = "{0} * {1} == {2}")
86 @CsvSource(value = {
87 "7.82, 3.4, 2.3",
88 "null, 3.4, null",
89 "7.82, null, null",
90 "null, null, null"
91 }, nullValues = "null")
92 void divTest(Double a, Double b, Double result) {
93 var term = RealTerms.div(RealTerms.constant(a), RealTerms.constant(b));
94 assertThat(term.getType(), is(Double.class));
95 assertThat(term.evaluate(Valuation.empty()), closeToOrNull(result));
96 }
97
98 @ParameterizedTest(name = "{0} ** {1} == {2}")
99 @CsvSource(value = {
100 "2.0, 6.0, 64.0",
101 "null, 6.0, null",
102 "2.0, null, null",
103 "null, null, null"
104 }, nullValues = "null")
105 void powTest(Double a, Double b, Double result) {
106 var term = RealTerms.pow(RealTerms.constant(a), RealTerms.constant(b));
107 assertThat(term.getType(), is(Double.class));
108 assertThat(term.evaluate(Valuation.empty()), closeToOrNull(result));
109 }
110
111 @ParameterizedTest(name = "min({0}, {1}) == {2}")
112 @CsvSource(value = {
113 "1.5, 2.7, 1.5",
114 "2.7, 1.5, 1.5",
115 "null, 2.7, null",
116 "1.5, null, null",
117 "null, null, null"
118 }, nullValues = "null")
119 void minTest(Double a, Double b, Double result) {
120 var term = RealTerms.min(RealTerms.constant(a), RealTerms.constant(b));
121 assertThat(term.getType(), is(Double.class));
122 assertThat(term.evaluate(Valuation.empty()), closeToOrNull(result));
123 }
124
125 @ParameterizedTest(name = "max({0}, {1}) == {2}")
126 @CsvSource(value = {
127 "1.5, 2.7, 2.7",
128 "2.7, 1.7, 2.7",
129 "null, 2.7, null",
130 "1.5, null, null",
131 "null, null, null"
132 }, nullValues = "null")
133 void maxTest(Double a, Double b, Double result) {
134 var term = RealTerms.max(RealTerms.constant(a), RealTerms.constant(b));
135 assertThat(term.getType(), is(Double.class));
136 assertThat(term.evaluate(Valuation.empty()), closeToOrNull(result));
137 }
138
139 @ParameterizedTest(name = "({0} == {1}) == {2}")
140 @CsvSource(value = {
141 "1.5, 1.5, true",
142 "1.5, 2.7, false",
143 "null, 1.5, null",
144 "1.5, null, null",
145 "null, null, null"
146 }, nullValues = "null")
147 void eqTest(Double a, Double b, Boolean result) {
148 var term = RealTerms.eq(RealTerms.constant(a), RealTerms.constant(b));
149 assertThat(term.getType(), is(Boolean.class));
150 assertThat(term.evaluate(Valuation.empty()), is(result));
151 }
152
153 @ParameterizedTest(name = "({0} != {1}) == {2}")
154 @CsvSource(value = {
155 "1.5, 1.5, false",
156 "1.5, 2.7, true",
157 "null, 1.5, null",
158 "1.5, null, null",
159 "null, null, null"
160 }, nullValues = "null")
161 void notEqTest(Double a, Double b, Boolean result) {
162 var term = RealTerms.notEq(RealTerms.constant(a), RealTerms.constant(b));
163 assertThat(term.getType(), is(Boolean.class));
164 assertThat(term.evaluate(Valuation.empty()), is(result));
165 }
166
167 @ParameterizedTest(name = "({0} < {1}) == {2}")
168 @CsvSource(value = {
169 "1.5, -2.7, false",
170 "1.5, 1.5, false",
171 "1.5, 2.7, true",
172 "null, 1.5, null",
173 "1.5, null, null",
174 "null, null, null"
175 }, nullValues = "null")
176 void lessTest(Double a, Double b, Boolean result) {
177 var term = RealTerms.less(RealTerms.constant(a), RealTerms.constant(b));
178 assertThat(term.getType(), is(Boolean.class));
179 assertThat(term.evaluate(Valuation.empty()), is(result));
180 }
181
182 @ParameterizedTest(name = "({0} <= {1}) == {2}")
183 @CsvSource(value = {
184 "1.5, -2.7, false",
185 "1.5, 1.5, true",
186 "1.5, 2.7, true",
187 "null, 1.5, null",
188 "1.5, null, null",
189 "null, null, null"
190 }, nullValues = "null")
191 void lessEqTest(Double a, Double b, Boolean result) {
192 var term = RealTerms.lessEq(RealTerms.constant(a), RealTerms.constant(b));
193 assertThat(term.getType(), is(Boolean.class));
194 assertThat(term.evaluate(Valuation.empty()), is(result));
195 }
196
197 @ParameterizedTest(name = "({0} > {1}) == {2}")
198 @CsvSource(value = {
199 "1.5, -2.7, true",
200 "1.5, 1.5, false",
201 "1.5, 2.7, false",
202 "null, 1.5, null",
203 "1.5, null, null",
204 "null, null, null"
205 }, nullValues = "null")
206 void greaterTest(Double a, Double b, Boolean result) {
207 var term = RealTerms.greater(RealTerms.constant(a), RealTerms.constant(b));
208 assertThat(term.getType(), is(Boolean.class));
209 assertThat(term.evaluate(Valuation.empty()), is(result));
210 }
211
212 @ParameterizedTest(name = "({0} >= {1}) == {2}")
213 @CsvSource(value = {
214 "1.5, -2.7, true",
215 "1.5, 1.5, true",
216 "1.5, 2.7, false",
217 "null, 1.5, null",
218 "1.5, null, null",
219 "null, null, null"
220 }, nullValues = "null")
221 void greaterEqTest(Double a, Double b, Boolean result) {
222 var term = RealTerms.greaterEq(RealTerms.constant(a), RealTerms.constant(b));
223 assertThat(term.getType(), is(Boolean.class));
224 assertThat(term.evaluate(Valuation.empty()), is(result));
225 }
226
227 @ParameterizedTest(name = "{0} as real == {1}")
228 @CsvSource(value = {
229 "0, 0.0",
230 "5, 5.0",
231 "null, null"
232 }, nullValues = "null")
233 void asRealTest(Integer a, Double result) {
234 var term = RealTerms.asReal(IntTerms.constant(a));
235 assertThat(term.getType(), is(Double.class));
236 assertThat(term.evaluate(Valuation.empty()), closeToOrNull(result));
237 }
238}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorStreamTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorStreamTest.java
deleted file mode 100644
index 31baf36e..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorStreamTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.term.uppercardinality;
7
8import org.junit.jupiter.params.ParameterizedTest;
9import org.junit.jupiter.params.provider.Arguments;
10import org.junit.jupiter.params.provider.MethodSource;
11import tools.refinery.store.representation.cardinality.UpperCardinalities;
12import tools.refinery.store.representation.cardinality.UpperCardinality;
13
14import java.util.List;
15import java.util.stream.Stream;
16
17import static org.hamcrest.MatcherAssert.assertThat;
18import static org.hamcrest.Matchers.is;
19
20class UpperCardinalitySumAggregatorStreamTest {
21 @ParameterizedTest
22 @MethodSource
23 void testStream(List<UpperCardinality> list, UpperCardinality expected) {
24 var result = UpperCardinalitySumAggregator.INSTANCE.aggregateStream(list.stream());
25 assertThat(result, is(expected));
26 }
27
28 static Stream<Arguments> testStream() {
29 return Stream.of(
30 Arguments.of(List.of(), UpperCardinalities.ZERO),
31 Arguments.of(List.of(UpperCardinality.of(3)), UpperCardinality.of(3)),
32 Arguments.of(
33 List.of(
34 UpperCardinality.of(2),
35 UpperCardinality.of(3)
36 ),
37 UpperCardinality.of(5)
38 ),
39 Arguments.of(List.of(UpperCardinalities.UNBOUNDED), UpperCardinalities.UNBOUNDED),
40 Arguments.of(
41 List.of(
42 UpperCardinalities.UNBOUNDED,
43 UpperCardinalities.UNBOUNDED
44 ),
45 UpperCardinalities.UNBOUNDED
46 ),
47 Arguments.of(
48 List.of(
49 UpperCardinalities.UNBOUNDED,
50 UpperCardinality.of(3)
51 ),
52 UpperCardinalities.UNBOUNDED
53 )
54 );
55 }
56}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorTest.java
deleted file mode 100644
index 780cd0ab..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalitySumAggregatorTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.term.uppercardinality;
7
8import org.junit.jupiter.api.BeforeEach;
9import org.junit.jupiter.api.Test;
10import tools.refinery.store.query.term.StatefulAggregate;
11import tools.refinery.store.representation.cardinality.UpperCardinalities;
12import tools.refinery.store.representation.cardinality.UpperCardinality;
13
14import static org.hamcrest.MatcherAssert.assertThat;
15import static org.hamcrest.Matchers.is;
16
17class UpperCardinalitySumAggregatorTest {
18 private StatefulAggregate<UpperCardinality, UpperCardinality> accumulator;
19
20 @BeforeEach
21 void beforeEach() {
22 accumulator = UpperCardinalitySumAggregator.INSTANCE.createEmptyAggregate();
23 }
24
25 @Test
26 void emptyAggregationTest() {
27 assertThat(accumulator.getResult(), is(UpperCardinality.of(0)));
28 }
29
30 @Test
31 void singleBoundedTest() {
32 accumulator.add(UpperCardinality.of(3));
33 assertThat(accumulator.getResult(), is(UpperCardinality.of(3)));
34 }
35
36 @Test
37 void multipleBoundedTest() {
38 accumulator.add(UpperCardinality.of(2));
39 accumulator.add(UpperCardinality.of(3));
40 assertThat(accumulator.getResult(), is(UpperCardinality.of(5)));
41 }
42
43 @Test
44 void singleUnboundedTest() {
45 accumulator.add(UpperCardinalities.UNBOUNDED);
46 assertThat(accumulator.getResult(), is(UpperCardinalities.UNBOUNDED));
47 }
48
49 @Test
50 void multipleUnboundedTest() {
51 accumulator.add(UpperCardinalities.UNBOUNDED);
52 accumulator.add(UpperCardinalities.UNBOUNDED);
53 assertThat(accumulator.getResult(), is(UpperCardinalities.UNBOUNDED));
54 }
55
56 @Test
57 void removeBoundedTest() {
58 accumulator.add(UpperCardinality.of(2));
59 accumulator.add(UpperCardinality.of(3));
60 accumulator.remove(UpperCardinality.of(2));
61 assertThat(accumulator.getResult(), is(UpperCardinality.of(3)));
62 }
63
64 @Test
65 void removeAllUnboundedTest() {
66 accumulator.add(UpperCardinalities.UNBOUNDED);
67 accumulator.add(UpperCardinality.of(3));
68 accumulator.remove(UpperCardinalities.UNBOUNDED);
69 assertThat(accumulator.getResult(), is(UpperCardinality.of(3)));
70 }
71
72 @Test
73 void removeSomeUnboundedTest() {
74 accumulator.add(UpperCardinalities.UNBOUNDED);
75 accumulator.add(UpperCardinalities.UNBOUNDED);
76 accumulator.add(UpperCardinality.of(3));
77 accumulator.remove(UpperCardinalities.UNBOUNDED);
78 assertThat(accumulator.getResult(), is(UpperCardinalities.UNBOUNDED));
79 }
80}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityTermsEvaluateTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityTermsEvaluateTest.java
deleted file mode 100644
index 9d0f3bde..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/term/uppercardinality/UpperCardinalityTermsEvaluateTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.term.uppercardinality;
7
8import org.junit.jupiter.params.ParameterizedTest;
9import org.junit.jupiter.params.provider.Arguments;
10import org.junit.jupiter.params.provider.MethodSource;
11import tools.refinery.store.query.valuation.Valuation;
12import tools.refinery.store.representation.cardinality.UpperCardinalities;
13import tools.refinery.store.representation.cardinality.UpperCardinality;
14
15import java.util.stream.Stream;
16
17import static org.hamcrest.MatcherAssert.assertThat;
18import static org.hamcrest.Matchers.is;
19
20class UpperCardinalityTermsEvaluateTest {
21 @ParameterizedTest(name = "min({0}, {1}) == {2}")
22 @MethodSource
23 void minTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) {
24 var term = UpperCardinalityTerms.min(UpperCardinalityTerms.constant(a), UpperCardinalityTerms.constant(b));
25 assertThat(term.getType(), is(UpperCardinality.class));
26 assertThat(term.evaluate(Valuation.empty()), is(expected));
27 }
28
29 static Stream<Arguments> minTest() {
30 return Stream.of(
31 Arguments.of(UpperCardinality.of(0), UpperCardinality.of(0), UpperCardinality.of(0)),
32 Arguments.of(UpperCardinality.of(0), UpperCardinality.of(1), UpperCardinality.of(0)),
33 Arguments.of(UpperCardinality.of(1), UpperCardinality.of(0), UpperCardinality.of(0)),
34 Arguments.of(UpperCardinality.of(0), UpperCardinalities.UNBOUNDED, UpperCardinality.of(0)),
35 Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(0), UpperCardinality.of(0)),
36 Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED),
37 Arguments.of(UpperCardinality.of(1), null, null),
38 Arguments.of(null, UpperCardinality.of(1), null),
39 Arguments.of(null, null, null)
40 );
41 }
42
43 @ParameterizedTest(name = "max({0}, {1}) == {2}")
44 @MethodSource
45 void maxTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) {
46 var term = UpperCardinalityTerms.max(UpperCardinalityTerms.constant(a), UpperCardinalityTerms.constant(b));
47 assertThat(term.getType(), is(UpperCardinality.class));
48 assertThat(term.evaluate(Valuation.empty()), is(expected));
49 }
50
51 static Stream<Arguments> maxTest() {
52 return Stream.of(
53 Arguments.of(UpperCardinality.of(0), UpperCardinality.of(0), UpperCardinality.of(0)),
54 Arguments.of(UpperCardinality.of(0), UpperCardinality.of(1), UpperCardinality.of(1)),
55 Arguments.of(UpperCardinality.of(1), UpperCardinality.of(0), UpperCardinality.of(1)),
56 Arguments.of(UpperCardinality.of(0), UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED),
57 Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(0), UpperCardinalities.UNBOUNDED),
58 Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED),
59 Arguments.of(UpperCardinality.of(1), null, null),
60 Arguments.of(null, UpperCardinality.of(1), null),
61 Arguments.of(null, null, null)
62 );
63 }
64
65 @ParameterizedTest(name = "{0} + {1} == {2}")
66 @MethodSource
67 void addTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) {
68 var term = UpperCardinalityTerms.add(UpperCardinalityTerms.constant(a), UpperCardinalityTerms.constant(b));
69 assertThat(term.getType(), is(UpperCardinality.class));
70 assertThat(term.evaluate(Valuation.empty()), is(expected));
71 }
72
73 static Stream<Arguments> addTest() {
74 return Stream.of(
75 Arguments.of(UpperCardinality.of(2), UpperCardinality.of(3), UpperCardinality.of(5)),
76 Arguments.of(UpperCardinality.of(2), UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED),
77 Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(2), UpperCardinalities.UNBOUNDED),
78 Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED),
79 Arguments.of(UpperCardinality.of(1), null, null),
80 Arguments.of(null, UpperCardinality.of(1), null),
81 Arguments.of(null, null, null)
82 );
83 }
84
85 @ParameterizedTest(name = "{0} * {1} == {2}")
86 @MethodSource
87 void mulTest(UpperCardinality a, UpperCardinality b, UpperCardinality expected) {
88 var term = UpperCardinalityTerms.mul(UpperCardinalityTerms.constant(a), UpperCardinalityTerms.constant(b));
89 assertThat(term.getType(), is(UpperCardinality.class));
90 assertThat(term.evaluate(Valuation.empty()), is(expected));
91 }
92
93 static Stream<Arguments> mulTest() {
94 return Stream.of(
95 Arguments.of(UpperCardinality.of(2), UpperCardinality.of(3), UpperCardinality.of(6)),
96 Arguments.of(UpperCardinality.of(2), UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED),
97 Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinality.of(2), UpperCardinalities.UNBOUNDED),
98 Arguments.of(UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED, UpperCardinalities.UNBOUNDED),
99 Arguments.of(UpperCardinality.of(1), null, null),
100 Arguments.of(null, UpperCardinality.of(1), null),
101 Arguments.of(null, null, null)
102 );
103 }
104}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToRawTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToRawTest.java
deleted file mode 100644
index d447e99c..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToRawTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.tests;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.dnf.Dnf;
10import tools.refinery.store.query.dnf.SymbolicParameter;
11import tools.refinery.store.query.term.NodeVariable;
12import tools.refinery.store.query.term.ParameterDirection;
13import tools.refinery.store.query.term.Variable;
14import tools.refinery.store.query.view.AnySymbolView;
15import tools.refinery.store.query.view.KeyOnlyView;
16import tools.refinery.store.representation.Symbol;
17
18import java.util.List;
19
20import static org.hamcrest.CoreMatchers.containsString;
21import static org.hamcrest.MatcherAssert.assertThat;
22import static org.hamcrest.Matchers.allOf;
23import static org.junit.jupiter.api.Assertions.assertThrows;
24import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo;
25
26class StructurallyEqualToRawTest {
27 private static final Symbol<Boolean> person = Symbol.of("Person", 1);
28 private static final Symbol<Boolean> friend = Symbol.of("friend", 2);
29 private static final AnySymbolView personView = new KeyOnlyView<>(person);
30 private static final AnySymbolView friendView = new KeyOnlyView<>(friend);
31 private static final NodeVariable p = Variable.of("p");
32 private static final NodeVariable q = Variable.of("q");
33
34 @Test
35 void flatEqualsTest() {
36 var actual = Dnf.builder("Actual").parameters(p).clause(personView.call(p)).build();
37
38 assertThat(actual, structurallyEqualTo(
39 List.of(new SymbolicParameter(q, ParameterDirection.OUT)),
40 List.of(List.of(personView.call(q)))
41 ));
42 }
43
44 @Test
45 void flatNotEqualsTest() {
46 var actual = Dnf.builder("Actual").parameters(p).clause(friendView.call(p, q)).build();
47
48 var assertion = structurallyEqualTo(
49 List.of(new SymbolicParameter(q, ParameterDirection.OUT)),
50 List.of(List.of(friendView.call(q, q)))
51 );
52 assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
53 }
54
55 @Test
56 void deepEqualsTest() {
57 var actual = Dnf.builder("Actual").parameters(q).clause(
58 Dnf.builder("Actual2").parameters(p).clause(personView.call(p)).build().call(q)
59 ).build();
60
61 assertThat(actual, structurallyEqualTo(
62 List.of(new SymbolicParameter(q, ParameterDirection.OUT)),
63 List.of(
64 List.of(
65 Dnf.builder("Expected2").parameters(p).clause(personView.call(p)).build().call(q)
66 )
67 )
68 ));
69 }
70
71 @Test
72 void deepNotEqualsTest() {
73 var actual = Dnf.builder("Actual").parameter(q).clause(
74 Dnf.builder("Actual2").parameters(p).clause(friendView.call(p, q)).build().call(q)
75 ).build();
76
77 var assertion = structurallyEqualTo(
78 List.of(new SymbolicParameter(q, ParameterDirection.OUT)),
79 List.of(
80 List.of(
81 Dnf.builder("Expected2")
82 .parameters(p)
83 .clause(friendView.call(p, p))
84 .build()
85 .call(q)
86 )
87 )
88 );
89 var error = assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
90 assertThat(error.getMessage(), allOf(containsString("Expected2"), containsString("Actual2")));
91 }
92
93 @Test
94 void parameterListLengthMismatchTest() {
95 var actual = Dnf.builder("Actual").parameters(p, q).clause(
96 friendView.call(p, q)
97 ).build();
98
99 var assertion = structurallyEqualTo(
100 List.of(new SymbolicParameter(p, ParameterDirection.OUT)),
101 List.of(List.of(friendView.call(p, p)))
102 );
103
104 assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
105 }
106
107 @Test
108 void parameterDirectionMismatchTest() {
109 var actual = Dnf.builder("Actual").parameter(p, ParameterDirection.IN).clause(
110 personView.call(p)
111 ).build();
112
113 var assertion = structurallyEqualTo(
114 List.of(new SymbolicParameter(p, ParameterDirection.OUT)),
115 List.of(List.of(personView.call(p)))
116 );
117
118 assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
119 }
120
121 @Test
122 void clauseCountMismatchTest() {
123 var actual = Dnf.builder("Actual").parameters(p, q).clause(
124 friendView.call(p, q)
125 ).build();
126
127 var assertion = structurallyEqualTo(
128 List.of(
129 new SymbolicParameter(p, ParameterDirection.OUT),
130 new SymbolicParameter(q, ParameterDirection.OUT)
131 ),
132 List.of(
133 List.of(friendView.call(p, q)),
134 List.of(friendView.call(q, p))
135 )
136 );
137
138 assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
139 }
140
141 @Test
142 void literalCountMismatchTest() {
143 var actual = Dnf.builder("Actual").parameters(p, q).clause(
144 friendView.call(p, q)
145 ).build();
146
147 var assertion = structurallyEqualTo(
148 List.of(
149 new SymbolicParameter(p, ParameterDirection.OUT),
150 new SymbolicParameter(q, ParameterDirection.OUT)
151 ),
152 List.of(
153 List.of(friendView.call(p, q), friendView.call(q, p))
154 )
155 );
156
157 assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
158 }
159}
diff --git a/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java b/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java
deleted file mode 100644
index f716b805..00000000
--- a/subprojects/store-query/src/test/java/tools/refinery/store/query/tests/StructurallyEqualToTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.query.tests;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.query.dnf.Dnf;
10import tools.refinery.store.query.term.NodeVariable;
11import tools.refinery.store.query.term.ParameterDirection;
12import tools.refinery.store.query.term.Variable;
13import tools.refinery.store.query.view.AnySymbolView;
14import tools.refinery.store.query.view.KeyOnlyView;
15import tools.refinery.store.representation.Symbol;
16
17import static org.hamcrest.CoreMatchers.containsString;
18import static org.hamcrest.MatcherAssert.assertThat;
19import static org.junit.jupiter.api.Assertions.assertThrows;
20import static tools.refinery.store.query.tests.QueryMatchers.structurallyEqualTo;
21
22class StructurallyEqualToTest {
23 private static final Symbol<Boolean> person = Symbol.of("Person", 1);
24 private static final Symbol<Boolean> friend = Symbol.of("friend", 2);
25 private static final AnySymbolView personView = new KeyOnlyView<>(person);
26 private static final AnySymbolView friendView = new KeyOnlyView<>(friend);
27 private static final NodeVariable p = Variable.of("p");
28 private static final NodeVariable q = Variable.of("q");
29
30 @Test
31 void flatEqualsTest() {
32 var expected = Dnf.builder("Expected").parameters(q).clause(personView.call(q)).build();
33 var actual = Dnf.builder("Actual").parameters(p).clause(personView.call(p)).build();
34
35 assertThat(actual, structurallyEqualTo(expected));
36 }
37
38 @Test
39 void flatNotEqualsTest() {
40 var expected = Dnf.builder("Expected").parameters(q).clause(friendView.call(q, q)).build();
41 var actual = Dnf.builder("Actual").parameters(p).clause(friendView.call(p, q)).build();
42
43 var assertion = structurallyEqualTo(expected);
44 assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
45 }
46
47 @Test
48 void deepEqualsTest() {
49 var expected = Dnf.builder("Expected").parameters(q).clause(
50 Dnf.builder("Expected2").parameters(p).clause(personView.call(p)).build().call(q)
51 ).build();
52 var actual = Dnf.builder("Actual").parameters(q).clause(
53 Dnf.builder("Actual2").parameters(p).clause(personView.call(p)).build().call(q)
54 ).build();
55
56 assertThat(actual, structurallyEqualTo(expected));
57 }
58
59 @Test
60 void deepNotEqualsTest() {
61 var expected = Dnf.builder("Expected").parameters(q).clause(
62 Dnf.builder("Expected2").parameters(p).clause(friendView.call(p, p)).build().call(q)
63 ).build();
64 var actual = Dnf.builder("Actual").parameter(q).clause(
65 Dnf.builder("Actual2").parameters(p).clause(friendView.call(p, q)).build().call(q)
66 ).build();
67
68 var assertion = structurallyEqualTo(expected);
69 var error = assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
70 assertThat(error.getMessage(), containsString(" called from Expected/1 "));
71 }
72
73 @Test
74 void parameterListLengthMismatchTest() {
75 var expected = Dnf.builder("Expected").parameter(p).clause(
76 friendView.call(p, p)
77 ).build();
78 var actual = Dnf.builder("Actual").parameters(p, q).clause(
79 friendView.call(p, q)
80 ).build();
81
82 var assertion = structurallyEqualTo(expected);
83 assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
84 }
85
86 @Test
87 void parameterDirectionMismatchTest() {
88 var expected = Dnf.builder("Expected").parameter(p, ParameterDirection.OUT).clause(
89 personView.call(p)
90 ).build();
91 var actual = Dnf.builder("Actual").parameter(p, ParameterDirection.IN).clause(
92 personView.call(p)
93 ).build();
94
95 var assertion = structurallyEqualTo(expected);
96 assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
97 }
98
99 @Test
100 void clauseCountMismatchTest() {
101 var expected = Dnf.builder("Expected")
102 .parameters(p, q)
103 .clause(friendView.call(p, q))
104 .clause(friendView.call(q, p))
105 .build();
106 var actual = Dnf.builder("Actual").parameters(p, q).clause(
107 friendView.call(p, q)
108 ).build();
109
110 var assertion = structurallyEqualTo(expected);
111 assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
112 }
113
114 @Test
115 void literalCountMismatchTest() {
116 var expected = Dnf.builder("Expected").parameters(p, q).clause(
117 friendView.call(p, q),
118 friendView.call(q, p)
119 ).build();
120 var actual = Dnf.builder("Actual").parameters(p, q).clause(
121 friendView.call(p, q)
122 ).build();
123
124 var assertion = structurallyEqualTo(expected);
125 assertThrows(AssertionError.class, () -> assertThat(actual, assertion));
126 }
127}