From dd2d8a1517f3f198fe005ebf91a4f8e912609c1b Mon Sep 17 00:00:00 2001 From: nagilooh Date: Tue, 25 Jul 2023 17:17:17 +0200 Subject: Add visualization adapter Uses Graphviz to create a visualization of the models and can save them to disk as an image or various textual representations --- subprojects/visualization/build.gradle.kts | 14 ++++ .../visualization/ModelVisualizerAdapter.java | 22 ++++++ .../visualization/ModelVisualizerBuilder.java | 6 ++ .../visualization/ModelVisualizerStoreAdapter.java | 7 ++ .../internal/ModelVisualizeStoreAdapterImpl.java | 24 ++++++ .../internal/ModelVisualizerAdapterImpl.java | 88 ++++++++++++++++++++++ .../internal/ModelVisualizerBuilderImpl.java | 14 ++++ 7 files changed, 175 insertions(+) create mode 100644 subprojects/visualization/build.gradle.kts create mode 100644 subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java create mode 100644 subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java create mode 100644 subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java create mode 100644 subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java create mode 100644 subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java create mode 100644 subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java (limited to 'subprojects/visualization') diff --git a/subprojects/visualization/build.gradle.kts b/subprojects/visualization/build.gradle.kts new file mode 100644 index 00000000..97b1688a --- /dev/null +++ b/subprojects/visualization/build.gradle.kts @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ + +plugins { + id("tools.refinery.gradle.java-library") +} + +dependencies { + implementation ("guru.nidi:graphviz-java:0.18.1") + api(project(":refinery-store-query")) +} diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java new file mode 100644 index 00000000..ae23e3bc --- /dev/null +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java @@ -0,0 +1,22 @@ +package tools.refinery.visualization; + +import guru.nidi.graphviz.engine.Format; +import guru.nidi.graphviz.model.MutableGraph; +import tools.refinery.store.adapter.ModelAdapter; +import tools.refinery.visualization.internal.ModelVisualizerBuilderImpl; + +public interface ModelVisualizerAdapter extends ModelAdapter { + + ModelVisualizerStoreAdapter getStoreAdapter(); + static ModelVisualizerBuilder builder() { + return new ModelVisualizerBuilderImpl(); + } + + public MutableGraph createVisualizationForCurrentModelState(); + + public MutableGraph createVisualizationForModelState(Long version); + + public boolean saveVisualization(MutableGraph graph, String path); + + public boolean saveVisualization(MutableGraph graph, Format format, String path); +} diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java new file mode 100644 index 00000000..9c1bd0e0 --- /dev/null +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java @@ -0,0 +1,6 @@ +package tools.refinery.visualization; + +import tools.refinery.store.adapter.ModelAdapterBuilder; + +public interface ModelVisualizerBuilder extends ModelAdapterBuilder { +} diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java new file mode 100644 index 00000000..764de6d4 --- /dev/null +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java @@ -0,0 +1,7 @@ +package tools.refinery.visualization; + +import tools.refinery.store.adapter.ModelStoreAdapter; +import tools.refinery.store.query.ModelQueryStoreAdapter; + +public interface ModelVisualizerStoreAdapter extends ModelStoreAdapter { +} diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java new file mode 100644 index 00000000..6e158c28 --- /dev/null +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java @@ -0,0 +1,24 @@ +package tools.refinery.visualization.internal; + +import tools.refinery.store.adapter.ModelAdapter; +import tools.refinery.store.model.Model; +import tools.refinery.store.model.ModelStore; +import tools.refinery.visualization.ModelVisualizerStoreAdapter; + +public class ModelVisualizeStoreAdapterImpl implements ModelVisualizerStoreAdapter { + private final ModelStore store; + + public ModelVisualizeStoreAdapterImpl(ModelStore store) { + this.store = store; + } + + @Override + public ModelStore getStore() { + return store; + } + + @Override + public ModelAdapter createModelAdapter(Model model) { + return new ModelVisualizerAdapterImpl(model, this); + } +} 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 new file mode 100644 index 00000000..475ae416 --- /dev/null +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java @@ -0,0 +1,88 @@ +package tools.refinery.visualization.internal; + +import guru.nidi.graphviz.attribute.Label; +import guru.nidi.graphviz.engine.Format; +import guru.nidi.graphviz.engine.Graphviz; +import guru.nidi.graphviz.model.MutableGraph; +import tools.refinery.store.model.Model; +import tools.refinery.visualization.ModelVisualizerAdapter; +import tools.refinery.visualization.ModelVisualizerStoreAdapter; + +import java.io.File; +import java.io.IOException; + +import static guru.nidi.graphviz.model.Factory.*; + +public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { + private final Model model; + private final ModelVisualizerStoreAdapter storeAdapter; + public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) { + this.model = model; + this.storeAdapter = storeAdapter; + } + + @Override + public Model getModel() { + return model; + } + + @Override + public ModelVisualizerStoreAdapter getStoreAdapter() { + return storeAdapter; + } + + @Override + public MutableGraph createVisualizationForCurrentModelState() { + var interpretations = model.getInterpretations(); + MutableGraph graph = mutGraph("model").setDirected(true); + for (var entry : interpretations.entrySet()) { + var key = entry.getKey(); + var arity = key.arity(); + if (arity < 1 || arity > 2) { + continue; + } + var valueType = key.valueType(); + // TODO: support TruthValue + if (valueType != Boolean.class) { + continue; + } + var cursor = entry.getValue().getAll(); + while (cursor.move()) { + if (arity == 1) { + var id = cursor.getKey().get(0); + graph.add(mutNode(String.valueOf(id)).add("label", key.name() + ": " + id)); + } else { + var from = cursor.getKey().get(0); + var to = cursor.getKey().get(1); + graph.add(mutNode(String.valueOf(from)).addLink(to(mutNode(String.valueOf(to))).with(Label.of(key.name())))); + } + } + } + return graph; + } + + @Override + public MutableGraph createVisualizationForModelState(Long version) { + var currentVersion = model.getState(); + model.restore(version); + MutableGraph graph = createVisualizationForCurrentModelState(); + model.restore(currentVersion); + return graph; + } + + @Override + public boolean saveVisualization(MutableGraph graph, String path) { + return saveVisualization(graph, Format.PNG, path); + } + + @Override + public boolean saveVisualization(MutableGraph graph, Format format, String path) { + try { + Graphviz.fromGraph(graph).render(format).toFile(new File(path)); + return true; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } +} diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java new file mode 100644 index 00000000..4148c24a --- /dev/null +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java @@ -0,0 +1,14 @@ +package tools.refinery.visualization.internal; + +import tools.refinery.store.adapter.AbstractModelAdapterBuilder; +import tools.refinery.store.model.ModelStore; +import tools.refinery.visualization.ModelVisualizerBuilder; + +public class ModelVisualizerBuilderImpl + extends AbstractModelAdapterBuilder + implements ModelVisualizerBuilder { + @Override + protected ModelVisualizeStoreAdapterImpl doBuild(ModelStore store) { + return new ModelVisualizeStoreAdapterImpl(store); + } +} -- cgit v1.2.3-70-g09d2 From 68aa56964c736c2fc4fa4dcdae1af4d4db94bf7d Mon Sep 17 00:00:00 2001 From: nagilooh Date: Thu, 27 Jul 2023 12:12:26 +0200 Subject: Add visualization using DOT language --- .../visualization/ModelVisualizerAdapter.java | 11 ++ .../visualization/internal/FileFormat.java | 21 ++++ .../internal/ModelVisualizerAdapterImpl.java | 113 ++++++++++++++++++--- 3 files changed, 132 insertions(+), 13 deletions(-) create mode 100644 subprojects/visualization/src/main/java/tools/refinery/visualization/internal/FileFormat.java (limited to 'subprojects/visualization') 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 ae23e3bc..42f01242 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java @@ -3,6 +3,7 @@ package tools.refinery.visualization; import guru.nidi.graphviz.engine.Format; import guru.nidi.graphviz.model.MutableGraph; import tools.refinery.store.adapter.ModelAdapter; +import tools.refinery.visualization.internal.FileFormat; import tools.refinery.visualization.internal.ModelVisualizerBuilderImpl; public interface ModelVisualizerAdapter extends ModelAdapter { @@ -16,7 +17,17 @@ public interface ModelVisualizerAdapter extends ModelAdapter { public MutableGraph createVisualizationForModelState(Long version); + public String createDotForCurrentModelState(); + + public String createDotForModelState(Long version); + public boolean saveVisualization(MutableGraph graph, String path); public boolean saveVisualization(MutableGraph graph, Format format, String path); + + public boolean saveDot(String dot, String filePath); + + public boolean renderDot(String dot, String filePath); + + public boolean renderDot(String dot, FileFormat format, String filePath); } diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/FileFormat.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/FileFormat.java new file mode 100644 index 00000000..43d6eb3f --- /dev/null +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/FileFormat.java @@ -0,0 +1,21 @@ +package tools.refinery.visualization.internal; + +public enum FileFormat { + BMP("bmp"), + DOT("dot"), + JPEG("jpg"), + PDF("pdf"), + PLAIN("plain"), + PNG("png"), + SVG("svg"); + + private final String format; + + FileFormat(String format) { + this.format = format; + } + + public String getFormat() { + return format; + } +} 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 475ae416..7456d913 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,24 +1,51 @@ package tools.refinery.visualization.internal; +import guru.nidi.graphviz.attribute.GraphAttr; import guru.nidi.graphviz.attribute.Label; import guru.nidi.graphviz.engine.Format; import guru.nidi.graphviz.engine.Graphviz; import guru.nidi.graphviz.model.MutableGraph; +import tools.refinery.store.model.Interpretation; import tools.refinery.store.model.Model; +import tools.refinery.store.representation.AnySymbol; +import tools.refinery.store.representation.TruthValue; import tools.refinery.visualization.ModelVisualizerAdapter; import tools.refinery.visualization.ModelVisualizerStoreAdapter; -import java.io.File; -import java.io.IOException; +import java.io.*; +import java.util.HashMap; +import java.util.Map; import static guru.nidi.graphviz.model.Factory.*; public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { private final Model model; private final ModelVisualizerStoreAdapter storeAdapter; + private final Map> interpretations; public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) { this.model = model; this.storeAdapter = storeAdapter; + this.interpretations = new HashMap<>(); + for (var symbol : storeAdapter.getStore().getSymbols()) { + var arity = symbol.arity(); + if (arity < 1 || arity > 2) { + continue; + } + var interpretation = model.getInterpretation(symbol); + var valueType = symbol.valueType(); + Interpretation castInterpretation; + if (valueType == Boolean.class) { + castInterpretation = (Interpretation) interpretation; + } + // TODO: support TruthValue +// else if (valueType == TruthValue.class) { +// castInterpretation = (Interpretation) interpretation; +// } + else { + continue; + } + interpretations.put(symbol, castInterpretation); + } } @Override @@ -33,19 +60,10 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { @Override public MutableGraph createVisualizationForCurrentModelState() { - var interpretations = model.getInterpretations(); - MutableGraph graph = mutGraph("model").setDirected(true); + var graph = mutGraph("model").setDirected(true).graphAttrs().add(GraphAttr.dpi(100)); for (var entry : interpretations.entrySet()) { var key = entry.getKey(); var arity = key.arity(); - if (arity < 1 || arity > 2) { - continue; - } - var valueType = key.valueType(); - // TODO: support TruthValue - if (valueType != Boolean.class) { - continue; - } var cursor = entry.getValue().getAll(); while (cursor.move()) { if (arity == 1) { @@ -65,7 +83,41 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { public MutableGraph createVisualizationForModelState(Long version) { var currentVersion = model.getState(); model.restore(version); - MutableGraph graph = createVisualizationForCurrentModelState(); + var graph = createVisualizationForCurrentModelState(); + model.restore(currentVersion); + return graph; + } + + @Override + public String createDotForCurrentModelState() { + var sb = new StringBuilder(); + sb.append("digraph model {\n"); + for (var entry : interpretations.entrySet()) { + var key = entry.getKey(); + var arity = key.arity(); + var cursor = entry.getValue().getAll(); + while (cursor.move()) { + if (arity == 1) { + var id = cursor.getKey().get(0); + sb.append("\t").append(id).append(" [label=\"").append(key.name()).append(": ").append(id) + .append("\"]\n"); + } else { + var from = cursor.getKey().get(0); + var to = cursor.getKey().get(1); + sb.append("\t").append(from).append(" -> ").append(to).append(" [label=\"").append(key.name()) + .append("\"]\n"); + } + } + } + sb.append("}"); + return sb.toString(); + } + + @Override + public String createDotForModelState(Long version) { + var currentVersion = model.getState(); + model.restore(version); + var graph = createDotForCurrentModelState(); model.restore(currentVersion); return graph; } @@ -85,4 +137,39 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { return false; } } + + @Override + public boolean saveDot(String dot, String filePath) { + File file = new File(filePath); + file.getParentFile().mkdirs(); + + try (FileWriter writer = new FileWriter(file)) { + writer.write(dot); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + + @Override + public boolean renderDot(String dot, String filePath) { + return renderDot(dot, FileFormat.SVG, filePath); + } + + @Override + public boolean renderDot(String dot, FileFormat format, String filePath) { + try { + Process process = new ProcessBuilder("dot", "-T" + format.getFormat(), "-o", filePath).start(); + + OutputStream osToProcess = process.getOutputStream(); + PrintWriter pwToProcess = new PrintWriter(osToProcess); + pwToProcess.write(dot); + pwToProcess.close(); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + return true; + } } -- cgit v1.2.3-70-g09d2 From 00c8fcf947d3f5c375d49a907bcefa5d8e1dd8ea Mon Sep 17 00:00:00 2001 From: nagilooh Date: Tue, 1 Aug 2023 12:41:45 +0200 Subject: 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 --- subprojects/store-query-viatra/build.gradle.kts | 1 - .../DesignSpaceExplorationAdapterImpl.java | 21 ++++ .../tools/refinery/store/query/dse/DebugTest.java | 15 +-- subprojects/visualization/build.gradle.kts | 1 - .../visualization/ModelVisualizerAdapter.java | 23 ++-- .../internal/ModelVisualizerAdapterImpl.java | 120 +++++++++++---------- 6 files changed, 109 insertions(+), 72 deletions(-) (limited to 'subprojects/visualization') 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 { dependencies { implementation(libs.ecore) - implementation ("guru.nidi:graphviz-java:0.18.1") api(libs.viatra) api(project(":refinery-store-query")) 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; import tools.refinery.store.representation.Symbol; import tools.refinery.store.tuple.Tuple; import tools.refinery.store.tuple.Tuple1; +import tools.refinery.visualization.ModelVisualizerAdapter; import java.util.*; @@ -40,6 +41,8 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration private Random random = new Random(); private Objective[][] leveledObjectives; private boolean isNewState = false; + private final boolean isVisualizationEnabled; + private final ModelVisualizerAdapter modelVisualizerAdapter; public List getTrajectory() { return new LinkedList<>(trajectory); @@ -66,6 +69,8 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration statesAndUntraversedActivations = new HashMap<>(); statesAndTraversedActivations = new HashMap<>(); strategy = storeAdapter.getStrategy(); + modelVisualizerAdapter = model.tryGetAdapter(ModelVisualizerAdapter.class).orElse(null); + isVisualizationEnabled = modelVisualizerAdapter != null; } @@ -129,6 +134,10 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration if (trajectory.size() < 2) { return false; } + if (isVisualizationEnabled) { + modelVisualizerAdapter.addTransition(trajectory.get(trajectory.size() - 1), + trajectory.get(trajectory.size() - 2), "backtrack"); + } model.restore(trajectory.get(trajectory.size() - 2)); trajectory.remove(trajectory.size() - 1); return true; @@ -137,6 +146,10 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration @Override public void restoreTrajectory(List trajectory) { model.restore(trajectory.get(trajectory.size() - 1)); +// if (isVisualizationEnabled) { +// modelVisualizerAdapter.addTransition(this.trajectory.get(trajectory.size() - 1), +// trajectory.get(trajectory.size() - 1), "restore"); +// } this.trajectory = trajectory; } @@ -173,6 +186,9 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration public void newSolution() { var state = model.getState(); solutions.add(state); + if (isVisualizationEnabled) { + modelVisualizerAdapter.addSolution(state); + } } @Override @@ -212,6 +228,11 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration isNewState = !statesAndUntraversedActivations.containsKey(newState); statesAndUntraversedActivations.put(newState, getAllActivations()); statesAndTraversedActivations.put(newState, new HashSet<>()); + if (isVisualizationEnabled) { + modelVisualizerAdapter.addTransition(trajectory.get(trajectory.size() - 2), + trajectory.get(trajectory.size() - 1), activation.transformationRule().getName(), + activation.activation()); + } return true; } 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; import tools.refinery.store.query.ModelQueryAdapter; import tools.refinery.store.query.dnf.Query; import tools.refinery.store.query.dse.internal.TransformationRule; +import tools.refinery.store.query.dse.strategy.BestFirstStrategy; import tools.refinery.store.query.dse.strategy.DepthFirstStrategy; import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; import tools.refinery.store.query.view.AnySymbolView; @@ -12,6 +13,7 @@ import tools.refinery.store.query.view.KeyOnlyView; import tools.refinery.store.representation.Symbol; import tools.refinery.store.tuple.Tuple; import tools.refinery.visualization.ModelVisualizerAdapter; +import tools.refinery.visualization.internal.FileFormat; public class DebugTest { private static final Symbol classModel = Symbol.of("ClassModel", 1); @@ -83,30 +85,31 @@ public class DebugTest { .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features) .with(ViatraModelQueryAdapter.builder() .queries(createClassPrecondition, createFeaturePrecondition)) + .with(ModelVisualizerAdapter.builder()) .with(DesignSpaceExplorationAdapter.builder() .transformations(createClassRule, createFeatureRule) .strategy(new DepthFirstStrategy(4).continueIfHardObjectivesFulfilled() // .strategy(new BestFirstStrategy(4).continueIfHardObjectivesFulfilled() // .goOnOnlyIfFitnessIsBetter() )) - .with(ModelVisualizerAdapter.builder()) .build(); var model = store.createEmptyModel(); var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); +// dseAdapter.setRandom(1); var queryEngine = model.getAdapter(ModelQueryAdapter.class); var modelElementInterpretation = model.getInterpretation(classModel); - modelElementInterpretation.put(dseAdapter.createObject(), true); + var classElementInterpretation = model.getInterpretation(classElement); + var modelElement = dseAdapter.createObject(); + modelElementInterpretation.put(modelElement, true); + classElementInterpretation.put(modelElement, true); queryEngine.flushChanges(); var states = dseAdapter.explore(); var visualizer = model.getAdapter(ModelVisualizerAdapter.class); - for (var state : states) { - var visualization = visualizer.createVisualizationForModelState(state); - visualizer.saveVisualization(visualization, "test_output" + state.hashCode() + ".png"); - } + visualizer.renderDesignSpace("test_output", FileFormat.SVG); System.out.println("states size: " + states.size()); System.out.println("states: " + states); 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 { } dependencies { - implementation ("guru.nidi:graphviz-java:0.18.1") api(project(":refinery-store-query")) } 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 @@ package tools.refinery.visualization; -import guru.nidi.graphviz.engine.Format; -import guru.nidi.graphviz.model.MutableGraph; import tools.refinery.store.adapter.ModelAdapter; +import tools.refinery.store.tuple.Tuple; import tools.refinery.visualization.internal.FileFormat; import tools.refinery.visualization.internal.ModelVisualizerBuilderImpl; @@ -13,21 +12,25 @@ public interface ModelVisualizerAdapter extends ModelAdapter { return new ModelVisualizerBuilderImpl(); } - public MutableGraph createVisualizationForCurrentModelState(); - - public MutableGraph createVisualizationForModelState(Long version); - public String createDotForCurrentModelState(); public String createDotForModelState(Long version); - public boolean saveVisualization(MutableGraph graph, String path); - - public boolean saveVisualization(MutableGraph graph, Format format, String path); - public boolean saveDot(String dot, String filePath); public boolean renderDot(String dot, String filePath); public boolean renderDot(String dot, FileFormat format, String filePath); + + public void addTransition(Long from, Long to, String action); + + + public void addTransition(Long from, Long to, String action, Tuple activation); + public void addSolution(Long state); + + public boolean saveDesignSpace(String path); + + public boolean renderDesignSpace(String path); + + public boolean renderDesignSpace(String path, FileFormat format); } 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 @@ package tools.refinery.visualization.internal; -import guru.nidi.graphviz.attribute.GraphAttr; -import guru.nidi.graphviz.attribute.Label; -import guru.nidi.graphviz.engine.Format; -import guru.nidi.graphviz.engine.Graphviz; -import guru.nidi.graphviz.model.MutableGraph; import tools.refinery.store.model.Interpretation; import tools.refinery.store.model.Model; import tools.refinery.store.representation.AnySymbol; -import tools.refinery.store.representation.TruthValue; +import tools.refinery.store.tuple.Tuple; import tools.refinery.visualization.ModelVisualizerAdapter; import tools.refinery.visualization.ModelVisualizerStoreAdapter; @@ -16,12 +11,13 @@ import java.io.*; import java.util.HashMap; import java.util.Map; -import static guru.nidi.graphviz.model.Factory.*; - public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { private final Model model; private final ModelVisualizerStoreAdapter storeAdapter; private final Map> interpretations; + private final StringBuilder designSpaceBuilder = new StringBuilder(); + private int transitionCounter = 0; + public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) { this.model = model; this.storeAdapter = storeAdapter; @@ -46,6 +42,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { } interpretations.put(symbol, castInterpretation); } + designSpaceBuilder.append("digraph designSpace {\n"); } @Override @@ -58,36 +55,6 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { return storeAdapter; } - @Override - public MutableGraph createVisualizationForCurrentModelState() { - var graph = mutGraph("model").setDirected(true).graphAttrs().add(GraphAttr.dpi(100)); - for (var entry : interpretations.entrySet()) { - var key = entry.getKey(); - var arity = key.arity(); - var cursor = entry.getValue().getAll(); - while (cursor.move()) { - if (arity == 1) { - var id = cursor.getKey().get(0); - graph.add(mutNode(String.valueOf(id)).add("label", key.name() + ": " + id)); - } else { - var from = cursor.getKey().get(0); - var to = cursor.getKey().get(1); - graph.add(mutNode(String.valueOf(from)).addLink(to(mutNode(String.valueOf(to))).with(Label.of(key.name())))); - } - } - } - return graph; - } - - @Override - public MutableGraph createVisualizationForModelState(Long version) { - var currentVersion = model.getState(); - model.restore(version); - var graph = createVisualizationForCurrentModelState(); - model.restore(currentVersion); - return graph; - } - @Override public String createDotForCurrentModelState() { var sb = new StringBuilder(); @@ -122,22 +89,6 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { return graph; } - @Override - public boolean saveVisualization(MutableGraph graph, String path) { - return saveVisualization(graph, Format.PNG, path); - } - - @Override - public boolean saveVisualization(MutableGraph graph, Format format, String path) { - try { - Graphviz.fromGraph(graph).render(format).toFile(new File(path)); - return true; - } catch (IOException e) { - e.printStackTrace(); - return false; - } - } - @Override public boolean saveDot(String dot, String filePath) { File file = new File(filePath); @@ -172,4 +123,65 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { } return true; } + + @Override + public void addTransition(Long from, Long to, String action) { + designSpaceBuilder.append(from).append(" -> ").append(to).append(" [label=\"").append(transitionCounter++) + .append(": ").append(action).append("\"]\n"); + + } + + @Override + public void addTransition(Long from, Long to, String action, Tuple activation) { + designSpaceBuilder.append(from).append(" -> ").append(to).append(" [label=\"").append(transitionCounter++) + .append(": ").append(action).append(" / "); + + + for (int i = 0; i < activation.getSize(); i++) { + designSpaceBuilder.append(activation.get(i)); + if (i < activation.getSize() - 1) { + designSpaceBuilder.append(", "); + } + } + designSpaceBuilder.append("\"]\n"); + } + + @Override + public void addSolution(Long state) { + designSpaceBuilder.append(state).append(" [shape = doublecircle]\n"); + } + + private String buildDesignSpaceDot() { + for (var state : storeAdapter.getStore().getStates()) { + designSpaceBuilder.append(state).append(" [URL=\"./").append(state).append(".svg\"]\n"); + } + designSpaceBuilder.append("}"); + return designSpaceBuilder.toString(); + } + + @Override + public boolean saveDesignSpace(String path) { + saveDot(buildDesignSpaceDot(), path + "/designSpace.dot"); + for (var state : storeAdapter.getStore().getStates()) { + saveDot(createDotForModelState(state), path + "/" + state + ".dot"); + } + return true; + } + + @Override + public boolean renderDesignSpace(String path) { + return renderDesignSpace(path, FileFormat.SVG); + } + + @Override + public boolean renderDesignSpace(String path, FileFormat format) { + for (var state : storeAdapter.getStore().getStates()) { + var stateDot = createDotForModelState(state); + saveDot(stateDot, path + "/" + state + ".dot"); + renderDot(stateDot, path + "/" + state + "." + format.getFormat()); + } + var designSpaceDot = buildDesignSpaceDot(); + saveDot(designSpaceDot, path + "/designSpace.dot"); + return renderDot(designSpaceDot, format, path + "/designSpace." + format.getFormat()); + } } -- cgit v1.2.3-70-g09d2 From 87fe96f3c67993ab1e4b131d73ecf276482e65a9 Mon Sep 17 00:00:00 2001 From: nagilooh Date: Thu, 3 Aug 2023 16:58:25 +0200 Subject: Improve visualization -Display values from all relevant interpretations -Support TruthValue -Add tabular formatting -Add colors --- .../internal/ModelVisualizerAdapterImpl.java | 214 +++++++++++++++++---- 1 file changed, 178 insertions(+), 36 deletions(-) (limited to 'subprojects/visualization') 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 33c5a43b..8555da5f 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 @@ -4,13 +4,14 @@ import tools.refinery.store.map.Version; import tools.refinery.store.model.Interpretation; import tools.refinery.store.model.Model; import tools.refinery.store.representation.AnySymbol; +import tools.refinery.store.representation.TruthValue; import tools.refinery.store.tuple.Tuple; import tools.refinery.visualization.ModelVisualizerAdapter; import tools.refinery.visualization.ModelVisualizerStoreAdapter; import java.io.*; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.stream.Collectors; public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { private final Model model; @@ -20,6 +21,15 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { private final Map states = new HashMap<>(); private int transitionCounter = 0; private Integer numberOfStates = 0; + private static final Map truthValueToDot = new HashMap<>() + {{ + put(TruthValue.TRUE, "1"); + put(TruthValue.FALSE, "0"); + put(TruthValue.UNKNOWN, "½"); + put(TruthValue.ERROR, "E"); + put(true, "1"); + put(false, "0"); + }}; public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) { this.model = model; @@ -30,22 +40,16 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { if (arity < 1 || arity > 2) { continue; } - var interpretation = model.getInterpretation(symbol); - var valueType = symbol.valueType(); - Interpretation castInterpretation; - if (valueType == Boolean.class) { - castInterpretation = (Interpretation) interpretation; - } - // TODO: support TruthValue -// else if (valueType == TruthValue.class) { -// castInterpretation = (Interpretation) interpretation; -// } - else { - continue; - } - interpretations.put(symbol, castInterpretation); + var interpretation = (Interpretation) model.getInterpretation(symbol); + interpretations.put(symbol, interpretation); } designSpaceBuilder.append("digraph designSpace {\n"); + designSpaceBuilder.append(""" + node[ + style=filled + fillcolor=white + ] + """); } @Override @@ -60,29 +64,165 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { @Override public String createDotForCurrentModelState() { + + var unaryTupleToInterpretationsMap = new HashMap>>(); + var sb = new StringBuilder(); + sb.append("digraph model {\n"); + sb.append(""" + node [ + \tstyle="filled, rounded" + \tshape=plain + \tpencolor="#00000088" + \tfontname="Helvetica" + ] + """); + sb.append(""" + edge [ + \tlabeldistance=3 + \tfontname="Helvetica" + ] + """); + for (var entry : interpretations.entrySet()) { var key = entry.getKey(); var arity = key.arity(); var cursor = entry.getValue().getAll(); - while (cursor.move()) { - if (arity == 1) { - var id = cursor.getKey().get(0); - sb.append("\t").append(id).append(" [label=\"").append(key.name()).append(": ").append(id) - .append("\"]\n"); - } else { - var from = cursor.getKey().get(0); - var to = cursor.getKey().get(1); - sb.append("\t").append(from).append(" -> ").append(to).append(" [label=\"").append(key.name()) - .append("\"]\n"); + if (arity == 1) { + while (cursor.move()) { + unaryTupleToInterpretationsMap.computeIfAbsent(cursor.getKey(), k -> new LinkedHashSet<>()) + .add(entry.getValue()); + } + } else if (arity == 2) { + while (cursor.move()) { + var tuple = cursor.getKey(); + for (var i = 0; i < tuple.getSize(); i++) { + var id = tuple.get(i); + unaryTupleToInterpretationsMap.computeIfAbsent(Tuple.of(id), k -> new LinkedHashSet<>()); + } + sb.append(drawEdge(cursor.getKey(), key, entry.getValue())); } } } + for (var entry : unaryTupleToInterpretationsMap.entrySet()) { + sb.append(drawElement(entry)); + } sb.append("}"); return sb.toString(); } + private StringBuilder drawElement(Map.Entry>> entry) { + var sb = new StringBuilder(); + + var tableStyle = " CELLSPACING=\"0\" BORDER=\"2\" CELLBORDER=\"0\" CELLPADDING=\"4\" STYLE=\"ROUNDED\""; + + var key = entry.getKey(); + var id = key.get(0); + var mainLabel = String.valueOf(id); + var interpretations = entry.getValue(); + var backgroundColor = toBackgroundColorString(averageColor(interpretations)); + + sb.append(id); + sb.append(" [\n"); + sb.append("\tfillcolor=\"").append(backgroundColor).append("\"\n"); + sb.append("\tlabel="); + if (interpretations.isEmpty()) { + sb.append("<\n\t").append(mainLabel).append(""); + } + else { + sb.append("<\n\t\t") + .append(mainLabel).append("\n"); + for (var interpretation : interpretations) { + var rawValue = interpretation.get(key); + + if (rawValue == null || rawValue.equals(TruthValue.FALSE) || rawValue.equals(false)) { + continue; + } + var color = "black"; + if (rawValue.equals(TruthValue.ERROR)) { + color = "red"; + } + var value = truthValueToDot.getOrDefault(rawValue, rawValue.toString()); + var symbol = interpretation.getSymbol(); + + if (symbol.valueType() == String.class) { + value = "\"" + value + "\""; + } + sb.append("\t\t") + .append(interpretation.getSymbol().name()) + .append("") + .append("=").append(value) + .append("\n"); + } + } + sb.append("\t\t>\n"); + sb.append("]\n"); + + return sb; + } + + private String drawEdge(Tuple edge, AnySymbol symbol, Interpretation interpretation) { + var value = interpretation.get(edge); + + if (value == null || value.equals(TruthValue.FALSE) || value.equals(false)) { + return ""; + } + + var sb = new StringBuilder(); + var style = "solid"; + var color = "black"; + if (value.equals(TruthValue.UNKNOWN)) { + style = "dotted"; + } + else if (value.equals(TruthValue.ERROR)) { + style = "dashed"; + color = "red"; + } + + var from = edge.get(0); + var to = edge.get(1); + var name = symbol.name(); + sb.append(from).append(" -> ").append(to) + .append(" [\n\tstyle=").append(style) + .append("\n\tcolor=").append(color) + .append("\n\tfontcolor=").append(color) + .append("\n\tlabel=\"").append(name) + .append("\"]\n"); + return sb.toString(); + } + + private String toBackgroundColorString(Integer[] backgroundColor) { + if (backgroundColor.length == 3) + return String.format("#%02x%02x%02x", backgroundColor[0], backgroundColor[1], backgroundColor[2]); + else if (backgroundColor.length == 4) + return String.format("#%02x%02x%02x%02x", backgroundColor[0], backgroundColor[1], backgroundColor[2], + backgroundColor[3]); + return null; + } + + private Integer[] typePredicateColor(String name) { + var random = new Random(name.hashCode()); + return new Integer[] { random.nextInt(128) + 128, random.nextInt(128) + 128, random.nextInt(128) + 128 }; + } + + private Integer[] averageColor(Set> interpretations) { + if(interpretations.isEmpty()) { + return new Integer[]{256, 256, 256}; + } + // TODO: Only use interpretations where the value is not false (or unknown) + var symbols = interpretations.stream() + .map(i -> typePredicateColor(i.getSymbol().name())).toArray(Integer[][]::new); + + + + return new Integer[] { + Arrays.stream(symbols).map(i -> i[0]).collect(Collectors.averagingInt(Integer::intValue)).intValue(), + Arrays.stream(symbols).map(i -> i[1]).collect(Collectors.averagingInt(Integer::intValue)).intValue(), + Arrays.stream(symbols).map(i -> i[2]).collect(Collectors.averagingInt(Integer::intValue)).intValue() + }; + } + @Override public String createDotForModelState(Version version) { var currentVersion = model.getState(); @@ -129,15 +269,14 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { @Override public void addTransition(Version from, Version to, String action) { - designSpaceBuilder.append(states.get(from)).append(" -> ").append(states.get(to)).append(" [label=\"") - .append(transitionCounter++).append(": ").append(action).append("\"]\n"); - + designSpaceBuilder.append(states.get(from)).append(" -> ").append(states.get(to)) + .append(" [label=\"").append(transitionCounter++).append(": ").append(action).append("\"]\n"); } @Override public void addTransition(Version from, Version to, String action, Tuple activation) { - designSpaceBuilder.append(states.get(from)).append(" -> ").append(states.get(to)).append(" [label=\"").append(transitionCounter++) - .append(": ").append(action).append(" / "); + designSpaceBuilder.append(states.get(from)).append(" -> ").append(states.get(to)) + .append(" [label=\"").append(transitionCounter++).append(": ").append(action).append(" / "); for (int i = 0; i < activation.getSize(); i++) { @@ -151,12 +290,16 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { @Override public void addState(Version state) { + if (states.containsKey(state)) { + return; + } states.put(state, numberOfStates++); designSpaceBuilder.append(states.get(state)).append(" [URL=\"./").append(states.get(state)).append(".svg\"]\n"); } @Override public void addSolution(Version state) { + addState(state); designSpaceBuilder.append(states.get(state)).append(" [shape = doublecircle]\n"); } @@ -168,8 +311,8 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { @Override public boolean saveDesignSpace(String path) { saveDot(buildDesignSpaceDot(), path + "/designSpace.dot"); - for (var state : states.keySet()) { - saveDot(createDotForModelState(state), path + "/" + states.get(state) + ".dot"); + for (var entry : states.entrySet()) { + saveDot(createDotForModelState(entry.getKey()), path + "/" + entry.getValue() + ".dot"); } return true; } @@ -182,11 +325,10 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { @Override public boolean renderDesignSpace(String path, FileFormat format) { for (var entry : states.entrySet()) { - var state = entry.getKey(); var stateId = entry.getValue(); - var stateDot = createDotForModelState(state); + var stateDot = createDotForModelState(entry.getKey()); saveDot(stateDot, path + "/" + stateId + ".dot"); - renderDot(stateDot, path + "/" + stateId + "." + format.getFormat()); + renderDot(stateDot, format, path + "/" + stateId + "." + format.getFormat()); } var designSpaceDot = buildDesignSpaceDot(); saveDot(designSpaceDot, path + "/designSpace.dot"); -- cgit v1.2.3-70-g09d2 From e1de155531c9e36a5ffa3e38f9b5764e7f8ab607 Mon Sep 17 00:00:00 2001 From: nagilooh Date: Fri, 4 Aug 2023 12:08:38 +0200 Subject: Add missing copyright headers --- .../src/main/java/tools/refinery/store/dse/ActionFactory.java | 5 +++++ .../tools/refinery/store/dse/DesignSpaceExplorationAdapter.java | 5 +++++ .../tools/refinery/store/dse/DesignSpaceExplorationBuilder.java | 5 +++++ .../refinery/store/dse/DesignSpaceExplorationStoreAdapter.java | 5 +++++ .../src/main/java/tools/refinery/store/dse/Strategy.java | 5 +++++ .../main/java/tools/refinery/store/dse/internal/Activation.java | 5 +++++ .../store/dse/internal/DesignSpaceExplorationAdapterImpl.java | 9 +++++++++ .../store/dse/internal/DesignSpaceExplorationBuilderImpl.java | 5 +++++ .../dse/internal/DesignSpaceExplorationStoreAdapterImpl.java | 5 +++++ .../tools/refinery/store/dse/internal/TransformationRule.java | 5 +++++ .../store/dse/objectives/AlwaysSatisfiedDummyHardObjective.java | 1 + .../java/tools/refinery/store/dse/objectives/BaseObjective.java | 1 + .../java/tools/refinery/store/dse/objectives/Comparators.java | 1 + .../main/java/tools/refinery/store/dse/objectives/Fitness.java | 9 +++++++++ .../main/java/tools/refinery/store/dse/objectives/Objective.java | 1 + .../refinery/store/dse/objectives/ObjectiveComparatorHelper.java | 1 + .../tools/refinery/store/dse/strategy/BestFirstStrategy.java | 9 +++++++++ .../tools/refinery/store/dse/strategy/DepthFirstStrategy.java | 9 +++++++++ .../src/test/java/tools/refinery/store/dse/CRAExamplesTest.java | 5 +++++ .../src/test/java/tools/refinery/store/dse/DebugTest.java | 5 +++++ .../tools/refinery/store/dse/DesignSpaceExplorationTest.java | 5 +++++ .../java/tools/refinery/store/dse/TransformationRuleTest.java | 5 +++++ .../tools/refinery/visualization/ModelVisualizerAdapter.java | 5 +++++ .../tools/refinery/visualization/ModelVisualizerBuilder.java | 5 +++++ .../refinery/visualization/ModelVisualizerStoreAdapter.java | 5 +++++ .../java/tools/refinery/visualization/internal/FileFormat.java | 5 +++++ .../visualization/internal/ModelVisualizeStoreAdapterImpl.java | 5 +++++ .../visualization/internal/ModelVisualizerAdapterImpl.java | 9 +++++++-- .../visualization/internal/ModelVisualizerBuilderImpl.java | 5 +++++ 29 files changed, 143 insertions(+), 2 deletions(-) (limited to 'subprojects/visualization') diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/ActionFactory.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/ActionFactory.java index 2af22963..524c2f55 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/ActionFactory.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/ActionFactory.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse; import org.eclipse.collections.api.block.procedure.Procedure; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java index 729a6fc9..8963a496 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse; import tools.refinery.store.adapter.ModelAdapter; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationBuilder.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationBuilder.java index 8ca0037d..4def5cb2 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationBuilder.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationBuilder.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse; import tools.refinery.store.adapter.ModelAdapterBuilder; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationStoreAdapter.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationStoreAdapter.java index 5964cd82..186bfebb 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationStoreAdapter.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationStoreAdapter.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse; import tools.refinery.store.adapter.ModelStoreAdapter; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/Strategy.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/Strategy.java index cef43386..e240f478 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/Strategy.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/Strategy.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse; public interface Strategy { diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/Activation.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/Activation.java index f1de00e6..1893ce2e 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/Activation.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/Activation.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse.internal; import tools.refinery.store.tuple.Tuple; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java index 5fb54da9..b32e9696 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java @@ -1,3 +1,12 @@ +/******************************************************************************* + * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro + * Copyright (c) 2023 The Refinery Authors + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ package tools.refinery.store.dse.internal; import tools.refinery.store.map.Version; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationBuilderImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationBuilderImpl.java index 03508adc..8f7056f2 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationBuilderImpl.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationBuilderImpl.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse.internal; import tools.refinery.store.adapter.AbstractModelAdapterBuilder; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationStoreAdapterImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationStoreAdapterImpl.java index b06462ce..09925ae7 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationStoreAdapterImpl.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationStoreAdapterImpl.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse.internal; import tools.refinery.store.adapter.ModelAdapter; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java index ed2e77f1..015d4815 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse.internal; import org.eclipse.collections.api.block.procedure.Procedure; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedDummyHardObjective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedDummyHardObjective.java index 82695704..afed75fd 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedDummyHardObjective.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedDummyHardObjective.java @@ -1,5 +1,6 @@ /******************************************************************************* * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro + * Copyright (c) 2023 The Refinery Authors * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/BaseObjective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/BaseObjective.java index 24e3280d..7df33efe 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/BaseObjective.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/BaseObjective.java @@ -1,5 +1,6 @@ /******************************************************************************* * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro + * Copyright (c) 2023 The Refinery Authors * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Comparators.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Comparators.java index e64e04e8..476504b0 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Comparators.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Comparators.java @@ -1,5 +1,6 @@ /******************************************************************************* * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro + * Copyright (c) 2023 The Refinery Authors * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Fitness.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Fitness.java index 16caed85..92709d3e 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Fitness.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Fitness.java @@ -1,3 +1,12 @@ +/******************************************************************************* + * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro + * Copyright (c) 2023 The Refinery Authors + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ package tools.refinery.store.dse.objectives; import java.util.HashMap; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Objective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Objective.java index 4e14c9a3..c7313622 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Objective.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Objective.java @@ -1,5 +1,6 @@ /******************************************************************************* * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro + * Copyright (c) 2023 The Refinery Authors * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/ObjectiveComparatorHelper.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/ObjectiveComparatorHelper.java index 3184b8c4..1d676562 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/ObjectiveComparatorHelper.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/ObjectiveComparatorHelper.java @@ -1,5 +1,6 @@ /******************************************************************************* * Copyright (c) 2010-2015, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro + * Copyright (c) 2023 The Refinery Authors * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-v20.html. diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java index 05cc5bac..8648864c 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java @@ -1,3 +1,12 @@ +/******************************************************************************* + * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro + * Copyright (c) 2023 The Refinery Authors + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ package tools.refinery.store.dse.strategy; import tools.refinery.store.map.Version; diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java index 42985013..1405789b 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java @@ -1,3 +1,12 @@ +/******************************************************************************* + * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro + * Copyright (c) 2023 The Refinery Authors + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ package tools.refinery.store.dse.strategy; import tools.refinery.store.dse.DesignSpaceExplorationAdapter; 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 e7cc60d6..4bdb05ec 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 @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse; import org.junit.jupiter.api.Test; 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 911c0661..101a5362 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 @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse; import org.junit.jupiter.api.Test; 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 index 7db2c708..f4644407 100644 --- 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 @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse; import org.junit.jupiter.api.Test; 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 index a32d392b..312bcebd 100644 --- 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 @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.store.dse; import org.junit.jupiter.api.Test; 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 b3f833ef..bc32323d 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.visualization; import tools.refinery.store.adapter.ModelAdapter; diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java index 9c1bd0e0..56cc425e 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.visualization; import tools.refinery.store.adapter.ModelAdapterBuilder; diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java index 764de6d4..6599d4c3 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.visualization; import tools.refinery.store.adapter.ModelStoreAdapter; diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/FileFormat.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/FileFormat.java index 43d6eb3f..c5dffeb2 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/FileFormat.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/FileFormat.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.visualization.internal; public enum FileFormat { diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java index 6e158c28..b4db2682 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.visualization.internal; import tools.refinery.store.adapter.ModelAdapter; 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 8555da5f..06cc8113 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,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.visualization.internal; import tools.refinery.store.map.Version; @@ -201,7 +206,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { return null; } - private Integer[] typePredicateColor(String name) { + private Integer[] typeColor(String name) { var random = new Random(name.hashCode()); return new Integer[] { random.nextInt(128) + 128, random.nextInt(128) + 128, random.nextInt(128) + 128 }; } @@ -212,7 +217,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { } // TODO: Only use interpretations where the value is not false (or unknown) var symbols = interpretations.stream() - .map(i -> typePredicateColor(i.getSymbol().name())).toArray(Integer[][]::new); + .map(i -> typeColor(i.getSymbol().name())).toArray(Integer[][]::new); diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java index 4148c24a..d19cf2cf 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors + * + * SPDX-License-Identifier: EPL-2.0 + */ package tools.refinery.visualization.internal; import tools.refinery.store.adapter.AbstractModelAdapterBuilder; -- cgit v1.2.3-70-g09d2 From a20fd33c647d8511762f84436dbd8d1632b57fe8 Mon Sep 17 00:00:00 2001 From: Attila Ficsor Date: Mon, 7 Aug 2023 12:59:35 +0200 Subject: Clean up design space exploration --- .../store/dse/DesignSpaceExplorationAdapter.java | 2 - .../DesignSpaceExplorationAdapterImpl.java | 7 +-- .../store/dse/objectives/BaseObjective.java | 2 +- .../refinery/store/dse/objectives/Comparators.java | 2 +- .../refinery/store/dse/objectives/Fitness.java | 15 +++++ .../dse/objectives/ObjectiveComparatorHelper.java | 1 + .../store/dse/strategy/BestFirstStrategy.java | 65 +++++++--------------- .../store/dse/strategy/DepthFirstStrategy.java | 23 +++----- .../tools/refinery/store/dse/CRAExamplesTest.java | 2 +- .../java/tools/refinery/store/dse/DebugTest.java | 2 +- .../store/dse/DesignSpaceExplorationTest.java | 2 +- .../refinery/store/dse/TransformationRuleTest.java | 2 +- .../visualization/ModelVisualizerStoreAdapter.java | 1 - .../internal/ModelVisualizerAdapterImpl.java | 57 ++++++++++++------- 14 files changed, 89 insertions(+), 94 deletions(-) (limited to 'subprojects/visualization') diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java index c4aa97c2..c45f088a 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java @@ -52,8 +52,6 @@ public interface DesignSpaceExplorationAdapter extends ModelAdapter { public void fireRandomActivation(); - public boolean isCurrentInTrajectory(); - public List getTrajectory(); public boolean isCurrentStateAlreadyTraversed(); diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java index 4e5cc467..1329480c 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java @@ -43,7 +43,6 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration private ObjectiveComparatorHelper objectiveComparatorHelper; private List trajectory = new ArrayList<>(); private Map parents = new HashMap<>(); - private Fitness lastFitness; private final List solutions = new ArrayList<>(); private Map> statesAndTraversedActivations; private Random random = new Random(); @@ -184,9 +183,7 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration @Override public Fitness getFitness() { - var result = fitnessCache.computeIfAbsent(model.getState(), s -> calculateFitness()); - lastFitness = result; - return result; + return fitnessCache.computeIfAbsent(model.getState(), s -> calculateFitness()); } private Fitness calculateFitness() { @@ -201,8 +198,6 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration } result.setSatisfiesHardObjectives(satisfiesHardObjectives); - lastFitness = result; - return result; } diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/BaseObjective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/BaseObjective.java index 7df33efe..b76598fb 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/BaseObjective.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/BaseObjective.java @@ -30,7 +30,7 @@ public abstract class BaseObjective implements Objective { protected boolean isThereFitnessConstraint = false; protected Comparator fitnessConstraintComparator; - public BaseObjective(String name) { + protected BaseObjective(String name) { Objects.requireNonNull(name, "Name of the objective cannot be null."); this.name = name; } diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Comparators.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Comparators.java index 476504b0..181397b3 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Comparators.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Comparators.java @@ -15,7 +15,7 @@ public class Comparators { private Comparators() { /*Utility class constructor*/ } - public static final Comparator HIGHER_IS_BETTER = (o1, o2) -> o1.compareTo(o2); + public static final Comparator HIGHER_IS_BETTER = Double::compareTo; public static final Comparator LOWER_IS_BETTER = (o1, o2) -> o2.compareTo(o1); diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Fitness.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Fitness.java index 92709d3e..0bf956d2 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Fitness.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/Fitness.java @@ -27,4 +27,19 @@ public class Fitness extends HashMap { public String toString() { return super.toString() + " hardObjectives=" + satisfiesHardObjectives; } + + @Override + public boolean equals(Object other) { + if (other == null) return false; + if (getClass() != other.getClass()) return false; + return satisfiesHardObjectives == ((Fitness) other).satisfiesHardObjectives; + } + + @Override + public int hashCode() { + int h = super.hashCode(); + h = h * 31 + (satisfiesHardObjectives ? 1 : 0); + return h; + } + } diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/ObjectiveComparatorHelper.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/ObjectiveComparatorHelper.java index 1d676562..eb03eeaf 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/ObjectiveComparatorHelper.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/ObjectiveComparatorHelper.java @@ -49,6 +49,7 @@ public class ObjectiveComparatorHelper { } } if (o2HasBetterFitness) { + return -1; } else if (o1HasBetterFitness) { return 1; } diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java index 57f86401..98af5695 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java @@ -25,29 +25,18 @@ public class BestFirstStrategy implements Strategy { private DesignSpaceExplorationAdapter dseAdapter; - private int maxDepth; - private int maxSolutions; + private final int maxDepth; + private final int maxSolutions; private boolean backTrackIfSolution = true; private boolean onlyBetterFirst = false; private PriorityQueue trajectoriesToExplore; - private static class TrajectoryWithFitness { - - public List trajectory; - public Fitness fitness; - - public TrajectoryWithFitness(List trajectory, Fitness fitness) { - super(); - this.trajectory = trajectory; - this.fitness = fitness; - } - + private record TrajectoryWithFitness(List trajectory, Fitness fitness) { @Override public String toString() { - return trajectory.toString() + fitness.toString(); - } - + return trajectory.toString() + fitness.toString(); + } } public BestFirstStrategy() { @@ -99,14 +88,14 @@ public class BestFirstStrategy implements Strategy { boolean globalConstraintsAreSatisfied = dseAdapter.checkGlobalConstraints(); if (!globalConstraintsAreSatisfied) { - // "Global constraint is not satisfied in the first state. Terminate."); + // Global constraint is not satisfied in the first state. Terminate. return; } final Fitness firstFitness = dseAdapter.getFitness(); if (firstFitness.isSatisfiesHardObjectives()) { dseAdapter.newSolution(); - // "First state is a solution. Terminate."); + // First state is a solution. Terminate. if (backTrackIfSolution) { return; } @@ -116,12 +105,6 @@ public class BestFirstStrategy implements Strategy { return; } -// final List firstTrajectory = dseAdapter.getTrajectory(); - -// TrajectoryWithFitness currentTrajectoryWithFitness = new TrajectoryWithFitness(dseAdapter.getTrajectory(), -// firstFitness); -// trajectoriesToExplore.add(currentTrajectoryWithFitness); - var firstTrajectoryWithFitness = new TrajectoryWithFitness(dseAdapter.getTrajectory(), firstFitness); trajectoriesToExplore.add(firstTrajectoryWithFitness); @@ -131,13 +114,11 @@ public class BestFirstStrategy implements Strategy { if (currentTrajectoryWithFitness == null) { if (trajectoriesToExplore.isEmpty()) { - // "State space is fully traversed."); + // State space is fully traversed. return; } else { currentTrajectoryWithFitness = trajectoriesToExplore.element(); -// if (logger.isDebugEnabled()) { -// "New trajectory is chosen: " + currentTrajectoryWithFitness); -// } + // New trajectory is chosen: " + currentTrajectoryWithFitness dseAdapter.restoreTrajectory(currentTrajectoryWithFitness.trajectory); } } @@ -150,19 +131,17 @@ public class BestFirstStrategy implements Strategy { while (iterator.hasNext()) { final Activation nextActivation = iterator.next(); if (!iterator.hasNext()) { - // "Last untraversed activation of the state."); + // Last untraversed activation of the state. trajectoriesToExplore.remove(currentTrajectoryWithFitness); } -// if (logger.isDebugEnabled()) { -// "Executing new activation: " + nextActivation); -// } + // Executing new activation dseAdapter.fireActivation(nextActivation); if (dseAdapter.isCurrentStateAlreadyTraversed()) { - // "The new state is already visited."); + // The new state is already visited. dseAdapter.backtrack(); } else if (!dseAdapter.checkGlobalConstraints()) { - // "Global constraint is not satisfied."); + // Global constraint is not satisfied. dseAdapter.backtrack(); } else { final Fitness nextFitness = dseAdapter.getFitness(); @@ -172,14 +151,14 @@ public class BestFirstStrategy implements Strategy { if (solutions >= maxSolutions) { return; } - // "Found a solution."); + // Found a solution. if (backTrackIfSolution) { dseAdapter.backtrack(); continue; } } if (dseAdapter.getDepth() >= maxDepth) { - // "Reached max depth."); + // Reached max depth. dseAdapter.backtrack(); continue; } @@ -191,33 +170,31 @@ public class BestFirstStrategy implements Strategy { int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFitness.fitness, nextTrajectoryWithFitness.fitness); if (compare < 0) { - // "Better fitness, moving on: " + nextFitness); + // Better fitness, moving on currentTrajectoryWithFitness = nextTrajectoryWithFitness; continue mainLoop; } else if (compare == 0) { if (onlyBetterFirst) { - // "Equally good fitness, backtrack: " + nextFitness); + // Equally good fitness, backtrack dseAdapter.backtrack(); - continue; } else { - // "Equally good fitness, moving on: " + nextFitness); + // Equally good fitness, moving on currentTrajectoryWithFitness = nextTrajectoryWithFitness; continue mainLoop; } } else { - // "Worse fitness."); + //"Worse fitness currentTrajectoryWithFitness = null; continue mainLoop; } } } - // "State is fully traversed."); + // State is fully traversed. trajectoriesToExplore.remove(currentTrajectoryWithFitness); currentTrajectoryWithFitness = null; } - // "Interrupted."); - + // Interrupted. } } diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java index f4a0747a..15529371 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java @@ -65,11 +65,11 @@ public class DepthFirstStrategy implements Strategy { if (!globalConstraintsAreSatisfied) { var isSuccessfulUndo = dseAdapter.backtrack(); if (!isSuccessfulUndo) { -// "Global constraint is not satisfied and cannot backtrack." + // Global constraint is not satisfied and cannot backtrack. break; } else { -// "Global constraint is not satisfied, backtrack." + // Global constraint is not satisfied, backtrack. continue; } } @@ -84,10 +84,10 @@ public class DepthFirstStrategy implements Strategy { if (backTrackIfSolution) { var isSuccessfulUndo = dseAdapter.backtrack(); if (!isSuccessfulUndo) { -// "Found a solution but cannot backtrack." + // Found a solution but cannot backtrack. break; } else { -// "Found a solution, backtrack." + // Found a solution, backtrack. continue; } } @@ -96,7 +96,7 @@ public class DepthFirstStrategy implements Strategy { if (dseAdapter.getDepth() >= maxDepth) { var isSuccessfulUndo = dseAdapter.backtrack(); if (!isSuccessfulUndo) { -// "Reached max depth but cannot backtrack." + // Reached max depth but cannot backtrack. break; } } @@ -104,16 +104,11 @@ public class DepthFirstStrategy implements Strategy { Collection activations; do { activations = dseAdapter.getUntraversedActivations(); - if (activations.isEmpty()) { - if (!dseAdapter.backtrack()) { - // "No more transitions from current state and cannot backtrack." - break mainloop; - } - else { - // "No more transitions from current state, backtrack." - continue; - } + if (activations.isEmpty() && !dseAdapter.backtrack()) { + // No more transitions from current state and cannot backtrack. + break mainloop; } + // No more transitions from current state, backtrack. } while (activations.isEmpty()); dseAdapter.fireRandomActivation(); 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 4bdb05ec..f1e90280 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 @@ -25,7 +25,7 @@ import java.util.List; import static tools.refinery.store.query.literal.Literals.not; -public class CRAExamplesTest { +class CRAExamplesTest { private static final Symbol name = Symbol.of("Name", 1, String.class); // private static final Symbol classModel = Symbol.of("ClassModel", 1); 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 101a5362..553510c8 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 @@ -20,7 +20,7 @@ import tools.refinery.store.tuple.Tuple; import tools.refinery.visualization.ModelVisualizerAdapter; import tools.refinery.visualization.internal.FileFormat; -public class DebugTest { +class DebugTest { private static final Symbol classModel = Symbol.of("ClassModel", 1); private static final Symbol classElement = Symbol.of("ClassElement", 1); private static final Symbol feature = Symbol.of("Feature", 1); 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 index f4644407..a379835d 100644 --- 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 @@ -21,7 +21,7 @@ import tools.refinery.visualization.ModelVisualizerAdapter; import static org.junit.jupiter.api.Assertions.assertEquals; -public class DesignSpaceExplorationTest { +class DesignSpaceExplorationTest { // private static final Symbol namedElement = Symbol.of("NamedElement", 1); // private static final Symbol attribute = Symbol.of("Attribute", 1); // private static final Symbol method = Symbol.of("Method", 1); 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 index f57f68ef..3aa4c92e 100644 --- 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 @@ -23,7 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static tools.refinery.store.query.literal.Literals.not; import static tools.refinery.store.dse.tests.QueryAssertions.assertResults; -public class TransformationRuleTest { +class TransformationRuleTest { private static final Symbol classModel = Symbol.of("ClassModel", 1); private static final Symbol classElement = Symbol.of("ClassElement", 1); diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java index 6599d4c3..6e6453fd 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java @@ -6,7 +6,6 @@ package tools.refinery.visualization; import tools.refinery.store.adapter.ModelStoreAdapter; -import tools.refinery.store.query.ModelQueryStoreAdapter; public interface ModelVisualizerStoreAdapter extends ModelStoreAdapter { } 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 06cc8113..efafe5a2 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 @@ -21,38 +21,39 @@ import java.util.stream.Collectors; public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { private final Model model; private final ModelVisualizerStoreAdapter storeAdapter; - private final Map> interpretations; + private final Map> allInterpretations; private final StringBuilder designSpaceBuilder = new StringBuilder(); private final Map states = new HashMap<>(); private int transitionCounter = 0; private Integer numberOfStates = 0; - private static final Map truthValueToDot = new HashMap<>() - {{ - put(TruthValue.TRUE, "1"); - put(TruthValue.FALSE, "0"); - put(TruthValue.UNKNOWN, "½"); - put(TruthValue.ERROR, "E"); - put(true, "1"); - put(false, "0"); - }}; + private static final Map truthValueToDot = Map.of( + TruthValue.TRUE, "1", + TruthValue.FALSE, "0", + TruthValue.UNKNOWN, "½", + TruthValue.ERROR, "E", + true, "1", + false, "0" + ); public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) { this.model = model; this.storeAdapter = storeAdapter; - this.interpretations = new HashMap<>(); + this.allInterpretations = new HashMap<>(); for (var symbol : storeAdapter.getStore().getSymbols()) { var arity = symbol.arity(); if (arity < 1 || arity > 2) { continue; } var interpretation = (Interpretation) model.getInterpretation(symbol); - interpretations.put(symbol, interpretation); + allInterpretations.put(symbol, interpretation); } designSpaceBuilder.append("digraph designSpace {\n"); designSpaceBuilder.append(""" + nodesep=0 + ranksep=5 node[ - style=filled - fillcolor=white + \tstyle=filled + \tfillcolor=white ] """); } @@ -90,7 +91,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { ] """); - for (var entry : interpretations.entrySet()) { + for (var entry : allInterpretations.entrySet()) { var key = entry.getKey(); var arity = key.arity(); var cursor = entry.getValue().getAll(); @@ -302,6 +303,20 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { designSpaceBuilder.append(states.get(state)).append(" [URL=\"./").append(states.get(state)).append(".svg\"]\n"); } + @Override + public void addState(Version state, Collection fitness) { + if (states.containsKey(state)) { + return; + } + states.put(state, numberOfStates++); + designSpaceBuilder.append(states.get(state)).append(" [label = \"").append(states.get(state)).append(" ("); + + for (var f : fitness) { + designSpaceBuilder.append(f).append(", "); + } + designSpaceBuilder.append(")\"\n").append("URL=\"./").append(states.get(state)).append(".svg\"]\n"); + } + @Override public void addSolution(Version state) { addState(state); @@ -329,12 +344,12 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { @Override public boolean renderDesignSpace(String path, FileFormat format) { - for (var entry : states.entrySet()) { - var stateId = entry.getValue(); - var stateDot = createDotForModelState(entry.getKey()); - saveDot(stateDot, path + "/" + stateId + ".dot"); - renderDot(stateDot, format, path + "/" + stateId + "." + format.getFormat()); - } +// for (var entry : states.entrySet()) { +// var stateId = entry.getValue(); +// var stateDot = createDotForModelState(entry.getKey()); +// saveDot(stateDot, path + "/" + stateId + ".dot"); +// renderDot(stateDot, format, path + "/" + stateId + "." + format.getFormat()); +// } var designSpaceDot = buildDesignSpaceDot(); saveDot(designSpaceDot, path + "/designSpace.dot"); return renderDot(designSpaceDot, format, path + "/designSpace." + format.getFormat()); -- cgit v1.2.3-70-g09d2 From d5d8ad817c2f7d348a1fb40ca3f627ccc4ea37d5 Mon Sep 17 00:00:00 2001 From: Attila Ficsor Date: Mon, 7 Aug 2023 15:10:07 +0200 Subject: Update visualizer builder --- .../DesignSpaceExplorationAdapterImpl.java | 10 +-- .../AlwaysSatisfiedRandomHardObjective.java | 56 ++++++++++++++ .../tools/refinery/store/dse/CRAExamplesTest.java | 11 ++- .../java/tools/refinery/store/dse/DebugTest.java | 11 ++- .../visualization/ModelVisualizerAdapter.java | 22 ++---- .../visualization/ModelVisualizerBuilder.java | 5 ++ .../visualization/ModelVisualizerStoreAdapter.java | 11 +++ .../internal/ModelVisualizeStoreAdapterImpl.java | 33 +++++++- .../internal/ModelVisualizerAdapterImpl.java | 88 +++++++++++++++------- .../internal/ModelVisualizerBuilderImpl.java | 38 +++++++++- 10 files changed, 223 insertions(+), 62 deletions(-) create mode 100644 subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedRandomHardObjective.java (limited to 'subprojects/visualization') diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java index 1329480c..008b2dab 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java @@ -96,6 +96,9 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration trajectory.add(state); strategy.initStrategy(this); strategy.explore(); + if (isVisualizationEnabled) { + modelVisualizerAdapter.visualize(); + } return solutions; } @@ -247,7 +250,7 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration isNewState = !statesAndTraversedActivations.containsKey(newState); if (isVisualizationEnabled) { if (isNewState) { - modelVisualizerAdapter.addState(newState); + modelVisualizerAdapter.addState(newState, getFitness().values()); } // TODO: Change to this: modelVisualizerAdapter.addTransition(previousState, newState, activation.transformationRule().getName(), @@ -272,11 +275,6 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration fireActivation(activationId); } - @Override - public boolean isCurrentInTrajectory() { - return trajectory.contains(model.getState()); - } - public List getAllActivations() { List result = new LinkedList<>(); for (var rule : transformationRules) { diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedRandomHardObjective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedRandomHardObjective.java new file mode 100644 index 00000000..327d5e2f --- /dev/null +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedRandomHardObjective.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2010-2016, Andras Szabolcs Nagy, Zoltan Ujhelyi and Daniel Varro + * Copyright (c) 2023 The Refinery Authors + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package tools.refinery.store.dse.objectives; + +import tools.refinery.store.dse.DesignSpaceExplorationAdapter; + +import java.util.Random; + +/** + * This hard objective is fulfilled in any circumstances. Use it if all states should be regarded as a valid solution. + * + * @author Andras Szabolcs Nagy + * + */ +public class AlwaysSatisfiedRandomHardObjective extends BaseObjective { + + private static final String DEFAULT_NAME = "AlwaysSatisfiedDummyHardObjective"; + private static final Random random = new Random(0); + + public AlwaysSatisfiedRandomHardObjective() { + super(DEFAULT_NAME); + } + + public AlwaysSatisfiedRandomHardObjective(String name) { + super(name); + } + + @Override + public Double getFitness(DesignSpaceExplorationAdapter context) { +// return 0d; + return random.nextDouble(); + } + + @Override + public boolean isHardObjective() { + return true; + } + + @Override + public boolean satisfiesHardObjective(Double fitness) { + return true; + } + + @Override + public Objective createNew() { + return this; + } + +} 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 f1e90280..23f0e703 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 @@ -188,7 +188,13 @@ class CRAExamplesTest { .queries(feature, assignFeaturePreconditionHelper, assignFeaturePrecondition, deleteEmptyClassPrecondition, createClassPreconditionHelper, createClassPrecondition, moveFeaturePrecondition)) - .with(ModelVisualizerAdapter.builder()) + .with(ModelVisualizerAdapter.builder() + .withOutputpath("test_output") + .withFormat(FileFormat.DOT) + .withFormat(FileFormat.SVG) + .saveStates() + .saveDesignSpace() + ) .with(DesignSpaceExplorationAdapter.builder() .transformations(assignFeatureRule, deleteEmptyClassRule, createClassRule, moveFeatureRule) // .strategy(new DepthFirstStrategy(3).continueIfHardObjectivesFulfilled() @@ -271,9 +277,6 @@ class CRAExamplesTest { var states = dseAdapter.explore(); System.out.println("states size: " + states.size()); - System.out.println("states: " + states); - var visualizer = model.getAdapter(ModelVisualizerAdapter.class); - visualizer.renderDesignSpace("test_output", FileFormat.SVG); } } 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 553510c8..88c4f152 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 @@ -90,7 +90,13 @@ class DebugTest { .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features) .with(ViatraModelQueryAdapter.builder() .queries(createClassPrecondition, createFeaturePrecondition)) - .with(ModelVisualizerAdapter.builder()) + .with(ModelVisualizerAdapter.builder() + .withOutputpath("test_output") + .withFormat(FileFormat.DOT) + .withFormat(FileFormat.SVG) + .saveStates() + .saveDesignSpace() + ) .with(DesignSpaceExplorationAdapter.builder() .transformations(createClassRule, createFeatureRule) .strategy(new DepthFirstStrategy(4).continueIfHardObjectivesFulfilled() @@ -113,10 +119,7 @@ class DebugTest { var states = dseAdapter.explore(); - var visualizer = model.getAdapter(ModelVisualizerAdapter.class); - visualizer.renderDesignSpace("test_output", FileFormat.SVG); System.out.println("states size: " + states.size()); - System.out.println("states: " + states); } } 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 bc32323d..ae87d8ac 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java @@ -8,9 +8,10 @@ package tools.refinery.visualization; import tools.refinery.store.adapter.ModelAdapter; import tools.refinery.store.map.Version; import tools.refinery.store.tuple.Tuple; -import tools.refinery.visualization.internal.FileFormat; import tools.refinery.visualization.internal.ModelVisualizerBuilderImpl; +import java.util.Collection; + public interface ModelVisualizerAdapter extends ModelAdapter { ModelVisualizerStoreAdapter getStoreAdapter(); @@ -18,27 +19,14 @@ public interface ModelVisualizerAdapter extends ModelAdapter { return new ModelVisualizerBuilderImpl(); } - public String createDotForCurrentModelState(); - - public String createDotForModelState(Version version); - - public boolean saveDot(String dot, String filePath); - - public boolean renderDot(String dot, String filePath); - - public boolean renderDot(String dot, FileFormat format, String filePath); - public void addTransition(Version from, Version to, String action); public void addTransition(Version from, Version to, String action, Tuple activation); public void addState(Version state); + public void addState(Version state, Collection fitness); + public void addState(Version state, String label); public void addSolution(Version state); - - public boolean saveDesignSpace(String path); - - public boolean renderDesignSpace(String path); - - public boolean renderDesignSpace(String path, FileFormat format); + public void visualize(); } diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java index 56cc425e..592f5fcf 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerBuilder.java @@ -6,6 +6,11 @@ package tools.refinery.visualization; import tools.refinery.store.adapter.ModelAdapterBuilder; +import tools.refinery.visualization.internal.FileFormat; public interface ModelVisualizerBuilder extends ModelAdapterBuilder { + ModelVisualizerBuilder withOutputpath(String outputpath); + ModelVisualizerBuilder withFormat(FileFormat format); + ModelVisualizerBuilder saveDesignSpace(); + ModelVisualizerBuilder saveStates(); } diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java index 6e6453fd..46663b2a 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerStoreAdapter.java @@ -6,6 +6,17 @@ package tools.refinery.visualization; import tools.refinery.store.adapter.ModelStoreAdapter; +import tools.refinery.visualization.internal.FileFormat; + +import java.util.Set; public interface ModelVisualizerStoreAdapter extends ModelStoreAdapter { + + String getOutputPath(); + + boolean isRenderDesignSpace(); + + boolean isRenderStates(); + + Set getFormats(); } diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java index b4db2682..04be22d6 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizeStoreAdapterImpl.java @@ -10,11 +10,22 @@ import tools.refinery.store.model.Model; import tools.refinery.store.model.ModelStore; import tools.refinery.visualization.ModelVisualizerStoreAdapter; +import java.util.Set; + public class ModelVisualizeStoreAdapterImpl implements ModelVisualizerStoreAdapter { private final ModelStore store; + private final String outputPath; + private final boolean renderDesignSpace; + private final boolean renderStates; + private final Set formats; - public ModelVisualizeStoreAdapterImpl(ModelStore store) { + public ModelVisualizeStoreAdapterImpl(ModelStore store, String outputPath, Set formats, + boolean renderDesignSpace, boolean renderStates) { this.store = store; + this.outputPath = outputPath; + this.formats = formats; + this.renderDesignSpace = renderDesignSpace; + this.renderStates = renderStates; } @Override @@ -26,4 +37,24 @@ public class ModelVisualizeStoreAdapterImpl implements ModelVisualizerStoreAdapt public ModelAdapter createModelAdapter(Model model) { return new ModelVisualizerAdapterImpl(model, this); } + + @Override + public String getOutputPath() { + return outputPath; + } + + @Override + public boolean isRenderDesignSpace() { + return renderDesignSpace; + } + + @Override + public boolean isRenderStates() { + return renderStates; + } + + @Override + public Set getFormats() { + return formats; + } } 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 efafe5a2..531969b4 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 @@ -26,6 +26,11 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { private final Map states = new HashMap<>(); private int transitionCounter = 0; private Integer numberOfStates = 0; + private final String outputPath; + private final Set formats; + private final boolean renderDesignSpace; + private final boolean renderStates; + private static final Map truthValueToDot = Map.of( TruthValue.TRUE, "1", TruthValue.FALSE, "0", @@ -38,6 +43,14 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { public ModelVisualizerAdapterImpl(Model model, ModelVisualizerStoreAdapter storeAdapter) { this.model = model; this.storeAdapter = storeAdapter; + this.outputPath = storeAdapter.getOutputPath(); + this.formats = storeAdapter.getFormats(); + if (formats.isEmpty()) { + formats.add(FileFormat.SVG); + } + this.renderDesignSpace = storeAdapter.isRenderDesignSpace(); + this.renderStates = storeAdapter.isRenderStates(); + this.allInterpretations = new HashMap<>(); for (var symbol : storeAdapter.getStore().getSymbols()) { var arity = symbol.arity(); @@ -68,8 +81,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { return storeAdapter; } - @Override - public String createDotForCurrentModelState() { + private String createDotForCurrentModelState() { var unaryTupleToInterpretationsMap = new HashMap>>(); @@ -229,8 +241,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { }; } - @Override - public String createDotForModelState(Version version) { + private String createDotForModelState(Version version) { var currentVersion = model.getState(); model.restore(version); var graph = createDotForCurrentModelState(); @@ -238,8 +249,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { return graph; } - @Override - public boolean saveDot(String dot, String filePath) { + private boolean saveDot(String dot, String filePath) { File file = new File(filePath); file.getParentFile().mkdirs(); @@ -252,13 +262,11 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { return true; } - @Override - public boolean renderDot(String dot, String filePath) { + private boolean renderDot(String dot, String filePath) { return renderDot(dot, FileFormat.SVG, filePath); } - @Override - public boolean renderDot(String dot, FileFormat format, String filePath) { + private boolean renderDot(String dot, FileFormat format, String filePath) { try { Process process = new ProcessBuilder("dot", "-T" + format.getFormat(), "-o", filePath).start(); @@ -305,15 +313,21 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { @Override public void addState(Version state, Collection fitness) { + var labelBuilder = new StringBuilder(); + for (var f : fitness) { + labelBuilder.append(f).append(", "); + } + addState(state, labelBuilder.toString()); + } + + @Override + public void addState(Version state, String label) { if (states.containsKey(state)) { return; } states.put(state, numberOfStates++); designSpaceBuilder.append(states.get(state)).append(" [label = \"").append(states.get(state)).append(" ("); - - for (var f : fitness) { - designSpaceBuilder.append(f).append(", "); - } + designSpaceBuilder.append(label); designSpaceBuilder.append(")\"\n").append("URL=\"./").append(states.get(state)).append(".svg\"]\n"); } @@ -328,8 +342,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { return designSpaceBuilder.toString(); } - @Override - public boolean saveDesignSpace(String path) { + private boolean saveDesignSpace(String path) { saveDot(buildDesignSpaceDot(), path + "/designSpace.dot"); for (var entry : states.entrySet()) { saveDot(createDotForModelState(entry.getKey()), path + "/" + entry.getValue() + ".dot"); @@ -337,21 +350,38 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { return true; } - @Override - public boolean renderDesignSpace(String path) { - return renderDesignSpace(path, FileFormat.SVG); + private void renderDesignSpace(String path, Set formats) { + File filePath = new File(path); + filePath.mkdirs(); + if (renderStates) { + for (var entry : states.entrySet()) { + var stateId = entry.getValue(); + var stateDot = createDotForModelState(entry.getKey()); + for (var format : formats) { + if (format == FileFormat.DOT) { + saveDot(stateDot, path + "/" + stateId + ".dot"); + } + else { + renderDot(stateDot, format, path + "/" + stateId + "." + format.getFormat()); + } + } + } + } + if (renderDesignSpace) { + var designSpaceDot = buildDesignSpaceDot(); + for (var format : formats) { + if (format == FileFormat.DOT) { + saveDot(designSpaceDot, path + "/designSpace.dot"); + } + else { + renderDot(designSpaceDot, format, path + "/designSpace." + format.getFormat()); + } + } + } } @Override - public boolean renderDesignSpace(String path, FileFormat format) { -// for (var entry : states.entrySet()) { -// var stateId = entry.getValue(); -// var stateDot = createDotForModelState(entry.getKey()); -// saveDot(stateDot, path + "/" + stateId + ".dot"); -// renderDot(stateDot, format, path + "/" + stateId + "." + format.getFormat()); -// } - var designSpaceDot = buildDesignSpaceDot(); - saveDot(designSpaceDot, path + "/designSpace.dot"); - return renderDot(designSpaceDot, format, path + "/designSpace." + format.getFormat()); + public void visualize() { + renderDesignSpace(outputPath, formats); } } diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java index d19cf2cf..e4d801d8 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerBuilderImpl.java @@ -9,11 +9,47 @@ import tools.refinery.store.adapter.AbstractModelAdapterBuilder; import tools.refinery.store.model.ModelStore; import tools.refinery.visualization.ModelVisualizerBuilder; +import java.util.LinkedHashSet; +import java.util.Set; + public class ModelVisualizerBuilderImpl extends AbstractModelAdapterBuilder implements ModelVisualizerBuilder { + private String outputPath; + private boolean saveDesignSpace = false; + private boolean saveStates = false; + private Set formats = new LinkedHashSet<>(); + @Override protected ModelVisualizeStoreAdapterImpl doBuild(ModelStore store) { - return new ModelVisualizeStoreAdapterImpl(store); + return new ModelVisualizeStoreAdapterImpl(store, outputPath, formats, saveDesignSpace, saveStates); + } + + @Override + public ModelVisualizerBuilder withOutputpath(String outputpath) { + checkNotConfigured(); + this.outputPath = outputpath; + return this; + } + + @Override + public ModelVisualizerBuilder withFormat(FileFormat format) { + checkNotConfigured(); + this.formats.add(format); + return this; + } + + @Override + public ModelVisualizerBuilder saveDesignSpace() { + checkNotConfigured(); + this.saveDesignSpace = true; + return this; + } + + @Override + public ModelVisualizerBuilder saveStates() { + checkNotConfigured(); + this.saveStates = true; + return this; } } -- cgit v1.2.3-70-g09d2