aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-10-30 19:27:34 -0400
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-11-05 19:41:17 +0100
commit960af83c7c1cb871da03b9ac4ec6f44c94e78a1d (patch)
tree7d37ee007ee2d3b031d62ca892920d326758f438 /subprojects/store
parentrefactor: DNF query builder (diff)
downloadrefinery-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')
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/internal/ImmutableNode.java8
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/internal/MapDiffCursor.java4
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/internal/MutableNode.java18
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/map/internal/Node.java20
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/AbstractCallAtom.java30
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/BasicCallKind.java26
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/CallAtom.java66
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/CallKind.java23
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/ComparisonOperator.java22
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/ConstantAtom.java12
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/CountCallKind.java13
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/CountNotEqualsAtom.java31
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/DNFCallAtom.java40
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/ModalRelation.java17
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/ModalRelationAtom.java38
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java7
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationAtom.java32
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java14
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 */
17public class MapDiffCursor<K, V> implements DiffCursor<K, V>, Cursor<K, V> { 17public 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 @@
1package tools.refinery.store.query.atom;
2
3import tools.refinery.store.model.RelationLike;
4import tools.refinery.store.query.Variable;
5
6import java.util.List;
7import java.util.Set;
8
9public 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 @@
1package tools.refinery.store.query.atom;
2
3public 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 @@
1package tools.refinery.store.query.atom;
2
3import tools.refinery.store.model.RelationLike;
4import tools.refinery.store.query.Variable;
5
6import java.util.List;
7import java.util.Objects;
8import java.util.Set;
9
10public 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 @@
1package tools.refinery.store.query.atom; 1package tools.refinery.store.query.atom;
2 2
3public enum CallKind { 3public 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 @@
1package tools.refinery.store.query.atom;
2
3public 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 @@
1package tools.refinery.store.query.atom;
2
3import tools.refinery.store.query.Variable;
4
5import java.util.Set;
6
7public 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 @@
1package tools.refinery.store.query.atom;
2
3public 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 @@
1package tools.refinery.store.query.atom;
2
3import tools.refinery.store.model.RelationLike;
4import tools.refinery.store.query.Variable;
5
6import java.util.List;
7import java.util.Set;
8
9public 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 @@
1package tools.refinery.store.query.atom;
2
3import tools.refinery.store.query.DNF;
4import tools.refinery.store.query.Variable;
5
6import java.util.List;
7import java.util.Objects;
8
9public 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 @@
1package tools.refinery.store.query.atom;
2
3import tools.refinery.store.model.RelationLike;
4import tools.refinery.store.model.representation.Relation;
5import tools.refinery.store.model.representation.TruthValue;
6
7public 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 @@
1package tools.refinery.store.query.atom;
2
3import tools.refinery.store.model.representation.Relation;
4import tools.refinery.store.model.representation.TruthValue;
5import tools.refinery.store.query.Variable;
6
7import java.util.List;
8import java.util.Objects;
9
10public 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 @@
1package tools.refinery.store.query.atom; 1package tools.refinery.store.query.atom;
2 2
3import java.util.Locale;
4
3public enum Modality { 5public 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 @@
1package tools.refinery.store.query.atom;
2
3import tools.refinery.store.model.representation.Relation;
4import tools.refinery.store.query.Variable;
5
6import java.util.List;
7import java.util.Objects;
8
9public 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) {