diff options
Diffstat (limited to 'subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CountLiteral.java')
-rw-r--r-- | subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CountLiteral.java | 80 |
1 files changed, 12 insertions, 68 deletions
diff --git a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CountLiteral.java b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CountLiteral.java index 4d4749c8..3d078d89 100644 --- a/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CountLiteral.java +++ b/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CountLiteral.java | |||
@@ -6,96 +6,40 @@ | |||
6 | package tools.refinery.store.query.literal; | 6 | package tools.refinery.store.query.literal; |
7 | 7 | ||
8 | import tools.refinery.store.query.Constraint; | 8 | import tools.refinery.store.query.Constraint; |
9 | import tools.refinery.store.query.equality.LiteralEqualityHelper; | ||
10 | import tools.refinery.store.query.substitution.Substitution; | 9 | import tools.refinery.store.query.substitution.Substitution; |
11 | import tools.refinery.store.query.term.DataVariable; | 10 | import tools.refinery.store.query.term.DataVariable; |
12 | import tools.refinery.store.query.term.Variable; | 11 | import tools.refinery.store.query.term.Variable; |
13 | import tools.refinery.store.query.term.int_.IntTerms; | ||
14 | 12 | ||
15 | import java.util.List; | 13 | import java.util.List; |
16 | import java.util.Objects; | ||
17 | import java.util.Set; | ||
18 | |||
19 | public class CountLiteral extends AbstractCallLiteral { | ||
20 | private final DataVariable<Integer> resultVariable; | ||
21 | 14 | ||
15 | public class CountLiteral extends AbstractCountLiteral<Integer> { | ||
22 | public CountLiteral(DataVariable<Integer> resultVariable, Constraint target, List<Variable> arguments) { | 16 | public CountLiteral(DataVariable<Integer> resultVariable, Constraint target, List<Variable> arguments) { |
23 | super(target, arguments); | 17 | super(Integer.class, resultVariable, target, arguments); |
24 | if (!resultVariable.getType().equals(Integer.class)) { | ||
25 | throw new IllegalArgumentException("Count result variable %s must be of type %s, got %s instead".formatted( | ||
26 | resultVariable, Integer.class.getName(), resultVariable.getType().getName())); | ||
27 | } | ||
28 | if (arguments.contains(resultVariable)) { | ||
29 | throw new IllegalArgumentException("Count result variable %s must not appear in the argument list" | ||
30 | .formatted(resultVariable)); | ||
31 | } | ||
32 | this.resultVariable = resultVariable; | ||
33 | } | ||
34 | |||
35 | public DataVariable<Integer> getResultVariable() { | ||
36 | return resultVariable; | ||
37 | } | 18 | } |
38 | 19 | ||
39 | @Override | 20 | @Override |
40 | public Set<Variable> getOutputVariables() { | 21 | protected Integer zero() { |
41 | return Set.of(resultVariable); | 22 | return 0; |
42 | } | 23 | } |
43 | 24 | ||
44 | @Override | 25 | @Override |
45 | public Literal reduce() { | 26 | protected Integer one() { |
46 | var reduction = getTarget().getReduction(); | 27 | return 1; |
47 | return switch (reduction) { | ||
48 | case ALWAYS_FALSE -> getResultVariable().assign(IntTerms.constant(0)); | ||
49 | // The only way a constant {@code true} predicate can be called in a negative position is to have all of | ||
50 | // its arguments bound as input variables. Thus, there will only be a single match. | ||
51 | case ALWAYS_TRUE -> getResultVariable().assign(IntTerms.constant(1)); | ||
52 | case NOT_REDUCIBLE -> this; | ||
53 | }; | ||
54 | } | 28 | } |
55 | 29 | ||
56 | @Override | 30 | @Override |
57 | protected Literal doSubstitute(Substitution substitution, List<Variable> substitutedArguments) { | 31 | protected Literal doSubstitute(Substitution substitution, List<Variable> substitutedArguments) { |
58 | return new CountLiteral(substitution.getTypeSafeSubstitute(resultVariable), getTarget(), substitutedArguments); | 32 | return new CountLiteral(substitution.getTypeSafeSubstitute(getResultVariable()), getTarget(), |
59 | } | 33 | substitutedArguments); |
60 | |||
61 | @Override | ||
62 | public boolean equalsWithSubstitution(LiteralEqualityHelper helper, Literal other) { | ||
63 | if (!super.equalsWithSubstitution(helper, other)) { | ||
64 | return false; | ||
65 | } | ||
66 | var otherCountLiteral = (CountLiteral) other; | ||
67 | return helper.variableEqual(resultVariable, otherCountLiteral.resultVariable); | ||
68 | } | ||
69 | |||
70 | @Override | ||
71 | public boolean equals(Object o) { | ||
72 | if (this == o) return true; | ||
73 | if (o == null || getClass() != o.getClass()) return false; | ||
74 | if (!super.equals(o)) return false; | ||
75 | CountLiteral that = (CountLiteral) o; | ||
76 | return resultVariable.equals(that.resultVariable); | ||
77 | } | 34 | } |
78 | 35 | ||
79 | @Override | 36 | @Override |
80 | public int hashCode() { | 37 | public AbstractCallLiteral withArguments(Constraint newTarget, List<Variable> newArguments) { |
81 | return Objects.hash(super.hashCode(), resultVariable); | 38 | return new CountLiteral(getResultVariable(), newTarget, newArguments); |
82 | } | 39 | } |
83 | 40 | ||
84 | @Override | 41 | @Override |
85 | public String toString() { | 42 | protected String operatorName() { |
86 | var builder = new StringBuilder(); | 43 | return "count"; |
87 | builder.append(resultVariable); | ||
88 | builder.append(" is count "); | ||
89 | builder.append(getTarget().toReferenceString()); | ||
90 | builder.append("("); | ||
91 | var argumentIterator = getArguments().iterator(); | ||
92 | if (argumentIterator.hasNext()) { | ||
93 | builder.append(argumentIterator.next()); | ||
94 | while (argumentIterator.hasNext()) { | ||
95 | builder.append(", ").append(argumentIterator.next()); | ||
96 | } | ||
97 | } | ||
98 | builder.append(")"); | ||
99 | return builder.toString(); | ||
100 | } | 44 | } |
101 | } | 45 | } |