diff options
26 files changed, 974 insertions, 187 deletions
diff --git a/gradle.properties b/gradle.properties index c4d174df..5c0df1d3 100644 --- a/gradle.properties +++ b/gradle.properties | |||
@@ -1,5 +1,6 @@ | |||
1 | ecoreVersion=2.25.0 | 1 | ecoreVersion=2.25.0 |
2 | ecoreCodegenVersion=2.27.0 | 2 | ecoreCodegenVersion=2.27.0 |
3 | ecoreXmiVersion=2.16.0 | ||
3 | hamcrestVersion=2.2 | 4 | hamcrestVersion=2.2 |
4 | jettyVersion=11.0.6 | 5 | jettyVersion=11.0.6 |
5 | jmhVersion=1.32 | 6 | jmhVersion=1.32 |
diff --git a/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java b/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java index b2e3c90b..76a67f96 100644 --- a/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java +++ b/language-ide/src/main/java/tools/refinery/language/ide/syntaxcoloring/ProblemSemanticHighlightingCalculator.java | |||
@@ -15,7 +15,7 @@ import org.eclipse.xtext.util.CancelIndicator; | |||
15 | import com.google.common.collect.ImmutableList; | 15 | import com.google.common.collect.ImmutableList; |
16 | import com.google.inject.Inject; | 16 | import com.google.inject.Inject; |
17 | 17 | ||
18 | import tools.refinery.language.ProblemUtil; | 18 | import tools.refinery.language.model.ProblemUtil; |
19 | import tools.refinery.language.model.problem.ClassDeclaration; | 19 | import tools.refinery.language.model.problem.ClassDeclaration; |
20 | import tools.refinery.language.model.problem.EnumDeclaration; | 20 | import tools.refinery.language.model.problem.EnumDeclaration; |
21 | import tools.refinery.language.model.problem.NamedElement; | 21 | import tools.refinery.language.model.problem.NamedElement; |
diff --git a/language-model/build.gradle b/language-model/build.gradle index d01f8dfc..46ae839b 100644 --- a/language-model/build.gradle +++ b/language-model/build.gradle | |||
@@ -1,9 +1,11 @@ | |||
1 | apply plugin: 'java-library' | 1 | apply plugin: 'java-library' |
2 | apply plugin: 'java-test-fixtures' | ||
2 | apply from: "${rootDir}/gradle/java-common.gradle" | 3 | apply from: "${rootDir}/gradle/java-common.gradle" |
3 | apply from: "${rootDir}/gradle/mwe2.gradle" | 4 | apply from: "${rootDir}/gradle/mwe2.gradle" |
4 | 5 | ||
5 | dependencies { | 6 | dependencies { |
6 | api "org.eclipse.emf:org.eclipse.emf.ecore:${ecoreVersion}" | 7 | api "org.eclipse.emf:org.eclipse.emf.ecore:${ecoreVersion}" |
8 | api "org.eclipse.emf:org.eclipse.emf.ecore.xmi:${ecoreXmiVersion}" | ||
7 | mwe2 "org.eclipse.emf:org.eclipse.emf.codegen.ecore:${ecoreCodegenVersion}" | 9 | mwe2 "org.eclipse.emf:org.eclipse.emf.codegen.ecore:${ecoreCodegenVersion}" |
8 | mwe2 "org.eclipse.emf:org.eclipse.emf.mwe.utils:${mweVersion}" | 10 | mwe2 "org.eclipse.emf:org.eclipse.emf.mwe.utils:${mweVersion}" |
9 | mwe2 "org.eclipse.emf:org.eclipse.emf.mwe2.lib:${mwe2Version}" | 11 | mwe2 "org.eclipse.emf:org.eclipse.emf.mwe2.lib:${mwe2Version}" |
diff --git a/language-model/plugin.xml b/language-model/plugin.xml index 1e1a246e..4ca005a8 100644 --- a/language-model/plugin.xml +++ b/language-model/plugin.xml | |||
@@ -14,4 +14,11 @@ | |||
14 | genModel="src/main/resources/model/problem.genmodel"/> | 14 | genModel="src/main/resources/model/problem.genmodel"/> |
15 | </extension> | 15 | </extension> |
16 | 16 | ||
17 | <extension point="org.eclipse.emf.ecore.extension_parser"> | ||
18 | <!-- @generated problem --> | ||
19 | <parser | ||
20 | type="problem_xmi" | ||
21 | class="tools.refinery.language.model.problem.util.ProblemResourceFactoryImpl"/> | ||
22 | </extension> | ||
23 | |||
17 | </plugin> | 24 | </plugin> |
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 @@ | |||
1 | package tools.refinery.language.model; | ||
2 | |||
3 | import org.eclipse.emf.ecore.EPackage; | ||
4 | import org.eclipse.emf.ecore.resource.Resource; | ||
5 | |||
6 | import tools.refinery.language.model.problem.ProblemPackage; | ||
7 | import tools.refinery.language.model.problem.impl.ProblemFactoryImpl; | ||
8 | |||
9 | public 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/src/main/java/tools/refinery/language/ProblemUtil.java b/language-model/src/main/java/tools/refinery/language/model/ProblemUtil.java index ae2efc3d..b6b199f8 100644 --- a/language/src/main/java/tools/refinery/language/ProblemUtil.java +++ b/language-model/src/main/java/tools/refinery/language/model/ProblemUtil.java | |||
@@ -1,4 +1,4 @@ | |||
1 | package tools.refinery.language; | 1 | package tools.refinery.language.model; |
2 | 2 | ||
3 | import java.util.ArrayDeque; | 3 | import java.util.ArrayDeque; |
4 | import java.util.Collection; | 4 | import java.util.Collection; |
@@ -7,11 +7,10 @@ import java.util.HashSet; | |||
7 | import java.util.Optional; | 7 | import java.util.Optional; |
8 | import java.util.Set; | 8 | import java.util.Set; |
9 | 9 | ||
10 | import org.eclipse.emf.common.util.URI; | ||
10 | import org.eclipse.emf.ecore.EObject; | 11 | import org.eclipse.emf.ecore.EObject; |
11 | import org.eclipse.emf.ecore.resource.Resource; | 12 | import org.eclipse.emf.ecore.resource.Resource; |
12 | 13 | ||
13 | import com.google.common.collect.ImmutableList; | ||
14 | |||
15 | import tools.refinery.language.model.problem.ClassDeclaration; | 14 | import tools.refinery.language.model.problem.ClassDeclaration; |
16 | import tools.refinery.language.model.problem.Node; | 15 | import tools.refinery.language.model.problem.Node; |
17 | import tools.refinery.language.model.problem.Problem; | 16 | import tools.refinery.language.model.problem.Problem; |
@@ -19,15 +18,18 @@ import tools.refinery.language.model.problem.ProblemPackage; | |||
19 | import tools.refinery.language.model.problem.ReferenceDeclaration; | 18 | import tools.refinery.language.model.problem.ReferenceDeclaration; |
20 | import tools.refinery.language.model.problem.Relation; | 19 | import tools.refinery.language.model.problem.Relation; |
21 | import tools.refinery.language.model.problem.Variable; | 20 | import tools.refinery.language.model.problem.Variable; |
22 | import tools.refinery.language.scoping.ProblemGlobalScopeProvider; | ||
23 | 21 | ||
24 | public final class ProblemUtil { | 22 | public 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 | |||
25 | private ProblemUtil() { | 29 | private ProblemUtil() { |
26 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); | 30 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); |
27 | } | 31 | } |
28 | 32 | ||
29 | public static final String NODE_CLASS_NAME = "node"; | ||
30 | |||
31 | public static boolean isSingletonVariable(Variable variable) { | 33 | public static boolean isSingletonVariable(Variable variable) { |
32 | return variable.eContainingFeature() == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__SINGLETON_VARIABLE; | 34 | return variable.eContainingFeature() == ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__SINGLETON_VARIABLE; |
33 | } | 35 | } |
@@ -44,8 +46,8 @@ public final class ProblemUtil { | |||
44 | 46 | ||
45 | public static Optional<Problem> getBuiltInLibrary(EObject context) { | 47 | public static Optional<Problem> getBuiltInLibrary(EObject context) { |
46 | return Optional.ofNullable(context.eResource()).map(Resource::getResourceSet) | 48 | return Optional.ofNullable(context.eResource()).map(Resource::getResourceSet) |
47 | .map(resourceSet -> resourceSet.getResource(ProblemGlobalScopeProvider.BULTIN_LIBRARY_URI, true)) | 49 | .map(resourceSet -> resourceSet.getResource(BUILTIN_LIBRARY_URI, true)).map(Resource::getContents) |
48 | .map(Resource::getContents).filter(contents -> !contents.isEmpty()).map(contents -> contents.get(0)) | 50 | .filter(contents -> !contents.isEmpty()).map(contents -> contents.get(0)) |
49 | .filter(Problem.class::isInstance).map(Problem.class::cast); | 51 | .filter(Problem.class::isInstance).map(Problem.class::cast); |
50 | } | 52 | } |
51 | 53 | ||
@@ -53,7 +55,7 @@ public final class ProblemUtil { | |||
53 | if (eObject != null) { | 55 | if (eObject != null) { |
54 | var eResource = eObject.eResource(); | 56 | var eResource = eObject.eResource(); |
55 | if (eResource != null) { | 57 | if (eResource != null) { |
56 | return ProblemGlobalScopeProvider.BULTIN_LIBRARY_URI.equals(eResource.getURI()); | 58 | return BUILTIN_LIBRARY_URI.equals(eResource.getURI()); |
57 | } | 59 | } |
58 | } | 60 | } |
59 | return false; | 61 | return false; |
@@ -85,10 +87,16 @@ public final class ProblemUtil { | |||
85 | } | 87 | } |
86 | 88 | ||
87 | public static Collection<ReferenceDeclaration> getAllReferenceDeclarations(ClassDeclaration classDeclaration) { | 89 | public static Collection<ReferenceDeclaration> getAllReferenceDeclarations(ClassDeclaration classDeclaration) { |
88 | ImmutableList.Builder<ReferenceDeclaration> builder = ImmutableList.builder(); | 90 | Set<ReferenceDeclaration> referenceDeclarations = new HashSet<>(); |
89 | for (ClassDeclaration superclass : getSuperclassesAndSelf(classDeclaration)) { | 91 | for (ClassDeclaration superclass : getSuperclassesAndSelf(classDeclaration)) { |
90 | builder.addAll(superclass.getReferenceDeclarations()); | 92 | referenceDeclarations.addAll(superclass.getReferenceDeclarations()); |
91 | } | 93 | } |
92 | return builder.build(); | 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()); | ||
93 | } | 101 | } |
94 | } | 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"/> |
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 new file mode 100644 index 00000000..b412ed1f --- /dev/null +++ b/language-model/src/testFixtures/java/tools/refinery/language/model/tests/ProblemTestUtil.java | |||
@@ -0,0 +1,154 @@ | |||
1 | package tools.refinery.language.model.tests; | ||
2 | |||
3 | import java.util.List; | ||
4 | import java.util.stream.Stream; | ||
5 | |||
6 | import org.eclipse.emf.ecore.resource.Resource.Diagnostic; | ||
7 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
8 | |||
9 | import tools.refinery.language.model.ProblemUtil; | ||
10 | import tools.refinery.language.model.problem.Argument; | ||
11 | import tools.refinery.language.model.problem.Assertion; | ||
12 | import tools.refinery.language.model.problem.AssertionArgument; | ||
13 | import tools.refinery.language.model.problem.Atom; | ||
14 | import tools.refinery.language.model.problem.ClassDeclaration; | ||
15 | import tools.refinery.language.model.problem.Conjunction; | ||
16 | import tools.refinery.language.model.problem.EnumDeclaration; | ||
17 | import tools.refinery.language.model.problem.Literal; | ||
18 | import tools.refinery.language.model.problem.NamedElement; | ||
19 | import tools.refinery.language.model.problem.NegativeLiteral; | ||
20 | import tools.refinery.language.model.problem.Node; | ||
21 | import tools.refinery.language.model.problem.NodeAssertionArgument; | ||
22 | import tools.refinery.language.model.problem.NodeValueAssertion; | ||
23 | import tools.refinery.language.model.problem.Parameter; | ||
24 | import tools.refinery.language.model.problem.PredicateDefinition; | ||
25 | import tools.refinery.language.model.problem.Problem; | ||
26 | import tools.refinery.language.model.problem.ReferenceDeclaration; | ||
27 | import tools.refinery.language.model.problem.Relation; | ||
28 | import tools.refinery.language.model.problem.Statement; | ||
29 | import tools.refinery.language.model.problem.UniqueDeclaration; | ||
30 | import tools.refinery.language.model.problem.Variable; | ||
31 | import tools.refinery.language.model.problem.VariableOrNode; | ||
32 | import tools.refinery.language.model.problem.VariableOrNodeArgument; | ||
33 | |||
34 | public class ProblemTestUtil { | ||
35 | public Problem builtin(Problem problem) { | ||
36 | return ProblemUtil.getBuiltInLibrary(problem).get(); | ||
37 | } | ||
38 | |||
39 | public List<Diagnostic> errors(Problem problem) { | ||
40 | EcoreUtil.resolveAll(problem); | ||
41 | return problem.eResource().getErrors(); | ||
42 | } | ||
43 | |||
44 | public List<String> nodeNames(Problem problem) { | ||
45 | return problem.getNodes().stream().map(node -> node.getName()).toList(); | ||
46 | } | ||
47 | |||
48 | public PredicateDefinition pred(Problem problem, String name) { | ||
49 | return namedStatementOfType(problem, PredicateDefinition.class, name); | ||
50 | } | ||
51 | |||
52 | public Parameter param(PredicateDefinition definition, int i) { | ||
53 | return definition.getParameters().get(i); | ||
54 | } | ||
55 | |||
56 | public Conjunction conj(PredicateDefinition definition, int i) { | ||
57 | return definition.getBodies().get(i); | ||
58 | } | ||
59 | |||
60 | public Literal lit(Conjunction conjunction, int i) { | ||
61 | return conjunction.getLiterals().get(i); | ||
62 | } | ||
63 | |||
64 | public Atom negated(Literal literal) { | ||
65 | return ((NegativeLiteral) literal).getAtom(); | ||
66 | } | ||
67 | |||
68 | public Relation relation(Literal literal) { | ||
69 | return ((Atom) literal).getRelation(); | ||
70 | } | ||
71 | |||
72 | public Argument arg(Atom atom, int i) { | ||
73 | return atom.getArguments().get(i); | ||
74 | } | ||
75 | |||
76 | public Argument arg(Literal literal, int i) { | ||
77 | return arg((Atom) literal, i); | ||
78 | } | ||
79 | |||
80 | public VariableOrNode variableOrNode(Argument argument) { | ||
81 | return ((VariableOrNodeArgument) argument).getVariableOrNode(); | ||
82 | } | ||
83 | |||
84 | public Variable variable(Argument argument) { | ||
85 | return (Variable) variableOrNode(argument); | ||
86 | } | ||
87 | |||
88 | public Node node(Argument argument) { | ||
89 | return (Node) variableOrNode(argument); | ||
90 | } | ||
91 | |||
92 | public Assertion assertion(Problem problem, int i) { | ||
93 | return nthStatementOfType(problem, Assertion.class, i); | ||
94 | } | ||
95 | |||
96 | public AssertionArgument arg(Assertion assertion, int i) { | ||
97 | return assertion.getArguments().get(i); | ||
98 | } | ||
99 | |||
100 | public Node node(AssertionArgument argument) { | ||
101 | return ((NodeAssertionArgument) argument).getNode(); | ||
102 | } | ||
103 | |||
104 | public Node node(Problem problem, String name) { | ||
105 | return named(problem.getNodes(), name); | ||
106 | } | ||
107 | |||
108 | public Node uniqueNode(Problem problem, String name) { | ||
109 | var uniqueNodes = statementsOfType(problem, UniqueDeclaration.class) | ||
110 | .flatMap(declaration -> declaration.getNodes().stream()); | ||
111 | return named(uniqueNodes, name); | ||
112 | } | ||
113 | |||
114 | public NodeValueAssertion nodeValueAssertion(Problem problem, int i) { | ||
115 | return nthStatementOfType(problem, NodeValueAssertion.class, i); | ||
116 | } | ||
117 | |||
118 | public ClassDeclaration findClass(Problem problem, String name) { | ||
119 | return namedStatementOfType(problem, ClassDeclaration.class, name); | ||
120 | } | ||
121 | |||
122 | public ReferenceDeclaration reference(ClassDeclaration declaration, String name) { | ||
123 | return named(declaration.getReferenceDeclarations(), name); | ||
124 | } | ||
125 | |||
126 | public EnumDeclaration findEnum(Problem problem, String name) { | ||
127 | return namedStatementOfType(problem, EnumDeclaration.class, name); | ||
128 | } | ||
129 | |||
130 | public Node literal(EnumDeclaration declaration, String name) { | ||
131 | return named(declaration.getLiterals(), name); | ||
132 | } | ||
133 | |||
134 | private <T extends NamedElement> T named(Stream<? extends T> stream, String name) { | ||
135 | return stream.filter(statement -> name.equals(statement.getName())).findAny().get(); | ||
136 | } | ||
137 | |||
138 | private <T extends NamedElement> T named(List<? extends T> list, String name) { | ||
139 | return named(list.stream(), name); | ||
140 | } | ||
141 | |||
142 | private <T extends Statement> Stream<T> statementsOfType(Problem problem, Class<? extends T> type) { | ||
143 | return problem.getStatements().stream().filter(type::isInstance).map(type::cast); | ||
144 | } | ||
145 | |||
146 | private <T extends Statement & NamedElement> T namedStatementOfType(Problem problem, Class<? extends T> type, | ||
147 | String name) { | ||
148 | return named(statementsOfType(problem, type), name); | ||
149 | } | ||
150 | |||
151 | private <T extends Statement> T nthStatementOfType(Problem problem, Class<? extends T> type, int n) { | ||
152 | return statementsOfType(problem, type).skip(n).findFirst().get(); | ||
153 | } | ||
154 | } | ||
diff --git a/language-to-store/src/main/java/tools/refinery/language/mapping/PartialModelMapper.java b/language-to-store/src/main/java/tools/refinery/language/mapping/PartialModelMapper.java index a2cab671..d37c9ec7 100644 --- a/language-to-store/src/main/java/tools/refinery/language/mapping/PartialModelMapper.java +++ b/language-to-store/src/main/java/tools/refinery/language/mapping/PartialModelMapper.java | |||
@@ -1,11 +1,248 @@ | |||
1 | package tools.refinery.language.mapping; | 1 | package tools.refinery.language.mapping; |
2 | 2 | ||
3 | import java.util.HashMap; | ||
4 | import java.util.HashSet; | ||
5 | import java.util.Map; | ||
6 | import java.util.Optional; | ||
7 | |||
8 | import org.eclipse.emf.common.util.EList; | ||
9 | |||
10 | import tools.refinery.language.model.ProblemUtil; | ||
11 | import tools.refinery.language.model.problem.Assertion; | ||
12 | import tools.refinery.language.model.problem.AssertionArgument; | ||
13 | import tools.refinery.language.model.problem.ClassDeclaration; | ||
14 | import tools.refinery.language.model.problem.EnumDeclaration; | ||
15 | import tools.refinery.language.model.problem.LogicValue; | ||
16 | import tools.refinery.language.model.problem.Node; | ||
17 | import tools.refinery.language.model.problem.NodeAssertionArgument; | ||
18 | import tools.refinery.language.model.problem.PredicateDefinition; | ||
3 | import tools.refinery.language.model.problem.Problem; | 19 | import tools.refinery.language.model.problem.Problem; |
20 | import tools.refinery.language.model.problem.ReferenceDeclaration; | ||
21 | import tools.refinery.language.model.problem.Statement; | ||
22 | import tools.refinery.language.model.problem.UniqueDeclaration; | ||
4 | import tools.refinery.store.model.Model; | 23 | import tools.refinery.store.model.Model; |
24 | import tools.refinery.store.model.ModelStore; | ||
25 | import tools.refinery.store.model.ModelStoreImpl; | ||
26 | import tools.refinery.store.model.Tuple; | ||
27 | import tools.refinery.store.model.representation.Relation; | ||
28 | import tools.refinery.store.model.representation.TruthValue; | ||
29 | |||
5 | 30 | ||
6 | public class PartialModelMapper { | 31 | public class PartialModelMapper { |
7 | public Model transformProblem(Problem problem) { | 32 | public PartialModelMapperDTO transformProblem(Problem problem) throws PartialModelMapperException { |
8 | // TODO @Marci Implement this | 33 | //Defining an integer in order to assign different values to all the nodes |
9 | throw new UnsupportedOperationException(); | 34 | int[] nodeIter = new int[] {0}; |
35 | |||
36 | //Getting the relations and the nodes from the given problem | ||
37 | PartialModelMapperDTO pmmDTO = initTransform(problem, nodeIter); | ||
38 | |||
39 | //Getting the relations and the nodes from the built in problem | ||
40 | Optional<Problem> builtinProblem = ProblemUtil.getBuiltInLibrary(problem); | ||
41 | if (builtinProblem.isEmpty()) throw new PartialModelMapperException("builtin.problem not found"); | ||
42 | PartialModelMapperDTO builtinProblemDTO = initTransform(builtinProblem.get(), nodeIter); | ||
43 | |||
44 | //Merging the relation and the nodes from the given problem and from the built in problem | ||
45 | pmmDTO.getRelationMap().putAll(builtinProblemDTO.getRelationMap()); | ||
46 | pmmDTO.getNodeMap().putAll(builtinProblemDTO.getNodeMap()); | ||
47 | pmmDTO.getEnumNodeMap().putAll(builtinProblemDTO.getEnumNodeMap()); | ||
48 | pmmDTO.getNewNodeMap().putAll(builtinProblemDTO.getNewNodeMap()); | ||
49 | pmmDTO.getUniqueNodeMap().putAll(builtinProblemDTO.getUniqueNodeMap()); | ||
50 | |||
51 | //Definition of store and model | ||
52 | ModelStore store = new ModelStoreImpl(new HashSet<>(pmmDTO.getRelationMap().values())); | ||
53 | Model model = store.createModel(); | ||
54 | pmmDTO.setModel(model); | ||
55 | |||
56 | //Collecting all the nodes in one map | ||
57 | Map<Node,Integer> allNodesMap = mergeNodeMaps(pmmDTO.getEnumNodeMap(), | ||
58 | pmmDTO.getUniqueNodeMap(), | ||
59 | pmmDTO.getNewNodeMap(), | ||
60 | pmmDTO.getNodeMap()); | ||
61 | |||
62 | //Filling up the relations with unknown truth values | ||
63 | for (tools.refinery.language.model.problem.Relation relation : pmmDTO.getRelationMap().keySet()) { | ||
64 | if(!(relation instanceof PredicateDefinition pd && pd.isError())) { | ||
65 | Relation<TruthValue> r = pmmDTO.getRelationMap().get(relation); | ||
66 | if(r.getArity() == 1) | ||
67 | for(Integer i : allNodesMap.values()) { | ||
68 | pmmDTO.getModel().put(r, Tuple.of(i), TruthValue.UNKNOWN); | ||
69 | } | ||
70 | else if(r.getArity() == 2) | ||
71 | for(Integer i : allNodesMap.values()) { | ||
72 | for (Integer j : allNodesMap.values()) { | ||
73 | pmmDTO.getModel().put(r, Tuple.of(i,j), TruthValue.UNKNOWN); | ||
74 | } | ||
75 | } | ||
76 | else throw new PartialModelMapperException("Relation with arity above 2 is not supported"); | ||
77 | } | ||
78 | } | ||
79 | |||
80 | //Filling up the exists | ||
81 | tools.refinery.language.model.problem.Relation existsRelation = findingRelationInDTO(builtinProblemDTO, "exists", | ||
82 | "The exists not found in built in problem"); | ||
83 | for (Node n : allNodesMap.keySet()) { | ||
84 | if(pmmDTO.getNewNodeMap().containsKey(n)) { | ||
85 | pmmDTO.getModel().put(builtinProblemDTO.getRelationMap().get(existsRelation), | ||
86 | Tuple.of(allNodesMap.get(n)), | ||
87 | TruthValue.UNKNOWN); | ||
88 | } | ||
89 | else { | ||
90 | pmmDTO.getModel().put(builtinProblemDTO.getRelationMap().get(existsRelation), | ||
91 | Tuple.of(allNodesMap.get(n)), | ||
92 | TruthValue.TRUE); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | //Filling up the equals | ||
97 | tools.refinery.language.model.problem.Relation equalsRelation = findingRelationInDTO(builtinProblemDTO, "equals", | ||
98 | "The equals not found in built in problem"); | ||
99 | for (Node n1 : allNodesMap.keySet()) { | ||
100 | for(Node n2 : allNodesMap.keySet()) { | ||
101 | if(n1.equals(n2)) { | ||
102 | if(pmmDTO.getNewNodeMap().containsKey(n1)) { | ||
103 | pmmDTO.getModel().put(builtinProblemDTO.getRelationMap().get(equalsRelation), | ||
104 | Tuple.of(allNodesMap.get(n1),allNodesMap.get(n2)), | ||
105 | TruthValue.UNKNOWN); | ||
106 | } | ||
107 | else { | ||
108 | pmmDTO.getModel().put(builtinProblemDTO.getRelationMap().get(equalsRelation), | ||
109 | Tuple.of(allNodesMap.get(n1),allNodesMap.get(n2)), | ||
110 | TruthValue.TRUE); | ||
111 | } | ||
112 | } | ||
113 | else { | ||
114 | pmmDTO.getModel().put(builtinProblemDTO.getRelationMap().get(equalsRelation), | ||
115 | Tuple.of(allNodesMap.get(n1),allNodesMap.get(n2)), | ||
116 | TruthValue.FALSE); | ||
117 | } | ||
118 | } | ||
119 | } | ||
120 | |||
121 | //Transforming the assertions | ||
122 | processAssertions(problem, pmmDTO, allNodesMap); | ||
123 | processAssertions(builtinProblem.get(), pmmDTO, allNodesMap); | ||
124 | |||
125 | return pmmDTO; | ||
126 | } | ||
127 | |||
128 | //Searches for and gives back a relation in a PartialModelMapperDTO | ||
129 | private tools.refinery.language.model.problem.Relation findingRelationInDTO(PartialModelMapperDTO partialModelMapperDTO, String searchedRelation, String errorText) | ||
130 | throws PartialModelMapperException { | ||
131 | tools.refinery.language.model.problem.Relation relation = null; | ||
132 | for (tools.refinery.language.model.problem.Relation r : partialModelMapperDTO.getRelationMap().keySet()) { | ||
133 | if (r.getName().equals(searchedRelation)) relation = r; | ||
134 | } | ||
135 | if(relation.equals(null)) throw new PartialModelMapperException(errorText); | ||
136 | return relation; | ||
137 | } | ||
138 | |||
139 | //Processing assertions and placing them in the model | ||
140 | private void processAssertions(Problem problem, PartialModelMapperDTO pmmDTO, Map<Node, Integer> allNodesMap) { | ||
141 | for(Statement s : problem.getStatements()) { | ||
142 | if(s instanceof Assertion assertion) { | ||
143 | Relation<TruthValue> r1 = pmmDTO.getRelationMap().get(assertion.getRelation()); | ||
144 | int i = 0; | ||
145 | int[] integers = new int[assertion.getArguments().size()]; | ||
146 | for (AssertionArgument aa : assertion.getArguments()) { | ||
147 | if (aa instanceof NodeAssertionArgument nas) { | ||
148 | integers[i] = allNodesMap.get(nas.getNode()); | ||
149 | i++; | ||
150 | } | ||
151 | } | ||
152 | pmmDTO.getModel().put(r1, Tuple.of(integers), logicValueToTruthValue(assertion.getValue())); | ||
153 | } | ||
154 | else if (s instanceof ClassDeclaration cd) { | ||
155 | if(!cd.isAbstract()) | ||
156 | pmmDTO.getModel().put(pmmDTO.getRelationMap().get(cd), | ||
157 | Tuple.of(pmmDTO.getNewNodeMap().get(cd.getNewNode())), | ||
158 | TruthValue.TRUE); | ||
159 | } | ||
160 | else if (s instanceof EnumDeclaration ed) { | ||
161 | for (Node n : ed.getLiterals()) { | ||
162 | pmmDTO.getModel().put(pmmDTO.getRelationMap().get(ed), | ||
163 | Tuple.of(pmmDTO.getEnumNodeMap().get(n)), | ||
164 | TruthValue.TRUE); | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | |||
170 | //Getting the relations and nodes from the problem | ||
171 | private PartialModelMapperDTO initTransform(Problem problem, int[] nodeIter) { | ||
172 | //Defining needed Maps | ||
173 | Map<tools.refinery.language.model.problem.Relation, Relation<TruthValue>> relationMap = new HashMap<>(); | ||
174 | Map<Node, Integer> enumNodeMap = new HashMap<>(); | ||
175 | Map<Node, Integer> uniqueNodeMap = new HashMap<>(); | ||
176 | Map<Node, Integer> newNodeMap = new HashMap<>(); | ||
177 | |||
178 | //Definition of Relations, filling up the enumNodeMap, uniqueNodeMap, newNodeMap | ||
179 | EList<Statement> statements = problem.getStatements(); | ||
180 | for (Statement s : statements) { | ||
181 | if (s instanceof ClassDeclaration cd) { | ||
182 | Relation<TruthValue> r1 = new Relation<>(cd.getName(), 1, TruthValue.FALSE); | ||
183 | relationMap.put(cd, r1); | ||
184 | if(!cd.isAbstract()) newNodeMap.put(cd.getNewNode(), nodeIter[0]++); | ||
185 | EList<ReferenceDeclaration> refDeclList = cd.getReferenceDeclarations(); | ||
186 | for (ReferenceDeclaration refDec : refDeclList) { | ||
187 | Relation<TruthValue> r2 = new Relation<>(refDec.getName(), 2, TruthValue.FALSE); | ||
188 | relationMap.put(refDec, r2); | ||
189 | } | ||
190 | } | ||
191 | else if (s instanceof EnumDeclaration ed) { | ||
192 | Relation<TruthValue> r = new Relation<>(ed.getName(), 1, TruthValue.FALSE); | ||
193 | relationMap.put(ed, r); | ||
194 | for (Node n : ed.getLiterals()) { | ||
195 | enumNodeMap.put(n, nodeIter[0]++); | ||
196 | } | ||
197 | } | ||
198 | else if (s instanceof UniqueDeclaration ud) { | ||
199 | for (Node n : ud.getNodes()) { | ||
200 | uniqueNodeMap.put(n, nodeIter[0]++); | ||
201 | } | ||
202 | } | ||
203 | else if (s instanceof PredicateDefinition pd) { | ||
204 | Relation<TruthValue> r = new Relation<>(pd.getName(), 1, TruthValue.FALSE); | ||
205 | relationMap.put(pd, r); | ||
206 | } | ||
207 | } | ||
208 | |||
209 | //Filling the nodeMap up | ||
210 | Map<Node, Integer> nodeMap = new HashMap<>(); | ||
211 | for(Node n : problem.getNodes()) { | ||
212 | nodeMap.put(n, nodeIter[0]++); | ||
213 | } | ||
214 | |||
215 | return new PartialModelMapperDTO(null,relationMap,nodeMap,enumNodeMap,uniqueNodeMap,newNodeMap); | ||
216 | } | ||
217 | |||
218 | //Merging the maps of nodes into one map | ||
219 | private Map<Node, Integer> mergeNodeMaps(Map<Node, Integer> enumNodeMap, | ||
220 | Map<Node, Integer> uniqueNodeMap, | ||
221 | Map<Node, Integer> newNodeMap, | ||
222 | Map<Node, Integer> nodeMap) { | ||
223 | Map<Node, Integer> out = new HashMap<>(); | ||
224 | out.putAll(enumNodeMap); | ||
225 | out.putAll(uniqueNodeMap); | ||
226 | out.putAll(newNodeMap); | ||
227 | out.putAll(nodeMap); | ||
228 | return out; | ||
229 | } | ||
230 | |||
231 | //Exchange method from LogicValue to TruthValue | ||
232 | private TruthValue logicValueToTruthValue(LogicValue value) { | ||
233 | if(value.equals(LogicValue.TRUE)) return TruthValue.TRUE; | ||
234 | else if(value.equals(LogicValue.FALSE)) return TruthValue.FALSE; | ||
235 | else if(value.equals(LogicValue.UNKNOWN)) return TruthValue.UNKNOWN; | ||
236 | else return TruthValue.ERROR; | ||
237 | } | ||
238 | |||
239 | public class PartialModelMapperException extends Exception{ | ||
240 | private static final long serialVersionUID = 1L; | ||
241 | public PartialModelMapperException(String errorText) { | ||
242 | super(errorText); | ||
243 | } | ||
244 | public PartialModelMapperException() { | ||
245 | super(); | ||
246 | } | ||
10 | } | 247 | } |
11 | } | 248 | } |
diff --git a/language-to-store/src/main/java/tools/refinery/language/mapping/PartialModelMapperDTO.java b/language-to-store/src/main/java/tools/refinery/language/mapping/PartialModelMapperDTO.java new file mode 100644 index 00000000..3397b4bd --- /dev/null +++ b/language-to-store/src/main/java/tools/refinery/language/mapping/PartialModelMapperDTO.java | |||
@@ -0,0 +1,54 @@ | |||
1 | package tools.refinery.language.mapping; | ||
2 | |||
3 | import java.util.Map; | ||
4 | |||
5 | import tools.refinery.language.model.problem.Node; | ||
6 | import tools.refinery.store.model.Model; | ||
7 | import tools.refinery.store.model.representation.Relation; | ||
8 | import tools.refinery.store.model.representation.TruthValue; | ||
9 | |||
10 | public class PartialModelMapperDTO { | ||
11 | private Model model; | ||
12 | private Map<tools.refinery.language.model.problem.Relation, Relation<TruthValue>> relationMap; | ||
13 | private Map<Node, Integer> nodeMap; | ||
14 | private Map<Node, Integer> enumNodeMap; | ||
15 | private Map<Node, Integer> uniqueNodeMap; | ||
16 | private Map<Node, Integer> newNodeMap; | ||
17 | |||
18 | public PartialModelMapperDTO(Model model, | ||
19 | Map<tools.refinery.language.model.problem.Relation, Relation<TruthValue>> relationMap, | ||
20 | Map<Node, Integer> nodeMap, | ||
21 | Map<Node, Integer> enumNodeMap, | ||
22 | Map<Node, Integer> uniqueNodeMap, | ||
23 | Map<Node, Integer> newNodeMap) { | ||
24 | this.model = model; | ||
25 | this.relationMap = relationMap; | ||
26 | this.nodeMap = nodeMap; | ||
27 | this.enumNodeMap = enumNodeMap; | ||
28 | this.uniqueNodeMap = uniqueNodeMap; | ||
29 | this.newNodeMap = newNodeMap; | ||
30 | } | ||
31 | |||
32 | public Model getModel() { | ||
33 | return this.model; | ||
34 | } | ||
35 | public Map<tools.refinery.language.model.problem.Relation, Relation<TruthValue>> getRelationMap(){ | ||
36 | return this.relationMap; | ||
37 | } | ||
38 | public Map<Node, Integer> getNodeMap() { | ||
39 | return this.nodeMap; | ||
40 | } | ||
41 | public Map<Node, Integer> getEnumNodeMap() { | ||
42 | return this.enumNodeMap; | ||
43 | } | ||
44 | public Map<Node, Integer> getUniqueNodeMap() { | ||
45 | return this.uniqueNodeMap; | ||
46 | } | ||
47 | public Map<Node, Integer> getNewNodeMap() { | ||
48 | return this.newNodeMap; | ||
49 | } | ||
50 | |||
51 | public void setModel(Model model) { | ||
52 | this.model = model; | ||
53 | } | ||
54 | } | ||
diff --git a/language-to-store/src/test/java/tools/refinery/language/mapping/tests/PartialModelMapperTest.xtend b/language-to-store/src/test/java/tools/refinery/language/mapping/tests/PartialModelMapperTest.xtend index 41a7b7fd..dcdea332 100644 --- a/language-to-store/src/test/java/tools/refinery/language/mapping/tests/PartialModelMapperTest.xtend +++ b/language-to-store/src/test/java/tools/refinery/language/mapping/tests/PartialModelMapperTest.xtend | |||
@@ -1,25 +1,32 @@ | |||
1 | package tools.refinery.language.mapping.tests | 1 | package tools.refinery.language.mapping.tests |
2 | 2 | ||
3 | import com.google.inject.Inject | 3 | import com.google.inject.Inject |
4 | import org.eclipse.emf.ecore.util.EcoreUtil | ||
4 | import org.eclipse.xtext.testing.InjectWith | 5 | import org.eclipse.xtext.testing.InjectWith |
5 | import org.eclipse.xtext.testing.extensions.InjectionExtension | 6 | import org.eclipse.xtext.testing.extensions.InjectionExtension |
6 | import org.eclipse.xtext.testing.util.ParseHelper | 7 | import org.eclipse.xtext.testing.util.ParseHelper |
7 | import org.junit.jupiter.api.BeforeEach | 8 | import org.junit.jupiter.api.BeforeEach |
8 | import org.junit.jupiter.api.Disabled | ||
9 | import org.junit.jupiter.api.Test | 9 | import org.junit.jupiter.api.Test |
10 | import org.junit.jupiter.api.^extension.ExtendWith | 10 | import org.junit.jupiter.api.^extension.ExtendWith |
11 | import tools.refinery.language.mapping.PartialModelMapper | 11 | import tools.refinery.language.mapping.PartialModelMapper |
12 | import tools.refinery.language.model.problem.Problem | 12 | import tools.refinery.language.model.problem.Problem |
13 | import tools.refinery.language.model.tests.ProblemTestUtil | ||
13 | import tools.refinery.language.tests.ProblemInjectorProvider | 14 | import tools.refinery.language.tests.ProblemInjectorProvider |
15 | import tools.refinery.store.model.Tuple | ||
16 | import tools.refinery.store.model.representation.TruthValue | ||
14 | 17 | ||
15 | import static org.hamcrest.MatcherAssert.assertThat | 18 | import static org.hamcrest.MatcherAssert.assertThat |
16 | import static org.hamcrest.Matchers.* | 19 | import static org.hamcrest.Matchers.* |
20 | import static org.junit.jupiter.api.Assertions.assertTrue | ||
17 | 21 | ||
18 | @ExtendWith(InjectionExtension) | 22 | @ExtendWith(InjectionExtension) |
19 | @InjectWith(ProblemInjectorProvider) | 23 | @InjectWith(ProblemInjectorProvider) |
20 | class PartialModelMapperTest { | 24 | class PartialModelMapperTest { |
21 | @Inject | 25 | @Inject |
22 | ParseHelper<Problem> parseHelper | 26 | ParseHelper<Problem> parseHelper |
27 | |||
28 | @Inject | ||
29 | extension ProblemTestUtil | ||
23 | 30 | ||
24 | PartialModelMapper mapper | 31 | PartialModelMapper mapper |
25 | 32 | ||
@@ -28,9 +35,9 @@ class PartialModelMapperTest { | |||
28 | mapper = new PartialModelMapper | 35 | mapper = new PartialModelMapper |
29 | } | 36 | } |
30 | 37 | ||
38 | //Testing the relation | ||
31 | @Test | 39 | @Test |
32 | @Disabled("Method not yet implemented") | 40 | def void relationTest() { |
33 | def void exampleTest() { | ||
34 | val problem = parseHelper.parse(''' | 41 | val problem = parseHelper.parse(''' |
35 | class Person { | 42 | class Person { |
36 | Person[0..*] friend | 43 | Person[0..*] friend |
@@ -38,7 +45,301 @@ class PartialModelMapperTest { | |||
38 | 45 | ||
39 | friend(a, b). | 46 | friend(a, b). |
40 | ''') | 47 | ''') |
41 | val model = mapper.transformProblem(problem) | 48 | EcoreUtil.resolveAll(problem) |
42 | assertThat(model, notNullValue()) | 49 | |
50 | val modelAndMaps = mapper.transformProblem(problem) | ||
51 | assertThat(modelAndMaps, notNullValue()) | ||
52 | |||
53 | val model = modelAndMaps.model | ||
54 | val relationMap = modelAndMaps.relationMap | ||
55 | val nodeMap = modelAndMaps.nodeMap | ||
56 | |||
57 | val person = problem.findClass("Person") | ||
58 | val friend = problem.findClass("Person").reference("friend") | ||
59 | val a = problem.node("a") | ||
60 | val b = problem.node("b") | ||
61 | |||
62 | assertTrue(model.getDataRepresentations().contains(relationMap.get(person))); | ||
63 | assertTrue(model.getDataRepresentations().contains(relationMap.get(friend))); | ||
64 | assertTrue(model.get(relationMap.get(friend), Tuple.of(nodeMap.get(a),nodeMap.get(b))).equals(TruthValue.TRUE)); | ||
65 | } | ||
66 | |||
67 | //Testing the class | ||
68 | @Test | ||
69 | def void classTest() { | ||
70 | val problem = parseHelper.parse(''' | ||
71 | class Person { | ||
72 | Person[0..*] friend | ||
73 | } | ||
74 | |||
75 | Person(a). | ||
76 | ''') | ||
77 | EcoreUtil.resolveAll(problem) | ||
78 | |||
79 | val modelAndMaps = mapper.transformProblem(problem) | ||
80 | assertThat(modelAndMaps, notNullValue()) | ||
81 | |||
82 | val model = modelAndMaps.model | ||
83 | val relationMap = modelAndMaps.relationMap | ||
84 | val nodeMap = modelAndMaps.nodeMap | ||
85 | |||
86 | val person = problem.findClass("Person") | ||
87 | val friend = problem.findClass("Person").reference("friend") | ||
88 | val a = problem.node("a") | ||
89 | |||
90 | assertTrue(model.getDataRepresentations().contains(relationMap.get(person))); | ||
91 | assertTrue(model.getDataRepresentations().contains(relationMap.get(friend))); | ||
92 | |||
93 | assertTrue(model.get(relationMap.get(person), Tuple.of(nodeMap.get(a))).equals(TruthValue.TRUE)); | ||
94 | } | ||
95 | |||
96 | //Testing the equals and exists from the built in problem | ||
97 | @Test | ||
98 | def void equalsAndExistTest() { | ||
99 | val problem = parseHelper.parse(''' | ||
100 | node(a). | ||
101 | node(b). | ||
102 | |||
103 | class Person. | ||
104 | ''') | ||
105 | EcoreUtil.resolveAll(problem) | ||
106 | val builtin = problem.builtin; | ||
107 | |||
108 | val modelAndMaps = mapper.transformProblem(problem) | ||
109 | assertThat(modelAndMaps, notNullValue()) | ||
110 | |||
111 | val model = modelAndMaps.model | ||
112 | val relationMap = modelAndMaps.relationMap | ||
113 | val nodeMap = modelAndMaps.nodeMap | ||
114 | val newNodeMap = modelAndMaps.newNodeMap | ||
115 | |||
116 | val a = problem.node("a") | ||
117 | val b = problem.node("b") | ||
118 | val Person = problem.findClass("Person") | ||
119 | val PersonNew = problem.findClass("Person").newNode | ||
120 | val exists = builtin.pred("exists") | ||
121 | val equals = builtin.findClass("node").reference("equals") | ||
122 | |||
123 | assertTrue(model.getDataRepresentations().contains(relationMap.get(Person))) | ||
124 | assertTrue(model.getDataRepresentations().contains(relationMap.get(exists))) | ||
125 | assertTrue(model.getDataRepresentations().contains(relationMap.get(equals))) | ||
126 | |||
127 | assertTrue(model.get(relationMap.get(exists), Tuple.of(nodeMap.get(a))).equals(TruthValue.TRUE)) | ||
128 | assertTrue(model.get(relationMap.get(exists), Tuple.of(nodeMap.get(b))).equals(TruthValue.TRUE)) | ||
129 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(a), nodeMap.get(a))).equals(TruthValue.TRUE)) | ||
130 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(b), nodeMap.get(b))).equals(TruthValue.TRUE)) | ||
131 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(a), nodeMap.get(b))).equals(TruthValue.FALSE)) | ||
132 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(b), nodeMap.get(a))).equals(TruthValue.FALSE)) | ||
133 | |||
134 | assertTrue(model.get(relationMap.get(exists), Tuple.of(newNodeMap.get(PersonNew))).equals(TruthValue.UNKNOWN)) | ||
135 | assertTrue(model.get(relationMap.get(equals), Tuple.of(newNodeMap.get(PersonNew), newNodeMap.get(PersonNew))).equals(TruthValue.UNKNOWN)) | ||
136 | assertTrue(model.get(relationMap.get(equals), Tuple.of(newNodeMap.get(PersonNew), nodeMap.get(a))).equals(TruthValue.FALSE)) | ||
137 | assertTrue(model.get(relationMap.get(equals), Tuple.of(newNodeMap.get(PersonNew), nodeMap.get(b))).equals(TruthValue.FALSE)) | ||
138 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(a), newNodeMap.get(PersonNew))).equals(TruthValue.FALSE)) | ||
139 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(b), newNodeMap.get(PersonNew))).equals(TruthValue.FALSE)) | ||
140 | } | ||
141 | |||
142 | //Testing the equals and exists from the built in problem with a different example | ||
143 | @Test | ||
144 | def void equalsAndExistTest2() { | ||
145 | val problem = parseHelper.parse(''' | ||
146 | class Person. | ||
147 | |||
148 | Person(a). | ||
149 | Person(b). | ||
150 | ''') | ||
151 | val builtin = problem.builtin; | ||
152 | EcoreUtil.resolveAll(problem) | ||
153 | |||
154 | val modelAndMaps = mapper.transformProblem(problem) | ||
155 | assertThat(modelAndMaps, notNullValue()) | ||
156 | |||
157 | val model = modelAndMaps.model | ||
158 | val relationMap = modelAndMaps.relationMap | ||
159 | val nodeMap = modelAndMaps.nodeMap | ||
160 | val newNodeMap = modelAndMaps.newNodeMap | ||
161 | |||
162 | val a = problem.node("a") | ||
163 | val b = problem.node("b") | ||
164 | val Person = problem.findClass("Person") | ||
165 | val PersonNew = problem.findClass("Person").newNode | ||
166 | val exists = builtin.pred("exists") | ||
167 | val equals = builtin.findClass("node").reference("equals") | ||
168 | |||
169 | assertTrue(model.getDataRepresentations().contains(relationMap.get(Person))); | ||
170 | assertTrue(model.getDataRepresentations().contains(relationMap.get(exists))); | ||
171 | assertTrue(model.getDataRepresentations().contains(relationMap.get(equals))); | ||
172 | |||
173 | assertTrue(model.get(relationMap.get(exists), Tuple.of(nodeMap.get(a))).equals(TruthValue.TRUE)); | ||
174 | assertTrue(model.get(relationMap.get(exists), Tuple.of(nodeMap.get(b))).equals(TruthValue.TRUE)); | ||
175 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(a), nodeMap.get(a))).equals(TruthValue.TRUE)); | ||
176 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(b), nodeMap.get(b))).equals(TruthValue.TRUE)); | ||
177 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(a), nodeMap.get(b))).equals(TruthValue.FALSE)); | ||
178 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(b), nodeMap.get(a))).equals(TruthValue.FALSE)); | ||
179 | |||
180 | assertTrue(model.get(relationMap.get(exists), Tuple.of(newNodeMap.get(PersonNew))).equals(TruthValue.UNKNOWN)); | ||
181 | assertTrue(model.get(relationMap.get(equals), Tuple.of(newNodeMap.get(PersonNew), newNodeMap.get(PersonNew))).equals(TruthValue.UNKNOWN)); | ||
182 | assertTrue(model.get(relationMap.get(equals), Tuple.of(newNodeMap.get(PersonNew), nodeMap.get(a))).equals(TruthValue.FALSE)); | ||
183 | assertTrue(model.get(relationMap.get(equals), Tuple.of(newNodeMap.get(PersonNew), nodeMap.get(b))).equals(TruthValue.FALSE)); | ||
184 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(a), newNodeMap.get(PersonNew))).equals(TruthValue.FALSE)); | ||
185 | assertTrue(model.get(relationMap.get(equals), Tuple.of(nodeMap.get(b), newNodeMap.get(PersonNew))).equals(TruthValue.FALSE)); | ||
186 | } | ||
187 | |||
188 | //Testing the behavior of the newNodes | ||
189 | @Test | ||
190 | def void newNodeTest(){ | ||
191 | val problem = parseHelper.parse(''' | ||
192 | class Person. | ||
193 | abstract class Family. | ||
194 | ''') | ||
195 | EcoreUtil.resolveAll(problem) | ||
196 | |||
197 | val modelAndMaps = mapper.transformProblem(problem); | ||
198 | assertThat(modelAndMaps, notNullValue()) | ||
199 | |||
200 | val model = modelAndMaps.model | ||
201 | val relationMap = modelAndMaps.relationMap | ||
202 | val newNodeMap = modelAndMaps.newNodeMap | ||
203 | |||
204 | val Person = problem.findClass("Person") | ||
205 | val Family = problem.findClass("Family") | ||
206 | val PersonNew = problem.findClass("Person").newNode | ||
207 | |||
208 | |||
209 | assertTrue(model.getDataRepresentations().contains(relationMap.get(Person))); | ||
210 | assertTrue(model.getDataRepresentations().contains(relationMap.get(Family))); | ||
211 | |||
212 | assertTrue(newNodeMap.size.equals(4)) //3 from builtin.problem, 1 from Person | ||
213 | assertTrue(model.get(relationMap.get(Person), Tuple.of(newNodeMap.get(PersonNew))).equals(TruthValue.TRUE)); | ||
214 | } | ||
215 | |||
216 | //Testing the behavior of enumerations | ||
217 | @Test | ||
218 | def void enumTest(){ | ||
219 | val problem = parseHelper.parse(''' | ||
220 | enum TaxStatus { | ||
221 | child, student, adult, retired | ||
222 | } | ||
223 | ''') | ||
224 | EcoreUtil.resolveAll(problem) | ||
225 | |||
226 | val modelAndMaps = mapper.transformProblem(problem) | ||
227 | assertThat(modelAndMaps, notNullValue()) | ||
228 | |||
229 | val model = modelAndMaps.model | ||
230 | val relationMap = modelAndMaps.relationMap | ||
231 | val enumNodeMap = modelAndMaps.enumNodeMap | ||
232 | |||
233 | val TaxStatus = problem.findEnum("TaxStatus") | ||
234 | val child = problem.findEnum("TaxStatus").literal("child") | ||
235 | val student = problem.findEnum("TaxStatus").literal("student") | ||
236 | val adult = problem.findEnum("TaxStatus").literal("adult") | ||
237 | val retired = problem.findEnum("TaxStatus").literal("retired") | ||
238 | |||
239 | assertTrue(model.getDataRepresentations().contains(relationMap.get(TaxStatus))); | ||
240 | assertTrue(model.get(relationMap.get(TaxStatus), Tuple.of(enumNodeMap.get(child))).equals(TruthValue.TRUE)); | ||
241 | assertTrue(model.get(relationMap.get(TaxStatus), Tuple.of(enumNodeMap.get(student))).equals(TruthValue.TRUE)); | ||
242 | assertTrue(model.get(relationMap.get(TaxStatus), Tuple.of(enumNodeMap.get(adult))).equals(TruthValue.TRUE)); | ||
243 | assertTrue(model.get(relationMap.get(TaxStatus), Tuple.of(enumNodeMap.get(retired))).equals(TruthValue.TRUE)); | ||
244 | } | ||
245 | |||
246 | //Testing the bool from the built in problem | ||
247 | @Test | ||
248 | def void builtinBoolTest(){ | ||
249 | val problem = parseHelper.parse(''' | ||
250 | class Person. | ||
251 | ''') | ||
252 | EcoreUtil.resolveAll(problem) | ||
253 | val builtin = problem.builtin; | ||
254 | |||
255 | val modelAndMaps = mapper.transformProblem(problem) | ||
256 | assertThat(modelAndMaps, notNullValue()) | ||
257 | |||
258 | val model = modelAndMaps.model | ||
259 | val relationMap = modelAndMaps.relationMap | ||
260 | val enumNodeMap = modelAndMaps.enumNodeMap | ||
261 | |||
262 | val bool = builtin.findEnum("bool") | ||
263 | val trueEnum = builtin.findEnum("bool").literal("true") //Emiatt nem sikerül a teszt | ||
264 | val falseEnum = builtin.findEnum("bool").literal("false") | ||
265 | |||
266 | assertTrue(model.getDataRepresentations().contains(relationMap.get(bool))); | ||
267 | assertTrue(model.get(relationMap.get(bool), Tuple.of(enumNodeMap.get(trueEnum))).equals(TruthValue.TRUE)); | ||
268 | assertTrue(model.get(relationMap.get(bool), Tuple.of(enumNodeMap.get(falseEnum))).equals(TruthValue.TRUE)); | ||
269 | } | ||
270 | |||
271 | //Testing different aspects of the behavior | ||
272 | @Test | ||
273 | def void compositeTest() { | ||
274 | val problem = parseHelper.parse(''' | ||
275 | class Family { | ||
276 | contains Person[] members | ||
277 | } | ||
278 | |||
279 | class Person { | ||
280 | Person[0..*] children | ||
281 | Person[0..1] parent | ||
282 | TaxStatus taxStatus | ||
283 | } | ||
284 | |||
285 | enum TaxStatus { | ||
286 | child, student, adult, retired | ||
287 | } | ||
288 | |||
289 | % A child cannot have any dependents. | ||
290 | error invalidTaxStatus(Person p) <-> | ||
291 | taxStatus(p, child), children(p, _q). | ||
292 | |||
293 | unique family. | ||
294 | Family(family). | ||
295 | members(family, anne): true. | ||
296 | members(family, bob). | ||
297 | members(family, ciri). | ||
298 | children(anne, ciri). | ||
299 | ?children(bob, ciri). | ||
300 | taxStatus(anne, adult). | ||
301 | ''') | ||
302 | EcoreUtil.resolveAll(problem) | ||
303 | |||
304 | val modelAndMaps = mapper.transformProblem(problem) | ||
305 | assertThat(modelAndMaps, notNullValue()) | ||
306 | |||
307 | val model = modelAndMaps.model | ||
308 | val relationMap = modelAndMaps.relationMap | ||
309 | val nodeMap = modelAndMaps.nodeMap | ||
310 | val uniqueNodeMap = modelAndMaps.uniqueNodeMap | ||
311 | val enumNodeMap = modelAndMaps.enumNodeMap | ||
312 | |||
313 | val Family = problem.findClass("Family") | ||
314 | val members = problem.findClass("Family").reference("members") | ||
315 | val Person = problem.findClass("Person") | ||
316 | val children = problem.findClass("Person").reference("children") | ||
317 | val parent = problem.findClass("Person").reference("parent") | ||
318 | val taxStatus = problem.findClass("Person").reference("taxStatus") | ||
319 | val TaxStatus = problem.findEnum("TaxStatus") | ||
320 | val invalidTaxStatus = problem.pred("invalidTaxStatus") | ||
321 | |||
322 | val anne = problem.node("anne") | ||
323 | val bob = problem.node("bob") | ||
324 | val ciri = problem.node("ciri") | ||
325 | val family = problem.uniqueNode("family") | ||
326 | val adult = problem.findEnum("TaxStatus").literal("adult") | ||
327 | |||
328 | assertTrue(model.getDataRepresentations().contains(relationMap.get(Family))); | ||
329 | assertTrue(model.getDataRepresentations().contains(relationMap.get(members))); | ||
330 | assertTrue(model.getDataRepresentations().contains(relationMap.get(Person))); | ||
331 | assertTrue(model.getDataRepresentations().contains(relationMap.get(children))); | ||
332 | assertTrue(model.getDataRepresentations().contains(relationMap.get(parent))); | ||
333 | assertTrue(model.getDataRepresentations().contains(relationMap.get(taxStatus))); | ||
334 | assertTrue(model.getDataRepresentations().contains(relationMap.get(TaxStatus))); | ||
335 | assertTrue(model.getDataRepresentations().contains(relationMap.get(invalidTaxStatus))); | ||
336 | |||
337 | assertTrue(model.get(relationMap.get(Family), Tuple.of(uniqueNodeMap.get(family))).equals(TruthValue.TRUE)); | ||
338 | assertTrue(model.get(relationMap.get(members), Tuple.of(uniqueNodeMap.get(family),nodeMap.get(anne))).equals(TruthValue.TRUE)); | ||
339 | assertTrue(model.get(relationMap.get(members), Tuple.of(uniqueNodeMap.get(family),nodeMap.get(bob))).equals(TruthValue.TRUE)); | ||
340 | assertTrue(model.get(relationMap.get(members), Tuple.of(uniqueNodeMap.get(family),nodeMap.get(ciri))).equals(TruthValue.TRUE)); | ||
341 | assertTrue(model.get(relationMap.get(children), Tuple.of(nodeMap.get(anne),nodeMap.get(ciri))).equals(TruthValue.TRUE)); | ||
342 | assertTrue(model.get(relationMap.get(children), Tuple.of(nodeMap.get(bob),nodeMap.get(ciri))).equals(TruthValue.UNKNOWN)); | ||
343 | assertTrue(model.get(relationMap.get(taxStatus), Tuple.of(nodeMap.get(anne),enumNodeMap.get(adult))).equals(TruthValue.TRUE)); | ||
43 | } | 344 | } |
44 | } | 345 | } |
diff --git a/language/build.gradle b/language/build.gradle index 85b0902f..f2b20ab5 100644 --- a/language/build.gradle +++ b/language/build.gradle | |||
@@ -12,6 +12,7 @@ dependencies { | |||
12 | api "org.eclipse.emf:org.eclipse.emf.ecore:${ecoreVersion}" | 12 | api "org.eclipse.emf:org.eclipse.emf.ecore:${ecoreVersion}" |
13 | api project(':refinery-language-model') | 13 | api project(':refinery-language-model') |
14 | testFixturesApi "org.eclipse.xtext:org.eclipse.xtext.testing:${xtextVersion}" | 14 | testFixturesApi "org.eclipse.xtext:org.eclipse.xtext.testing:${xtextVersion}" |
15 | testFixturesApi testFixtures(project(':refinery-language-model')) | ||
15 | mwe2 "org.eclipse.xtext:org.eclipse.xtext.common.types:${xtextVersion}" | 16 | mwe2 "org.eclipse.xtext:org.eclipse.xtext.common.types:${xtextVersion}" |
16 | mwe2 "org.eclipse.xtext:org.eclipse.xtext.xtext.generator:${xtextVersion}" | 17 | mwe2 "org.eclipse.xtext:org.eclipse.xtext.xtext.generator:${xtextVersion}" |
17 | mwe2 "org.eclipse.xtext:xtext-antlr-generator:${xtextAntlrGeneratorVersion}" | 18 | mwe2 "org.eclipse.xtext:xtext-antlr-generator:${xtextAntlrGeneratorVersion}" |
diff --git a/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java b/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java index f49069a5..d753a119 100644 --- a/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java +++ b/language/src/main/java/tools/refinery/language/ProblemStandaloneSetup.java | |||
@@ -3,11 +3,14 @@ | |||
3 | */ | 3 | */ |
4 | package tools.refinery.language; | 4 | package tools.refinery.language; |
5 | 5 | ||
6 | import org.eclipse.emf.ecore.EPackage; | 6 | import org.eclipse.emf.ecore.resource.Resource; |
7 | import org.eclipse.xtext.resource.IResourceFactory; | ||
8 | import org.eclipse.xtext.resource.IResourceServiceProvider; | ||
7 | 9 | ||
10 | import com.google.inject.Guice; | ||
8 | import com.google.inject.Injector; | 11 | import com.google.inject.Injector; |
9 | 12 | ||
10 | import tools.refinery.language.model.problem.ProblemPackage; | 13 | import tools.refinery.language.model.ProblemEMFSetup; |
11 | 14 | ||
12 | /** | 15 | /** |
13 | * Initialization support for running Xtext languages without Equinox extension | 16 | * Initialization support for running Xtext languages without Equinox extension |
@@ -20,15 +23,22 @@ public class ProblemStandaloneSetup extends ProblemStandaloneSetupGenerated { | |||
20 | } | 23 | } |
21 | 24 | ||
22 | @Override | 25 | @Override |
23 | // Here we can't rely on java.util.HashMap#computeIfAbsent, because | ||
24 | // org.eclipse.emf.ecore.impl.EPackageRegistryImpl#containsKey is overridden | ||
25 | // without also overriding computeIfAbsent. We must make sure to call the | ||
26 | // overridden containsKey implementation. | ||
27 | @SuppressWarnings("squid:S3824") | ||
28 | public Injector createInjectorAndDoEMFRegistration() { | 26 | public Injector createInjectorAndDoEMFRegistration() { |
29 | if (!EPackage.Registry.INSTANCE.containsKey(ProblemPackage.eNS_URI)) { | 27 | ProblemEMFSetup.doEMFRegistration(); |
30 | EPackage.Registry.INSTANCE.put(ProblemPackage.eNS_URI, ProblemPackage.eINSTANCE); | 28 | var xmiInjector = createXmiInjector(); |
31 | } | 29 | registerXmiInjector(xmiInjector); |
32 | return super.createInjectorAndDoEMFRegistration(); | 30 | return super.createInjectorAndDoEMFRegistration(); |
33 | } | 31 | } |
32 | |||
33 | protected Injector createXmiInjector() { | ||
34 | return Guice.createInjector(new ProblemXmiRuntimeModule()); | ||
35 | } | ||
36 | |||
37 | protected void registerXmiInjector(Injector injector) { | ||
38 | IResourceFactory resourceFactory = injector.getInstance(IResourceFactory.class); | ||
39 | IResourceServiceProvider serviceProvider = injector.getInstance(IResourceServiceProvider.class); | ||
40 | |||
41 | Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(ProblemEMFSetup.XMI_RESOURCE_EXTENSION, resourceFactory); | ||
42 | IResourceServiceProvider.Registry.INSTANCE.getExtensionToFactoryMap().put(ProblemEMFSetup.XMI_RESOURCE_EXTENSION, serviceProvider); | ||
43 | } | ||
34 | } | 44 | } |
diff --git a/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java b/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java new file mode 100644 index 00000000..03a33bee --- /dev/null +++ b/language/src/main/java/tools/refinery/language/ProblemXmiRuntimeModule.java | |||
@@ -0,0 +1,35 @@ | |||
1 | package tools.refinery.language; | ||
2 | |||
3 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | ||
4 | import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; | ||
5 | import org.eclipse.xtext.resource.IResourceFactory; | ||
6 | import org.eclipse.xtext.resource.generic.AbstractGenericResourceRuntimeModule; | ||
7 | |||
8 | import tools.refinery.language.model.ProblemEMFSetup; | ||
9 | import tools.refinery.language.naming.ProblemQualifiedNameConverter; | ||
10 | import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; | ||
11 | import tools.refinery.language.resource.ProblemXmiResourceFactory; | ||
12 | |||
13 | public class ProblemXmiRuntimeModule extends AbstractGenericResourceRuntimeModule { | ||
14 | @Override | ||
15 | protected String getLanguageName() { | ||
16 | return "tools.refinery.language.ProblemXmi"; | ||
17 | } | ||
18 | |||
19 | @Override | ||
20 | protected String getFileExtensions() { | ||
21 | return ProblemEMFSetup.XMI_RESOURCE_EXTENSION; | ||
22 | } | ||
23 | |||
24 | public Class<? extends IResourceFactory> bindIResourceFactory() { | ||
25 | return ProblemXmiResourceFactory.class; | ||
26 | } | ||
27 | |||
28 | public Class<? extends IQualifiedNameConverter> bindIQualifiedNameConverter() { | ||
29 | return ProblemQualifiedNameConverter.class; | ||
30 | } | ||
31 | |||
32 | public Class<? extends IDefaultResourceDescriptionStrategy> bindIDefaultResourceDescriptionStrategy() { | ||
33 | return ProblemResourceDescriptionStrategy.class; | ||
34 | } | ||
35 | } | ||
diff --git a/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java b/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java index f6a3ec75..b51de05d 100644 --- a/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java +++ b/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java | |||
@@ -4,7 +4,7 @@ import org.eclipse.emf.ecore.EObject; | |||
4 | import org.eclipse.xtext.resource.DefaultLocationInFileProvider; | 4 | import org.eclipse.xtext.resource.DefaultLocationInFileProvider; |
5 | import org.eclipse.xtext.util.ITextRegion; | 5 | import org.eclipse.xtext.util.ITextRegion; |
6 | 6 | ||
7 | import tools.refinery.language.ProblemUtil; | 7 | import tools.refinery.language.model.ProblemUtil; |
8 | import tools.refinery.language.model.problem.ImplicitVariable; | 8 | import tools.refinery.language.model.problem.ImplicitVariable; |
9 | import tools.refinery.language.model.problem.Node; | 9 | import tools.refinery.language.model.problem.Node; |
10 | 10 | ||
diff --git a/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java b/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java index c5dea671..e745b6a5 100644 --- a/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java +++ b/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java | |||
@@ -12,7 +12,7 @@ import org.eclipse.xtext.util.IAcceptor; | |||
12 | import com.google.inject.Inject; | 12 | import com.google.inject.Inject; |
13 | import com.google.inject.Singleton; | 13 | import com.google.inject.Singleton; |
14 | 14 | ||
15 | import tools.refinery.language.ProblemUtil; | 15 | import tools.refinery.language.model.ProblemUtil; |
16 | import tools.refinery.language.model.problem.NamedElement; | 16 | import tools.refinery.language.model.problem.NamedElement; |
17 | import tools.refinery.language.model.problem.Node; | 17 | import tools.refinery.language.model.problem.Node; |
18 | import tools.refinery.language.model.problem.Problem; | 18 | import tools.refinery.language.model.problem.Problem; |
diff --git a/language/src/main/java/tools/refinery/language/resource/ProblemXmiResourceFactory.java b/language/src/main/java/tools/refinery/language/resource/ProblemXmiResourceFactory.java new file mode 100644 index 00000000..68aa6016 --- /dev/null +++ b/language/src/main/java/tools/refinery/language/resource/ProblemXmiResourceFactory.java | |||
@@ -0,0 +1,16 @@ | |||
1 | package tools.refinery.language.resource; | ||
2 | |||
3 | import org.eclipse.emf.common.util.URI; | ||
4 | import org.eclipse.emf.ecore.resource.Resource; | ||
5 | import org.eclipse.xtext.resource.IResourceFactory; | ||
6 | |||
7 | import tools.refinery.language.model.problem.util.ProblemResourceFactoryImpl; | ||
8 | |||
9 | public class ProblemXmiResourceFactory implements IResourceFactory { | ||
10 | private Resource.Factory problemResourceFactory = new ProblemResourceFactoryImpl(); | ||
11 | |||
12 | @Override | ||
13 | public Resource createResource(URI uri) { | ||
14 | return problemResourceFactory.createResource(uri); | ||
15 | } | ||
16 | } | ||
diff --git a/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java b/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java index a21c3bd2..b582d16b 100644 --- a/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java +++ b/language/src/main/java/tools/refinery/language/scoping/ProblemGlobalScopeProvider.java | |||
@@ -6,20 +6,13 @@ import org.eclipse.emf.common.util.URI; | |||
6 | import org.eclipse.emf.ecore.resource.Resource; | 6 | import org.eclipse.emf.ecore.resource.Resource; |
7 | import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider; | 7 | import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider; |
8 | 8 | ||
9 | public class ProblemGlobalScopeProvider extends ImportUriGlobalScopeProvider { | 9 | import tools.refinery.language.model.ProblemUtil; |
10 | public static final String BUILTIN_LIBRARY_NAME = "builtin"; | ||
11 | |||
12 | public static final URI BULTIN_LIBRARY_URI = getLibraryUri(BUILTIN_LIBRARY_NAME); | ||
13 | 10 | ||
11 | public class ProblemGlobalScopeProvider extends ImportUriGlobalScopeProvider { | ||
14 | @Override | 12 | @Override |
15 | protected LinkedHashSet<URI> getImportedUris(Resource resource) { | 13 | protected LinkedHashSet<URI> getImportedUris(Resource resource) { |
16 | LinkedHashSet<URI> importedUris = new LinkedHashSet<>(); | 14 | LinkedHashSet<URI> importedUris = new LinkedHashSet<>(); |
17 | importedUris.add(BULTIN_LIBRARY_URI); | 15 | importedUris.add(ProblemUtil.BUILTIN_LIBRARY_URI); |
18 | return importedUris; | 16 | return importedUris; |
19 | } | 17 | } |
20 | |||
21 | private static URI getLibraryUri(String libraryName) { | ||
22 | return URI.createURI(ProblemGlobalScopeProvider.class.getClassLoader() | ||
23 | .getResource("tools/refinery/" + libraryName + ".problem").toString()); | ||
24 | } | ||
25 | } | 18 | } |
diff --git a/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java b/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java index 05a3bcf9..85797025 100644 --- a/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java +++ b/language/src/main/java/tools/refinery/language/scoping/ProblemLocalScopeProvider.java | |||
@@ -13,9 +13,11 @@ import org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider; | |||
13 | 13 | ||
14 | import com.google.inject.Inject; | 14 | import com.google.inject.Inject; |
15 | 15 | ||
16 | import tools.refinery.language.model.ProblemUtil; | ||
17 | |||
16 | public class ProblemLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider { | 18 | public class ProblemLocalScopeProvider extends ImportedNamespaceAwareLocalScopeProvider { |
17 | private static final QualifiedName BUILTIN_LIBRARY_QUALIFIED_NAME = QualifiedName | 19 | private static final QualifiedName BUILTIN_LIBRARY_QUALIFIED_NAME = QualifiedName |
18 | .create(ProblemGlobalScopeProvider.BUILTIN_LIBRARY_NAME); | 20 | .create(ProblemUtil.BUILTIN_LIBRARY_NAME); |
19 | 21 | ||
20 | @Inject | 22 | @Inject |
21 | private IResourceDescriptionsProvider resourceDescriptionsProvider; | 23 | private IResourceDescriptionsProvider resourceDescriptionsProvider; |
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 61a3c8f9..86b39dbc 100644 --- a/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java +++ b/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java | |||
@@ -12,7 +12,7 @@ import org.eclipse.xtext.EcoreUtil2; | |||
12 | import org.eclipse.xtext.scoping.IScope; | 12 | import org.eclipse.xtext.scoping.IScope; |
13 | import org.eclipse.xtext.scoping.Scopes; | 13 | import org.eclipse.xtext.scoping.Scopes; |
14 | 14 | ||
15 | import tools.refinery.language.ProblemUtil; | 15 | import tools.refinery.language.model.ProblemUtil; |
16 | import tools.refinery.language.model.problem.ClassDeclaration; | 16 | import tools.refinery.language.model.problem.ClassDeclaration; |
17 | import tools.refinery.language.model.problem.ExistentialQuantifier; | 17 | import tools.refinery.language.model.problem.ExistentialQuantifier; |
18 | import tools.refinery.language.model.problem.PredicateDefinition; | 18 | import tools.refinery.language.model.problem.PredicateDefinition; |
diff --git a/language/src/main/resources/tools/refinery/builtin.problem b/language/src/main/resources/tools/refinery/builtin.problem deleted file mode 100644 index 7c4f6685..00000000 --- a/language/src/main/resources/tools/refinery/builtin.problem +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | problem builtin. | ||
2 | |||
3 | abstract class node { | ||
4 | node[] equals opposite equals | ||
5 | } | ||
6 | |||
7 | pred exists(node node). | ||
8 | |||
9 | abstract class domain extends node. | ||
10 | |||
11 | abstract class data extends node. | ||
12 | |||
13 | enum bool { | ||
14 | true, false | ||
15 | } | ||
16 | |||
17 | class real extends data. | ||
18 | |||
19 | class int extends data. | ||
20 | |||
21 | class string extends data. | ||
diff --git a/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.xtend b/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.xtend index 9bd728d6..99cf0a86 100644 --- a/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.xtend +++ b/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.xtend | |||
@@ -10,6 +10,7 @@ import org.eclipse.xtext.testing.util.ParseHelper | |||
10 | import org.junit.jupiter.api.Test | 10 | import org.junit.jupiter.api.Test |
11 | import org.junit.jupiter.api.^extension.ExtendWith | 11 | import org.junit.jupiter.api.^extension.ExtendWith |
12 | import tools.refinery.language.model.problem.Problem | 12 | import tools.refinery.language.model.problem.Problem |
13 | import tools.refinery.language.model.tests.ProblemTestUtil | ||
13 | 14 | ||
14 | import static org.hamcrest.MatcherAssert.assertThat | 15 | import static org.hamcrest.MatcherAssert.assertThat |
15 | import static org.hamcrest.Matchers.* | 16 | import static org.hamcrest.Matchers.* |
@@ -19,10 +20,10 @@ import static org.hamcrest.Matchers.* | |||
19 | class ProblemParsingTest { | 20 | class ProblemParsingTest { |
20 | @Inject | 21 | @Inject |
21 | ParseHelper<Problem> parseHelper | 22 | ParseHelper<Problem> parseHelper |
22 | 23 | ||
23 | @Inject | 24 | @Inject |
24 | extension ProblemTestUtil | 25 | extension ProblemTestUtil |
25 | 26 | ||
26 | @Test | 27 | @Test |
27 | def void exampleTest() { | 28 | def void exampleTest() { |
28 | val it = parseHelper.parse(''' | 29 | val it = parseHelper.parse(''' |
diff --git a/language/src/test/java/tools/refinery/language/tests/ProblemTestUtil.xtend b/language/src/test/java/tools/refinery/language/tests/ProblemTestUtil.xtend deleted file mode 100644 index 46418892..00000000 --- a/language/src/test/java/tools/refinery/language/tests/ProblemTestUtil.xtend +++ /dev/null | |||
@@ -1,114 +0,0 @@ | |||
1 | package tools.refinery.language.tests | ||
2 | |||
3 | import tools.refinery.language.ProblemUtil | ||
4 | import tools.refinery.language.model.problem.Argument | ||
5 | import tools.refinery.language.model.problem.Assertion | ||
6 | import tools.refinery.language.model.problem.AssertionArgument | ||
7 | import tools.refinery.language.model.problem.Atom | ||
8 | import tools.refinery.language.model.problem.ClassDeclaration | ||
9 | import tools.refinery.language.model.problem.Conjunction | ||
10 | import tools.refinery.language.model.problem.EnumDeclaration | ||
11 | import tools.refinery.language.model.problem.Literal | ||
12 | import tools.refinery.language.model.problem.NegativeLiteral | ||
13 | import tools.refinery.language.model.problem.Node | ||
14 | import tools.refinery.language.model.problem.NodeAssertionArgument | ||
15 | import tools.refinery.language.model.problem.NodeValueAssertion | ||
16 | import tools.refinery.language.model.problem.PredicateDefinition | ||
17 | import tools.refinery.language.model.problem.Problem | ||
18 | import tools.refinery.language.model.problem.UniqueDeclaration | ||
19 | import tools.refinery.language.model.problem.Variable | ||
20 | import tools.refinery.language.model.problem.VariableOrNodeArgument | ||
21 | |||
22 | class ProblemTestUtil { | ||
23 | def builtin(Problem it) { | ||
24 | ProblemUtil.getBuiltInLibrary(it).get | ||
25 | } | ||
26 | |||
27 | def errors(Problem it) { | ||
28 | eResource.errors | ||
29 | } | ||
30 | |||
31 | def nodeNames(Problem it) { | ||
32 | nodes.map[name] | ||
33 | } | ||
34 | |||
35 | def pred(Problem it, String name) { | ||
36 | statements.filter(PredicateDefinition).findFirst[it.name == name] | ||
37 | } | ||
38 | |||
39 | def param(PredicateDefinition it, int i) { | ||
40 | parameters.get(i) | ||
41 | } | ||
42 | |||
43 | def conj(PredicateDefinition it, int i) { | ||
44 | bodies.get(i) | ||
45 | } | ||
46 | |||
47 | def lit(Conjunction it, int i) { | ||
48 | literals.get(i) | ||
49 | } | ||
50 | |||
51 | def negated(Literal it) { | ||
52 | (it as NegativeLiteral).atom | ||
53 | } | ||
54 | |||
55 | def relation(Literal it) { | ||
56 | (it as Atom).relation | ||
57 | } | ||
58 | |||
59 | def arg(Atom it, int i) { | ||
60 | it.arguments.get(i) | ||
61 | } | ||
62 | |||
63 | def arg(Literal it, int i) { | ||
64 | (it as Atom).arg(i) | ||
65 | } | ||
66 | |||
67 | def variable(Argument it) { | ||
68 | (it as VariableOrNodeArgument).variableOrNode as Variable | ||
69 | } | ||
70 | |||
71 | def node(Argument it) { | ||
72 | (it as VariableOrNodeArgument).variableOrNode as Node | ||
73 | } | ||
74 | |||
75 | def assertion(Problem it, int i) { | ||
76 | statements.filter(Assertion).get(i) | ||
77 | } | ||
78 | |||
79 | def nodeValueAssertion(Problem it, int i) { | ||
80 | statements.filter(NodeValueAssertion).get(i) | ||
81 | } | ||
82 | |||
83 | def arg(Assertion it, int i) { | ||
84 | arguments.get(i) | ||
85 | } | ||
86 | |||
87 | def node(AssertionArgument it) { | ||
88 | (it as NodeAssertionArgument).node | ||
89 | } | ||
90 | |||
91 | def node(Problem it, String name) { | ||
92 | nodes.findFirst[it.name == name] | ||
93 | } | ||
94 | |||
95 | def uniqueNode(Problem it, String name) { | ||
96 | statements.filter(UniqueDeclaration).flatMap[nodes].findFirst[it.name == name] | ||
97 | } | ||
98 | |||
99 | def findClass(Problem it, String name) { | ||
100 | statements.filter(ClassDeclaration).findFirst[it.name == name] | ||
101 | } | ||
102 | |||
103 | def reference(ClassDeclaration it, String name) { | ||
104 | it.referenceDeclarations.findFirst[it.name == name] | ||
105 | } | ||
106 | |||
107 | def findEnum(Problem it, String name) { | ||
108 | statements.filter(EnumDeclaration).findFirst[it.name == name] | ||
109 | } | ||
110 | |||
111 | def literal(EnumDeclaration it, String name) { | ||
112 | literals.findFirst[it.name == name] | ||
113 | } | ||
114 | } | ||
diff --git a/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.xtend b/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.xtend index ab3e325f..5ff7a2c9 100644 --- a/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.xtend +++ b/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.xtend | |||
@@ -12,8 +12,8 @@ import org.junit.jupiter.params.provider.Arguments | |||
12 | import org.junit.jupiter.params.provider.MethodSource | 12 | import org.junit.jupiter.params.provider.MethodSource |
13 | import org.junit.jupiter.params.provider.ValueSource | 13 | import org.junit.jupiter.params.provider.ValueSource |
14 | import tools.refinery.language.model.problem.Problem | 14 | import tools.refinery.language.model.problem.Problem |
15 | import tools.refinery.language.model.tests.ProblemTestUtil | ||
15 | import tools.refinery.language.tests.ProblemInjectorProvider | 16 | import tools.refinery.language.tests.ProblemInjectorProvider |
16 | import tools.refinery.language.tests.ProblemTestUtil | ||
17 | 17 | ||
18 | import static org.hamcrest.MatcherAssert.assertThat | 18 | import static org.hamcrest.MatcherAssert.assertThat |
19 | import static org.hamcrest.Matchers.* | 19 | import static org.hamcrest.Matchers.* |