diff options
author | 2024-02-29 02:24:06 +0100 | |
---|---|---|
committer | 2024-04-07 14:55:46 +0200 | |
commit | 71fc54a96bf33dde7895ade0bd280887553125b0 (patch) | |
tree | 5b475f117ba9e999d9df8699d0bea77555e45bb5 /subprojects/language | |
parent | feat(query): left join for data variables (diff) | |
download | refinery-71fc54a96bf33dde7895ade0bd280887553125b0.tar.gz refinery-71fc54a96bf33dde7895ade0bd280887553125b0.tar.zst refinery-71fc54a96bf33dde7895ade0bd280887553125b0.zip |
refactor(language): assignment and cast expression
Also reorganizes operator names for easier future extension.
Diffstat (limited to 'subprojects/language')
4 files changed, 50 insertions, 48 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 a2fea627..43351d3e 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext +++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext | |||
@@ -103,7 +103,10 @@ Parameter: | |||
103 | // name=Identifier; | 103 | // name=Identifier; |
104 | 104 | ||
105 | Expr: | 105 | Expr: |
106 | ComparisonExpr; | 106 | AssignmentExpr; |
107 | |||
108 | AssignmentExpr returns Expr: | ||
109 | ComparisonExpr ({AssignmentExpr.left=current}"is" right=ComparisonExpr)*; | ||
107 | 110 | ||
108 | enum ComparisonOp: | 111 | enum ComparisonOp: |
109 | LESS="<" | LESS_EQ="<=" | GREATER=">" | GREATER_EQ=">=" | EQ="==" | NOT_EQ="!=" | | 112 | LESS="<" | LESS_EQ="<=" | GREATER=">" | GREATER_EQ=">=" | EQ="==" | NOT_EQ="!=" | |
@@ -113,15 +116,16 @@ ComparisonExpr returns Expr: | |||
113 | LatticeExpr ({ComparisonExpr.left=current} | 116 | LatticeExpr ({ComparisonExpr.left=current} |
114 | op=ComparisonOp right=LatticeExpr)*; | 117 | op=ComparisonOp right=LatticeExpr)*; |
115 | 118 | ||
116 | enum LatticeOp returns BinaryOp: | 119 | enum LatticeBinaryOp: |
117 | MEET="/\\" | JOIN="\\/"; | 120 | MEET="/\\" | JOIN="\\/"; |
118 | 121 | ||
119 | LatticeExpr returns Expr: | 122 | LatticeExpr returns Expr: |
120 | RangeExpr ({ArithmeticBinaryExpr.left=current} | 123 | RangeExpr ({LatticeBinaryExpr.left=current} |
121 | op=LatticeOp right=RangeExpr)*; | 124 | op=LatticeBinaryOp right=RangeExpr)*; |
122 | 125 | ||
123 | RangeExpr returns Expr: | 126 | RangeExpr returns Expr: |
124 | AdditiveExpr ({RangeExpr.left=current} ".." right=AdditiveExpr)*; | 127 | AdditiveExpr ({RangeExpr.left=current} ".." ("*" | right=AdditiveExpr))* | |
128 | {RangeExpr} "*" ".." ("*" | right=AdditiveExpr); | ||
125 | 129 | ||
126 | enum AdditiveOp returns BinaryOp: | 130 | enum AdditiveOp returns BinaryOp: |
127 | ADD="+" | SUB="-"; | 131 | ADD="+" | SUB="-"; |
@@ -145,8 +149,8 @@ ExponentialExpr returns Expr: | |||
145 | op=ExponentialOp right=ExponentialExpr)?; | 149 | op=ExponentialOp right=ExponentialExpr)?; |
146 | 150 | ||
147 | UnaryExpr returns Expr: | 151 | UnaryExpr returns Expr: |
148 | ArithmeticUnaryExpr | ModalExpr | NegationExpr | CountExpr | AggregationExpr | | 152 | ArithmeticUnaryExpr | ModalExpr | NegationExpr | |
149 | Atom | VariableOrNodeExpr | Constant | "(" Expr ")"; | 153 | CountExpr | AggregationExpr | CastExpr; |
150 | 154 | ||
151 | enum UnaryOp: | 155 | enum UnaryOp: |
152 | PLUS="+" | MINUS="-"; | 156 | PLUS="+" | MINUS="-"; |
@@ -170,7 +174,13 @@ enum AggregationOp: | |||
170 | SUM="sum" | PROD="prod" | MIN="min" | MAX="max"; | 174 | SUM="sum" | PROD="prod" | MIN="min" | MAX="max"; |
171 | 175 | ||
172 | AggregationExpr: | 176 | AggregationExpr: |
173 | op=AggregationOp "{" value=Expr "|" condition=Expr "}"; | 177 | op=AggregationOp "{" value=Expr "|" condition=ComparisonExpr "}"; |
178 | |||
179 | CastExpr returns Expr: | ||
180 | CastExprBody ({CastExpr.body=current} "as" targetType=[Relation|QualifiedName])?; | ||
181 | |||
182 | CastExprBody returns Expr: | ||
183 | Atom | VariableOrNodeExpr | Constant | "(" Expr ")"; | ||
174 | 184 | ||
175 | Atom: | 185 | Atom: |
176 | relation=[Relation|QualifiedName] | 186 | relation=[Relation|QualifiedName] |
@@ -181,7 +191,7 @@ VariableOrNodeExpr: | |||
181 | variableOrNode=[VariableOrNode|QualifiedName]; | 191 | variableOrNode=[VariableOrNode|QualifiedName]; |
182 | 192 | ||
183 | Constant: | 193 | Constant: |
184 | RealConstant | IntConstant | InfConstant | StringConstant | LogicConstant; | 194 | RealConstant | IntConstant | StringConstant | LogicConstant; |
185 | 195 | ||
186 | IntConstant: | 196 | IntConstant: |
187 | intValue=INT; | 197 | intValue=INT; |
@@ -189,9 +199,6 @@ IntConstant: | |||
189 | RealConstant: | 199 | RealConstant: |
190 | realValue=Real; | 200 | realValue=Real; |
191 | 201 | ||
192 | InfConstant: | ||
193 | {InfConstant} "*"; | ||
194 | |||
195 | StringConstant: | 202 | StringConstant: |
196 | stringValue=STRING; | 203 | stringValue=STRING; |
197 | 204 | ||
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/state/DerivedVariableComputer.java b/subprojects/language/src/main/java/tools/refinery/language/resource/state/DerivedVariableComputer.java index f0baf35f..f096264b 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/state/DerivedVariableComputer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/state/DerivedVariableComputer.java | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
@@ -44,15 +44,14 @@ public class DerivedVariableComputer { | |||
44 | knownVariables.add(name); | 44 | knownVariables.add(name); |
45 | } | 45 | } |
46 | } | 46 | } |
47 | if (definition instanceof PredicateDefinition predicateDefinition) { | 47 | switch (definition) { |
48 | installDerivedPredicateDefinitionState(predicateDefinition, knownVariables); | 48 | case PredicateDefinition predicateDefinition -> |
49 | } else if (definition instanceof FunctionDefinition functionDefinition) { | 49 | installDerivedPredicateDefinitionState(predicateDefinition, knownVariables); |
50 | installDerivedFunctionDefinitionState(functionDefinition, knownVariables); | 50 | case FunctionDefinition functionDefinition -> |
51 | } else if (definition instanceof RuleDefinition ruleDefinition) { | 51 | installDerivedFunctionDefinitionState(functionDefinition, knownVariables); |
52 | installDerivedRuleDefinitionState(ruleDefinition, knownVariables); | 52 | case RuleDefinition ruleDefinition -> installDerivedRuleDefinitionState(ruleDefinition, knownVariables); |
53 | } else { | 53 | default -> throw new IllegalArgumentException("Unknown ParametricDefinition: " + definition); |
54 | throw new IllegalArgumentException("Unknown ParametricDefinition: " + definition); | 54 | } |
55 | } | ||
56 | } | 55 | } |
57 | 56 | ||
58 | protected void installDerivedPredicateDefinitionState(PredicateDefinition definition, Set<String> knownVariables) { | 57 | protected void installDerivedPredicateDefinitionState(PredicateDefinition definition, Set<String> knownVariables) { |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/state/ImplicitVariableScope.java b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ImplicitVariableScope.java index e25887ad..c8e01724 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/state/ImplicitVariableScope.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/state/ImplicitVariableScope.java | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
@@ -16,10 +16,7 @@ import org.eclipse.xtext.scoping.IScopeProvider; | |||
16 | import tools.refinery.language.model.problem.*; | 16 | import tools.refinery.language.model.problem.*; |
17 | import tools.refinery.language.naming.NamingUtil; | 17 | import tools.refinery.language.naming.NamingUtil; |
18 | 18 | ||
19 | import java.util.Deque; | 19 | import java.util.*; |
20 | import java.util.HashSet; | ||
21 | import java.util.List; | ||
22 | import java.util.Set; | ||
23 | 20 | ||
24 | public class ImplicitVariableScope { | 21 | public class ImplicitVariableScope { |
25 | private final EObject root; | 22 | private final EObject root; |
@@ -71,13 +68,12 @@ public class ImplicitVariableScope { | |||
71 | if ((hasKnownVariables && hasParent) || (!hasKnownVariables && !hasParent)) { | 68 | if ((hasKnownVariables && hasParent) || (!hasKnownVariables && !hasParent)) { |
72 | throw new IllegalStateException("Either known variables or parent must be provided, but not both"); | 69 | throw new IllegalStateException("Either known variables or parent must be provided, but not both"); |
73 | } | 70 | } |
74 | if (hasKnownVariables) { | 71 | if (!hasKnownVariables) { |
75 | return; | 72 | if (parent.knownVariables == null) { |
76 | } | 73 | throw new IllegalStateException("Parent scope must be processed before current scope"); |
77 | if (parent.knownVariables == null) { | 74 | } |
78 | throw new IllegalStateException("Parent scope must be processed before current scope"); | 75 | knownVariables = new HashSet<>(parent.knownVariables); |
79 | } | 76 | } |
80 | knownVariables = new HashSet<>(parent.knownVariables); | ||
81 | } | 77 | } |
82 | 78 | ||
83 | private void processEObject(EObject eObject, IScopeProvider scopeProvider, LinkingHelper linkingHelper, | 79 | private void processEObject(EObject eObject, IScopeProvider scopeProvider, LinkingHelper linkingHelper, |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java index a4437ba6..f83a7ebd 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java +++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | 2 | * SPDX-FileCopyrightText: 2021-2024 The Refinery Authors <https://refinery.tools/> |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: EPL-2.0 | 4 | * SPDX-License-Identifier: EPL-2.0 |
5 | */ | 5 | */ |
@@ -18,8 +18,8 @@ import org.eclipse.xtext.scoping.Scopes; | |||
18 | import tools.refinery.language.model.problem.*; | 18 | import tools.refinery.language.model.problem.*; |
19 | import tools.refinery.language.utils.ProblemDesugarer; | 19 | import tools.refinery.language.utils.ProblemDesugarer; |
20 | 20 | ||
21 | import java.util.ArrayList; | 21 | import java.util.Collection; |
22 | import java.util.List; | 22 | import java.util.LinkedHashSet; |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * This class contains custom scoping description. | 25 | * This class contains custom scoping description. |
@@ -58,7 +58,7 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { | |||
58 | } | 58 | } |
59 | 59 | ||
60 | protected IScope getVariableScope(EObject context, IScope delegateScope) { | 60 | protected IScope getVariableScope(EObject context, IScope delegateScope) { |
61 | List<Variable> variables = new ArrayList<>(); | 61 | Collection<Variable> variables = new LinkedHashSet<>(); |
62 | addSingletonVariableToScope(context, variables); | 62 | addSingletonVariableToScope(context, variables); |
63 | EObject currentContext = context; | 63 | EObject currentContext = context; |
64 | while (currentContext != null && !(currentContext instanceof ParametricDefinition)) { | 64 | while (currentContext != null && !(currentContext instanceof ParametricDefinition)) { |
@@ -73,7 +73,7 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { | |||
73 | return Scopes.scopeFor(variables, parentScope); | 73 | return Scopes.scopeFor(variables, parentScope); |
74 | } | 74 | } |
75 | 75 | ||
76 | protected void addSingletonVariableToScope(EObject context, List<Variable> variables) { | 76 | protected void addSingletonVariableToScope(EObject context, Collection<Variable> variables) { |
77 | if (context instanceof VariableOrNodeExpr expr) { | 77 | if (context instanceof VariableOrNodeExpr expr) { |
78 | Variable singletonVariable = expr.getSingletonVariable(); | 78 | Variable singletonVariable = expr.getSingletonVariable(); |
79 | if (singletonVariable != null) { | 79 | if (singletonVariable != null) { |
@@ -82,18 +82,21 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { | |||
82 | } | 82 | } |
83 | } | 83 | } |
84 | 84 | ||
85 | protected void addExistentiallyQualifiedVariableToScope(EObject currentContext, List<Variable> variables) { | 85 | protected void addExistentiallyQualifiedVariableToScope(EObject currentContext, Collection<Variable> variables) { |
86 | if (currentContext instanceof ExistentialQuantifier quantifier) { | 86 | switch (currentContext) { |
87 | variables.addAll(quantifier.getImplicitVariables()); | 87 | case ExistentialQuantifier quantifier -> variables.addAll(quantifier.getImplicitVariables()); |
88 | } else if (currentContext instanceof Match match) { | 88 | case Match match -> variables.addAll(match.getCondition().getImplicitVariables()); |
89 | variables.addAll(match.getCondition().getImplicitVariables()); | 89 | case Consequent consequent -> { |
90 | } else if (currentContext instanceof Consequent consequent) { | ||
91 | for (var literal : consequent.getActions()) { | 90 | for (var literal : consequent.getActions()) { |
92 | if (literal instanceof NewAction newAction && newAction.getVariable() != null) { | 91 | if (literal instanceof NewAction newAction && newAction.getVariable() != null) { |
93 | variables.add(newAction.getVariable()); | 92 | variables.add(newAction.getVariable()); |
94 | } | 93 | } |
95 | } | 94 | } |
96 | } | 95 | } |
96 | default -> { | ||
97 | // Nothing to add. | ||
98 | } | ||
99 | } | ||
97 | } | 100 | } |
98 | 101 | ||
99 | protected IScope getOppositeScope(EObject context) { | 102 | protected IScope getOppositeScope(EObject context) { |
@@ -105,10 +108,7 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { | |||
105 | if (!(relation instanceof ClassDeclaration classDeclaration)) { | 108 | if (!(relation instanceof ClassDeclaration classDeclaration)) { |
106 | return IScope.NULLSCOPE; | 109 | return IScope.NULLSCOPE; |
107 | } | 110 | } |
108 | var referenceDeclarations = classDeclaration.getFeatureDeclarations() | 111 | var referenceDeclarations = classDeclaration.getFeatureDeclarations(); |
109 | .stream() | ||
110 | .filter(ReferenceDeclaration.class::isInstance) | ||
111 | .toList(); | ||
112 | return Scopes.scopeFor(referenceDeclarations); | 112 | return Scopes.scopeFor(referenceDeclarations); |
113 | } | 113 | } |
114 | } | 114 | } |