aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-09-26 00:39:23 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-10-03 20:06:52 +0200
commitaac386f0d8c4e4585026b11bfeca20f378f7f261 (patch)
treecad56fc2c88a1abd56258d64b5ce3a16baaff011
parentchore: fix some warnings (diff)
downloadrefinery-aac386f0d8c4e4585026b11bfeca20f378f7f261.tar.gz
refinery-aac386f0d8c4e4585026b11bfeca20f378f7f261.tar.zst
refinery-aac386f0d8c4e4585026b11bfeca20f378f7f261.zip
refactor: move viatra into a separate subproject
-rw-r--r--settings.gradle1
-rw-r--r--subprojects/store-query-viatra/build.gradle16
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStoreImpl.java)69
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RawPatternMatcher.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/internal/RawPatternMatcher.java)38
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalScope.java)26
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/internal/QueriableModelImpl.java)107
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/DummyBaseIndexer.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/internal/DummyBaseIndexer.java)13
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalEngineContext.java)8
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java44
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalRuntimeContext.java)78
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java)119
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/SimplePQuery.java74
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/internal/ModelUpdateListener.java)54
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdate.java)4
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateBuffer.java)28
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateTranslator.java)33
-rw-r--r--subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java (renamed from subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTest.java)223
-rw-r--r--subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java (renamed from subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTransactionTest.java)40
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/QueriableModel.java)12
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java (renamed from subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStore.java)14
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/building/RelationAtom.java30
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/internal/PredicateResult.java24
-rw-r--r--subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalQueryMetaContext.java58
23 files changed, 533 insertions, 580 deletions
diff --git a/settings.gradle b/settings.gradle
index 36721f4b..3149380d 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -7,6 +7,7 @@ include 'language-model'
7include 'language-semantics' 7include 'language-semantics'
8include 'language-web' 8include 'language-web'
9include 'store' 9include 'store'
10include 'store-query-viatra'
10 11
11for (project in rootProject.children) { 12for (project in rootProject.children) {
12 def projectName = project.name 13 def projectName = project.name
diff --git a/subprojects/store-query-viatra/build.gradle b/subprojects/store-query-viatra/build.gradle
new file mode 100644
index 00000000..32a23fe7
--- /dev/null
+++ b/subprojects/store-query-viatra/build.gradle
@@ -0,0 +1,16 @@
1plugins {
2 id 'refinery-java-library'
3}
4
5configurations.testRuntimeClasspath {
6 // VIATRA requires log4j 1.x, but we use log4j-over-slf4j instead
7 exclude group: 'log4j', module: 'log4j'
8}
9
10dependencies {
11 implementation libs.ecore
12 implementation libs.viatra
13 api project(':refinery-store')
14 testImplementation libs.slf4j.simple
15 testImplementation libs.slf4j.log4j
16}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStoreImpl.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java
index 653783dd..5a02ca08 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStoreImpl.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java
@@ -1,48 +1,49 @@
1package tools.refinery.store.query; 1package tools.refinery.store.query.viatra;
2
3import java.util.Collections;
4import java.util.HashMap;
5import java.util.Map;
6import java.util.Set;
7 2
8import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; 3import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification;
9
10import tools.refinery.store.model.ModelDiffCursor; 4import tools.refinery.store.model.ModelDiffCursor;
11import tools.refinery.store.model.ModelStore; 5import tools.refinery.store.model.ModelStore;
12import tools.refinery.store.model.ModelStoreImpl; 6import tools.refinery.store.model.ModelStoreImpl;
13import tools.refinery.store.model.representation.DataRepresentation; 7import tools.refinery.store.model.representation.DataRepresentation;
14import tools.refinery.store.query.building.DNFAnd; 8import tools.refinery.store.query.QueryableModel;
15import tools.refinery.store.query.building.DNFAtom; 9import tools.refinery.store.query.QueryableModelStore;
16import tools.refinery.store.query.building.DNFPredicate; 10import tools.refinery.store.query.building.*;
17import tools.refinery.store.query.building.PredicateAtom; 11import tools.refinery.store.query.viatra.internal.ViatraQueryableModel;
18import tools.refinery.store.query.building.RelationAtom; 12import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery;
19import tools.refinery.store.query.internal.DNF2PQuery; 13import tools.refinery.store.query.viatra.internal.RawPatternMatcher;
20import tools.refinery.store.query.internal.QueriableModelImpl; 14import tools.refinery.store.query.viatra.internal.pquery.SimplePQuery;
21import tools.refinery.store.query.internal.RawPatternMatcher;
22import tools.refinery.store.query.internal.DNF2PQuery.SimplePQuery;
23import tools.refinery.store.query.view.RelationView; 15import tools.refinery.store.query.view.RelationView;
24 16
25public class QueriableModelStoreImpl implements QueriableModelStore { 17import java.util.Collections;
18import java.util.HashMap;
19import java.util.Map;
20import java.util.Set;
21
22public class ViatraQueryableModelStore implements QueryableModelStore {
26 protected final ModelStore store; 23 protected final ModelStore store;
27 protected final Set<RelationView<?>> relationViews; 24 protected final Set<RelationView<?>> relationViews;
28 protected final Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates; 25 protected final Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates;
29 26
30 public QueriableModelStoreImpl(Set<DataRepresentation<?, ?>> dataRepresentations, 27 public ViatraQueryableModelStore(ModelStore store, Set<RelationView<?>> relationViews,
31 Set<RelationView<?>> relationViews, Set<DNFPredicate> predicates) { 28 Set<DNFPredicate> predicates) {
32 this.store = new ModelStoreImpl(dataRepresentations); 29 this.store = store;
33 validateViews(dataRepresentations, relationViews); 30 validateViews(store.getDataRepresentations(), relationViews);
34 this.relationViews = Collections.unmodifiableSet(relationViews); 31 this.relationViews = Collections.unmodifiableSet(relationViews);
35 validatePredicates(relationViews, predicates); 32 validatePredicates(relationViews, predicates);
36 this.predicates = initPredicates(predicates); 33 this.predicates = initPredicates(predicates);
37 } 34 }
38 35
36 public ViatraQueryableModelStore(Set<DataRepresentation<?, ?>> dataRepresentations,
37 Set<RelationView<?>> relationViews, Set<DNFPredicate> predicates) {
38 this(new ModelStoreImpl(dataRepresentations), relationViews, predicates);
39 }
40
39 private void validateViews(Set<DataRepresentation<?, ?>> dataRepresentations, Set<RelationView<?>> relationViews) { 41 private void validateViews(Set<DataRepresentation<?, ?>> dataRepresentations, Set<RelationView<?>> relationViews) {
40 for (RelationView<?> relationView : relationViews) { 42 for (RelationView<?> relationView : relationViews) {
41 // TODO: make it work for non-relation representation?
42 if (!dataRepresentations.contains(relationView.getRepresentation())) { 43 if (!dataRepresentations.contains(relationView.getRepresentation())) {
43 throw new IllegalArgumentException( 44 throw new IllegalArgumentException(
44 DataRepresentation.class.getSimpleName() + " " + relationView.getStringID() + " added to " 45 DataRepresentation.class.getSimpleName() + " " + relationView.getStringID() + " added to "
45 + QueriableModelStore.class.getSimpleName() + " without a referred representation."); 46 + QueryableModelStore.class.getSimpleName() + " without a referred representation.");
46 } 47 }
47 } 48 }
48 } 49 }
@@ -62,16 +63,17 @@ public class QueriableModelStoreImpl implements QueriableModelStore {
62 } 63 }
63 64
64 private void validateRelationAtom(Set<RelationView<?>> relationViews, DNFPredicate dnfPredicate, 65 private void validateRelationAtom(Set<RelationView<?>> relationViews, DNFPredicate dnfPredicate,
65 RelationAtom relationAtom) { 66 RelationAtom relationAtom) {
66 if (!relationViews.contains(relationAtom.getView())) { 67 if (!relationViews.contains(relationAtom.view())) {
67 throw new IllegalArgumentException(DNFPredicate.class.getSimpleName() + " " 68 throw new IllegalArgumentException(DNFPredicate.class.getSimpleName() + " "
68 + dnfPredicate.getUniqueName() + " contains reference to a view of " 69 + dnfPredicate.getUniqueName() + " contains reference to a view of "
69 + relationAtom.getView().getRepresentation().getName() 70 + relationAtom.view().getRepresentation().getName()
70 + " that is not in the model."); 71 + " that is not in the model.");
71 } 72 }
72 } 73 }
74
73 private void validatePredicateAtom(Set<DNFPredicate> predicates, DNFPredicate dnfPredicate, 75 private void validatePredicateAtom(Set<DNFPredicate> predicates, DNFPredicate dnfPredicate,
74 PredicateAtom predicateAtom) { 76 PredicateAtom predicateAtom) {
75 if (!predicates.contains(predicateAtom.getReferred())) { 77 if (!predicates.contains(predicateAtom.getReferred())) {
76 throw new IllegalArgumentException( 78 throw new IllegalArgumentException(
77 DNFPredicate.class.getSimpleName() + " " + dnfPredicate.getUniqueName() 79 DNFPredicate.class.getSimpleName() + " " + dnfPredicate.getUniqueName()
@@ -85,7 +87,8 @@ public class QueriableModelStoreImpl implements QueriableModelStore {
85 Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> result = new HashMap<>(); 87 Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> result = new HashMap<>();
86 Map<DNFPredicate, SimplePQuery> dnf2PQueryMap = new HashMap<>(); 88 Map<DNFPredicate, SimplePQuery> dnf2PQueryMap = new HashMap<>();
87 for (DNFPredicate dnfPredicate : predicates) { 89 for (DNFPredicate dnfPredicate : predicates) {
88 GenericQuerySpecification<RawPatternMatcher> query = DNF2PQuery.translate(dnfPredicate,dnf2PQueryMap).build(); 90 GenericQuerySpecification<RawPatternMatcher> query =
91 DNF2PQuery.translate(dnfPredicate, dnf2PQueryMap).build();
89 result.put(dnfPredicate, query); 92 result.put(dnfPredicate, query);
90 } 93 }
91 94
@@ -96,23 +99,25 @@ public class QueriableModelStoreImpl implements QueriableModelStore {
96 public Set<DataRepresentation<?, ?>> getDataRepresentations() { 99 public Set<DataRepresentation<?, ?>> getDataRepresentations() {
97 return store.getDataRepresentations(); 100 return store.getDataRepresentations();
98 } 101 }
102
99 @Override 103 @Override
100 public Set<RelationView<?>> getViews() { 104 public Set<RelationView<?>> getViews() {
101 return this.relationViews; 105 return this.relationViews;
102 } 106 }
107
103 @Override 108 @Override
104 public Set<DNFPredicate> getPredicates() { 109 public Set<DNFPredicate> getPredicates() {
105 return predicates.keySet(); 110 return predicates.keySet();
106 } 111 }
107 112
108 @Override 113 @Override
109 public QueriableModel createModel() { 114 public QueryableModel createModel() {
110 return new QueriableModelImpl(this, this.store.createModel(), predicates); 115 return new ViatraQueryableModel(this, this.store.createModel(), predicates);
111 } 116 }
112 117
113 @Override 118 @Override
114 public QueriableModel createModel(long state) { 119 public QueryableModel createModel(long state) {
115 return new QueriableModelImpl(this, this.store.createModel(state), predicates); 120 return new ViatraQueryableModel(this, this.store.createModel(state), predicates);
116 } 121 }
117 122
118 @Override 123 @Override
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RawPatternMatcher.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RawPatternMatcher.java
index c6d6353c..be348a63 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RawPatternMatcher.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RawPatternMatcher.java
@@ -1,56 +1,50 @@
1package tools.refinery.store.query.internal; 1package tools.refinery.store.query.viatra.internal;
2
3import java.util.Optional;
4import java.util.stream.Stream;
5 2
6import org.eclipse.viatra.query.runtime.api.GenericPatternMatcher; 3import org.eclipse.viatra.query.runtime.api.GenericPatternMatcher;
7import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; 4import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification;
8import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
9import org.eclipse.viatra.query.runtime.matchers.tuple.AbstractTuple; 5import org.eclipse.viatra.query.runtime.matchers.tuple.AbstractTuple;
6import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
10 7
11public class RawPatternMatcher extends GenericPatternMatcher implements PredicateResult{ 8import java.util.Optional;
12 9import java.util.stream.Stream;
10
11public class RawPatternMatcher extends GenericPatternMatcher {
13 protected final Object[] empty; 12 protected final Object[] empty;
14 13
15 public RawPatternMatcher(GenericQuerySpecification<? extends GenericPatternMatcher> specification) { 14 public RawPatternMatcher(GenericQuerySpecification<? extends GenericPatternMatcher> specification) {
16 super(specification); 15 super(specification);
17 this.empty = new Object[specification.getParameterNames().size()]; 16 this.empty = new Object[specification.getParameterNames().size()];
18 } 17 }
19 18
20 @Override
21 public boolean hasResult() { 19 public boolean hasResult() {
22 return hasResult(empty); 20 return hasResult(empty);
23 } 21 }
24 @Override 22
25 public boolean hasResult(Object[] parameters) { 23 public boolean hasResult(Object[] parameters) {
26 return this.backend.hasMatch(parameters); 24 return this.backend.hasMatch(parameters);
27 } 25 }
28 @Override 26
29 public Optional<Object[]> oneResult() { 27 public Optional<Object[]> oneResult() {
30 return oneResult(empty); 28 return oneResult(empty);
31 } 29 }
32 @Override 30
33 public Optional<Object[]> oneResult(Object[] parameters) { 31 public Optional<Object[]> oneResult(Object[] parameters) {
34 Optional<Tuple> tuple = this.backend.getOneArbitraryMatch(parameters); 32 Optional<Tuple> tuple = this.backend.getOneArbitraryMatch(parameters);
35 if(tuple.isPresent()) { 33 return tuple.map(AbstractTuple::getElements);
36 return Optional.of(tuple.get().getElements());
37 } else {
38 return Optional.empty();
39 }
40 } 34 }
41 @Override 35
42 public Stream<Object[]> allResults() { 36 public Stream<Object[]> allResults() {
43 return allResults(empty); 37 return allResults(empty);
44 } 38 }
45 @Override 39
46 public Stream<Object[]> allResults(Object[] parameters) { 40 public Stream<Object[]> allResults(Object[] parameters) {
47 return this.backend.getAllMatches(parameters).map(AbstractTuple::getElements); 41 return this.backend.getAllMatches(parameters).map(AbstractTuple::getElements);
48 } 42 }
49 @Override 43
50 public int countResults() { 44 public int countResults() {
51 return countResults(empty); 45 return countResults(empty);
52 } 46 }
53 @Override 47
54 public int countResults(Object[] parameters) { 48 public int countResults(Object[] parameters) {
55 return backend.countMatches(parameters); 49 return backend.countMatches(parameters);
56 } 50 }
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalScope.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java
index e8d45356..8dfa22e0 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalScope.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java
@@ -1,43 +1,43 @@
1package tools.refinery.store.query.internal; 1package tools.refinery.store.query.viatra.internal;
2
3import java.util.Set;
4 2
5import org.apache.log4j.Logger; 3import org.apache.log4j.Logger;
6import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; 4import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
7import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; 5import org.eclipse.viatra.query.runtime.api.scope.IEngineContext;
8import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; 6import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener;
9import org.eclipse.viatra.query.runtime.api.scope.QueryScope; 7import org.eclipse.viatra.query.runtime.api.scope.QueryScope;
10
11import tools.refinery.store.model.Model; 8import tools.refinery.store.model.Model;
12import tools.refinery.store.model.Tuple; 9import tools.refinery.store.model.Tuple;
13import tools.refinery.store.model.representation.Relation; 10import tools.refinery.store.model.representation.Relation;
11import tools.refinery.store.query.viatra.internal.context.RelationalEngineContext;
12import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener;
14import tools.refinery.store.query.view.RelationView; 13import tools.refinery.store.query.view.RelationView;
15 14
16public class RelationalScope extends QueryScope{ 15import java.util.Set;
16
17public class RelationalScope extends QueryScope {
17 private final Model model; 18 private final Model model;
18 private final ModelUpdateListener updateListener; 19 private final ModelUpdateListener updateListener;
19 20
20 public RelationalScope(Model model, Set<RelationView<?>> relationViews) { 21 public RelationalScope(Model model, Set<RelationView<?>> relationViews) {
21 this.model = model; 22 this.model = model;
22 this.updateListener = new ModelUpdateListener(relationViews); 23 this.updateListener = new ModelUpdateListener(relationViews);
23 //this.changeListener = new
24 } 24 }
25 25
26 public <D> void processUpdate(Relation<D> relation, Tuple key, D oldValue, D newValue) { 26 public <D> void processUpdate(Relation<D> relation, Tuple key, D oldValue, D newValue) {
27 updateListener.addUpdate(relation, key, oldValue, newValue); 27 updateListener.addUpdate(relation, key, oldValue, newValue);
28 } 28 }
29 29
30 public boolean hasChange() { 30 public boolean hasChanges() {
31 return updateListener.hasChange(); 31 return updateListener.hasChanges();
32 } 32 }
33 33
34 public void flush() { 34 public void flush() {
35 updateListener.flush(); 35 updateListener.flush();
36 } 36 }
37 37
38 @Override 38 @Override
39 protected IEngineContext createEngineContext(ViatraQueryEngine engine, IIndexingErrorListener errorListener, 39 protected IEngineContext createEngineContext(ViatraQueryEngine engine, IIndexingErrorListener errorListener,
40 Logger logger) { 40 Logger logger) {
41 return new RelationalEngineContext(model, updateListener); 41 return new RelationalEngineContext(model, updateListener);
42 } 42 }
43} 43}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/QueriableModelImpl.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java
index 0f4d609f..3803702d 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/QueriableModelImpl.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java
@@ -1,16 +1,9 @@
1package tools.refinery.store.query.internal; 1package tools.refinery.store.query.viatra.internal;
2
3import java.util.HashMap;
4import java.util.Map;
5import java.util.Optional;
6import java.util.Set;
7import java.util.stream.Stream;
8 2
9import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine; 3import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine;
10import org.eclipse.viatra.query.runtime.api.GenericQueryGroup; 4import org.eclipse.viatra.query.runtime.api.GenericQueryGroup;
11import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; 5import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification;
12import org.eclipse.viatra.query.runtime.api.IQueryGroup; 6import org.eclipse.viatra.query.runtime.api.IQueryGroup;
13
14import tools.refinery.store.map.Cursor; 7import tools.refinery.store.map.Cursor;
15import tools.refinery.store.map.DiffCursor; 8import tools.refinery.store.map.DiffCursor;
16import tools.refinery.store.model.Model; 9import tools.refinery.store.model.Model;
@@ -18,21 +11,31 @@ import tools.refinery.store.model.ModelDiffCursor;
18import tools.refinery.store.model.Tuple; 11import tools.refinery.store.model.Tuple;
19import tools.refinery.store.model.representation.DataRepresentation; 12import tools.refinery.store.model.representation.DataRepresentation;
20import tools.refinery.store.model.representation.Relation; 13import tools.refinery.store.model.representation.Relation;
21import tools.refinery.store.query.QueriableModel; 14import tools.refinery.store.query.QueryableModel;
22import tools.refinery.store.query.QueriableModelStore; 15import tools.refinery.store.query.QueryableModelStore;
23import tools.refinery.store.query.building.DNFPredicate; 16import tools.refinery.store.query.building.DNFPredicate;
24 17
25public class QueriableModelImpl implements QueriableModel { 18import java.util.HashMap;
26 protected final QueriableModelStore store; 19import java.util.Map;
20import java.util.Optional;
21import java.util.Set;
22import java.util.stream.Stream;
23
24public class ViatraQueryableModel implements QueryableModel {
25 protected final QueryableModelStore store;
26
27 protected final Model model; 27 protected final Model model;
28
28 protected final Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates2PQuery; 29 protected final Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates2PQuery;
29 30
30 protected RelationalScope scope; 31 protected RelationalScope scope;
32
31 protected AdvancedViatraQueryEngine engine; 33 protected AdvancedViatraQueryEngine engine;
34
32 protected Map<DNFPredicate, RawPatternMatcher> predicate2Matcher; 35 protected Map<DNFPredicate, RawPatternMatcher> predicate2Matcher;
33 36
34 public QueriableModelImpl(QueriableModelStore store, Model model, 37 public ViatraQueryableModel(QueryableModelStore store, Model model,
35 Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates2PQuery) { 38 Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates2PQuery) {
36 this.store = store; 39 this.store = store;
37 this.model = model; 40 this.model = model;
38 this.predicates2PQuery = predicates2PQuery; 41 this.predicates2PQuery = predicates2PQuery;
@@ -45,7 +48,8 @@ public class QueriableModelImpl implements QueriableModel {
45 this.predicate2Matcher = initMatchers(this.engine, this.predicates2PQuery); 48 this.predicate2Matcher = initMatchers(this.engine, this.predicates2PQuery);
46 } 49 }
47 50
48 private Map<DNFPredicate, RawPatternMatcher> initMatchers(AdvancedViatraQueryEngine engine, 51 private Map<DNFPredicate, RawPatternMatcher> initMatchers(
52 AdvancedViatraQueryEngine engine,
49 Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates2pQuery) { 53 Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates2pQuery) {
50 // 1. prepare group 54 // 1. prepare group
51 IQueryGroup queryGroup = GenericQueryGroup.of(Set.copyOf(predicates2pQuery.values())); 55 IQueryGroup queryGroup = GenericQueryGroup.of(Set.copyOf(predicates2pQuery.values()));
@@ -84,18 +88,19 @@ public class QueriableModelImpl implements QueriableModel {
84 @Override 88 @Override
85 public <K, V> V put(DataRepresentation<K, V> representation, K key, V value) { 89 public <K, V> V put(DataRepresentation<K, V> representation, K key, V value) {
86 V oldValue = this.model.put(representation, key, value); 90 V oldValue = this.model.put(representation, key, value);
87 if(representation instanceof Relation<?> relation) { 91 if (representation instanceof Relation<?> relation) {
88 this.scope.processUpdate((Relation<V>)relation, (Tuple)key, oldValue, value); 92 this.scope.processUpdate((Relation<V>) relation, (Tuple) key, oldValue, value);
89 } 93 }
90 return oldValue; 94 return oldValue;
91 } 95 }
92 96
93 @Override 97 @Override
94 public <K, V> void putAll(DataRepresentation<K, V> representation, Cursor<K, V> cursor) { 98 public <K, V> void putAll(DataRepresentation<K, V> representation, Cursor<K, V> cursor) {
95 if(representation instanceof Relation<?>) { 99 if (representation instanceof Relation<?>) {
100 //noinspection RedundantSuppression
96 @SuppressWarnings("unchecked") 101 @SuppressWarnings("unchecked")
97 Relation<V> relation = (Relation<V>) representation; 102 Relation<V> relation = (Relation<V>) representation;
98 while(cursor.move()) { 103 while (cursor.move()) {
99 Tuple key = (Tuple) cursor.getKey(); 104 Tuple key = (Tuple) cursor.getKey();
100 V newValue = cursor.getValue(); 105 V newValue = cursor.getValue();
101 V oldValue = this.model.put(relation, key, newValue); 106 V oldValue = this.model.put(relation, key, newValue);
@@ -111,10 +116,10 @@ public class QueriableModelImpl implements QueriableModel {
111 return model.getSize(representation); 116 return model.getSize(representation);
112 } 117 }
113 118
114 protected PredicateResult getPredicateResult(DNFPredicate predicate) { 119 protected RawPatternMatcher getMatcher(DNFPredicate predicate) {
115 var result = this.predicate2Matcher.get(predicate); 120 var result = this.predicate2Matcher.get(predicate);
116 if (result == null) { 121 if (result == null) {
117 throw new IllegalArgumentException("Model does not contain predicate " + predicate.getName() + "!"); 122 throw new IllegalArgumentException("Model does not contain predicate %s".formatted(predicate.getName()));
118 } else 123 } else
119 return result; 124 return result;
120 } 125 }
@@ -123,55 +128,62 @@ public class QueriableModelImpl implements QueriableModel {
123 int predicateArity = predicate.getVariables().size(); 128 int predicateArity = predicate.getVariables().size();
124 int parameterArity = parameters.length; 129 int parameterArity = parameters.length;
125 if (parameterArity != predicateArity) { 130 if (parameterArity != predicateArity) {
126 throw new IllegalArgumentException("Predicate " + predicate.getName() + " with " + predicateArity 131 throw new IllegalArgumentException(
127 + " arity called with different number of parameters (" + parameterArity + ")!"); 132 "Predicate %s with %d arity called with different number of parameters (%d)"
133 .formatted(predicate.getName(), predicateArity, parameterArity));
128 } 134 }
129 } 135 }
130 136
131 @Override 137 @Override
132 public boolean hasResult(DNFPredicate predicate) { 138 public boolean hasResult(DNFPredicate predicate) {
133 return getPredicateResult(predicate).hasResult(); 139 return getMatcher(predicate).hasResult();
134 } 140 }
135 141
136 @Override 142 @Override
137 public boolean hasResult(DNFPredicate predicate, Object[] parameters) { 143 public boolean hasResult(DNFPredicate predicate, Object[] parameters) {
138 validateParameters(predicate, parameters); 144 validateParameters(predicate, parameters);
139 return getPredicateResult(predicate).hasResult(parameters); 145 return getMatcher(predicate).hasResult(parameters);
140 } 146 }
141 147
142 @Override 148 @Override
143 public Optional<Object[]> oneResult(DNFPredicate predicate){ 149 public Optional<Object[]> oneResult(DNFPredicate predicate) {
144 return getPredicateResult(predicate).oneResult(); 150 return getMatcher(predicate).oneResult();
145 } 151 }
146 152
147 @Override 153 @Override
148 public Optional<Object[]> oneResult(DNFPredicate predicate, Object[] parameters){ 154 public Optional<Object[]> oneResult(DNFPredicate predicate, Object[] parameters) {
149 validateParameters(predicate, parameters); 155 validateParameters(predicate, parameters);
150 return getPredicateResult(predicate).oneResult(parameters); 156 return getMatcher(predicate).oneResult(parameters);
151 } 157 }
152 158
153 @Override 159 @Override
154 public Stream<Object[]> allResults(DNFPredicate predicate){ 160 public Stream<Object[]> allResults(DNFPredicate predicate) {
155 return getPredicateResult(predicate).allResults(); 161 return getMatcher(predicate).allResults();
156 } 162 }
157 163
158 @Override 164 @Override
159 public Stream<Object[]> allResults(DNFPredicate predicate, Object[] parameters){ 165 public Stream<Object[]> allResults(DNFPredicate predicate, Object[] parameters) {
160 validateParameters(predicate, parameters); 166 validateParameters(predicate, parameters);
161 return getPredicateResult(predicate).allResults(parameters); 167 return getMatcher(predicate).allResults(parameters);
162 } 168 }
163 169
164 @Override 170 @Override
165 public int countResults(DNFPredicate predicate){ 171 public int countResults(DNFPredicate predicate) {
166 return getPredicateResult(predicate).countResults(); 172 return getMatcher(predicate).countResults();
167 } 173 }
168 174
169 @Override 175 @Override
170 public int countResults(DNFPredicate predicate, Object[] parameters){ 176 public int countResults(DNFPredicate predicate, Object[] parameters) {
171 validateParameters(predicate, parameters); 177 validateParameters(predicate, parameters);
172 return getPredicateResult(predicate).countResults(parameters); 178 return getMatcher(predicate).countResults(parameters);
173 179
180 }
181
182 @Override
183 public boolean hasChanges() {
184 return scope.hasChanges();
174 } 185 }
186
175 @Override 187 @Override
176 public void flushChanges() { 188 public void flushChanges() {
177 this.scope.flush(); 189 this.scope.flush();
@@ -192,21 +204,16 @@ public class QueriableModelImpl implements QueriableModel {
192 restoreWithDiffReplay(state); 204 restoreWithDiffReplay(state);
193 } 205 }
194 206
195 public void restoreWithDiffReplay(long state) { 207 private void restoreWithDiffReplay(long state) {
196 var modelDiffCursor = getDiffCursor(state); 208 var modelDiffCursor = getDiffCursor(state);
197 for(DataRepresentation<?,?> dataRepresentation : this.getDataRepresentations()) { 209 for (DataRepresentation<?, ?> dataRepresentation : this.getDataRepresentations()) {
198 restoreRepresentationWithDiffReplay(modelDiffCursor, dataRepresentation); 210 restoreRepresentationWithDiffReplay(modelDiffCursor, dataRepresentation);
199 } 211 }
200 } 212 }
201 213
202 private <K,V> void restoreRepresentationWithDiffReplay(ModelDiffCursor modelDiffCursor, 214 private <K, V> void restoreRepresentationWithDiffReplay(ModelDiffCursor modelDiffCursor,
203 DataRepresentation<K, V> dataRepresentation) { 215 DataRepresentation<K, V> dataRepresentation) {
204 DiffCursor<K,V> diffCursor = modelDiffCursor.getCursor(dataRepresentation); 216 DiffCursor<K, V> diffCursor = modelDiffCursor.getCursor(dataRepresentation);
205 this.putAll(dataRepresentation, diffCursor); 217 this.putAll(dataRepresentation, diffCursor);
206 } 218 }
207
208 public void restoreWithReinit(long state) {
209 model.restore(state);
210 this.initEngine();
211 }
212} 219}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/DummyBaseIndexer.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/DummyBaseIndexer.java
index 49637071..4b311a64 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/DummyBaseIndexer.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/DummyBaseIndexer.java
@@ -1,18 +1,17 @@
1package tools.refinery.store.query.internal; 1package tools.refinery.store.query.viatra.internal.context;
2
3import java.lang.reflect.InvocationTargetException;
4import java.util.concurrent.Callable;
5 2
6import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; 3import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex;
7import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; 4import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener;
8import org.eclipse.viatra.query.runtime.api.scope.IInstanceObserver; 5import org.eclipse.viatra.query.runtime.api.scope.IInstanceObserver;
9import org.eclipse.viatra.query.runtime.api.scope.ViatraBaseIndexChangeListener; 6import org.eclipse.viatra.query.runtime.api.scope.ViatraBaseIndexChangeListener;
10 7
8import java.lang.reflect.InvocationTargetException;
9import java.util.concurrent.Callable;
10
11/** 11/**
12 * copied from org.eclipse.viatra.query.runtime.tabular.TabularEngineContext; 12 * Copied from <code>org.eclipse.viatra.query.runtime.tabular.TabularEngineContext</code>
13 */ 13 */
14public class DummyBaseIndexer implements IBaseIndex{ 14public class DummyBaseIndexer implements IBaseIndex {
15
16 @Override 15 @Override
17 public <V> V coalesceTraversals(Callable<V> callable) throws InvocationTargetException { 16 public <V> V coalesceTraversals(Callable<V> callable) throws InvocationTargetException {
18 try { 17 try {
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalEngineContext.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java
index dfbd8545..882734cb 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalEngineContext.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java
@@ -1,15 +1,15 @@
1package tools.refinery.store.query.internal; 1package tools.refinery.store.query.viatra.internal.context;
2 2
3import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; 3import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex;
4import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; 4import org.eclipse.viatra.query.runtime.api.scope.IEngineContext;
5import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext; 5import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext;
6 6
7import tools.refinery.store.model.Model; 7import tools.refinery.store.model.Model;
8import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener;
8 9
9public class RelationalEngineContext implements IEngineContext{ 10public class RelationalEngineContext implements IEngineContext {
10 private final IBaseIndex baseIndex = new DummyBaseIndexer(); 11 private final IBaseIndex baseIndex = new DummyBaseIndexer();
11 private final RelationalRuntimeContext runtimeContext; 12 private final RelationalRuntimeContext runtimeContext;
12
13 13
14 public RelationalEngineContext(Model model, ModelUpdateListener updateListener) { 14 public RelationalEngineContext(Model model, ModelUpdateListener updateListener) {
15 runtimeContext = new RelationalRuntimeContext(model, updateListener); 15 runtimeContext = new RelationalRuntimeContext(model, updateListener);
@@ -22,7 +22,7 @@ public class RelationalEngineContext implements IEngineContext{
22 22
23 @Override 23 @Override
24 public void dispose() { 24 public void dispose() {
25 //lifecycle not controlled by engine 25 // Nothing to dispose, because lifecycle is not controlled by the engine.
26 } 26 }
27 27
28 @Override 28 @Override
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java
new file mode 100644
index 00000000..64c23c61
--- /dev/null
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java
@@ -0,0 +1,44 @@
1package tools.refinery.store.query.viatra.internal.context;
2
3import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContext;
4import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
5import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication;
6import tools.refinery.store.query.view.RelationView;
7
8import java.util.*;
9
10/**
11 * The meta context information for String scopes.
12 */
13public class RelationalQueryMetaContext extends AbstractQueryMetaContext {
14 @Override
15 public boolean isEnumerable(IInputKey key) {
16 ensureValidKey(key);
17 return key.isEnumerable();
18 }
19
20 @Override
21 public boolean isStateless(IInputKey key) {
22 ensureValidKey(key);
23 return true;
24 }
25
26 @Override
27 public Collection<InputKeyImplication> getImplications(IInputKey implyingKey) {
28 ensureValidKey(implyingKey);
29 return Set.of();
30 }
31
32 @Override
33 public Map<Set<Integer>, Set<Integer>> getFunctionalDependencies(IInputKey key) {
34 ensureValidKey(key);
35 return Map.of();
36 }
37
38 public void ensureValidKey(IInputKey key) {
39 if (key instanceof RelationView<?>) {
40 return;
41 }
42 throw new IllegalArgumentException("The input key %s is not a valid input key.".formatted(key));
43 }
44}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalRuntimeContext.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java
index a186b5dd..0bd1b807 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalRuntimeContext.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java
@@ -1,53 +1,47 @@
1package tools.refinery.store.query.internal; 1package tools.refinery.store.query.viatra.internal.context;
2 2
3import static tools.refinery.store.util.CollectionsUtil.filter; 3import org.eclipse.viatra.query.runtime.matchers.context.*;
4import static tools.refinery.store.util.CollectionsUtil.map;
5
6import java.lang.reflect.InvocationTargetException;
7import java.util.Iterator;
8import java.util.Optional;
9import java.util.concurrent.Callable;
10
11import org.eclipse.viatra.query.runtime.base.core.NavigationHelperImpl;
12import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
13import org.eclipse.viatra.query.runtime.matchers.context.IQueryMetaContext;
14import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext;
15import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener;
16import org.eclipse.viatra.query.runtime.matchers.context.IndexingService;
17import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 4import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple;
18import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; 5import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
19import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask; 6import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask;
20import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 7import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
21import org.eclipse.viatra.query.runtime.matchers.util.Accuracy; 8import org.eclipse.viatra.query.runtime.matchers.util.Accuracy;
22
23import tools.refinery.store.model.Model; 9import tools.refinery.store.model.Model;
10import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener;
24import tools.refinery.store.query.view.RelationView; 11import tools.refinery.store.query.view.RelationView;
25 12
13import java.lang.reflect.InvocationTargetException;
14import java.util.Iterator;
15import java.util.Optional;
16import java.util.concurrent.Callable;
17
18import static tools.refinery.store.util.CollectionsUtil.filter;
19import static tools.refinery.store.util.CollectionsUtil.map;
20
26public class RelationalRuntimeContext implements IQueryRuntimeContext { 21public class RelationalRuntimeContext implements IQueryRuntimeContext {
27 private final RelationalQueryMetaContext metaContext = new RelationalQueryMetaContext(); 22 private final RelationalQueryMetaContext metaContext = new RelationalQueryMetaContext();
23
28 private final ModelUpdateListener modelUpdateListener; 24 private final ModelUpdateListener modelUpdateListener;
25
29 private final Model model; 26 private final Model model;
30 27
31 public RelationalRuntimeContext(Model model, ModelUpdateListener relationUpdateListener) { 28 public RelationalRuntimeContext(Model model, ModelUpdateListener relationUpdateListener) {
32 this.model = model; 29 this.model = model;
33 this.modelUpdateListener = relationUpdateListener; 30 this.modelUpdateListener = relationUpdateListener;
34 } 31 }
35 32
36 @Override 33 @Override
37 public IQueryMetaContext getMetaContext() { 34 public IQueryMetaContext getMetaContext() {
38 return metaContext; 35 return metaContext;
39 } 36 }
40 37
41 /**
42 * TODO: check {@link NavigationHelperImpl#coalesceTraversals(Callable)}
43 */
44 @Override 38 @Override
45 public <V> V coalesceTraversals(Callable<V> callable) throws InvocationTargetException { 39 public <V> V coalesceTraversals(Callable<V> callable) throws InvocationTargetException {
46 try { 40 try {
47 return callable.call(); 41 return callable.call();
48 } catch (Exception e) { 42 } catch (Exception e) {
49 throw new InvocationTargetException(e); 43 throw new InvocationTargetException(e);
50 } 44 }
51 } 45 }
52 46
53 @Override 47 @Override
@@ -57,7 +51,7 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
57 51
58 @Override 52 @Override
59 public boolean isIndexed(IInputKey key, IndexingService service) { 53 public boolean isIndexed(IInputKey key, IndexingService service) {
60 if(key instanceof RelationView<?> relationalKey) { 54 if (key instanceof RelationView<?> relationalKey) {
61 return this.modelUpdateListener.containsRelationalView(relationalKey); 55 return this.modelUpdateListener.containsRelationalView(relationalKey);
62 } else { 56 } else {
63 return false; 57 return false;
@@ -66,15 +60,15 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
66 60
67 @Override 61 @Override
68 public void ensureIndexed(IInputKey key, IndexingService service) { 62 public void ensureIndexed(IInputKey key, IndexingService service) {
69 if(!isIndexed(key, service)) { 63 if (!isIndexed(key, service)) {
70 throw new IllegalStateException("Engine tries to index a new key " +key); 64 throw new IllegalStateException("Engine tries to index a new key " + key);
71 } 65 }
72 } 66 }
67
73 @SuppressWarnings("squid:S1452") 68 @SuppressWarnings("squid:S1452")
74 RelationView<?> checkKey(IInputKey key) { 69 RelationView<?> checkKey(IInputKey key) {
75 if(key instanceof RelationView) { 70 if (key instanceof RelationView<?> relationViewKey) {
76 RelationView<?> relationViewKey = (RelationView<?>) key; 71 if (modelUpdateListener.containsRelationalView(relationViewKey)) {
77 if(modelUpdateListener.containsRelationalView(relationViewKey)) {
78 return relationViewKey; 72 return relationViewKey;
79 } else { 73 } else {
80 throw new IllegalStateException("Query is asking for non-indexed key"); 74 throw new IllegalStateException("Query is asking for non-indexed key");
@@ -83,15 +77,15 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
83 throw new IllegalStateException("Query is asking for non-relational key"); 77 throw new IllegalStateException("Query is asking for non-relational key");
84 } 78 }
85 } 79 }
86 80
87 @Override 81 @Override
88 public int countTuples(IInputKey key, TupleMask seedMask, ITuple seed) { 82 public int countTuples(IInputKey key, TupleMask seedMask, ITuple seed) {
89 RelationView<?> relationalViewKey = checkKey(key); 83 RelationView<?> relationalViewKey = checkKey(key);
90 Iterable<Object[]> allObjects = relationalViewKey.getAll(model); 84 Iterable<Object[]> allObjects = relationalViewKey.getAll(model);
91 Iterable<Object[]> filteredBySeed = filter(allObjects,objectArray -> isMatching(objectArray,seedMask,seed)); 85 Iterable<Object[]> filteredBySeed = filter(allObjects, objectArray -> isMatching(objectArray, seedMask, seed));
92 Iterator<Object[]> iterator = filteredBySeed.iterator(); 86 Iterator<Object[]> iterator = filteredBySeed.iterator();
93 int result = 0; 87 int result = 0;
94 while(iterator.hasNext()) { 88 while (iterator.hasNext()) {
95 iterator.next(); 89 iterator.next();
96 result++; 90 result++;
97 } 91 }
@@ -107,15 +101,15 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
107 public Iterable<Tuple> enumerateTuples(IInputKey key, TupleMask seedMask, ITuple seed) { 101 public Iterable<Tuple> enumerateTuples(IInputKey key, TupleMask seedMask, ITuple seed) {
108 RelationView<?> relationalViewKey = checkKey(key); 102 RelationView<?> relationalViewKey = checkKey(key);
109 Iterable<Object[]> allObjects = relationalViewKey.getAll(model); 103 Iterable<Object[]> allObjects = relationalViewKey.getAll(model);
110 Iterable<Object[]> filteredBySeed = filter(allObjects,objectArray -> isMatching(objectArray,seedMask,seed)); 104 Iterable<Object[]> filteredBySeed = filter(allObjects, objectArray -> isMatching(objectArray, seedMask, seed));
111 return map(filteredBySeed,Tuples::flatTupleOf); 105 return map(filteredBySeed, Tuples::flatTupleOf);
112 } 106 }
113 107
114 private boolean isMatching(Object[] tuple, TupleMask seedMask, ITuple seed) { 108 private boolean isMatching(Object[] tuple, TupleMask seedMask, ITuple seed) {
115 for(int i=0; i<seedMask.indices.length; i++) { 109 for (int i = 0; i < seedMask.indices.length; i++) {
116 final Object seedElement = seed.get(i); 110 final Object seedElement = seed.get(i);
117 final Object tupleElement = tuple[seedMask.indices[i]]; 111 final Object tupleElement = tuple[seedMask.indices[i]];
118 if(!tupleElement.equals(seedElement)) { 112 if (!tupleElement.equals(seedElement)) {
119 return false; 113 return false;
120 } 114 }
121 } 115 }
@@ -130,14 +124,14 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
130 @Override 124 @Override
131 public boolean containsTuple(IInputKey key, ITuple seed) { 125 public boolean containsTuple(IInputKey key, ITuple seed) {
132 RelationView<?> relationalViewKey = checkKey(key); 126 RelationView<?> relationalViewKey = checkKey(key);
133 return relationalViewKey.get(model,seed.getElements()); 127 return relationalViewKey.get(model, seed.getElements());
134 } 128 }
135 129
136 @Override 130 @Override
137 public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { 131 public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) {
138 RelationView<?> relationalKey = checkKey(key); 132 RelationView<?> relationalKey = checkKey(key);
139 this.modelUpdateListener.addListener(relationalKey, seed, listener); 133 this.modelUpdateListener.addListener(relationalKey, seed, listener);
140 134
141 } 135 }
142 136
143 @Override 137 @Override
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java
index bcc03fb4..c093be47 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java
@@ -1,17 +1,5 @@
1package tools.refinery.store.query.internal; 1package tools.refinery.store.query.viatra.internal.pquery;
2 2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.InputMismatchException;
6import java.util.LinkedHashSet;
7import java.util.List;
8import java.util.Map;
9import java.util.Set;
10
11import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification;
12import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
13import org.eclipse.viatra.query.runtime.api.scope.QueryScope;
14import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint;
15import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; 3import org.eclipse.viatra.query.runtime.matchers.psystem.PBody;
16import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; 4import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable;
17import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; 5import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality;
@@ -21,39 +9,35 @@ import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativeP
21import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure; 9import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure;
22import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; 10import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
23import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; 11import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint;
24import org.eclipse.viatra.query.runtime.matchers.psystem.queries.BasePQuery;
25import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; 12import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter;
26import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility;
27import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 13import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
14import tools.refinery.store.query.building.*;
28 15
29import tools.refinery.store.query.building.DNFAnd; 16import java.util.*;
30import tools.refinery.store.query.building.DNFAtom;
31import tools.refinery.store.query.building.DNFPredicate;
32import tools.refinery.store.query.building.EquivalenceAtom;
33import tools.refinery.store.query.building.PredicateAtom;
34import tools.refinery.store.query.building.RelationAtom;
35import tools.refinery.store.query.building.Variable;
36 17
37public class DNF2PQuery { 18public class DNF2PQuery {
19 private DNF2PQuery() {
20 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
21 }
38 22
39 public static SimplePQuery translate(DNFPredicate predicate, Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) { 23 public static SimplePQuery translate(DNFPredicate predicate, Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) {
40 SimplePQuery query = dnf2PQueryMap.get(predicate); 24 SimplePQuery query = dnf2PQueryMap.get(predicate);
41 if (query != null) { 25 if (query != null) {
42 return query; 26 return query;
43 } 27 }
44 query = new DNF2PQuery().new SimplePQuery(predicate.getName()); 28 query = new SimplePQuery(predicate.getName());
45 Map<Variable, PParameter> parameters = new HashMap<>(); 29 Map<Variable, PParameter> parameters = new HashMap<>();
46 30
47 predicate.getVariables().forEach(variable -> parameters.put(variable, new PParameter(variable.getName()))); 31 predicate.getVariables().forEach(variable -> parameters.put(variable, new PParameter(variable.getName())));
48 List<PParameter> parameterList = new ArrayList<>(); 32 List<PParameter> parameterList = new ArrayList<>();
49 for(var param : predicate.getVariables()) { 33 for (var param : predicate.getVariables()) {
50 parameterList.add(parameters.get(param)); 34 parameterList.add(parameters.get(param));
51 } 35 }
52 query.setParameter(parameterList); 36 query.setParameters(parameterList);
53 for (DNFAnd clause : predicate.getClauses()) { 37 for (DNFAnd clause : predicate.getClauses()) {
54 PBody body = new PBody(query); 38 PBody body = new PBody(query);
55 List<ExportedParameter> symbolicParameters = new ArrayList<>(); 39 List<ExportedParameter> symbolicParameters = new ArrayList<>();
56 for(var param : predicate.getVariables()) { 40 for (var param : predicate.getVariables()) {
57 PVariable pVar = body.getOrCreateVariableByName(param.getName()); 41 PVariable pVar = body.getOrCreateVariableByName(param.getName());
58 symbolicParameters.add(new ExportedParameter(body, pVar, parameters.get(param))); 42 symbolicParameters.add(new ExportedParameter(body, pVar, parameters.get(param)));
59 } 43 }
@@ -67,7 +51,8 @@ public class DNF2PQuery {
67 return query; 51 return query;
68 } 52 }
69 53
70 private static void translateDNFAtom(DNFAtom constraint, PBody body, Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) { 54 private static void translateDNFAtom(DNFAtom constraint, PBody body,
55 Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) {
71 if (constraint instanceof EquivalenceAtom equivalence) { 56 if (constraint instanceof EquivalenceAtom equivalence) {
72 translateEquivalenceAtom(equivalence, body); 57 translateEquivalenceAtom(equivalence, body);
73 } 58 }
@@ -89,18 +74,19 @@ public class DNF2PQuery {
89 } 74 }
90 75
91 private static void translateRelationAtom(RelationAtom relation, PBody body) { 76 private static void translateRelationAtom(RelationAtom relation, PBody body) {
92 if (relation.getSubstitution().size() != relation.getView().getArity()) { 77 if (relation.substitution().size() != relation.view().getArity()) {
93 throw new IllegalArgumentException("Arity (" + relation.getView().getArity() 78 throw new IllegalArgumentException("Arity (%d) does not match parameter numbers (%d)".formatted(
94 + ") does not match parameter numbers (" + relation.getSubstitution().size() + ")"); 79 relation.view().getArity(), relation.substitution().size()));
95 } 80 }
96 Object[] variables = new Object[relation.getSubstitution().size()]; 81 Object[] variables = new Object[relation.substitution().size()];
97 for (int i = 0; i < relation.getSubstitution().size(); i++) { 82 for (int i = 0; i < relation.substitution().size(); i++) {
98 variables[i] = body.getOrCreateVariableByName(relation.getSubstitution().get(i).getName()); 83 variables[i] = body.getOrCreateVariableByName(relation.substitution().get(i).getName());
99 } 84 }
100 new TypeConstraint(body, Tuples.flatTupleOf(variables), relation.getView()); 85 new TypeConstraint(body, Tuples.flatTupleOf(variables), relation.view());
101 } 86 }
102 87
103 private static void translatePredicateAtom(PredicateAtom predicate, PBody body, Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) { 88 private static void translatePredicateAtom(PredicateAtom predicate, PBody body,
89 Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) {
104 Object[] variables = new Object[predicate.getSubstitution().size()]; 90 Object[] variables = new Object[predicate.getSubstitution().size()];
105 for (int i = 0; i < predicate.getSubstitution().size(); i++) { 91 for (int i = 0; i < predicate.getSubstitution().size(); i++) {
106 variables[i] = body.getOrCreateVariableByName(predicate.getSubstitution().get(i).getName()); 92 variables[i] = body.getOrCreateVariableByName(predicate.getSubstitution().get(i).getName());
@@ -125,65 +111,4 @@ public class DNF2PQuery {
125 } 111 }
126 } 112 }
127 } 113 }
128 114}
129 public class SimplePQuery extends BasePQuery {
130
131 private String fullyQualifiedName;
132 private List<PParameter> parameters;
133 private LinkedHashSet<PBody> bodies = new LinkedHashSet<>();
134
135 public SimplePQuery(String name) {
136 super(PVisibility.PUBLIC);
137 fullyQualifiedName = name;
138 }
139
140 @Override
141 public String getFullyQualifiedName() {
142 return fullyQualifiedName;
143 }
144
145 public void setParameter(List<PParameter> parameters) {
146 this.parameters = parameters;
147 }
148
149 @Override
150 public List<PParameter> getParameters() {
151 return parameters;
152 }
153
154 public void addBody(PBody body) {
155 bodies.add(body);
156 }
157
158 @Override
159 protected Set<PBody> doGetContainedBodies() {
160 setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED));
161 return bodies;
162 }
163
164 public GenericQuerySpecification<RawPatternMatcher> build() {
165 return new GenericQuerySpecification<RawPatternMatcher>(this) {
166
167 @Override
168 public Class<? extends QueryScope> getPreferredScopeClass() {
169 return RelationalScope.class;
170 }
171
172 @Override
173 protected RawPatternMatcher instantiate(ViatraQueryEngine engine) {
174 RawPatternMatcher matcher = engine.getExistingMatcher(this);
175 if (matcher == null) {
176 matcher = engine.getMatcher(this);
177 }
178 return matcher;
179 }
180
181 @Override
182 public RawPatternMatcher instantiate() {
183 return new RawPatternMatcher(this);
184 }
185
186 };
187 }
188 }
189} \ No newline at end of file
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/SimplePQuery.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/SimplePQuery.java
new file mode 100644
index 00000000..a367cbf2
--- /dev/null
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/SimplePQuery.java
@@ -0,0 +1,74 @@
1package tools.refinery.store.query.viatra.internal.pquery;
2
3import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification;
4import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
5import org.eclipse.viatra.query.runtime.api.scope.QueryScope;
6import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint;
7import org.eclipse.viatra.query.runtime.matchers.psystem.PBody;
8import org.eclipse.viatra.query.runtime.matchers.psystem.queries.BasePQuery;
9import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter;
10import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility;
11import tools.refinery.store.query.viatra.internal.RawPatternMatcher;
12import tools.refinery.store.query.viatra.internal.RelationalScope;
13
14import java.util.LinkedHashSet;
15import java.util.List;
16import java.util.Set;
17
18public class SimplePQuery extends BasePQuery {
19 private final String fullyQualifiedName;
20 private List<PParameter> parameters;
21 private final LinkedHashSet<PBody> bodies = new LinkedHashSet<>();
22
23 public SimplePQuery(String name) {
24 super(PVisibility.PUBLIC);
25 fullyQualifiedName = name;
26 setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED));
27 }
28
29 @Override
30 public String getFullyQualifiedName() {
31 return fullyQualifiedName;
32 }
33
34 public void setParameters(List<PParameter> parameters) {
35 this.parameters = parameters;
36 }
37
38 @Override
39 public List<PParameter> getParameters() {
40 return parameters;
41 }
42
43 public void addBody(PBody body) {
44 bodies.add(body);
45 }
46
47 @Override
48 protected Set<PBody> doGetContainedBodies() {
49 return bodies;
50 }
51
52 public GenericQuerySpecification<RawPatternMatcher> build() {
53 return new GenericQuerySpecification<>(this) {
54 @Override
55 public Class<? extends QueryScope> getPreferredScopeClass() {
56 return RelationalScope.class;
57 }
58
59 @Override
60 protected RawPatternMatcher instantiate(ViatraQueryEngine engine) {
61 RawPatternMatcher matcher = engine.getExistingMatcher(this);
62 if (matcher == null) {
63 matcher = engine.getMatcher(this);
64 }
65 return matcher;
66 }
67
68 @Override
69 public RawPatternMatcher instantiate() {
70 return new RawPatternMatcher(this);
71 }
72 };
73 }
74}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ModelUpdateListener.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java
index aa80985f..25919888 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ModelUpdateListener.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java
@@ -1,22 +1,22 @@
1package tools.refinery.store.query.internal; 1package tools.refinery.store.query.viatra.internal.viewupdate;
2
3import java.util.HashMap;
4import java.util.HashSet;
5import java.util.Map;
6import java.util.Set;
7 2
8import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; 3import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener;
9import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 4import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple;
10
11import tools.refinery.store.model.Tuple; 5import tools.refinery.store.model.Tuple;
12import tools.refinery.store.model.representation.Relation; 6import tools.refinery.store.model.representation.Relation;
13import tools.refinery.store.query.view.RelationView; 7import tools.refinery.store.query.view.RelationView;
14 8
9import java.util.HashMap;
10import java.util.HashSet;
11import java.util.Map;
12import java.util.Set;
13
15public class ModelUpdateListener { 14public class ModelUpdateListener {
16 /** 15 /**
17 * Collections of Relations and their Views. 16 * Collections of Relations and their Views.
18 */ 17 */
19 private final Map<Relation<?>, Set<RelationView<?>>> relation2View; 18 private final Map<Relation<?>, Set<RelationView<?>>> relation2View;
19
20 /** 20 /**
21 * Collection of Views and their buffers. 21 * Collection of Views and their buffers.
22 */ 22 */
@@ -35,18 +35,18 @@ public class ModelUpdateListener {
35 Relation<?> relation = view.getRepresentation(); 35 Relation<?> relation = view.getRepresentation();
36 36
37 // 1. register views to relations, if necessary 37 // 1. register views to relations, if necessary
38 var views = relation2View.computeIfAbsent(relation, x->new HashSet<>()); 38 var views = relation2View.computeIfAbsent(relation, x -> new HashSet<>());
39 views.add(view); 39 views.add(view);
40 40
41 // 2. register notifier map to views, if necessary 41 // 2. register notifier map to views, if necessary
42 view2Buffers.computeIfAbsent(view, x->new HashSet<>()); 42 view2Buffers.computeIfAbsent(view, x -> new HashSet<>());
43 } 43 }
44 44
45 boolean containsRelationalView(RelationView<?> relationalKey) { 45 public boolean containsRelationalView(RelationView<?> relationalKey) {
46 return view2Buffers.containsKey(relationalKey); 46 return view2Buffers.containsKey(relationalKey);
47 } 47 }
48 48
49 <D> void addListener(RelationView<D> relationView, ITuple seed, IQueryRuntimeContextListener listener) { 49 public <D> void addListener(RelationView<D> relationView, ITuple seed, IQueryRuntimeContextListener listener) {
50 if (view2Buffers.containsKey(relationView)) { 50 if (view2Buffers.containsKey(relationView)) {
51 ViewUpdateTranslator<D> updateListener = new ViewUpdateTranslator<>(relationView, seed, listener); 51 ViewUpdateTranslator<D> updateListener = new ViewUpdateTranslator<>(relationView, seed, listener);
52 ViewUpdateBuffer<D> updateBuffer = new ViewUpdateBuffer<>(updateListener); 52 ViewUpdateBuffer<D> updateBuffer = new ViewUpdateBuffer<>(updateListener);
@@ -55,38 +55,40 @@ public class ModelUpdateListener {
55 throw new IllegalArgumentException(); 55 throw new IllegalArgumentException();
56 } 56 }
57 57
58 void removeListener(RelationView<?> relationView, ITuple seed, IQueryRuntimeContextListener listener) { 58 public void removeListener(RelationView<?> relationView, ITuple seed, IQueryRuntimeContextListener listener) {
59 if (view2Buffers.containsKey(relationView)) { 59 if (view2Buffers.containsKey(relationView)) {
60 Set<ViewUpdateBuffer<?>> buffers = this.view2Buffers.get(relationView); 60 Set<ViewUpdateBuffer<?>> buffers = this.view2Buffers.get(relationView);
61 for(var buffer : buffers) { 61 for (var buffer : buffers) {
62 if(buffer.getUpdateListener().key == seed && buffer.getUpdateListener().listener == listener) { 62 if (buffer.getUpdateListener().equals(relationView, seed, listener)) {
63 // remove buffer and terminate immediately, or it will break iterator. 63 // remove buffer and terminate immediately, or it will break iterator.
64 buffers.remove(buffer); 64 buffers.remove(buffer);
65 return; 65 return;
66 } 66 }
67 } 67 }
68 } else 68 } else {
69 throw new IllegalArgumentException(); 69 throw new IllegalArgumentException("Relation view is not registered for updates");
70 }
70 } 71 }
71 72
72 public <D> void addUpdate(Relation<D> relation, Tuple key, D oldValue, D newValue) { 73 public <D> void addUpdate(Relation<D> relation, Tuple key, D oldValue, D newValue) {
73 var views = this.relation2View.get(relation); 74 var views = this.relation2View.get(relation);
74 if (views != null) { 75 if (views == null) {
75 for (var view : views) { 76 return;
76 var buffers = this.view2Buffers.get(view); 77 }
77 for (var buffer : buffers) { 78 for (var view : views) {
78 @SuppressWarnings("unchecked") 79 var buffers = this.view2Buffers.get(view);
79 var typedBuffer = (ViewUpdateBuffer<D>) buffer; 80 for (var buffer : buffers) {
80 typedBuffer.addChange(key, oldValue, newValue); 81 @SuppressWarnings("unchecked")
81 } 82 var typedBuffer = (ViewUpdateBuffer<D>) buffer;
83 typedBuffer.addChange(key, oldValue, newValue);
82 } 84 }
83 } 85 }
84 } 86 }
85 87
86 public boolean hasChange() { 88 public boolean hasChanges() {
87 for (var bufferCollection : this.view2Buffers.values()) { 89 for (var bufferCollection : this.view2Buffers.values()) {
88 for (ViewUpdateBuffer<?> buffer : bufferCollection) { 90 for (ViewUpdateBuffer<?> buffer : bufferCollection) {
89 if (buffer.hasChange()) 91 if (buffer.hasChanges())
90 return true; 92 return true;
91 } 93 }
92 } 94 }
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdate.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java
index 7d1a4c05..c727f046 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdate.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java
@@ -1,4 +1,4 @@
1package tools.refinery.store.query.internal; 1package tools.refinery.store.query.viatra.internal.viewupdate;
2 2
3import java.util.Arrays; 3import java.util.Arrays;
4import java.util.Objects; 4import java.util.Objects;
@@ -30,5 +30,5 @@ record ViewUpdate (Object[] tuple, boolean isInsertion) {
30 public String toString() { 30 public String toString() {
31 return "ViewUpdate [" + Arrays.toString(tuple) + "insertion= "+this.isInsertion+"]"; 31 return "ViewUpdate [" + Arrays.toString(tuple) + "insertion= "+this.isInsertion+"]";
32 } 32 }
33 33
34} 34}
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateBuffer.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java
index 6bc4c96a..5a4243f2 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateBuffer.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java
@@ -1,42 +1,42 @@
1package tools.refinery.store.query.internal; 1package tools.refinery.store.query.viatra.internal.viewupdate;
2
3import tools.refinery.store.model.Tuple;
2 4
3import java.util.ArrayList; 5import java.util.ArrayList;
4import java.util.Arrays; 6import java.util.Arrays;
5import java.util.List; 7import java.util.List;
6 8
7import tools.refinery.store.model.Tuple;
8
9public class ViewUpdateBuffer<D> { 9public class ViewUpdateBuffer<D> {
10 protected final ViewUpdateTranslator<D> updateListener; 10 protected final ViewUpdateTranslator<D> updateListener;
11 protected final List<ViewUpdate> buffer = new ArrayList<>(); 11 protected final List<ViewUpdate> buffer = new ArrayList<>();
12 12
13 public ViewUpdateBuffer(ViewUpdateTranslator<D> updateListener) { 13 public ViewUpdateBuffer(ViewUpdateTranslator<D> updateListener) {
14 this.updateListener = updateListener; 14 this.updateListener = updateListener;
15 } 15 }
16 16
17 public ViewUpdateTranslator<D> getUpdateListener() { 17 public ViewUpdateTranslator<D> getUpdateListener() {
18 return updateListener; 18 return updateListener;
19 } 19 }
20 20
21 public boolean hasChange() { 21 public boolean hasChanges() {
22 return ! buffer.isEmpty(); 22 return !buffer.isEmpty();
23 } 23 }
24 24
25 public void addChange(Tuple tuple, D oldValue, D newValue) { 25 public void addChange(Tuple tuple, D oldValue, D newValue) {
26 if(oldValue != newValue) { 26 if (oldValue != newValue) {
27 Object[] oldTuple = updateListener.isMatching(tuple, oldValue); 27 Object[] oldTuple = updateListener.isMatching(tuple, oldValue);
28 Object[] newTuple = updateListener.isMatching(tuple, newValue); 28 Object[] newTuple = updateListener.isMatching(tuple, newValue);
29 if(!Arrays.equals(oldTuple, newTuple)) { 29 if (!Arrays.equals(oldTuple, newTuple)) {
30 if(oldTuple != null) { 30 if (oldTuple != null) {
31 buffer.add(new ViewUpdate(oldTuple, false)); 31 buffer.add(new ViewUpdate(oldTuple, false));
32 } 32 }
33 if(newTuple != null) { 33 if (newTuple != null) {
34 buffer.add(new ViewUpdate(newTuple, true)); 34 buffer.add(new ViewUpdate(newTuple, true));
35 } 35 }
36 } 36 }
37 } 37 }
38 } 38 }
39 39
40 public void flush() { 40 public void flush() {
41 for (ViewUpdate viewChange : buffer) { 41 for (ViewUpdate viewChange : buffer) {
42 updateListener.processChange(viewChange); 42 updateListener.processChange(viewChange);
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateTranslator.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java
index 1c210c5f..2f7f9a9c 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/ViewUpdateTranslator.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java
@@ -1,38 +1,44 @@
1package tools.refinery.store.query.internal; 1package tools.refinery.store.query.viatra.internal.viewupdate;
2
3import java.util.Objects;
4 2
5import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; 3import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener;
6import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 4import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple;
7import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 5import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
8
9import tools.refinery.store.model.Tuple; 6import tools.refinery.store.model.Tuple;
10import tools.refinery.store.query.view.RelationView; 7import tools.refinery.store.query.view.RelationView;
11 8
9import java.util.Objects;
10
12public class ViewUpdateTranslator<D> { 11public class ViewUpdateTranslator<D> {
13 final RelationView<D> key; 12 private final RelationView<D> key;
14 final ITuple filter; 13
15 final IQueryRuntimeContextListener listener; 14 private final ITuple filter;
16 15
16 private final IQueryRuntimeContextListener listener;
17
17 public ViewUpdateTranslator(RelationView<D> key, ITuple filter, IQueryRuntimeContextListener listener) { 18 public ViewUpdateTranslator(RelationView<D> key, ITuple filter, IQueryRuntimeContextListener listener) {
18 super(); 19 super();
19 this.key = key; 20 this.key = key;
20 this.filter = filter; 21 this.filter = filter;
21 this.listener = listener; 22 this.listener = listener;
22 } 23 }
23 24
25 public boolean equals(RelationView<?> relationView, ITuple seed, IQueryRuntimeContextListener listener) {
26 return key == relationView && filter.equals(seed) && this.listener == listener;
27 }
28
24 public void processChange(ViewUpdate change) { 29 public void processChange(ViewUpdate change) {
25 listener.update(key, Tuples.flatTupleOf(change.tuple()), change.isInsertion()); 30 listener.update(key, Tuples.flatTupleOf(change.tuple()), change.isInsertion());
26 } 31 }
27 32
28 public Object[] isMatching(Tuple tuple, D value){ 33 public Object[] isMatching(Tuple tuple, D value) {
29 return isMatching(key.getWrappedKey().transform(tuple, value), filter); 34 return isMatching(key.getWrappedKey().transform(tuple, value), filter);
30 } 35 }
36
31 @SuppressWarnings("squid:S1168") 37 @SuppressWarnings("squid:S1168")
32 private Object[] isMatching(Object[] tuple, ITuple filter) { 38 private Object[] isMatching(Object[] tuple, ITuple filter) {
33 for(int i = 0; i<filter.getSize(); i++) { 39 for (int i = 0; i < filter.getSize(); i++) {
34 final Object filterObject = filter.get(i); 40 final Object filterObject = filter.get(i);
35 if(filterObject != null && !filterObject.equals(tuple[i])) { 41 if (filterObject != null && !filterObject.equals(tuple[i])) {
36 return null; 42 return null;
37 } 43 }
38 } 44 }
@@ -48,9 +54,8 @@ public class ViewUpdateTranslator<D> {
48 public boolean equals(Object obj) { 54 public boolean equals(Object obj) {
49 if (this == obj) 55 if (this == obj)
50 return true; 56 return true;
51 if (!(obj instanceof ViewUpdateTranslator)) 57 if (!(obj instanceof ViewUpdateTranslator<?> other))
52 return false; 58 return false;
53 ViewUpdateTranslator<?> other = (ViewUpdateTranslator<?>) obj;
54 return Objects.equals(filter, other.filter) && Objects.equals(key, other.key) 59 return Objects.equals(filter, other.filter) && Objects.equals(key, other.key)
55 && Objects.equals(listener, other.listener); 60 && Objects.equals(listener, other.listener);
56 } 61 }
diff --git a/subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java
index 02381bcd..4307ab6b 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTest.java
+++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java
@@ -1,64 +1,37 @@
1package tools.refinery.store.query.test; 1package tools.refinery.store.query.viatra.tests;
2
3import static org.junit.jupiter.api.Assertions.assertEquals;
4
5import java.util.ArrayList;
6import java.util.Arrays;
7import java.util.Collections;
8import java.util.HashSet;
9import java.util.List;
10import java.util.Set;
11import java.util.stream.Stream;
12 2
13import org.junit.jupiter.api.Test; 3import org.junit.jupiter.api.Test;
14
15import tools.refinery.store.model.Tuple; 4import tools.refinery.store.model.Tuple;
16import tools.refinery.store.model.representation.Relation; 5import tools.refinery.store.model.representation.Relation;
17import tools.refinery.store.model.representation.TruthValue; 6import tools.refinery.store.model.representation.TruthValue;
18import tools.refinery.store.query.QueriableModel; 7import tools.refinery.store.query.QueryableModel;
19import tools.refinery.store.query.QueriableModelStore; 8import tools.refinery.store.query.QueryableModelStore;
20import tools.refinery.store.query.QueriableModelStoreImpl; 9import tools.refinery.store.query.building.*;
21import tools.refinery.store.query.building.DNFAnd; 10import tools.refinery.store.query.viatra.ViatraQueryableModelStore;
22import tools.refinery.store.query.building.DNFPredicate;
23import tools.refinery.store.query.building.EquivalenceAtom;
24import tools.refinery.store.query.building.PredicateAtom;
25import tools.refinery.store.query.building.RelationAtom;
26import tools.refinery.store.query.building.Variable;
27import tools.refinery.store.query.view.FilteredRelationView; 11import tools.refinery.store.query.view.FilteredRelationView;
28import tools.refinery.store.query.view.KeyOnlyRelationView; 12import tools.refinery.store.query.view.KeyOnlyRelationView;
29import tools.refinery.store.query.view.RelationView; 13import tools.refinery.store.query.view.RelationView;
30 14
31class QueryTest { 15import java.util.*;
32 16import java.util.stream.Stream;
33 static void compareMatchSets(Stream<Object[]> matchSet, Set<List<Tuple>> expected) {
34 Set<List<Tuple>> translatedMatchSet = new HashSet<>();
35 var interator = matchSet.iterator();
36 while (interator.hasNext()) {
37 var element = interator.next();
38 List<Tuple> elementToTranslatedMatchSet = new ArrayList<>();
39 for (int i = 0; i < element.length; i++) {
40 elementToTranslatedMatchSet.add((Tuple) element[i]);
41 }
42 translatedMatchSet.add(elementToTranslatedMatchSet);
43 }
44 17
45 assertEquals(expected, translatedMatchSet); 18import static org.junit.jupiter.api.Assertions.assertEquals;
46 }
47 19
20class QueryTest {
48 @Test 21 @Test
49 void typeConstraintTest() { 22 void typeConstraintTest() {
50 Relation<Boolean> person = new Relation<>("Person", 1, false); 23 Relation<Boolean> person = new Relation<>("Person", 1, false);
51 Relation<Boolean> asset = new Relation<>("Asset", 1, false); 24 Relation<Boolean> asset = new Relation<>("Asset", 1, false);
52 RelationView<Boolean> persionView = new KeyOnlyRelationView(person); 25 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
53 26
54 List<Variable> parameters = Arrays.asList(new Variable("p1")); 27 List<Variable> parameters = List.of(new Variable("p1"));
55 RelationAtom personRelationAtom = new RelationAtom(persionView, parameters); 28 RelationAtom personRelationAtom = new RelationAtom(personView, parameters);
56 DNFAnd clause = new DNFAnd(Collections.emptySet(), Arrays.asList(personRelationAtom)); 29 DNFAnd clause = new DNFAnd(Collections.emptySet(), List.of(personRelationAtom));
57 DNFPredicate predicate = new DNFPredicate("TypeConstraint", parameters, Arrays.asList(clause)); 30 DNFPredicate predicate = new DNFPredicate("TypeConstraint", parameters, List.of(clause));
58 31
59 QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, asset), Set.of(persionView), 32 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, asset), Set.of(personView),
60 Set.of(predicate)); 33 Set.of(predicate));
61 QueriableModel model = store.createModel(); 34 QueryableModel model = store.createModel();
62 35
63 model.put(person, Tuple.of(0), true); 36 model.put(person, Tuple.of(0), true);
64 model.put(person, Tuple.of(1), true); 37 model.put(person, Tuple.of(1), true);
@@ -74,23 +47,23 @@ class QueryTest {
74 void relationConstraintTest() { 47 void relationConstraintTest() {
75 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false); 48 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
76 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE); 49 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
77 RelationView<Boolean> persionView = new KeyOnlyRelationView(person); 50 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
78 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must()); 51 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
79 52
80 Variable p1 = new Variable("p1"); 53 Variable p1 = new Variable("p1");
81 Variable p2 = new Variable("p2"); 54 Variable p2 = new Variable("p2");
82 List<Variable> parameters = Arrays.asList(p1, p2); 55 List<Variable> parameters = Arrays.asList(p1, p2);
83 56
84 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); 57 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1));
85 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); 58 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2));
86 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 59 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
87 DNFAnd clause = new DNFAnd(Collections.emptySet(), 60 DNFAnd clause = new DNFAnd(Collections.emptySet(),
88 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); 61 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom));
89 DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); 62 DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause));
90 63
91 QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), 64 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
92 Set.of(persionView, friendMustView), Set.of(predicate)); 65 Set.of(personView, friendMustView), Set.of(predicate));
93 QueriableModel model = store.createModel(); 66 QueryableModel model = store.createModel();
94 67
95 assertEquals(0, model.countResults(predicate)); 68 assertEquals(0, model.countResults(predicate));
96 69
@@ -113,24 +86,24 @@ class QueryTest {
113 void andTest() { 86 void andTest() {
114 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false); 87 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
115 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE); 88 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
116 RelationView<Boolean> persionView = new KeyOnlyRelationView(person); 89 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
117 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must()); 90 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
118 91
119 Variable p1 = new Variable("p1"); 92 Variable p1 = new Variable("p1");
120 Variable p2 = new Variable("p2"); 93 Variable p2 = new Variable("p2");
121 List<Variable> parameters = Arrays.asList(p1, p2); 94 List<Variable> parameters = Arrays.asList(p1, p2);
122 95
123 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); 96 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1));
124 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); 97 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2));
125 RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 98 RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
126 RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p2, p1)); 99 RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p2, p1));
127 DNFAnd clause = new DNFAnd(Collections.emptySet(), 100 DNFAnd clause = new DNFAnd(Collections.emptySet(),
128 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom1, friendRelationAtom2)); 101 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom1, friendRelationAtom2));
129 DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); 102 DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause));
130 103
131 QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), 104 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
132 Set.of(persionView, friendMustView), Set.of(predicate)); 105 Set.of(personView, friendMustView), Set.of(predicate));
133 QueriableModel model = store.createModel(); 106 QueryableModel model = store.createModel();
134 107
135 assertEquals(0, model.countResults(predicate)); 108 assertEquals(0, model.countResults(predicate));
136 109
@@ -162,23 +135,23 @@ class QueryTest {
162 void existTest() { 135 void existTest() {
163 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false); 136 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
164 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE); 137 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
165 RelationView<Boolean> persionView = new KeyOnlyRelationView(person); 138 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
166 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must()); 139 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
167 140
168 Variable p1 = new Variable("p1"); 141 Variable p1 = new Variable("p1");
169 Variable p2 = new Variable("p2"); 142 Variable p2 = new Variable("p2");
170 List<Variable> parameters = Arrays.asList(p1); 143 List<Variable> parameters = List.of(p1);
171 144
172 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); 145 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1));
173 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); 146 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2));
174 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 147 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
175 DNFAnd clause = new DNFAnd(Set.of(p2), 148 DNFAnd clause = new DNFAnd(Set.of(p2),
176 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); 149 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom));
177 DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); 150 DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause));
178 151
179 QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), 152 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
180 Set.of(persionView, friendMustView), Set.of(predicate)); 153 Set.of(personView, friendMustView), Set.of(predicate));
181 QueriableModel model = store.createModel(); 154 QueryableModel model = store.createModel();
182 155
183 assertEquals(0, model.countResults(predicate)); 156 assertEquals(0, model.countResults(predicate));
184 157
@@ -201,7 +174,7 @@ class QueryTest {
201 Relation<Boolean> person = new Relation<>("Person", 1, false); 174 Relation<Boolean> person = new Relation<>("Person", 1, false);
202 Relation<Boolean> animal = new Relation<>("Animal", 1, false); 175 Relation<Boolean> animal = new Relation<>("Animal", 1, false);
203 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE); 176 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
204 RelationView<Boolean> persionView = new KeyOnlyRelationView(person); 177 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
205 RelationView<Boolean> animalView = new KeyOnlyRelationView(animal); 178 RelationView<Boolean> animalView = new KeyOnlyRelationView(animal);
206 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must()); 179 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
207 180
@@ -210,15 +183,15 @@ class QueryTest {
210 List<Variable> parameters = Arrays.asList(p1, p2); 183 List<Variable> parameters = Arrays.asList(p1, p2);
211 184
212 // Person-Person friendship 185 // Person-Person friendship
213 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); 186 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1));
214 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); 187 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2));
215 RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 188 RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
216 DNFAnd clause1 = new DNFAnd(Collections.emptySet(), 189 DNFAnd clause1 = new DNFAnd(Collections.emptySet(),
217 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom1)); 190 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom1));
218 191
219 // Animal-Animal friendship 192 // Animal-Animal friendship
220 RelationAtom animalRelationAtom1 = new RelationAtom(animalView, Arrays.asList(p1)); 193 RelationAtom animalRelationAtom1 = new RelationAtom(animalView, List.of(p1));
221 RelationAtom animalRelationAtom2 = new RelationAtom(animalView, Arrays.asList(p2)); 194 RelationAtom animalRelationAtom2 = new RelationAtom(animalView, List.of(p2));
222 RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 195 RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
223 DNFAnd clause2 = new DNFAnd(Collections.emptySet(), 196 DNFAnd clause2 = new DNFAnd(Collections.emptySet(),
224 Arrays.asList(animalRelationAtom1, animalRelationAtom2, friendRelationAtom2)); 197 Arrays.asList(animalRelationAtom1, animalRelationAtom2, friendRelationAtom2));
@@ -227,9 +200,9 @@ class QueryTest {
227 200
228 DNFPredicate predicate = new DNFPredicate("Or", parameters, Arrays.asList(clause1, clause2)); 201 DNFPredicate predicate = new DNFPredicate("Or", parameters, Arrays.asList(clause1, clause2));
229 202
230 QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, animal, friend), 203 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, animal, friend),
231 Set.of(persionView, animalView, friendMustView), Set.of(predicate)); 204 Set.of(personView, animalView, friendMustView), Set.of(predicate));
232 QueriableModel model = store.createModel(); 205 QueryableModel model = store.createModel();
233 206
234 model.put(person, Tuple.of(0), true); 207 model.put(person, Tuple.of(0), true);
235 model.put(person, Tuple.of(1), true); 208 model.put(person, Tuple.of(1), true);
@@ -249,21 +222,21 @@ class QueryTest {
249 @Test 222 @Test
250 void equalityTest() { 223 void equalityTest() {
251 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false); 224 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
252 RelationView<Boolean> persionView = new KeyOnlyRelationView(person); 225 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
253 226
254 Variable p1 = new Variable("p1"); 227 Variable p1 = new Variable("p1");
255 Variable p2 = new Variable("p2"); 228 Variable p2 = new Variable("p2");
256 List<Variable> parameters = Arrays.asList(p1, p2); 229 List<Variable> parameters = Arrays.asList(p1, p2);
257 230
258 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); 231 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1));
259 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); 232 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2));
260 EquivalenceAtom equivalenceAtom = new EquivalenceAtom(true, p1, p2); 233 EquivalenceAtom equivalenceAtom = new EquivalenceAtom(true, p1, p2);
261 DNFAnd clause = new DNFAnd(Collections.emptySet(), 234 DNFAnd clause = new DNFAnd(Collections.emptySet(),
262 Arrays.asList(personRelationAtom1, personRelationAtom2, equivalenceAtom)); 235 Arrays.asList(personRelationAtom1, personRelationAtom2, equivalenceAtom));
263 DNFPredicate predicate = new DNFPredicate("Equality", parameters, Arrays.asList(clause)); 236 DNFPredicate predicate = new DNFPredicate("Equality", parameters, List.of(clause));
264 237
265 QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person), Set.of(persionView), Set.of(predicate)); 238 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person), Set.of(personView), Set.of(predicate));
266 QueriableModel model = store.createModel(); 239 QueryableModel model = store.createModel();
267 240
268 model.put(person, Tuple.of(0), true); 241 model.put(person, Tuple.of(0), true);
269 model.put(person, Tuple.of(1), true); 242 model.put(person, Tuple.of(1), true);
@@ -279,7 +252,7 @@ class QueryTest {
279 void inequalityTest() { 252 void inequalityTest() {
280 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false); 253 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
281 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE); 254 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
282 RelationView<Boolean> persionView = new KeyOnlyRelationView(person); 255 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
283 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must()); 256 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
284 257
285 Variable p1 = new Variable("p1"); 258 Variable p1 = new Variable("p1");
@@ -287,18 +260,18 @@ class QueryTest {
287 Variable p3 = new Variable("p3"); 260 Variable p3 = new Variable("p3");
288 List<Variable> parameters = Arrays.asList(p1, p2, p3); 261 List<Variable> parameters = Arrays.asList(p1, p2, p3);
289 262
290 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); 263 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1));
291 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); 264 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2));
292 RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p3)); 265 RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p3));
293 RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p2, p3)); 266 RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p2, p3));
294 EquivalenceAtom inequivalenceAtom = new EquivalenceAtom(false, p1, p2); 267 EquivalenceAtom inequivalenceAtom = new EquivalenceAtom(false, p1, p2);
295 DNFAnd clause = new DNFAnd(Collections.emptySet(), Arrays.asList(personRelationAtom1, personRelationAtom2, 268 DNFAnd clause = new DNFAnd(Collections.emptySet(), Arrays.asList(personRelationAtom1, personRelationAtom2,
296 friendRelationAtom1, friendRelationAtom2, inequivalenceAtom)); 269 friendRelationAtom1, friendRelationAtom2, inequivalenceAtom));
297 DNFPredicate predicate = new DNFPredicate("Inequality", parameters, Arrays.asList(clause)); 270 DNFPredicate predicate = new DNFPredicate("Inequality", parameters, List.of(clause));
298 271
299 QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), 272 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
300 Set.of(persionView, friendMustView), Set.of(predicate)); 273 Set.of(personView, friendMustView), Set.of(predicate));
301 QueriableModel model = store.createModel(); 274 QueryableModel model = store.createModel();
302 275
303 model.put(person, Tuple.of(0), true); 276 model.put(person, Tuple.of(0), true);
304 model.put(person, Tuple.of(1), true); 277 model.put(person, Tuple.of(1), true);
@@ -316,33 +289,33 @@ class QueryTest {
316 void patternCallTest() { 289 void patternCallTest() {
317 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false); 290 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
318 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE); 291 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
319 RelationView<Boolean> persionView = new KeyOnlyRelationView(person); 292 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
320 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must()); 293 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
321 294
322 Variable p1 = new Variable("p1"); 295 Variable p1 = new Variable("p1");
323 Variable p2 = new Variable("p2"); 296 Variable p2 = new Variable("p2");
324 List<Variable> parameters = Arrays.asList(p1, p2); 297 List<Variable> parameters = Arrays.asList(p1, p2);
325 298
326 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); 299 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1));
327 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); 300 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2));
328 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 301 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
329 DNFAnd clause = new DNFAnd(Collections.emptySet(), 302 DNFAnd clause = new DNFAnd(Collections.emptySet(),
330 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); 303 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom));
331 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); 304 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause));
332 305
333 Variable p3 = new Variable("p3"); 306 Variable p3 = new Variable("p3");
334 Variable p4 = new Variable("p4"); 307 Variable p4 = new Variable("p4");
335 List<Variable> substitution = Arrays.asList(p3, p4); 308 List<Variable> substitution = Arrays.asList(p3, p4);
336 RelationAtom personRelationAtom3 = new RelationAtom(persionView, Arrays.asList(p3)); 309 RelationAtom personRelationAtom3 = new RelationAtom(personView, List.of(p3));
337 RelationAtom personRelationAtom4 = new RelationAtom(persionView, Arrays.asList(p4)); 310 RelationAtom personRelationAtom4 = new RelationAtom(personView, List.of(p4));
338 PredicateAtom friendPredicateAtom = new PredicateAtom(true, false, friendPredicate, substitution); 311 PredicateAtom friendPredicateAtom = new PredicateAtom(true, false, friendPredicate, substitution);
339 DNFAnd patternCallClause = new DNFAnd(Collections.emptySet(), 312 DNFAnd patternCallClause = new DNFAnd(Collections.emptySet(),
340 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); 313 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom));
341 DNFPredicate predicate = new DNFPredicate("PatternCall", substitution, Arrays.asList(patternCallClause)); 314 DNFPredicate predicate = new DNFPredicate("PatternCall", substitution, List.of(patternCallClause));
342 315
343 QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), 316 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
344 Set.of(persionView, friendMustView), Set.of(friendPredicate, predicate)); 317 Set.of(personView, friendMustView), Set.of(friendPredicate, predicate));
345 QueriableModel model = store.createModel(); 318 QueryableModel model = store.createModel();
346 319
347 model.put(person, Tuple.of(0), true); 320 model.put(person, Tuple.of(0), true);
348 model.put(person, Tuple.of(1), true); 321 model.put(person, Tuple.of(1), true);
@@ -360,34 +333,34 @@ class QueryTest {
360 void negativePatternCallTest() { 333 void negativePatternCallTest() {
361 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false); 334 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
362 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE); 335 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
363 RelationView<Boolean> persionView = new KeyOnlyRelationView(person); 336 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
364 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must()); 337 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
365 338
366 Variable p1 = new Variable("p1"); 339 Variable p1 = new Variable("p1");
367 Variable p2 = new Variable("p2"); 340 Variable p2 = new Variable("p2");
368 List<Variable> parameters = Arrays.asList(p1, p2); 341 List<Variable> parameters = Arrays.asList(p1, p2);
369 342
370 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); 343 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1));
371 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); 344 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2));
372 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 345 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
373 DNFAnd clause = new DNFAnd(Collections.emptySet(), 346 DNFAnd clause = new DNFAnd(Collections.emptySet(),
374 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); 347 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom));
375 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); 348 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause));
376 349
377 Variable p3 = new Variable("p3"); 350 Variable p3 = new Variable("p3");
378 Variable p4 = new Variable("p4"); 351 Variable p4 = new Variable("p4");
379 List<Variable> substitution = Arrays.asList(p3, p4); 352 List<Variable> substitution = Arrays.asList(p3, p4);
380 RelationAtom personRelationAtom3 = new RelationAtom(persionView, Arrays.asList(p3)); 353 RelationAtom personRelationAtom3 = new RelationAtom(personView, List.of(p3));
381 RelationAtom personRelationAtom4 = new RelationAtom(persionView, Arrays.asList(p4)); 354 RelationAtom personRelationAtom4 = new RelationAtom(personView, List.of(p4));
382 PredicateAtom friendPredicateAtom = new PredicateAtom(false, false, friendPredicate, substitution); 355 PredicateAtom friendPredicateAtom = new PredicateAtom(false, false, friendPredicate, substitution);
383 DNFAnd negativePatternCallClause = new DNFAnd(Collections.emptySet(), 356 DNFAnd negativePatternCallClause = new DNFAnd(Collections.emptySet(),
384 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); 357 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom));
385 DNFPredicate predicate = new DNFPredicate("NegativePatternCall", substitution, 358 DNFPredicate predicate = new DNFPredicate("NegativePatternCall", substitution,
386 Arrays.asList(negativePatternCallClause)); 359 List.of(negativePatternCallClause));
387 360
388 QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), 361 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
389 Set.of(persionView, friendMustView), Set.of(friendPredicate, predicate)); 362 Set.of(personView, friendMustView), Set.of(friendPredicate, predicate));
390 QueriableModel model = store.createModel(); 363 QueryableModel model = store.createModel();
391 364
392 model.put(person, Tuple.of(0), true); 365 model.put(person, Tuple.of(0), true);
393 model.put(person, Tuple.of(1), true); 366 model.put(person, Tuple.of(1), true);
@@ -404,42 +377,56 @@ class QueryTest {
404 void transitivePatternCallTest() { 377 void transitivePatternCallTest() {
405 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false); 378 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
406 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE); 379 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
407 RelationView<Boolean> persionView = new KeyOnlyRelationView(person); 380 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
408 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must()); 381 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
409 382
410 Variable p1 = new Variable("p1"); 383 Variable p1 = new Variable("p1");
411 Variable p2 = new Variable("p2"); 384 Variable p2 = new Variable("p2");
412 List<Variable> parameters = Arrays.asList(p1, p2); 385 List<Variable> parameters = Arrays.asList(p1, p2);
413 386
414 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1)); 387 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1));
415 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2)); 388 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2));
416 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 389 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
417 DNFAnd clause = new DNFAnd(Collections.emptySet(), 390 DNFAnd clause = new DNFAnd(Collections.emptySet(),
418 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); 391 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom));
419 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause)); 392 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause));
420 393
421 Variable p3 = new Variable("p3"); 394 Variable p3 = new Variable("p3");
422 Variable p4 = new Variable("p4"); 395 Variable p4 = new Variable("p4");
423 List<Variable> substitution = Arrays.asList(p3, p4); 396 List<Variable> substitution = Arrays.asList(p3, p4);
424 RelationAtom personRelationAtom3 = new RelationAtom(persionView, Arrays.asList(p3)); 397 RelationAtom personRelationAtom3 = new RelationAtom(personView, List.of(p3));
425 RelationAtom personRelationAtom4 = new RelationAtom(persionView, Arrays.asList(p4)); 398 RelationAtom personRelationAtom4 = new RelationAtom(personView, List.of(p4));
426 PredicateAtom friendPredicateAtom = new PredicateAtom(true, true, friendPredicate, substitution); 399 PredicateAtom friendPredicateAtom = new PredicateAtom(true, true, friendPredicate, substitution);
427 DNFAnd patternCallClause = new DNFAnd(Collections.emptySet(), 400 DNFAnd patternCallClause = new DNFAnd(Collections.emptySet(),
428 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); 401 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom));
429 DNFPredicate predicate = new DNFPredicate("TransitivePatternCall", substitution, 402 DNFPredicate predicate = new DNFPredicate("TransitivePatternCall", substitution,
430 Arrays.asList(patternCallClause)); 403 List.of(patternCallClause));
431 404
432 QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, friend), 405 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
433 Set.of(persionView, friendMustView), Set.of(friendPredicate, predicate)); 406 Set.of(personView, friendMustView), Set.of(friendPredicate, predicate));
434 QueriableModel model = store.createModel(); 407 QueryableModel model = store.createModel();
435 408
436 model.put(person, Tuple.of(0), true); 409 model.put(person, Tuple.of(0), true);
437 model.put(person, Tuple.of(1), true); 410 model.put(person, Tuple.of(1), true);
438 model.put(person, Tuple.of(2), true); 411 model.put(person, Tuple.of(2), true);
439 model.put(friend, Tuple.of(0, 1), TruthValue.TRUE); 412 model.put(friend, Tuple.of(0, 1), TruthValue.TRUE);
440 model.put(friend, Tuple.of(1, 2), TruthValue.TRUE); 413 model.put(friend, Tuple.of(1, 2), TruthValue.TRUE);
441 414
442 model.flushChanges(); 415 model.flushChanges();
443 assertEquals(3, model.countResults(predicate)); 416 assertEquals(3, model.countResults(predicate));
444 } 417 }
445} \ No newline at end of file 418 static void compareMatchSets(Stream<Object[]> matchSet, Set<List<Tuple>> expected) {
419 Set<List<Tuple>> translatedMatchSet = new HashSet<>();
420 var iterator = matchSet.iterator();
421 while (iterator.hasNext()) {
422 var element = iterator.next();
423 List<Tuple> elementToTranslatedMatchSet = new ArrayList<>();
424 for (Object o : element) {
425 elementToTranslatedMatchSet.add((Tuple) o);
426 }
427 translatedMatchSet.add(elementToTranslatedMatchSet);
428 }
429
430 assertEquals(expected, translatedMatchSet);
431 }
432}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTransactionTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java
index e72186b9..613d0074 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/query/test/QueryTransactionTest.java
+++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java
@@ -1,41 +1,39 @@
1package tools.refinery.store.query.test; 1package tools.refinery.store.query.viatra.tests;
2
3import static org.junit.jupiter.api.Assertions.assertEquals;
4
5import java.util.Arrays;
6import java.util.Collections;
7import java.util.List;
8import java.util.Set;
9 2
10import org.junit.jupiter.api.Test; 3import org.junit.jupiter.api.Test;
11
12import tools.refinery.store.model.Tuple; 4import tools.refinery.store.model.Tuple;
13import tools.refinery.store.model.representation.Relation; 5import tools.refinery.store.model.representation.Relation;
14import tools.refinery.store.query.QueriableModel; 6import tools.refinery.store.query.QueryableModel;
15import tools.refinery.store.query.QueriableModelStore; 7import tools.refinery.store.query.QueryableModelStore;
16import tools.refinery.store.query.QueriableModelStoreImpl;
17import tools.refinery.store.query.building.DNFAnd; 8import tools.refinery.store.query.building.DNFAnd;
18import tools.refinery.store.query.building.DNFPredicate; 9import tools.refinery.store.query.building.DNFPredicate;
19import tools.refinery.store.query.building.RelationAtom; 10import tools.refinery.store.query.building.RelationAtom;
20import tools.refinery.store.query.building.Variable; 11import tools.refinery.store.query.building.Variable;
12import tools.refinery.store.query.viatra.ViatraQueryableModelStore;
21import tools.refinery.store.query.view.KeyOnlyRelationView; 13import tools.refinery.store.query.view.KeyOnlyRelationView;
22import tools.refinery.store.query.view.RelationView; 14import tools.refinery.store.query.view.RelationView;
23 15
16import java.util.Collections;
17import java.util.List;
18import java.util.Set;
19
20import static org.junit.jupiter.api.Assertions.assertEquals;
21
24class QueryTransactionTest { 22class QueryTransactionTest {
25 @Test 23 @Test
26 void flushTest() { 24 void flushTest() {
27 Relation<Boolean> person = new Relation<>("Person", 1, false); 25 Relation<Boolean> person = new Relation<>("Person", 1, false);
28 Relation<Boolean> asset = new Relation<>("Asset", 1, false); 26 Relation<Boolean> asset = new Relation<>("Asset", 1, false);
29 RelationView<Boolean> persionView = new KeyOnlyRelationView(person); 27 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
30 28
31 List<Variable> parameters = Arrays.asList(new Variable("p1")); 29 List<Variable> parameters = List.of(new Variable("p1"));
32 RelationAtom personRelationAtom = new RelationAtom(persionView, parameters); 30 RelationAtom personRelationAtom = new RelationAtom(personView, parameters);
33 DNFAnd clause = new DNFAnd(Collections.emptySet(), Arrays.asList(personRelationAtom)); 31 DNFAnd clause = new DNFAnd(Collections.emptySet(), List.of(personRelationAtom));
34 DNFPredicate predicate = new DNFPredicate("TypeConstraint", parameters, Arrays.asList(clause)); 32 DNFPredicate predicate = new DNFPredicate("TypeConstraint", parameters, List.of(clause));
35 33
36 QueriableModelStore store = new QueriableModelStoreImpl(Set.of(person, asset), Set.of(persionView), 34 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, asset), Set.of(personView),
37 Set.of(predicate)); 35 Set.of(predicate));
38 QueriableModel model = store.createModel(); 36 QueryableModel model = store.createModel();
39 37
40 assertEquals(0, model.countResults(predicate)); 38 assertEquals(0, model.countResults(predicate));
41 39
@@ -48,10 +46,10 @@ class QueryTransactionTest {
48 46
49 model.flushChanges(); 47 model.flushChanges();
50 assertEquals(2, model.countResults(predicate)); 48 assertEquals(2, model.countResults(predicate));
51 49
52 model.put(person, Tuple.of(4), true); 50 model.put(person, Tuple.of(4), true);
53 assertEquals(2, model.countResults(predicate)); 51 assertEquals(2, model.countResults(predicate));
54 52
55 model.flushChanges(); 53 model.flushChanges();
56 assertEquals(3, model.countResults(predicate)); 54 assertEquals(3, model.countResults(predicate));
57 } 55 }
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModel.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java
index f669b3ed..187abbc2 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModel.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModel.java
@@ -1,15 +1,17 @@
1package tools.refinery.store.query; 1package tools.refinery.store.query;
2 2
3import tools.refinery.store.model.Model;
4import tools.refinery.store.query.building.DNFPredicate;
5
3import java.util.Optional; 6import java.util.Optional;
4import java.util.Set; 7import java.util.Set;
5import java.util.stream.Stream; 8import java.util.stream.Stream;
6 9
7import tools.refinery.store.model.Model; 10public interface QueryableModel extends Model{
8import tools.refinery.store.query.building.DNFPredicate;
9
10public interface QueriableModel extends Model{
11 Set<DNFPredicate> getPredicates(); 11 Set<DNFPredicate> getPredicates();
12 12
13 boolean hasChanges();
14
13 void flushChanges(); 15 void flushChanges();
14 16
15 boolean hasResult(DNFPredicate predicate); 17 boolean hasResult(DNFPredicate predicate);
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStore.java b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
index 3a5b51ff..08efe17c 100644
--- a/subprojects/store/src/main/java/tools/refinery/store/query/QueriableModelStore.java
+++ b/subprojects/store/src/main/java/tools/refinery/store/query/QueryableModelStore.java
@@ -1,23 +1,23 @@
1package tools.refinery.store.query; 1package tools.refinery.store.query;
2 2
3import java.util.Set;
4
5import tools.refinery.store.model.ModelDiffCursor; 3import tools.refinery.store.model.ModelDiffCursor;
6import tools.refinery.store.model.ModelStore; 4import tools.refinery.store.model.ModelStore;
7import tools.refinery.store.model.representation.DataRepresentation; 5import tools.refinery.store.model.representation.DataRepresentation;
8import tools.refinery.store.query.building.DNFPredicate; 6import tools.refinery.store.query.building.DNFPredicate;
9import tools.refinery.store.query.view.RelationView; 7import tools.refinery.store.query.view.RelationView;
10 8
11public interface QueriableModelStore extends ModelStore{ 9import java.util.Set;
10
11public interface QueryableModelStore extends ModelStore{
12 @SuppressWarnings("squid:S1452") 12 @SuppressWarnings("squid:S1452")
13 Set<DataRepresentation<?, ?>> getDataRepresentations(); 13 Set<DataRepresentation<?, ?>> getDataRepresentations();
14 @SuppressWarnings("squid:S1452") 14 @SuppressWarnings("squid:S1452")
15 Set<RelationView<?>> getViews(); 15 Set<RelationView<?>> getViews();
16 Set<DNFPredicate> getPredicates(); 16 Set<DNFPredicate> getPredicates();
17 17
18 QueriableModel createModel(); 18 QueryableModel createModel();
19 QueriableModel createModel(long state); 19 QueryableModel createModel(long state);
20 20
21 Set<Long> getStates(); 21 Set<Long> getStates();
22 ModelDiffCursor getDiffCursor(long from, long to); 22 ModelDiffCursor getDiffCursor(long from, long to);
23} 23}
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
index 1238f1d7..f66245fc 100644
--- 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
@@ -1,35 +1,17 @@
1package tools.refinery.store.query.building; 1package tools.refinery.store.query.building;
2 2
3import tools.refinery.store.query.view.RelationView;
4
5import java.util.ArrayList;
3import java.util.List; 6import java.util.List;
4import java.util.Map; 7import java.util.Map;
5import java.util.Set; 8import java.util.Set;
6 9
7import tools.refinery.store.query.view.FilteredRelationView; 10public record RelationAtom(RelationView<?> view, List<Variable> substitution) implements DNFAtom {
8import tools.refinery.store.query.view.RelationView;
9
10public class RelationAtom implements DNFAtom {
11 RelationView<?> view;
12 List<Variable> substitution;
13
14 public RelationAtom(RelationView<?> view, List<Variable> substitution) { 11 public RelationAtom(RelationView<?> view, List<Variable> substitution) {
15 this.view = view; 12 this.view = view;
16 this.substitution = substitution; 13 // Create a mutable copy of substitution so that unifyVariables can change it.
17 } 14 this.substitution = new ArrayList<>(substitution);
18
19 public RelationView<?> getView() {
20 return view;
21 }
22
23 public void setView(FilteredRelationView<?> view) {
24 this.view = view;
25 }
26
27 public List<Variable> getSubstitution() {
28 return substitution;
29 }
30
31 public void setSubstitution(List<Variable> substitution) {
32 this.substitution = substitution;
33 } 15 }
34 16
35 @Override 17 @Override
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/PredicateResult.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/PredicateResult.java
deleted file mode 100644
index 65d23eb6..00000000
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/PredicateResult.java
+++ /dev/null
@@ -1,24 +0,0 @@
1package tools.refinery.store.query.internal;
2
3import java.util.Optional;
4import java.util.stream.Stream;
5
6public interface PredicateResult {
7
8 boolean hasResult();
9
10 boolean hasResult(Object[] parameters);
11
12 Optional<Object[]> oneResult();
13
14 Optional<Object[]> oneResult(Object[] parameters);
15
16 Stream<Object[]> allResults();
17
18 Stream<Object[]> allResults(Object[] parameters);
19
20 int countResults();
21
22 int countResults(Object[] parameters);
23
24} \ No newline at end of file
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalQueryMetaContext.java b/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalQueryMetaContext.java
deleted file mode 100644
index 05fb0904..00000000
--- a/subprojects/store/src/main/java/tools/refinery/store/query/internal/RelationalQueryMetaContext.java
+++ /dev/null
@@ -1,58 +0,0 @@
1package tools.refinery.store.query.internal;
2
3import java.util.Collection;
4import java.util.Collections;
5import java.util.HashMap;
6import java.util.HashSet;
7import java.util.Map;
8import java.util.Set;
9
10import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContext;
11import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
12import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication;
13
14import tools.refinery.store.query.view.RelationView;
15
16/**
17 * The meta context information for String scopes.
18 */
19public final class RelationalQueryMetaContext extends AbstractQueryMetaContext {
20
21 @Override
22 public boolean isEnumerable(IInputKey key) {
23 ensureValidKey(key);
24 return key.isEnumerable();
25 }
26
27 @Override
28 public boolean isStateless(IInputKey key) {
29 ensureValidKey(key);
30 return key instanceof RelationView<?>;
31 }
32
33 @Override
34 public Collection<InputKeyImplication> getImplications(IInputKey implyingKey) {
35 ensureValidKey(implyingKey);
36 return new HashSet<InputKeyImplication>();
37 }
38
39 @Override
40 public Map<Set<Integer>, Set<Integer>> getFunctionalDependencies(IInputKey key) {
41 ensureValidKey(key);
42 if (key instanceof RelationView) {
43 return new HashMap<Set<Integer>, Set<Integer>>();
44 } else {
45 return Collections.emptyMap();
46 }
47 }
48
49 public void ensureValidKey(IInputKey key) {
50 if (! (key instanceof RelationView<?>))
51 illegalInputKey(key);
52 }
53
54 public void illegalInputKey(IInputKey key) {
55 throw new IllegalArgumentException("The input key " + key + " is not a valid input key.");
56 }
57
58}