diff options
Diffstat (limited to 'subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java')
-rw-r--r-- | subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java | 274 |
1 files changed, 274 insertions, 0 deletions
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 new file mode 100644 index 00000000..e7cc60d6 --- /dev/null +++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java | |||
@@ -0,0 +1,274 @@ | |||
1 | package tools.refinery.store.dse; | ||
2 | |||
3 | import org.junit.jupiter.api.Test; | ||
4 | import tools.refinery.store.model.ModelStore; | ||
5 | import tools.refinery.store.query.ModelQueryAdapter; | ||
6 | import tools.refinery.store.query.dnf.Query; | ||
7 | import tools.refinery.store.query.dnf.RelationalQuery; | ||
8 | import tools.refinery.store.dse.internal.TransformationRule; | ||
9 | import tools.refinery.store.dse.strategy.BestFirstStrategy; | ||
10 | import tools.refinery.store.dse.strategy.DepthFirstStrategy; | ||
11 | import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; | ||
12 | import tools.refinery.store.query.view.AnySymbolView; | ||
13 | import tools.refinery.store.query.view.KeyOnlyView; | ||
14 | import tools.refinery.store.representation.Symbol; | ||
15 | import tools.refinery.store.tuple.Tuple; | ||
16 | import tools.refinery.visualization.ModelVisualizerAdapter; | ||
17 | import tools.refinery.visualization.internal.FileFormat; | ||
18 | |||
19 | import java.util.List; | ||
20 | |||
21 | import static tools.refinery.store.query.literal.Literals.not; | ||
22 | |||
23 | public class CRAExamplesTest { | ||
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); | ||
27 | private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 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); | ||
31 | |||
32 | // private static final Symbol<Boolean> isEncapsulatedBy = Symbol.of("IsEncapsulatedBy", 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); | ||
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 attributeView = new KeyOnlyView<>(attribute); | ||
44 | private static final AnySymbolView methodView = new KeyOnlyView<>(method); | ||
45 | // private static final AnySymbolView isEncapsulatedByView = new KeyOnlyView<>(isEncapsulatedBy); | ||
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); | ||
49 | private static final AnySymbolView featuresView = new KeyOnlyView<>(features); | ||
50 | private static final AnySymbolView classesView = new KeyOnlyView<>(classes); | ||
51 | |||
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 | |||
60 | private static final RelationalQuery assignFeaturePreconditionHelper = Query.of("AssignFeaturePreconditionHelper", | ||
61 | (builder, c, f) -> builder.clause( | ||
62 | classElementView.call(c), | ||
63 | // classesView.call(model, c), | ||
64 | encapsulatesView.call(c, f) | ||
65 | )); | ||
66 | |||
67 | private static final RelationalQuery assignFeaturePrecondition = Query.of("AssignFeaturePrecondition", | ||
68 | (builder, f, c1) -> builder.clause((c2) -> List.of( | ||
69 | // classModelView.call(model), | ||
70 | feature.call(f), | ||
71 | classElementView.call(c1), | ||
72 | // featuresView.call(model, f), | ||
73 | not(assignFeaturePreconditionHelper.call(c2, f)), | ||
74 | not(encapsulatesView.call(c1, f)) | ||
75 | ))); | ||
76 | |||
77 | private static final RelationalQuery deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition", | ||
78 | (builder, c) -> builder.clause((f) -> List.of( | ||
79 | // classModelView.call(model), | ||
80 | classElementView.call(c), | ||
81 | // featuresView.call(model, f), | ||
82 | not(encapsulatesView.call(c, f)) | ||
83 | ))); | ||
84 | |||
85 | private static final RelationalQuery createClassPreconditionHelper = Query.of("CreateClassPreconditionHelper", | ||
86 | (builder, f, c) -> builder.clause( | ||
87 | classElementView.call(c), | ||
88 | // classesView.call(model, c), | ||
89 | encapsulatesView.call(c, f) | ||
90 | )); | ||
91 | |||
92 | private static final RelationalQuery createClassPrecondition = Query.of("CreateClassPrecondition", | ||
93 | (builder, f) -> builder.clause((c) -> List.of( | ||
94 | // classModelView.call(model), | ||
95 | feature.call(f), | ||
96 | not(createClassPreconditionHelper.call(f, c)) | ||
97 | ))); | ||
98 | |||
99 | private static final RelationalQuery moveFeaturePrecondition = Query.of("MoveFeature", | ||
100 | (builder, c1, c2, f) -> builder.clause( | ||
101 | // classModelView.call(model), | ||
102 | classElementView.call(c1), | ||
103 | classElementView.call(c2), | ||
104 | c1.notEquivalent(c2), | ||
105 | feature.call(f), | ||
106 | // classesView.call(model, c1), | ||
107 | // classesView.call(model, c2), | ||
108 | // featuresView.call(model, f), | ||
109 | encapsulatesView.call(c1, f) | ||
110 | )); | ||
111 | |||
112 | private static final TransformationRule assignFeatureRule = new TransformationRule("AssignFeature", | ||
113 | assignFeaturePrecondition, | ||
114 | (model) -> { | ||
115 | // var isEncapsulatedByInterpretation = model.getInterpretation(isEncapsulatedBy); | ||
116 | var encapsulatesInterpretation = model.getInterpretation(encapsulates); | ||
117 | return ((Tuple activation) -> { | ||
118 | var feature = activation.get(0); | ||
119 | var classElement = activation.get(1); | ||
120 | |||
121 | // isEncapsulatedByInterpretation.put(Tuple.of(feature, classElement), true); | ||
122 | encapsulatesInterpretation.put(Tuple.of(classElement, feature), true); | ||
123 | }); | ||
124 | }); | ||
125 | |||
126 | private static final TransformationRule deleteEmptyClassRule = new TransformationRule("DeleteEmptyClass", | ||
127 | deleteEmptyClassPrecondition, | ||
128 | (model) -> { | ||
129 | // var classesInterpretation = model.getInterpretation(classes); | ||
130 | var classElementInterpretation = model.getInterpretation(classElement); | ||
131 | return ((Tuple activation) -> { | ||
132 | // TODO: can we move dseAdapter outside? | ||
133 | var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); | ||
134 | // var modelElement = activation.get(0); | ||
135 | var classElement = activation.get(0); | ||
136 | |||
137 | // classesInterpretation.put(Tuple.of(modelElement, classElement), false); | ||
138 | classElementInterpretation.put(Tuple.of(classElement), false); | ||
139 | dseAdapter.deleteObject(Tuple.of(classElement)); | ||
140 | }); | ||
141 | }); | ||
142 | |||
143 | private static final TransformationRule createClassRule = new TransformationRule("CreateClass", | ||
144 | createClassPrecondition, | ||
145 | (model) -> { | ||
146 | var classElementInterpretation = model.getInterpretation(classElement); | ||
147 | // var classesInterpretation = model.getInterpretation(classes); | ||
148 | var encapsulatesInterpretation = model.getInterpretation(encapsulates); | ||
149 | return ((Tuple activation) -> { | ||
150 | // TODO: can we move dseAdapter outside? | ||
151 | var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); | ||
152 | // var modelElement = activation.get(0); | ||
153 | var feature = activation.get(0); | ||
154 | |||
155 | var newClassElement = dseAdapter.createObject(); | ||
156 | var newClassElementId = newClassElement.get(0); | ||
157 | classElementInterpretation.put(newClassElement, true); | ||
158 | // classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true); | ||
159 | encapsulatesInterpretation.put(Tuple.of(newClassElementId, feature), true); | ||
160 | }); | ||
161 | }); | ||
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 | |||
274 | } | ||