diff options
author | Kristóf Marussy <kristof@marussy.com> | 2022-10-30 19:27:34 -0400 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2022-11-05 19:41:17 +0100 |
commit | 960af83c7c1cb871da03b9ac4ec6f44c94e78a1d (patch) | |
tree | 7d37ee007ee2d3b031d62ca892920d326758f438 /subprojects/store/src | |
parent | refactor: DNF query builder (diff) | |
download | refinery-960af83c7c1cb871da03b9ac4ec6f44c94e78a1d.tar.gz refinery-960af83c7c1cb871da03b9ac4ec6f44c94e78a1d.tar.zst refinery-960af83c7c1cb871da03b9ac4ec6f44c94e78a1d.zip |
refactor: DNF atoms
Restore count != capability.
Still needs semantics and tests for count atoms over partial models.
Diffstat (limited to 'subprojects/store/src')
18 files changed, 231 insertions, 190 deletions
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/ImmutableNode.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/ImmutableNode.java index f68734ab..9397dede 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/map/internal/ImmutableNode.java +++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/ImmutableNode.java | |||
@@ -35,7 +35,7 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
35 | 35 | ||
36 | /** | 36 | /** |
37 | * Constructor that copies a mutable node to an immutable. | 37 | * Constructor that copies a mutable node to an immutable. |
38 | * | 38 | * |
39 | * @param node A mutable node. | 39 | * @param node A mutable node. |
40 | * @param cache A cache of existing immutable nodes. It can be used to search | 40 | * @param cache A cache of existing immutable nodes. It can be used to search |
41 | * and place reference immutable nodes. It can be null, if no cache | 41 | * and place reference immutable nodes. It can be null, if no cache |
@@ -151,7 +151,7 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
151 | oldValue.setOldValue(value); | 151 | oldValue.setOldValue(value); |
152 | return this; | 152 | return this; |
153 | } else { | 153 | } else { |
154 | // update existing value | 154 | // update existing nodeId |
155 | MutableNode<K, V> mutable = this.toMutable(); | 155 | MutableNode<K, V> mutable = this.toMutable(); |
156 | return mutable.updateValue(value, oldValue, selectedHashFragment); | 156 | return mutable.updateValue(value, oldValue, selectedHashFragment); |
157 | } | 157 | } |
@@ -161,7 +161,7 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
161 | oldValue.setOldValue(defaultValue); | 161 | oldValue.setOldValue(defaultValue); |
162 | return this; | 162 | return this; |
163 | } else { | 163 | } else { |
164 | // add new key + value | 164 | // add new key + nodeId |
165 | MutableNode<K, V> mutable = this.toMutable(); | 165 | MutableNode<K, V> mutable = this.toMutable(); |
166 | return mutable.putValue(key, value, oldValue, hashProvider, defaultValue, hash, depth); | 166 | return mutable.putValue(key, value, oldValue, hashProvider, defaultValue, hash, depth); |
167 | } | 167 | } |
@@ -182,7 +182,7 @@ public class ImmutableNode<K, V> extends Node<K, V> { | |||
182 | return mutable.updateWithSubNode(selectedHashFragment, newsubNode, value.equals(defaultValue)); | 182 | return mutable.updateWithSubNode(selectedHashFragment, newsubNode, value.equals(defaultValue)); |
183 | } | 183 | } |
184 | } else { | 184 | } else { |
185 | // add new key + value | 185 | // add new key + nodeId |
186 | MutableNode<K, V> mutable = this.toMutable(); | 186 | MutableNode<K, V> mutable = this.toMutable(); |
187 | return mutable.putValue(key, value, oldValue, hashProvider, defaultValue, hash, depth); | 187 | return mutable.putValue(key, value, oldValue, hashProvider, defaultValue, hash, depth); |
188 | } | 188 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java index 42333635..a4ca813c 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java +++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java | |||
@@ -10,13 +10,13 @@ import tools.refinery.store.map.VersionedMap; | |||
10 | 10 | ||
11 | /** | 11 | /** |
12 | * A cursor representing the difference between two states of a map. | 12 | * A cursor representing the difference between two states of a map. |
13 | * | 13 | * |
14 | * @author Oszkar Semerath | 14 | * @author Oszkar Semerath |
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | public class MapDiffCursor<K, V> implements DiffCursor<K, V>, Cursor<K, V> { | 17 | public class MapDiffCursor<K, V> implements DiffCursor<K, V>, Cursor<K, V> { |
18 | /** | 18 | /** |
19 | * Default value representing missing elements. | 19 | * Default nodeId representing missing elements. |
20 | */ | 20 | */ |
21 | private V defaultValue; | 21 | private V defaultValue; |
22 | private MapCursor<K, V> cursor1; | 22 | private MapCursor<K, V> cursor1; |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MutableNode.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MutableNode.java index 54853010..7c3cf7e8 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/map/internal/MutableNode.java +++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/MutableNode.java | |||
@@ -31,7 +31,7 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Constructs a {@link MutableNode} as a copy of an {@link ImmutableNode} | 33 | * Constructs a {@link MutableNode} as a copy of an {@link ImmutableNode} |
34 | * | 34 | * |
35 | * @param node | 35 | * @param node |
36 | */ | 36 | */ |
37 | protected MutableNode(ImmutableNode<K, V> node) { | 37 | protected MutableNode(ImmutableNode<K, V> node) { |
@@ -107,18 +107,18 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
107 | } | 107 | } |
108 | } | 108 | } |
109 | } else { | 109 | } else { |
110 | // If it does not have key, check for value | 110 | // If it does not have key, check for nodeId |
111 | @SuppressWarnings("unchecked") | 111 | @SuppressWarnings("unchecked") |
112 | var nodeCandidate = (Node<K, V>) content[2 * selectedHashFragment + 1]; | 112 | var nodeCandidate = (Node<K, V>) content[2 * selectedHashFragment + 1]; |
113 | if (nodeCandidate != null) { | 113 | if (nodeCandidate != null) { |
114 | // If it has value, it is a subnode -> upate that | 114 | // If it has nodeId, it is a subnode -> upate that |
115 | var newNode = nodeCandidate.putValue(key, value, oldValueBox, hashProvider, defaultValue, | 115 | var newNode = nodeCandidate.putValue(key, value, oldValueBox, hashProvider, defaultValue, |
116 | newHash(hashProvider, key, hash, depth + 1), depth + 1); | 116 | newHash(hashProvider, key, hash, depth + 1), depth + 1); |
117 | return updateWithSubNode(selectedHashFragment, newNode, value.equals(defaultValue)); | 117 | return updateWithSubNode(selectedHashFragment, newNode, value.equals(defaultValue)); |
118 | } else { | 118 | } else { |
119 | // If it does not have value, put it in the empty place | 119 | // If it does not have nodeId, put it in the empty place |
120 | if (value == defaultValue) { | 120 | if (value == defaultValue) { |
121 | // dont need to add new key-value pair | 121 | // dont need to add new key-nodeId pair |
122 | oldValueBox.setOldValue(defaultValue); | 122 | oldValueBox.setOldValue(defaultValue); |
123 | return this; | 123 | return this; |
124 | } else { | 124 | } else { |
@@ -138,8 +138,8 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
138 | } | 138 | } |
139 | 139 | ||
140 | /** | 140 | /** |
141 | * Updates an entry in a selected hash-fragment to a non-default value. | 141 | * Updates an entry in a selected hash-fragment to a non-default nodeId. |
142 | * | 142 | * |
143 | * @param value | 143 | * @param value |
144 | * @param selectedHashFragment | 144 | * @param selectedHashFragment |
145 | * @return | 145 | * @return |
@@ -153,7 +153,7 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
153 | } | 153 | } |
154 | 154 | ||
155 | /** | 155 | /** |
156 | * | 156 | * |
157 | * @param selectedHashFragment | 157 | * @param selectedHashFragment |
158 | * @param newNode | 158 | * @param newNode |
159 | * @return | 159 | * @return |
@@ -400,7 +400,7 @@ public class MutableNode<K, V> extends Node<K, V> { | |||
400 | V value = (V) this.content[2 * i + 1]; | 400 | V value = (V) this.content[2 * i + 1]; |
401 | 401 | ||
402 | if (value == defaultValue) { | 402 | if (value == defaultValue) { |
403 | throw new IllegalStateException("Node contains default value!"); | 403 | throw new IllegalStateException("Node contains default nodeId!"); |
404 | } | 404 | } |
405 | int hashCode = hashProvider.getHash(key, hashDepth(depth)); | 405 | int hashCode = hashProvider.getHash(key, hashDepth(depth)); |
406 | int shiftDepth = shiftDepth(depth); | 406 | int shiftDepth = shiftDepth(depth); |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/map/internal/Node.java b/subprojects/store/src/main/java/tools/refinery/store/map/internal/Node.java index 234a4ff3..2260cd5b 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/map/internal/Node.java +++ b/subprojects/store/src/main/java/tools/refinery/store/map/internal/Node.java | |||
@@ -10,7 +10,7 @@ public abstract class Node<K,V>{ | |||
10 | protected static final int NUMBER_OF_FACTORS = Integer.SIZE / BRANCHING_FACTOR_BITS; | 10 | protected static final int NUMBER_OF_FACTORS = Integer.SIZE / BRANCHING_FACTOR_BITS; |
11 | protected static final int FACTOR_MASK = FACTOR-1; | 11 | protected static final int FACTOR_MASK = FACTOR-1; |
12 | public static final int EFFECTIVE_BITS = BRANCHING_FACTOR_BITS * NUMBER_OF_FACTORS; | 12 | public static final int EFFECTIVE_BITS = BRANCHING_FACTOR_BITS * NUMBER_OF_FACTORS; |
13 | 13 | ||
14 | /** | 14 | /** |
15 | * Calculates the index for the continuous hash. | 15 | * Calculates the index for the continuous hash. |
16 | * @param depth The depth of the node in the tree. | 16 | * @param depth The depth of the node in the tree. |
@@ -19,10 +19,10 @@ public abstract class Node<K,V>{ | |||
19 | protected static int hashDepth(int depth) { | 19 | protected static int hashDepth(int depth) { |
20 | return depth/NUMBER_OF_FACTORS; | 20 | return depth/NUMBER_OF_FACTORS; |
21 | } | 21 | } |
22 | 22 | ||
23 | /** | 23 | /** |
24 | * Calculates the which segment of a single hash should be used. | 24 | * Calculates the which segment of a single hash should be used. |
25 | * @param depth The depth of the node in the tree. | 25 | * @param depth The depth of the node in the tree. |
26 | * @return The segment of a hash code. | 26 | * @return The segment of a hash code. |
27 | */ | 27 | */ |
28 | protected static int shiftDepth(int depth) { | 28 | protected static int shiftDepth(int depth) { |
@@ -38,7 +38,7 @@ public abstract class Node<K,V>{ | |||
38 | if(shiftDepth<0 || Node.NUMBER_OF_FACTORS<shiftDepth) throw new IllegalArgumentException("Invalid shift depth! valid intervall=[0;5], input="+shiftDepth); | 38 | if(shiftDepth<0 || Node.NUMBER_OF_FACTORS<shiftDepth) throw new IllegalArgumentException("Invalid shift depth! valid intervall=[0;5], input="+shiftDepth); |
39 | return (hash >>> shiftDepth*BRANCHING_FACTOR_BITS) & FACTOR_MASK; | 39 | return (hash >>> shiftDepth*BRANCHING_FACTOR_BITS) & FACTOR_MASK; |
40 | } | 40 | } |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * Returns the hash code for a given depth. It may calculate new hash code, or reuse a hash code calculated for depth-1. | 43 | * Returns the hash code for a given depth. It may calculate new hash code, or reuse a hash code calculated for depth-1. |
44 | * @param key The key. | 44 | * @param key The key. |
@@ -55,12 +55,12 @@ public abstract class Node<K,V>{ | |||
55 | hashProvider.getHash(key, hashDepth) : | 55 | hashProvider.getHash(key, hashDepth) : |
56 | hash; | 56 | hash; |
57 | } | 57 | } |
58 | 58 | ||
59 | 59 | ||
60 | public abstract V getValue(K key, ContinousHashProvider<? super K> hashProvider, V defaultValue, int hash, int depth); | 60 | public abstract V getValue(K key, ContinousHashProvider<? super K> hashProvider, V defaultValue, int hash, int depth); |
61 | public abstract Node<K,V> putValue(K key, V value, OldValueBox<V> old, ContinousHashProvider<? super K> hashProvider, V defaultValue, int hash, int depth); | 61 | public abstract Node<K,V> putValue(K key, V value, OldValueBox<V> old, ContinousHashProvider<? super K> hashProvider, V defaultValue, int hash, int depth); |
62 | public abstract long getSize(); | 62 | public abstract long getSize(); |
63 | 63 | ||
64 | abstract MutableNode<K, V> toMutable(); | 64 | abstract MutableNode<K, V> toMutable(); |
65 | public abstract ImmutableNode<K, V> toImmutable( | 65 | public abstract ImmutableNode<K, V> toImmutable( |
66 | Map<Node<K, V>,ImmutableNode<K, V>> cache); | 66 | Map<Node<K, V>,ImmutableNode<K, V>> cache); |
@@ -68,10 +68,10 @@ public abstract class Node<K,V>{ | |||
68 | /** | 68 | /** |
69 | * Moves a {@link MapCursor} to its next position. | 69 | * Moves a {@link MapCursor} to its next position. |
70 | * @param cursor the cursor | 70 | * @param cursor the cursor |
71 | * @return Whether there was a next value to move on. | 71 | * @return Whether there was a next nodeId to move on. |
72 | */ | 72 | */ |
73 | abstract boolean moveToNext(MapCursor<K,V> cursor); | 73 | abstract boolean moveToNext(MapCursor<K,V> cursor); |
74 | 74 | ||
75 | ///////// FOR printing | 75 | ///////// FOR printing |
76 | public abstract void prettyPrint(StringBuilder builder, int depth, int code); | 76 | public abstract void prettyPrint(StringBuilder builder, int depth, int code); |
77 | @Override | 77 | @Override |
@@ -81,5 +81,5 @@ public abstract class Node<K,V>{ | |||
81 | return stringBuilder.toString(); | 81 | return stringBuilder.toString(); |
82 | } | 82 | } |
83 | public void checkIntegrity(ContinousHashProvider<? super K> hashProvider, V defaultValue, int depth) {} | 83 | public void checkIntegrity(ContinousHashProvider<? super K> hashProvider, V defaultValue, int depth) {} |
84 | 84 | ||
85 | } | 85 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/AbstractCallAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/AbstractCallAtom.java deleted file mode 100644 index fb8d7432..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/atom/AbstractCallAtom.java +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | package tools.refinery.store.query.atom; | ||
2 | |||
3 | import tools.refinery.store.model.RelationLike; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | |||
6 | import java.util.List; | ||
7 | import java.util.Set; | ||
8 | |||
9 | public abstract class AbstractCallAtom<T extends RelationLike> extends AbstractSubstitutionAtom<T> { | ||
10 | private final CallKind kind; | ||
11 | |||
12 | protected AbstractCallAtom(CallKind kind, T target, List<Variable> substitution) { | ||
13 | super(target, substitution); | ||
14 | if (kind.isTransitive() && target.getArity() != 2) { | ||
15 | throw new IllegalArgumentException("Transitive closures can only take binary relations"); | ||
16 | } | ||
17 | this.kind = kind; | ||
18 | } | ||
19 | |||
20 | public CallKind getKind() { | ||
21 | return kind; | ||
22 | } | ||
23 | |||
24 | @Override | ||
25 | public void collectAllVariables(Set<Variable> variables) { | ||
26 | if (kind.isPositive()) { | ||
27 | super.collectAllVariables(variables); | ||
28 | } | ||
29 | } | ||
30 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/BasicCallKind.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/BasicCallKind.java new file mode 100644 index 00000000..cf2ffc07 --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/BasicCallKind.java | |||
@@ -0,0 +1,26 @@ | |||
1 | package tools.refinery.store.query.atom; | ||
2 | |||
3 | public enum BasicCallKind implements CallKind { | ||
4 | POSITIVE(true, false), | ||
5 | NEGATIVE(false, false), | ||
6 | TRANSITIVE(true, true); | ||
7 | |||
8 | private final boolean positive; | ||
9 | |||
10 | private final boolean transitive; | ||
11 | |||
12 | BasicCallKind(boolean positive, boolean transitive) { | ||
13 | this.positive = positive; | ||
14 | this.transitive = transitive; | ||
15 | } | ||
16 | |||
17 | @Override | ||
18 | public boolean isPositive() { | ||
19 | return positive; | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public boolean isTransitive() { | ||
24 | return transitive; | ||
25 | } | ||
26 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/CallAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/CallAtom.java new file mode 100644 index 00000000..e52e33ac --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/CallAtom.java | |||
@@ -0,0 +1,66 @@ | |||
1 | package tools.refinery.store.query.atom; | ||
2 | |||
3 | import tools.refinery.store.model.RelationLike; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | |||
6 | import java.util.List; | ||
7 | import java.util.Objects; | ||
8 | import java.util.Set; | ||
9 | |||
10 | public final class CallAtom<T extends RelationLike> extends AbstractSubstitutionAtom<T> { | ||
11 | private final CallKind kind; | ||
12 | |||
13 | public CallAtom(CallKind kind, T target, List<Variable> substitution) { | ||
14 | super(target, substitution); | ||
15 | if (kind.isTransitive() && target.getArity() != 2) { | ||
16 | throw new IllegalArgumentException("Transitive closures can only take binary relations"); | ||
17 | } | ||
18 | this.kind = kind; | ||
19 | } | ||
20 | |||
21 | public CallAtom(CallKind kind, T target, Variable... substitution) { | ||
22 | this(kind, target, List.of(substitution)); | ||
23 | } | ||
24 | |||
25 | public CallAtom(boolean positive, T target, List<Variable> substitution) { | ||
26 | this(CallKind.fromBoolean(positive), target, substitution); | ||
27 | } | ||
28 | |||
29 | public CallAtom(boolean positive, T target, Variable... substitution) { | ||
30 | this(positive, target, List.of(substitution)); | ||
31 | } | ||
32 | |||
33 | public CallAtom(T target, List<Variable> substitution) { | ||
34 | this(true, target, substitution); | ||
35 | } | ||
36 | |||
37 | public CallAtom(T target, Variable... substitution) { | ||
38 | this(target, List.of(substitution)); | ||
39 | } | ||
40 | |||
41 | public CallKind getKind() { | ||
42 | return kind; | ||
43 | } | ||
44 | |||
45 | @Override | ||
46 | public void collectAllVariables(Set<Variable> variables) { | ||
47 | if (kind.isPositive()) { | ||
48 | super.collectAllVariables(variables); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | @Override | ||
53 | public boolean equals(Object o) { | ||
54 | if (this == o) return true; | ||
55 | if (o == null || getClass() != o.getClass()) return false; | ||
56 | CallAtom<?> that = (CallAtom<?>) o; | ||
57 | return Objects.equals(kind, that.kind) | ||
58 | && Objects.equals(getTarget(), that.getTarget()) | ||
59 | && Objects.equals(getSubstitution(), that.getSubstitution()); | ||
60 | } | ||
61 | |||
62 | @Override | ||
63 | public int hashCode() { | ||
64 | return Objects.hash(kind, getTarget(), getSubstitution()); | ||
65 | } | ||
66 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/CallKind.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/CallKind.java index c7cbc955..86066b8e 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/query/atom/CallKind.java +++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/CallKind.java | |||
@@ -1,24 +1,11 @@ | |||
1 | package tools.refinery.store.query.atom; | 1 | package tools.refinery.store.query.atom; |
2 | 2 | ||
3 | public enum CallKind { | 3 | public sealed interface CallKind permits BasicCallKind, CountCallKind { |
4 | POSITIVE(true, false), | 4 | boolean isPositive(); |
5 | NEGATIVE(false, false), | ||
6 | TRANSITIVE(true, true); | ||
7 | 5 | ||
8 | private final boolean positive; | 6 | boolean isTransitive(); |
9 | 7 | ||
10 | private final boolean transitive; | 8 | static CallKind fromBoolean(boolean positive) { |
11 | 9 | return positive ? BasicCallKind.POSITIVE : BasicCallKind.NEGATIVE; | |
12 | CallKind(boolean positive, boolean transitive) { | ||
13 | this.positive = positive; | ||
14 | this.transitive = transitive; | ||
15 | } | ||
16 | |||
17 | public boolean isPositive() { | ||
18 | return positive; | ||
19 | } | ||
20 | |||
21 | public boolean isTransitive() { | ||
22 | return transitive; | ||
23 | } | 10 | } |
24 | } | 11 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/ComparisonOperator.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/ComparisonOperator.java new file mode 100644 index 00000000..ca113181 --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/ComparisonOperator.java | |||
@@ -0,0 +1,22 @@ | |||
1 | package tools.refinery.store.query.atom; | ||
2 | |||
3 | public enum ComparisonOperator { | ||
4 | EQUALS, | ||
5 | NOT_EQUALS, | ||
6 | LESS, | ||
7 | LESS_EQUALS, | ||
8 | GREATER, | ||
9 | GREATER_EQUALS; | ||
10 | |||
11 | @Override | ||
12 | public String toString() { | ||
13 | return switch (this) { | ||
14 | case EQUALS -> "=="; | ||
15 | case NOT_EQUALS -> "!="; | ||
16 | case LESS -> "<"; | ||
17 | case LESS_EQUALS -> "<="; | ||
18 | case GREATER -> ">"; | ||
19 | case GREATER_EQUALS -> ">="; | ||
20 | }; | ||
21 | } | ||
22 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/ConstantAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/ConstantAtom.java new file mode 100644 index 00000000..13dae7d0 --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/ConstantAtom.java | |||
@@ -0,0 +1,12 @@ | |||
1 | package tools.refinery.store.query.atom; | ||
2 | |||
3 | import tools.refinery.store.query.Variable; | ||
4 | |||
5 | import java.util.Set; | ||
6 | |||
7 | public record ConstantAtom(Variable variable, int nodeId) implements DNFAtom { | ||
8 | @Override | ||
9 | public void collectAllVariables(Set<Variable> variables) { | ||
10 | variables.add(variable); | ||
11 | } | ||
12 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/CountCallKind.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/CountCallKind.java new file mode 100644 index 00000000..2c85cb4f --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/CountCallKind.java | |||
@@ -0,0 +1,13 @@ | |||
1 | package tools.refinery.store.query.atom; | ||
2 | |||
3 | public record CountCallKind(ComparisonOperator operator, int threshold) implements CallKind { | ||
4 | @Override | ||
5 | public boolean isPositive() { | ||
6 | return false; | ||
7 | } | ||
8 | |||
9 | @Override | ||
10 | public boolean isTransitive() { | ||
11 | return false; | ||
12 | } | ||
13 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/CountNotEqualsAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/CountNotEqualsAtom.java new file mode 100644 index 00000000..312e5fb8 --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/CountNotEqualsAtom.java | |||
@@ -0,0 +1,31 @@ | |||
1 | package tools.refinery.store.query.atom; | ||
2 | |||
3 | import tools.refinery.store.model.RelationLike; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | |||
6 | import java.util.List; | ||
7 | import java.util.Set; | ||
8 | |||
9 | public record CountNotEqualsAtom<T extends RelationLike>(boolean must, int threshold, T mayTarget, T mustTarget, | ||
10 | List<Variable> substitution) implements DNFAtom { | ||
11 | public CountNotEqualsAtom { | ||
12 | if (substitution.size() != mayTarget.getArity()) { | ||
13 | throw new IllegalArgumentException("%s needs %d arguments, but got %s".formatted(mayTarget.getName(), | ||
14 | mayTarget.getArity(), substitution.size())); | ||
15 | } | ||
16 | if (substitution.size() != mustTarget.getArity()) { | ||
17 | throw new IllegalArgumentException("%s needs %d arguments, but got %s".formatted(mustTarget.getName(), | ||
18 | mustTarget.getArity(), substitution.size())); | ||
19 | } | ||
20 | } | ||
21 | |||
22 | public CountNotEqualsAtom(boolean must, int threshold, T mayTarget, T mustTarget, Variable... substitution) { | ||
23 | this(must, threshold, mayTarget, mustTarget, List.of(substitution)); | ||
24 | } | ||
25 | |||
26 | @Override | ||
27 | public void collectAllVariables(Set<Variable> variables) { | ||
28 | // No variables to collect, because all variables should either appear in other clauses, | ||
29 | // or are quantified by this clause. | ||
30 | } | ||
31 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/DNFCallAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/DNFCallAtom.java deleted file mode 100644 index 9d2efa53..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/atom/DNFCallAtom.java +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | package tools.refinery.store.query.atom; | ||
2 | |||
3 | import tools.refinery.store.query.DNF; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | |||
6 | import java.util.List; | ||
7 | import java.util.Objects; | ||
8 | |||
9 | public final class DNFCallAtom extends AbstractCallAtom<DNF> { | ||
10 | public DNFCallAtom(CallKind kind, DNF target, List<Variable> substitution) { | ||
11 | super(kind, target, substitution); | ||
12 | } | ||
13 | |||
14 | public DNFCallAtom(CallKind kind, DNF target, Variable... substitution) { | ||
15 | super(kind, target, List.of(substitution)); | ||
16 | } | ||
17 | |||
18 | public DNFCallAtom(DNF target, List<Variable> substitution) { | ||
19 | this(CallKind.POSITIVE, target, substitution); | ||
20 | } | ||
21 | |||
22 | public DNFCallAtom(DNF target, Variable... substitution) { | ||
23 | this(target, List.of(substitution)); | ||
24 | } | ||
25 | |||
26 | @Override | ||
27 | public boolean equals(Object o) { | ||
28 | if (this == o) return true; | ||
29 | if (o == null || getClass() != o.getClass()) return false; | ||
30 | DNFCallAtom dnfCallAtom = (DNFCallAtom) o; | ||
31 | return Objects.equals(getKind(), dnfCallAtom.getKind()) | ||
32 | && Objects.equals(getTarget(), dnfCallAtom.getTarget()) | ||
33 | && Objects.equals(getSubstitution(), dnfCallAtom.getSubstitution()); | ||
34 | } | ||
35 | |||
36 | @Override | ||
37 | public int hashCode() { | ||
38 | return Objects.hash(getKind(), getTarget(), getSubstitution()); | ||
39 | } | ||
40 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/ModalRelation.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/ModalRelation.java new file mode 100644 index 00000000..1e4f8f55 --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/ModalRelation.java | |||
@@ -0,0 +1,17 @@ | |||
1 | package tools.refinery.store.query.atom; | ||
2 | |||
3 | import tools.refinery.store.model.RelationLike; | ||
4 | import tools.refinery.store.model.representation.Relation; | ||
5 | import tools.refinery.store.model.representation.TruthValue; | ||
6 | |||
7 | public record ModalRelation(Modality modality, Relation<TruthValue> relation) implements RelationLike { | ||
8 | @Override | ||
9 | public String getName() { | ||
10 | return "%s %s".formatted(modality, relation); | ||
11 | } | ||
12 | |||
13 | @Override | ||
14 | public int getArity() { | ||
15 | return relation.getArity(); | ||
16 | } | ||
17 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/ModalRelationAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/ModalRelationAtom.java deleted file mode 100644 index 2480e82e..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/atom/ModalRelationAtom.java +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | package tools.refinery.store.query.atom; | ||
2 | |||
3 | import tools.refinery.store.model.representation.Relation; | ||
4 | import tools.refinery.store.model.representation.TruthValue; | ||
5 | import tools.refinery.store.query.Variable; | ||
6 | |||
7 | import java.util.List; | ||
8 | import java.util.Objects; | ||
9 | |||
10 | public final class ModalRelationAtom extends AbstractCallAtom<Relation<TruthValue>> { | ||
11 | private final Modality modality; | ||
12 | |||
13 | public ModalRelationAtom(CallKind kind, Modality modality, Relation<TruthValue> target, | ||
14 | List<Variable> substitution) { | ||
15 | super(kind, target, substitution); | ||
16 | this.modality = modality; | ||
17 | } | ||
18 | |||
19 | public ModalRelationAtom(Modality modality, Relation<TruthValue> target, List<Variable> substitution) { | ||
20 | this(CallKind.POSITIVE, modality, target, substitution); | ||
21 | } | ||
22 | |||
23 | @Override | ||
24 | public boolean equals(Object o) { | ||
25 | if (this == o) return true; | ||
26 | if (o == null || getClass() != o.getClass()) return false; | ||
27 | ModalRelationAtom modalRelationAtom = (ModalRelationAtom) o; | ||
28 | return Objects.equals(getKind(), modalRelationAtom.getKind()) | ||
29 | && modality == modalRelationAtom.modality | ||
30 | && Objects.equals(getTarget(), modalRelationAtom.getTarget()) | ||
31 | && Objects.equals(getSubstitution(), modalRelationAtom.getSubstitution()); | ||
32 | } | ||
33 | |||
34 | @Override | ||
35 | public int hashCode() { | ||
36 | return Objects.hash(getKind(), modality, getTarget(), getSubstitution()); | ||
37 | } | ||
38 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java index 9344a9d3..bc107b76 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java +++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java | |||
@@ -1,7 +1,14 @@ | |||
1 | package tools.refinery.store.query.atom; | 1 | package tools.refinery.store.query.atom; |
2 | 2 | ||
3 | import java.util.Locale; | ||
4 | |||
3 | public enum Modality { | 5 | public enum Modality { |
4 | MUST, | 6 | MUST, |
5 | MAY, | 7 | MAY, |
6 | CURRENT; | 8 | CURRENT; |
9 | |||
10 | @Override | ||
11 | public String toString() { | ||
12 | return name().toLowerCase(Locale.ROOT); | ||
13 | } | ||
7 | } | 14 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationAtom.java deleted file mode 100644 index 06098139..00000000 --- a/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationAtom.java +++ /dev/null | |||
@@ -1,32 +0,0 @@ | |||
1 | package tools.refinery.store.query.atom; | ||
2 | |||
3 | import tools.refinery.store.model.representation.Relation; | ||
4 | import tools.refinery.store.query.Variable; | ||
5 | |||
6 | import java.util.List; | ||
7 | import java.util.Objects; | ||
8 | |||
9 | public final class RelationAtom extends AbstractCallAtom<Relation<?>> { | ||
10 | public RelationAtom(CallKind kind, Relation<?> target, List<Variable> substitution) { | ||
11 | super(kind, target, substitution); | ||
12 | } | ||
13 | |||
14 | public RelationAtom(Relation<?> target, List<Variable> substitution) { | ||
15 | this(CallKind.POSITIVE, target, substitution); | ||
16 | } | ||
17 | |||
18 | @Override | ||
19 | public boolean equals(Object o) { | ||
20 | if (this == o) return true; | ||
21 | if (o == null || getClass() != o.getClass()) return false; | ||
22 | RelationAtom relationAtom = (RelationAtom) o; | ||
23 | return Objects.equals(getKind(), relationAtom.getKind()) | ||
24 | && Objects.equals(getTarget(), relationAtom.getTarget()) | ||
25 | && Objects.equals(getSubstitution(), relationAtom.getSubstitution()); | ||
26 | } | ||
27 | |||
28 | @Override | ||
29 | public int hashCode() { | ||
30 | return Objects.hash(getKind(), getTarget(), getSubstitution()); | ||
31 | } | ||
32 | } | ||
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java index 991b4f51..a4ba7441 100644 --- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java +++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java | |||
@@ -56,7 +56,7 @@ public class MapTestEnvironment<K, V> { | |||
56 | } | 56 | } |
57 | 57 | ||
58 | } | 58 | } |
59 | 59 | ||
60 | public static <K, V> void compareTwoMaps(String title, VersionedMapImpl<K, V> map1, | 60 | public static <K, V> void compareTwoMaps(String title, VersionedMapImpl<K, V> map1, |
61 | VersionedMapImpl<K, V> map2) { | 61 | VersionedMapImpl<K, V> map2) { |
62 | compareTwoMaps(title, map1, map2, null); | 62 | compareTwoMaps(title, map1, map2, null); |
@@ -112,7 +112,7 @@ public class MapTestEnvironment<K, V> { | |||
112 | oldOracleValue = oracle.remove(key); | 112 | oldOracleValue = oracle.remove(key); |
113 | } | 113 | } |
114 | if(oldSutValue == sut.getDefaultValue() && oldOracleValue != null) { | 114 | if(oldSutValue == sut.getDefaultValue() && oldOracleValue != null) { |
115 | fail("After put, SUT old value was default, but oracle old walue was " + oldOracleValue); | 115 | fail("After put, SUT old nodeId was default, but oracle old walue was " + oldOracleValue); |
116 | } | 116 | } |
117 | if(oldSutValue != sut.getDefaultValue()) { | 117 | if(oldSutValue != sut.getDefaultValue()) { |
118 | assertEquals(oldOracleValue, oldSutValue); | 118 | assertEquals(oldOracleValue, oldSutValue); |
@@ -127,8 +127,8 @@ public class MapTestEnvironment<K, V> { | |||
127 | fail(title + ": " + e.getMessage()); | 127 | fail(title + ": " + e.getMessage()); |
128 | } | 128 | } |
129 | 129 | ||
130 | // 1. Checking: if Reference contains <key,value> pair, then SUT contains | 130 | // 1. Checking: if Reference contains <key,nodeId> pair, then SUT contains |
131 | // <key,value> pair. | 131 | // <key,nodeId> pair. |
132 | // Tests get functions | 132 | // Tests get functions |
133 | for (Entry<K, V> entry : oracle.entrySet()) { | 133 | for (Entry<K, V> entry : oracle.entrySet()) { |
134 | V sutValue = sut.get(entry.getKey()); | 134 | V sutValue = sut.get(entry.getKey()); |
@@ -140,8 +140,8 @@ public class MapTestEnvironment<K, V> { | |||
140 | } | 140 | } |
141 | } | 141 | } |
142 | 142 | ||
143 | // 2. Checking: if SUT contains <key,value> pair, then Reference contains | 143 | // 2. Checking: if SUT contains <key,nodeId> pair, then Reference contains |
144 | // <key,value> pair. | 144 | // <key,nodeId> pair. |
145 | // Tests iterators | 145 | // Tests iterators |
146 | int elementsInSutEntrySet = 0; | 146 | int elementsInSutEntrySet = 0; |
147 | Cursor<K, V> cursor = sut.getAll(); | 147 | Cursor<K, V> cursor = sut.getAll(); |
@@ -160,7 +160,7 @@ public class MapTestEnvironment<K, V> { | |||
160 | } | 160 | } |
161 | 161 | ||
162 | // 3. Checking sizes | 162 | // 3. Checking sizes |
163 | // Counting of non-default value pairs. | 163 | // Counting of non-default nodeId pairs. |
164 | int oracleSize = oracle.entrySet().size(); | 164 | int oracleSize = oracle.entrySet().size(); |
165 | long sutSize = sut.getSize(); | 165 | long sutSize = sut.getSize(); |
166 | if (oracleSize != sutSize || oracleSize != elementsInSutEntrySet) { | 166 | if (oracleSize != sutSize || oracleSize != elementsInSutEntrySet) { |