From b98bb0df11fb8bc9748247da004321ab94e954c5 Mon Sep 17 00:00:00 2001
From: Garami Bence <85867500+garamibence@users.noreply.github.com>
Date: Wed, 13 Oct 2021 20:59:35 +0200
Subject: Add scope for new and delete with tests
---
language-model/problem.aird | 14 ++--
.../language/model/tests/ProblemTestUtil.java | 47 ++++++++++-
.../language/resource/DerivedVariableComputer.java | 18 ++--
.../language/scoping/ProblemScopeProvider.java | 23 ++++--
.../tests/rules/DirectRuleParsingTest.xtend | 96 ++++++++++++++++++++++
5 files changed, 176 insertions(+), 22 deletions(-)
create mode 100644 language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.xtend
diff --git a/language-model/problem.aird b/language-model/problem.aird
index 52f96061..c5652fe4 100644
--- a/language-model/problem.aird
+++ b/language-model/problem.aird
@@ -7,7 +7,7 @@
build/resources/main/model/problem.genmodel
-
+
@@ -765,8 +765,8 @@
-
-
+
+
@@ -1731,17 +1731,17 @@
-
+
-
+
-
+
-
+
diff --git a/language-model/src/testFixtures/java/tools/refinery/language/model/tests/ProblemTestUtil.java b/language-model/src/testFixtures/java/tools/refinery/language/model/tests/ProblemTestUtil.java
index b412ed1f..dadc5330 100644
--- a/language-model/src/testFixtures/java/tools/refinery/language/model/tests/ProblemTestUtil.java
+++ b/language-model/src/testFixtures/java/tools/refinery/language/model/tests/ProblemTestUtil.java
@@ -7,26 +7,33 @@ import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
import org.eclipse.emf.ecore.util.EcoreUtil;
import tools.refinery.language.model.ProblemUtil;
+import tools.refinery.language.model.problem.ActionLiteral;
import tools.refinery.language.model.problem.Argument;
import tools.refinery.language.model.problem.Assertion;
import tools.refinery.language.model.problem.AssertionArgument;
import tools.refinery.language.model.problem.Atom;
import tools.refinery.language.model.problem.ClassDeclaration;
import tools.refinery.language.model.problem.Conjunction;
+import tools.refinery.language.model.problem.DeleteActionLiteral;
import tools.refinery.language.model.problem.EnumDeclaration;
import tools.refinery.language.model.problem.Literal;
import tools.refinery.language.model.problem.NamedElement;
import tools.refinery.language.model.problem.NegativeLiteral;
+import tools.refinery.language.model.problem.NewActionLiteral;
import tools.refinery.language.model.problem.Node;
import tools.refinery.language.model.problem.NodeAssertionArgument;
import tools.refinery.language.model.problem.NodeValueAssertion;
import tools.refinery.language.model.problem.Parameter;
+import tools.refinery.language.model.problem.ParametricDefinition;
import tools.refinery.language.model.problem.PredicateDefinition;
import tools.refinery.language.model.problem.Problem;
import tools.refinery.language.model.problem.ReferenceDeclaration;
import tools.refinery.language.model.problem.Relation;
+import tools.refinery.language.model.problem.RuleDefinition;
import tools.refinery.language.model.problem.Statement;
import tools.refinery.language.model.problem.UniqueDeclaration;
+import tools.refinery.language.model.problem.ValueActionLiteral;
+import tools.refinery.language.model.problem.ValueLiteral;
import tools.refinery.language.model.problem.Variable;
import tools.refinery.language.model.problem.VariableOrNode;
import tools.refinery.language.model.problem.VariableOrNodeArgument;
@@ -49,17 +56,29 @@ public class ProblemTestUtil {
return namedStatementOfType(problem, PredicateDefinition.class, name);
}
- public Parameter param(PredicateDefinition definition, int i) {
+ public RuleDefinition rule(Problem problem, String name) {
+ return namedStatementOfType(problem, RuleDefinition.class, name);
+ }
+
+ public Parameter param(ParametricDefinition definition, int i) {
return definition.getParameters().get(i);
}
- public Conjunction conj(PredicateDefinition definition, int i) {
+ public Conjunction conj(ParametricDefinition definition, int i) {
return definition.getBodies().get(i);
}
public Literal lit(Conjunction conjunction, int i) {
return conjunction.getLiterals().get(i);
}
+
+ public ActionLiteral actionLit(RuleDefinition rule, int i) {
+ return rule.getAction().getActionLiterals().get(i);
+ }
+
+ public Atom valueAtom(Literal literal) {
+ return ((ValueLiteral) literal).getAtom();
+ }
public Atom negated(Literal literal) {
return ((NegativeLiteral) literal).getAtom();
@@ -85,6 +104,30 @@ public class ProblemTestUtil {
return (Variable) variableOrNode(argument);
}
+ public Variable variable(ValueActionLiteral valueActionLiteral, int i) {
+ return variable(arg(valueActionLiteral.getAtom(), i));
+ }
+
+ public Variable variable(NewActionLiteral newActionLiteral) {
+ return newActionLiteral.getVariable();
+ }
+
+ public VariableOrNode deleteVar(ActionLiteral actionLiteral) {
+ return ((DeleteActionLiteral) actionLiteral).getVariableOrNode();
+ }
+
+ public VariableOrNode newVar(ActionLiteral actionLiteral) {
+ return ((NewActionLiteral) actionLiteral).getVariable();
+ }
+
+ public Atom valueAtom(ActionLiteral actionLiteral) {
+ return ((ValueActionLiteral) actionLiteral).getAtom();
+ }
+
+ public Variable variable(DeleteActionLiteral deleteActionLiteral) {
+ return (Variable) deleteActionLiteral.getVariableOrNode();
+ }
+
public Node node(Argument argument) {
return (Node) variableOrNode(argument);
}
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;
import tools.refinery.language.model.problem.Literal;
import tools.refinery.language.model.problem.NegativeLiteral;
import tools.refinery.language.model.problem.Parameter;
-import tools.refinery.language.model.problem.PredicateDefinition;
+import tools.refinery.language.model.problem.ParametricDefinition;
import tools.refinery.language.model.problem.Problem;
import tools.refinery.language.model.problem.ProblemFactory;
import tools.refinery.language.model.problem.ProblemPackage;
import tools.refinery.language.model.problem.Statement;
+import tools.refinery.language.model.problem.ValueLiteral;
import tools.refinery.language.model.problem.VariableOrNodeArgument;
import tools.refinery.language.naming.NamingUtil;
@@ -46,13 +47,13 @@ public class DerivedVariableComputer {
public void installDerivedVariables(Problem problem, Set nodeNames) {
for (Statement statement : problem.getStatements()) {
- if (statement instanceof PredicateDefinition definition) {
- installDerivedPredicateDefinitionState(definition, nodeNames);
+ if (statement instanceof ParametricDefinition definition) {
+ installDerivedParametricDefinitionState(definition, nodeNames);
}
}
}
- protected void installDerivedPredicateDefinitionState(PredicateDefinition definition, Set nodeNames) {
+ protected void installDerivedParametricDefinitionState(ParametricDefinition definition, Set nodeNames) {
Set knownVariables = new HashSet<>();
knownVariables.addAll(nodeNames);
for (Parameter parameter : definition.getParameters()) {
@@ -71,6 +72,9 @@ public class DerivedVariableComputer {
for (Literal literal : conjunction.getLiterals()) {
if (literal instanceof Atom atom) {
createSigletonVariablesAndCollectVariables(atom, knownVariables, newVariables);
+ } else
+ if (literal instanceof ValueLiteral valueLiteral) {
+ createSigletonVariablesAndCollectVariables(valueLiteral.getAtom(), knownVariables, newVariables);
}
}
createVariables(conjunction, newVariables);
@@ -156,13 +160,13 @@ public class DerivedVariableComputer {
public void discardDerivedVariables(Problem problem) {
for (Statement statement : problem.getStatements()) {
- if (statement instanceof PredicateDefinition predicateDefinition) {
- discardPredicateDefinitionState(predicateDefinition);
+ if (statement instanceof ParametricDefinition parametricDefinition) {
+ discardParametricDefinitionState(parametricDefinition);
}
}
}
- protected void discardPredicateDefinitionState(PredicateDefinition definition) {
+ protected void discardParametricDefinitionState(ParametricDefinition definition) {
for (Conjunction body : definition.getBodies()) {
body.getImplicitVariables().clear();
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;
import tools.refinery.language.model.ProblemUtil;
import tools.refinery.language.model.problem.ClassDeclaration;
import tools.refinery.language.model.problem.ExistentialQuantifier;
-import tools.refinery.language.model.problem.PredicateDefinition;
+import tools.refinery.language.model.problem.NewActionLiteral;
+import tools.refinery.language.model.problem.ParametricDefinition;
+import tools.refinery.language.model.problem.Action;
import tools.refinery.language.model.problem.Problem;
import tools.refinery.language.model.problem.ProblemPackage;
import tools.refinery.language.model.problem.ReferenceDeclaration;
@@ -38,7 +40,8 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
|| reference == ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE) {
return getNodesScope(context, scope);
}
- if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE) {
+ if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE
+ || reference == ProblemPackage.Literals.DELETE_ACTION_LITERAL__VARIABLE_OR_NODE) {
return getVariableScope(context, scope);
}
if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) {
@@ -64,17 +67,25 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
variables.add(singletonVariable);
}
}
- while (currentContext != null && !(currentContext instanceof PredicateDefinition)) {
+ while (currentContext != null && !(currentContext instanceof ParametricDefinition)) {
if (currentContext instanceof ExistentialQuantifier quantifier) {
variables.addAll(quantifier.getImplicitVariables());
+ } else
+ if(currentContext instanceof Action action) {
+ for (var literal : action.getActionLiterals()) {
+ if(literal instanceof NewActionLiteral newActionLiteral && newActionLiteral.getVariable() != null) {
+ variables.add(newActionLiteral.getVariable());
+ }
+ }
}
currentContext = currentContext.eContainer();
}
+ IScope parentScope = getNodesScope(context, delegateScope);
if (currentContext != null) {
- PredicateDefinition definition = (PredicateDefinition) currentContext;
- variables.addAll(definition.getParameters());
+ ParametricDefinition definition = (ParametricDefinition) currentContext;
+ parentScope = Scopes.scopeFor(definition.getParameters(),parentScope);
}
- return Scopes.scopeFor(variables, getNodesScope(context, delegateScope));
+ return Scopes.scopeFor(variables,parentScope);
}
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 @@
+package tools.refinery.language.tests.rules
+
+import com.google.inject.Inject
+import org.eclipse.xtext.testing.InjectWith
+import org.eclipse.xtext.testing.extensions.InjectionExtension
+import org.eclipse.xtext.testing.util.ParseHelper
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.^extension.ExtendWith
+import tools.refinery.language.model.problem.Problem
+import tools.refinery.language.tests.ProblemInjectorProvider
+import tools.refinery.language.model.tests.ProblemTestUtil
+
+import static org.hamcrest.MatcherAssert.assertThat
+import static org.hamcrest.Matchers.*
+
+@ExtendWith(InjectionExtension)
+@InjectWith(ProblemInjectorProvider)
+class DirectRuleParsingTest {
+ @Inject
+ ParseHelper parseHelper
+
+ @Inject
+ extension ProblemTestUtil
+
+ @Test
+ def void relationValueRewriteTest() {
+ val it = parseHelper.parse('''
+ pred Person(p).
+ direct rule r(p1): Person(p1) = true ~> Person(p1) = false.
+ ''')
+ assertThat(errors, empty)
+ }
+
+ @Test
+ def void relationValueMergeTest() {
+ val it = parseHelper.parse('''
+ pred Person(p).
+ direct rule r(p1): Person(p1): true ~> Person(p1): false.
+ ''')
+ assertThat(errors, empty)
+ }
+
+ @Test
+ def void newNodeTest() {
+ val it = parseHelper.parse('''
+ pred Person(p).
+ direct rule r(p1): Person(p1) = true ~> new p2, Person(p2) = unknown.
+ ''')
+ assertThat(errors, empty)
+ assertThat(rule("r").param(0), equalTo(rule("r").conj(0).lit(0).valueAtom.arg(0).variable))
+ assertThat(rule("r").actionLit(0).newVar,
+ equalTo(rule("r").actionLit(1).valueAtom.arg(0).variable)
+ )
+ }
+
+ @Test
+ def void differentScopeTest() {
+ val it = parseHelper.parse('''
+ pred Friend(a, b).
+ direct rule r(p1): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true.
+ ''')
+ assertThat(errors, empty)
+ assertThat(rule("r").conj(0).lit(0).valueAtom.arg(1).variable,
+ not(equalTo(rule("r").actionLit(1).valueAtom.arg(1).variable)))
+ }
+
+ @Test
+ def void parameterShadowingTest() {
+ val it = parseHelper.parse('''
+ pred Friend(a, b).
+ direct rule r(p1, p2): Friend(p1, p2) = false ~> new p2, Friend(p1, p2) = true.
+ ''')
+ assertThat(errors, empty)
+ assertThat(rule("r").param(1),
+ not(equalTo(rule("r").actionLit(1).valueAtom.arg(1).variable)))
+ }
+
+ @Test
+ def void deleteParameterNodeTest() {
+ val it = parseHelper.parse('''
+ pred Person(p).
+ direct rule r(p1): Person(p1): false ~> delete p1.
+ ''')
+ assertThat(errors, empty)
+ }
+
+ @Test
+ def void deleteDifferentScopeNodeTest() {
+ val it = parseHelper.parse('''
+ pred Friend(p).
+ direct rule r(p1): Friend(p1, p2) = true ~> delete p2.
+ ''')
+ assertThat(errors, not(empty))
+ }
+
+}
--
cgit v1.2.3-54-g00ecf