aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-reasoning/src
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-08-18 20:35:21 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-08-18 20:35:21 +0200
commitecf62ce9828a1fdf45e81d9bf91655513a0e26d6 (patch)
treeb1e0e2f00f81fc795d5654df7942c9be2fd5c11b /subprojects/store-reasoning/src
parentbuild: fix deprecation warning (diff)
downloadrefinery-ecf62ce9828a1fdf45e81d9bf91655513a0e26d6.tar.gz
refinery-ecf62ce9828a1fdf45e81d9bf91655513a0e26d6.tar.zst
refinery-ecf62ce9828a1fdf45e81d9bf91655513a0e26d6.zip
feat: predicate semantics
Diffstat (limited to 'subprojects/store-reasoning/src')
-rw-r--r--subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/predicate/PredicateTranslator.java85
1 files changed, 85 insertions, 0 deletions
diff --git a/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/predicate/PredicateTranslator.java b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/predicate/PredicateTranslator.java
new file mode 100644
index 00000000..ee022f2d
--- /dev/null
+++ b/subprojects/store-reasoning/src/main/java/tools/refinery/store/reasoning/translator/predicate/PredicateTranslator.java
@@ -0,0 +1,85 @@
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.predicate;
7
8import tools.refinery.store.model.ModelStoreBuilder;
9import tools.refinery.store.model.ModelStoreConfiguration;
10import tools.refinery.store.query.dnf.Query;
11import tools.refinery.store.query.dnf.RelationalQuery;
12import tools.refinery.store.query.literal.Literal;
13import tools.refinery.store.query.term.NodeVariable;
14import tools.refinery.store.query.term.Variable;
15import tools.refinery.store.query.view.ForbiddenView;
16import tools.refinery.store.query.view.MayView;
17import tools.refinery.store.query.view.MustView;
18import tools.refinery.store.reasoning.representation.PartialRelation;
19import tools.refinery.store.reasoning.translator.PartialRelationTranslator;
20import tools.refinery.store.representation.Symbol;
21import tools.refinery.store.representation.TruthValue;
22
23import static tools.refinery.store.query.literal.Literals.not;
24import static tools.refinery.store.reasoning.literal.PartialLiterals.may;
25import static tools.refinery.store.reasoning.literal.PartialLiterals.must;
26
27public class PredicateTranslator implements ModelStoreConfiguration {
28 private final PartialRelation relation;
29 private final RelationalQuery query;
30 private final boolean mutable;
31 private final TruthValue defaultValue;
32
33 public PredicateTranslator(PartialRelation relation, RelationalQuery query, boolean mutable,
34 TruthValue defaultValue) {
35 if (relation.arity() != query.arity()) {
36 throw new IllegalArgumentException("Expected arity %d query for partial relation %s, got %d instead"
37 .formatted(relation.arity(), relation, query.arity()));
38 }
39 if (defaultValue.must()) {
40 throw new IllegalArgumentException("Default value must be UNKNOWN or FALSE");
41 }
42 this.relation = relation;
43 this.query = query;
44 this.mutable = mutable;
45 this.defaultValue = defaultValue;
46 }
47
48 @Override
49 public void apply(ModelStoreBuilder storeBuilder) {
50 var translator = PartialRelationTranslator.of(relation)
51 .query(query);
52 if (mutable) {
53 var symbol = Symbol.of(relation.name(), relation.arity(), TruthValue.class, defaultValue);
54 translator.symbol(symbol);
55
56 var parameters = new NodeVariable[relation.arity()];
57 for (int i = 0; i < parameters.length; i++) {
58 parameters[i] = Variable.of("p" + i);
59 }
60
61 var must = Query.builder()
62 .parameters(parameters)
63 .clause(must(query.call(parameters)))
64 .clause(new MustView(symbol).call(parameters))
65 .build();
66 translator.must(must);
67
68 var mayLiterals = new Literal[2];
69 mayLiterals[0] = may(query.call(parameters));
70 if (defaultValue.may()) {
71 mayLiterals[1] = not(new ForbiddenView(symbol).call(parameters));
72 } else {
73 mayLiterals[1] = new MayView(symbol).call(parameters);
74 }
75 var may = Query.builder()
76 .parameters(parameters)
77 .clause(mayLiterals)
78 .build();
79 translator.may(may);
80 } else if (!defaultValue.may()) {
81 translator.mayNever();
82 }
83 storeBuilder.with(translator);
84 }
85}