aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language-semantics/src/main/java/tools
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/language-semantics/src/main/java/tools')
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/NodeNameProvider.java62
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java38
2 files changed, 71 insertions, 29 deletions
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/NodeNameProvider.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/NodeNameProvider.java
new file mode 100644
index 00000000..517b8604
--- /dev/null
+++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/NodeNameProvider.java
@@ -0,0 +1,62 @@
1/*
2 * SPDX-FileCopyrightText: 2024 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics;
7
8import com.google.inject.Inject;
9import org.eclipse.collections.api.factory.primitive.ObjectIntMaps;
10import org.eclipse.collections.api.map.primitive.MutableObjectIntMap;
11import org.eclipse.xtext.naming.IQualifiedNameConverter;
12import org.eclipse.xtext.naming.QualifiedName;
13import org.eclipse.xtext.scoping.IScopeProvider;
14import tools.refinery.language.model.problem.Node;
15import tools.refinery.language.model.problem.Problem;
16import tools.refinery.language.model.problem.ProblemPackage;
17
18import java.util.Locale;
19
20public class NodeNameProvider {
21 @Inject
22 private IQualifiedNameConverter qualifiedNameConverter;
23
24 @Inject
25 private SemanticsUtils semanticsUtils;
26
27 @Inject
28 private IScopeProvider scopeProvider;
29
30 private Problem problem;
31 private final MutableObjectIntMap<String> indexMap = ObjectIntMaps.mutable.empty();
32
33 public void setProblem(Problem problem) {
34 if (this.problem != null) {
35 throw new IllegalStateException("Problem was already set");
36 }
37 this.problem = problem;
38 }
39
40 public String getNextName(String typeName) {
41 if (problem == null) {
42 throw new IllegalStateException("Problem was not set");
43 }
44 String namePrefix;
45 if (typeName == null || typeName.isEmpty()) {
46 namePrefix = "node";
47 } else {
48 namePrefix = typeName.substring(0, 1).toLowerCase(Locale.ROOT) + typeName.substring(1);
49 }
50 int index = indexMap.getIfAbsent(namePrefix, 0);
51 String nodeName;
52 QualifiedName qualifiedName;
53 var scope = scopeProvider.getScope(problem, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE);
54 do {
55 index++;
56 nodeName = namePrefix + index;
57 qualifiedName = qualifiedNameConverter.toQualifiedName(nodeName);
58 } while (semanticsUtils.maybeGetElement(problem, scope, qualifiedName, Node.class) != null);
59 indexMap.put(namePrefix, index);
60 return nodeName;
61 }
62}
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java
index 57af599e..09ba34fc 100644
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java
+++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SolutionSerializer.java
@@ -1,5 +1,5 @@
1/* 1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> 2 * SPDX-FileCopyrightText: 2023-2024 The Refinery Authors <https://refinery.tools/>
3 * 3 *
4 * SPDX-License-Identifier: EPL-2.0 4 * SPDX-License-Identifier: EPL-2.0
5 */ 5 */
@@ -8,12 +8,9 @@ package tools.refinery.language.semantics;
8import com.google.inject.Inject; 8import com.google.inject.Inject;
9import com.google.inject.Provider; 9import com.google.inject.Provider;
10import org.eclipse.collections.api.factory.primitive.IntObjectMaps; 10import org.eclipse.collections.api.factory.primitive.IntObjectMaps;
11import org.eclipse.collections.api.factory.primitive.ObjectIntMaps;
12import org.eclipse.collections.api.map.primitive.MutableIntObjectMap; 11import org.eclipse.collections.api.map.primitive.MutableIntObjectMap;
13import org.eclipse.collections.api.map.primitive.MutableObjectIntMap;
14import org.eclipse.emf.common.util.URI; 12import org.eclipse.emf.common.util.URI;
15import org.eclipse.emf.ecore.util.EcoreUtil; 13import org.eclipse.emf.ecore.util.EcoreUtil;
16import org.eclipse.xtext.naming.IQualifiedNameConverter;
17import org.eclipse.xtext.naming.IQualifiedNameProvider; 14import org.eclipse.xtext.naming.IQualifiedNameProvider;
18import org.eclipse.xtext.naming.QualifiedName; 15import org.eclipse.xtext.naming.QualifiedName;
19import org.eclipse.xtext.resource.FileExtensionProvider; 16import org.eclipse.xtext.resource.FileExtensionProvider;
@@ -37,7 +34,6 @@ import tools.refinery.store.tuple.Tuple;
37import java.io.ByteArrayInputStream; 34import java.io.ByteArrayInputStream;
38import java.io.ByteArrayOutputStream; 35import java.io.ByteArrayOutputStream;
39import java.io.IOException; 36import java.io.IOException;
40import java.util.Locale;
41import java.util.Map; 37import java.util.Map;
42import java.util.TreeMap; 38import java.util.TreeMap;
43import java.util.TreeSet; 39import java.util.TreeSet;
@@ -57,9 +53,6 @@ public class SolutionSerializer {
57 private IQualifiedNameProvider qualifiedNameProvider; 53 private IQualifiedNameProvider qualifiedNameProvider;
58 54
59 @Inject 55 @Inject
60 private IQualifiedNameConverter qualifiedNameConverter;
61
62 @Inject
63 private SemanticsUtils semanticsUtils; 56 private SemanticsUtils semanticsUtils;
64 57
65 @Inject 58 @Inject
@@ -68,6 +61,9 @@ public class SolutionSerializer {
68 @Inject 61 @Inject
69 private ProblemDesugarer desugarer; 62 private ProblemDesugarer desugarer;
70 63
64 @Inject
65 private NodeNameProvider nameProvider;
66
71 private ProblemTrace trace; 67 private ProblemTrace trace;
72 private Model model; 68 private Model model;
73 private ReasoningAdapter reasoningAdapter; 69 private ReasoningAdapter reasoningAdapter;
@@ -95,6 +91,7 @@ public class SolutionSerializer {
95 problem = copyProblem(originalProblem, uri); 91 problem = copyProblem(originalProblem, uri);
96 problem.getStatements().removeIf(SolutionSerializer::shouldRemoveStatement); 92 problem.getStatements().removeIf(SolutionSerializer::shouldRemoveStatement);
97 problem.getNodes().removeIf(this::shouldRemoveNode); 93 problem.getNodes().removeIf(this::shouldRemoveNode);
94 nameProvider.setProblem(problem);
98 addExistsAssertions(); 95 addExistsAssertions();
99 addClassAssertions(); 96 addClassAssertions();
100 addReferenceAssertions(); 97 addReferenceAssertions();
@@ -172,11 +169,6 @@ public class SolutionSerializer {
172 return findNode(qualifiedName); 169 return findNode(qualifiedName);
173 } 170 }
174 171
175 private Node findNode(String name) {
176 var qualifiedName = qualifiedNameConverter.toQualifiedName(name);
177 return findNode(qualifiedName);
178 }
179
180 private Node findNode(QualifiedName qualifiedName) { 172 private Node findNode(QualifiedName qualifiedName) {
181 var scope = scopeProvider.getScope(problem, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE); 173 var scope = scopeProvider.getScope(problem, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE);
182 return semanticsUtils.maybeGetElement(problem, scope, qualifiedName, Node.class); 174 return semanticsUtils.maybeGetElement(problem, scope, qualifiedName, Node.class);
@@ -222,19 +214,17 @@ public class SolutionSerializer {
222 private void addClassAssertions() { 214 private void addClassAssertions() {
223 var types = trace.getMetamodel().typeHierarchy().getPreservedTypes().keySet().stream() 215 var types = trace.getMetamodel().typeHierarchy().getPreservedTypes().keySet().stream()
224 .collect(Collectors.toMap(Function.identity(), this::findPartialRelation)); 216 .collect(Collectors.toMap(Function.identity(), this::findPartialRelation));
225 var indexMap = ObjectIntMaps.mutable.empty();
226 var cursor = model.getInterpretation(TypeHierarchyTranslator.TYPE_SYMBOL).getAll(); 217 var cursor = model.getInterpretation(TypeHierarchyTranslator.TYPE_SYMBOL).getAll();
227 while (cursor.move()) { 218 while (cursor.move()) {
228 var key = cursor.getKey(); 219 var key = cursor.getKey();
229 var nodeId = key.get(0); 220 var nodeId = key.get(0);
230 if (isExistingNode(nodeId)) { 221 if (isExistingNode(nodeId)) {
231 createNodeAndAssertType(nodeId, cursor.getValue(), types, indexMap); 222 createNodeAndAssertType(nodeId, cursor.getValue(), types);
232 } 223 }
233 } 224 }
234 } 225 }
235 226
236 private void createNodeAndAssertType(int nodeId, InferredType inferredType, Map<PartialRelation, Relation> types, 227 private void createNodeAndAssertType(int nodeId, InferredType inferredType, Map<PartialRelation, Relation> types) {
237 MutableObjectIntMap<Object> indexMap) {
238 var candidateTypeSymbol = inferredType.candidateType(); 228 var candidateTypeSymbol = inferredType.candidateType();
239 var candidateRelation = types.get(candidateTypeSymbol); 229 var candidateRelation = types.get(candidateTypeSymbol);
240 if (candidateRelation instanceof EnumDeclaration) { 230 if (candidateRelation instanceof EnumDeclaration) {
@@ -243,18 +233,8 @@ public class SolutionSerializer {
243 } 233 }
244 Node node = nodes.get(nodeId); 234 Node node = nodes.get(nodeId);
245 if (node == null) { 235 if (node == null) {
246 String typeName = candidateRelation.getName(); 236 var typeName = candidateRelation.getName();
247 if (typeName == null || typeName.isEmpty()) { 237 var nodeName = nameProvider.getNextName(typeName);
248 typeName = "node";
249 } else {
250 typeName = typeName.substring(0, 1).toLowerCase(Locale.ROOT) + typeName.substring(1);
251 }
252 int index = indexMap.getIfAbsent(typeName, 0);
253 String nodeName;
254 do {
255 index++;
256 nodeName = typeName + index;
257 } while (findNode(nodeName) != null);
258 node = ProblemFactory.eINSTANCE.createNode(); 238 node = ProblemFactory.eINSTANCE.createNode();
259 node.setName(nodeName); 239 node.setName(nodeName);
260 problem.getNodes().add(node); 240 problem.getNodes().add(node);