diff options
author | 2021-10-13 20:59:35 +0200 | |
---|---|---|
committer | 2021-10-20 21:12:33 +0200 | |
commit | b98bb0df11fb8bc9748247da004321ab94e954c5 (patch) | |
tree | ff128c03cfa0a1459de4e928f78f150484fdd269 /language/src | |
parent | Add syntax for direct rules and direct predicates (diff) | |
download | refinery-b98bb0df11fb8bc9748247da004321ab94e954c5.tar.gz refinery-b98bb0df11fb8bc9748247da004321ab94e954c5.tar.zst refinery-b98bb0df11fb8bc9748247da004321ab94e954c5.zip |
Add scope for new and delete with tests
Diffstat (limited to 'language/src')
3 files changed, 124 insertions, 13 deletions
diff --git a/language/src/main/java/tools/refinery/language/resource/DerivedVariableComputer.java b/language/src/main/java/tools/refinery/language/resource/DerivedVariableComputer.java index 2061c30e..bb1226c4 100644 --- a/language/src/main/java/tools/refinery/language/resource/DerivedVariableComputer.java +++ b/language/src/main/java/tools/refinery/language/resource/DerivedVariableComputer.java | |||
@@ -24,11 +24,12 @@ import tools.refinery.language.model.problem.ImplicitVariable; | |||
24 | import tools.refinery.language.model.problem.Literal; | 24 | import tools.refinery.language.model.problem.Literal; |
25 | import tools.refinery.language.model.problem.NegativeLiteral; | 25 | import tools.refinery.language.model.problem.NegativeLiteral; |
26 | import tools.refinery.language.model.problem.Parameter; | 26 | import tools.refinery.language.model.problem.Parameter; |
27 | import tools.refinery.language.model.problem.PredicateDefinition; | 27 | import tools.refinery.language.model.problem.ParametricDefinition; |
28 | import tools.refinery.language.model.problem.Problem; | 28 | import tools.refinery.language.model.problem.Problem; |
29 | import tools.refinery.language.model.problem.ProblemFactory; | 29 | import tools.refinery.language.model.problem.ProblemFactory; |
30 | import tools.refinery.language.model.problem.ProblemPackage; | 30 | import tools.refinery.language.model.problem.ProblemPackage; |
31 | import tools.refinery.language.model.problem.Statement; | 31 | import tools.refinery.language.model.problem.Statement; |
32 | import tools.refinery.language.model.problem.ValueLiteral; | ||
32 | import tools.refinery.language.model.problem.VariableOrNodeArgument; | 33 | import tools.refinery.language.model.problem.VariableOrNodeArgument; |
33 | import tools.refinery.language.naming.NamingUtil; | 34 | import tools.refinery.language.naming.NamingUtil; |
34 | 35 | ||
@@ -46,13 +47,13 @@ public class DerivedVariableComputer { | |||
46 | 47 | ||
47 | public void installDerivedVariables(Problem problem, Set<String> nodeNames) { | 48 | public void installDerivedVariables(Problem problem, Set<String> nodeNames) { |
48 | for (Statement statement : problem.getStatements()) { | 49 | for (Statement statement : problem.getStatements()) { |
49 | if (statement instanceof PredicateDefinition definition) { | 50 | if (statement instanceof ParametricDefinition definition) { |
50 | installDerivedPredicateDefinitionState(definition, nodeNames); | 51 | installDerivedParametricDefinitionState(definition, nodeNames); |
51 | } | 52 | } |
52 | } | 53 | } |
53 | } | 54 | } |
54 | 55 | ||
55 | protected void installDerivedPredicateDefinitionState(PredicateDefinition definition, Set<String> nodeNames) { | 56 | protected void installDerivedParametricDefinitionState(ParametricDefinition definition, Set<String> nodeNames) { |
56 | Set<String> knownVariables = new HashSet<>(); | 57 | Set<String> knownVariables = new HashSet<>(); |
57 | knownVariables.addAll(nodeNames); | 58 | knownVariables.addAll(nodeNames); |
58 | for (Parameter parameter : definition.getParameters()) { | 59 | for (Parameter parameter : definition.getParameters()) { |
@@ -71,6 +72,9 @@ public class DerivedVariableComputer { | |||
71 | for (Literal literal : conjunction.getLiterals()) { | 72 | for (Literal literal : conjunction.getLiterals()) { |
72 | if (literal instanceof Atom atom) { | 73 | if (literal instanceof Atom atom) { |
73 | createSigletonVariablesAndCollectVariables(atom, knownVariables, newVariables); | 74 | createSigletonVariablesAndCollectVariables(atom, knownVariables, newVariables); |
75 | } else | ||
76 | if (literal instanceof ValueLiteral valueLiteral) { | ||
77 | createSigletonVariablesAndCollectVariables(valueLiteral.getAtom(), knownVariables, newVariables); | ||
74 | } | 78 | } |
75 | } | 79 | } |
76 | createVariables(conjunction, newVariables); | 80 | createVariables(conjunction, newVariables); |
@@ -156,13 +160,13 @@ public class DerivedVariableComputer { | |||
156 | 160 | ||
157 | public void discardDerivedVariables(Problem problem) { | 161 | public void discardDerivedVariables(Problem problem) { |
158 | for (Statement statement : problem.getStatements()) { | 162 | for (Statement statement : problem.getStatements()) { |
159 | if (statement instanceof PredicateDefinition predicateDefinition) { | 163 | if (statement instanceof ParametricDefinition parametricDefinition) { |
160 | discardPredicateDefinitionState(predicateDefinition); | 164 | discardParametricDefinitionState(parametricDefinition); |
161 | } | 165 | } |
162 | } | 166 | } |
163 | } | 167 | } |
164 | 168 | ||
165 | protected void discardPredicateDefinitionState(PredicateDefinition definition) { | 169 | protected void discardParametricDefinitionState(ParametricDefinition definition) { |
166 | for (Conjunction body : definition.getBodies()) { | 170 | for (Conjunction body : definition.getBodies()) { |
167 | body.getImplicitVariables().clear(); | 171 | body.getImplicitVariables().clear(); |
168 | for (Literal literal : body.getLiterals()) { | 172 | for (Literal literal : body.getLiterals()) { |
diff --git a/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java b/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java index 86b39dbc..d31a5308 100644 --- a/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java +++ b/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java | |||
@@ -15,7 +15,9 @@ import org.eclipse.xtext.scoping.Scopes; | |||
15 | import tools.refinery.language.model.ProblemUtil; | 15 | import tools.refinery.language.model.ProblemUtil; |
16 | import tools.refinery.language.model.problem.ClassDeclaration; | 16 | import tools.refinery.language.model.problem.ClassDeclaration; |
17 | import tools.refinery.language.model.problem.ExistentialQuantifier; | 17 | import tools.refinery.language.model.problem.ExistentialQuantifier; |
18 | import tools.refinery.language.model.problem.PredicateDefinition; | 18 | import tools.refinery.language.model.problem.NewActionLiteral; |
19 | import tools.refinery.language.model.problem.ParametricDefinition; | ||
20 | import tools.refinery.language.model.problem.Action; | ||
19 | import tools.refinery.language.model.problem.Problem; | 21 | import tools.refinery.language.model.problem.Problem; |
20 | import tools.refinery.language.model.problem.ProblemPackage; | 22 | import tools.refinery.language.model.problem.ProblemPackage; |
21 | import tools.refinery.language.model.problem.ReferenceDeclaration; | 23 | import tools.refinery.language.model.problem.ReferenceDeclaration; |
@@ -38,7 +40,8 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { | |||
38 | || reference == ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE) { | 40 | || reference == ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE) { |
39 | return getNodesScope(context, scope); | 41 | return getNodesScope(context, scope); |
40 | } | 42 | } |
41 | if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE) { | 43 | if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE |
44 | || reference == ProblemPackage.Literals.DELETE_ACTION_LITERAL__VARIABLE_OR_NODE) { | ||
42 | return getVariableScope(context, scope); | 45 | return getVariableScope(context, scope); |
43 | } | 46 | } |
44 | if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) { | 47 | if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) { |
@@ -64,17 +67,25 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { | |||
64 | variables.add(singletonVariable); | 67 | variables.add(singletonVariable); |
65 | } | 68 | } |
66 | } | 69 | } |
67 | while (currentContext != null && !(currentContext instanceof PredicateDefinition)) { | 70 | while (currentContext != null && !(currentContext instanceof ParametricDefinition)) { |
68 | if (currentContext instanceof ExistentialQuantifier quantifier) { | 71 | if (currentContext instanceof ExistentialQuantifier quantifier) { |
69 | variables.addAll(quantifier.getImplicitVariables()); | 72 | variables.addAll(quantifier.getImplicitVariables()); |
73 | } else | ||
74 | if(currentContext instanceof Action action) { | ||
75 | for (var literal : action.getActionLiterals()) { | ||
76 | if(literal instanceof NewActionLiteral newActionLiteral && newActionLiteral.getVariable() != null) { | ||
77 | variables.add(newActionLiteral.getVariable()); | ||
78 | } | ||
79 | } | ||
70 | } | 80 | } |
71 | currentContext = currentContext.eContainer(); | 81 | currentContext = currentContext.eContainer(); |
72 | } | 82 | } |
83 | IScope parentScope = getNodesScope(context, delegateScope); | ||
73 | if (currentContext != null) { | 84 | if (currentContext != null) { |
74 | PredicateDefinition definition = (PredicateDefinition) currentContext; | 85 | ParametricDefinition definition = (ParametricDefinition) currentContext; |
75 | variables.addAll(definition.getParameters()); | 86 | parentScope = Scopes.scopeFor(definition.getParameters(),parentScope); |
76 | } | 87 | } |
77 | return Scopes.scopeFor(variables, getNodesScope(context, delegateScope)); | 88 | return Scopes.scopeFor(variables,parentScope); |
78 | } | 89 | } |
79 | 90 | ||
80 | protected IScope getOppositeScope(EObject context, IScope delegateScope) { | 91 | protected IScope getOppositeScope(EObject context, IScope delegateScope) { |
diff --git a/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.xtend b/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.xtend new file mode 100644 index 00000000..d60651a0 --- /dev/null +++ b/language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.xtend | |||
@@ -0,0 +1,96 @@ | |||
1 | package tools.refinery.language.tests.rules | ||
2 | |||
3 | import com.google.inject.Inject | ||
4 | import org.eclipse.xtext.testing.InjectWith | ||
5 | import org.eclipse.xtext.testing.extensions.InjectionExtension | ||
6 | import org.eclipse.xtext.testing.util.ParseHelper | ||
7 | import org.junit.jupiter.api.Test | ||
8 | import org.junit.jupiter.api.^extension.ExtendWith | ||
9 | import tools.refinery.language.model.problem.Problem | ||
10 | import tools.refinery.language.tests.ProblemInjectorProvider | ||
11 | import tools.refinery.language.model.tests.ProblemTestUtil | ||
12 | |||
13 | import static org.hamcrest.MatcherAssert.assertThat | ||
14 | import static org.hamcrest.Matchers.* | ||
15 | |||
16 | @ExtendWith(InjectionExtension) | ||
17 | @InjectWith(ProblemInjectorProvider) | ||
18 | class DirectRuleParsingTest { | ||
19 | @Inject | ||
20 | ParseHelper<Problem> parseHelper | ||
21 | |||
22 | @Inject | ||
23 | extension ProblemTestUtil | ||
24 | |||
25 | @Test | ||
26 | def void relationValueRewriteTest() { | ||
27 | val it = parseHelper.parse(''' | ||
28 | pred Person(p). | ||
29 | direct rule r(p1): Person(p1) = true ~> Person(p1) = false. | ||
30 | ''') | ||
31 | assertThat(errors, empty) | ||
32 | } | ||
33 | |||
34 | @Test | ||
35 | def void relationValueMergeTest() { | ||
36 | val it = parseHelper.parse(''' | ||
37 | pred Person(p). | ||
38 | direct rule r(p1): Person(p1): true ~> Person(p1): false. | ||
39 | ''') | ||
40 | assertThat(errors, empty) | ||
41 | } | ||
42 | |||
43 | @Test | ||
44 | def void newNodeTest() { | ||
45 | val it = parseHelper.parse(''' | ||
46 | pred Person(p). | ||
47 | direct rule r(p1): Person(p1) = true ~> new p2, Person(p2) = unknown. | ||
48 | ''') | ||
49 | assertThat(errors, empty) | ||
50 | assertThat(rule("r").param(0), equalTo(rule("r").conj(0).lit(0).valueAtom.arg(0).variable)) | ||
51 | assertThat(rule("r").actionLit(0).newVar, | ||
52 | equalTo(rule("r").actionLit(1).valueAtom.arg(0).variable) | ||
53 | ) | ||
54 | } | ||
55 | |||
56 | @Test | ||
57 | def void differentScopeTest() { | ||
58 | val it = parseHelper.parse(''' | ||
59 | pred Friend(a, b). | ||
60 | direct rule r(p1): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true. | ||
61 | ''') | ||
62 | assertThat(errors, empty) | ||
63 | assertThat(rule("r").conj(0).lit(0).valueAtom.arg(1).variable, | ||
64 | not(equalTo(rule("r").actionLit(1).valueAtom.arg(1).variable))) | ||
65 | } | ||
66 | |||
67 | @Test | ||
68 | def void parameterShadowingTest() { | ||
69 | val it = parseHelper.parse(''' | ||
70 | pred Friend(a, b). | ||
71 | direct rule r(p1, p2): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true. | ||
72 | ''') | ||
73 | assertThat(errors, empty) | ||
74 | assertThat(rule("r").param(1), | ||
75 | not(equalTo(rule("r").actionLit(1).valueAtom.arg(1).variable))) | ||
76 | } | ||
77 | |||
78 | @Test | ||
79 | def void deleteParameterNodeTest() { | ||
80 | val it = parseHelper.parse(''' | ||
81 | pred Person(p). | ||
82 | direct rule r(p1): Person(p1): false ~> delete p1. | ||
83 | ''') | ||
84 | assertThat(errors, empty) | ||
85 | } | ||
86 | |||
87 | @Test | ||
88 | def void deleteDifferentScopeNodeTest() { | ||
89 | val it = parseHelper.parse(''' | ||
90 | pred Friend(p). | ||
91 | direct rule r(p1): Friend(p1, p2) = true ~> delete p2. | ||
92 | ''') | ||
93 | assertThat(errors, not(empty)) | ||
94 | } | ||
95 | |||
96 | } | ||