aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2021-11-06 16:56:11 +0100
committerLibravatar GitHub <noreply@github.com>2021-11-06 16:56:11 +0100
commitbf479290c950c004d8f99eda967e3a6c76e0e64b (patch)
tree2d805f058ab6b4289d4338b8f6beb12c51c31d09
parentMerge pull request #11 from kris7t/unique-to-individual (diff)
parentchore(lang): seralize assertions in short form (diff)
downloadrefinery-bf479290c950c004d8f99eda967e3a6c76e0e64b.tar.gz
refinery-bf479290c950c004d8f99eda967e3a6c76e0e64b.tar.zst
refinery-bf479290c950c004d8f99eda967e3a6c76e0e64b.zip
Merge pull request #12 from kris7t/xtext-serialization
Make sure Xtext serialization works
-rw-r--r--language-model/META-INF/MANIFEST.MF1
-rw-r--r--language-model/src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe26
-rw-r--r--language-model/src/main/resources/model/problem.ecore8
-rw-r--r--language-model/src/main/resources/model/problem.genmodel2
-rw-r--r--language-to-store/src/test/java/tools/refinery/language/mapping/tests/PartialModelMapperTest.xtend2
-rw-r--r--language-web/src/main/js/index.tsx2
-rw-r--r--language-web/src/main/js/language/problem.grammar2
-rw-r--r--language-web/src/main/js/language/problemLanguageSupport.ts2
-rw-r--r--language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java2
-rw-r--r--language-web/src/test/java/tools/refinery/language/web/xtext/servlet/TransactionExecutorTest.java2
-rw-r--r--language/src/main/java/tools/refinery/language/Problem.xtext14
-rw-r--r--language/src/main/java/tools/refinery/language/validation/ProblemValidator.java2
-rw-r--r--language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.xtend2
-rw-r--r--language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.xtend6
-rw-r--r--language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java215
15 files changed, 242 insertions, 26 deletions
diff --git a/language-model/META-INF/MANIFEST.MF b/language-model/META-INF/MANIFEST.MF
index 88725730..96617f85 100644
--- a/language-model/META-INF/MANIFEST.MF
+++ b/language-model/META-INF/MANIFEST.MF
@@ -12,5 +12,6 @@ Export-Package: tools.refinery.language.model.problem,
12 tools.refinery.language.model.problem.impl, 12 tools.refinery.language.model.problem.impl,
13 tools.refinery.language.model.problem.util 13 tools.refinery.language.model.problem.util
14Require-Bundle: org.eclipse.emf.ecore;visibility:=reexport, 14Require-Bundle: org.eclipse.emf.ecore;visibility:=reexport,
15 org.eclipse.emf.ecore.xmi;visibility:=reexport,
15 org.eclipse.core.runtime 16 org.eclipse.core.runtime
16Bundle-ActivationPolicy: lazy 17Bundle-ActivationPolicy: lazy
diff --git a/language-model/src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2 b/language-model/src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2
index 7f998448..c1518b4d 100644
--- a/language-model/src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2
+++ b/language-model/src/main/java/tools/refinery/language/model/GenerateProblemModel.mwe2
@@ -3,7 +3,7 @@ module tools.refinery.language.model.GenerateProblemModel
3Workflow { 3Workflow {
4 bean = org.eclipse.emf.mwe.utils.StandaloneSetup { 4 bean = org.eclipse.emf.mwe.utils.StandaloneSetup {
5 projectMapping = { 5 projectMapping = {
6 projectName = "language-model" 6 projectName = "refinery-language-model"
7 path = "." 7 path = "."
8 } 8 }
9 } 9 }
@@ -14,7 +14,7 @@ Workflow {
14 14
15 component = org.eclipse.emf.mwe2.ecore.EcoreGenerator { 15 component = org.eclipse.emf.mwe2.ecore.EcoreGenerator {
16 generateCustomClasses = false 16 generateCustomClasses = false
17 genModel = "platform:/resource/language-model/src/main/resources/model/problem.genmodel" 17 genModel = "platform:/resource/refinery-language-model/src/main/resources/model/problem.genmodel"
18 srcPath = "platform:/resource/language-model/src/main/emf-gen" 18 srcPath = "platform:/resource/refinery-language-model/src/main/emf-gen"
19 } 19 }
20} 20}
diff --git a/language-model/src/main/resources/model/problem.ecore b/language-model/src/main/resources/model/problem.ecore
index 77211b66..582f67c8 100644
--- a/language-model/src/main/resources/model/problem.ecore
+++ b/language-model/src/main/resources/model/problem.ecore
@@ -3,7 +3,7 @@
3 xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="problem" nsURI="https://refinery.tools/emf/2021/Problem" nsPrefix="problem"> 3 xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="problem" nsURI="https://refinery.tools/emf/2021/Problem" nsPrefix="problem">
4 <eClassifiers xsi:type="ecore:EClass" name="Problem" eSuperTypes="#//NamedElement"> 4 <eClassifiers xsi:type="ecore:EClass" name="Problem" eSuperTypes="#//NamedElement">
5 <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1" 5 <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
6 eType="#//Node" containment="true"/> 6 eType="#//Node" transient="true" containment="true"/>
7 <eStructuralFeatures xsi:type="ecore:EReference" name="statements" upperBound="-1" 7 <eStructuralFeatures xsi:type="ecore:EReference" name="statements" upperBound="-1"
8 eType="#//Statement" containment="true"/> 8 eType="#//Statement" containment="true"/>
9 </eClassifiers> 9 </eClassifiers>
@@ -15,7 +15,7 @@
15 <eStructuralFeatures xsi:type="ecore:EReference" name="referenceDeclarations" 15 <eStructuralFeatures xsi:type="ecore:EReference" name="referenceDeclarations"
16 upperBound="-1" eType="#//ReferenceDeclaration" containment="true"/> 16 upperBound="-1" eType="#//ReferenceDeclaration" containment="true"/>
17 <eStructuralFeatures xsi:type="ecore:EReference" name="newNode" eType="#//Node" 17 <eStructuralFeatures xsi:type="ecore:EReference" name="newNode" eType="#//Node"
18 containment="true"/> 18 transient="true" containment="true"/>
19 </eClassifiers> 19 </eClassifiers>
20 <eClassifiers xsi:type="ecore:EClass" name="ReferenceDeclaration" eSuperTypes="#//Relation"> 20 <eClassifiers xsi:type="ecore:EClass" name="ReferenceDeclaration" eSuperTypes="#//Relation">
21 <eStructuralFeatures xsi:type="ecore:EReference" name="referenceType" eType="#//Relation"/> 21 <eStructuralFeatures xsi:type="ecore:EReference" name="referenceType" eType="#//Relation"/>
@@ -52,7 +52,7 @@
52 <eClassifiers xsi:type="ecore:EClass" name="ExistentialQuantifier" abstract="true" 52 <eClassifiers xsi:type="ecore:EClass" name="ExistentialQuantifier" abstract="true"
53 interface="true"> 53 interface="true">
54 <eStructuralFeatures xsi:type="ecore:EReference" name="implicitVariables" upperBound="-1" 54 <eStructuralFeatures xsi:type="ecore:EReference" name="implicitVariables" upperBound="-1"
55 eType="#//ImplicitVariable" containment="true"/> 55 eType="#//ImplicitVariable" transient="true" containment="true"/>
56 </eClassifiers> 56 </eClassifiers>
57 <eClassifiers xsi:type="ecore:EClass" name="Assertion" eSuperTypes="#//Statement"> 57 <eClassifiers xsi:type="ecore:EClass" name="Assertion" eSuperTypes="#//Statement">
58 <eStructuralFeatures xsi:type="ecore:EReference" name="relation" eType="#//Relation"/> 58 <eStructuralFeatures xsi:type="ecore:EReference" name="relation" eType="#//Relation"/>
@@ -95,7 +95,7 @@
95 <eClassifiers xsi:type="ecore:EClass" name="VariableOrNodeArgument" eSuperTypes="#//Argument"> 95 <eClassifiers xsi:type="ecore:EClass" name="VariableOrNodeArgument" eSuperTypes="#//Argument">
96 <eStructuralFeatures xsi:type="ecore:EReference" name="variableOrNode" eType="#//VariableOrNode"/> 96 <eStructuralFeatures xsi:type="ecore:EReference" name="variableOrNode" eType="#//VariableOrNode"/>
97 <eStructuralFeatures xsi:type="ecore:EReference" name="singletonVariable" eType="#//ImplicitVariable" 97 <eStructuralFeatures xsi:type="ecore:EReference" name="singletonVariable" eType="#//ImplicitVariable"
98 containment="true"/> 98 transient="true" containment="true"/>
99 </eClassifiers> 99 </eClassifiers>
100 <eClassifiers xsi:type="ecore:EClass" name="EnumDeclaration" eSuperTypes="#//Relation #//Statement"> 100 <eClassifiers xsi:type="ecore:EClass" name="EnumDeclaration" eSuperTypes="#//Relation #//Statement">
101 <eStructuralFeatures xsi:type="ecore:EReference" name="literals" upperBound="-1" 101 <eStructuralFeatures xsi:type="ecore:EReference" name="literals" upperBound="-1"
diff --git a/language-model/src/main/resources/model/problem.genmodel b/language-model/src/main/resources/model/problem.genmodel
index 094533e7..3e0ee35e 100644
--- a/language-model/src/main/resources/model/problem.genmodel
+++ b/language-model/src/main/resources/model/problem.genmodel
@@ -1,7 +1,7 @@
1<?xml version="1.0" encoding="UTF-8"?> 1<?xml version="1.0" encoding="UTF-8"?>
2<genmodel:GenModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2<genmodel:GenModel 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" xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" 3 xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel"
4 modelDirectory="/language-model/src/main/emf-gen" creationIcons="false" 4 modelDirectory="/refinery-language-model/src/main/emf-gen" creationIcons="false"
5 editDirectory="/language-edit/src/main/emf-gen" editorDirectory="/org.eclipse.viatra.solver.language.model.editor/src-gen" 5 editDirectory="/language-edit/src/main/emf-gen" editorDirectory="/org.eclipse.viatra.solver.language.model.editor/src-gen"
6 modelPluginID="language-model" modelName="Problem" rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container" 6 modelPluginID="language-model" modelName="Problem" rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container"
7 codeFormatting="true" importerID="org.eclipse.emf.importer.ecore" complianceLevel="5.0" 7 codeFormatting="true" importerID="org.eclipse.emf.importer.ecore" complianceLevel="5.0"
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 add73c87..b2fcbaa9 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
@@ -290,7 +290,7 @@ class PartialModelMapperTest {
290 error invalidTaxStatus(Person p) <-> 290 error invalidTaxStatus(Person p) <->
291 taxStatus(p, child), children(p, _q). 291 taxStatus(p, child), children(p, _q).
292 292
293 individual family. 293 indiv family.
294 Family(family). 294 Family(family).
295 members(family, anne): true. 295 members(family, anne): true.
296 members(family, bob). 296 members(family, bob).
diff --git a/language-web/src/main/js/index.tsx b/language-web/src/main/js/index.tsx
index 3e077ba8..d368c9ba 100644
--- a/language-web/src/main/js/index.tsx
+++ b/language-web/src/main/js/index.tsx
@@ -38,7 +38,7 @@ direct rule createChild(p):
38 children(p, q) = true, 38 children(p, q) = true,
39 taxStatus(q, child) = true. 39 taxStatus(q, child) = true.
40 40
41individual family. 41indiv family.
42Family(family). 42Family(family).
43members(family, anne). 43members(family, anne).
44members(family, bob). 44members(family, bob).
diff --git a/language-web/src/main/js/language/problem.grammar b/language-web/src/main/js/language/problem.grammar
index 0cbfa831..bccc2e31 100644
--- a/language-web/src/main/js/language/problem.grammar
+++ b/language-web/src/main/js/language/problem.grammar
@@ -35,7 +35,7 @@ statement {
35 IndividualNodeName ":" Constant "." 35 IndividualNodeName ":" Constant "."
36 } | 36 } |
37 IndividualDeclaration { 37 IndividualDeclaration {
38 ckw<"individual"> sep<",", IndividualNodeName> "." 38 ckw<"indiv"> sep<",", IndividualNodeName> "."
39 } | 39 } |
40 ScopeDeclaration { 40 ScopeDeclaration {
41 kw<"scope"> sep<",", ScopeElement> "." 41 kw<"scope"> sep<",", ScopeElement> "."
diff --git a/language-web/src/main/js/language/problemLanguageSupport.ts b/language-web/src/main/js/language/problemLanguageSupport.ts
index 1dba3447..6508a2c0 100644
--- a/language-web/src/main/js/language/problemLanguageSupport.ts
+++ b/language-web/src/main/js/language/problemLanguageSupport.ts
@@ -27,7 +27,7 @@ const parserWithMetadata = (parser as LRParser).configure({
27 styleTags({ 27 styleTags({
28 LineComment: t.lineComment, 28 LineComment: t.lineComment,
29 BlockComment: t.blockComment, 29 BlockComment: t.blockComment,
30 'problem class enum pred rule individual scope': t.definitionKeyword, 30 'problem class enum pred rule indiv scope': t.definitionKeyword,
31 'abstract extends refers contains opposite error direct default': t.modifier, 31 'abstract extends refers contains opposite error direct default': t.modifier,
32 'true false unknown error': t.keyword, 32 'true false unknown error': t.keyword,
33 'new delete': t.operatorKeyword, 33 'new delete': t.operatorKeyword,
diff --git a/language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java b/language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java
index d34a1610..a26ce040 100644
--- a/language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java
+++ b/language-web/src/test/java/tools/refinery/language/web/ProblemWebSocketServletIntegrationTest.java
@@ -96,7 +96,7 @@ class ProblemWebSocketServletIntegrationTest {
96 case 0 -> session.getRemote().sendString( 96 case 0 -> session.getRemote().sendString(
97 "{\"id\":\"foo\",\"request\":{\"resource\":\"test.problem\",\"serviceType\":\"update\",\"fullText\":\"class Person.\n\"}}"); 97 "{\"id\":\"foo\",\"request\":{\"resource\":\"test.problem\",\"serviceType\":\"update\",\"fullText\":\"class Person.\n\"}}");
98 case 3 -> session.getRemote().sendString( 98 case 3 -> session.getRemote().sendString(
99 "{\"id\":\"bar\",\"request\":{\"resource\":\"test.problem\",\"serviceType\":\"update\",\"requiredStateId\":\"-80000000\",\"deltaText\":\"individual q.\nnode(q).\n\",\"deltaOffset\":\"0\",\"deltaReplaceLength\":\"0\"}}"); 99 "{\"id\":\"bar\",\"request\":{\"resource\":\"test.problem\",\"serviceType\":\"update\",\"requiredStateId\":\"-80000000\",\"deltaText\":\"indiv q.\nnode(q).\n\",\"deltaOffset\":\"0\",\"deltaReplaceLength\":\"0\"}}");
100 case 5 -> session.close(); 100 case 5 -> session.close();
101 } 101 }
102 } 102 }
diff --git a/language-web/src/test/java/tools/refinery/language/web/xtext/servlet/TransactionExecutorTest.java b/language-web/src/test/java/tools/refinery/language/web/xtext/servlet/TransactionExecutorTest.java
index 3229597e..5b8fedba 100644
--- a/language-web/src/test/java/tools/refinery/language/web/xtext/servlet/TransactionExecutorTest.java
+++ b/language-web/src/test/java/tools/refinery/language/web/xtext/servlet/TransactionExecutorTest.java
@@ -92,7 +92,7 @@ class TransactionExecutorTest {
92 var stateId = updateFullText(); 92 var stateId = updateFullText();
93 var responseHandler = sendRequestAndWaitForAllResponses( 93 var responseHandler = sendRequestAndWaitForAllResponses(
94 new XtextWebRequest("bar", Map.of("resource", RESOURCE_NAME, "serviceType", "update", "requiredStateId", 94 new XtextWebRequest("bar", Map.of("resource", RESOURCE_NAME, "serviceType", "update", "requiredStateId",
95 stateId, "deltaText", "individual q.\nnode(q).\n", "deltaOffset", "0", "deltaReplaceLength", "0"))); 95 stateId, "deltaText", "indiv q.\nnode(q).\n", "deltaOffset", "0", "deltaReplaceLength", "0")));
96 96
97 var captor = newCaptor(); 97 var captor = newCaptor();
98 verify(responseHandler, times(2)).onResponse(captor.capture()); 98 verify(responseHandler, times(2)).onResponse(captor.capture());
diff --git a/language/src/main/java/tools/refinery/language/Problem.xtext b/language/src/main/java/tools/refinery/language/Problem.xtext
index b7562759..26773047 100644
--- a/language/src/main/java/tools/refinery/language/Problem.xtext
+++ b/language/src/main/java/tools/refinery/language/Problem.xtext
@@ -109,12 +109,12 @@ ConstantArgument:
109 109
110Assertion: 110Assertion:
111 default?="default"? 111 default?="default"?
112 (relation=[Relation|QualifiedName] 112 (value=ShortLogicValue?
113 "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")"
114 ":" value=LogicValue |
115 value=ShortLogicValue?
116 relation=[Relation|QualifiedName] 113 relation=[Relation|QualifiedName]
117 "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")") 114 "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")"
115 | relation=[Relation|QualifiedName]
116 "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")"
117 ":" value=LogicValue)
118 "."; 118 ".";
119 119
120AssertionArgument: 120AssertionArgument:
@@ -174,7 +174,7 @@ ExactMultiplicity:
174 exactValue=INT; 174 exactValue=INT;
175 175
176IndividualDeclaration: 176IndividualDeclaration:
177 "individual" nodes+=EnumLiteral ("," nodes+=EnumLiteral)* "."; 177 "indiv" nodes+=EnumLiteral ("," nodes+=EnumLiteral)* ".";
178 178
179UpperBound returns ecore::EInt: 179UpperBound returns ecore::EInt:
180 INT | "*"; 180 INT | "*";
@@ -184,7 +184,7 @@ QualifiedName hidden():
184 184
185Identifier: 185Identifier:
186 ID | "true" | "false" | "unknown" | "error" | "class" | "abstract" | "extends" | "enum" | "pred" | 186 ID | "true" | "false" | "unknown" | "error" | "class" | "abstract" | "extends" | "enum" | "pred" |
187 "individual" | "problem" | "new" | "delete" | "direct" | "rule"; 187 "indiv" | "problem" | "new" | "delete" | "direct" | "rule";
188 188
189Integer returns ecore::EInt hidden(): 189Integer returns ecore::EInt hidden():
190 "-"? INT; 190 "-"? INT;
diff --git a/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java b/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
index 3c10d39e..975fdca2 100644
--- a/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
+++ b/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
@@ -53,7 +53,7 @@ public class ProblemValidator extends AbstractProblemValidator {
53 var variableOrNode = argument.getVariableOrNode(); 53 var variableOrNode = argument.getVariableOrNode();
54 if (variableOrNode instanceof Node node && !ProblemUtil.isIndividualNode(node)) { 54 if (variableOrNode instanceof Node node && !ProblemUtil.isIndividualNode(node)) {
55 var name = node.getName(); 55 var name = node.getName();
56 var message = "Only individual nodes can be referenced in predicates. Mark '%s' as individual with the declaration 'individual %s.'" 56 var message = "Only individual nodes can be referenced in predicates. Mark '%s' as individual with the declaration 'indiv %s.'"
57 .formatted(name, name); 57 .formatted(name, name);
58 error(message, argument, ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE, 58 error(message, argument, ProblemPackage.Literals.VARIABLE_OR_NODE_ARGUMENT__VARIABLE_OR_NODE,
59 INSIGNIFICANT_INDEX, NON_INDIVIDUAL_NODE_ISSUE); 59 INSIGNIFICANT_INDEX, NON_INDIVIDUAL_NODE_ISSUE);
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 9e357529..53d31a6c 100644
--- a/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.xtend
+++ b/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.xtend
@@ -46,7 +46,7 @@ class ProblemParsingTest {
46 error invalidTaxStatus(Person p) <-> 46 error invalidTaxStatus(Person p) <->
47 taxStatus(p, child), children(p, _q). 47 taxStatus(p, child), children(p, _q).
48 48
49 individual family. 49 indiv family.
50 Family(family). 50 Family(family).
51 members(family, anne): true. 51 members(family, anne): true.
52 members(family, bob). 52 members(family, bob).
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 5f669847..3a046341 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
@@ -81,7 +81,7 @@ class NodeScopingTest {
81 def void individualNodeInAssertionTest(String qualifiedNamePrefix, boolean namedProblem) { 81 def void individualNodeInAssertionTest(String qualifiedNamePrefix, boolean namedProblem) {
82 val it = parseHelper.parse(''' 82 val it = parseHelper.parse('''
83 «IF namedProblem»problem test.«ENDIF» 83 «IF namedProblem»problem test.«ENDIF»
84 individual a, b. 84 indiv a, b.
85 pred predicate(node x, node y) <-> node(x). 85 pred predicate(node x, node y) <-> node(x).
86 predicate(«qualifiedNamePrefix»a, «qualifiedNamePrefix»a). 86 predicate(«qualifiedNamePrefix»a, «qualifiedNamePrefix»a).
87 ?predicate(«qualifiedNamePrefix»a, «qualifiedNamePrefix»b). 87 ?predicate(«qualifiedNamePrefix»a, «qualifiedNamePrefix»b).
@@ -99,7 +99,7 @@ class NodeScopingTest {
99 def void individualNodeInNodeValueAssertionTest(String qualifiedNamePrefix, boolean namedProblem) { 99 def void individualNodeInNodeValueAssertionTest(String qualifiedNamePrefix, boolean namedProblem) {
100 val it = parseHelper.parse(''' 100 val it = parseHelper.parse('''
101 «IF namedProblem»problem test.«ENDIF» 101 «IF namedProblem»problem test.«ENDIF»
102 individual a. 102 indiv a.
103 «qualifiedNamePrefix»a: 16. 103 «qualifiedNamePrefix»a: 16.
104 ''') 104 ''')
105 assertThat(errors, empty) 105 assertThat(errors, empty)
@@ -112,7 +112,7 @@ class NodeScopingTest {
112 def void individualNodeInPredicateTest(String qualifiedNamePrefix, boolean namedProblem) { 112 def void individualNodeInPredicateTest(String qualifiedNamePrefix, boolean namedProblem) {
113 val it = parseHelper.parse(''' 113 val it = parseHelper.parse('''
114 «IF namedProblem»problem test.«ENDIF» 114 «IF namedProblem»problem test.«ENDIF»
115 individual b. 115 indiv b.
116 pred predicate(node a) <-> node(«qualifiedNamePrefix»b). 116 pred predicate(node a) <-> node(«qualifiedNamePrefix»b).
117 ''') 117 ''')
118 assertThat(errors, empty) 118 assertThat(errors, empty)
diff --git a/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java b/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java
new file mode 100644
index 00000000..802457cb
--- /dev/null
+++ b/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java
@@ -0,0 +1,215 @@
1package tools.refinery.language.tests.serializer;
2
3import static org.hamcrest.MatcherAssert.assertThat;
4import static org.hamcrest.Matchers.equalTo;
5
6import java.io.ByteArrayOutputStream;
7import java.io.IOException;
8import java.util.Map;
9import java.util.stream.Stream;
10
11import org.eclipse.emf.common.util.URI;
12import org.eclipse.emf.ecore.resource.Resource;
13import org.eclipse.emf.ecore.resource.ResourceSet;
14import org.eclipse.xtext.testing.InjectWith;
15import org.eclipse.xtext.testing.extensions.InjectionExtension;
16import org.junit.jupiter.api.BeforeEach;
17import org.junit.jupiter.api.Test;
18import org.junit.jupiter.api.extension.ExtendWith;
19import org.junit.jupiter.params.ParameterizedTest;
20import org.junit.jupiter.params.provider.Arguments;
21import org.junit.jupiter.params.provider.MethodSource;
22
23import com.google.inject.Inject;
24
25import tools.refinery.language.model.ProblemUtil;
26import tools.refinery.language.model.problem.Atom;
27import tools.refinery.language.model.problem.LogicValue;
28import tools.refinery.language.model.problem.Node;
29import tools.refinery.language.model.problem.PredicateDefinition;
30import tools.refinery.language.model.problem.Problem;
31import tools.refinery.language.model.problem.ProblemFactory;
32import tools.refinery.language.model.problem.Relation;
33import tools.refinery.language.model.problem.VariableOrNode;
34import tools.refinery.language.model.tests.ProblemTestUtil;
35import tools.refinery.language.tests.ProblemInjectorProvider;
36
37@ExtendWith(InjectionExtension.class)
38@InjectWith(ProblemInjectorProvider.class)
39public class ProblemSerializerTest {
40 @Inject
41 ResourceSet resourceSet;
42
43 @Inject
44 ProblemTestUtil testUtil;
45
46 Resource resource;
47
48 Problem problem;
49
50 Problem builtin;
51
52 @BeforeEach
53 void beforeEach() {
54 problem = ProblemFactory.eINSTANCE.createProblem();
55 resource = resourceSet.createResource(URI.createFileURI("test.problem"));
56 resource.getContents().add(problem);
57 builtin = ProblemUtil.getBuiltInLibrary(problem).get();
58 }
59
60 @ParameterizedTest
61 @MethodSource
62 void assertionTest(LogicValue value, String serializedAssertion) {
63 var pred = createPred();
64 var node = ProblemFactory.eINSTANCE.createNode();
65 node.setName("a");
66 var individualDeclaration = ProblemFactory.eINSTANCE.createIndividualDeclaration();
67 individualDeclaration.getNodes().add(node);
68 problem.getStatements().add(individualDeclaration);
69 createAssertion(pred, node, value);
70
71 assertSerializedResult("pred foo ( node p ) . indiv a . " + serializedAssertion);
72 }
73
74 static Stream<Arguments> assertionTest() {
75 return Stream.of(Arguments.of(LogicValue.TRUE, "foo ( a ) ."),
76 Arguments.of(LogicValue.FALSE, "! foo ( a ) ."),
77 Arguments.of(LogicValue.UNKNOWN, "? foo ( a ) ."),
78 Arguments.of(LogicValue.ERROR, "foo ( a ) : error ."));
79 }
80
81 @Test
82 void implicitNodeTest() {
83 var pred = createPred();
84 var node = ProblemFactory.eINSTANCE.createNode();
85 node.setName("a");
86 problem.getNodes().add(node);
87 createAssertion(pred, node);
88
89 assertSerializedResult("pred foo ( node p ) . foo ( a ) .");
90 }
91
92 private PredicateDefinition createPred() {
93 var pred = ProblemFactory.eINSTANCE.createPredicateDefinition();
94 pred.setName("foo");
95 var parameter = ProblemFactory.eINSTANCE.createParameter();
96 var nodeType = testUtil.findClass(builtin, "node");
97 parameter.setParameterType(nodeType);
98 parameter.setName("p");
99 pred.getParameters().add(parameter);
100 problem.getStatements().add(pred);
101 return pred;
102 }
103
104 @Test
105 void newNodeTest() {
106 var classDeclaration = ProblemFactory.eINSTANCE.createClassDeclaration();
107 classDeclaration.setName("Foo");
108 var newNode = ProblemFactory.eINSTANCE.createNode();
109 newNode.setName("new");
110 classDeclaration.setNewNode(newNode);
111 problem.getStatements().add(classDeclaration);
112 createAssertion(classDeclaration, newNode);
113
114 assertSerializedResult("class Foo . Foo ( Foo::new ) .");
115 }
116
117 private void createAssertion(Relation relation, Node node) {
118 createAssertion(relation, node, LogicValue.TRUE);
119 }
120
121 private void createAssertion(Relation relation, Node node, LogicValue value) {
122 var assertion = ProblemFactory.eINSTANCE.createAssertion();
123 assertion.setRelation(relation);
124 var argument = ProblemFactory.eINSTANCE.createNodeAssertionArgument();
125 argument.setNode(node);
126 assertion.getArguments().add(argument);
127 assertion.setValue(value);
128 problem.getStatements().add(assertion);
129 }
130
131 @Test
132 void implicitVariableTest() {
133 var pred = ProblemFactory.eINSTANCE.createPredicateDefinition();
134 pred.setName("foo");
135 var nodeType = testUtil.findClass(builtin, "node");
136 var parameter1 = ProblemFactory.eINSTANCE.createParameter();
137 parameter1.setParameterType(nodeType);
138 parameter1.setName("p1");
139 pred.getParameters().add(parameter1);
140 var parameter2 = ProblemFactory.eINSTANCE.createParameter();
141 parameter2.setParameterType(nodeType);
142 parameter2.setName("p2");
143 pred.getParameters().add(parameter2);
144 var conjunction = ProblemFactory.eINSTANCE.createConjunction();
145 var variable = ProblemFactory.eINSTANCE.createImplicitVariable();
146 variable.setName("q");
147 conjunction.getImplicitVariables().add(variable);
148 var equals = testUtil.reference(nodeType, "equals");
149 conjunction.getLiterals().add(createAtom(equals, parameter1, variable));
150 conjunction.getLiterals().add(createAtom(equals, variable, parameter2));
151 pred.getBodies().add(conjunction);
152 problem.getStatements().add(pred);
153
154 assertSerializedResult("pred foo ( node p1 , node p2 ) <-> equals ( p1 , q ) , equals ( q , p2 ) .");
155 }
156
157 private Atom createAtom(Relation relation, VariableOrNode variable1, VariableOrNode variable2) {
158 var atom = ProblemFactory.eINSTANCE.createAtom();
159 atom.setRelation(relation);
160 var arg1 = ProblemFactory.eINSTANCE.createVariableOrNodeArgument();
161 arg1.setVariableOrNode(variable1);
162 atom.getArguments().add(arg1);
163 var arg2 = ProblemFactory.eINSTANCE.createVariableOrNodeArgument();
164 arg2.setVariableOrNode(variable2);
165 atom.getArguments().add(arg2);
166 return atom;
167 }
168
169 @Test
170 void singletonVariableTest() {
171 var pred = ProblemFactory.eINSTANCE.createPredicateDefinition();
172 pred.setName("foo");
173 var nodeType = testUtil.findClass(builtin, "node");
174 var parameter = ProblemFactory.eINSTANCE.createParameter();
175 parameter.setParameterType(nodeType);
176 parameter.setName("p");
177 pred.getParameters().add(parameter);
178 var conjunction = ProblemFactory.eINSTANCE.createConjunction();
179 var atom = ProblemFactory.eINSTANCE.createAtom();
180 var equals = testUtil.reference(nodeType, "equals");
181 atom.setRelation(equals);
182 var arg1 = ProblemFactory.eINSTANCE.createVariableOrNodeArgument();
183 arg1.setVariableOrNode(parameter);
184 atom.getArguments().add(arg1);
185 var arg2 = ProblemFactory.eINSTANCE.createVariableOrNodeArgument();
186 var variable = ProblemFactory.eINSTANCE.createImplicitVariable();
187 variable.setName("_q");
188 arg2.setSingletonVariable(variable);
189 arg2.setVariableOrNode(variable);
190 atom.getArguments().add(arg2);
191 conjunction.getLiterals().add(atom);
192 pred.getBodies().add(conjunction);
193 problem.getStatements().add(pred);
194
195 assertSerializedResult("pred foo ( node p ) <-> equals ( p , _q ) .");
196 }
197
198 private void assertSerializedResult(String expected) {
199 var outputStream = new ByteArrayOutputStream();
200 try {
201 resource.save(outputStream, Map.of());
202 } catch (IOException e) {
203 throw new AssertionError("Failed to serialize problem", e);
204 } finally {
205 try {
206 outputStream.close();
207 } catch (IOException e) {
208 // Nothing to handle in a test.
209 }
210 }
211 var problemString = outputStream.toString();
212
213 assertThat(problemString, equalTo(expected));
214 }
215}