diff options
author | 2023-11-03 19:12:08 +0100 | |
---|---|---|
committer | 2023-11-03 19:12:19 +0100 | |
commit | 32d469d0284d1ab1540423e705a5d3c8e7d99705 (patch) | |
tree | dcff140c1af411612c2ca61a34471134d762843a /subprojects/generator | |
parent | refactor(langauge-web): use generator facades (diff) | |
download | refinery-32d469d0284d1ab1540423e705a5d3c8e7d99705.tar.gz refinery-32d469d0284d1ab1540423e705a5d3c8e7d99705.tar.zst refinery-32d469d0284d1ab1540423e705a5d3c8e7d99705.zip |
refactor: smenatics and facades
Also moves model metadata into language-web, since we only use it on the
frontent.
Diffstat (limited to 'subprojects/generator')
15 files changed, 333 insertions, 565 deletions
diff --git a/subprojects/generator/build.gradle.kts b/subprojects/generator/build.gradle.kts index f1a4ed54..d87ce6de 100644 --- a/subprojects/generator/build.gradle.kts +++ b/subprojects/generator/build.gradle.kts | |||
@@ -10,6 +10,6 @@ plugins { | |||
10 | 10 | ||
11 | dependencies { | 11 | dependencies { |
12 | api(project(":refinery-language-semantics")) | 12 | api(project(":refinery-language-semantics")) |
13 | api(libs.eclipseCollections.api) | ||
13 | implementation(project(":refinery-store-query-interpreter")) | 14 | implementation(project(":refinery-store-query-interpreter")) |
14 | implementation(project(":refinery-store-reasoning-scope")) | ||
15 | } | 15 | } |
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/AbstractRefinery.java b/subprojects/generator/src/main/java/tools/refinery/generator/AbstractRefinery.java deleted file mode 100644 index 56c7a23b..00000000 --- a/subprojects/generator/src/main/java/tools/refinery/generator/AbstractRefinery.java +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import tools.refinery.generator.impl.ProblemTraceImpl; | ||
9 | import tools.refinery.language.semantics.metadata.NodeMetadata; | ||
10 | import tools.refinery.store.model.Model; | ||
11 | import tools.refinery.store.model.ModelStore; | ||
12 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
13 | import tools.refinery.store.reasoning.ReasoningStoreAdapter; | ||
14 | import tools.refinery.store.reasoning.seed.ModelSeed; | ||
15 | import tools.refinery.store.reasoning.translator.TranslationException; | ||
16 | |||
17 | import java.util.List; | ||
18 | |||
19 | public abstract class AbstractRefinery { | ||
20 | protected final ProblemTrace problemTrace; | ||
21 | protected final ModelStore store; | ||
22 | protected final Model model; | ||
23 | protected final ReasoningAdapter reasoningAdapter; | ||
24 | |||
25 | protected AbstractRefinery(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) { | ||
26 | this.problemTrace = problemTrace; | ||
27 | this.store = store; | ||
28 | try { | ||
29 | model = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(modelSeed); | ||
30 | } catch (TranslationException e) { | ||
31 | throw ProblemTraceImpl.wrapException(problemTrace, e); | ||
32 | } | ||
33 | reasoningAdapter = model.getAdapter(ReasoningAdapter.class); | ||
34 | } | ||
35 | |||
36 | public ProblemTrace getProblemTrace() { | ||
37 | return problemTrace; | ||
38 | } | ||
39 | |||
40 | public ModelStore getModelStore() { | ||
41 | return store; | ||
42 | } | ||
43 | |||
44 | public Model getModel() { | ||
45 | return model; | ||
46 | } | ||
47 | |||
48 | public List<NodeMetadata> getNodesMetadata() { | ||
49 | int nodeCount = reasoningAdapter.getNodeCount(); | ||
50 | return problemTrace.getNodesMetadata(nodeCount, isPreserveNewNodes()); | ||
51 | } | ||
52 | |||
53 | protected abstract boolean isPreserveNewNodes(); | ||
54 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/AbstractRefineryBuilder.java b/subprojects/generator/src/main/java/tools/refinery/generator/AbstractRefineryBuilder.java deleted file mode 100644 index d4649051..00000000 --- a/subprojects/generator/src/main/java/tools/refinery/generator/AbstractRefineryBuilder.java +++ /dev/null | |||
@@ -1,159 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import com.google.inject.Inject; | ||
9 | import com.google.inject.Provider; | ||
10 | import org.eclipse.emf.common.util.URI; | ||
11 | import org.eclipse.emf.ecore.resource.Resource; | ||
12 | import org.eclipse.xtext.diagnostics.Severity; | ||
13 | import org.eclipse.xtext.resource.IResourceFactory; | ||
14 | import org.eclipse.xtext.resource.XtextResourceSet; | ||
15 | import org.eclipse.xtext.util.LazyStringInputStream; | ||
16 | import org.eclipse.xtext.validation.CheckMode; | ||
17 | import org.eclipse.xtext.validation.IResourceValidator; | ||
18 | import tools.refinery.generator.impl.ProblemTraceImpl; | ||
19 | import tools.refinery.language.model.problem.Problem; | ||
20 | import tools.refinery.language.semantics.model.ModelInitializer; | ||
21 | import tools.refinery.store.query.ModelQueryBuilder; | ||
22 | import tools.refinery.store.query.interpreter.QueryInterpreterAdapter; | ||
23 | import tools.refinery.store.reasoning.literal.Concreteness; | ||
24 | import tools.refinery.store.reasoning.translator.TranslationException; | ||
25 | import tools.refinery.store.util.CancellationToken; | ||
26 | |||
27 | import java.io.File; | ||
28 | import java.io.IOException; | ||
29 | import java.io.InputStream; | ||
30 | import java.util.Collection; | ||
31 | import java.util.Map; | ||
32 | |||
33 | // This class is used as a fluent builder. | ||
34 | @SuppressWarnings("UnusedReturnValue") | ||
35 | public abstract class AbstractRefineryBuilder<T> { | ||
36 | @Inject | ||
37 | private Provider<XtextResourceSet> resourceSetProvider; | ||
38 | |||
39 | @Inject | ||
40 | private IResourceFactory resourceFactory; | ||
41 | |||
42 | @Inject | ||
43 | private IResourceValidator resourceValidator; | ||
44 | |||
45 | @Inject | ||
46 | protected ModelInitializer initializer; | ||
47 | |||
48 | @Inject | ||
49 | private ProblemTraceImpl problemTrace; | ||
50 | |||
51 | protected CancellationToken cancellationToken = CancellationToken.NONE; | ||
52 | private boolean problemLoaded; | ||
53 | private ModelQueryBuilder queryEngineBuilder; | ||
54 | protected Collection<Concreteness> requiredInterpretations; | ||
55 | |||
56 | protected AbstractRefineryBuilder(Collection<Concreteness> defaultRequiredInterpretations) { | ||
57 | requiredInterpretations = defaultRequiredInterpretations; | ||
58 | } | ||
59 | |||
60 | protected abstract T self(); | ||
61 | |||
62 | public T cancellationToken(CancellationToken cancellationToken) { | ||
63 | this.cancellationToken = cancellationToken; | ||
64 | return self(); | ||
65 | } | ||
66 | |||
67 | public T fromString(String problemString) throws IOException { | ||
68 | try (var stream = new LazyStringInputStream(problemString)) { | ||
69 | return fromStream(stream); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | public T fromStream(InputStream inputStream) throws IOException { | ||
74 | var resourceSet = resourceSetProvider.get(); | ||
75 | var resource = resourceFactory.createResource(URI.createFileURI("__synthetic.problem")); | ||
76 | resourceSet.getResources().add(resource); | ||
77 | resource.load(inputStream, Map.of()); | ||
78 | return fromResource(resource); | ||
79 | } | ||
80 | |||
81 | public T fromFile(File file) throws IOException { | ||
82 | return fromFile(file.getAbsolutePath()); | ||
83 | } | ||
84 | |||
85 | public T fromFile(String filePath) throws IOException { | ||
86 | return fromUri(URI.createFileURI(filePath)); | ||
87 | } | ||
88 | |||
89 | public T fromUri(URI uri) throws IOException { | ||
90 | var resourceSet = resourceSetProvider.get(); | ||
91 | var resource = resourceFactory.createResource(uri); | ||
92 | resourceSet.getResources().add(resource); | ||
93 | resource.load(Map.of()); | ||
94 | return fromResource(resource); | ||
95 | } | ||
96 | |||
97 | public T fromResource(Resource resource) { | ||
98 | var issues = resourceValidator.validate(resource, CheckMode.ALL, () -> { | ||
99 | cancellationToken.checkCancelled(); | ||
100 | return Thread.interrupted(); | ||
101 | }); | ||
102 | cancellationToken.checkCancelled(); | ||
103 | var errors = issues.stream() | ||
104 | .filter(issue -> issue.getSeverity() == Severity.ERROR) | ||
105 | .toList(); | ||
106 | if (!errors.isEmpty()) { | ||
107 | throw new ValidationErrorsException(resource.getURI(), errors); | ||
108 | } | ||
109 | if (resource.getContents().isEmpty() || !(resource.getContents().get(0) instanceof Problem problem)) { | ||
110 | throw new IllegalArgumentException("Model generation problem not found in resource " + resource.getURI()); | ||
111 | } | ||
112 | return problem(problem); | ||
113 | } | ||
114 | |||
115 | public T problem(Problem problem) { | ||
116 | if (problemLoaded) { | ||
117 | throw new IllegalStateException("Problem was already set"); | ||
118 | } | ||
119 | problemTrace.setInitializer(initializer); | ||
120 | try { | ||
121 | initializer.readProblem(problem); | ||
122 | } catch (TranslationException e) { | ||
123 | throw ProblemTraceImpl.wrapException(problemTrace, e); | ||
124 | } | ||
125 | problemLoaded = true; | ||
126 | return self(); | ||
127 | } | ||
128 | |||
129 | public ProblemTrace getProblemTrace() { | ||
130 | checkProblem(); | ||
131 | return problemTrace; | ||
132 | } | ||
133 | |||
134 | public T queryEngine(ModelQueryBuilder queryEngineBuilder) { | ||
135 | if (this.queryEngineBuilder != null) { | ||
136 | throw new IllegalStateException("Query engine was already set"); | ||
137 | } | ||
138 | this.queryEngineBuilder = queryEngineBuilder; | ||
139 | return self(); | ||
140 | } | ||
141 | |||
142 | public T requiredInterpretations(Collection<Concreteness> requiredInterpretations) { | ||
143 | this.requiredInterpretations = requiredInterpretations; | ||
144 | return self(); | ||
145 | } | ||
146 | |||
147 | protected void checkProblem() { | ||
148 | if (!problemLoaded) { | ||
149 | throw new IllegalStateException("Problem was not loaded"); | ||
150 | } | ||
151 | } | ||
152 | |||
153 | protected ModelQueryBuilder getQueryEngineBuilder() { | ||
154 | if (queryEngineBuilder == null) { | ||
155 | return QueryInterpreterAdapter.builder(); | ||
156 | } | ||
157 | return queryEngineBuilder; | ||
158 | } | ||
159 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java new file mode 100644 index 00000000..a00ddc46 --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelFacade.java | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import tools.refinery.language.semantics.ProblemTrace; | ||
9 | import tools.refinery.store.model.Model; | ||
10 | import tools.refinery.store.model.ModelStore; | ||
11 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
12 | import tools.refinery.store.reasoning.ReasoningStoreAdapter; | ||
13 | import tools.refinery.store.reasoning.interpretation.PartialInterpretation; | ||
14 | import tools.refinery.store.reasoning.literal.Concreteness; | ||
15 | import tools.refinery.store.reasoning.representation.PartialSymbol; | ||
16 | import tools.refinery.store.reasoning.seed.ModelSeed; | ||
17 | import tools.refinery.store.reasoning.translator.TranslationException; | ||
18 | |||
19 | public abstract class ModelFacade { | ||
20 | private final ProblemTrace problemTrace; | ||
21 | private final ModelStore store; | ||
22 | private final Model model; | ||
23 | private final ReasoningAdapter reasoningAdapter; | ||
24 | private final Concreteness concreteness; | ||
25 | |||
26 | protected ModelFacade(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed, | ||
27 | Concreteness concreteness) { | ||
28 | this.problemTrace = problemTrace; | ||
29 | this.store = store; | ||
30 | try { | ||
31 | model = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(modelSeed); | ||
32 | } catch (TranslationException e) { | ||
33 | throw problemTrace.wrapException(e); | ||
34 | } | ||
35 | reasoningAdapter = model.getAdapter(ReasoningAdapter.class); | ||
36 | this.concreteness = concreteness; | ||
37 | } | ||
38 | |||
39 | public ProblemTrace getProblemTrace() { | ||
40 | return problemTrace; | ||
41 | } | ||
42 | |||
43 | public ModelStore getModelStore() { | ||
44 | return store; | ||
45 | } | ||
46 | |||
47 | public Model getModel() { | ||
48 | return model; | ||
49 | } | ||
50 | |||
51 | public Concreteness getConcreteness() { | ||
52 | return concreteness; | ||
53 | } | ||
54 | |||
55 | public <A, C> PartialInterpretation<A, C> getPartialInterpretation(PartialSymbol<A, C> partialSymbol) { | ||
56 | return reasoningAdapter.getPartialInterpretation(concreteness, partialSymbol); | ||
57 | } | ||
58 | } | ||
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 78c807d1..5b44c10a 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java | |||
@@ -5,33 +5,25 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.generator; | 6 | package tools.refinery.generator; |
7 | 7 | ||
8 | import org.eclipse.xtext.naming.QualifiedName; | 8 | import tools.refinery.language.semantics.ProblemTrace; |
9 | import tools.refinery.language.model.problem.Relation; | ||
10 | import tools.refinery.store.dse.strategy.BestFirstStoreManager; | 9 | import tools.refinery.store.dse.strategy.BestFirstStoreManager; |
11 | import tools.refinery.store.dse.transition.VersionWithObjectiveValue; | ||
12 | import tools.refinery.store.map.Version; | 10 | import tools.refinery.store.map.Version; |
13 | import tools.refinery.store.model.ModelStore; | 11 | import tools.refinery.store.model.ModelStore; |
14 | import tools.refinery.store.reasoning.interpretation.PartialInterpretation; | 12 | import tools.refinery.store.reasoning.interpretation.PartialInterpretation; |
15 | import tools.refinery.store.reasoning.literal.Concreteness; | 13 | import tools.refinery.store.reasoning.literal.Concreteness; |
16 | import tools.refinery.store.reasoning.representation.PartialSymbol; | 14 | import tools.refinery.store.reasoning.representation.PartialSymbol; |
17 | import tools.refinery.store.reasoning.seed.ModelSeed; | 15 | import tools.refinery.store.reasoning.seed.ModelSeed; |
18 | import tools.refinery.store.representation.TruthValue; | ||
19 | 16 | ||
20 | import java.util.Collection; | 17 | public class ModelGenerator extends ModelFacade { |
21 | |||
22 | public class ModelGenerator extends AbstractRefinery { | ||
23 | private final Version initialVersion; | 18 | private final Version initialVersion; |
24 | 19 | ||
25 | private int randomSeed = 1; | 20 | private int randomSeed = 0; |
26 | 21 | ||
27 | public ModelGenerator(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) { | 22 | private boolean lastGenerationSuccessful; |
28 | super(problemTrace, store, modelSeed); | ||
29 | initialVersion = model.commit(); | ||
30 | } | ||
31 | 23 | ||
32 | @Override | 24 | public ModelGenerator(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) { |
33 | protected boolean isPreserveNewNodes() { | 25 | super(problemTrace, store, modelSeed, Concreteness.CANDIDATE); |
34 | return false; | 26 | initialVersion = getModel().commit(); |
35 | } | 27 | } |
36 | 28 | ||
37 | public int getRandomSeed() { | 29 | public int getRandomSeed() { |
@@ -40,56 +32,40 @@ public class ModelGenerator extends AbstractRefinery { | |||
40 | 32 | ||
41 | public void setRandomSeed(int randomSeed) { | 33 | public void setRandomSeed(int randomSeed) { |
42 | this.randomSeed = randomSeed; | 34 | this.randomSeed = randomSeed; |
35 | this.lastGenerationSuccessful = false; | ||
43 | } | 36 | } |
44 | 37 | ||
45 | public Collection<Version> run(int maxNumberOfSolutions) { | 38 | public boolean isLastGenerationSuccessful() { |
46 | var bestFirst = new BestFirstStoreManager(store, maxNumberOfSolutions); | 39 | return lastGenerationSuccessful; |
47 | int currentRandomSeed = randomSeed; | ||
48 | // Increment random seed even if generation is unsuccessful. | ||
49 | randomSeed++; | ||
50 | bestFirst.startExploration(initialVersion, currentRandomSeed); | ||
51 | return bestFirst.getSolutionStore() | ||
52 | .getSolutions() | ||
53 | .stream() | ||
54 | .map(VersionWithObjectiveValue::version) | ||
55 | .toList(); | ||
56 | } | 40 | } |
57 | 41 | ||
58 | // This method only makes sense if it returns {@code true} on success. | 42 | // This method only makes sense if it returns {@code true} on success. |
59 | @SuppressWarnings("BooleanMethodIsAlwaysInverted") | 43 | @SuppressWarnings("BooleanMethodIsAlwaysInverted") |
60 | public boolean tryRun() { | 44 | public boolean tryGenerate() { |
61 | var iterator = run(1).iterator(); | 45 | lastGenerationSuccessful = false; |
62 | if (!iterator.hasNext()) { | 46 | randomSeed++; |
47 | var bestFirst = new BestFirstStoreManager(getModelStore(), 1); | ||
48 | bestFirst.startExploration(initialVersion, randomSeed); | ||
49 | var solutions = bestFirst.getSolutionStore().getSolutions(); | ||
50 | if (solutions.isEmpty()) { | ||
63 | return false; | 51 | return false; |
64 | } | 52 | } |
65 | model.restore(iterator.next()); | 53 | getModel().restore(solutions.get(0).version()); |
54 | lastGenerationSuccessful = true; | ||
66 | return true; | 55 | return true; |
67 | } | 56 | } |
68 | 57 | ||
69 | public void run() { | 58 | public void generate() { |
70 | if (!tryRun()) { | 59 | if (!tryGenerate()) { |
71 | throw new UnsatisfiableProblemException(); | 60 | throw new UnsatisfiableProblemException(); |
72 | } | 61 | } |
73 | } | 62 | } |
74 | 63 | ||
75 | public <A, C> PartialInterpretation<A, C> getCandidateInterpretation(PartialSymbol<A, C> partialSymbol) { | 64 | @Override |
76 | return reasoningAdapter.getPartialInterpretation(Concreteness.CANDIDATE, partialSymbol); | 65 | public <A, C> PartialInterpretation<A, C> getPartialInterpretation(PartialSymbol<A, C> partialSymbol) { |
77 | } | 66 | if (!lastGenerationSuccessful) { |
78 | 67 | throw new IllegalStateException("No generated model is available"); | |
79 | public PartialInterpretation<TruthValue, Boolean> getCandidateInterpretation(Relation relation) { | 68 | } |
80 | return getCandidateInterpretation(problemTrace.getPartialRelation(relation)); | 69 | return super.getPartialInterpretation(partialSymbol); |
81 | } | ||
82 | |||
83 | public PartialInterpretation<TruthValue, Boolean> getCandidateInterpretation(QualifiedName qualifiedName) { | ||
84 | return getCandidateInterpretation(problemTrace.getPartialRelation(qualifiedName)); | ||
85 | } | ||
86 | |||
87 | public PartialInterpretation<TruthValue, Boolean> getCandidateInterpretation(String qualifiedName) { | ||
88 | return getCandidateInterpretation(problemTrace.getPartialRelation(qualifiedName)); | ||
89 | } | ||
90 | |||
91 | public static ModelGeneratorBuilder standaloneBuilder() { | ||
92 | var injector = StandaloneInjectorHolder.getInjector(); | ||
93 | return injector.getInstance(ModelGeneratorBuilder.class); | ||
94 | } | 70 | } |
95 | } | 71 | } |
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorBuilder.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorBuilder.java deleted file mode 100644 index d14cbe3a..00000000 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorBuilder.java +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import tools.refinery.store.dse.propagation.PropagationAdapter; | ||
9 | import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter; | ||
10 | import tools.refinery.store.model.ModelStore; | ||
11 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
12 | import tools.refinery.store.reasoning.literal.Concreteness; | ||
13 | import tools.refinery.store.statecoding.StateCoderAdapter; | ||
14 | |||
15 | import java.util.Set; | ||
16 | |||
17 | public final class ModelGeneratorBuilder extends AbstractRefineryBuilder<ModelGeneratorBuilder> { | ||
18 | public ModelGeneratorBuilder() { | ||
19 | super(Set.of(Concreteness.CANDIDATE)); | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | protected ModelGeneratorBuilder self() { | ||
24 | return this; | ||
25 | } | ||
26 | |||
27 | public ModelGenerator build() { | ||
28 | checkProblem(); | ||
29 | var storeBuilder = ModelStore.builder() | ||
30 | .cancellationToken(cancellationToken) | ||
31 | .with(getQueryEngineBuilder()) | ||
32 | .with(PropagationAdapter.builder()) | ||
33 | .with(StateCoderAdapter.builder()) | ||
34 | .with(DesignSpaceExplorationAdapter.builder()) | ||
35 | .with(ReasoningAdapter.builder() | ||
36 | .requiredInterpretations(requiredInterpretations)); | ||
37 | initializer.configureStoreBuilder(storeBuilder); | ||
38 | var store = storeBuilder.build(); | ||
39 | return new ModelGenerator(getProblemTrace(), store, initializer.getModelSeed()); | ||
40 | } | ||
41 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java new file mode 100644 index 00000000..6642d591 --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorFactory.java | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import com.google.inject.Inject; | ||
9 | import com.google.inject.Provider; | ||
10 | import tools.refinery.language.model.problem.Problem; | ||
11 | import tools.refinery.language.semantics.ModelInitializer; | ||
12 | import tools.refinery.store.dse.propagation.PropagationAdapter; | ||
13 | import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter; | ||
14 | import tools.refinery.store.model.ModelStore; | ||
15 | import tools.refinery.store.query.interpreter.QueryInterpreterAdapter; | ||
16 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
17 | import tools.refinery.store.reasoning.literal.Concreteness; | ||
18 | import tools.refinery.store.statecoding.StateCoderAdapter; | ||
19 | import tools.refinery.store.util.CancellationToken; | ||
20 | |||
21 | import java.util.Collection; | ||
22 | import java.util.Set; | ||
23 | |||
24 | public final class ModelGeneratorFactory { | ||
25 | @Inject | ||
26 | private Provider<ModelInitializer> initializerProvider; | ||
27 | |||
28 | private CancellationToken cancellationToken = CancellationToken.NONE; | ||
29 | |||
30 | private boolean debugPartialInterpretations; | ||
31 | |||
32 | public ModelGeneratorFactory cancellationToken(CancellationToken cancellationToken) { | ||
33 | this.cancellationToken = cancellationToken; | ||
34 | return this; | ||
35 | } | ||
36 | |||
37 | public ModelGeneratorFactory debugPartialInterpretations(boolean debugPartialInterpretations) { | ||
38 | this.debugPartialInterpretations = debugPartialInterpretations; | ||
39 | return this; | ||
40 | } | ||
41 | |||
42 | public ModelGenerator createGenerator(Problem problem) { | ||
43 | var initializer = initializerProvider.get(); | ||
44 | initializer.readProblem(problem); | ||
45 | cancellationToken.checkCancelled(); | ||
46 | var storeBuilder = ModelStore.builder() | ||
47 | .cancellationToken(cancellationToken) | ||
48 | .with(QueryInterpreterAdapter.builder()) | ||
49 | .with(PropagationAdapter.builder()) | ||
50 | .with(StateCoderAdapter.builder()) | ||
51 | .with(DesignSpaceExplorationAdapter.builder()) | ||
52 | .with(ReasoningAdapter.builder() | ||
53 | .requiredInterpretations(getRequiredInterpretations())); | ||
54 | initializer.configureStoreBuilder(storeBuilder); | ||
55 | var store = storeBuilder.build(); | ||
56 | return new ModelGenerator(initializer.getProblemTrace(), store, initializer.getModelSeed()); | ||
57 | } | ||
58 | |||
59 | private Collection<Concreteness> getRequiredInterpretations() { | ||
60 | return debugPartialInterpretations ? Set.of(Concreteness.PARTIAL, Concreteness.CANDIDATE) : | ||
61 | Set.of(Concreteness.CANDIDATE); | ||
62 | } | ||
63 | } | ||
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 661bc97c..bc02c887 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemantics.java +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemantics.java | |||
@@ -5,43 +5,13 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.generator; | 6 | package tools.refinery.generator; |
7 | 7 | ||
8 | import org.eclipse.xtext.naming.QualifiedName; | 8 | import tools.refinery.language.semantics.ProblemTrace; |
9 | import tools.refinery.language.model.problem.Relation; | ||
10 | import tools.refinery.store.model.ModelStore; | 9 | import tools.refinery.store.model.ModelStore; |
11 | import tools.refinery.store.reasoning.interpretation.PartialInterpretation; | ||
12 | import tools.refinery.store.reasoning.literal.Concreteness; | 10 | import tools.refinery.store.reasoning.literal.Concreteness; |
13 | import tools.refinery.store.reasoning.representation.PartialSymbol; | ||
14 | import tools.refinery.store.reasoning.seed.ModelSeed; | 11 | import tools.refinery.store.reasoning.seed.ModelSeed; |
15 | import tools.refinery.store.representation.TruthValue; | ||
16 | 12 | ||
17 | public class ModelSemantics extends AbstractRefinery { | 13 | public class ModelSemantics extends ModelFacade { |
18 | public ModelSemantics(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) { | 14 | public ModelSemantics(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) { |
19 | super(problemTrace, store, modelSeed); | 15 | super(problemTrace, store, modelSeed, Concreteness.PARTIAL); |
20 | } | ||
21 | |||
22 | @Override | ||
23 | protected boolean isPreserveNewNodes() { | ||
24 | return true; | ||
25 | } | ||
26 | |||
27 | public <A, C> PartialInterpretation<A, C> getPartialInterpretation(PartialSymbol<A, C> partialSymbol) { | ||
28 | return reasoningAdapter.getPartialInterpretation(Concreteness.PARTIAL, partialSymbol); | ||
29 | } | ||
30 | |||
31 | public PartialInterpretation<TruthValue, Boolean> getPartialInterpretation(Relation relation) { | ||
32 | return getPartialInterpretation(problemTrace.getPartialRelation(relation)); | ||
33 | } | ||
34 | |||
35 | public PartialInterpretation<TruthValue, Boolean> getPartialInterpretation(QualifiedName qualifiedName) { | ||
36 | return getPartialInterpretation(problemTrace.getPartialRelation(qualifiedName)); | ||
37 | } | ||
38 | |||
39 | public PartialInterpretation<TruthValue, Boolean> getPartialInterpretation(String qualifiedName) { | ||
40 | return getPartialInterpretation(problemTrace.getPartialRelation(qualifiedName)); | ||
41 | } | ||
42 | |||
43 | public static ModelSemanticsBuilder standaloneBuilder() { | ||
44 | var injector = StandaloneInjectorHolder.getInjector(); | ||
45 | return injector.getInstance(ModelSemanticsBuilder.class); | ||
46 | } | 16 | } |
47 | } | 17 | } |
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemanticsBuilder.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemanticsBuilder.java deleted file mode 100644 index a560ebe4..00000000 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemanticsBuilder.java +++ /dev/null | |||
@@ -1,37 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import tools.refinery.store.dse.propagation.PropagationAdapter; | ||
9 | import tools.refinery.store.model.ModelStore; | ||
10 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
11 | import tools.refinery.store.reasoning.literal.Concreteness; | ||
12 | |||
13 | import java.util.Set; | ||
14 | |||
15 | public final class ModelSemanticsBuilder extends AbstractRefineryBuilder<ModelSemanticsBuilder> { | ||
16 | public ModelSemanticsBuilder() { | ||
17 | super(Set.of(Concreteness.PARTIAL)); | ||
18 | } | ||
19 | |||
20 | @Override | ||
21 | protected ModelSemanticsBuilder self() { | ||
22 | return this; | ||
23 | } | ||
24 | |||
25 | public ModelSemantics build() { | ||
26 | checkProblem(); | ||
27 | var storeBuilder = ModelStore.builder() | ||
28 | .cancellationToken(cancellationToken) | ||
29 | .with(getQueryEngineBuilder()) | ||
30 | .with(PropagationAdapter.builder()) | ||
31 | .with(ReasoningAdapter.builder() | ||
32 | .requiredInterpretations(requiredInterpretations)); | ||
33 | initializer.configureStoreBuilder(storeBuilder); | ||
34 | var store = storeBuilder.build(); | ||
35 | return new ModelSemantics(getProblemTrace(), store, initializer.getModelSeed()); | ||
36 | } | ||
37 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemanticsFactory.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemanticsFactory.java new file mode 100644 index 00000000..b6263b37 --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelSemanticsFactory.java | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import com.google.inject.Inject; | ||
9 | import com.google.inject.Provider; | ||
10 | import tools.refinery.language.model.problem.Problem; | ||
11 | import tools.refinery.language.semantics.ModelInitializer; | ||
12 | import tools.refinery.store.dse.propagation.PropagationAdapter; | ||
13 | import tools.refinery.store.model.ModelStore; | ||
14 | import tools.refinery.store.query.interpreter.QueryInterpreterAdapter; | ||
15 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
16 | import tools.refinery.store.reasoning.literal.Concreteness; | ||
17 | import tools.refinery.store.util.CancellationToken; | ||
18 | |||
19 | import java.util.Set; | ||
20 | |||
21 | public final class ModelSemanticsFactory { | ||
22 | @Inject | ||
23 | private Provider<ModelInitializer> initializerProvider; | ||
24 | |||
25 | private CancellationToken cancellationToken = CancellationToken.NONE; | ||
26 | |||
27 | public ModelSemanticsFactory cancellationToken(CancellationToken cancellationToken) { | ||
28 | this.cancellationToken = cancellationToken; | ||
29 | return this; | ||
30 | } | ||
31 | |||
32 | public ModelSemantics createSemantics(Problem problem) { | ||
33 | var initializer = initializerProvider.get(); | ||
34 | initializer.readProblem(problem); | ||
35 | var storeBuilder = ModelStore.builder() | ||
36 | .cancellationToken(cancellationToken) | ||
37 | .with(QueryInterpreterAdapter.builder()) | ||
38 | .with(PropagationAdapter.builder()) | ||
39 | .with(ReasoningAdapter.builder() | ||
40 | .requiredInterpretations(Set.of(Concreteness.PARTIAL))); | ||
41 | initializer.configureStoreBuilder(storeBuilder); | ||
42 | var store = storeBuilder.build(); | ||
43 | return new ModelSemantics(initializer.getProblemTrace(), store, initializer.getModelSeed()); | ||
44 | } | ||
45 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java new file mode 100644 index 00000000..29f80714 --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemLoader.java | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import com.google.inject.Inject; | ||
9 | import com.google.inject.Provider; | ||
10 | import org.eclipse.emf.common.util.URI; | ||
11 | import org.eclipse.emf.ecore.resource.Resource; | ||
12 | import org.eclipse.xtext.diagnostics.Severity; | ||
13 | import org.eclipse.xtext.resource.IResourceFactory; | ||
14 | import org.eclipse.xtext.resource.XtextResourceSet; | ||
15 | import org.eclipse.xtext.util.LazyStringInputStream; | ||
16 | import org.eclipse.xtext.validation.CheckMode; | ||
17 | import org.eclipse.xtext.validation.IResourceValidator; | ||
18 | import tools.refinery.language.model.problem.Problem; | ||
19 | import tools.refinery.store.util.CancellationToken; | ||
20 | |||
21 | import java.io.File; | ||
22 | import java.io.IOException; | ||
23 | import java.io.InputStream; | ||
24 | import java.util.Map; | ||
25 | |||
26 | public class ProblemLoader { | ||
27 | @Inject | ||
28 | private Provider<XtextResourceSet> resourceSetProvider; | ||
29 | |||
30 | @Inject | ||
31 | private IResourceFactory resourceFactory; | ||
32 | |||
33 | @Inject | ||
34 | private IResourceValidator resourceValidator; | ||
35 | |||
36 | private CancellationToken cancellationToken = CancellationToken.NONE; | ||
37 | |||
38 | public ProblemLoader cancellationToken(CancellationToken cancellationToken) { | ||
39 | this.cancellationToken = cancellationToken; | ||
40 | return this; | ||
41 | } | ||
42 | |||
43 | public Problem loadString(String problemString) throws IOException { | ||
44 | try (var stream = new LazyStringInputStream(problemString)) { | ||
45 | return loadStream(stream); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | public Problem loadStream(InputStream inputStream) throws IOException { | ||
50 | var resourceSet = resourceSetProvider.get(); | ||
51 | var resource = resourceFactory.createResource(URI.createFileURI("__synthetic.problem")); | ||
52 | resourceSet.getResources().add(resource); | ||
53 | resource.load(inputStream, Map.of()); | ||
54 | return loadResource(resource); | ||
55 | } | ||
56 | |||
57 | public Problem loadFile(File file) throws IOException { | ||
58 | return loadFile(file.getAbsolutePath()); | ||
59 | } | ||
60 | |||
61 | public Problem loadFile(String filePath) throws IOException { | ||
62 | return loadUri(URI.createFileURI(filePath)); | ||
63 | } | ||
64 | |||
65 | public Problem loadUri(URI uri) throws IOException { | ||
66 | var resourceSet = resourceSetProvider.get(); | ||
67 | var resource = resourceFactory.createResource(uri); | ||
68 | resourceSet.getResources().add(resource); | ||
69 | resource.load(Map.of()); | ||
70 | return loadResource(resource); | ||
71 | } | ||
72 | |||
73 | public Problem loadResource(Resource resource) { | ||
74 | var issues = resourceValidator.validate(resource, CheckMode.ALL, () -> { | ||
75 | cancellationToken.checkCancelled(); | ||
76 | return Thread.interrupted(); | ||
77 | }); | ||
78 | cancellationToken.checkCancelled(); | ||
79 | var errors = issues.stream() | ||
80 | .filter(issue -> issue.getSeverity() == Severity.ERROR) | ||
81 | .toList(); | ||
82 | if (!errors.isEmpty()) { | ||
83 | throw new ValidationErrorsException(resource.getURI(), errors); | ||
84 | } | ||
85 | if (resource.getContents().isEmpty() || !(resource.getContents().get(0) instanceof Problem problem)) { | ||
86 | throw new IllegalArgumentException("Model generation problem not found in resource " + resource.getURI()); | ||
87 | } | ||
88 | return problem; | ||
89 | } | ||
90 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemTrace.java b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemTrace.java deleted file mode 100644 index f7963c58..00000000 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemTrace.java +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import org.eclipse.xtext.naming.QualifiedName; | ||
9 | import tools.refinery.language.model.problem.Problem; | ||
10 | import tools.refinery.language.model.problem.Relation; | ||
11 | import tools.refinery.language.semantics.metadata.NodeMetadata; | ||
12 | import tools.refinery.language.semantics.metadata.RelationMetadata; | ||
13 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; | ||
14 | import tools.refinery.store.reasoning.representation.PartialRelation; | ||
15 | |||
16 | import java.util.List; | ||
17 | import java.util.Map; | ||
18 | |||
19 | public interface ProblemTrace { | ||
20 | Problem getProblem(); | ||
21 | |||
22 | Map<Relation, PartialRelation> getRelationTrace(); | ||
23 | |||
24 | Relation getInverseTrace(AnyPartialSymbol partialSymbol); | ||
25 | |||
26 | PartialRelation getPartialRelation(Relation relation); | ||
27 | |||
28 | PartialRelation getPartialRelation(QualifiedName qualifiedName); | ||
29 | |||
30 | PartialRelation getPartialRelation(String qualifiedName); | ||
31 | |||
32 | List<RelationMetadata> getRelationsMetadata(); | ||
33 | |||
34 | List<NodeMetadata> getNodesMetadata(int nodeCount, boolean preserveNewNodes); | ||
35 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/StandaloneInjectorHolder.java b/subprojects/generator/src/main/java/tools/refinery/generator/StandaloneInjectorHolder.java deleted file mode 100644 index 7db96163..00000000 --- a/subprojects/generator/src/main/java/tools/refinery/generator/StandaloneInjectorHolder.java +++ /dev/null | |||
@@ -1,27 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import com.google.inject.Injector; | ||
9 | import tools.refinery.language.ProblemStandaloneSetup; | ||
10 | |||
11 | public final class StandaloneInjectorHolder { | ||
12 | private StandaloneInjectorHolder() { | ||
13 | throw new IllegalArgumentException("This is a static utility class and should not be instantiated directly"); | ||
14 | } | ||
15 | |||
16 | public static Injector getInjector() { | ||
17 | return LazyHolder.INJECTOR; | ||
18 | } | ||
19 | |||
20 | private static final class LazyHolder { | ||
21 | private static final Injector INJECTOR = createInjector(); | ||
22 | |||
23 | private static Injector createInjector() { | ||
24 | return new ProblemStandaloneSetup().createInjectorAndDoEMFRegistration(); | ||
25 | } | ||
26 | } | ||
27 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/impl/ProblemTraceImpl.java b/subprojects/generator/src/main/java/tools/refinery/generator/impl/ProblemTraceImpl.java deleted file mode 100644 index 5671d3f8..00000000 --- a/subprojects/generator/src/main/java/tools/refinery/generator/impl/ProblemTraceImpl.java +++ /dev/null | |||
@@ -1,127 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator.impl; | ||
7 | |||
8 | import com.google.inject.Inject; | ||
9 | import com.google.inject.Provider; | ||
10 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
11 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | ||
12 | import org.eclipse.xtext.naming.IQualifiedNameProvider; | ||
13 | import org.eclipse.xtext.naming.QualifiedName; | ||
14 | import org.eclipse.xtext.scoping.IScopeProvider; | ||
15 | import tools.refinery.generator.ProblemTrace; | ||
16 | import tools.refinery.language.model.problem.Problem; | ||
17 | import tools.refinery.language.model.problem.ProblemPackage; | ||
18 | import tools.refinery.language.model.problem.Relation; | ||
19 | import tools.refinery.language.semantics.metadata.MetadataCreator; | ||
20 | import tools.refinery.language.semantics.metadata.NodeMetadata; | ||
21 | import tools.refinery.language.semantics.metadata.RelationMetadata; | ||
22 | import tools.refinery.language.semantics.model.ModelInitializer; | ||
23 | import tools.refinery.language.semantics.model.TracedException; | ||
24 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; | ||
25 | import tools.refinery.store.reasoning.representation.PartialRelation; | ||
26 | import tools.refinery.store.reasoning.translator.TranslationException; | ||
27 | |||
28 | import java.util.Collections; | ||
29 | import java.util.List; | ||
30 | import java.util.Map; | ||
31 | |||
32 | public final class ProblemTraceImpl implements ProblemTrace { | ||
33 | @Inject | ||
34 | private IQualifiedNameConverter qualifiedNameConverter; | ||
35 | |||
36 | @Inject | ||
37 | private IQualifiedNameProvider qualifiedNameProvider; | ||
38 | |||
39 | @Inject | ||
40 | private IScopeProvider scopeProvider; | ||
41 | |||
42 | @Inject | ||
43 | private Provider<MetadataCreator> metadataCreatorProvider; | ||
44 | |||
45 | private ModelInitializer initializer; | ||
46 | private Map<Relation, PartialRelation> relationTrace; | ||
47 | private MetadataCreator metadataCreator; | ||
48 | |||
49 | public void setInitializer(ModelInitializer initializer) { | ||
50 | this.initializer = initializer; | ||
51 | relationTrace = Collections.unmodifiableMap(initializer.getRelationTrace()); | ||
52 | } | ||
53 | |||
54 | public Problem getProblem() { | ||
55 | return initializer.getProblem(); | ||
56 | } | ||
57 | |||
58 | public Map<Relation, PartialRelation> getRelationTrace() { | ||
59 | return relationTrace; | ||
60 | } | ||
61 | |||
62 | @Override | ||
63 | public Relation getInverseTrace(AnyPartialSymbol partialSymbol) { | ||
64 | return initializer.getInverseTrace(partialSymbol); | ||
65 | } | ||
66 | |||
67 | public PartialRelation getPartialRelation(Relation relation) { | ||
68 | var partialRelation = relationTrace.get(relation); | ||
69 | if (partialRelation == null) { | ||
70 | var qualifiedName = qualifiedNameProvider.getFullyQualifiedName(relation); | ||
71 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
72 | throw new IllegalArgumentException("No partial relation for relation " + qualifiedNameString); | ||
73 | } | ||
74 | return partialRelation; | ||
75 | } | ||
76 | |||
77 | public PartialRelation getPartialRelation(QualifiedName qualifiedName) { | ||
78 | var scope = scopeProvider.getScope(getProblem(), ProblemPackage.Literals.ASSERTION__RELATION); | ||
79 | var iterator = scope.getElements(qualifiedName).iterator(); | ||
80 | if (!iterator.hasNext()) { | ||
81 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
82 | throw new IllegalArgumentException("No such relation: " + qualifiedNameString); | ||
83 | } | ||
84 | var eObjectDescription = iterator.next(); | ||
85 | if (iterator.hasNext()) { | ||
86 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
87 | throw new IllegalArgumentException("Ambiguous relation: " + qualifiedNameString); | ||
88 | } | ||
89 | var eObject = EcoreUtil.resolve(eObjectDescription.getEObjectOrProxy(), getProblem()); | ||
90 | if (!(eObject instanceof Relation relation)) { | ||
91 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
92 | throw new IllegalArgumentException("Not a relation: " + qualifiedNameString); | ||
93 | } | ||
94 | return getPartialRelation(relation); | ||
95 | } | ||
96 | |||
97 | public PartialRelation getPartialRelation(String qualifiedName) { | ||
98 | var convertedName = qualifiedNameConverter.toQualifiedName(qualifiedName); | ||
99 | return getPartialRelation(convertedName); | ||
100 | } | ||
101 | |||
102 | @Override | ||
103 | public List<RelationMetadata> getRelationsMetadata() { | ||
104 | return getMetadataCreator().getRelationsMetadata(); | ||
105 | } | ||
106 | |||
107 | @Override | ||
108 | public List<NodeMetadata> getNodesMetadata(int nodeCount, boolean preserveNewNodes) { | ||
109 | return getMetadataCreator().getNodesMetadata(nodeCount, preserveNewNodes); | ||
110 | } | ||
111 | |||
112 | private MetadataCreator getMetadataCreator() { | ||
113 | if (metadataCreator == null) { | ||
114 | metadataCreator = metadataCreatorProvider.get(); | ||
115 | metadataCreator.setInitializer(initializer); | ||
116 | } | ||
117 | return metadataCreator; | ||
118 | } | ||
119 | |||
120 | public static RuntimeException wrapException(ProblemTrace trace, TranslationException translationException) { | ||
121 | var source = trace.getInverseTrace(translationException.getPartialSymbol()); | ||
122 | if (source == null) { | ||
123 | return translationException; | ||
124 | } | ||
125 | return new TracedException(source, translationException); | ||
126 | } | ||
127 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/standalone/StandaloneRefinery.java b/subprojects/generator/src/main/java/tools/refinery/generator/standalone/StandaloneRefinery.java new file mode 100644 index 00000000..b444491b --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/standalone/StandaloneRefinery.java | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator.standalone; | ||
7 | |||
8 | import com.google.inject.Injector; | ||
9 | import tools.refinery.generator.ModelGeneratorFactory; | ||
10 | import tools.refinery.generator.ModelSemanticsFactory; | ||
11 | import tools.refinery.language.ProblemStandaloneSetup; | ||
12 | import tools.refinery.generator.ProblemLoader; | ||
13 | |||
14 | public final class StandaloneRefinery { | ||
15 | private StandaloneRefinery() { | ||
16 | throw new IllegalArgumentException("This is a static utility class and should not be instantiated directly"); | ||
17 | } | ||
18 | |||
19 | public static Injector getInjector() { | ||
20 | return LazyHolder.INJECTOR; | ||
21 | } | ||
22 | |||
23 | public static <T> T getInstance(Class<T> type) { | ||
24 | return getInjector().getInstance(type); | ||
25 | } | ||
26 | |||
27 | public static ProblemLoader getProblemLoader() { | ||
28 | return getInstance(ProblemLoader.class); | ||
29 | } | ||
30 | |||
31 | public static ModelGeneratorFactory getGeneratorFactory() { | ||
32 | return getInstance(ModelGeneratorFactory.class); | ||
33 | } | ||
34 | |||
35 | public static ModelSemanticsFactory getSemanticsFactory() { | ||
36 | return getInstance(ModelSemanticsFactory.class); | ||
37 | } | ||
38 | |||
39 | private static final class LazyHolder { | ||
40 | private static final Injector INJECTOR = createInjector(); | ||
41 | |||
42 | private static Injector createInjector() { | ||
43 | return new ProblemStandaloneSetup().createInjectorAndDoEMFRegistration(); | ||
44 | } | ||
45 | } | ||
46 | } | ||