diff options
author | Kristóf Marussy <kristof@marussy.com> | 2023-11-03 19:12:08 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2023-11-03 19:12:19 +0100 |
commit | 32d469d0284d1ab1540423e705a5d3c8e7d99705 (patch) | |
tree | dcff140c1af411612c2ca61a34471134d762843a | |
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.
47 files changed, 719 insertions, 722 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/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 | } | ||
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/ModelInitializer.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java index a05e647d..b3c58366 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/ModelInitializer.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java | |||
@@ -3,13 +3,11 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model; | 6 | package tools.refinery.language.semantics; |
7 | 7 | ||
8 | import com.google.inject.Inject; | 8 | import com.google.inject.Inject; |
9 | import org.eclipse.collections.api.factory.primitive.ObjectIntMaps; | ||
10 | import org.eclipse.collections.api.map.primitive.MutableObjectIntMap; | ||
11 | import tools.refinery.language.model.problem.*; | 9 | import tools.refinery.language.model.problem.*; |
12 | import tools.refinery.language.semantics.model.internal.MutableSeed; | 10 | import tools.refinery.language.semantics.internal.MutableSeed; |
13 | import tools.refinery.language.utils.BuiltinSymbols; | 11 | import tools.refinery.language.utils.BuiltinSymbols; |
14 | import tools.refinery.language.utils.ProblemDesugarer; | 12 | import tools.refinery.language.utils.ProblemDesugarer; |
15 | import tools.refinery.language.utils.ProblemUtil; | 13 | import tools.refinery.language.utils.ProblemUtil; |
@@ -23,11 +21,11 @@ import tools.refinery.store.query.literal.*; | |||
23 | import tools.refinery.store.query.term.NodeVariable; | 21 | import tools.refinery.store.query.term.NodeVariable; |
24 | import tools.refinery.store.query.term.Variable; | 22 | import tools.refinery.store.query.term.Variable; |
25 | import tools.refinery.store.reasoning.ReasoningAdapter; | 23 | import tools.refinery.store.reasoning.ReasoningAdapter; |
26 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; | ||
27 | import tools.refinery.store.reasoning.representation.PartialRelation; | 24 | import tools.refinery.store.reasoning.representation.PartialRelation; |
28 | import tools.refinery.store.reasoning.scope.ScopePropagator; | 25 | import tools.refinery.store.reasoning.scope.ScopePropagator; |
29 | import tools.refinery.store.reasoning.seed.ModelSeed; | 26 | import tools.refinery.store.reasoning.seed.ModelSeed; |
30 | import tools.refinery.store.reasoning.seed.Seed; | 27 | import tools.refinery.store.reasoning.seed.Seed; |
28 | import tools.refinery.store.reasoning.translator.TranslationException; | ||
31 | import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; | 29 | import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; |
32 | import tools.refinery.store.reasoning.translator.metamodel.Metamodel; | 30 | import tools.refinery.store.reasoning.translator.metamodel.Metamodel; |
33 | import tools.refinery.store.reasoning.translator.metamodel.MetamodelBuilder; | 31 | import tools.refinery.store.reasoning.translator.metamodel.MetamodelBuilder; |
@@ -52,24 +50,19 @@ public class ModelInitializer { | |||
52 | @Inject | 50 | @Inject |
53 | private SemanticsUtils semanticsUtils; | 51 | private SemanticsUtils semanticsUtils; |
54 | 52 | ||
55 | private Problem problem; | 53 | @Inject |
54 | private ProblemTraceImpl problemTrace; | ||
56 | 55 | ||
57 | private ModelStoreBuilder storeBuilder; | 56 | private Problem problem; |
58 | 57 | ||
59 | private BuiltinSymbols builtinSymbols; | 58 | private BuiltinSymbols builtinSymbols; |
60 | 59 | ||
61 | private PartialRelation nodeRelation; | 60 | private PartialRelation nodeRelation; |
62 | 61 | ||
63 | private final MutableObjectIntMap<Node> nodeTrace = ObjectIntMaps.mutable.empty(); | ||
64 | |||
65 | private final Map<Relation, RelationInfo> relationInfoMap = new LinkedHashMap<>(); | 62 | private final Map<Relation, RelationInfo> relationInfoMap = new LinkedHashMap<>(); |
66 | 63 | ||
67 | private final Map<PartialRelation, RelationInfo> partialRelationInfoMap = new HashMap<>(); | 64 | private final Map<PartialRelation, RelationInfo> partialRelationInfoMap = new HashMap<>(); |
68 | 65 | ||
69 | private final Map<AnyPartialSymbol, Relation> inverseTrace = new HashMap<>(); | ||
70 | |||
71 | private final Map<Relation, PartialRelation> relationTrace = new LinkedHashMap<>(); | ||
72 | |||
73 | private final MetamodelBuilder metamodelBuilder = Metamodel.builder(); | 66 | private final MetamodelBuilder metamodelBuilder = Metamodel.builder(); |
74 | 67 | ||
75 | private Metamodel metamodel; | 68 | private Metamodel metamodel; |
@@ -80,81 +73,74 @@ public class ModelInitializer { | |||
80 | 73 | ||
81 | private ModelSeed modelSeed; | 74 | private ModelSeed modelSeed; |
82 | 75 | ||
83 | public Problem getProblem() { | ||
84 | return problem; | ||
85 | } | ||
86 | |||
87 | public int getNodeCount() { | ||
88 | return nodeTrace.size(); | ||
89 | } | ||
90 | |||
91 | public MutableObjectIntMap<Node> getNodeTrace() { | ||
92 | return nodeTrace; | ||
93 | } | ||
94 | |||
95 | public Map<Relation, PartialRelation> getRelationTrace() { | ||
96 | return relationTrace; | ||
97 | } | ||
98 | |||
99 | public Relation getInverseTrace(AnyPartialSymbol partialRelation) { | ||
100 | return inverseTrace.get(partialRelation); | ||
101 | } | ||
102 | |||
103 | public Metamodel getMetamodel() { | ||
104 | return metamodel; | ||
105 | } | ||
106 | |||
107 | public void readProblem(Problem problem) { | 76 | public void readProblem(Problem problem) { |
77 | if (this.problem != null) { | ||
78 | throw new IllegalArgumentException("Problem was already set"); | ||
79 | } | ||
108 | this.problem = problem; | 80 | this.problem = problem; |
109 | builtinSymbols = desugarer.getBuiltinSymbols(problem).orElseThrow(() -> new IllegalArgumentException( | 81 | problemTrace.setProblem(problem); |
110 | "Problem has no builtin library")); | 82 | try { |
111 | var nodeInfo = collectPartialRelation(builtinSymbols.node(), 1, TruthValue.TRUE, TruthValue.TRUE); | 83 | builtinSymbols = desugarer.getBuiltinSymbols(problem).orElseThrow(() -> new IllegalArgumentException( |
112 | nodeRelation = nodeInfo.partialRelation(); | 84 | "Problem has no builtin library")); |
113 | metamodelBuilder.type(nodeRelation); | 85 | var nodeInfo = collectPartialRelation(builtinSymbols.node(), 1, TruthValue.TRUE, TruthValue.TRUE); |
114 | putRelationInfo(builtinSymbols.exists(), new RelationInfo(ReasoningAdapter.EXISTS_SYMBOL, null, | 86 | nodeRelation = nodeInfo.partialRelation(); |
115 | TruthValue.TRUE)); | 87 | metamodelBuilder.type(nodeRelation); |
116 | putRelationInfo(builtinSymbols.equals(), new RelationInfo(ReasoningAdapter.EQUALS_SYMBOL, | 88 | putRelationInfo(builtinSymbols.exists(), new RelationInfo(ReasoningAdapter.EXISTS_SYMBOL, null, |
117 | (TruthValue) null, | 89 | TruthValue.TRUE)); |
118 | null)); | 90 | putRelationInfo(builtinSymbols.equals(), new RelationInfo(ReasoningAdapter.EQUALS_SYMBOL, |
119 | putRelationInfo(builtinSymbols.contained(), new RelationInfo(ContainmentHierarchyTranslator.CONTAINED_SYMBOL, | 91 | (TruthValue) null, |
120 | null, TruthValue.UNKNOWN)); | 92 | null)); |
121 | putRelationInfo(builtinSymbols.contains(), new RelationInfo(ContainmentHierarchyTranslator.CONTAINS_SYMBOL, | 93 | putRelationInfo(builtinSymbols.contained(), |
122 | null, TruthValue.UNKNOWN)); | 94 | new RelationInfo(ContainmentHierarchyTranslator.CONTAINED_SYMBOL, null, TruthValue.UNKNOWN)); |
123 | putRelationInfo(builtinSymbols.invalidContainer(), | 95 | putRelationInfo(builtinSymbols.contains(), new RelationInfo(ContainmentHierarchyTranslator.CONTAINS_SYMBOL, |
124 | new RelationInfo(ContainmentHierarchyTranslator.INVALID_CONTAINER, TruthValue.FALSE, | 96 | null, TruthValue.UNKNOWN)); |
125 | TruthValue.FALSE)); | 97 | putRelationInfo(builtinSymbols.invalidContainer(), |
126 | collectNodes(); | 98 | new RelationInfo(ContainmentHierarchyTranslator.INVALID_CONTAINER, TruthValue.FALSE, |
127 | collectPartialSymbols(); | 99 | TruthValue.FALSE)); |
128 | collectMetamodel(); | 100 | collectNodes(); |
129 | metamodel = metamodelBuilder.build(); | 101 | collectPartialSymbols(); |
130 | collectAssertions(); | 102 | collectMetamodel(); |
131 | int nodeCount = getNodeCount(); | 103 | metamodel = metamodelBuilder.build(); |
132 | var modelSeedBuilder = ModelSeed.builder(nodeCount); | 104 | problemTrace.setMetamodel(metamodel); |
133 | for (var entry : relationInfoMap.entrySet()) { | 105 | collectAssertions(); |
134 | var relation = entry.getKey(); | 106 | int nodeCount = problemTrace.getNodeTrace().size(); |
135 | var info = entry.getValue(); | 107 | var modelSeedBuilder = ModelSeed.builder(nodeCount); |
136 | var partialRelation = info.partialRelation(); | 108 | for (var entry : relationInfoMap.entrySet()) { |
137 | relationTrace.put(relation, partialRelation); | 109 | var info = entry.getValue(); |
138 | modelSeedBuilder.seed(partialRelation, info.toSeed(nodeCount)); | 110 | var partialRelation = info.partialRelation(); |
139 | } | 111 | modelSeedBuilder.seed(partialRelation, info.toSeed(nodeCount)); |
140 | collectScopes(); | 112 | } |
141 | modelSeedBuilder.seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder | 113 | collectScopes(); |
142 | .reducedValue(CardinalityIntervals.SET) | 114 | modelSeedBuilder.seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder |
143 | .putAll(countSeed)); | 115 | .reducedValue(CardinalityIntervals.SET) |
144 | modelSeed = modelSeedBuilder.build(); | 116 | .putAll(countSeed)); |
117 | modelSeed = modelSeedBuilder.build(); | ||
118 | } catch (TranslationException e) { | ||
119 | throw problemTrace.wrapException(e); | ||
120 | } | ||
145 | } | 121 | } |
146 | 122 | ||
147 | public void configureStoreBuilder(ModelStoreBuilder storeBuilder) { | 123 | public void configureStoreBuilder(ModelStoreBuilder storeBuilder) { |
148 | this.storeBuilder = storeBuilder; | 124 | checkProblem(); |
149 | storeBuilder.with(new MultiObjectTranslator()); | 125 | try { |
150 | storeBuilder.with(new MetamodelTranslator(metamodel)); | 126 | storeBuilder.with(new MultiObjectTranslator()); |
151 | if (scopePropagator != null) { | 127 | storeBuilder.with(new MetamodelTranslator(metamodel)); |
152 | if (storeBuilder.tryGetAdapter(PropagationBuilder.class).isEmpty()) { | 128 | if (scopePropagator != null) { |
153 | throw new TracedException(problem, "Type scopes require a PropagationBuilder"); | 129 | if (storeBuilder.tryGetAdapter(PropagationBuilder.class).isEmpty()) { |
130 | throw new TracedException(problem, "Type scopes require a PropagationBuilder"); | ||
131 | } | ||
132 | storeBuilder.with(scopePropagator); | ||
154 | } | 133 | } |
155 | storeBuilder.with(scopePropagator); | 134 | collectPredicates(storeBuilder); |
135 | } catch (TranslationException e) { | ||
136 | throw problemTrace.wrapException(e); | ||
137 | } | ||
138 | } | ||
139 | |||
140 | private void checkProblem() { | ||
141 | if (problem == null) { | ||
142 | throw new IllegalStateException("Problem is not set"); | ||
156 | } | 143 | } |
157 | collectPredicates(); | ||
158 | } | 144 | } |
159 | 145 | ||
160 | public ModelSeed createModel(Problem problem, ModelStoreBuilder storeBuilder) { | 146 | public ModelSeed createModel(Problem problem, ModelStoreBuilder storeBuilder) { |
@@ -163,7 +149,13 @@ public class ModelInitializer { | |||
163 | return getModelSeed(); | 149 | return getModelSeed(); |
164 | } | 150 | } |
165 | 151 | ||
152 | public ProblemTrace getProblemTrace() { | ||
153 | checkProblem(); | ||
154 | return problemTrace; | ||
155 | } | ||
156 | |||
166 | public ModelSeed getModelSeed() { | 157 | public ModelSeed getModelSeed() { |
158 | checkProblem(); | ||
167 | return modelSeed; | 159 | return modelSeed; |
168 | } | 160 | } |
169 | 161 | ||
@@ -190,7 +182,7 @@ public class ModelInitializer { | |||
190 | } | 182 | } |
191 | 183 | ||
192 | private void collectNode(Node node) { | 184 | private void collectNode(Node node) { |
193 | nodeTrace.getIfAbsentPut(node, this::getNodeCount); | 185 | problemTrace.collectNode(node); |
194 | } | 186 | } |
195 | 187 | ||
196 | private void collectPartialSymbols() { | 188 | private void collectPartialSymbols() { |
@@ -232,7 +224,7 @@ public class ModelInitializer { | |||
232 | private void putRelationInfo(Relation relation, RelationInfo info) { | 224 | private void putRelationInfo(Relation relation, RelationInfo info) { |
233 | relationInfoMap.put(relation, info); | 225 | relationInfoMap.put(relation, info); |
234 | partialRelationInfoMap.put(info.partialRelation(), info); | 226 | partialRelationInfoMap.put(info.partialRelation(), info); |
235 | inverseTrace.put(info.partialRelation(), relation); | 227 | problemTrace.putRelation(relation, info.partialRelation()); |
236 | } | 228 | } |
237 | 229 | ||
238 | private RelationInfo collectPartialRelation(Relation relation, int arity, TruthValue value, | 230 | private RelationInfo collectPartialRelation(Relation relation, int arity, TruthValue value, |
@@ -241,7 +233,7 @@ public class ModelInitializer { | |||
241 | var name = getName(relation); | 233 | var name = getName(relation); |
242 | var info = new RelationInfo(name, arity, value, defaultValue); | 234 | var info = new RelationInfo(name, arity, value, defaultValue); |
243 | partialRelationInfoMap.put(info.partialRelation(), info); | 235 | partialRelationInfoMap.put(info.partialRelation(), info); |
244 | inverseTrace.put(info.partialRelation(), relation); | 236 | problemTrace.putRelation(relation, info.partialRelation()); |
245 | return info; | 237 | return info; |
246 | }); | 238 | }); |
247 | } | 239 | } |
@@ -421,7 +413,7 @@ public class ModelInitializer { | |||
421 | } | 413 | } |
422 | 414 | ||
423 | private int getNodeId(Node node) { | 415 | private int getNodeId(Node node) { |
424 | return nodeTrace.getOrThrow(node); | 416 | return problemTrace.getNodeId(node); |
425 | } | 417 | } |
426 | 418 | ||
427 | private Tuple getTuple(Assertion assertion) { | 419 | private Tuple getTuple(Assertion assertion) { |
@@ -453,17 +445,18 @@ public class ModelInitializer { | |||
453 | }; | 445 | }; |
454 | } | 446 | } |
455 | 447 | ||
456 | private void collectPredicates() { | 448 | private void collectPredicates(ModelStoreBuilder storeBuilder) { |
457 | for (var statement : problem.getStatements()) { | 449 | for (var statement : problem.getStatements()) { |
458 | if (statement instanceof PredicateDefinition predicateDefinition) { | 450 | if (statement instanceof PredicateDefinition predicateDefinition) { |
459 | collectPredicateDefinitionTraced(predicateDefinition); | 451 | collectPredicateDefinitionTraced(predicateDefinition, storeBuilder); |
460 | } | 452 | } |
461 | } | 453 | } |
462 | } | 454 | } |
463 | 455 | ||
464 | private void collectPredicateDefinitionTraced(PredicateDefinition predicateDefinition) { | 456 | private void collectPredicateDefinitionTraced(PredicateDefinition predicateDefinition, |
457 | ModelStoreBuilder storeBuilder) { | ||
465 | try { | 458 | try { |
466 | collectPredicateDefinition(predicateDefinition); | 459 | collectPredicateDefinition(predicateDefinition, storeBuilder); |
467 | } catch (InvalidClauseException e) { | 460 | } catch (InvalidClauseException e) { |
468 | int clauseIndex = e.getClauseIndex(); | 461 | int clauseIndex = e.getClauseIndex(); |
469 | var bodies = predicateDefinition.getBodies(); | 462 | var bodies = predicateDefinition.getBodies(); |
@@ -477,7 +470,7 @@ public class ModelInitializer { | |||
477 | } | 470 | } |
478 | } | 471 | } |
479 | 472 | ||
480 | private void collectPredicateDefinition(PredicateDefinition predicateDefinition) { | 473 | private void collectPredicateDefinition(PredicateDefinition predicateDefinition, ModelStoreBuilder storeBuilder) { |
481 | var partialRelation = getPartialRelation(predicateDefinition); | 474 | var partialRelation = getPartialRelation(predicateDefinition); |
482 | var query = toQuery(partialRelation.name(), predicateDefinition); | 475 | var query = toQuery(partialRelation.name(), predicateDefinition); |
483 | boolean mutable; | 476 | boolean mutable; |
@@ -488,7 +481,7 @@ public class ModelInitializer { | |||
488 | } else { | 481 | } else { |
489 | var seed = modelSeed.getSeed(partialRelation); | 482 | var seed = modelSeed.getSeed(partialRelation); |
490 | defaultValue = seed.reducedValue() == TruthValue.FALSE ? TruthValue.FALSE : TruthValue.UNKNOWN; | 483 | defaultValue = seed.reducedValue() == TruthValue.FALSE ? TruthValue.FALSE : TruthValue.UNKNOWN; |
491 | var cursor = seed.getCursor(defaultValue, getNodeCount()); | 484 | var cursor = seed.getCursor(defaultValue, problemTrace.getNodeTrace().size()); |
492 | // The symbol should be mutable if there is at least one non-default entry in the seed. | 485 | // The symbol should be mutable if there is at least one non-default entry in the seed. |
493 | mutable = cursor.move(); | 486 | mutable = cursor.move(); |
494 | } | 487 | } |
@@ -652,8 +645,8 @@ public class ModelInitializer { | |||
652 | if (newNode == null) { | 645 | if (newNode == null) { |
653 | throw new TracedException(typeScope, "Target of incremental type scope must be concrete class"); | 646 | throw new TracedException(typeScope, "Target of incremental type scope must be concrete class"); |
654 | } | 647 | } |
655 | int newNodeId = nodeTrace.get(newNode); | 648 | int newNodeId = getNodeId(newNode); |
656 | var type = relationTrace.get(classDeclaration); | 649 | var type = problemTrace.getPartialRelation(classDeclaration); |
657 | var typeInfo = metamodel.typeHierarchy().getAnalysisResult(type); | 650 | var typeInfo = metamodel.typeHierarchy().getAnalysisResult(type); |
658 | if (!typeInfo.getDirectSubtypes().isEmpty()) { | 651 | if (!typeInfo.getDirectSubtypes().isEmpty()) { |
659 | throw new TracedException(typeScope, "Target of incremental type scope cannot have any subclasses"); | 652 | throw new TracedException(typeScope, "Target of incremental type scope cannot have any subclasses"); |
@@ -664,10 +657,7 @@ public class ModelInitializer { | |||
664 | } | 657 | } |
665 | 658 | ||
666 | private void collectTypeScope(TypeScope typeScope) { | 659 | private void collectTypeScope(TypeScope typeScope) { |
667 | var type = relationTrace.get(typeScope.getTargetType()); | 660 | var type = problemTrace.getPartialRelation(typeScope.getTargetType()); |
668 | if (type == null) { | ||
669 | throw new TracedException(typeScope, "Unknown target type"); | ||
670 | } | ||
671 | var interval = getCardinalityInterval(typeScope.getMultiplicity()); | 661 | var interval = getCardinalityInterval(typeScope.getMultiplicity()); |
672 | if (scopePropagator == null) { | 662 | if (scopePropagator == null) { |
673 | scopePropagator = new ScopePropagator(); | 663 | scopePropagator = new ScopePropagator(); |
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemTrace.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTrace.java index f7963c58..b8d0b804 100644 --- a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemTrace.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTrace.java | |||
@@ -3,33 +3,44 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.generator; | 6 | package tools.refinery.language.semantics; |
7 | 7 | ||
8 | import org.eclipse.collections.api.map.primitive.ObjectIntMap; | ||
8 | import org.eclipse.xtext.naming.QualifiedName; | 9 | import org.eclipse.xtext.naming.QualifiedName; |
10 | import tools.refinery.language.model.problem.Node; | ||
9 | import tools.refinery.language.model.problem.Problem; | 11 | import tools.refinery.language.model.problem.Problem; |
10 | import tools.refinery.language.model.problem.Relation; | 12 | 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; | 13 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; |
14 | import tools.refinery.store.reasoning.representation.PartialRelation; | 14 | import tools.refinery.store.reasoning.representation.PartialRelation; |
15 | import tools.refinery.store.reasoning.translator.TranslationException; | ||
16 | import tools.refinery.store.reasoning.translator.metamodel.Metamodel; | ||
15 | 17 | ||
16 | import java.util.List; | ||
17 | import java.util.Map; | 18 | import java.util.Map; |
18 | 19 | ||
19 | public interface ProblemTrace { | 20 | public interface ProblemTrace { |
20 | Problem getProblem(); | 21 | Problem getProblem(); |
21 | 22 | ||
23 | Metamodel getMetamodel(); | ||
24 | |||
25 | ObjectIntMap<Node> getNodeTrace(); | ||
26 | |||
27 | int getNodeId(Node node); | ||
28 | |||
29 | int getNodeId(QualifiedName qualifiedName); | ||
30 | |||
31 | int getNodeId(String qualifiedName); | ||
32 | |||
22 | Map<Relation, PartialRelation> getRelationTrace(); | 33 | Map<Relation, PartialRelation> getRelationTrace(); |
23 | 34 | ||
24 | Relation getInverseTrace(AnyPartialSymbol partialSymbol); | 35 | Map<AnyPartialSymbol, Relation> getInverseRelationTrace(); |
36 | |||
37 | Relation getRelation(AnyPartialSymbol partialSymbol); | ||
38 | |||
39 | RuntimeException wrapException(TranslationException translationException); | ||
25 | 40 | ||
26 | PartialRelation getPartialRelation(Relation relation); | 41 | PartialRelation getPartialRelation(Relation relation); |
27 | 42 | ||
28 | PartialRelation getPartialRelation(QualifiedName qualifiedName); | 43 | PartialRelation getPartialRelation(QualifiedName qualifiedName); |
29 | 44 | ||
30 | PartialRelation getPartialRelation(String qualifiedName); | 45 | PartialRelation getPartialRelation(String qualifiedName); |
31 | |||
32 | List<RelationMetadata> getRelationsMetadata(); | ||
33 | |||
34 | List<NodeMetadata> getNodesMetadata(int nodeCount, boolean preserveNewNodes); | ||
35 | } | 46 | } |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTraceImpl.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTraceImpl.java new file mode 100644 index 00000000..cc634949 --- /dev/null +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTraceImpl.java | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.language.semantics; | ||
7 | |||
8 | import com.google.inject.Inject; | ||
9 | import org.eclipse.collections.api.factory.primitive.ObjectIntMaps; | ||
10 | import org.eclipse.collections.api.map.primitive.MutableObjectIntMap; | ||
11 | import org.eclipse.collections.api.map.primitive.ObjectIntMap; | ||
12 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
13 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | ||
14 | import org.eclipse.xtext.naming.QualifiedName; | ||
15 | import org.eclipse.xtext.scoping.IScope; | ||
16 | import org.eclipse.xtext.scoping.IScopeProvider; | ||
17 | import tools.refinery.language.model.problem.Node; | ||
18 | import tools.refinery.language.model.problem.Problem; | ||
19 | import tools.refinery.language.model.problem.ProblemPackage; | ||
20 | import tools.refinery.language.model.problem.Relation; | ||
21 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; | ||
22 | import tools.refinery.store.reasoning.representation.PartialRelation; | ||
23 | import tools.refinery.store.reasoning.translator.TranslationException; | ||
24 | import tools.refinery.store.reasoning.translator.metamodel.Metamodel; | ||
25 | |||
26 | import java.util.Collections; | ||
27 | import java.util.HashMap; | ||
28 | import java.util.LinkedHashMap; | ||
29 | import java.util.Map; | ||
30 | |||
31 | public class ProblemTraceImpl implements ProblemTrace { | ||
32 | @Inject | ||
33 | private IQualifiedNameConverter qualifiedNameConverter; | ||
34 | |||
35 | @Inject | ||
36 | private SemanticsUtils semanticsUtils; | ||
37 | |||
38 | @Inject | ||
39 | private IScopeProvider scopeProvider; | ||
40 | |||
41 | private Problem problem; | ||
42 | private Metamodel metamodel; | ||
43 | private final MutableObjectIntMap<Node> mutableNodeTrace = ObjectIntMaps.mutable.empty(); | ||
44 | private final ObjectIntMap<Node> nodeTrace = mutableNodeTrace.asUnmodifiable(); | ||
45 | private final Map<Relation, PartialRelation> mutableRelationTrace = new LinkedHashMap<>(); | ||
46 | private final Map<Relation, PartialRelation> relationTrace = | ||
47 | Collections.unmodifiableMap(mutableRelationTrace); | ||
48 | private final Map<AnyPartialSymbol, Relation> mutableInverseTrace = new HashMap<>(); | ||
49 | private final Map<AnyPartialSymbol, Relation> inverseTrace = Collections.unmodifiableMap(mutableInverseTrace); | ||
50 | |||
51 | @Override | ||
52 | public Problem getProblem() { | ||
53 | return problem; | ||
54 | } | ||
55 | |||
56 | void setProblem(Problem problem) { | ||
57 | this.problem = problem; | ||
58 | } | ||
59 | |||
60 | @Override | ||
61 | public Metamodel getMetamodel() { | ||
62 | return metamodel; | ||
63 | } | ||
64 | |||
65 | void setMetamodel(Metamodel metamodel) { | ||
66 | this.metamodel = metamodel; | ||
67 | } | ||
68 | |||
69 | @Override | ||
70 | public ObjectIntMap<Node> getNodeTrace() { | ||
71 | return nodeTrace; | ||
72 | } | ||
73 | |||
74 | void collectNode(Node node) { | ||
75 | mutableNodeTrace.getIfAbsentPut(node, mutableNodeTrace.size()); | ||
76 | } | ||
77 | |||
78 | @Override | ||
79 | public int getNodeId(Node node) { | ||
80 | try { | ||
81 | return nodeTrace.getOrThrow(node); | ||
82 | } catch (IllegalStateException e) { | ||
83 | var qualifiedName = semanticsUtils.getName(node); | ||
84 | throw new TracedException(node, "No node ID for " + qualifiedName, e); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | @Override | ||
89 | public int getNodeId(QualifiedName qualifiedName) { | ||
90 | var nodeScope = scopeProvider.getScope(problem, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE); | ||
91 | return getNodeId(getElement(nodeScope, qualifiedName, Node.class)); | ||
92 | } | ||
93 | |||
94 | @Override | ||
95 | public int getNodeId(String qualifiedName) { | ||
96 | var convertedName = qualifiedNameConverter.toQualifiedName(qualifiedName); | ||
97 | return getNodeId(convertedName); | ||
98 | } | ||
99 | |||
100 | @Override | ||
101 | public Map<Relation, PartialRelation> getRelationTrace() { | ||
102 | return relationTrace; | ||
103 | } | ||
104 | |||
105 | void putRelation(Relation relation, PartialRelation partialRelation) { | ||
106 | var oldPartialRelation = mutableRelationTrace.put(relation, partialRelation); | ||
107 | if (oldPartialRelation != null) { | ||
108 | throw new TracedException(relation, "Relation already mapped to partial relation: " + oldPartialRelation); | ||
109 | } | ||
110 | var oldRelation = mutableInverseTrace.put(partialRelation, relation); | ||
111 | if (oldRelation != null) { | ||
112 | throw new TracedException(oldRelation, "Partial relation %s was already mapped to relation" | ||
113 | .formatted(partialRelation)); | ||
114 | } | ||
115 | } | ||
116 | |||
117 | @Override | ||
118 | public Map<AnyPartialSymbol, Relation> getInverseRelationTrace() { | ||
119 | return inverseTrace; | ||
120 | } | ||
121 | |||
122 | @Override | ||
123 | public Relation getRelation(AnyPartialSymbol partialSymbol) { | ||
124 | var relation = mutableInverseTrace.get(partialSymbol); | ||
125 | if (relation == null) { | ||
126 | throw new IllegalArgumentException("No relation for partial symbol: " + partialSymbol); | ||
127 | } | ||
128 | return relation; | ||
129 | } | ||
130 | |||
131 | @Override | ||
132 | public RuntimeException wrapException(TranslationException translationException) { | ||
133 | var partialSymbol = translationException.getPartialSymbol(); | ||
134 | if (partialSymbol == null) { | ||
135 | return translationException; | ||
136 | } | ||
137 | var relation = mutableInverseTrace.get(partialSymbol); | ||
138 | if (relation == null) { | ||
139 | return translationException; | ||
140 | } | ||
141 | return new TracedException(relation, translationException); | ||
142 | } | ||
143 | |||
144 | @Override | ||
145 | public PartialRelation getPartialRelation(Relation relation) { | ||
146 | var partialRelation = mutableRelationTrace.get(relation); | ||
147 | if (partialRelation == null) { | ||
148 | var qualifiedName = semanticsUtils.getName(relation); | ||
149 | throw new TracedException(relation, "No partial relation for " + qualifiedName); | ||
150 | } | ||
151 | return partialRelation; | ||
152 | } | ||
153 | |||
154 | @Override | ||
155 | public PartialRelation getPartialRelation(QualifiedName qualifiedName) { | ||
156 | var relationScope = scopeProvider.getScope(problem, ProblemPackage.Literals.ASSERTION__RELATION); | ||
157 | return getPartialRelation(getElement(relationScope, qualifiedName, Relation.class)); | ||
158 | } | ||
159 | |||
160 | @Override | ||
161 | public PartialRelation getPartialRelation(String qualifiedName) { | ||
162 | var convertedName = qualifiedNameConverter.toQualifiedName(qualifiedName); | ||
163 | return getPartialRelation(convertedName); | ||
164 | } | ||
165 | |||
166 | private <T> T getElement(IScope scope, QualifiedName qualifiedName, Class<T> type) { | ||
167 | var iterator = scope.getElements(qualifiedName).iterator(); | ||
168 | if (!iterator.hasNext()) { | ||
169 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
170 | throw new IllegalArgumentException("No such %s: %s" | ||
171 | .formatted(type.getName(), qualifiedNameString)); | ||
172 | } | ||
173 | var eObjectDescription = iterator.next(); | ||
174 | if (iterator.hasNext()) { | ||
175 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
176 | throw new IllegalArgumentException("Ambiguous %s: %s" | ||
177 | .formatted(type.getName(), qualifiedNameString)); | ||
178 | } | ||
179 | var eObject = EcoreUtil.resolve(eObjectDescription.getEObjectOrProxy(), getProblem()); | ||
180 | if (!type.isInstance(eObject)) { | ||
181 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
182 | throw new IllegalArgumentException("Not a %s: %s" | ||
183 | .formatted(type.getName(), qualifiedNameString)); | ||
184 | } | ||
185 | return type.cast(eObject); | ||
186 | } | ||
187 | } | ||
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/SemanticsUtils.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SemanticsUtils.java index 47c89e9b..b195a8e7 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/SemanticsUtils.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SemanticsUtils.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model; | 6 | package tools.refinery.language.semantics; |
7 | 7 | ||
8 | import com.google.inject.Inject; | 8 | import com.google.inject.Inject; |
9 | import com.google.inject.Singleton; | 9 | import com.google.inject.Singleton; |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/TracedException.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/TracedException.java index 38fd8a67..8636bdab 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/TracedException.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/TracedException.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model; | 6 | package tools.refinery.language.semantics; |
7 | 7 | ||
8 | import org.eclipse.emf.ecore.EObject; | 8 | import org.eclipse.emf.ecore.EObject; |
9 | 9 | ||
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTree.java index 32112e61..c732f784 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTree.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model.internal; | 6 | package tools.refinery.language.semantics.internal; |
7 | 7 | ||
8 | import org.eclipse.collections.api.factory.primitive.IntObjectMaps; | 8 | import org.eclipse.collections.api.factory.primitive.IntObjectMaps; |
9 | import tools.refinery.store.map.Cursor; | 9 | import tools.refinery.store.map.Cursor; |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeCursor.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java index a9fc644a..71b54cbd 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeCursor.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model.internal; | 6 | package tools.refinery.language.semantics.internal; |
7 | 7 | ||
8 | import tools.refinery.store.map.Cursor; | 8 | import tools.refinery.store.map.Cursor; |
9 | import tools.refinery.store.representation.TruthValue; | 9 | import tools.refinery.store.representation.TruthValue; |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeNode.java index 3c54e3c5..ebca2634 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeNode.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model.internal; | 6 | package tools.refinery.language.semantics.internal; |
7 | 7 | ||
8 | import org.eclipse.collections.api.LazyIntIterable; | 8 | import org.eclipse.collections.api.LazyIntIterable; |
9 | import tools.refinery.store.tuple.Tuple; | 9 | import tools.refinery.store.tuple.Tuple; |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeValue.java index 915ae2bf..5053e7ac 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeValue.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model.internal; | 6 | package tools.refinery.language.semantics.internal; |
7 | 7 | ||
8 | import tools.refinery.store.representation.TruthValue; | 8 | import tools.refinery.store.representation.TruthValue; |
9 | 9 | ||
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/IntermediateNode.java index e6f01d48..0e2f5d18 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/IntermediateNode.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model.internal; | 6 | package tools.refinery.language.semantics.internal; |
7 | 7 | ||
8 | import org.eclipse.collections.api.LazyIntIterable; | 8 | import org.eclipse.collections.api.LazyIntIterable; |
9 | import org.eclipse.collections.api.factory.primitive.IntObjectMaps; | 9 | import org.eclipse.collections.api.factory.primitive.IntObjectMaps; |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/MutableSeed.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/MutableSeed.java index 99019e2a..693b9e1f 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/MutableSeed.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/MutableSeed.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model.internal; | 6 | package tools.refinery.language.semantics.internal; |
7 | 7 | ||
8 | import tools.refinery.store.reasoning.seed.Seed; | 8 | import tools.refinery.store.reasoning.seed.Seed; |
9 | import tools.refinery.store.representation.TruthValue; | 9 | import tools.refinery.store.representation.TruthValue; |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/NullaryMutableSeed.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/NullaryMutableSeed.java index 80644b1f..7a72c656 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/NullaryMutableSeed.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/NullaryMutableSeed.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model.internal; | 6 | package tools.refinery.language.semantics.internal; |
7 | 7 | ||
8 | import tools.refinery.store.map.Cursor; | 8 | import tools.refinery.store.map.Cursor; |
9 | import tools.refinery.store.map.Cursors; | 9 | import tools.refinery.store.map.Cursors; |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/TerminalNode.java index ce49aa62..d3dd757c 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/TerminalNode.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model.internal; | 6 | package tools.refinery.language.semantics.internal; |
7 | 7 | ||
8 | import org.eclipse.collections.api.LazyIntIterable; | 8 | import org.eclipse.collections.api.LazyIntIterable; |
9 | import org.eclipse.collections.api.factory.primitive.IntObjectMaps; | 9 | import org.eclipse.collections.api.factory.primitive.IntObjectMaps; |
diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/CountPropagationTest.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/CountPropagationTest.java index 6beae93a..b679c1ef 100644 --- a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/CountPropagationTest.java +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/CountPropagationTest.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model; | 6 | package tools.refinery.language.semantics; |
7 | 7 | ||
8 | import org.junit.jupiter.api.Test; | 8 | import org.junit.jupiter.api.Test; |
9 | import tools.refinery.store.dse.propagation.PropagationAdapter; | 9 | import tools.refinery.store.dse.propagation.PropagationAdapter; |
diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/ModelGenerationTest.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/ModelGenerationTest.java index c8a79c37..899e3cb3 100644 --- a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/ModelGenerationTest.java +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/ModelGenerationTest.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model; | 6 | package tools.refinery.language.semantics; |
7 | 7 | ||
8 | import com.google.inject.Inject; | 8 | import com.google.inject.Inject; |
9 | import org.eclipse.xtext.testing.InjectWith; | 9 | import org.eclipse.xtext.testing.InjectWith; |
diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/internal/DecisionTreeTests.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/internal/DecisionTreeTests.java index 5d039308..2320de2c 100644 --- a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/internal/DecisionTreeTests.java +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/internal/DecisionTreeTests.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.model.internal; | 6 | package tools.refinery.language.semantics.internal; |
7 | 7 | ||
8 | import org.junit.jupiter.api.Test; | 8 | import org.junit.jupiter.api.Test; |
9 | import tools.refinery.store.representation.TruthValue; | 9 | import tools.refinery.store.representation.TruthValue; |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/generator/ModelGenerationSuccessResult.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/generator/ModelGenerationSuccessResult.java index 21be4e08..0abe116e 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/generator/ModelGenerationSuccessResult.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/generator/ModelGenerationSuccessResult.java | |||
@@ -6,8 +6,8 @@ | |||
6 | package tools.refinery.language.web.generator; | 6 | package tools.refinery.language.web.generator; |
7 | 7 | ||
8 | import com.google.gson.JsonObject; | 8 | import com.google.gson.JsonObject; |
9 | import tools.refinery.language.semantics.metadata.NodeMetadata; | 9 | import tools.refinery.language.web.semantics.metadata.NodeMetadata; |
10 | import tools.refinery.language.semantics.metadata.RelationMetadata; | 10 | import tools.refinery.language.web.semantics.metadata.RelationMetadata; |
11 | 11 | ||
12 | import java.util.List; | 12 | import java.util.List; |
13 | import java.util.UUID; | 13 | import java.util.UUID; |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/generator/ModelGenerationWorker.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/generator/ModelGenerationWorker.java index 7b4f957c..a3b6ca82 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/generator/ModelGenerationWorker.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/generator/ModelGenerationWorker.java | |||
@@ -9,12 +9,14 @@ import com.google.inject.Inject; | |||
9 | import org.eclipse.xtext.service.OperationCanceledManager; | 9 | import org.eclipse.xtext.service.OperationCanceledManager; |
10 | import org.slf4j.Logger; | 10 | import org.slf4j.Logger; |
11 | import org.slf4j.LoggerFactory; | 11 | import org.slf4j.LoggerFactory; |
12 | import tools.refinery.generator.ModelGeneratorBuilder; | 12 | import tools.refinery.generator.ModelGenerator; |
13 | import tools.refinery.generator.ModelGeneratorFactory; | ||
14 | import tools.refinery.language.web.semantics.metadata.MetadataCreator; | ||
15 | import tools.refinery.generator.ProblemLoader; | ||
13 | import tools.refinery.generator.ValidationErrorsException; | 16 | import tools.refinery.generator.ValidationErrorsException; |
14 | import tools.refinery.language.web.semantics.PartialInterpretation2Json; | 17 | import tools.refinery.language.web.semantics.PartialInterpretation2Json; |
15 | import tools.refinery.language.web.xtext.server.ThreadPoolExecutorServiceProvider; | 18 | import tools.refinery.language.web.xtext.server.ThreadPoolExecutorServiceProvider; |
16 | import tools.refinery.language.web.xtext.server.push.PushWebDocument; | 19 | import tools.refinery.language.web.xtext.server.push.PushWebDocument; |
17 | import tools.refinery.store.reasoning.literal.Concreteness; | ||
18 | import tools.refinery.store.util.CancellationToken; | 20 | import tools.refinery.store.util.CancellationToken; |
19 | 21 | ||
20 | import java.io.IOException; | 22 | import java.io.IOException; |
@@ -38,7 +40,13 @@ public class ModelGenerationWorker implements Runnable { | |||
38 | private OperationCanceledManager operationCanceledManager; | 40 | private OperationCanceledManager operationCanceledManager; |
39 | 41 | ||
40 | @Inject | 42 | @Inject |
41 | private ModelGeneratorBuilder generatorBuilder; | 43 | private ProblemLoader problemLoader; |
44 | |||
45 | @Inject | ||
46 | private ModelGeneratorFactory generatorFactory; | ||
47 | |||
48 | @Inject | ||
49 | private MetadataCreator metadataCreator; | ||
42 | 50 | ||
43 | @Inject | 51 | @Inject |
44 | private PartialInterpretation2Json partialInterpretation2Json; | 52 | private PartialInterpretation2Json partialInterpretation2Json; |
@@ -127,9 +135,10 @@ public class ModelGenerationWorker implements Runnable { | |||
127 | 135 | ||
128 | public ModelGenerationResult doRun() throws IOException { | 136 | public ModelGenerationResult doRun() throws IOException { |
129 | cancellationToken.checkCancelled(); | 137 | cancellationToken.checkCancelled(); |
138 | var problem = problemLoader.cancellationToken(cancellationToken).loadString(text); | ||
139 | ModelGenerator generator; | ||
130 | try { | 140 | try { |
131 | generatorBuilder.cancellationToken(cancellationToken); | 141 | generator = generatorFactory.cancellationToken(cancellationToken).createGenerator(problem); |
132 | generatorBuilder.fromString(text); | ||
133 | } catch (ValidationErrorsException e) { | 142 | } catch (ValidationErrorsException e) { |
134 | var errors = e.getErrors(); | 143 | var errors = e.getErrors(); |
135 | if (errors != null && !errors.isEmpty()) { | 144 | if (errors != null && !errors.isEmpty()) { |
@@ -137,20 +146,19 @@ public class ModelGenerationWorker implements Runnable { | |||
137 | } | 146 | } |
138 | throw e; | 147 | throw e; |
139 | } | 148 | } |
140 | var generator = generatorBuilder.build(); | ||
141 | notifyResult(new ModelGenerationStatusResult(uuid, "Generating model")); | 149 | notifyResult(new ModelGenerationStatusResult(uuid, "Generating model")); |
142 | generator.setRandomSeed(randomSeed); | 150 | generator.setRandomSeed(randomSeed); |
143 | if (!generator.tryRun()) { | 151 | if (!generator.tryGenerate()) { |
144 | return new ModelGenerationErrorResult(uuid, "Problem is unsatisfiable"); | 152 | return new ModelGenerationErrorResult(uuid, "Problem is unsatisfiable"); |
145 | } | 153 | } |
146 | notifyResult(new ModelGenerationStatusResult(uuid, "Saving generated model")); | 154 | notifyResult(new ModelGenerationStatusResult(uuid, "Saving generated model")); |
147 | cancellationToken.checkCancelled(); | 155 | cancellationToken.checkCancelled(); |
148 | var nodesMetadata = generator.getNodesMetadata(); | 156 | metadataCreator.setProblemTrace(generator.getProblemTrace()); |
157 | var nodesMetadata = metadataCreator.getNodesMetadata(generator.getModel(), false); | ||
149 | cancellationToken.checkCancelled(); | 158 | cancellationToken.checkCancelled(); |
150 | var relationsMetadata = generator.getProblemTrace().getRelationsMetadata(); | 159 | var relationsMetadata = metadataCreator.getRelationsMetadata(); |
151 | cancellationToken.checkCancelled(); | 160 | cancellationToken.checkCancelled(); |
152 | var partialInterpretation = partialInterpretation2Json.getPartialInterpretation(generator, | 161 | var partialInterpretation = partialInterpretation2Json.getPartialInterpretation(generator, cancellationToken); |
153 | Concreteness.CANDIDATE, cancellationToken); | ||
154 | return new ModelGenerationSuccessResult(uuid, nodesMetadata, relationsMetadata, partialInterpretation); | 162 | return new ModelGenerationSuccessResult(uuid, nodesMetadata, relationsMetadata, partialInterpretation); |
155 | } | 163 | } |
156 | 164 | ||
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/PartialInterpretation2Json.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/PartialInterpretation2Json.java index 7afed5c0..efe04592 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/PartialInterpretation2Json.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/PartialInterpretation2Json.java | |||
@@ -9,12 +9,10 @@ import com.google.gson.JsonArray; | |||
9 | import com.google.gson.JsonObject; | 9 | import com.google.gson.JsonObject; |
10 | import com.google.inject.Inject; | 10 | import com.google.inject.Inject; |
11 | import com.google.inject.Singleton; | 11 | import com.google.inject.Singleton; |
12 | import tools.refinery.generator.AbstractRefinery; | 12 | import tools.refinery.generator.ModelFacade; |
13 | import tools.refinery.language.semantics.model.SemanticsUtils; | 13 | import tools.refinery.language.semantics.SemanticsUtils; |
14 | import tools.refinery.store.map.Cursor; | 14 | import tools.refinery.store.map.Cursor; |
15 | import tools.refinery.store.model.Model; | 15 | import tools.refinery.store.model.Model; |
16 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
17 | import tools.refinery.store.reasoning.literal.Concreteness; | ||
18 | import tools.refinery.store.reasoning.representation.PartialRelation; | 16 | import tools.refinery.store.reasoning.representation.PartialRelation; |
19 | import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; | 17 | import tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator; |
20 | import tools.refinery.store.tuple.Tuple; | 18 | import tools.refinery.store.tuple.Tuple; |
@@ -27,15 +25,13 @@ public class PartialInterpretation2Json { | |||
27 | @Inject | 25 | @Inject |
28 | private SemanticsUtils semanticsUtils; | 26 | private SemanticsUtils semanticsUtils; |
29 | 27 | ||
30 | public JsonObject getPartialInterpretation(AbstractRefinery refinery, Concreteness concreteness, | 28 | public JsonObject getPartialInterpretation(ModelFacade facade, CancellationToken cancellationToken) { |
31 | CancellationToken cancellationToken) { | 29 | var model = facade.getModel(); |
32 | var model = refinery.getModel(); | ||
33 | var adapter = model.getAdapter(ReasoningAdapter.class); | ||
34 | var json = new JsonObject(); | 30 | var json = new JsonObject(); |
35 | for (var entry : refinery.getProblemTrace().getRelationTrace().entrySet()) { | 31 | for (var entry : facade.getProblemTrace().getRelationTrace().entrySet()) { |
36 | var relation = entry.getKey(); | 32 | var relation = entry.getKey(); |
37 | var partialSymbol = entry.getValue(); | 33 | var partialSymbol = entry.getValue(); |
38 | var tuples = getTuplesJson(adapter, concreteness, partialSymbol); | 34 | var tuples = getTuplesJson(facade, partialSymbol); |
39 | var name = semanticsUtils.getName(relation).orElse(partialSymbol.name()); | 35 | var name = semanticsUtils.getName(relation).orElse(partialSymbol.name()); |
40 | json.add(name, tuples); | 36 | json.add(name, tuples); |
41 | cancellationToken.checkCancelled(); | 37 | cancellationToken.checkCancelled(); |
@@ -44,9 +40,8 @@ public class PartialInterpretation2Json { | |||
44 | return json; | 40 | return json; |
45 | } | 41 | } |
46 | 42 | ||
47 | private static JsonArray getTuplesJson(ReasoningAdapter adapter, Concreteness concreteness, | 43 | private static JsonArray getTuplesJson(ModelFacade facade, PartialRelation partialSymbol) { |
48 | PartialRelation partialSymbol) { | 44 | var interpretation = facade.getPartialInterpretation(partialSymbol); |
49 | var interpretation = adapter.getPartialInterpretation(concreteness, partialSymbol); | ||
50 | var cursor = interpretation.getAll(); | 45 | var cursor = interpretation.getAll(); |
51 | return getTuplesJson(cursor); | 46 | return getTuplesJson(cursor); |
52 | } | 47 | } |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsSuccessResult.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsSuccessResult.java index 350b0b2b..f26fa2b2 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsSuccessResult.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsSuccessResult.java | |||
@@ -6,8 +6,8 @@ | |||
6 | package tools.refinery.language.web.semantics; | 6 | package tools.refinery.language.web.semantics; |
7 | 7 | ||
8 | import com.google.gson.JsonObject; | 8 | import com.google.gson.JsonObject; |
9 | import tools.refinery.language.semantics.metadata.NodeMetadata; | 9 | import tools.refinery.language.web.semantics.metadata.NodeMetadata; |
10 | import tools.refinery.language.semantics.metadata.RelationMetadata; | 10 | import tools.refinery.language.web.semantics.metadata.RelationMetadata; |
11 | 11 | ||
12 | import java.util.List; | 12 | import java.util.List; |
13 | 13 | ||
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsWorker.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsWorker.java index a8f16c84..44974869 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsWorker.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/SemanticsWorker.java | |||
@@ -16,10 +16,10 @@ import org.eclipse.xtext.validation.IDiagnosticConverter; | |||
16 | import org.eclipse.xtext.validation.Issue; | 16 | import org.eclipse.xtext.validation.Issue; |
17 | import org.eclipse.xtext.web.server.validation.ValidationResult; | 17 | import org.eclipse.xtext.web.server.validation.ValidationResult; |
18 | import tools.refinery.generator.ModelSemantics; | 18 | import tools.refinery.generator.ModelSemantics; |
19 | import tools.refinery.generator.ModelSemanticsBuilder; | 19 | import tools.refinery.generator.ModelSemanticsFactory; |
20 | import tools.refinery.language.model.problem.Problem; | 20 | import tools.refinery.language.model.problem.Problem; |
21 | import tools.refinery.language.semantics.model.TracedException; | 21 | import tools.refinery.language.web.semantics.metadata.MetadataCreator; |
22 | import tools.refinery.store.reasoning.literal.Concreteness; | 22 | import tools.refinery.language.semantics.TracedException; |
23 | import tools.refinery.store.reasoning.translator.TranslationException; | 23 | import tools.refinery.store.reasoning.translator.TranslationException; |
24 | import tools.refinery.store.util.CancellationToken; | 24 | import tools.refinery.store.util.CancellationToken; |
25 | 25 | ||
@@ -30,16 +30,19 @@ class SemanticsWorker implements Callable<SemanticsResult> { | |||
30 | private static final String DIAGNOSTIC_ID = "tools.refinery.language.semantics.SemanticError"; | 30 | private static final String DIAGNOSTIC_ID = "tools.refinery.language.semantics.SemanticError"; |
31 | 31 | ||
32 | @Inject | 32 | @Inject |
33 | private PartialInterpretation2Json partialInterpretation2Json; | ||
34 | |||
35 | @Inject | ||
36 | private OperationCanceledManager operationCanceledManager; | 33 | private OperationCanceledManager operationCanceledManager; |
37 | 34 | ||
38 | @Inject | 35 | @Inject |
39 | private IDiagnosticConverter diagnosticConverter; | 36 | private IDiagnosticConverter diagnosticConverter; |
40 | 37 | ||
41 | @Inject | 38 | @Inject |
42 | private ModelSemanticsBuilder semanticsBuilder; | 39 | private ModelSemanticsFactory semanticsFactory; |
40 | |||
41 | @Inject | ||
42 | private MetadataCreator metadataCreator; | ||
43 | |||
44 | @Inject | ||
45 | private PartialInterpretation2Json partialInterpretation2Json; | ||
43 | 46 | ||
44 | private Problem problem; | 47 | private Problem problem; |
45 | 48 | ||
@@ -56,13 +59,10 @@ class SemanticsWorker implements Callable<SemanticsResult> { | |||
56 | 59 | ||
57 | @Override | 60 | @Override |
58 | public SemanticsResult call() { | 61 | public SemanticsResult call() { |
59 | semanticsBuilder.cancellationToken(cancellationToken); | ||
60 | cancellationToken.checkCancelled(); | 62 | cancellationToken.checkCancelled(); |
61 | ModelSemantics semantics; | 63 | ModelSemantics semantics; |
62 | try { | 64 | try { |
63 | semanticsBuilder.problem(problem); | 65 | semantics = semanticsFactory.cancellationToken(cancellationToken).createSemantics(problem); |
64 | cancellationToken.checkCancelled(); | ||
65 | semantics = semanticsBuilder.build(); | ||
66 | } catch (TranslationException e) { | 66 | } catch (TranslationException e) { |
67 | return new SemanticsInternalErrorResult(e.getMessage()); | 67 | return new SemanticsInternalErrorResult(e.getMessage()); |
68 | } catch (TracedException e) { | 68 | } catch (TracedException e) { |
@@ -72,12 +72,12 @@ class SemanticsWorker implements Callable<SemanticsResult> { | |||
72 | return getTracedErrorResult(e.getSourceElement(), message); | 72 | return getTracedErrorResult(e.getSourceElement(), message); |
73 | } | 73 | } |
74 | cancellationToken.checkCancelled(); | 74 | cancellationToken.checkCancelled(); |
75 | var nodesMetadata = semantics.getNodesMetadata(); | 75 | metadataCreator.setProblemTrace(semantics.getProblemTrace()); |
76 | var nodesMetadata = metadataCreator.getNodesMetadata(semantics.getModel(), true); | ||
76 | cancellationToken.checkCancelled(); | 77 | cancellationToken.checkCancelled(); |
77 | var relationsMetadata = semantics.getProblemTrace().getRelationsMetadata(); | 78 | var relationsMetadata = metadataCreator.getRelationsMetadata(); |
78 | cancellationToken.checkCancelled(); | 79 | cancellationToken.checkCancelled(); |
79 | var partialInterpretation = partialInterpretation2Json.getPartialInterpretation(semantics, | 80 | var partialInterpretation = partialInterpretation2Json.getPartialInterpretation(semantics, cancellationToken); |
80 | Concreteness.PARTIAL, cancellationToken); | ||
81 | return new SemanticsSuccessResult(nodesMetadata, relationsMetadata, partialInterpretation); | 81 | return new SemanticsSuccessResult(nodesMetadata, relationsMetadata, partialInterpretation); |
82 | } | 82 | } |
83 | 83 | ||
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/BuiltInDetail.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/BuiltInDetail.java index 6f706069..27eb7ad7 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/BuiltInDetail.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/BuiltInDetail.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.metadata; | 6 | package tools.refinery.language.web.semantics.metadata; |
7 | 7 | ||
8 | public record BuiltInDetail() implements RelationDetail { | 8 | public record BuiltInDetail() implements RelationDetail { |
9 | public static final BuiltInDetail INSTANCE = new BuiltInDetail(); | 9 | public static final BuiltInDetail INSTANCE = new BuiltInDetail(); |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ClassDetail.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/ClassDetail.java index 1d3190f5..42495950 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ClassDetail.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/ClassDetail.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.metadata; | 6 | package tools.refinery.language.web.semantics.metadata; |
7 | 7 | ||
8 | public record ClassDetail(boolean abstractClass) implements RelationDetail { | 8 | public record ClassDetail(boolean abstractClass) implements RelationDetail { |
9 | public static final ClassDetail CONCRETE_CLASS = new ClassDetail(false); | 9 | public static final ClassDetail CONCRETE_CLASS = new ClassDetail(false); |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/Metadata.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/Metadata.java index d2dcb43a..5e1fac05 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/Metadata.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/Metadata.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.metadata; | 6 | package tools.refinery.language.web.semantics.metadata; |
7 | 7 | ||
8 | public sealed interface Metadata permits NodeMetadata, RelationMetadata { | 8 | public sealed interface Metadata permits NodeMetadata, RelationMetadata { |
9 | String name(); | 9 | String name(); |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/MetadataCreator.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/MetadataCreator.java index 3694f5f4..3fbc5d2d 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/MetadataCreator.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/MetadataCreator.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.metadata; | 6 | package tools.refinery.language.web.semantics.metadata; |
7 | 7 | ||
8 | import com.google.inject.Inject; | 8 | import com.google.inject.Inject; |
9 | import org.eclipse.emf.ecore.EObject; | 9 | import org.eclipse.emf.ecore.EObject; |
@@ -13,12 +13,17 @@ import org.eclipse.xtext.naming.QualifiedName; | |||
13 | import org.eclipse.xtext.scoping.IScope; | 13 | import org.eclipse.xtext.scoping.IScope; |
14 | import org.eclipse.xtext.scoping.IScopeProvider; | 14 | import org.eclipse.xtext.scoping.IScopeProvider; |
15 | import tools.refinery.language.model.problem.*; | 15 | import tools.refinery.language.model.problem.*; |
16 | import tools.refinery.language.semantics.model.ModelInitializer; | 16 | import tools.refinery.language.semantics.ProblemTrace; |
17 | import tools.refinery.language.semantics.model.TracedException; | 17 | import tools.refinery.language.semantics.TracedException; |
18 | import tools.refinery.language.utils.ProblemUtil; | 18 | import tools.refinery.language.utils.ProblemUtil; |
19 | import tools.refinery.store.model.Model; | ||
20 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
19 | import tools.refinery.store.reasoning.representation.PartialRelation; | 21 | import tools.refinery.store.reasoning.representation.PartialRelation; |
20 | 22 | ||
21 | import java.util.*; | 23 | import java.util.ArrayList; |
24 | import java.util.Collections; | ||
25 | import java.util.Comparator; | ||
26 | import java.util.List; | ||
22 | 27 | ||
23 | public class MetadataCreator { | 28 | public class MetadataCreator { |
24 | @Inject | 29 | @Inject |
@@ -30,18 +35,18 @@ public class MetadataCreator { | |||
30 | @Inject | 35 | @Inject |
31 | private IQualifiedNameConverter qualifiedNameConverter; | 36 | private IQualifiedNameConverter qualifiedNameConverter; |
32 | 37 | ||
33 | private ModelInitializer initializer; | 38 | private ProblemTrace problemTrace; |
34 | 39 | ||
35 | private IScope nodeScope; | 40 | private IScope nodeScope; |
36 | 41 | ||
37 | private IScope relationScope; | 42 | private IScope relationScope; |
38 | 43 | ||
39 | public void setInitializer(ModelInitializer initializer) { | 44 | public void setProblemTrace(ProblemTrace problemTrace) { |
40 | if (initializer == null) { | 45 | if (this.problemTrace != null) { |
41 | throw new IllegalArgumentException("Initializer was already set"); | 46 | throw new IllegalArgumentException("Problem trace was already set"); |
42 | } | 47 | } |
43 | this.initializer = initializer; | 48 | this.problemTrace = problemTrace; |
44 | var problem = initializer.getProblem(); | 49 | var problem = problemTrace.getProblem(); |
45 | nodeScope = scopeProvider.getScope(problem, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE); | 50 | nodeScope = scopeProvider.getScope(problem, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE); |
46 | relationScope = scopeProvider.getScope(problem, ProblemPackage.Literals.ASSERTION__RELATION); | 51 | relationScope = scopeProvider.getScope(problem, ProblemPackage.Literals.ASSERTION__RELATION); |
47 | } | 52 | } |
@@ -50,13 +55,11 @@ public class MetadataCreator { | |||
50 | return "::" + nodeId; | 55 | return "::" + nodeId; |
51 | } | 56 | } |
52 | 57 | ||
53 | public List<NodeMetadata> getNodesMetadata() { | 58 | public List<NodeMetadata> getNodesMetadata(Model model, boolean preserveNewNodes) { |
54 | return getNodesMetadata(initializer.getNodeCount(), true); | 59 | int nodeCount = model.getAdapter(ReasoningAdapter.class).getNodeCount(); |
55 | } | 60 | var nodeTrace = problemTrace.getNodeTrace(); |
56 | 61 | var nodes = new NodeMetadata[Math.max(nodeTrace.size(), nodeCount)]; | |
57 | public List<NodeMetadata> getNodesMetadata(int nodeCount, boolean preserveNewNodes) { | 62 | for (var entry : nodeTrace.keyValuesView()) { |
58 | var nodes = new NodeMetadata[Math.max(initializer.getNodeCount(), nodeCount)]; | ||
59 | for (var entry : initializer.getNodeTrace().keyValuesView()) { | ||
60 | var node = entry.getOne(); | 63 | var node = entry.getOne(); |
61 | var id = entry.getTwo(); | 64 | var id = entry.getTwo(); |
62 | nodes[id] = getNodeMetadata(id, node, preserveNewNodes); | 65 | nodes[id] = getNodeMetadata(id, node, preserveNewNodes); |
@@ -95,7 +98,7 @@ public class MetadataCreator { | |||
95 | } | 98 | } |
96 | 99 | ||
97 | public List<RelationMetadata> getRelationsMetadata() { | 100 | public List<RelationMetadata> getRelationsMetadata() { |
98 | var relationTrace = initializer.getRelationTrace(); | 101 | var relationTrace = problemTrace.getRelationTrace(); |
99 | var relations = new ArrayList<RelationMetadata>(relationTrace.size()); | 102 | var relations = new ArrayList<RelationMetadata>(relationTrace.size()); |
100 | for (var entry : relationTrace.entrySet()) { | 103 | for (var entry : relationTrace.entrySet()) { |
101 | var relation = entry.getKey(); | 104 | var relation = entry.getKey(); |
@@ -142,7 +145,7 @@ public class MetadataCreator { | |||
142 | } | 145 | } |
143 | 146 | ||
144 | private RelationDetail getReferenceDetail(PartialRelation partialRelation) { | 147 | private RelationDetail getReferenceDetail(PartialRelation partialRelation) { |
145 | var metamodel = initializer.getMetamodel(); | 148 | var metamodel = problemTrace.getMetamodel(); |
146 | var opposite = metamodel.oppositeReferences().get(partialRelation); | 149 | var opposite = metamodel.oppositeReferences().get(partialRelation); |
147 | if (opposite == null) { | 150 | if (opposite == null) { |
148 | boolean isContainment = metamodel.containmentHierarchy().containsKey(partialRelation); | 151 | boolean isContainment = metamodel.containmentHierarchy().containsKey(partialRelation); |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeKind.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeKind.java index 01f0cd09..fa863bc2 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeKind.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeKind.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.metadata; | 6 | package tools.refinery.language.web.semantics.metadata; |
7 | 7 | ||
8 | public enum NodeKind { | 8 | public enum NodeKind { |
9 | IMPLICIT, | 9 | IMPLICIT, |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeMetadata.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadata.java index 812952c0..5da28acf 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeMetadata.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/NodeMetadata.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.metadata; | 6 | package tools.refinery.language.web.semantics.metadata; |
7 | 7 | ||
8 | public record NodeMetadata(String name, String simpleName, NodeKind kind) implements Metadata { | 8 | public record NodeMetadata(String name, String simpleName, NodeKind kind) implements Metadata { |
9 | } | 9 | } |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/OppositeReferenceDetail.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/OppositeReferenceDetail.java index 26d7461c..98e7fec8 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/OppositeReferenceDetail.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/OppositeReferenceDetail.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.metadata; | 6 | package tools.refinery.language.web.semantics.metadata; |
7 | 7 | ||
8 | public record OppositeReferenceDetail(boolean container, String opposite) implements RelationDetail { | 8 | public record OppositeReferenceDetail(boolean container, String opposite) implements RelationDetail { |
9 | } | 9 | } |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/PredicateDetail.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/PredicateDetail.java index ca397eca..d4ac4b65 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/PredicateDetail.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/PredicateDetail.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.metadata; | 6 | package tools.refinery.language.web.semantics.metadata; |
7 | 7 | ||
8 | public record PredicateDetail(boolean error) implements RelationDetail { | 8 | public record PredicateDetail(boolean error) implements RelationDetail { |
9 | public static final PredicateDetail PREDICATE = new PredicateDetail(false); | 9 | public static final PredicateDetail PREDICATE = new PredicateDetail(false); |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ReferenceDetail.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/ReferenceDetail.java index 36771566..42799417 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ReferenceDetail.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/ReferenceDetail.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.metadata; | 6 | package tools.refinery.language.web.semantics.metadata; |
7 | 7 | ||
8 | public record ReferenceDetail(boolean containment) implements RelationDetail { | 8 | public record ReferenceDetail(boolean containment) implements RelationDetail { |
9 | public static final ReferenceDetail CROSS_REFERENCE = new ReferenceDetail(false); | 9 | public static final ReferenceDetail CROSS_REFERENCE = new ReferenceDetail(false); |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationDetail.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/RelationDetail.java index 105179fd..bbe563cd 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationDetail.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/RelationDetail.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.metadata; | 6 | package tools.refinery.language.web.semantics.metadata; |
7 | 7 | ||
8 | public sealed interface RelationDetail permits ClassDetail, ReferenceDetail, PredicateDetail, OppositeReferenceDetail, | 8 | public sealed interface RelationDetail permits ClassDetail, ReferenceDetail, PredicateDetail, OppositeReferenceDetail, |
9 | BuiltInDetail { | 9 | BuiltInDetail { |
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationMetadata.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/RelationMetadata.java index 5abcc253..e5d3a091 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationMetadata.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/semantics/metadata/RelationMetadata.java | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
6 | package tools.refinery.language.semantics.metadata; | 6 | package tools.refinery.language.web.semantics.metadata; |
7 | 7 | ||
8 | public record RelationMetadata(String name, String simpleName, int arity, RelationDetail detail) implements Metadata { | 8 | public record RelationMetadata(String name, String simpleName, int arity, RelationDetail detail) implements Metadata { |
9 | } | 9 | } |
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java index 1fde1be5..818bd80e 100644 --- a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java +++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java | |||
@@ -17,7 +17,7 @@ import org.eclipse.xtext.resource.IResourceServiceProvider; | |||
17 | import org.eclipse.xtext.web.server.ISession; | 17 | import org.eclipse.xtext.web.server.ISession; |
18 | import org.slf4j.Logger; | 18 | import org.slf4j.Logger; |
19 | import org.slf4j.LoggerFactory; | 19 | import org.slf4j.LoggerFactory; |
20 | import tools.refinery.language.semantics.metadata.*; | 20 | import tools.refinery.language.web.semantics.metadata.*; |
21 | import tools.refinery.language.web.xtext.server.ResponseHandler; | 21 | import tools.refinery.language.web.xtext.server.ResponseHandler; |
22 | import tools.refinery.language.web.xtext.server.ResponseHandlerException; | 22 | import tools.refinery.language.web.xtext.server.ResponseHandlerException; |
23 | import tools.refinery.language.web.xtext.server.TransactionExecutor; | 23 | import tools.refinery.language.web.xtext.server.TransactionExecutor; |