diff options
author | 2024-07-01 20:54:43 +0200 | |
---|---|---|
committer | 2024-07-01 20:54:43 +0200 | |
commit | a9e7d00503c7b7db79fd1dd4f71cc1724473e2aa (patch) | |
tree | c06ace162acef62766b86e39d22ccf2b8ca02e79 /subprojects/language/src/main/java/tools | |
parent | refactor(language): change computed value symbol (diff) | |
download | refinery-a9e7d00503c7b7db79fd1dd4f71cc1724473e2aa.tar.gz refinery-a9e7d00503c7b7db79fd1dd4f71cc1724473e2aa.tar.zst refinery-a9e7d00503c7b7db79fd1dd4f71cc1724473e2aa.zip |
refactor(language): shadow predicates instead of computed value operator
Diffstat (limited to 'subprojects/language/src/main/java/tools')
6 files changed, 71 insertions, 35 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 8d7d485b..cca94e66 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext +++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext | |||
@@ -58,6 +58,7 @@ ReferenceMultiplicity returns Multiplicity: | |||
58 | "[" Multiplicity "]"; | 58 | "[" Multiplicity "]"; |
59 | 59 | ||
60 | PredicateDefinition: | 60 | PredicateDefinition: |
61 | shadow?="shadow"? | ||
61 | ("pred" | error?="error" "pred"?) | 62 | ("pred" | error?="error" "pred"?) |
62 | name=Identifier | 63 | name=Identifier |
63 | "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" | 64 | "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" |
@@ -200,7 +201,6 @@ CastExprBody returns Expr: | |||
200 | 201 | ||
201 | Atom: | 202 | Atom: |
202 | relation=[Relation|QualifiedName] | 203 | relation=[Relation|QualifiedName] |
203 | computed?="$"? | ||
204 | transitiveClosure?=TRANSITIVE_CLOSURE? | 204 | transitiveClosure?=TRANSITIVE_CLOSURE? |
205 | "(" (arguments+=Expr ("," arguments+=Expr)*)? ")"; | 205 | "(" (arguments+=Expr ("," arguments+=Expr)*)? ")"; |
206 | 206 | ||
@@ -297,7 +297,7 @@ Identifier: | |||
297 | 297 | ||
298 | NonContainmentIdentifier: | 298 | NonContainmentIdentifier: |
299 | ID | "atom" | "multi" | "contained" | "problem" | "module" | | 299 | ID | "atom" | "multi" | "contained" | "problem" | "module" | |
300 | "datatype" | "aggregator" | "decision" | "propagation"; | 300 | "datatype" | "aggregator" | "decision" | "propagation" | "computed"; |
301 | 301 | ||
302 | Real returns ecore::EDouble: | 302 | Real returns ecore::EDouble: |
303 | EXPONENTIAL | INT "." (INT | EXPONENTIAL); | 303 | EXPONENTIAL | INT "." (INT | EXPONENTIAL); |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/ProblemTokenSource.java b/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/ProblemTokenSource.java index d47863da..487e4ceb 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/ProblemTokenSource.java +++ b/subprojects/language/src/main/java/tools/refinery/language/parser/antlr/ProblemTokenSource.java | |||
@@ -28,8 +28,6 @@ public class ProblemTokenSource implements TokenSource { | |||
28 | 28 | ||
29 | private boolean seenId; | 29 | private boolean seenId; |
30 | 30 | ||
31 | private boolean seenComputed; | ||
32 | |||
33 | private boolean lastVisible; | 31 | private boolean lastVisible; |
34 | 32 | ||
35 | public ProblemTokenSource(TokenSource delegate) { | 33 | public ProblemTokenSource(TokenSource delegate) { |
@@ -59,13 +57,10 @@ public class ProblemTokenSource implements TokenSource { | |||
59 | } else if (lastVisible && isQualifiedNameSeparator(token)) { | 57 | } else if (lastVisible && isQualifiedNameSeparator(token)) { |
60 | token.setType(InternalProblemParser.RULE_QUALIFIED_NAME_SEPARATOR); | 58 | token.setType(InternalProblemParser.RULE_QUALIFIED_NAME_SEPARATOR); |
61 | } | 59 | } |
62 | } else if (seenComputed && isPlusOrTransitiveClosure(token) && peekForTransitiveClosure()) { | ||
63 | token.setType(InternalProblemParser.RULE_TRANSITIVE_CLOSURE); | ||
64 | } | 60 | } |
65 | lastVisible = isVisibleToken(token); | 61 | lastVisible = isVisibleToken(token); |
66 | if (lastVisible) { | 62 | if (lastVisible) { |
67 | seenId = isIdentifier(token); | 63 | seenId = isIdentifier(token); |
68 | seenComputed = isComputed(token); | ||
69 | } | 64 | } |
70 | return token; | 65 | return token; |
71 | } | 66 | } |
@@ -87,10 +82,6 @@ public class ProblemTokenSource implements TokenSource { | |||
87 | return token.getType() == InternalProblemParser.ColonColon; | 82 | return token.getType() == InternalProblemParser.ColonColon; |
88 | } | 83 | } |
89 | 84 | ||
90 | protected boolean isComputed(Token token) { | ||
91 | return token.getType() == InternalProblemParser.DollarSign; | ||
92 | } | ||
93 | |||
94 | protected boolean isVisibleToken(Token token) { | 85 | protected boolean isVisibleToken(Token token) { |
95 | int tokenId = token.getType(); | 86 | int tokenId = token.getType(); |
96 | return tokenId != InternalProblemParser.RULE_WS && tokenId != InternalProblemParser.RULE_SL_COMMENT && | 87 | return tokenId != InternalProblemParser.RULE_WS && tokenId != InternalProblemParser.RULE_SL_COMMENT && |
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 cad98d50..8ebd34a5 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 | |||
@@ -46,8 +46,8 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti | |||
46 | public static final String MODULE_KIND = DATA_PREFIX + "MODULE_KIND"; | 46 | public static final String MODULE_KIND = DATA_PREFIX + "MODULE_KIND"; |
47 | public static final String COLOR_RELATION = DATA_PREFIX + "COLOR_RELATION"; | 47 | public static final String COLOR_RELATION = DATA_PREFIX + "COLOR_RELATION"; |
48 | public static final String COLOR_RELATION_TRUE = "true"; | 48 | public static final String COLOR_RELATION_TRUE = "true"; |
49 | public static final String COMPUTED_VALUE = DATA_PREFIX + "COMPUTED_VALUE"; | 49 | public static final String SHADOW_PREDICATE = DATA_PREFIX + "COMPUTED_VALUE"; |
50 | public static final String COMPUTED_VALUE_TRUE = "true"; | 50 | public static final String SHADOW_PREDICATE_TRUE = "true"; |
51 | 51 | ||
52 | @Inject | 52 | @Inject |
53 | private IQualifiedNameConverter qualifiedNameConverter; | 53 | private IQualifiedNameConverter qualifiedNameConverter; |
@@ -165,8 +165,8 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti | |||
165 | if (ProblemUtil.isError(eObject)) { | 165 | if (ProblemUtil.isError(eObject)) { |
166 | builder.put(ERROR_PREDICATE, ERROR_PREDICATE_TRUE); | 166 | builder.put(ERROR_PREDICATE, ERROR_PREDICATE_TRUE); |
167 | } | 167 | } |
168 | if (ProblemUtil.isComputedValue(eObject)) { | 168 | if (ProblemUtil.isShadow(eObject)) { |
169 | builder.put(COMPUTED_VALUE, COMPUTED_VALUE_TRUE); | 169 | builder.put(SHADOW_PREDICATE, SHADOW_PREDICATE_TRUE); |
170 | } | 170 | } |
171 | var documentationMap = documentationCommentParser.parseDocumentation(eObject); | 171 | var documentationMap = documentationCommentParser.parseDocumentation(eObject); |
172 | builder.putAll(documentationMap); | 172 | builder.putAll(documentationMap); |
@@ -178,7 +178,8 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti | |||
178 | return !ProblemUtil.isMultiNode(node); | 178 | return !ProblemUtil.isMultiNode(node); |
179 | } | 179 | } |
180 | if (eObject instanceof PredicateDefinition predicateDefinition) { | 180 | if (eObject instanceof PredicateDefinition predicateDefinition) { |
181 | return !ProblemUtil.isInvalidMultiplicityConstraint(predicateDefinition); | 181 | return !ProblemUtil.isInvalidMultiplicityConstraint(predicateDefinition) && |
182 | !ProblemUtil.isComputedValuePredicate(predicateDefinition); | ||
182 | } | 183 | } |
183 | return true; | 184 | return true; |
184 | } | 185 | } |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/state/ProblemDerivedStateComputer.java b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ProblemDerivedStateComputer.java index efa77c50..6b9b76d1 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/state/ProblemDerivedStateComputer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ProblemDerivedStateComputer.java | |||
@@ -22,6 +22,7 @@ import tools.refinery.language.utils.ProblemUtil; | |||
22 | 22 | ||
23 | import java.util.*; | 23 | import java.util.*; |
24 | import java.util.function.Function; | 24 | import java.util.function.Function; |
25 | import java.util.function.UnaryOperator; | ||
25 | 26 | ||
26 | @Singleton | 27 | @Singleton |
27 | public class ProblemDerivedStateComputer implements IDerivedStateComputer { | 28 | public class ProblemDerivedStateComputer implements IDerivedStateComputer { |
@@ -59,7 +60,7 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
59 | } | 60 | } |
60 | 61 | ||
61 | protected void installDerivedProblemState(Problem problem, Adapter adapter, boolean preLinkingPhase) { | 62 | protected void installDerivedProblemState(Problem problem, Adapter adapter, boolean preLinkingPhase) { |
62 | installDerivedClassDeclarationState(problem, adapter); | 63 | installDerivedDeclarationState(problem, adapter); |
63 | if (preLinkingPhase) { | 64 | if (preLinkingPhase) { |
64 | return; | 65 | return; |
65 | } | 66 | } |
@@ -67,13 +68,15 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
67 | derivedVariableComputer.installDerivedVariables(problem, nodeNames); | 68 | derivedVariableComputer.installDerivedVariables(problem, nodeNames); |
68 | } | 69 | } |
69 | 70 | ||
70 | protected void installDerivedClassDeclarationState(Problem problem, Adapter adapter) { | 71 | protected void installDerivedDeclarationState(Problem problem, Adapter adapter) { |
71 | for (var statement : problem.getStatements()) { | 72 | for (var statement : problem.getStatements()) { |
72 | if (statement instanceof ClassDeclaration classDeclaration) { | 73 | if (statement instanceof ClassDeclaration classDeclaration) { |
73 | installOrRemoveNewNode(adapter, classDeclaration); | 74 | installOrRemoveNewNode(adapter, classDeclaration); |
74 | for (var referenceDeclaration : classDeclaration.getFeatureDeclarations()) { | 75 | for (var referenceDeclaration : classDeclaration.getFeatureDeclarations()) { |
75 | installOrRemoveInvalidMultiplicityPredicate(adapter, classDeclaration, referenceDeclaration); | 76 | installOrRemoveInvalidMultiplicityPredicate(adapter, classDeclaration, referenceDeclaration); |
76 | } | 77 | } |
78 | } else if (statement instanceof PredicateDefinition predicateDefinition) { | ||
79 | installOrRemoveComputedValuePredicate(adapter, predicateDefinition); | ||
77 | } | 80 | } |
78 | } | 81 | } |
79 | } | 82 | } |
@@ -118,6 +121,27 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
118 | } | 121 | } |
119 | } | 122 | } |
120 | 123 | ||
124 | protected void installOrRemoveComputedValuePredicate(Adapter adapter, PredicateDefinition predicateDefinition) { | ||
125 | if (ProblemUtil.hasComputedValue(predicateDefinition)) { | ||
126 | var computedValue = adapter.createComputedValuePredicateIfAbsent(predicateDefinition, key -> { | ||
127 | var predicate = ProblemFactory.eINSTANCE.createPredicateDefinition(); | ||
128 | predicate.setShadow(true); | ||
129 | predicate.setName("definition"); | ||
130 | return predicate; | ||
131 | }); | ||
132 | var parameters = computedValue.getParameters(); | ||
133 | parameters.clear(); | ||
134 | parameters.addAll(EcoreUtil.copyAll(predicateDefinition.getParameters())); | ||
135 | predicateDefinition.setComputedValue(computedValue); | ||
136 | } else { | ||
137 | var computedValue = predicateDefinition.getComputedValue(); | ||
138 | if (computedValue != null) { | ||
139 | predicateDefinition.setComputedValue(null); | ||
140 | adapter.removeComputedValuePredicate(computedValue); | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | |||
121 | protected Set<String> installDerivedNodes(Problem problem) { | 145 | protected Set<String> installDerivedNodes(Problem problem) { |
122 | var collector = nodeNameCollectorProvider.get(); | 146 | var collector = nodeNameCollectorProvider.get(); |
123 | collector.collectNodeNames(problem); | 147 | collector.collectNodeNames(problem); |
@@ -148,6 +172,7 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
148 | protected void discardDerivedProblemState(Problem problem, Adapter adapter) { | 172 | protected void discardDerivedProblemState(Problem problem, Adapter adapter) { |
149 | var abstractClassDeclarations = new HashSet<ClassDeclaration>(); | 173 | var abstractClassDeclarations = new HashSet<ClassDeclaration>(); |
150 | var referenceDeclarationsWithMultiplicity = new HashSet<ReferenceDeclaration>(); | 174 | var referenceDeclarationsWithMultiplicity = new HashSet<ReferenceDeclaration>(); |
175 | var predicateDefinitionsWithComputedValue = new HashSet<PredicateDefinition>(); | ||
151 | problem.getNodes().clear(); | 176 | problem.getNodes().clear(); |
152 | for (var statement : problem.getStatements()) { | 177 | for (var statement : problem.getStatements()) { |
153 | if (statement instanceof ClassDeclaration classDeclaration) { | 178 | if (statement instanceof ClassDeclaration classDeclaration) { |
@@ -160,9 +185,13 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
160 | referenceDeclarationsWithMultiplicity.add(referenceDeclaration); | 185 | referenceDeclarationsWithMultiplicity.add(referenceDeclaration); |
161 | } | 186 | } |
162 | } | 187 | } |
188 | } else if (statement instanceof PredicateDefinition predicateDefinition && | ||
189 | ProblemUtil.hasComputedValue(predicateDefinition)) { | ||
190 | predicateDefinitionsWithComputedValue.add(predicateDefinition); | ||
163 | } | 191 | } |
164 | } | 192 | } |
165 | adapter.retainAll(abstractClassDeclarations, referenceDeclarationsWithMultiplicity); | 193 | adapter.retainAll(abstractClassDeclarations, referenceDeclarationsWithMultiplicity, |
194 | predicateDefinitionsWithComputedValue); | ||
166 | derivedVariableComputer.discardDerivedVariables(problem); | 195 | derivedVariableComputer.discardDerivedVariables(problem); |
167 | } | 196 | } |
168 | 197 | ||
@@ -185,6 +214,7 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
185 | protected static class Adapter extends AdapterImpl { | 214 | protected static class Adapter extends AdapterImpl { |
186 | private final Map<ClassDeclaration, Node> newNodes = new HashMap<>(); | 215 | private final Map<ClassDeclaration, Node> newNodes = new HashMap<>(); |
187 | private final Map<ReferenceDeclaration, PredicateDefinition> invalidMultiplicityPredicates = new HashMap<>(); | 216 | private final Map<ReferenceDeclaration, PredicateDefinition> invalidMultiplicityPredicates = new HashMap<>(); |
217 | private final Map<PredicateDefinition, PredicateDefinition> computedValuePredicates = new HashMap<>(); | ||
188 | 218 | ||
189 | public Node createNewNodeIfAbsent(ClassDeclaration classDeclaration, | 219 | public Node createNewNodeIfAbsent(ClassDeclaration classDeclaration, |
190 | Function<ClassDeclaration, Node> createNode) { | 220 | Function<ClassDeclaration, Node> createNode) { |
@@ -205,10 +235,21 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
205 | invalidMultiplicityPredicates.remove(referenceDeclaration); | 235 | invalidMultiplicityPredicates.remove(referenceDeclaration); |
206 | } | 236 | } |
207 | 237 | ||
238 | public PredicateDefinition createComputedValuePredicateIfAbsent( | ||
239 | PredicateDefinition predicateDefinition, UnaryOperator<PredicateDefinition> createPredicate) { | ||
240 | return computedValuePredicates.computeIfAbsent(predicateDefinition, createPredicate); | ||
241 | } | ||
242 | |||
243 | public void removeComputedValuePredicate(PredicateDefinition predicateDefinition) { | ||
244 | computedValuePredicates.remove(predicateDefinition); | ||
245 | } | ||
246 | |||
208 | public void retainAll(Collection<ClassDeclaration> abstractClassDeclarations, | 247 | public void retainAll(Collection<ClassDeclaration> abstractClassDeclarations, |
209 | Collection<ReferenceDeclaration> referenceDeclarationsWithMultiplicity) { | 248 | Collection<ReferenceDeclaration> referenceDeclarationsWithMultiplicity, |
249 | Collection<PredicateDefinition> predicateDefinitionsWithComputedValue) { | ||
210 | newNodes.keySet().retainAll(abstractClassDeclarations); | 250 | newNodes.keySet().retainAll(abstractClassDeclarations); |
211 | invalidMultiplicityPredicates.keySet().retainAll(referenceDeclarationsWithMultiplicity); | 251 | invalidMultiplicityPredicates.keySet().retainAll(referenceDeclarationsWithMultiplicity); |
252 | computedValuePredicates.keySet().retainAll(predicateDefinitionsWithComputedValue); | ||
212 | } | 253 | } |
213 | 254 | ||
214 | @Override | 255 | @Override |
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 7e7de681..c2c19d74 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 | |||
@@ -53,8 +53,8 @@ public final class ProblemUtil { | |||
53 | return eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isError(); | 53 | return eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isError(); |
54 | } | 54 | } |
55 | 55 | ||
56 | public static boolean isComputedValue(EObject eObject) { | 56 | public static boolean isShadow(EObject eObject) { |
57 | return eObject instanceof PredicateDefinition predicateDefinition && !predicateDefinition.getBodies().isEmpty(); | 57 | return eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isShadow(); |
58 | } | 58 | } |
59 | 59 | ||
60 | public static boolean isAtomNode(Node node) { | 60 | public static boolean isAtomNode(Node node) { |
@@ -77,9 +77,12 @@ public final class ProblemUtil { | |||
77 | return node.eContainingFeature() == ProblemPackage.Literals.NODE_DECLARATION__NODES; | 77 | return node.eContainingFeature() == ProblemPackage.Literals.NODE_DECLARATION__NODES; |
78 | } | 78 | } |
79 | 79 | ||
80 | public static boolean isInvalidMultiplicityConstraint(PredicateDefinition predicateDefinition) { | 80 | public static boolean isInvalidMultiplicityConstraint(Relation relation) { |
81 | return predicateDefinition.eContainingFeature() == | 81 | return relation.eContainingFeature() == ProblemPackage.Literals.REFERENCE_DECLARATION__INVALID_MULTIPLICITY; |
82 | ProblemPackage.Literals.REFERENCE_DECLARATION__INVALID_MULTIPLICITY; | 82 | } |
83 | |||
84 | public static boolean isComputedValuePredicate(Relation relation) { | ||
85 | return relation.eContainingFeature() == ProblemPackage.Literals.PREDICATE_DEFINITION__COMPUTED_VALUE; | ||
83 | } | 86 | } |
84 | 87 | ||
85 | public static boolean hasMultiplicityConstraint(ReferenceDeclaration referenceDeclaration) { | 88 | public static boolean hasMultiplicityConstraint(ReferenceDeclaration referenceDeclaration) { |
@@ -100,6 +103,10 @@ public final class ProblemUtil { | |||
100 | return true; | 103 | return true; |
101 | } | 104 | } |
102 | 105 | ||
106 | public static boolean hasComputedValue(PredicateDefinition predicateDefinition) { | ||
107 | return !predicateDefinition.isShadow() && !predicateDefinition.getBodies().isEmpty(); | ||
108 | } | ||
109 | |||
103 | public static boolean isTypeLike(Relation relation) { | 110 | public static boolean isTypeLike(Relation relation) { |
104 | if (relation instanceof ClassDeclaration || relation instanceof EnumDeclaration || | 111 | if (relation instanceof ClassDeclaration || relation instanceof EnumDeclaration || |
105 | relation instanceof DatatypeDeclaration) { | 112 | relation instanceof DatatypeDeclaration) { |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java index 7114b693..58d86fa0 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java +++ b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java | |||
@@ -49,7 +49,7 @@ public class ProblemValidator extends AbstractProblemValidator { | |||
49 | public static final String INVALID_MODALITY_ISSUE = ISSUE_PREFIX + "INVALID_MODALITY"; | 49 | public static final String INVALID_MODALITY_ISSUE = ISSUE_PREFIX + "INVALID_MODALITY"; |
50 | public static final String INVALID_RULE_ISSUE = ISSUE_PREFIX + "INVALID_RULE"; | 50 | public static final String INVALID_RULE_ISSUE = ISSUE_PREFIX + "INVALID_RULE"; |
51 | public static final String INVALID_TRANSITIVE_CLOSURE_ISSUE = ISSUE_PREFIX + "INVALID_TRANSITIVE_CLOSURE"; | 51 | public static final String INVALID_TRANSITIVE_CLOSURE_ISSUE = ISSUE_PREFIX + "INVALID_TRANSITIVE_CLOSURE"; |
52 | public static final String INVALID_COMPUTED_VALUE_ISSUE = ISSUE_PREFIX + "INVALID_COMPUTED_VALUE"; | 52 | public static final String SHADOW_RELATION_ISSUE = ISSUE_PREFIX + "SHADOW_RELATION"; |
53 | public static final String UNSUPPORTED_ASSERTION_ISSUE = ISSUE_PREFIX + "UNSUPPORTED_ASSERTION"; | 53 | public static final String UNSUPPORTED_ASSERTION_ISSUE = ISSUE_PREFIX + "UNSUPPORTED_ASSERTION"; |
54 | public static final String UNKNOWN_EXPRESSION_ISSUE = ISSUE_PREFIX + "UNKNOWN_EXPRESSION"; | 54 | public static final String UNKNOWN_EXPRESSION_ISSUE = ISSUE_PREFIX + "UNKNOWN_EXPRESSION"; |
55 | public static final String INVALID_ASSIGNMENT_ISSUE = ISSUE_PREFIX + "INVALID_ASSIGNMENT"; | 55 | public static final String INVALID_ASSIGNMENT_ISSUE = ISSUE_PREFIX + "INVALID_ASSIGNMENT"; |
@@ -426,16 +426,12 @@ public class ProblemValidator extends AbstractProblemValidator { | |||
426 | acceptError(message, atom, ProblemPackage.Literals.ATOM__TRANSITIVE_CLOSURE, 0, | 426 | acceptError(message, atom, ProblemPackage.Literals.ATOM__TRANSITIVE_CLOSURE, 0, |
427 | INVALID_TRANSITIVE_CLOSURE_ISSUE); | 427 | INVALID_TRANSITIVE_CLOSURE_ISSUE); |
428 | } | 428 | } |
429 | if (atom.isComputed()) { | 429 | var target = atom.getRelation(); |
430 | var target = atom.getRelation(); | 430 | if (target != null && !target.eIsProxy() && ProblemUtil.isShadow(target)) { |
431 | if (target != null && !target.eIsProxy() && !ProblemUtil.isComputedValue(target)) { | ||
432 | var message = "Relation '%s' has no computed value.".formatted(target.getName()); | ||
433 | acceptError(message, atom, ProblemPackage.Literals.ATOM__COMPUTED, 0, INVALID_COMPUTED_VALUE_ISSUE); | ||
434 | } | ||
435 | var definitionContext = EcoreUtil2.getContainerOfType(atom, ParametricDefinition.class); | 431 | var definitionContext = EcoreUtil2.getContainerOfType(atom, ParametricDefinition.class); |
436 | if (!(definitionContext instanceof RuleDefinition)) { | 432 | if (!(definitionContext instanceof RuleDefinition)){ |
437 | var message = "Computed value references may only appear in rule definitions."; | 433 | var message = "Shadow relation '%s' may only appear in rule definitions.".formatted(target.getName()); |
438 | acceptError(message, atom, ProblemPackage.Literals.ATOM__COMPUTED, 0, INVALID_COMPUTED_VALUE_ISSUE); | 434 | acceptError(message, atom, ProblemPackage.Literals.ATOM__RELATION, 0, SHADOW_RELATION_ISSUE); |
439 | } | 435 | } |
440 | } | 436 | } |
441 | } | 437 | } |