diff options
-rw-r--r-- | subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/dse/CRAExamplesTest.java | 233 |
1 files changed, 186 insertions, 47 deletions
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/dse/CRAExamplesTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/dse/CRAExamplesTest.java index 8fe50a42..2effb353 100644 --- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/dse/CRAExamplesTest.java +++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/dse/CRAExamplesTest.java | |||
@@ -1,112 +1,140 @@ | |||
1 | package tools.refinery.store.query.dse; | 1 | package tools.refinery.store.query.dse; |
2 | 2 | ||
3 | import org.junit.jupiter.api.Test; | ||
4 | import tools.refinery.store.model.ModelStore; | ||
5 | import tools.refinery.store.query.ModelQueryAdapter; | ||
3 | import tools.refinery.store.query.dnf.Query; | 6 | import tools.refinery.store.query.dnf.Query; |
4 | import tools.refinery.store.query.dnf.RelationalQuery; | 7 | import tools.refinery.store.query.dnf.RelationalQuery; |
5 | import tools.refinery.store.query.dse.internal.TransformationRule; | 8 | import tools.refinery.store.query.dse.internal.TransformationRule; |
9 | import tools.refinery.store.query.dse.strategy.BestFirstStrategy; | ||
10 | import tools.refinery.store.query.dse.strategy.DepthFirstStrategy; | ||
11 | import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; | ||
6 | import tools.refinery.store.query.view.AnySymbolView; | 12 | import tools.refinery.store.query.view.AnySymbolView; |
7 | import tools.refinery.store.query.view.KeyOnlyView; | 13 | import tools.refinery.store.query.view.KeyOnlyView; |
8 | import tools.refinery.store.representation.Symbol; | 14 | import tools.refinery.store.representation.Symbol; |
9 | import tools.refinery.store.tuple.Tuple; | 15 | import tools.refinery.store.tuple.Tuple; |
16 | import tools.refinery.visualization.ModelVisualizerAdapter; | ||
17 | import tools.refinery.visualization.internal.FileFormat; | ||
10 | 18 | ||
11 | import java.util.List; | 19 | import java.util.List; |
12 | 20 | ||
13 | import static tools.refinery.store.query.literal.Literals.not; | 21 | import static tools.refinery.store.query.literal.Literals.not; |
14 | 22 | ||
15 | public class CRAExamplesTest { | 23 | public class CRAExamplesTest { |
16 | private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1); | 24 | private static final Symbol<String> name = Symbol.of("Name", 1, String.class); |
25 | |||
26 | // private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1); | ||
17 | private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1); | 27 | private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1); |
18 | private static final Symbol<Boolean> feature = Symbol.of("Feature", 1); | 28 | // private static final Symbol<Boolean> feature = Symbol.of("Feature", 1); |
29 | private static final Symbol<Boolean> attribute = Symbol.of("Attribute", 1); | ||
30 | private static final Symbol<Boolean> method = Symbol.of("Method", 1); | ||
19 | 31 | ||
20 | private static final Symbol<Boolean> isEncapsulatedBy = Symbol.of("IsEncapsulatedBy", 2); | 32 | // private static final Symbol<Boolean> isEncapsulatedBy = Symbol.of("IsEncapsulatedBy", 2); |
21 | private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2); | 33 | private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2); |
34 | private static final Symbol<Boolean> dataDependency = Symbol.of("DataDependency", 2); | ||
35 | private static final Symbol<Boolean> functionalDependency = Symbol.of("FunctionalDependency", 2); | ||
22 | 36 | ||
23 | private static final Symbol<Boolean> features = Symbol.of("Features", 2); | 37 | private static final Symbol<Boolean> features = Symbol.of("Features", 2); |
24 | private static final Symbol<Boolean> classes = Symbol.of("Classes", 2); | 38 | private static final Symbol<Boolean> classes = Symbol.of("Classes", 2); |
25 | 39 | ||
26 | private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel); | 40 | // private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel); |
27 | private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement); | 41 | private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement); |
28 | private static final AnySymbolView featureView = new KeyOnlyView<>(feature); | 42 | // private static final AnySymbolView featureView = new KeyOnlyView<>(feature); |
29 | private static final AnySymbolView isEncapsulatedByView = new KeyOnlyView<>(isEncapsulatedBy); | 43 | private static final AnySymbolView attributeView = new KeyOnlyView<>(attribute); |
44 | private static final AnySymbolView methodView = new KeyOnlyView<>(method); | ||
45 | // private static final AnySymbolView isEncapsulatedByView = new KeyOnlyView<>(isEncapsulatedBy); | ||
30 | private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates); | 46 | private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates); |
47 | private static final AnySymbolView dataDependencyView = new KeyOnlyView<>(dataDependency); | ||
48 | private static final AnySymbolView functionalDependencyView = new KeyOnlyView<>(functionalDependency); | ||
31 | private static final AnySymbolView featuresView = new KeyOnlyView<>(features); | 49 | private static final AnySymbolView featuresView = new KeyOnlyView<>(features); |
32 | private static final AnySymbolView classesView = new KeyOnlyView<>(classes); | 50 | private static final AnySymbolView classesView = new KeyOnlyView<>(classes); |
33 | 51 | ||
34 | /*Example Transformation rules*/ | 52 | /*Example Transformation rules*/ |
53 | private static final RelationalQuery feature = Query.of("Feature", | ||
54 | (builder, f) -> builder.clause( | ||
55 | attributeView.call(f)) | ||
56 | .clause( | ||
57 | methodView.call(f)) | ||
58 | ); | ||
59 | |||
35 | private static final RelationalQuery assignFeaturePreconditionHelper = Query.of("AssignFeaturePreconditionHelper", | 60 | private static final RelationalQuery assignFeaturePreconditionHelper = Query.of("AssignFeaturePreconditionHelper", |
36 | (builder, model, c, f) -> builder.clause( | 61 | (builder, c, f) -> builder.clause( |
37 | classElementView.call(c), | 62 | classElementView.call(c), |
38 | classesView.call(model, c), | 63 | // classesView.call(model, c), |
39 | encapsulatesView.call(c, f) | 64 | encapsulatesView.call(c, f) |
40 | )); | 65 | )); |
41 | 66 | ||
42 | private static final RelationalQuery assignFeaturePrecondition = Query.of("AssignFeaturePrecondition", (builder, c2, f) | 67 | private static final RelationalQuery assignFeaturePrecondition = Query.of("AssignFeaturePrecondition", |
43 | -> builder.clause((model, c1) -> List.of( | 68 | (builder, f, c1) -> builder.clause((c2) -> List.of( |
44 | classModelView.call(model), | 69 | // classModelView.call(model), |
45 | featureView.call(f), | 70 | feature.call(f), |
46 | classElementView.call(c2), | 71 | classElementView.call(c1), |
47 | featuresView.call(model, f), | 72 | // featuresView.call(model, f), |
48 | classesView.call(model, c1), | 73 | not(assignFeaturePreconditionHelper.call(c2, f)), |
49 | not(assignFeaturePreconditionHelper.call(model, c2, f)), | 74 | not(encapsulatesView.call(c1, f)) |
50 | not(encapsulatesView.call(c2, f)) | ||
51 | ))); | 75 | ))); |
52 | 76 | ||
53 | private static final RelationalQuery deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition", | 77 | private static final RelationalQuery deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition", |
54 | (builder, model, c) -> builder.clause((f) -> List.of( | 78 | (builder, c) -> builder.clause((f) -> List.of( |
55 | classModelView.call(model), | 79 | // classModelView.call(model), |
56 | classElementView.call(c), | 80 | classElementView.call(c), |
57 | featuresView.call(model, f), | 81 | // featuresView.call(model, f), |
58 | not(encapsulatesView.call(c, f)) | 82 | not(encapsulatesView.call(c, f)) |
59 | ))); | 83 | ))); |
60 | 84 | ||
61 | private static final RelationalQuery createClassPreconditionHelper = Query.of("CreateClassPreconditionHelper", | 85 | private static final RelationalQuery createClassPreconditionHelper = Query.of("CreateClassPreconditionHelper", |
62 | (builder, model, f, c) -> builder.clause( | 86 | (builder, f, c) -> builder.clause( |
63 | classElementView.call(c), | 87 | classElementView.call(c), |
64 | classesView.call(model, c), | 88 | // classesView.call(model, c), |
65 | encapsulatesView.call(c, f) | 89 | encapsulatesView.call(c, f) |
66 | )); | 90 | )); |
67 | 91 | ||
68 | private static final RelationalQuery createClassPrecondition = Query.of("CreateClassPrecondition", | 92 | private static final RelationalQuery createClassPrecondition = Query.of("CreateClassPrecondition", |
69 | (builder, model, f) -> builder.clause((c) -> List.of( | 93 | (builder, f) -> builder.clause((c) -> List.of( |
70 | classModelView.call(model), | 94 | // classModelView.call(model), |
71 | featureView.call(f), | 95 | feature.call(f), |
72 | not(createClassPreconditionHelper.call(model, f, c)) | 96 | not(createClassPreconditionHelper.call(f, c)) |
73 | ))); | 97 | ))); |
74 | 98 | ||
75 | private static final RelationalQuery moveFeature = Query.of("MoveFeature", | 99 | private static final RelationalQuery moveFeaturePrecondition = Query.of("MoveFeature", |
76 | (builder, c1, c2, f) -> builder.clause((model) -> List.of( | 100 | (builder, c1, c2, f) -> builder.clause( |
77 | classModelView.call(model), | 101 | // classModelView.call(model), |
78 | classElementView.call(c1), | 102 | classElementView.call(c1), |
79 | classElementView.call(c2), | 103 | classElementView.call(c2), |
80 | featureView.call(f), | 104 | c1.notEquivalent(c2), |
81 | classesView.call(model, c1), | 105 | feature.call(f), |
82 | classesView.call(model, c2), | 106 | // classesView.call(model, c1), |
83 | featuresView.call(model, f), | 107 | // classesView.call(model, c2), |
108 | // featuresView.call(model, f), | ||
84 | encapsulatesView.call(c1, f) | 109 | encapsulatesView.call(c1, f) |
85 | ))); | 110 | )); |
86 | 111 | ||
87 | private static final TransformationRule assignFeatureRule = new TransformationRule("AssignFeature", | 112 | private static final TransformationRule assignFeatureRule = new TransformationRule("AssignFeature", |
88 | assignFeaturePrecondition, | 113 | assignFeaturePrecondition, |
89 | (model) -> { | 114 | (model) -> { |
90 | var isEncapsulatedByInterpretation = model.getInterpretation(isEncapsulatedBy); | 115 | // var isEncapsulatedByInterpretation = model.getInterpretation(isEncapsulatedBy); |
116 | var encapsulatesInterpretation = model.getInterpretation(encapsulates); | ||
91 | return ((Tuple activation) -> { | 117 | return ((Tuple activation) -> { |
92 | var feature = activation.get(0); | 118 | var feature = activation.get(0); |
93 | var classElement = activation.get(1); | 119 | var classElement = activation.get(1); |
94 | 120 | ||
95 | isEncapsulatedByInterpretation.put(Tuple.of(feature, classElement), true); | 121 | // isEncapsulatedByInterpretation.put(Tuple.of(feature, classElement), true); |
122 | encapsulatesInterpretation.put(Tuple.of(classElement, feature), true); | ||
96 | }); | 123 | }); |
97 | }); | 124 | }); |
98 | 125 | ||
99 | private static final TransformationRule deleteEmptyClassRule = new TransformationRule("DeleteEmptyClass", | 126 | private static final TransformationRule deleteEmptyClassRule = new TransformationRule("DeleteEmptyClass", |
100 | deleteEmptyClassPrecondition, | 127 | deleteEmptyClassPrecondition, |
101 | (model) -> { | 128 | (model) -> { |
102 | var classesInterpretation = model.getInterpretation(classes); | 129 | // var classesInterpretation = model.getInterpretation(classes); |
103 | var classElementInterpretation = model.getInterpretation(classElement); | 130 | var classElementInterpretation = model.getInterpretation(classElement); |
104 | var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); | ||
105 | return ((Tuple activation) -> { | 131 | return ((Tuple activation) -> { |
106 | var modelElement = activation.get(0); | 132 | // TODO: can we move dseAdapter outside? |
107 | var classElement = activation.get(1); | 133 | var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); |
134 | // var modelElement = activation.get(0); | ||
135 | var classElement = activation.get(0); | ||
108 | 136 | ||
109 | classesInterpretation.put(Tuple.of(modelElement, classElement), false); | 137 | // classesInterpretation.put(Tuple.of(modelElement, classElement), false); |
110 | classElementInterpretation.put(Tuple.of(classElement), false); | 138 | classElementInterpretation.put(Tuple.of(classElement), false); |
111 | dseAdapter.deleteObject(Tuple.of(classElement)); | 139 | dseAdapter.deleteObject(Tuple.of(classElement)); |
112 | }); | 140 | }); |
@@ -115,21 +143,132 @@ public class CRAExamplesTest { | |||
115 | private static final TransformationRule createClassRule = new TransformationRule("CreateClass", | 143 | private static final TransformationRule createClassRule = new TransformationRule("CreateClass", |
116 | createClassPrecondition, | 144 | createClassPrecondition, |
117 | (model) -> { | 145 | (model) -> { |
118 | var adapter = model.getAdapter(DesignSpaceExplorationAdapter.class); | ||
119 | var classElementInterpretation = model.getInterpretation(classElement); | 146 | var classElementInterpretation = model.getInterpretation(classElement); |
120 | var classesInterpretation = model.getInterpretation(classes); | 147 | // var classesInterpretation = model.getInterpretation(classes); |
121 | var encapsulatesInterpretation = model.getInterpretation(encapsulates); | 148 | var encapsulatesInterpretation = model.getInterpretation(encapsulates); |
122 | var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); | ||
123 | return ((Tuple activation) -> { | 149 | return ((Tuple activation) -> { |
124 | var modelElement = activation.get(0); | 150 | // TODO: can we move dseAdapter outside? |
125 | var feature = activation.get(1); | 151 | var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); |
152 | // var modelElement = activation.get(0); | ||
153 | var feature = activation.get(0); | ||
126 | 154 | ||
127 | var newClassElement = dseAdapter.createObject(); | 155 | var newClassElement = dseAdapter.createObject(); |
128 | var newClassElementId = newClassElement.get(0); | 156 | var newClassElementId = newClassElement.get(0); |
129 | classElementInterpretation.put(newClassElement, true); | 157 | classElementInterpretation.put(newClassElement, true); |
130 | classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true); | 158 | // classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true); |
131 | encapsulatesInterpretation.put(Tuple.of(newClassElementId, feature), true); | 159 | encapsulatesInterpretation.put(Tuple.of(newClassElementId, feature), true); |
132 | }); | 160 | }); |
133 | }); | 161 | }); |
134 | 162 | ||
163 | private static final TransformationRule moveFeatureRule = new TransformationRule("MoveFeature", | ||
164 | moveFeaturePrecondition, | ||
165 | (model) -> { | ||
166 | var encapsulatesInterpretation = model.getInterpretation(encapsulates); | ||
167 | return ((Tuple activation) -> { | ||
168 | var classElement1 = activation.get(0); | ||
169 | var classElement2 = activation.get(1); | ||
170 | var feature = activation.get(2); | ||
171 | |||
172 | encapsulatesInterpretation.put(Tuple.of(classElement1, feature), false); | ||
173 | encapsulatesInterpretation.put(Tuple.of(classElement2, feature), true); | ||
174 | }); | ||
175 | }); | ||
176 | |||
177 | @Test | ||
178 | void craTest() { | ||
179 | var store = ModelStore.builder() | ||
180 | .symbols(classElement, encapsulates, classes, features, attribute, method, dataDependency, | ||
181 | functionalDependency, name) | ||
182 | .with(ViatraModelQueryAdapter.builder() | ||
183 | .queries(feature, assignFeaturePreconditionHelper, assignFeaturePrecondition, | ||
184 | deleteEmptyClassPrecondition, createClassPreconditionHelper, createClassPrecondition, | ||
185 | moveFeaturePrecondition)) | ||
186 | .with(ModelVisualizerAdapter.builder()) | ||
187 | .with(DesignSpaceExplorationAdapter.builder() | ||
188 | .transformations(assignFeatureRule, deleteEmptyClassRule, createClassRule, moveFeatureRule) | ||
189 | // .strategy(new DepthFirstStrategy(3).continueIfHardObjectivesFulfilled() | ||
190 | .strategy(new BestFirstStrategy(6).continueIfHardObjectivesFulfilled() | ||
191 | // .goOnOnlyIfFitnessIsBetter() | ||
192 | )) | ||
193 | .build(); | ||
194 | |||
195 | var model = store.createEmptyModel(); | ||
196 | var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); | ||
197 | // dseAdapter.setRandom(1); | ||
198 | var queryEngine = model.getAdapter(ModelQueryAdapter.class); | ||
199 | |||
200 | // var modelInterpretation = model.getInterpretation(classModel); | ||
201 | var nameInterpretation = model.getInterpretation(name); | ||
202 | var methodInterpretation = model.getInterpretation(method); | ||
203 | var attributeInterpretation = model.getInterpretation(attribute); | ||
204 | var dataDependencyInterpretation = model.getInterpretation(dataDependency); | ||
205 | var functionalDependencyInterpretation = model.getInterpretation(functionalDependency); | ||
206 | |||
207 | // var modelElement = dseAdapter.createObject(); | ||
208 | var method1 = dseAdapter.createObject(); | ||
209 | var method1Id = method1.get(0); | ||
210 | var method2 = dseAdapter.createObject(); | ||
211 | var method2Id = method2.get(0); | ||
212 | var method3 = dseAdapter.createObject(); | ||
213 | var method3Id = method3.get(0); | ||
214 | var method4 = dseAdapter.createObject(); | ||
215 | var method4Id = method4.get(0); | ||
216 | var attribute1 = dseAdapter.createObject(); | ||
217 | var attribute1Id = attribute1.get(0); | ||
218 | var attribute2 = dseAdapter.createObject(); | ||
219 | var attribute2Id = attribute2.get(0); | ||
220 | var attribute3 = dseAdapter.createObject(); | ||
221 | var attribute3Id = attribute3.get(0); | ||
222 | var attribute4 = dseAdapter.createObject(); | ||
223 | var attribute4Id = attribute4.get(0); | ||
224 | var attribute5 = dseAdapter.createObject(); | ||
225 | var attribute5Id = attribute5.get(0); | ||
226 | |||
227 | nameInterpretation.put(method1, "M1"); | ||
228 | nameInterpretation.put(method2, "M2"); | ||
229 | nameInterpretation.put(method3, "M3"); | ||
230 | nameInterpretation.put(method4, "M4"); | ||
231 | nameInterpretation.put(attribute1, "A1"); | ||
232 | nameInterpretation.put(attribute2, "A2"); | ||
233 | nameInterpretation.put(attribute3, "A3"); | ||
234 | nameInterpretation.put(attribute4, "A4"); | ||
235 | nameInterpretation.put(attribute5, "A5"); | ||
236 | |||
237 | |||
238 | |||
239 | // modelInterpretation.put(modelElement, true); | ||
240 | methodInterpretation.put(method1, true); | ||
241 | methodInterpretation.put(method2, true); | ||
242 | methodInterpretation.put(method3, true); | ||
243 | methodInterpretation.put(method4, true); | ||
244 | attributeInterpretation.put(attribute1, true); | ||
245 | attributeInterpretation.put(attribute2, true); | ||
246 | attributeInterpretation.put(attribute3, true); | ||
247 | attributeInterpretation.put(attribute4, true); | ||
248 | attributeInterpretation.put(attribute5, true); | ||
249 | |||
250 | dataDependencyInterpretation.put(Tuple.of(method1Id, attribute1Id), true); | ||
251 | dataDependencyInterpretation.put(Tuple.of(method1Id, attribute3Id), true); | ||
252 | dataDependencyInterpretation.put(Tuple.of(method2Id, attribute2Id), true); | ||
253 | dataDependencyInterpretation.put(Tuple.of(method3Id, attribute3Id), true); | ||
254 | dataDependencyInterpretation.put(Tuple.of(method3Id, attribute4Id), true); | ||
255 | dataDependencyInterpretation.put(Tuple.of(method4Id, attribute3Id), true); | ||
256 | dataDependencyInterpretation.put(Tuple.of(method4Id, attribute5Id), true); | ||
257 | |||
258 | functionalDependencyInterpretation.put(Tuple.of(method1Id, attribute3Id), true); | ||
259 | functionalDependencyInterpretation.put(Tuple.of(method1Id, attribute4Id), true); | ||
260 | functionalDependencyInterpretation.put(Tuple.of(method2Id, attribute1Id), true); | ||
261 | functionalDependencyInterpretation.put(Tuple.of(method3Id, attribute1Id), true); | ||
262 | functionalDependencyInterpretation.put(Tuple.of(method3Id, attribute4Id), true); | ||
263 | functionalDependencyInterpretation.put(Tuple.of(method4Id, attribute2Id), true); | ||
264 | |||
265 | queryEngine.flushChanges(); | ||
266 | |||
267 | var states = dseAdapter.explore(); | ||
268 | System.out.println("states size: " + states.size()); | ||
269 | System.out.println("states: " + states); | ||
270 | var visualizer = model.getAdapter(ModelVisualizerAdapter.class); | ||
271 | visualizer.renderDesignSpace("test_output", FileFormat.SVG); | ||
272 | } | ||
273 | |||
135 | } | 274 | } |