aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-reasoning-scope/src/main/java/tools
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-09-07 18:04:42 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-09-07 18:04:42 +0200
commita128e05f18a101983d331d0819008740b521d6df (patch)
treecc23c330eea900ab7b513a6c21a241ebf0795785 /subprojects/store-reasoning-scope/src/main/java/tools
parentfeat(dse): transformation rule builder (diff)
downloadrefinery-a128e05f18a101983d331d0819008740b521d6df.tar.gz
refinery-a128e05f18a101983d331d0819008740b521d6df.tar.zst
refinery-a128e05f18a101983d331d0819008740b521d6df.zip
feat: declarative DSE rules and model refinement
Diffstat (limited to 'subprojects/store-reasoning-scope/src/main/java/tools')
-rw-r--r--subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/LowerTypeScopePropagator.java40
-rw-r--r--subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/MultiView.java23
-rw-r--r--subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/ScopePropagatorAdapterImpl.java22
-rw-r--r--subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/ScopePropagatorBuilderImpl.java11
-rw-r--r--subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/TypeScopePropagator.java12
-rw-r--r--subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/UpperTypeScopePropagator.java9
6 files changed, 67 insertions, 50 deletions
diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/LowerTypeScopePropagator.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/LowerTypeScopePropagator.java
index b1c421b7..393c4b72 100644
--- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/LowerTypeScopePropagator.java
+++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/LowerTypeScopePropagator.java
@@ -5,43 +5,55 @@
5 */ 5 */
6package tools.refinery.store.reasoning.scope.internal; 6package tools.refinery.store.reasoning.scope.internal;
7 7
8import tools.refinery.store.dse.transition.DesignSpaceExplorationBuilder;
9import tools.refinery.store.dse.transition.objectives.Criteria;
10import tools.refinery.store.dse.transition.objectives.Objectives;
11import tools.refinery.store.model.ModelStoreBuilder;
8import tools.refinery.store.query.dnf.AnyQuery; 12import tools.refinery.store.query.dnf.AnyQuery;
9import tools.refinery.store.query.dnf.Query; 13import tools.refinery.store.query.dnf.Query;
10import tools.refinery.store.query.dnf.RelationalQuery; 14import tools.refinery.store.query.dnf.RelationalQuery;
15import tools.refinery.store.query.term.Variable;
16import tools.refinery.store.reasoning.ReasoningBuilder;
17import tools.refinery.store.reasoning.literal.CountCandidateLowerBoundLiteral;
11import tools.refinery.store.reasoning.representation.PartialRelation; 18import tools.refinery.store.reasoning.representation.PartialRelation;
12 19
13import java.util.Collection; 20import java.util.Collection;
14import java.util.List; 21import java.util.List;
15 22
23import static tools.refinery.store.query.literal.Literals.check;
24import static tools.refinery.store.query.term.int_.IntTerms.*;
16import static tools.refinery.store.reasoning.literal.PartialLiterals.may; 25import static tools.refinery.store.reasoning.literal.PartialLiterals.may;
26import static tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator.MULTI_VIEW;
17 27
18class LowerTypeScopePropagator extends TypeScopePropagator { 28class LowerTypeScopePropagator extends TypeScopePropagator {
19 private final int lowerBound; 29 private final int lowerBound;
20 30
21 private LowerTypeScopePropagator(ScopePropagatorAdapterImpl adapter, int lowerBound, RelationalQuery allQuery, 31 private LowerTypeScopePropagator(ScopePropagatorAdapterImpl adapter, int lowerBound, RelationalQuery allQuery,
22 RelationalQuery multiQuery) { 32 RelationalQuery multiQuery) {
23 super(adapter, allQuery, multiQuery); 33 super(adapter, allQuery, multiQuery);
24 this.lowerBound = lowerBound; 34 this.lowerBound = lowerBound;
25 } 35 }
26 36
27 @Override 37 @Override
28 public void updateBounds() { 38 public void updateBounds() {
29 constraint.setLb(lowerBound - getSingleCount()); 39 constraint.setLb((lowerBound - getSingleCount()));
30 } 40 }
31 41
32 public static class Factory implements TypeScopePropagator.Factory { 42 public static class Factory extends TypeScopePropagator.Factory {
43 private final PartialRelation type;
33 private final int lowerBound; 44 private final int lowerBound;
34 private final RelationalQuery allMay; 45 private final RelationalQuery allMay;
35 private final RelationalQuery multiMay; 46 private final RelationalQuery multiMay;
36 47
37 public Factory(RelationalQuery multi, PartialRelation type, int lowerBound) { 48 public Factory(PartialRelation type, int lowerBound) {
49 this.type = type;
38 this.lowerBound = lowerBound; 50 this.lowerBound = lowerBound;
39 allMay = Query.of(type.name() + "#may", (builder, instance) -> builder.clause( 51 allMay = Query.of(type.name() + "#may", (builder, instance) -> builder.clause(
40 may(type.call(instance)) 52 may(type.call(instance))
41 )); 53 ));
42 multiMay = Query.of(type.name() + "#multiMay", (builder, instance) -> builder.clause( 54 multiMay = Query.of(type.name() + "#multiMay", (builder, instance) -> builder.clause(
43 may(type.call(instance)), 55 may(type.call(instance)),
44 multi.call(instance) 56 MULTI_VIEW.call(instance)
45 )); 57 ));
46 } 58 }
47 59
@@ -51,8 +63,24 @@ class LowerTypeScopePropagator extends TypeScopePropagator {
51 } 63 }
52 64
53 @Override 65 @Override
54 public Collection<AnyQuery> getQueries() { 66 protected Collection<AnyQuery> getQueries() {
55 return List.of(allMay, multiMay); 67 return List.of(allMay, multiMay);
56 } 68 }
69
70 @Override
71 public void configure(ModelStoreBuilder storeBuilder) {
72 super.configure(storeBuilder);
73
74 var requiredObjects = Query.of(type.name() + "#required", Integer.class, (builder, output) -> builder
75 .clause(Integer.class, currentCount -> List.of(
76 new CountCandidateLowerBoundLiteral(currentCount, type, List.of(Variable.of())),
77 output.assign(sub(currentCount, constant(lowerBound))),
78 check(greater(currentCount, constant(0)))
79 )));
80
81 storeBuilder.getAdapter(ReasoningBuilder.class).objective(Objectives.value(requiredObjects));
82 storeBuilder.tryGetAdapter(DesignSpaceExplorationBuilder.class).ifPresent(dseBuilder ->
83 dseBuilder.accept(Criteria.whenNoMatch(requiredObjects)));
84 }
57 } 85 }
58} 86}
diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/MultiView.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/MultiView.java
deleted file mode 100644
index cea4e07d..00000000
--- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/MultiView.java
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.scope.internal;
7
8import tools.refinery.store.query.view.TuplePreservingView;
9import tools.refinery.store.representation.Symbol;
10import tools.refinery.store.representation.cardinality.CardinalityInterval;
11import tools.refinery.store.representation.cardinality.CardinalityIntervals;
12import tools.refinery.store.tuple.Tuple;
13
14class MultiView extends TuplePreservingView<CardinalityInterval> {
15 protected MultiView(Symbol<CardinalityInterval> symbol) {
16 super(symbol, "multi");
17 }
18
19 @Override
20 protected boolean doFilter(Tuple key, CardinalityInterval value) {
21 return !CardinalityIntervals.ONE.equals(value);
22 }
23}
diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/ScopePropagatorAdapterImpl.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/ScopePropagatorAdapterImpl.java
index c257df6b..99c501ce 100644
--- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/ScopePropagatorAdapterImpl.java
+++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/ScopePropagatorAdapterImpl.java
@@ -85,12 +85,7 @@ class ScopePropagatorAdapterImpl implements ScopePropagatorAdapter {
85 int nodeId = key.get(0); 85 int nodeId = key.get(0);
86 if ((toValue == null || toValue.equals(CardinalityIntervals.ONE))) { 86 if ((toValue == null || toValue.equals(CardinalityIntervals.ONE))) {
87 if (fromValue != null && !fromValue.equals(CardinalityIntervals.ONE)) { 87 if (fromValue != null && !fromValue.equals(CardinalityIntervals.ONE)) {
88 var variable = variables.get(nodeId); 88 removeActiveVariable(toValue, nodeId);
89 if (variable == null || !activeVariables.remove(nodeId)) {
90 throw new AssertionError("Variable not active: " + nodeId);
91 }
92 variable.setBounds(0, 0);
93 markAsChanged();
94 } 89 }
95 return; 90 return;
96 } 91 }
@@ -115,6 +110,21 @@ class ScopePropagatorAdapterImpl implements ScopePropagatorAdapter {
115 } 110 }
116 } 111 }
117 112
113 private void removeActiveVariable(CardinalityInterval toValue, int nodeId) {
114 var variable = variables.get(nodeId);
115 if (variable == null || !activeVariables.remove(nodeId)) {
116 throw new AssertionError("Variable not active: " + nodeId);
117 }
118 if (toValue == null) {
119 variable.setBounds(0, 0);
120 } else {
121 // Until queries are flushed and the constraints can be properly updated,
122 // the variable corresponding to the (previous) multi-object has to stand in for a single object.
123 variable.setBounds(1, 1);
124 }
125 markAsChanged();
126 }
127
118 MPConstraint makeConstraint() { 128 MPConstraint makeConstraint() {
119 return solver.makeConstraint(); 129 return solver.makeConstraint();
120 } 130 }
diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/ScopePropagatorBuilderImpl.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/ScopePropagatorBuilderImpl.java
index 11ca7381..531a7440 100644
--- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/ScopePropagatorBuilderImpl.java
+++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/ScopePropagatorBuilderImpl.java
@@ -9,8 +9,6 @@ import com.google.ortools.Loader;
9import tools.refinery.store.adapter.AbstractModelAdapterBuilder; 9import tools.refinery.store.adapter.AbstractModelAdapterBuilder;
10import tools.refinery.store.model.ModelStore; 10import tools.refinery.store.model.ModelStore;
11import tools.refinery.store.model.ModelStoreBuilder; 11import tools.refinery.store.model.ModelStoreBuilder;
12import tools.refinery.store.query.ModelQueryBuilder;
13import tools.refinery.store.query.dnf.Query;
14import tools.refinery.store.reasoning.representation.PartialRelation; 12import tools.refinery.store.reasoning.representation.PartialRelation;
15import tools.refinery.store.reasoning.scope.ScopePropagatorBuilder; 13import tools.refinery.store.reasoning.scope.ScopePropagatorBuilder;
16import tools.refinery.store.reasoning.scope.ScopePropagatorStoreAdapter; 14import tools.refinery.store.reasoning.scope.ScopePropagatorStoreAdapter;
@@ -60,25 +58,22 @@ public class ScopePropagatorBuilderImpl extends AbstractModelAdapterBuilder<Scop
60 58
61 @Override 59 @Override
62 protected void doConfigure(ModelStoreBuilder storeBuilder) { 60 protected void doConfigure(ModelStoreBuilder storeBuilder) {
63 var multiQuery = Query.of("MULTI", (builder, instance) -> builder.clause(
64 new MultiView(countSymbol).call(instance)));
65 typeScopePropagatorFactories = new ArrayList<>(scopes.size()); 61 typeScopePropagatorFactories = new ArrayList<>(scopes.size());
66 for (var entry : scopes.entrySet()) { 62 for (var entry : scopes.entrySet()) {
67 var type = entry.getKey(); 63 var type = entry.getKey();
68 var bounds = entry.getValue(); 64 var bounds = entry.getValue();
69 if (bounds.lowerBound() > 0) { 65 if (bounds.lowerBound() > 0) {
70 var lowerFactory = new LowerTypeScopePropagator.Factory(multiQuery, type, bounds.lowerBound()); 66 var lowerFactory = new LowerTypeScopePropagator.Factory(type, bounds.lowerBound());
71 typeScopePropagatorFactories.add(lowerFactory); 67 typeScopePropagatorFactories.add(lowerFactory);
72 } 68 }
73 if (bounds.upperBound() instanceof FiniteUpperCardinality finiteUpperCardinality) { 69 if (bounds.upperBound() instanceof FiniteUpperCardinality finiteUpperCardinality) {
74 var upperFactory = new UpperTypeScopePropagator.Factory(multiQuery, type, 70 var upperFactory = new UpperTypeScopePropagator.Factory(type,
75 finiteUpperCardinality.finiteUpperBound()); 71 finiteUpperCardinality.finiteUpperBound());
76 typeScopePropagatorFactories.add(upperFactory); 72 typeScopePropagatorFactories.add(upperFactory);
77 } 73 }
78 } 74 }
79 var queryBuilder = storeBuilder.getAdapter(ModelQueryBuilder.class);
80 for (var factory : typeScopePropagatorFactories) { 75 for (var factory : typeScopePropagatorFactories) {
81 queryBuilder.queries(factory.getQueries()); 76 factory.configure(storeBuilder);
82 } 77 }
83 } 78 }
84 79
diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/TypeScopePropagator.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/TypeScopePropagator.java
index 98f6ed8b..cfb95829 100644
--- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/TypeScopePropagator.java
+++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/TypeScopePropagator.java
@@ -6,7 +6,9 @@
6package tools.refinery.store.reasoning.scope.internal; 6package tools.refinery.store.reasoning.scope.internal;
7 7
8import com.google.ortools.linearsolver.MPConstraint; 8import com.google.ortools.linearsolver.MPConstraint;
9import tools.refinery.store.model.ModelStoreBuilder;
9import tools.refinery.store.query.ModelQueryAdapter; 10import tools.refinery.store.query.ModelQueryAdapter;
11import tools.refinery.store.query.ModelQueryBuilder;
10import tools.refinery.store.query.dnf.AnyQuery; 12import tools.refinery.store.query.dnf.AnyQuery;
11import tools.refinery.store.query.dnf.RelationalQuery; 13import tools.refinery.store.query.dnf.RelationalQuery;
12import tools.refinery.store.query.resultset.ResultSet; 14import tools.refinery.store.query.resultset.ResultSet;
@@ -53,9 +55,13 @@ abstract class TypeScopePropagator {
53 adapter.markAsChanged(); 55 adapter.markAsChanged();
54 } 56 }
55 57
56 interface Factory { 58 public abstract static class Factory {
57 TypeScopePropagator createPropagator(ScopePropagatorAdapterImpl adapter); 59 public abstract TypeScopePropagator createPropagator(ScopePropagatorAdapterImpl adapter);
58 60
59 Collection<AnyQuery> getQueries(); 61 protected abstract Collection<AnyQuery> getQueries();
62
63 public void configure(ModelStoreBuilder storeBuilder) {
64 storeBuilder.getAdapter(ModelQueryBuilder.class).queries(getQueries());
65 }
60 } 66 }
61} 67}
diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/UpperTypeScopePropagator.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/UpperTypeScopePropagator.java
index 9f09ed56..a0be0fb4 100644
--- a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/UpperTypeScopePropagator.java
+++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/internal/UpperTypeScopePropagator.java
@@ -14,6 +14,7 @@ import java.util.Collection;
14import java.util.List; 14import java.util.List;
15 15
16import static tools.refinery.store.reasoning.literal.PartialLiterals.must; 16import static tools.refinery.store.reasoning.literal.PartialLiterals.must;
17import static tools.refinery.store.reasoning.translator.multiobject.MultiObjectTranslator.MULTI_VIEW;
17 18
18class UpperTypeScopePropagator extends TypeScopePropagator { 19class UpperTypeScopePropagator extends TypeScopePropagator {
19 private final int upperBound; 20 private final int upperBound;
@@ -29,19 +30,19 @@ class UpperTypeScopePropagator extends TypeScopePropagator {
29 constraint.setUb(upperBound - getSingleCount()); 30 constraint.setUb(upperBound - getSingleCount());
30 } 31 }
31 32
32 public static class Factory implements TypeScopePropagator.Factory { 33 public static class Factory extends TypeScopePropagator.Factory {
33 private final int upperBound; 34 private final int upperBound;
34 private final RelationalQuery allMust; 35 private final RelationalQuery allMust;
35 private final RelationalQuery multiMust; 36 private final RelationalQuery multiMust;
36 37
37 public Factory(RelationalQuery multi, PartialRelation type, int upperBound) { 38 public Factory(PartialRelation type, int upperBound) {
38 this.upperBound = upperBound; 39 this.upperBound = upperBound;
39 allMust = Query.of(type.name() + "#must", (builder, instance) -> builder.clause( 40 allMust = Query.of(type.name() + "#must", (builder, instance) -> builder.clause(
40 must(type.call(instance)) 41 must(type.call(instance))
41 )); 42 ));
42 multiMust = Query.of(type.name() + "#multiMust", (builder, instance) -> builder.clause( 43 multiMust = Query.of(type.name() + "#multiMust", (builder, instance) -> builder.clause(
43 must(type.call(instance)), 44 must(type.call(instance)),
44 multi.call(instance) 45 MULTI_VIEW.call(instance)
45 )); 46 ));
46 } 47 }
47 48
@@ -51,7 +52,7 @@ class UpperTypeScopePropagator extends TypeScopePropagator {
51 } 52 }
52 53
53 @Override 54 @Override
54 public Collection<AnyQuery> getQueries() { 55 protected Collection<AnyQuery> getQueries() {
55 return List.of(allMust, multiMust); 56 return List.of(allMust, multiMust);
56 } 57 }
57 } 58 }