aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language/src/main/java/tools
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2024-05-17 17:13:21 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2024-05-26 17:22:31 +0200
commit378d97f41ab9bf1a3dc2136f340bb57d263ea474 (patch)
tree55e4002d0bfb00392f4ab9538f804ee241c9d84e /subprojects/language/src/main/java/tools
parentchore(deps): bump dependencies (diff)
downloadrefinery-378d97f41ab9bf1a3dc2136f340bb57d263ea474.tar.gz
refinery-378d97f41ab9bf1a3dc2136f340bb57d263ea474.tar.zst
refinery-378d97f41ab9bf1a3dc2136f340bb57d263ea474.zip
feat: rule parsing
Diffstat (limited to 'subprojects/language/src/main/java/tools')
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/Problem.xtext72
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java15
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java11
3 files changed, 55 insertions, 43 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 08f7a585..64998cd0 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
+++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
@@ -18,7 +18,7 @@ enum ModuleKind:
18Statement: 18Statement:
19 ImportStatement | Assertion | ClassDeclaration | EnumDeclaration | 19 ImportStatement | Assertion | ClassDeclaration | EnumDeclaration |
20 DatatypeDeclaration | AggregatorDeclaration | PredicateDefinition | 20 DatatypeDeclaration | AggregatorDeclaration | PredicateDefinition |
21 /* FunctionDefinition | RuleDefinition | */ 21 /* FunctionDefinition | */ RuleDefinition |
22 ScopeDeclaration | NodeDeclaration; 22 ScopeDeclaration | NodeDeclaration;
23 23
24ImportStatement: 24ImportStatement:
@@ -75,35 +75,40 @@ Conjunction:
75// 75//
76//Case: 76//Case:
77// Conjunction ({Match.condition=current} "->" value=Expr)?; 77// Conjunction ({Match.condition=current} "->" value=Expr)?;
78//RuleDefinition: 78
79// "rule" 79enum RuleKind:
80// name=Identifier 80 DECISION="decision" | PROPAGATION="propagation";
81// "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" 81
82// (":" preconditions+=Conjunction (";" preconditions+=Conjunction)*)? 82RuleDefinition:
83// "==>" consequents+=Consequent (";" consequents+=Consequent)*)? 83 kind=RuleKind? "rule"
84// "."; 84 name=Identifier
85 "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")"
86 (":" preconditions+=Conjunction (";" preconditions+=Conjunction)*)?
87 ("==>" consequents+=Consequent (";" consequents+=Consequent)*)?
88 ".";
89
90enum ParameterBinding:
91 FOCUS="&" | MULTI="*";
85 92
86Parameter: 93Parameter:
87 parameterType=[Relation|QualifiedName]? name=Identifier; 94 (
95 (concreteness=Concreteness? modality=Modality)?
96 parameterType=[Relation|QualifiedName]
97 )? binding=ParameterBinding? name=Identifier;
88 98
89//Consequent: 99Consequent:
90// actions+=Action ("," actions+=Action)*; 100 actions+=Action ("," actions+=Action)*;
91// 101
92//Action: 102Action:
93// AssertionAction | DeleteAction | NewAction; 103 AssertionAction;
94// 104
95//AssertionAction: 105AssertionAction:
96// value=ShortLogicValue? atom=Atom | 106 relation=[Relation|QualifiedName]
97// atom=Atom (overwrite?=":=" | "<:") value=LogicValue; 107 "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")"
98// 108 ":" value=Expr |
99//DeleteAction: 109 value=ShortLogicConstant
100// "delete" variableOrNode=[VariableOrNode|QualifiedName]; 110 relation=[Relation|QualifiedName]
101// 111 "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")";
102//NewAction:
103// "new" variable=NewVariable ("<:" parent=[VariableOrNode|QualifiedName])?;
104//
105//NewVariable:
106// name=Identifier;
107 112
108Expr: 113Expr:
109 AssignmentExpr; 114 AssignmentExpr;
@@ -159,7 +164,7 @@ RangeExpr returns Expr:
159 164
160UnaryExpr returns Expr: 165UnaryExpr returns Expr:
161 ArithmeticUnaryExpr | NegationExpr | 166 ArithmeticUnaryExpr | NegationExpr |
162 CountExpr | AggregationExpr | CastExpr; 167 CountExpr | AggregationExpr | ModalExpr | CastExpr;
163 168
164enum UnaryOp: 169enum UnaryOp:
165 PLUS="+" | MINUS="-"; 170 PLUS="+" | MINUS="-";
@@ -177,6 +182,15 @@ AggregationExpr:
177 aggregator=[AggregatorDeclaration|QualifiedName] 182 aggregator=[AggregatorDeclaration|QualifiedName]
178 "{" value=Expr "|" condition=ComparisonExpr "}"; 183 "{" value=Expr "|" condition=ComparisonExpr "}";
179 184
185enum Concreteness:
186 CANDIDATE="candidate";
187
188enum Modality:
189 MUST="must" | MAY="may";
190
191ModalExpr:
192 concreteness=Concreteness? modality=Modality body=UnaryExpr;
193
180CastExpr returns Expr: 194CastExpr returns Expr:
181 CastExprBody ({CastExpr.body=current} "as" targetType=[Relation|QualifiedName])?; 195 CastExprBody ({CastExpr.body=current} "as" targetType=[Relation|QualifiedName])?;
182 196
@@ -281,7 +295,7 @@ Identifier:
281 295
282NonContainmentIdentifier: 296NonContainmentIdentifier:
283 ID | "atom" | "multi" | "contained" | "problem" | "module" | 297 ID | "atom" | "multi" | "contained" | "problem" | "module" |
284 "datatype" | "aggregator"; 298 "datatype" | "aggregator" | "decision" | "propagation";
285 299
286Real returns ecore::EDouble: 300Real returns ecore::EDouble:
287 EXPONENTIAL | INT "." (INT | EXPONENTIAL); 301 EXPONENTIAL | INT "." (INT | EXPONENTIAL);
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 d94c9a13..21f64236 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
@@ -31,11 +31,11 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
31 public IScope getScope(EObject context, EReference reference) { 31 public IScope getScope(EObject context, EReference reference) {
32 var scope = super.getScope(context, reference); 32 var scope = super.getScope(context, reference);
33 if (reference == ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE) { 33 if (reference == ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE) {
34 return getNodesScope(context, scope); 34 // On the right side of a rule, assertion arguments may refer to variables.
35 var rule = EcoreUtil2.getContainerOfType(context, RuleDefinition.class);
36 return rule == null ? getNodesScope(context, scope) : getVariableScope(context, scope);
35 } 37 }
36 if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE 38 if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE) {
37 || reference == ProblemPackage.Literals.NEW_ACTION__PARENT
38 || reference == ProblemPackage.Literals.DELETE_ACTION__VARIABLE_OR_NODE) {
39 return getVariableScope(context, scope); 39 return getVariableScope(context, scope);
40 } 40 }
41 if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) { 41 if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) {
@@ -81,13 +81,6 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
81 switch (currentContext) { 81 switch (currentContext) {
82 case ExistentialQuantifier quantifier -> variables.addAll(quantifier.getImplicitVariables()); 82 case ExistentialQuantifier quantifier -> variables.addAll(quantifier.getImplicitVariables());
83 case Match match -> variables.addAll(match.getCondition().getImplicitVariables()); 83 case Match match -> variables.addAll(match.getCondition().getImplicitVariables());
84 case Consequent consequent -> {
85 for (var literal : consequent.getActions()) {
86 if (literal instanceof NewAction newAction && newAction.getVariable() != null) {
87 variables.add(newAction.getVariable());
88 }
89 }
90 }
91 default -> { 84 default -> {
92 // Nothing to add. 85 // Nothing to add.
93 } 86 }
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 745e2d2b..c49718ab 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
@@ -472,7 +472,10 @@ public class ProblemValidator extends AbstractProblemValidator {
472 return null; 472 return null;
473 } 473 }
474 if (argument instanceof NodeAssertionArgument nodeAssertionArgument) { 474 if (argument instanceof NodeAssertionArgument nodeAssertionArgument) {
475 return nodeAssertionArgument.getNode(); 475 var variableOrNode = nodeAssertionArgument.getNode();
476 if (variableOrNode == null || variableOrNode instanceof Node) {
477 return (Node) variableOrNode;
478 }
476 } 479 }
477 throw new IllegalArgumentException("Unknown assertion argument: " + argument); 480 throw new IllegalArgumentException("Unknown assertion argument: " + argument);
478 } 481 }
@@ -484,8 +487,10 @@ public class ProblemValidator extends AbstractProblemValidator {
484 } 487 }
485 for (var argument : assertion.getArguments()) { 488 for (var argument : assertion.getArguments()) {
486 if (argument instanceof NodeAssertionArgument nodeAssertionArgument) { 489 if (argument instanceof NodeAssertionArgument nodeAssertionArgument) {
487 var node = nodeAssertionArgument.getNode(); 490 var variableOrNode = nodeAssertionArgument.getNode();
488 if (node != null && !node.eIsProxy() && ProblemUtil.isImplicitNode(node)) { 491 if (variableOrNode instanceof Node node &&
492 !variableOrNode.eIsProxy() &&
493 ProblemUtil.isImplicitNode(node)) {
489 var name = node.getName(); 494 var name = node.getName();
490 var message = ("Implicit nodes are not allowed in modules. Explicitly declare '%s' as a node " + 495 var message = ("Implicit nodes are not allowed in modules. Explicitly declare '%s' as a node " +
491 "with the declaration 'declare %s.'").formatted(name, name); 496 "with the declaration 'declare %s.'").formatted(name, name);