diff options
author | 2022-11-19 21:39:00 +0100 | |
---|---|---|
committer | 2022-11-22 16:40:03 +0100 | |
commit | 3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c (patch) | |
tree | 1e25f513e3b34b2ea29dbcc6cc3795e5927a1362 /subprojects/language/src | |
parent | feat(language): numeric expressions (diff) | |
download | refinery-3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c.tar.gz refinery-3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c.tar.zst refinery-3aa4a2b58221a3e83b17d0c04c9a6e9c41e5500c.zip |
refactor: separate primitive types from nodes
Diffstat (limited to 'subprojects/language/src')
21 files changed, 322 insertions, 483 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 bc1ee465..8b13a693 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext +++ b/subprojects/language/src/main/java/tools/refinery/language/Problem.xtext | |||
@@ -10,14 +10,13 @@ Problem: | |||
10 | Statement: | 10 | Statement: |
11 | ClassDeclaration | EnumDeclaration | | 11 | ClassDeclaration | EnumDeclaration | |
12 | PredicateDefinition | FunctionDefinition | /* RuleDefinition | */ | 12 | PredicateDefinition | FunctionDefinition | /* RuleDefinition | */ |
13 | Assertion | NodeValueAssertion | | 13 | Assertion | ScopeDeclaration | IndividualDeclaration; |
14 | ScopeDeclaration | IndividualDeclaration; | ||
15 | 14 | ||
16 | ClassDeclaration: | 15 | ClassDeclaration: |
17 | abstract?="abstract"? "class" | 16 | abstract?="abstract"? "class" |
18 | name=Identifier | 17 | name=Identifier |
19 | ("extends" superTypes+=[Relation|QualifiedName] ("," superTypes+=[Relation|QualifiedName])*)? | 18 | ("extends" superTypes+=[Relation|QualifiedName] ("," superTypes+=[Relation|QualifiedName])*)? |
20 | ("{" (referenceDeclarations+=ReferenceDeclaration ";"?)* "}" | "."); | 19 | ("{" (featureDeclarations+=FeatureDeclaration ";"?)* "}" | "."); |
21 | 20 | ||
22 | EnumDeclaration: | 21 | EnumDeclaration: |
23 | "enum" | 22 | "enum" |
@@ -27,16 +26,27 @@ EnumDeclaration: | |||
27 | EnumLiteral returns Node: | 26 | EnumLiteral returns Node: |
28 | name=Identifier; | 27 | name=Identifier; |
29 | 28 | ||
29 | FeatureDeclaration: | ||
30 | ReferenceDeclaration | AttributeDeclaration | FlagDeclaration; | ||
31 | |||
30 | enum ReferenceKind: | 32 | enum ReferenceKind: |
31 | REFERENCE="refers" | CONTAINMENT="contains" | CONTAINER="container"; | 33 | REFERENCE="refers" | CONTAINMENT="contains" | CONTAINER="container"; |
32 | 34 | ||
33 | ReferenceDeclaration: | 35 | ReferenceDeclaration: |
34 | (kind=ReferenceKind referenceType=[Relation|QualifiedName] | | 36 | kind=ReferenceKind referenceType=[Relation|QualifiedName] |
35 | referenceType=[Relation|NonRelationKindQualifiedName]) | ||
36 | ("[" multiplicity=Multiplicity "]")? | 37 | ("[" multiplicity=Multiplicity "]")? |
37 | name=Identifier | 38 | name=Identifier |
38 | ("opposite" opposite=[ReferenceDeclaration|QualifiedName])?; | 39 | ("opposite" opposite=[ReferenceDeclaration|QualifiedName])?; |
39 | 40 | ||
41 | enum PrimitiveType: | ||
42 | INT="int" | REAL="real" | STRING="string"; | ||
43 | |||
44 | AttributeDeclaration: | ||
45 | attributeType=PrimitiveType name=Identifier; | ||
46 | |||
47 | FlagDeclaration: | ||
48 | "bool" name=Identifier; | ||
49 | |||
40 | enum ErrorKind returns PredicateKind: | 50 | enum ErrorKind returns PredicateKind: |
41 | ERROR="error"; | 51 | ERROR="error"; |
42 | 52 | ||
@@ -54,7 +64,7 @@ Conjunction: | |||
54 | literals+=Expr ("," literals+=Expr)*; | 64 | literals+=Expr ("," literals+=Expr)*; |
55 | 65 | ||
56 | FunctionDefinition: | 66 | FunctionDefinition: |
57 | functionType=[Relation|QualifiedName] name=Identifier | 67 | functionType=PrimitiveType name=Identifier |
58 | "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" | 68 | "(" (parameters+=Parameter ("," parameters+=Parameter)*)? ")" |
59 | ("=" cases+=Case (";" cases+=Case)*)? | 69 | ("=" cases+=Case (";" cases+=Case)*)? |
60 | "."; | 70 | "."; |
@@ -96,11 +106,21 @@ Expr: | |||
96 | ComparisonExpr; | 106 | ComparisonExpr; |
97 | 107 | ||
98 | enum ComparisonOp: | 108 | enum ComparisonOp: |
99 | LESS="<" | LESS_EQ="<=" | GREATER=">" | GREATER_EQ=">=" | EQ="==" | NOT_EQ="!="; | 109 | LESS="<" | LESS_EQ="<=" | GREATER=">" | GREATER_EQ=">=" | EQ="==" | NOT_EQ="!=" | IN="in"; |
100 | 110 | ||
101 | ComparisonExpr returns Expr: | 111 | ComparisonExpr returns Expr: |
102 | AdditiveExpr ({ComparisonExpr.left=current} | 112 | LatticeExpr ({ComparisonExpr.left=current} |
103 | op=ComparisonOp right=AdditiveExpr)*; | 113 | op=ComparisonOp right=LatticeExpr)*; |
114 | |||
115 | enum LatticeOp returns BinaryOp: | ||
116 | MEET="/\\" | JOIN="\\/"; | ||
117 | |||
118 | LatticeExpr returns Expr: | ||
119 | RangeExpr ({ArithmeticBinaryExpr.left=current} | ||
120 | op=LatticeOp right=RangeExpr)*; | ||
121 | |||
122 | RangeExpr returns Expr: | ||
123 | AdditiveExpr ({RangeExpr.left=current} ".." right=AdditiveExpr)*; | ||
104 | 124 | ||
105 | enum AdditiveOp returns BinaryOp: | 125 | enum AdditiveOp returns BinaryOp: |
106 | ADD="+" | SUB="-"; | 126 | ADD="+" | SUB="-"; |
@@ -125,7 +145,7 @@ ExponentialExpr returns Expr: | |||
125 | 145 | ||
126 | UnaryExpr returns Expr: | 146 | UnaryExpr returns Expr: |
127 | ArithmeticUnaryExpr | ModalExpr | NegationExpr | CountExpr | AggregationExpr | | 147 | ArithmeticUnaryExpr | ModalExpr | NegationExpr | CountExpr | AggregationExpr | |
128 | Atom | VariableOrNodeExpr | ConstantExpr | "(" Expr ")"; | 148 | Atom | VariableOrNodeExpr | Constant | "(" Expr ")"; |
129 | 149 | ||
130 | enum UnaryOp: | 150 | enum UnaryOp: |
131 | PLUS="+" | MINUS="-"; | 151 | PLUS="+" | MINUS="-"; |
@@ -159,21 +179,33 @@ Atom: | |||
159 | VariableOrNodeExpr: | 179 | VariableOrNodeExpr: |
160 | variableOrNode=[VariableOrNode|QualifiedName]; | 180 | variableOrNode=[VariableOrNode|QualifiedName]; |
161 | 181 | ||
162 | ConstantExpr: | 182 | Constant: |
163 | constant=Constant; | 183 | RealConstant | IntConstant | InfConstant | StringConstant; |
184 | |||
185 | IntConstant: | ||
186 | intValue=INT; | ||
187 | |||
188 | RealConstant: | ||
189 | realValue=Real; | ||
190 | |||
191 | InfConstant: | ||
192 | {InfConstant} "*"; | ||
193 | |||
194 | StringConstant: | ||
195 | stringValue=STRING; | ||
164 | 196 | ||
165 | Assertion: | 197 | Assertion: |
166 | default?="default"? | 198 | default?="default"? |
167 | (value=ShortLogicValue? | 199 | (relation=[Relation|QualifiedName] |
168 | relation=[Relation|QualifiedName] | ||
169 | "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")" | ||
170 | | relation=[Relation|QualifiedName] | ||
171 | "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")" | 200 | "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")" |
172 | ":" value=LogicValue) | 201 | value=AssertionValue | |
202 | value=ShortLogicAssertionValue | ||
203 | relation=[Relation|QualifiedName] | ||
204 | "(" (arguments+=AssertionArgument ("," arguments+=AssertionArgument)*)? ")") | ||
173 | "."; | 205 | "."; |
174 | 206 | ||
175 | AssertionArgument: | 207 | AssertionArgument: |
176 | NodeAssertionArgument | WildcardAssertionArgument | ConstantAssertionArgument; | 208 | NodeAssertionArgument | WildcardAssertionArgument; |
177 | 209 | ||
178 | NodeAssertionArgument: | 210 | NodeAssertionArgument: |
179 | node=[Node|QualifiedName]; | 211 | node=[Node|QualifiedName]; |
@@ -181,29 +213,23 @@ NodeAssertionArgument: | |||
181 | WildcardAssertionArgument: | 213 | WildcardAssertionArgument: |
182 | {WildcardAssertionArgument} "*"; | 214 | {WildcardAssertionArgument} "*"; |
183 | 215 | ||
184 | ConstantAssertionArgument: | 216 | AssertionValue: |
185 | negative?="-"? constant=Constant; | 217 | LogicAssertionValue | ExprAssertionValue; |
186 | 218 | ||
187 | enum LogicValue: | 219 | enum LogicValue: |
188 | TRUE="true" | FALSE="false" | UNKNOWN="unknown" | ERROR="error"; | 220 | TRUE="true" | FALSE="false" | UNKNOWN="unknown" | ERROR="error"; |
189 | 221 | ||
190 | enum ShortLogicValue returns LogicValue: | 222 | LogicAssertionValue: |
191 | FALSE="!" | UNKNOWN="?"; | 223 | ":" logicValue=LogicValue; |
192 | 224 | ||
193 | NodeValueAssertion: | 225 | ExprAssertionValue: |
194 | node=[Node|QualifiedName] ":" value=Constant "."; | 226 | (range?="in" | "=") body=Expr; |
195 | |||
196 | Constant: | ||
197 | RealConstant | IntConstant | StringConstant; | ||
198 | |||
199 | IntConstant: | ||
200 | intValue=INT; | ||
201 | 227 | ||
202 | RealConstant: | 228 | enum ShortLogicValue returns LogicValue: |
203 | realValue=Real; | 229 | FALSE="!" | UNKNOWN="?"; |
204 | 230 | ||
205 | StringConstant: | 231 | ShortLogicAssertionValue returns LogicAssertionValue: |
206 | stringValue=STRING; | 232 | {LogicAssertionValue} logicValue=ShortLogicValue?; |
207 | 233 | ||
208 | ScopeDeclaration: | 234 | ScopeDeclaration: |
209 | "scope" typeScopes+=TypeScope ("," typeScopes+=TypeScope)* "."; | 235 | "scope" typeScopes+=TypeScope ("," typeScopes+=TypeScope)* "."; |
@@ -234,17 +260,11 @@ IndividualDeclaration: | |||
234 | UpperBound returns ecore::EInt: | 260 | UpperBound returns ecore::EInt: |
235 | INT | "*"; | 261 | INT | "*"; |
236 | 262 | ||
237 | NonRelationKindQualifiedName hidden(): | ||
238 | NonRelationKindIdentifier ("::" Identifier)*; | ||
239 | |||
240 | QualifiedName hidden(): | 263 | QualifiedName hidden(): |
241 | Identifier ("::" Identifier)*; | 264 | Identifier ("::" Identifier)*; |
242 | 265 | ||
243 | NonRelationKindIdentifier: | ||
244 | ID | "true" | "false" | "contained" | "sum" | "prod" | "min" | "max"; | ||
245 | |||
246 | Identifier: | 266 | Identifier: |
247 | NonRelationKindIdentifier | "contains"; | 267 | ID | "contains" | "contained" | "sum" | "prod" | "min" | "max"; |
248 | 268 | ||
249 | Real returns ecore::EDouble: | 269 | Real returns ecore::EDouble: |
250 | EXPONENTIAL | INT "." (INT | EXPONENTIAL); | 270 | EXPONENTIAL | INT "." (INT | EXPONENTIAL); |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java b/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java index c0777038..5efcdc81 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java +++ b/subprojects/language/src/main/java/tools/refinery/language/ProblemRuntimeModule.java | |||
@@ -3,25 +3,18 @@ | |||
3 | */ | 3 | */ |
4 | package tools.refinery.language; | 4 | package tools.refinery.language; |
5 | 5 | ||
6 | import com.google.inject.Binder; | ||
7 | import com.google.inject.name.Names; | ||
6 | import org.eclipse.xtext.conversion.IValueConverterService; | 8 | import org.eclipse.xtext.conversion.IValueConverterService; |
7 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | 9 | import org.eclipse.xtext.naming.IQualifiedNameConverter; |
8 | import org.eclipse.xtext.parser.IParser; | 10 | import org.eclipse.xtext.parser.IParser; |
9 | import org.eclipse.xtext.resource.DerivedStateAwareResource; | 11 | import org.eclipse.xtext.resource.*; |
10 | import org.eclipse.xtext.resource.DerivedStateAwareResourceDescriptionManager; | ||
11 | import org.eclipse.xtext.resource.IDefaultResourceDescriptionStrategy; | ||
12 | import org.eclipse.xtext.resource.IDerivedStateComputer; | ||
13 | import org.eclipse.xtext.resource.ILocationInFileProvider; | ||
14 | import org.eclipse.xtext.resource.IResourceDescription; | ||
15 | import org.eclipse.xtext.resource.XtextResource; | ||
16 | import org.eclipse.xtext.scoping.IGlobalScopeProvider; | 12 | import org.eclipse.xtext.scoping.IGlobalScopeProvider; |
17 | import org.eclipse.xtext.scoping.IScopeProvider; | 13 | import org.eclipse.xtext.scoping.IScopeProvider; |
18 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; | 14 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; |
15 | import org.eclipse.xtext.serializer.sequencer.ISemanticSequencer; | ||
19 | import org.eclipse.xtext.validation.IResourceValidator; | 16 | import org.eclipse.xtext.validation.IResourceValidator; |
20 | import org.eclipse.xtext.xbase.annotations.validation.DerivedStateAwareResourceValidator; | 17 | import org.eclipse.xtext.xbase.annotations.validation.DerivedStateAwareResourceValidator; |
21 | |||
22 | import com.google.inject.Binder; | ||
23 | import com.google.inject.name.Names; | ||
24 | |||
25 | import tools.refinery.language.conversion.ProblemValueConverterService; | 18 | import tools.refinery.language.conversion.ProblemValueConverterService; |
26 | import tools.refinery.language.naming.ProblemQualifiedNameConverter; | 19 | import tools.refinery.language.naming.ProblemQualifiedNameConverter; |
27 | import tools.refinery.language.parser.antlr.TokenSourceInjectingProblemParser; | 20 | import tools.refinery.language.parser.antlr.TokenSourceInjectingProblemParser; |
@@ -30,6 +23,7 @@ import tools.refinery.language.resource.ProblemLocationInFileProvider; | |||
30 | import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; | 23 | import tools.refinery.language.resource.ProblemResourceDescriptionStrategy; |
31 | import tools.refinery.language.scoping.ProblemGlobalScopeProvider; | 24 | import tools.refinery.language.scoping.ProblemGlobalScopeProvider; |
32 | import tools.refinery.language.scoping.ProblemLocalScopeProvider; | 25 | import tools.refinery.language.scoping.ProblemLocalScopeProvider; |
26 | import tools.refinery.language.serializer.PreferShortAssertionsProblemSemanticSequencer; | ||
33 | 27 | ||
34 | /** | 28 | /** |
35 | * Use this class to register components to be used at runtime / without the | 29 | * Use this class to register components to be used at runtime / without the |
@@ -88,4 +82,9 @@ public class ProblemRuntimeModule extends AbstractProblemRuntimeModule { | |||
88 | public Class<? extends ILocationInFileProvider> bindILocationInFileProvider() { | 82 | public Class<? extends ILocationInFileProvider> bindILocationInFileProvider() { |
89 | return ProblemLocationInFileProvider.class; | 83 | return ProblemLocationInFileProvider.class; |
90 | } | 84 | } |
85 | |||
86 | @Override | ||
87 | public Class<? extends ISemanticSequencer> bindISemanticSequencer() { | ||
88 | return PreferShortAssertionsProblemSemanticSequencer.class; | ||
89 | } | ||
91 | } | 90 | } |
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 a65e0750..46870edb 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 | |||
@@ -3,6 +3,7 @@ | |||
3 | */ | 3 | */ |
4 | package tools.refinery.language.formatting2; | 4 | package tools.refinery.language.formatting2; |
5 | 5 | ||
6 | import com.google.inject.Inject; | ||
6 | import org.eclipse.emf.ecore.EObject; | 7 | import org.eclipse.emf.ecore.EObject; |
7 | import org.eclipse.xtext.formatting2.AbstractJavaFormatter; | 8 | import org.eclipse.xtext.formatting2.AbstractJavaFormatter; |
8 | import org.eclipse.xtext.formatting2.IFormattableDocument; | 9 | import org.eclipse.xtext.formatting2.IFormattableDocument; |
@@ -12,9 +13,12 @@ import org.eclipse.xtext.formatting2.regionaccess.ISequentialRegion; | |||
12 | import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; | 13 | import org.eclipse.xtext.xbase.lib.Procedures.Procedure1; |
13 | 14 | ||
14 | import tools.refinery.language.model.problem.*; | 15 | import tools.refinery.language.model.problem.*; |
16 | import tools.refinery.language.services.ProblemGrammarAccess; | ||
15 | 17 | ||
16 | @SuppressWarnings("UnstableApiUsage") | 18 | @SuppressWarnings("UnstableApiUsage") |
17 | public class ProblemFormatter extends AbstractJavaFormatter { | 19 | public class ProblemFormatter extends AbstractJavaFormatter { |
20 | @Inject | ||
21 | private ProblemGrammarAccess problemGrammarAccess; | ||
18 | 22 | ||
19 | protected void format(Problem problem, IFormattableDocument doc) { | 23 | protected void format(Problem problem, IFormattableDocument doc) { |
20 | doc.prepend(problem, this::noSpace); | 24 | doc.prepend(problem, this::noSpace); |
@@ -31,17 +35,35 @@ public class ProblemFormatter extends AbstractJavaFormatter { | |||
31 | surroundNewLines(doc, assertion, this::singleNewLine); | 35 | surroundNewLines(doc, assertion, this::singleNewLine); |
32 | var region = regionFor(assertion); | 36 | var region = regionFor(assertion); |
33 | doc.append(region.feature(ProblemPackage.Literals.ASSERTION__DEFAULT), this::oneSpace); | 37 | doc.append(region.feature(ProblemPackage.Literals.ASSERTION__DEFAULT), this::oneSpace); |
34 | doc.append(region.feature(ProblemPackage.Literals.ASSERTION__VALUE), this::noSpace); | ||
35 | doc.append(region.feature(ProblemPackage.Literals.ASSERTION__RELATION), this::noSpace); | 38 | doc.append(region.feature(ProblemPackage.Literals.ASSERTION__RELATION), this::noSpace); |
36 | formatParenthesizedList(region, doc); | 39 | formatParenthesizedList(region, doc); |
37 | doc.prepend(region.keyword(":"), this::noSpace); | 40 | var value = assertion.getValue(); |
38 | doc.append(region.keyword(":"), this::oneSpace); | 41 | if (value != null) { |
42 | doc.append(value, this::noSpace); | ||
43 | doc.format(value); | ||
44 | } | ||
39 | doc.prepend(region.keyword("."), this::noSpace); | 45 | doc.prepend(region.keyword("."), this::noSpace); |
40 | for (var argument : assertion.getArguments()) { | 46 | for (var argument : assertion.getArguments()) { |
41 | doc.format(argument); | 47 | doc.format(argument); |
42 | } | 48 | } |
43 | } | 49 | } |
44 | 50 | ||
51 | protected void format(LogicAssertionValue assertionValue, IFormattableDocument doc) { | ||
52 | var region = regionFor(assertionValue); | ||
53 | doc.prepend(region.keyword(":"), this::noSpace); | ||
54 | doc.append(region.keyword(":"), this::oneSpace); | ||
55 | } | ||
56 | |||
57 | protected void format(ExprAssertionValue assertionValue, IFormattableDocument doc) { | ||
58 | var region = regionFor(assertionValue); | ||
59 | doc.surround(region.keyword("="), this::oneSpace); | ||
60 | doc.surround(region.keyword("in"), this::oneSpace); | ||
61 | var body = assertionValue.getBody(); | ||
62 | if (body != null) { | ||
63 | doc.format(body); | ||
64 | } | ||
65 | } | ||
66 | |||
45 | protected void format(ClassDeclaration classDeclaration, IFormattableDocument doc) { | 67 | protected void format(ClassDeclaration classDeclaration, IFormattableDocument doc) { |
46 | surroundNewLines(doc, classDeclaration, this::twoNewLines); | 68 | surroundNewLines(doc, classDeclaration, this::twoNewLines); |
47 | var region = regionFor(classDeclaration); | 69 | var region = regionFor(classDeclaration); |
@@ -53,8 +75,8 @@ public class ProblemFormatter extends AbstractJavaFormatter { | |||
53 | doc.append(region.keyword("{"), it -> it.setNewLines(1, 1, 2)); | 75 | doc.append(region.keyword("{"), it -> it.setNewLines(1, 1, 2)); |
54 | doc.prepend(region.keyword("}"), it -> it.setNewLines(1, 1, 2)); | 76 | doc.prepend(region.keyword("}"), it -> it.setNewLines(1, 1, 2)); |
55 | doc.prepend(region.keyword("."), this::noSpace); | 77 | doc.prepend(region.keyword("."), this::noSpace); |
56 | for (var referenceDeclaration : classDeclaration.getReferenceDeclarations()) { | 78 | for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) { |
57 | doc.format(referenceDeclaration); | 79 | doc.format(featureDeclaration); |
58 | } | 80 | } |
59 | } | 81 | } |
60 | 82 | ||
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java b/subprojects/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java index 99bf9b64..419be0d3 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/NodeNameCollector.java | |||
@@ -1,10 +1,9 @@ | |||
1 | package tools.refinery.language.resource; | 1 | package tools.refinery.language.resource; |
2 | 2 | ||
3 | import java.util.List; | 3 | import com.google.common.collect.ImmutableSet; |
4 | import java.util.Set; | 4 | import com.google.inject.Inject; |
5 | 5 | import com.google.inject.name.Named; | |
6 | import org.eclipse.emf.ecore.EObject; | 6 | import org.eclipse.emf.ecore.EObject; |
7 | import org.eclipse.emf.ecore.EStructuralFeature; | ||
8 | import org.eclipse.xtext.linking.impl.LinkingHelper; | 7 | import org.eclipse.xtext.linking.impl.LinkingHelper; |
9 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | 8 | import org.eclipse.xtext.naming.IQualifiedNameConverter; |
10 | import org.eclipse.xtext.nodemodel.INode; | 9 | import org.eclipse.xtext.nodemodel.INode; |
@@ -12,20 +11,12 @@ import org.eclipse.xtext.nodemodel.util.NodeModelUtils; | |||
12 | import org.eclipse.xtext.scoping.IScope; | 11 | import org.eclipse.xtext.scoping.IScope; |
13 | import org.eclipse.xtext.scoping.IScopeProvider; | 12 | import org.eclipse.xtext.scoping.IScopeProvider; |
14 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; | 13 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; |
15 | 14 | import tools.refinery.language.model.problem.*; | |
16 | import com.google.common.collect.ImmutableSet; | ||
17 | import com.google.inject.Inject; | ||
18 | import com.google.inject.name.Named; | ||
19 | |||
20 | import tools.refinery.language.model.problem.Assertion; | ||
21 | import tools.refinery.language.model.problem.AssertionArgument; | ||
22 | import tools.refinery.language.model.problem.NodeAssertionArgument; | ||
23 | import tools.refinery.language.model.problem.NodeValueAssertion; | ||
24 | import tools.refinery.language.model.problem.Problem; | ||
25 | import tools.refinery.language.model.problem.ProblemPackage; | ||
26 | import tools.refinery.language.model.problem.Statement; | ||
27 | import tools.refinery.language.naming.NamingUtil; | 15 | import tools.refinery.language.naming.NamingUtil; |
28 | 16 | ||
17 | import java.util.List; | ||
18 | import java.util.Set; | ||
19 | |||
29 | public class NodeNameCollector { | 20 | public class NodeNameCollector { |
30 | @Inject | 21 | @Inject |
31 | private LinkingHelper linkingHelper; | 22 | private LinkingHelper linkingHelper; |
@@ -55,25 +46,20 @@ public class NodeNameCollector { | |||
55 | protected void collectStatementNodeNames(Statement statement) { | 46 | protected void collectStatementNodeNames(Statement statement) { |
56 | if (statement instanceof Assertion assertion) { | 47 | if (statement instanceof Assertion assertion) { |
57 | collectAssertionNodeNames(assertion); | 48 | collectAssertionNodeNames(assertion); |
58 | } else if (statement instanceof NodeValueAssertion nodeValueAssertion) { | ||
59 | collectNodeValueAssertionNodeNames(nodeValueAssertion); | ||
60 | } | 49 | } |
61 | } | 50 | } |
62 | 51 | ||
63 | protected void collectAssertionNodeNames(Assertion assertion) { | 52 | protected void collectAssertionNodeNames(Assertion assertion) { |
64 | for (AssertionArgument argument : assertion.getArguments()) { | 53 | for (AssertionArgument argument : assertion.getArguments()) { |
65 | if (argument instanceof NodeAssertionArgument) { | 54 | if (argument instanceof NodeAssertionArgument) { |
66 | collectNodeNames(argument, ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE); | 55 | collectNodeNames(argument); |
67 | } | 56 | } |
68 | } | 57 | } |
69 | } | 58 | } |
70 | 59 | ||
71 | protected void collectNodeValueAssertionNodeNames(NodeValueAssertion nodeValueAssertion) { | 60 | private void collectNodeNames(EObject eObject) { |
72 | collectNodeNames(nodeValueAssertion, ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE); | 61 | List<INode> nodes = NodeModelUtils.findNodesForFeature(eObject, |
73 | } | 62 | ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE); |
74 | |||
75 | private void collectNodeNames(EObject eObject, EStructuralFeature feature) { | ||
76 | List<INode> nodes = NodeModelUtils.findNodesForFeature(eObject, feature); | ||
77 | for (INode node : nodes) { | 63 | for (INode node : nodes) { |
78 | var nodeName = linkingHelper.getCrossRefNodeAsString(node, true); | 64 | var nodeName = linkingHelper.getCrossRefNodeAsString(node, true); |
79 | if (!NamingUtil.isValidId(nodeName)) { | 65 | if (!NamingUtil.isValidId(nodeName)) { |
@@ -85,4 +71,4 @@ public class NodeNameCollector { | |||
85 | } | 71 | } |
86 | } | 72 | } |
87 | } | 73 | } |
88 | } \ No newline at end of file | 74 | } |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java index f28e1791..8d3a552a 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/resource/ProblemDerivedStateComputer.java | |||
@@ -1,13 +1,9 @@ | |||
1 | package tools.refinery.language.resource; | 1 | package tools.refinery.language.resource; |
2 | 2 | ||
3 | import java.util.Collection; | 3 | import com.google.inject.Inject; |
4 | import java.util.HashMap; | 4 | import com.google.inject.Provider; |
5 | import java.util.HashSet; | 5 | import com.google.inject.Singleton; |
6 | import java.util.List; | 6 | import com.google.inject.name.Named; |
7 | import java.util.Map; | ||
8 | import java.util.Set; | ||
9 | import java.util.function.Function; | ||
10 | |||
11 | import org.eclipse.emf.common.notify.impl.AdapterImpl; | 7 | import org.eclipse.emf.common.notify.impl.AdapterImpl; |
12 | import org.eclipse.emf.ecore.EObject; | 8 | import org.eclipse.emf.ecore.EObject; |
13 | import org.eclipse.emf.ecore.resource.Resource; | 9 | import org.eclipse.emf.ecore.resource.Resource; |
@@ -16,37 +12,20 @@ import org.eclipse.xtext.Constants; | |||
16 | import org.eclipse.xtext.resource.DerivedStateAwareResource; | 12 | import org.eclipse.xtext.resource.DerivedStateAwareResource; |
17 | import org.eclipse.xtext.resource.IDerivedStateComputer; | 13 | import org.eclipse.xtext.resource.IDerivedStateComputer; |
18 | import org.eclipse.xtext.resource.XtextResource; | 14 | import org.eclipse.xtext.resource.XtextResource; |
19 | import org.eclipse.xtext.scoping.IScopeProvider; | 15 | import tools.refinery.language.model.problem.*; |
20 | import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; | ||
21 | |||
22 | import com.google.inject.Inject; | ||
23 | import com.google.inject.Provider; | ||
24 | import com.google.inject.Singleton; | ||
25 | import com.google.inject.name.Named; | ||
26 | 16 | ||
27 | import tools.refinery.language.model.problem.Assertion; | 17 | import java.util.*; |
28 | import tools.refinery.language.model.problem.ClassDeclaration; | 18 | import java.util.function.Function; |
29 | import tools.refinery.language.model.problem.ConstantAssertionArgument; | ||
30 | import tools.refinery.language.model.problem.Node; | ||
31 | import tools.refinery.language.model.problem.Problem; | ||
32 | import tools.refinery.language.model.problem.ProblemFactory; | ||
33 | import tools.refinery.language.model.problem.Statement; | ||
34 | 19 | ||
35 | @Singleton | 20 | @Singleton |
36 | public class ProblemDerivedStateComputer implements IDerivedStateComputer { | 21 | public class ProblemDerivedStateComputer implements IDerivedStateComputer { |
37 | public static final String NEW_NODE = "new"; | 22 | public static final String NEW_NODE = "new"; |
38 | 23 | ||
39 | public static final String CONSTANT_NODE = "constant"; | ||
40 | |||
41 | @Inject | 24 | @Inject |
42 | @Named(Constants.LANGUAGE_NAME) | 25 | @Named(Constants.LANGUAGE_NAME) |
43 | private String languageName; | 26 | private String languageName; |
44 | 27 | ||
45 | @Inject | 28 | @Inject |
46 | @Named(AbstractDeclarativeScopeProvider.NAMED_DELEGATE) | ||
47 | private IScopeProvider scopeProvider; | ||
48 | |||
49 | @Inject | ||
50 | private Provider<NodeNameCollector> nodeNameCollectorProvider; | 29 | private Provider<NodeNameCollector> nodeNameCollectorProvider; |
51 | 30 | ||
52 | @Inject | 31 | @Inject |
@@ -88,15 +67,6 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
88 | && declaration.getNewNode() == null) { | 67 | && declaration.getNewNode() == null) { |
89 | var newNode = adapter.createNewNodeIfAbsent(declaration, key -> createNode(NEW_NODE)); | 68 | var newNode = adapter.createNewNodeIfAbsent(declaration, key -> createNode(NEW_NODE)); |
90 | declaration.setNewNode(newNode); | 69 | declaration.setNewNode(newNode); |
91 | } else if (statement instanceof Assertion assertion) { | ||
92 | for (var argument : assertion.getArguments()) { | ||
93 | if (argument instanceof ConstantAssertionArgument constantAssertionArgument | ||
94 | && constantAssertionArgument.getNode() == null) { | ||
95 | var constantNode = adapter.createConstantNodeIfAbsent(constantAssertionArgument, | ||
96 | key -> createNode(CONSTANT_NODE)); | ||
97 | constantAssertionArgument.setNode(constantNode); | ||
98 | } | ||
99 | } | ||
100 | } | 70 | } |
101 | } | 71 | } |
102 | } | 72 | } |
@@ -130,22 +100,14 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
130 | 100 | ||
131 | protected void discardDerivedProblemState(Problem problem, Adapter adapter) { | 101 | protected void discardDerivedProblemState(Problem problem, Adapter adapter) { |
132 | Set<ClassDeclaration> classDeclarations = new HashSet<>(); | 102 | Set<ClassDeclaration> classDeclarations = new HashSet<>(); |
133 | Set<ConstantAssertionArgument> constantAssertionArguments = new HashSet<>(); | ||
134 | problem.getNodes().clear(); | 103 | problem.getNodes().clear(); |
135 | for (var statement : problem.getStatements()) { | 104 | for (var statement : problem.getStatements()) { |
136 | if (statement instanceof ClassDeclaration classDeclaration) { | 105 | if (statement instanceof ClassDeclaration classDeclaration) { |
137 | classDeclaration.setNewNode(null); | 106 | classDeclaration.setNewNode(null); |
138 | classDeclarations.add(classDeclaration); | 107 | classDeclarations.add(classDeclaration); |
139 | } else if (statement instanceof Assertion assertion) { | ||
140 | for (var argument : assertion.getArguments()) { | ||
141 | if (argument instanceof ConstantAssertionArgument constantAssertionArgument) { | ||
142 | constantAssertionArgument.setNode(null); | ||
143 | constantAssertionArguments.add(constantAssertionArgument); | ||
144 | } | ||
145 | } | ||
146 | } | 108 | } |
147 | } | 109 | } |
148 | adapter.retainAll(classDeclarations, constantAssertionArguments); | 110 | adapter.retainAll(classDeclarations); |
149 | derivedVariableComputer.discardDerivedVariables(problem); | 111 | derivedVariableComputer.discardDerivedVariables(problem); |
150 | } | 112 | } |
151 | 113 | ||
@@ -166,24 +128,15 @@ public class ProblemDerivedStateComputer implements IDerivedStateComputer { | |||
166 | } | 128 | } |
167 | 129 | ||
168 | protected static class Adapter extends AdapterImpl { | 130 | protected static class Adapter extends AdapterImpl { |
169 | private Map<ClassDeclaration, Node> newNodes = new HashMap<>(); | 131 | private final Map<ClassDeclaration, Node> newNodes = new HashMap<>(); |
170 | |||
171 | private Map<ConstantAssertionArgument, Node> constantNodes = new HashMap<>(); | ||
172 | 132 | ||
173 | public Node createNewNodeIfAbsent(ClassDeclaration classDeclaration, | 133 | public Node createNewNodeIfAbsent(ClassDeclaration classDeclaration, |
174 | Function<ClassDeclaration, Node> createNode) { | 134 | Function<ClassDeclaration, Node> createNode) { |
175 | return newNodes.computeIfAbsent(classDeclaration, createNode); | 135 | return newNodes.computeIfAbsent(classDeclaration, createNode); |
176 | } | 136 | } |
177 | 137 | ||
178 | public Node createConstantNodeIfAbsent(ConstantAssertionArgument constantAssertionArgument, | 138 | public void retainAll(Collection<ClassDeclaration> classDeclarations) { |
179 | Function<ConstantAssertionArgument, Node> createNode) { | ||
180 | return constantNodes.computeIfAbsent(constantAssertionArgument, createNode); | ||
181 | } | ||
182 | |||
183 | public void retainAll(Collection<ClassDeclaration> classDeclarations, | ||
184 | Collection<ConstantAssertionArgument> constantAssertionArguments) { | ||
185 | newNodes.keySet().retainAll(classDeclarations); | 139 | newNodes.keySet().retainAll(classDeclarations); |
186 | constantNodes.keySet().retainAll(constantAssertionArguments); | ||
187 | } | 140 | } |
188 | 141 | ||
189 | @Override | 142 | @Override |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java index c2045aea..3ab07496 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java +++ b/subprojects/language/src/main/java/tools/refinery/language/scoping/ProblemScopeProvider.java | |||
@@ -29,8 +29,7 @@ public class ProblemScopeProvider extends AbstractProblemScopeProvider { | |||
29 | @Override | 29 | @Override |
30 | public IScope getScope(EObject context, EReference reference) { | 30 | public IScope getScope(EObject context, EReference reference) { |
31 | var scope = super.getScope(context, reference); | 31 | var scope = super.getScope(context, reference); |
32 | if (reference == ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE | 32 | if (reference == ProblemPackage.Literals.NODE_ASSERTION_ARGUMENT__NODE) { |
33 | || reference == ProblemPackage.Literals.NODE_VALUE_ASSERTION__NODE) { | ||
34 | return getNodesScope(context, scope); | 33 | return getNodesScope(context, scope); |
35 | } | 34 | } |
36 | if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE | 35 | if (reference == ProblemPackage.Literals.VARIABLE_OR_NODE_EXPR__VARIABLE_OR_NODE |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java b/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java new file mode 100644 index 00000000..c51a5e28 --- /dev/null +++ b/subprojects/language/src/main/java/tools/refinery/language/serializer/PreferShortAssertionsProblemSemanticSequencer.java | |||
@@ -0,0 +1,52 @@ | |||
1 | package tools.refinery.language.serializer; | ||
2 | |||
3 | import com.google.inject.Inject; | ||
4 | import org.eclipse.xtext.serializer.ISerializationContext; | ||
5 | import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ListTransient; | ||
6 | import org.eclipse.xtext.serializer.sequencer.ITransientValueService.ValueTransient; | ||
7 | import tools.refinery.language.model.problem.Assertion; | ||
8 | import tools.refinery.language.model.problem.LogicAssertionValue; | ||
9 | import tools.refinery.language.model.problem.LogicValue; | ||
10 | import tools.refinery.language.model.problem.ProblemPackage; | ||
11 | import tools.refinery.language.services.ProblemGrammarAccess; | ||
12 | |||
13 | public class PreferShortAssertionsProblemSemanticSequencer extends ProblemSemanticSequencer { | ||
14 | @Inject | ||
15 | private ProblemGrammarAccess grammarAccess; | ||
16 | |||
17 | @Override | ||
18 | protected void sequence_Assertion(ISerializationContext context, Assertion semanticObject) { | ||
19 | if (semanticObject.isDefault() || | ||
20 | !(semanticObject.getValue() instanceof LogicAssertionValue logicAssertionValue) || | ||
21 | logicAssertionValue.getLogicValue() == LogicValue.ERROR) { | ||
22 | super.sequence_Assertion(context, semanticObject); | ||
23 | return; | ||
24 | } | ||
25 | if (errorAcceptor != null) { | ||
26 | if (transientValues.isValueTransient(semanticObject, ProblemPackage.Literals.ASSERTION__RELATION) == ValueTransient.YES) { | ||
27 | errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, | ||
28 | ProblemPackage.Literals.ASSERTION__RELATION)); | ||
29 | } | ||
30 | if (transientValues.isListTransient(semanticObject, ProblemPackage.Literals.ASSERTION__ARGUMENTS) == ListTransient.YES) { | ||
31 | errorAcceptor.accept(diagnosticProvider.createFeatureValueMissing(semanticObject, | ||
32 | ProblemPackage.Literals.ASSERTION__ARGUMENTS)); | ||
33 | } | ||
34 | } | ||
35 | var feeder = createSequencerFeeder(context, semanticObject); | ||
36 | var access = grammarAccess.getAssertionAccess(); | ||
37 | feeder.accept(access.getValueShortLogicAssertionValueParserRuleCall_1_1_0_0(), logicAssertionValue); | ||
38 | feeder.accept(access.getRelationRelationQualifiedNameParserRuleCall_1_1_1_0_1(), semanticObject.getRelation()); | ||
39 | var iterator = semanticObject.getArguments().iterator(); | ||
40 | if (iterator.hasNext()) { | ||
41 | var firstArgument = iterator.next(); | ||
42 | feeder.accept(access.getArgumentsAssertionArgumentParserRuleCall_1_1_3_0_0(), firstArgument, 0); | ||
43 | int index = 1; | ||
44 | while (iterator.hasNext()) { | ||
45 | var argument = iterator.next(); | ||
46 | feeder.accept(access.getArgumentsAssertionArgumentParserRuleCall_1_1_3_1_1_0(), argument, index); | ||
47 | index++; | ||
48 | } | ||
49 | } | ||
50 | feeder.finish(); | ||
51 | } | ||
52 | } | ||
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java b/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java index 7e43cecf..d3777cd3 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java +++ b/subprojects/language/src/main/java/tools/refinery/language/utils/BuiltinSymbols.java | |||
@@ -1,14 +1,8 @@ | |||
1 | package tools.refinery.language.utils; | 1 | package tools.refinery.language.utils; |
2 | 2 | ||
3 | import tools.refinery.language.model.problem.ClassDeclaration; | 3 | import tools.refinery.language.model.problem.*; |
4 | import tools.refinery.language.model.problem.EnumDeclaration; | ||
5 | import tools.refinery.language.model.problem.Node; | ||
6 | import tools.refinery.language.model.problem.PredicateDefinition; | ||
7 | import tools.refinery.language.model.problem.Problem; | ||
8 | import tools.refinery.language.model.problem.ReferenceDeclaration; | ||
9 | 4 | ||
10 | public record BuiltinSymbols(Problem problem, ClassDeclaration node, ReferenceDeclaration equals, | 5 | public record BuiltinSymbols(Problem problem, ClassDeclaration node, ReferenceDeclaration equals, |
11 | PredicateDefinition exists, ClassDeclaration domain, ClassDeclaration data, EnumDeclaration bool, Node boolTrue, | 6 | PredicateDefinition exists, PredicateDefinition contained, PredicateDefinition contains, |
12 | Node boolFalse, ClassDeclaration intClass, ClassDeclaration real, ClassDeclaration string, | 7 | PredicateDefinition root) { |
13 | PredicateDefinition contained, PredicateDefinition contains, PredicateDefinition root) { | ||
14 | } | 8 | } |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java b/subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java index 38db0e29..c8f47653 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java +++ b/subprojects/language/src/main/java/tools/refinery/language/utils/NodeInfo.java | |||
@@ -1,12 +1,4 @@ | |||
1 | package tools.refinery.language.utils; | 1 | package tools.refinery.language.utils; |
2 | 2 | ||
3 | import java.util.ArrayList; | 3 | public record NodeInfo(String name, boolean individual) { |
4 | import java.util.Collection; | ||
5 | |||
6 | import tools.refinery.language.model.problem.NodeValueAssertion; | ||
7 | |||
8 | public record NodeInfo(String name, boolean individual, Collection<NodeValueAssertion> valueAssertions) { | ||
9 | public NodeInfo(String name, boolean individual) { | ||
10 | this(name, individual, new ArrayList<>()); | ||
11 | } | ||
12 | } | 4 | } |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java index 23fd8982..b8200919 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java +++ b/subprojects/language/src/main/java/tools/refinery/language/utils/ProblemDesugarer.java | |||
@@ -40,19 +40,10 @@ public class ProblemDesugarer { | |||
40 | var node = doGetDeclaration(builtin, ClassDeclaration.class, "node"); | 40 | var node = doGetDeclaration(builtin, ClassDeclaration.class, "node"); |
41 | var equals = doGetEqualsReference(node); | 41 | var equals = doGetEqualsReference(node); |
42 | var exists = doGetDeclaration(builtin, PredicateDefinition.class, "exists"); | 42 | var exists = doGetDeclaration(builtin, PredicateDefinition.class, "exists"); |
43 | var domain = doGetDeclaration(builtin, ClassDeclaration.class, "domain"); | ||
44 | var data = doGetDeclaration(builtin, ClassDeclaration.class, "data"); | ||
45 | var bool = doGetDeclaration(builtin, EnumDeclaration.class, "bool"); | ||
46 | var boolTrue = doGetLiteral(bool, "true"); | ||
47 | var boolFalse = doGetLiteral(bool, "false"); | ||
48 | var intClass = doGetDeclaration(builtin, ClassDeclaration.class, "int"); | ||
49 | var real = doGetDeclaration(builtin, ClassDeclaration.class, "real"); | ||
50 | var string = doGetDeclaration(builtin, ClassDeclaration.class, "string"); | ||
51 | var contained = doGetDeclaration(builtin, PredicateDefinition.class, "contained"); | 43 | var contained = doGetDeclaration(builtin, PredicateDefinition.class, "contained"); |
52 | var contains = doGetDeclaration(builtin, PredicateDefinition.class, "contains"); | 44 | var contains = doGetDeclaration(builtin, PredicateDefinition.class, "contains"); |
53 | var root = doGetDeclaration(builtin, PredicateDefinition.class, "root"); | 45 | var root = doGetDeclaration(builtin, PredicateDefinition.class, "root"); |
54 | return new BuiltinSymbols(builtin, node, equals, exists, domain, data, bool, boolTrue, boolFalse, intClass, | 46 | return new BuiltinSymbols(builtin, node, equals, exists, contained, contains, root); |
55 | real, string, contained, contains, root); | ||
56 | } | 47 | } |
57 | 48 | ||
58 | private <T extends Statement & NamedElement> T doGetDeclaration(Problem builtin, Class<T> type, String name) { | 49 | private <T extends Statement & NamedElement> T doGetDeclaration(Problem builtin, Class<T> type, String name) { |
@@ -62,16 +53,12 @@ public class ProblemDesugarer { | |||
62 | } | 53 | } |
63 | 54 | ||
64 | private ReferenceDeclaration doGetEqualsReference(ClassDeclaration nodeClassDeclaration) { | 55 | private ReferenceDeclaration doGetEqualsReference(ClassDeclaration nodeClassDeclaration) { |
65 | return nodeClassDeclaration.getReferenceDeclarations().stream() | 56 | return (ReferenceDeclaration) nodeClassDeclaration.getFeatureDeclarations().stream() |
66 | .filter(reference -> "equals".equals(reference.getName())).findFirst() | 57 | .filter(reference -> reference instanceof ReferenceDeclaration && |
58 | "equals".equals(reference.getName())).findFirst() | ||
67 | .orElseThrow(() -> new IllegalArgumentException("Reference " + "equals" + " not found")); | 59 | .orElseThrow(() -> new IllegalArgumentException("Reference " + "equals" + " not found")); |
68 | } | 60 | } |
69 | 61 | ||
70 | private Node doGetLiteral(EnumDeclaration enumDeclaration, String name) { | ||
71 | return enumDeclaration.getLiterals().stream().filter(literal -> name.equals(literal.getName())).findFirst() | ||
72 | .orElseThrow(() -> new IllegalArgumentException("Enum literal " + name + " not found")); | ||
73 | } | ||
74 | |||
75 | public Collection<ClassDeclaration> getSuperclassesAndSelf(ClassDeclaration classDeclaration) { | 62 | public Collection<ClassDeclaration> getSuperclassesAndSelf(ClassDeclaration classDeclaration) { |
76 | return cache.get(Tuples.create(classDeclaration, "superclassesAndSelf"), classDeclaration.eResource(), | 63 | return cache.get(Tuples.create(classDeclaration, "superclassesAndSelf"), classDeclaration.eResource(), |
77 | () -> doGetSuperclassesAndSelf(classDeclaration)); | 64 | () -> doGetSuperclassesAndSelf(classDeclaration)); |
@@ -94,9 +81,6 @@ public class ProblemDesugarer { | |||
94 | } | 81 | } |
95 | } | 82 | } |
96 | } | 83 | } |
97 | if (builtinSymbols.isPresent() && !found.contains(builtinSymbols.get().data())) { | ||
98 | found.add(builtinSymbols.get().domain()); | ||
99 | } | ||
100 | return found; | 84 | return found; |
101 | } | 85 | } |
102 | 86 | ||
@@ -108,31 +92,17 @@ public class ProblemDesugarer { | |||
108 | private Collection<ReferenceDeclaration> doGetAllReferenceDeclarations(ClassDeclaration classDeclaration) { | 92 | private Collection<ReferenceDeclaration> doGetAllReferenceDeclarations(ClassDeclaration classDeclaration) { |
109 | Set<ReferenceDeclaration> referenceDeclarations = new HashSet<>(); | 93 | Set<ReferenceDeclaration> referenceDeclarations = new HashSet<>(); |
110 | for (ClassDeclaration superclass : getSuperclassesAndSelf(classDeclaration)) { | 94 | for (ClassDeclaration superclass : getSuperclassesAndSelf(classDeclaration)) { |
111 | referenceDeclarations.addAll(superclass.getReferenceDeclarations()); | 95 | for (FeatureDeclaration featureDeclaration : superclass.getFeatureDeclarations()) { |
96 | if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration) { | ||
97 | referenceDeclarations.add(referenceDeclaration); | ||
98 | } | ||
99 | } | ||
112 | } | 100 | } |
113 | return referenceDeclarations; | 101 | return referenceDeclarations; |
114 | } | 102 | } |
115 | 103 | ||
116 | public boolean isContainmentReference(ReferenceDeclaration referenceDeclaration) { | 104 | public boolean isContainmentReference(ReferenceDeclaration referenceDeclaration) { |
117 | switch (referenceDeclaration.getKind()) { | 105 | return referenceDeclaration.getKind() == ReferenceKind.CONTAINMENT; |
118 | case REFERENCE, CONTAINER: | ||
119 | return false; | ||
120 | case CONTAINMENT: | ||
121 | return true; | ||
122 | case DEFAULT: | ||
123 | return isDataClass(referenceDeclaration.getReferenceType()); | ||
124 | default: | ||
125 | throw new IllegalArgumentException("Unknown reference kind " + referenceDeclaration.getKind()); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | public boolean isDataClass(Relation relation) { | ||
130 | if (relation instanceof ClassDeclaration classDeclaration) { | ||
131 | var supertypes = getSuperclassesAndSelf(classDeclaration); | ||
132 | var builtinSymbols = getBuiltinSymbols(relation); | ||
133 | return builtinSymbols.isPresent() && supertypes.contains(builtinSymbols.get().data()); | ||
134 | } | ||
135 | return false; | ||
136 | } | 106 | } |
137 | 107 | ||
138 | public CollectedSymbols collectSymbols(Problem problem) { | 108 | public CollectedSymbols collectSymbols(Problem problem) { |
diff --git a/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java b/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java index 210e96ab..5412f620 100644 --- a/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java +++ b/subprojects/language/src/main/java/tools/refinery/language/utils/SymbolCollector.java | |||
@@ -2,7 +2,6 @@ package tools.refinery.language.utils; | |||
2 | 2 | ||
3 | import com.google.inject.Inject; | 3 | import com.google.inject.Inject; |
4 | import org.eclipse.emf.ecore.EObject; | 4 | import org.eclipse.emf.ecore.EObject; |
5 | import org.eclipse.emf.ecore.util.EcoreUtil; | ||
6 | import org.eclipse.xtext.naming.IQualifiedNameConverter; | 5 | import org.eclipse.xtext.naming.IQualifiedNameConverter; |
7 | import org.eclipse.xtext.naming.IQualifiedNameProvider; | 6 | import org.eclipse.xtext.naming.IQualifiedNameProvider; |
8 | import tools.refinery.language.model.problem.*; | 7 | import tools.refinery.language.model.problem.*; |
@@ -64,43 +63,65 @@ class SymbolCollector { | |||
64 | } | 63 | } |
65 | 64 | ||
66 | private void collectClass(ClassDeclaration classDeclaration) { | 65 | private void collectClass(ClassDeclaration classDeclaration) { |
67 | // node and domain classes are not contained by default, but every other type is | 66 | var contained = classDeclaration != builtinSymbols.node(); |
68 | // contained, including data types. | ||
69 | var contained = | ||
70 | classDeclaration != builtinSymbols.node() && classDeclaration != builtinSymbols.domain(); | ||
71 | var containmentRole = contained ? ContainmentRole.CONTAINED : ContainmentRole.NONE; | 67 | var containmentRole = contained ? ContainmentRole.CONTAINED : ContainmentRole.NONE; |
72 | var instanceParameter = ProblemFactory.eINSTANCE.createParameter(); | 68 | var instanceParameter = ProblemFactory.eINSTANCE.createParameter(); |
73 | instanceParameter.setName("instance"); | 69 | instanceParameter.setName("instance"); |
74 | var classInfo = new RelationInfo(getQualifiedNameString(classDeclaration), containmentRole, | 70 | var classInfo = new RelationInfo(getQualifiedNameString(classDeclaration), containmentRole, |
75 | List.of(instanceParameter), null, null, List.of()); | 71 | List.of(instanceParameter), null, null, List.of()); |
76 | relations.put(classDeclaration, classInfo); | 72 | relations.put(classDeclaration, classInfo); |
77 | collectReferences(classDeclaration); | 73 | collectFeatures(classDeclaration); |
78 | } | 74 | } |
79 | 75 | ||
80 | private void collectReferences(ClassDeclaration classDeclaration) { | 76 | private void collectFeatures(ClassDeclaration classDeclaration) { |
81 | for (var referenceDeclaration : classDeclaration.getReferenceDeclarations()) { | 77 | for (var featureDeclaration : classDeclaration.getFeatureDeclarations()) { |
82 | var referenceRole = desugarer.isContainmentReference(referenceDeclaration) ? | 78 | if (featureDeclaration instanceof ReferenceDeclaration referenceDeclaration) { |
83 | ContainmentRole.CONTAINMENT : | 79 | collectReference(classDeclaration, referenceDeclaration); |
84 | ContainmentRole.NONE; | 80 | } else if (featureDeclaration instanceof AttributeDeclaration attributeDeclaration) { |
85 | var sourceParameter = ProblemFactory.eINSTANCE.createParameter(); | 81 | collectAttribute(classDeclaration, attributeDeclaration); |
86 | sourceParameter.setName("source"); | 82 | } else if (featureDeclaration instanceof FlagDeclaration flagDeclaration) { |
87 | sourceParameter.setParameterType(classDeclaration); | 83 | collectFlag(classDeclaration, flagDeclaration); |
88 | var targetParameter = ProblemFactory.eINSTANCE.createParameter(); | 84 | } else { |
89 | targetParameter.setName("target"); | 85 | throw new IllegalArgumentException("Unknown FeatureDeclaration: " + featureDeclaration); |
90 | var multiplicity = referenceDeclaration.getMultiplicity(); | ||
91 | if (multiplicity == null) { | ||
92 | var exactMultiplicity = ProblemFactory.eINSTANCE.createExactMultiplicity(); | ||
93 | exactMultiplicity.setExactValue(1); | ||
94 | multiplicity = exactMultiplicity; | ||
95 | } | 86 | } |
96 | targetParameter.setParameterType(referenceDeclaration.getReferenceType()); | ||
97 | var referenceInfo = new RelationInfo(getQualifiedNameString(referenceDeclaration), referenceRole, | ||
98 | List.of(sourceParameter, targetParameter), multiplicity, referenceDeclaration.getOpposite(), | ||
99 | List.of()); | ||
100 | this.relations.put(referenceDeclaration, referenceInfo); | ||
101 | } | 87 | } |
102 | } | 88 | } |
103 | 89 | ||
90 | private void collectReference(ClassDeclaration classDeclaration, ReferenceDeclaration referenceDeclaration) { | ||
91 | var referenceRole = desugarer.isContainmentReference(referenceDeclaration) ? | ||
92 | ContainmentRole.CONTAINMENT : | ||
93 | ContainmentRole.NONE; | ||
94 | var sourceParameter = ProblemFactory.eINSTANCE.createParameter(); | ||
95 | sourceParameter.setName("source"); | ||
96 | sourceParameter.setParameterType(classDeclaration); | ||
97 | var targetParameter = ProblemFactory.eINSTANCE.createParameter(); | ||
98 | targetParameter.setName("target"); | ||
99 | var multiplicity = referenceDeclaration.getMultiplicity(); | ||
100 | if (multiplicity == null) { | ||
101 | var exactMultiplicity = ProblemFactory.eINSTANCE.createExactMultiplicity(); | ||
102 | exactMultiplicity.setExactValue(1); | ||
103 | multiplicity = exactMultiplicity; | ||
104 | } | ||
105 | targetParameter.setParameterType(referenceDeclaration.getReferenceType()); | ||
106 | var referenceInfo = new RelationInfo(getQualifiedNameString(referenceDeclaration), referenceRole, | ||
107 | List.of(sourceParameter, targetParameter), multiplicity, referenceDeclaration.getOpposite(), | ||
108 | List.of()); | ||
109 | this.relations.put(referenceDeclaration, referenceInfo); | ||
110 | } | ||
111 | |||
112 | private void collectAttribute(ClassDeclaration classDeclaration, AttributeDeclaration attributeDeclaration) { | ||
113 | // TODO Implement attribute handling. | ||
114 | } | ||
115 | |||
116 | private void collectFlag(ClassDeclaration classDeclaration, FlagDeclaration flagDeclaration) { | ||
117 | var parameter = ProblemFactory.eINSTANCE.createParameter(); | ||
118 | parameter.setName("object"); | ||
119 | parameter.setParameterType(classDeclaration); | ||
120 | var referenceInfo = new RelationInfo(getQualifiedNameString(flagDeclaration), ContainmentRole.NONE, | ||
121 | List.of(parameter), null, null, List.of()); | ||
122 | this.relations.put(flagDeclaration, referenceInfo); | ||
123 | } | ||
124 | |||
104 | private void collectEnum(EnumDeclaration enumDeclaration) { | 125 | private void collectEnum(EnumDeclaration enumDeclaration) { |
105 | var instanceParameter = ProblemFactory.eINSTANCE.createParameter(); | 126 | var instanceParameter = ProblemFactory.eINSTANCE.createParameter(); |
106 | instanceParameter.setName("instance"); | 127 | instanceParameter.setName("instance"); |
@@ -117,8 +138,6 @@ class SymbolCollector { | |||
117 | collectNewNode(classDeclaration); | 138 | collectNewNode(classDeclaration); |
118 | } else if (statement instanceof EnumDeclaration enumDeclaration) { | 139 | } else if (statement instanceof EnumDeclaration enumDeclaration) { |
119 | collectEnumLiterals(enumDeclaration); | 140 | collectEnumLiterals(enumDeclaration); |
120 | } else if (statement instanceof Assertion assertion) { | ||
121 | collectConstantNodes(assertion); | ||
122 | } | 141 | } |
123 | } | 142 | } |
124 | for (var node : problem.getNodes()) { | 143 | for (var node : problem.getNodes()) { |
@@ -145,17 +164,6 @@ class SymbolCollector { | |||
145 | } | 164 | } |
146 | } | 165 | } |
147 | 166 | ||
148 | private void collectConstantNodes(Assertion assertion) { | ||
149 | for (var argument : assertion.getArguments()) { | ||
150 | if (argument instanceof ConstantAssertionArgument constantAssertionArgument) { | ||
151 | var constantNode = constantAssertionArgument.getNode(); | ||
152 | if (constantNode != null) { | ||
153 | addNode(constantNode, false); | ||
154 | } | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | |||
159 | private void addNode(Node node, boolean individual) { | 167 | private void addNode(Node node, boolean individual) { |
160 | var info = new NodeInfo(getQualifiedNameString(node), individual); | 168 | var info = new NodeInfo(getQualifiedNameString(node), individual); |
161 | this.nodes.put(node, info); | 169 | this.nodes.put(node, info); |
@@ -173,8 +181,6 @@ class SymbolCollector { | |||
173 | for (var statement : problem.getStatements()) { | 181 | for (var statement : problem.getStatements()) { |
174 | if (statement instanceof Assertion assertion) { | 182 | if (statement instanceof Assertion assertion) { |
175 | collectAssertion(assertion); | 183 | collectAssertion(assertion); |
176 | } else if (statement instanceof NodeValueAssertion nodeValueAssertion) { | ||
177 | collectNodeValueAssertion(nodeValueAssertion); | ||
178 | } else if (statement instanceof PredicateDefinition predicateDefinition) { | 184 | } else if (statement instanceof PredicateDefinition predicateDefinition) { |
179 | collectPredicateAssertion(predicateDefinition); | 185 | collectPredicateAssertion(predicateDefinition); |
180 | } else if (statement instanceof ClassDeclaration classDeclaration) { | 186 | } else if (statement instanceof ClassDeclaration classDeclaration) { |
@@ -196,48 +202,6 @@ class SymbolCollector { | |||
196 | return; | 202 | return; |
197 | } | 203 | } |
198 | relationInfo.assertions().add(assertion); | 204 | relationInfo.assertions().add(assertion); |
199 | for (var argument : assertion.getArguments()) { | ||
200 | if (argument instanceof ConstantAssertionArgument constantAssertionArgument) { | ||
201 | var constantNode = constantAssertionArgument.getNode(); | ||
202 | if (constantNode != null) { | ||
203 | var valueAssertion = ProblemFactory.eINSTANCE.createNodeValueAssertion(); | ||
204 | valueAssertion.setNode(constantNode); | ||
205 | valueAssertion.setValue(EcoreUtil.copy(constantAssertionArgument.getConstant())); | ||
206 | collectNodeValueAssertion(valueAssertion); | ||
207 | var logicValue = assertion.getValue(); | ||
208 | if (logicValue != LogicValue.TRUE) { | ||
209 | addAssertion(builtinSymbols.exists(), logicValue, constantNode); | ||
210 | } | ||
211 | } | ||
212 | } | ||
213 | } | ||
214 | } | ||
215 | |||
216 | private void collectNodeValueAssertion(NodeValueAssertion nodeValueAssertion) { | ||
217 | var node = nodeValueAssertion.getNode(); | ||
218 | if (node == null) { | ||
219 | return; | ||
220 | } | ||
221 | var nodeInfo = this.nodes.get(node); | ||
222 | if (nodeInfo == null) { | ||
223 | throw new IllegalStateException("Node value assertion refers to unknown node"); | ||
224 | } | ||
225 | nodeInfo.valueAssertions().add(nodeValueAssertion); | ||
226 | var constant = nodeValueAssertion.getValue(); | ||
227 | if (constant == null) { | ||
228 | return; | ||
229 | } | ||
230 | Relation dataType; | ||
231 | if (constant instanceof IntConstant) { | ||
232 | dataType = builtinSymbols.intClass(); | ||
233 | } else if (constant instanceof RealConstant) { | ||
234 | dataType = builtinSymbols.real(); | ||
235 | } else if (constant instanceof StringConstant) { | ||
236 | dataType = builtinSymbols.string(); | ||
237 | } else { | ||
238 | throw new IllegalArgumentException("Unknown constant type"); | ||
239 | } | ||
240 | addAssertion(dataType, LogicValue.TRUE, node); | ||
241 | } | 205 | } |
242 | 206 | ||
243 | private void collectPredicateAssertion(PredicateDefinition predicateDefinition) { | 207 | private void collectPredicateAssertion(PredicateDefinition predicateDefinition) { |
@@ -278,7 +242,9 @@ class SymbolCollector { | |||
278 | } | 242 | } |
279 | assertion.getArguments().add(argument); | 243 | assertion.getArguments().add(argument); |
280 | } | 244 | } |
281 | assertion.setValue(logicValue); | 245 | var value = ProblemFactory.eINSTANCE.createLogicAssertionValue(); |
246 | value.setLogicValue(logicValue); | ||
247 | assertion.setValue(value); | ||
282 | collectAssertion(assertion); | 248 | collectAssertion(assertion); |
283 | } | 249 | } |
284 | } | 250 | } |
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 38e77237..06b6da1d 100644 --- a/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem +++ b/subprojects/language/src/main/resources/tools/refinery/language/builtin.problem | |||
@@ -6,19 +6,21 @@ abstract class node { | |||
6 | 6 | ||
7 | pred exists(node node). | 7 | pred exists(node node). |
8 | 8 | ||
9 | abstract class domain extends node. | 9 | % class Integer { |
10 | 10 | % int intValue | |
11 | abstract class data extends node. | 11 | % } |
12 | 12 | % | |
13 | enum bool { | 13 | % class Real { |
14 | true, false | 14 | % real realValue |
15 | } | 15 | % } |
16 | 16 | % | |
17 | class int extends data. | 17 | % class String { |
18 | 18 | % string stringValue | |
19 | class real extends data. | 19 | % } |
20 | 20 | % | |
21 | class string extends data. | 21 | % enum Boolean { |
22 | % TRUE, FALSE | ||
23 | % } | ||
22 | 24 | ||
23 | pred contained(node node). | 25 | pred contained(node node). |
24 | 26 | ||
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 3a6e015f..e0dee496 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 | |||
@@ -24,10 +24,10 @@ class ProblemParsingTest { | |||
24 | } | 24 | } |
25 | 25 | ||
26 | class Person { | 26 | class Person { |
27 | Person[0..*] children opposite parent | 27 | refers Person[0..*] children opposite parent |
28 | Person[0..1] parent opposite children | 28 | refers Person[0..1] parent opposite children |
29 | int age | 29 | int age |
30 | TaxStatus taxStatus | 30 | refers TaxStatus taxStatus |
31 | } | 31 | } |
32 | 32 | ||
33 | enum TaxStatus { | 33 | enum TaxStatus { |
@@ -46,10 +46,8 @@ class ProblemParsingTest { | |||
46 | children(anne, ciri). | 46 | children(anne, ciri). |
47 | ?children(bob, ciri). | 47 | ?children(bob, ciri). |
48 | taxStatus(anne, adult). | 48 | taxStatus(anne, adult). |
49 | age(anne, 35). | 49 | age(bob) in 21..35. |
50 | bobAge: 27. | 50 | age(ciri) = 10. |
51 | age(bob, bobAge). | ||
52 | !age(ciri, bobAge). | ||
53 | """); | 51 | """); |
54 | assertThat(problem.errors(), empty()); | 52 | assertThat(problem.errors(), empty()); |
55 | } | 53 | } |
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/parser/antlr/TransitiveClosureParserTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/parser/antlr/TransitiveClosureParserTest.java index 96d12edf..6e702720 100644 --- a/subprojects/language/src/test/java/tools/refinery/language/tests/parser/antlr/TransitiveClosureParserTest.java +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/parser/antlr/TransitiveClosureParserTest.java | |||
@@ -24,7 +24,9 @@ class TransitiveClosureParserTest { | |||
24 | @Test | 24 | @Test |
25 | void binaryAddOperatorTest() { | 25 | void binaryAddOperatorTest() { |
26 | var problem = parseHelper.parse(""" | 26 | var problem = parseHelper.parse(""" |
27 | pred foo(int a, int b) <-> a + (b) > 10. | 27 | int a(). |
28 | int b(). | ||
29 | pred foo() <-> a() + (b()) > 10. | ||
28 | """); | 30 | """); |
29 | assertThat(problem.errors(), empty()); | 31 | assertThat(problem.errors(), empty()); |
30 | var literal = problem.pred("foo").conj(0).lit(0).get(); | 32 | var literal = problem.pred("foo").conj(0).lit(0).get(); |
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/rules/RuleParsingTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/rules/RuleParsingTest.java index 4b42f4aa..72e5e18a 100644 --- a/subprojects/language/src/test/java/tools/refinery/language/tests/rules/RuleParsingTest.java +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/rules/RuleParsingTest.java | |||
@@ -1,10 +1,6 @@ | |||
1 | package tools.refinery.language.tests.rules; | 1 | package tools.refinery.language.tests.rules; |
2 | 2 | ||
3 | import static org.hamcrest.MatcherAssert.assertThat; | 3 | import com.google.inject.Inject; |
4 | import static org.hamcrest.Matchers.empty; | ||
5 | import static org.hamcrest.Matchers.equalTo; | ||
6 | import static org.hamcrest.Matchers.not; | ||
7 | |||
8 | import org.eclipse.xtext.testing.InjectWith; | 4 | import org.eclipse.xtext.testing.InjectWith; |
9 | import org.eclipse.xtext.testing.extensions.InjectionExtension; | 5 | import org.eclipse.xtext.testing.extensions.InjectionExtension; |
10 | import org.junit.jupiter.api.Disabled; | 6 | import org.junit.jupiter.api.Disabled; |
@@ -12,13 +8,13 @@ import org.junit.jupiter.api.Test; | |||
12 | import org.junit.jupiter.api.extension.ExtendWith; | 8 | import org.junit.jupiter.api.extension.ExtendWith; |
13 | import org.junit.jupiter.params.ParameterizedTest; | 9 | import org.junit.jupiter.params.ParameterizedTest; |
14 | import org.junit.jupiter.params.provider.ValueSource; | 10 | import org.junit.jupiter.params.provider.ValueSource; |
15 | |||
16 | import com.google.inject.Inject; | ||
17 | |||
18 | import tools.refinery.language.model.tests.utils.ProblemParseHelper; | 11 | import tools.refinery.language.model.tests.utils.ProblemParseHelper; |
19 | import tools.refinery.language.tests.ProblemInjectorProvider; | 12 | import tools.refinery.language.tests.ProblemInjectorProvider; |
20 | 13 | ||
21 | @Disabled | 14 | import static org.hamcrest.MatcherAssert.assertThat; |
15 | import static org.hamcrest.Matchers.*; | ||
16 | |||
17 | @Disabled("TODO: Rework transformation rules") | ||
22 | @ExtendWith(InjectionExtension.class) | 18 | @ExtendWith(InjectionExtension.class) |
23 | @InjectWith(ProblemInjectorProvider.class) | 19 | @InjectWith(ProblemInjectorProvider.class) |
24 | class RuleParsingTest { | 20 | class RuleParsingTest { |
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 9049b8ec..2fd647e5 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 | |||
@@ -3,6 +3,7 @@ package tools.refinery.language.tests.scoping; | |||
3 | import com.google.inject.Inject; | 3 | import com.google.inject.Inject; |
4 | import org.eclipse.xtext.testing.InjectWith; | 4 | import org.eclipse.xtext.testing.InjectWith; |
5 | import org.eclipse.xtext.testing.extensions.InjectionExtension; | 5 | import org.eclipse.xtext.testing.extensions.InjectionExtension; |
6 | import org.junit.jupiter.api.Disabled; | ||
6 | import org.junit.jupiter.api.Test; | 7 | import org.junit.jupiter.api.Test; |
7 | import org.junit.jupiter.api.extension.ExtendWith; | 8 | import org.junit.jupiter.api.extension.ExtendWith; |
8 | import org.junit.jupiter.params.ParameterizedTest; | 9 | import org.junit.jupiter.params.ParameterizedTest; |
@@ -28,15 +29,11 @@ class NodeScopingTest { | |||
28 | @ValueSource(strings = { "", "builtin::" }) | 29 | @ValueSource(strings = { "", "builtin::" }) |
29 | void builtInArgumentTypeTest(String qualifiedNamePrefix) { | 30 | void builtInArgumentTypeTest(String qualifiedNamePrefix) { |
30 | var problem = parse(""" | 31 | var problem = parse(""" |
31 | pred predicate({PARAM}node a, {PARAM}data b, {PARAM}int c). | 32 | pred predicate({PARAM}node a). |
32 | """, qualifiedNamePrefix); | 33 | """, qualifiedNamePrefix); |
33 | assertThat(problem.errors(), empty()); | 34 | assertThat(problem.errors(), empty()); |
34 | assertThat(problem.pred("predicate").param(0).getParameterType(), | 35 | assertThat(problem.pred("predicate").param(0).getParameterType(), |
35 | equalTo(problem.builtin().findClass("node").get())); | 36 | equalTo(problem.builtin().findClass("node").get())); |
36 | assertThat(problem.pred("predicate").param(1).getParameterType(), | ||
37 | equalTo(problem.builtin().findClass("data").get())); | ||
38 | assertThat(problem.pred("predicate").param(2).getParameterType(), | ||
39 | equalTo(problem.builtin().findClass("int").get())); | ||
40 | } | 37 | } |
41 | 38 | ||
42 | @Test | 39 | @Test |
@@ -55,16 +52,6 @@ class NodeScopingTest { | |||
55 | } | 52 | } |
56 | 53 | ||
57 | @Test | 54 | @Test |
58 | void implicitNodeInNodeValueAssertionTest() { | ||
59 | var problem = parseHelper.parse(""" | ||
60 | a: 16. | ||
61 | """); | ||
62 | assertThat(problem.errors(), empty()); | ||
63 | assertThat(problem.nodeNames(), hasItems("a")); | ||
64 | assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.node("a"))); | ||
65 | } | ||
66 | |||
67 | @Test | ||
68 | void implicitNodeInPredicateTest() { | 55 | void implicitNodeInPredicateTest() { |
69 | var problem = parse(""" | 56 | var problem = parse(""" |
70 | pred predicate(node a) <-> node(b). | 57 | pred predicate(node a) <-> node(b). |
@@ -95,18 +82,6 @@ class NodeScopingTest { | |||
95 | 82 | ||
96 | @ParameterizedTest | 83 | @ParameterizedTest |
97 | @MethodSource("individualNodeReferenceSource") | 84 | @MethodSource("individualNodeReferenceSource") |
98 | void individualNodeInNodeValueAssertionTest(String qualifiedNamePrefix, boolean namedProblem) { | ||
99 | var problem = parse(""" | ||
100 | individual a. | ||
101 | {PARAM}a: 16. | ||
102 | """, qualifiedNamePrefix, namedProblem); | ||
103 | assertThat(problem.errors(), empty()); | ||
104 | assertThat(problem.nodeNames(), empty()); | ||
105 | assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.individualNode("a"))); | ||
106 | } | ||
107 | |||
108 | @ParameterizedTest | ||
109 | @MethodSource("individualNodeReferenceSource") | ||
110 | void individualNodeInPredicateTest(String qualifiedNamePrefix, boolean namedProblem) { | 85 | void individualNodeInPredicateTest(String qualifiedNamePrefix, boolean namedProblem) { |
111 | var problem = parse(""" | 86 | var problem = parse(""" |
112 | individual b. | 87 | individual b. |
@@ -121,6 +96,7 @@ class NodeScopingTest { | |||
121 | return Stream.of(Arguments.of("", false), Arguments.of("", true), Arguments.of("test::", true)); | 96 | return Stream.of(Arguments.of("", false), Arguments.of("", true), Arguments.of("test::", true)); |
122 | } | 97 | } |
123 | 98 | ||
99 | @Disabled("No nodes are present in builtin.problem currently") | ||
124 | @ParameterizedTest | 100 | @ParameterizedTest |
125 | @MethodSource("builtInNodeReferencesSource") | 101 | @MethodSource("builtInNodeReferencesSource") |
126 | void builtInNodeTest(String qualifiedName) { | 102 | void builtInNodeTest(String qualifiedName) { |
@@ -133,18 +109,7 @@ class NodeScopingTest { | |||
133 | assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.builtin().findClass("int").get().getNewNode())); | 109 | assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.builtin().findClass("int").get().getNewNode())); |
134 | } | 110 | } |
135 | 111 | ||
136 | @ParameterizedTest | 112 | @Disabled("No nodes are present in builtin.problem currently") |
137 | @MethodSource("builtInNodeReferencesSource") | ||
138 | void builtInNodeInNodeValueAssertionTest(String qualifiedName) { | ||
139 | var problem = parse(""" | ||
140 | {PARAM}: 16. | ||
141 | """, qualifiedName); | ||
142 | assertThat(problem.errors(), empty()); | ||
143 | assertThat(problem.nodeNames(), empty()); | ||
144 | assertThat(problem.nodeValueAssertion(0).getNode(), | ||
145 | equalTo(problem.builtin().findClass("int").get().getNewNode())); | ||
146 | } | ||
147 | |||
148 | @ParameterizedTest | 113 | @ParameterizedTest |
149 | @MethodSource("builtInNodeReferencesSource") | 114 | @MethodSource("builtInNodeReferencesSource") |
150 | void builtInNodeInPredicateTest(String qualifiedName) { | 115 | void builtInNodeInPredicateTest(String qualifiedName) { |
@@ -176,18 +141,6 @@ class NodeScopingTest { | |||
176 | 141 | ||
177 | @ParameterizedTest | 142 | @ParameterizedTest |
178 | @MethodSource("classNewNodeReferencesSource") | 143 | @MethodSource("classNewNodeReferencesSource") |
179 | void classNewNodeInNodeValueAssertionTest(String qualifiedName, boolean namedProblem) { | ||
180 | var problem = parse(""" | ||
181 | class Foo. | ||
182 | {PARAM}: 16. | ||
183 | """, qualifiedName, namedProblem); | ||
184 | assertThat(problem.errors(), empty()); | ||
185 | assertThat(problem.nodeNames(), empty()); | ||
186 | assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.findClass("Foo").get().getNewNode())); | ||
187 | } | ||
188 | |||
189 | @ParameterizedTest | ||
190 | @MethodSource("classNewNodeReferencesSource") | ||
191 | void classNewNodeInPredicateTest(String qualifiedName, boolean namedProblem) { | 144 | void classNewNodeInPredicateTest(String qualifiedName, boolean namedProblem) { |
192 | var problem = parse(""" | 145 | var problem = parse(""" |
193 | class Foo. | 146 | class Foo. |
@@ -231,18 +184,6 @@ class NodeScopingTest { | |||
231 | 184 | ||
232 | @ParameterizedTest | 185 | @ParameterizedTest |
233 | @MethodSource("enumLiteralReferencesSource") | 186 | @MethodSource("enumLiteralReferencesSource") |
234 | void enumLiteralInNodeValueAssertionTest(String qualifiedName, boolean namedProblem) { | ||
235 | var problem = parse(""" | ||
236 | enum Foo { alpha, beta } | ||
237 | {PARAM}: 16. | ||
238 | """, qualifiedName, namedProblem); | ||
239 | assertThat(problem.errors(), empty()); | ||
240 | assertThat(problem.nodeNames(), empty()); | ||
241 | assertThat(problem.nodeValueAssertion(0).getNode(), equalTo(problem.findEnum("Foo").literal("alpha"))); | ||
242 | } | ||
243 | |||
244 | @ParameterizedTest | ||
245 | @MethodSource("enumLiteralReferencesSource") | ||
246 | void enumLiteralInPredicateTest(String qualifiedName, boolean namedProblem) { | 187 | void enumLiteralInPredicateTest(String qualifiedName, boolean namedProblem) { |
247 | var problem = parse(""" | 188 | var problem = parse(""" |
248 | enum Foo { alpha, beta } | 189 | enum Foo { alpha, beta } |
@@ -260,6 +201,7 @@ class NodeScopingTest { | |||
260 | Arguments.of("test::Foo::alpha", true)); | 201 | Arguments.of("test::Foo::alpha", true)); |
261 | } | 202 | } |
262 | 203 | ||
204 | @Disabled("No enum literals are present in builtin.problem currently") | ||
263 | @ParameterizedTest | 205 | @ParameterizedTest |
264 | @MethodSource("builtInEnumLiteralReferencesSource") | 206 | @MethodSource("builtInEnumLiteralReferencesSource") |
265 | void builtInEnumLiteralTest(String qualifiedName) { | 207 | void builtInEnumLiteralTest(String qualifiedName) { |
@@ -272,18 +214,7 @@ class NodeScopingTest { | |||
272 | assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.builtin().findEnum("bool").literal("true"))); | 214 | assertThat(problem.assertion(0).arg(0).node(), equalTo(problem.builtin().findEnum("bool").literal("true"))); |
273 | } | 215 | } |
274 | 216 | ||
275 | @ParameterizedTest | 217 | @Disabled("No enum literals are present in builtin.problem currently") |
276 | @MethodSource("builtInEnumLiteralReferencesSource") | ||
277 | void builtInEnumLiteralInNodeValueAssertionTest(String qualifiedName) { | ||
278 | var problem = parse(""" | ||
279 | {PARAM}: 16. | ||
280 | """, qualifiedName); | ||
281 | assertThat(problem.errors(), empty()); | ||
282 | assertThat(problem.nodeNames(), empty()); | ||
283 | assertThat(problem.nodeValueAssertion(0).getNode(), | ||
284 | equalTo(problem.builtin().findEnum("bool").literal("true"))); | ||
285 | } | ||
286 | |||
287 | @ParameterizedTest | 218 | @ParameterizedTest |
288 | @MethodSource("builtInEnumLiteralReferencesSource") | 219 | @MethodSource("builtInEnumLiteralReferencesSource") |
289 | void bultInEnumLiteralInPredicateTest(String qualifiedName) { | 220 | void bultInEnumLiteralInPredicateTest(String qualifiedName) { |
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 150e47a4..5024fb45 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 | |||
@@ -68,6 +68,29 @@ class ProblemSerializerTest { | |||
68 | Arguments.of(LogicValue.UNKNOWN, "?foo(a)."), Arguments.of(LogicValue.ERROR, "foo(a): error.")); | 68 | Arguments.of(LogicValue.UNKNOWN, "?foo(a)."), Arguments.of(LogicValue.ERROR, "foo(a): error.")); |
69 | } | 69 | } |
70 | 70 | ||
71 | @ParameterizedTest | ||
72 | @MethodSource | ||
73 | void defaultAssertionTest(LogicValue value, String valueAsString) { | ||
74 | var pred = createPred(); | ||
75 | var node = ProblemFactory.eINSTANCE.createNode(); | ||
76 | node.setName("a"); | ||
77 | var individualDeclaration = ProblemFactory.eINSTANCE.createIndividualDeclaration(); | ||
78 | individualDeclaration.getNodes().add(node); | ||
79 | problem.getStatements().add(individualDeclaration); | ||
80 | createAssertion(pred, node, value, true); | ||
81 | |||
82 | assertSerializedResult(""" | ||
83 | pred foo(node p). | ||
84 | |||
85 | individual a. | ||
86 | default foo(a):\040""" + valueAsString + ".\n"); | ||
87 | } | ||
88 | |||
89 | static Stream<Arguments> defaultAssertionTest() { | ||
90 | return Stream.of(Arguments.of(LogicValue.TRUE, "true"), Arguments.of(LogicValue.FALSE, "false"), | ||
91 | Arguments.of(LogicValue.UNKNOWN, "unknown"), Arguments.of(LogicValue.ERROR, "error")); | ||
92 | } | ||
93 | |||
71 | @Test | 94 | @Test |
72 | void implicitNodeTest() { | 95 | void implicitNodeTest() { |
73 | var pred = createPred(); | 96 | var pred = createPred(); |
@@ -116,13 +139,20 @@ class ProblemSerializerTest { | |||
116 | createAssertion(relation, node, LogicValue.TRUE); | 139 | createAssertion(relation, node, LogicValue.TRUE); |
117 | } | 140 | } |
118 | 141 | ||
119 | private void createAssertion(Relation relation, Node node, LogicValue value) { | 142 | private void createAssertion(Relation relation, Node node, LogicValue logicValue) { |
143 | createAssertion(relation, node, logicValue, false); | ||
144 | } | ||
145 | |||
146 | private void createAssertion(Relation relation, Node node, LogicValue logicValue, boolean isDefault) { | ||
120 | var assertion = ProblemFactory.eINSTANCE.createAssertion(); | 147 | var assertion = ProblemFactory.eINSTANCE.createAssertion(); |
121 | assertion.setRelation(relation); | 148 | assertion.setRelation(relation); |
122 | var argument = ProblemFactory.eINSTANCE.createNodeAssertionArgument(); | 149 | var argument = ProblemFactory.eINSTANCE.createNodeAssertionArgument(); |
123 | argument.setNode(node); | 150 | argument.setNode(node); |
124 | assertion.getArguments().add(argument); | 151 | assertion.getArguments().add(argument); |
152 | var value = ProblemFactory.eINSTANCE.createLogicAssertionValue(); | ||
153 | value.setLogicValue(logicValue); | ||
125 | assertion.setValue(value); | 154 | assertion.setValue(value); |
155 | assertion.setDefault(isDefault); | ||
126 | problem.getStatements().add(assertion); | 156 | problem.getStatements().add(assertion); |
127 | } | 157 | } |
128 | 158 | ||
@@ -143,7 +173,7 @@ class ProblemSerializerTest { | |||
143 | var variable = ProblemFactory.eINSTANCE.createImplicitVariable(); | 173 | var variable = ProblemFactory.eINSTANCE.createImplicitVariable(); |
144 | variable.setName("q"); | 174 | variable.setName("q"); |
145 | conjunction.getImplicitVariables().add(variable); | 175 | conjunction.getImplicitVariables().add(variable); |
146 | var equals = nodeType.reference("equals"); | 176 | var equals = nodeType.feature("equals"); |
147 | conjunction.getLiterals().add(createAtom(equals, parameter1, variable)); | 177 | conjunction.getLiterals().add(createAtom(equals, parameter1, variable)); |
148 | conjunction.getLiterals().add(createAtom(equals, variable, parameter2)); | 178 | conjunction.getLiterals().add(createAtom(equals, variable, parameter2)); |
149 | pred.getBodies().add(conjunction); | 179 | pred.getBodies().add(conjunction); |
@@ -177,7 +207,7 @@ class ProblemSerializerTest { | |||
177 | pred.getParameters().add(parameter); | 207 | pred.getParameters().add(parameter); |
178 | var conjunction = ProblemFactory.eINSTANCE.createConjunction(); | 208 | var conjunction = ProblemFactory.eINSTANCE.createConjunction(); |
179 | var atom = ProblemFactory.eINSTANCE.createAtom(); | 209 | var atom = ProblemFactory.eINSTANCE.createAtom(); |
180 | var equals = nodeType.reference("equals"); | 210 | var equals = nodeType.feature("equals"); |
181 | atom.setRelation(equals); | 211 | atom.setRelation(equals); |
182 | var arg1 = ProblemFactory.eINSTANCE.createVariableOrNodeExpr(); | 212 | var arg1 = ProblemFactory.eINSTANCE.createVariableOrNodeExpr(); |
183 | arg1.setVariableOrNode(parameter); | 213 | arg1.setVariableOrNode(parameter); |
diff --git a/subprojects/language/src/test/java/tools/refinery/language/tests/utils/SymbolCollectorTest.java b/subprojects/language/src/test/java/tools/refinery/language/tests/utils/SymbolCollectorTest.java index 98c16352..66b7f1ab 100644 --- a/subprojects/language/src/test/java/tools/refinery/language/tests/utils/SymbolCollectorTest.java +++ b/subprojects/language/src/test/java/tools/refinery/language/tests/utils/SymbolCollectorTest.java | |||
@@ -4,6 +4,7 @@ import com.google.inject.Inject; | |||
4 | import org.eclipse.xtext.testing.InjectWith; | 4 | import org.eclipse.xtext.testing.InjectWith; |
5 | import org.eclipse.xtext.testing.extensions.InjectionExtension; | 5 | import org.eclipse.xtext.testing.extensions.InjectionExtension; |
6 | import org.hamcrest.Matcher; | 6 | import org.hamcrest.Matcher; |
7 | import org.junit.jupiter.api.Disabled; | ||
7 | import org.junit.jupiter.api.Test; | 8 | import org.junit.jupiter.api.Test; |
8 | import org.junit.jupiter.api.extension.ExtendWith; | 9 | import org.junit.jupiter.api.extension.ExtendWith; |
9 | import org.junit.jupiter.params.ParameterizedTest; | 10 | import org.junit.jupiter.params.ParameterizedTest; |
@@ -87,15 +88,15 @@ class SymbolCollectorTest { | |||
87 | void referenceTest() { | 88 | void referenceTest() { |
88 | var problem = parseHelper.parse(""" | 89 | var problem = parseHelper.parse(""" |
89 | class Foo { | 90 | class Foo { |
90 | Foo[] bar opposite quux | 91 | refers Foo[] bar opposite quux |
91 | Foo quux opposite bar | 92 | refers Foo quux opposite bar |
92 | } | 93 | } |
93 | """); | 94 | """); |
94 | var collectedSymbols = desugarer.collectSymbols(problem.get()); | 95 | var collectedSymbols = desugarer.collectSymbols(problem.get()); |
95 | var fooClass = problem.findClass("Foo"); | 96 | var fooClass = problem.findClass("Foo"); |
96 | var barReference = fooClass.reference("bar"); | 97 | var barReference = fooClass.feature("bar"); |
97 | var barInfo = collectedSymbols.relations().get(barReference); | 98 | var barInfo = collectedSymbols.relations().get(barReference); |
98 | var quuxReference = fooClass.reference("quux"); | 99 | var quuxReference = fooClass.feature("quux"); |
99 | var quuxInfo = collectedSymbols.relations().get(quuxReference); | 100 | var quuxInfo = collectedSymbols.relations().get(quuxReference); |
100 | assertThat(barInfo.containmentRole(), is(ContainmentRole.NONE)); | 101 | assertThat(barInfo.containmentRole(), is(ContainmentRole.NONE)); |
101 | assertThat(barInfo.opposite(), is(quuxReference)); | 102 | assertThat(barInfo.opposite(), is(quuxReference)); |
@@ -116,10 +117,11 @@ class SymbolCollectorTest { | |||
116 | } | 117 | } |
117 | """); | 118 | """); |
118 | var collectedSymbols = desugarer.collectSymbols(problem.get()); | 119 | var collectedSymbols = desugarer.collectSymbols(problem.get()); |
119 | assertThat(collectedSymbols.relations().get(problem.findClass("Foo").reference("bar")).containmentRole(), | 120 | assertThat(collectedSymbols.relations().get(problem.findClass("Foo").feature("bar")).containmentRole(), |
120 | is(ContainmentRole.CONTAINMENT)); | 121 | is(ContainmentRole.CONTAINMENT)); |
121 | } | 122 | } |
122 | 123 | ||
124 | @Disabled("TODO: Rework numerical references") | ||
123 | @Test | 125 | @Test |
124 | void dataReferenceTest() { | 126 | void dataReferenceTest() { |
125 | var problem = parseHelper.parse(""" | 127 | var problem = parseHelper.parse(""" |
@@ -128,7 +130,7 @@ class SymbolCollectorTest { | |||
128 | } | 130 | } |
129 | """); | 131 | """); |
130 | var collectedSymbols = desugarer.collectSymbols(problem.get()); | 132 | var collectedSymbols = desugarer.collectSymbols(problem.get()); |
131 | assertThat(collectedSymbols.relations().get(problem.findClass("Foo").reference("bar")).containmentRole(), | 133 | assertThat(collectedSymbols.relations().get(problem.findClass("Foo").feature("bar")).containmentRole(), |
132 | is(ContainmentRole.CONTAINMENT)); | 134 | is(ContainmentRole.CONTAINMENT)); |
133 | } | 135 | } |
134 | 136 | ||
@@ -204,61 +206,6 @@ class SymbolCollectorTest { | |||
204 | assertThat(collectedSymbols.relations().get(problem.pred("foo").get()).assertions(), hasSize(0)); | 206 | assertThat(collectedSymbols.relations().get(problem.pred("foo").get()).assertions(), hasSize(0)); |
205 | } | 207 | } |
206 | 208 | ||
207 | @ParameterizedTest | ||
208 | @MethodSource("valueTypes") | ||
209 | void nodeValueAssertionTest(String value, String typeName) { | ||
210 | var problem = parseHelper.parse("a: %s.".formatted(value)); | ||
211 | var collectedSymbols = desugarer.collectSymbols(problem.get()); | ||
212 | var node = problem.node("a"); | ||
213 | var nodeInfo = collectedSymbols.nodes().get(node); | ||
214 | assertThat(nodeInfo.individual(), is(false)); | ||
215 | assertThat(nodeInfo.valueAssertions(), hasSize(1)); | ||
216 | assertThat(collectedSymbols.relations().get(problem.builtin().findClass(typeName).get()).assertions(), | ||
217 | assertsNode(node, LogicValue.TRUE)); | ||
218 | } | ||
219 | |||
220 | @ParameterizedTest | ||
221 | @MethodSource("valueTypes") | ||
222 | void constantInAssertionTest(String value, String typeName) { | ||
223 | var problem = parseHelper.parse(""" | ||
224 | containment pred foo(node x, data y). | ||
225 | foo(a, %s). | ||
226 | """.formatted(value)); | ||
227 | var collectedSymbols = desugarer.collectSymbols(problem.get()); | ||
228 | var node = problem.assertion(0).arg(1).constantNode(); | ||
229 | var nodeInfo = collectedSymbols.nodes().get(node); | ||
230 | assertThat(nodeInfo.individual(), is(false)); | ||
231 | assertThat(nodeInfo.valueAssertions(), hasSize(1)); | ||
232 | assertThat(collectedSymbols.relations().get(problem.pred("foo").get()).assertions(), assertsNode(node, | ||
233 | LogicValue.TRUE)); | ||
234 | assertThat(collectedSymbols.relations().get(problem.builtin().findClass(typeName).get()).assertions(), | ||
235 | assertsNode(node, LogicValue.TRUE)); | ||
236 | } | ||
237 | |||
238 | @ParameterizedTest | ||
239 | @MethodSource("valueTypes") | ||
240 | void constantInUnknownAssertionTest(String value, String typeName) { | ||
241 | var problem = parseHelper.parse(""" | ||
242 | containment pred foo(node x, data y). | ||
243 | foo(a, %s): unknown. | ||
244 | """.formatted(value)); | ||
245 | var collectedSymbols = desugarer.collectSymbols(problem.get()); | ||
246 | var node = problem.assertion(0).arg(1).constantNode(); | ||
247 | var nodeInfo = collectedSymbols.nodes().get(node); | ||
248 | assertThat(nodeInfo.individual(), is(false)); | ||
249 | assertThat(nodeInfo.valueAssertions(), hasSize(1)); | ||
250 | assertThat(collectedSymbols.relations().get(problem.pred("foo").get()).assertions(), assertsNode(node, | ||
251 | LogicValue.UNKNOWN)); | ||
252 | assertThat(collectedSymbols.relations().get(problem.builtin().findClass(typeName).get()).assertions(), | ||
253 | assertsNode(node, LogicValue.TRUE)); | ||
254 | assertThat(collectedSymbols.relations().get(problem.builtinSymbols().exists()).assertions(), assertsNode(node, | ||
255 | LogicValue.UNKNOWN)); | ||
256 | } | ||
257 | |||
258 | static Stream<Arguments> valueTypes() { | ||
259 | return Stream.of(Arguments.of("3", "int"), Arguments.of("3.14", "real"), Arguments.of("\"foo\"", "string")); | ||
260 | } | ||
261 | |||
262 | @Test | 209 | @Test |
263 | void invalidProblemTest() { | 210 | void invalidProblemTest() { |
264 | var problem = parseHelper.parse(""" | 211 | var problem = parseHelper.parse(""" |
@@ -279,13 +226,13 @@ class SymbolCollectorTest { | |||
279 | var fooInfo = collectedSymbols.relations().get(problem.pred("foo").get()); | 226 | var fooInfo = collectedSymbols.relations().get(problem.pred("foo").get()); |
280 | assertThat(fooInfo.assertions(), hasSize(1)); | 227 | assertThat(fooInfo.assertions(), hasSize(1)); |
281 | var assertion = fooInfo.assertions().stream().findFirst().orElseThrow(); | 228 | var assertion = fooInfo.assertions().stream().findFirst().orElseThrow(); |
282 | assertThat(assertion.getValue(), is(LogicValue.FALSE)); | 229 | assertThat(assertion.getValue(), hasProperty("logicValue", is(LogicValue.FALSE))); |
283 | assertThat(assertion.getArguments(), hasSize(2)); | 230 | assertThat(assertion.getArguments(), hasSize(2)); |
284 | assertThat(assertion.getArguments(), everyItem(instanceOf(WildcardAssertionArgument.class))); | 231 | assertThat(assertion.getArguments(), everyItem(instanceOf(WildcardAssertionArgument.class))); |
285 | } | 232 | } |
286 | 233 | ||
287 | private static Matcher<Iterable<? super Assertion>> assertsNode(Node node, LogicValue value) { | 234 | private static Matcher<Iterable<? super Assertion>> assertsNode(Node node, LogicValue value) { |
288 | return hasItem(allOf(hasProperty("arguments", hasItem(hasProperty("node", is(node)))), hasProperty("value", | 235 | return hasItem(allOf(hasProperty("arguments", hasItem(hasProperty("node", is(node)))), hasProperty("value", |
289 | is(value)))); | 236 | hasProperty("logicValue", is(value))))); |
290 | } | 237 | } |
291 | } | 238 | } |
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java index b8b3a7de..840c1f74 100644 --- a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedAssertionArgument.java | |||
@@ -1,7 +1,6 @@ | |||
1 | package tools.refinery.language.model.tests.utils; | 1 | package tools.refinery.language.model.tests.utils; |
2 | 2 | ||
3 | import tools.refinery.language.model.problem.AssertionArgument; | 3 | import tools.refinery.language.model.problem.AssertionArgument; |
4 | import tools.refinery.language.model.problem.ConstantAssertionArgument; | ||
5 | import tools.refinery.language.model.problem.Node; | 4 | import tools.refinery.language.model.problem.Node; |
6 | import tools.refinery.language.model.problem.NodeAssertionArgument; | 5 | import tools.refinery.language.model.problem.NodeAssertionArgument; |
7 | 6 | ||
@@ -13,8 +12,4 @@ public record WrappedAssertionArgument(AssertionArgument assertionArgument) { | |||
13 | public Node node() { | 12 | public Node node() { |
14 | return ((NodeAssertionArgument) assertionArgument).getNode(); | 13 | return ((NodeAssertionArgument) assertionArgument).getNode(); |
15 | } | 14 | } |
16 | |||
17 | public Node constantNode() { | ||
18 | return ((ConstantAssertionArgument) assertionArgument).getNode(); | ||
19 | } | ||
20 | } | 15 | } |
diff --git a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java index d8926c29..41b2ea62 100644 --- a/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java +++ b/subprojects/language/src/testFixtures/java/tools/refinery/language/model/tests/utils/WrappedClassDeclaration.java | |||
@@ -1,14 +1,14 @@ | |||
1 | package tools.refinery.language.model.tests.utils; | 1 | package tools.refinery.language.model.tests.utils; |
2 | 2 | ||
3 | import tools.refinery.language.model.problem.ClassDeclaration; | 3 | import tools.refinery.language.model.problem.ClassDeclaration; |
4 | import tools.refinery.language.model.problem.ReferenceDeclaration; | 4 | import tools.refinery.language.model.problem.FeatureDeclaration; |
5 | 5 | ||
6 | public record WrappedClassDeclaration(ClassDeclaration classDeclaration) { | 6 | public record WrappedClassDeclaration(ClassDeclaration classDeclaration) { |
7 | public ClassDeclaration get() { | 7 | public ClassDeclaration get() { |
8 | return classDeclaration; | 8 | return classDeclaration; |
9 | } | 9 | } |
10 | 10 | ||
11 | public ReferenceDeclaration reference(String name) { | 11 | public FeatureDeclaration feature(String name) { |
12 | return ProblemNavigationUtil.named(classDeclaration.getReferenceDeclarations(), name); | 12 | return ProblemNavigationUtil.named(classDeclaration.getFeatureDeclarations(), name); |
13 | } | 13 | } |
14 | } | 14 | } |
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 aef96b5b..78ca95c7 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 | |||
@@ -1,25 +1,14 @@ | |||
1 | package tools.refinery.language.model.tests.utils; | 1 | package tools.refinery.language.model.tests.utils; |
2 | 2 | ||
3 | import java.util.List; | ||
4 | import java.util.stream.Stream; | ||
5 | |||
6 | import org.eclipse.emf.ecore.resource.Resource.Diagnostic; | 3 | import org.eclipse.emf.ecore.resource.Resource.Diagnostic; |
7 | import org.eclipse.emf.ecore.util.EcoreUtil; | 4 | import org.eclipse.emf.ecore.util.EcoreUtil; |
8 | 5 | import tools.refinery.language.model.problem.*; | |
9 | import tools.refinery.language.model.problem.Assertion; | ||
10 | import tools.refinery.language.model.problem.ClassDeclaration; | ||
11 | import tools.refinery.language.model.problem.EnumDeclaration; | ||
12 | import tools.refinery.language.model.problem.IndividualDeclaration; | ||
13 | import tools.refinery.language.model.problem.NamedElement; | ||
14 | import tools.refinery.language.model.problem.Node; | ||
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.RuleDefinition; | ||
19 | import tools.refinery.language.model.problem.Statement; | ||
20 | import tools.refinery.language.utils.BuiltinSymbols; | 6 | import tools.refinery.language.utils.BuiltinSymbols; |
21 | import tools.refinery.language.utils.ProblemDesugarer; | 7 | import tools.refinery.language.utils.ProblemDesugarer; |
22 | 8 | ||
9 | import java.util.List; | ||
10 | import java.util.stream.Stream; | ||
11 | |||
23 | public record WrappedProblem(Problem problem) { | 12 | public record WrappedProblem(Problem problem) { |
24 | public Problem get() { | 13 | public Problem get() { |
25 | return problem; | 14 | return problem; |
@@ -72,10 +61,6 @@ public record WrappedProblem(Problem problem) { | |||
72 | return ProblemNavigationUtil.named(uniqueNodes, name); | 61 | return ProblemNavigationUtil.named(uniqueNodes, name); |
73 | } | 62 | } |
74 | 63 | ||
75 | public NodeValueAssertion nodeValueAssertion(int i) { | ||
76 | return nthStatementOfType(NodeValueAssertion.class, i); | ||
77 | } | ||
78 | |||
79 | private <T extends Statement> Stream<T> statementsOfType(Class<? extends T> type) { | 64 | private <T extends Statement> Stream<T> statementsOfType(Class<? extends T> type) { |
80 | return problem.getStatements().stream().filter(type::isInstance).map(type::cast); | 65 | return problem.getStatements().stream().filter(type::isInstance).map(type::cast); |
81 | } | 66 | } |