aboutsummaryrefslogtreecommitdiffstats
path: root/language/src/main/java/org/eclipse/viatra/solver
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-06-28 02:45:33 +0200
committerLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-06-28 02:47:34 +0200
commitb7db563dc425dbf90e42b1c69fb4d52c41a18503 (patch)
tree99bf06a66e6d63b9afda017f6f23266cac46def2 /language/src/main/java/org/eclipse/viatra/solver
parentAdd data constant support (diff)
downloadrefinery-b7db563dc425dbf90e42b1c69fb4d52c41a18503.tar.gz
refinery-b7db563dc425dbf90e42b1c69fb4d52c41a18503.tar.zst
refinery-b7db563dc425dbf90e42b1c69fb4d52c41a18503.zip
Add scoping tests and simplify implicit nodes
* Do not export implicit nodes to the global scope * Enum literals must not be quoted * Plan for the future: unify quoted nodes from the global scope in post-processing
Diffstat (limited to 'language/src/main/java/org/eclipse/viatra/solver')
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe24
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/Problem.xtext7
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.java30
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.xtend25
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java36
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java94
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java18
7 files changed, 122 insertions, 92 deletions
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2 b/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2
index a63681c8..da5e95a4 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2
@@ -43,9 +43,7 @@ Workflow {
43 validator = { 43 validator = {
44 generateDeprecationValidation = true 44 generateDeprecationValidation = true
45 } 45 }
46 generator = { 46 generator = null
47 generateXtendStub = true
48 }
49 junitSupport = { 47 junitSupport = {
50 junitVersion = "5" 48 junitVersion = "5"
51 } 49 }
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/Problem.xtext b/language/src/main/java/org/eclipse/viatra/solver/language/Problem.xtext
index 7e253ef5..495f50e4 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/Problem.xtext
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/Problem.xtext
@@ -22,7 +22,7 @@ EnumDeclaration:
22 ("{" (literals+=EnumLiteral ("," literals+=EnumLiteral)* ("," | ";")?)? "}" | "."); 22 ("{" (literals+=EnumLiteral ("," literals+=EnumLiteral)* ("," | ";")?)? "}" | ".");
23 23
24EnumLiteral returns Node: 24EnumLiteral returns Node:
25 name=QuotedOrUnquotedId; 25 name=Identifier;
26 26
27ReferenceDeclaration: 27ReferenceDeclaration:
28 (containment?="contains" | "refers")? 28 (containment?="contains" | "refers")?
@@ -129,11 +129,8 @@ ExactMultiplicity:
129UpperBound returns ecore::EInt: 129UpperBound returns ecore::EInt:
130 INT | "*"; 130 INT | "*";
131 131
132QuotedOrUnquotedId:
133 QUOTED_ID | Identifier;
134
135QualifiedName hidden(): 132QualifiedName hidden():
136 QUOTED_ID | Identifier ("::" Identifier)* ("::" QUOTED_ID)?; 133 QUOTED_ID | Identifier ("::" Identifier)*;
137 134
138Identifier: 135Identifier:
139 ID | "true" | "false" | "e" | "E"; 136 ID | "true" | "false" | "e" | "E";
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.java b/language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.java
new file mode 100644
index 00000000..b6ea3553
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.java
@@ -0,0 +1,30 @@
1/*
2 * generated by Xtext 2.26.0.M1
3 */
4package org.eclipse.viatra.solver.language.generator;
5
6import org.eclipse.emf.ecore.resource.Resource;
7import org.eclipse.xtext.generator.AbstractGenerator;
8import org.eclipse.xtext.generator.IFileSystemAccess2;
9import org.eclipse.xtext.generator.IGeneratorContext;
10
11/**
12 * Generates code from your model files on save.
13 *
14 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
15 */
16public class ProblemGenerator extends AbstractGenerator {
17
18 @Override
19 public void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
20// Iterator<Greeting> filtered = Iterators.filter(resource.getAllContents(), Greeting.class);
21// Iterator<String> names = Iterators.transform(filtered, new Function<Greeting, String>() {
22//
23// @Override
24// public String apply(Greeting greeting) {
25// return greeting.getName();
26// }
27// });
28// fsa.generateFile("greetings.txt", "People to greet: " + IteratorExtensions.join(names, ", "));
29 }
30}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.xtend b/language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.xtend
deleted file mode 100644
index 0930f244..00000000
--- a/language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.xtend
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * generated by Xtext 2.25.0
3 */
4package org.eclipse.viatra.solver.language.generator
5
6import org.eclipse.emf.ecore.resource.Resource
7import org.eclipse.xtext.generator.AbstractGenerator
8import org.eclipse.xtext.generator.IFileSystemAccess2
9import org.eclipse.xtext.generator.IGeneratorContext
10
11/**
12 * Generates code from your model files on save.
13 *
14 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
15 */
16class ProblemGenerator extends AbstractGenerator {
17
18 override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
19// fsa.generateFile('greetings.txt', 'People to greet: ' +
20// resource.allContents
21// .filter(Greeting)
22// .map[name]
23// .join(', '))
24 }
25}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java
index fc03fa87..56d8ad71 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java
@@ -73,13 +73,14 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
73 73
74 protected void installDerivedProblemState(Problem problem, boolean preLinkingPhase) { 74 protected void installDerivedProblemState(Problem problem, boolean preLinkingPhase) {
75 installNewNodes(problem); 75 installNewNodes(problem);
76 if (!preLinkingPhase) { 76 if (preLinkingPhase) {
77 installDerivedNodes(problem); 77 return;
78 for (Statement statement : problem.getStatements()) { 78 }
79 if (statement instanceof PredicateDefinition) { 79 Set<String> nodeNames = installDerivedNodes(problem);
80 PredicateDefinition definition = (PredicateDefinition) statement; 80 for (Statement statement : problem.getStatements()) {
81 installDerivedPredicateDefinitionState(definition); 81 if (statement instanceof PredicateDefinition) {
82 } 82 PredicateDefinition definition = (PredicateDefinition) statement;
83 installDerivedPredicateDefinitionState(definition, nodeNames);
83 } 84 }
84 } 85 }
85 } 86 }
@@ -88,7 +89,7 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
88 for (Statement statement : problem.getStatements()) { 89 for (Statement statement : problem.getStatements()) {
89 if (statement instanceof ClassDeclaration) { 90 if (statement instanceof ClassDeclaration) {
90 ClassDeclaration declaration = (ClassDeclaration) statement; 91 ClassDeclaration declaration = (ClassDeclaration) statement;
91 if (!declaration.isAbstract()) { 92 if (!declaration.isAbstract() && declaration.getNewNode() == null) {
92 Node newNode = createNode(NEW_NODE); 93 Node newNode = createNode(NEW_NODE);
93 declaration.setNewNode(newNode); 94 declaration.setNewNode(newNode);
94 } 95 }
@@ -96,7 +97,7 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
96 } 97 }
97 } 98 }
98 99
99 protected void installDerivedNodes(Problem problem) { 100 protected Set<String> installDerivedNodes(Problem problem) {
100 IScope nodeScope = scopeProvider.getScope(problem, ProblemPackage.Literals.ASSERTION__ARGUMENTS); 101 IScope nodeScope = scopeProvider.getScope(problem, ProblemPackage.Literals.ASSERTION__ARGUMENTS);
101 Set<String> nodeNames = new HashSet<>(); 102 Set<String> nodeNames = new HashSet<>();
102 for (Statement statement : problem.getStatements()) { 103 for (Statement statement : problem.getStatements()) {
@@ -142,6 +143,7 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
142 Node graphNode = createNode(nodeName); 143 Node graphNode = createNode(nodeName);
143 grapNodes.add(graphNode); 144 grapNodes.add(graphNode);
144 } 145 }
146 return nodeNames;
145 } 147 }
146 148
147 private void addNodeNames(Set<String> nodeNames, IScope nodeScope, EObject eObject, EStructuralFeature feature, 149 private void addNodeNames(Set<String> nodeNames, IScope nodeScope, EObject eObject, EStructuralFeature feature,
@@ -165,16 +167,17 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
165 return node; 167 return node;
166 } 168 }
167 169
168 protected void installDerivedPredicateDefinitionState(PredicateDefinition definition) { 170 protected void installDerivedPredicateDefinitionState(PredicateDefinition definition, Set<String> nodeNames) {
169 Set<String> parameterNames = new HashSet<>(); 171 Set<String> knownVariables = new HashSet<>();
172 knownVariables.addAll(nodeNames);
170 for (Parameter parameter : definition.getParameters()) { 173 for (Parameter parameter : definition.getParameters()) {
171 String name = parameter.getName(); 174 String name = parameter.getName();
172 if (name != null) { 175 if (name != null) {
173 parameterNames.add(name); 176 knownVariables.add(name);
174 } 177 }
175 } 178 }
176 for (Conjunction body : definition.getBodies()) { 179 for (Conjunction body : definition.getBodies()) {
177 installDeriveConjunctionState(body, parameterNames); 180 installDeriveConjunctionState(body, knownVariables);
178 } 181 }
179 } 182 }
180 183
@@ -271,10 +274,9 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer {
271 protected void discardDerivedProblemState(Problem problem) { 274 protected void discardDerivedProblemState(Problem problem) {
272 problem.getNodes().clear(); 275 problem.getNodes().clear();
273 for (Statement statement : problem.getStatements()) { 276 for (Statement statement : problem.getStatements()) {
274 if (statement instanceof ClassDeclaration) { 277 // We deliberately don't clean up {@link ClassDeclaration#getNewNode()} nodes,
275 ClassDeclaration classDeclaration = (ClassDeclaration) statement; 278 // because they have already been exported to the Xtext index.
276 classDeclaration.setNewNode(null); 279 if (statement instanceof PredicateDefinition) {
277 } else if (statement instanceof PredicateDefinition) {
278 PredicateDefinition definition = (PredicateDefinition) statement; 280 PredicateDefinition definition = (PredicateDefinition) statement;
279 for (Conjunction body : definition.getBodies()) { 281 for (Conjunction body : definition.getBodies()) {
280 body.getImplicitVariables().clear(); 282 body.getImplicitVariables().clear();
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java
index edb25a1c..4d932a92 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java
@@ -24,56 +24,70 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
24 24
25 @Override 25 @Override
26 public boolean createEObjectDescriptions(EObject eObject, IAcceptor<IEObjectDescription> acceptor) { 26 public boolean createEObjectDescriptions(EObject eObject, IAcceptor<IEObjectDescription> acceptor) {
27 if (eObject instanceof Variable) { 27 if (!shouldExport(eObject)) {
28 return false; 28 return false;
29 } 29 }
30 if (eObject instanceof NamedElement) { 30 if (!(eObject instanceof NamedElement)) {
31 NamedElement namedElement = (NamedElement) eObject; 31 return true;
32 String name = namedElement.getName(); 32 }
33 if (name == null || name.isEmpty()) { 33 NamedElement namedElement = (NamedElement) eObject;
34 return true; 34 String name = namedElement.getName();
35 } 35 if (name == null || name.isEmpty()) {
36 Problem problem = EcoreUtil2.getContainerOfType(namedElement, Problem.class); 36 return true;
37 QualifiedName problemQualifiedName = null; 37 }
38 if (problem != null) { 38 Problem problem = EcoreUtil2.getContainerOfType(namedElement, Problem.class);
39 String problemName = problem.getName(); 39 QualifiedName problemQualifiedName = null;
40 if (problemName != null && !problemName.isEmpty()) { 40 if (problem != null) {
41 problemQualifiedName = qualifiedNameConverter.toQualifiedName(problemName); 41 String problemName = problem.getName();
42 } 42 if (problemName != null && !problemName.isEmpty()) {
43 } 43 problemQualifiedName = qualifiedNameConverter.toQualifiedName(problemName);
44 QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(namedElement.getName());
45 boolean nameExported;
46 if (shouldExportSimpleName(namedElement)) {
47 acceptEObjectDescription(namedElement, problemQualifiedName, qualifiedName, acceptor);
48 nameExported = true;
49 } else {
50 nameExported = false;
51 } 44 }
52 EObject parent = namedElement.eContainer(); 45 }
53 while (parent != null && parent != problem) { 46 QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(namedElement.getName());
54 if (parent instanceof NamedElement) { 47 boolean nameExported;
55 NamedElement namedParent = (NamedElement) parent; 48 if (shouldExportSimpleName(namedElement)) {
56 String parentName = namedParent.getName(); 49 acceptEObjectDescription(namedElement, problemQualifiedName, qualifiedName, acceptor);
57 if (parentName != null || !name.isEmpty()) { 50 nameExported = true;
58 QualifiedName parentQualifiedName = qualifiedNameConverter.toQualifiedName(parentName); 51 } else {
59 qualifiedName = parentQualifiedName.append(qualifiedName); 52 nameExported = false;
60 if (shouldExportSimpleName(parent)) { 53 }
61 acceptEObjectDescription(namedElement, problemQualifiedName, qualifiedName, acceptor); 54 EObject parent = namedElement.eContainer();
62 nameExported = true; 55 while (parent != null && parent != problem) {
63 } else { 56 if (parent instanceof NamedElement) {
64 nameExported = false; 57 NamedElement namedParent = (NamedElement) parent;
65 } 58 String parentName = namedParent.getName();
59 if (parentName != null || !name.isEmpty()) {
60 QualifiedName parentQualifiedName = qualifiedNameConverter.toQualifiedName(parentName);
61 qualifiedName = parentQualifiedName.append(qualifiedName);
62 if (shouldExportSimpleName(namedParent)) {
63 acceptEObjectDescription(namedElement, problemQualifiedName, qualifiedName, acceptor);
64 nameExported = true;
65 } else {
66 nameExported = false;
66 } 67 }
67 } 68 }
68 parent = parent.eContainer();
69 }
70 if (!nameExported) {
71 acceptEObjectDescription(namedElement, problemQualifiedName, qualifiedName, acceptor);
72 } 69 }
70 parent = parent.eContainer();
71 }
72 if (!nameExported) {
73 acceptEObjectDescription(namedElement, problemQualifiedName, qualifiedName, acceptor);
73 } 74 }
74 return true; 75 return true;
75 } 76 }
76 77
78 protected boolean shouldExport(EObject eObject) {
79 if (eObject instanceof Variable) {
80 // Variables are always private to the containing predicate definition.
81 return false;
82 }
83 if (eObject instanceof Node) {
84 Node node = (Node) eObject;
85 // Only enum literals and new nodes are visible across problem files.
86 return ProblemUtil.isEnumLiteral(node) || ProblemUtil.isNewNode(node);
87 }
88 return true;
89 }
90
77 protected boolean shouldExportSimpleName(EObject eObject) { 91 protected boolean shouldExportSimpleName(EObject eObject) {
78 if (eObject instanceof Node) { 92 if (eObject instanceof Node) {
79 return !ProblemUtil.isNewNode((Node) eObject); 93 return !ProblemUtil.isNewNode((Node) eObject);
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java b/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java
index 3748e81d..597085a8 100644
--- a/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java
@@ -13,6 +13,7 @@ import org.eclipse.viatra.solver.language.ProblemUtil;
13import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration; 13import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration;
14import org.eclipse.viatra.solver.language.model.problem.ExistentialQuantifier; 14import org.eclipse.viatra.solver.language.model.problem.ExistentialQuantifier;
15import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition; 15import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition;
16import org.eclipse.viatra.solver.language.model.problem.Problem;
16import org.eclipse.viatra.solver.language.model.problem.ProblemPackage; 17import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
17import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration; 18import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration;
18import org.eclipse.viatra.solver.language.model.problem.Relation; 19import org.eclipse.viatra.solver.language.model.problem.Relation;
@@ -34,14 +35,27 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
34 @Override 35 @Override
35 public IScope getScope(EObject context, EReference reference) { 36 public IScope getScope(EObject context, EReference reference) {
36 IScope scope = super.getScope(context, reference); 37 IScope scope = super.getScope(context, reference);
38 if (reference == ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE
39 || reference == ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE) {
40 return getNodesScope(context, scope);
41 }
37 if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE) { 42 if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE) {
38 return getVariableScope(context, scope); 43 return getVariableScope(context, scope);
39 } else if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) { 44 }
45 if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) {
40 return getOppositeScope(context, scope); 46 return getOppositeScope(context, scope);
41 } 47 }
42 return scope; 48 return scope;
43 } 49 }
44 50
51 protected IScope getNodesScope(EObject context, IScope delegateScope) {
52 Problem problem = EcoreUtil2.getContainerOfType(context, Problem.class);
53 if (problem == null) {
54 return delegateScope;
55 }
56 return Scopes.scopeFor(problem.getNodes(), delegateScope);
57 }
58
45 protected IScope getVariableScope(EObject context, IScope delegateScope) { 59 protected IScope getVariableScope(EObject context, IScope delegateScope) {
46 List<Variable> variables = new ArrayList<>(); 60 List<Variable> variables = new ArrayList<>();
47 EObject currentContext = context; 61 EObject currentContext = context;
@@ -63,7 +77,7 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider {
63 PredicateDefinition definition = (PredicateDefinition) currentContext; 77 PredicateDefinition definition = (PredicateDefinition) currentContext;
64 variables.addAll(definition.getParameters()); 78 variables.addAll(definition.getParameters());
65 } 79 }
66 return Scopes.scopeFor(variables, delegateScope); 80 return Scopes.scopeFor(variables, getNodesScope(context, delegateScope));
67 } 81 }
68 82
69 protected IScope getOppositeScope(EObject context, IScope delegateScope) { 83 protected IScope getOppositeScope(EObject context, IScope delegateScope) {