aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language/src
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/language/src')
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe22
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/Problem.xtext17
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java10
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java4
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java6
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java20
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java12
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java2
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java8
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java26
-rw-r--r--subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java18
-rw-r--r--subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java5
12 files changed, 74 insertions, 56 deletions
diff --git a/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2 b/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
index 59eba8f7..863e55d4 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
+++ b/subprojects/language/src/main/java/tools/refinery/language/GenerateProblem.mwe2
@@ -51,7 +51,7 @@ Workflow {
51 51
52 language = StandardLanguage { 52 language = StandardLanguage {
53 name = 'tools.refinery.language.Problem' 53 name = 'tools.refinery.language.Problem'
54 fileExtensions = 'problem' 54 fileExtensions = 'refinery,problem'
55 referencedResource = 'platform:/resource/tools.refinery.refinery-language-model/model/problem.genmodel' 55 referencedResource = 'platform:/resource/tools.refinery.refinery-language-model/model/problem.genmodel'
56 serializer = { 56 serializer = {
57 generateStub = false 57 generateStub = false
diff --git a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
index 0fb96954..c5c42ebe 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
+++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
@@ -9,13 +9,16 @@ import "http://www.eclipse.org/emf/2002/Ecore" as ecore
9import "https://refinery.tools/emf/2021/Problem" 9import "https://refinery.tools/emf/2021/Problem"
10 10
11Problem: 11Problem:
12 ("problem" name=Identifier ".")? 12 (kind=ModuleKind name=QualifiedName? ".")?
13 statements+=Statement*; 13 statements+=Statement*;
14 14
15enum ModuleKind:
16 PROBLEM="problem" | MODULE="module";
17
15Statement: 18Statement:
16 Assertion | ClassDeclaration | EnumDeclaration | 19 Assertion | ClassDeclaration | EnumDeclaration |
17 PredicateDefinition | /* FunctionDefinition | RuleDefinition | */ 20 PredicateDefinition | /* FunctionDefinition | RuleDefinition | */
18 ScopeDeclaration | IndividualDeclaration; 21 ScopeDeclaration | NodeDeclaration;
19 22
20ClassDeclaration: 23ClassDeclaration:
21 abstract?="abstract"? "class" 24 abstract?="abstract"? "class"
@@ -252,8 +255,11 @@ RangeMultiplicity:
252ExactMultiplicity: 255ExactMultiplicity:
253 exactValue=INT; 256 exactValue=INT;
254 257
255IndividualDeclaration: 258NodeDeclaration:
256 "indiv" nodes+=EnumLiteral ("," nodes+=EnumLiteral)* "."; 259 kind=NodeKind nodes+=EnumLiteral ("," nodes+=EnumLiteral)* ".";
260
261enum NodeKind:
262 NODE="node" | ATOM="atom" | MULTI="multi";
257 263
258UpperBound returns ecore::EInt: 264UpperBound returns ecore::EInt:
259 INT | "*"; 265 INT | "*";
@@ -268,7 +274,8 @@ Identifier:
268 NonContainmentIdentifier | "contains" | "container"; 274 NonContainmentIdentifier | "contains" | "container";
269 275
270NonContainmentIdentifier: 276NonContainmentIdentifier:
271 ID | "contained" | "sum" | "prod" | "min" | "max"; 277 ID | "node" | "atom" | "multi" | "contained" |
278 "sum" | "prod" | "min" | "max" | "problem" | "module";
272 279
273Real returns ecore::EDouble: 280Real returns ecore::EDouble:
274 EXPONENTIAL | INT "." (INT | EXPONENTIAL); 281 EXPONENTIAL | INT "." (INT | EXPONENTIAL);
diff --git a/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java b/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java
index 0f3bd3ee..0b87e8bb 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/formatting2/ProblemFormatter.java
@@ -23,7 +23,7 @@ public class ProblemFormatter extends AbstractJavaFormatter {
23 protected void format(Problem problem, IFormattableDocument doc) { 23 protected void format(Problem problem, IFormattableDocument doc) {
24 doc.prepend(problem, this::noSpace); 24 doc.prepend(problem, this::noSpace);
25 var region = regionFor(problem); 25 var region = regionFor(problem);
26 doc.append(region.keyword("problem"), this::oneSpace); 26 doc.append(region.feature(ProblemPackage.Literals.PROBLEM__KIND), this::oneSpace);
27 doc.prepend(region.keyword("."), this::noSpace); 27 doc.prepend(region.keyword("."), this::noSpace);
28 appendNewLines(doc, region.keyword("."), this::twoNewLines); 28 appendNewLines(doc, region.keyword("."), this::twoNewLines);
29 for (var statement : problem.getStatements()) { 29 for (var statement : problem.getStatements()) {
@@ -132,10 +132,10 @@ public class ProblemFormatter extends AbstractJavaFormatter {
132 } 132 }
133 } 133 }
134 134
135 protected void format(IndividualDeclaration individualDeclaration, IFormattableDocument doc) { 135 protected void format(NodeDeclaration nodeDeclaration, IFormattableDocument doc) {
136 surroundNewLines(doc, individualDeclaration, this::singleNewLine); 136 surroundNewLines(doc, nodeDeclaration, this::singleNewLine);
137 var region = regionFor(individualDeclaration); 137 var region = regionFor(nodeDeclaration);
138 doc.append(region.keyword("indiv"), this::oneSpace); 138 doc.append(region.feature(ProblemPackage.Literals.NODE_DECLARATION__KIND), this::oneSpace);
139 formatList(region, ",", doc); 139 formatList(region, ",", doc);
140 doc.prepend(region.keyword("."), this::noSpace); 140 doc.prepend(region.keyword("."), this::noSpace);
141 } 141 }
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
index 29eaad84..c81431e5 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemLocationInFileProvider.java
@@ -25,10 +25,10 @@ public class ProblemLocationInFileProvider extends DefaultLocationInFileProvider
25 } 25 }
26 26
27 protected ITextRegion getNodeTextRegion(Node node, RegionDescription query) { 27 protected ITextRegion getNodeTextRegion(Node node, RegionDescription query) {
28 if (ProblemUtil.isIndividualNode(node)) { 28 if (ProblemUtil.isDeclaredNode(node)) {
29 return super.doGetTextRegion(node, query); 29 return super.doGetTextRegion(node, query);
30 } 30 }
31 if (ProblemUtil.isNewNode(node)) { 31 if (ProblemUtil.isMultiNode(node)) {
32 EObject container = node.eContainer(); 32 EObject container = node.eContainer();
33 return doGetTextRegion(container, query); 33 return doGetTextRegion(container, query);
34 } 34 }
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
index c04c7d09..79dad6e7 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemResourceDescriptionStrategy.java
@@ -91,8 +91,7 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
91 return false; 91 return false;
92 } 92 }
93 if (eObject instanceof Node node) { 93 if (eObject instanceof Node node) {
94 // Only enum literals and new nodes are visible across problem files. 94 return !ProblemUtil.isImplicitNode(node);
95 return ProblemUtil.isIndividualNode(node) || ProblemUtil.isNewNode(node);
96 } 95 }
97 return true; 96 return true;
98 } 97 }
@@ -111,7 +110,7 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
111 110
112 protected boolean shouldExportSimpleName(EObject eObject) { 111 protected boolean shouldExportSimpleName(EObject eObject) {
113 if (eObject instanceof Node node) { 112 if (eObject instanceof Node node) {
114 return !ProblemUtil.isNewNode(node); 113 return !ProblemUtil.isMultiNode(node);
115 } 114 }
116 if (eObject instanceof PredicateDefinition predicateDefinition) { 115 if (eObject instanceof PredicateDefinition predicateDefinition) {
117 return !ProblemUtil.isInvalidMultiplicityConstraint(predicateDefinition); 116 return !ProblemUtil.isInvalidMultiplicityConstraint(predicateDefinition);
@@ -146,6 +145,5 @@ public class ProblemResourceDescriptionStrategy extends DefaultResourceDescripti
146 return false; 145 return false;
147 } 146 }
148 return eObject instanceof ClassDeclaration || eObject instanceof EnumDeclaration; 147 return eObject instanceof ClassDeclaration || eObject instanceof EnumDeclaration;
149
150 } 148 }
151} 149}
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java
index 7b6407e1..ee0e141d 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemUtil.java
@@ -54,14 +54,24 @@ public final class ProblemUtil {
54 return eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isError(); 54 return eObject instanceof PredicateDefinition predicateDefinition && predicateDefinition.isError();
55 } 55 }
56 56
57 public static boolean isIndividualNode(Node node) { 57 public static boolean isAtomNode(Node node) {
58 var containingFeature = node.eContainingFeature(); 58 var containingFeature = node.eContainingFeature();
59 return containingFeature == ProblemPackage.Literals.INDIVIDUAL_DECLARATION__NODES 59 if (containingFeature == ProblemPackage.Literals.NODE_DECLARATION__NODES) {
60 || containingFeature == ProblemPackage.Literals.ENUM_DECLARATION__LITERALS; 60 return ((NodeDeclaration) node.eContainer()).getKind() == NodeKind.ATOM;
61 }
62 return containingFeature == ProblemPackage.Literals.ENUM_DECLARATION__LITERALS;
63 }
64
65 public static boolean isMultiNode(Node node) {
66 var containingFeature = node.eContainingFeature();
67 if (containingFeature == ProblemPackage.Literals.NODE_DECLARATION__NODES) {
68 return ((NodeDeclaration) node.eContainer()).getKind() == NodeKind.MULTI;
69 }
70 return containingFeature == ProblemPackage.Literals.CLASS_DECLARATION__NEW_NODE;
61 } 71 }
62 72
63 public static boolean isNewNode(Node node) { 73 public static boolean isDeclaredNode(Node node) {
64 return node.eContainingFeature() == ProblemPackage.Literals.CLASS_DECLARATION__NEW_NODE; 74 return node.eContainingFeature() == ProblemPackage.Literals.NODE_DECLARATION__NODES;
65 } 75 }
66 76
67 public static boolean isInvalidMultiplicityConstraint(PredicateDefinition predicateDefinition) { 77 public static boolean isInvalidMultiplicityConstraint(PredicateDefinition predicateDefinition) {
diff --git a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
index 8bda4b95..a95e8b3c 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/validation/ProblemValidator.java
@@ -84,7 +84,7 @@ public class ProblemValidator extends AbstractProblemValidator {
84 @Check 84 @Check
85 public void checkNodeConstants(VariableOrNodeExpr expr) { 85 public void checkNodeConstants(VariableOrNodeExpr expr) {
86 var variableOrNode = expr.getVariableOrNode(); 86 var variableOrNode = expr.getVariableOrNode();
87 if (variableOrNode instanceof Node node && !ProblemUtil.isIndividualNode(node)) { 87 if (variableOrNode instanceof Node node && !ProblemUtil.isAtomNode(node)) {
88 var name = node.getName(); 88 var name = node.getName();
89 var message = ("Only individuals can be referenced in predicates. " + 89 var message = ("Only individuals can be referenced in predicates. " +
90 "Mark '%s' as individual with the declaration 'indiv %s.'").formatted(name, name); 90 "Mark '%s' as individual with the declaration 'indiv %s.'").formatted(name, name);
@@ -96,16 +96,16 @@ public class ProblemValidator extends AbstractProblemValidator {
96 @Check 96 @Check
97 public void checkUniqueDeclarations(Problem problem) { 97 public void checkUniqueDeclarations(Problem problem) {
98 var relations = new ArrayList<Relation>(); 98 var relations = new ArrayList<Relation>();
99 var individuals = new ArrayList<Node>(); 99 var nodes = new ArrayList<Node>();
100 for (var statement : problem.getStatements()) { 100 for (var statement : problem.getStatements()) {
101 if (statement instanceof Relation relation) { 101 if (statement instanceof Relation relation) {
102 relations.add(relation); 102 relations.add(relation);
103 } else if (statement instanceof IndividualDeclaration individualDeclaration) { 103 } else if (statement instanceof NodeDeclaration nodeDeclaration) {
104 individuals.addAll(individualDeclaration.getNodes()); 104 nodes.addAll(nodeDeclaration.getNodes());
105 } 105 }
106 } 106 }
107 checkUniqueSimpleNames(relations); 107 checkUniqueSimpleNames(relations);
108 checkUniqueSimpleNames(individuals); 108 checkUniqueSimpleNames(nodes);
109 } 109 }
110 110
111 @Check 111 @Check
@@ -362,7 +362,7 @@ public class ProblemValidator extends AbstractProblemValidator {
362 return; 362 return;
363 } 363 }
364 var node = getNodeArgumentForMultiObjectAssertion(arguments.get(0)); 364 var node = getNodeArgumentForMultiObjectAssertion(arguments.get(0));
365 if (node != null && !node.eIsProxy() && ProblemUtil.isIndividualNode(node)) { 365 if (node != null && !node.eIsProxy() && ProblemUtil.isAtomNode(node)) {
366 acceptError("Individual nodes must exist.", assertion, null, 0, UNSUPPORTED_ASSERTION_ISSUE); 366 acceptError("Individual nodes must exist.", assertion, null, 0, UNSUPPORTED_ASSERTION_ISSUE);
367 } 367 }
368 } 368 }
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java
index 72d57f54..17ae5fbb 100644
--- a/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java
+++ b/subprojects/language/src/test/java/tools/refinery/language/tests/ProblemParsingTest.java
@@ -42,7 +42,7 @@ class ProblemParsingTest {
42 error invalidTaxStatus(Person p) <-> 42 error invalidTaxStatus(Person p) <->
43 taxStatus(p, CHILD), children(p, _q). 43 taxStatus(p, CHILD), children(p, _q).
44 44
45 indiv family. 45 atom family.
46 Family(family). 46 Family(family).
47 members(family, anne): true. 47 members(family, anne): true.
48 members(family, bob). 48 members(family, bob).
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java
index f688d970..4a15f9de 100644
--- a/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java
+++ b/subprojects/language/src/test/java/tools/refinery/language/tests/formatting2/ProblemFormatterTest.java
@@ -183,8 +183,8 @@ class ProblemFormatterTest {
183 } 183 }
184 184
185 @Test 185 @Test
186 void individualDeclarationTest() { 186 void atomDeclarationTest() {
187 testFormatter(" indiv a , b . ", "indiv a, b.\n"); 187 testFormatter(" atom a , b . ", "atom a, b.\n");
188 } 188 }
189 189
190 @Test 190 @Test
@@ -194,7 +194,7 @@ class ProblemFormatterTest {
194 pred foo(node a). 194 pred foo(node a).
195 class Foo. 195 class Foo.
196 foo(n1, n2). 196 foo(n1, n2).
197 indiv i1. 197 atom i1.
198 !foo(i1, n1). 198 !foo(i1, n1).
199 pred bar(node a, node b). 199 pred bar(node a, node b).
200 pred quux(). 200 pred quux().
@@ -207,7 +207,7 @@ class ProblemFormatterTest {
207 class Foo. 207 class Foo.
208 208
209 foo(n1, n2). 209 foo(n1, n2).
210 indiv i1. 210 atom i1.
211 !foo(i1, n1). 211 !foo(i1, n1).
212 212
213 pred bar(node a, node b). 213 pred bar(node a, node b).
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java
index e76d2993..bc0320a6 100644
--- a/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java
+++ b/subprojects/language/src/test/java/tools/refinery/language/tests/scoping/NodeScopingTest.java
@@ -69,35 +69,35 @@ class NodeScopingTest {
69 } 69 }
70 70
71 @ParameterizedTest 71 @ParameterizedTest
72 @MethodSource("individualNodeReferenceSource") 72 @MethodSource("atomNodeReferenceSource")
73 void individualNodeInAssertionTest(String qualifiedNamePrefix, boolean namedProblem) { 73 void atomNodeInAssertionTest(String qualifiedNamePrefix, boolean namedProblem) {
74 var problem = parse(""" 74 var problem = parse("""
75 indiv a, b. 75 atom a, b.
76 pred predicate(node x, node y) <-> node(x). 76 pred predicate(node x, node y) <-> node(x).
77 predicate({PARAM}a, {PARAM}a). 77 predicate({PARAM}a, {PARAM}a).
78 ?predicate({PARAM}a, {PARAM}b). 78 ?predicate({PARAM}a, {PARAM}b).
79 """, qualifiedNamePrefix, namedProblem); 79 """, qualifiedNamePrefix, namedProblem);
80 assertThat(problem.getResourceErrors(), empty()); 80 assertThat(problem.getResourceErrors(), empty());
81 assertThat(problem.nodeNames(), empty()); 81 assertThat(problem.nodeNames(), empty());
82 assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.individualNode("a"))); 82 assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.atomNode("a")));
83 assertThat(problem.assertion(0).arg(1).node(), equalTo(problem.individualNode("a"))); 83 assertThat(problem.assertion(0).arg(1).node(), equalTo(problem.atomNode("a")));
84 assertThat(problem.assertion(1).arg(0).node(), equalTo(problem.individualNode("a"))); 84 assertThat(problem.assertion(1).arg(0).node(), equalTo(problem.atomNode("a")));
85 assertThat(problem.assertion(1).arg(1).node(), equalTo(problem.individualNode("b"))); 85 assertThat(problem.assertion(1).arg(1).node(), equalTo(problem.atomNode("b")));
86 } 86 }
87 87
88 @ParameterizedTest 88 @ParameterizedTest
89 @MethodSource("individualNodeReferenceSource") 89 @MethodSource("atomNodeReferenceSource")
90 void individualNodeInPredicateTest(String qualifiedNamePrefix, boolean namedProblem) { 90 void atomNodeInPredicateTest(String qualifiedNamePrefix, boolean namedProblem) {
91 var problem = parse(""" 91 var problem = parse("""
92 indiv b. 92 atom b.
93 pred predicate(node a) <-> node({PARAM}b). 93 pred predicate(node a) <-> node({PARAM}b).
94 """); 94 """, qualifiedNamePrefix, namedProblem);
95 assertThat(problem.getResourceErrors(), empty()); 95 assertThat(problem.getResourceErrors(), empty());
96 assertThat(problem.nodeNames(), empty()); 96 assertThat(problem.nodeNames(), empty());
97 assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(), equalTo(problem.individualNode("b"))); 97 assertThat(problem.pred("predicate").conj(0).lit(0).arg(0).node(), equalTo(problem.atomNode("b")));
98 } 98 }
99 99
100 static Stream<Arguments> individualNodeReferenceSource() { 100 static Stream<Arguments> atomNodeReferenceSource() {
101 return Stream.of(Arguments.of("", false), Arguments.of("", true), Arguments.of("test::", true)); 101 return Stream.of(Arguments.of("", false), Arguments.of("", true), Arguments.of("test::", true));
102 } 102 }
103 103
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java
index 65675b6b..ad583f8e 100644
--- a/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java
+++ b/subprojects/language/src/test/java/tools/refinery/language/tests/serializer/ProblemSerializerTest.java
@@ -56,15 +56,16 @@ class ProblemSerializerTest {
56 var pred = createPred(); 56 var pred = createPred();
57 var node = ProblemFactory.eINSTANCE.createNode(); 57 var node = ProblemFactory.eINSTANCE.createNode();
58 node.setName("a"); 58 node.setName("a");
59 var individualDeclaration = ProblemFactory.eINSTANCE.createIndividualDeclaration(); 59 var atomDeclaration = ProblemFactory.eINSTANCE.createNodeDeclaration();
60 individualDeclaration.getNodes().add(node); 60 atomDeclaration.setKind(NodeKind.ATOM);
61 problem.getStatements().add(individualDeclaration); 61 atomDeclaration.getNodes().add(node);
62 problem.getStatements().add(atomDeclaration);
62 createAssertion(pred, node, value); 63 createAssertion(pred, node, value);
63 64
64 assertSerializedResult(""" 65 assertSerializedResult("""
65 pred foo(node p). 66 pred foo(node p).
66 67
67 indiv a. 68 atom a.
68 """ + serializedAssertion + "\n"); 69 """ + serializedAssertion + "\n");
69 } 70 }
70 71
@@ -79,15 +80,16 @@ class ProblemSerializerTest {
79 var pred = createPred(); 80 var pred = createPred();
80 var node = ProblemFactory.eINSTANCE.createNode(); 81 var node = ProblemFactory.eINSTANCE.createNode();
81 node.setName("a"); 82 node.setName("a");
82 var individualDeclaration = ProblemFactory.eINSTANCE.createIndividualDeclaration(); 83 var atomDeclaration = ProblemFactory.eINSTANCE.createNodeDeclaration();
83 individualDeclaration.getNodes().add(node); 84 atomDeclaration.setKind(NodeKind.ATOM);
84 problem.getStatements().add(individualDeclaration); 85 atomDeclaration.getNodes().add(node);
86 problem.getStatements().add(atomDeclaration);
85 createAssertion(pred, node, value, true); 87 createAssertion(pred, node, value, true);
86 88
87 assertSerializedResult(""" 89 assertSerializedResult("""
88 pred foo(node p). 90 pred foo(node p).
89 91
90 indiv a. 92 atom a.
91 default\040""" + serializedAssertion + "\n"); 93 default\040""" + serializedAssertion + "\n");
92 } 94 }
93 95
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java
index fc51ff57..58bfce44 100644
--- a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java
+++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedProblem.java
@@ -67,8 +67,9 @@ public record WrappedProblem(Problem problem) {
67 return ProblemNavigationUtil.named(problem.getNodes(), name); 67 return ProblemNavigationUtil.named(problem.getNodes(), name);
68 } 68 }
69 69
70 public Node individualNode(String name) { 70 public Node atomNode(String name) {
71 var uniqueNodes = statementsOfType(IndividualDeclaration.class) 71 var uniqueNodes = statementsOfType(NodeDeclaration.class)
72 .filter(declaration -> declaration.getKind() == NodeKind.ATOM)
72 .flatMap(declaration -> declaration.getNodes().stream()); 73 .flatMap(declaration -> declaration.getNodes().stream());
73 return ProblemNavigationUtil.named(uniqueNodes, name); 74 return ProblemNavigationUtil.named(uniqueNodes, name);
74 } 75 }