aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java')
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java255
1 files changed, 0 insertions, 255 deletions
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java b/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java
deleted file mode 100644
index a4ea1113..00000000
--- a/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java
+++ /dev/null
@@ -1,255 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.language.utils;
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 tools.refinery.language.model.problem.*;
13
14import java.util.LinkedHashMap;
15import java.util.List;
16import java.util.Map;
17
18class SymbolCollector {
19 @Inject
20 private IQualifiedNameProvider qualifiedNameProvider;
21
22 @Inject
23 private IQualifiedNameConverter qualifiedNameConverter;
24
25 @Inject
26 private ProblemDesugarer desugarer;
27
28 private BuiltinSymbols builtinSymbols;
29
30 private final Map<Node, NodeInfo> nodes = new LinkedHashMap<>();
31
32 private final Map<Relation, RelationInfo> relations = new LinkedHashMap<>();
33
34 public CollectedSymbols collectSymbols(Problem problem) {
35 builtinSymbols = desugarer.getBuiltinSymbols(problem).orElseThrow(() -> new IllegalArgumentException(
36 "Problem has no associated built-in library"));
37 collectOwnSymbols(builtinSymbols.problem());
38 collectOwnSymbols(problem);
39 return new CollectedSymbols(nodes, relations);
40 }
41
42 public void collectOwnSymbols(Problem problem) {
43 collectOwnRelations(problem);
44 collectOwnNodes(problem);
45 collectOwnAssertions(problem);
46 }
47
48 private void collectOwnRelations(Problem problem) {
49 for (var statement : problem.getStatements()) {
50 if (statement instanceof PredicateDefinition predicateDefinition) {
51 collectPredicate(predicateDefinition);
52 } else if (statement instanceof ClassDeclaration classDeclaration) {
53 collectClass(classDeclaration);
54 } else if (statement instanceof EnumDeclaration enumDeclaration) {
55 collectEnum(enumDeclaration);
56 } else if (statement instanceof RuleDefinition) {
57 throw new UnsupportedOperationException("Rules are not currently supported");
58 }
59 }
60 }
61
62 private void collectPredicate(PredicateDefinition predicateDefinition) {
63 var predicateKind = predicateDefinition.getKind();
64 var info = new RelationInfo(getQualifiedNameString(predicateDefinition),
65 ContainmentRole.fromPredicateKind(predicateKind), predicateDefinition.getParameters(), null, null,
66 predicateDefinition.getBodies());
67 relations.put(predicateDefinition, info);
68 }
69
70 private void collectClass(ClassDeclaration classDeclaration) {
71 var contained = classDeclaration != builtinSymbols.node();
72 var containmentRole = contained ? ContainmentRole.CONTAINED : ContainmentRole.NONE;
73 var instanceParameter = ProblemFactory.eINSTANCE.createParameter();
74 instanceParameter.setName("instance");
75 var classInfo = new RelationInfo(getQualifiedNameString(classDeclaration), containmentRole,
76 List.of(instanceParameter), null, null, List.of());
77 relations.put(classDeclaration, classInfo);
78 collectFeatures(classDeclaration);
79 }
80
81 private void collectFeatures(ClassDeclaration classDeclaration) {
82 for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) {
83 if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration) {
84 collectReference(classDeclaration, referenceDeclaration);
85 } else if (featureDeclaration instanceof AttributeDeclaration attributeDeclaration) {
86 collectAttribute(classDeclaration, attributeDeclaration);
87 } else if (featureDeclaration instanceof FlagDeclaration flagDeclaration) {
88 collectFlag(classDeclaration, flagDeclaration);
89 } else {
90 throw new IllegalArgumentException("Unknown FeatureDeclaration: " + featureDeclaration);
91 }
92 }
93 }
94
95 private void collectReference(ClassDeclaration classDeclaration, ReferenceDeclaration referenceDeclaration) {
96 var referenceRole = desugarer.isContainmentReference(referenceDeclaration) ?
97 ContainmentRole.CONTAINMENT :
98 ContainmentRole.NONE;
99 var sourceParameter = ProblemFactory.eINSTANCE.createParameter();
100 sourceParameter.setName("source");
101 sourceParameter.setParameterType(classDeclaration);
102 var targetParameter = ProblemFactory.eINSTANCE.createParameter();
103 targetParameter.setName("target");
104 var multiplicity = referenceDeclaration.getMultiplicity();
105 if (multiplicity == null) {
106 var exactMultiplicity = ProblemFactory.eINSTANCE.createExactMultiplicity();
107 exactMultiplicity.setExactValue(1);
108 multiplicity = exactMultiplicity;
109 }
110 targetParameter.setParameterType(referenceDeclaration.getReferenceType());
111 var referenceInfo = new RelationInfo(getQualifiedNameString(referenceDeclaration), referenceRole,
112 List.of(sourceParameter, targetParameter), multiplicity, referenceDeclaration.getOpposite(),
113 List.of());
114 this.relations.put(referenceDeclaration, referenceInfo);
115 }
116
117 private void collectAttribute(ClassDeclaration classDeclaration, AttributeDeclaration attributeDeclaration) {
118 // TODO Implement attribute handling.
119 }
120
121 private void collectFlag(ClassDeclaration classDeclaration, FlagDeclaration flagDeclaration) {
122 var parameter = ProblemFactory.eINSTANCE.createParameter();
123 parameter.setName("object");
124 parameter.setParameterType(classDeclaration);
125 var referenceInfo = new RelationInfo(getQualifiedNameString(flagDeclaration), ContainmentRole.NONE,
126 List.of(parameter), null, null, List.of());
127 this.relations.put(flagDeclaration, referenceInfo);
128 }
129
130 private void collectEnum(EnumDeclaration enumDeclaration) {
131 var instanceParameter = ProblemFactory.eINSTANCE.createParameter();
132 instanceParameter.setName("instance");
133 var info = new RelationInfo(getQualifiedNameString(enumDeclaration), ContainmentRole.NONE,
134 List.of(instanceParameter), null, null, List.of());
135 this.relations.put(enumDeclaration, info);
136 }
137
138 private void collectOwnNodes(Problem problem) {
139 for (var statement : problem.getStatements()) {
140 if (statement instanceof IndividualDeclaration individualDeclaration) {
141 collectIndividuals(individualDeclaration);
142 } else if (statement instanceof ClassDeclaration classDeclaration) {
143 collectNewNode(classDeclaration);
144 } else if (statement instanceof EnumDeclaration enumDeclaration) {
145 collectEnumLiterals(enumDeclaration);
146 }
147 }
148 for (var node : problem.getNodes()) {
149 addNode(node, false);
150 }
151 }
152
153 private void collectIndividuals(IndividualDeclaration individualDeclaration) {
154 for (var individual : individualDeclaration.getNodes()) {
155 addNode(individual, true);
156 }
157 }
158
159 private void collectNewNode(ClassDeclaration classDeclaration) {
160 var newNode = classDeclaration.getNewNode();
161 if (newNode != null) {
162 addNode(newNode, false);
163 }
164 }
165
166 private void collectEnumLiterals(EnumDeclaration enumDeclaration) {
167 for (var literal : enumDeclaration.getLiterals()) {
168 addNode(literal, true);
169 }
170 }
171
172 private void addNode(Node node, boolean individual) {
173 var info = new NodeInfo(getQualifiedNameString(node), individual);
174 this.nodes.put(node, info);
175 }
176
177 private String getQualifiedNameString(EObject eObject) {
178 var qualifiedName = qualifiedNameProvider.getFullyQualifiedName(eObject);
179 if (qualifiedName == null) {
180 return null;
181 }
182 return qualifiedNameConverter.toString(qualifiedName);
183 }
184
185 private void collectOwnAssertions(Problem problem) {
186 for (var statement : problem.getStatements()) {
187 if (statement instanceof Assertion assertion) {
188 collectAssertion(assertion);
189 } else if (statement instanceof PredicateDefinition predicateDefinition) {
190 collectPredicateAssertion(predicateDefinition);
191 } else if (statement instanceof ClassDeclaration classDeclaration) {
192 collectClassAssertion(classDeclaration);
193 } else if (statement instanceof EnumDeclaration enumDeclaration) {
194 collectEnumAssertions(enumDeclaration);
195 }
196 }
197 }
198
199 private void collectAssertion(Assertion assertion) {
200 var relationInfo = this.relations.get(assertion.getRelation());
201 if (relationInfo == null) {
202 throw new IllegalStateException("Assertion refers to unknown relation");
203 }
204 if (assertion.getArguments().size() != relationInfo.parameters().size()) {
205 // Silently ignoring assertions of invalid arity helps when SymbolCollector is called on an invalid
206 // Problem during editing. The errors can still be detected by the Problem validator.
207 return;
208 }
209 relationInfo.assertions().add(assertion);
210 }
211
212 private void collectPredicateAssertion(PredicateDefinition predicateDefinition) {
213 if (predicateDefinition.getKind() != PredicateKind.ERROR) {
214 return;
215 }
216 int arity = predicateDefinition.getParameters().size();
217 addAssertion(predicateDefinition, LogicValue.FALSE, new Node[arity]);
218 }
219
220 private void collectClassAssertion(ClassDeclaration classDeclaration) {
221 var node = classDeclaration.getNewNode();
222 if (node == null) {
223 return;
224 }
225 addAssertion(classDeclaration, LogicValue.TRUE, node);
226 addAssertion(builtinSymbols.exists(), LogicValue.UNKNOWN, node);
227 addAssertion(builtinSymbols.equals(), LogicValue.UNKNOWN, node, node);
228 }
229
230 private void collectEnumAssertions(EnumDeclaration enumDeclaration) {
231 for (var literal : enumDeclaration.getLiterals()) {
232 addAssertion(enumDeclaration, LogicValue.TRUE, literal);
233 }
234 }
235
236 private void addAssertion(Relation relation, LogicValue logicValue, Node... nodes) {
237 var assertion = ProblemFactory.eINSTANCE.createAssertion();
238 assertion.setRelation(relation);
239 for (var node : nodes) {
240 AssertionArgument argument;
241 if (node == null) {
242 argument = ProblemFactory.eINSTANCE.createWildcardAssertionArgument();
243 } else {
244 var nodeArgument = ProblemFactory.eINSTANCE.createNodeAssertionArgument();
245 nodeArgument.setNode(node);
246 argument = nodeArgument;
247 }
248 assertion.getArguments().add(argument);
249 }
250 var value = ProblemFactory.eINSTANCE.createLogicConstant();
251 value.setLogicValue(logicValue);
252 assertion.setValue(value);
253 collectAssertion(assertion);
254 }
255}