aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/language-semantics
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-09-03 17:57:38 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-09-03 17:57:38 +0200
commitcd96a9a4f54d45cda3ddf5df474946445d557090 (patch)
tree7a96a177236888ede9a51ffdd51940a672cfd070 /subprojects/language-semantics
parentbuild: runtimeOnly Eclipse Collections if posible (diff)
downloadrefinery-cd96a9a4f54d45cda3ddf5df474946445d557090.tar.gz
refinery-cd96a9a4f54d45cda3ddf5df474946445d557090.tar.zst
refinery-cd96a9a4f54d45cda3ddf5df474946445d557090.zip
feat: scope propagator in language
Diffstat (limited to 'subprojects/language-semantics')
-rw-r--r--subprojects/language-semantics/build.gradle.kts1
-rw-r--r--subprojects/language-semantics/src/main/java/tools/refinery/language/semantics/model/ModelInitializer.java69
2 files changed, 64 insertions, 6 deletions
diff --git a/subprojects/language-semantics/build.gradle.kts b/subprojects/language-semantics/build.gradle.kts
index b6f3f709..4374f78c 100644
--- a/subprojects/language-semantics/build.gradle.kts
+++ b/subprojects/language-semantics/build.gradle.kts
@@ -14,5 +14,6 @@ dependencies {
14 api(project(":refinery-store")) 14 api(project(":refinery-store"))
15 api(project(":refinery-store-query")) 15 api(project(":refinery-store-query"))
16 api(project(":refinery-store-reasoning")) 16 api(project(":refinery-store-reasoning"))
17 implementation(project(":refinery-store-reasoning-scope"))
17 runtimeOnly(libs.eclipseCollections) 18 runtimeOnly(libs.eclipseCollections)
18} 19}
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;
24import tools.refinery.store.reasoning.ReasoningAdapter; 24import tools.refinery.store.reasoning.ReasoningAdapter;
25import tools.refinery.store.reasoning.representation.AnyPartialSymbol; 25import tools.refinery.store.reasoning.representation.AnyPartialSymbol;
26import tools.refinery.store.reasoning.representation.PartialRelation; 26import tools.refinery.store.reasoning.representation.PartialRelation;
27import tools.refinery.store.reasoning.scope.ScopePropagatorBuilder;
27import tools.refinery.store.reasoning.seed.ModelSeed; 28import tools.refinery.store.reasoning.seed.ModelSeed;
28import tools.refinery.store.reasoning.seed.Seed; 29import tools.refinery.store.reasoning.seed.Seed;
29import tools.refinery.store.reasoning.translator.containment.ContainmentHierarchyTranslator; 30import 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) {