diff options
Diffstat (limited to 'subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/TypeScopePropagator.java')
-rw-r--r-- | subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/TypeScopePropagator.java | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/TypeScopePropagator.java b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/TypeScopePropagator.java new file mode 100644 index 00000000..bb50656b --- /dev/null +++ b/subprojects/store-reasoning-scope/src/main/java/tools/refinery/store/reasoning/scope/TypeScopePropagator.java | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.reasoning.scope; | ||
7 | |||
8 | import com.google.ortools.linearsolver.MPConstraint; | ||
9 | import tools.refinery.store.model.ModelStoreBuilder; | ||
10 | import tools.refinery.store.query.ModelQueryBuilder; | ||
11 | import tools.refinery.store.query.dnf.AnyQuery; | ||
12 | import tools.refinery.store.query.dnf.RelationalQuery; | ||
13 | import tools.refinery.store.query.resultset.ResultSet; | ||
14 | import tools.refinery.store.tuple.Tuple; | ||
15 | |||
16 | import java.util.Collection; | ||
17 | |||
18 | abstract class TypeScopePropagator { | ||
19 | private final BoundScopePropagator adapter; | ||
20 | private final ResultSet<Boolean> allNodes; | ||
21 | private final ResultSet<Boolean> multiNodes; | ||
22 | protected final MPConstraint constraint; | ||
23 | |||
24 | protected TypeScopePropagator(BoundScopePropagator adapter, RelationalQuery allQuery, | ||
25 | RelationalQuery multiQuery) { | ||
26 | this.adapter = adapter; | ||
27 | var queryEngine = adapter.getQueryEngine(); | ||
28 | allNodes = queryEngine.getResultSet(allQuery); | ||
29 | multiNodes = queryEngine.getResultSet(multiQuery); | ||
30 | constraint = adapter.makeConstraint(); | ||
31 | constraint.setBounds(0, Double.POSITIVE_INFINITY); | ||
32 | var cursor = multiNodes.getAll(); | ||
33 | while (cursor.move()) { | ||
34 | var variable = adapter.getVariable(cursor.getKey().get(0)); | ||
35 | constraint.setCoefficient(variable, 1); | ||
36 | } | ||
37 | allNodes.addListener(this::allChanged); | ||
38 | multiNodes.addListener(this::multiChanged); | ||
39 | } | ||
40 | |||
41 | protected abstract void doUpdateBounds(); | ||
42 | |||
43 | public boolean updateBounds() { | ||
44 | doUpdateBounds(); | ||
45 | return constraint.lb() <= constraint.ub(); | ||
46 | } | ||
47 | |||
48 | protected int getSingleCount() { | ||
49 | return allNodes.size() - multiNodes.size(); | ||
50 | } | ||
51 | |||
52 | private void allChanged(Tuple ignoredKey, Boolean ignoredOldValue, Boolean ignoredNewValue) { | ||
53 | adapter.markAsChanged(); | ||
54 | } | ||
55 | |||
56 | private void multiChanged(Tuple key, Boolean ignoredOldValue, Boolean newValue) { | ||
57 | var variable = adapter.getVariable(key.get(0)); | ||
58 | constraint.setCoefficient(variable, Boolean.TRUE.equals(newValue) ? 1 : 0); | ||
59 | adapter.markAsChanged(); | ||
60 | } | ||
61 | |||
62 | public abstract static class Factory { | ||
63 | public abstract TypeScopePropagator createPropagator(BoundScopePropagator adapter); | ||
64 | |||
65 | protected abstract Collection<AnyQuery> getQueries(); | ||
66 | |||
67 | public void configure(ModelStoreBuilder storeBuilder) { | ||
68 | storeBuilder.getAdapter(ModelQueryBuilder.class).queries(getQueries()); | ||
69 | } | ||
70 | } | ||
71 | } | ||