aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-12-24 17:28:11 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-12-24 17:41:29 +0100
commitf7c9414c4bcc8a48cbc1c25879e9c8eafe772320 (patch)
treeb3adee36064e0dcf1fefac89466b41cfc52e631b
parentchore(deps): bump dependencies (diff)
downloadrefinery-f7c9414c4bcc8a48cbc1c25879e9c8eafe772320.tar.gz
refinery-f7c9414c4bcc8a48cbc1c25879e9c8eafe772320.tar.zst
refinery-f7c9414c4bcc8a48cbc1c25879e9c8eafe772320.zip
feat: command line model generator
-rw-r--r--gradle/libs.versions.toml1
-rw-r--r--settings.gradle.kts1
-rw-r--r--subprojects/generator-cli/build.gradle.kts24
-rw-r--r--subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/RefineryCli.java64
-rw-r--r--subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/commands/GenerateCommand.java141
-rw-r--r--subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java30
-rw-r--r--subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java7
-rw-r--r--subprojects/generator/src/main/java/tools/refinery/generator/ModelSemantics.java2
-rw-r--r--subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java18
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstExplorer.java4
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java2
11 files changed, 276 insertions, 18 deletions
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index b9a750dd..e65ffc03 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -23,6 +23,7 @@ gradlePlugin-shadow = { group = "com.github.johnrengelman", name = "shadow", ver
23gradlePlugin-sonarqube = { group = "org.sonarsource.scanner.gradle", name = "sonarqube-gradle-plugin", version = "4.4.1.3373" } 23gradlePlugin-sonarqube = { group = "org.sonarsource.scanner.gradle", name = "sonarqube-gradle-plugin", version = "4.4.1.3373" }
24gson = { group = "com.google.code.gson", name = "gson", version = "2.10.1" } 24gson = { group = "com.google.code.gson", name = "gson", version = "2.10.1" }
25hamcrest = { group = "org.hamcrest", name = "hamcrest", version = "2.2" } 25hamcrest = { group = "org.hamcrest", name = "hamcrest", version = "2.2" }
26jcommander = { group = "org.jcommander", name = "jcommander", version = "1.83" }
26jetbrainsAnnotations = { group = "org.jetbrains", name = "annotations", version = "24.1.0" } 27jetbrainsAnnotations = { group = "org.jetbrains", name = "annotations", version = "24.1.0" }
27jetty-server = { group = "org.eclipse.jetty", name = "jetty-server", version.ref = "jetty" } 28jetty-server = { group = "org.eclipse.jetty", name = "jetty-server", version.ref = "jetty" }
28jetty-servlet = { group = "org.eclipse.jetty.ee10", name = "jetty-ee10-servlet", version.ref = "jetty" } 29jetty-servlet = { group = "org.eclipse.jetty.ee10", name = "jetty-ee10-servlet", version.ref = "jetty" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 40df30ff..6e5a72e9 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -9,6 +9,7 @@ rootProject.name = "refinery"
9include( 9include(
10 "frontend", 10 "frontend",
11 "generator", 11 "generator",
12 "generator-cli",
12 "interpreter", 13 "interpreter",
13 "interpreter-localsearch", 14 "interpreter-localsearch",
14 "interpreter-rete", 15 "interpreter-rete",
diff --git a/subprojects/generator-cli/build.gradle.kts b/subprojects/generator-cli/build.gradle.kts
new file mode 100644
index 00000000..6c681222
--- /dev/null
+++ b/subprojects/generator-cli/build.gradle.kts
@@ -0,0 +1,24 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6
7plugins {
8 id("tools.refinery.gradle.java-application")
9}
10
11dependencies {
12 implementation(project(":refinery-generator"))
13 implementation(libs.jcommander)
14 implementation(libs.slf4j.api)
15}
16
17application {
18 mainClass.set("tools.refinery.generator.cli.RefineryCli")
19}
20
21tasks.shadowJar {
22 // Silence Xtext warning.
23 append("plugin.properties")
24}
diff --git a/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/RefineryCli.java b/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/RefineryCli.java
new file mode 100644
index 00000000..5de579e6
--- /dev/null
+++ b/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/RefineryCli.java
@@ -0,0 +1,64 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.generator.cli;
7
8import com.beust.jcommander.JCommander;
9import com.beust.jcommander.ParameterException;
10import com.google.inject.Inject;
11import tools.refinery.generator.cli.commands.GenerateCommand;
12import tools.refinery.generator.standalone.StandaloneRefinery;
13
14import java.io.IOException;
15
16public class RefineryCli {
17 private static final String GENERATE_COMMAND = "generate";
18
19 @Inject
20 private GenerateCommand generateCommand;
21
22 private JCommander jCommander;
23
24 public String parseArguments(String... args) {
25 var jc = getJCommander();
26 jc.parse(args);
27 return jc.getParsedCommand();
28 }
29
30 public void run(String command) throws IOException {
31 switch (command) {
32 case GENERATE_COMMAND -> generateCommand.run();
33 case null, default -> showUsageAndExit();
34 }
35 }
36
37 public void showUsageAndExit() {
38 getJCommander().usage();
39 System.exit(1);
40 }
41
42 private JCommander getJCommander() {
43 if (jCommander == null) {
44 jCommander = JCommander.newBuilder()
45 .programName("refinery")
46 .addObject(this)
47 .addCommand(GENERATE_COMMAND, generateCommand)
48 .build();
49 }
50 return jCommander;
51 }
52
53 public static void main(String[] args) throws IOException {
54 var cli = StandaloneRefinery.getInjector().getInstance(RefineryCli.class);
55 String command = null;
56 try {
57 command = cli.parseArguments(args);
58 } catch (ParameterException e) {
59 System.err.println(e.getMessage());
60 cli.showUsageAndExit();
61 }
62 cli.run(command);
63 }
64}
diff --git a/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/commands/GenerateCommand.java b/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/commands/GenerateCommand.java
new file mode 100644
index 00000000..6c1d105d
--- /dev/null
+++ b/subprojects/generator-cli/src/main/java/tools/refinery/generator/cli/commands/GenerateCommand.java
@@ -0,0 +1,141 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.generator.cli.commands;
7
8import com.beust.jcommander.Parameter;
9import com.beust.jcommander.Parameters;
10import com.google.inject.Inject;
11import org.eclipse.emf.ecore.resource.Resource;
12import tools.refinery.generator.ModelGeneratorFactory;
13import tools.refinery.generator.ProblemLoader;
14import tools.refinery.language.model.problem.Problem;
15import tools.refinery.language.model.problem.Relation;
16import tools.refinery.language.model.problem.ScopeDeclaration;
17
18import java.io.ByteArrayOutputStream;
19import java.io.FileOutputStream;
20import java.io.IOException;
21import java.nio.charset.StandardCharsets;
22import java.util.ArrayList;
23import java.util.HashSet;
24import java.util.List;
25import java.util.Map;
26
27@Parameters(commandDescription = "Generate a model from a partial model")
28public class GenerateCommand {
29 @Inject
30 private ProblemLoader loader;
31
32 @Inject
33 private ModelGeneratorFactory generatorFactory;
34
35 private String problemPath;
36 private String outputPath = "-";
37 private List<String> scopes = new ArrayList<>();
38 private List<String> overrideScopes = new ArrayList<>();
39 private long randomSeed = 1;
40
41 @Parameter(description = "Input path", required = true)
42 public void setProblemPath(String problemPath) {
43 this.problemPath = problemPath;
44 }
45
46 @Parameter(names = {"-output", "-o"}, description = "Output path")
47 public void setOutputPath(String outputPath) {
48 this.outputPath = outputPath;
49 }
50
51 @Parameter(names = {"-scope", "-s"}, description = "Extra scope constraints")
52 public void setScopes(List<String> scopes) {
53 this.scopes = scopes;
54 }
55
56 @Parameter(names = {"-scope-override", "-S"}, description = "Override scope constraints")
57 public void setOverrideScopes(List<String> overrideScopes) {
58 this.overrideScopes = overrideScopes;
59 }
60
61 @Parameter(names = {"-random-seed", "-r"}, description = "Random seed")
62 public void setRandomSeed(long randomSeed) {
63 this.randomSeed = randomSeed;
64 }
65
66 public void run() throws IOException {
67 var problem = addScopeConstraints(loader.loadFile(problemPath));
68 var generator = generatorFactory.createGenerator(problem);
69 generator.setRandomSeed(randomSeed);
70 generator.generate();
71 var solution = generator.serializeSolution();
72 var solutionResource = solution.eResource();
73 var saveOptions = Map.of();
74 if (outputPath == null || outputPath.equals("-")) {
75 printSolution(solutionResource, saveOptions);
76 } else {
77 try (var outputStream = new FileOutputStream(outputPath)) {
78 solutionResource.save(outputStream, saveOptions);
79 }
80 }
81 }
82
83 private Problem addScopeConstraints(Problem problem) throws IOException {
84 var allScopes = new ArrayList<>(scopes);
85 allScopes.addAll(overrideScopes);
86 if (allScopes.isEmpty()) {
87 return problem;
88 }
89 int originalStatementCount = problem.getStatements().size();
90 var builder = new StringBuilder();
91 var problemResource = problem.eResource();
92 try (var outputStream = new ByteArrayOutputStream()) {
93 problemResource.save(outputStream, Map.of());
94 builder.append(outputStream.toString(StandardCharsets.UTF_8));
95 }
96 builder.append('\n');
97 for (var scope : allScopes) {
98 builder.append("scope ").append(scope).append(".\n");
99 }
100 var modifiedProblem = loader.loadString(builder.toString(), problemResource.getURI());
101 var modifiedStatements = modifiedProblem.getStatements();
102 int modifiedStatementCount = modifiedStatements.size();
103 if (modifiedStatementCount != originalStatementCount + allScopes.size()) {
104 throw new IllegalStateException("Failed to parse scope constraints");
105 }
106 // Override scopes remove any scope constraint from the original problem with the same target type.
107 var overriddenScopes = new HashSet<Relation>();
108 for (int i = modifiedStatementCount - overrideScopes.size(); i < modifiedStatementCount; i++) {
109 var statement = modifiedStatements.get(i);
110 if (!(statement instanceof ScopeDeclaration scopeDeclaration)) {
111 throw new IllegalStateException("Invalid scope constraint: " + statement);
112 }
113 for (var typeScope : scopeDeclaration.getTypeScopes()) {
114 overriddenScopes.add(typeScope.getTargetType());
115 }
116 }
117 int statementIndex = 0;
118 var iterator = modifiedStatements.iterator();
119 // Scope overrides only affect type scopes from the original problem and leave type scopes added on the
120 // command line intact.
121 while (statementIndex < originalStatementCount && iterator.hasNext()) {
122 var statement = iterator.next();
123 if (statement instanceof ScopeDeclaration scopeDeclaration) {
124 var typeScopes = scopeDeclaration.getTypeScopes();
125 typeScopes.removeIf(typeScope -> overriddenScopes.contains(typeScope.getTargetType()));
126 // Scope declarations with no type scopes are invalid, so we have to remove them.
127 if (typeScopes.isEmpty()) {
128 iterator.remove();
129 }
130 }
131 statementIndex++;
132 }
133 return modifiedProblem;
134 }
135
136 // We deliberately write to the standard output if no output path is specified.
137 @SuppressWarnings("squid:S106")
138 private void printSolution(Resource solutionResource, Map<?, ?> saveOptions) throws IOException {
139 solutionResource.save(System.out, saveOptions);
140 }
141}
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java
index 5b44c10a..1515dceb 100644
--- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java
+++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java
@@ -5,7 +5,10 @@
5 */ 5 */
6package tools.refinery.generator; 6package tools.refinery.generator;
7 7
8import com.google.inject.Provider;
9import tools.refinery.language.model.problem.Problem;
8import tools.refinery.language.semantics.ProblemTrace; 10import tools.refinery.language.semantics.ProblemTrace;
11import tools.refinery.language.semantics.SolutionSerializer;
9import tools.refinery.store.dse.strategy.BestFirstStoreManager; 12import tools.refinery.store.dse.strategy.BestFirstStoreManager;
10import tools.refinery.store.map.Version; 13import tools.refinery.store.map.Version;
11import tools.refinery.store.model.ModelStore; 14import tools.refinery.store.model.ModelStore;
@@ -16,21 +19,22 @@ import tools.refinery.store.reasoning.seed.ModelSeed;
16 19
17public class ModelGenerator extends ModelFacade { 20public class ModelGenerator extends ModelFacade {
18 private final Version initialVersion; 21 private final Version initialVersion;
19 22 private final Provider<SolutionSerializer> solutionSerializerProvider;
20 private int randomSeed = 0; 23 private long randomSeed = 1;
21
22 private boolean lastGenerationSuccessful; 24 private boolean lastGenerationSuccessful;
23 25
24 public ModelGenerator(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) { 26 ModelGenerator(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed,
27 Provider<SolutionSerializer> solutionSerializerProvider) {
25 super(problemTrace, store, modelSeed, Concreteness.CANDIDATE); 28 super(problemTrace, store, modelSeed, Concreteness.CANDIDATE);
29 this.solutionSerializerProvider = solutionSerializerProvider;
26 initialVersion = getModel().commit(); 30 initialVersion = getModel().commit();
27 } 31 }
28 32
29 public int getRandomSeed() { 33 public long getRandomSeed() {
30 return randomSeed; 34 return randomSeed;
31 } 35 }
32 36
33 public void setRandomSeed(int randomSeed) { 37 public void setRandomSeed(long randomSeed) {
34 this.randomSeed = randomSeed; 38 this.randomSeed = randomSeed;
35 this.lastGenerationSuccessful = false; 39 this.lastGenerationSuccessful = false;
36 } 40 }
@@ -50,7 +54,7 @@ public class ModelGenerator extends ModelFacade {
50 if (solutions.isEmpty()) { 54 if (solutions.isEmpty()) {
51 return false; 55 return false;
52 } 56 }
53 getModel().restore(solutions.get(0).version()); 57 getModel().restore(solutions.getFirst().version());
54 lastGenerationSuccessful = true; 58 lastGenerationSuccessful = true;
55 return true; 59 return true;
56 } 60 }
@@ -63,9 +67,19 @@ public class ModelGenerator extends ModelFacade {
63 67
64 @Override 68 @Override
65 public <A, C> PartialInterpretation<A, C> getPartialInterpretation(PartialSymbol<A, C> partialSymbol) { 69 public <A, C> PartialInterpretation<A, C> getPartialInterpretation(PartialSymbol<A, C> partialSymbol) {
70 checkSuccessfulGeneration();
71 return super.getPartialInterpretation(partialSymbol);
72 }
73
74 public Problem serializeSolution() {
75 checkSuccessfulGeneration();
76 var serializer = solutionSerializerProvider.get();
77 return serializer.serializeSolution(getProblemTrace(), getModel());
78 }
79
80 private void checkSuccessfulGeneration() {
66 if (!lastGenerationSuccessful) { 81 if (!lastGenerationSuccessful) {
67 throw new IllegalStateException("No generated model is available"); 82 throw new IllegalStateException("No generated model is available");
68 } 83 }
69 return super.getPartialInterpretation(partialSymbol);
70 } 84 }
71} 85}
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java
index 6642d591..587601f2 100644
--- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java
+++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java
@@ -9,6 +9,7 @@ import com.google.inject.Inject;
9import com.google.inject.Provider; 9import com.google.inject.Provider;
10import tools.refinery.language.model.problem.Problem; 10import tools.refinery.language.model.problem.Problem;
11import tools.refinery.language.semantics.ModelInitializer; 11import tools.refinery.language.semantics.ModelInitializer;
12import tools.refinery.language.semantics.SolutionSerializer;
12import tools.refinery.store.dse.propagation.PropagationAdapter; 13import tools.refinery.store.dse.propagation.PropagationAdapter;
13import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter; 14import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter;
14import tools.refinery.store.model.ModelStore; 15import tools.refinery.store.model.ModelStore;
@@ -25,6 +26,9 @@ public final class ModelGeneratorFactory {
25 @Inject 26 @Inject
26 private Provider<ModelInitializer> initializerProvider; 27 private Provider<ModelInitializer> initializerProvider;
27 28
29 @Inject
30 private Provider<SolutionSerializer> solutionSerializerProvider;
31
28 private CancellationToken cancellationToken = CancellationToken.NONE; 32 private CancellationToken cancellationToken = CancellationToken.NONE;
29 33
30 private boolean debugPartialInterpretations; 34 private boolean debugPartialInterpretations;
@@ -53,7 +57,8 @@ public final class ModelGeneratorFactory {
53 .requiredInterpretations(getRequiredInterpretations())); 57 .requiredInterpretations(getRequiredInterpretations()));
54 initializer.configureStoreBuilder(storeBuilder); 58 initializer.configureStoreBuilder(storeBuilder);
55 var store = storeBuilder.build(); 59 var store = storeBuilder.build();
56 return new ModelGenerator(initializer.getProblemTrace(), store, initializer.getModelSeed()); 60 return new ModelGenerator(initializer.getProblemTrace(), store, initializer.getModelSeed(),
61 solutionSerializerProvider);
57 } 62 }
58 63
59 private Collection<Concreteness> getRequiredInterpretations() { 64 private Collection<Concreteness> getRequiredInterpretations() {
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemantics.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemantics.java
index bc02c887..7207a509 100644
--- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemantics.java
+++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemantics.java
@@ -11,7 +11,7 @@ import tools.refinery.store.reasoning.literal.Concreteness;
11import tools.refinery.store.reasoning.seed.ModelSeed; 11import tools.refinery.store.reasoning.seed.ModelSeed;
12 12
13public class ModelSemantics extends ModelFacade { 13public class ModelSemantics extends ModelFacade {
14 public ModelSemantics(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) { 14 ModelSemantics(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) {
15 super(problemTrace, store, modelSeed, Concreteness.PARTIAL); 15 super(problemTrace, store, modelSeed, Concreteness.PARTIAL);
16 } 16 }
17} 17}
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java
index 2d93a5ad..abfbe7e6 100644
--- a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java
+++ b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java
@@ -48,21 +48,29 @@ public class ProblemLoader {
48 return this; 48 return this;
49 } 49 }
50 50
51 public Problem loadString(String problemString) throws IOException { 51 public Problem loadString(String problemString, URI uri) throws IOException {
52 try (var stream = new LazyStringInputStream(problemString)) { 52 try (var stream = new LazyStringInputStream(problemString)) {
53 return loadStream(stream); 53 return loadStream(stream, uri);
54 } 54 }
55 } 55 }
56 56
57 public Problem loadStream(InputStream inputStream) throws IOException { 57 public Problem loadString(String problemString) throws IOException {
58 return loadString(problemString, null);
59 }
60
61 public Problem loadStream(InputStream inputStream, URI uri) throws IOException {
58 var resourceSet = resourceSetProvider.get(); 62 var resourceSet = resourceSetProvider.get();
59 var uri = URI.createFileURI("__synthetic." + fileExtension); 63 var resourceUri = uri == null ? URI.createFileURI("__synthetic." + fileExtension) : uri;
60 var resource = resourceFactory.createResource(uri); 64 var resource = resourceFactory.createResource(resourceUri);
61 resourceSet.getResources().add(resource); 65 resourceSet.getResources().add(resource);
62 resource.load(inputStream, Map.of()); 66 resource.load(inputStream, Map.of());
63 return loadResource(resource); 67 return loadResource(resource);
64 } 68 }
65 69
70 public Problem loadStream(InputStream inputStream) throws IOException {
71 return loadStream(inputStream, null);
72 }
73
66 public Problem loadFile(File file) throws IOException { 74 public Problem loadFile(File file) throws IOException {
67 return loadFile(file.getAbsolutePath()); 75 return loadFile(file.getAbsolutePath());
68 } 76 }
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 ce3efb21..22f38ca9 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
@@ -10,10 +10,10 @@ import tools.refinery.store.model.Model;
10import java.util.Random; 10import java.util.Random;
11 11
12public class BestFirstExplorer extends BestFirstWorker { 12public class BestFirstExplorer extends BestFirstWorker {
13 final int id; 13 final long id;
14 Random random; 14 Random random;
15 15
16 public BestFirstExplorer(BestFirstStoreManager storeManager, Model model, int id) { 16 public BestFirstExplorer(BestFirstStoreManager storeManager, Model model, long id) {
17 super(storeManager, model); 17 super(storeManager, model);
18 this.id = id; 18 this.id = id;
19 // The use of a non-cryptographic random generator is safe here, because we only use it to direct the state 19 // The use of a non-cryptographic random generator is safe here, because we only use it to direct the state
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 3d32f84c..c20ab9a0 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
@@ -79,7 +79,7 @@ public class BestFirstStoreManager {
79 startExploration(initial, 1); 79 startExploration(initial, 1);
80 } 80 }
81 81
82 public void startExploration(Version initial, int randomSeed) { 82 public void startExploration(Version initial, long randomSeed) {
83 BestFirstExplorer bestFirstExplorer = new BestFirstExplorer(this, modelStore.createModelForState(initial), 83 BestFirstExplorer bestFirstExplorer = new BestFirstExplorer(this, modelStore.createModelForState(initial),
84 randomSeed); 84 randomSeed);
85 bestFirstExplorer.explore(); 85 bestFirstExplorer.explore();