aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java')
-rw-r--r--subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java103
1 files changed, 103 insertions, 0 deletions
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java
new file mode 100644
index 00000000..5bf6f8c5
--- /dev/null
+++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/dnf/FunctionalQuery.java
@@ -0,0 +1,103 @@
1package tools.refinery.store.query.dnf;
2
3import tools.refinery.store.query.literal.CallPolarity;
4import tools.refinery.store.query.term.*;
5
6import java.util.ArrayList;
7import java.util.List;
8import java.util.Objects;
9
10public final class FunctionalQuery<T> implements Query<T> {
11 private final Dnf dnf;
12 private final Class<T> type;
13
14 FunctionalQuery(Dnf dnf, Class<T> type) {
15 var parameters = dnf.getParameters();
16 int outputIndex = dnf.arity() - 1;
17 for (int i = 0; i < outputIndex; i++) {
18 var parameter = parameters.get(i);
19 if (!(parameter instanceof NodeVariable)) {
20 throw new IllegalArgumentException("Expected parameter %s of %s to be of sort %s, but got %s instead"
21 .formatted(parameter, dnf, NodeSort.INSTANCE, parameter.getSort()));
22 }
23 }
24 var outputParameter = parameters.get(outputIndex);
25 if (!(outputParameter instanceof DataVariable<?> dataOutputParameter) ||
26 !dataOutputParameter.getType().equals(type)) {
27 throw new IllegalArgumentException("Expected parameter %s of %s to be of sort %s, but got %s instead"
28 .formatted(outputParameter, dnf, type, outputParameter.getSort()));
29 }
30 this.dnf = dnf;
31 this.type = type;
32 }
33
34 @Override
35 public String name() {
36 return dnf.name();
37 }
38
39 @Override
40 public int arity() {
41 return dnf.arity() - 1;
42 }
43
44 @Override
45 public Class<T> valueType() {
46 return type;
47 }
48
49 @Override
50 public T defaultValue() {
51 return null;
52 }
53
54 @Override
55 public Dnf getDnf() {
56 return dnf;
57 }
58
59 public AssignedValue<T> call(List<NodeVariable> arguments) {
60 return targetVariable -> {
61 var argumentsWithTarget = new ArrayList<Variable>(arguments.size() + 1);
62 argumentsWithTarget.addAll(arguments);
63 argumentsWithTarget.add(targetVariable);
64 return dnf.call(CallPolarity.POSITIVE, argumentsWithTarget);
65 };
66 }
67
68 public AssignedValue<T> call(NodeVariable... arguments) {
69 return call(List.of(arguments));
70 }
71
72 public <R> AssignedValue<R> aggregate(Aggregator<R, T> aggregator, List<NodeVariable> arguments) {
73 return targetVariable -> {
74 var placeholderVariable = Variable.of(type);
75 var argumentsWithPlaceholder = new ArrayList<Variable>(arguments.size() + 1);
76 argumentsWithPlaceholder.addAll(arguments);
77 argumentsWithPlaceholder.add(placeholderVariable);
78 return dnf.aggregate(placeholderVariable, aggregator, argumentsWithPlaceholder).toLiteral(targetVariable);
79 };
80 }
81
82 public <R> AssignedValue<R> aggregate(Aggregator<R, T> aggregator, NodeVariable... arguments) {
83 return aggregate(aggregator, List.of(arguments));
84 }
85
86 @Override
87 public boolean equals(Object o) {
88 if (this == o) return true;
89 if (o == null || getClass() != o.getClass()) return false;
90 FunctionalQuery<?> that = (FunctionalQuery<?>) o;
91 return dnf.equals(that.dnf) && type.equals(that.type);
92 }
93
94 @Override
95 public int hashCode() {
96 return Objects.hash(dnf, type);
97 }
98
99 @Override
100 public String toString() {
101 return dnf.toString();
102 }
103}