aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects
diff options
context:
space:
mode:
authorLibravatar nagilooh <ficsorattila96@gmail.com>2023-08-01 12:41:45 +0200
committerLibravatar nagilooh <ficsorattila96@gmail.com>2023-08-02 12:10:20 +0200
commit00c8fcf947d3f5c375d49a907bcefa5d8e1dd8ea (patch)
tree6d0fd3a59d5c46e8337d1b0aab3521842da5a3cb /subprojects
parentAdd trivial test cases for DSE Strategies (diff)
downloadrefinery-00c8fcf947d3f5c375d49a907bcefa5d8e1dd8ea.tar.gz
refinery-00c8fcf947d3f5c375d49a907bcefa5d8e1dd8ea.tar.zst
refinery-00c8fcf947d3f5c375d49a907bcefa5d8e1dd8ea.zip
Update visualization
- Replace guru.nidi:graphviz-java with DOT based solution - Draws the design space as well as the model states - Design space nodes link to visualization of the sate
Diffstat (limited to 'subprojects')
-rw-r--r--subprojects/store-query-viatra/build.gradle.kts1
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/dse/internal/DesignSpaceExplorationAdapterImpl.java21
-rw-r--r--subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/dse/DebugTest.java15
-rw-r--r--subprojects/visualization/build.gradle.kts1
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java23
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java120
6 files changed, 109 insertions, 72 deletions
diff --git a/subprojects/store-query-viatra/build.gradle.kts b/subprojects/store-query-viatra/build.gradle.kts
index 1f804247..ef73e10a 100644
--- a/subprojects/store-query-viatra/build.gradle.kts
+++ b/subprojects/store-query-viatra/build.gradle.kts
@@ -10,7 +10,6 @@ plugins {
10 10
11dependencies { 11dependencies {
12 implementation(libs.ecore) 12 implementation(libs.ecore)
13 implementation ("guru.nidi:graphviz-java:0.18.1")
14 api(libs.viatra) 13 api(libs.viatra)
15 api(project(":refinery-store-query")) 14 api(project(":refinery-store-query"))
16 api(project(":refinery-store-reasoning")) 15 api(project(":refinery-store-reasoning"))
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/dse/internal/DesignSpaceExplorationAdapterImpl.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/dse/internal/DesignSpaceExplorationAdapterImpl.java
index c4c51e79..0fcc719d 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/dse/internal/DesignSpaceExplorationAdapterImpl.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/dse/internal/DesignSpaceExplorationAdapterImpl.java
@@ -15,6 +15,7 @@ import tools.refinery.store.query.resultset.ResultSet;
15import tools.refinery.store.representation.Symbol; 15import tools.refinery.store.representation.Symbol;
16import tools.refinery.store.tuple.Tuple; 16import tools.refinery.store.tuple.Tuple;
17import tools.refinery.store.tuple.Tuple1; 17import tools.refinery.store.tuple.Tuple1;
18import tools.refinery.visualization.ModelVisualizerAdapter;
18 19
19import java.util.*; 20import java.util.*;
20 21
@@ -40,6 +41,8 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration
40 private Random random = new Random(); 41 private Random random = new Random();
41 private Objective[][] leveledObjectives; 42 private Objective[][] leveledObjectives;
42 private boolean isNewState = false; 43 private boolean isNewState = false;
44 private final boolean isVisualizationEnabled;
45 private final ModelVisualizerAdapter modelVisualizerAdapter;
43 46
44 public List<Long> getTrajectory() { 47 public List<Long> getTrajectory() {
45 return new LinkedList<>(trajectory); 48 return new LinkedList<>(trajectory);
@@ -66,6 +69,8 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration
66 statesAndUntraversedActivations = new HashMap<>(); 69 statesAndUntraversedActivations = new HashMap<>();
67 statesAndTraversedActivations = new HashMap<>(); 70 statesAndTraversedActivations = new HashMap<>();
68 strategy = storeAdapter.getStrategy(); 71 strategy = storeAdapter.getStrategy();
72 modelVisualizerAdapter = model.tryGetAdapter(ModelVisualizerAdapter.class).orElse(null);
73 isVisualizationEnabled = modelVisualizerAdapter != null;
69 74
70 } 75 }
71 76
@@ -129,6 +134,10 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration
129 if (trajectory.size() < 2) { 134 if (trajectory.size() < 2) {
130 return false; 135 return false;
131 } 136 }
137 if (isVisualizationEnabled) {
138 modelVisualizerAdapter.addTransition(trajectory.get(trajectory.size() - 1),
139 trajectory.get(trajectory.size() - 2), "backtrack");
140 }
132 model.restore(trajectory.get(trajectory.size() - 2)); 141 model.restore(trajectory.get(trajectory.size() - 2));
133 trajectory.remove(trajectory.size() - 1); 142 trajectory.remove(trajectory.size() - 1);
134 return true; 143 return true;
@@ -137,6 +146,10 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration
137 @Override 146 @Override
138 public void restoreTrajectory(List<Long> trajectory) { 147 public void restoreTrajectory(List<Long> trajectory) {
139 model.restore(trajectory.get(trajectory.size() - 1)); 148 model.restore(trajectory.get(trajectory.size() - 1));
149// if (isVisualizationEnabled) {
150// modelVisualizerAdapter.addTransition(this.trajectory.get(trajectory.size() - 1),
151// trajectory.get(trajectory.size() - 1), "restore");
152// }
140 this.trajectory = trajectory; 153 this.trajectory = trajectory;
141 154
142 } 155 }
@@ -173,6 +186,9 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration
173 public void newSolution() { 186 public void newSolution() {
174 var state = model.getState(); 187 var state = model.getState();
175 solutions.add(state); 188 solutions.add(state);
189 if (isVisualizationEnabled) {
190 modelVisualizerAdapter.addSolution(state);
191 }
176 } 192 }
177 193
178 @Override 194 @Override
@@ -212,6 +228,11 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration
212 isNewState = !statesAndUntraversedActivations.containsKey(newState); 228 isNewState = !statesAndUntraversedActivations.containsKey(newState);
213 statesAndUntraversedActivations.put(newState, getAllActivations()); 229 statesAndUntraversedActivations.put(newState, getAllActivations());
214 statesAndTraversedActivations.put(newState, new HashSet<>()); 230 statesAndTraversedActivations.put(newState, new HashSet<>());
231 if (isVisualizationEnabled) {
232 modelVisualizerAdapter.addTransition(trajectory.get(trajectory.size() - 2),
233 trajectory.get(trajectory.size() - 1), activation.transformationRule().getName(),
234 activation.activation());
235 }
215 return true; 236 return true;
216 } 237 }
217 238
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/dse/DebugTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/dse/DebugTest.java
index 969afbcb..821be7e6 100644
--- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/dse/DebugTest.java
+++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/dse/DebugTest.java
@@ -5,6 +5,7 @@ import tools.refinery.store.model.ModelStore;
5import tools.refinery.store.query.ModelQueryAdapter; 5import tools.refinery.store.query.ModelQueryAdapter;
6import tools.refinery.store.query.dnf.Query; 6import tools.refinery.store.query.dnf.Query;
7import tools.refinery.store.query.dse.internal.TransformationRule; 7import tools.refinery.store.query.dse.internal.TransformationRule;
8import tools.refinery.store.query.dse.strategy.BestFirstStrategy;
8import tools.refinery.store.query.dse.strategy.DepthFirstStrategy; 9import tools.refinery.store.query.dse.strategy.DepthFirstStrategy;
9import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; 10import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
10import tools.refinery.store.query.view.AnySymbolView; 11import tools.refinery.store.query.view.AnySymbolView;
@@ -12,6 +13,7 @@ import tools.refinery.store.query.view.KeyOnlyView;
12import tools.refinery.store.representation.Symbol; 13import tools.refinery.store.representation.Symbol;
13import tools.refinery.store.tuple.Tuple; 14import tools.refinery.store.tuple.Tuple;
14import tools.refinery.visualization.ModelVisualizerAdapter; 15import tools.refinery.visualization.ModelVisualizerAdapter;
16import tools.refinery.visualization.internal.FileFormat;
15 17
16public class DebugTest { 18public class DebugTest {
17 private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1); 19 private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1);
@@ -83,30 +85,31 @@ public class DebugTest {
83 .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features) 85 .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features)
84 .with(ViatraModelQueryAdapter.builder() 86 .with(ViatraModelQueryAdapter.builder()
85 .queries(createClassPrecondition, createFeaturePrecondition)) 87 .queries(createClassPrecondition, createFeaturePrecondition))
88 .with(ModelVisualizerAdapter.builder())
86 .with(DesignSpaceExplorationAdapter.builder() 89 .with(DesignSpaceExplorationAdapter.builder()
87 .transformations(createClassRule, createFeatureRule) 90 .transformations(createClassRule, createFeatureRule)
88 .strategy(new DepthFirstStrategy(4).continueIfHardObjectivesFulfilled() 91 .strategy(new DepthFirstStrategy(4).continueIfHardObjectivesFulfilled()
89// .strategy(new BestFirstStrategy(4).continueIfHardObjectivesFulfilled() 92// .strategy(new BestFirstStrategy(4).continueIfHardObjectivesFulfilled()
90// .goOnOnlyIfFitnessIsBetter() 93// .goOnOnlyIfFitnessIsBetter()
91 )) 94 ))
92 .with(ModelVisualizerAdapter.builder())
93 .build(); 95 .build();
94 96
95 var model = store.createEmptyModel(); 97 var model = store.createEmptyModel();
96 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); 98 var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
99// dseAdapter.setRandom(1);
97 var queryEngine = model.getAdapter(ModelQueryAdapter.class); 100 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
98 101
99 var modelElementInterpretation = model.getInterpretation(classModel); 102 var modelElementInterpretation = model.getInterpretation(classModel);
100 modelElementInterpretation.put(dseAdapter.createObject(), true); 103 var classElementInterpretation = model.getInterpretation(classElement);
104 var modelElement = dseAdapter.createObject();
105 modelElementInterpretation.put(modelElement, true);
106 classElementInterpretation.put(modelElement, true);
101 queryEngine.flushChanges(); 107 queryEngine.flushChanges();
102 108
103 109
104 var states = dseAdapter.explore(); 110 var states = dseAdapter.explore();
105 var visualizer = model.getAdapter(ModelVisualizerAdapter.class); 111 var visualizer = model.getAdapter(ModelVisualizerAdapter.class);
106 for (var state : states) { 112 visualizer.renderDesignSpace("test_output", FileFormat.SVG);
107 var visualization = visualizer.createVisualizationForModelState(state);
108 visualizer.saveVisualization(visualization, "test_output" + state.hashCode() + ".png");
109 }
110 System.out.println("states size: " + states.size()); 113 System.out.println("states size: " + states.size());
111 System.out.println("states: " + states); 114 System.out.println("states: " + states);
112 115
diff --git a/subprojects/visualization/build.gradle.kts b/subprojects/visualization/build.gradle.kts
index 97b1688a..abad0491 100644
--- a/subprojects/visualization/build.gradle.kts
+++ b/subprojects/visualization/build.gradle.kts
@@ -9,6 +9,5 @@ plugins {
9} 9}
10 10
11dependencies { 11dependencies {
12 implementation ("guru.nidi:graphviz-java:0.18.1")
13 api(project(":refinery-store-query")) 12 api(project(":refinery-store-query"))
14} 13}
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java
index 42f01242..2f71d4f3 100644
--- a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java
@@ -1,8 +1,7 @@
1package tools.refinery.visualization; 1package tools.refinery.visualization;
2 2
3import guru.nidi.graphviz.engine.Format;
4import guru.nidi.graphviz.model.MutableGraph;
5import tools.refinery.store.adapter.ModelAdapter; 3import tools.refinery.store.adapter.ModelAdapter;
4import tools.refinery.store.tuple.Tuple;
6import tools.refinery.visualization.internal.FileFormat; 5import tools.refinery.visualization.internal.FileFormat;
7import tools.refinery.visualization.internal.ModelVisualizerBuilderImpl; 6import tools.refinery.visualization.internal.ModelVisualizerBuilderImpl;
8 7
@@ -13,21 +12,25 @@ public interface ModelVisualizerAdapter extends ModelAdapter {
13 return new ModelVisualizerBuilderImpl(); 12 return new ModelVisualizerBuilderImpl();
14 } 13 }
15 14
16 public MutableGraph createVisualizationForCurrentModelState();
17
18 public MutableGraph createVisualizationForModelState(Long version);
19
20 public String createDotForCurrentModelState(); 15 public String createDotForCurrentModelState();
21 16
22 public String createDotForModelState(Long version); 17 public String createDotForModelState(Long version);
23 18
24 public boolean saveVisualization(MutableGraph graph, String path);
25
26 public boolean saveVisualization(MutableGraph graph, Format format, String path);
27
28 public boolean saveDot(String dot, String filePath); 19 public boolean saveDot(String dot, String filePath);
29 20
30 public boolean renderDot(String dot, String filePath); 21 public boolean renderDot(String dot, String filePath);
31 22
32 public boolean renderDot(String dot, FileFormat format, String filePath); 23 public boolean renderDot(String dot, FileFormat format, String filePath);
24
25 public void addTransition(Long from, Long to, String action);
26
27
28 public void addTransition(Long from, Long to, String action, Tuple activation);
29 public void addSolution(Long state);
30
31 public boolean saveDesignSpace(String path);
32
33 public boolean renderDesignSpace(String path);
34
35 public boolean renderDesignSpace(String path, FileFormat format);
33} 36}
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java
index 7456d913..9a284e24 100644
--- a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java
@@ -1,14 +1,9 @@
1package tools.refinery.visualization.internal; 1package tools.refinery.visualization.internal;
2 2
3import guru.nidi.graphviz.attribute.GraphAttr;
4import guru.nidi.graphviz.attribute.Label;
5import guru.nidi.graphviz.engine.Format;
6import guru.nidi.graphviz.engine.Graphviz;
7import guru.nidi.graphviz.model.MutableGraph;
8import tools.refinery.store.model.Interpretation; 3import tools.refinery.store.model.Interpretation;
9import tools.refinery.store.model.Model; 4import tools.refinery.store.model.Model;
10import tools.refinery.store.representation.AnySymbol; 5import tools.refinery.store.representation.AnySymbol;
11import tools.refinery.store.representation.TruthValue; 6import tools.refinery.store.tuple.Tuple;
12import tools.refinery.visualization.ModelVisualizerAdapter; 7import tools.refinery.visualization.ModelVisualizerAdapter;
13import tools.refinery.visualization.ModelVisualizerStoreAdapter; 8import tools.refinery.visualization.ModelVisualizerStoreAdapter;
14 9
@@ -16,12 +11,13 @@ import java.io.*;
16import java.util.HashMap; 11import java.util.HashMap;
17import java.util.Map; 12import java.util.Map;
18 13
19import static guru.nidi.graphviz.model.Factory.*;
20
21public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { 14public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
22 private final Model model; 15 private final Model model;
23 private final ModelVisualizerStoreAdapter storeAdapter; 16 private final ModelVisualizerStoreAdapter storeAdapter;
24 private final Map<AnySymbol, Interpretation<?>> interpretations; 17 private final Map<AnySymbol, Interpretation<?>> interpretations;
18 private final StringBuilder designSpaceBuilder = new StringBuilder();
19 private int transitionCounter = 0;
20
25 public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) { 21 public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) {
26 this.model = model; 22 this.model = model;
27 this.storeAdapter = storeAdapter; 23 this.storeAdapter = storeAdapter;
@@ -46,6 +42,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
46 } 42 }
47 interpretations.put(symbol, castInterpretation); 43 interpretations.put(symbol, castInterpretation);
48 } 44 }
45 designSpaceBuilder.append("digraph designSpace {\n");
49 } 46 }
50 47
51 @Override 48 @Override
@@ -59,36 +56,6 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
59 } 56 }
60 57
61 @Override 58 @Override
62 public MutableGraph createVisualizationForCurrentModelState() {
63 var graph = mutGraph("model").setDirected(true).graphAttrs().add(GraphAttr.dpi(100));
64 for (var entry : interpretations.entrySet()) {
65 var key = entry.getKey();
66 var arity = key.arity();
67 var cursor = entry.getValue().getAll();
68 while (cursor.move()) {
69 if (arity == 1) {
70 var id = cursor.getKey().get(0);
71 graph.add(mutNode(String.valueOf(id)).add("label", key.name() + ": " + id));
72 } else {
73 var from = cursor.getKey().get(0);
74 var to = cursor.getKey().get(1);
75 graph.add(mutNode(String.valueOf(from)).addLink(to(mutNode(String.valueOf(to))).with(Label.of(key.name()))));
76 }
77 }
78 }
79 return graph;
80 }
81
82 @Override
83 public MutableGraph createVisualizationForModelState(Long version) {
84 var currentVersion = model.getState();
85 model.restore(version);
86 var graph = createVisualizationForCurrentModelState();
87 model.restore(currentVersion);
88 return graph;
89 }
90
91 @Override
92 public String createDotForCurrentModelState() { 59 public String createDotForCurrentModelState() {
93 var sb = new StringBuilder(); 60 var sb = new StringBuilder();
94 sb.append("digraph model {\n"); 61 sb.append("digraph model {\n");
@@ -123,22 +90,6 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
123 } 90 }
124 91
125 @Override 92 @Override
126 public boolean saveVisualization(MutableGraph graph, String path) {
127 return saveVisualization(graph, Format.PNG, path);
128 }
129
130 @Override
131 public boolean saveVisualization(MutableGraph graph, Format format, String path) {
132 try {
133 Graphviz.fromGraph(graph).render(format).toFile(new File(path));
134 return true;
135 } catch (IOException e) {
136 e.printStackTrace();
137 return false;
138 }
139 }
140
141 @Override
142 public boolean saveDot(String dot, String filePath) { 93 public boolean saveDot(String dot, String filePath) {
143 File file = new File(filePath); 94 File file = new File(filePath);
144 file.getParentFile().mkdirs(); 95 file.getParentFile().mkdirs();
@@ -172,4 +123,65 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
172 } 123 }
173 return true; 124 return true;
174 } 125 }
126
127 @Override
128 public void addTransition(Long from, Long to, String action) {
129 designSpaceBuilder.append(from).append(" -> ").append(to).append(" [label=\"").append(transitionCounter++)
130 .append(": ").append(action).append("\"]\n");
131
132 }
133
134 @Override
135 public void addTransition(Long from, Long to, String action, Tuple activation) {
136 designSpaceBuilder.append(from).append(" -> ").append(to).append(" [label=\"").append(transitionCounter++)
137 .append(": ").append(action).append(" / ");
138
139
140 for (int i = 0; i < activation.getSize(); i++) {
141 designSpaceBuilder.append(activation.get(i));
142 if (i < activation.getSize() - 1) {
143 designSpaceBuilder.append(", ");
144 }
145 }
146 designSpaceBuilder.append("\"]\n");
147 }
148
149 @Override
150 public void addSolution(Long state) {
151 designSpaceBuilder.append(state).append(" [shape = doublecircle]\n");
152 }
153
154 private String buildDesignSpaceDot() {
155 for (var state : storeAdapter.getStore().getStates()) {
156 designSpaceBuilder.append(state).append(" [URL=\"./").append(state).append(".svg\"]\n");
157 }
158 designSpaceBuilder.append("}");
159 return designSpaceBuilder.toString();
160 }
161
162 @Override
163 public boolean saveDesignSpace(String path) {
164 saveDot(buildDesignSpaceDot(), path + "/designSpace.dot");
165 for (var state : storeAdapter.getStore().getStates()) {
166 saveDot(createDotForModelState(state), path + "/" + state + ".dot");
167 }
168 return true;
169 }
170
171 @Override
172 public boolean renderDesignSpace(String path) {
173 return renderDesignSpace(path, FileFormat.SVG);
174 }
175
176 @Override
177 public boolean renderDesignSpace(String path, FileFormat format) {
178 for (var state : storeAdapter.getStore().getStates()) {
179 var stateDot = createDotForModelState(state);
180 saveDot(stateDot, path + "/" + state + ".dot");
181 renderDot(stateDot, path + "/" + state + "." + format.getFormat());
182 }
183 var designSpaceDot = buildDesignSpaceDot();
184 saveDot(designSpaceDot, path + "/designSpace.dot");
185 return renderDot(designSpaceDot, format, path + "/designSpace." + format.getFormat());
186 }
175} 187}