diff options
35 files changed, 1062 insertions, 602 deletions
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/DiagonalQueryTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/DiagonalQueryTest.java index 5cffef71..3ff01064 100644 --- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/DiagonalQueryTest.java +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/DiagonalQueryTest.java | |||
@@ -10,13 +10,13 @@ import tools.refinery.store.model.ModelStore; | |||
10 | import tools.refinery.store.query.ModelQuery; | 10 | import tools.refinery.store.query.ModelQuery; |
11 | import tools.refinery.store.query.dnf.Dnf; | 11 | import tools.refinery.store.query.dnf.Dnf; |
12 | import tools.refinery.store.query.dnf.Query; | 12 | import tools.refinery.store.query.dnf.Query; |
13 | import tools.refinery.store.query.term.Variable; | ||
14 | import tools.refinery.store.query.viatra.tests.QueryEngineTest; | 13 | import tools.refinery.store.query.viatra.tests.QueryEngineTest; |
15 | import tools.refinery.store.query.view.FunctionView; | 14 | import tools.refinery.store.query.view.FunctionView; |
16 | import tools.refinery.store.query.view.KeyOnlyView; | 15 | import tools.refinery.store.query.view.KeyOnlyView; |
17 | import tools.refinery.store.representation.Symbol; | 16 | import tools.refinery.store.representation.Symbol; |
18 | import tools.refinery.store.tuple.Tuple; | 17 | import tools.refinery.store.tuple.Tuple; |
19 | 18 | ||
19 | import java.util.List; | ||
20 | import java.util.Map; | 20 | import java.util.Map; |
21 | import java.util.Optional; | 21 | import java.util.Optional; |
22 | 22 | ||
@@ -33,15 +33,10 @@ class DiagonalQueryTest { | |||
33 | var personView = new KeyOnlyView<>(person); | 33 | var personView = new KeyOnlyView<>(person); |
34 | var symbolView = new KeyOnlyView<>(symbol); | 34 | var symbolView = new KeyOnlyView<>(symbol); |
35 | 35 | ||
36 | var p1 = Variable.of("p1"); | 36 | var query = Query.of("Diagonal", (builder, p1) -> builder.clause(p2 -> List.of( |
37 | var p2 = Variable.of("p2"); | 37 | personView.call(p1), |
38 | var query = Query.builder("Diagonal") | 38 | not(symbolView.call(p1, p1, p2, p2)) |
39 | .parameter(p1) | 39 | ))); |
40 | .clause( | ||
41 | personView.call(p1), | ||
42 | not(symbolView.call(p1, p1, p2, p2)) | ||
43 | ) | ||
44 | .build(); | ||
45 | 40 | ||
46 | var store = ModelStore.builder() | 41 | var store = ModelStore.builder() |
47 | .symbols(person, symbol) | 42 | .symbols(person, symbol) |
@@ -81,28 +76,24 @@ class DiagonalQueryTest { | |||
81 | var personView = new KeyOnlyView<>(person); | 76 | var personView = new KeyOnlyView<>(person); |
82 | var symbolView = new KeyOnlyView<>(symbol); | 77 | var symbolView = new KeyOnlyView<>(symbol); |
83 | 78 | ||
84 | var p1 = Variable.of("p1"); | 79 | var subQuery = Dnf.of("SubQuery", builder -> { |
85 | var p2 = Variable.of("p2"); | 80 | var p1 = builder.parameter("p1"); |
86 | var p3 = Variable.of("p3"); | 81 | var p2 = builder.parameter("p2"); |
87 | var p4 = Variable.of("p4"); | 82 | var p3 = builder.parameter("p3"); |
88 | var subQuery = Dnf.builder("SubQuery") | 83 | var p4 = builder.parameter("p4"); |
89 | .parameters(p1, p2, p3, p4) | 84 | builder.clause( |
90 | .clause( | 85 | personView.call(p1), |
91 | personView.call(p1), | 86 | symbolView.call(p1, p2, p3, p4) |
92 | symbolView.call(p1, p2, p3, p4) | 87 | ); |
93 | ) | 88 | builder.clause( |
94 | .clause( | 89 | personView.call(p2), |
95 | personView.call(p2), | 90 | symbolView.call(p1, p2, p3, p4) |
96 | symbolView.call(p1, p2, p3, p4) | 91 | ); |
97 | ) | 92 | }); |
98 | .build(); | 93 | var query = Query.of("Diagonal", (builder, p1) -> builder.clause(p2 -> List.of( |
99 | var query = Query.builder("Diagonal") | 94 | personView.call(p1), |
100 | .parameter(p1) | 95 | not(subQuery.call(p1, p1, p2, p2)) |
101 | .clause( | 96 | ))); |
102 | personView.call(p1), | ||
103 | not(subQuery.call(p1, p1, p2, p2)) | ||
104 | ) | ||
105 | .build(); | ||
106 | 97 | ||
107 | var store = ModelStore.builder() | 98 | var store = ModelStore.builder() |
108 | .symbols(person, symbol) | 99 | .symbols(person, symbol) |
@@ -142,17 +133,10 @@ class DiagonalQueryTest { | |||
142 | var personView = new KeyOnlyView<>(person); | 133 | var personView = new KeyOnlyView<>(person); |
143 | var symbolView = new KeyOnlyView<>(symbol); | 134 | var symbolView = new KeyOnlyView<>(symbol); |
144 | 135 | ||
145 | var p1 = Variable.of("p1"); | 136 | var query = Query.of("Diagonal", Integer.class, (builder, p1, output) -> builder.clause(p2 -> List.of( |
146 | var p2 = Variable.of("p2"); | 137 | personView.call(p1), |
147 | var x = Variable.of("x", Integer.class); | 138 | output.assign(symbolView.count(p1, p1, p2, p2)) |
148 | var query = Query.builder("Diagonal") | 139 | ))); |
149 | .parameter(p1) | ||
150 | .output(x) | ||
151 | .clause( | ||
152 | personView.call(p1), | ||
153 | x.assign(symbolView.count(p1, p1, p2, p2)) | ||
154 | ) | ||
155 | .build(); | ||
156 | 140 | ||
157 | var store = ModelStore.builder() | 141 | var store = ModelStore.builder() |
158 | .symbols(person, symbol) | 142 | .symbols(person, symbol) |
@@ -193,30 +177,24 @@ class DiagonalQueryTest { | |||
193 | var personView = new KeyOnlyView<>(person); | 177 | var personView = new KeyOnlyView<>(person); |
194 | var symbolView = new KeyOnlyView<>(symbol); | 178 | var symbolView = new KeyOnlyView<>(symbol); |
195 | 179 | ||
196 | var p1 = Variable.of("p1"); | 180 | var subQuery = Dnf.of("SubQuery", builder -> { |
197 | var p2 = Variable.of("p2"); | 181 | var p1 = builder.parameter("p1"); |
198 | var p3 = Variable.of("p3"); | 182 | var p2 = builder.parameter("p2"); |
199 | var p4 = Variable.of("p4"); | 183 | var p3 = builder.parameter("p3"); |
200 | var x = Variable.of("x", Integer.class); | 184 | var p4 = builder.parameter("p4"); |
201 | var subQuery = Dnf.builder("SubQuery") | 185 | builder.clause( |
202 | .parameters(p1, p2, p3, p4) | 186 | personView.call(p1), |
203 | .clause( | 187 | symbolView.call(p1, p2, p3, p4) |
204 | personView.call(p1), | 188 | ); |
205 | symbolView.call(p1, p2, p3, p4) | 189 | builder.clause( |
206 | ) | 190 | personView.call(p2), |
207 | .clause( | 191 | symbolView.call(p1, p2, p3, p4) |
208 | personView.call(p2), | 192 | ); |
209 | symbolView.call(p1, p2, p3, p4) | 193 | }); |
210 | ) | 194 | var query = Query.of("Diagonal", Integer.class, (builder, p1, output) -> builder.clause(p2 -> List.of( |
211 | .build(); | 195 | personView.call(p1), |
212 | var query = Query.builder("Diagonal") | 196 | output.assign(subQuery.count(p1, p1, p2, p2)) |
213 | .parameter(p1) | 197 | ))); |
214 | .output(x) | ||
215 | .clause( | ||
216 | personView.call(p1), | ||
217 | x.assign(subQuery.count(p1, p1, p2, p2)) | ||
218 | ) | ||
219 | .build(); | ||
220 | 198 | ||
221 | var store = ModelStore.builder() | 199 | var store = ModelStore.builder() |
222 | .symbols(person, symbol) | 200 | .symbols(person, symbol) |
@@ -257,18 +235,11 @@ class DiagonalQueryTest { | |||
257 | var personView = new KeyOnlyView<>(person); | 235 | var personView = new KeyOnlyView<>(person); |
258 | var symbolView = new FunctionView<>(symbol); | 236 | var symbolView = new FunctionView<>(symbol); |
259 | 237 | ||
260 | var p1 = Variable.of("p1"); | 238 | var query = Query.of("Diagonal", Integer.class, (builder, p1, output) -> builder.clause(Integer.class, |
261 | var p2 = Variable.of("p2"); | 239 | (p2, y) -> List.of( |
262 | var x = Variable.of("x", Integer.class); | ||
263 | var y = Variable.of("y", Integer.class); | ||
264 | var query = Query.builder("Diagonal") | ||
265 | .parameter(p1) | ||
266 | .output(x) | ||
267 | .clause( | ||
268 | personView.call(p1), | 240 | personView.call(p1), |
269 | x.assign(symbolView.aggregate(y, INT_SUM, p1, p1, p2, p2, y)) | 241 | output.assign(symbolView.aggregate(y, INT_SUM, p1, p1, p2, p2, y)) |
270 | ) | 242 | ))); |
271 | .build(); | ||
272 | 243 | ||
273 | var store = ModelStore.builder() | 244 | var store = ModelStore.builder() |
274 | .symbols(person, symbol) | 245 | .symbols(person, symbol) |
@@ -309,34 +280,29 @@ class DiagonalQueryTest { | |||
309 | var personView = new KeyOnlyView<>(person); | 280 | var personView = new KeyOnlyView<>(person); |
310 | var symbolView = new FunctionView<>(symbol); | 281 | var symbolView = new FunctionView<>(symbol); |
311 | 282 | ||
312 | var p1 = Variable.of("p1"); | 283 | var subQuery = Dnf.of("SubQuery", builder -> { |
313 | var p2 = Variable.of("p2"); | 284 | var p1 = builder.parameter("p1"); |
314 | var p3 = Variable.of("p3"); | 285 | var p2 = builder.parameter("p2"); |
315 | var p4 = Variable.of("p4"); | 286 | var p3 = builder.parameter("p3"); |
316 | var x = Variable.of("x", Integer.class); | 287 | var p4 = builder.parameter("p4"); |
317 | var y = Variable.of("y", Integer.class); | 288 | var x = builder.parameter("x", Integer.class); |
318 | var z = Variable.of("z", Integer.class); | 289 | var y = builder.parameter("y", Integer.class); |
319 | var subQuery = Dnf.builder("SubQuery") | 290 | builder.clause( |
320 | .parameters(p1, p2, p3, p4, x, y) | 291 | personView.call(p1), |
321 | .clause( | 292 | symbolView.call(p1, p2, p3, p4, x), |
322 | personView.call(p1), | 293 | y.assign(x) |
323 | symbolView.call(p1, p2, p3, p4, x), | 294 | ); |
324 | y.assign(x) | 295 | builder.clause( |
325 | ) | 296 | personView.call(p2), |
326 | .clause( | 297 | symbolView.call(p1, p2, p3, p4, x), |
327 | personView.call(p2), | 298 | y.assign(x) |
328 | symbolView.call(p1, p2, p3, p4, x), | 299 | ); |
329 | y.assign(x) | 300 | }); |
330 | ) | 301 | var query = Query.of("Diagonal", Integer.class, (builder, p1, output) -> builder.clause(Integer.class, |
331 | .build(); | 302 | (p2, y) -> List.of( |
332 | var query = Query.builder("Diagonal") | ||
333 | .parameter(p1) | ||
334 | .output(x) | ||
335 | .clause( | ||
336 | personView.call(p1), | 303 | personView.call(p1), |
337 | x.assign(subQuery.aggregate(z, INT_SUM, p1, p1, p2, p2, z, z)) | 304 | output.assign(subQuery.aggregate(y, INT_SUM, p1, p1, p2, p2, y, y)) |
338 | ) | 305 | ))); |
339 | .build(); | ||
340 | 306 | ||
341 | var store = ModelStore.builder() | 307 | var store = ModelStore.builder() |
342 | .symbols(person, symbol) | 308 | .symbols(person, symbol) |
@@ -377,14 +343,10 @@ class DiagonalQueryTest { | |||
377 | var personView = new KeyOnlyView<>(person); | 343 | var personView = new KeyOnlyView<>(person); |
378 | var symbolView = new KeyOnlyView<>(symbol); | 344 | var symbolView = new KeyOnlyView<>(symbol); |
379 | 345 | ||
380 | var p1 = Variable.of("p1"); | 346 | var query = Query.of("Diagonal", (builder, p1) -> builder.clause( |
381 | var query = Query.builder("Diagonal") | 347 | personView.call(p1), |
382 | .parameter(p1) | 348 | symbolView.callTransitive(p1, p1) |
383 | .clause( | 349 | )); |
384 | personView.call(p1), | ||
385 | symbolView.callTransitive(p1, p1) | ||
386 | ) | ||
387 | .build(); | ||
388 | 350 | ||
389 | var store = ModelStore.builder() | 351 | var store = ModelStore.builder() |
390 | .symbols(person, symbol) | 352 | .symbols(person, symbol) |
@@ -423,26 +385,22 @@ class DiagonalQueryTest { | |||
423 | var personView = new KeyOnlyView<>(person); | 385 | var personView = new KeyOnlyView<>(person); |
424 | var symbolView = new KeyOnlyView<>(symbol); | 386 | var symbolView = new KeyOnlyView<>(symbol); |
425 | 387 | ||
426 | var p1 = Variable.of("p1"); | 388 | var subQuery = Dnf.of("SubQuery", builder -> { |
427 | var p2 = Variable.of("p2"); | 389 | var p1 = builder.parameter("p1"); |
428 | var subQuery = Dnf.builder("SubQuery") | 390 | var p2 = builder.parameter("p2"); |
429 | .parameters(p1, p2) | 391 | builder.clause( |
430 | .clause( | 392 | personView.call(p1), |
431 | personView.call(p1), | 393 | symbolView.call(p1, p2) |
432 | symbolView.call(p1, p2) | 394 | ); |
433 | ) | 395 | builder.clause( |
434 | .clause( | 396 | personView.call(p2), |
435 | personView.call(p2), | 397 | symbolView.call(p1, p2) |
436 | symbolView.call(p1, p2) | 398 | ); |
437 | ) | 399 | }); |
438 | .build(); | 400 | var query = Query.of("Diagonal", (builder, p1) -> builder.clause( |
439 | var query = Query.builder("Diagonal") | 401 | personView.call(p1), |
440 | .parameter(p1) | 402 | subQuery.callTransitive(p1, p1) |
441 | .clause( | 403 | )); |
442 | personView.call(p1), | ||
443 | subQuery.callTransitive(p1, p1) | ||
444 | ) | ||
445 | .build(); | ||
446 | 404 | ||
447 | var store = ModelStore.builder() | 405 | var store = ModelStore.builder() |
448 | .symbols(person, symbol) | 406 | .symbols(person, symbol) |
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/FunctionalQueryTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/FunctionalQueryTest.java index 19584273..ffa5e60b 100644 --- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/FunctionalQueryTest.java +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/FunctionalQueryTest.java | |||
@@ -20,6 +20,7 @@ import tools.refinery.store.representation.Symbol; | |||
20 | import tools.refinery.store.representation.TruthValue; | 20 | import tools.refinery.store.representation.TruthValue; |
21 | import tools.refinery.store.tuple.Tuple; | 21 | import tools.refinery.store.tuple.Tuple; |
22 | 22 | ||
23 | import java.util.List; | ||
23 | import java.util.Map; | 24 | import java.util.Map; |
24 | import java.util.Optional; | 25 | import java.util.Optional; |
25 | 26 | ||
@@ -41,16 +42,10 @@ class FunctionalQueryTest { | |||
41 | var personView = new KeyOnlyView<>(person); | 42 | var personView = new KeyOnlyView<>(person); |
42 | var ageView = new FunctionView<>(age); | 43 | var ageView = new FunctionView<>(age); |
43 | 44 | ||
44 | var p1 = Variable.of("p1"); | 45 | var query = Query.of("InputKey", Integer.class, (builder, p1, output) -> builder.clause( |
45 | var x = Variable.of("x", Integer.class); | 46 | personView.call(p1), |
46 | var query = Query.builder("InputKey") | 47 | ageView.call(p1, output) |
47 | .parameter(p1) | 48 | )); |
48 | .output(x) | ||
49 | .clause( | ||
50 | personView.call(p1), | ||
51 | ageView.call(p1, x) | ||
52 | ) | ||
53 | .build(); | ||
54 | 49 | ||
55 | var store = ModelStore.builder() | 50 | var store = ModelStore.builder() |
56 | .symbols(person, age) | 51 | .symbols(person, age) |
@@ -87,23 +82,18 @@ class FunctionalQueryTest { | |||
87 | var personView = new KeyOnlyView<>(person); | 82 | var personView = new KeyOnlyView<>(person); |
88 | var ageView = new FunctionView<>(age); | 83 | var ageView = new FunctionView<>(age); |
89 | 84 | ||
90 | var p1 = Variable.of("p1"); | 85 | var subQuery = Dnf.of("SubQuery", builder -> { |
91 | var x = Variable.of("x", Integer.class); | 86 | var p1 = builder.parameter("p1"); |
92 | var subQuery = Dnf.builder("SubQuery") | 87 | var x = builder.parameter("x", Integer.class); |
93 | .parameters(p1, x) | 88 | builder.clause( |
94 | .clause( | 89 | personView.call(p1), |
95 | personView.call(p1), | 90 | ageView.call(p1, x) |
96 | ageView.call(p1, x) | 91 | ); |
97 | ) | 92 | }); |
98 | .build(); | 93 | var query = Query.of("Predicate", Integer.class, (builder, p1, output) -> builder.clause( |
99 | var query = Query.builder("Predicate") | 94 | personView.call(p1), |
100 | .parameter(p1) | 95 | subQuery.call(p1, output) |
101 | .output(x) | 96 | )); |
102 | .clause( | ||
103 | personView.call(p1), | ||
104 | subQuery.call(p1, x) | ||
105 | ) | ||
106 | .build(); | ||
107 | 97 | ||
108 | var store = ModelStore.builder() | 98 | var store = ModelStore.builder() |
109 | .symbols(person, age) | 99 | .symbols(person, age) |
@@ -140,18 +130,14 @@ class FunctionalQueryTest { | |||
140 | var personView = new KeyOnlyView<>(person); | 130 | var personView = new KeyOnlyView<>(person); |
141 | var ageView = new FunctionView<>(age); | 131 | var ageView = new FunctionView<>(age); |
142 | 132 | ||
143 | var p1 = Variable.of("p1"); | 133 | var query = Query.of("Computation", Integer.class, (builder, p1, output) -> builder.clause(() -> { |
144 | var x = Variable.of("x", Integer.class); | 134 | var x = Variable.of("x", Integer.class); |
145 | var y = Variable.of("y", Integer.class); | 135 | return List.of( |
146 | var query = Query.builder("Computation") | 136 | personView.call(p1), |
147 | .parameter(p1) | 137 | ageView.call(p1, x), |
148 | .output(y) | 138 | output.assign(mul(x, constant(7))) |
149 | .clause( | 139 | ); |
150 | personView.call(p1), | 140 | })); |
151 | ageView.call(p1, x), | ||
152 | y.assign(mul(x, constant(7))) | ||
153 | ) | ||
154 | .build(); | ||
155 | 141 | ||
156 | var store = ModelStore.builder() | 142 | var store = ModelStore.builder() |
157 | .symbols(person, age) | 143 | .symbols(person, age) |
@@ -187,17 +173,10 @@ class FunctionalQueryTest { | |||
187 | var personView = new KeyOnlyView<>(person); | 173 | var personView = new KeyOnlyView<>(person); |
188 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 174 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
189 | 175 | ||
190 | var p1 = Variable.of("p1"); | 176 | var query = Query.of("Count", Integer.class, (builder, p1, output) -> builder.clause( |
191 | var p2 = Variable.of("p2"); | 177 | personView.call(p1), |
192 | var x = Variable.of("x", Integer.class); | 178 | output.assign(friendMustView.count(p1, Variable.of())) |
193 | var query = Query.builder("Count") | 179 | )); |
194 | .parameter(p1) | ||
195 | .output(x) | ||
196 | .clause( | ||
197 | personView.call(p1), | ||
198 | x.assign(friendMustView.count(p1, p2)) | ||
199 | ) | ||
200 | .build(); | ||
201 | 180 | ||
202 | var store = ModelStore.builder() | 181 | var store = ModelStore.builder() |
203 | .symbols(person, friend) | 182 | .symbols(person, friend) |
@@ -236,25 +215,19 @@ class FunctionalQueryTest { | |||
236 | var personView = new KeyOnlyView<>(person); | 215 | var personView = new KeyOnlyView<>(person); |
237 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 216 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
238 | 217 | ||
239 | var p1 = Variable.of("p1"); | 218 | var subQuery = Dnf.of("SubQuery", builder -> { |
240 | var p2 = Variable.of("p2"); | 219 | var p1 = builder.parameter("p1"); |
241 | var x = Variable.of("x", Integer.class); | 220 | var p2 = builder.parameter("p2"); |
242 | var subQuery = Dnf.builder("SubQuery") | 221 | builder.clause( |
243 | .parameters(p1, p2) | 222 | personView.call(p1), |
244 | .clause( | 223 | personView.call(p2), |
245 | personView.call(p1), | 224 | friendMustView.call(p1, p2) |
246 | personView.call(p2), | 225 | ); |
247 | friendMustView.call(p1, p2) | 226 | }); |
248 | ) | 227 | var query = Query.of("Count", Integer.class, (builder, p1, output) -> builder.clause( |
249 | .build(); | 228 | personView.call(p1), |
250 | var query = Query.builder("Count") | 229 | output.assign(subQuery.count(p1, Variable.of())) |
251 | .parameter(p1) | 230 | )); |
252 | .output(x) | ||
253 | .clause( | ||
254 | personView.call(p1), | ||
255 | x.assign(subQuery.count(p1, p2)) | ||
256 | ) | ||
257 | .build(); | ||
258 | 231 | ||
259 | var store = ModelStore.builder() | 232 | var store = ModelStore.builder() |
260 | .symbols(person, friend) | 233 | .symbols(person, friend) |
@@ -291,15 +264,8 @@ class FunctionalQueryTest { | |||
291 | var age = new Symbol<>("age", 1, Integer.class, null); | 264 | var age = new Symbol<>("age", 1, Integer.class, null); |
292 | var ageView = new FunctionView<>(age); | 265 | var ageView = new FunctionView<>(age); |
293 | 266 | ||
294 | var p1 = Variable.of("p1"); | 267 | var query = Query.of("Aggregate", Integer.class, (builder, output) -> builder.clause(Integer.class, |
295 | var x = Variable.of("x", Integer.class); | 268 | (y) -> List.of(output.assign(ageView.aggregate(y, INT_SUM, Variable.of(), y))))); |
296 | var y = Variable.of("y", Integer.class); | ||
297 | var query = Query.builder("Aggregate") | ||
298 | .output(x) | ||
299 | .clause( | ||
300 | x.assign(ageView.aggregate(y, INT_SUM, p1, y)) | ||
301 | ) | ||
302 | .build(); | ||
303 | 269 | ||
304 | var store = ModelStore.builder() | 270 | var store = ModelStore.builder() |
305 | .symbols(age) | 271 | .symbols(age) |
@@ -327,22 +293,16 @@ class FunctionalQueryTest { | |||
327 | var personView = new KeyOnlyView<>(person); | 293 | var personView = new KeyOnlyView<>(person); |
328 | var ageView = new FunctionView<>(age); | 294 | var ageView = new FunctionView<>(age); |
329 | 295 | ||
330 | var p1 = Variable.of("p1"); | 296 | var subQuery = Dnf.of("SubQuery", builder -> { |
331 | var x = Variable.of("x", Integer.class); | 297 | var p1 = builder.parameter("p1"); |
332 | var y = Variable.of("y", Integer.class); | 298 | var x = builder.parameter("x", Integer.class); |
333 | var subQuery = Dnf.builder("SubQuery") | 299 | builder.clause( |
334 | .parameters(p1, x) | 300 | personView.call(p1), |
335 | .clause( | 301 | ageView.call(p1, x) |
336 | personView.call(p1), | 302 | ); |
337 | ageView.call(p1, x) | 303 | }); |
338 | ) | 304 | var query = Query.of("Aggregate", Integer.class, (builder, output) -> builder.clause(Integer.class, |
339 | .build(); | 305 | (y) -> List.of(output.assign(subQuery.aggregate(y, INT_SUM, Variable.of(), y))))); |
340 | var query = Query.builder("Aggregate") | ||
341 | .output(x) | ||
342 | .clause( | ||
343 | x.assign(subQuery.aggregate(y, INT_SUM, p1, y)) | ||
344 | ) | ||
345 | .build(); | ||
346 | 306 | ||
347 | var store = ModelStore.builder() | 307 | var store = ModelStore.builder() |
348 | .symbols(person, age) | 308 | .symbols(person, age) |
@@ -374,29 +334,18 @@ class FunctionalQueryTest { | |||
374 | var personView = new KeyOnlyView<>(person); | 334 | var personView = new KeyOnlyView<>(person); |
375 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 335 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
376 | 336 | ||
377 | var p1 = Variable.of("p1"); | 337 | var subQuery = Dnf.of("SubQuery", builder -> { |
378 | var p2 = Variable.of("p2"); | 338 | var p1 = builder.parameter("p1"); |
379 | var x = Variable.of("x", Integer.class); | 339 | var x = builder.parameter("x", Integer.class); |
380 | var y = Variable.of("y", Integer.class); | 340 | builder.clause( |
381 | var subQuery = Dnf.builder("SubQuery") | 341 | personView.call(p1), |
382 | .parameters(p1, x) | 342 | x.assign(friendMustView.count(p1, Variable.of())) |
383 | .clause( | 343 | ); |
384 | personView.call(p1), | 344 | }); |
385 | x.assign(friendMustView.count(p1, p2)) | 345 | var minQuery = Query.of("Min", Integer.class, (builder, output) -> builder.clause(Integer.class, |
386 | ) | 346 | (y) -> List.of(output.assign(subQuery.aggregate(y, INT_MIN, Variable.of(), y))))); |
387 | .build(); | 347 | var maxQuery = Query.of("Max", Integer.class, (builder, output) -> builder.clause(Integer.class, |
388 | var minQuery = Query.builder("Min") | 348 | (y) -> List.of(output.assign(subQuery.aggregate(y, INT_MAX, Variable.of(), y))))); |
389 | .output(x) | ||
390 | .clause( | ||
391 | x.assign(subQuery.aggregate(y, INT_MIN, p1, y)) | ||
392 | ) | ||
393 | .build(); | ||
394 | var maxQuery = Query.builder("Max") | ||
395 | .output(x) | ||
396 | .clause( | ||
397 | x.assign(subQuery.aggregate(y, INT_MAX, p1, y)) | ||
398 | ) | ||
399 | .build(); | ||
400 | 349 | ||
401 | var store = ModelStore.builder() | 350 | var store = ModelStore.builder() |
402 | .symbols(person, friend) | 351 | .symbols(person, friend) |
@@ -450,18 +399,12 @@ class FunctionalQueryTest { | |||
450 | var personView = new KeyOnlyView<>(person); | 399 | var personView = new KeyOnlyView<>(person); |
451 | var ageView = new FunctionView<>(age); | 400 | var ageView = new FunctionView<>(age); |
452 | 401 | ||
453 | var p1 = Variable.of("p1"); | 402 | var query = Query.of("InvalidComputation", Integer.class, |
454 | var x = Variable.of("x", Integer.class); | 403 | (builder, p1, output) -> builder.clause(Integer.class, (x) -> List.of( |
455 | var y = Variable.of("y", Integer.class); | ||
456 | var query = Query.builder("InvalidComputation") | ||
457 | .parameter(p1) | ||
458 | .output(y) | ||
459 | .clause( | ||
460 | personView.call(p1), | 404 | personView.call(p1), |
461 | ageView.call(p1, x), | 405 | ageView.call(p1, x), |
462 | y.assign(div(constant(120), x)) | 406 | output.assign(div(constant(120), x)) |
463 | ) | 407 | ))); |
464 | .build(); | ||
465 | 408 | ||
466 | var store = ModelStore.builder() | 409 | var store = ModelStore.builder() |
467 | .symbols(person, age) | 410 | .symbols(person, age) |
@@ -497,16 +440,11 @@ class FunctionalQueryTest { | |||
497 | var personView = new KeyOnlyView<>(person); | 440 | var personView = new KeyOnlyView<>(person); |
498 | var ageView = new FunctionView<>(age); | 441 | var ageView = new FunctionView<>(age); |
499 | 442 | ||
500 | var p1 = Variable.of("p1"); | 443 | var query = Query.of("InvalidAssume", (builder, p1) -> builder.clause(Integer.class, (x) -> List.of( |
501 | var x = Variable.of("x", Integer.class); | 444 | personView.call(p1), |
502 | var query = Query.builder("InvalidComputation") | 445 | ageView.call(p1, x), |
503 | .parameter(p1) | 446 | assume(lessEq(div(constant(120), x), constant(5))) |
504 | .clause( | 447 | ))); |
505 | personView.call(p1), | ||
506 | ageView.call(p1, x), | ||
507 | assume(lessEq(div(constant(120), x), constant(5))) | ||
508 | ) | ||
509 | .build(); | ||
510 | 448 | ||
511 | var store = ModelStore.builder() | 449 | var store = ModelStore.builder() |
512 | .symbols(person, age) | 450 | .symbols(person, age) |
@@ -547,18 +485,11 @@ class FunctionalQueryTest { | |||
547 | var ageView = new FunctionView<>(age); | 485 | var ageView = new FunctionView<>(age); |
548 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 486 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
549 | 487 | ||
550 | var p1 = Variable.of("p1"); | 488 | var query = Query.of("NotFunctional", Integer.class, (builder, p1, output) -> builder.clause((p2) -> List.of( |
551 | var p2 = Variable.of("p2"); | 489 | personView.call(p1), |
552 | var x = Variable.of("x", Integer.class); | 490 | friendMustView.call(p1, p2), |
553 | var query = Query.builder("NotFunctional") | 491 | ageView.call(p2, output) |
554 | .parameter(p1) | 492 | ))); |
555 | .output(x) | ||
556 | .clause( | ||
557 | personView.call(p1), | ||
558 | friendMustView.call(p1, p2), | ||
559 | ageView.call(p2, x) | ||
560 | ) | ||
561 | .build(); | ||
562 | 493 | ||
563 | var store = ModelStore.builder() | 494 | var store = ModelStore.builder() |
564 | .symbols(person, age, friend) | 495 | .symbols(person, age, friend) |
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java index 11ee98f5..a90889c6 100644 --- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTest.java | |||
@@ -20,6 +20,7 @@ import tools.refinery.store.representation.Symbol; | |||
20 | import tools.refinery.store.representation.TruthValue; | 20 | import tools.refinery.store.representation.TruthValue; |
21 | import tools.refinery.store.tuple.Tuple; | 21 | import tools.refinery.store.tuple.Tuple; |
22 | 22 | ||
23 | import java.util.List; | ||
23 | import java.util.Map; | 24 | import java.util.Map; |
24 | 25 | ||
25 | import static org.junit.jupiter.api.Assertions.assertThrows; | 26 | import static org.junit.jupiter.api.Assertions.assertThrows; |
@@ -36,11 +37,7 @@ class QueryTest { | |||
36 | var asset = new Symbol<>("Asset", 1, Boolean.class, false); | 37 | var asset = new Symbol<>("Asset", 1, Boolean.class, false); |
37 | var personView = new KeyOnlyView<>(person); | 38 | var personView = new KeyOnlyView<>(person); |
38 | 39 | ||
39 | var p1 = Variable.of("p1"); | 40 | var predicate = Query.of("TypeConstraint", (builder, p1) -> builder.clause(personView.call(p1))); |
40 | var predicate = Query.builder("TypeConstraint") | ||
41 | .parameters(p1) | ||
42 | .clause(personView.call(p1)) | ||
43 | .build(); | ||
44 | 41 | ||
45 | var store = ModelStore.builder() | 42 | var store = ModelStore.builder() |
46 | .symbols(person, asset) | 43 | .symbols(person, asset) |
@@ -76,16 +73,11 @@ class QueryTest { | |||
76 | var personView = new KeyOnlyView<>(person); | 73 | var personView = new KeyOnlyView<>(person); |
77 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 74 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
78 | 75 | ||
79 | var p1 = Variable.of("p1"); | 76 | var predicate = Query.of("RelationConstraint", (builder, p1, p2) -> builder.clause( |
80 | var p2 = Variable.of("p2"); | 77 | personView.call(p1), |
81 | var predicate = Query.builder("RelationConstraint") | 78 | personView.call(p2), |
82 | .parameters(p1, p2) | 79 | friendMustView.call(p1, p2) |
83 | .clause( | 80 | )); |
84 | personView.call(p1), | ||
85 | personView.call(p2), | ||
86 | friendMustView.call(p1, p2) | ||
87 | ) | ||
88 | .build(); | ||
89 | 81 | ||
90 | var store = ModelStore.builder() | 82 | var store = ModelStore.builder() |
91 | .symbols(person, friend) | 83 | .symbols(person, friend) |
@@ -125,16 +117,11 @@ class QueryTest { | |||
125 | var personView = new KeyOnlyView<>(person); | 117 | var personView = new KeyOnlyView<>(person); |
126 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 118 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
127 | 119 | ||
128 | var p1 = Variable.of("p1"); | 120 | var predicate = Query.of("Exists", (builder, p1) -> builder.clause((p2) -> List.of( |
129 | var p2 = Variable.of("p2"); | 121 | personView.call(p1), |
130 | var predicate = Query.builder("RelationConstraint") | 122 | personView.call(p2), |
131 | .parameters(p1) | 123 | friendMustView.call(p1, p2) |
132 | .clause( | 124 | ))); |
133 | personView.call(p1), | ||
134 | personView.call(p2), | ||
135 | friendMustView.call(p1, p2) | ||
136 | ) | ||
137 | .build(); | ||
138 | 125 | ||
139 | var store = ModelStore.builder() | 126 | var store = ModelStore.builder() |
140 | .symbols(person, friend) | 127 | .symbols(person, friend) |
@@ -176,21 +163,15 @@ class QueryTest { | |||
176 | var animalView = new KeyOnlyView<>(animal); | 163 | var animalView = new KeyOnlyView<>(animal); |
177 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 164 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
178 | 165 | ||
179 | var p1 = Variable.of("p1"); | 166 | var predicate = Query.of("Or", (builder, p1, p2) -> builder.clause( |
180 | var p2 = Variable.of("p2"); | 167 | personView.call(p1), |
181 | var predicate = Query.builder("Or") | 168 | personView.call(p2), |
182 | .parameters(p1, p2) | 169 | friendMustView.call(p1, p2) |
183 | .clause( | 170 | ).clause( |
184 | personView.call(p1), | 171 | animalView.call(p1), |
185 | personView.call(p2), | 172 | animalView.call(p2), |
186 | friendMustView.call(p1, p2) | 173 | friendMustView.call(p1, p2) |
187 | ) | 174 | )); |
188 | .clause( | ||
189 | animalView.call(p1), | ||
190 | animalView.call(p2), | ||
191 | friendMustView.call(p1, p2) | ||
192 | ) | ||
193 | .build(); | ||
194 | 175 | ||
195 | var store = ModelStore.builder() | 176 | var store = ModelStore.builder() |
196 | .symbols(person, animal, friend) | 177 | .symbols(person, animal, friend) |
@@ -232,16 +213,11 @@ class QueryTest { | |||
232 | var person = new Symbol<>("Person", 1, Boolean.class, false); | 213 | var person = new Symbol<>("Person", 1, Boolean.class, false); |
233 | var personView = new KeyOnlyView<>(person); | 214 | var personView = new KeyOnlyView<>(person); |
234 | 215 | ||
235 | var p1 = Variable.of("p1"); | 216 | var predicate = Query.of("Equality", (builder, p1, p2) -> builder.clause( |
236 | var p2 = Variable.of("p2"); | 217 | personView.call(p1), |
237 | var predicate = Query.builder("Equality") | 218 | personView.call(p2), |
238 | .parameters(p1, p2) | 219 | p1.isEquivalent(p2) |
239 | .clause( | 220 | )); |
240 | personView.call(p1), | ||
241 | personView.call(p2), | ||
242 | p1.isEquivalent(p2) | ||
243 | ) | ||
244 | .build(); | ||
245 | 221 | ||
246 | var store = ModelStore.builder() | 222 | var store = ModelStore.builder() |
247 | .symbols(person) | 223 | .symbols(person) |
@@ -276,19 +252,13 @@ class QueryTest { | |||
276 | var personView = new KeyOnlyView<>(person); | 252 | var personView = new KeyOnlyView<>(person); |
277 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 253 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
278 | 254 | ||
279 | var p1 = Variable.of("p1"); | 255 | var predicate = Query.of("Inequality", (builder, p1, p2, p3) -> builder.clause( |
280 | var p2 = Variable.of("p2"); | 256 | personView.call(p1), |
281 | var p3 = Variable.of("p3"); | 257 | personView.call(p2), |
282 | var predicate = Query.builder("Inequality") | 258 | friendMustView.call(p1, p3), |
283 | .parameters(p1, p2, p3) | 259 | friendMustView.call(p2, p3), |
284 | .clause( | 260 | p1.notEquivalent(p2) |
285 | personView.call(p1), | 261 | )); |
286 | personView.call(p2), | ||
287 | friendMustView.call(p1, p3), | ||
288 | friendMustView.call(p2, p3), | ||
289 | p1.notEquivalent(p2) | ||
290 | ) | ||
291 | .build(); | ||
292 | 262 | ||
293 | var store = ModelStore.builder() | 263 | var store = ModelStore.builder() |
294 | .symbols(person, friend) | 264 | .symbols(person, friend) |
@@ -325,27 +295,20 @@ class QueryTest { | |||
325 | var personView = new KeyOnlyView<>(person); | 295 | var personView = new KeyOnlyView<>(person); |
326 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 296 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
327 | 297 | ||
328 | var p1 = Variable.of("p1"); | 298 | var friendPredicate = Dnf.of("Friend", builder -> { |
329 | var p2 = Variable.of("p2"); | 299 | var p1 = builder.parameter("p1"); |
330 | var friendPredicate = Dnf.builder("RelationConstraint") | 300 | var p2 = builder.parameter("p2"); |
331 | .parameters(p1, p2) | 301 | builder.clause( |
332 | .clause( | 302 | personView.call(p1), |
333 | personView.call(p1), | 303 | personView.call(p2), |
334 | personView.call(p2), | 304 | friendMustView.call(p1, p2) |
335 | friendMustView.call(p1, p2) | 305 | ); |
336 | ) | 306 | }); |
337 | .build(); | 307 | var predicate = Query.of("PositivePatternCall", (builder, p3, p4) -> builder.clause( |
338 | 308 | personView.call(p3), | |
339 | var p3 = Variable.of("p3"); | 309 | personView.call(p4), |
340 | var p4 = Variable.of("p4"); | 310 | friendPredicate.call(p3, p4) |
341 | var predicate = Query.builder("PositivePatternCall") | 311 | )); |
342 | .parameters(p3, p4) | ||
343 | .clause( | ||
344 | personView.call(p3), | ||
345 | personView.call(p4), | ||
346 | friendPredicate.call(p3, p4) | ||
347 | ) | ||
348 | .build(); | ||
349 | 312 | ||
350 | var store = ModelStore.builder() | 313 | var store = ModelStore.builder() |
351 | .symbols(person, friend) | 314 | .symbols(person, friend) |
@@ -384,16 +347,11 @@ class QueryTest { | |||
384 | var personView = new KeyOnlyView<>(person); | 347 | var personView = new KeyOnlyView<>(person); |
385 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 348 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
386 | 349 | ||
387 | var p1 = Variable.of("p1"); | 350 | var predicate = Query.of("NegativePatternCall", (builder, p1, p2) -> builder.clause( |
388 | var p2 = Variable.of("p2"); | 351 | personView.call(p1), |
389 | var predicate = Query.builder("NegativePatternCall") | 352 | personView.call(p2), |
390 | .parameters(p1, p2) | 353 | not(friendMustView.call(p1, p2)) |
391 | .clause( | 354 | )); |
392 | personView.call(p1), | ||
393 | personView.call(p2), | ||
394 | not(friendMustView.call(p1, p2)) | ||
395 | ) | ||
396 | .build(); | ||
397 | 355 | ||
398 | var store = ModelStore.builder() | 356 | var store = ModelStore.builder() |
399 | .symbols(person, friend) | 357 | .symbols(person, friend) |
@@ -438,27 +396,20 @@ class QueryTest { | |||
438 | var personView = new KeyOnlyView<>(person); | 396 | var personView = new KeyOnlyView<>(person); |
439 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 397 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
440 | 398 | ||
441 | var p1 = Variable.of("p1"); | 399 | var friendPredicate = Dnf.of("Friend", builder -> { |
442 | var p2 = Variable.of("p2"); | 400 | var p1 = builder.parameter("p1"); |
443 | var friendPredicate = Dnf.builder("RelationConstraint") | 401 | var p2 = builder.parameter("p2"); |
444 | .parameters(p1, p2) | 402 | builder.clause( |
445 | .clause( | 403 | personView.call(p1), |
446 | personView.call(p1), | 404 | personView.call(p2), |
447 | personView.call(p2), | 405 | friendMustView.call(p1, p2) |
448 | friendMustView.call(p1, p2) | 406 | ); |
449 | ) | 407 | }); |
450 | .build(); | 408 | var predicate = Query.of("NegativePatternCall", (builder, p3, p4) -> builder.clause( |
451 | 409 | personView.call(p3), | |
452 | var p3 = Variable.of("p3"); | 410 | personView.call(p4), |
453 | var p4 = Variable.of("p4"); | 411 | not(friendPredicate.call(p3, p4)) |
454 | var predicate = Query.builder("NegativePatternCall") | 412 | )); |
455 | .parameters(p3, p4) | ||
456 | .clause( | ||
457 | personView.call(p3), | ||
458 | personView.call(p4), | ||
459 | not(friendPredicate.call(p3, p4)) | ||
460 | ) | ||
461 | .build(); | ||
462 | 413 | ||
463 | var store = ModelStore.builder() | 414 | var store = ModelStore.builder() |
464 | .symbols(person, friend) | 415 | .symbols(person, friend) |
@@ -503,16 +454,10 @@ class QueryTest { | |||
503 | var personView = new KeyOnlyView<>(person); | 454 | var personView = new KeyOnlyView<>(person); |
504 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 455 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
505 | 456 | ||
506 | var p1 = Variable.of("p1"); | 457 | var predicate = Query.of("Negative", (builder, p1) -> builder.clause( |
507 | var p2 = Variable.of("p2"); | 458 | personView.call(p1), |
508 | 459 | not(friendMustView.call(p1, Variable.of())) | |
509 | var predicate = Query.builder("Count") | 460 | )); |
510 | .parameters(p1) | ||
511 | .clause( | ||
512 | personView.call(p1), | ||
513 | not(friendMustView.call(p1, p2)) | ||
514 | ) | ||
515 | .build(); | ||
516 | 461 | ||
517 | var store = ModelStore.builder() | 462 | var store = ModelStore.builder() |
518 | .symbols(person, friend) | 463 | .symbols(person, friend) |
@@ -550,25 +495,19 @@ class QueryTest { | |||
550 | var personView = new KeyOnlyView<>(person); | 495 | var personView = new KeyOnlyView<>(person); |
551 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 496 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
552 | 497 | ||
553 | var p1 = Variable.of("p1"); | 498 | var called = Dnf.of("Called", builder -> { |
554 | var p2 = Variable.of("p2"); | 499 | var p1 = builder.parameter("p1"); |
555 | 500 | var p2 = builder.parameter("p2"); | |
556 | var called = Dnf.builder("Called") | 501 | builder.clause( |
557 | .parameters(p1, p2) | 502 | personView.call(p1), |
558 | .clause( | 503 | personView.call(p2), |
559 | personView.call(p1), | 504 | friendMustView.call(p1, p2) |
560 | personView.call(p2), | 505 | ); |
561 | friendMustView.call(p1, p2) | 506 | }); |
562 | ) | 507 | var predicate = Query.of("Negative", (builder, p1) -> builder.clause( |
563 | .build(); | 508 | personView.call(p1), |
564 | 509 | not(called.call(p1, Variable.of())) | |
565 | var predicate = Query.builder("Count") | 510 | )); |
566 | .parameters(p1) | ||
567 | .clause( | ||
568 | personView.call(p1), | ||
569 | not(called.call(p1, p2)) | ||
570 | ) | ||
571 | .build(); | ||
572 | 511 | ||
573 | var store = ModelStore.builder() | 512 | var store = ModelStore.builder() |
574 | .symbols(person, friend) | 513 | .symbols(person, friend) |
@@ -606,16 +545,11 @@ class QueryTest { | |||
606 | var personView = new KeyOnlyView<>(person); | 545 | var personView = new KeyOnlyView<>(person); |
607 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 546 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
608 | 547 | ||
609 | var p1 = Variable.of("p1"); | 548 | var predicate = Query.of("Transitive", (builder, p1, p2) -> builder.clause( |
610 | var p2 = Variable.of("p2"); | 549 | personView.call(p1), |
611 | var predicate = Query.builder("TransitivePatternCall") | 550 | personView.call(p2), |
612 | .parameters(p1, p2) | 551 | friendMustView.callTransitive(p1, p2) |
613 | .clause( | 552 | )); |
614 | personView.call(p1), | ||
615 | personView.call(p2), | ||
616 | friendMustView.callTransitive(p1, p2) | ||
617 | ) | ||
618 | .build(); | ||
619 | 553 | ||
620 | var store = ModelStore.builder() | 554 | var store = ModelStore.builder() |
621 | .symbols(person, friend) | 555 | .symbols(person, friend) |
@@ -659,27 +593,20 @@ class QueryTest { | |||
659 | var personView = new KeyOnlyView<>(person); | 593 | var personView = new KeyOnlyView<>(person); |
660 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); | 594 | var friendMustView = new FilteredView<>(friend, "must", TruthValue::must); |
661 | 595 | ||
662 | var p1 = Variable.of("p1"); | 596 | var called = Dnf.of("Called", builder -> { |
663 | var p2 = Variable.of("p2"); | 597 | var p1 = builder.parameter("p1"); |
664 | var friendPredicate = Dnf.builder("RelationConstraint") | 598 | var p2 = builder.parameter("p2"); |
665 | .parameters(p1, p2) | 599 | builder.clause( |
666 | .clause( | 600 | personView.call(p1), |
667 | personView.call(p1), | 601 | personView.call(p2), |
668 | personView.call(p2), | 602 | friendMustView.call(p1, p2) |
669 | friendMustView.call(p1, p2) | 603 | ); |
670 | ) | 604 | }); |
671 | .build(); | 605 | var predicate = Query.of("Transitive", (builder, p1, p2) -> builder.clause( |
672 | 606 | personView.call(p1), | |
673 | var p3 = Variable.of("p3"); | 607 | personView.call(p2), |
674 | var p4 = Variable.of("p4"); | 608 | called.callTransitive(p1, p2) |
675 | var predicate = Query.builder("TransitivePatternCall") | 609 | )); |
676 | .parameters(p3, p4) | ||
677 | .clause( | ||
678 | personView.call(p3), | ||
679 | personView.call(p4), | ||
680 | friendPredicate.callTransitive(p3, p4) | ||
681 | ) | ||
682 | .build(); | ||
683 | 610 | ||
684 | var store = ModelStore.builder() | 611 | var store = ModelStore.builder() |
685 | .symbols(person, friend) | 612 | .symbols(person, friend) |
@@ -723,16 +650,11 @@ class QueryTest { | |||
723 | var personView = new KeyOnlyView<>(person); | 650 | var personView = new KeyOnlyView<>(person); |
724 | var ageView = new FunctionView<>(age); | 651 | var ageView = new FunctionView<>(age); |
725 | 652 | ||
726 | var p1 = Variable.of("p1"); | 653 | var query = Query.of("Constraint", (builder, p1) -> builder.clause(Integer.class, (x) -> List.of( |
727 | var x = Variable.of("x", Integer.class); | 654 | personView.call(p1), |
728 | var query = Query.builder("Constraint") | 655 | ageView.call(p1, x), |
729 | .parameter(p1) | 656 | assume(greaterEq(x, constant(18))) |
730 | .clause( | 657 | ))); |
731 | personView.call(p1), | ||
732 | ageView.call(p1, x), | ||
733 | assume(greaterEq(x, constant(18))) | ||
734 | ) | ||
735 | .build(); | ||
736 | 658 | ||
737 | var store = ModelStore.builder() | 659 | var store = ModelStore.builder() |
738 | .symbols(person, age) | 660 | .symbols(person, age) |
@@ -765,8 +687,7 @@ class QueryTest { | |||
765 | void alwaysFalseTest() { | 687 | void alwaysFalseTest() { |
766 | var person = new Symbol<>("Person", 1, Boolean.class, false); | 688 | var person = new Symbol<>("Person", 1, Boolean.class, false); |
767 | 689 | ||
768 | var p1 = Variable.of("p1"); | 690 | var predicate = Query.of("AlwaysFalse", builder -> builder.parameter("p1")); |
769 | var predicate = Query.builder("AlwaysFalse").parameters(p1).build(); | ||
770 | 691 | ||
771 | var store = ModelStore.builder() | 692 | var store = ModelStore.builder() |
772 | .symbols(person) | 693 | .symbols(person) |
@@ -789,8 +710,6 @@ class QueryTest { | |||
789 | 710 | ||
790 | @Test | 711 | @Test |
791 | void alwaysTrueTest() { | 712 | void alwaysTrueTest() { |
792 | var person = new Symbol<>("Person", 1, Boolean.class, false); | ||
793 | |||
794 | var p1 = Variable.of("p1"); | 713 | var p1 = Variable.of("p1"); |
795 | var predicate = Query.builder("AlwaysTrue").parameters(p1).clause().build(); | 714 | var predicate = Query.builder("AlwaysTrue").parameters(p1).clause().build(); |
796 | 715 | ||
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTransactionTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTransactionTest.java index bd6b6b81..9de2655f 100644 --- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTransactionTest.java +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/QueryTransactionTest.java | |||
@@ -11,7 +11,6 @@ import org.junit.jupiter.api.Test; | |||
11 | import tools.refinery.store.model.ModelStore; | 11 | import tools.refinery.store.model.ModelStore; |
12 | import tools.refinery.store.query.ModelQuery; | 12 | import tools.refinery.store.query.ModelQuery; |
13 | import tools.refinery.store.query.dnf.Query; | 13 | import tools.refinery.store.query.dnf.Query; |
14 | import tools.refinery.store.query.term.Variable; | ||
15 | import tools.refinery.store.query.view.FilteredView; | 14 | import tools.refinery.store.query.view.FilteredView; |
16 | import tools.refinery.store.query.view.FunctionView; | 15 | import tools.refinery.store.query.view.FunctionView; |
17 | import tools.refinery.store.query.view.KeyOnlyView; | 16 | import tools.refinery.store.query.view.KeyOnlyView; |
@@ -32,11 +31,7 @@ class QueryTransactionTest { | |||
32 | var person = new Symbol<>("Person", 1, Boolean.class, false); | 31 | var person = new Symbol<>("Person", 1, Boolean.class, false); |
33 | var personView = new KeyOnlyView<>(person); | 32 | var personView = new KeyOnlyView<>(person); |
34 | 33 | ||
35 | var p1 = Variable.of("p1"); | 34 | var predicate = Query.of("TypeConstraint", (builder, p1) -> builder.clause(personView.call(p1))); |
36 | var predicate = Query.builder("TypeConstraint") | ||
37 | .parameters(p1) | ||
38 | .clause(personView.call(p1)) | ||
39 | .build(); | ||
40 | 35 | ||
41 | var store = ModelStore.builder() | 36 | var store = ModelStore.builder() |
42 | .symbols(person) | 37 | .symbols(person) |
@@ -103,11 +98,7 @@ class QueryTransactionTest { | |||
103 | var person = new Symbol<>("Person", 1, Boolean.class, false); | 98 | var person = new Symbol<>("Person", 1, Boolean.class, false); |
104 | var personView = new KeyOnlyView<>(person); | 99 | var personView = new KeyOnlyView<>(person); |
105 | 100 | ||
106 | var p1 = Variable.of("p1"); | 101 | var predicate = Query.of("TypeConstraint", (builder, p1) -> builder.clause(personView.call(p1))); |
107 | var predicate = Query.builder("TypeConstraint") | ||
108 | .parameters(p1) | ||
109 | .clause(personView.call(p1)) | ||
110 | .build(); | ||
111 | 102 | ||
112 | var store = ModelStore.builder() | 103 | var store = ModelStore.builder() |
113 | .symbols(person) | 104 | .symbols(person) |
@@ -158,11 +149,7 @@ class QueryTransactionTest { | |||
158 | var asset = new Symbol<>("Asset", 1, Boolean.class, false); | 149 | var asset = new Symbol<>("Asset", 1, Boolean.class, false); |
159 | var personView = new KeyOnlyView<>(person); | 150 | var personView = new KeyOnlyView<>(person); |
160 | 151 | ||
161 | var p1 = Variable.of("p1"); | 152 | var predicate = Query.of("TypeConstraint", (builder, p1) -> builder.clause(personView.call(p1))); |
162 | var predicate = Query.builder("TypeConstraint") | ||
163 | .parameters(p1) | ||
164 | .clause(personView.call(p1)) | ||
165 | .build(); | ||
166 | 153 | ||
167 | var store = ModelStore.builder() | 154 | var store = ModelStore.builder() |
168 | .symbols(person, asset) | 155 | .symbols(person, asset) |
@@ -232,16 +219,10 @@ class QueryTransactionTest { | |||
232 | var personView = new KeyOnlyView<>(person); | 219 | var personView = new KeyOnlyView<>(person); |
233 | var ageView = new FunctionView<>(age); | 220 | var ageView = new FunctionView<>(age); |
234 | 221 | ||
235 | var p1 = Variable.of("p1"); | 222 | var query = Query.of("TypeConstraint", Integer.class, (builder, p1, output) -> builder.clause( |
236 | var x = Variable.of("x", Integer.class); | 223 | personView.call(p1), |
237 | var query = Query.builder() | 224 | ageView.call(p1, output) |
238 | .parameter(p1) | 225 | )); |
239 | .output(x) | ||
240 | .clause( | ||
241 | personView.call(p1), | ||
242 | ageView.call(p1, x) | ||
243 | ) | ||
244 | .build(); | ||
245 | 226 | ||
246 | var store = ModelStore.builder() | 227 | var store = ModelStore.builder() |
247 | .symbols(person, age) | 228 | .symbols(person, age) |
@@ -280,15 +261,10 @@ class QueryTransactionTest { | |||
280 | var personView = new KeyOnlyView<>(person); | 261 | var personView = new KeyOnlyView<>(person); |
281 | var adultView = new FilteredView<>(age, "adult", n -> n != null && n >= 18); | 262 | var adultView = new FilteredView<>(age, "adult", n -> n != null && n >= 18); |
282 | 263 | ||
283 | var p1 = Variable.of("p1"); | 264 | var query = Query.of("TypeConstraint", (builder, p1) -> builder.clause( |
284 | var x = Variable.of("x", Integer.class); | 265 | personView.call(p1), |
285 | var query = Query.builder() | 266 | adultView.call(p1) |
286 | .parameter(p1) | 267 | )); |
287 | .clause( | ||
288 | personView.call(p1), | ||
289 | adultView.call(p1) | ||
290 | ) | ||
291 | .build(); | ||
292 | 268 | ||
293 | var store = ModelStore.builder() | 269 | var store = ModelStore.builder() |
294 | .symbols(person, age) | 270 | .symbols(person, age) |
@@ -326,11 +302,7 @@ class QueryTransactionTest { | |||
326 | var person = new Symbol<>("Person", 1, Boolean.class, false); | 302 | var person = new Symbol<>("Person", 1, Boolean.class, false); |
327 | var personView = new KeyOnlyView<>(person); | 303 | var personView = new KeyOnlyView<>(person); |
328 | 304 | ||
329 | var p1 = Variable.of("p1"); | 305 | var predicate = Query.of("TypeConstraint", (builder, p1) -> builder.clause(personView.call(p1))); |
330 | var predicate = Query.builder("TypeConstraint") | ||
331 | .parameters(p1) | ||
332 | .clause(personView.call(p1)) | ||
333 | .build(); | ||
334 | 306 | ||
335 | var store = ModelStore.builder() | 307 | var store = ModelStore.builder() |
336 | .symbols(person) | 308 | .symbols(person) |
@@ -384,11 +356,7 @@ class QueryTransactionTest { | |||
384 | var person = new Symbol<>("Person", 1, Boolean.class, false); | 356 | var person = new Symbol<>("Person", 1, Boolean.class, false); |
385 | var personView = new KeyOnlyView<>(person); | 357 | var personView = new KeyOnlyView<>(person); |
386 | 358 | ||
387 | var p1 = Variable.of("p1"); | 359 | var predicate = Query.of("TypeConstraint", (builder, p1) -> builder.clause(personView.call(p1))); |
388 | var predicate = Query.builder("TypeConstraint") | ||
389 | .parameters(p1) | ||
390 | .clause(personView.call(p1)) | ||
391 | .build(); | ||
392 | 360 | ||
393 | var store = ModelStore.builder() | 361 | var store = ModelStore.builder() |
394 | .symbols(person) | 362 | .symbols(person) |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/AbstractQueryBuilder.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/AbstractQueryBuilder.java new file mode 100644 index 00000000..ddd69b9f --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/AbstractQueryBuilder.java | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf; | ||
7 | |||
8 | import tools.refinery.store.query.dnf.callback.*; | ||
9 | import tools.refinery.store.query.literal.Literal; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | import tools.refinery.store.query.term.Variable; | ||
12 | |||
13 | import java.util.Collection; | ||
14 | import java.util.List; | ||
15 | import java.util.Set; | ||
16 | |||
17 | public abstract class AbstractQueryBuilder<T extends AbstractQueryBuilder<T>> { | ||
18 | protected final DnfBuilder dnfBuilder; | ||
19 | |||
20 | protected AbstractQueryBuilder(DnfBuilder dnfBuilder) { | ||
21 | this.dnfBuilder = dnfBuilder; | ||
22 | } | ||
23 | |||
24 | protected abstract T self(); | ||
25 | |||
26 | public NodeVariable parameter() { | ||
27 | return dnfBuilder.parameter(); | ||
28 | } | ||
29 | |||
30 | public NodeVariable parameter(String name) { | ||
31 | return dnfBuilder.parameter(name); | ||
32 | } | ||
33 | |||
34 | public T parameter(NodeVariable variable) { | ||
35 | dnfBuilder.parameter(variable); | ||
36 | return self(); | ||
37 | } | ||
38 | |||
39 | public T parameters(NodeVariable... variables) { | ||
40 | dnfBuilder.parameters(variables); | ||
41 | return self(); | ||
42 | } | ||
43 | |||
44 | public T parameters(List<NodeVariable> variables) { | ||
45 | dnfBuilder.parameters(variables); | ||
46 | return self(); | ||
47 | } | ||
48 | |||
49 | public T functionalDependencies(Collection<FunctionalDependency<Variable>> functionalDependencies) { | ||
50 | dnfBuilder.functionalDependencies(functionalDependencies); | ||
51 | return self(); | ||
52 | } | ||
53 | |||
54 | public T functionalDependency(FunctionalDependency<Variable> functionalDependency) { | ||
55 | dnfBuilder.functionalDependency(functionalDependency); | ||
56 | return self(); | ||
57 | } | ||
58 | |||
59 | public T functionalDependency(Set<? extends Variable> forEach, Set<? extends Variable> unique) { | ||
60 | dnfBuilder.functionalDependency(forEach, unique); | ||
61 | return self(); | ||
62 | } | ||
63 | |||
64 | public T clause(ClauseCallback0 callback) { | ||
65 | dnfBuilder.clause(callback); | ||
66 | return self(); | ||
67 | } | ||
68 | |||
69 | public T clause(ClauseCallback1Data0 callback) { | ||
70 | dnfBuilder.clause(callback); | ||
71 | return self(); | ||
72 | } | ||
73 | |||
74 | public <U1> T clause(Class<U1> type1, ClauseCallback1Data1<U1> callback) { | ||
75 | dnfBuilder.clause(type1, callback); | ||
76 | return self(); | ||
77 | } | ||
78 | |||
79 | public T clause(ClauseCallback2Data0 callback) { | ||
80 | dnfBuilder.clause(callback); | ||
81 | return self(); | ||
82 | } | ||
83 | |||
84 | public <U1> T clause(Class<U1> type1, ClauseCallback2Data1<U1> callback) { | ||
85 | dnfBuilder.clause(type1, callback); | ||
86 | return self(); | ||
87 | } | ||
88 | |||
89 | public <U1, U2> T clause(Class<U1> type1, Class<U2> type2, ClauseCallback2Data2<U1, U2> callback) { | ||
90 | dnfBuilder.clause(type1, type2, callback); | ||
91 | return self(); | ||
92 | } | ||
93 | |||
94 | public T clause(ClauseCallback3Data0 callback) { | ||
95 | dnfBuilder.clause(callback); | ||
96 | return self(); | ||
97 | } | ||
98 | |||
99 | public <U1> T clause(Class<U1> type1, ClauseCallback3Data1<U1> callback) { | ||
100 | dnfBuilder.clause(type1, callback); | ||
101 | return self(); | ||
102 | } | ||
103 | |||
104 | public <U1, U2> T clause(Class<U1> type1, Class<U2> type2, ClauseCallback3Data2<U1, U2> callback) { | ||
105 | dnfBuilder.clause(type1, type2, callback); | ||
106 | return self(); | ||
107 | } | ||
108 | |||
109 | public <U1, U2, U3> T clause(Class<U1> type1, Class<U2> type2, Class<U3> type3, | ||
110 | ClauseCallback3Data3<U1, U2, U3> callback) { | ||
111 | dnfBuilder.clause(type1, type2, type3, callback); | ||
112 | return self(); | ||
113 | } | ||
114 | |||
115 | public T clause(ClauseCallback4Data0 callback) { | ||
116 | dnfBuilder.clause(callback); | ||
117 | return self(); | ||
118 | } | ||
119 | |||
120 | public <U1> T clause(Class<U1> type1, ClauseCallback4Data1<U1> callback) { | ||
121 | dnfBuilder.clause(type1, callback); | ||
122 | return self(); | ||
123 | } | ||
124 | |||
125 | public <U1, U2> T clause(Class<U1> type1, Class<U2> type2, ClauseCallback4Data2<U1, U2> callback) { | ||
126 | dnfBuilder.clause(type1, type2, callback); | ||
127 | return self(); | ||
128 | } | ||
129 | |||
130 | public <U1, U2, U3> T clause(Class<U1> type1, Class<U2> type2, Class<U3> type3, | ||
131 | ClauseCallback4Data3<U1, U2, U3> callback) { | ||
132 | dnfBuilder.clause(type1, type2, type3, callback); | ||
133 | return self(); | ||
134 | } | ||
135 | |||
136 | public <U1, U2, U3, U4> T clause(Class<U1> type1, Class<U2> type2, Class<U3> type3, Class<U4> type4, | ||
137 | ClauseCallback4Data4<U1, U2, U3, U4> callback) { | ||
138 | dnfBuilder.clause(type1, type2, type3, type4, callback); | ||
139 | return self(); | ||
140 | } | ||
141 | |||
142 | public T clause(Literal... literals) { | ||
143 | dnfBuilder.clause(literals); | ||
144 | return self(); | ||
145 | } | ||
146 | |||
147 | public T clause(Collection<? extends Literal> literals) { | ||
148 | dnfBuilder.clause(literals); | ||
149 | return self(); | ||
150 | } | ||
151 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java index 3321a10f..8de5079d 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Dnf.java | |||
@@ -16,6 +16,7 @@ import java.util.Collection; | |||
16 | import java.util.HashSet; | 16 | import java.util.HashSet; |
17 | import java.util.List; | 17 | import java.util.List; |
18 | import java.util.Set; | 18 | import java.util.Set; |
19 | import java.util.function.Consumer; | ||
19 | 20 | ||
20 | public final class Dnf implements Constraint { | 21 | public final class Dnf implements Constraint { |
21 | private static final String INDENTATION = " "; | 22 | private static final String INDENTATION = " "; |
@@ -196,4 +197,14 @@ public final class Dnf implements Constraint { | |||
196 | public static DnfBuilder builder(String name) { | 197 | public static DnfBuilder builder(String name) { |
197 | return new DnfBuilder(name); | 198 | return new DnfBuilder(name); |
198 | } | 199 | } |
200 | |||
201 | public static Dnf of(Consumer<DnfBuilder> callback) { | ||
202 | return of(null, callback); | ||
203 | } | ||
204 | |||
205 | public static Dnf of(String name, Consumer<DnfBuilder> callback) { | ||
206 | var builder = builder(name); | ||
207 | callback.accept(builder); | ||
208 | return builder.build(); | ||
209 | } | ||
199 | } | 210 | } |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java index 4f920f8f..a42ae558 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/DnfBuilder.java | |||
@@ -5,8 +5,10 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.store.query.dnf; | 6 | package tools.refinery.store.query.dnf; |
7 | 7 | ||
8 | import tools.refinery.store.query.dnf.callback.*; | ||
8 | import tools.refinery.store.query.literal.Literal; | 9 | import tools.refinery.store.query.literal.Literal; |
9 | import tools.refinery.store.query.term.DataVariable; | 10 | import tools.refinery.store.query.term.DataVariable; |
11 | import tools.refinery.store.query.term.NodeVariable; | ||
10 | import tools.refinery.store.query.term.Variable; | 12 | import tools.refinery.store.query.term.Variable; |
11 | 13 | ||
12 | import java.util.*; | 14 | import java.util.*; |
@@ -25,6 +27,26 @@ public final class DnfBuilder { | |||
25 | this.name = name; | 27 | this.name = name; |
26 | } | 28 | } |
27 | 29 | ||
30 | public NodeVariable parameter() { | ||
31 | return parameter((String) null); | ||
32 | } | ||
33 | |||
34 | public NodeVariable parameter(String name) { | ||
35 | var variable = Variable.of(name); | ||
36 | parameter(variable); | ||
37 | return variable; | ||
38 | } | ||
39 | |||
40 | public <T> DataVariable<T> parameter(Class<T> type) { | ||
41 | return parameter(null, type); | ||
42 | } | ||
43 | |||
44 | public <T> DataVariable<T> parameter(String name, Class<T> type) { | ||
45 | var variable = Variable.of(name, type); | ||
46 | parameter(variable); | ||
47 | return variable; | ||
48 | } | ||
49 | |||
28 | public DnfBuilder parameter(Variable variable) { | 50 | public DnfBuilder parameter(Variable variable) { |
29 | if (parameters.contains(variable)) { | 51 | if (parameters.contains(variable)) { |
30 | throw new IllegalArgumentException("Duplicate parameter: " + variable); | 52 | throw new IllegalArgumentException("Duplicate parameter: " + variable); |
@@ -56,6 +78,74 @@ public final class DnfBuilder { | |||
56 | return functionalDependency(new FunctionalDependency<>(Set.copyOf(forEach), Set.copyOf(unique))); | 78 | return functionalDependency(new FunctionalDependency<>(Set.copyOf(forEach), Set.copyOf(unique))); |
57 | } | 79 | } |
58 | 80 | ||
81 | public DnfBuilder clause(ClauseCallback0 callback) { | ||
82 | return clause(callback.toLiterals()); | ||
83 | } | ||
84 | |||
85 | public DnfBuilder clause(ClauseCallback1Data0 callback) { | ||
86 | return clause(callback.toLiterals(Variable.of("v1"))); | ||
87 | } | ||
88 | |||
89 | public <T> DnfBuilder clause(Class<T> type1, ClauseCallback1Data1<T> callback) { | ||
90 | return clause(callback.toLiterals(Variable.of("v1", type1))); | ||
91 | } | ||
92 | |||
93 | public DnfBuilder clause(ClauseCallback2Data0 callback) { | ||
94 | return clause(callback.toLiterals(Variable.of("v1"), Variable.of("v2"))); | ||
95 | } | ||
96 | |||
97 | public <T> DnfBuilder clause(Class<T> type1, ClauseCallback2Data1<T> callback) { | ||
98 | return clause(callback.toLiterals(Variable.of("v1"), Variable.of("d1", type1))); | ||
99 | } | ||
100 | |||
101 | public <T1, T2> DnfBuilder clause(Class<T1> type1, Class<T2> type2, ClauseCallback2Data2<T1, T2> callback) { | ||
102 | return clause(callback.toLiterals(Variable.of("d1", type1), Variable.of("d2", type2))); | ||
103 | } | ||
104 | |||
105 | public DnfBuilder clause(ClauseCallback3Data0 callback) { | ||
106 | return clause(callback.toLiterals(Variable.of("v1"), Variable.of("v2"), Variable.of("v3"))); | ||
107 | } | ||
108 | |||
109 | public <T> DnfBuilder clause(Class<T> type1, ClauseCallback3Data1<T> callback) { | ||
110 | return clause(callback.toLiterals(Variable.of("v1"), Variable.of("v2"), Variable.of("d1", type1))); | ||
111 | } | ||
112 | |||
113 | public <T1, T2> DnfBuilder clause(Class<T1> type1, Class<T2> type2, ClauseCallback3Data2<T1, T2> callback) { | ||
114 | return clause(callback.toLiterals(Variable.of("v1"), Variable.of("d1", type1), Variable.of("d2", type2))); | ||
115 | } | ||
116 | |||
117 | public <T1, T2, T3> DnfBuilder clause(Class<T1> type1, Class<T2> type2, Class<T3> type3, | ||
118 | ClauseCallback3Data3<T1, T2, T3> callback) { | ||
119 | return clause(callback.toLiterals(Variable.of("d1", type1), Variable.of("d2", type2), | ||
120 | Variable.of("d3", type3))); | ||
121 | } | ||
122 | |||
123 | public DnfBuilder clause(ClauseCallback4Data0 callback) { | ||
124 | return clause(callback.toLiterals(Variable.of("v1"), Variable.of("v2"), Variable.of("v3"), Variable.of("v4"))); | ||
125 | } | ||
126 | |||
127 | public <T> DnfBuilder clause(Class<T> type1, ClauseCallback4Data1<T> callback) { | ||
128 | return clause(callback.toLiterals(Variable.of("v1"), Variable.of("v2"), Variable.of("v3"), Variable.of("d1", | ||
129 | type1))); | ||
130 | } | ||
131 | |||
132 | public <T1, T2> DnfBuilder clause(Class<T1> type1, Class<T2> type2, ClauseCallback4Data2<T1, T2> callback) { | ||
133 | return clause(callback.toLiterals(Variable.of("v1"), Variable.of("v2"), Variable.of("d1", type1), | ||
134 | Variable.of("d2", type2))); | ||
135 | } | ||
136 | |||
137 | public <T1, T2, T3> DnfBuilder clause(Class<T1> type1, Class<T2> type2, Class<T3> type3, | ||
138 | ClauseCallback4Data3<T1, T2, T3> callback) { | ||
139 | return clause(callback.toLiterals(Variable.of("v1"), Variable.of("d1", type1), Variable.of("d2", type2), | ||
140 | Variable.of("d3", type3))); | ||
141 | } | ||
142 | |||
143 | public <T1, T2, T3, T4> DnfBuilder clause(Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, | ||
144 | ClauseCallback4Data4<T1, T2, T3, T4> callback) { | ||
145 | return clause(callback.toLiterals(Variable.of("d1", type1), Variable.of("d2", type2), | ||
146 | Variable.of("d3", type3), Variable.of("d4", type4))); | ||
147 | } | ||
148 | |||
59 | public DnfBuilder clause(Literal... literals) { | 149 | public DnfBuilder clause(Literal... literals) { |
60 | clause(List.of(literals)); | 150 | clause(List.of(literals)); |
61 | return this; | 151 | return this; |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQueryBuilder.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQueryBuilder.java index 63580676..d1cd7ba8 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQueryBuilder.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQueryBuilder.java | |||
@@ -5,47 +5,25 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.store.query.dnf; | 6 | package tools.refinery.store.query.dnf; |
7 | 7 | ||
8 | import tools.refinery.store.query.literal.Literal; | 8 | import tools.refinery.store.query.term.DataVariable; |
9 | import tools.refinery.store.query.term.Variable; | ||
10 | 9 | ||
11 | import java.util.Collection; | 10 | public final class FunctionalQueryBuilder<T> extends AbstractQueryBuilder<FunctionalQueryBuilder<T>> { |
12 | import java.util.Set; | 11 | private final DataVariable<T> outputVariable; |
13 | |||
14 | public final class FunctionalQueryBuilder<T> { | ||
15 | private final DnfBuilder dnfBuilder; | ||
16 | private final Class<T> type; | 12 | private final Class<T> type; |
17 | 13 | ||
18 | FunctionalQueryBuilder(DnfBuilder dnfBuilder, Class<T> type) { | 14 | FunctionalQueryBuilder(DataVariable<T> outputVariable, DnfBuilder dnfBuilder, Class<T> type) { |
19 | this.dnfBuilder = dnfBuilder; | 15 | super(dnfBuilder); |
16 | this.outputVariable = outputVariable; | ||
20 | this.type = type; | 17 | this.type = type; |
21 | } | 18 | } |
22 | 19 | ||
23 | public FunctionalQueryBuilder<T> functionalDependencies(Collection<FunctionalDependency<Variable>> functionalDependencies) { | 20 | @Override |
24 | dnfBuilder.functionalDependencies(functionalDependencies); | 21 | protected FunctionalQueryBuilder<T> self() { |
25 | return this; | ||
26 | } | ||
27 | |||
28 | public FunctionalQueryBuilder<T> functionalDependency(FunctionalDependency<Variable> functionalDependency) { | ||
29 | dnfBuilder.functionalDependency(functionalDependency); | ||
30 | return this; | ||
31 | } | ||
32 | |||
33 | public FunctionalQueryBuilder<T> functionalDependency(Set<? extends Variable> forEach, Set<? extends Variable> unique) { | ||
34 | dnfBuilder.functionalDependency(forEach, unique); | ||
35 | return this; | ||
36 | } | ||
37 | |||
38 | public FunctionalQueryBuilder<T> clause(Literal... literals) { | ||
39 | dnfBuilder.clause(literals); | ||
40 | return this; | ||
41 | } | ||
42 | |||
43 | public FunctionalQueryBuilder<T> clause(Collection<? extends Literal> literals) { | ||
44 | dnfBuilder.clause(literals); | ||
45 | return this; | 22 | return this; |
46 | } | 23 | } |
47 | 24 | ||
48 | public FunctionalQuery<T> build() { | 25 | public FunctionalQuery<T> build() { |
26 | dnfBuilder.output(outputVariable); | ||
49 | return dnfBuilder.build().asFunction(type); | 27 | return dnfBuilder.build().asFunction(type); |
50 | } | 28 | } |
51 | } | 29 | } |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Query.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Query.java index d3de475f..e94c0c6b 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Query.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/Query.java | |||
@@ -5,17 +5,130 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.store.query.dnf; | 6 | package tools.refinery.store.query.dnf; |
7 | 7 | ||
8 | import tools.refinery.store.query.dnf.callback.*; | ||
9 | import tools.refinery.store.query.term.Variable; | ||
10 | |||
8 | public sealed interface Query<T> extends AnyQuery permits RelationalQuery, FunctionalQuery { | 11 | public sealed interface Query<T> extends AnyQuery permits RelationalQuery, FunctionalQuery { |
12 | String OUTPUT_VARIABLE_NAME = "output"; | ||
13 | |||
9 | @Override | 14 | @Override |
10 | Class<T> valueType(); | 15 | Class<T> valueType(); |
11 | 16 | ||
12 | T defaultValue(); | 17 | T defaultValue(); |
13 | 18 | ||
14 | static QueryBuilder builder() { | 19 | static QueryBuilder builder() { |
15 | return new QueryBuilder(); | 20 | return builder(null); |
16 | } | 21 | } |
17 | 22 | ||
18 | static QueryBuilder builder(String name) { | 23 | static QueryBuilder builder(String name) { |
19 | return new QueryBuilder(name); | 24 | return new QueryBuilder(name); |
20 | } | 25 | } |
26 | |||
27 | static RelationalQuery of(QueryCallback0 callback) { | ||
28 | return of(null, callback); | ||
29 | } | ||
30 | |||
31 | static RelationalQuery of(String name, QueryCallback0 callback) { | ||
32 | var builder = builder(name); | ||
33 | callback.accept(builder); | ||
34 | return builder.build(); | ||
35 | } | ||
36 | |||
37 | static RelationalQuery of(QueryCallback1 callback) { | ||
38 | return of(null, callback); | ||
39 | } | ||
40 | |||
41 | static RelationalQuery of(String name, QueryCallback1 callback) { | ||
42 | var builder = builder(name); | ||
43 | callback.accept(builder, builder.parameter("p1")); | ||
44 | return builder.build(); | ||
45 | } | ||
46 | |||
47 | static RelationalQuery of(QueryCallback2 callback) { | ||
48 | return of(null, callback); | ||
49 | } | ||
50 | |||
51 | static RelationalQuery of(String name, QueryCallback2 callback) { | ||
52 | var builder = builder(name); | ||
53 | callback.accept(builder, builder.parameter("p1"), builder.parameter("p2")); | ||
54 | return builder.build(); | ||
55 | } | ||
56 | |||
57 | static RelationalQuery of(QueryCallback3 callback) { | ||
58 | return of(null, callback); | ||
59 | } | ||
60 | |||
61 | static RelationalQuery of(String name, QueryCallback3 callback) { | ||
62 | var builder = builder(name); | ||
63 | callback.accept(builder, builder.parameter("p1"), builder.parameter("p2"), builder.parameter("p3")); | ||
64 | return builder.build(); | ||
65 | } | ||
66 | |||
67 | static RelationalQuery of(QueryCallback4 callback) { | ||
68 | return of(null, callback); | ||
69 | } | ||
70 | |||
71 | static RelationalQuery of(String name, QueryCallback4 callback) { | ||
72 | var builder = builder(name); | ||
73 | callback.accept(builder, builder.parameter("p1"), builder.parameter("p2"), builder.parameter("p3"), | ||
74 | builder.parameter("p4")); | ||
75 | return builder.build(); | ||
76 | } | ||
77 | |||
78 | static <T> FunctionalQuery<T> of(Class<T> type, FunctionalQueryCallback0<T> callback) { | ||
79 | return of(null, type, callback); | ||
80 | } | ||
81 | |||
82 | static <T> FunctionalQuery<T> of(String name, Class<T> type, FunctionalQueryCallback0<T> callback) { | ||
83 | var outputVariable = Variable.of(OUTPUT_VARIABLE_NAME, type); | ||
84 | var builder = builder(name).output(outputVariable); | ||
85 | callback.accept(builder, outputVariable); | ||
86 | return builder.build(); | ||
87 | } | ||
88 | |||
89 | static <T> FunctionalQuery<T> of(Class<T> type, FunctionalQueryCallback1<T> callback) { | ||
90 | return of(null, type, callback); | ||
91 | } | ||
92 | |||
93 | static <T> FunctionalQuery<T> of(String name, Class<T> type, FunctionalQueryCallback1<T> callback) { | ||
94 | var outputVariable = Variable.of(OUTPUT_VARIABLE_NAME, type); | ||
95 | var builder = builder(name).output(outputVariable); | ||
96 | callback.accept(builder, builder.parameter("p1"), outputVariable); | ||
97 | return builder.build(); | ||
98 | } | ||
99 | |||
100 | static <T> FunctionalQuery<T> of(Class<T> type, FunctionalQueryCallback2<T> callback) { | ||
101 | return of(null, type, callback); | ||
102 | } | ||
103 | |||
104 | static <T> FunctionalQuery<T> of(String name, Class<T> type, FunctionalQueryCallback2<T> callback) { | ||
105 | var outputVariable = Variable.of(OUTPUT_VARIABLE_NAME, type); | ||
106 | var builder = builder(name).output(outputVariable); | ||
107 | callback.accept(builder, builder.parameter("p1"), builder.parameter("p2"), outputVariable); | ||
108 | return builder.build(); | ||
109 | } | ||
110 | |||
111 | static <T> FunctionalQuery<T> of(Class<T> type, FunctionalQueryCallback3<T> callback) { | ||
112 | return of(null, type, callback); | ||
113 | } | ||
114 | |||
115 | static <T> FunctionalQuery<T> of(String name, Class<T> type, FunctionalQueryCallback3<T> callback) { | ||
116 | var outputVariable = Variable.of(OUTPUT_VARIABLE_NAME, type); | ||
117 | var builder = builder(name).output(outputVariable); | ||
118 | callback.accept(builder, builder.parameter("p1"), builder.parameter("p2"), builder.parameter("p3"), | ||
119 | outputVariable); | ||
120 | return builder.build(); | ||
121 | } | ||
122 | |||
123 | static <T> FunctionalQuery<T> of(Class<T> type, FunctionalQueryCallback4<T> callback) { | ||
124 | return of(null, type, callback); | ||
125 | } | ||
126 | |||
127 | static <T> FunctionalQuery<T> of(String name, Class<T> type, FunctionalQueryCallback4<T> callback) { | ||
128 | var outputVariable = Variable.of(OUTPUT_VARIABLE_NAME, type); | ||
129 | var builder = builder(name).output(outputVariable); | ||
130 | callback.accept(builder, builder.parameter("p1"), builder.parameter("p2"), builder.parameter("p3"), | ||
131 | builder.parameter("p4"), outputVariable); | ||
132 | return builder.build(); | ||
133 | } | ||
21 | } | 134 | } |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/QueryBuilder.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/QueryBuilder.java index f925c9ac..138911bc 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/QueryBuilder.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/QueryBuilder.java | |||
@@ -5,69 +5,20 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.store.query.dnf; | 6 | package tools.refinery.store.query.dnf; |
7 | 7 | ||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.DataVariable; | 8 | import tools.refinery.store.query.term.DataVariable; |
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | import tools.refinery.store.query.term.Variable; | ||
12 | |||
13 | import java.util.Collection; | ||
14 | import java.util.List; | ||
15 | import java.util.Set; | ||
16 | |||
17 | public final class QueryBuilder { | ||
18 | private final DnfBuilder dnfBuilder; | ||
19 | 9 | ||
10 | public final class QueryBuilder extends AbstractQueryBuilder<QueryBuilder> { | ||
20 | QueryBuilder(String name) { | 11 | QueryBuilder(String name) { |
21 | dnfBuilder = Dnf.builder(name); | 12 | super(Dnf.builder(name)); |
22 | } | ||
23 | |||
24 | QueryBuilder() { | ||
25 | dnfBuilder = Dnf.builder(); | ||
26 | } | ||
27 | |||
28 | public QueryBuilder parameter(NodeVariable variable) { | ||
29 | dnfBuilder.parameter(variable); | ||
30 | return this; | ||
31 | } | 13 | } |
32 | 14 | ||
33 | public QueryBuilder parameters(NodeVariable... variables) { | 15 | @Override |
34 | dnfBuilder.parameters(variables); | 16 | protected QueryBuilder self() { |
35 | return this; | ||
36 | } | ||
37 | |||
38 | public QueryBuilder parameters(List<NodeVariable> variables) { | ||
39 | dnfBuilder.parameters(variables); | ||
40 | return this; | 17 | return this; |
41 | } | 18 | } |
42 | 19 | ||
43 | public <T> FunctionalQueryBuilder<T> output(DataVariable<T> outputVariable) { | 20 | public <T> FunctionalQueryBuilder<T> output(DataVariable<T> outputVariable) { |
44 | dnfBuilder.output(outputVariable); | 21 | return new FunctionalQueryBuilder<>(outputVariable, dnfBuilder, outputVariable.getType()); |
45 | return new FunctionalQueryBuilder<>(dnfBuilder, outputVariable.getType()); | ||
46 | } | ||
47 | |||
48 | public QueryBuilder functionalDependencies(Collection<FunctionalDependency<Variable>> functionalDependencies) { | ||
49 | dnfBuilder.functionalDependencies(functionalDependencies); | ||
50 | return this; | ||
51 | } | ||
52 | |||
53 | public QueryBuilder functionalDependency(FunctionalDependency<Variable> functionalDependency) { | ||
54 | dnfBuilder.functionalDependency(functionalDependency); | ||
55 | return this; | ||
56 | } | ||
57 | |||
58 | public QueryBuilder functionalDependency(Set<? extends Variable> forEach, Set<? extends Variable> unique) { | ||
59 | dnfBuilder.functionalDependency(forEach, unique); | ||
60 | return this; | ||
61 | } | ||
62 | |||
63 | public QueryBuilder clause(Literal... literals) { | ||
64 | dnfBuilder.clause(literals); | ||
65 | return this; | ||
66 | } | ||
67 | |||
68 | public QueryBuilder clause(Collection<? extends Literal> literals) { | ||
69 | dnfBuilder.clause(literals); | ||
70 | return this; | ||
71 | } | 22 | } |
72 | 23 | ||
73 | public RelationalQuery build() { | 24 | public RelationalQuery build() { |
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback0.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback0.java new file mode 100644 index 00000000..d98dda2e --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback0.java | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | |||
10 | import java.util.Collection; | ||
11 | |||
12 | @FunctionalInterface | ||
13 | public interface ClauseCallback0 { | ||
14 | Collection<Literal> toLiterals(); | ||
15 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data0.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data0.java new file mode 100644 index 00000000..4c01a527 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data0.java | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.NodeVariable; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | |||
13 | @FunctionalInterface | ||
14 | public interface ClauseCallback1Data0 { | ||
15 | Collection<Literal> toLiterals(NodeVariable v1); | ||
16 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data1.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data1.java new file mode 100644 index 00000000..2c0cb6eb --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback1Data1.java | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | |||
13 | @FunctionalInterface | ||
14 | public interface ClauseCallback1Data1<T> { | ||
15 | Collection<Literal> toLiterals(DataVariable<T> d1); | ||
16 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data0.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data0.java new file mode 100644 index 00000000..d764bdba --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data0.java | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.NodeVariable; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | |||
13 | @FunctionalInterface | ||
14 | public interface ClauseCallback2Data0 { | ||
15 | Collection<Literal> toLiterals(NodeVariable v1, NodeVariable v2); | ||
16 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data1.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data1.java new file mode 100644 index 00000000..140af03a --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data1.java | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | |||
12 | import java.util.Collection; | ||
13 | |||
14 | @FunctionalInterface | ||
15 | public interface ClauseCallback2Data1<T> { | ||
16 | Collection<Literal> toLiterals(NodeVariable v1, DataVariable<T> x1); | ||
17 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data2.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data2.java new file mode 100644 index 00000000..bfc8637c --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback2Data2.java | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | |||
13 | @FunctionalInterface | ||
14 | public interface ClauseCallback2Data2<T1, T2> { | ||
15 | Collection<Literal> toLiterals(DataVariable<T1> x1, DataVariable<T2> x2); | ||
16 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data0.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data0.java new file mode 100644 index 00000000..074df65b --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data0.java | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.NodeVariable; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | |||
13 | @FunctionalInterface | ||
14 | public interface ClauseCallback3Data0 { | ||
15 | Collection<Literal> toLiterals(NodeVariable v1, NodeVariable v2, NodeVariable v3); | ||
16 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data1.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data1.java new file mode 100644 index 00000000..24ba5187 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data1.java | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | |||
12 | import java.util.Collection; | ||
13 | |||
14 | @FunctionalInterface | ||
15 | public interface ClauseCallback3Data1<T> { | ||
16 | Collection<Literal> toLiterals(NodeVariable v1, NodeVariable v2, DataVariable<T> d1); | ||
17 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data2.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data2.java new file mode 100644 index 00000000..2a2e837a --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data2.java | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | |||
12 | import java.util.Collection; | ||
13 | |||
14 | @FunctionalInterface | ||
15 | public interface ClauseCallback3Data2<T1, T2> { | ||
16 | Collection<Literal> toLiterals(NodeVariable v1, DataVariable<T1> d1, DataVariable<T2> d2); | ||
17 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data3.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data3.java new file mode 100644 index 00000000..8f4bdd01 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback3Data3.java | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | |||
13 | @FunctionalInterface | ||
14 | public interface ClauseCallback3Data3<T1, T2, T3> { | ||
15 | Collection<Literal> toLiterals(DataVariable<T1> d1, DataVariable<T2> d2, DataVariable<T3> d3); | ||
16 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data0.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data0.java new file mode 100644 index 00000000..ed0f87b2 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data0.java | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.NodeVariable; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | |||
13 | @FunctionalInterface | ||
14 | public interface ClauseCallback4Data0 { | ||
15 | Collection<Literal> toLiterals(NodeVariable v1, NodeVariable v2, NodeVariable v3, NodeVariable v4); | ||
16 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data1.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data1.java new file mode 100644 index 00000000..9b27e2e1 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data1.java | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | |||
12 | import java.util.Collection; | ||
13 | |||
14 | @FunctionalInterface | ||
15 | public interface ClauseCallback4Data1<T> { | ||
16 | Collection<Literal> toLiterals(NodeVariable v1, NodeVariable v2, NodeVariable v3, DataVariable<T> d1); | ||
17 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data2.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data2.java new file mode 100644 index 00000000..cbc4808e --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data2.java | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | |||
12 | import java.util.Collection; | ||
13 | |||
14 | @FunctionalInterface | ||
15 | public interface ClauseCallback4Data2<T1, T2> { | ||
16 | Collection<Literal> toLiterals(NodeVariable v1, NodeVariable v2, DataVariable<T1> d1, DataVariable<T2> d2); | ||
17 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data3.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data3.java new file mode 100644 index 00000000..a6258f36 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data3.java | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | |||
12 | import java.util.Collection; | ||
13 | |||
14 | @FunctionalInterface | ||
15 | public interface ClauseCallback4Data3<T1, T2, T3> { | ||
16 | Collection<Literal> toLiterals(NodeVariable v1, DataVariable<T1> d1, DataVariable<T2> d2, DataVariable<T3> d3); | ||
17 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data4.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data4.java new file mode 100644 index 00000000..b52a911a --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/ClauseCallback4Data4.java | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.literal.Literal; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | |||
11 | import java.util.Collection; | ||
12 | |||
13 | @FunctionalInterface | ||
14 | public interface ClauseCallback4Data4<T1, T2, T3, T4> { | ||
15 | Collection<Literal> toLiterals(DataVariable<T1> d1, DataVariable<T2> d2, DataVariable<T3> d3, DataVariable<T4> d4); | ||
16 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback0.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback0.java new file mode 100644 index 00000000..63b3eee6 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback0.java | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.dnf.FunctionalQueryBuilder; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | |||
11 | @FunctionalInterface | ||
12 | public interface FunctionalQueryCallback0<T> { | ||
13 | void accept(FunctionalQueryBuilder<T> builder, DataVariable<T> output); | ||
14 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback1.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback1.java new file mode 100644 index 00000000..1295a118 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback1.java | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.dnf.FunctionalQueryBuilder; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | |||
12 | @FunctionalInterface | ||
13 | public interface FunctionalQueryCallback1<T> { | ||
14 | void accept(FunctionalQueryBuilder<T> builder, NodeVariable p1, DataVariable<T> output); | ||
15 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback2.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback2.java new file mode 100644 index 00000000..d5b7f9ff --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback2.java | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.dnf.FunctionalQueryBuilder; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | |||
12 | @FunctionalInterface | ||
13 | public interface FunctionalQueryCallback2<T> { | ||
14 | void accept(FunctionalQueryBuilder<T> builder, NodeVariable p1, NodeVariable p2, DataVariable<T> output); | ||
15 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback3.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback3.java new file mode 100644 index 00000000..dc8404a0 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback3.java | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.dnf.FunctionalQueryBuilder; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | |||
12 | @FunctionalInterface | ||
13 | public interface FunctionalQueryCallback3<T> { | ||
14 | void accept(FunctionalQueryBuilder<T> builder, NodeVariable p1, NodeVariable p2, NodeVariable p3, | ||
15 | DataVariable<T> output); | ||
16 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback4.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback4.java new file mode 100644 index 00000000..b6d3ddb0 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/FunctionalQueryCallback4.java | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.dnf.FunctionalQueryBuilder; | ||
9 | import tools.refinery.store.query.term.DataVariable; | ||
10 | import tools.refinery.store.query.term.NodeVariable; | ||
11 | |||
12 | @FunctionalInterface | ||
13 | public interface FunctionalQueryCallback4<T> { | ||
14 | void accept(FunctionalQueryBuilder<T> builder, NodeVariable p1, NodeVariable p2, NodeVariable p3, NodeVariable p4, | ||
15 | DataVariable<T> output); | ||
16 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback0.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback0.java new file mode 100644 index 00000000..3cf1de48 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback0.java | |||
@@ -0,0 +1,13 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.dnf.QueryBuilder; | ||
9 | |||
10 | @FunctionalInterface | ||
11 | public interface QueryCallback0 { | ||
12 | void accept(QueryBuilder builder); | ||
13 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback1.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback1.java new file mode 100644 index 00000000..0a150955 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback1.java | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.dnf.QueryBuilder; | ||
9 | import tools.refinery.store.query.term.NodeVariable; | ||
10 | |||
11 | @FunctionalInterface | ||
12 | public interface QueryCallback1 { | ||
13 | void accept(QueryBuilder builder, NodeVariable p1); | ||
14 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback2.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback2.java new file mode 100644 index 00000000..9493a7b4 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback2.java | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.dnf.QueryBuilder; | ||
9 | import tools.refinery.store.query.term.NodeVariable; | ||
10 | |||
11 | @FunctionalInterface | ||
12 | public interface QueryCallback2 { | ||
13 | void accept(QueryBuilder builder, NodeVariable p1, NodeVariable p2); | ||
14 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback3.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback3.java new file mode 100644 index 00000000..358c7da7 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback3.java | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.dnf.QueryBuilder; | ||
9 | import tools.refinery.store.query.term.NodeVariable; | ||
10 | |||
11 | @FunctionalInterface | ||
12 | public interface QueryCallback3 { | ||
13 | void accept(QueryBuilder builder, NodeVariable p1, NodeVariable p2, NodeVariable p3); | ||
14 | } | ||
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback4.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback4.java new file mode 100644 index 00000000..890dda16 --- /dev/null +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/callback/QueryCallback4.java | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.query.dnf.callback; | ||
7 | |||
8 | import tools.refinery.store.query.dnf.QueryBuilder; | ||
9 | import tools.refinery.store.query.term.NodeVariable; | ||
10 | |||
11 | @FunctionalInterface | ||
12 | public interface QueryCallback4 { | ||
13 | void accept(QueryBuilder builder, NodeVariable p1, NodeVariable p2, NodeVariable p3, NodeVariable p4); | ||
14 | } | ||