diff options
Diffstat (limited to 'subprojects')
22 files changed, 532 insertions, 580 deletions
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 @@ | |||
1 | plugins { | ||
2 | id 'refinery-java-library' | ||
3 | } | ||
4 | |||
5 | configurations.testRuntimeClasspath { | ||
6 | // VIATRA requires log4j 1.x, but we use log4j-over-slf4j instead | ||
7 | exclude group: 'log4j', module: 'log4j' | ||
8 | } | ||
9 | |||
10 | dependencies { | ||
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 @@ | |||
1 | package tools.refinery.store.query; | 1 | package tools.refinery.store.query.viatra; |
2 | |||
3 | import java.util.Collections; | ||
4 | import java.util.HashMap; | ||
5 | import java.util.Map; | ||
6 | import java.util.Set; | ||
7 | 2 | ||
8 | import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; | 3 | import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; |
9 | |||
10 | import tools.refinery.store.model.ModelDiffCursor; | 4 | import tools.refinery.store.model.ModelDiffCursor; |
11 | import tools.refinery.store.model.ModelStore; | 5 | import tools.refinery.store.model.ModelStore; |
12 | import tools.refinery.store.model.ModelStoreImpl; | 6 | import tools.refinery.store.model.ModelStoreImpl; |
13 | import tools.refinery.store.model.representation.DataRepresentation; | 7 | import tools.refinery.store.model.representation.DataRepresentation; |
14 | import tools.refinery.store.query.building.DNFAnd; | 8 | import tools.refinery.store.query.QueryableModel; |
15 | import tools.refinery.store.query.building.DNFAtom; | 9 | import tools.refinery.store.query.QueryableModelStore; |
16 | import tools.refinery.store.query.building.DNFPredicate; | 10 | import tools.refinery.store.query.building.*; |
17 | import tools.refinery.store.query.building.PredicateAtom; | 11 | import tools.refinery.store.query.viatra.internal.ViatraQueryableModel; |
18 | import tools.refinery.store.query.building.RelationAtom; | 12 | import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery; |
19 | import tools.refinery.store.query.internal.DNF2PQuery; | 13 | import tools.refinery.store.query.viatra.internal.RawPatternMatcher; |
20 | import tools.refinery.store.query.internal.QueriableModelImpl; | 14 | import tools.refinery.store.query.viatra.internal.pquery.SimplePQuery; |
21 | import tools.refinery.store.query.internal.RawPatternMatcher; | ||
22 | import tools.refinery.store.query.internal.DNF2PQuery.SimplePQuery; | ||
23 | import tools.refinery.store.query.view.RelationView; | 15 | import tools.refinery.store.query.view.RelationView; |
24 | 16 | ||
25 | public class QueriableModelStoreImpl implements QueriableModelStore { | 17 | import java.util.Collections; |
18 | import java.util.HashMap; | ||
19 | import java.util.Map; | ||
20 | import java.util.Set; | ||
21 | |||
22 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | 1 | package tools.refinery.store.query.viatra.internal; |
2 | |||
3 | import java.util.Optional; | ||
4 | import java.util.stream.Stream; | ||
5 | 2 | ||
6 | import org.eclipse.viatra.query.runtime.api.GenericPatternMatcher; | 3 | import org.eclipse.viatra.query.runtime.api.GenericPatternMatcher; |
7 | import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; | 4 | import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; |
8 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
9 | import org.eclipse.viatra.query.runtime.matchers.tuple.AbstractTuple; | 5 | import org.eclipse.viatra.query.runtime.matchers.tuple.AbstractTuple; |
6 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
10 | 7 | ||
11 | public class RawPatternMatcher extends GenericPatternMatcher implements PredicateResult{ | 8 | import java.util.Optional; |
12 | 9 | import java.util.stream.Stream; | |
10 | |||
11 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | 1 | package tools.refinery.store.query.viatra.internal; |
2 | |||
3 | import java.util.Set; | ||
4 | 2 | ||
5 | import org.apache.log4j.Logger; | 3 | import org.apache.log4j.Logger; |
6 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | 4 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; |
7 | import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; | 5 | import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; |
8 | import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; | 6 | import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; |
9 | import org.eclipse.viatra.query.runtime.api.scope.QueryScope; | 7 | import org.eclipse.viatra.query.runtime.api.scope.QueryScope; |
10 | |||
11 | import tools.refinery.store.model.Model; | 8 | import tools.refinery.store.model.Model; |
12 | import tools.refinery.store.model.Tuple; | 9 | import tools.refinery.store.model.Tuple; |
13 | import tools.refinery.store.model.representation.Relation; | 10 | import tools.refinery.store.model.representation.Relation; |
11 | import tools.refinery.store.query.viatra.internal.context.RelationalEngineContext; | ||
12 | import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; | ||
14 | import tools.refinery.store.query.view.RelationView; | 13 | import tools.refinery.store.query.view.RelationView; |
15 | 14 | ||
16 | public class RelationalScope extends QueryScope{ | 15 | import java.util.Set; |
16 | |||
17 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | 1 | package tools.refinery.store.query.viatra.internal; |
2 | |||
3 | import java.util.HashMap; | ||
4 | import java.util.Map; | ||
5 | import java.util.Optional; | ||
6 | import java.util.Set; | ||
7 | import java.util.stream.Stream; | ||
8 | 2 | ||
9 | import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine; | 3 | import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine; |
10 | import org.eclipse.viatra.query.runtime.api.GenericQueryGroup; | 4 | import org.eclipse.viatra.query.runtime.api.GenericQueryGroup; |
11 | import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; | 5 | import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; |
12 | import org.eclipse.viatra.query.runtime.api.IQueryGroup; | 6 | import org.eclipse.viatra.query.runtime.api.IQueryGroup; |
13 | |||
14 | import tools.refinery.store.map.Cursor; | 7 | import tools.refinery.store.map.Cursor; |
15 | import tools.refinery.store.map.DiffCursor; | 8 | import tools.refinery.store.map.DiffCursor; |
16 | import tools.refinery.store.model.Model; | 9 | import tools.refinery.store.model.Model; |
@@ -18,21 +11,31 @@ import tools.refinery.store.model.ModelDiffCursor; | |||
18 | import tools.refinery.store.model.Tuple; | 11 | import tools.refinery.store.model.Tuple; |
19 | import tools.refinery.store.model.representation.DataRepresentation; | 12 | import tools.refinery.store.model.representation.DataRepresentation; |
20 | import tools.refinery.store.model.representation.Relation; | 13 | import tools.refinery.store.model.representation.Relation; |
21 | import tools.refinery.store.query.QueriableModel; | 14 | import tools.refinery.store.query.QueryableModel; |
22 | import tools.refinery.store.query.QueriableModelStore; | 15 | import tools.refinery.store.query.QueryableModelStore; |
23 | import tools.refinery.store.query.building.DNFPredicate; | 16 | import tools.refinery.store.query.building.DNFPredicate; |
24 | 17 | ||
25 | public class QueriableModelImpl implements QueriableModel { | 18 | import java.util.HashMap; |
26 | protected final QueriableModelStore store; | 19 | import java.util.Map; |
20 | import java.util.Optional; | ||
21 | import java.util.Set; | ||
22 | import java.util.stream.Stream; | ||
23 | |||
24 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | 1 | package tools.refinery.store.query.viatra.internal.context; |
2 | |||
3 | import java.lang.reflect.InvocationTargetException; | ||
4 | import java.util.concurrent.Callable; | ||
5 | 2 | ||
6 | import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; | 3 | import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; |
7 | import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; | 4 | import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; |
8 | import org.eclipse.viatra.query.runtime.api.scope.IInstanceObserver; | 5 | import org.eclipse.viatra.query.runtime.api.scope.IInstanceObserver; |
9 | import org.eclipse.viatra.query.runtime.api.scope.ViatraBaseIndexChangeListener; | 6 | import org.eclipse.viatra.query.runtime.api.scope.ViatraBaseIndexChangeListener; |
10 | 7 | ||
8 | import java.lang.reflect.InvocationTargetException; | ||
9 | import 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 | */ |
14 | public class DummyBaseIndexer implements IBaseIndex{ | 14 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | 1 | package tools.refinery.store.query.viatra.internal.context; |
2 | 2 | ||
3 | import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; | 3 | import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; |
4 | import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; | 4 | import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; |
5 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext; | 5 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext; |
6 | 6 | ||
7 | import tools.refinery.store.model.Model; | 7 | import tools.refinery.store.model.Model; |
8 | import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; | ||
8 | 9 | ||
9 | public class RelationalEngineContext implements IEngineContext{ | 10 | public 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 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.context; | ||
2 | |||
3 | import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContext; | ||
4 | import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; | ||
5 | import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication; | ||
6 | import tools.refinery.store.query.view.RelationView; | ||
7 | |||
8 | import java.util.*; | ||
9 | |||
10 | /** | ||
11 | * The meta context information for String scopes. | ||
12 | */ | ||
13 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | 1 | package tools.refinery.store.query.viatra.internal.context; |
2 | 2 | ||
3 | import static tools.refinery.store.util.CollectionsUtil.filter; | 3 | import org.eclipse.viatra.query.runtime.matchers.context.*; |
4 | import static tools.refinery.store.util.CollectionsUtil.map; | ||
5 | |||
6 | import java.lang.reflect.InvocationTargetException; | ||
7 | import java.util.Iterator; | ||
8 | import java.util.Optional; | ||
9 | import java.util.concurrent.Callable; | ||
10 | |||
11 | import org.eclipse.viatra.query.runtime.base.core.NavigationHelperImpl; | ||
12 | import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; | ||
13 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryMetaContext; | ||
14 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext; | ||
15 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; | ||
16 | import org.eclipse.viatra.query.runtime.matchers.context.IndexingService; | ||
17 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | 4 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; |
18 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | 5 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; |
19 | import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask; | 6 | import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask; |
20 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | 7 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; |
21 | import org.eclipse.viatra.query.runtime.matchers.util.Accuracy; | 8 | import org.eclipse.viatra.query.runtime.matchers.util.Accuracy; |
22 | |||
23 | import tools.refinery.store.model.Model; | 9 | import tools.refinery.store.model.Model; |
10 | import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; | ||
24 | import tools.refinery.store.query.view.RelationView; | 11 | import tools.refinery.store.query.view.RelationView; |
25 | 12 | ||
13 | import java.lang.reflect.InvocationTargetException; | ||
14 | import java.util.Iterator; | ||
15 | import java.util.Optional; | ||
16 | import java.util.concurrent.Callable; | ||
17 | |||
18 | import static tools.refinery.store.util.CollectionsUtil.filter; | ||
19 | import static tools.refinery.store.util.CollectionsUtil.map; | ||
20 | |||
26 | public class RelationalRuntimeContext implements IQueryRuntimeContext { | 21 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | 1 | package tools.refinery.store.query.viatra.internal.pquery; |
2 | 2 | ||
3 | import java.util.ArrayList; | ||
4 | import java.util.HashMap; | ||
5 | import java.util.InputMismatchException; | ||
6 | import java.util.LinkedHashSet; | ||
7 | import java.util.List; | ||
8 | import java.util.Map; | ||
9 | import java.util.Set; | ||
10 | |||
11 | import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; | ||
12 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
13 | import org.eclipse.viatra.query.runtime.api.scope.QueryScope; | ||
14 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
15 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | 3 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; |
16 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | 4 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; |
17 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | 5 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; |
@@ -21,39 +9,35 @@ import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativeP | |||
21 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure; | 9 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure; |
22 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; | 10 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; |
23 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | 11 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; |
24 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.BasePQuery; | ||
25 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | 12 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; |
26 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
27 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | 13 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; |
14 | import tools.refinery.store.query.building.*; | ||
28 | 15 | ||
29 | import tools.refinery.store.query.building.DNFAnd; | 16 | import java.util.*; |
30 | import tools.refinery.store.query.building.DNFAtom; | ||
31 | import tools.refinery.store.query.building.DNFPredicate; | ||
32 | import tools.refinery.store.query.building.EquivalenceAtom; | ||
33 | import tools.refinery.store.query.building.PredicateAtom; | ||
34 | import tools.refinery.store.query.building.RelationAtom; | ||
35 | import tools.refinery.store.query.building.Variable; | ||
36 | 17 | ||
37 | public class DNF2PQuery { | 18 | public 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 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.pquery; | ||
2 | |||
3 | import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; | ||
4 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
5 | import org.eclipse.viatra.query.runtime.api.scope.QueryScope; | ||
6 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
7 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
8 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.BasePQuery; | ||
9 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
10 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
11 | import tools.refinery.store.query.viatra.internal.RawPatternMatcher; | ||
12 | import tools.refinery.store.query.viatra.internal.RelationalScope; | ||
13 | |||
14 | import java.util.LinkedHashSet; | ||
15 | import java.util.List; | ||
16 | import java.util.Set; | ||
17 | |||
18 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | 1 | package tools.refinery.store.query.viatra.internal.viewupdate; |
2 | |||
3 | import java.util.HashMap; | ||
4 | import java.util.HashSet; | ||
5 | import java.util.Map; | ||
6 | import java.util.Set; | ||
7 | 2 | ||
8 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; | 3 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; |
9 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | 4 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; |
10 | |||
11 | import tools.refinery.store.model.Tuple; | 5 | import tools.refinery.store.model.Tuple; |
12 | import tools.refinery.store.model.representation.Relation; | 6 | import tools.refinery.store.model.representation.Relation; |
13 | import tools.refinery.store.query.view.RelationView; | 7 | import tools.refinery.store.query.view.RelationView; |
14 | 8 | ||
9 | import java.util.HashMap; | ||
10 | import java.util.HashSet; | ||
11 | import java.util.Map; | ||
12 | import java.util.Set; | ||
13 | |||
15 | public class ModelUpdateListener { | 14 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | 1 | package tools.refinery.store.query.viatra.internal.viewupdate; |
2 | 2 | ||
3 | import java.util.Arrays; | 3 | import java.util.Arrays; |
4 | import java.util.Objects; | 4 | import 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 @@ | |||
1 | package tools.refinery.store.query.internal; | 1 | package tools.refinery.store.query.viatra.internal.viewupdate; |
2 | |||
3 | import tools.refinery.store.model.Tuple; | ||
2 | 4 | ||
3 | import java.util.ArrayList; | 5 | import java.util.ArrayList; |
4 | import java.util.Arrays; | 6 | import java.util.Arrays; |
5 | import java.util.List; | 7 | import java.util.List; |
6 | 8 | ||
7 | import tools.refinery.store.model.Tuple; | ||
8 | |||
9 | public class ViewUpdateBuffer<D> { | 9 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | 1 | package tools.refinery.store.query.viatra.internal.viewupdate; |
2 | |||
3 | import java.util.Objects; | ||
4 | 2 | ||
5 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; | 3 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; |
6 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | 4 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; |
7 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | 5 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; |
8 | |||
9 | import tools.refinery.store.model.Tuple; | 6 | import tools.refinery.store.model.Tuple; |
10 | import tools.refinery.store.query.view.RelationView; | 7 | import tools.refinery.store.query.view.RelationView; |
11 | 8 | ||
9 | import java.util.Objects; | ||
10 | |||
12 | public class ViewUpdateTranslator<D> { | 11 | public 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 @@ | |||
1 | package tools.refinery.store.query.test; | 1 | package tools.refinery.store.query.viatra.tests; |
2 | |||
3 | import static org.junit.jupiter.api.Assertions.assertEquals; | ||
4 | |||
5 | import java.util.ArrayList; | ||
6 | import java.util.Arrays; | ||
7 | import java.util.Collections; | ||
8 | import java.util.HashSet; | ||
9 | import java.util.List; | ||
10 | import java.util.Set; | ||
11 | import java.util.stream.Stream; | ||
12 | 2 | ||
13 | import org.junit.jupiter.api.Test; | 3 | import org.junit.jupiter.api.Test; |
14 | |||
15 | import tools.refinery.store.model.Tuple; | 4 | import tools.refinery.store.model.Tuple; |
16 | import tools.refinery.store.model.representation.Relation; | 5 | import tools.refinery.store.model.representation.Relation; |
17 | import tools.refinery.store.model.representation.TruthValue; | 6 | import tools.refinery.store.model.representation.TruthValue; |
18 | import tools.refinery.store.query.QueriableModel; | 7 | import tools.refinery.store.query.QueryableModel; |
19 | import tools.refinery.store.query.QueriableModelStore; | 8 | import tools.refinery.store.query.QueryableModelStore; |
20 | import tools.refinery.store.query.QueriableModelStoreImpl; | 9 | import tools.refinery.store.query.building.*; |
21 | import tools.refinery.store.query.building.DNFAnd; | 10 | import tools.refinery.store.query.viatra.ViatraQueryableModelStore; |
22 | import tools.refinery.store.query.building.DNFPredicate; | ||
23 | import tools.refinery.store.query.building.EquivalenceAtom; | ||
24 | import tools.refinery.store.query.building.PredicateAtom; | ||
25 | import tools.refinery.store.query.building.RelationAtom; | ||
26 | import tools.refinery.store.query.building.Variable; | ||
27 | import tools.refinery.store.query.view.FilteredRelationView; | 11 | import tools.refinery.store.query.view.FilteredRelationView; |
28 | import tools.refinery.store.query.view.KeyOnlyRelationView; | 12 | import tools.refinery.store.query.view.KeyOnlyRelationView; |
29 | import tools.refinery.store.query.view.RelationView; | 13 | import tools.refinery.store.query.view.RelationView; |
30 | 14 | ||
31 | class QueryTest { | 15 | import java.util.*; |
32 | 16 | import 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); | 18 | import static org.junit.jupiter.api.Assertions.assertEquals; |
46 | } | ||
47 | 19 | ||
20 | class 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 @@ | |||
1 | package tools.refinery.store.query.test; | 1 | package tools.refinery.store.query.viatra.tests; |
2 | |||
3 | import static org.junit.jupiter.api.Assertions.assertEquals; | ||
4 | |||
5 | import java.util.Arrays; | ||
6 | import java.util.Collections; | ||
7 | import java.util.List; | ||
8 | import java.util.Set; | ||
9 | 2 | ||
10 | import org.junit.jupiter.api.Test; | 3 | import org.junit.jupiter.api.Test; |
11 | |||
12 | import tools.refinery.store.model.Tuple; | 4 | import tools.refinery.store.model.Tuple; |
13 | import tools.refinery.store.model.representation.Relation; | 5 | import tools.refinery.store.model.representation.Relation; |
14 | import tools.refinery.store.query.QueriableModel; | 6 | import tools.refinery.store.query.QueryableModel; |
15 | import tools.refinery.store.query.QueriableModelStore; | 7 | import tools.refinery.store.query.QueryableModelStore; |
16 | import tools.refinery.store.query.QueriableModelStoreImpl; | ||
17 | import tools.refinery.store.query.building.DNFAnd; | 8 | import tools.refinery.store.query.building.DNFAnd; |
18 | import tools.refinery.store.query.building.DNFPredicate; | 9 | import tools.refinery.store.query.building.DNFPredicate; |
19 | import tools.refinery.store.query.building.RelationAtom; | 10 | import tools.refinery.store.query.building.RelationAtom; |
20 | import tools.refinery.store.query.building.Variable; | 11 | import tools.refinery.store.query.building.Variable; |
12 | import tools.refinery.store.query.viatra.ViatraQueryableModelStore; | ||
21 | import tools.refinery.store.query.view.KeyOnlyRelationView; | 13 | import tools.refinery.store.query.view.KeyOnlyRelationView; |
22 | import tools.refinery.store.query.view.RelationView; | 14 | import tools.refinery.store.query.view.RelationView; |
23 | 15 | ||
16 | import java.util.Collections; | ||
17 | import java.util.List; | ||
18 | import java.util.Set; | ||
19 | |||
20 | import static org.junit.jupiter.api.Assertions.assertEquals; | ||
21 | |||
24 | class QueryTransactionTest { | 22 | class 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 @@ | |||
1 | package tools.refinery.store.query; | 1 | package tools.refinery.store.query; |
2 | 2 | ||
3 | import tools.refinery.store.model.Model; | ||
4 | import tools.refinery.store.query.building.DNFPredicate; | ||
5 | |||
3 | import java.util.Optional; | 6 | import java.util.Optional; |
4 | import java.util.Set; | 7 | import java.util.Set; |
5 | import java.util.stream.Stream; | 8 | import java.util.stream.Stream; |
6 | 9 | ||
7 | import tools.refinery.store.model.Model; | 10 | public interface QueryableModel extends Model{ |
8 | import tools.refinery.store.query.building.DNFPredicate; | ||
9 | |||
10 | public 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 @@ | |||
1 | package tools.refinery.store.query; | 1 | package tools.refinery.store.query; |
2 | 2 | ||
3 | import java.util.Set; | ||
4 | |||
5 | import tools.refinery.store.model.ModelDiffCursor; | 3 | import tools.refinery.store.model.ModelDiffCursor; |
6 | import tools.refinery.store.model.ModelStore; | 4 | import tools.refinery.store.model.ModelStore; |
7 | import tools.refinery.store.model.representation.DataRepresentation; | 5 | import tools.refinery.store.model.representation.DataRepresentation; |
8 | import tools.refinery.store.query.building.DNFPredicate; | 6 | import tools.refinery.store.query.building.DNFPredicate; |
9 | import tools.refinery.store.query.view.RelationView; | 7 | import tools.refinery.store.query.view.RelationView; |
10 | 8 | ||
11 | public interface QueriableModelStore extends ModelStore{ | 9 | import java.util.Set; |
10 | |||
11 | public 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 @@ | |||
1 | package tools.refinery.store.query.building; | 1 | package tools.refinery.store.query.building; |
2 | 2 | ||
3 | import tools.refinery.store.query.view.RelationView; | ||
4 | |||
5 | import java.util.ArrayList; | ||
3 | import java.util.List; | 6 | import java.util.List; |
4 | import java.util.Map; | 7 | import java.util.Map; |
5 | import java.util.Set; | 8 | import java.util.Set; |
6 | 9 | ||
7 | import tools.refinery.store.query.view.FilteredRelationView; | 10 | public record RelationAtom(RelationView<?> view, List<Variable> substitution) implements DNFAtom { |
8 | import tools.refinery.store.query.view.RelationView; | ||
9 | |||
10 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | ||
2 | |||
3 | import java.util.Optional; | ||
4 | import java.util.stream.Stream; | ||
5 | |||
6 | public 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 @@ | |||
1 | package tools.refinery.store.query.internal; | ||
2 | |||
3 | import java.util.Collection; | ||
4 | import java.util.Collections; | ||
5 | import java.util.HashMap; | ||
6 | import java.util.HashSet; | ||
7 | import java.util.Map; | ||
8 | import java.util.Set; | ||
9 | |||
10 | import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContext; | ||
11 | import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; | ||
12 | import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication; | ||
13 | |||
14 | import tools.refinery.store.query.view.RelationView; | ||
15 | |||
16 | /** | ||
17 | * The meta context information for String scopes. | ||
18 | */ | ||
19 | public 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 | } | ||