aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator')
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/Advice.java159
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/AdviceSlot.java30
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/AnyPartialSymbolTranslator.java16
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialRelationTranslator.java263
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java156
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/RoundingMode.java12
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/TranslatedRelation.java27
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/TranslationUnit.java32
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/BaseDecisionInterpretation.java93
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/BaseDecisionTranslationUnit.java49
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/TranslatedBaseDecision.java54
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMayTypeView.java40
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMustTypeView.java40
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslationUnit.java37
14 files changed, 447 insertions, 561 deletions
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/Advice.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/Advice.java
deleted file mode 100644
index d6a9e02c..00000000
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/Advice.java
+++ /dev/null
@@ -1,159 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator;
7
8import tools.refinery.store.query.substitution.Substitution;
9import tools.refinery.store.reasoning.representation.AnyPartialSymbol;
10import tools.refinery.store.reasoning.representation.PartialRelation;
11import tools.refinery.store.query.term.Variable;
12import tools.refinery.store.query.literal.Literal;
13
14import java.util.*;
15
16public final class Advice {
17 private final AnyPartialSymbol source;
18 private final PartialRelation target;
19 private final AdviceSlot slot;
20 private final boolean mandatory;
21 private final List<Variable> parameters;
22 private final List<Literal> literals;
23 private boolean processed;
24
25 public Advice(AnyPartialSymbol source, PartialRelation target, AdviceSlot slot, boolean mandatory, List<Variable> parameters, List<Literal> literals) {
26 if (mandatory && !slot.isMonotonic()) {
27 throw new IllegalArgumentException("Only monotonic advice can be mandatory");
28 }
29 this.source = source;
30 this.target = target;
31 this.slot = slot;
32 this.mandatory = mandatory;
33 checkArity(parameters);
34 this.parameters = parameters;
35 this.literals = literals;
36 }
37
38 public AnyPartialSymbol source() {
39 return source;
40 }
41
42 public PartialRelation target() {
43 return target;
44 }
45
46 public AdviceSlot slot() {
47 return slot;
48 }
49
50 public boolean mandatory() {
51 return mandatory;
52 }
53
54 public List<Variable> parameters() {
55 return parameters;
56 }
57
58 public List<Literal> literals() {
59 return literals;
60 }
61
62 public boolean processed() {
63 return processed;
64 }
65
66 public List<Literal> substitute(List<Variable> substituteParameters) {
67 checkArity(substituteParameters);
68 markProcessed();
69 // Use a renewing substitution to remove any non-parameter variables and avoid clashed between variables
70 // coming from different advice in the same clause.
71 var substitution = Substitution.builder().putManyChecked(parameters, substituteParameters).renewing().build();
72 return literals.stream().map(literal -> literal.substitute(substitution)).toList();
73 }
74
75 private void markProcessed() {
76 processed = true;
77 }
78
79 public void checkProcessed() {
80 if (mandatory && !processed) {
81 throw new IllegalStateException("Mandatory advice %s was not processed".formatted(this));
82 }
83 }
84
85 private void checkArity(List<Variable> toCheck) {
86 if (toCheck.size() != target.arity()) {
87 throw new IllegalArgumentException("%s needs %d parameters, but got %s".formatted(target.name(),
88 target.arity(), parameters.size()));
89 }
90 }
91
92 public static Builder builderFor(AnyPartialSymbol source, PartialRelation target, AdviceSlot slot) {
93 return new Builder(source, target, slot);
94 }
95
96
97 @Override
98 public String toString() {
99 return "Advice[source=%s, target=%s, slot=%s, mandatory=%s, parameters=%s, literals=%s]".formatted(source,
100 target, slot, mandatory, parameters, literals);
101 }
102
103 public static class Builder {
104 private final AnyPartialSymbol source;
105 private final PartialRelation target;
106 private final AdviceSlot slot;
107 private boolean mandatory;
108 private final List<Variable> parameters = new ArrayList<>();
109 private final List<Literal> literals = new ArrayList<>();
110
111 private Builder(AnyPartialSymbol source, PartialRelation target, AdviceSlot slot) {
112 this.source = source;
113 this.target = target;
114 this.slot = slot;
115 }
116
117 public Builder mandatory(boolean mandatory) {
118 this.mandatory = mandatory;
119 return this;
120 }
121
122 public Builder mandatory() {
123 return mandatory(false);
124 }
125
126 public Builder parameters(List<Variable> variables) {
127 parameters.addAll(variables);
128 return this;
129 }
130
131 public Builder parameters(Variable... variables) {
132 return parameters(List.of(variables));
133 }
134
135 public Builder parameter(Variable variable) {
136 parameters.add(variable);
137 return this;
138 }
139
140 public Builder literals(Collection<Literal> literals) {
141 this.literals.addAll(literals);
142 return this;
143 }
144
145 public Builder literals(Literal... literals) {
146 return literals(List.of(literals));
147 }
148
149 public Builder literal(Literal literal) {
150 literals.add(literal);
151 return this;
152 }
153
154 public Advice build() {
155 return new Advice(source, target, slot, mandatory, Collections.unmodifiableList(parameters),
156 Collections.unmodifiableList(literals));
157 }
158 }
159}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/AdviceSlot.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/AdviceSlot.java
deleted file mode 100644
index bab20340..00000000
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/AdviceSlot.java
+++ /dev/null
@@ -1,30 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator;
7
8import tools.refinery.store.representation.TruthValue;
9
10public enum AdviceSlot {
11 EXTEND_MUST(true),
12
13 RESTRICT_MAY(true),
14
15 /**
16 * Same as {@link #RESTRICT_MAY}, but only active if the value of the relation is not {@link TruthValue#TRUE} or
17 * {@link TruthValue#ERROR}.
18 */
19 RESTRICT_NEW(false);
20
21 private final boolean monotonic;
22
23 AdviceSlot(boolean monotonic) {
24 this.monotonic = monotonic;
25 }
26
27 public boolean isMonotonic() {
28 return monotonic;
29 }
30}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/AnyPartialSymbolTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/AnyPartialSymbolTranslator.java
new file mode 100644
index 00000000..48c84348
--- /dev/null
+++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/AnyPartialSymbolTranslator.java
@@ -0,0 +1,16 @@
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.translator;
7
8import tools.refinery.store.model.ModelStoreBuilder;
9import tools.refinery.store.model.ModelStoreConfiguration;
10import tools.refinery.store.reasoning.representation.AnyPartialSymbol;
11
12public sealed interface AnyPartialSymbolTranslator extends ModelStoreConfiguration permits PartialSymbolTranslator {
13 AnyPartialSymbol getPartialSymbol();
14
15 void configure(ModelStoreBuilder storeBuilder);
16}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialRelationTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialRelationTranslator.java
new file mode 100644
index 00000000..fe8e8d6c
--- /dev/null
+++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialRelationTranslator.java
@@ -0,0 +1,263 @@
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.translator;
7
8import tools.refinery.store.model.ModelStoreBuilder;
9import tools.refinery.store.query.Constraint;
10import tools.refinery.store.query.ModelQueryBuilder;
11import tools.refinery.store.query.dnf.Query;
12import tools.refinery.store.query.dnf.RelationalQuery;
13import tools.refinery.store.query.term.Variable;
14import tools.refinery.store.query.view.MayView;
15import tools.refinery.store.query.view.MustView;
16import tools.refinery.store.reasoning.ReasoningBuilder;
17import tools.refinery.store.reasoning.interpretation.PartialInterpretation;
18import tools.refinery.store.reasoning.interpretation.PartialRelationRewriter;
19import tools.refinery.store.reasoning.interpretation.QueryBasedRelationInterpretationFactory;
20import tools.refinery.store.reasoning.interpretation.QueryBasedRelationRewriter;
21import tools.refinery.store.reasoning.literal.Concreteness;
22import tools.refinery.store.reasoning.literal.Modality;
23import tools.refinery.store.reasoning.refinement.ConcreteSymbolRefiner;
24import tools.refinery.store.reasoning.refinement.PartialInterpretationRefiner;
25import tools.refinery.store.reasoning.refinement.StorageRefiner;
26import tools.refinery.store.reasoning.representation.PartialRelation;
27import tools.refinery.store.representation.AnySymbol;
28import tools.refinery.store.representation.Symbol;
29import tools.refinery.store.representation.TruthValue;
30
31@SuppressWarnings("UnusedReturnValue")
32public final class PartialRelationTranslator extends PartialSymbolTranslator<TruthValue, Boolean> {
33 private final PartialRelation partialRelation;
34 private PartialRelationRewriter rewriter;
35 private Query<Boolean> query;
36 private Query<Boolean> may;
37 private Query<Boolean> must;
38 private Query<Boolean> candidateMay;
39 private Query<Boolean> candidateMust;
40 private RoundingMode roundingMode;
41
42 private PartialRelationTranslator(PartialRelation partialRelation) {
43 super(partialRelation);
44 this.partialRelation = partialRelation;
45 }
46
47 public PartialRelation getPartialRelation() {
48 return partialRelation;
49 }
50
51 @Override
52 public PartialRelationTranslator symbol(AnySymbol storageSymbol) {
53 super.symbol(storageSymbol);
54 return this;
55 }
56
57 @Override
58 public <T> PartialRelationTranslator symbol(Symbol<T> storageSymbol,
59 StorageRefiner.Factory<T> storageRefiner) {
60 super.symbol(storageSymbol, storageRefiner);
61 return this;
62 }
63
64 @Override
65 public PartialRelationTranslator interpretation(
66 PartialInterpretation.Factory<TruthValue, Boolean> interpretationFactory) {
67 super.interpretation(interpretationFactory);
68 return this;
69 }
70
71 @Override
72 public PartialRelationTranslator refiner(
73 PartialInterpretationRefiner.Factory<TruthValue, Boolean> interpretationRefiner) {
74 super.refiner(interpretationRefiner);
75 return this;
76 }
77
78 public PartialRelationTranslator rewriter(PartialRelationRewriter rewriter) {
79 checkNotConfigured();
80 if (this.rewriter != null) {
81 throw new IllegalArgumentException("Rewriter was already set");
82 }
83 this.rewriter = rewriter;
84 return this;
85 }
86
87 public PartialRelationTranslator query(RelationalQuery query) {
88 checkNotConfigured();
89 if (this.query != null) {
90 throw new IllegalArgumentException("Query was already set");
91 }
92 this.query = query;
93 return this;
94 }
95
96 public PartialRelationTranslator may(RelationalQuery may) {
97 checkNotConfigured();
98 if (this.may != null) {
99 throw new IllegalArgumentException("May query was already set");
100 }
101 this.may = may;
102 return this;
103 }
104
105 public PartialRelationTranslator must(RelationalQuery must) {
106 checkNotConfigured();
107 if (this.must != null) {
108 throw new IllegalArgumentException("Must query was already set");
109 }
110 this.must = must;
111 return this;
112 }
113
114 public PartialRelationTranslator candidate(RelationalQuery candidate) {
115 candidateMay(candidate);
116 candidateMust(candidate);
117 return this;
118 }
119
120 public PartialRelationTranslator candidateMay(RelationalQuery candidateMay) {
121 checkNotConfigured();
122 if (this.candidateMay != null) {
123 throw new IllegalArgumentException("Candidate may query was already set");
124 }
125 this.candidateMay = candidateMay;
126 return this;
127 }
128
129 public PartialRelationTranslator candidateMust(RelationalQuery candidateMust) {
130 checkNotConfigured();
131 if (this.candidateMust != null) {
132 throw new IllegalArgumentException("Candidate must query was already set");
133 }
134 this.candidateMust = candidateMust;
135 return this;
136 }
137
138 public PartialRelationTranslator roundingMode(RoundingMode roundingMode) {
139 checkNotConfigured();
140 if (this.roundingMode != null) {
141 throw new IllegalArgumentException("Rounding mode was already set");
142 }
143 this.roundingMode = roundingMode;
144 return this;
145 }
146
147 @Override
148 protected void doConfigure(ModelStoreBuilder storeBuilder) {
149 setFallbackRoundingMode();
150 createFallbackQueryFromRewriter();
151 liftQueries(storeBuilder);
152 createFallbackQueriesFromSymbol();
153 setFallbackCandidateQueries();
154 createFallbackRewriter();
155 createFallbackInterpretation(storeBuilder);
156 createFallbackRefiner();
157 super.doConfigure(storeBuilder);
158 }
159
160 private void setFallbackRoundingMode() {
161 if (roundingMode == null) {
162 roundingMode = query == null && storageSymbol != null ? RoundingMode.PREFER_FALSE : RoundingMode.NONE;
163 }
164 }
165
166 private RelationalQuery createQuery(Constraint constraint) {
167 int arity = partialRelation.arity();
168 var queryBuilder = Query.builder(partialRelation.name());
169 var parameters = new Variable[arity];
170 for (int i = 0; i < arity; i++) {
171 parameters[i] = queryBuilder.parameter("p" + 1);
172 }
173 queryBuilder.clause(constraint.call(parameters));
174 return queryBuilder.build();
175 }
176
177 private void createFallbackQueryFromRewriter() {
178 if (rewriter != null && query == null) {
179 query = createQuery(partialRelation);
180 }
181 }
182
183 private void createFallbackQueriesFromSymbol() {
184 if (storageSymbol == null || storageSymbol.valueType() != TruthValue.class) {
185 return;
186 }
187 // We checked in the guard clause that this is safe.
188 @SuppressWarnings("unchecked")
189 var typedStorageSymbol = (Symbol<TruthValue>) storageSymbol;
190 var defaultValue = typedStorageSymbol.defaultValue();
191 if (may == null && !defaultValue.may()) {
192 may = createQuery(new MayView(typedStorageSymbol));
193 }
194 if (must == null && !defaultValue.must()) {
195 must = createQuery(new MustView(typedStorageSymbol));
196 }
197 }
198
199 private void liftQueries(ModelStoreBuilder storeBuilder) {
200 if (query != null) {
201 var reasoningBuilder = storeBuilder.getAdapter(ReasoningBuilder.class);
202 if (may == null) {
203 may = reasoningBuilder.lift(Modality.MAY, Concreteness.PARTIAL, query);
204 }
205 if (must == null) {
206 must = reasoningBuilder.lift(Modality.MUST, Concreteness.PARTIAL, query);
207 }
208 if (candidateMay == null) {
209 candidateMay = reasoningBuilder.lift(Modality.MAY, Concreteness.CANDIDATE, query);
210 }
211 if (candidateMust == null) {
212 candidateMust = reasoningBuilder.lift(Modality.MAY, Concreteness.CANDIDATE, query);
213 }
214 }
215 }
216
217 private void setFallbackCandidateQueries() {
218 if (candidateMay == null) {
219 candidateMay = switch (roundingMode) {
220 case NONE, PREFER_TRUE -> may;
221 case PREFER_FALSE -> must;
222 };
223 }
224 if (candidateMust == null) {
225 candidateMust = switch (roundingMode) {
226 case NONE, PREFER_FALSE -> must;
227 case PREFER_TRUE -> may;
228 };
229 }
230 }
231
232 private void createFallbackRewriter() {
233 if (rewriter == null) {
234 rewriter = new QueryBasedRelationRewriter(may, must, candidateMay, candidateMust);
235 }
236 }
237
238 private void createFallbackInterpretation(ModelStoreBuilder storeBuilder) {
239 if (interpretationFactory == null) {
240 var queryBuilder = storeBuilder.getAdapter(ModelQueryBuilder.class);
241 interpretationFactory = new QueryBasedRelationInterpretationFactory(may, must, candidateMay, candidateMust);
242 queryBuilder.queries(may, must, candidateMay, candidateMust);
243 }
244 }
245
246 private void createFallbackRefiner() {
247 if (interpretationRefiner == null && storageSymbol != null && storageSymbol.valueType() == TruthValue.class) {
248 // We checked in the condition that this is safe.
249 @SuppressWarnings("unchecked")
250 var typedStorageSymbol = (Symbol<TruthValue>) storageSymbol;
251 interpretationRefiner = ConcreteSymbolRefiner.of(typedStorageSymbol);
252 }
253 }
254
255 public PartialRelationRewriter getRewriter() {
256 checkConfigured();
257 return rewriter;
258 }
259
260 public static PartialRelationTranslator of(PartialRelation relation) {
261 return new PartialRelationTranslator(relation);
262 }
263}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java
new file mode 100644
index 00000000..07d1d19b
--- /dev/null
+++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/PartialSymbolTranslator.java
@@ -0,0 +1,156 @@
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.translator;
7
8import tools.refinery.store.model.ModelStoreBuilder;
9import tools.refinery.store.reasoning.ReasoningBuilder;
10import tools.refinery.store.reasoning.interpretation.PartialInterpretation;
11import tools.refinery.store.reasoning.refinement.PartialInterpretationRefiner;
12import tools.refinery.store.reasoning.refinement.PartialModelInitializer;
13import tools.refinery.store.reasoning.refinement.StorageRefiner;
14import tools.refinery.store.reasoning.representation.PartialSymbol;
15import tools.refinery.store.reasoning.seed.Seed;
16import tools.refinery.store.reasoning.seed.SeedInitializer;
17import tools.refinery.store.representation.AnySymbol;
18import tools.refinery.store.representation.Symbol;
19
20@SuppressWarnings("UnusedReturnValue")
21public abstract sealed class PartialSymbolTranslator<A, C> implements AnyPartialSymbolTranslator
22 permits PartialRelationTranslator {
23 private final PartialSymbol<A, C> partialSymbol;
24 private boolean configured = false;
25 protected PartialInterpretationRefiner.Factory<A, C> interpretationRefiner;
26 protected AnySymbol storageSymbol;
27 protected StorageRefiner.Factory<?> storageRefiner;
28 protected PartialInterpretation.Factory<A, C> interpretationFactory;
29 protected PartialModelInitializer initializer;
30
31 PartialSymbolTranslator(PartialSymbol<A, C> partialSymbol) {
32 this.partialSymbol = partialSymbol;
33 }
34
35 @Override
36 public PartialSymbol<A, C> getPartialSymbol() {
37 return partialSymbol;
38 }
39
40 @Override
41 public void apply(ModelStoreBuilder storeBuilder) {
42 storeBuilder.getAdapter(ReasoningBuilder.class).partialSymbol(this);
43 }
44
45 public boolean isConfigured() {
46 return configured;
47 }
48
49 protected void checkConfigured() {
50 if (!configured) {
51 throw new IllegalStateException("Partial symbol was not configured");
52 }
53 }
54
55 protected void checkNotConfigured() {
56 if (configured) {
57 throw new IllegalStateException("Partial symbol was already configured");
58 }
59 }
60
61 public PartialSymbolTranslator<A, C> symbol(AnySymbol storageSymbol) {
62 return symbol((Symbol<?>) storageSymbol, null);
63 }
64
65 public <T> PartialSymbolTranslator<A, C> symbol(Symbol<T> storageSymbol,
66 StorageRefiner.Factory<T> storageRefiner) {
67 checkNotConfigured();
68 if (this.storageSymbol != null) {
69 throw new IllegalStateException("Representation symbol was already set");
70 }
71 this.storageSymbol = storageSymbol;
72 this.storageRefiner = storageRefiner;
73 return this;
74 }
75
76 public PartialSymbolTranslator<A, C> interpretation(PartialInterpretation.Factory<A, C> interpretationFactory) {
77 checkNotConfigured();
78 if (this.interpretationFactory != null) {
79 throw new IllegalStateException("Interpretation factory was already set");
80 }
81 this.interpretationFactory = interpretationFactory;
82 return this;
83 }
84
85 public PartialSymbolTranslator<A, C> refiner(PartialInterpretationRefiner.Factory<A, C> interpretationRefiner) {
86 checkNotConfigured();
87 if (this.interpretationRefiner != null) {
88 throw new IllegalStateException("Interpretation refiner was already set");
89 }
90 this.interpretationRefiner = interpretationRefiner;
91 return this;
92 }
93
94 public PartialSymbolTranslator<A, C> initializer(PartialModelInitializer initializer) {
95 checkNotConfigured();
96 if (this.initializer != null) {
97 throw new IllegalStateException("Initializer was already set");
98 }
99 this.initializer = initializer;
100 return this;
101 }
102
103 public <T> PartialSymbolTranslator<A, C> seed(Seed<T> seed) {
104 if (storageSymbol == null) {
105 throw new IllegalArgumentException("Seed requires setting a storage symbol");
106 }
107 if (!seed.valueType().equals(storageSymbol.valueType())) {
108 throw new IllegalArgumentException("Seed type %s does not match storage symbol type %s"
109 .formatted(seed.valueType(), storageSymbol.valueType()));
110 }
111 // The guard clause only allows a well-typed seed.
112 @SuppressWarnings("unchecked")
113 var typedStorageSymbol = (Symbol<T>) storageSymbol;
114 return initializer(new SeedInitializer<>(typedStorageSymbol, seed));
115 }
116
117 @Override
118 public void configure(ModelStoreBuilder storeBuilder) {
119 checkNotConfigured();
120 doConfigure(storeBuilder);
121 configured = true;
122 }
123
124 protected void doConfigure(ModelStoreBuilder storeBuilder) {
125 if (interpretationFactory == null) {
126 throw new IllegalArgumentException("Interpretation factory must be set");
127 }
128 var reasoningBuilder = storeBuilder.getAdapter(ReasoningBuilder.class);
129 if (storageSymbol != null) {
130 storeBuilder.symbol(storageSymbol);
131 if (storageRefiner != null) {
132 registerStorageRefiner(reasoningBuilder, storageRefiner);
133 }
134 }
135 if (initializer != null) {
136 reasoningBuilder.initializer(initializer);
137 }
138 }
139
140 private <T> void registerStorageRefiner(ReasoningBuilder reasoningBuilder, StorageRefiner.Factory<T> factory) {
141 // The builder only allows setting a well-typed representation refiner.
142 @SuppressWarnings("unchecked")
143 var typedStorageSymbol = (Symbol<T>) storageSymbol;
144 reasoningBuilder.storageRefiner(typedStorageSymbol, factory);
145 }
146
147 public PartialInterpretation.Factory<A, C> getInterpretationFactory() {
148 checkConfigured();
149 return interpretationFactory;
150 }
151
152 public PartialInterpretationRefiner.Factory<A, C> getInterpretationRefiner() {
153 checkConfigured();
154 return interpretationRefiner;
155 }
156}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/RoundingMode.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/RoundingMode.java
new file mode 100644
index 00000000..dd956a50
--- /dev/null
+++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/RoundingMode.java
@@ -0,0 +1,12 @@
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.translator;
7
8public enum RoundingMode {
9 NONE,
10 PREFER_TRUE,
11 PREFER_FALSE
12}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/TranslatedRelation.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/TranslatedRelation.java
deleted file mode 100644
index 4a5a8843..00000000
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/TranslatedRelation.java
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.query.term.Variable;
10import tools.refinery.store.query.literal.CallPolarity;
11import tools.refinery.store.query.literal.Literal;
12import tools.refinery.store.reasoning.PartialInterpretation;
13import tools.refinery.store.reasoning.literal.Modality;
14import tools.refinery.store.reasoning.representation.PartialRelation;
15import tools.refinery.store.representation.TruthValue;
16
17import java.util.List;
18
19public interface TranslatedRelation {
20 PartialRelation getSource();
21
22 void configure(List<Advice> advices);
23
24 List<Literal> call(CallPolarity polarity, Modality modality, List<Variable> arguments);
25
26 PartialInterpretation<TruthValue, Boolean> createPartialInterpretation(Model model);
27}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/TranslationUnit.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/TranslationUnit.java
deleted file mode 100644
index 6e44a7d7..00000000
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/TranslationUnit.java
+++ /dev/null
@@ -1,32 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.reasoning.ReasoningBuilder;
10
11import java.util.Collection;
12
13public abstract class TranslationUnit {
14 private ReasoningBuilder reasoningBuilder;
15
16 protected ReasoningBuilder getReasoningBuilder() {
17 return reasoningBuilder;
18 }
19
20 public void setPartialInterpretationBuilder(ReasoningBuilder reasoningBuilder) {
21 this.reasoningBuilder = reasoningBuilder;
22 configureReasoningBuilder();
23 }
24
25 protected void configureReasoningBuilder() {
26 // Nothing to configure by default.
27 }
28
29 public abstract Collection<TranslatedRelation> getTranslatedRelations();
30
31 public abstract void initializeModel(Model model, int nodeCount);
32}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/BaseDecisionInterpretation.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/BaseDecisionInterpretation.java
deleted file mode 100644
index 2a151aa2..00000000
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/BaseDecisionInterpretation.java
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator.base;
7
8import tools.refinery.store.map.Cursor;
9import tools.refinery.store.model.Interpretation;
10import tools.refinery.store.query.resultset.ResultSet;
11import tools.refinery.store.reasoning.MergeResult;
12import tools.refinery.store.reasoning.PartialInterpretation;
13import tools.refinery.store.reasoning.ReasoningAdapter;
14import tools.refinery.store.reasoning.representation.PartialRelation;
15import tools.refinery.store.representation.TruthValue;
16import tools.refinery.store.tuple.Tuple;
17
18public class BaseDecisionInterpretation implements PartialInterpretation<TruthValue, Boolean> {
19 private final ReasoningAdapter reasoningAdapter;
20 private PartialRelation partialRelation;
21 private final ResultSet<Boolean> mustResultSet;
22 private final ResultSet<Boolean> mayResultSet;
23 private final ResultSet<Boolean> errorResultSet;
24 private final ResultSet<Boolean> currentResultSet;
25 private final Interpretation<TruthValue> interpretation;
26
27 public BaseDecisionInterpretation(ReasoningAdapter reasoningAdapter, ResultSet<Boolean> mustResultSet,
28 ResultSet<Boolean> mayResultSet, ResultSet<Boolean> errorResultSet,
29 ResultSet<Boolean> currentResultSet, Interpretation<TruthValue> interpretation) {
30 this.reasoningAdapter = reasoningAdapter;
31 this.mustResultSet = mustResultSet;
32 this.mayResultSet = mayResultSet;
33 this.errorResultSet = errorResultSet;
34 this.currentResultSet = currentResultSet;
35 this.interpretation = interpretation;
36 }
37
38 @Override
39 public ReasoningAdapter getAdapter() {
40 return reasoningAdapter;
41 }
42
43 @Override
44 public int countUnfinished() {
45 return 0;
46 }
47
48 @Override
49 public int countErrors() {
50 return errorResultSet.size();
51 }
52
53 @Override
54 public PartialRelation getPartialSymbol() {
55 return partialRelation;
56 }
57
58 @Override
59 public TruthValue get(Tuple key) {
60 return null;
61 }
62
63 @Override
64 public Cursor<Tuple, TruthValue> getAll() {
65 return null;
66 }
67
68 @Override
69 public MergeResult merge(Tuple key, TruthValue value) {
70 TruthValue newValue;
71 switch (value) {
72 case UNKNOWN -> {
73 return MergeResult.UNCHANGED;
74 }
75 case TRUE -> newValue = mayResultSet.get(key) ? TruthValue.TRUE : TruthValue.ERROR;
76 case FALSE -> newValue = mustResultSet.get(key) ? TruthValue.ERROR : TruthValue.FALSE;
77 case ERROR -> newValue = TruthValue.ERROR;
78 default -> throw new IllegalArgumentException("Unknown truth value: " + value);
79 }
80 var oldValue = interpretation.put(key, newValue);
81 return oldValue == TruthValue.ERROR ? MergeResult.UNCHANGED : MergeResult.REFINED;
82 }
83
84 @Override
85 public Boolean getConcrete(Tuple key) {
86 return currentResultSet.get(key);
87 }
88
89 @Override
90 public Cursor<Tuple, Boolean> getAllConcrete() {
91 return null;
92 }
93}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/BaseDecisionTranslationUnit.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/BaseDecisionTranslationUnit.java
deleted file mode 100644
index a1e4b816..00000000
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/BaseDecisionTranslationUnit.java
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator.base;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.reasoning.representation.PartialRelation;
10import tools.refinery.store.reasoning.seed.Seed;
11import tools.refinery.store.reasoning.seed.UniformSeed;
12import tools.refinery.store.reasoning.translator.TranslatedRelation;
13import tools.refinery.store.reasoning.translator.TranslationUnit;
14import tools.refinery.store.representation.Symbol;
15import tools.refinery.store.representation.TruthValue;
16
17import java.util.Collection;
18import java.util.List;
19
20public class BaseDecisionTranslationUnit extends TranslationUnit {
21 private final PartialRelation partialRelation;
22 private final Seed<TruthValue> seed;
23 private final Symbol<TruthValue> symbol;
24
25 public BaseDecisionTranslationUnit(PartialRelation partialRelation, Seed<TruthValue> seed) {
26 if (seed.arity() != partialRelation.arity()) {
27 throw new IllegalArgumentException("Expected seed with arity %d for %s, got arity %s"
28 .formatted(partialRelation.arity(), partialRelation, seed.arity()));
29 }
30 this.partialRelation = partialRelation;
31 this.seed = seed;
32 symbol = Symbol.of(partialRelation.name(), partialRelation.arity(), TruthValue.class, TruthValue.UNKNOWN);
33 }
34
35 public BaseDecisionTranslationUnit(PartialRelation partialRelation) {
36 this(partialRelation, new UniformSeed<>(partialRelation.arity(), TruthValue.UNKNOWN));
37 }
38
39 @Override
40 public Collection<TranslatedRelation> getTranslatedRelations() {
41 return List.of(new TranslatedBaseDecision(getReasoningBuilder(), partialRelation, symbol));
42 }
43
44 @Override
45 public void initializeModel(Model model, int nodeCount) {
46 var interpretation = model.getInterpretation(symbol);
47 interpretation.putAll(seed.getCursor(TruthValue.UNKNOWN, nodeCount));
48 }
49}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/TranslatedBaseDecision.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/TranslatedBaseDecision.java
deleted file mode 100644
index 4782eb46..00000000
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/base/TranslatedBaseDecision.java
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator.base;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.query.term.Variable;
10import tools.refinery.store.query.literal.CallPolarity;
11import tools.refinery.store.query.literal.Literal;
12import tools.refinery.store.reasoning.PartialInterpretation;
13import tools.refinery.store.reasoning.ReasoningBuilder;
14import tools.refinery.store.reasoning.literal.Modality;
15import tools.refinery.store.reasoning.representation.PartialRelation;
16import tools.refinery.store.reasoning.translator.Advice;
17import tools.refinery.store.reasoning.translator.TranslatedRelation;
18import tools.refinery.store.representation.Symbol;
19import tools.refinery.store.representation.TruthValue;
20
21import java.util.List;
22
23class TranslatedBaseDecision implements TranslatedRelation {
24 private final ReasoningBuilder reasoningBuilder;
25 private final PartialRelation partialRelation;
26 private final Symbol<TruthValue> symbol;
27
28 public TranslatedBaseDecision(ReasoningBuilder reasoningBuilder, PartialRelation partialRelation,
29 Symbol<TruthValue> symbol) {
30 this.reasoningBuilder = reasoningBuilder;
31 this.partialRelation = partialRelation;
32 this.symbol = symbol;
33 }
34
35 @Override
36 public PartialRelation getSource() {
37 return partialRelation;
38 }
39
40 @Override
41 public void configure(List<Advice> advices) {
42
43 }
44
45 @Override
46 public List<Literal> call(CallPolarity polarity, Modality modality, List<Variable> arguments) {
47 return null;
48 }
49
50 @Override
51 public PartialInterpretation<TruthValue, Boolean> createPartialInterpretation(Model model) {
52 return null;
53 }
54}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMayTypeView.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMayTypeView.java
deleted file mode 100644
index 40de4644..00000000
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMayTypeView.java
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator.typehierarchy;
7
8import tools.refinery.store.reasoning.representation.PartialRelation;
9import tools.refinery.store.query.view.TuplePreservingView;
10import tools.refinery.store.tuple.Tuple;
11
12import java.util.Objects;
13
14class InferredMayTypeView extends TuplePreservingView<InferredType> {
15 private final PartialRelation type;
16
17 InferredMayTypeView(PartialRelation type) {
18 super(TypeHierarchyTranslationUnit.INFERRED_TYPE_SYMBOL, "%s#may".formatted(type));
19 this.type = type;
20 }
21
22 @Override
23 protected boolean doFilter(Tuple key, InferredType value) {
24 return value.mayConcreteTypes().contains(type);
25 }
26
27 @Override
28 public boolean equals(Object o) {
29 if (this == o) return true;
30 if (o == null || getClass() != o.getClass()) return false;
31 if (!super.equals(o)) return false;
32 InferredMayTypeView that = (InferredMayTypeView) o;
33 return Objects.equals(type, that.type);
34 }
35
36 @Override
37 public int hashCode() {
38 return Objects.hash(super.hashCode(), type);
39 }
40}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMustTypeView.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMustTypeView.java
deleted file mode 100644
index 1a121547..00000000
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/InferredMustTypeView.java
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator.typehierarchy;
7
8import tools.refinery.store.reasoning.representation.PartialRelation;
9import tools.refinery.store.query.view.TuplePreservingView;
10import tools.refinery.store.tuple.Tuple;
11
12import java.util.Objects;
13
14class InferredMustTypeView extends TuplePreservingView<InferredType> {
15 private final PartialRelation type;
16
17 InferredMustTypeView(PartialRelation type) {
18 super(TypeHierarchyTranslationUnit.INFERRED_TYPE_SYMBOL, "%s#must".formatted(type));
19 this.type = type;
20 }
21
22 @Override
23 protected boolean doFilter(Tuple key, InferredType value) {
24 return value.mustTypes().contains(type);
25 }
26
27 @Override
28 public boolean equals(Object o) {
29 if (this == o) return true;
30 if (o == null || getClass() != o.getClass()) return false;
31 if (!super.equals(o)) return false;
32 InferredMustTypeView that = (InferredMustTypeView) o;
33 return Objects.equals(type, that.type);
34 }
35
36 @Override
37 public int hashCode() {
38 return Objects.hash(super.hashCode(), type);
39 }
40}
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslationUnit.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslationUnit.java
deleted file mode 100644
index 06e3c05f..00000000
--- a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/typehierarchy/TypeHierarchyTranslationUnit.java
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.reasoning.translator.typehierarchy;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.reasoning.representation.PartialRelation;
10import tools.refinery.store.reasoning.translator.TranslatedRelation;
11import tools.refinery.store.reasoning.translator.TranslationUnit;
12import tools.refinery.store.representation.Symbol;
13
14import java.util.Collection;
15import java.util.List;
16import java.util.Map;
17
18public class TypeHierarchyTranslationUnit extends TranslationUnit {
19 static final Symbol<InferredType> INFERRED_TYPE_SYMBOL = Symbol.of(
20 "inferredType", 1, InferredType.class, InferredType.UNTYPED);
21
22 private final TypeAnalyzer typeAnalyzer;
23
24 public TypeHierarchyTranslationUnit(Map<PartialRelation, TypeInfo> typeInfoMap) {
25 typeAnalyzer = new TypeAnalyzer(typeInfoMap);
26 }
27
28 @Override
29 public Collection<TranslatedRelation> getTranslatedRelations() {
30 return List.of();
31 }
32
33 @Override
34 public void initializeModel(Model model, int nodeCount) {
35
36 }
37}