diff options
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.java | 103 |
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 @@ | |||
1 | package tools.refinery.store.query.dnf; | ||
2 | |||
3 | import tools.refinery.store.query.literal.CallPolarity; | ||
4 | import tools.refinery.store.query.term.*; | ||
5 | |||
6 | import java.util.ArrayList; | ||
7 | import java.util.List; | ||
8 | import java.util.Objects; | ||
9 | |||
10 | public 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 | } | ||