diff options
Diffstat (limited to 'subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java')
-rw-r--r-- | subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java | 182 |
1 files changed, 123 insertions, 59 deletions
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java index 38bf5a61..c2bca2a5 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/ModelInitializer.java | |||
@@ -6,7 +6,9 @@ | |||
6 | package tools.refinery.language.semantics; | 6 | package tools.refinery.language.semantics; |
7 | 7 | ||
8 | import com.google.inject.Inject; | 8 | import com.google.inject.Inject; |
9 | import tools.refinery.language.library.BuiltinLibrary; | ||
9 | import tools.refinery.language.model.problem.*; | 10 | import tools.refinery.language.model.problem.*; |
11 | import tools.refinery.language.scoping.imports.ImportCollector; | ||
10 | import tools.refinery.language.semantics.internal.MutableSeed; | 12 | import tools.refinery.language.semantics.internal.MutableSeed; |
11 | import tools.refinery.language.utils.BuiltinSymbols; | 13 | import tools.refinery.language.utils.BuiltinSymbols; |
12 | import tools.refinery.language.utils.ProblemDesugarer; | 14 | import tools.refinery.language.utils.ProblemDesugarer; |
@@ -51,8 +53,13 @@ public class ModelInitializer { | |||
51 | @Inject | 53 | @Inject |
52 | private ProblemTraceImpl problemTrace; | 54 | private ProblemTraceImpl problemTrace; |
53 | 55 | ||
56 | @Inject | ||
57 | private ImportCollector importCollector; | ||
58 | |||
54 | private Problem problem; | 59 | private Problem problem; |
55 | 60 | ||
61 | private final Set<Problem> importedProblems = new HashSet<>(); | ||
62 | |||
56 | private BuiltinSymbols builtinSymbols; | 63 | private BuiltinSymbols builtinSymbols; |
57 | 64 | ||
58 | private PartialRelation nodeRelation; | 65 | private PartialRelation nodeRelation; |
@@ -82,6 +89,8 @@ public class ModelInitializer { | |||
82 | throw new IllegalArgumentException("Problem was already set"); | 89 | throw new IllegalArgumentException("Problem was already set"); |
83 | } | 90 | } |
84 | this.problem = problem; | 91 | this.problem = problem; |
92 | loadImportedProblems(); | ||
93 | importedProblems.add(problem); | ||
85 | problemTrace.setProblem(problem); | 94 | problemTrace.setProblem(problem); |
86 | try { | 95 | try { |
87 | builtinSymbols = desugarer.getBuiltinSymbols(problem).orElseThrow(() -> new IllegalArgumentException( | 96 | builtinSymbols = desugarer.getBuiltinSymbols(problem).orElseThrow(() -> new IllegalArgumentException( |
@@ -128,6 +137,29 @@ public class ModelInitializer { | |||
128 | } | 137 | } |
129 | } | 138 | } |
130 | 139 | ||
140 | private void loadImportedProblems() { | ||
141 | var resource = problem.eResource(); | ||
142 | if (resource == null) { | ||
143 | return; | ||
144 | } | ||
145 | var resourceSet = resource.getResourceSet(); | ||
146 | if (resourceSet == null) { | ||
147 | return; | ||
148 | } | ||
149 | var importedUris = importCollector.getAllImports(resource).toUriSet(); | ||
150 | for (var uri : importedUris) { | ||
151 | if (BuiltinLibrary.BUILTIN_LIBRARY_URI.equals(uri)) { | ||
152 | // We hard-code the behavior of the builtin library. | ||
153 | continue; | ||
154 | } | ||
155 | var importedResource = resourceSet.getResource(uri, false); | ||
156 | if (importedResource != null && !importedResource.getContents().isEmpty() && | ||
157 | importedResource.getContents().getFirst() instanceof Problem importedProblem) { | ||
158 | importedProblems.add(importedProblem); | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | |||
131 | public void configureStoreBuilder(ModelStoreBuilder storeBuilder) { | 163 | public void configureStoreBuilder(ModelStoreBuilder storeBuilder) { |
132 | checkProblem(); | 164 | checkProblem(); |
133 | try { | 165 | try { |
@@ -168,19 +200,21 @@ public class ModelInitializer { | |||
168 | } | 200 | } |
169 | 201 | ||
170 | private void collectNodes() { | 202 | private void collectNodes() { |
171 | for (var statement : problem.getStatements()) { | 203 | for (var importedProblem : importedProblems) { |
172 | if (statement instanceof IndividualDeclaration individualDeclaration) { | 204 | for (var statement : importedProblem.getStatements()) { |
173 | for (var individual : individualDeclaration.getNodes()) { | 205 | if (statement instanceof NodeDeclaration nodeDeclaration) { |
174 | collectNode(individual); | 206 | for (var node : nodeDeclaration.getNodes()) { |
175 | } | 207 | collectNode(node); |
176 | } else if (statement instanceof ClassDeclaration classDeclaration) { | 208 | } |
177 | var newNode = classDeclaration.getNewNode(); | 209 | } else if (statement instanceof ClassDeclaration classDeclaration) { |
178 | if (newNode != null) { | 210 | var newNode = classDeclaration.getNewNode(); |
179 | collectNode(newNode); | 211 | if (newNode != null) { |
180 | } | 212 | collectNode(newNode); |
181 | } else if (statement instanceof EnumDeclaration enumDeclaration) { | 213 | } |
182 | for (var literal : enumDeclaration.getLiterals()) { | 214 | } else if (statement instanceof EnumDeclaration enumDeclaration) { |
183 | collectNode(literal); | 215 | for (var literal : enumDeclaration.getLiterals()) { |
216 | collectNode(literal); | ||
217 | } | ||
184 | } | 218 | } |
185 | } | 219 | } |
186 | } | 220 | } |
@@ -194,13 +228,15 @@ public class ModelInitializer { | |||
194 | } | 228 | } |
195 | 229 | ||
196 | private void collectPartialSymbols() { | 230 | private void collectPartialSymbols() { |
197 | for (var statement : problem.getStatements()) { | 231 | for (var importedProblem : importedProblems) { |
198 | if (statement instanceof ClassDeclaration classDeclaration) { | 232 | for (var statement : importedProblem.getStatements()) { |
199 | collectClassDeclarationSymbols(classDeclaration); | 233 | if (statement instanceof ClassDeclaration classDeclaration) { |
200 | } else if (statement instanceof EnumDeclaration enumDeclaration) { | 234 | collectClassDeclarationSymbols(classDeclaration); |
201 | collectPartialRelation(enumDeclaration, 1, TruthValue.FALSE, TruthValue.FALSE); | 235 | } else if (statement instanceof EnumDeclaration enumDeclaration) { |
202 | } else if (statement instanceof PredicateDefinition predicateDefinition) { | 236 | collectPartialRelation(enumDeclaration, 1, TruthValue.FALSE, TruthValue.FALSE); |
203 | collectPredicateDefinitionSymbol(predicateDefinition); | 237 | } else if (statement instanceof PredicateDefinition predicateDefinition) { |
238 | collectPredicateDefinitionSymbol(predicateDefinition); | ||
239 | } | ||
204 | } | 240 | } |
205 | } | 241 | } |
206 | } | 242 | } |
@@ -247,15 +283,17 @@ public class ModelInitializer { | |||
247 | } | 283 | } |
248 | 284 | ||
249 | private String getName(Relation relation) { | 285 | private String getName(Relation relation) { |
250 | return semanticsUtils.getName(relation).orElseGet(() -> "::" + relationInfoMap.size()); | 286 | return semanticsUtils.getNameWithoutRootPrefix(relation).orElseGet(() -> "::" + relationInfoMap.size()); |
251 | } | 287 | } |
252 | 288 | ||
253 | private void collectMetamodel() { | 289 | private void collectMetamodel() { |
254 | for (var statement : problem.getStatements()) { | 290 | for (var importedProblem : importedProblems) { |
255 | if (statement instanceof ClassDeclaration classDeclaration) { | 291 | for (var statement : importedProblem.getStatements()) { |
256 | collectClassDeclarationMetamodel(classDeclaration); | 292 | if (statement instanceof ClassDeclaration classDeclaration) { |
257 | } else if (statement instanceof EnumDeclaration enumDeclaration) { | 293 | collectClassDeclarationMetamodel(classDeclaration); |
258 | collectEnumMetamodel(enumDeclaration); | 294 | } else if (statement instanceof EnumDeclaration enumDeclaration) { |
295 | collectEnumMetamodel(enumDeclaration); | ||
296 | } | ||
259 | } | 297 | } |
260 | } | 298 | } |
261 | } | 299 | } |
@@ -350,17 +388,17 @@ public class ModelInitializer { | |||
350 | } | 388 | } |
351 | 389 | ||
352 | private void collectAssertions() { | 390 | private void collectAssertions() { |
353 | for (var statement : problem.getStatements()) { | 391 | for (var importedProblem : importedProblems) { |
354 | if (statement instanceof ClassDeclaration classDeclaration) { | 392 | for (var statement : importedProblem.getStatements()) { |
355 | collectClassDeclarationAssertions(classDeclaration); | 393 | if (statement instanceof ClassDeclaration classDeclaration) { |
356 | } else if (statement instanceof EnumDeclaration enumDeclaration) { | 394 | collectClassDeclarationAssertions(classDeclaration); |
357 | collectEnumAssertions(enumDeclaration); | 395 | } else if (statement instanceof EnumDeclaration enumDeclaration) { |
358 | } else if (statement instanceof IndividualDeclaration individualDeclaration) { | 396 | collectEnumAssertions(enumDeclaration); |
359 | for (var individual : individualDeclaration.getNodes()) { | 397 | } else if (statement instanceof NodeDeclaration nodeDeclaration) { |
360 | collectIndividualAssertions(individual); | 398 | collectNodeDeclarationAssertions(nodeDeclaration); |
399 | } else if (statement instanceof Assertion assertion) { | ||
400 | collectAssertion(assertion); | ||
361 | } | 401 | } |
362 | } else if (statement instanceof Assertion assertion) { | ||
363 | collectAssertion(assertion); | ||
364 | } | 402 | } |
365 | } | 403 | } |
366 | } | 404 | } |
@@ -379,7 +417,7 @@ public class ModelInitializer { | |||
379 | private void collectEnumAssertions(EnumDeclaration enumDeclaration) { | 417 | private void collectEnumAssertions(EnumDeclaration enumDeclaration) { |
380 | var overlay = MutableSeed.of(1, null); | 418 | var overlay = MutableSeed.of(1, null); |
381 | for (var literal : enumDeclaration.getLiterals()) { | 419 | for (var literal : enumDeclaration.getLiterals()) { |
382 | collectIndividualAssertions(literal); | 420 | collectCardinalityAssertions(literal, TruthValue.TRUE); |
383 | var nodeId = getNodeId(literal); | 421 | var nodeId = getNodeId(literal); |
384 | overlay.mergeValue(Tuple.of(nodeId), TruthValue.TRUE); | 422 | overlay.mergeValue(Tuple.of(nodeId), TruthValue.TRUE); |
385 | } | 423 | } |
@@ -387,9 +425,25 @@ public class ModelInitializer { | |||
387 | info.assertions().overwriteValues(overlay); | 425 | info.assertions().overwriteValues(overlay); |
388 | } | 426 | } |
389 | 427 | ||
390 | private void collectIndividualAssertions(Node node) { | 428 | private void collectNodeDeclarationAssertions(NodeDeclaration nodeDeclaration) { |
429 | var kind = nodeDeclaration.getKind(); | ||
430 | TruthValue value; | ||
431 | switch (kind) { | ||
432 | case ATOM -> value = TruthValue.TRUE; | ||
433 | case MULTI -> value = TruthValue.UNKNOWN; | ||
434 | case NODE -> { | ||
435 | return; | ||
436 | } | ||
437 | default -> throw new IllegalArgumentException("Unknown node kind: " + kind); | ||
438 | } | ||
439 | for (var node : nodeDeclaration.getNodes()) { | ||
440 | collectCardinalityAssertions(node, value); | ||
441 | } | ||
442 | } | ||
443 | |||
444 | private void collectCardinalityAssertions(Node node, TruthValue value) { | ||
391 | var nodeId = getNodeId(node); | 445 | var nodeId = getNodeId(node); |
392 | collectCardinalityAssertions(nodeId, TruthValue.TRUE); | 446 | collectCardinalityAssertions(nodeId, value); |
393 | } | 447 | } |
394 | 448 | ||
395 | private void collectCardinalityAssertions(int nodeId, TruthValue value) { | 449 | private void collectCardinalityAssertions(int nodeId, TruthValue value) { |
@@ -415,9 +469,11 @@ public class ModelInitializer { | |||
415 | } | 469 | } |
416 | 470 | ||
417 | private void fixClassDeclarationAssertions() { | 471 | private void fixClassDeclarationAssertions() { |
418 | for (var statement : problem.getStatements()) { | 472 | for (var importedProblem : importedProblems) { |
419 | if (statement instanceof ClassDeclaration classDeclaration) { | 473 | for (var statement : importedProblem.getStatements()) { |
420 | fixClassDeclarationAssertions(classDeclaration); | 474 | if (statement instanceof ClassDeclaration classDeclaration) { |
475 | fixClassDeclarationAssertions(classDeclaration); | ||
476 | } | ||
421 | } | 477 | } |
422 | } | 478 | } |
423 | } | 479 | } |
@@ -485,9 +541,11 @@ public class ModelInitializer { | |||
485 | } | 541 | } |
486 | 542 | ||
487 | private void collectPredicates(ModelStoreBuilder storeBuilder) { | 543 | private void collectPredicates(ModelStoreBuilder storeBuilder) { |
488 | for (var statement : problem.getStatements()) { | 544 | for (var importedProblem : importedProblems) { |
489 | if (statement instanceof PredicateDefinition predicateDefinition) { | 545 | for (var statement : importedProblem.getStatements()) { |
490 | collectPredicateDefinitionTraced(predicateDefinition, storeBuilder); | 546 | if (statement instanceof PredicateDefinition predicateDefinition) { |
547 | collectPredicateDefinitionTraced(predicateDefinition, storeBuilder); | ||
548 | } | ||
491 | } | 549 | } |
492 | } | 550 | } |
493 | } | 551 | } |
@@ -587,18 +645,21 @@ public class ModelInitializer { | |||
587 | 645 | ||
588 | private void toLiterals(Expr expr, Map<tools.refinery.language.model.problem.Variable, Variable> localScope, | 646 | private void toLiterals(Expr expr, Map<tools.refinery.language.model.problem.Variable, Variable> localScope, |
589 | List<Literal> literals) { | 647 | List<Literal> literals) { |
590 | if (expr instanceof LogicConstant logicConstant) { | 648 | switch (expr) { |
649 | case LogicConstant logicConstant -> { | ||
591 | switch (logicConstant.getLogicValue()) { | 650 | switch (logicConstant.getLogicValue()) { |
592 | case TRUE -> literals.add(BooleanLiteral.TRUE); | 651 | case TRUE -> literals.add(BooleanLiteral.TRUE); |
593 | case FALSE -> literals.add(BooleanLiteral.FALSE); | 652 | case FALSE -> literals.add(BooleanLiteral.FALSE); |
594 | default -> throw new TracedException(logicConstant, "Unsupported literal"); | 653 | default -> throw new TracedException(logicConstant, "Unsupported literal"); |
595 | } | 654 | } |
596 | } else if (expr instanceof Atom atom) { | 655 | } |
656 | case Atom atom -> { | ||
597 | var target = getPartialRelation(atom.getRelation()); | 657 | var target = getPartialRelation(atom.getRelation()); |
598 | var polarity = atom.isTransitiveClosure() ? CallPolarity.TRANSITIVE : CallPolarity.POSITIVE; | 658 | var polarity = atom.isTransitiveClosure() ? CallPolarity.TRANSITIVE : CallPolarity.POSITIVE; |
599 | var argumentList = toArgumentList(atom.getArguments(), localScope, literals); | 659 | var argumentList = toArgumentList(atom.getArguments(), localScope, literals); |
600 | literals.add(target.call(polarity, argumentList)); | 660 | literals.add(target.call(polarity, argumentList)); |
601 | } else if (expr instanceof NegationExpr negationExpr) { | 661 | } |
662 | case NegationExpr negationExpr -> { | ||
602 | var body = negationExpr.getBody(); | 663 | var body = negationExpr.getBody(); |
603 | if (!(body instanceof Atom atom)) { | 664 | if (!(body instanceof Atom atom)) { |
604 | throw new TracedException(body, "Cannot negate literal"); | 665 | throw new TracedException(body, "Cannot negate literal"); |
@@ -615,7 +676,8 @@ public class ModelInitializer { | |||
615 | var negatedScope = extendScope(localScope, negationExpr.getImplicitVariables()); | 676 | var negatedScope = extendScope(localScope, negationExpr.getImplicitVariables()); |
616 | var argumentList = toArgumentList(atom.getArguments(), negatedScope, literals); | 677 | var argumentList = toArgumentList(atom.getArguments(), negatedScope, literals); |
617 | literals.add(constraint.call(CallPolarity.NEGATIVE, argumentList)); | 678 | literals.add(constraint.call(CallPolarity.NEGATIVE, argumentList)); |
618 | } else if (expr instanceof ComparisonExpr comparisonExpr) { | 679 | } |
680 | case ComparisonExpr comparisonExpr -> { | ||
619 | var argumentList = toArgumentList(List.of(comparisonExpr.getLeft(), comparisonExpr.getRight()), | 681 | var argumentList = toArgumentList(List.of(comparisonExpr.getLeft(), comparisonExpr.getRight()), |
620 | localScope, literals); | 682 | localScope, literals); |
621 | boolean positive = switch (comparisonExpr.getOp()) { | 683 | boolean positive = switch (comparisonExpr.getOp()) { |
@@ -625,8 +687,8 @@ public class ModelInitializer { | |||
625 | comparisonExpr, "Unsupported operator"); | 687 | comparisonExpr, "Unsupported operator"); |
626 | }; | 688 | }; |
627 | literals.add(new EquivalenceLiteral(positive, argumentList.get(0), argumentList.get(1))); | 689 | literals.add(new EquivalenceLiteral(positive, argumentList.get(0), argumentList.get(1))); |
628 | } else { | 690 | } |
629 | throw new TracedException(expr, "Unsupported literal"); | 691 | default -> throw new TracedException(expr, "Unsupported literal"); |
630 | } | 692 | } |
631 | } | 693 | } |
632 | 694 | ||
@@ -641,7 +703,7 @@ public class ModelInitializer { | |||
641 | var variableOrNode = variableOrNodeExpr.getVariableOrNode(); | 703 | var variableOrNode = variableOrNodeExpr.getVariableOrNode(); |
642 | if (variableOrNode instanceof Node node) { | 704 | if (variableOrNode instanceof Node node) { |
643 | int nodeId = getNodeId(node); | 705 | int nodeId = getNodeId(node); |
644 | var tempVariable = Variable.of(semanticsUtils.getName(node).orElse("_" + nodeId)); | 706 | var tempVariable = Variable.of(semanticsUtils.getNameWithoutRootPrefix(node).orElse("_" + nodeId)); |
645 | literals.add(new ConstantLiteral(tempVariable, nodeId)); | 707 | literals.add(new ConstantLiteral(tempVariable, nodeId)); |
646 | argumentList.add(tempVariable); | 708 | argumentList.add(tempVariable); |
647 | } else if (variableOrNode instanceof tools.refinery.language.model.problem.Variable problemVariable) { | 709 | } else if (variableOrNode instanceof tools.refinery.language.model.problem.Variable problemVariable) { |
@@ -662,13 +724,15 @@ public class ModelInitializer { | |||
662 | } | 724 | } |
663 | 725 | ||
664 | private void collectScopes() { | 726 | private void collectScopes() { |
665 | for (var statement : problem.getStatements()) { | 727 | for (var importedProblem : importedProblems) { |
666 | if (statement instanceof ScopeDeclaration scopeDeclaration) { | 728 | for (var statement : importedProblem.getStatements()) { |
667 | for (var typeScope : scopeDeclaration.getTypeScopes()) { | 729 | if (statement instanceof ScopeDeclaration scopeDeclaration) { |
668 | if (typeScope.isIncrement()) { | 730 | for (var typeScope : scopeDeclaration.getTypeScopes()) { |
669 | collectTypeScopeIncrement(typeScope); | 731 | if (typeScope.isIncrement()) { |
670 | } else { | 732 | collectTypeScopeIncrement(typeScope); |
671 | collectTypeScope(typeScope); | 733 | } else { |
734 | collectTypeScope(typeScope); | ||
735 | } | ||
672 | } | 736 | } |
673 | } | 737 | } |
674 | } | 738 | } |