aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar nagilooh <ficsorattila96@gmail.com>2023-09-07 17:34:37 +0200
committerLibravatar nagilooh <ficsorattila96@gmail.com>2023-09-07 17:52:34 +0200
commit741ff77e0e841cdf3fd893e1fb3d1ccccc6a83e4 (patch)
tree5670015d5e4e02ab1453fad2cf8888ac9d1a9a2d
parentMerge remote-tracking branch 'oszkar/datastructure' into datastructure (diff)
downloadrefinery-741ff77e0e841cdf3fd893e1fb3d1ccccc6a83e4.tar.gz
refinery-741ff77e0e841cdf3fd893e1fb3d1ccccc6a83e4.tar.zst
refinery-741ff77e0e841cdf3fd893e1fb3d1ccccc6a83e4.zip
fix issues with DSE framework
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstExplorer.java2
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java22
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstWorker.java64
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/EquivalenceClassStore.java1
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/AbstractEquivalenceClassStore.java7
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java7
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreWorker.java1
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/FastEquivalenceClassStore.java4
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java28
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/DebugTest.java190
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyCriterion.java5
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyObjective.java5
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomCriterion.java25
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomObjective.java23
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java13
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java61
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/statespace/VisualizationStore.java13
-rw-r--r--subprojects/visualization/src/main/java/tools/refinery/visualization/statespace/internal/VisualizationStoreImpl.java46
18 files changed, 310 insertions, 207 deletions
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstExplorer.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstExplorer.java
index 9a03b0b8..a2b6268f 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstExplorer.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstExplorer.java
@@ -36,7 +36,6 @@ public class BestFirstExplorer extends BestFirstWorker {
36 if (lastVisited == null) { 36 if (lastVisited == null) {
37 lastVisited = this.restoreToBest(); 37 lastVisited = this.restoreToBest();
38 if(lastVisited == null) { 38 if(lastVisited == null) {
39 visualizerAdapter.visualize();
40 return; 39 return;
41 } 40 }
42 } 41 }
@@ -162,7 +161,6 @@ public class BestFirstExplorer extends BestFirstWorker {
162*/ 161*/
163 } 162 }
164 // Interrupted. 163 // Interrupted.
165 visualizerAdapter.visualize();
166 164
167 } 165 }
168} 166}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java
index 3795daa4..0b9aae9c 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java
@@ -18,14 +18,20 @@ import tools.refinery.store.dse.transition.statespace.internal.ObjectivePriority
18import tools.refinery.store.dse.transition.statespace.internal.SolutionStoreImpl; 18import tools.refinery.store.dse.transition.statespace.internal.SolutionStoreImpl;
19import tools.refinery.store.map.Version; 19import tools.refinery.store.map.Version;
20import tools.refinery.store.model.ModelStore; 20import tools.refinery.store.model.ModelStore;
21import tools.refinery.store.statecoding.StateCoderResult;
21import tools.refinery.store.statecoding.StateCoderStoreAdapter; 22import tools.refinery.store.statecoding.StateCoderStoreAdapter;
23import tools.refinery.visualization.ModelVisualizerStoreAdapter;
24import tools.refinery.visualization.statespace.VisualizationStore;
25import tools.refinery.visualization.statespace.internal.VisualizationStoreImpl;
22 26
23public class BestFirstStoreManager { 27public class BestFirstStoreManager {
28
24 ModelStore modelStore; 29 ModelStore modelStore;
25 ObjectivePriorityQueue objectiveStore; 30 ObjectivePriorityQueue objectiveStore;
26 ActivationStore activationStore; 31 ActivationStore activationStore;
27 SolutionStore solutionStore; 32 SolutionStore solutionStore;
28 EquivalenceClassStore equivalenceClassStore; 33 EquivalenceClassStore equivalenceClassStore;
34 VisualizationStore visualizationStore;
29 35
30 public BestFirstStoreManager(ModelStore modelStore) { 36 public BestFirstStoreManager(ModelStore modelStore) {
31 this.modelStore = modelStore; 37 this.modelStore = modelStore;
@@ -35,17 +41,17 @@ public class BestFirstStoreManager {
35 objectiveStore = new ObjectivePriorityQueueImpl(storeAdapter.getObjectives()); 41 objectiveStore = new ObjectivePriorityQueueImpl(storeAdapter.getObjectives());
36 Procedure<VersionWithObjectiveValue> whenAllActivationsVisited = x -> objectiveStore.remove(x); 42 Procedure<VersionWithObjectiveValue> whenAllActivationsVisited = x -> objectiveStore.remove(x);
37 activationStore = new ActivationStoreImpl(storeAdapter.getTransformations().size(), whenAllActivationsVisited); 43 activationStore = new ActivationStoreImpl(storeAdapter.getTransformations().size(), whenAllActivationsVisited);
38 solutionStore = new SolutionStoreImpl(10); 44 solutionStore = new SolutionStoreImpl(50);
39 equivalenceClassStore = new FastEquivalenceClassStore(modelStore.getAdapter(StateCoderStoreAdapter.class)) { 45 equivalenceClassStore = new FastEquivalenceClassStore(modelStore.getAdapter(StateCoderStoreAdapter.class)) {
40 @Override 46 @Override
41 protected void delegate(VersionWithObjectiveValue version, int[] emptyActivations, boolean accept) { 47 protected void delegate(VersionWithObjectiveValue version, int[] emptyActivations, boolean accept) {
42 objectiveStore.submit(version); 48 throw new UnsupportedOperationException("This equivalence storage is not prepared to resolve symmetries!");
43 activationStore.markNewAsVisited(version, emptyActivations);
44 if(accept) {
45 solutionStore.submit(version);
46 }
47 } 49 }
48 }; 50 };
51 visualizationStore = new VisualizationStoreImpl();
52 }
53 public ModelStore getModelStore() {
54 return modelStore;
49 } 55 }
50 56
51 ObjectivePriorityQueue getObjectiveStore() { 57 ObjectivePriorityQueue getObjectiveStore() {
@@ -64,6 +70,10 @@ public class BestFirstStoreManager {
64 return equivalenceClassStore; 70 return equivalenceClassStore;
65 } 71 }
66 72
73 public VisualizationStore getVisualizationStore() {
74 return visualizationStore;
75 }
76
67 public void startExploration(Version initial) { 77 public void startExploration(Version initial) {
68 BestFirstExplorer bestFirstExplorer = new BestFirstExplorer(this, modelStore.createModelForState(initial), 1); 78 BestFirstExplorer bestFirstExplorer = new BestFirstExplorer(this, modelStore.createModelForState(initial), 1);
69 bestFirstExplorer.explore(); 79 bestFirstExplorer.explore();
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstWorker.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstWorker.java
index 0f1702ea..f1bec14f 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstWorker.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstWorker.java
@@ -13,7 +13,7 @@ import tools.refinery.store.map.Version;
13import tools.refinery.store.model.Model; 13import tools.refinery.store.model.Model;
14import tools.refinery.store.query.ModelQueryAdapter; 14import tools.refinery.store.query.ModelQueryAdapter;
15import tools.refinery.store.statecoding.StateCoderAdapter; 15import tools.refinery.store.statecoding.StateCoderAdapter;
16import tools.refinery.visualization.ModelVisualizerAdapter; 16import tools.refinery.visualization.statespace.VisualizationStore;
17 17
18import java.util.Random; 18import java.util.Random;
19 19
@@ -24,7 +24,7 @@ public class BestFirstWorker {
24 final StateCoderAdapter stateCoderAdapter; 24 final StateCoderAdapter stateCoderAdapter;
25 final DesignSpaceExplorationAdapter explorationAdapter; 25 final DesignSpaceExplorationAdapter explorationAdapter;
26 final ModelQueryAdapter queryAdapter; 26 final ModelQueryAdapter queryAdapter;
27 final ModelVisualizerAdapter visualizerAdapter; 27 final VisualizationStore visualizationStore;
28 final boolean isVisualizationEnabled; 28 final boolean isVisualizationEnabled;
29 29
30 public BestFirstWorker(BestFirstStoreManager storeManager, Model model) { 30 public BestFirstWorker(BestFirstStoreManager storeManager, Model model) {
@@ -36,9 +36,8 @@ public class BestFirstWorker {
36 queryAdapter = model.getAdapter(ModelQueryAdapter.class); 36 queryAdapter = model.getAdapter(ModelQueryAdapter.class);
37 activationStoreWorker = new ActivationStoreWorker(storeManager.getActivationStore(), 37 activationStoreWorker = new ActivationStoreWorker(storeManager.getActivationStore(),
38 explorationAdapter.getTransformations()); 38 explorationAdapter.getTransformations());
39 visualizerAdapter = model.getAdapter(ModelVisualizerAdapter.class); 39 visualizationStore = storeManager.getVisualizationStore();
40 System.out.println("visualizerAdapter = " + visualizerAdapter); 40 isVisualizationEnabled = visualizationStore != null;
41 isVisualizationEnabled = visualizerAdapter != null;
42 } 41 }
43 42
44 private VersionWithObjectiveValue last = null; 43 private VersionWithObjectiveValue last = null;
@@ -47,28 +46,41 @@ public class BestFirstWorker {
47 46
48 public SubmitResult submit() { 47 public SubmitResult submit() {
49 if (explorationAdapter.checkExclude()) { 48 if (explorationAdapter.checkExclude()) {
50 last = null;
51 return new SubmitResult(false, false, null, null); 49 return new SubmitResult(false, false, null, null);
52 } 50 }
53 51
54 Version version = model.commit();
55 queryAdapter.flushChanges();
56 ObjectiveValue objectiveValue = explorationAdapter.getObjectiveValue();
57 last = new VersionWithObjectiveValue(version, objectiveValue);
58 var code = stateCoderAdapter.calculateStateCode(); 52 var code = stateCoderAdapter.calculateStateCode();
59 var accepted = explorationAdapter.checkAccept(); 53
60 boolean isNew = storeManager.getEquivalenceClassStore().submit(last, code, 54 boolean isNew = storeManager.getEquivalenceClassStore().submit(code);
61 activationStoreWorker.calculateEmptyActivationSize(), accepted); 55 if (isNew) {
62 return new SubmitResult(isNew, accepted, objectiveValue, isNew ? last : null); 56 Version version = model.commit();
57 ObjectiveValue objectiveValue = explorationAdapter.getObjectiveValue();
58 var versionWithObjectiveValue = new VersionWithObjectiveValue(version, objectiveValue);
59 last = versionWithObjectiveValue;
60 var accepted = explorationAdapter.checkAccept();
61
62 storeManager.getObjectiveStore().submit(versionWithObjectiveValue);
63 storeManager.getActivationStore().markNewAsVisited(versionWithObjectiveValue, activationStoreWorker.calculateEmptyActivationSize());
64 if(accepted) {
65 storeManager.solutionStore.submit(versionWithObjectiveValue);
66 }
67
68 if (isVisualizationEnabled) {
69 visualizationStore.addState(last.version(), last.objectiveValue().toString());
70 if (accepted) {
71 visualizationStore.addSolution(last.version());
72 }
73 }
74
75 return new SubmitResult(true, accepted, objectiveValue, last);
76 }
77
78 return new SubmitResult(false, false, null, null);
63 } 79 }
64 80
65 public void restoreToLast() { 81 public void restoreToLast() {
66 if (explorationAdapter.getModel().hasUncommittedChanges()) { 82 if (explorationAdapter.getModel().hasUncommittedChanges()) {
67 var oldVersion = model.getState();
68 explorationAdapter.getModel().restore(last.version()); 83 explorationAdapter.getModel().restore(last.version());
69 if (isVisualizationEnabled) {
70 visualizerAdapter.addTransition(oldVersion, last.version(), "");
71 }
72 } 84 }
73 } 85 }
74 86
@@ -78,7 +90,7 @@ public class BestFirstWorker {
78 var oldVersion = model.getState(); 90 var oldVersion = model.getState();
79 this.model.restore(bestVersion.version()); 91 this.model.restore(bestVersion.version());
80 if (isVisualizationEnabled) { 92 if (isVisualizationEnabled) {
81 visualizerAdapter.addTransition(oldVersion, last.version(), ""); 93 visualizationStore.addTransition(oldVersion, last.version(), "");
82 } 94 }
83 } 95 }
84 return bestVersion; 96 return bestVersion;
@@ -105,7 +117,7 @@ public class BestFirstWorker {
105 } 117 }
106 } 118 }
107 119
108 record RandomVisitResult(SubmitResult submitResult, boolean shouldRetry) { 120 public record RandomVisitResult(SubmitResult submitResult, boolean shouldRetry) {
109 } 121 }
110 122
111 public RandomVisitResult visitRandomUnvisited(Random random) { 123 public RandomVisitResult visitRandomUnvisited(Random random) {
@@ -119,15 +131,9 @@ public class BestFirstWorker {
119 oldVersion = last.version(); 131 oldVersion = last.version();
120 } 132 }
121 var submitResult = submit(); 133 var submitResult = submit();
122 if (isVisualizationEnabled) { 134 if (isVisualizationEnabled && submitResult.newVersion() != null) {
123 135 var newVersion = submitResult.newVersion().version();
124 Version newVersion = null; 136 visualizationStore.addTransition(oldVersion, newVersion, "");
125 if (submitResult.newVersion() != null) {
126 newVersion = submitResult.newVersion().version();
127 visualizerAdapter.addState(newVersion, submitResult.newVersion().objectiveValue().toString());
128 visualizerAdapter.addSolution(newVersion);
129 }
130 visualizerAdapter.addTransition(oldVersion, newVersion, "");
131 } 137 }
132 return new RandomVisitResult(submitResult, visitResult.mayHaveMore()); 138 return new RandomVisitResult(submitResult, visitResult.mayHaveMore());
133 } else { 139 } else {
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/EquivalenceClassStore.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/EquivalenceClassStore.java
index bbe26fe5..28d1488b 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/EquivalenceClassStore.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/EquivalenceClassStore.java
@@ -10,6 +10,7 @@ import tools.refinery.store.statecoding.StateCoderResult;
10 10
11public interface EquivalenceClassStore { 11public interface EquivalenceClassStore {
12 boolean submit(VersionWithObjectiveValue version, StateCoderResult stateCoderResult, int[] emptyActivations, boolean accept); 12 boolean submit(VersionWithObjectiveValue version, StateCoderResult stateCoderResult, int[] emptyActivations, boolean accept);
13 boolean submit(StateCoderResult stateCoderResult);
13 boolean hasUnresolvedSymmetry(); 14 boolean hasUnresolvedSymmetry();
14 void resolveOneSymmetry(); 15 void resolveOneSymmetry();
15 int getNumberOfUnresolvedSymmetries(); 16 int getNumberOfUnresolvedSymmetries();
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/AbstractEquivalenceClassStore.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/AbstractEquivalenceClassStore.java
index 8466a0f3..b5087e86 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/AbstractEquivalenceClassStore.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/AbstractEquivalenceClassStore.java
@@ -22,6 +22,13 @@ public abstract class AbstractEquivalenceClassStore implements EquivalenceClassS
22 protected abstract boolean tryToAdd(StateCoderResult stateCoderResult, VersionWithObjectiveValue newVersion, 22 protected abstract boolean tryToAdd(StateCoderResult stateCoderResult, VersionWithObjectiveValue newVersion,
23 int[] emptyActivations, boolean accept); 23 int[] emptyActivations, boolean accept);
24 24
25 public abstract boolean tryToAdd(StateCoderResult stateCoderResult);
26
27 @Override
28 public boolean submit(StateCoderResult stateCoderResult) {
29 return tryToAdd(stateCoderResult);
30 }
31
25 @Override 32 @Override
26 public synchronized boolean submit(VersionWithObjectiveValue version, StateCoderResult stateCoderResult, 33 public synchronized boolean submit(VersionWithObjectiveValue version, StateCoderResult stateCoderResult,
27 int[] emptyActivations, boolean accept) { 34 int[] emptyActivations, boolean accept) {
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java
index fbd5b17f..9186741f 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java
@@ -69,7 +69,7 @@ public class ActivationStoreImpl implements ActivationStore {
69 if(!hasMoreInActivation) { 69 if(!hasMoreInActivation) {
70 boolean hasMoreInOtherTransformation = false; 70 boolean hasMoreInOtherTransformation = false;
71 for (var e : entries) { 71 for (var e : entries) {
72 if (e != entry && e.getNumberOfVisitedActivations() > 0) { 72 if (e != entry && e.getNumberOfUnvisitedActivations() > 0) {
73 hasMoreInOtherTransformation = true; 73 hasMoreInOtherTransformation = true;
74 break; 74 break;
75 } 75 }
@@ -108,6 +108,11 @@ public class ActivationStoreImpl implements ActivationStore {
108 sum1 += entry.getNumberOfUnvisitedActivations(); 108 sum1 += entry.getNumberOfUnvisitedActivations();
109 } 109 }
110 110
111 if(sum1 == 0) {
112 this.actionWhenAllActivationVisited.accept(version);
113 return new VisitResult(false, false, -1, -1);
114 }
115
111 int selected = random.nextInt(sum1); 116 int selected = random.nextInt(sum1);
112 int sum2 = 0; 117 int sum2 = 0;
113 int transformation = 0; 118 int transformation = 0;
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreWorker.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreWorker.java
index e05f5122..881b133c 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreWorker.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreWorker.java
@@ -8,7 +8,6 @@ package tools.refinery.store.dse.transition.statespace.internal;
8import tools.refinery.store.dse.transition.Transformation; 8import tools.refinery.store.dse.transition.Transformation;
9import tools.refinery.store.dse.transition.VersionWithObjectiveValue; 9import tools.refinery.store.dse.transition.VersionWithObjectiveValue;
10import tools.refinery.store.dse.transition.statespace.ActivationStore; 10import tools.refinery.store.dse.transition.statespace.ActivationStore;
11import tools.refinery.store.map.Version;
12 11
13import java.util.List; 12import java.util.List;
14import java.util.Random; 13import java.util.Random;
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/FastEquivalenceClassStore.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/FastEquivalenceClassStore.java
index faeedba5..6eba87d4 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/FastEquivalenceClassStore.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/FastEquivalenceClassStore.java
@@ -26,6 +26,10 @@ public abstract class FastEquivalenceClassStore extends AbstractEquivalenceClass
26 return this.codes.add(stateCoderResult.modelCode()); 26 return this.codes.add(stateCoderResult.modelCode());
27 } 27 }
28 28
29 public synchronized boolean tryToAdd(StateCoderResult stateCoderResult) {
30 return this.codes.add(stateCoderResult.modelCode());
31 }
32
29 @Override 33 @Override
30 public void resolveOneSymmetry() { 34 public void resolveOneSymmetry() {
31 throw new IllegalArgumentException("This equivalence storage is not prepared to resolve symmetries!"); 35 throw new IllegalArgumentException("This equivalence storage is not prepared to resolve symmetries!");
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 f4c38b18..831b9ff0 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
@@ -9,6 +9,8 @@ import org.junit.jupiter.api.Disabled;
9import org.junit.jupiter.api.Test; 9import org.junit.jupiter.api.Test;
10import tools.refinery.store.dse.modification.ModificationAdapter; 10import tools.refinery.store.dse.modification.ModificationAdapter;
11import tools.refinery.store.dse.strategy.BestFirstStoreManager; 11import tools.refinery.store.dse.strategy.BestFirstStoreManager;
12import tools.refinery.store.dse.tests.DummyRandomCriterion;
13import tools.refinery.store.dse.tests.DummyRandomObjective;
12import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter; 14import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter;
13import tools.refinery.store.dse.tests.DummyCriterion; 15import tools.refinery.store.dse.tests.DummyCriterion;
14import tools.refinery.store.dse.tests.DummyObjective; 16import tools.refinery.store.dse.tests.DummyObjective;
@@ -188,7 +190,7 @@ class CRAExamplesTest {
188 }); 190 });
189 191
190 @Test 192 @Test
191// @Disabled("This test is only for debugging purposes") 193 @Disabled("This test is only for debugging purposes")
192 void craTest() { 194 void craTest() {
193 var store = ModelStore.builder() 195 var store = ModelStore.builder()
194 .symbols(classElement, encapsulates, classes, features, attribute, method, dataDependency, 196 .symbols(classElement, encapsulates, classes, features, attribute, method, dataDependency,
@@ -197,24 +199,20 @@ class CRAExamplesTest {
197 .queries(feature, assignFeaturePreconditionHelper, assignFeaturePrecondition, 199 .queries(feature, assignFeaturePreconditionHelper, assignFeaturePrecondition,
198 deleteEmptyClassPrecondition, createClassPreconditionHelper, createClassPrecondition, 200 deleteEmptyClassPrecondition, createClassPreconditionHelper, createClassPrecondition,
199 moveFeaturePrecondition)) 201 moveFeaturePrecondition))
200// .with(ModelVisualizerAdapter.builder() 202 .with(ModelVisualizerAdapter.builder()
201// .withOutputpath("test_output") 203 .withOutputpath("test_output")
202// .withFormat(FileFormat.DOT) 204 .withFormat(FileFormat.DOT)
203// .withFormat(FileFormat.SVG) 205 .withFormat(FileFormat.SVG)
204// .saveStates() 206 .saveStates()
205// .saveDesignSpace() 207 .saveDesignSpace()
206// ) 208 )
207 .with(StateCoderAdapter.builder()) 209 .with(StateCoderAdapter.builder())
208 .with(ModificationAdapter.builder()) 210 .with(ModificationAdapter.builder())
209 .with(DesignSpaceExplorationAdapter.builder() 211 .with(DesignSpaceExplorationAdapter.builder()
210 .transformations(assignFeatureRule, deleteEmptyClassRule, createClassRule, moveFeatureRule) 212 .transformations(assignFeatureRule, deleteEmptyClassRule, createClassRule, moveFeatureRule)
211 .objectives(new DummyObjective()) 213 .objectives(new DummyRandomObjective())
212 .accept(new DummyCriterion(true)) 214 .accept(new DummyRandomCriterion())
213 .exclude(new DummyCriterion(false)) 215 .exclude(new DummyCriterion(false))
214// .objectives(new AlwaysSatisfiedRandomHardObjective())
215// .strategy(new DepthFirstStrategy().withDepthLimit(3).continueIfHardObjectivesFulfilled()
216// .strategy(new BestFirstStrategy().withDepthLimit(6).continueIfHardObjectivesFulfilled()
217// .goOnOnlyIfFitnessIsBetter())
218 ) 216 )
219 .build(); 217 .build();
220 218
@@ -296,7 +294,5 @@ class CRAExamplesTest {
296 bestFirst.startExploration(initialVersion); 294 bestFirst.startExploration(initialVersion);
297 var resultStore = bestFirst.getSolutionStore(); 295 var resultStore = bestFirst.getSolutionStore();
298 System.out.println("states size: " + resultStore.getSolutions().size()); 296 System.out.println("states size: " + resultStore.getSolutions().size());
299 var modelVisualizerAdapter = model.getAdapter(ModelVisualizerAdapter.class);
300 modelVisualizerAdapter.visualize();
301 } 297 }
302} 298}
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 1d757a5f..87c3892a 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
@@ -5,9 +5,27 @@
5 */ 5 */
6package tools.refinery.store.dse; 6package tools.refinery.store.dse;
7 7
8import org.junit.jupiter.api.Disabled;
9import org.junit.jupiter.api.Test;
10import tools.refinery.store.dse.modification.ModificationAdapter;
11import tools.refinery.store.dse.strategy.BestFirstStoreManager;
12import tools.refinery.store.dse.tests.DummyCriterion;
13import tools.refinery.store.dse.tests.DummyObjective;
14import tools.refinery.store.dse.tests.DummyRandomCriterion;
15import tools.refinery.store.dse.tests.DummyRandomObjective;
16import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter;
17import tools.refinery.store.dse.transition.TransformationRule;
18import tools.refinery.store.model.ModelStore;
19import tools.refinery.store.query.ModelQueryAdapter;
20import tools.refinery.store.query.dnf.Query;
21import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
8import tools.refinery.store.query.view.AnySymbolView; 22import tools.refinery.store.query.view.AnySymbolView;
9import tools.refinery.store.query.view.KeyOnlyView; 23import tools.refinery.store.query.view.KeyOnlyView;
10import tools.refinery.store.representation.Symbol; 24import tools.refinery.store.representation.Symbol;
25import tools.refinery.store.statecoding.StateCoderAdapter;
26import tools.refinery.store.tuple.Tuple;
27import tools.refinery.visualization.ModelVisualizerAdapter;
28import tools.refinery.visualization.internal.FileFormat;
11 29
12class DebugTest { 30class DebugTest {
13 private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1); 31 private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1);
@@ -29,88 +47,92 @@ class DebugTest {
29 private static final AnySymbolView classesView = new KeyOnlyView<>(classes); 47 private static final AnySymbolView classesView = new KeyOnlyView<>(classes);
30 48
31 49
32// @Test 50 @Test
33// @Disabled("This test is only for debugging purposes") 51 @Disabled("This test is only for debugging purposes")
34// void BFSTest() { 52 void BFSTest() {
35// var createClassPrecondition = Query.of("CreateClassPrecondition", 53 var createClassPrecondition = Query.of("CreateClassPrecondition",
36// (builder, model) -> builder.clause( 54 (builder, model) -> builder.clause(
37// classModelView.call(model) 55 classModelView.call(model)
38// )); 56 ));
39// 57
40// var createClassRule = new TransformationRule("CreateClass", 58 var createClassRule = new TransformationRule("CreateClass",
41// createClassPrecondition, 59 createClassPrecondition,
42// (model) -> { 60 (model) -> {
43// var classesInterpretation = model.getInterpretation(classes); 61 var classesInterpretation = model.getInterpretation(classes);
44// var classElementInterpretation = model.getInterpretation(classElement); 62 var classElementInterpretation = model.getInterpretation(classElement);
45// return ((Tuple activation) -> { 63 return ((Tuple activation) -> {
46// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); 64 var dseAdapter = model.getAdapter(ModificationAdapter.class);
47// var modelElement = activation.get(0); 65 var modelElement = activation.get(0);
48// 66
49// var newClassElement = dseAdapter.createObject(); 67 var newClassElement = dseAdapter.createObject();
50// var newClassElementId = newClassElement.get(0); 68 var newClassElementId = newClassElement.get(0);
51// 69
52// classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true); 70 classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
53// classElementInterpretation.put(Tuple.of(newClassElementId), true); 71 classElementInterpretation.put(Tuple.of(newClassElementId), true);
54// }); 72 });
55// }); 73 });
56// 74
57// var createFeaturePrecondition = Query.of("CreateFeaturePrecondition", 75 var createFeaturePrecondition = Query.of("CreateFeaturePrecondition",
58// (builder, model) -> builder.clause( 76 (builder, model) -> builder.clause(
59// classModelView.call(model) 77 classModelView.call(model)
60// )); 78 ));
61// 79
62// var createFeatureRule = new TransformationRule("CreateFeature", 80 var createFeatureRule = new TransformationRule("CreateFeature",
63// createFeaturePrecondition, 81 createFeaturePrecondition,
64// (model) -> { 82 (model) -> {
65// var featuresInterpretation = model.getInterpretation(features); 83 var featuresInterpretation = model.getInterpretation(features);
66// var featureInterpretation = model.getInterpretation(feature); 84 var featureInterpretation = model.getInterpretation(feature);
67// return ((Tuple activation) -> { 85 return ((Tuple activation) -> {
68// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); 86 var dseAdapter = model.getAdapter(ModificationAdapter.class);
69// var modelElement = activation.get(0); 87 var modelElement = activation.get(0);
70// 88
71// var newClassElement = dseAdapter.createObject(); 89 var newClassElement = dseAdapter.createObject();
72// var newClassElementId = newClassElement.get(0); 90 var newClassElementId = newClassElement.get(0);
73// 91
74// featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true); 92 featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
75// featureInterpretation.put(Tuple.of(newClassElementId), true); 93 featureInterpretation.put(Tuple.of(newClassElementId), true);
76// }); 94 });
77// }); 95 });
78// 96
79// var store = ModelStore.builder() 97 var store = ModelStore.builder()
80// .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features) 98 .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features)
81// .with(ViatraModelQueryAdapter.builder() 99 .with(ViatraModelQueryAdapter.builder()
82// .queries(createClassPrecondition, createFeaturePrecondition)) 100 .queries(createClassPrecondition, createFeaturePrecondition))
83// .with(ModelVisualizerAdapter.builder() 101 .with(ModelVisualizerAdapter.builder()
84// .withOutputpath("test_output") 102 .withOutputpath("test_output")
85// .withFormat(FileFormat.DOT) 103 .withFormat(FileFormat.DOT)
86// .withFormat(FileFormat.SVG) 104 .withFormat(FileFormat.SVG)
87// .saveStates() 105 .saveStates()
88// .saveDesignSpace() 106 .saveDesignSpace()
89// ) 107 )
90// .with(DesignSpaceExplorationAdapter.builder() 108 .with(StateCoderAdapter.builder())
91// .transformations(createClassRule, createFeatureRule) 109 .with(ModificationAdapter.builder())
92// .objectives(new AlwaysSatisfiedRandomHardObjective()) 110 .with(DesignSpaceExplorationAdapter.builder()
93// .strategy(new DepthFirstStrategy().withDepthLimit(4).continueIfHardObjectivesFulfilled() 111 .transformations(createClassRule, createFeatureRule)
94//// .strategy(new BestFirstStrategy().withDepthLimit(4).continueIfHardObjectivesFulfilled() 112 .objectives(new DummyRandomObjective())
95//// .goOnOnlyIfFitnessIsBetter() 113 .accept(new DummyRandomCriterion())
96// )) 114 .exclude(new DummyRandomCriterion())
97// .build(); 115 )
98// 116 .build();
99// var model = store.createEmptyModel(); 117
100// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); 118 var model = store.createEmptyModel();
101//// dseAdapter.setRandom(1); 119 var dseAdapter = model.getAdapter(ModificationAdapter.class);
102// var queryEngine = model.getAdapter(ModelQueryAdapter.class); 120// dseAdapter.setRandom(1);
103// 121 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
104// var modelElementInterpretation = model.getInterpretation(classModel); 122
105// var classElementInterpretation = model.getInterpretation(classElement); 123 var modelElementInterpretation = model.getInterpretation(classModel);
106// var modelElement = dseAdapter.createObject(); 124 var classElementInterpretation = model.getInterpretation(classElement);
107// modelElementInterpretation.put(modelElement, true); 125 var modelElement = dseAdapter.createObject();
108// classElementInterpretation.put(modelElement, true); 126 modelElementInterpretation.put(modelElement, true);
109// queryEngine.flushChanges(); 127 classElementInterpretation.put(modelElement, true);
110// 128 var initialVersion = model.commit();
111// 129 queryEngine.flushChanges();
112// var states = dseAdapter.explore(); 130
113// System.out.println("states size: " + states.size()); 131
114// 132 var bestFirst = new BestFirstStoreManager(store);
115// } 133 bestFirst.startExploration(initialVersion);
134 var resultStore = bestFirst.getSolutionStore();
135 System.out.println("states size: " + resultStore.getSolutions().size());
136
137 }
116} 138}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyCriterion.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyCriterion.java
index 6bcbd1c3..2d5a0f36 100644
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyCriterion.java
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyCriterion.java
@@ -1,3 +1,8 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
1package tools.refinery.store.dse.tests; 6package tools.refinery.store.dse.tests;
2 7
3import tools.refinery.store.dse.transition.objectives.Criterion; 8import tools.refinery.store.dse.transition.objectives.Criterion;
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyObjective.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyObjective.java
index 77a23d62..f5d281aa 100644
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyObjective.java
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyObjective.java
@@ -1,3 +1,8 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
1package tools.refinery.store.dse.tests; 6package tools.refinery.store.dse.tests;
2 7
3import tools.refinery.store.dse.transition.objectives.Objective; 8import tools.refinery.store.dse.transition.objectives.Objective;
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomCriterion.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomCriterion.java
new file mode 100644
index 00000000..71fd4403
--- /dev/null
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomCriterion.java
@@ -0,0 +1,25 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.tests;
7
8import tools.refinery.store.dse.transition.objectives.Criterion;
9import tools.refinery.store.dse.transition.objectives.CriterionCalculator;
10import tools.refinery.store.model.Model;
11
12import java.util.Random;
13
14public class DummyRandomCriterion implements Criterion {
15
16 @SuppressWarnings("squid:S2245")
17 private static final Random random = new Random(9856654);
18 public DummyRandomCriterion() {
19 }
20
21 @Override
22 public CriterionCalculator createCalculator(Model model) {
23 return random::nextBoolean;
24 }
25}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomObjective.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomObjective.java
new file mode 100644
index 00000000..219e74c6
--- /dev/null
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/DummyRandomObjective.java
@@ -0,0 +1,23 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.tests;
7
8import tools.refinery.store.dse.transition.objectives.Objective;
9import tools.refinery.store.dse.transition.objectives.ObjectiveCalculator;
10import tools.refinery.store.model.Model;
11
12import java.util.Random;
13
14public class DummyRandomObjective implements Objective {
15
16 @SuppressWarnings("squid:S2245")
17 private static final Random random = new Random(9856654);
18
19 @Override
20 public ObjectiveCalculator createCalculator(Model model) {
21 return random::nextDouble;
22 }
23}
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java
index ae87d8ac..ad80bbc6 100644
--- a/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/ModelVisualizerAdapter.java
@@ -9,6 +9,7 @@ import tools.refinery.store.adapter.ModelAdapter;
9import tools.refinery.store.map.Version; 9import tools.refinery.store.map.Version;
10import tools.refinery.store.tuple.Tuple; 10import tools.refinery.store.tuple.Tuple;
11import tools.refinery.visualization.internal.ModelVisualizerBuilderImpl; 11import tools.refinery.visualization.internal.ModelVisualizerBuilderImpl;
12import tools.refinery.visualization.statespace.VisualizationStore;
12 13
13import java.util.Collection; 14import java.util.Collection;
14 15
@@ -18,15 +19,5 @@ public interface ModelVisualizerAdapter extends ModelAdapter {
18 static ModelVisualizerBuilder builder() { 19 static ModelVisualizerBuilder builder() {
19 return new ModelVisualizerBuilderImpl(); 20 return new ModelVisualizerBuilderImpl();
20 } 21 }
21 22 void visualize(VisualizationStore visualizationStore);
22 public void addTransition(Version from, Version to, String action);
23
24
25 public void addTransition(Version from, Version to, String action, Tuple activation);
26 public void addState(Version state);
27 public void addState(Version state, Collection<Double> fitness);
28 public void addState(Version state, String label);
29 public void addSolution(Version state);
30 public void visualize();
31
32} 23}
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 531969b4..031b2e6b 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
@@ -13,6 +13,7 @@ import tools.refinery.store.representation.TruthValue;
13import tools.refinery.store.tuple.Tuple; 13import tools.refinery.store.tuple.Tuple;
14import tools.refinery.visualization.ModelVisualizerAdapter; 14import tools.refinery.visualization.ModelVisualizerAdapter;
15import tools.refinery.visualization.ModelVisualizerStoreAdapter; 15import tools.refinery.visualization.ModelVisualizerStoreAdapter;
16import tools.refinery.visualization.statespace.VisualizationStore;
16 17
17import java.io.*; 18import java.io.*;
18import java.util.*; 19import java.util.*;
@@ -281,62 +282,6 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
281 return true; 282 return true;
282 } 283 }
283 284
284 @Override
285 public void addTransition(Version from, Version to, String action) {
286 designSpaceBuilder.append(states.get(from)).append(" -> ").append(states.get(to))
287 .append(" [label=\"").append(transitionCounter++).append(": ").append(action).append("\"]\n");
288 }
289
290 @Override
291 public void addTransition(Version from, Version to, String action, Tuple activation) {
292 designSpaceBuilder.append(states.get(from)).append(" -> ").append(states.get(to))
293 .append(" [label=\"").append(transitionCounter++).append(": ").append(action).append(" / ");
294
295
296 for (int i = 0; i < activation.getSize(); i++) {
297 designSpaceBuilder.append(activation.get(i));
298 if (i < activation.getSize() - 1) {
299 designSpaceBuilder.append(", ");
300 }
301 }
302 designSpaceBuilder.append("\"]\n");
303 }
304
305 @Override
306 public void addState(Version state) {
307 if (states.containsKey(state)) {
308 return;
309 }
310 states.put(state, numberOfStates++);
311 designSpaceBuilder.append(states.get(state)).append(" [URL=\"./").append(states.get(state)).append(".svg\"]\n");
312 }
313
314 @Override
315 public void addState(Version state, Collection<Double> fitness) {
316 var labelBuilder = new StringBuilder();
317 for (var f : fitness) {
318 labelBuilder.append(f).append(", ");
319 }
320 addState(state, labelBuilder.toString());
321 }
322
323 @Override
324 public void addState(Version state, String label) {
325 if (states.containsKey(state)) {
326 return;
327 }
328 states.put(state, numberOfStates++);
329 designSpaceBuilder.append(states.get(state)).append(" [label = \"").append(states.get(state)).append(" (");
330 designSpaceBuilder.append(label);
331 designSpaceBuilder.append(")\"\n").append("URL=\"./").append(states.get(state)).append(".svg\"]\n");
332 }
333
334 @Override
335 public void addSolution(Version state) {
336 addState(state);
337 designSpaceBuilder.append(states.get(state)).append(" [shape = doublecircle]\n");
338 }
339
340 private String buildDesignSpaceDot() { 285 private String buildDesignSpaceDot() {
341 designSpaceBuilder.append("}"); 286 designSpaceBuilder.append("}");
342 return designSpaceBuilder.toString(); 287 return designSpaceBuilder.toString();
@@ -381,7 +326,9 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter {
381 } 326 }
382 327
383 @Override 328 @Override
384 public void visualize() { 329 public void visualize(VisualizationStore visualizationStore) {
330 this.designSpaceBuilder.append(visualizationStore.getDesignSpaceStringBuilder());
331 this.states.putAll(visualizationStore.getStates());
385 renderDesignSpace(outputPath, formats); 332 renderDesignSpace(outputPath, formats);
386 } 333 }
387} 334}
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/statespace/VisualizationStore.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/statespace/VisualizationStore.java
new file mode 100644
index 00000000..0bf9d4a5
--- /dev/null
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/statespace/VisualizationStore.java
@@ -0,0 +1,13 @@
1package tools.refinery.visualization.statespace;
2
3import tools.refinery.store.map.Version;
4
5import java.util.Map;
6
7public interface VisualizationStore {
8 void addState(Version state, String label);
9 void addSolution(Version state);
10 void addTransition(Version from, Version to, String label);
11 StringBuilder getDesignSpaceStringBuilder();
12 Map<Version, Integer> getStates();
13}
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/statespace/internal/VisualizationStoreImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/statespace/internal/VisualizationStoreImpl.java
new file mode 100644
index 00000000..13794667
--- /dev/null
+++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/statespace/internal/VisualizationStoreImpl.java
@@ -0,0 +1,46 @@
1package tools.refinery.visualization.statespace.internal;
2
3import tools.refinery.store.map.Version;
4import tools.refinery.visualization.statespace.VisualizationStore;
5
6import java.util.HashMap;
7import java.util.Map;
8
9public class VisualizationStoreImpl implements VisualizationStore {
10
11 private final Map<Version, Integer> states = new HashMap<>();
12 private int transitionCounter = 0;
13 private Integer numberOfStates = 0;
14 private final StringBuilder designSpaceBuilder = new StringBuilder();
15
16 @Override
17 public synchronized void addState(Version state, String label) {
18 if (states.containsKey(state)) {
19 return;
20 }
21 states.put(state, numberOfStates++);
22 designSpaceBuilder.append(states.get(state)).append(" [label = \"").append(states.get(state)).append(" (");
23 designSpaceBuilder.append(label);
24 designSpaceBuilder.append(")\"\n").append("URL=\"./").append(states.get(state)).append(".svg\"]\n");
25 }
26
27 @Override
28 public synchronized void addSolution(Version state) {
29 designSpaceBuilder.append(states.get(state)).append(" [peripheries = 2]\n");
30 }
31
32 @Override
33 public synchronized void addTransition(Version from, Version to, String label) {
34 designSpaceBuilder.append(states.get(from)).append(" -> ").append(states.get(to))
35 .append(" [label=\"").append(transitionCounter++).append(": ").append(label).append("\"]\n");
36 }
37
38 public synchronized StringBuilder getDesignSpaceStringBuilder() {
39 return designSpaceBuilder;
40 }
41
42 @Override
43 public Map<Version, Integer> getStates() {
44 return states;
45 }
46}