aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationInterpretationFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationInterpretationFactory.java')
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationInterpretationFactory.java180
1 files changed, 180 insertions, 0 deletions
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationInterpretationFactory.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationInterpretationFactory.java
new file mode 100644
index 00000000..2535714a
--- /dev/null
+++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/interpretation/QueryBasedRelationInterpretationFactory.java
@@ -0,0 +1,180 @@
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.interpretation;
7
8import tools.refinery.store.map.Cursor;
9import tools.refinery.store.query.ModelQueryAdapter;
10import tools.refinery.store.query.dnf.Query;
11import tools.refinery.store.query.resultset.ResultSet;
12import tools.refinery.store.reasoning.ReasoningAdapter;
13import tools.refinery.store.reasoning.literal.Concreteness;
14import tools.refinery.store.reasoning.representation.PartialSymbol;
15import tools.refinery.store.representation.TruthValue;
16import tools.refinery.store.tuple.Tuple;
17
18public class QueryBasedRelationInterpretationFactory implements PartialInterpretation.Factory<TruthValue, Boolean> {
19 private final Query<Boolean> may;
20 private final Query<Boolean> must;
21 private final Query<Boolean> candidateMay;
22 private final Query<Boolean> candidateMust;
23
24 public QueryBasedRelationInterpretationFactory(
25 Query<Boolean> may, Query<Boolean> must, Query<Boolean> candidateMay, Query<Boolean> candidateMust) {
26 this.may = may;
27 this.must = must;
28 this.candidateMay = candidateMay;
29 this.candidateMust = candidateMust;
30 }
31
32 @Override
33 public PartialInterpretation<TruthValue, Boolean> create(
34 ReasoningAdapter adapter, Concreteness concreteness, PartialSymbol<TruthValue, Boolean> partialSymbol) {
35 var queryEngine = adapter.getModel().getAdapter(ModelQueryAdapter.class);
36 ResultSet<Boolean> mayResultSet;
37 ResultSet<Boolean> mustResultSet;
38 switch (concreteness) {
39 case PARTIAL -> {
40 mayResultSet = queryEngine.getResultSet(may);
41 mustResultSet = queryEngine.getResultSet(must);
42 }
43 case CANDIDATE -> {
44 mayResultSet = queryEngine.getResultSet(candidateMay);
45 mustResultSet = queryEngine.getResultSet(candidateMust);
46 }
47 default -> throw new IllegalArgumentException("Unknown concreteness: " + concreteness);
48 }
49 if (mayResultSet.equals(mustResultSet)) {
50 return new TwoValuedInterpretation(adapter, concreteness, partialSymbol, mustResultSet);
51 } else {
52 return new FourValuedInterpretation(
53 adapter, concreteness, partialSymbol, mayResultSet, mustResultSet);
54 }
55 }
56
57 private static class TwoValuedInterpretation extends AbstractPartialInterpretation<TruthValue, Boolean> {
58 private final ResultSet<Boolean> resultSet;
59
60 protected TwoValuedInterpretation(
61 ReasoningAdapter adapter, Concreteness concreteness, PartialSymbol<TruthValue, Boolean> partialSymbol,
62 ResultSet<Boolean> resultSet) {
63 super(adapter, concreteness, partialSymbol);
64 this.resultSet = resultSet;
65 }
66
67 @Override
68 public TruthValue get(Tuple key) {
69 return TruthValue.toTruthValue(resultSet.get(key));
70 }
71
72 @Override
73 public Cursor<Tuple, TruthValue> getAll() {
74 return new TwoValuedCursor(resultSet.getAll());
75 }
76
77 private record TwoValuedCursor(Cursor<Tuple, Boolean> cursor) implements Cursor<Tuple, TruthValue> {
78 @Override
79 public Tuple getKey() {
80 return cursor.getKey();
81 }
82
83 @Override
84 public TruthValue getValue() {
85 return TruthValue.toTruthValue(cursor.getValue());
86 }
87
88 @Override
89 public boolean isTerminated() {
90 return cursor.isTerminated();
91 }
92
93 @Override
94 public boolean move() {
95 return cursor.move();
96 }
97 }
98 }
99
100 private static class FourValuedInterpretation extends AbstractPartialInterpretation<TruthValue, Boolean> {
101 private final ResultSet<Boolean> mayResultSet;
102 private final ResultSet<Boolean> mustResultSet;
103
104 public FourValuedInterpretation(
105 ReasoningAdapter adapter, Concreteness concreteness, PartialSymbol<TruthValue, Boolean> partialSymbol,
106 ResultSet<Boolean> mayResultSet, ResultSet<Boolean> mustResultSet) {
107 super(adapter, concreteness, partialSymbol);
108 this.mayResultSet = mayResultSet;
109 this.mustResultSet = mustResultSet;
110 }
111
112 @Override
113 public TruthValue get(Tuple key) {
114 boolean isMay = mayResultSet.get(key);
115 boolean isMust = mustResultSet.get(key);
116 if (isMust) {
117 return isMay ? TruthValue.TRUE : TruthValue.ERROR;
118 } else {
119 return isMay ? TruthValue.UNKNOWN : TruthValue.FALSE;
120 }
121 }
122
123 @Override
124 public Cursor<Tuple, TruthValue> getAll() {
125 return new FourValuedCursor();
126 }
127
128 private final class FourValuedCursor implements Cursor<Tuple, TruthValue> {
129 private final Cursor<Tuple, Boolean> mayCursor;
130 private Cursor<Tuple, Boolean> mustCursor;
131
132 private FourValuedCursor() {
133 this.mayCursor = mayResultSet.getAll();
134 }
135
136 @Override
137 public Tuple getKey() {
138 return mustCursor == null ? mayCursor.getKey() : mustCursor.getKey();
139 }
140
141 @Override
142 public TruthValue getValue() {
143 if (mustCursor != null) {
144 return TruthValue.ERROR;
145 }
146 if (Boolean.TRUE.equals(mustResultSet.get(mayCursor.getKey()))) {
147 return TruthValue.TRUE;
148 }
149 return TruthValue.UNKNOWN;
150 }
151
152 @Override
153 public boolean isTerminated() {
154 return mustCursor != null && mustCursor.isTerminated();
155 }
156
157 @Override
158 public boolean move() {
159 if (mayCursor.isTerminated()) {
160 return moveMust();
161 }
162 if (mayCursor.move()) {
163 return true;
164 }
165 mustCursor = mustResultSet.getAll();
166 return moveMust();
167 }
168
169 private boolean moveMust() {
170 while (mustCursor.move()) {
171 // We already iterated over {@code TRUE} truth values with {@code mayCursor}.
172 if (!Boolean.TRUE.equals(mayResultSet.get(mustCursor.getKey()))) {
173 return true;
174 }
175 }
176 return false;
177 }
178 }
179 }
180}