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/resource/DerivedVariableComputer.java | 18 ++-- .../language/scoping/ProblemScopeProvider.java | 23 ++++-- .../tests/rules/DirectRuleParsingTest.xtend | 96 ++++++++++++++++++++++ 3 files changed, 124 insertions(+), 13 deletions(-) create mode 100644 language/src/test/java/tools/refinery/language/tests/rules/DirectRuleParsingTest.xtend (limited to 'language') 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-70-g09d2