diff options
author | Kristóf Marussy <kristof@marussy.com> | 2023-11-03 02:03:56 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2023-11-03 02:03:56 +0100 |
commit | eddf21f4b583fecb982c2c2f4ee733ee156371d7 (patch) | |
tree | b22730c84e63e6c32fc498edae6d565b7cadced9 /subprojects/generator | |
parent | refactor(interpreter): aggreagator batching (diff) | |
download | refinery-eddf21f4b583fecb982c2c2f4ee733ee156371d7.tar.gz refinery-eddf21f4b583fecb982c2c2f4ee733ee156371d7.tar.zst refinery-eddf21f4b583fecb982c2c2f4ee733ee156371d7.zip |
feat: model generator facade
Diffstat (limited to 'subprojects/generator')
8 files changed, 498 insertions, 0 deletions
diff --git a/subprojects/generator/build.gradle.kts b/subprojects/generator/build.gradle.kts new file mode 100644 index 00000000..f1a4ed54 --- /dev/null +++ b/subprojects/generator/build.gradle.kts | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | |||
7 | plugins { | ||
8 | id("tools.refinery.gradle.java-library") | ||
9 | } | ||
10 | |||
11 | dependencies { | ||
12 | api(project(":refinery-language-semantics")) | ||
13 | implementation(project(":refinery-store-query-interpreter")) | ||
14 | implementation(project(":refinery-store-reasoning-scope")) | ||
15 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java new file mode 100644 index 00000000..4c3e52f3 --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGenerator.java | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import org.eclipse.xtext.naming.QualifiedName; | ||
9 | import tools.refinery.language.model.problem.Relation; | ||
10 | import tools.refinery.store.dse.strategy.BestFirstStoreManager; | ||
11 | import tools.refinery.store.dse.transition.VersionWithObjectiveValue; | ||
12 | import tools.refinery.store.map.Version; | ||
13 | import tools.refinery.store.model.Model; | ||
14 | import tools.refinery.store.model.ModelStore; | ||
15 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
16 | import tools.refinery.store.reasoning.ReasoningStoreAdapter; | ||
17 | import tools.refinery.store.reasoning.interpretation.PartialInterpretation; | ||
18 | import tools.refinery.store.reasoning.literal.Concreteness; | ||
19 | import tools.refinery.store.reasoning.representation.PartialSymbol; | ||
20 | import tools.refinery.store.reasoning.seed.ModelSeed; | ||
21 | import tools.refinery.store.representation.TruthValue; | ||
22 | |||
23 | import java.util.Collection; | ||
24 | |||
25 | public class ModelGenerator { | ||
26 | private final ProblemTrace problemTrace; | ||
27 | private final ModelStore store; | ||
28 | private final Model model; | ||
29 | private final ReasoningAdapter reasoningAdapter; | ||
30 | private final Version initialVersion; | ||
31 | |||
32 | private int randomSeed = 1; | ||
33 | |||
34 | public ModelGenerator(ProblemTrace problemTrace, ModelStore store, ModelSeed modelSeed) { | ||
35 | this.problemTrace = problemTrace; | ||
36 | this.store = store; | ||
37 | model = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(modelSeed); | ||
38 | reasoningAdapter = model.getAdapter(ReasoningAdapter.class); | ||
39 | initialVersion = model.commit(); | ||
40 | } | ||
41 | |||
42 | public ProblemTrace getProblemTrace() { | ||
43 | return problemTrace; | ||
44 | } | ||
45 | |||
46 | public ModelStore getModelStore() { | ||
47 | return store; | ||
48 | } | ||
49 | |||
50 | public Model getModel() { | ||
51 | return model; | ||
52 | } | ||
53 | |||
54 | public int getRandomSeed() { | ||
55 | return randomSeed; | ||
56 | } | ||
57 | |||
58 | public void setRandomSeed(int randomSeed) { | ||
59 | this.randomSeed = randomSeed; | ||
60 | } | ||
61 | |||
62 | public Collection<Version> run(int maxNumberOfSolutions) { | ||
63 | var bestFirst = new BestFirstStoreManager(store, maxNumberOfSolutions); | ||
64 | int currentRandomSeed = randomSeed; | ||
65 | // Increment random seed even if generation is unsuccessful. | ||
66 | randomSeed++; | ||
67 | bestFirst.startExploration(initialVersion, currentRandomSeed); | ||
68 | return bestFirst.getSolutionStore() | ||
69 | .getSolutions() | ||
70 | .stream() | ||
71 | .map(VersionWithObjectiveValue::version) | ||
72 | .toList(); | ||
73 | } | ||
74 | |||
75 | public boolean tryRun() { | ||
76 | var iterator = run(1).iterator(); | ||
77 | if (!iterator.hasNext()) { | ||
78 | return false; | ||
79 | } | ||
80 | model.restore(iterator.next()); | ||
81 | return true; | ||
82 | } | ||
83 | |||
84 | public <A, C> PartialInterpretation<A, C> getCandidateInterpretation(PartialSymbol<A, C> partialSymbol) { | ||
85 | return reasoningAdapter.getPartialInterpretation(Concreteness.CANDIDATE, partialSymbol); | ||
86 | } | ||
87 | |||
88 | public PartialInterpretation<TruthValue, Boolean> getCandidateInterpretation(Relation relation) { | ||
89 | return getCandidateInterpretation(problemTrace.getPartialRelation(relation)); | ||
90 | } | ||
91 | |||
92 | public PartialInterpretation<TruthValue, Boolean> getCandidateInterpretation(QualifiedName qualifiedName) { | ||
93 | return getCandidateInterpretation(problemTrace.getPartialRelation(qualifiedName)); | ||
94 | } | ||
95 | |||
96 | public PartialInterpretation<TruthValue, Boolean> getCandidateInterpretation(String qualifiedName) { | ||
97 | return getCandidateInterpretation(problemTrace.getPartialRelation(qualifiedName)); | ||
98 | } | ||
99 | |||
100 | public static ModelGeneratorBuilder standaloneBuilder() { | ||
101 | var injector = StandaloneInjectorHolder.getInjector(); | ||
102 | return injector.getInstance(ModelGeneratorBuilder.class); | ||
103 | } | ||
104 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorBuilder.java b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorBuilder.java new file mode 100644 index 00000000..98b6653d --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ModelGeneratorBuilder.java | |||
@@ -0,0 +1,167 @@ | |||
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.dse.propagation.PropagationAdapter; | ||
22 | import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter; | ||
23 | import tools.refinery.store.model.ModelStore; | ||
24 | import tools.refinery.store.query.ModelQueryBuilder; | ||
25 | import tools.refinery.store.query.interpreter.QueryInterpreterAdapter; | ||
26 | import tools.refinery.store.reasoning.ReasoningAdapter; | ||
27 | import tools.refinery.store.reasoning.literal.Concreteness; | ||
28 | import tools.refinery.store.statecoding.StateCoderAdapter; | ||
29 | import tools.refinery.store.util.CancellationToken; | ||
30 | |||
31 | import java.io.File; | ||
32 | import java.io.IOException; | ||
33 | import java.io.InputStream; | ||
34 | import java.util.Collection; | ||
35 | import java.util.Map; | ||
36 | import java.util.Set; | ||
37 | |||
38 | public abstract class ModelGeneratorBuilder { | ||
39 | @Inject | ||
40 | private Provider<XtextResourceSet> resourceSetProvider; | ||
41 | |||
42 | @Inject | ||
43 | private IResourceFactory resourceFactory; | ||
44 | |||
45 | @Inject | ||
46 | private IResourceValidator resourceValidator; | ||
47 | |||
48 | @Inject | ||
49 | private ModelInitializer initializer; | ||
50 | |||
51 | @Inject | ||
52 | private ProblemTraceImpl problemTrace; | ||
53 | |||
54 | private CancellationToken cancellationToken = CancellationToken.NONE; | ||
55 | private boolean problemLoaded; | ||
56 | private ModelQueryBuilder queryEngineBuilder; | ||
57 | private Collection<Concreteness> requiredInterpretations = Set.of(Concreteness.CANDIDATE); | ||
58 | |||
59 | public ModelGeneratorBuilder cancellationToken(CancellationToken cancellationToken) { | ||
60 | this.cancellationToken = cancellationToken; | ||
61 | return this; | ||
62 | } | ||
63 | |||
64 | public ModelGeneratorBuilder fromString(String problemString) throws IOException { | ||
65 | try (var stream = new LazyStringInputStream(problemString)) { | ||
66 | return fromStream(stream); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | public ModelGeneratorBuilder fromStream(InputStream inputStream) throws IOException { | ||
71 | var resourceSet = resourceSetProvider.get(); | ||
72 | var resource = resourceFactory.createResource(URI.createFileURI("__synthetic.problem")); | ||
73 | resourceSet.getResources().add(resource); | ||
74 | resource.load(inputStream, Map.of()); | ||
75 | return fromResource(resource); | ||
76 | } | ||
77 | |||
78 | public ModelGeneratorBuilder fromFile(File file) throws IOException { | ||
79 | return fromFile(file.getAbsolutePath()); | ||
80 | } | ||
81 | |||
82 | public ModelGeneratorBuilder fromFile(String filePath) throws IOException { | ||
83 | return fromUri(URI.createFileURI(filePath)); | ||
84 | } | ||
85 | |||
86 | public ModelGeneratorBuilder fromUri(URI uri) throws IOException { | ||
87 | var resourceSet = resourceSetProvider.get(); | ||
88 | var resource = resourceFactory.createResource(uri); | ||
89 | resourceSet.getResources().add(resource); | ||
90 | resource.load(Map.of()); | ||
91 | return fromResource(resource); | ||
92 | } | ||
93 | |||
94 | public ModelGeneratorBuilder fromResource(Resource resource) { | ||
95 | var issues = resourceValidator.validate(resource, CheckMode.ALL, () -> { | ||
96 | cancellationToken.checkCancelled(); | ||
97 | return Thread.interrupted(); | ||
98 | }); | ||
99 | cancellationToken.checkCancelled(); | ||
100 | var errors = issues.stream() | ||
101 | .filter(issue -> issue.getSeverity() == Severity.ERROR) | ||
102 | .toList(); | ||
103 | if (!errors.isEmpty()) { | ||
104 | throw new ValidationErrorsException(resource.getURI(), errors); | ||
105 | } | ||
106 | if (resource.getContents().isEmpty() || !(resource.getContents().get(0) instanceof Problem problem)) { | ||
107 | throw new IllegalArgumentException("Model generation problem not found in resource " + resource.getURI()); | ||
108 | } | ||
109 | return problem(problem); | ||
110 | } | ||
111 | |||
112 | public ModelGeneratorBuilder problem(Problem problem) { | ||
113 | if (problemLoaded) { | ||
114 | throw new IllegalStateException("Problem was already set"); | ||
115 | } | ||
116 | initializer.readProblem(problem); | ||
117 | problemTrace.setInitializer(initializer); | ||
118 | problemLoaded = true; | ||
119 | return this; | ||
120 | } | ||
121 | |||
122 | public ProblemTrace getProblemTrace() { | ||
123 | checkProblem(); | ||
124 | return problemTrace; | ||
125 | } | ||
126 | |||
127 | public ModelGeneratorBuilder queryEngine(ModelQueryBuilder queryEngineBuilder) { | ||
128 | if (this.queryEngineBuilder != null) { | ||
129 | throw new IllegalStateException("Query engine was already set"); | ||
130 | } | ||
131 | this.queryEngineBuilder = queryEngineBuilder; | ||
132 | return this; | ||
133 | } | ||
134 | |||
135 | public ModelGeneratorBuilder requiredInterpretations(Collection<Concreteness> requiredInterpretations) { | ||
136 | this.requiredInterpretations = requiredInterpretations; | ||
137 | return this; | ||
138 | } | ||
139 | |||
140 | public ModelGenerator build() { | ||
141 | checkProblem(); | ||
142 | var storeBuilder = ModelStore.builder() | ||
143 | .cancellationToken(cancellationToken) | ||
144 | .with(getQueryEngineBuilder()) | ||
145 | .with(PropagationAdapter.builder()) | ||
146 | .with(StateCoderAdapter.builder()) | ||
147 | .with(DesignSpaceExplorationAdapter.builder()) | ||
148 | .with(ReasoningAdapter.builder() | ||
149 | .requiredInterpretations(requiredInterpretations)); | ||
150 | initializer.configureStoreBuilder(storeBuilder); | ||
151 | var store = storeBuilder.build(); | ||
152 | return new ModelGenerator(problemTrace, store, initializer.getModelSeed()); | ||
153 | } | ||
154 | |||
155 | private void checkProblem() { | ||
156 | if (!problemLoaded) { | ||
157 | throw new IllegalStateException("Problem was not loaded"); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | private ModelQueryBuilder getQueryEngineBuilder() { | ||
162 | if (queryEngineBuilder == null) { | ||
163 | return QueryInterpreterAdapter.builder(); | ||
164 | } | ||
165 | return queryEngineBuilder; | ||
166 | } | ||
167 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ProblemTrace.java b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemTrace.java new file mode 100644 index 00000000..7be2dc00 --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ProblemTrace.java | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import org.eclipse.xtext.naming.QualifiedName; | ||
9 | import tools.refinery.language.model.problem.Problem; | ||
10 | import tools.refinery.language.model.problem.Relation; | ||
11 | import tools.refinery.store.reasoning.representation.PartialRelation; | ||
12 | |||
13 | import java.util.Map; | ||
14 | |||
15 | public interface ProblemTrace { | ||
16 | Problem getProblem(); | ||
17 | |||
18 | Map<Relation, PartialRelation> getRelationTrace(); | ||
19 | |||
20 | PartialRelation getPartialRelation(Relation relation); | ||
21 | |||
22 | PartialRelation getPartialRelation(QualifiedName qualifiedName); | ||
23 | |||
24 | PartialRelation getPartialRelation(String qualifiedName); | ||
25 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/StandaloneInjectorHolder.java b/subprojects/generator/src/main/java/tools/refinery/generator/StandaloneInjectorHolder.java new file mode 100644 index 00000000..7db96163 --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/StandaloneInjectorHolder.java | |||
@@ -0,0 +1,27 @@ | |||
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/UnsatisfiableProblemException.java b/subprojects/generator/src/main/java/tools/refinery/generator/UnsatisfiableProblemException.java new file mode 100644 index 00000000..4fb18b90 --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/UnsatisfiableProblemException.java | |||
@@ -0,0 +1,12 @@ | |||
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 | public class UnsatisfiableProblemException extends RuntimeException { | ||
9 | public UnsatisfiableProblemException() { | ||
10 | super("Model generation problem was unsatisfiable"); | ||
11 | } | ||
12 | } | ||
diff --git a/subprojects/generator/src/main/java/tools/refinery/generator/ValidationErrorsException.java b/subprojects/generator/src/main/java/tools/refinery/generator/ValidationErrorsException.java new file mode 100644 index 00000000..d668e51d --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/ValidationErrorsException.java | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.generator; | ||
7 | |||
8 | import org.eclipse.emf.common.util.URI; | ||
9 | import org.eclipse.xtext.validation.Issue; | ||
10 | |||
11 | import java.util.List; | ||
12 | |||
13 | public class ValidationErrorsException extends IllegalArgumentException { | ||
14 | private final transient URI resourceUri; | ||
15 | |||
16 | private final String resourceUriString; | ||
17 | |||
18 | private final transient List<Issue> errors; | ||
19 | |||
20 | private final List<String> errorStrings; | ||
21 | |||
22 | public ValidationErrorsException(URI resourceUri, List<Issue> errors) { | ||
23 | this.resourceUri = resourceUri; | ||
24 | resourceUriString = resourceUri.toString(); | ||
25 | this.errors = errors; | ||
26 | errorStrings = errors.stream() | ||
27 | .map(Issue::toString) | ||
28 | .toList(); | ||
29 | } | ||
30 | |||
31 | public URI getResourceUri() { | ||
32 | return resourceUri; | ||
33 | } | ||
34 | |||
35 | public String getResourceUriString() { | ||
36 | return resourceUriString; | ||
37 | } | ||
38 | |||
39 | public List<Issue> getErrors() { | ||
40 | return errors; | ||
41 | } | ||
42 | |||
43 | public List<String> getErrorStrings() { | ||
44 | return errorStrings; | ||
45 | } | ||
46 | |||
47 | @Override | ||
48 | public String getMessage() { | ||
49 | var builder = new StringBuilder(); | ||
50 | builder.append("Validation errors in resource "); | ||
51 | builder.append(resourceUriString); | ||
52 | builder.append(": "); | ||
53 | var iterator = errorStrings.iterator(); | ||
54 | if (!iterator.hasNext()) { | ||
55 | return builder.toString(); | ||
56 | } | ||
57 | builder.append(iterator.next()); | ||
58 | while (iterator.hasNext()) { | ||
59 | builder.append(",\n"); | ||
60 | builder.append(iterator.next()); | ||
61 | } | ||
62 | return builder.toString(); | ||
63 | } | ||
64 | } | ||
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 new file mode 100644 index 00000000..109e34af --- /dev/null +++ b/subprojects/generator/src/main/java/tools/refinery/generator/impl/ProblemTraceImpl.java | |||
@@ -0,0 +1,84 @@ | |||
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 org.eclipse.emf.ecore.util.EcoreUtil; | ||
10 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | ||
11 | import org.eclipse.xtext.naming.IQualifiedNameProvider; | ||
12 | import org.eclipse.xtext.naming.QualifiedName; | ||
13 | import org.eclipse.xtext.scoping.IScopeProvider; | ||
14 | import tools.refinery.generator.ProblemTrace; | ||
15 | import tools.refinery.language.model.problem.Problem; | ||
16 | import tools.refinery.language.model.problem.ProblemPackage; | ||
17 | import tools.refinery.language.model.problem.Relation; | ||
18 | import tools.refinery.language.semantics.model.ModelInitializer; | ||
19 | import tools.refinery.store.reasoning.representation.PartialRelation; | ||
20 | |||
21 | import java.util.Collections; | ||
22 | import java.util.Map; | ||
23 | |||
24 | public final class ProblemTraceImpl implements ProblemTrace { | ||
25 | @Inject | ||
26 | private IQualifiedNameConverter qualifiedNameConverter; | ||
27 | |||
28 | @Inject | ||
29 | private IQualifiedNameProvider qualifiedNameProvider; | ||
30 | |||
31 | @Inject | ||
32 | private IScopeProvider scopeProvider; | ||
33 | |||
34 | private Problem problem; | ||
35 | private Map<Relation, PartialRelation> relationTrace; | ||
36 | |||
37 | public void setInitializer(ModelInitializer initializer) { | ||
38 | problem = initializer.getProblem(); | ||
39 | relationTrace = Collections.unmodifiableMap(initializer.getRelationTrace()); | ||
40 | } | ||
41 | |||
42 | public Problem getProblem() { | ||
43 | return problem; | ||
44 | } | ||
45 | |||
46 | public Map<Relation, PartialRelation> getRelationTrace() { | ||
47 | return relationTrace; | ||
48 | } | ||
49 | |||
50 | public PartialRelation getPartialRelation(Relation relation) { | ||
51 | var partialRelation = relationTrace.get(relation); | ||
52 | if (partialRelation == null) { | ||
53 | var qualifiedName = qualifiedNameProvider.getFullyQualifiedName(relation); | ||
54 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
55 | throw new IllegalArgumentException("No partial relation for relation " + qualifiedNameString); | ||
56 | } | ||
57 | return partialRelation; | ||
58 | } | ||
59 | |||
60 | public PartialRelation getPartialRelation(QualifiedName qualifiedName) { | ||
61 | var scope = scopeProvider.getScope(problem, ProblemPackage.Literals.ASSERTION__RELATION); | ||
62 | var iterator = scope.getElements(qualifiedName).iterator(); | ||
63 | if (!iterator.hasNext()) { | ||
64 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
65 | throw new IllegalArgumentException("No such relation: " + qualifiedNameString); | ||
66 | } | ||
67 | var eObjectDescription = iterator.next(); | ||
68 | if (iterator.hasNext()) { | ||
69 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
70 | throw new IllegalArgumentException("Ambiguous relation: " + qualifiedNameString); | ||
71 | } | ||
72 | var eObject = EcoreUtil.resolve(eObjectDescription.getEObjectOrProxy(), problem); | ||
73 | if (!(eObject instanceof Relation relation)) { | ||
74 | var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName); | ||
75 | throw new IllegalArgumentException("Not a relation: " + qualifiedNameString); | ||
76 | } | ||
77 | return getPartialRelation(relation); | ||
78 | } | ||
79 | |||
80 | public PartialRelation getPartialRelation(String qualifiedName) { | ||
81 | var convertedName = qualifiedNameConverter.toQualifiedName(qualifiedName); | ||
82 | return getPartialRelation(convertedName); | ||
83 | } | ||
84 | } | ||