aboutsummaryrefslogtreecommitdiffstats
path: root/language-model/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'language-model/src/main')
-rw-r--r--language-model/src/main/java/tools/refinery/language/model/ProblemEMFSetup.java34
-rw-r--r--language-model/src/main/java/tools/refinery/language/model/ProblemUtil.java102
-rw-r--r--language-model/src/main/resources/model/builtin.problem_xmi67
-rw-r--r--language-model/src/main/resources/model/problem.ecore3
-rw-r--r--language-model/src/main/resources/model/problem.genmodel4
5 files changed, 206 insertions, 4 deletions
diff --git a/language-model/src/main/java/tools/refinery/language/model/ProblemEMFSetup.java b/language-model/src/main/java/tools/refinery/language/model/ProblemEMFSetup.java
new file mode 100644
index 00000000..9383098b
--- /dev/null
+++ b/language-model/src/main/java/tools/refinery/language/model/ProblemEMFSetup.java
@@ -0,0 +1,34 @@
1package tools.refinery.language.model;
2
3import org.eclipse.emf.ecore.EPackage;
4import org.eclipse.emf.ecore.resource.Resource;
5
6import tools.refinery.language.model.problem.ProblemPackage;
7import tools.refinery.language.model.problem.impl.ProblemFactoryImpl;
8
9public class ProblemEMFSetup {
10 public static final String XMI_RESOURCE_EXTENSION = "problem_xmi";
11
12 private ProblemEMFSetup() {
13 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
14 }
15
16 // Here we can't rely on java.util.HashMap#putIfAbsent, because
17 // org.eclipse.emf.ecore.impl.EPackageRegistryImpl#containsKey is overridden
18 // without also overriding putIfAbsent. We must make sure to call the
19 // overridden containsKey implementation.
20 @SuppressWarnings("squid:S3824")
21 public static void doEMFRegistration() {
22 if (!EPackage.Registry.INSTANCE.containsKey(ProblemPackage.eNS_URI)) {
23 EPackage.Registry.INSTANCE.put(ProblemPackage.eNS_URI, ProblemPackage.eINSTANCE);
24 }
25
26 // This Resource.Factory is not actually used once
27 // tools.refinery.language.ProblemStandaloneSetup.createInjectorAndDoEMFRegistration()
28 // is called, because if will be replaced by
29 // tools.refinery.language.resource.ProblemXmiResourceFactory, which implements
30 // org.eclipse.xtext.resource.IResourceFactory as required by Xtext.
31 Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().putIfAbsent(XMI_RESOURCE_EXTENSION,
32 new ProblemFactoryImpl());
33 }
34}
diff --git a/language-model/src/main/java/tools/refinery/language/model/ProblemUtil.java b/language-model/src/main/java/tools/refinery/language/model/ProblemUtil.java
new file mode 100644
index 00000000..b6b199f8
--- /dev/null
+++ b/language-model/src/main/java/tools/refinery/language/model/ProblemUtil.java
@@ -0,0 +1,102 @@
1package tools.refinery.language.model;
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.common.util.URI;
11import org.eclipse.emf.ecore.EObject;
12import org.eclipse.emf.ecore.resource.Resource;
13
14import tools.refinery.language.model.problem.ClassDeclaration;
15import tools.refinery.language.model.problem.Node;
16import tools.refinery.language.model.problem.Problem;
17import tools.refinery.language.model.problem.ProblemPackage;
18import tools.refinery.language.model.problem.ReferenceDeclaration;
19import tools.refinery.language.model.problem.Relation;
20import tools.refinery.language.model.problem.Variable;
21
22public final class ProblemUtil {
23 public static final String BUILTIN_LIBRARY_NAME = "builtin";
24
25 public static final URI BUILTIN_LIBRARY_URI = getLibraryUri(BUILTIN_LIBRARY_NAME);
26
27 public static final String NODE_CLASS_NAME = "node";
28
29 private ProblemUtil() {
30 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
31 }
32
33 public static boolean isSingletonVariable(Variable variable) {
34 return variable.eContainingFeature() == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__SINGLETON_VARIABLE;
35 }
36
37 public static boolean isUniqueNode(Node node) {
38 var containingFeature = node.eContainingFeature();
39 return containingFeature == ProblemPackage.Literals.UNIQUE_DECLARATION__NODES
40 || containingFeature == ProblemPackage.Literals.ENUM_DECLARATION__LITERALS;
41 }
42
43 public static boolean isNewNode(Node node) {
44 return node.eContainingFeature() == ProblemPackage.Literals.CLASS_DECLARATION__NEW_NODE;
45 }
46
47 public static Optional<Problem> getBuiltInLibrary(EObject context) {
48 return Optional.ofNullable(context.eResource()).map(Resource::getResourceSet)
49 .map(resourceSet -> resourceSet.getResource(BUILTIN_LIBRARY_URI, true)).map(Resource::getContents)
50 .filter(contents -> !contents.isEmpty()).map(contents -> contents.get(0))
51 .filter(Problem.class::isInstance).map(Problem.class::cast);
52 }
53
54 public static boolean isBuiltIn(EObject eObject) {
55 if (eObject != null) {
56 var eResource = eObject.eResource();
57 if (eResource != null) {
58 return BUILTIN_LIBRARY_URI.equals(eResource.getURI());
59 }
60 }
61 return false;
62 }
63
64 public static Optional<ClassDeclaration> getNodeClassDeclaration(EObject context) {
65 return getBuiltInLibrary(context).flatMap(problem -> problem.getStatements().stream()
66 .filter(ClassDeclaration.class::isInstance).map(ClassDeclaration.class::cast)
67 .filter(declaration -> NODE_CLASS_NAME.equals(declaration.getName())).findFirst());
68 }
69
70 public static Collection<ClassDeclaration> getSuperclassesAndSelf(ClassDeclaration classDeclaration) {
71 Set<ClassDeclaration> found = new HashSet<>();
72 getNodeClassDeclaration(classDeclaration).ifPresent(found::add);
73 Deque<ClassDeclaration> queue = new ArrayDeque<>();
74 queue.addLast(classDeclaration);
75 while (!queue.isEmpty()) {
76 ClassDeclaration current = queue.removeFirst();
77 if (!found.contains(current)) {
78 found.add(current);
79 for (Relation superType : current.getSuperTypes()) {
80 if (superType instanceof ClassDeclaration superDeclaration) {
81 queue.addLast(superDeclaration);
82 }
83 }
84 }
85 }
86 return found;
87 }
88
89 public static Collection<ReferenceDeclaration> getAllReferenceDeclarations(ClassDeclaration classDeclaration) {
90 Set<ReferenceDeclaration> referenceDeclarations = new HashSet<>();
91 for (ClassDeclaration superclass : getSuperclassesAndSelf(classDeclaration)) {
92 referenceDeclarations.addAll(superclass.getReferenceDeclarations());
93 }
94 return referenceDeclarations;
95 }
96
97 private static URI getLibraryUri(String libraryName) {
98 return URI.createURI(ProblemUtil.class.getClassLoader()
99 .getResource("model/" + libraryName + "." + ProblemEMFSetup.XMI_RESOURCE_EXTENSION)
100 .toString());
101 }
102}
diff --git a/language-model/src/main/resources/model/builtin.problem_xmi b/language-model/src/main/resources/model/builtin.problem_xmi
new file mode 100644
index 00000000..9255ab66
--- /dev/null
+++ b/language-model/src/main/resources/model/builtin.problem_xmi
@@ -0,0 +1,67 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<problem:Problem
3 xmi:version="2.0"
4 xmlns:xmi="http://www.omg.org/XMI"
5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6 xmlns:problem="https://refinery.tools/emf/2021/Problem"
7 xsi:schemaLocation="https://refinery.tools/emf/2021/Problem problem.ecore"
8 name="builtin">
9 <statements
10 xsi:type="problem:ClassDeclaration"
11 name="node"
12 abstract="true">
13 <referenceDeclarations
14 name="equals"
15 referenceType="//@statements.0"
16 opposite="//@statements.0/@referenceDeclarations.0">
17 <multiplicity
18 xsi:type="problem:UnboundedMultiplicity"/>
19 </referenceDeclarations>
20 </statements>
21 <statements
22 xsi:type="problem:PredicateDefinition"
23 name="exists">
24 <parameters
25 name="node"
26 parameterType="//@statements.0"/>
27 </statements>
28 <statements
29 xsi:type="problem:ClassDeclaration"
30 name="domain"
31 abstract="true"
32 superTypes="//@statements.0"/>
33 <statements
34 xsi:type="problem:ClassDeclaration"
35 name="data"
36 abstract="true"
37 superTypes="//@statements.0"/>
38 <statements
39 xsi:type="problem:EnumDeclaration"
40 name="bool">
41 <literals
42 name="false"/>
43 <literals
44 name="true"/>
45 </statements>
46 <statements
47 xsi:type="problem:ClassDeclaration"
48 name="real"
49 superTypes="//@statements.3">
50 <newNode
51 name="new"/>
52 </statements>
53 <statements
54 xsi:type="problem:ClassDeclaration"
55 name="int"
56 superTypes="//@statements.3">
57 <newNode
58 name="new"/>
59 </statements>
60 <statements
61 xsi:type="problem:ClassDeclaration"
62 name="string"
63 superTypes="//@statements.3">
64 <newNode
65 name="new"/>
66 </statements>
67</problem:Problem>
diff --git a/language-model/src/main/resources/model/problem.ecore b/language-model/src/main/resources/model/problem.ecore
index a62590ac..e86f0afd 100644
--- a/language-model/src/main/resources/model/problem.ecore
+++ b/language-model/src/main/resources/model/problem.ecore
@@ -1,7 +1,6 @@
1<?xml version="1.0" encoding="UTF-8"?> 1<?xml version="1.0" encoding="UTF-8"?>
2<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="problem" nsURI="https://refinery.tools/emf/2021/Problem" 3 xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="problem" nsURI="https://refinery.tools/emf/2021/Problem" nsPrefix="problem">
4 nsPrefix="problem">
5 <eClassifiers xsi:type="ecore:EClass" name="Problem" eSuperTypes="#//NamedElement"> 4 <eClassifiers xsi:type="ecore:EClass" name="Problem" eSuperTypes="#//NamedElement">
6 <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" 5 <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
7 eType="#//Node" containment="true"/> 6 eType="#//Node" containment="true"/>
diff --git a/language-model/src/main/resources/model/problem.genmodel b/language-model/src/main/resources/model/problem.genmodel
index e529977f..057b4917 100644
--- a/language-model/src/main/resources/model/problem.genmodel
+++ b/language-model/src/main/resources/model/problem.genmodel
@@ -8,8 +8,8 @@
8 copyrightFields="false" operationReflection="true" importOrganizing="true"> 8 copyrightFields="false" operationReflection="true" importOrganizing="true">
9 <foreignModel>problem.ecore</foreignModel> 9 <foreignModel>problem.ecore</foreignModel>
10 <testsDirectory xsi:nil="true"/> 10 <testsDirectory xsi:nil="true"/>
11 <genPackages prefix="Problem" basePackage="tools.refinery.language.model" 11 <genPackages prefix="Problem" basePackage="tools.refinery.language.model" resource="XMI"
12 disposableProviderFactory="true" ecorePackage="problem.ecore#/"> 12 disposableProviderFactory="true" fileExtensions="problem_xmi" ecorePackage="problem.ecore#/">
13 <genEnums typeSafeEnumCompatible="false" ecoreEnum="problem.ecore#//LogicValue"> 13 <genEnums typeSafeEnumCompatible="false" ecoreEnum="problem.ecore#//LogicValue">
14 <genEnumLiterals ecoreEnumLiteral="problem.ecore#//LogicValue/TRUE"/> 14 <genEnumLiterals ecoreEnumLiteral="problem.ecore#//LogicValue/TRUE"/>
15 <genEnumLiterals ecoreEnumLiteral="problem.ecore#//LogicValue/FALSE"/> 15 <genEnumLiterals ecoreEnumLiteral="problem.ecore#//LogicValue/FALSE"/>