aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query/src/main/java/tools/refinery/store/query/literal/CountLiteral.java
diff options
context:
space:
mode:
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.java80
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 @@
6package tools.refinery.store.query.literal; 6package tools.refinery.store.query.literal;
7 7
8import tools.refinery.store.query.Constraint; 8import tools.refinery.store.query.Constraint;
9import tools.refinery.store.query.equality.LiteralEqualityHelper;
10import tools.refinery.store.query.substitution.Substitution; 9import tools.refinery.store.query.substitution.Substitution;
11import tools.refinery.store.query.term.DataVariable; 10import tools.refinery.store.query.term.DataVariable;
12import tools.refinery.store.query.term.Variable; 11import tools.refinery.store.query.term.Variable;
13import tools.refinery.store.query.term.int_.IntTerms;
14 12
15import java.util.List; 13import java.util.List;
16import java.util.Objects;
17import java.util.Set;
18
19public class CountLiteral extends AbstractCallLiteral {
20 private final DataVariable<Integer> resultVariable;
21 14
15public 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}