aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store/src/main
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-10-19 12:22:14 -0400
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-11-05 19:41:16 +0100
commitf7e6301423e380e86dd4bd42409e2c4c9d6aade0 (patch)
treec5c95c2cdc4e83c6c5514b238bbd3e31c1d09048 /subprojects/store/src/main
parentrefactor(frontend): minor theme improvements (diff)
downloadrefinery-f7e6301423e380e86dd4bd42409e2c4c9d6aade0.tar.gz
refinery-f7e6301423e380e86dd4bd42409e2c4c9d6aade0.tar.zst
refinery-f7e6301423e380e86dd4bd42409e2c4c9d6aade0.zip
refactor: DNF query builder
Diffstat (limited to 'subprojects/store/src/main')
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java19
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/RelationLike.java7
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxilaryData.java22
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java22
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java22
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java23
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/DNF.java121
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/DNFAnd.java9
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/DNFUtils.java19
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java19
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java3
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/Variable.java43
-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/AbstractSubstitutionAtom.java35
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/CallKind.java24
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/atom/DNFAtom.java9
-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/EquivalenceAtom.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/main/java/tools/refinery/store/query/atom/RelationViewAtom.java31
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/building/DNFAnd.java37
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/building/DNFAtom.java33
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/building/DNFPredicate.java72
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/building/EquivalenceAtom.java44
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/building/PredicateAtom.java66
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/building/RelationAtom.java31
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/building/Variable.java22
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java6
30 files changed, 527 insertions, 376 deletions
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
index b5e1c453..d08cf0f8 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/ModelStoreImpl.java
@@ -1,24 +1,15 @@
1package tools.refinery.store.model; 1package tools.refinery.store.model;
2 2
3import java.util.HashMap; 3import tools.refinery.store.map.*;
4import java.util.LinkedList;
5import java.util.List;
6import java.util.Map;
7import java.util.Map.Entry;
8
9import tools.refinery.store.map.ContinousHashProvider;
10import tools.refinery.store.map.DiffCursor;
11import tools.refinery.store.map.VersionedMap;
12import tools.refinery.store.map.VersionedMapStore;
13import tools.refinery.store.map.VersionedMapStoreImpl;
14import tools.refinery.store.model.internal.ModelImpl; 4import tools.refinery.store.model.internal.ModelImpl;
15import tools.refinery.store.model.internal.SimilarRelationEquivalenceClass; 5import tools.refinery.store.model.internal.SimilarRelationEquivalenceClass;
16import tools.refinery.store.model.representation.AuxilaryData; 6import tools.refinery.store.model.representation.AuxiliaryData;
17import tools.refinery.store.model.representation.DataRepresentation; 7import tools.refinery.store.model.representation.DataRepresentation;
18import tools.refinery.store.model.representation.Relation; 8import tools.refinery.store.model.representation.Relation;
19import tools.refinery.store.tuple.Tuple; 9import tools.refinery.store.tuple.Tuple;
20 10
21import java.util.Set; 11import java.util.*;
12import java.util.Map.Entry;
22 13
23public class ModelStoreImpl implements ModelStore { 14public class ModelStoreImpl implements ModelStore {
24 15
@@ -38,7 +29,7 @@ public class ModelStoreImpl implements ModelStore {
38 if (dataRepresentation instanceof Relation<?> symbolRepresentation) { 29 if (dataRepresentation instanceof Relation<?> symbolRepresentation) {
39 addOrCreate(symbolRepresentationsPerHashPerArity, 30 addOrCreate(symbolRepresentationsPerHashPerArity,
40 new SimilarRelationEquivalenceClass(symbolRepresentation), symbolRepresentation); 31 new SimilarRelationEquivalenceClass(symbolRepresentation), symbolRepresentation);
41 } else if (dataRepresentation instanceof AuxilaryData<?, ?>) { 32 } else if (dataRepresentation instanceof AuxiliaryData<?, ?>) {
42 VersionedMapStoreImpl<?, ?> store = new VersionedMapStoreImpl<>(dataRepresentation.getHashProvider(), 33 VersionedMapStoreImpl<?, ?> store = new VersionedMapStoreImpl<>(dataRepresentation.getHashProvider(),
43 dataRepresentation.getDefaultValue()); 34 dataRepresentation.getDefaultValue());
44 result.put(dataRepresentation, store); 35 result.put(dataRepresentation, store);
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/RelationLike.java b/subprojects/store/src/main/java/tools/refinery/store/model/RelationLike.java
new file mode 100644
index 00000000..6a5fdcd5
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/RelationLike.java
@@ -0,0 +1,7 @@
1package tools.refinery.store.model;
2
3public interface RelationLike {
4 String getName();
5
6 int getArity();
7}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxilaryData.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxilaryData.java
deleted file mode 100644
index ddd8a5f2..00000000
--- a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxilaryData.java
+++ /dev/null
@@ -1,22 +0,0 @@
1package tools.refinery.store.model.representation;
2
3import tools.refinery.store.map.ContinousHashProvider;
4
5public class AuxilaryData<K,V> extends DataRepresentation<K, V> {
6 private final String name;
7
8 public AuxilaryData(String name, ContinousHashProvider<K> hashProvider, V defaultValue) {
9 super(hashProvider, defaultValue);
10 this.name = name;
11 }
12
13 @Override
14 public String getName() {
15 return name;
16 }
17
18 @Override
19 public boolean isValidKey(K key) {
20 return true;
21 }
22}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java
new file mode 100644
index 00000000..1a968f50
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/AuxiliaryData.java
@@ -0,0 +1,22 @@
1package tools.refinery.store.model.representation;
2
3import tools.refinery.store.map.ContinousHashProvider;
4
5public final class AuxiliaryData<K, V> extends DataRepresentation<K, V> {
6 private final ContinousHashProvider<K> hashProvider;
7
8 public AuxiliaryData(String name, ContinousHashProvider<K> hashProvider, V defaultValue) {
9 super(name, defaultValue);
10 this.hashProvider = hashProvider;
11 }
12
13 @Override
14 public ContinousHashProvider<K> getHashProvider() {
15 return hashProvider;
16 }
17
18 @Override
19 public boolean isValidKey(K key) {
20 return true;
21 }
22}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java
index 585e7b88..49f74717 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/DataRepresentation.java
@@ -2,20 +2,22 @@ package tools.refinery.store.model.representation;
2 2
3import tools.refinery.store.map.ContinousHashProvider; 3import tools.refinery.store.map.ContinousHashProvider;
4 4
5public abstract class DataRepresentation<K, V> { 5public abstract sealed class DataRepresentation<K, V> permits Relation, AuxiliaryData {
6 protected final ContinousHashProvider<K> hashProvider; 6 private final String name;
7 protected final V defaultValue;
8 7
9 protected DataRepresentation(ContinousHashProvider<K> hashProvider, V defaultValue) { 8 private final V defaultValue;
10 this.hashProvider = hashProvider; 9
10 protected DataRepresentation(String name, V defaultValue) {
11 this.name = name;
11 this.defaultValue = defaultValue; 12 this.defaultValue = defaultValue;
12 } 13 }
13 14
14 public abstract String getName(); 15 public String getName() {
15 16 return name;
16 public ContinousHashProvider<K> getHashProvider() {
17 return hashProvider;
18 } 17 }
18
19 public abstract ContinousHashProvider<K> getHashProvider();
20
19 public abstract boolean isValidKey(K key); 21 public abstract boolean isValidKey(K key);
20 22
21 public V getDefaultValue() { 23 public V getDefaultValue() {
diff --git a/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java b/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
index c0f31d08..2e21ea37 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/model/representation/Relation.java
@@ -1,31 +1,34 @@
1package tools.refinery.store.model.representation; 1package tools.refinery.store.model.representation;
2 2
3import tools.refinery.store.map.ContinousHashProvider;
4import tools.refinery.store.model.RelationLike;
3import tools.refinery.store.tuple.Tuple; 5import tools.refinery.store.tuple.Tuple;
4import tools.refinery.store.model.TupleHashProvider; 6import tools.refinery.store.model.TupleHashProvider;
5 7
6public class Relation<D> extends DataRepresentation<Tuple, D> { 8public final class Relation<D> extends DataRepresentation<Tuple, D> implements RelationLike {
7 private final String name;
8 private final int arity; 9 private final int arity;
9 10
10 public Relation(String name, int arity, D defaultValue) { 11 public Relation(String name, int arity, D defaultValue) {
11 super(TupleHashProvider.singleton(), defaultValue); 12 super(name, defaultValue);
12 this.name = name;
13 this.arity = arity; 13 this.arity = arity;
14 } 14 }
15 15
16 @Override 16 @Override
17 public String getName() {
18 return name;
19 }
20
21 public int getArity() { 17 public int getArity() {
22 return arity; 18 return arity;
23 } 19 }
24 20
25 @Override 21 @Override
22 public ContinousHashProvider<Tuple> getHashProvider() {
23 return TupleHashProvider.singleton();
24 }
25
26 @Override
26 public boolean isValidKey(Tuple key) { 27 public boolean isValidKey(Tuple key) {
27 if(key == null) { 28 if (key == null) {
28 return false; 29 return false;
29 } else return key.getSize() == getArity(); 30 } else {
31 return key.getSize() == getArity();
32 }
30 } 33 }
31} 34}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/DNF.java b/subprojects/store/src/main/java/tools/refinery/store/query/DNF.java
new file mode 100644
index 00000000..7d4b3091
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/DNF.java
@@ -0,0 +1,121 @@
1package tools.refinery.store.query;
2
3import tools.refinery.store.model.RelationLike;
4import tools.refinery.store.query.atom.DNFAtom;
5
6import java.util.*;
7
8public class DNF implements RelationLike {
9 private final String name;
10
11 private final String uniqueName;
12
13 private final List<Variable> parameters;
14
15 private final List<DNFAnd> clauses;
16
17 private DNF(String name, List<Variable> parameters, List<DNFAnd> clauses) {
18 this.name = name;
19 this.uniqueName = DNFUtils.generateUniqueName(name);
20 this.parameters = parameters;
21 this.clauses = clauses;
22 }
23
24 @Override
25 public String getName() {
26 return name;
27 }
28
29 public String getUniqueName() {
30 return uniqueName;
31 }
32
33 public List<Variable> getParameters() {
34 return parameters;
35 }
36
37 @Override
38 public int getArity() {
39 return parameters.size();
40 }
41
42 public List<DNFAnd> getClauses() {
43 return clauses;
44 }
45
46 public static Builder builder() {
47 return builder(null);
48 }
49
50 public static Builder builder(String name) {
51 return new Builder(name);
52 }
53
54 @SuppressWarnings("UnusedReturnValue")
55 public static class Builder {
56 private final String name;
57
58 private final List<Variable> parameters = new ArrayList<>();
59
60 private final List<List<DNFAtom>> clauses = new ArrayList<>();
61
62 private Builder(String name) {
63 this.name = name;
64 }
65
66 public Builder parameter(Variable variable) {
67 this.parameters.add(variable);
68 return this;
69 }
70
71 public Builder parameters(Variable... variables) {
72 return parameters(List.of(variables));
73 }
74
75 public Builder parameters(Collection<Variable> variables) {
76 this.parameters.addAll(variables);
77 return this;
78 }
79
80 public Builder clause(DNFAtom... atoms) {
81 clauses.add(List.of(atoms));
82 return this;
83 }
84
85 public Builder clause(Collection<DNFAtom> atoms) {
86 clauses.add(List.copyOf(atoms));
87 return this;
88 }
89
90 public Builder clause(DNFAnd clause) {
91 return clause(clause.constraints());
92 }
93
94 public Builder clauses(DNFAnd... clauses) {
95 for (var clause : clauses) {
96 this.clause(clause);
97 }
98 return this;
99 }
100
101 public Builder clauses(Collection<DNFAnd> clauses) {
102 for (var clause : clauses) {
103 this.clause(clause);
104 }
105 return this;
106 }
107
108 public DNF build() {
109 var postProcessedClauses = new ArrayList<DNFAnd>();
110 for (var constraints : clauses) {
111 var variables = new HashSet<Variable>();
112 for (var constraint : constraints) {
113 constraint.collectAllVariables(variables);
114 }
115 parameters.forEach(variables::remove);
116 postProcessedClauses.add(new DNFAnd(variables, constraints));
117 }
118 return new DNF(name, List.copyOf(parameters), postProcessedClauses);
119 }
120 }
121}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/DNFAnd.java b/subprojects/store/src/main/java/tools/refinery/store/query/DNFAnd.java
new file mode 100644
index 00000000..8c3bf05d
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/DNFAnd.java
@@ -0,0 +1,9 @@
1package tools.refinery.store.query;
2
3import tools.refinery.store.query.atom.DNFAtom;
4
5import java.util.List;
6import java.util.Set;
7
8public record DNFAnd(Set<Variable> quantifiedVariables, List<DNFAtom> constraints) {
9}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/DNFUtils.java b/subprojects/store/src/main/java/tools/refinery/store/query/DNFUtils.java
new file mode 100644
index 00000000..0ef77d49
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/DNFUtils.java
@@ -0,0 +1,19 @@
1package tools.refinery.store.query;
2
3import java.util.UUID;
4
5public final class DNFUtils {
6 private DNFUtils() {
7 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
8 }
9
10 public static String generateUniqueName(String originalName) {
11 UUID uuid = UUID.randomUUID();
12 String uniqueString = "_" + uuid.toString().replace('-', '_');
13 if (originalName == null) {
14 return uniqueString;
15 } else {
16 return originalName + uniqueString;
17 }
18 }
19}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java
index 648c3a36..9655d1a1 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java
@@ -1,7 +1,6 @@
1package tools.refinery.store.query; 1package tools.refinery.store.query;
2 2
3import tools.refinery.store.model.Model; 3import tools.refinery.store.model.Model;
4import tools.refinery.store.query.building.DNFPredicate;
5import tools.refinery.store.tuple.Tuple; 4import tools.refinery.store.tuple.Tuple;
6import tools.refinery.store.tuple.TupleLike; 5import tools.refinery.store.tuple.TupleLike;
7 6
@@ -10,25 +9,25 @@ import java.util.Set;
10import java.util.stream.Stream; 9import java.util.stream.Stream;
11 10
12public interface QueryableModel extends Model { 11public interface QueryableModel extends Model {
13 Set<DNFPredicate> getPredicates(); 12 Set<DNF> getPredicates();
14 13
15 boolean hasChanges(); 14 boolean hasChanges();
16 15
17 void flushChanges(); 16 void flushChanges();
18 17
19 boolean hasResult(DNFPredicate predicate); 18 boolean hasResult(DNF predicate);
20 19
21 boolean hasResult(DNFPredicate predicate, Tuple parameters); 20 boolean hasResult(DNF predicate, Tuple parameters);
22 21
23 Optional<TupleLike> oneResult(DNFPredicate predicate); 22 Optional<TupleLike> oneResult(DNF predicate);
24 23
25 Optional<TupleLike> oneResult(DNFPredicate predicate, Tuple parameters); 24 Optional<TupleLike> oneResult(DNF predicate, Tuple parameters);
26 25
27 Stream<TupleLike> allResults(DNFPredicate predicate); 26 Stream<TupleLike> allResults(DNF predicate);
28 27
29 Stream<TupleLike> allResults(DNFPredicate predicate, Tuple parameters); 28 Stream<TupleLike> allResults(DNF predicate, Tuple parameters);
30 29
31 int countResults(DNFPredicate predicate); 30 int countResults(DNF predicate);
32 31
33 int countResults(DNFPredicate predicate, Tuple parameters); 32 int countResults(DNF predicate, Tuple parameters);
34} 33}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
index 878e1058..41f47e64 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
@@ -2,7 +2,6 @@ package tools.refinery.store.query;
2 2
3import tools.refinery.store.model.ModelStore; 3import tools.refinery.store.model.ModelStore;
4import tools.refinery.store.model.representation.DataRepresentation; 4import tools.refinery.store.model.representation.DataRepresentation;
5import tools.refinery.store.query.building.DNFPredicate;
6import tools.refinery.store.query.view.RelationView; 5import tools.refinery.store.query.view.RelationView;
7 6
8import java.util.Set; 7import java.util.Set;
@@ -14,7 +13,7 @@ public interface QueryableModelStore extends ModelStore {
14 @SuppressWarnings("squid:S1452") 13 @SuppressWarnings("squid:S1452")
15 Set<RelationView<?>> getViews(); 14 Set<RelationView<?>> getViews();
16 15
17 Set<DNFPredicate> getPredicates(); 16 Set<DNF> getPredicates();
18 17
19 QueryableModel createModel(); 18 QueryableModel createModel();
20 19
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/Variable.java b/subprojects/store/src/main/java/tools/refinery/store/query/Variable.java
new file mode 100644
index 00000000..3632f3c5
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/Variable.java
@@ -0,0 +1,43 @@
1package tools.refinery.store.query;
2
3import java.util.Objects;
4
5public class Variable {
6 private final String name;
7 private final String uniqueName;
8
9 public Variable() {
10 this(null);
11 }
12
13 public Variable(String name) {
14 super();
15 this.name = name;
16 this.uniqueName = DNFUtils.generateUniqueName(name);
17
18 }
19 public String getName() {
20 return name;
21 }
22
23 public String getUniqueName() {
24 return uniqueName;
25 }
26
27 public boolean isNamed() {
28 return name != null;
29 }
30
31 @Override
32 public boolean equals(Object o) {
33 if (this == o) return true;
34 if (o == null || getClass() != o.getClass()) return false;
35 Variable variable = (Variable) o;
36 return Objects.equals(uniqueName, variable.uniqueName);
37 }
38
39 @Override
40 public int hashCode() {
41 return Objects.hash(uniqueName);
42 }
43}
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
new file mode 100644
index 00000000..fb8d7432
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/AbstractCallAtom.java
@@ -0,0 +1,30 @@
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/AbstractSubstitutionAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/AbstractSubstitutionAtom.java
new file mode 100644
index 00000000..e8a8b5e1
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/AbstractSubstitutionAtom.java
@@ -0,0 +1,35 @@
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 AbstractSubstitutionAtom<T extends RelationLike> implements DNFAtom {
10 private final T target;
11
12 private final List<Variable> substitution;
13
14 protected AbstractSubstitutionAtom(T target, List<Variable> substitution) {
15 if (substitution.size() != target.getArity()) {
16 throw new IllegalArgumentException("%s needs %d arguments, but got %s".formatted(target.getName(),
17 target.getArity(), substitution.size()));
18 }
19 this.target = target;
20 this.substitution = substitution;
21 }
22
23 public T getTarget() {
24 return target;
25 }
26
27 public List<Variable> getSubstitution() {
28 return substitution;
29 }
30
31 @Override
32 public void collectAllVariables(Set<Variable> variables) {
33 variables.addAll(substitution);
34 }
35}
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
new file mode 100644
index 00000000..c7cbc955
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/CallKind.java
@@ -0,0 +1,24 @@
1package tools.refinery.store.query.atom;
2
3public enum 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 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 }
24}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/atom/DNFAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/DNFAtom.java
new file mode 100644
index 00000000..ebf71236
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/DNFAtom.java
@@ -0,0 +1,9 @@
1package tools.refinery.store.query.atom;
2
3import tools.refinery.store.query.Variable;
4
5import java.util.Set;
6
7public interface DNFAtom {
8 void collectAllVariables(Set<Variable> variables);
9}
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
new file mode 100644
index 00000000..9d2efa53
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/DNFCallAtom.java
@@ -0,0 +1,40 @@
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/EquivalenceAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/EquivalenceAtom.java
new file mode 100644
index 00000000..b1b3a6f7
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/EquivalenceAtom.java
@@ -0,0 +1,17 @@
1package tools.refinery.store.query.atom;
2
3import tools.refinery.store.query.Variable;
4
5import java.util.Set;
6
7public record EquivalenceAtom(boolean positive, Variable left, Variable right) implements DNFAtom {
8 public EquivalenceAtom(Variable left, Variable right) {
9 this(true, left, right);
10 }
11
12 @Override
13 public void collectAllVariables(Set<Variable> variables) {
14 variables.add(left);
15 variables.add(right);
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
new file mode 100644
index 00000000..2480e82e
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/ModalRelationAtom.java
@@ -0,0 +1,38 @@
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
new file mode 100644
index 00000000..9344a9d3
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/Modality.java
@@ -0,0 +1,7 @@
1package tools.refinery.store.query.atom;
2
3public enum Modality {
4 MUST,
5 MAY,
6 CURRENT;
7}
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
new file mode 100644
index 00000000..06098139
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationAtom.java
@@ -0,0 +1,32 @@
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/main/java/tools/refinery/store/query/atom/RelationViewAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java
new file mode 100644
index 00000000..762a41f1
--- /dev/null
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/atom/RelationViewAtom.java
@@ -0,0 +1,31 @@
1package tools.refinery.store.query.atom;
2
3import tools.refinery.store.query.Variable;
4import tools.refinery.store.query.view.RelationView;
5
6import java.util.List;
7import java.util.Objects;
8
9public final class RelationViewAtom extends AbstractSubstitutionAtom<RelationView<?>> {
10 public RelationViewAtom(RelationView<?> target, List<Variable> substitution) {
11 super(target, substitution);
12 }
13
14 public RelationViewAtom(RelationView<?> target, Variable... substitution) {
15 this(target, List.of(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 RelationViewAtom relationViewAtom = (RelationViewAtom) o;
23 return Objects.equals(getTarget(), relationViewAtom.getTarget())
24 && Objects.equals(getSubstitution(), relationViewAtom.getSubstitution());
25 }
26
27 @Override
28 public int hashCode() {
29 return Objects.hash(getTarget(), getSubstitution());
30 }
31}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/building/DNFAnd.java b/subprojects/store/src/main/java/tools/refinery/store/query/building/DNFAnd.java
deleted file mode 100644
index 48dabce2..00000000
--- a/subprojects/store/src/main/java/tools/refinery/store/query/building/DNFAnd.java
+++ /dev/null
@@ -1,37 +0,0 @@
1package tools.refinery.store.query.building;
2
3import java.util.HashMap;
4import java.util.HashSet;
5import java.util.List;
6import java.util.Map;
7import java.util.Set;
8
9public class DNFAnd {
10 private Set<Variable> existentiallyQuantified;
11 private List<DNFAtom> constraints;
12 public DNFAnd(Set<Variable> quantifiedVariables, List<DNFAtom> constraints) {
13 super();
14 this.existentiallyQuantified = quantifiedVariables;
15 this.constraints = constraints;
16 }
17 public Set<Variable> getExistentiallyQuantified() {
18 return existentiallyQuantified;
19 }
20 public List<DNFAtom> getConstraints() {
21 return constraints;
22 }
23 void unifyVariables(Map<String,Variable> uniqueVariableMap) {
24 Map<String,Variable> uniqueVariableMapForClause = new HashMap<>(uniqueVariableMap);
25 for(DNFAtom atom : constraints) {
26 atom.unifyVariables(uniqueVariableMapForClause);
27 }
28 }
29 void collectQuantifiedVariables(Set<Variable> parameters) {
30 Set<Variable> result = new HashSet<>();
31 for(DNFAtom constraint : constraints) {
32 constraint.collectAllVariables(result);
33 }
34 result.removeAll(parameters);
35 existentiallyQuantified = result;
36 }
37}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/building/DNFAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/building/DNFAtom.java
deleted file mode 100644
index b047d7c8..00000000
--- a/subprojects/store/src/main/java/tools/refinery/store/query/building/DNFAtom.java
+++ /dev/null
@@ -1,33 +0,0 @@
1package tools.refinery.store.query.building;
2
3import java.util.Collection;
4import java.util.Iterator;
5import java.util.Map;
6import java.util.Set;
7
8public interface DNFAtom {
9 void unifyVariables(Map<String,Variable> variables);
10 static Variable unifyVariables(Map<String,Variable> unifiedVariables, Variable variable) {
11 if(variable != null) {
12 if(variable.isNamed() && unifiedVariables.containsKey(variable.getName())) {
13 return unifiedVariables.get(variable.getName());
14 }
15 return variable;
16 } else {
17 return null;
18 }
19 }
20 void collectAllVariables(Set<Variable> variables);
21 static void addToCollection(Set<Variable> variables, Variable variable) {
22 if(variable != null) {
23 variables.add(variable);
24 }
25 }
26 static void addToCollection(Set<Variable> variables, Collection<Variable> variableCollection) {
27 Iterator<Variable> iterator = variableCollection.iterator();
28 while(iterator.hasNext()) {
29 Variable variable = iterator.next();
30 addToCollection(variables, variable);
31 }
32 }
33}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/building/DNFPredicate.java b/subprojects/store/src/main/java/tools/refinery/store/query/building/DNFPredicate.java
deleted file mode 100644
index f0c9ac42..00000000
--- a/subprojects/store/src/main/java/tools/refinery/store/query/building/DNFPredicate.java
+++ /dev/null
@@ -1,72 +0,0 @@
1package tools.refinery.store.query.building;
2
3import java.util.HashMap;
4import java.util.HashSet;
5import java.util.List;
6import java.util.Map;
7import java.util.UUID;
8
9public class DNFPredicate {
10 private final String name;
11 private final String uniqueName;
12 private final List<Variable> parameters;
13 private final List<DNFAnd> clauses;
14
15 public DNFPredicate(String name, List<Variable> parameters, List<DNFAnd> clauses) {
16 this.name = name;
17 this.uniqueName = generateUniqueName(name,"predicate");
18 this.parameters = parameters;
19 this.clauses = clauses;
20
21 postProcess();
22 }
23
24 public static String generateUniqueName(String originalName, String defaultPrefix) {
25 UUID uuid = UUID.randomUUID();
26 String uniqueString = uuid.toString().replace('-', '_');
27 if(originalName == null) {
28 return defaultPrefix+uniqueString;
29 } else {
30 return originalName+uniqueString;
31 }
32 }
33
34 public String getName() {
35 return name;
36 }
37 public String getUniqueName() {
38 return uniqueName;
39 }
40 public List<Variable> getVariables() {
41 return parameters;
42 }
43 public List<DNFAnd> getClauses() {
44 return clauses;
45 }
46
47 public void unifyVariables() {
48 Map<String,Variable> uniqueVariableMap = new HashMap<>();
49 for(Variable parameter : this.parameters) {
50 if(parameter.isNamed()) {
51 String parameterName = parameter.getName();
52 if(uniqueVariableMap.containsKey(parameterName)) {
53 throw new IllegalArgumentException("Multiple parameters has the name "+parameterName);
54 } else {
55 uniqueVariableMap.put(parameterName, parameter);
56 }
57 }
58 }
59 for(DNFAnd clause : this.clauses) {
60 clause.unifyVariables(uniqueVariableMap);
61 }
62 }
63 public void collectQuantifiedVariables() {
64 for(DNFAnd clause : this.clauses) {
65 clause.collectQuantifiedVariables(new HashSet<>(parameters));
66 }
67 }
68 public void postProcess() {
69 unifyVariables();
70 collectQuantifiedVariables();
71 }
72}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/building/EquivalenceAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/building/EquivalenceAtom.java
deleted file mode 100644
index fede2518..00000000
--- a/subprojects/store/src/main/java/tools/refinery/store/query/building/EquivalenceAtom.java
+++ /dev/null
@@ -1,44 +0,0 @@
1package tools.refinery.store.query.building;
2
3import java.util.Map;
4import java.util.Set;
5
6public class EquivalenceAtom implements DNFAtom{
7 private boolean positive;
8 private Variable left;
9 private Variable right;
10 public EquivalenceAtom(boolean positive, Variable left, Variable right) {
11 this.positive = positive;
12 this.left = left;
13 this.right = right;
14 }
15 public boolean isPositive() {
16 return positive;
17 }
18 public void setPositive(boolean positive) {
19 this.positive = positive;
20 }
21 public Variable getLeft() {
22 return left;
23 }
24 public void setLeft(Variable left) {
25 this.left = left;
26 }
27 public Variable getRight() {
28 return right;
29 }
30 public void setRight(Variable right) {
31 this.right = right;
32 }
33
34 @Override
35 public void unifyVariables(Map<String, Variable> variables) {
36 this.left = DNFAtom.unifyVariables(variables,left);
37 this.right = DNFAtom.unifyVariables(variables,right);
38 }
39 @Override
40 public void collectAllVariables(Set<Variable> variables) {
41 DNFAtom.addToCollection(variables, left);
42 DNFAtom.addToCollection(variables, right);
43 }
44}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/building/PredicateAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/building/PredicateAtom.java
deleted file mode 100644
index 42394922..00000000
--- a/subprojects/store/src/main/java/tools/refinery/store/query/building/PredicateAtom.java
+++ /dev/null
@@ -1,66 +0,0 @@
1package tools.refinery.store.query.building;
2
3import java.util.List;
4import java.util.Map;
5import java.util.Set;
6
7public class PredicateAtom implements DNFAtom {
8 private DNFPredicate referred;
9 private List<Variable> substitution;
10 private boolean positive;
11 private boolean transitive;
12
13 public PredicateAtom(boolean positive, boolean transitive, DNFPredicate referred, List<Variable> substitution) {
14 this.positive = positive;
15 this.referred = referred;
16 this.substitution = substitution;
17 this.transitive = transitive;
18 }
19
20 public DNFPredicate getReferred() {
21 return referred;
22 }
23
24 public void setReferred(DNFPredicate referred) {
25 this.referred = referred;
26 }
27
28 public List<Variable> getSubstitution() {
29 return substitution;
30 }
31
32 public void setSubstitution(List<Variable> substitution) {
33 this.substitution = substitution;
34 }
35
36 public boolean isPositive() {
37 return positive;
38 }
39
40 public void setPositive(boolean positive) {
41 this.positive = positive;
42 }
43
44 public boolean isTransitive() {
45 return transitive;
46 }
47
48 public void setTransitive(boolean transitive) {
49 this.transitive = transitive;
50 }
51
52 @Override
53 public void unifyVariables(Map<String, Variable> variables) {
54 for (int i = 0; i < this.substitution.size(); i++) {
55 final Object term = this.substitution.get(i);
56 if (term instanceof Variable variableReference) {
57 this.substitution.set(i, DNFAtom.unifyVariables(variables, variableReference));
58 }
59 }
60 }
61
62 @Override
63 public void collectAllVariables(Set<Variable> variables) {
64 DNFAtom.addToCollection(variables, substitution);
65 }
66}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/building/RelationAtom.java b/subprojects/store/src/main/java/tools/refinery/store/query/building/RelationAtom.java
deleted file mode 100644
index f66245fc..00000000
--- a/subprojects/store/src/main/java/tools/refinery/store/query/building/RelationAtom.java
+++ /dev/null
@@ -1,31 +0,0 @@
1package tools.refinery.store.query.building;
2
3import tools.refinery.store.query.view.RelationView;
4
5import java.util.ArrayList;
6import java.util.List;
7import java.util.Map;
8import java.util.Set;
9
10public record RelationAtom(RelationView<?> view, List<Variable> substitution) implements DNFAtom {
11 public RelationAtom(RelationView<?> view, List<Variable> substitution) {
12 this.view = view;
13 // Create a mutable copy of substitution so that unifyVariables can change it.
14 this.substitution = new ArrayList<>(substitution);
15 }
16
17 @Override
18 public void unifyVariables(Map<String, Variable> variables) {
19 for (int i = 0; i < this.substitution.size(); i++) {
20 final Object term = this.substitution.get(i);
21 if (term instanceof Variable variableReference) {
22 this.substitution.set(i, DNFAtom.unifyVariables(variables, variableReference));
23 }
24 }
25 }
26
27 @Override
28 public void collectAllVariables(Set<Variable> variables) {
29 DNFAtom.addToCollection(variables, substitution);
30 }
31}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/building/Variable.java b/subprojects/store/src/main/java/tools/refinery/store/query/building/Variable.java
deleted file mode 100644
index 9ea7ce83..00000000
--- a/subprojects/store/src/main/java/tools/refinery/store/query/building/Variable.java
+++ /dev/null
@@ -1,22 +0,0 @@
1package tools.refinery.store.query.building;
2
3public class Variable {
4 private final String name;
5 private final String uniqueName;
6
7 public Variable(String name) {
8 super();
9 this.name = name;
10 this.uniqueName = DNFPredicate.generateUniqueName(name, "variable");
11
12 }
13 public String getName() {
14 return name;
15 }
16 public String getUniqueName() {
17 return uniqueName;
18 }
19 public boolean isNamed() {
20 return name != null;
21 }
22}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
index ceaf7d55..96f8584a 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java
@@ -2,6 +2,7 @@ package tools.refinery.store.query.view;
2 2
3import tools.refinery.store.map.CursorAsIterator; 3import tools.refinery.store.map.CursorAsIterator;
4import tools.refinery.store.model.Model; 4import tools.refinery.store.model.Model;
5import tools.refinery.store.model.RelationLike;
5import tools.refinery.store.tuple.Tuple; 6import tools.refinery.store.tuple.Tuple;
6import tools.refinery.store.model.representation.Relation; 7import tools.refinery.store.model.representation.Relation;
7 8
@@ -14,7 +15,7 @@ import java.util.UUID;
14 * @param <D> 15 * @param <D>
15 * @author Oszkar Semerath 16 * @author Oszkar Semerath
16 */ 17 */
17public abstract class RelationView<D> { 18public abstract class RelationView<D> implements RelationLike {
18 private final Relation<D> representation; 19 private final Relation<D> representation;
19 20
20 private final String name; 21 private final String name;
@@ -28,12 +29,11 @@ public abstract class RelationView<D> {
28 this(representation, UUID.randomUUID().toString()); 29 this(representation, UUID.randomUUID().toString());
29 } 30 }
30 31
31 public abstract int getArity();
32
33 public Relation<D> getRepresentation() { 32 public Relation<D> getRepresentation() {
34 return representation; 33 return representation;
35 } 34 }
36 35
36 @Override
37 public String getName() { 37 public String getName() {
38 return representation.getName() + "#" + name; 38 return representation.getName() + "#" + name;
39 } 39 }