aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-09-13 20:39:27 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-09-14 12:10:43 +0200
commit748bf89911359bffbfafe354e522f7d656488146 (patch)
tree555fe86e0a068eda1f84538faaca8d6e76fd3bd8 /subprojects/language
parentchore(deps): bump dependencies (diff)
downloadrefinery-748bf89911359bffbfafe354e522f7d656488146.tar.gz
refinery-748bf89911359bffbfafe354e522f7d656488146.tar.zst
refinery-748bf89911359bffbfafe354e522f7d656488146.zip
refactor(language): clarify containment hierarchy
Diffstat (limited to 'subprojects/language')
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/Problem.xtext27
-rw-r--r--subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java37
-rw-r--r--subprojects/language/src/main/resources/tools/refinery/language/builtin.problem19
3 files changed, 74 insertions, 9 deletions
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 f7b86dca..2a5af628 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
+++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext
@@ -26,15 +26,23 @@ EnumDeclaration:
26EnumLiteral returns Node: 26EnumLiteral returns Node:
27 name=Identifier; 27 name=Identifier;
28 28
29enum ReferenceKind:
30 REFERENCE="refers" | CONTAINMENT="contains" | CONTAINER="container";
31
29ReferenceDeclaration: 32ReferenceDeclaration:
30 (containment?="contains" | "refers")? 33 (
31 referenceType=[Relation|QualifiedName] 34 kind=ReferenceKind referenceType=[Relation|QualifiedName] |
35 referenceType=[Relation|NonRelationKindQualifiedName]
36 )
32 ("[" multiplicity=Multiplicity "]")? 37 ("[" multiplicity=Multiplicity "]")?
33 name=Identifier 38 name=Identifier
34 ("opposite" opposite=[ReferenceDeclaration|QualifiedName])?; 39 ("opposite" opposite=[ReferenceDeclaration|QualifiedName])?;
35 40
41enum PredicateKind:
42 ERROR="error" | CONTAINED="contained" | CONTAINMENT="containment";
43
36PredicateDefinition: 44PredicateDefinition:
37 (error?="error" "pred"? | "pred") 45 (kind=PredicateKind "pred"? | "pred")
38 name=Identifier 46 name=Identifier
39 "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" 47 "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")"
40 ("<->" bodies+=Conjunction (";" bodies+=Conjunction)*)? 48 ("<->" bodies+=Conjunction (";" bodies+=Conjunction)*)?
@@ -150,7 +158,7 @@ ScopeDeclaration:
150 "scope" typeScopes+=TypeScope ("," typeScopes+=TypeScope)* "."; 158 "scope" typeScopes+=TypeScope ("," typeScopes+=TypeScope)* ".";
151 159
152TypeScope: 160TypeScope:
153 targetType=[ClassDeclaration|QualifiedName] 161 targetType=[Relation|QualifiedName]
154 (increment?="+=" | "=") 162 (increment?="+=" | "=")
155 multiplicity=DefiniteMultiplicity; 163 multiplicity=DefiniteMultiplicity;
156 164
@@ -175,12 +183,19 @@ IndividualDeclaration:
175UpperBound returns ecore::EInt: 183UpperBound returns ecore::EInt:
176 INT | "*"; 184 INT | "*";
177 185
186NonRelationKindQualifiedName hidden():
187 NonRelationKindIdentifier ("::" Identifier)*;
188
178QualifiedName hidden(): 189QualifiedName hidden():
179 Identifier ("::" Identifier)*; 190 Identifier ("::" Identifier)*;
180 191
192NonRelationKindIdentifier:
193 ID | "true" | "false" | "unknown" | "error" | "class" | "abstract" | "extends" | "enum" |
194 "pred" | "indiv" | "problem" | "new" | "delete" | "rule" | "may" | "must" | "current" |
195 "count" | "default" | "scope" | "contained" | "containment";
196
181Identifier: 197Identifier:
182 ID | "true" | "false" | "unknown" | "error" | "class" | "abstract" | "extends" | "enum" | "pred" | 198 NonRelationKindIdentifier | "refers" | "contains" | "container";
183 "indiv" | "problem" | "new" | "delete" | "rule" | "may" | "must" | "current" | "count";
184 199
185Integer returns ecore::EInt hidden(): 200Integer returns ecore::EInt hidden():
186 "-"? INT; 201 "-"? INT;
diff --git a/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java b/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java
index b1e39176..0be296fd 100644
--- a/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java
+++ b/subprojects/language/src/main/java/tools/refinery/language/ProblemUtil.java
@@ -27,6 +27,10 @@ public final class ProblemUtil {
27 27
28 public static final String NODE_CLASS_NAME = "node"; 28 public static final String NODE_CLASS_NAME = "node";
29 29
30 public static final String DOMAIN_CLASS_NAME = "domain";
31
32 public static final String DATA_CLASS_NAME = "data";
33
30 private ProblemUtil() { 34 private ProblemUtil() {
31 throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); 35 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
32 } 36 }
@@ -80,15 +84,15 @@ public final class ProblemUtil {
80 return false; 84 return false;
81 } 85 }
82 86
83 public static Optional<ClassDeclaration> getNodeClassDeclaration(EObject context) { 87 public static Optional<ClassDeclaration> getBuiltinClassDeclaration(EObject context, String name) {
84 return getBuiltInLibrary(context).flatMap(problem -> problem.getStatements().stream() 88 return getBuiltInLibrary(context).flatMap(problem -> problem.getStatements().stream()
85 .filter(ClassDeclaration.class::isInstance).map(ClassDeclaration.class::cast) 89 .filter(ClassDeclaration.class::isInstance).map(ClassDeclaration.class::cast)
86 .filter(declaration -> NODE_CLASS_NAME.equals(declaration.getName())).findFirst()); 90 .filter(declaration -> name.equals(declaration.getName())).findFirst());
87 } 91 }
88 92
89 public static Collection<ClassDeclaration> getSuperclassesAndSelf(ClassDeclaration classDeclaration) { 93 public static Collection<ClassDeclaration> getSuperclassesAndSelf(ClassDeclaration classDeclaration) {
90 Set<ClassDeclaration> found = new HashSet<>(); 94 Set<ClassDeclaration> found = new HashSet<>();
91 getNodeClassDeclaration(classDeclaration).ifPresent(found::add); 95 getBuiltinClassDeclaration(classDeclaration, NODE_CLASS_NAME).ifPresent(found::add);
92 Deque<ClassDeclaration> queue = new ArrayDeque<>(); 96 Deque<ClassDeclaration> queue = new ArrayDeque<>();
93 queue.addLast(classDeclaration); 97 queue.addLast(classDeclaration);
94 while (!queue.isEmpty()) { 98 while (!queue.isEmpty()) {
@@ -102,6 +106,11 @@ public final class ProblemUtil {
102 } 106 }
103 } 107 }
104 } 108 }
109 getBuiltinClassDeclaration(classDeclaration, DATA_CLASS_NAME).ifPresent((dataClassDelcaration) -> {
110 if (!found.contains(dataClassDelcaration)) {
111 getBuiltinClassDeclaration(classDeclaration, DOMAIN_CLASS_NAME).ifPresent(found::add);
112 }
113 });
105 return found; 114 return found;
106 } 115 }
107 116
@@ -113,6 +122,28 @@ public final class ProblemUtil {
113 return referenceDeclarations; 122 return referenceDeclarations;
114 } 123 }
115 124
125 public static boolean isDataClass(Relation relation) {
126 if (relation instanceof ClassDeclaration classDeclaration) {
127 var supertypes = getSuperclassesAndSelf(classDeclaration);
128 return getBuiltinClassDeclaration(classDeclaration, DATA_CLASS_NAME).map(supertypes::contains)
129 .orElse(false);
130 }
131 return false;
132 }
133
134 public static boolean isContainmentReference(ReferenceDeclaration referenceDeclaration) {
135 switch (referenceDeclaration.getKind()) {
136 case REFERENCE, CONTAINER:
137 return false;
138 case CONTAINMENT:
139 return true;
140 case DEFAULT:
141 return isDataClass(referenceDeclaration.getReferenceType());
142 default:
143 throw new IllegalArgumentException("Unknown reference kind " + referenceDeclaration.getKind());
144 }
145 }
146
116 private static URI getLibraryUri(String libraryName) { 147 private static URI getLibraryUri(String libraryName) {
117 return URI.createURI(ProblemUtil.class.getClassLoader() 148 return URI.createURI(ProblemUtil.class.getClassLoader()
118 .getResource("tools/refinery/language/%s.problem".formatted(libraryName)).toString()); 149 .getResource("tools/refinery/language/%s.problem".formatted(libraryName)).toString());
diff --git a/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem b/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem
index 323e03f1..e39ff1a3 100644
--- a/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem
+++ b/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem
@@ -19,3 +19,22 @@ class real extends data.
19class int extends data. 19class int extends data.
20 20
21class string extends data. 21class string extends data.
22
23pred contained(node node).
24
25pred contains(node container, node contained).
26
27pred root(node node).
28
29% error missingContainer(contained node) <->
30% !contains(node, _), !root(node).
31%
32% error tooManyContainers(contained node) <->
33% count contains(_, node) > 1
34% ;
35% contains(_, node), root(node)
36% ;
37% contains(_, node), !contained(node).
38%
39% error containmentCycle(node node) <->
40% contains+(node, node).