aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/language/src/main')
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/Problem.xtext48
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java96
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java1
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java44
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java6
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/utils/CollectedSymbols.java15
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/utils/ContainmentRole.java22
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java9
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java24
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java47
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/utils/RelationInfo.java29
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java255
-rw-r--r--subprojects/language/src/main/resources/tools/refinery/language/builtin.problem41
13 files changed, 171 insertions, 466 deletions
diff --git a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
index 9e330347..0a91178b 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
+++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
@@ -14,7 +14,7 @@ Problem:
14 14
15Statement: 15Statement:
16 Assertion | ClassDeclaration | EnumDeclaration | 16 Assertion | ClassDeclaration | EnumDeclaration |
17 PredicateDefinition | FunctionDefinition | /* RuleDefinition | */ 17 PredicateDefinition | /* FunctionDefinition | RuleDefinition | */
18 ScopeDeclaration | IndividualDeclaration; 18 ScopeDeclaration | IndividualDeclaration;
19 19
20ClassDeclaration: 20ClassDeclaration:
@@ -32,7 +32,7 @@ EnumLiteral returns Node:
32 name=Identifier; 32 name=Identifier;
33 33
34FeatureDeclaration: 34FeatureDeclaration:
35 ReferenceDeclaration | AttributeDeclaration | FlagDeclaration; 35 ReferenceDeclaration /* | AttributeDeclaration | FlagDeclaration */;
36 36
37enum ReferenceKind: 37enum ReferenceKind:
38 REFERENCE="refers" | CONTAINMENT="contains" | CONTAINER="container"; 38 REFERENCE="refers" | CONTAINMENT="contains" | CONTAINER="container";
@@ -44,23 +44,17 @@ ReferenceDeclaration:
44 name=Identifier 44 name=Identifier
45 ("opposite" opposite=[ReferenceDeclaration|QualifiedName])?; 45 ("opposite" opposite=[ReferenceDeclaration|QualifiedName])?;
46 46
47enum PrimitiveType: 47//enum PrimitiveType:
48 INT="int" | REAL="real" | STRING="string"; 48// INT="int" | REAL="real" | STRING="string";
49 49//
50AttributeDeclaration: 50//AttributeDeclaration:
51 attributeType=PrimitiveType name=Identifier; 51// attributeType=PrimitiveType name=Identifier;
52 52//
53FlagDeclaration: 53//FlagDeclaration:
54 "bool" name=Identifier; 54// "bool" name=Identifier;
55
56enum ErrorKind returns PredicateKind:
57 ERROR="error";
58
59enum PredicateKind:
60 ERROR="error" | CONTAINED="contained" | CONTAINMENT="containment";
61 55
62PredicateDefinition: 56PredicateDefinition:
63 (kind=ErrorKind | kind=PredicateKind? "pred") 57 ("pred" | error?="error" "pred"?)
64 name=Identifier 58 name=Identifier
65 "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" 59 "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")"
66 ("<->" bodies+=Conjunction (";" bodies+=Conjunction)*)? 60 ("<->" bodies+=Conjunction (";" bodies+=Conjunction)*)?
@@ -69,14 +63,14 @@ PredicateDefinition:
69Conjunction: 63Conjunction:
70 literals+=Expr ("," literals+=Expr)*; 64 literals+=Expr ("," literals+=Expr)*;
71 65
72FunctionDefinition: 66//FunctionDefinition:
73 "fn" functionType=PrimitiveType name=Identifier 67// "fn" functionType=PrimitiveType name=Identifier
74 "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" 68// "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")"
75 ("=" cases+=Case (";" cases+=Case)*)? 69// ("=" cases+=Case (";" cases+=Case)*)?
76 "."; 70// ".";
77 71//
78Case: 72//Case:
79 Conjunction ({Match.condition=current} "->" value=Expr)?; 73// Conjunction ({Match.condition=current} "->" value=Expr)?;
80 74
81//RuleDefinition: 75//RuleDefinition:
82// "rule" 76// "rule"
@@ -87,7 +81,7 @@ Case:
87// "."; 81// ".";
88 82
89Parameter: 83Parameter:
90 (modality=Modality? parameterType=[Relation|QualifiedName])? name=Identifier; 84 parameterType=[Relation|QualifiedName]? name=Identifier;
91 85
92//Consequent: 86//Consequent:
93// actions+=Action ("," actions+=Action)*; 87// actions+=Action ("," actions+=Action)*;
@@ -268,7 +262,7 @@ NonContainmentQualifiedName hidden():
268 NonContainmentIdentifier ("::" Identifier)*; 262 NonContainmentIdentifier ("::" Identifier)*;
269 263
270Identifier: 264Identifier:
271 NonContainmentIdentifier | "contains"; 265 NonContainmentIdentifier | "contains" | "container";
272 266
273NonContainmentIdentifier: 267NonContainmentIdentifier:
274 ID | "contained" | "sum" | "prod" | "min" | "max"; 268 ID | "contained" | "sum" | "prod" | "min" | "max";
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java
index b145ef27..31eb55a6 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java
@@ -18,6 +18,7 @@ import org.eclipse.xtext.resource.DerivedStateAwareResource;
18import org.eclipse.xtext.resource.IDerivedStateComputer; 18import org.eclipse.xtext.resource.IDerivedStateComputer;
19import org.eclipse.xtext.resource.XtextResource; 19import org.eclipse.xtext.resource.XtextResource;
20import tools.refinery.language.model.problem.*; 20import tools.refinery.language.model.problem.*;
21import tools.refinery.language.utils.ProblemUtil;
21 22
22import java.util.*; 23import java.util.*;
23import java.util.function.Function; 24import java.util.function.Function;
@@ -58,7 +59,7 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
58 } 59 }
59 60
60 protected void installDerivedProblemState(Problem problem, Adapter adapter, boolean preLinkingPhase) { 61 protected void installDerivedProblemState(Problem problem, Adapter adapter, boolean preLinkingPhase) {
61 installNewNodes(problem, adapter); 62 installDerivedClassDeclarationState(problem, adapter);
62 if (preLinkingPhase) { 63 if (preLinkingPhase) {
63 return; 64 return;
64 } 65 }
@@ -66,24 +67,67 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
66 derivedVariableComputer.installDerivedVariables(problem, nodeNames); 67 derivedVariableComputer.installDerivedVariables(problem, nodeNames);
67 } 68 }
68 69
69 protected void installNewNodes(Problem problem, Adapter adapter) { 70 protected void installDerivedClassDeclarationState(Problem problem, Adapter adapter) {
70 for (Statement statement : problem.getStatements()) { 71 for (var statement : problem.getStatements()) {
71 if (statement instanceof ClassDeclaration declaration && !declaration.isAbstract() 72 if (statement instanceof ClassDeclaration classDeclaration) {
72 && declaration.getNewNode() == null) { 73 installOrRemoveNewNode(adapter, classDeclaration);
74 for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) {
75 if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration) {
76 installOrRemoveInvalidMultiplicityPredicate(adapter, classDeclaration, referenceDeclaration);
77 }
78 }
79 }
80 }
81 }
82
83 protected void installOrRemoveNewNode(Adapter adapter, ClassDeclaration declaration) {
84 if (declaration.isAbstract()) {
85 var newNode = declaration.getNewNode();
86 if (newNode != null) {
87 declaration.setNewNode(null);
88 adapter.removeNewNode(declaration);
89 }
90 } else {
91 if (declaration.getNewNode() == null) {
73 var newNode = adapter.createNewNodeIfAbsent(declaration, key -> createNode(NEW_NODE)); 92 var newNode = adapter.createNewNodeIfAbsent(declaration, key -> createNode(NEW_NODE));
74 declaration.setNewNode(newNode); 93 declaration.setNewNode(newNode);
75 } 94 }
76 } 95 }
77 } 96 }
78 97
98 protected void installOrRemoveInvalidMultiplicityPredicate(
99 Adapter adapter, ClassDeclaration containingClassDeclaration, ReferenceDeclaration declaration) {
100 if (ProblemUtil.hasMultiplicityConstraint(declaration)) {
101 if (declaration.getInvalidMultiplicity() == null) {
102 var invalidMultiplicity = adapter.createInvalidMultiplicityPredicateIfAbsent(declaration, key -> {
103 var predicate = ProblemFactory.eINSTANCE.createPredicateDefinition();
104 predicate.setError(true);
105 predicate.setName("invalidMultiplicity");
106 var parameter = ProblemFactory.eINSTANCE.createParameter();
107 parameter.setParameterType(containingClassDeclaration);
108 parameter.setName("node");
109 predicate.getParameters().add(parameter);
110 return predicate;
111 });
112 declaration.setInvalidMultiplicity(invalidMultiplicity);
113 }
114 } else {
115 var invalidMultiplicity = declaration.getInvalidMultiplicity();
116 if (invalidMultiplicity != null) {
117 declaration.setInvalidMultiplicity(null);
118 adapter.removeInvalidMultiplicityPredicate(declaration);
119 }
120 }
121 }
122
79 protected Set<String> installDerivedNodes(Problem problem) { 123 protected Set<String> installDerivedNodes(Problem problem) {
80 var collector = nodeNameCollectorProvider.get(); 124 var collector = nodeNameCollectorProvider.get();
81 collector.collectNodeNames(problem); 125 collector.collectNodeNames(problem);
82 Set<String> nodeNames = collector.getNodeNames(); 126 Set<String> nodeNames = collector.getNodeNames();
83 List<Node> grapNodes = problem.getNodes(); 127 List<Node> graphNodes = problem.getNodes();
84 for (String nodeName : nodeNames) { 128 for (String nodeName : nodeNames) {
85 var graphNode = createNode(nodeName); 129 var graphNode = createNode(nodeName);
86 grapNodes.add(graphNode); 130 graphNodes.add(graphNode);
87 } 131 }
88 return nodeNames; 132 return nodeNames;
89 } 133 }
@@ -104,15 +148,24 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
104 } 148 }
105 149
106 protected void discardDerivedProblemState(Problem problem, Adapter adapter) { 150 protected void discardDerivedProblemState(Problem problem, Adapter adapter) {
107 Set<ClassDeclaration> classDeclarations = new HashSet<>(); 151 var abstractClassDeclarations = new HashSet<ClassDeclaration>();
152 var referenceDeclarationsWithMultiplicity = new HashSet<ReferenceDeclaration>();
108 problem.getNodes().clear(); 153 problem.getNodes().clear();
109 for (var statement : problem.getStatements()) { 154 for (var statement : problem.getStatements()) {
110 if (statement instanceof ClassDeclaration classDeclaration) { 155 if (statement instanceof ClassDeclaration classDeclaration) {
111 classDeclaration.setNewNode(null); 156 classDeclaration.setNewNode(null);
112 classDeclarations.add(classDeclaration); 157 if (classDeclaration.isAbstract()) {
158 abstractClassDeclarations.add(classDeclaration);
159 }
160 for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) {
161 if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration &&
162 ProblemUtil.hasMultiplicityConstraint(referenceDeclaration)) {
163 referenceDeclarationsWithMultiplicity.add(referenceDeclaration);
164 }
165 }
113 } 166 }
114 } 167 }
115 adapter.retainAll(classDeclarations); 168 adapter.retainAll(abstractClassDeclarations, referenceDeclarationsWithMultiplicity);
116 derivedVariableComputer.discardDerivedVariables(problem); 169 derivedVariableComputer.discardDerivedVariables(problem);
117 } 170 }
118 171
@@ -134,14 +187,31 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
134 187
135 protected static class Adapter extends AdapterImpl { 188 protected static class Adapter extends AdapterImpl {
136 private final Map<ClassDeclaration, Node> newNodes = new HashMap<>(); 189 private final Map<ClassDeclaration, Node> newNodes = new HashMap<>();
190 private final Map<ReferenceDeclaration, PredicateDefinition> invalidMultiplicityPredicates = new HashMap<>();
137 191
138 public Node createNewNodeIfAbsent(ClassDeclaration classDeclaration, 192 public Node createNewNodeIfAbsent(ClassDeclaration classDeclaration,
139 Function<ClassDeclaration, Node> createNode) { 193 Function<ClassDeclaration, Node> createNode) {
140 return newNodes.computeIfAbsent(classDeclaration, createNode); 194 return newNodes.computeIfAbsent(classDeclaration, createNode);
141 } 195 }
142 196
143 public void retainAll(Collection<ClassDeclaration> classDeclarations) { 197 public void removeNewNode(ClassDeclaration classDeclaration) {
144 newNodes.keySet().retainAll(classDeclarations); 198 newNodes.remove(classDeclaration);
199 }
200
201 public PredicateDefinition createInvalidMultiplicityPredicateIfAbsent(
202 ReferenceDeclaration referenceDeclaration,
203 Function<ReferenceDeclaration, PredicateDefinition> createPredicate) {
204 return invalidMultiplicityPredicates.computeIfAbsent(referenceDeclaration, createPredicate);
205 }
206
207 public void removeInvalidMultiplicityPredicate(ReferenceDeclaration referenceDeclaration) {
208 invalidMultiplicityPredicates.remove(referenceDeclaration);
209 }
210
211 public void retainAll(Collection<ClassDeclaration> abstractClassDeclarations,
212 Collection<ReferenceDeclaration> referenceDeclarationsWithMultiplicity) {
213 newNodes.keySet().retainAll(abstractClassDeclarations);
214 invalidMultiplicityPredicates.keySet().retainAll(referenceDeclarationsWithMultiplicity);
145 } 215 }
146 216
147 @Override 217 @Override
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
index 1fe2df89..29eaad84 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
@@ -8,7 +8,6 @@ package tools.refinery.language.resource;
8import org.eclipse.emf.ecore.EObject; 8import org.eclipse.emf.ecore.EObject;
9import org.eclipse.xtext.resource.DefaultLocationInFileProvider; 9import org.eclipse.xtext.resource.DefaultLocationInFileProvider;
10import org.eclipse.xtext.util.ITextRegion; 10import org.eclipse.xtext.util.ITextRegion;
11
12import tools.refinery.language.model.problem.ImplicitVariable; 11import tools.refinery.language.model.problem.ImplicitVariable;
13import tools.refinery.language.model.problem.Node; 12import tools.refinery.language.model.problem.Node;
14import tools.refinery.language.utils.ProblemUtil; 13import tools.refinery.language.utils.ProblemUtil;
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
index 630be379..a16f77eb 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
@@ -5,6 +5,9 @@
5 */ 5 */
6package tools.refinery.language.resource; 6package tools.refinery.language.resource;
7 7
8import com.google.common.collect.ImmutableMap;
9import com.google.inject.Inject;
10import com.google.inject.Singleton;
8import org.eclipse.emf.ecore.EObject; 11import org.eclipse.emf.ecore.EObject;
9import org.eclipse.xtext.EcoreUtil2; 12import org.eclipse.xtext.EcoreUtil2;
10import org.eclipse.xtext.naming.IQualifiedNameConverter; 13import org.eclipse.xtext.naming.IQualifiedNameConverter;
@@ -13,19 +16,18 @@ import org.eclipse.xtext.resource.EObjectDescription;
13import org.eclipse.xtext.resource.IEObjectDescription; 16import org.eclipse.xtext.resource.IEObjectDescription;
14import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionStrategy; 17import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionStrategy;
15import org.eclipse.xtext.util.IAcceptor; 18import org.eclipse.xtext.util.IAcceptor;
16 19import tools.refinery.language.model.problem.*;
17import com.google.inject.Inject;
18import com.google.inject.Singleton;
19
20import tools.refinery.language.model.problem.NamedElement;
21import tools.refinery.language.model.problem.Node;
22import tools.refinery.language.model.problem.Problem;
23import tools.refinery.language.model.problem.Variable;
24import tools.refinery.language.naming.NamingUtil; 20import tools.refinery.language.naming.NamingUtil;
25import tools.refinery.language.utils.ProblemUtil; 21import tools.refinery.language.utils.ProblemUtil;
26 22
23import java.util.Map;
24
27@Singleton 25@Singleton
28public class ProblemResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy { 26public class ProblemResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy {
27 public static final String ERROR_PREDICATE = "tools.refinery.language.resource" +
28 ".ProblemResourceDescriptionStrategy.ERROR_PREDICATE";
29 public static final String ERROR_PREDICATE_TRUE = "true";
30
29 @Inject 31 @Inject
30 private IQualifiedNameConverter qualifiedNameConverter; 32 private IQualifiedNameConverter qualifiedNameConverter;
31 33
@@ -40,9 +42,10 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
40 } 42 }
41 var problem = EcoreUtil2.getContainerOfType(eObject, Problem.class); 43 var problem = EcoreUtil2.getContainerOfType(eObject, Problem.class);
42 var problemQualifiedName = getNameAsQualifiedName(problem); 44 var problemQualifiedName = getNameAsQualifiedName(problem);
45 var userData = getUserData(eObject);
43 boolean nameExported; 46 boolean nameExported;
44 if (shouldExportSimpleName(eObject)) { 47 if (shouldExportSimpleName(eObject)) {
45 acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, acceptor); 48 acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, userData, acceptor);
46 nameExported = true; 49 nameExported = true;
47 } else { 50 } else {
48 nameExported = false; 51 nameExported = false;
@@ -56,7 +59,7 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
56 } 59 }
57 qualifiedName = parentQualifiedName.append(qualifiedName); 60 qualifiedName = parentQualifiedName.append(qualifiedName);
58 if (shouldExportSimpleName(parent)) { 61 if (shouldExportSimpleName(parent)) {
59 acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, acceptor); 62 acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, userData, acceptor);
60 nameExported = true; 63 nameExported = true;
61 } else { 64 } else {
62 nameExported = false; 65 nameExported = false;
@@ -64,16 +67,15 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
64 parent = parent.eContainer(); 67 parent = parent.eContainer();
65 } 68 }
66 if (!nameExported) { 69 if (!nameExported) {
67 acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, acceptor); 70 acceptEObjectDescription(eObject, problemQualifiedName, qualifiedName, userData, acceptor);
68 } 71 }
69 return true; 72 return true;
70 } 73 }
71 74
72 protected QualifiedName getNameAsQualifiedName(EObject eObject) { 75 protected QualifiedName getNameAsQualifiedName(EObject eObject) {
73 if (!(eObject instanceof NamedElement)) { 76 if (!(eObject instanceof NamedElement namedElement)) {
74 return null; 77 return null;
75 } 78 }
76 var namedElement = (NamedElement) eObject;
77 var name = namedElement.getName(); 79 var name = namedElement.getName();
78 if (NamingUtil.isNullOrEmpty(name)) { 80 if (NamingUtil.isNullOrEmpty(name)) {
79 return null; 81 return null;
@@ -93,16 +95,28 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
93 return true; 95 return true;
94 } 96 }
95 97
98 protected Map<String, String> getUserData(EObject eObject) {
99 var builder = ImmutableMap.<String, String>builder();
100 if (eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isError()) {
101 builder.put(ERROR_PREDICATE, ERROR_PREDICATE_TRUE);
102 }
103 return builder.build();
104 }
105
96 protected boolean shouldExportSimpleName(EObject eObject) { 106 protected boolean shouldExportSimpleName(EObject eObject) {
97 if (eObject instanceof Node node) { 107 if (eObject instanceof Node node) {
98 return !ProblemUtil.isNewNode(node); 108 return !ProblemUtil.isNewNode(node);
99 } 109 }
110 if (eObject instanceof PredicateDefinition predicateDefinition) {
111 return !ProblemUtil.isInvalidMultiplicityConstraint(predicateDefinition);
112 }
100 return true; 113 return true;
101 } 114 }
102 115
103 private void acceptEObjectDescription(EObject eObject, QualifiedName prefix, QualifiedName qualifiedName, 116 private void acceptEObjectDescription(EObject eObject, QualifiedName prefix, QualifiedName qualifiedName,
104 IAcceptor<IEObjectDescription> acceptor) { 117 Map<String, String> userData, IAcceptor<IEObjectDescription> acceptor) {
105 var qualifiedNameWithPrefix = prefix == null ? qualifiedName : prefix.append(qualifiedName); 118 var qualifiedNameWithPrefix = prefix == null ? qualifiedName : prefix.append(qualifiedName);
106 acceptor.accept(EObjectDescription.create(qualifiedNameWithPrefix, eObject)); 119 var description = EObjectDescription.create(qualifiedNameWithPrefix, eObject, userData);
120 acceptor.accept(description);
107 } 121 }
108} 122}
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java b/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java
index c8c7fd4a..c87fa044 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java
@@ -7,7 +7,7 @@ package tools.refinery.language.utils;
7 7
8import tools.refinery.language.model.problem.*; 8import tools.refinery.language.model.problem.*;
9 9
10public record BuiltinSymbols(Problem problem, ClassDeclaration node, ReferenceDeclaration equals, 10public record BuiltinSymbols(Problem problem, ClassDeclaration node, PredicateDefinition equals,
11 PredicateDefinition exists, PredicateDefinition contained, PredicateDefinition contains, 11 PredicateDefinition exists, ClassDeclaration contained, PredicateDefinition contains,
12 PredicateDefinition root) { 12 PredicateDefinition invalidContainer) {
13} 13}
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/CollectedSymbols.java b/subprojects/language/src/main/java/tools/refinery/language/utils/CollectedSymbols.java
deleted file mode 100644
index e4e4d07a..00000000
--- a/subprojects/language/src/main/java/tools/refinery/language/utils/CollectedSymbols.java
+++ /dev/null
@@ -1,15 +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 java.util.Map;
9
10import tools.refinery.language.model.problem.Node;
11import tools.refinery.language.model.problem.Relation;
12
13public record CollectedSymbols(Map<Node, NodeInfo> nodes, Map<Relation, RelationInfo> relations) {
14
15}
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/ContainmentRole.java b/subprojects/language/src/main/java/tools/refinery/language/utils/ContainmentRole.java
deleted file mode 100644
index a43c7dfe..00000000
--- a/subprojects/language/src/main/java/tools/refinery/language/utils/ContainmentRole.java
+++ /dev/null
@@ -1,22 +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 tools.refinery.language.model.problem.PredicateKind;
9
10public enum ContainmentRole {
11 NONE,
12 CONTAINED,
13 CONTAINMENT;
14
15 public static ContainmentRole fromPredicateKind(PredicateKind predicateKind) {
16 return switch (predicateKind) {
17 case CONTAINED -> CONTAINED;
18 case CONTAINMENT -> CONTAINMENT;
19 default -> NONE;
20 };
21 }
22}
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java b/subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java
deleted file mode 100644
index 0fa7a454..00000000
--- a/subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java
+++ /dev/null
@@ -1,9 +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
8public record NodeInfo(String name, boolean individual) {
9}
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java
index 738a0896..59e26561 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java
@@ -6,7 +6,6 @@
6package tools.refinery.language.utils; 6package tools.refinery.language.utils;
7 7
8import com.google.inject.Inject; 8import com.google.inject.Inject;
9import com.google.inject.Provider;
10import com.google.inject.Singleton; 9import com.google.inject.Singleton;
11import org.eclipse.emf.ecore.EObject; 10import org.eclipse.emf.ecore.EObject;
12import org.eclipse.emf.ecore.resource.Resource; 11import org.eclipse.emf.ecore.resource.Resource;
@@ -21,9 +20,6 @@ public class ProblemDesugarer {
21 @Inject 20 @Inject
22 private IResourceScopeCache cache = IResourceScopeCache.NullImpl.INSTANCE; 21 private IResourceScopeCache cache = IResourceScopeCache.NullImpl.INSTANCE;
23 22
24 @Inject
25 private Provider<SymbolCollector> symbolCollectorProvider;
26
27 public Optional<Problem> getBuiltinProblem(EObject context) { 23 public Optional<Problem> getBuiltinProblem(EObject context) {
28 return Optional.ofNullable(context).map(EObject::eResource).flatMap(resource -> 24 return Optional.ofNullable(context).map(EObject::eResource).flatMap(resource ->
29 cache.get("builtinProblem", resource, () -> doGetBuiltinProblem(resource))); 25 cache.get("builtinProblem", resource, () -> doGetBuiltinProblem(resource)));
@@ -43,12 +39,12 @@ public class ProblemDesugarer {
43 39
44 private BuiltinSymbols doGetBuiltinSymbols(Problem builtin) { 40 private BuiltinSymbols doGetBuiltinSymbols(Problem builtin) {
45 var node = doGetDeclaration(builtin, ClassDeclaration.class, "node"); 41 var node = doGetDeclaration(builtin, ClassDeclaration.class, "node");
46 var equals = doGetEqualsReference(node); 42 var equals = doGetDeclaration(builtin, PredicateDefinition.class, "equals");
47 var exists = doGetDeclaration(builtin, PredicateDefinition.class, "exists"); 43 var exists = doGetDeclaration(builtin, PredicateDefinition.class, "exists");
48 var contained = doGetDeclaration(builtin, PredicateDefinition.class, "contained"); 44 var contained = doGetDeclaration(builtin, ClassDeclaration.class, "contained");
49 var contains = doGetDeclaration(builtin, PredicateDefinition.class, "contains"); 45 var contains = doGetDeclaration(builtin, PredicateDefinition.class, "contains");
50 var root = doGetDeclaration(builtin, PredicateDefinition.class, "root"); 46 var invalidContainer = doGetDeclaration(builtin, PredicateDefinition.class, "invalidContainer");
51 return new BuiltinSymbols(builtin, node, equals, exists, contained, contains, root); 47 return new BuiltinSymbols(builtin, node, equals, exists, contained, contains, invalidContainer);
52 } 48 }
53 49
54 private <T extends Statement & NamedElement> T doGetDeclaration(Problem builtin, Class<T> type, String name) { 50 private <T extends Statement & NamedElement> T doGetDeclaration(Problem builtin, Class<T> type, String name) {
@@ -57,13 +53,6 @@ public class ProblemDesugarer {
57 .orElseThrow(() -> new IllegalArgumentException("Built-in declaration " + name + " was not found")); 53 .orElseThrow(() -> new IllegalArgumentException("Built-in declaration " + name + " was not found"));
58 } 54 }
59 55
60 private ReferenceDeclaration doGetEqualsReference(ClassDeclaration nodeClassDeclaration) {
61 return (ReferenceDeclaration) nodeClassDeclaration.getFeatureDeclarations().stream()
62 .filter(reference -> reference instanceof ReferenceDeclaration &&
63 "equals".equals(reference.getName())).findFirst()
64 .orElseThrow(() -> new IllegalArgumentException("Reference " + "equals" + " not found"));
65 }
66
67 public Collection<ClassDeclaration> getSuperclassesAndSelf(ClassDeclaration classDeclaration) { 56 public Collection<ClassDeclaration> getSuperclassesAndSelf(ClassDeclaration classDeclaration) {
68 return cache.get(Tuples.create(classDeclaration, "superclassesAndSelf"), classDeclaration.eResource(), 57 return cache.get(Tuples.create(classDeclaration, "superclassesAndSelf"), classDeclaration.eResource(),
69 () -> doGetSuperclassesAndSelf(classDeclaration)); 58 () -> doGetSuperclassesAndSelf(classDeclaration));
@@ -109,9 +98,4 @@ public class ProblemDesugarer {
109 public boolean isContainmentReference(ReferenceDeclaration referenceDeclaration) { 98 public boolean isContainmentReference(ReferenceDeclaration referenceDeclaration) {
110 return referenceDeclaration.getKind() == ReferenceKind.CONTAINMENT; 99 return referenceDeclaration.getKind() == ReferenceKind.CONTAINMENT;
111 } 100 }
112
113 public CollectedSymbols collectSymbols(Problem problem) {
114 return cache.get(Tuples.create(problem, "collectedSymbols"), problem.eResource(),
115 () -> symbolCollectorProvider.get().collectSymbols(problem));
116 }
117} 101}
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java
index 9486dc2a..a9efc4bb 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java
@@ -7,33 +7,12 @@ package tools.refinery.language.utils;
7 7
8import org.eclipse.emf.common.util.URI; 8import org.eclipse.emf.common.util.URI;
9import org.eclipse.emf.ecore.EObject; 9import org.eclipse.emf.ecore.EObject;
10 10import tools.refinery.language.model.problem.*;
11import tools.refinery.language.model.problem.ImplicitVariable;
12import tools.refinery.language.model.problem.Node;
13import tools.refinery.language.model.problem.ProblemPackage;
14import tools.refinery.language.model.problem.Variable;
15 11
16public final class ProblemUtil { 12public final class ProblemUtil {
17 public static final String BUILTIN_LIBRARY_NAME = "builtin"; 13 public static final String BUILTIN_LIBRARY_NAME = "builtin";
18
19 public static final URI BUILTIN_LIBRARY_URI = getLibraryUri(BUILTIN_LIBRARY_NAME); 14 public static final URI BUILTIN_LIBRARY_URI = getLibraryUri(BUILTIN_LIBRARY_NAME);
20 15
21 public static final String NODE_CLASS_NAME = "node";
22
23 public static final String DOMAIN_CLASS_NAME = "domain";
24
25 public static final String DATA_CLASS_NAME = "data";
26
27 public static final String INT_CLASS_NAME = "int";
28
29 public static final String REAL_CLASS_NAME = "real";
30
31 public static final String STRING_CLASS_NAME = "string";
32
33 public static final String EQUALS_RELATION_NAME = "equals";
34
35 public static final String EXISTS_PREDICATE_NAME = "exists";
36
37 private ProblemUtil() { 16 private ProblemUtil() {
38 throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); 17 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
39 } 18 }
@@ -70,6 +49,10 @@ public final class ProblemUtil {
70 } 49 }
71 } 50 }
72 51
52 public static boolean isError(EObject eObject) {
53 return eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isError();
54 }
55
73 public static boolean isIndividualNode(Node node) { 56 public static boolean isIndividualNode(Node node) {
74 var containingFeature = node.eContainingFeature(); 57 var containingFeature = node.eContainingFeature();
75 return containingFeature == ProblemPackage.Literals.INDIVIDUAL_DECLARATION__NODES 58 return containingFeature == ProblemPackage.Literals.INDIVIDUAL_DECLARATION__NODES
@@ -80,6 +63,26 @@ public final class ProblemUtil {
80 return node.eContainingFeature() == ProblemPackage.Literals.CLASS_DECLARATION__NEW_NODE; 63 return node.eContainingFeature() == ProblemPackage.Literals.CLASS_DECLARATION__NEW_NODE;
81 } 64 }
82 65
66 public static boolean isInvalidMultiplicityConstraint(PredicateDefinition predicateDefinition) {
67 return predicateDefinition.eContainingFeature() ==
68 ProblemPackage.Literals.REFERENCE_DECLARATION__INVALID_MULTIPLICITY;
69 }
70
71 public static boolean hasMultiplicityConstraint(ReferenceDeclaration referenceDeclaration) {
72 var opposite = referenceDeclaration.getOpposite();
73 if (opposite != null && opposite.getKind() == ReferenceKind.CONTAINMENT) {
74 return false;
75 }
76 var multiplicity = referenceDeclaration.getMultiplicity();
77 if (multiplicity instanceof UnboundedMultiplicity) {
78 return false;
79 }
80 if (multiplicity instanceof RangeMultiplicity rangeMultiplicity) {
81 return rangeMultiplicity.getLowerBound() > 0 || rangeMultiplicity.getUpperBound() >= 0;
82 }
83 return true;
84 }
85
83 private static URI getLibraryUri(String libraryName) { 86 private static URI getLibraryUri(String libraryName) {
84 return URI.createURI(ProblemUtil.class.getClassLoader() 87 return URI.createURI(ProblemUtil.class.getClassLoader()
85 .getResource("tools/refinery/language/%s.problem".formatted(libraryName)).toString()); 88 .getResource("tools/refinery/language/%s.problem".formatted(libraryName)).toString());
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/RelationInfo.java b/subprojects/language/src/main/java/tools/refinery/language/utils/RelationInfo.java
deleted file mode 100644
index 1c46fe72..00000000
--- a/subprojects/language/src/main/java/tools/refinery/language/utils/RelationInfo.java
+++ /dev/null
@@ -1,29 +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 tools.refinery.language.model.problem.*;
9
10import java.util.ArrayList;
11import java.util.Collection;
12import java.util.List;
13
14public record RelationInfo(String name, ContainmentRole containmentRole, List<Parameter> parameters,
15 Multiplicity multiplicity, Relation opposite, Collection<Conjunction> bodies,
16 Collection<Assertion> assertions, Collection<TypeScope> typeScopes) {
17 public RelationInfo(String name, ContainmentRole containmentRole, List<Parameter> parameters,
18 Multiplicity multiplicity, Relation opposite, Collection<Conjunction> bodies) {
19 this(name, containmentRole, parameters, multiplicity, opposite, bodies, new ArrayList<>(), new ArrayList<>());
20 }
21
22 public boolean hasDefinition() {
23 return bodies != null && !bodies.isEmpty();
24 }
25
26 public int arity() {
27 return parameters.size();
28 }
29}
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}
diff --git a/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem b/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem
index 9c1d7669..022c3167 100644
--- a/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem
+++ b/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem
@@ -3,43 +3,14 @@
3% SPDX-License-Identifier: EPL-2.0 3% SPDX-License-Identifier: EPL-2.0
4problem builtin. 4problem builtin.
5 5
6abstract class node { 6abstract class node.
7 refers node[] equals opposite equals
8}
9 7
10pred exists(node node). 8pred exists(node).
11 9
12% class Integer { 10pred equals(left, right).
13% int intValue
14% }
15%
16% class Real {
17% real realValue
18% }
19%
20% class String {
21% string stringValue
22% }
23%
24% enum Boolean {
25% TRUE, FALSE
26% }
27 11
28pred contained(node node). 12abstract class contained extends node.
29 13
30pred contains(node container, node contained). 14pred contains(container, contained contained).
31 15
32pred root(node node). 16error invalidContainer(contained contained).
33
34% error missingContainer(contained node) <->
35% !contains(node, _), !root(node).
36%
37% error tooManyContainers(contained node) <->
38% #contains(_, node) > 1
39% ;
40% contains(_, node), root(node)
41% ;
42% contains(_, node), !contained(node).
43%
44% error containmentCycle(node node) <->
45% contains+(node, node).