aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language-semantics/src
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-11-03 19:12:08 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-11-03 19:12:19 +0100
commit32d469d0284d1ab1540423e705a5d3c8e7d99705 (patch)
treedcff140c1af411612c2ca61a34471134d762843a /subprojects/language-semantics/src
parentrefactor(langauge-web): use generator facades (diff)
downloadrefinery-32d469d0284d1ab1540423e705a5d3c8e7d99705.tar.gz
refinery-32d469d0284d1ab1540423e705a5d3c8e7d99705.tar.zst
refinery-32d469d0284d1ab1540423e705a5d3c8e7d99705.zip
refactor: smenatics and facades
Also moves model metadata into language-web, since we only use it on the frontent.
Diffstat (limited to 'subprojects/language-semantics/src')
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java (renamed from subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/ModelInitializer.java)184
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTrace.java46
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTraceImpl.java187
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/SemanticsUtils.java (renamed from subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/SemanticsUtils.java)2
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/TracedException.java (renamed from subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/TracedException.java)2
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTree.java (renamed from subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTree.java)2
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeCursor.java (renamed from subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeCursor.java)2
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeNode.java (renamed from subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeNode.java)2
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/DecisionTreeValue.java (renamed from subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/DecisionTreeValue.java)2
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/IntermediateNode.java (renamed from subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/IntermediateNode.java)2
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/MutableSeed.java (renamed from subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/MutableSeed.java)2
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/NullaryMutableSeed.java (renamed from subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/NullaryMutableSeed.java)2
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/internal/TerminalNode.java (renamed from subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/internal/TerminalNode.java)2
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/BuiltInDetail.java10
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ClassDetail.java16
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/Metadata.java12
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/MetadataCreator.java199
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeKind.java12
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeMetadata.java9
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/OppositeReferenceDetail.java9
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/PredicateDetail.java16
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ReferenceDetail.java16
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationDetail.java10
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationMetadata.java9
-rw-r--r--subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/CountPropagationTest.java (renamed from subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/CountPropagationTest.java)2
-rw-r--r--subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/ModelGenerationTest.java (renamed from subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/ModelGenerationTest.java)2
-rw-r--r--subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/internal/DecisionTreeTests.java (renamed from subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/internal/DecisionTreeTests.java)2
27 files changed, 333 insertions, 428 deletions
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 */
6package tools.refinery.language.semantics.model; 6package tools.refinery.language.semantics;
7 7
8import com.google.inject.Inject; 8import com.google.inject.Inject;
9import org.eclipse.collections.api.factory.primitive.ObjectIntMaps;
10import org.eclipse.collections.api.map.primitive.MutableObjectIntMap;
11import tools.refinery.language.model.problem.*; 9import tools.refinery.language.model.problem.*;
12import tools.refinery.language.semantics.model.internal.MutableSeed; 10import tools.refinery.language.semantics.internal.MutableSeed;
13import tools.refinery.language.utils.BuiltinSymbols; 11import tools.refinery.language.utils.BuiltinSymbols;
14import tools.refinery.language.utils.ProblemDesugarer; 12import tools.refinery.language.utils.ProblemDesugarer;
15import tools.refinery.language.utils.ProblemUtil; 13import tools.refinery.language.utils.ProblemUtil;
@@ -23,11 +21,11 @@ import tools.refinery.store.query.literal.*;
23import tools.refinery.store.query.term.NodeVariable; 21import tools.refinery.store.query.term.NodeVariable;
24import tools.refinery.store.query.term.Variable; 22import tools.refinery.store.query.term.Variable;
25import tools.refinery.store.reasoning.ReasoningAdapter; 23import tools.refinery.store.reasoning.ReasoningAdapter;
26import tools.refinery.store.reasoning.representation.AnyPartialSymbol;
27import tools.refinery.store.reasoning.representation.PartialRelation; 24import tools.refinery.store.reasoning.representation.PartialRelation;
28import tools.refinery.store.reasoning.scope.ScopePropagator; 25import tools.refinery.store.reasoning.scope.ScopePropagator;
29import tools.refinery.store.reasoning.seed.ModelSeed; 26import tools.refinery.store.reasoning.seed.ModelSeed;
30import tools.refinery.store.reasoning.seed.Seed; 27import tools.refinery.store.reasoning.seed.Seed;
28import tools.refinery.store.reasoning.translator.TranslationException;
31import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; 29import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator;
32import tools.refinery.store.reasoning.translator.metamodel.Metamodel; 30import tools.refinery.store.reasoning.translator.metamodel.Metamodel;
33import tools.refinery.store.reasoning.translator.metamodel.MetamodelBuilder; 31import 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/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTrace.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTrace.java
new file mode 100644
index 00000000..b8d0b804
--- /dev/null
+++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ProblemTrace.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 */
6package tools.refinery.language.semantics;
7
8import org.eclipse.collections.api.map.primitive.ObjectIntMap;
9import org.eclipse.xtext.naming.QualifiedName;
10import tools.refinery.language.model.problem.Node;
11import tools.refinery.language.model.problem.Problem;
12import tools.refinery.language.model.problem.Relation;
13import tools.refinery.store.reasoning.representation.AnyPartialSymbol;
14import tools.refinery.store.reasoning.representation.PartialRelation;
15import tools.refinery.store.reasoning.translator.TranslationException;
16import tools.refinery.store.reasoning.translator.metamodel.Metamodel;
17
18import java.util.Map;
19
20public interface ProblemTrace {
21 Problem getProblem();
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
33 Map<Relation, PartialRelation> getRelationTrace();
34
35 Map<AnyPartialSymbol, Relation> getInverseRelationTrace();
36
37 Relation getRelation(AnyPartialSymbol partialSymbol);
38
39 RuntimeException wrapException(TranslationException translationException);
40
41 PartialRelation getPartialRelation(Relation relation);
42
43 PartialRelation getPartialRelation(QualifiedName qualifiedName);
44
45 PartialRelation getPartialRelation(String qualifiedName);
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 */
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.collections.api.map.primitive.ObjectIntMap;
12import org.eclipse.emf.ecore.util.EcoreUtil;
13import org.eclipse.xtext.naming.IQualifiedNameConverter;
14import org.eclipse.xtext.naming.QualifiedName;
15import org.eclipse.xtext.scoping.IScope;
16import org.eclipse.xtext.scoping.IScopeProvider;
17import tools.refinery.language.model.problem.Node;
18import tools.refinery.language.model.problem.Problem;
19import tools.refinery.language.model.problem.ProblemPackage;
20import tools.refinery.language.model.problem.Relation;
21import tools.refinery.store.reasoning.representation.AnyPartialSymbol;
22import tools.refinery.store.reasoning.representation.PartialRelation;
23import tools.refinery.store.reasoning.translator.TranslationException;
24import tools.refinery.store.reasoning.translator.metamodel.Metamodel;
25
26import java.util.Collections;
27import java.util.HashMap;
28import java.util.LinkedHashMap;
29import java.util.Map;
30
31public 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 */
6package tools.refinery.language.semantics.model; 6package tools.refinery.language.semantics;
7 7
8import com.google.inject.Inject; 8import com.google.inject.Inject;
9import com.google.inject.Singleton; 9import 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 */
6package tools.refinery.language.semantics.model; 6package tools.refinery.language.semantics;
7 7
8import org.eclipse.emf.ecore.EObject; 8import 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 */
6package tools.refinery.language.semantics.model.internal; 6package tools.refinery.language.semantics.internal;
7 7
8import org.eclipse.collections.api.factory.primitive.IntObjectMaps; 8import org.eclipse.collections.api.factory.primitive.IntObjectMaps;
9import tools.refinery.store.map.Cursor; 9import 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 */
6package tools.refinery.language.semantics.model.internal; 6package tools.refinery.language.semantics.internal;
7 7
8import tools.refinery.store.map.Cursor; 8import tools.refinery.store.map.Cursor;
9import tools.refinery.store.representation.TruthValue; 9import 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 */
6package tools.refinery.language.semantics.model.internal; 6package tools.refinery.language.semantics.internal;
7 7
8import org.eclipse.collections.api.LazyIntIterable; 8import org.eclipse.collections.api.LazyIntIterable;
9import tools.refinery.store.tuple.Tuple; 9import 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 */
6package tools.refinery.language.semantics.model.internal; 6package tools.refinery.language.semantics.internal;
7 7
8import tools.refinery.store.representation.TruthValue; 8import 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 */
6package tools.refinery.language.semantics.model.internal; 6package tools.refinery.language.semantics.internal;
7 7
8import org.eclipse.collections.api.LazyIntIterable; 8import org.eclipse.collections.api.LazyIntIterable;
9import org.eclipse.collections.api.factory.primitive.IntObjectMaps; 9import 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 */
6package tools.refinery.language.semantics.model.internal; 6package tools.refinery.language.semantics.internal;
7 7
8import tools.refinery.store.reasoning.seed.Seed; 8import tools.refinery.store.reasoning.seed.Seed;
9import tools.refinery.store.representation.TruthValue; 9import 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 */
6package tools.refinery.language.semantics.model.internal; 6package tools.refinery.language.semantics.internal;
7 7
8import tools.refinery.store.map.Cursor; 8import tools.refinery.store.map.Cursor;
9import tools.refinery.store.map.Cursors; 9import 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 */
6package tools.refinery.language.semantics.model.internal; 6package tools.refinery.language.semantics.internal;
7 7
8import org.eclipse.collections.api.LazyIntIterable; 8import org.eclipse.collections.api.LazyIntIterable;
9import org.eclipse.collections.api.factory.primitive.IntObjectMaps; 9import org.eclipse.collections.api.factory.primitive.IntObjectMaps;
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/BuiltInDetail.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/BuiltInDetail.java
deleted file mode 100644
index 6f706069..00000000
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/BuiltInDetail.java
+++ /dev/null
@@ -1,10 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics.metadata;
7
8public record BuiltInDetail() implements RelationDetail {
9 public static final BuiltInDetail INSTANCE = new BuiltInDetail();
10}
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ClassDetail.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ClassDetail.java
deleted file mode 100644
index 1d3190f5..00000000
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ClassDetail.java
+++ /dev/null
@@ -1,16 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics.metadata;
7
8public record ClassDetail(boolean abstractClass) implements RelationDetail {
9 public static final ClassDetail CONCRETE_CLASS = new ClassDetail(false);
10
11 public static final ClassDetail ABSTRACT_CLASS = new ClassDetail(true);
12
13 public static ClassDetail ofAbstractClass(boolean abstractClass) {
14 return abstractClass ? ABSTRACT_CLASS : CONCRETE_CLASS;
15 }
16}
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/Metadata.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/Metadata.java
deleted file mode 100644
index d2dcb43a..00000000
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/Metadata.java
+++ /dev/null
@@ -1,12 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics.metadata;
7
8public sealed interface Metadata permits NodeMetadata, RelationMetadata {
9 String name();
10
11 String simpleName();
12}
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/MetadataCreator.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/MetadataCreator.java
deleted file mode 100644
index 3694f5f4..00000000
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/MetadataCreator.java
+++ /dev/null
@@ -1,199 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics.metadata;
7
8import com.google.inject.Inject;
9import org.eclipse.emf.ecore.EObject;
10import org.eclipse.xtext.naming.IQualifiedNameConverter;
11import org.eclipse.xtext.naming.IQualifiedNameProvider;
12import org.eclipse.xtext.naming.QualifiedName;
13import org.eclipse.xtext.scoping.IScope;
14import org.eclipse.xtext.scoping.IScopeProvider;
15import tools.refinery.language.model.problem.*;
16import tools.refinery.language.semantics.model.ModelInitializer;
17import tools.refinery.language.semantics.model.TracedException;
18import tools.refinery.language.utils.ProblemUtil;
19import tools.refinery.store.reasoning.representation.PartialRelation;
20
21import java.util.*;
22
23public class MetadataCreator {
24 @Inject
25 private IScopeProvider scopeProvider;
26
27 @Inject
28 private IQualifiedNameProvider qualifiedNameProvider;
29
30 @Inject
31 private IQualifiedNameConverter qualifiedNameConverter;
32
33 private ModelInitializer initializer;
34
35 private IScope nodeScope;
36
37 private IScope relationScope;
38
39 public void setInitializer(ModelInitializer initializer) {
40 if (initializer == null) {
41 throw new IllegalArgumentException("Initializer was already set");
42 }
43 this.initializer = initializer;
44 var problem = initializer.getProblem();
45 nodeScope = scopeProvider.getScope(problem, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE);
46 relationScope = scopeProvider.getScope(problem, ProblemPackage.Literals.ASSERTION__RELATION);
47 }
48
49 public static String unnamedNode(int nodeId) {
50 return "::" + nodeId;
51 }
52
53 public List<NodeMetadata> getNodesMetadata() {
54 return getNodesMetadata(initializer.getNodeCount(), true);
55 }
56
57 public List<NodeMetadata> getNodesMetadata(int nodeCount, boolean preserveNewNodes) {
58 var nodes = new NodeMetadata[Math.max(initializer.getNodeCount(), nodeCount)];
59 for (var entry : initializer.getNodeTrace().keyValuesView()) {
60 var node = entry.getOne();
61 var id = entry.getTwo();
62 nodes[id] = getNodeMetadata(id, node, preserveNewNodes);
63 }
64 for (int i = 0; i < nodes.length; i++) {
65 if (nodes[i] == null) {
66 var nodeName = unnamedNode(i);
67 nodes[i] = new NodeMetadata(nodeName, nodeName, NodeKind.IMPLICIT);
68 }
69 }
70 return List.of(nodes);
71 }
72
73 private NodeMetadata getNodeMetadata(int nodeId, Node node, boolean preserveNewNodes) {
74 var kind = getNodeKind(node);
75 if (!preserveNewNodes && kind == NodeKind.NEW) {
76 var nodeName = unnamedNode(nodeId);
77 return new NodeMetadata(nodeName, nodeName, NodeKind.IMPLICIT);
78 }
79 var qualifiedName = getQualifiedName(node);
80 var simpleName = getSimpleName(node, qualifiedName, nodeScope);
81 return new NodeMetadata(qualifiedNameConverter.toString(qualifiedName),
82 qualifiedNameConverter.toString(simpleName), getNodeKind(node));
83 }
84
85 private NodeKind getNodeKind(Node node) {
86 if (ProblemUtil.isImplicitNode(node)) {
87 return NodeKind.IMPLICIT;
88 } else if (ProblemUtil.isIndividualNode(node)) {
89 return NodeKind.INDIVIDUAL;
90 } else if (ProblemUtil.isNewNode(node)) {
91 return NodeKind.NEW;
92 } else {
93 throw new TracedException(node, "Unknown node type");
94 }
95 }
96
97 public List<RelationMetadata> getRelationsMetadata() {
98 var relationTrace = initializer.getRelationTrace();
99 var relations = new ArrayList<RelationMetadata>(relationTrace.size());
100 for (var entry : relationTrace.entrySet()) {
101 var relation = entry.getKey();
102 var partialRelation = entry.getValue();
103 var metadata = getRelationMetadata(relation, partialRelation);
104 relations.add(metadata);
105 }
106 return Collections.unmodifiableList(relations);
107 }
108
109 private RelationMetadata getRelationMetadata(Relation relation, PartialRelation partialRelation) {
110 var qualifiedName = getQualifiedName(relation);
111 var qualifiedNameString = qualifiedNameConverter.toString(qualifiedName);
112 var simpleName = getSimpleName(relation, qualifiedName, relationScope);
113 var simpleNameString = qualifiedNameConverter.toString(simpleName);
114 var arity = partialRelation.arity();
115 var detail = getRelationDetail(relation, partialRelation);
116 return new RelationMetadata(qualifiedNameString, simpleNameString, arity, detail);
117 }
118
119 private RelationDetail getRelationDetail(Relation relation, PartialRelation partialRelation) {
120 if (ProblemUtil.isBuiltIn(relation) && !ProblemUtil.isError(relation)) {
121 return getBuiltInDetail();
122 }
123 if (relation instanceof ClassDeclaration classDeclaration) {
124 return getClassDetail(classDeclaration);
125 } else if (relation instanceof ReferenceDeclaration) {
126 return getReferenceDetail(partialRelation);
127 } else if (relation instanceof EnumDeclaration) {
128 return getEnumDetail();
129 } else if (relation instanceof PredicateDefinition predicateDefinition) {
130 return getPredicateDetail(predicateDefinition);
131 } else {
132 throw new TracedException(relation, "Unknown relation");
133 }
134 }
135
136 private RelationDetail getBuiltInDetail() {
137 return BuiltInDetail.INSTANCE;
138 }
139
140 private RelationDetail getClassDetail(ClassDeclaration classDeclaration) {
141 return ClassDetail.ofAbstractClass(classDeclaration.isAbstract());
142 }
143
144 private RelationDetail getReferenceDetail(PartialRelation partialRelation) {
145 var metamodel = initializer.getMetamodel();
146 var opposite = metamodel.oppositeReferences().get(partialRelation);
147 if (opposite == null) {
148 boolean isContainment = metamodel.containmentHierarchy().containsKey(partialRelation);
149 return ReferenceDetail.ofContainment(isContainment);
150 } else {
151 boolean isContainer = metamodel.containmentHierarchy().containsKey(opposite);
152 return new OppositeReferenceDetail(isContainer, opposite.name());
153 }
154 }
155
156 private RelationDetail getEnumDetail() {
157 return ClassDetail.CONCRETE_CLASS;
158 }
159
160 private RelationDetail getPredicateDetail(PredicateDefinition predicate) {
161 return PredicateDetail.ofError(predicate.isError());
162 }
163
164 private QualifiedName getQualifiedName(EObject eObject) {
165 var qualifiedName = qualifiedNameProvider.getFullyQualifiedName(eObject);
166 if (qualifiedName == null) {
167 throw new TracedException(eObject, "Unknown qualified name");
168 }
169 return qualifiedName;
170 }
171
172 private QualifiedName getSimpleName(EObject eObject, QualifiedName qualifiedName, IScope scope) {
173 var descriptions = scope.getElements(eObject);
174 var names = new ArrayList<QualifiedName>();
175 for (var description : descriptions) {
176 // {@code getQualifiedName()} will refer to the full name for objects that are loaded from the global
177 // scope, but {@code getName()} returns the qualified name that we set in
178 // {@code ProblemResourceDescriptionStrategy}.
179 names.add(description.getName());
180 }
181 names.sort(Comparator.comparingInt(QualifiedName::getSegmentCount));
182 for (var simpleName : names) {
183 if (names.contains(simpleName) && isUnique(scope, simpleName)) {
184 return simpleName;
185 }
186 }
187 throw new TracedException(eObject, "Ambiguous qualified name: " +
188 qualifiedNameConverter.toString(qualifiedName));
189 }
190
191 private boolean isUnique(IScope scope, QualifiedName name) {
192 var iterator = scope.getElements(name).iterator();
193 if (!iterator.hasNext()) {
194 return false;
195 }
196 iterator.next();
197 return !iterator.hasNext();
198 }
199}
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeKind.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeKind.java
deleted file mode 100644
index 01f0cd09..00000000
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeKind.java
+++ /dev/null
@@ -1,12 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics.metadata;
7
8public enum NodeKind {
9 IMPLICIT,
10 INDIVIDUAL,
11 NEW
12}
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeMetadata.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeMetadata.java
deleted file mode 100644
index 812952c0..00000000
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/NodeMetadata.java
+++ /dev/null
@@ -1,9 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics.metadata;
7
8public record NodeMetadata(String name, String simpleName, NodeKind kind) implements Metadata {
9}
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/OppositeReferenceDetail.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/OppositeReferenceDetail.java
deleted file mode 100644
index 26d7461c..00000000
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/OppositeReferenceDetail.java
+++ /dev/null
@@ -1,9 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics.metadata;
7
8public record OppositeReferenceDetail(boolean container, String opposite) implements RelationDetail {
9}
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/PredicateDetail.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/PredicateDetail.java
deleted file mode 100644
index ca397eca..00000000
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/PredicateDetail.java
+++ /dev/null
@@ -1,16 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics.metadata;
7
8public record PredicateDetail(boolean error) implements RelationDetail {
9 public static final PredicateDetail PREDICATE = new PredicateDetail(false);
10
11 public static final PredicateDetail ERROR_PREDICATE = new PredicateDetail(true);
12
13 public static PredicateDetail ofError(boolean error) {
14 return error ? ERROR_PREDICATE : PREDICATE;
15 }
16}
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ReferenceDetail.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ReferenceDetail.java
deleted file mode 100644
index 36771566..00000000
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/ReferenceDetail.java
+++ /dev/null
@@ -1,16 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics.metadata;
7
8public record ReferenceDetail(boolean containment) implements RelationDetail {
9 public static final ReferenceDetail CROSS_REFERENCE = new ReferenceDetail(false);
10
11 public static final ReferenceDetail CONTAINMENT_REFERENCE = new ReferenceDetail(true);
12
13 public static ReferenceDetail ofContainment(boolean containment) {
14 return containment ? CONTAINMENT_REFERENCE : CROSS_REFERENCE;
15 }
16}
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationDetail.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationDetail.java
deleted file mode 100644
index 105179fd..00000000
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationDetail.java
+++ /dev/null
@@ -1,10 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics.metadata;
7
8public sealed interface RelationDetail permits ClassDetail, ReferenceDetail, PredicateDetail, OppositeReferenceDetail,
9 BuiltInDetail {
10}
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationMetadata.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationMetadata.java
deleted file mode 100644
index 5abcc253..00000000
--- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/metadata/RelationMetadata.java
+++ /dev/null
@@ -1,9 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.semantics.metadata;
7
8public record RelationMetadata(String name, String simpleName, int arity, RelationDetail detail) implements Metadata {
9}
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 */
6package tools.refinery.language.semantics.model; 6package tools.refinery.language.semantics;
7 7
8import org.junit.jupiter.api.Test; 8import org.junit.jupiter.api.Test;
9import tools.refinery.store.dse.propagation.PropagationAdapter; 9import 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 */
6package tools.refinery.language.semantics.model; 6package tools.refinery.language.semantics;
7 7
8import com.google.inject.Inject; 8import com.google.inject.Inject;
9import org.eclipse.xtext.testing.InjectWith; 9import 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 */
6package tools.refinery.language.semantics.model.internal; 6package tools.refinery.language.semantics.internal;
7 7
8import org.junit.jupiter.api.Test; 8import org.junit.jupiter.api.Test;
9import tools.refinery.store.representation.TruthValue; 9import tools.refinery.store.representation.TruthValue;