diff options
author | Kristóf Marussy <kristof@marussy.com> | 2023-09-03 17:57:38 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2023-09-03 17:57:38 +0200 |
commit | cd96a9a4f54d45cda3ddf5df474946445d557090 (patch) | |
tree | 7a96a177236888ede9a51ffdd51940a672cfd070 /subprojects/language-semantics/src | |
parent | build: runtimeOnly Eclipse Collections if posible (diff) | |
download | refinery-cd96a9a4f54d45cda3ddf5df474946445d557090.tar.gz refinery-cd96a9a4f54d45cda3ddf5df474946445d557090.tar.zst refinery-cd96a9a4f54d45cda3ddf5df474946445d557090.zip |
feat: scope propagator in language
Diffstat (limited to 'subprojects/language-semantics/src')
-rw-r--r-- | subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/ModelInitializer.java | 69 |
1 files changed, 63 insertions, 6 deletions
diff --git a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/ModelInitializer.java b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/ModelInitializer.java index 13e25d0a..89c41a8e 100644 --- a/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/ModelInitializer.java +++ b/subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/ModelInitializer.java | |||
@@ -24,6 +24,7 @@ import tools.refinery.store.query.term.Variable; | |||
24 | import tools.refinery.store.reasoning.ReasoningAdapter; | 24 | import tools.refinery.store.reasoning.ReasoningAdapter; |
25 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; | 25 | import tools.refinery.store.reasoning.representation.AnyPartialSymbol; |
26 | import tools.refinery.store.reasoning.representation.PartialRelation; | 26 | import tools.refinery.store.reasoning.representation.PartialRelation; |
27 | import tools.refinery.store.reasoning.scope.ScopePropagatorBuilder; | ||
27 | import tools.refinery.store.reasoning.seed.ModelSeed; | 28 | import tools.refinery.store.reasoning.seed.ModelSeed; |
28 | import tools.refinery.store.reasoning.seed.Seed; | 29 | import tools.refinery.store.reasoning.seed.Seed; |
29 | import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; | 30 | import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; |
@@ -72,6 +73,8 @@ public class ModelInitializer { | |||
72 | 73 | ||
73 | private Metamodel metamodel; | 74 | private Metamodel metamodel; |
74 | 75 | ||
76 | private Map<Tuple, CardinalityInterval> countSeed = new LinkedHashMap<>(); | ||
77 | |||
75 | private ModelSeed modelSeed; | 78 | private ModelSeed modelSeed; |
76 | 79 | ||
77 | public Problem getProblem() { | 80 | public Problem getProblem() { |
@@ -135,6 +138,10 @@ public class ModelInitializer { | |||
135 | relationTrace.put(relation, partialRelation); | 138 | relationTrace.put(relation, partialRelation); |
136 | modelSeedBuilder.seed(partialRelation, info.toSeed(nodeCount)); | 139 | modelSeedBuilder.seed(partialRelation, info.toSeed(nodeCount)); |
137 | } | 140 | } |
141 | collectScopes(); | ||
142 | modelSeedBuilder.seed(MultiObjectTranslator.COUNT_SYMBOL, builder -> builder | ||
143 | .reducedValue(CardinalityIntervals.SET) | ||
144 | .putAll(countSeed)); | ||
138 | modelSeed = modelSeedBuilder.build(); | 145 | modelSeed = modelSeedBuilder.build(); |
139 | collectPredicates(); | 146 | collectPredicates(); |
140 | return modelSeed; | 147 | return modelSeed; |
@@ -288,20 +295,26 @@ public class ModelInitializer { | |||
288 | CardinalityInterval interval; | 295 | CardinalityInterval interval; |
289 | if (problemMultiplicity == null) { | 296 | if (problemMultiplicity == null) { |
290 | interval = CardinalityIntervals.LONE; | 297 | interval = CardinalityIntervals.LONE; |
291 | } else if (problemMultiplicity instanceof ExactMultiplicity exactMultiplicity) { | 298 | } else { |
292 | interval = CardinalityIntervals.exactly(exactMultiplicity.getExactValue()); | 299 | interval = getCardinalityInterval(problemMultiplicity); |
300 | } | ||
301 | var constraint = getRelationInfo(referenceDeclaration.getInvalidMultiplicity()).partialRelation(); | ||
302 | return ConstrainedMultiplicity.of(interval, constraint); | ||
303 | } | ||
304 | |||
305 | private static CardinalityInterval getCardinalityInterval( | ||
306 | tools.refinery.language.model.problem.Multiplicity problemMultiplicity) { | ||
307 | if (problemMultiplicity instanceof ExactMultiplicity exactMultiplicity) { | ||
308 | return CardinalityIntervals.exactly(exactMultiplicity.getExactValue()); | ||
293 | } else if (problemMultiplicity instanceof RangeMultiplicity rangeMultiplicity) { | 309 | } else if (problemMultiplicity instanceof RangeMultiplicity rangeMultiplicity) { |
294 | var upperBound = rangeMultiplicity.getUpperBound(); | 310 | var upperBound = rangeMultiplicity.getUpperBound(); |
295 | interval = CardinalityIntervals.between(rangeMultiplicity.getLowerBound(), | 311 | return CardinalityIntervals.between(rangeMultiplicity.getLowerBound(), |
296 | upperBound < 0 ? UpperCardinalities.UNBOUNDED : UpperCardinalities.atMost(upperBound)); | 312 | upperBound < 0 ? UpperCardinalities.UNBOUNDED : UpperCardinalities.atMost(upperBound)); |
297 | } else { | 313 | } else { |
298 | throw new TracedException(problemMultiplicity, "Unknown multiplicity"); | 314 | throw new TracedException(problemMultiplicity, "Unknown multiplicity"); |
299 | } | 315 | } |
300 | var constraint = getRelationInfo(referenceDeclaration.getInvalidMultiplicity()).partialRelation(); | ||
301 | return ConstrainedMultiplicity.of(interval, constraint); | ||
302 | } | 316 | } |
303 | 317 | ||
304 | |||
305 | private void collectAssertions() { | 318 | private void collectAssertions() { |
306 | for (var statement : problem.getStatements()) { | 319 | for (var statement : problem.getStatements()) { |
307 | if (statement instanceof ClassDeclaration classDeclaration) { | 320 | if (statement instanceof ClassDeclaration classDeclaration) { |
@@ -598,6 +611,50 @@ public class ModelInitializer { | |||
598 | return argumentList; | 611 | return argumentList; |
599 | } | 612 | } |
600 | 613 | ||
614 | private void collectScopes() { | ||
615 | for (var statement : problem.getStatements()) { | ||
616 | if (statement instanceof ScopeDeclaration scopeDeclaration) { | ||
617 | for (var typeScope : scopeDeclaration.getTypeScopes()) { | ||
618 | if (typeScope.isIncrement()) { | ||
619 | collectTypeScopeIncrement(typeScope); | ||
620 | } else { | ||
621 | collectTypeScope(typeScope); | ||
622 | } | ||
623 | } | ||
624 | } | ||
625 | } | ||
626 | } | ||
627 | |||
628 | private void collectTypeScopeIncrement(TypeScope typeScope) { | ||
629 | if (!(typeScope.getTargetType() instanceof ClassDeclaration classDeclaration)) { | ||
630 | throw new TracedException(typeScope, "Target of incremental type scope must be a class declaration"); | ||
631 | } | ||
632 | var newNode = classDeclaration.getNewNode(); | ||
633 | if (newNode == null) { | ||
634 | throw new TracedException(typeScope, "Target of incremental type scope must be concrete class"); | ||
635 | } | ||
636 | int newNodeId = nodeTrace.get(newNode); | ||
637 | var type = relationTrace.get(classDeclaration); | ||
638 | var typeInfo = metamodel.typeHierarchy().getAnalysisResult(type); | ||
639 | if (!typeInfo.getDirectSubtypes().isEmpty()) { | ||
640 | throw new TracedException(typeScope, "Target of incremental type scope cannot have any subclasses"); | ||
641 | } | ||
642 | var interval = getCardinalityInterval(typeScope.getMultiplicity()); | ||
643 | countSeed.compute(Tuple.of(newNodeId), (key, oldValue) -> | ||
644 | oldValue == null ? interval : oldValue.meet(interval)); | ||
645 | } | ||
646 | |||
647 | private void collectTypeScope(TypeScope typeScope) { | ||
648 | var scopePropagatorBuilder = storeBuilder.tryGetAdapter(ScopePropagatorBuilder.class).orElseThrow( | ||
649 | () -> new TracedException(typeScope, "Type scopes require a ScopePropagatorBuilder")); | ||
650 | var type = relationTrace.get(typeScope.getTargetType()); | ||
651 | if (type == null) { | ||
652 | throw new TracedException(typeScope, "Unknown target type"); | ||
653 | } | ||
654 | var interval = getCardinalityInterval(typeScope.getMultiplicity()); | ||
655 | scopePropagatorBuilder.scope(type, interval); | ||
656 | } | ||
657 | |||
601 | private record RelationInfo(PartialRelation partialRelation, MutableSeed<TruthValue> assertions, | 658 | private record RelationInfo(PartialRelation partialRelation, MutableSeed<TruthValue> assertions, |
602 | MutableSeed<TruthValue> defaultAssertions) { | 659 | MutableSeed<TruthValue> defaultAssertions) { |
603 | public RelationInfo(String name, int arity, TruthValue value, TruthValue defaultValue) { | 660 | public RelationInfo(String name, int arity, TruthValue value, TruthValue defaultValue) { |