aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2024-02-29 02:24:06 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2024-04-07 14:55:46 +0200
commit71fc54a96bf33dde7895ade0bd280887553125b0 (patch)
tree5b475f117ba9e999d9df8699d0bea77555e45bb5 /subprojects/language
parentfeat(query): left join for data variables (diff)
downloadrefinery-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')
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/Problem.xtext31
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/resource/state/DerivedVariableComputer.java19
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/resource/state/ImplicitVariableScope.java18
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java30
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
105Expr: 105Expr:
106 ComparisonExpr; 106 AssignmentExpr;
107
108AssignmentExpr returns Expr:
109 ComparisonExpr ({AssignmentExpr.left=current}"is" right=ComparisonExpr)*;
107 110
108enum ComparisonOp: 111enum 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
116enum LatticeOp returns BinaryOp: 119enum LatticeBinaryOp:
117 MEET="/\\" | JOIN="\\/"; 120 MEET="/\\" | JOIN="\\/";
118 121
119LatticeExpr returns Expr: 122LatticeExpr returns Expr:
120 RangeExpr ({ArithmeticBinaryExpr.left=current} 123 RangeExpr ({LatticeBinaryExpr.left=current}
121 op=LatticeOp right=RangeExpr)*; 124 op=LatticeBinaryOp right=RangeExpr)*;
122 125
123RangeExpr returns Expr: 126RangeExpr returns Expr:
124 AdditiveExpr ({RangeExpr.left=current} ".." right=AdditiveExpr)*; 127 AdditiveExpr ({RangeExpr.left=current} ".." ("*" | right=AdditiveExpr))* |
128 {RangeExpr} "*" ".." ("*" | right=AdditiveExpr);
125 129
126enum AdditiveOp returns BinaryOp: 130enum 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
147UnaryExpr returns Expr: 151UnaryExpr returns Expr:
148 ArithmeticUnaryExpr | ModalExpr | NegationExpr | CountExpr | AggregationExpr | 152 ArithmeticUnaryExpr | ModalExpr | NegationExpr |
149 Atom | VariableOrNodeExpr | Constant | "(" Expr ")"; 153 CountExpr | AggregationExpr | CastExpr;
150 154
151enum UnaryOp: 155enum 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
172AggregationExpr: 176AggregationExpr:
173 op=AggregationOp "{" value=Expr "|" condition=Expr "}"; 177 op=AggregationOp "{" value=Expr "|" condition=ComparisonExpr "}";
178
179CastExpr returns Expr:
180 CastExprBody ({CastExpr.body=current} "as" targetType=[Relation|QualifiedName])?;
181
182CastExprBody returns Expr:
183 Atom | VariableOrNodeExpr | Constant | "(" Expr ")";
174 184
175Atom: 185Atom:
176 relation=[Relation|QualifiedName] 186 relation=[Relation|QualifiedName]
@@ -181,7 +191,7 @@ VariableOrNodeExpr:
181 variableOrNode=[VariableOrNode|QualifiedName]; 191 variableOrNode=[VariableOrNode|QualifiedName];
182 192
183Constant: 193Constant:
184 RealConstant | IntConstant | InfConstant | StringConstant | LogicConstant; 194 RealConstant | IntConstant | StringConstant | LogicConstant;
185 195
186IntConstant: 196IntConstant:
187 intValue=INT; 197 intValue=INT;
@@ -189,9 +199,6 @@ IntConstant:
189RealConstant: 199RealConstant:
190 realValue=Real; 200 realValue=Real;
191 201
192InfConstant:
193 {InfConstant} "*";
194
195StringConstant: 202StringConstant:
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;
16import tools.refinery.language.model.problem.*; 16import tools.refinery.language.model.problem.*;
17import tools.refinery.language.naming.NamingUtil; 17import tools.refinery.language.naming.NamingUtil;
18 18
19import java.util.Deque; 19import java.util.*;
20import java.util.HashSet;
21import java.util.List;
22import java.util.Set;
23 20
24public class ImplicitVariableScope { 21public 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;
18import tools.refinery.language.model.problem.*; 18import tools.refinery.language.model.problem.*;
19import tools.refinery.language.utils.ProblemDesugarer; 19import tools.refinery.language.utils.ProblemDesugarer;
20 20
21import java.util.ArrayList; 21import java.util.Collection;
22import java.util.List; 22import 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}