aboutsummaryrefslogtreecommitdiffstats
path: root/language/src/main/java/org/eclipse/viatra/solver
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2021-06-27 14:22:40 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2021-06-27 14:22:40 +0200
commit07719e927f9d398765e661c84fd8778cefb39083 (patch)
tree9652080f7e580f09a0763a3e258348dea6e02684 /language/src/main/java/org/eclipse/viatra/solver
parentAdd enum support (diff)
downloadrefinery-07719e927f9d398765e661c84fd8778cefb39083.tar.gz
refinery-07719e927f9d398765e661c84fd8778cefb39083.tar.zst
refinery-07719e927f9d398765e661c84fd8778cefb39083.zip
Simplify project layout
Diffstat (limited to 'language/src/main/java/org/eclipse/viatra/solver')
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe259
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/Problem.xtext116
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/ProblemRuntimeModule.java80
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/ProblemStandaloneSetup.java26
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java98
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/conversion/ProblemValueConverterService.java17
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/conversion/UpperBoundValueConverter.java35
-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/naming/ProblemQualifiedNameConverter.java15
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java299
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemLocationInFileProvider.java32
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java89
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemGlobalScopeProvider.java25
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemLocalScopeProvider.java40
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java83
-rw-r--r--language/src/main/java/org/eclipse/viatra/solver/language/validation/ProblemValidator.java25
16 files changed, 1064 insertions, 0 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
new file mode 100644
index 00000000..76563e2c
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/GenerateProblem.mwe2
@@ -0,0 +1,59 @@
1module org.eclipse.viatra.solver.language.GenerateProblem
2
3import org.eclipse.xtext.xtext.generator.*
4import org.eclipse.xtext.xtext.generator.model.project.*
5
6var rootPath = ".."
7
8Workflow {
9 component = XtextGenerator {
10 configuration = {
11 project = StandardProjectConfig {
12 baseName = "language"
13 rootPath = rootPath
14 runtimeTest = {
15 enabled = true
16 }
17 genericIde = {
18 name = "language-ide"
19 }
20 web = {
21 enabled = true
22 name = "language-web"
23 }
24 mavenLayout = true
25 }
26 code = {
27 encoding = "UTF-8"
28 lineDelimiter = "\n"
29 fileHeader = "/*\n * generated by Xtext \${version}\n */"
30 preferXtendStubs = false
31 }
32 }
33
34 language = StandardLanguage {
35 name = "org.eclipse.viatra.solver.language.Problem"
36 fileExtensions = "problem"
37 referencedResource = "platform:/resource/language-model/model/problem.genmodel"
38
39 serializer = {
40 generateStub = false
41 }
42 validator = {
43 // composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
44 // Generates checks for @Deprecated grammar annotations, an IssueProvider and a corresponding PropertyPage
45 generateDeprecationValidation = true
46 }
47 generator = {
48 generateXtendStub = true
49 }
50 junitSupport = {
51 junitVersion = "5"
52 }
53 webSupport = {
54 framework = "CodeMirror"
55 suppressPattern = "string_singleQuote"
56 }
57 }
58 }
59}
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
new file mode 100644
index 00000000..5f8b35f3
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/Problem.xtext
@@ -0,0 +1,116 @@
1grammar org.eclipse.viatra.solver.language.Problem with org.eclipse.xtext.common.Terminals
2
3import "http://www.eclipse.org/emf/2002/Ecore" as ecore
4import "http://www.eclipse.org/viatra/solver/language/model/Problem"
5
6Problem:
7 ("problem" name=Identifier ".")?
8 statements+=Statement*;
9
10Statement:
11 ClassDeclaration | EnumDeclaration | PredicateDefinition | Assertion | ScopeDeclaration;
12
13ClassDeclaration:
14 abstract?="abstract"? "class"
15 name=Identifier
16 ("extends" superTypes+=[Relation|QualifiedName] ("," superTypes+=[Relation|QualifiedName])*)?
17 ("{" (referenceDeclarations+=ReferenceDeclaration ";"?)* "}" | ".");
18
19EnumDeclaration:
20 "enum"
21 name=Identifier
22 ("{" (literals+=EnumLiteral ("," literals+=EnumLiteral)* ("," | ";")?)? "}" | ".");
23
24EnumLiteral returns Node:
25 name=QuotedOrUnquotedId;
26
27ReferenceDeclaration:
28 (containment?="contains" | "refers")?
29 referenceType=[Relation|QualifiedName]
30 ("[" multiplicity=Multiplicity "]")?
31 name=Identifier
32 ("opposite" opposite=[ReferenceDeclaration|QualifiedName])?;
33
34PredicateDefinition:
35 (error?="error" "pred"? | "pred")
36 name=Identifier
37 "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")"
38 (":-" bodies+=Conjunction (";" bodies+=Conjunction)*)?
39 ".";
40
41Parameter:
42 parameterType=[Relation|QualifiedName]? name=Identifier;
43
44Conjunction:
45 literals+=Literal ("," literals+=Literal)*;
46
47Literal:
48 Atom | NegativeLiteral;
49
50NegativeLiteral:
51 "!" atom=Atom;
52
53Atom:
54 relation=[Relation|QualifiedName]
55 transitiveClosure?="+"?
56 "(" (arguments+=Argument ("," arguments+=Argument)*)? ")";
57
58Argument:
59 variableOrNode=[VariableOrNode|QualifiedName];
60
61Assertion:
62 (relation=[Relation|QualifiedName]
63 "(" (arguments+=[Node|QualifiedName] ("," arguments+=[Node|QualifiedName])*)? ")"
64 ":" value=LogicValue |
65 value=ShortLogicValue?
66 relation=[Relation|QualifiedName]
67 "(" (arguments+=[Node|QualifiedName] ("," arguments+=[Node|QualifiedName])*)? ")")
68 ".";
69
70enum LogicValue:
71 TRUE="true" | FALSE="false" | UNKNOWN="unknown";
72
73enum ShortLogicValue returns LogicValue:
74 FALSE="!" | UNKNOWN="?";
75
76ScopeDeclaration:
77 "scope" typeScopes+=TypeScope ("," typeScopes+=TypeScope)* ".";
78
79TypeScope:
80 targetType=[ClassDeclaration]
81 (increment?="+=" | "=")
82 multiplicity=DefiniteMultiplicity;
83
84Multiplicity:
85 UnboundedMultiplicity | DefiniteMultiplicity;
86
87DefiniteMultiplicity returns Multiplicity:
88 RangeMultiplicity | ExactMultiplicity;
89
90UnboundedMultiplicity:
91 {UnboundedMultiplicity};
92
93RangeMultiplicity:
94 lowerBound=INT ".." upperBound=UpperBound;
95
96ExactMultiplicity:
97 exactValue=INT;
98
99UpperBound returns ecore::EInt:
100 INT | "*";
101
102QuotedOrUnquotedId:
103 QUOTED_ID | Identifier;
104
105QualifiedName:
106 QUOTED_ID | Identifier (":" Identifier)* (":" QUOTED_ID)?;
107
108Identifier:
109 ID | "true" | "false";
110
111@Override
112terminal STRING:
113 '"' ('\\' . /* 'b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\' */ | !('\\' | '"'))* '"';
114
115terminal QUOTED_ID:
116 "'" ('\\' . /* 'b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\' */ | !('\\' | "'"))* "'";
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/ProblemRuntimeModule.java b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemRuntimeModule.java
new file mode 100644
index 00000000..eb9ddd77
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemRuntimeModule.java
@@ -0,0 +1,80 @@
1/*
2 * generated by Xtext 2.25.0
3 */
4package org.eclipse.viatra.solver.language;
5
6import org.eclipse.viatra.solver.language.conversion.ProblemValueConverterService;
7import org.eclipse.viatra.solver.language.naming.ProblemQualifiedNameConverter;
8import org.eclipse.viatra.solver.language.resource.ProblemDerivedStateComputer;
9import org.eclipse.viatra.solver.language.resource.ProblemLocationInFileProvider;
10import org.eclipse.viatra.solver.language.resource.ProblemResourceDescriptionStrategy;
11import org.eclipse.viatra.solver.language.scoping.ProblemGlobalScopeProvider;
12import org.eclipse.viatra.solver.language.scoping.ProblemLocalScopeProvider;
13import org.eclipse.xtext.conversion.IValueConverterService;
14import org.eclipse.xtext.naming.IQualifiedNameConverter;
15import org.eclipse.xtext.resource.DerivedStateAwareResource;
16import org.eclipse.xtext.resource.DerivedStateAwareResourceDescriptionManager;
17import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy;
18import org.eclipse.xtext.resource.IDerivedStateComputer;
19import org.eclipse.xtext.resource.ILocationInFileProvider;
20import org.eclipse.xtext.resource.IResourceDescription;
21import org.eclipse.xtext.resource.XtextResource;
22import org.eclipse.xtext.scoping.IGlobalScopeProvider;
23import org.eclipse.xtext.scoping.IScopeProvider;
24import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
25import org.eclipse.xtext.validation.IResourceValidator;
26import org.eclipse.xtext.xbase.annotations.validation.DerivedStateAwareResourceValidator;
27
28import com.google.inject.Binder;
29import com.google.inject.name.Names;
30
31/**
32 * Use this class to register components to be used at runtime / without the
33 * Equinox extension registry.
34 */
35public class ProblemRuntimeModule extends AbstractProblemRuntimeModule {
36 public Class<? extends IQualifiedNameConverter> bindIQualifiedNameConverter() {
37 return ProblemQualifiedNameConverter.class;
38 }
39
40 public Class<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() {
41 return ProblemResourceDescriptionStrategy.class;
42 }
43
44 @Override
45 public Class<? extends IValueConverterService> bindIValueConverterService() {
46 return ProblemValueConverterService.class;
47 }
48
49 @Override
50 public Class<? extends IGlobalScopeProvider> bindIGlobalScopeProvider() {
51 return ProblemGlobalScopeProvider.class;
52 }
53
54 @Override
55 public void configureIScopeProviderDelegate(Binder binder) {
56 binder.bind(IScopeProvider.class).annotatedWith(Names.named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE))
57 .to(ProblemLocalScopeProvider.class);
58 }
59
60 @Override
61 public Class<? extends XtextResource> bindXtextResource() {
62 return DerivedStateAwareResource.class;
63 }
64
65 public Class<? extends IResourceDescription.Manager> bindIResourceDescription$Manager() {
66 return DerivedStateAwareResourceDescriptionManager.class;
67 }
68
69 public Class<? extends IResourceValidator> bindIResourceValidator() {
70 return DerivedStateAwareResourceValidator.class;
71 }
72
73 public Class<? extends IDerivedStateComputer> bindIDerivedStateComputer() {
74 return ProblemDerivedStateComputer.class;
75 }
76
77 public Class<? extends ILocationInFileProvider> bindILocationInFileProvider() {
78 return ProblemLocationInFileProvider.class;
79 }
80}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/ProblemStandaloneSetup.java b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemStandaloneSetup.java
new file mode 100644
index 00000000..5652f859
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemStandaloneSetup.java
@@ -0,0 +1,26 @@
1/*
2 * generated by Xtext 2.25.0
3 */
4package org.eclipse.viatra.solver.language;
5
6import org.eclipse.emf.ecore.EPackage;
7import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
8
9import com.google.inject.Injector;
10
11/**
12 * Initialization support for running Xtext languages without Equinox extension registry.
13 */
14public class ProblemStandaloneSetup extends ProblemStandaloneSetupGenerated {
15
16 public static void doSetup() {
17 new ProblemStandaloneSetup().createInjectorAndDoEMFRegistration();
18 }
19
20 @Override
21 public Injector createInjectorAndDoEMFRegistration() {
22 if (!EPackage.Registry.INSTANCE.containsKey(ProblemPackage.eNS_URI))
23 EPackage.Registry.INSTANCE.put(ProblemPackage.eNS_URI, ProblemPackage.eINSTANCE);
24 return super.createInjectorAndDoEMFRegistration();
25 }
26}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java
new file mode 100644
index 00000000..09f062f5
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/ProblemUtil.java
@@ -0,0 +1,98 @@
1package org.eclipse.viatra.solver.language;
2
3import java.util.ArrayDeque;
4import java.util.Collection;
5import java.util.Deque;
6import java.util.HashSet;
7import java.util.Optional;
8import java.util.Set;
9
10import org.eclipse.emf.ecore.EObject;
11import org.eclipse.emf.ecore.resource.Resource;
12import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration;
13import org.eclipse.viatra.solver.language.model.problem.Node;
14import org.eclipse.viatra.solver.language.model.problem.Problem;
15import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
16import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration;
17import org.eclipse.viatra.solver.language.model.problem.Relation;
18import org.eclipse.viatra.solver.language.model.problem.Variable;
19import org.eclipse.viatra.solver.language.scoping.ProblemGlobalScopeProvider;
20
21import com.google.common.collect.ImmutableList;
22import com.google.inject.Singleton;
23
24@Singleton
25public final class ProblemUtil {
26 private ProblemUtil() {
27 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
28 }
29
30 public static final String SINGLETON_VARIABLE_PREFIX = "_";
31
32 public static final String ENUM_NODE_NAME_QUOTE = "'";
33
34 public static final String NODE_CLASS_NAME = "node";
35
36 public static boolean isSingletonVariableName(String name) {
37 return name != null && name.startsWith(SINGLETON_VARIABLE_PREFIX);
38 }
39
40 public static boolean isSingletonVariable(Variable variable) {
41 return variable.eContainingFeature() == ProblemPackage.Literals.ARGUMENT__SINGLETON_VARIABLE;
42 }
43
44 public static boolean isEnumLiteral(Node node) {
45 return node.eContainingFeature() == ProblemPackage.Literals.ENUM_DECLARATION__LITERALS;
46 }
47
48 public static boolean isEnumNode(Node node) {
49 String name = node.getName();
50 boolean isNameQuoted = name != null && name.startsWith(ENUM_NODE_NAME_QUOTE)
51 && name.endsWith(ENUM_NODE_NAME_QUOTE);
52 return isNameQuoted || isEnumLiteral(node);
53 }
54
55 public static boolean isNewNode(Node node) {
56 return node.eContainingFeature() == ProblemPackage.Literals.CLASS_DECLARATION__NEW_NODE;
57 }
58
59 public static Optional<Problem> getBuiltInLibrary(EObject context) {
60 return Optional.ofNullable(context.eResource()).map(Resource::getResourceSet)
61 .map(resourceSet -> resourceSet.getResource(ProblemGlobalScopeProvider.BULTIN_LIBRARY_URI, true))
62 .map(Resource::getContents).filter(contents -> !contents.isEmpty()).map(contents -> contents.get(0))
63 .filter(Problem.class::isInstance).map(Problem.class::cast);
64 }
65
66 public static Optional<ClassDeclaration> getNodeClassDeclaration(EObject context) {
67 return getBuiltInLibrary(context).flatMap(problem -> problem.getStatements().stream()
68 .filter(ClassDeclaration.class::isInstance).map(ClassDeclaration.class::cast)
69 .filter(declaration -> NODE_CLASS_NAME.equals(declaration.getName())).findFirst());
70 }
71
72 public static Collection<ClassDeclaration> getSuperclassesAndSelf(ClassDeclaration classDeclaration) {
73 Set<ClassDeclaration> found = new HashSet<>();
74 getNodeClassDeclaration(classDeclaration).ifPresent(found::add);
75 Deque<ClassDeclaration> queue = new ArrayDeque<>();
76 queue.addLast(classDeclaration);
77 while (!queue.isEmpty()) {
78 ClassDeclaration current = queue.removeFirst();
79 if (!found.contains(current)) {
80 found.add(current);
81 for (Relation superType : current.getSuperTypes()) {
82 if (superType instanceof ClassDeclaration) {
83 queue.addLast((ClassDeclaration) superType);
84 }
85 }
86 }
87 }
88 return found;
89 }
90
91 public static Collection<ReferenceDeclaration> getAllReferenceDeclarations(ClassDeclaration classDeclaration) {
92 ImmutableList.Builder<ReferenceDeclaration> builder = ImmutableList.builder();
93 for (ClassDeclaration superclass : getSuperclassesAndSelf(classDeclaration)) {
94 builder.addAll(superclass.getReferenceDeclarations());
95 }
96 return builder.build();
97 }
98}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/conversion/ProblemValueConverterService.java b/language/src/main/java/org/eclipse/viatra/solver/language/conversion/ProblemValueConverterService.java
new file mode 100644
index 00000000..4f5fd069
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/conversion/ProblemValueConverterService.java
@@ -0,0 +1,17 @@
1package org.eclipse.viatra.solver.language.conversion;
2
3import org.eclipse.xtext.common.services.DefaultTerminalConverters;
4import org.eclipse.xtext.conversion.IValueConverter;
5import org.eclipse.xtext.conversion.ValueConverter;
6
7import com.google.inject.Inject;
8
9public class ProblemValueConverterService extends DefaultTerminalConverters {
10 @Inject
11 private UpperBoundValueConverter upperBoundValueConverter;
12
13 @ValueConverter(rule = "UpperBound")
14 public IValueConverter<Integer> UpperBound() {
15 return upperBoundValueConverter;
16 }
17}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/conversion/UpperBoundValueConverter.java b/language/src/main/java/org/eclipse/viatra/solver/language/conversion/UpperBoundValueConverter.java
new file mode 100644
index 00000000..3111b69b
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/conversion/UpperBoundValueConverter.java
@@ -0,0 +1,35 @@
1package org.eclipse.viatra.solver.language.conversion;
2
3import org.eclipse.xtext.conversion.ValueConverterException;
4import org.eclipse.xtext.conversion.impl.AbstractValueConverter;
5import org.eclipse.xtext.conversion.impl.INTValueConverter;
6import org.eclipse.xtext.nodemodel.INode;
7
8import com.google.inject.Inject;
9import com.google.inject.Singleton;
10
11@Singleton
12public class UpperBoundValueConverter extends AbstractValueConverter<Integer> {
13 public static final String INFINITY = "*";
14
15 @Inject
16 private INTValueConverter intValueConverter;
17
18 @Override
19 public Integer toValue(String string, INode node) throws ValueConverterException {
20 if (INFINITY.equals(string)) {
21 return -1;
22 } else {
23 return intValueConverter.toValue(string, node);
24 }
25 }
26
27 @Override
28 public String toString(Integer value) throws ValueConverterException {
29 if (value < 0) {
30 return INFINITY;
31 } else {
32 return intValueConverter.toString(value);
33 }
34 }
35}
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
new file mode 100644
index 00000000..0930f244
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/generator/ProblemGenerator.xtend
@@ -0,0 +1,25 @@
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/naming/ProblemQualifiedNameConverter.java b/language/src/main/java/org/eclipse/viatra/solver/language/naming/ProblemQualifiedNameConverter.java
new file mode 100644
index 00000000..3cee31f3
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/naming/ProblemQualifiedNameConverter.java
@@ -0,0 +1,15 @@
1package org.eclipse.viatra.solver.language.naming;
2
3import org.eclipse.xtext.naming.IQualifiedNameConverter;
4
5import com.google.inject.Singleton;
6
7@Singleton
8public class ProblemQualifiedNameConverter extends IQualifiedNameConverter.DefaultImpl {
9 public static final String DELIMITER = ":";
10
11 @Override
12 public String getDelimiter() {
13 return DELIMITER;
14 }
15}
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
new file mode 100644
index 00000000..b885ce0e
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemDerivedStateComputer.java
@@ -0,0 +1,299 @@
1package org.eclipse.viatra.solver.language.resource;
2
3import java.util.HashSet;
4import java.util.List;
5import java.util.Set;
6import java.util.function.Predicate;
7import java.util.regex.Pattern;
8
9import org.eclipse.emf.ecore.EObject;
10import org.eclipse.emf.ecore.EStructuralFeature;
11import org.eclipse.viatra.solver.language.ProblemUtil;
12import org.eclipse.viatra.solver.language.model.problem.Argument;
13import org.eclipse.viatra.solver.language.model.problem.Assertion;
14import org.eclipse.viatra.solver.language.model.problem.Atom;
15import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration;
16import org.eclipse.viatra.solver.language.model.problem.Conjunction;
17import org.eclipse.viatra.solver.language.model.problem.ExistentialQuantifier;
18import org.eclipse.viatra.solver.language.model.problem.ImplicitVariable;
19import org.eclipse.viatra.solver.language.model.problem.Literal;
20import org.eclipse.viatra.solver.language.model.problem.NegativeLiteral;
21import org.eclipse.viatra.solver.language.model.problem.Node;
22import org.eclipse.viatra.solver.language.model.problem.Parameter;
23import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition;
24import org.eclipse.viatra.solver.language.model.problem.Problem;
25import org.eclipse.viatra.solver.language.model.problem.ProblemFactory;
26import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
27import org.eclipse.viatra.solver.language.model.problem.Statement;
28import org.eclipse.xtext.linking.impl.LinkingHelper;
29import org.eclipse.xtext.naming.IQualifiedNameConverter;
30import org.eclipse.xtext.naming.QualifiedName;
31import org.eclipse.xtext.nodemodel.INode;
32import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
33import org.eclipse.xtext.resource.DerivedStateAwareResource;
34import org.eclipse.xtext.resource.IDerivedStateComputer;
35import org.eclipse.xtext.scoping.IScope;
36import org.eclipse.xtext.scoping.IScopeProvider;
37import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
38
39import com.google.inject.Inject;
40import com.google.inject.Singleton;
41import com.google.inject.name.Named;
42
43@Singleton
44public class ProblemDerivedStateComputer implements IDerivedStateComputer {
45 public static final String NEW_NODE = "new";
46
47 private static final Pattern ID_REGEX = Pattern.compile("[_a-zA-Z][_0-9a-zA-Z]*");
48
49 private static final Pattern QUOTED_ID_REGEX = Pattern.compile("'(\\\\.|[^\\'])*'");
50
51 @Inject
52 private LinkingHelper linkingHelper;
53
54 @Inject
55 private IQualifiedNameConverter qualifiedNameConverter;
56
57 @Inject
58 @Named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE)
59 private IScopeProvider scopeProvider;
60
61 @Override
62 public void installDerivedState(DerivedStateAwareResource resource, boolean preLinkingPhase) {
63 for (EObject object : resource.getContents()) {
64 if (object instanceof Problem) {
65 installDerivedProblemState((Problem) object, preLinkingPhase);
66 }
67 }
68 }
69
70 protected void installDerivedProblemState(Problem problem, boolean preLinkingPhase) {
71 installNewNodes(problem);
72 if (!preLinkingPhase) {
73 installDerivedNodes(problem);
74 for (Statement statement : problem.getStatements()) {
75 if (statement instanceof PredicateDefinition) {
76 PredicateDefinition definition = (PredicateDefinition) statement;
77 installDerivedPredicateDefinitionState(definition);
78 }
79 }
80 }
81 }
82
83 protected void installNewNodes(Problem problem) {
84 for (Statement statement : problem.getStatements()) {
85 if (statement instanceof ClassDeclaration) {
86 ClassDeclaration declaration = (ClassDeclaration) statement;
87 if (!declaration.isAbstract()) {
88 Node newNode = createNode(NEW_NODE);
89 declaration.setNewNode(newNode);
90 }
91 }
92 }
93 }
94
95 protected void installDerivedNodes(Problem problem) {
96 IScope nodeScope = scopeProvider.getScope(problem, ProblemPackage.Literals.ASSERTION__ARGUMENTS);
97 Set<String> nodeNames = new HashSet<>();
98 for (Statement statement : problem.getStatements()) {
99 if (statement instanceof Assertion) {
100 addNodeNames(nodeNames, nodeScope, statement, ProblemPackage.Literals.ASSERTION__ARGUMENTS,
101 ProblemDerivedStateComputer::validNodeName);
102 } else if (statement instanceof PredicateDefinition) {
103 PredicateDefinition predicateDefinition = (PredicateDefinition) statement;
104 for (Conjunction body : predicateDefinition.getBodies()) {
105 for (Literal literal : body.getLiterals()) {
106 Atom atom = null;
107 if (literal instanceof Atom) {
108 atom = (Atom) literal;
109 } else if (literal instanceof NegativeLiteral) {
110 NegativeLiteral negativeLiteral = (NegativeLiteral) literal;
111 atom = negativeLiteral.getAtom();
112 }
113 if (atom == null) {
114 continue;
115 }
116 for (Argument argument : atom.getArguments()) {
117 addNodeNames(nodeNames, nodeScope, argument,
118 ProblemPackage.Literals.ARGUMENT__VARIABLE_OR_NODE,
119 ProblemDerivedStateComputer::validQuotedId);
120 }
121 }
122 }
123 }
124 }
125 List<Node> grapNodes = problem.getNodes();
126 for (String nodeName : nodeNames) {
127 Node graphNode = createNode(nodeName);
128 grapNodes.add(graphNode);
129 }
130 }
131
132 private void addNodeNames(Set<String> nodeNames, IScope nodeScope, EObject eObject, EStructuralFeature feature,
133 Predicate<String> condition) {
134 List<INode> nodes = NodeModelUtils.findNodesForFeature(eObject, feature);
135 for (INode node : nodes) {
136 String nodeName = linkingHelper.getCrossRefNodeAsString(node, true);
137 if (!condition.test(nodeName)) {
138 continue;
139 }
140 QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(nodeName);
141 if (!nodeNames.contains(nodeName) && nodeScope.getSingleElement(qualifiedName) == null) {
142 nodeNames.add(nodeName);
143 }
144 }
145 }
146
147 protected Node createNode(String name) {
148 Node node = ProblemFactory.eINSTANCE.createNode();
149 node.setName(name);
150 return node;
151 }
152
153 protected void installDerivedPredicateDefinitionState(PredicateDefinition definition) {
154 Set<String> parameterNames = new HashSet<>();
155 for (Parameter parameter : definition.getParameters()) {
156 String name = parameter.getName();
157 if (name != null) {
158 parameterNames.add(name);
159 }
160 }
161 for (Conjunction body : definition.getBodies()) {
162 installDeriveConjunctionState(body, parameterNames);
163 }
164 }
165
166 protected void installDeriveConjunctionState(Conjunction conjunction, Set<String> knownVariables) {
167 Set<String> newVariables = new HashSet<>();
168 for (Literal literal : conjunction.getLiterals()) {
169 if (literal instanceof Atom) {
170 Atom atom = (Atom) literal;
171 createSigletonVariablesAndCollectVariables(atom, knownVariables, newVariables);
172 }
173 }
174 createVariables(conjunction, newVariables);
175 newVariables.addAll(knownVariables);
176 for (Literal literal : conjunction.getLiterals()) {
177 if (literal instanceof NegativeLiteral) {
178 NegativeLiteral negativeLiteral = (NegativeLiteral) literal;
179 installDeriveNegativeLiteralState(negativeLiteral, newVariables);
180 }
181 }
182 }
183
184 protected void installDeriveNegativeLiteralState(NegativeLiteral negativeLiteral, Set<String> knownVariables) {
185 Set<String> newVariables = new HashSet<>();
186 createSigletonVariablesAndCollectVariables(negativeLiteral.getAtom(), knownVariables, newVariables);
187 createVariables(negativeLiteral, newVariables);
188 }
189
190 protected void createSigletonVariablesAndCollectVariables(Atom atom, Set<String> knownVariables,
191 Set<String> newVariables) {
192 IScope scope = scopeProvider.getScope(atom, ProblemPackage.Literals.ARGUMENT__VARIABLE_OR_NODE);
193 List<INode> nodes = NodeModelUtils.findNodesForFeature(atom, ProblemPackage.Literals.ATOM__ARGUMENTS);
194 int nodesSize = nodes.size();
195 List<Argument> arguments = atom.getArguments();
196 int argumentsSize = arguments.size();
197 for (int i = 0; i < nodesSize; i++) {
198 INode node = nodes.get(i);
199 String variableName = linkingHelper.getCrossRefNodeAsString(node, true);
200 if (!validId(variableName)) {
201 continue;
202 }
203 QualifiedName qualifiedName = qualifiedNameConverter.toQualifiedName(variableName);
204 if (scope.getSingleElement(qualifiedName) != null) {
205 continue;
206 }
207 if (ProblemUtil.isSingletonVariableName(variableName)) {
208 if (i < argumentsSize) {
209 createSingletonVariable(arguments.get(i), variableName);
210 }
211 continue;
212 }
213 if (!knownVariables.contains(variableName)) {
214 newVariables.add(variableName);
215 }
216 }
217 }
218
219 protected void createVariables(ExistentialQuantifier quantifier, Set<String> newVariables) {
220 for (String variableName : newVariables) {
221 createVariable(quantifier, variableName);
222 }
223 }
224
225 protected void createVariable(ExistentialQuantifier quantifier, String variableName) {
226 if (validId(variableName)) {
227 ImplicitVariable variable = createNamedVariable(variableName);
228 quantifier.getImplicitVariables().add(variable);
229 }
230 }
231
232 protected void createSingletonVariable(Argument argument, String variableName) {
233 if (validId(variableName)) {
234 ImplicitVariable variable = createNamedVariable(variableName);
235 argument.setSingletonVariable(variable);
236 }
237 }
238
239 protected ImplicitVariable createNamedVariable(String variableName) {
240 ImplicitVariable variable = ProblemFactory.eINSTANCE.createImplicitVariable();
241 variable.setName(variableName);
242 return variable;
243 }
244
245 @Override
246 public void discardDerivedState(DerivedStateAwareResource resource) {
247 for (EObject object : resource.getContents()) {
248 if (object instanceof Problem) {
249 discardDerivedProblemState((Problem) object);
250 }
251 }
252 }
253
254 protected void discardDerivedProblemState(Problem problem) {
255 problem.getNodes().clear();
256 for (Statement statement : problem.getStatements()) {
257 if (statement instanceof ClassDeclaration) {
258 ClassDeclaration classDeclaration = (ClassDeclaration) statement;
259 classDeclaration.setNewNode(null);
260 } else if (statement instanceof PredicateDefinition) {
261 PredicateDefinition definition = (PredicateDefinition) statement;
262 for (Conjunction body : definition.getBodies()) {
263 body.getImplicitVariables().clear();
264 for (Literal literal : body.getLiterals()) {
265 if (literal instanceof Atom) {
266 discardDerivedAtomState((Atom) literal);
267 }
268 if (literal instanceof NegativeLiteral) {
269 NegativeLiteral negativeLiteral = (NegativeLiteral) literal;
270 negativeLiteral.getImplicitVariables().clear();
271 discardDerivedAtomState(negativeLiteral.getAtom());
272 }
273 }
274 }
275 }
276 }
277 }
278
279 protected void discardDerivedAtomState(Atom atom) {
280 if (atom == null) {
281 return;
282 }
283 for (Argument argument : atom.getArguments()) {
284 argument.setSingletonVariable(null);
285 }
286 }
287
288 protected static boolean validId(String name) {
289 return name != null && ID_REGEX.matcher(name).matches();
290 }
291
292 protected static boolean validQuotedId(String name) {
293 return name != null && QUOTED_ID_REGEX.matcher(name).matches();
294 }
295
296 protected static boolean validNodeName(String name) {
297 return validId(name) || validQuotedId(name);
298 }
299}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemLocationInFileProvider.java b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemLocationInFileProvider.java
new file mode 100644
index 00000000..94dbdfee
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemLocationInFileProvider.java
@@ -0,0 +1,32 @@
1package org.eclipse.viatra.solver.language.resource;
2
3import org.eclipse.emf.ecore.EObject;
4import org.eclipse.viatra.solver.language.ProblemUtil;
5import org.eclipse.viatra.solver.language.model.problem.ImplicitVariable;
6import org.eclipse.viatra.solver.language.model.problem.Node;
7import org.eclipse.xtext.resource.DefaultLocationInFileProvider;
8import org.eclipse.xtext.util.ITextRegion;
9
10public class ProblemLocationInFileProvider extends DefaultLocationInFileProvider {
11 @Override
12 protected ITextRegion doGetTextRegion(EObject obj, RegionDescription query) {
13 if (obj instanceof Node) {
14 return getNodeTextRegion((Node) obj, query);
15 }
16 if (obj instanceof ImplicitVariable) {
17 return ITextRegion.EMPTY_REGION;
18 }
19 return super.doGetTextRegion(obj, query);
20 }
21
22 protected ITextRegion getNodeTextRegion(Node node, RegionDescription query) {
23 if (ProblemUtil.isEnumLiteral(node)) {
24 return super.doGetTextRegion(node, query);
25 }
26 if (ProblemUtil.isNewNode(node)) {
27 EObject container = node.eContainer();
28 return doGetTextRegion(container, query);
29 }
30 return ITextRegion.EMPTY_REGION;
31 }
32}
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
new file mode 100644
index 00000000..edb25a1c
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/resource/ProblemResourceDescriptionStrategy.java
@@ -0,0 +1,89 @@
1package org.eclipse.viatra.solver.language.resource;
2
3import org.eclipse.emf.ecore.EObject;
4import org.eclipse.viatra.solver.language.ProblemUtil;
5import org.eclipse.viatra.solver.language.model.problem.NamedElement;
6import org.eclipse.viatra.solver.language.model.problem.Node;
7import org.eclipse.viatra.solver.language.model.problem.Problem;
8import org.eclipse.viatra.solver.language.model.problem.Variable;
9import org.eclipse.xtext.EcoreUtil2;
10import org.eclipse.xtext.naming.IQualifiedNameConverter;
11import org.eclipse.xtext.naming.QualifiedName;
12import org.eclipse.xtext.resource.EObjectDescription;
13import org.eclipse.xtext.resource.IEObjectDescription;
14import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionStrategy;
15import org.eclipse.xtext.util.IAcceptor;
16
17import com.google.inject.Inject;
18import com.google.inject.Singleton;
19
20@Singleton
21public class ProblemResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy {
22 @Inject
23 private IQualifiedNameConverter qualifiedNameConverter;
24
25 @Override
26 public boolean createEObjectDescriptions(EObject eObject, IAcceptor<IEObjectDescription> acceptor) {
27 if (eObject instanceof Variable) {
28 return false;
29 }
30 if (eObject instanceof NamedElement) {
31 NamedElement namedElement = (NamedElement) eObject;
32 String name = namedElement.getName();
33 if (name == null || name.isEmpty()) {
34 return true;
35 }
36 Problem problem = EcoreUtil2.getContainerOfType(namedElement, Problem.class);
37 QualifiedName problemQualifiedName = null;
38 if (problem != null) {
39 String problemName = problem.getName();
40 if (problemName != null && !problemName.isEmpty()) {
41 problemQualifiedName = qualifiedNameConverter.toQualifiedName(problemName);
42 }
43 }
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 }
52 EObject parent = namedElement.eContainer();
53 while (parent != null && parent != problem) {
54 if (parent instanceof NamedElement) {
55 NamedElement namedParent = (NamedElement) parent;
56 String parentName = namedParent.getName();
57 if (parentName != null || !name.isEmpty()) {
58 QualifiedName parentQualifiedName = qualifiedNameConverter.toQualifiedName(parentName);
59 qualifiedName = parentQualifiedName.append(qualifiedName);
60 if (shouldExportSimpleName(parent)) {
61 acceptEObjectDescription(namedElement, problemQualifiedName, qualifiedName, acceptor);
62 nameExported = true;
63 } else {
64 nameExported = false;
65 }
66 }
67 }
68 parent = parent.eContainer();
69 }
70 if (!nameExported) {
71 acceptEObjectDescription(namedElement, problemQualifiedName, qualifiedName, acceptor);
72 }
73 }
74 return true;
75 }
76
77 protected boolean shouldExportSimpleName(EObject eObject) {
78 if (eObject instanceof Node) {
79 return !ProblemUtil.isNewNode((Node) eObject);
80 }
81 return true;
82 }
83
84 private void acceptEObjectDescription(EObject eObject, QualifiedName prefix, QualifiedName qualifiedName,
85 IAcceptor<IEObjectDescription> acceptor) {
86 QualifiedName qualifiedNameWithPrefix = prefix == null ? qualifiedName : prefix.append(qualifiedName);
87 acceptor.accept(EObjectDescription.create(qualifiedNameWithPrefix, eObject));
88 }
89}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemGlobalScopeProvider.java b/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemGlobalScopeProvider.java
new file mode 100644
index 00000000..05da277a
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemGlobalScopeProvider.java
@@ -0,0 +1,25 @@
1package org.eclipse.viatra.solver.language.scoping;
2
3import java.util.LinkedHashSet;
4
5import org.eclipse.emf.common.util.URI;
6import org.eclipse.emf.ecore.resource.Resource;
7import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider;
8
9public class ProblemGlobalScopeProvider extends ImportUriGlobalScopeProvider {
10 public static final String BUILTIN_LIBRARY_NAME = "builtin";
11
12 public static final URI BULTIN_LIBRARY_URI = getLibraryUri(BUILTIN_LIBRARY_NAME);
13
14 @Override
15 protected LinkedHashSet<URI> getImportedUris(Resource resource) {
16 LinkedHashSet<URI> importedUris = new LinkedHashSet<>();
17 importedUris.add(BULTIN_LIBRARY_URI);
18 return importedUris;
19 }
20
21 private static URI getLibraryUri(String libraryName) {
22 return URI.createURI(ProblemGlobalScopeProvider.class.getClassLoader()
23 .getResource("org/eclipse/viatra/solver/language/" + libraryName + ".problem").toString());
24 }
25}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemLocalScopeProvider.java b/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemLocalScopeProvider.java
new file mode 100644
index 00000000..e832bb09
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemLocalScopeProvider.java
@@ -0,0 +1,40 @@
1package org.eclipse.viatra.solver.language.scoping;
2
3import java.util.List;
4
5import org.eclipse.emf.ecore.EObject;
6import org.eclipse.emf.ecore.resource.Resource;
7import org.eclipse.xtext.naming.QualifiedName;
8import org.eclipse.xtext.resource.IResourceDescriptions;
9import org.eclipse.xtext.resource.IResourceDescriptionsProvider;
10import org.eclipse.xtext.resource.ISelectable;
11import org.eclipse.xtext.scoping.impl.ImportNormalizer;
12import org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider;
13
14import com.google.inject.Inject;
15
16public class ProblemLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider {
17 private static final QualifiedName BUILTIN_LIBRARY_QUALIFIED_NAME = QualifiedName
18 .create(ProblemGlobalScopeProvider.BUILTIN_LIBRARY_NAME);
19
20 @Inject
21 private IResourceDescriptionsProvider resourceDescriptionsProvider;
22
23 @Override
24 protected List<ImportNormalizer> getImplicitImports(boolean ignoreCase) {
25 return List.of(doCreateImportNormalizer(BUILTIN_LIBRARY_QUALIFIED_NAME, true, ignoreCase));
26 }
27
28 @Override
29 protected List<ImportNormalizer> getImportedNamespaceResolvers(EObject context, boolean ignoreCase) {
30 return List.of();
31 }
32
33 @Override
34 protected ISelectable internalGetAllDescriptions(Resource resource) {
35 // Force the use of ProblemResourceDescriptionStrategy to include all QualifiedNames of objects.
36 IResourceDescriptions resourceDescriptions = resourceDescriptionsProvider
37 .getResourceDescriptions(resource.getResourceSet());
38 return resourceDescriptions.getResourceDescription(resource.getURI());
39 }
40}
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
new file mode 100644
index 00000000..fc4034ae
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/scoping/ProblemScopeProvider.java
@@ -0,0 +1,83 @@
1/*
2 * generated by Xtext 2.25.0
3 */
4package org.eclipse.viatra.solver.language.scoping;
5
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.List;
9
10import org.eclipse.emf.ecore.EObject;
11import org.eclipse.emf.ecore.EReference;
12import org.eclipse.viatra.solver.language.ProblemUtil;
13import org.eclipse.viatra.solver.language.model.problem.Argument;
14import org.eclipse.viatra.solver.language.model.problem.ClassDeclaration;
15import org.eclipse.viatra.solver.language.model.problem.ExistentialQuantifier;
16import org.eclipse.viatra.solver.language.model.problem.PredicateDefinition;
17import org.eclipse.viatra.solver.language.model.problem.ProblemPackage;
18import org.eclipse.viatra.solver.language.model.problem.ReferenceDeclaration;
19import org.eclipse.viatra.solver.language.model.problem.Relation;
20import org.eclipse.viatra.solver.language.model.problem.Variable;
21import org.eclipse.xtext.EcoreUtil2;
22import org.eclipse.xtext.scoping.IScope;
23import org.eclipse.xtext.scoping.Scopes;
24
25/**
26 * This class contains custom scoping description.
27 *
28 * See
29 * https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
30 * on how and when to use it.
31 */
32public class ProblemScopeProvider extends AbstractProblemScopeProvider {
33
34 @Override
35 public IScope getScope(EObject context, EReference reference) {
36 IScope scope = super.getScope(context, reference);
37 if (reference == ProblemPackage.Literals.ARGUMENT__VARIABLE_OR_NODE) {
38 return getVariableScope(context, scope);
39 } else if (reference == ProblemPackage.Literals.REFERENCE_DECLARATION__OPPOSITE) {
40 return getOppositeScope(context, scope);
41 }
42 return scope;
43 }
44
45 protected IScope getVariableScope(EObject context, IScope delegateScope) {
46 List<Variable> variables = new ArrayList<>();
47 EObject currentContext = context;
48 if (context instanceof Argument) {
49 Argument argument = (Argument) context;
50 Variable singletonVariable = argument.getSingletonVariable();
51 if (singletonVariable != null) {
52 variables.add(singletonVariable);
53 }
54 }
55 while (currentContext != null && !(currentContext instanceof PredicateDefinition)) {
56 if (currentContext instanceof ExistentialQuantifier) {
57 ExistentialQuantifier quantifier = (ExistentialQuantifier) currentContext;
58 variables.addAll(quantifier.getImplicitVariables());
59 }
60 currentContext = currentContext.eContainer();
61 }
62 if (currentContext instanceof PredicateDefinition) {
63 PredicateDefinition definition = (PredicateDefinition) currentContext;
64 variables.addAll(definition.getParameters());
65 }
66 return Scopes.scopeFor(variables, delegateScope);
67 }
68
69 protected IScope getOppositeScope(EObject context, IScope delegateScope) {
70 ReferenceDeclaration referenceDeclaration = EcoreUtil2.getContainerOfType(context, ReferenceDeclaration.class);
71 if (referenceDeclaration == null) {
72 return delegateScope;
73 }
74 Relation relation = referenceDeclaration.getReferenceType();
75 if (!(relation instanceof ClassDeclaration)) {
76 return delegateScope;
77 }
78 ClassDeclaration classDeclaration = (ClassDeclaration) relation;
79 Collection<ReferenceDeclaration> referenceDeclarations = ProblemUtil
80 .getAllReferenceDeclarations(classDeclaration);
81 return Scopes.scopeFor(referenceDeclarations, delegateScope);
82 }
83}
diff --git a/language/src/main/java/org/eclipse/viatra/solver/language/validation/ProblemValidator.java b/language/src/main/java/org/eclipse/viatra/solver/language/validation/ProblemValidator.java
new file mode 100644
index 00000000..2b17e222
--- /dev/null
+++ b/language/src/main/java/org/eclipse/viatra/solver/language/validation/ProblemValidator.java
@@ -0,0 +1,25 @@
1/*
2 * generated by Xtext 2.25.0
3 */
4package org.eclipse.viatra.solver.language.validation;
5
6
7/**
8 * This class contains custom validation rules.
9 *
10 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation
11 */
12public class ProblemValidator extends AbstractProblemValidator {
13
14// public static final String INVALID_NAME = "invalidName";
15//
16// @Check
17// public void checkGreetingStartsWithCapital(Greeting greeting) {
18// if (!Character.isUpperCase(greeting.getName().charAt(0))) {
19// warning("Name should start with a capital",
20// ProblemPackage.Literals.GREETING__NAME,
21// INVALID_NAME);
22// }
23// }
24
25}