aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-dse/src/test/java/tools
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2023-09-14 19:29:36 +0200
committerLibravatar GitHub <noreply@github.com>2023-09-14 19:29:36 +0200
commit98ed3b6db5f4e51961a161050cc31c66015116e8 (patch)
tree8bfd6d9bc8d6ed23b9eb0f889dd40b6c24fe8f92 /subprojects/store-dse/src/test/java/tools
parentMerge pull request #38 from nagilooh/design-space-exploration (diff)
parentMerge remote-tracking branch 'upstream/main' into partial-interpretation (diff)
downloadrefinery-98ed3b6db5f4e51961a161050cc31c66015116e8.tar.gz
refinery-98ed3b6db5f4e51961a161050cc31c66015116e8.tar.zst
refinery-98ed3b6db5f4e51961a161050cc31c66015116e8.zip
Merge pull request #39 from kris7t/partial-interpretation
Implement partial interpretation based model generation
Diffstat (limited to 'subprojects/store-dse/src/test/java/tools')
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/ActionEqualsTest.java629
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java237
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/DebugTest.java118
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/DesignSpaceExplorationTest.java607
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java413
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyCriterion.java22
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyObjective.java18
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomCriterion.java25
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomObjective.java23
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/QueryAssertions.java2
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java149
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/statespace/internal/ActivationUnitTest.java131
12 files changed, 494 insertions, 1880 deletions
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/ActionEqualsTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/ActionEqualsTest.java
deleted file mode 100644
index d4a05d12..00000000
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/ActionEqualsTest.java
+++ /dev/null
@@ -1,629 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse;
7
8import org.junit.jupiter.api.BeforeAll;
9import org.junit.jupiter.api.Test;
10import tools.refinery.store.dse.internal.action.*;
11import tools.refinery.store.dse.strategy.DepthFirstStrategy;
12import tools.refinery.store.model.Model;
13import tools.refinery.store.model.ModelStore;
14import tools.refinery.store.query.dnf.Query;
15import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
16import tools.refinery.store.query.view.KeyOnlyView;
17import tools.refinery.store.representation.Symbol;
18
19import static org.junit.jupiter.api.Assertions.assertFalse;
20import static org.junit.jupiter.api.Assertions.assertTrue;
21
22public class ActionEqualsTest {
23
24 private static Model model;
25 private static Symbol<Boolean> type1;
26 private static Symbol<Boolean> relation1;
27 private static Symbol<Boolean> relation2;
28
29 @BeforeAll
30 public static void init() {
31 type1 = Symbol.of("type1", 1);
32 relation1 = Symbol.of("relation1", 2);
33 relation2 = Symbol.of("relation2", 2);
34 var type1View = new KeyOnlyView<>(type1);
35 var precondition1 = Query.of("CreateClassPrecondition",
36 (builder, model) -> builder.clause(
37 type1View.call(model)
38 ));
39
40 var precondition2 = Query.of("CreateFeaturePrecondition",
41 (builder, model) -> builder.clause(
42 type1View.call(model)
43 ));
44 var store = ModelStore.builder()
45 .symbols(type1, relation2, relation1)
46 .with(ViatraModelQueryAdapter.builder()
47 .queries(precondition1, precondition2))
48 .with(DesignSpaceExplorationAdapter.builder()
49 .strategy(new DepthFirstStrategy()))
50 .build();
51
52
53 model = store.createEmptyModel();
54 }
55
56 @Test
57 void emptyActionEqualsTest() {
58 var action1 = new TransformationAction();
59 var action2 = new TransformationAction();
60
61 assertTrue(action1.equalsWithSubstitution(action1));
62 assertTrue(action2.equalsWithSubstitution(action2));
63 assertTrue(action1.equalsWithSubstitution(action2));
64 }
65
66 @Test
67 void actionTrivialTest() {
68 var newItemSymbol1 = new NewItemVariable();
69 var activationSymbol = new ActivationVariable();
70 var insertAction1 = new InsertAction<>(model.getInterpretation(type1), true, newItemSymbol1);
71 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
72 activationSymbol);
73 var insertAction3 = new InsertAction<>(model.getInterpretation(type1), true, newItemSymbol1);
74 var insertAction4 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
75 activationSymbol);
76
77 var action1 = new TransformationAction();
78 action1.add(newItemSymbol1);
79 action1.add(activationSymbol);
80 action1.add(insertAction1);
81 action1.add(insertAction2);
82 action1.prepare(model);
83
84 var action2 = new TransformationAction();
85 action2.add(newItemSymbol1);
86 action2.add(activationSymbol);
87 action2.add(insertAction3);
88 action2.add(insertAction4);
89 action2.prepare(model);
90
91 assertTrue(action1.equalsWithSubstitution(action2));
92 }
93
94 @Test
95 void actionIdenticalTest() {
96 var newItemSymbol1 = new NewItemVariable();
97 var activationSymbol1 = new ActivationVariable();
98 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
99 activationSymbol1);
100
101 var action1 = new TransformationAction();
102 action1.add(newItemSymbol1);
103 action1.add(activationSymbol1);
104 action1.add(insertAction1);
105 action1.prepare(model);
106
107 var newItemSymbol2 = new NewItemVariable();
108 var activationSymbol2 = new ActivationVariable();
109 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2,
110 activationSymbol2);
111
112 var action2 = new TransformationAction();
113 action2.add(newItemSymbol2);
114 action2.add(activationSymbol2);
115 action2.add(insertAction2);
116 action2.prepare(model);
117
118 assertTrue(action1.equalsWithSubstitution(action2));
119 }
120
121 @Test
122 void actionSymbolGlobalOrderTest() {
123 var newItemSymbol1 = new NewItemVariable();
124 var activationSymbol1 = new ActivationVariable();
125 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
126 activationSymbol1);
127
128 var action1 = new TransformationAction();
129 action1.add(newItemSymbol1);
130 action1.add(activationSymbol1);
131 action1.add(insertAction1);
132 action1.prepare(model);
133
134 var newItemSymbol2 = new NewItemVariable();
135 var activationSymbol2 = new ActivationVariable();
136 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2,
137 activationSymbol2);
138
139 var action2 = new TransformationAction();
140 action2.add(activationSymbol2);
141 action2.add(newItemSymbol2);
142 action2.add(insertAction2);
143 action2.prepare(model);
144
145 assertFalse(action1.equalsWithSubstitution(action2));
146 }
147
148 @Test
149 void actionSymbolRepeatedInInsertActionTest() {
150 var newItemSymbol1 = new NewItemVariable();
151 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
152 newItemSymbol1);
153
154 var action1 = new TransformationAction();
155 action1.add(newItemSymbol1);
156 action1.add(insertAction1);
157 action1.prepare(model);
158
159 var newItemSymbol2 = new NewItemVariable();
160 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2,
161 newItemSymbol2);
162
163 var action2 = new TransformationAction();
164 action2.add(newItemSymbol2);
165 action2.add(insertAction2);
166 action2.prepare(model);
167
168 assertTrue(action1.equalsWithSubstitution(action2));
169 }
170
171 @Test
172 void identicalInsertActionInDifferentOrderTest() {
173 var newItemSymbol1 = new NewItemVariable();
174 var activationSymbol1 = new ActivationVariable();
175 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
176 activationSymbol1);
177 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
178 activationSymbol1);
179
180 var action1 = new TransformationAction();
181 action1.add(newItemSymbol1);
182 action1.add(activationSymbol1);
183 action1.add(insertAction1);
184 action1.add(insertAction2);
185 action1.prepare(model);
186
187 var action2 = new TransformationAction();
188 action2.add(newItemSymbol1);
189 action2.add(activationSymbol1);
190 action2.add(insertAction2);
191 action2.add(insertAction1);
192 action2.prepare(model);
193
194 assertTrue(action1.equalsWithSubstitution(action2));
195 }
196
197 @Test
198 void identicalActionAndSymbolDifferentOrderTest() {
199 var newItemSymbol1 = new NewItemVariable();
200 var newItemSymbol2 = new NewItemVariable();
201 var activationSymbol1 = new ActivationVariable();
202 var activationSymbol2 = new ActivationVariable();
203
204 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
205 activationSymbol1);
206
207 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2,
208 activationSymbol2);
209
210 var action1 = new TransformationAction();
211 action1.add(newItemSymbol1);
212 action1.add(newItemSymbol2);
213 action1.add(activationSymbol1);
214 action1.add(activationSymbol2);
215 action1.add(insertAction1);
216 action1.add(insertAction2);
217 action1.prepare(model);
218
219 var action2 = new TransformationAction();
220 action2.add(newItemSymbol2);
221 action2.add(newItemSymbol1);
222 action2.add(activationSymbol2);
223 action2.add(activationSymbol1);
224 action2.add(insertAction2);
225 action2.add(insertAction1);
226 action2.prepare(model);
227
228 assertTrue(action1.equalsWithSubstitution(action2));
229 }
230
231 @Test
232 void identicalActionAndSymbolMixedOrderTest() {
233 var newItemSymbol1 = new NewItemVariable();
234 var activationSymbol1 = new ActivationVariable();
235 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
236 activationSymbol1);
237
238 var newItemSymbol2 = new NewItemVariable();
239 var activationSymbol2 = new ActivationVariable();
240 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2,
241 activationSymbol2);
242
243 var action1 = new TransformationAction();
244 action1.add(newItemSymbol1);
245 action1.add(newItemSymbol2);
246 action1.add(activationSymbol1);
247 action1.add(activationSymbol2);
248 action1.add(insertAction1);
249 action1.add(insertAction2);
250 action1.prepare(model);
251
252 var action2 = new TransformationAction();
253 action2.add(insertAction1);
254 action2.add(newItemSymbol1);
255 action2.add(newItemSymbol2);
256 action2.add(activationSymbol1);
257 action2.add(insertAction2);
258 action2.add(activationSymbol2);
259 action2.prepare(model);
260
261 assertTrue(action1.equalsWithSubstitution(action2));
262 }
263
264 @Test
265 void insertActionInterpretationTest() {
266 var newItemSymbol1 = new NewItemVariable();
267 var activationSymbol1 = new ActivationVariable();
268 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
269 activationSymbol1);
270 var insertAction2 = new InsertAction<>(model.getInterpretation(relation2), true, newItemSymbol1,
271 activationSymbol1);
272
273 var action1 = new TransformationAction();
274 action1.add(newItemSymbol1);
275 action1.add(activationSymbol1);
276 action1.add(insertAction1);
277 action1.prepare(model);
278
279 var action2 = new TransformationAction();
280 action2.add(newItemSymbol1);
281 action2.add(activationSymbol1);
282 action2.add(insertAction2);
283 action2.prepare(model);
284
285 assertFalse(action1.equalsWithSubstitution(action2));
286 }
287
288 @Test
289 void insertActionValueTest() {
290 var newItemSymbol1 = new NewItemVariable();
291 var activationSymbol1 = new ActivationVariable();
292 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
293 activationSymbol1);
294 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol1,
295 activationSymbol1);
296
297 var action1 = new TransformationAction();
298 action1.add(newItemSymbol1);
299 action1.add(activationSymbol1);
300 action1.add(insertAction1);
301 action1.prepare(model);
302
303 var action2 = new TransformationAction();
304 action2.add(newItemSymbol1);
305 action2.add(activationSymbol1);
306 action2.add(insertAction2);
307 action2.prepare(model);
308
309 assertFalse(action1.equalsWithSubstitution(action2));
310 }
311
312 @Test
313 void newItemSymbolDuplicateTest() {
314 var newItemSymbol1 = new NewItemVariable();
315 var newItemSymbol2 = new NewItemVariable();
316 var activationSymbol1 = new ActivationVariable();
317 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
318 activationSymbol1);
319 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2,
320 activationSymbol1);
321
322 var action1 = new TransformationAction();
323 action1.add(newItemSymbol1);
324 action1.add(activationSymbol1);
325 action1.add(insertAction1);
326 action1.prepare(model);
327
328 var action2 = new TransformationAction();
329 action2.add(newItemSymbol2);
330 action2.add(activationSymbol1);
331 action2.add(insertAction2);
332 action2.prepare(model);
333
334 assertTrue(action1.equalsWithSubstitution(action2));
335 }
336
337 @Test
338 void activationSymbolDuplicateTest() {
339 var newItemSymbol1 = new NewItemVariable();
340 var activationSymbol1 = new ActivationVariable();
341 var activationSymbol2 = new ActivationVariable();
342 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
343 activationSymbol1);
344 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
345 activationSymbol2);
346
347 var action1 = new TransformationAction();
348 action1.add(newItemSymbol1);
349 action1.add(activationSymbol1);
350 action1.add(insertAction1);
351 action1.prepare(model);
352
353 var action2 = new TransformationAction();
354 action2.add(newItemSymbol1);
355 action2.add(activationSymbol2);
356 action2.add(insertAction2);
357 action2.prepare(model);
358
359 assertTrue(action1.equalsWithSubstitution(action2));
360 }
361
362 @Test
363 void activationSymbolIndexTest() {
364 var newItemSymbol1 = new NewItemVariable();
365 var activationSymbol1 = new ActivationVariable(0);
366 var activationSymbol2 = new ActivationVariable(1);
367 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
368 activationSymbol1);
369 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
370 activationSymbol2);
371
372 var action1 = new TransformationAction();
373 action1.add(newItemSymbol1);
374 action1.add(activationSymbol1);
375 action1.add(insertAction1);
376 action1.prepare(model);
377
378 var action2 = new TransformationAction();
379 action2.add(newItemSymbol1);
380 action2.add(activationSymbol2);
381 action2.add(insertAction2);
382 action2.prepare(model);
383
384 assertFalse(action1.equalsWithSubstitution(action2));
385 }
386
387 @Test
388 void deleteActionTest() {
389 var newItemSymbol = new NewItemVariable();
390 var activationSymbol = new ActivationVariable(0);
391 var insertAction = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol,
392 activationSymbol);
393 var deleteAction = new DeleteAction(activationSymbol);
394
395 var action1 = new TransformationAction();
396 action1.add(newItemSymbol);
397 action1.add(activationSymbol);
398 action1.add(insertAction);
399 action1.add(deleteAction);
400 action1.prepare(model);
401
402 var action2 = new TransformationAction();
403 action2.add(newItemSymbol);
404 action2.add(activationSymbol);
405 action2.add(insertAction);
406 action2.add(deleteAction);
407 action2.prepare(model);
408
409 assertTrue(action1.equalsWithSubstitution(action2));
410 }
411
412 @Test
413 void deleteActionMissingTest() {
414 var newItemSymbol = new NewItemVariable();
415 var activationSymbol = new ActivationVariable(0);
416 var insertAction = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol,
417 activationSymbol);
418 var deleteAction = new DeleteAction(activationSymbol);
419
420 var action1 = new TransformationAction();
421 action1.add(newItemSymbol);
422 action1.add(activationSymbol);
423 action1.add(insertAction);
424 action1.add(deleteAction);
425 action1.prepare(model);
426
427 var action2 = new TransformationAction();
428 action2.add(newItemSymbol);
429 action2.add(activationSymbol);
430 action2.add(insertAction);
431 action2.prepare(model);
432
433 assertFalse(action1.equalsWithSubstitution(action2));
434 }
435
436 @Test
437 void deleteActionIdenticalTest() {
438 var newItemSymbol = new NewItemVariable();
439 var activationSymbol = new ActivationVariable(0);
440 var insertAction = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol,
441 activationSymbol);
442 var deleteAction1 = new DeleteAction(activationSymbol);
443 var deleteAction2 = new DeleteAction(activationSymbol);
444
445 var action1 = new TransformationAction();
446 action1.add(newItemSymbol);
447 action1.add(activationSymbol);
448 action1.add(insertAction);
449 action1.add(deleteAction1);
450 action1.prepare(model);
451
452 var action2 = new TransformationAction();
453 action2.add(newItemSymbol);
454 action2.add(activationSymbol);
455 action2.add(insertAction);
456 action2.add(deleteAction2);
457 action2.prepare(model);
458
459 assertTrue(action1.equalsWithSubstitution(action2));
460 }
461
462 @Test
463 void deleteActionSymbolTypeTest() {
464 var newItemSymbol = new NewItemVariable();
465 var activationSymbol = new ActivationVariable(0);
466 var insertAction = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol,
467 activationSymbol);
468 var deleteAction1 = new DeleteAction(activationSymbol);
469 var deleteAction2 = new DeleteAction(newItemSymbol);
470
471 var action1 = new TransformationAction();
472 action1.add(newItemSymbol);
473 action1.add(activationSymbol);
474 action1.add(insertAction);
475 action1.add(deleteAction1);
476 action1.prepare(model);
477
478 var action2 = new TransformationAction();
479 action2.add(newItemSymbol);
480 action2.add(activationSymbol);
481 action2.add(insertAction);
482 action2.add(deleteAction2);
483 action2.prepare(model);
484
485 assertFalse(action1.equalsWithSubstitution(action2));
486 }
487
488 @Test
489 void deleteActionOrderTest() {
490 var newItemSymbol = new NewItemVariable();
491 var activationSymbol = new ActivationVariable(0);
492 var insertAction = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol,
493 activationSymbol);
494 var deleteAction1 = new DeleteAction(activationSymbol);
495 var deleteAction2 = new DeleteAction(newItemSymbol);
496
497 var action1 = new TransformationAction();
498 action1.add(newItemSymbol);
499 action1.add(activationSymbol);
500 action1.add(insertAction);
501 action1.add(deleteAction1);
502 action1.add(deleteAction2);
503 action1.prepare(model);
504
505 var action2 = new TransformationAction();
506 action2.add(newItemSymbol);
507 action2.add(activationSymbol);
508 action2.add(insertAction);
509 action2.add(deleteAction2);
510 action2.add(deleteAction1);
511 action2.prepare(model);
512
513 assertFalse(action1.equalsWithSubstitution(action2));
514 }
515
516 @Test
517 void actionsMixedOrderTest() {
518 var newItemSymbol1 = new NewItemVariable();
519 var activationSymbol1 = new ActivationVariable();
520 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
521 activationSymbol1);
522 var deleteAction1 = new DeleteAction(newItemSymbol1);
523
524 var newItemSymbol2 = new NewItemVariable();
525 var activationSymbol2 = new ActivationVariable();
526 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2,
527 activationSymbol2);
528 var deleteAction2 = new DeleteAction(activationSymbol2);
529
530 var action1 = new TransformationAction();
531 action1.add(newItemSymbol1);
532 action1.add(newItemSymbol2);
533 action1.add(activationSymbol1);
534 action1.add(activationSymbol2);
535 action1.add(insertAction1);
536 action1.add(insertAction2);
537 action1.add(deleteAction1);
538 action1.add(deleteAction2);
539 action1.prepare(model);
540
541 var action2 = new TransformationAction();
542 action2.add(deleteAction1);
543 action2.add(newItemSymbol1);
544 action2.add(insertAction1);
545 action2.add(newItemSymbol2);
546 action2.add(deleteAction2);
547 action2.add(activationSymbol1);
548 action2.add(insertAction2);
549 action2.add(activationSymbol2);
550 action2.prepare(model);
551
552 assertTrue(action1.equalsWithSubstitution(action2));
553 }
554
555 @Test
556 void twoUnpreparedActionsTest() {
557 var newItemSymbol1 = new NewItemVariable();
558 var activationSymbol1 = new ActivationVariable();
559 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
560 activationSymbol1);
561 var deleteAction1 = new DeleteAction(newItemSymbol1);
562
563 var newItemSymbol2 = new NewItemVariable();
564 var activationSymbol2 = new ActivationVariable();
565 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2,
566 activationSymbol2);
567 var deleteAction2 = new DeleteAction(activationSymbol2);
568
569 var action1 = new TransformationAction();
570 action1.add(newItemSymbol1);
571 action1.add(newItemSymbol2);
572 action1.add(activationSymbol1);
573 action1.add(activationSymbol2);
574 action1.add(insertAction1);
575 action1.add(insertAction2);
576 action1.add(deleteAction1);
577 action1.add(deleteAction2);
578
579 var action2 = new TransformationAction();
580 action2.add(deleteAction1);
581 action2.add(newItemSymbol1);
582 action2.add(insertAction1);
583 action2.add(newItemSymbol2);
584 action2.add(deleteAction2);
585 action2.add(activationSymbol1);
586 action2.add(insertAction2);
587 action2.add(activationSymbol2);
588
589 assertTrue(action1.equalsWithSubstitution(action2));
590 }
591
592 @Test
593 void oneUnpreparedActionTest() {
594 var newItemSymbol1 = new NewItemVariable();
595 var activationSymbol1 = new ActivationVariable();
596 var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1,
597 activationSymbol1);
598 var deleteAction1 = new DeleteAction(newItemSymbol1);
599
600 var newItemSymbol2 = new NewItemVariable();
601 var activationSymbol2 = new ActivationVariable();
602 var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2,
603 activationSymbol2);
604 var deleteAction2 = new DeleteAction(activationSymbol2);
605
606 var action1 = new TransformationAction();
607 action1.add(newItemSymbol1);
608 action1.add(newItemSymbol2);
609 action1.add(activationSymbol1);
610 action1.add(activationSymbol2);
611 action1.add(insertAction1);
612 action1.add(insertAction2);
613 action1.add(deleteAction1);
614 action1.add(deleteAction2);
615 action1.prepare(model);
616
617 var action2 = new TransformationAction();
618 action2.add(deleteAction1);
619 action2.add(newItemSymbol1);
620 action2.add(insertAction1);
621 action2.add(newItemSymbol2);
622 action2.add(deleteAction2);
623 action2.add(activationSymbol1);
624 action2.add(insertAction2);
625 action2.add(activationSymbol2);
626
627 assertFalse(action1.equalsWithSubstitution(action2));
628 }
629}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java
index 225de32e..63da6cc3 100644
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java
@@ -7,236 +7,161 @@ package tools.refinery.store.dse;
7 7
8import org.junit.jupiter.api.Disabled; 8import org.junit.jupiter.api.Disabled;
9import org.junit.jupiter.api.Test; 9import org.junit.jupiter.api.Test;
10import tools.refinery.store.dse.objectives.AlwaysSatisfiedRandomHardObjective; 10import tools.refinery.store.dse.modification.DanglingEdges;
11import tools.refinery.store.dse.modification.ModificationAdapter;
12import tools.refinery.store.dse.strategy.BestFirstStoreManager;
13import tools.refinery.store.dse.tests.DummyCriterion;
14import tools.refinery.store.dse.tests.DummyRandomObjective;
15import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter;
16import tools.refinery.store.dse.transition.Rule;
17import tools.refinery.store.dse.transition.objectives.Criteria;
18import tools.refinery.store.dse.transition.objectives.Objectives;
11import tools.refinery.store.model.ModelStore; 19import tools.refinery.store.model.ModelStore;
12import tools.refinery.store.query.ModelQueryAdapter; 20import tools.refinery.store.query.ModelQueryAdapter;
13import tools.refinery.store.query.dnf.Query; 21import tools.refinery.store.query.dnf.Query;
14import tools.refinery.store.query.dnf.RelationalQuery; 22import tools.refinery.store.query.dnf.RelationalQuery;
15import tools.refinery.store.dse.internal.TransformationRule; 23import tools.refinery.store.query.term.Variable;
16import tools.refinery.store.dse.strategy.BestFirstStrategy;
17import tools.refinery.store.dse.strategy.DepthFirstStrategy;
18import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; 24import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
19import tools.refinery.store.query.view.AnySymbolView; 25import tools.refinery.store.query.view.AnySymbolView;
20import tools.refinery.store.query.view.KeyOnlyView; 26import tools.refinery.store.query.view.KeyOnlyView;
21import tools.refinery.store.representation.Symbol; 27import tools.refinery.store.representation.Symbol;
28import tools.refinery.store.statecoding.StateCoderAdapter;
22import tools.refinery.store.tuple.Tuple; 29import tools.refinery.store.tuple.Tuple;
23import tools.refinery.visualization.ModelVisualizerAdapter; 30import tools.refinery.visualization.ModelVisualizerAdapter;
24import tools.refinery.visualization.internal.FileFormat; 31import tools.refinery.visualization.internal.FileFormat;
25 32
26import java.util.List; 33import java.util.List;
27 34
35import static tools.refinery.store.dse.modification.actions.ModificationActionLiterals.create;
36import static tools.refinery.store.dse.modification.actions.ModificationActionLiterals.delete;
37import static tools.refinery.store.dse.transition.actions.ActionLiterals.add;
38import static tools.refinery.store.dse.transition.actions.ActionLiterals.remove;
28import static tools.refinery.store.query.literal.Literals.not; 39import static tools.refinery.store.query.literal.Literals.not;
29 40
30class CRAExamplesTest { 41class CRAExamplesTest {
31 private static final Symbol<String> name = Symbol.of("Name", 1, String.class); 42 private static final Symbol<String> name = Symbol.of("Name", 1, String.class);
32
33// private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1);
34 private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1); 43 private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1);
35// private static final Symbol<Boolean> feature = Symbol.of("Feature", 1);
36 private static final Symbol<Boolean> attribute = Symbol.of("Attribute", 1); 44 private static final Symbol<Boolean> attribute = Symbol.of("Attribute", 1);
37 private static final Symbol<Boolean> method = Symbol.of("Method", 1); 45 private static final Symbol<Boolean> method = Symbol.of("Method", 1);
38
39// private static final Symbol<Boolean> isEncapsulatedBy = Symbol.of("IsEncapsulatedBy", 2);
40 private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2); 46 private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2);
41 private static final Symbol<Boolean> dataDependency = Symbol.of("DataDependency", 2); 47 private static final Symbol<Boolean> dataDependency = Symbol.of("DataDependency", 2);
42 private static final Symbol<Boolean> functionalDependency = Symbol.of("FunctionalDependency", 2); 48 private static final Symbol<Boolean> functionalDependency = Symbol.of("FunctionalDependency", 2);
43 49
44 private static final Symbol<Boolean> features = Symbol.of("Features", 2);
45 private static final Symbol<Boolean> classes = Symbol.of("Classes", 2);
46
47// private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel);
48 private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement); 50 private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement);
49// private static final AnySymbolView featureView = new KeyOnlyView<>(feature);
50 private static final AnySymbolView attributeView = new KeyOnlyView<>(attribute); 51 private static final AnySymbolView attributeView = new KeyOnlyView<>(attribute);
51 private static final AnySymbolView methodView = new KeyOnlyView<>(method); 52 private static final AnySymbolView methodView = new KeyOnlyView<>(method);
52// private static final AnySymbolView isEncapsulatedByView = new KeyOnlyView<>(isEncapsulatedBy);
53 private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates); 53 private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates);
54 private static final AnySymbolView dataDependencyView = new KeyOnlyView<>(dataDependency);
55 private static final AnySymbolView functionalDependencyView = new KeyOnlyView<>(functionalDependency);
56 private static final AnySymbolView featuresView = new KeyOnlyView<>(features);
57 private static final AnySymbolView classesView = new KeyOnlyView<>(classes);
58 54
59 /*Example Transformation rules*/ 55 private static final RelationalQuery feature = Query.of("Feature", (builder, f) -> builder
60 private static final RelationalQuery feature = Query.of("Feature",
61 (builder, f) -> builder.clause(
62 attributeView.call(f))
63 .clause( 56 .clause(
64 methodView.call(f)) 57 attributeView.call(f)
65 ); 58 )
59 .clause(
60 methodView.call(f)
61 ));
66 62
67 private static final RelationalQuery assignFeaturePreconditionHelper = Query.of("AssignFeaturePreconditionHelper", 63 private static final RelationalQuery unEncapsulatedFeature = Query.of("unEncapsulatedFeature",
68 (builder, c, f) -> builder.clause( 64 (builder, f) -> builder.clause(
69 classElementView.call(c), 65 feature.call(f),
70// classesView.call(model, c), 66 not(encapsulatesView.call(Variable.of(), f))
71 encapsulatesView.call(c, f)
72 )); 67 ));
73 68
74 private static final RelationalQuery assignFeaturePrecondition = Query.of("AssignFeaturePrecondition", 69 private static final Rule assignFeatureRule = Rule.of("AssignFeature", (builder, f, c1) -> builder
75 (builder, f, c1) -> builder.clause((c2) -> List.of( 70 .clause(
76// classModelView.call(model),
77 feature.call(f), 71 feature.call(f),
78 classElementView.call(c1), 72 classElementView.call(c1),
79// featuresView.call(model, f), 73 not(encapsulatesView.call(Variable.of(), f))
80 not(assignFeaturePreconditionHelper.call(c2, f)), 74 )
81 not(encapsulatesView.call(c1, f)) 75 .action(
82 ))); 76 add(encapsulates, c1, f)
83 77 ));
84 private static final RelationalQuery deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition",
85 (builder, c) -> builder.clause((f) -> List.of(
86// classModelView.call(model),
87 classElementView.call(c),
88// featuresView.call(model, f),
89 not(encapsulatesView.call(c, f))
90 )));
91 78
92 private static final RelationalQuery createClassPreconditionHelper = Query.of("CreateClassPreconditionHelper", 79 private static final Rule deleteEmptyClassRule = Rule.of("DeleteEmptyClass", (builder, c) -> builder
93 (builder, f, c) -> builder.clause( 80 .clause(
94 classElementView.call(c), 81 classElementView.call(c),
95// classesView.call(model, c), 82 not(encapsulatesView.call(c, Variable.of()))
96 encapsulatesView.call(c, f) 83 )
84 .action(
85 remove(classElement, c),
86 delete(c, DanglingEdges.IGNORE)
97 )); 87 ));
98 88
99 private static final RelationalQuery createClassPrecondition = Query.of("CreateClassPrecondition", 89 private static final Rule createClassRule = Rule.of("CreateClass", (builder, f) -> builder
100 (builder, f) -> builder.clause((c) -> List.of( 90 .clause(
101// classModelView.call(model),
102 feature.call(f), 91 feature.call(f),
103 not(createClassPreconditionHelper.call(f, c)) 92 not(encapsulatesView.call(Variable.of(), f))
93 )
94 .action((newClass) -> List.of(
95 create(newClass),
96 add(classElement, newClass),
97 add(encapsulates, newClass, f)
104 ))); 98 )));
105 99
106 private static final RelationalQuery moveFeaturePrecondition = Query.of("MoveFeature", 100 private static final Rule moveFeatureRule = Rule.of("MoveFeature", (builder, c1, c2, f) -> builder
107 (builder, c1, c2, f) -> builder.clause( 101 .clause(
108// classModelView.call(model),
109 classElementView.call(c1), 102 classElementView.call(c1),
110 classElementView.call(c2), 103 classElementView.call(c2),
111 c1.notEquivalent(c2), 104 c1.notEquivalent(c2),
112 feature.call(f), 105 feature.call(f),
113// classesView.call(model, c1),
114// classesView.call(model, c2),
115// featuresView.call(model, f),
116 encapsulatesView.call(c1, f) 106 encapsulatesView.call(c1, f)
107 )
108 .action(
109 remove(encapsulates, c1, f),
110 add(encapsulates, c2, f)
117 )); 111 ));
118 112
119 private static final TransformationRule assignFeatureRule = new TransformationRule("AssignFeature",
120 assignFeaturePrecondition,
121 (model) -> {
122// var isEncapsulatedByInterpretation = model.getInterpretation(isEncapsulatedBy);
123 var encapsulatesInterpretation = model.getInterpretation(encapsulates);
124 return ((Tuple activation) -> {
125 var feature = activation.get(0);
126 var classElement = activation.get(1);
127
128// isEncapsulatedByInterpretation.put(Tuple.of(feature, classElement), true);
129 encapsulatesInterpretation.put(Tuple.of(classElement, feature), true);
130 });
131 });
132
133 private static final TransformationRule deleteEmptyClassRule = new TransformationRule("DeleteEmptyClass",
134 deleteEmptyClassPrecondition,
135 (model) -> {
136// var classesInterpretation = model.getInterpretation(classes);
137 var classElementInterpretation = model.getInterpretation(classElement);
138 return ((Tuple activation) -> {
139 // TODO: can we move dseAdapter outside?
140 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
141// var modelElement = activation.get(0);
142 var classElement = activation.get(0);
143
144// classesInterpretation.put(Tuple.of(modelElement, classElement), false);
145 classElementInterpretation.put(Tuple.of(classElement), false);
146 dseAdapter.deleteObject(Tuple.of(classElement));
147 });
148 });
149
150 private static final TransformationRule createClassRule = new TransformationRule("CreateClass",
151 createClassPrecondition,
152 (model) -> {
153 var classElementInterpretation = model.getInterpretation(classElement);
154// var classesInterpretation = model.getInterpretation(classes);
155 var encapsulatesInterpretation = model.getInterpretation(encapsulates);
156 return ((Tuple activation) -> {
157 // TODO: can we move dseAdapter outside?
158 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
159// var modelElement = activation.get(0);
160 var feature = activation.get(0);
161
162 var newClassElement = dseAdapter.createObject();
163 var newClassElementId = newClassElement.get(0);
164 classElementInterpretation.put(newClassElement, true);
165// classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
166 encapsulatesInterpretation.put(Tuple.of(newClassElementId, feature), true);
167 });
168 });
169
170 private static final TransformationRule moveFeatureRule = new TransformationRule("MoveFeature",
171 moveFeaturePrecondition,
172 (model) -> {
173 var encapsulatesInterpretation = model.getInterpretation(encapsulates);
174 return ((Tuple activation) -> {
175 var classElement1 = activation.get(0);
176 var classElement2 = activation.get(1);
177 var feature = activation.get(2);
178
179 encapsulatesInterpretation.put(Tuple.of(classElement1, feature), false);
180 encapsulatesInterpretation.put(Tuple.of(classElement2, feature), true);
181 });
182 });
183
184 @Test 113 @Test
185 @Disabled("This test is only for debugging purposes") 114 @Disabled("This test is only for debugging purposes")
186 void craTest() { 115 void craTest() {
187 var store = ModelStore.builder() 116 var store = ModelStore.builder()
188 .symbols(classElement, encapsulates, classes, features, attribute, method, dataDependency, 117 .symbols(classElement, encapsulates, attribute, method, dataDependency, functionalDependency, name)
189 functionalDependency, name) 118 .with(ViatraModelQueryAdapter.builder())
190 .with(ViatraModelQueryAdapter.builder()
191 .queries(feature, assignFeaturePreconditionHelper, assignFeaturePrecondition,
192 deleteEmptyClassPrecondition, createClassPreconditionHelper, createClassPrecondition,
193 moveFeaturePrecondition))
194 .with(ModelVisualizerAdapter.builder() 119 .with(ModelVisualizerAdapter.builder()
195 .withOutputpath("test_output") 120 .withOutputPath("test_output")
196 .withFormat(FileFormat.DOT) 121 .withFormat(FileFormat.DOT)
197 .withFormat(FileFormat.SVG) 122 .withFormat(FileFormat.SVG)
198 .saveStates() 123 .saveStates()
199 .saveDesignSpace() 124 .saveDesignSpace())
200 ) 125 .with(StateCoderAdapter.builder())
126 .with(ModificationAdapter.builder())
201 .with(DesignSpaceExplorationAdapter.builder() 127 .with(DesignSpaceExplorationAdapter.builder()
202 .transformations(assignFeatureRule, deleteEmptyClassRule, createClassRule, moveFeatureRule) 128 .transformations(assignFeatureRule, deleteEmptyClassRule, createClassRule, moveFeatureRule)
203 .objectives(new AlwaysSatisfiedRandomHardObjective()) 129 .objectives(Objectives.sum(
204// .strategy(new DepthFirstStrategy().withDepthLimit(3).continueIfHardObjectivesFulfilled() 130 new DummyRandomObjective(),
205 .strategy(new BestFirstStrategy().withDepthLimit(6).continueIfHardObjectivesFulfilled() 131 Objectives.count(unEncapsulatedFeature)
206// .goOnOnlyIfFitnessIsBetter()
207 )) 132 ))
133 .accept(Criteria.whenNoMatch(unEncapsulatedFeature))
134 .exclude(new DummyCriterion(false)))
208 .build(); 135 .build();
209 136
210 var model = store.createEmptyModel(); 137 var model = store.createEmptyModel();
211 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
212// dseAdapter.setRandom(1);
213 var queryEngine = model.getAdapter(ModelQueryAdapter.class); 138 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
214 139
215// var modelInterpretation = model.getInterpretation(classModel);
216 var nameInterpretation = model.getInterpretation(name); 140 var nameInterpretation = model.getInterpretation(name);
217 var methodInterpretation = model.getInterpretation(method); 141 var methodInterpretation = model.getInterpretation(method);
218 var attributeInterpretation = model.getInterpretation(attribute); 142 var attributeInterpretation = model.getInterpretation(attribute);
219 var dataDependencyInterpretation = model.getInterpretation(dataDependency); 143 var dataDependencyInterpretation = model.getInterpretation(dataDependency);
220 var functionalDependencyInterpretation = model.getInterpretation(functionalDependency); 144 var functionalDependencyInterpretation = model.getInterpretation(functionalDependency);
221 145
222// var modelElement = dseAdapter.createObject(); 146 var modificationAdapter = model.getAdapter(ModificationAdapter.class);
223 var method1 = dseAdapter.createObject(); 147
148 var method1 = modificationAdapter.createObject();
224 var method1Id = method1.get(0); 149 var method1Id = method1.get(0);
225 var method2 = dseAdapter.createObject(); 150 var method2 = modificationAdapter.createObject();
226 var method2Id = method2.get(0); 151 var method2Id = method2.get(0);
227 var method3 = dseAdapter.createObject(); 152 var method3 = modificationAdapter.createObject();
228 var method3Id = method3.get(0); 153 var method3Id = method3.get(0);
229 var method4 = dseAdapter.createObject(); 154 var method4 = modificationAdapter.createObject();
230 var method4Id = method4.get(0); 155 var method4Id = method4.get(0);
231 var attribute1 = dseAdapter.createObject(); 156 var attribute1 = modificationAdapter.createObject();
232 var attribute1Id = attribute1.get(0); 157 var attribute1Id = attribute1.get(0);
233 var attribute2 = dseAdapter.createObject(); 158 var attribute2 = modificationAdapter.createObject();
234 var attribute2Id = attribute2.get(0); 159 var attribute2Id = attribute2.get(0);
235 var attribute3 = dseAdapter.createObject(); 160 var attribute3 = modificationAdapter.createObject();
236 var attribute3Id = attribute3.get(0); 161 var attribute3Id = attribute3.get(0);
237 var attribute4 = dseAdapter.createObject(); 162 var attribute4 = modificationAdapter.createObject();
238 var attribute4Id = attribute4.get(0); 163 var attribute4Id = attribute4.get(0);
239 var attribute5 = dseAdapter.createObject(); 164 var attribute5 = modificationAdapter.createObject();
240 var attribute5Id = attribute5.get(0); 165 var attribute5Id = attribute5.get(0);
241 166
242 nameInterpretation.put(method1, "M1"); 167 nameInterpretation.put(method1, "M1");
@@ -249,9 +174,6 @@ class CRAExamplesTest {
249 nameInterpretation.put(attribute4, "A4"); 174 nameInterpretation.put(attribute4, "A4");
250 nameInterpretation.put(attribute5, "A5"); 175 nameInterpretation.put(attribute5, "A5");
251 176
252
253
254// modelInterpretation.put(modelElement, true);
255 methodInterpretation.put(method1, true); 177 methodInterpretation.put(method1, true);
256 methodInterpretation.put(method2, true); 178 methodInterpretation.put(method2, true);
257 methodInterpretation.put(method3, true); 179 methodInterpretation.put(method3, true);
@@ -277,10 +199,13 @@ class CRAExamplesTest {
277 functionalDependencyInterpretation.put(Tuple.of(method3Id, attribute4Id), true); 199 functionalDependencyInterpretation.put(Tuple.of(method3Id, attribute4Id), true);
278 functionalDependencyInterpretation.put(Tuple.of(method4Id, attribute2Id), true); 200 functionalDependencyInterpretation.put(Tuple.of(method4Id, attribute2Id), true);
279 201
202 var initialVersion = model.commit();
280 queryEngine.flushChanges(); 203 queryEngine.flushChanges();
281 204
282 var states = dseAdapter.explore(); 205 var bestFirst = new BestFirstStoreManager(store, 50);
283 System.out.println("states size: " + states.size()); 206 bestFirst.startExploration(initialVersion);
207 var resultStore = bestFirst.getSolutionStore();
208 System.out.println("states size: " + resultStore.getSolutions().size());
209 model.getAdapter(ModelVisualizerAdapter.class).visualize(bestFirst.getVisualizationStore());
284 } 210 }
285
286} 211}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DebugTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DebugTest.java
index c6da896c..b912eba3 100644
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DebugTest.java
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DebugTest.java
@@ -7,110 +7,79 @@ package tools.refinery.store.dse;
7 7
8import org.junit.jupiter.api.Disabled; 8import org.junit.jupiter.api.Disabled;
9import org.junit.jupiter.api.Test; 9import org.junit.jupiter.api.Test;
10import tools.refinery.store.dse.objectives.AlwaysSatisfiedRandomHardObjective; 10import tools.refinery.store.dse.modification.ModificationAdapter;
11import tools.refinery.store.dse.strategy.BestFirstStoreManager;
12import tools.refinery.store.dse.tests.DummyRandomCriterion;
13import tools.refinery.store.dse.tests.DummyRandomObjective;
14import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter;
15import tools.refinery.store.dse.transition.Rule;
11import tools.refinery.store.model.ModelStore; 16import tools.refinery.store.model.ModelStore;
12import tools.refinery.store.query.ModelQueryAdapter; 17import tools.refinery.store.query.ModelQueryAdapter;
13import tools.refinery.store.query.dnf.Query;
14import tools.refinery.store.dse.internal.TransformationRule;
15import tools.refinery.store.dse.strategy.BestFirstStrategy;
16import tools.refinery.store.dse.strategy.DepthFirstStrategy;
17import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; 18import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
18import tools.refinery.store.query.view.AnySymbolView; 19import tools.refinery.store.query.view.AnySymbolView;
19import tools.refinery.store.query.view.KeyOnlyView; 20import tools.refinery.store.query.view.KeyOnlyView;
20import tools.refinery.store.representation.Symbol; 21import tools.refinery.store.representation.Symbol;
21import tools.refinery.store.tuple.Tuple; 22import tools.refinery.store.statecoding.StateCoderAdapter;
22import tools.refinery.visualization.ModelVisualizerAdapter; 23import tools.refinery.visualization.ModelVisualizerAdapter;
23import tools.refinery.visualization.internal.FileFormat; 24import tools.refinery.visualization.internal.FileFormat;
24 25
26import java.util.List;
27
28import static tools.refinery.store.dse.modification.actions.ModificationActionLiterals.create;
29import static tools.refinery.store.dse.transition.actions.ActionLiterals.add;
30
25class DebugTest { 31class DebugTest {
26 private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1); 32 private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1);
27 private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1); 33 private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1);
28 private static final Symbol<Boolean> feature = Symbol.of("Feature", 1); 34 private static final Symbol<Boolean> feature = Symbol.of("Feature", 1);
29
30 private static final Symbol<Boolean> isEncapsulatedBy = Symbol.of("IsEncapsulatedBy", 2);
31 private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2);
32
33 private static final Symbol<Boolean> features = Symbol.of("Features", 2); 35 private static final Symbol<Boolean> features = Symbol.of("Features", 2);
34 private static final Symbol<Boolean> classes = Symbol.of("Classes", 2); 36 private static final Symbol<Boolean> classes = Symbol.of("Classes", 2);
35 37
36 private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel); 38 private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel);
37 private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement);
38 private static final AnySymbolView featureView = new KeyOnlyView<>(feature);
39 private static final AnySymbolView isEncapsulatedByView = new KeyOnlyView<>(isEncapsulatedBy);
40 private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates);
41 private static final AnySymbolView featuresView = new KeyOnlyView<>(features);
42 private static final AnySymbolView classesView = new KeyOnlyView<>(classes);
43
44 39
45 @Test 40 @Test
46 @Disabled("This test is only for debugging purposes") 41 @Disabled("This test is only for debugging purposes")
47 void BFSTest() { 42 void BFSTest() {
48 var createClassPrecondition = Query.of("CreateClassPrecondition", 43 var createClassRule = Rule.of("CreateClass", (builder, model) -> builder
49 (builder, model) -> builder.clause( 44 .clause(
50 classModelView.call(model) 45 classModelView.call(model)
51 )); 46 )
52 47 .action((newClassElement) -> List.of(
53 var createClassRule = new TransformationRule("CreateClass", 48 create(newClassElement),
54 createClassPrecondition, 49 add(classElement, newClassElement),
55 (model) -> { 50 add(classes, model, newClassElement)
56 var classesInterpretation = model.getInterpretation(classes); 51 )));
57 var classElementInterpretation = model.getInterpretation(classElement); 52
58 return ((Tuple activation) -> { 53 var createFeatureRule = Rule.of("CreateFeature", (builder, model) -> builder
59 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); 54 .clause(
60 var modelElement = activation.get(0);
61
62 var newClassElement = dseAdapter.createObject();
63 var newClassElementId = newClassElement.get(0);
64
65 classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
66 classElementInterpretation.put(Tuple.of(newClassElementId), true);
67 });
68 });
69
70 var createFeaturePrecondition = Query.of("CreateFeaturePrecondition",
71 (builder, model) -> builder.clause(
72 classModelView.call(model) 55 classModelView.call(model)
73 )); 56 )
74 57 .action((newFeature) -> List.of(
75 var createFeatureRule = new TransformationRule("CreateFeature", 58 create(newFeature),
76 createFeaturePrecondition, 59 add(feature, newFeature),
77 (model) -> { 60 add(features, model, newFeature)
78 var featuresInterpretation = model.getInterpretation(features); 61 )));
79 var featureInterpretation = model.getInterpretation(feature);
80 return ((Tuple activation) -> {
81 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
82 var modelElement = activation.get(0);
83
84 var newClassElement = dseAdapter.createObject();
85 var newClassElementId = newClassElement.get(0);
86
87 featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
88 featureInterpretation.put(Tuple.of(newClassElementId), true);
89 });
90 });
91 62
92 var store = ModelStore.builder() 63 var store = ModelStore.builder()
93 .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features) 64 .symbols(classModel, classElement, feature, classes, features)
94 .with(ViatraModelQueryAdapter.builder() 65 .with(ViatraModelQueryAdapter.builder())
95 .queries(createClassPrecondition, createFeaturePrecondition))
96 .with(ModelVisualizerAdapter.builder() 66 .with(ModelVisualizerAdapter.builder()
97 .withOutputpath("test_output") 67 .withOutputPath("test_output")
98 .withFormat(FileFormat.DOT) 68 .withFormat(FileFormat.DOT)
99 .withFormat(FileFormat.SVG) 69 .withFormat(FileFormat.SVG)
100 .saveStates() 70 .saveStates()
101 .saveDesignSpace() 71 .saveDesignSpace())
102 ) 72 .with(StateCoderAdapter.builder())
73 .with(ModificationAdapter.builder())
103 .with(DesignSpaceExplorationAdapter.builder() 74 .with(DesignSpaceExplorationAdapter.builder()
104 .transformations(createClassRule, createFeatureRule) 75 .transformations(createClassRule, createFeatureRule)
105 .objectives(new AlwaysSatisfiedRandomHardObjective()) 76 .objectives(new DummyRandomObjective())
106 .strategy(new DepthFirstStrategy().withDepthLimit(4).continueIfHardObjectivesFulfilled() 77 .accept(new DummyRandomCriterion())
107// .strategy(new BestFirstStrategy().withDepthLimit(4).continueIfHardObjectivesFulfilled() 78 .exclude(new DummyRandomCriterion()))
108// .goOnOnlyIfFitnessIsBetter()
109 ))
110 .build(); 79 .build();
111 80
112 var model = store.createEmptyModel(); 81 var model = store.createEmptyModel();
113 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); 82 var dseAdapter = model.getAdapter(ModificationAdapter.class);
114// dseAdapter.setRandom(1); 83// dseAdapter.setRandom(1);
115 var queryEngine = model.getAdapter(ModelQueryAdapter.class); 84 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
116 85
@@ -119,11 +88,12 @@ class DebugTest {
119 var modelElement = dseAdapter.createObject(); 88 var modelElement = dseAdapter.createObject();
120 modelElementInterpretation.put(modelElement, true); 89 modelElementInterpretation.put(modelElement, true);
121 classElementInterpretation.put(modelElement, true); 90 classElementInterpretation.put(modelElement, true);
91 var initialVersion = model.commit();
122 queryEngine.flushChanges(); 92 queryEngine.flushChanges();
123 93
124 94 var bestFirst = new BestFirstStoreManager(store, 50);
125 var states = dseAdapter.explore(); 95 bestFirst.startExploration(initialVersion);
126 System.out.println("states size: " + states.size()); 96 var resultStore = bestFirst.getSolutionStore();
127 97 System.out.println("states size: " + resultStore.getSolutions().size());
128 } 98 }
129} 99}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DesignSpaceExplorationTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DesignSpaceExplorationTest.java
deleted file mode 100644
index 91e33f4a..00000000
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DesignSpaceExplorationTest.java
+++ /dev/null
@@ -1,607 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.model.ModelStore;
10import tools.refinery.store.query.ModelQueryAdapter;
11import tools.refinery.store.query.dnf.Query;
12import tools.refinery.store.dse.internal.TransformationRule;
13import tools.refinery.store.dse.strategy.BestFirstStrategy;
14import tools.refinery.store.dse.strategy.DepthFirstStrategy;
15import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
16import tools.refinery.store.query.view.AnySymbolView;
17import tools.refinery.store.query.view.KeyOnlyView;
18import tools.refinery.store.representation.Symbol;
19import tools.refinery.store.tuple.Tuple;
20
21import static org.junit.jupiter.api.Assertions.assertEquals;
22
23class DesignSpaceExplorationTest {
24// private static final Symbol<Boolean> namedElement = Symbol.of("NamedElement", 1);
25// private static final Symbol<Boolean> attribute = Symbol.of("Attribute", 1);
26// private static final Symbol<Boolean> method = Symbol.of("Method", 1);
27// private static final Symbol<Boolean> dataDependency = Symbol.of("DataDependency", 2);
28// private static final Symbol<Boolean> functionalDependency = Symbol.of("FunctionalDependency", 2);
29
30 private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1);
31 private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1);
32 private static final Symbol<Boolean> feature = Symbol.of("Feature", 1);
33
34 private static final Symbol<Boolean> isEncapsulatedBy = Symbol.of("IsEncapsulatedBy", 2);
35 private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2);
36
37 private static final Symbol<Boolean> features = Symbol.of("Features", 2);
38 private static final Symbol<Boolean> classes = Symbol.of("Classes", 2);
39
40 private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel);
41 private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement);
42 private static final AnySymbolView featureView = new KeyOnlyView<>(feature);
43 private static final AnySymbolView isEncapsulatedByView = new KeyOnlyView<>(isEncapsulatedBy);
44 private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates);
45 private static final AnySymbolView featuresView = new KeyOnlyView<>(features);
46 private static final AnySymbolView classesView = new KeyOnlyView<>(classes);
47
48 @Test
49 void createObjectTest() {
50 var store = ModelStore.builder()
51 .with(ViatraModelQueryAdapter.builder())
52 .with(DesignSpaceExplorationAdapter.builder()
53 .strategy(new DepthFirstStrategy().withDepthLimit(0)))
54 .build();
55
56 var model = store.createEmptyModel();
57 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
58
59 assertEquals(0, dseAdapter.getModelSize());
60
61 var newModel = dseAdapter.createObject();
62 var newModelId = newModel.get(0);
63 var newClass1 = dseAdapter.createObject();
64 var newClass1Id = newClass1.get(0);
65 var newClass2 = dseAdapter.createObject();
66 var newClass2Id = newClass2.get(0);
67 var newField = dseAdapter.createObject();
68 var newFieldId = newField.get(0);
69
70 assertEquals(0, newModelId);
71 assertEquals(1, newClass1Id);
72 assertEquals(2, newClass2Id);
73 assertEquals(3, newFieldId);
74 assertEquals(4, dseAdapter.getModelSize());
75 }
76
77 @Test
78 void deleteMiddleObjectTest() {
79 var store = ModelStore.builder()
80 .with(ViatraModelQueryAdapter.builder())
81 .with(DesignSpaceExplorationAdapter.builder()
82 .strategy(new DepthFirstStrategy()))
83 .build();
84
85 var model = store.createEmptyModel();
86 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
87
88 assertEquals(0, dseAdapter.getModelSize());
89
90 var newObject0 = dseAdapter.createObject();
91 var newObject0Id = newObject0.get(0);
92 var newObject1 = dseAdapter.createObject();
93 var newObject1Id = newObject1.get(0);
94 var newObject2 = dseAdapter.createObject();
95 var newObject2Id = newObject2.get(0);
96 var newObject3 = dseAdapter.createObject();
97 var newObject3Id = newObject3.get(0);
98
99 assertEquals(0, newObject0Id);
100 assertEquals(1, newObject1Id);
101 assertEquals(2, newObject2Id);
102 assertEquals(3, newObject3Id);
103 assertEquals(4, dseAdapter.getModelSize());
104
105 dseAdapter.deleteObject(newObject1);
106 assertEquals(4, dseAdapter.getModelSize());
107
108 var newObject4 = dseAdapter.createObject();
109 var newObject4Id = newObject4.get(0);
110 assertEquals(4, newObject4Id);
111 assertEquals(5, dseAdapter.getModelSize());
112
113 dseAdapter.deleteObject(newObject4);
114 assertEquals(5, dseAdapter.getModelSize());
115 }
116
117 @Test
118 void DFSTrivialTest() {
119 var store = ModelStore.builder()
120 .symbols(classModel)
121 .with(ViatraModelQueryAdapter.builder())
122 .with(DesignSpaceExplorationAdapter.builder()
123 .strategy(new DepthFirstStrategy().withDepthLimit(0)))
124 .build();
125
126 var model = store.createEmptyModel();
127 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
128
129 var states = dseAdapter.explore();
130 assertEquals(1, states.size());
131 }
132
133 @Test
134 void DFSOneRuleTest() {
135 var createClassPrecondition = Query.of("CreateClassPrecondition",
136 (builder, model) -> builder.clause(
137 classModelView.call(model)
138 ));
139
140 var createClassRule = new TransformationRule("CreateClass",
141 createClassPrecondition,
142 (model) -> {
143 var classesInterpretation = model.getInterpretation(classes);
144 var classElementInterpretation = model.getInterpretation(classElement);
145 return ((Tuple activation) -> {
146 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
147 var modelElement = activation.get(0);
148
149 var newClassElement = dseAdapter.createObject();
150 var newClassElementId = newClassElement.get(0);
151
152 classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
153 classElementInterpretation.put(Tuple.of(newClassElementId), true);
154 });
155 });
156
157 var store = ModelStore.builder()
158 .symbols(classModel, classElement, classes)
159 .with(ViatraModelQueryAdapter.builder()
160 .queries(createClassPrecondition))
161 .with(DesignSpaceExplorationAdapter.builder()
162 .transformations(createClassRule)
163 .strategy(new DepthFirstStrategy().withDepthLimit(0)
164 ))
165 .build();
166
167 var model = store.createEmptyModel();
168 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
169 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
170
171 var modelElementInterpretation = model.getInterpretation(classModel);
172 modelElementInterpretation.put(dseAdapter.createObject(), true);
173 queryEngine.flushChanges();
174
175 var states = dseAdapter.explore();
176 assertEquals(1, states.size());
177 }
178
179 @Test
180 void DFSContinueTest() {
181 var createClassPrecondition = Query.of("CreateClassPrecondition",
182 (builder, model) -> builder.clause(
183 classModelView.call(model)
184 ));
185
186 var createClassRule = new TransformationRule("CreateClass",
187 createClassPrecondition,
188 (model) -> {
189 var classesInterpretation = model.getInterpretation(classes);
190 var classElementInterpretation = model.getInterpretation(classElement);
191 return ((Tuple activation) -> {
192 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
193 var modelElement = activation.get(0);
194
195 var newClassElement = dseAdapter.createObject();
196 var newClassElementId = newClassElement.get(0);
197
198 classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
199 classElementInterpretation.put(Tuple.of(newClassElementId), true);
200 });
201 });
202
203 var store = ModelStore.builder()
204 .symbols(classModel, classElement, classes)
205 .with(ViatraModelQueryAdapter.builder()
206 .queries(createClassPrecondition))
207 .with(DesignSpaceExplorationAdapter.builder()
208 .transformations(createClassRule)
209 .strategy(new DepthFirstStrategy().withDepthLimit(4).continueIfHardObjectivesFulfilled()
210 ))
211 .build();
212
213 var model = store.createEmptyModel();
214 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
215 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
216
217 var modelElementInterpretation = model.getInterpretation(classModel);
218 modelElementInterpretation.put(dseAdapter.createObject(), true);
219 queryEngine.flushChanges();
220
221 var states = dseAdapter.explore();
222 assertEquals(5, states.size());
223 }
224
225 @Test
226 void DFSCompletenessTest() {
227 var createClassPrecondition = Query.of("CreateClassPrecondition",
228 (builder, model) -> builder.clause(
229 classModelView.call(model)
230 ));
231
232 var createClassRule = new TransformationRule("CreateClass",
233 createClassPrecondition,
234 (model) -> {
235 var classesInterpretation = model.getInterpretation(classes);
236 var classElementInterpretation = model.getInterpretation(classElement);
237 return ((Tuple activation) -> {
238 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
239 var modelElement = activation.get(0);
240
241 var newClassElement = dseAdapter.createObject();
242 var newClassElementId = newClassElement.get(0);
243
244 classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
245 classElementInterpretation.put(Tuple.of(newClassElementId), true);
246 });
247 });
248
249 var createFeaturePrecondition = Query.of("CreateFeaturePrecondition",
250 (builder, model) -> builder.clause(
251 classModelView.call(model)
252 ));
253
254 var createFeatureRule = new TransformationRule("CreateFeature",
255 createFeaturePrecondition,
256 (model) -> {
257 var featuresInterpretation = model.getInterpretation(features);
258 var featureInterpretation = model.getInterpretation(feature);
259 return ((Tuple activation) -> {
260 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
261 var modelElement = activation.get(0);
262
263 var newClassElement = dseAdapter.createObject();
264 var newClassElementId = newClassElement.get(0);
265
266 featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
267 featureInterpretation.put(Tuple.of(newClassElementId), true);
268 });
269 });
270
271 var store = ModelStore.builder()
272 .symbols(classModel, classElement, classes, feature, features, isEncapsulatedBy, encapsulates)
273 .with(ViatraModelQueryAdapter.builder()
274 .queries(createClassPrecondition, createFeaturePrecondition))
275 .with(DesignSpaceExplorationAdapter.builder()
276 .transformations(createClassRule, createFeatureRule)
277 .strategy(new DepthFirstStrategy().withDepthLimit(10).continueIfHardObjectivesFulfilled()
278 ))
279 .build();
280
281 var model = store.createEmptyModel();
282 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
283 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
284
285 var modelElementInterpretation = model.getInterpretation(classModel);
286 modelElementInterpretation.put(dseAdapter.createObject(), true);
287 queryEngine.flushChanges();
288
289 var states = dseAdapter.explore();
290 assertEquals(2047, states.size());
291 }
292
293 @Test
294 void DFSSolutionLimitTest() {
295 var createClassPrecondition = Query.of("CreateClassPrecondition",
296 (builder, model) -> builder.clause(
297 classModelView.call(model)
298 ));
299
300 var createClassRule = new TransformationRule("CreateClass",
301 createClassPrecondition,
302 (model) -> {
303 var classesInterpretation = model.getInterpretation(classes);
304 var classElementInterpretation = model.getInterpretation(classElement);
305 return ((Tuple activation) -> {
306 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
307 var modelElement = activation.get(0);
308
309 var newClassElement = dseAdapter.createObject();
310 var newClassElementId = newClassElement.get(0);
311
312 classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
313 classElementInterpretation.put(Tuple.of(newClassElementId), true);
314 });
315 });
316
317 var createFeaturePrecondition = Query.of("CreateFeaturePrecondition",
318 (builder, model) -> builder.clause(
319 classModelView.call(model)
320 ));
321
322 var createFeatureRule = new TransformationRule("CreateFeature",
323 createFeaturePrecondition,
324 (model) -> {
325 var featuresInterpretation = model.getInterpretation(features);
326 var featureInterpretation = model.getInterpretation(feature);
327 return ((Tuple activation) -> {
328 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
329 var modelElement = activation.get(0);
330
331 var newClassElement = dseAdapter.createObject();
332 var newClassElementId = newClassElement.get(0);
333
334 featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
335 featureInterpretation.put(Tuple.of(newClassElementId), true);
336 });
337 });
338
339 var store = ModelStore.builder()
340 .symbols(classModel, classElement, classes, feature, features, isEncapsulatedBy, encapsulates)
341 .with(ViatraModelQueryAdapter.builder()
342 .queries(createClassPrecondition, createFeaturePrecondition))
343 .with(DesignSpaceExplorationAdapter.builder()
344 .transformations(createClassRule, createFeatureRule)
345 .strategy(new DepthFirstStrategy().withSolutionLimit(222)
346 .continueIfHardObjectivesFulfilled()
347 ))
348 .build();
349
350 var model = store.createEmptyModel();
351 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
352 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
353
354 var modelElementInterpretation = model.getInterpretation(classModel);
355 modelElementInterpretation.put(dseAdapter.createObject(), true);
356 queryEngine.flushChanges();
357
358 var states = dseAdapter.explore();
359 assertEquals(222, states.size());
360 }
361
362 @Test
363 void BeFSTrivialTest() {
364 var store = ModelStore.builder()
365 .symbols(classModel)
366 .with(ViatraModelQueryAdapter.builder())
367 .with(DesignSpaceExplorationAdapter.builder()
368 .strategy(new BestFirstStrategy().withDepthLimit(0)))
369 .build();
370
371 var model = store.createEmptyModel();
372 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
373
374 var states = dseAdapter.explore();
375 assertEquals(1, states.size());
376 }
377
378 @Test
379 void BeFSOneRuleTest() {
380 var createClassPrecondition = Query.of("CreateClassPrecondition",
381 (builder, model) -> builder.clause(
382 classModelView.call(model)
383 ));
384
385 var createClassRule = new TransformationRule("CreateClass",
386 createClassPrecondition,
387 (model) -> {
388 var classesInterpretation = model.getInterpretation(classes);
389 var classElementInterpretation = model.getInterpretation(classElement);
390 return ((Tuple activation) -> {
391 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
392 var modelElement = activation.get(0);
393
394 var newClassElement = dseAdapter.createObject();
395 var newClassElementId = newClassElement.get(0);
396
397 classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
398 classElementInterpretation.put(Tuple.of(newClassElementId), true);
399 });
400 });
401
402 var store = ModelStore.builder()
403 .symbols(classModel, classElement, classes)
404 .with(ViatraModelQueryAdapter.builder()
405 .queries(createClassPrecondition))
406 .with(DesignSpaceExplorationAdapter.builder()
407 .transformations(createClassRule)
408 .strategy(new BestFirstStrategy().withDepthLimit(4)
409 ))
410 .build();
411
412 var model = store.createEmptyModel();
413 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
414 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
415
416 var modelElementInterpretation = model.getInterpretation(classModel);
417 modelElementInterpretation.put(dseAdapter.createObject(), true);
418 queryEngine.flushChanges();
419
420 var states = dseAdapter.explore();
421 assertEquals(1, states.size());
422 }
423
424 @Test
425 void BeFSContinueTest() {
426 var createClassPrecondition = Query.of("CreateClassPrecondition",
427 (builder, model) -> builder.clause(
428 classModelView.call(model)
429 ));
430
431 var createClassRule = new TransformationRule("CreateClass",
432 createClassPrecondition,
433 (model) -> {
434 var classesInterpretation = model.getInterpretation(classes);
435 var classElementInterpretation = model.getInterpretation(classElement);
436 return ((Tuple activation) -> {
437 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
438 var modelElement = activation.get(0);
439
440 var newClassElement = dseAdapter.createObject();
441 var newClassElementId = newClassElement.get(0);
442
443 classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
444 classElementInterpretation.put(Tuple.of(newClassElementId), true);
445 });
446 });
447
448 var store = ModelStore.builder()
449 .symbols(classModel, classElement, classes)
450 .with(ViatraModelQueryAdapter.builder()
451 .queries(createClassPrecondition))
452 .with(DesignSpaceExplorationAdapter.builder()
453 .transformations(createClassRule)
454 .strategy(new BestFirstStrategy().withDepthLimit(4).continueIfHardObjectivesFulfilled()
455 ))
456 .build();
457
458 var model = store.createEmptyModel();
459 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
460 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
461
462 var modelElementInterpretation = model.getInterpretation(classModel);
463 modelElementInterpretation.put(dseAdapter.createObject(), true);
464 queryEngine.flushChanges();
465
466 var states = dseAdapter.explore();
467 assertEquals(5, states.size());
468 }
469
470 @Test
471 void BeFSCompletenessTest() {
472 var createClassPrecondition = Query.of("CreateClassPrecondition",
473 (builder, model) -> builder.clause(
474 classModelView.call(model)
475 ));
476
477 var createClassRule = new TransformationRule("CreateClass",
478 createClassPrecondition,
479 (model) -> {
480 var classesInterpretation = model.getInterpretation(classes);
481 var classElementInterpretation = model.getInterpretation(classElement);
482 return ((Tuple activation) -> {
483 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
484 var modelElement = activation.get(0);
485
486 var newClassElement = dseAdapter.createObject();
487 var newClassElementId = newClassElement.get(0);
488
489 classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
490 classElementInterpretation.put(Tuple.of(newClassElementId), true);
491 });
492 });
493
494 var createFeaturePrecondition = Query.of("CreateFeaturePrecondition",
495 (builder, model) -> builder.clause(
496 classModelView.call(model)
497 ));
498
499 var createFeatureRule = new TransformationRule("CreateFeature",
500 createFeaturePrecondition,
501 (model) -> {
502 var featuresInterpretation = model.getInterpretation(features);
503 var featureInterpretation = model.getInterpretation(feature);
504 return ((Tuple activation) -> {
505 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
506 var modelElement = activation.get(0);
507
508 var newClassElement = dseAdapter.createObject();
509 var newClassElementId = newClassElement.get(0);
510
511 featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
512 featureInterpretation.put(Tuple.of(newClassElementId), true);
513 });
514 });
515
516 var store = ModelStore.builder()
517 .symbols(classModel, classElement, classes, feature, features, isEncapsulatedBy, encapsulates)
518 .with(ViatraModelQueryAdapter.builder()
519 .queries(createClassPrecondition, createFeaturePrecondition))
520 .with(DesignSpaceExplorationAdapter.builder()
521 .transformations(createClassRule, createFeatureRule)
522 .strategy(new BestFirstStrategy().withDepthLimit(10).continueIfHardObjectivesFulfilled()
523 ))
524 .build();
525
526 var model = store.createEmptyModel();
527 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
528 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
529
530 var modelElementInterpretation = model.getInterpretation(classModel);
531 modelElementInterpretation.put(dseAdapter.createObject(), true);
532 queryEngine.flushChanges();
533
534 var states = dseAdapter.explore();
535 assertEquals(2047, states.size());
536 }
537
538 @Test
539 void BeFSSolutionLimitTest() {
540 var createClassPrecondition = Query.of("CreateClassPrecondition",
541 (builder, model) -> builder.clause(
542 classModelView.call(model)
543 ));
544
545 var createClassRule = new TransformationRule("CreateClass",
546 createClassPrecondition,
547 (model) -> {
548 var classesInterpretation = model.getInterpretation(classes);
549 var classElementInterpretation = model.getInterpretation(classElement);
550 return ((Tuple activation) -> {
551 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
552 var modelElement = activation.get(0);
553
554 var newClassElement = dseAdapter.createObject();
555 var newClassElementId = newClassElement.get(0);
556
557 classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
558 classElementInterpretation.put(Tuple.of(newClassElementId), true);
559 });
560 });
561
562 var createFeaturePrecondition = Query.of("CreateFeaturePrecondition",
563 (builder, model) -> builder.clause(
564 classModelView.call(model)
565 ));
566
567 var createFeatureRule = new TransformationRule("CreateFeature",
568 createFeaturePrecondition,
569 (model) -> {
570 var featuresInterpretation = model.getInterpretation(features);
571 var featureInterpretation = model.getInterpretation(feature);
572 return ((Tuple activation) -> {
573 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
574 var modelElement = activation.get(0);
575
576 var newClassElement = dseAdapter.createObject();
577 var newClassElementId = newClassElement.get(0);
578
579 featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
580 featureInterpretation.put(Tuple.of(newClassElementId), true);
581 });
582 });
583
584 var store = ModelStore.builder()
585 .symbols(classModel, classElement, classes, feature, features, isEncapsulatedBy, encapsulates)
586 .with(ViatraModelQueryAdapter.builder()
587 .queries(createClassPrecondition, createFeaturePrecondition))
588 .with(DesignSpaceExplorationAdapter.builder()
589 .transformations(createClassRule, createFeatureRule)
590 .strategy(new BestFirstStrategy().withSolutionLimit(222)
591 .continueIfHardObjectivesFulfilled()
592 ))
593 .build();
594
595 var model = store.createEmptyModel();
596 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
597 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
598
599 var modelElementInterpretation = model.getInterpretation(classModel);
600 modelElementInterpretation.put(dseAdapter.createObject(), true);
601 queryEngine.flushChanges();
602
603 var states = dseAdapter.explore();
604 assertEquals(222, states.size());
605 }
606
607}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java
deleted file mode 100644
index 5d24d712..00000000
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java
+++ /dev/null
@@ -1,413 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.dse.strategy.DepthFirstStrategy;
10import tools.refinery.store.model.ModelStore;
11import tools.refinery.store.query.ModelQueryAdapter;
12import tools.refinery.store.query.dnf.Query;
13import tools.refinery.store.dse.internal.TransformationRule;
14import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
15import tools.refinery.store.query.view.AnySymbolView;
16import tools.refinery.store.query.view.KeyOnlyView;
17import tools.refinery.store.representation.Symbol;
18import tools.refinery.store.tuple.Tuple;
19
20import java.util.List;
21import java.util.Map;
22
23import static org.junit.jupiter.api.Assertions.assertEquals;
24import static tools.refinery.store.query.literal.Literals.not;
25import static tools.refinery.store.dse.tests.QueryAssertions.assertResults;
26
27class TransformationRuleTest {
28
29 private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1);
30 private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1);
31 private static final Symbol<Boolean> feature = Symbol.of("Feature", 1);
32
33 private static final Symbol<Boolean> isEncapsulatedBy = Symbol.of("IsEncapsulatedBy", 2);
34 private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2);
35
36 private static final Symbol<Boolean> features = Symbol.of("Features", 2);
37 private static final Symbol<Boolean> classes = Symbol.of("Classes", 2);
38
39 private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel);
40 private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement);
41 private static final AnySymbolView featureView = new KeyOnlyView<>(feature);
42 private static final AnySymbolView isEncapsulatedByView = new KeyOnlyView<>(isEncapsulatedBy);
43 private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates);
44 private static final AnySymbolView featuresView = new KeyOnlyView<>(features);
45 private static final AnySymbolView classesView = new KeyOnlyView<>(classes);
46
47 @Test
48 void activationsTest() {
49 var assignFeaturePreconditionHelper = Query.of("AssignFeaturePreconditionHelper",
50 (builder, model, c, f) -> builder.clause(
51 classElementView.call(c),
52 classesView.call(model, c),
53 encapsulatesView.call(c, f)
54 ));
55
56 var assignFeaturePrecondition = Query.of("AssignFeaturePrecondition", (builder, c2, f)
57 -> builder.clause((model, c1) -> List.of(
58 classModelView.call(model),
59 featureView.call(f),
60 classElementView.call(c2),
61 featuresView.call(model, f),
62 classesView.call(model, c1),
63 not(assignFeaturePreconditionHelper.call(model, c2, f)),
64 not(encapsulatesView.call(c2, f))
65 )));
66
67 var deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition",
68 (builder, model, c) -> builder.clause((f) -> List.of(
69 classModelView.call(model),
70 classElementView.call(c),
71 featuresView.call(model, f),
72 not(encapsulatesView.call(c, f))
73 )));
74
75 TransformationRule assignFeatureRule = new TransformationRule("AssignFeature",
76 assignFeaturePrecondition,
77 (model) -> {
78 var isEncapsulatedByInterpretation = model.getInterpretation(isEncapsulatedBy);
79 return ((Tuple activation) -> {
80 var feature = activation.get(0);
81 var classElement = activation.get(1);
82
83 isEncapsulatedByInterpretation.put(Tuple.of(feature, classElement), true);
84 });
85 });
86
87 TransformationRule deleteEmptyClassRule = new TransformationRule("DeleteEmptyClass",
88 deleteEmptyClassPrecondition,
89 (model) -> {
90 var classesInterpretation = model.getInterpretation(classes);
91 var classElementInterpretation = model.getInterpretation(classElement);
92 return ((Tuple activation) -> {
93 var modelElement = activation.get(0);
94 var classElement = activation.get(1);
95
96 classesInterpretation.put(Tuple.of(modelElement, classElement), false);
97 classElementInterpretation.put(Tuple.of(classElement), false);
98 });
99 });
100
101
102 var store = ModelStore.builder()
103 .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features)
104 .with(ViatraModelQueryAdapter.builder()
105 .queries(assignFeaturePrecondition, assignFeaturePreconditionHelper,
106 deleteEmptyClassPrecondition))
107 .with(DesignSpaceExplorationAdapter.builder()
108 .strategy(new DepthFirstStrategy().withDepthLimit(0)))
109 .build();
110
111 var model = store.createEmptyModel();
112 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
113 assignFeatureRule.prepare(model, queryEngine);
114 deleteEmptyClassRule.prepare(model, queryEngine);
115
116 var classModelInterpretation = model.getInterpretation(classModel);
117 var classElementInterpretation = model.getInterpretation(classElement);
118 var featureInterpretation = model.getInterpretation(feature);
119 var featuresInterpretation = model.getInterpretation(features);
120 var classesInterpretation = model.getInterpretation(classes);
121
122 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
123 var newModel = dseAdapter.createObject();
124 var newModelId = newModel.get(0);
125 var newClass1 = dseAdapter.createObject();
126 var newClass1Id = newClass1.get(0);
127 var newClass2 = dseAdapter.createObject();
128 var newClass2Id = newClass2.get(0);
129 var newField = dseAdapter.createObject();
130 var newFieldId = newField.get(0);
131
132 classModelInterpretation.put(newModel, true);
133 classElementInterpretation.put(newClass1, true);
134 classElementInterpretation.put(newClass2, true);
135 featureInterpretation.put(newField, true);
136 classesInterpretation.put(Tuple.of(newModelId, newClass1Id), true);
137 classesInterpretation.put(Tuple.of(newModelId, newClass2Id), true);
138 featuresInterpretation.put(Tuple.of(newModelId, newFieldId), true);
139
140 queryEngine.flushChanges();
141
142 var assignFeatureRuleActivations = assignFeatureRule.getAllActivationsAsResultSet();
143 var deleteEmptyClassRuleActivations = deleteEmptyClassRule.getAllActivationsAsResultSet();
144
145 assertResults(Map.of(
146 Tuple.of(newClass1Id, newFieldId), true,
147 Tuple.of(newClass2Id, newFieldId), true
148 ), assignFeatureRuleActivations);
149
150 assertResults(Map.of(
151 Tuple.of(newModelId, newClass1Id), true,
152 Tuple.of(newModelId, newClass2Id), true
153 ), deleteEmptyClassRuleActivations);
154 }
155
156 @Test
157 void randomActivationTest() {
158 var deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition",
159 (builder, model, c) -> builder.clause((f) -> List.of(
160 classModelView.call(model),
161 classElementView.call(c),
162 featuresView.call(model, f),
163 not(encapsulatesView.call(c, f))
164 )));
165
166 TransformationRule deleteEmptyClassRule0 = new TransformationRule("DeleteEmptyClass0",
167 deleteEmptyClassPrecondition,
168 (model) -> {
169 var classesInterpretation = model.getInterpretation(classes);
170 var classElementInterpretation = model.getInterpretation(classElement);
171 return ((Tuple activation) -> {
172 var modelElement = activation.get(0);
173 var classElement = activation.get(1);
174
175 classesInterpretation.put(Tuple.of(modelElement, classElement), false);
176 classElementInterpretation.put(Tuple.of(classElement), false);
177 });
178 },
179 0L);
180
181 TransformationRule deleteEmptyClassRule1 = new TransformationRule("DeleteEmptyClass1",
182 deleteEmptyClassPrecondition,
183 (model) -> {
184 var classesInterpretation = model.getInterpretation(classes);
185 var classElementInterpretation = model.getInterpretation(classElement);
186 return ((Tuple activation) -> {
187 var modelElement = activation.get(0);
188 var classElement = activation.get(1);
189
190 classesInterpretation.put(Tuple.of(modelElement, classElement), false);
191 classElementInterpretation.put(Tuple.of(classElement), false);
192 });
193 },
194 78634L);
195
196 var store = ModelStore.builder()
197 .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features)
198 .with(ViatraModelQueryAdapter.builder()
199 .queries(deleteEmptyClassPrecondition))
200 .with(DesignSpaceExplorationAdapter.builder()
201 .strategy(new DepthFirstStrategy().withDepthLimit(0)))
202 .build();
203
204 var model = store.createEmptyModel();
205 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
206 deleteEmptyClassRule0.prepare(model, queryEngine);
207 deleteEmptyClassRule1.prepare(model, queryEngine);
208
209 var classModelInterpretation = model.getInterpretation(classModel);
210 var classElementInterpretation = model.getInterpretation(classElement);
211 var featureInterpretation = model.getInterpretation(feature);
212 var featuresInterpretation = model.getInterpretation(features);
213 var classesInterpretation = model.getInterpretation(classes);
214
215 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
216 var newModel = dseAdapter.createObject();
217 var newModelId = newModel.get(0);
218 var newClass1 = dseAdapter.createObject();
219 var newClass1Id = newClass1.get(0);
220 var newClass2 = dseAdapter.createObject();
221 var newClass2Id = newClass2.get(0);
222 var newField = dseAdapter.createObject();
223 var newFieldId = newField.get(0);
224
225 classModelInterpretation.put(newModel, true);
226 classElementInterpretation.put(newClass1, true);
227 classElementInterpretation.put(newClass2, true);
228 featureInterpretation.put(newField, true);
229 classesInterpretation.put(Tuple.of(newModelId, newClass1Id), true);
230 classesInterpretation.put(Tuple.of(newModelId, newClass2Id), true);
231 featuresInterpretation.put(Tuple.of(newModelId, newFieldId), true);
232
233 queryEngine.flushChanges();
234
235
236 var activation0 = deleteEmptyClassRule0.getRandomActivation().activation();
237 var activation1 = deleteEmptyClassRule1.getRandomActivation().activation();
238
239 assertResults(Map.of(
240 Tuple.of(newModelId, newClass1Id), true,
241 Tuple.of(newModelId, newClass2Id), true
242 ), deleteEmptyClassRule0.getAllActivationsAsResultSet());
243
244 assertResults(Map.of(
245 Tuple.of(newModelId, newClass1Id), true,
246 Tuple.of(newModelId, newClass2Id), true
247 ), deleteEmptyClassRule1.getAllActivationsAsResultSet());
248
249 assertEquals(Tuple.of(newModelId, newClass2Id), activation0);
250 assertEquals(Tuple.of(newModelId, newClass1Id), activation1);
251
252 }
253
254 @Test
255 void fireTest() {
256 var deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition",
257 (builder, model, c) -> builder.clause((f) -> List.of(
258 classModelView.call(model),
259 classElementView.call(c),
260 featuresView.call(model, f),
261 not(encapsulatesView.call(c, f))
262 )));
263
264 TransformationRule deleteEmptyClassRule = new TransformationRule("DeleteEmptyClass",
265 deleteEmptyClassPrecondition,
266 (model) -> {
267 var classesInterpretation = model.getInterpretation(classes);
268 var classElementInterpretation = model.getInterpretation(classElement);
269 return ((Tuple activation) -> {
270 var modelElement = activation.get(0);
271 var classElement = activation.get(1);
272
273 classesInterpretation.put(Tuple.of(modelElement, classElement), false);
274 classElementInterpretation.put(Tuple.of(classElement), false);
275 });
276 });
277
278 var store = ModelStore.builder()
279 .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features)
280 .with(ViatraModelQueryAdapter.builder()
281 .queries(deleteEmptyClassPrecondition))
282 .with(DesignSpaceExplorationAdapter.builder()
283 .strategy(new DepthFirstStrategy().withDepthLimit(0)))
284 .build();
285
286 var model = store.createEmptyModel();
287 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
288 deleteEmptyClassRule.prepare(model, queryEngine);
289
290 var classModelInterpretation = model.getInterpretation(classModel);
291 var classElementInterpretation = model.getInterpretation(classElement);
292 var featureInterpretation = model.getInterpretation(feature);
293 var featuresInterpretation = model.getInterpretation(features);
294 var classesInterpretation = model.getInterpretation(classes);
295
296 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
297 var newModel = dseAdapter.createObject();
298 var newModelId = newModel.get(0);
299 var newClass1 = dseAdapter.createObject();
300 var newClass1Id = newClass1.get(0);
301 var newClass2 = dseAdapter.createObject();
302 var newClass2Id = newClass2.get(0);
303 var newField = dseAdapter.createObject();
304 var newFieldId = newField.get(0);
305
306 classModelInterpretation.put(newModel, true);
307 classElementInterpretation.put(newClass1, true);
308 classElementInterpretation.put(newClass2, true);
309 featureInterpretation.put(newField, true);
310 classesInterpretation.put(Tuple.of(newModelId, newClass1Id), true);
311 classesInterpretation.put(Tuple.of(newModelId, newClass2Id), true);
312 featuresInterpretation.put(Tuple.of(newModelId, newFieldId), true);
313
314 queryEngine.flushChanges();
315
316 assertResults(Map.of(
317 Tuple.of(newModelId, newClass1Id), true,
318 Tuple.of(newModelId, newClass2Id), true
319 ), deleteEmptyClassRule.getAllActivationsAsResultSet());
320
321
322 deleteEmptyClassRule.fireActivation(Tuple.of(0, 1));
323
324 assertResults(Map.of(
325 Tuple.of(newModelId, newClass1Id), false,
326 Tuple.of(newModelId, newClass2Id), true
327 ), deleteEmptyClassRule.getAllActivationsAsResultSet());
328 }
329
330 @Test
331 void randomFireTest() {
332 var deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition",
333 (builder, model, c) -> builder.clause((f) -> List.of(
334 classModelView.call(model),
335 classElementView.call(c),
336 featuresView.call(model, f),
337 not(encapsulatesView.call(c, f))
338 )));
339
340 TransformationRule deleteEmptyClassRule = new TransformationRule("DeleteEmptyClass0",
341 deleteEmptyClassPrecondition,
342 (model) -> {
343 var classesInterpretation = model.getInterpretation(classes);
344 var classElementInterpretation = model.getInterpretation(classElement);
345 return ((Tuple activation) -> {
346 var modelElement = activation.get(0);
347 var classElement = activation.get(1);
348
349 classesInterpretation.put(Tuple.of(modelElement, classElement), false);
350 classElementInterpretation.put(Tuple.of(classElement), false);
351 });
352 },
353 0L);
354
355 var store = ModelStore.builder()
356 .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features)
357 .with(ViatraModelQueryAdapter.builder()
358 .queries(deleteEmptyClassPrecondition))
359 .with(DesignSpaceExplorationAdapter.builder()
360 .strategy(new DepthFirstStrategy().withDepthLimit(0)))
361 .build();
362
363 var model = store.createEmptyModel();
364 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
365 deleteEmptyClassRule.prepare(model, queryEngine);
366
367 var classModelInterpretation = model.getInterpretation(classModel);
368 var classElementInterpretation = model.getInterpretation(classElement);
369 var featureInterpretation = model.getInterpretation(feature);
370 var featuresInterpretation = model.getInterpretation(features);
371 var classesInterpretation = model.getInterpretation(classes);
372
373 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
374 var newModel = dseAdapter.createObject();
375 var newModelId = newModel.get(0);
376 var newClass1 = dseAdapter.createObject();
377 var newClass1Id = newClass1.get(0);
378 var newClass2 = dseAdapter.createObject();
379 var newClass2Id = newClass2.get(0);
380 var newField = dseAdapter.createObject();
381 var newFieldId = newField.get(0);
382
383 classModelInterpretation.put(newModel, true);
384 classElementInterpretation.put(newClass1, true);
385 classElementInterpretation.put(newClass2, true);
386 featureInterpretation.put(newField, true);
387 classesInterpretation.put(Tuple.of(newModelId, newClass1Id), true);
388 classesInterpretation.put(Tuple.of(newModelId, newClass2Id), true);
389 featuresInterpretation.put(Tuple.of(newModelId, newFieldId), true);
390
391 queryEngine.flushChanges();
392
393 assertResults(Map.of(
394 Tuple.of(newModelId, newClass1Id), true,
395 Tuple.of(newModelId, newClass2Id), true
396 ), deleteEmptyClassRule.getAllActivationsAsResultSet());
397
398 deleteEmptyClassRule.fireRandomActivation();
399
400 assertResults(Map.of(
401 Tuple.of(newModelId, newClass1Id), true,
402 Tuple.of(newModelId, newClass2Id), false
403 ), deleteEmptyClassRule.getAllActivationsAsResultSet());
404
405 deleteEmptyClassRule.fireRandomActivation();
406
407 assertResults(Map.of(
408 Tuple.of(newModelId, newClass1Id), false,
409 Tuple.of(newModelId, newClass2Id), false
410 ), deleteEmptyClassRule.getAllActivationsAsResultSet());
411
412 }
413}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyCriterion.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyCriterion.java
new file mode 100644
index 00000000..2d5a0f36
--- /dev/null
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyCriterion.java
@@ -0,0 +1,22 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.tests;
7
8import tools.refinery.store.dse.transition.objectives.Criterion;
9import tools.refinery.store.dse.transition.objectives.CriterionCalculator;
10import tools.refinery.store.model.Model;
11
12public class DummyCriterion implements Criterion {
13 protected final boolean returnValue;
14 public DummyCriterion(boolean returnValue) {
15 this.returnValue = returnValue;
16 }
17
18 @Override
19 public CriterionCalculator createCalculator(Model model) {
20 return () -> returnValue;
21 }
22}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyObjective.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyObjective.java
new file mode 100644
index 00000000..f5d281aa
--- /dev/null
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyObjective.java
@@ -0,0 +1,18 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.tests;
7
8import tools.refinery.store.dse.transition.objectives.Objective;
9import tools.refinery.store.dse.transition.objectives.ObjectiveCalculator;
10import tools.refinery.store.model.Model;
11
12public class DummyObjective implements Objective {
13
14 @Override
15 public ObjectiveCalculator createCalculator(Model model) {
16 return () -> {return 0d;};
17 }
18}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomCriterion.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomCriterion.java
new file mode 100644
index 00000000..71fd4403
--- /dev/null
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomCriterion.java
@@ -0,0 +1,25 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.tests;
7
8import tools.refinery.store.dse.transition.objectives.Criterion;
9import tools.refinery.store.dse.transition.objectives.CriterionCalculator;
10import tools.refinery.store.model.Model;
11
12import java.util.Random;
13
14public class DummyRandomCriterion implements Criterion {
15
16 @SuppressWarnings("squid:S2245")
17 private static final Random random = new Random(9856654);
18 public DummyRandomCriterion() {
19 }
20
21 @Override
22 public CriterionCalculator createCalculator(Model model) {
23 return random::nextBoolean;
24 }
25}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomObjective.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomObjective.java
new file mode 100644
index 00000000..219e74c6
--- /dev/null
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomObjective.java
@@ -0,0 +1,23 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.tests;
7
8import tools.refinery.store.dse.transition.objectives.Objective;
9import tools.refinery.store.dse.transition.objectives.ObjectiveCalculator;
10import tools.refinery.store.model.Model;
11
12import java.util.Random;
13
14public class DummyRandomObjective implements Objective {
15
16 @SuppressWarnings("squid:S2245")
17 private static final Random random = new Random(9856654);
18
19 @Override
20 public ObjectiveCalculator createCalculator(Model model) {
21 return random::nextDouble;
22 }
23}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/QueryAssertions.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/QueryAssertions.java
index be514eaf..f0a20720 100644
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/QueryAssertions.java
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/QueryAssertions.java
@@ -30,7 +30,7 @@ public final class QueryAssertions {
30 } 30 }
31 31
32 public static <T> void assertResults(Map<Tuple, T> expected, ResultSet<T> resultSet) { 32 public static <T> void assertResults(Map<Tuple, T> expected, ResultSet<T> resultSet) {
33 var defaultValue = resultSet.getQuery().defaultValue(); 33 var defaultValue = resultSet.getCanonicalQuery().defaultValue();
34 var filteredExpected = new LinkedHashMap<Tuple, T>(); 34 var filteredExpected = new LinkedHashMap<Tuple, T>();
35 var executables = new ArrayList<Executable>(); 35 var executables = new ArrayList<Executable>();
36 for (var entry : expected.entrySet()) { 36 for (var entry : expected.entrySet()) {
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java
new file mode 100644
index 00000000..42a0f89b
--- /dev/null
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java
@@ -0,0 +1,149 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition;
7
8import org.junit.jupiter.api.Test;
9import tools.refinery.store.dse.modification.ModificationAdapter;
10import tools.refinery.store.dse.transition.objectives.Criteria;
11import tools.refinery.store.dse.transition.objectives.Objectives;
12import tools.refinery.store.model.Model;
13import tools.refinery.store.model.ModelStore;
14import tools.refinery.store.query.ModelQueryAdapter;
15import tools.refinery.store.query.dnf.FunctionalQuery;
16import tools.refinery.store.query.dnf.Query;
17import tools.refinery.store.query.dnf.RelationalQuery;
18import tools.refinery.store.query.term.Variable;
19import tools.refinery.store.query.term.int_.IntTerms;
20import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
21import tools.refinery.store.query.view.AnySymbolView;
22import tools.refinery.store.query.view.KeyOnlyView;
23import tools.refinery.store.representation.Symbol;
24import tools.refinery.store.statecoding.StateCoderAdapter;
25import tools.refinery.store.tuple.Tuple;
26
27import java.util.List;
28
29import static org.junit.jupiter.api.Assertions.*;
30import static tools.refinery.store.query.literal.Literals.check;
31import static tools.refinery.store.query.literal.Literals.not;
32
33class TransitionBuildTests {
34 Symbol<Boolean> person = new Symbol<>("Person", 1, Boolean.class, false);
35 Symbol<Boolean> friend = new Symbol<>("friend", 2, Boolean.class, false);
36
37 AnySymbolView personView = new KeyOnlyView<>(person);
38 AnySymbolView friendView = new KeyOnlyView<>(friend);
39
40 RelationalQuery moreThan3Friends = Query.of("moreThan3Friends", (builder, tooMuchFriends) -> builder
41 .clause(Integer.class, (numberOfFriends) -> List.of(
42 numberOfFriends.assign(friendView.count(tooMuchFriends, Variable.of())),
43 check(IntTerms.less(IntTerms.constant(3), numberOfFriends)),
44 personView.call(tooMuchFriends)
45 )));
46
47 RelationalQuery somebodyHasNoFriend = Query.of("somebodyHasNoFriend", (builder, lonely) -> builder
48 .clause(
49 personView.call(lonely),
50 not(friendView.call(lonely, Variable.of()))
51 ));
52
53 FunctionalQuery<Integer> numberOfFriends = Query.of(Integer.class, (builder, output) -> builder
54 .clause(
55 output.assign(friendView.count(Variable.of(), Variable.of()))
56 ));
57
58 @Test
59 void acceptTest() {
60 Model model = getModel();
61
62 var dse = model.getAdapter(DesignSpaceExplorationAdapter.class);
63 var query = model.getAdapter(ModelQueryAdapter.class);
64 var personI = model.getInterpretation(person);
65 var friendI = model.getInterpretation(friend);
66
67 assertTrue(dse.checkAccept());
68 personI.put(Tuple.of(1), true);
69 personI.put(Tuple.of(2), true);
70
71 query.flushChanges();
72
73 assertFalse(dse.checkAccept());
74 friendI.put(Tuple.of(1, 2), true);
75 friendI.put(Tuple.of(2, 1), true);
76
77 query.flushChanges();
78
79 assertTrue(dse.checkAccept());
80 }
81
82 @Test
83 void includeTest() {
84 Model model = getModel();
85
86 var dse = model.getAdapter(DesignSpaceExplorationAdapter.class);
87 var query = model.getAdapter(ModelQueryAdapter.class);
88 var personI = model.getInterpretation(person);
89 var friendI = model.getInterpretation(friend);
90
91 assertFalse(dse.checkExclude());
92
93 personI.put(Tuple.of(1), true);
94 friendI.put(Tuple.of(1, 2), true);
95 friendI.put(Tuple.of(1, 3), true);
96 friendI.put(Tuple.of(1, 4), true);
97
98 query.flushChanges();
99 assertFalse(dse.checkExclude());
100
101 personI.put(Tuple.of(5), true);
102 friendI.put(Tuple.of(1, 5), true);
103
104 query.flushChanges();
105 assertTrue(dse.checkExclude());
106
107 friendI.put(Tuple.of(1, 2), false);
108
109 query.flushChanges();
110 assertFalse(dse.checkExclude());
111 }
112
113 @Test
114 void objectiveTest() {
115 Model model = getModel();
116
117 var dse = model.getAdapter(DesignSpaceExplorationAdapter.class);
118 var query = model.getAdapter(ModelQueryAdapter.class);
119 var friendI = model.getInterpretation(friend);
120
121 assertEquals(0.0, dse.getObjectiveValue().get(0), 0.01);
122
123 friendI.put(Tuple.of(1, 2), true);
124
125 query.flushChanges();
126 assertEquals(1.0, dse.getObjectiveValue().get(0), 0.01);
127
128 friendI.put(Tuple.of(1, 3), true);
129 friendI.put(Tuple.of(1, 4), true);
130
131 query.flushChanges();
132 assertEquals(3.0, dse.getObjectiveValue().get(0), 0.01);
133 }
134
135 private Model getModel() {
136 var store = ModelStore.builder()
137 .symbols(person, friend)
138 .with(ViatraModelQueryAdapter.builder())
139 .with(StateCoderAdapter.builder())
140 .with(ModificationAdapter.builder())
141 .with(DesignSpaceExplorationAdapter.builder()
142 .objective(Objectives.value(numberOfFriends))
143 .exclude(Criteria.whenHasMatch(moreThan3Friends))
144 .accept(Criteria.whenNoMatch(somebodyHasNoFriend)))
145 .build();
146
147 return store.createEmptyModel();
148 }
149}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/statespace/internal/ActivationUnitTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/statespace/internal/ActivationUnitTest.java
new file mode 100644
index 00000000..3a672b18
--- /dev/null
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/statespace/internal/ActivationUnitTest.java
@@ -0,0 +1,131 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.statespace.internal;
7
8import org.junit.jupiter.api.Assertions;
9import org.junit.jupiter.params.ParameterizedTest;
10import org.junit.jupiter.params.provider.MethodSource;
11
12import java.util.ArrayList;
13import java.util.Collections;
14import java.util.List;
15import java.util.Random;
16import java.util.function.Supplier;
17import java.util.stream.Stream;
18
19class ActivationUnitTest {
20 private final static int SMALL_SIZE = 5;
21
22 private static Stream<ActivationStoreEntry> entries() {
23 return Stream.of(
24 new ActivationStoreBitVectorEntry(SMALL_SIZE),
25 new ActivationStoreListEntry(SMALL_SIZE)
26 );
27 }
28
29 void addTest(ActivationStoreEntry entry, int elementsAdded) {
30 Assertions.assertEquals(elementsAdded, entry.getNumberOfVisitedActivations());
31 Assertions.assertEquals(SMALL_SIZE - elementsAdded, entry.getNumberOfUnvisitedActivations());
32 }
33
34 @ParameterizedTest
35 @MethodSource("entries")
36 void testDifferent(ActivationStoreEntry entry) {
37 int elementsAdded = 0;
38 addTest(entry, elementsAdded);
39 Assertions.assertEquals(2, entry.getAndAddActivationAfter(2));
40 addTest(entry, ++elementsAdded);
41 Assertions.assertEquals(3, entry.getAndAddActivationAfter(3));
42 addTest(entry, ++elementsAdded);
43 Assertions.assertEquals(1, entry.getAndAddActivationAfter(1));
44 addTest(entry, ++elementsAdded);
45 Assertions.assertEquals(4, entry.getAndAddActivationAfter(4));
46 addTest(entry, ++elementsAdded);
47 Assertions.assertEquals(0, entry.getAndAddActivationAfter(0));
48 addTest(entry, ++elementsAdded);
49 }
50
51
52 @ParameterizedTest
53 @MethodSource("entries")
54 void testSame(ActivationStoreEntry entry) {
55 int elementsAdded = 0;
56 addTest(entry, 0);
57 entry.getAndAddActivationAfter(2);
58 addTest(entry, ++elementsAdded);
59 entry.getAndAddActivationAfter(2);
60 addTest(entry, ++elementsAdded);
61 entry.getAndAddActivationAfter(2);
62 addTest(entry, ++elementsAdded);
63 entry.getAndAddActivationAfter(2);
64 addTest(entry, ++elementsAdded);
65 entry.getAndAddActivationAfter(2);
66 addTest(entry, ++elementsAdded);
67 }
68
69 @ParameterizedTest
70 @MethodSource("entries")
71 void testFilling(ActivationStoreEntry entry) {
72 int elementsAdded = 0;
73 while (elementsAdded < SMALL_SIZE) {
74 entry.getAndAddActivationAfter(2);
75 elementsAdded++;
76 }
77 Assertions.assertThrows(IllegalArgumentException.class, () -> entry.getAndAddActivationAfter(2));
78 }
79
80 void randomDifferentTestCase(ActivationStoreEntry entry, int seed) {
81 List<Integer> elements = new ArrayList<>(SMALL_SIZE);
82 for (int i = 0; i < SMALL_SIZE; i++) {
83 elements.add(i);
84 }
85 @SuppressWarnings("squid:S2245")
86 var random = new Random(seed);
87 Collections.shuffle(elements, random);
88
89 for (int element : elements) {
90 entry.getAndAddActivationAfter(element);
91 }
92 Assertions.assertThrows(IllegalArgumentException.class, () -> entry.getAndAddActivationAfter(2));
93 }
94
95 private static final int fuzzNumber = 20;
96
97 @ParameterizedTest
98 @MethodSource("entryFactories")
99 void randomDifferentTest(Supplier<ActivationStoreEntry> entry) {
100 for (int i = 0; i < fuzzNumber; i++) {
101 randomDifferentTestCase(entry.get(), i);
102 }
103 }
104
105 void randomSameTestCase(ActivationStoreEntry entry, int seed) {
106
107 @SuppressWarnings("squid:S2245")
108 var random = new Random(seed);
109
110 for (int i = 0; i < SMALL_SIZE; i++) {
111 entry.getAndAddActivationAfter(random.nextInt(SMALL_SIZE));
112 }
113
114 Assertions.assertThrows(IllegalArgumentException.class, () -> entry.getAndAddActivationAfter(2));
115 }
116
117 @ParameterizedTest
118 @MethodSource("entryFactories")
119 void randomSameTest(Supplier<ActivationStoreEntry> entry) {
120 for (int i = 0; i < fuzzNumber; i++) {
121 randomSameTestCase(entry.get(), i);
122 }
123 }
124
125 private static Stream<Supplier<ActivationStoreEntry>> entryFactories() {
126 return Stream.of(
127 () -> new ActivationStoreBitVectorEntry(SMALL_SIZE),
128 () -> new ActivationStoreListEntry(SMALL_SIZE)
129 );
130 }
131}