diff options
Diffstat (limited to 'subprojects')
16 files changed, 245 insertions, 159 deletions
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java index 5a02ca08..a63abc3a 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java | |||
@@ -8,10 +8,9 @@ import tools.refinery.store.model.representation.DataRepresentation; | |||
8 | import tools.refinery.store.query.QueryableModel; | 8 | import tools.refinery.store.query.QueryableModel; |
9 | import tools.refinery.store.query.QueryableModelStore; | 9 | import tools.refinery.store.query.QueryableModelStore; |
10 | import tools.refinery.store.query.building.*; | 10 | import tools.refinery.store.query.building.*; |
11 | import tools.refinery.store.query.viatra.internal.RawPatternMatcher; | ||
11 | import tools.refinery.store.query.viatra.internal.ViatraQueryableModel; | 12 | import tools.refinery.store.query.viatra.internal.ViatraQueryableModel; |
12 | import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery; | 13 | import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery; |
13 | import tools.refinery.store.query.viatra.internal.RawPatternMatcher; | ||
14 | import tools.refinery.store.query.viatra.internal.pquery.SimplePQuery; | ||
15 | import tools.refinery.store.query.view.RelationView; | 14 | import tools.refinery.store.query.view.RelationView; |
16 | 15 | ||
17 | import java.util.Collections; | 16 | import java.util.Collections; |
@@ -21,7 +20,9 @@ import java.util.Set; | |||
21 | 20 | ||
22 | public class ViatraQueryableModelStore implements QueryableModelStore { | 21 | public class ViatraQueryableModelStore implements QueryableModelStore { |
23 | protected final ModelStore store; | 22 | protected final ModelStore store; |
23 | |||
24 | protected final Set<RelationView<?>> relationViews; | 24 | protected final Set<RelationView<?>> relationViews; |
25 | |||
25 | protected final Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates; | 26 | protected final Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates; |
26 | 27 | ||
27 | public ViatraQueryableModelStore(ModelStore store, Set<RelationView<?>> relationViews, | 28 | public ViatraQueryableModelStore(ModelStore store, Set<RelationView<?>> relationViews, |
@@ -41,9 +42,9 @@ public class ViatraQueryableModelStore implements QueryableModelStore { | |||
41 | private void validateViews(Set<DataRepresentation<?, ?>> dataRepresentations, Set<RelationView<?>> relationViews) { | 42 | private void validateViews(Set<DataRepresentation<?, ?>> dataRepresentations, Set<RelationView<?>> relationViews) { |
42 | for (RelationView<?> relationView : relationViews) { | 43 | for (RelationView<?> relationView : relationViews) { |
43 | if (!dataRepresentations.contains(relationView.getRepresentation())) { | 44 | if (!dataRepresentations.contains(relationView.getRepresentation())) { |
44 | throw new IllegalArgumentException( | 45 | throw new IllegalArgumentException("%s %s added to %s without a referred representation.".formatted( |
45 | DataRepresentation.class.getSimpleName() + " " + relationView.getStringID() + " added to " | 46 | DataRepresentation.class.getSimpleName(), relationView.getName(), |
46 | + QueryableModelStore.class.getSimpleName() + " without a referred representation."); | 47 | QueryableModelStore.class.getSimpleName())); |
47 | } | 48 | } |
48 | } | 49 | } |
49 | } | 50 | } |
@@ -65,10 +66,10 @@ public class ViatraQueryableModelStore implements QueryableModelStore { | |||
65 | private void validateRelationAtom(Set<RelationView<?>> relationViews, DNFPredicate dnfPredicate, | 66 | private void validateRelationAtom(Set<RelationView<?>> relationViews, DNFPredicate dnfPredicate, |
66 | RelationAtom relationAtom) { | 67 | RelationAtom relationAtom) { |
67 | if (!relationViews.contains(relationAtom.view())) { | 68 | if (!relationViews.contains(relationAtom.view())) { |
68 | throw new IllegalArgumentException(DNFPredicate.class.getSimpleName() + " " | 69 | throw new IllegalArgumentException( |
69 | + dnfPredicate.getUniqueName() + " contains reference to a view of " | 70 | "%s %s contains reference to a view %s that is not in the model.".formatted( |
70 | + relationAtom.view().getRepresentation().getName() | 71 | DNFPredicate.class.getSimpleName(), dnfPredicate.getUniqueName(), |
71 | + " that is not in the model."); | 72 | relationAtom.view().getName())); |
72 | } | 73 | } |
73 | } | 74 | } |
74 | 75 | ||
@@ -76,19 +77,17 @@ public class ViatraQueryableModelStore implements QueryableModelStore { | |||
76 | PredicateAtom predicateAtom) { | 77 | PredicateAtom predicateAtom) { |
77 | if (!predicates.contains(predicateAtom.getReferred())) { | 78 | if (!predicates.contains(predicateAtom.getReferred())) { |
78 | throw new IllegalArgumentException( | 79 | throw new IllegalArgumentException( |
79 | DNFPredicate.class.getSimpleName() + " " + dnfPredicate.getUniqueName() | 80 | "%s %s contains reference to a predicate %s that is not in the model.".formatted( |
80 | + " contains reference to a predicate " | 81 | DNFPredicate.class.getSimpleName(), dnfPredicate.getUniqueName(), |
81 | + predicateAtom.getReferred().getName() | 82 | predicateAtom.getReferred().getName())); |
82 | + "that is not in the model."); | ||
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
86 | private Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> initPredicates(Set<DNFPredicate> predicates) { | 86 | private Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> initPredicates(Set<DNFPredicate> predicates) { |
87 | Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> result = new HashMap<>(); | 87 | Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> result = new HashMap<>(); |
88 | Map<DNFPredicate, SimplePQuery> dnf2PQueryMap = new HashMap<>(); | 88 | var dnf2PQuery = new DNF2PQuery(); |
89 | for (DNFPredicate dnfPredicate : predicates) { | 89 | for (DNFPredicate dnfPredicate : predicates) { |
90 | GenericQuerySpecification<RawPatternMatcher> query = | 90 | GenericQuerySpecification<RawPatternMatcher> query = dnf2PQuery.translate(dnfPredicate).build(); |
91 | DNF2PQuery.translate(dnfPredicate, dnf2PQueryMap).build(); | ||
92 | result.put(dnfPredicate, query); | 91 | result.put(dnfPredicate, query); |
93 | } | 92 | } |
94 | 93 | ||
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java index 882734cb..d32d49ba 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java | |||
@@ -29,5 +29,4 @@ public class RelationalEngineContext implements IEngineContext { | |||
29 | public IQueryRuntimeContext getQueryRuntimeContext() { | 29 | public IQueryRuntimeContext getQueryRuntimeContext() { |
30 | return runtimeContext; | 30 | return runtimeContext; |
31 | } | 31 | } |
32 | |||
33 | } | 32 | } |
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 index 64c23c61..eb3c6fbd 100644 --- 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 | |||
@@ -3,9 +3,11 @@ package tools.refinery.store.query.viatra.internal.context; | |||
3 | import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContext; | 3 | import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContext; |
4 | import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; | 4 | import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; |
5 | import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication; | 5 | import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication; |
6 | import tools.refinery.store.query.view.RelationView; | 6 | import tools.refinery.store.query.viatra.internal.pquery.RelationViewWrapper; |
7 | 7 | ||
8 | import java.util.*; | 8 | import java.util.Collection; |
9 | import java.util.Map; | ||
10 | import java.util.Set; | ||
9 | 11 | ||
10 | /** | 12 | /** |
11 | * The meta context information for String scopes. | 13 | * The meta context information for String scopes. |
@@ -36,9 +38,8 @@ public class RelationalQueryMetaContext extends AbstractQueryMetaContext { | |||
36 | } | 38 | } |
37 | 39 | ||
38 | public void ensureValidKey(IInputKey key) { | 40 | public void ensureValidKey(IInputKey key) { |
39 | if (key instanceof RelationView<?>) { | 41 | if (!(key instanceof RelationViewWrapper)) { |
40 | return; | 42 | throw new IllegalArgumentException("The input key %s is not a valid input key.".formatted(key)); |
41 | } | 43 | } |
42 | throw new IllegalArgumentException("The input key %s is not a valid input key.".formatted(key)); | ||
43 | } | 44 | } |
44 | } | 45 | } |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java index 0bd1b807..c007d630 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java | |||
@@ -7,6 +7,7 @@ import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask; | |||
7 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | 7 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; |
8 | import org.eclipse.viatra.query.runtime.matchers.util.Accuracy; | 8 | import org.eclipse.viatra.query.runtime.matchers.util.Accuracy; |
9 | import tools.refinery.store.model.Model; | 9 | import tools.refinery.store.model.Model; |
10 | import tools.refinery.store.query.viatra.internal.pquery.RelationViewWrapper; | ||
10 | import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; | 11 | import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; |
11 | import tools.refinery.store.query.view.RelationView; | 12 | import tools.refinery.store.query.view.RelationView; |
12 | 13 | ||
@@ -67,7 +68,8 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext { | |||
67 | 68 | ||
68 | @SuppressWarnings("squid:S1452") | 69 | @SuppressWarnings("squid:S1452") |
69 | RelationView<?> checkKey(IInputKey key) { | 70 | RelationView<?> checkKey(IInputKey key) { |
70 | if (key instanceof RelationView<?> relationViewKey) { | 71 | if (key instanceof RelationViewWrapper wrappedKey) { |
72 | var relationViewKey = wrappedKey.getWrappedKey(); | ||
71 | if (modelUpdateListener.containsRelationalView(relationViewKey)) { | 73 | if (modelUpdateListener.containsRelationalView(relationViewKey)) { |
72 | return relationViewKey; | 74 | return relationViewKey; |
73 | } else { | 75 | } else { |
@@ -117,7 +119,7 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext { | |||
117 | } | 119 | } |
118 | 120 | ||
119 | @Override | 121 | @Override |
120 | public Iterable<? extends Object> enumerateValues(IInputKey key, TupleMask seedMask, ITuple seed) { | 122 | public Iterable<?> enumerateValues(IInputKey key, TupleMask seedMask, ITuple seed) { |
121 | return enumerateTuples(key, seedMask, seed); | 123 | return enumerateTuples(key, seedMask, seed); |
122 | } | 124 | } |
123 | 125 | ||
@@ -130,14 +132,14 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext { | |||
130 | @Override | 132 | @Override |
131 | public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { | 133 | public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { |
132 | RelationView<?> relationalKey = checkKey(key); | 134 | RelationView<?> relationalKey = checkKey(key); |
133 | this.modelUpdateListener.addListener(relationalKey, seed, listener); | 135 | this.modelUpdateListener.addListener(key, relationalKey, seed, listener); |
134 | 136 | ||
135 | } | 137 | } |
136 | 138 | ||
137 | @Override | 139 | @Override |
138 | public void removeUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { | 140 | public void removeUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { |
139 | RelationView<?> relationalKey = checkKey(key); | 141 | RelationView<?> relationalKey = checkKey(key); |
140 | this.modelUpdateListener.removeListener(relationalKey, seed, listener); | 142 | this.modelUpdateListener.removeListener(key, relationalKey, seed, listener); |
141 | } | 143 | } |
142 | 144 | ||
143 | @Override | 145 | @Override |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java index c093be47..b6468e76 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java | |||
@@ -12,28 +12,53 @@ import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeCo | |||
12 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | 12 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; |
13 | 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.*; | 14 | import tools.refinery.store.query.building.*; |
15 | import tools.refinery.store.query.view.RelationView; | ||
15 | 16 | ||
16 | import java.util.*; | 17 | import java.util.*; |
18 | import java.util.stream.Collectors; | ||
17 | 19 | ||
18 | public class DNF2PQuery { | 20 | public class DNF2PQuery { |
19 | private DNF2PQuery() { | 21 | private final Set<DNFPredicate> translating = new LinkedHashSet<>(); |
20 | throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); | 22 | |
21 | } | 23 | private final Map<DNFPredicate, SimplePQuery> dnf2PQueryMap = new HashMap<>(); |
22 | 24 | ||
23 | public static SimplePQuery translate(DNFPredicate predicate, Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) { | 25 | private final Map<RelationView<?>, RelationViewWrapper> view2WrapperMap = new HashMap<>(); |
24 | SimplePQuery query = dnf2PQueryMap.get(predicate); | 26 | |
25 | if (query != null) { | 27 | public SimplePQuery translate(DNFPredicate predicate) { |
26 | return query; | 28 | if (translating.contains(predicate)) { |
29 | var path = translating.stream().map(DNFPredicate::getName).collect(Collectors.joining(" -> ")); | ||
30 | throw new IllegalStateException("Circular reference %s -> %s detected".formatted(path, | ||
31 | predicate.getName())); | ||
27 | } | 32 | } |
28 | query = new SimplePQuery(predicate.getName()); | 33 | // We can't use computeIfAbsent here, because translating referenced queries calls this method in a reentrant |
34 | // way, which would cause a ConcurrentModificationException with computeIfAbsent. | ||
35 | var pQuery = dnf2PQueryMap.get(predicate); | ||
36 | if (pQuery == null) { | ||
37 | translating.add(predicate); | ||
38 | try { | ||
39 | pQuery = doTranslate(predicate); | ||
40 | dnf2PQueryMap.put(predicate, pQuery); | ||
41 | } finally { | ||
42 | translating.remove(predicate); | ||
43 | } | ||
44 | } | ||
45 | return pQuery; | ||
46 | } | ||
47 | |||
48 | private SimplePQuery doTranslate(DNFPredicate predicate) { | ||
49 | var query = new SimplePQuery(predicate.getName()); | ||
50 | |||
29 | Map<Variable, PParameter> parameters = new HashMap<>(); | 51 | Map<Variable, PParameter> parameters = new HashMap<>(); |
52 | for (Variable variable : predicate.getVariables()) { | ||
53 | parameters.put(variable, new PParameter(variable.getName())); | ||
54 | } | ||
30 | 55 | ||
31 | predicate.getVariables().forEach(variable -> parameters.put(variable, new PParameter(variable.getName()))); | ||
32 | List<PParameter> parameterList = new ArrayList<>(); | 56 | List<PParameter> parameterList = new ArrayList<>(); |
33 | for (var param : predicate.getVariables()) { | 57 | for (var param : predicate.getVariables()) { |
34 | parameterList.add(parameters.get(param)); | 58 | parameterList.add(parameters.get(param)); |
35 | } | 59 | } |
36 | query.setParameters(parameterList); | 60 | query.setParameters(parameterList); |
61 | |||
37 | for (DNFAnd clause : predicate.getClauses()) { | 62 | for (DNFAnd clause : predicate.getClauses()) { |
38 | PBody body = new PBody(query); | 63 | PBody body = new PBody(query); |
39 | List<ExportedParameter> symbolicParameters = new ArrayList<>(); | 64 | List<ExportedParameter> symbolicParameters = new ArrayList<>(); |
@@ -44,15 +69,14 @@ public class DNF2PQuery { | |||
44 | body.setSymbolicParameters(symbolicParameters); | 69 | body.setSymbolicParameters(symbolicParameters); |
45 | query.addBody(body); | 70 | query.addBody(body); |
46 | for (DNFAtom constraint : clause.getConstraints()) { | 71 | for (DNFAtom constraint : clause.getConstraints()) { |
47 | translateDNFAtom(constraint, body, dnf2PQueryMap); | 72 | translateDNFAtom(constraint, body); |
48 | } | 73 | } |
49 | } | 74 | } |
50 | dnf2PQueryMap.put(predicate, query); | 75 | |
51 | return query; | 76 | return query; |
52 | } | 77 | } |
53 | 78 | ||
54 | private static void translateDNFAtom(DNFAtom constraint, PBody body, | 79 | private void translateDNFAtom(DNFAtom constraint, PBody body) { |
55 | Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) { | ||
56 | if (constraint instanceof EquivalenceAtom equivalence) { | 80 | if (constraint instanceof EquivalenceAtom equivalence) { |
57 | translateEquivalenceAtom(equivalence, body); | 81 | translateEquivalenceAtom(equivalence, body); |
58 | } | 82 | } |
@@ -60,11 +84,11 @@ public class DNF2PQuery { | |||
60 | translateRelationAtom(relation, body); | 84 | translateRelationAtom(relation, body); |
61 | } | 85 | } |
62 | if (constraint instanceof PredicateAtom predicate) { | 86 | if (constraint instanceof PredicateAtom predicate) { |
63 | translatePredicateAtom(predicate, body, dnf2PQueryMap); | 87 | translatePredicateAtom(predicate, body); |
64 | } | 88 | } |
65 | } | 89 | } |
66 | 90 | ||
67 | private static void translateEquivalenceAtom(EquivalenceAtom equivalence, PBody body) { | 91 | private void translateEquivalenceAtom(EquivalenceAtom equivalence, PBody body) { |
68 | PVariable varSource = body.getOrCreateVariableByName(equivalence.getLeft().getName()); | 92 | PVariable varSource = body.getOrCreateVariableByName(equivalence.getLeft().getName()); |
69 | PVariable varTarget = body.getOrCreateVariableByName(equivalence.getRight().getName()); | 93 | PVariable varTarget = body.getOrCreateVariableByName(equivalence.getRight().getName()); |
70 | if (equivalence.isPositive()) | 94 | if (equivalence.isPositive()) |
@@ -73,7 +97,7 @@ public class DNF2PQuery { | |||
73 | new Inequality(body, varSource, varTarget); | 97 | new Inequality(body, varSource, varTarget); |
74 | } | 98 | } |
75 | 99 | ||
76 | private static void translateRelationAtom(RelationAtom relation, PBody body) { | 100 | private void translateRelationAtom(RelationAtom relation, PBody body) { |
77 | if (relation.substitution().size() != relation.view().getArity()) { | 101 | if (relation.substitution().size() != relation.view().getArity()) { |
78 | throw new IllegalArgumentException("Arity (%d) does not match parameter numbers (%d)".formatted( | 102 | throw new IllegalArgumentException("Arity (%d) does not match parameter numbers (%d)".formatted( |
79 | relation.view().getArity(), relation.substitution().size())); | 103 | relation.view().getArity(), relation.substitution().size())); |
@@ -82,32 +106,34 @@ public class DNF2PQuery { | |||
82 | for (int i = 0; i < relation.substitution().size(); i++) { | 106 | for (int i = 0; i < relation.substitution().size(); i++) { |
83 | variables[i] = body.getOrCreateVariableByName(relation.substitution().get(i).getName()); | 107 | variables[i] = body.getOrCreateVariableByName(relation.substitution().get(i).getName()); |
84 | } | 108 | } |
85 | new TypeConstraint(body, Tuples.flatTupleOf(variables), relation.view()); | 109 | new TypeConstraint(body, Tuples.flatTupleOf(variables), wrapView(relation.view())); |
110 | } | ||
111 | |||
112 | private RelationViewWrapper wrapView(RelationView<?> relationView) { | ||
113 | return view2WrapperMap.computeIfAbsent(relationView, RelationViewWrapper::new); | ||
86 | } | 114 | } |
87 | 115 | ||
88 | private static void translatePredicateAtom(PredicateAtom predicate, PBody body, | 116 | private void translatePredicateAtom(PredicateAtom predicate, PBody body) { |
89 | Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) { | ||
90 | Object[] variables = new Object[predicate.getSubstitution().size()]; | 117 | Object[] variables = new Object[predicate.getSubstitution().size()]; |
91 | for (int i = 0; i < predicate.getSubstitution().size(); i++) { | 118 | for (int i = 0; i < predicate.getSubstitution().size(); i++) { |
92 | variables[i] = body.getOrCreateVariableByName(predicate.getSubstitution().get(i).getName()); | 119 | variables[i] = body.getOrCreateVariableByName(predicate.getSubstitution().get(i).getName()); |
93 | } | 120 | } |
121 | var variablesTuple = Tuples.flatTupleOf(variables); | ||
122 | var translatedReferred = translate(predicate.getReferred()); | ||
94 | if (predicate.isPositive()) { | 123 | if (predicate.isPositive()) { |
95 | if (predicate.isTransitive()) { | 124 | if (predicate.isTransitive()) { |
96 | if (predicate.getSubstitution().size() != 2) { | 125 | if (predicate.getSubstitution().size() != 2) { |
97 | throw new IllegalArgumentException("Transitive Predicate Atoms must be binary."); | 126 | throw new IllegalArgumentException("Transitive Predicate Atoms must be binary."); |
98 | } | 127 | } |
99 | new BinaryTransitiveClosure(body, Tuples.flatTupleOf(variables), | 128 | new BinaryTransitiveClosure(body, variablesTuple, translatedReferred); |
100 | DNF2PQuery.translate(predicate.getReferred(), dnf2PQueryMap)); | ||
101 | } else { | 129 | } else { |
102 | new PositivePatternCall(body, Tuples.flatTupleOf(variables), | 130 | new PositivePatternCall(body, variablesTuple, translatedReferred); |
103 | DNF2PQuery.translate(predicate.getReferred(), dnf2PQueryMap)); | ||
104 | } | 131 | } |
105 | } else { | 132 | } else { |
106 | if (predicate.isTransitive()) { | 133 | if (predicate.isTransitive()) { |
107 | throw new InputMismatchException("Transitive Predicate Atoms cannot be negative."); | 134 | throw new IllegalArgumentException("Transitive Predicate Atoms cannot be negative."); |
108 | } else { | 135 | } else { |
109 | new NegativePatternCall(body, Tuples.flatTupleOf(variables), | 136 | new NegativePatternCall(body, variablesTuple, translatedReferred); |
110 | DNF2PQuery.translate(predicate.getReferred(), dnf2PQueryMap)); | ||
111 | } | 137 | } |
112 | } | 138 | } |
113 | } | 139 | } |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java new file mode 100644 index 00000000..2a4148dc --- /dev/null +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java | |||
@@ -0,0 +1,30 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.pquery; | ||
2 | |||
3 | import org.eclipse.viatra.query.runtime.matchers.context.common.BaseInputKeyWrapper; | ||
4 | import tools.refinery.store.query.view.RelationView; | ||
5 | |||
6 | public class RelationViewWrapper extends BaseInputKeyWrapper<RelationView<?>> { | ||
7 | public RelationViewWrapper(RelationView<?> wrappedKey) { | ||
8 | super(wrappedKey); | ||
9 | } | ||
10 | |||
11 | @Override | ||
12 | public String getPrettyPrintableName() { | ||
13 | return wrappedKey.getName(); | ||
14 | } | ||
15 | |||
16 | @Override | ||
17 | public String getStringID() { | ||
18 | return getPrettyPrintableName(); | ||
19 | } | ||
20 | |||
21 | @Override | ||
22 | public int getArity() { | ||
23 | return wrappedKey.getArity(); | ||
24 | } | ||
25 | |||
26 | @Override | ||
27 | public boolean isEnumerable() { | ||
28 | return true; | ||
29 | } | ||
30 | } | ||
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java index 25919888..5a0da315 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java | |||
@@ -1,5 +1,6 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.viewupdate; | 1 | package tools.refinery.store.query.viatra.internal.viewupdate; |
2 | 2 | ||
3 | import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; | ||
3 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; | 4 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; |
4 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | 5 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; |
5 | import tools.refinery.store.model.Tuple; | 6 | import tools.refinery.store.model.Tuple; |
@@ -46,20 +47,23 @@ public class ModelUpdateListener { | |||
46 | return view2Buffers.containsKey(relationalKey); | 47 | return view2Buffers.containsKey(relationalKey); |
47 | } | 48 | } |
48 | 49 | ||
49 | public <D> void addListener(RelationView<D> relationView, ITuple seed, IQueryRuntimeContextListener listener) { | 50 | public <D> void addListener(IInputKey key, RelationView<D> relationView, ITuple seed, |
51 | IQueryRuntimeContextListener listener) { | ||
50 | if (view2Buffers.containsKey(relationView)) { | 52 | if (view2Buffers.containsKey(relationView)) { |
51 | ViewUpdateTranslator<D> updateListener = new ViewUpdateTranslator<>(relationView, seed, listener); | 53 | ViewUpdateTranslator<D> updateListener = new ViewUpdateTranslator<>(key, relationView, seed, listener); |
52 | ViewUpdateBuffer<D> updateBuffer = new ViewUpdateBuffer<>(updateListener); | 54 | ViewUpdateBuffer<D> updateBuffer = new ViewUpdateBuffer<>(updateListener); |
53 | view2Buffers.get(relationView).add(updateBuffer); | 55 | view2Buffers.get(relationView).add(updateBuffer); |
54 | } else | 56 | } else { |
55 | throw new IllegalArgumentException(); | 57 | throw new IllegalArgumentException(); |
58 | } | ||
56 | } | 59 | } |
57 | 60 | ||
58 | public void removeListener(RelationView<?> relationView, ITuple seed, IQueryRuntimeContextListener listener) { | 61 | public void removeListener(IInputKey key, RelationView<?> relationView, ITuple seed, |
62 | IQueryRuntimeContextListener listener) { | ||
59 | if (view2Buffers.containsKey(relationView)) { | 63 | if (view2Buffers.containsKey(relationView)) { |
60 | Set<ViewUpdateBuffer<?>> buffers = this.view2Buffers.get(relationView); | 64 | Set<ViewUpdateBuffer<?>> buffers = this.view2Buffers.get(relationView); |
61 | for (var buffer : buffers) { | 65 | for (var buffer : buffers) { |
62 | if (buffer.getUpdateListener().equals(relationView, seed, listener)) { | 66 | if (buffer.getUpdateListener().equals(key, relationView, seed, listener)) { |
63 | // remove buffer and terminate immediately, or it will break iterator. | 67 | // remove buffer and terminate immediately, or it will break iterator. |
64 | buffers.remove(buffer); | 68 | buffers.remove(buffer); |
65 | return; | 69 | return; |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java index c727f046..b9406018 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java | |||
@@ -3,8 +3,7 @@ package tools.refinery.store.query.viatra.internal.viewupdate; | |||
3 | import java.util.Arrays; | 3 | import java.util.Arrays; |
4 | import java.util.Objects; | 4 | import java.util.Objects; |
5 | 5 | ||
6 | record ViewUpdate (Object[] tuple, boolean isInsertion) { | 6 | record ViewUpdate(Object[] tuple, boolean isInsertion) { |
7 | |||
8 | @Override | 7 | @Override |
9 | public int hashCode() { | 8 | public int hashCode() { |
10 | final int prime = 31; | 9 | final int prime = 31; |
@@ -28,7 +27,6 @@ record ViewUpdate (Object[] tuple, boolean isInsertion) { | |||
28 | 27 | ||
29 | @Override | 28 | @Override |
30 | public String toString() { | 29 | public String toString() { |
31 | return "ViewUpdate [" + Arrays.toString(tuple) + "insertion= "+this.isInsertion+"]"; | 30 | return "ViewUpdate [" + Arrays.toString(tuple) + "insertion= " + this.isInsertion + "]"; |
32 | } | 31 | } |
33 | |||
34 | } | 32 | } |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java index 5a4243f2..e13a9cb8 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java | |||
@@ -8,6 +8,7 @@ import java.util.List; | |||
8 | 8 | ||
9 | public class ViewUpdateBuffer<D> { | 9 | public class ViewUpdateBuffer<D> { |
10 | protected final ViewUpdateTranslator<D> updateListener; | 10 | protected final ViewUpdateTranslator<D> updateListener; |
11 | |||
11 | protected final List<ViewUpdate> buffer = new ArrayList<>(); | 12 | protected final List<ViewUpdate> buffer = new ArrayList<>(); |
12 | 13 | ||
13 | public ViewUpdateBuffer(ViewUpdateTranslator<D> updateListener) { | 14 | public ViewUpdateBuffer(ViewUpdateTranslator<D> updateListener) { |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java index 2f7f9a9c..62a10e45 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java | |||
@@ -1,5 +1,6 @@ | |||
1 | package tools.refinery.store.query.viatra.internal.viewupdate; | 1 | package tools.refinery.store.query.viatra.internal.viewupdate; |
2 | 2 | ||
3 | import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; | ||
3 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; | 4 | import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; |
4 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; | 5 | import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; |
5 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | 6 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; |
@@ -9,29 +10,38 @@ import tools.refinery.store.query.view.RelationView; | |||
9 | import java.util.Objects; | 10 | import java.util.Objects; |
10 | 11 | ||
11 | public class ViewUpdateTranslator<D> { | 12 | public class ViewUpdateTranslator<D> { |
13 | private final IInputKey wrappedKey; | ||
14 | |||
12 | private final RelationView<D> key; | 15 | private final RelationView<D> key; |
13 | 16 | ||
14 | private final ITuple filter; | 17 | private final ITuple filter; |
15 | 18 | ||
16 | private final IQueryRuntimeContextListener listener; | 19 | private final IQueryRuntimeContextListener listener; |
17 | 20 | ||
18 | public ViewUpdateTranslator(RelationView<D> key, ITuple filter, IQueryRuntimeContextListener listener) { | 21 | public ViewUpdateTranslator(IInputKey wrappedKey, RelationView<D> key, ITuple filter, |
22 | IQueryRuntimeContextListener listener) { | ||
19 | super(); | 23 | super(); |
24 | this.wrappedKey = wrappedKey; | ||
20 | this.key = key; | 25 | this.key = key; |
21 | this.filter = filter; | 26 | this.filter = filter; |
22 | this.listener = listener; | 27 | this.listener = listener; |
23 | } | 28 | } |
24 | 29 | ||
25 | public boolean equals(RelationView<?> relationView, ITuple seed, IQueryRuntimeContextListener listener) { | 30 | public boolean equals(IInputKey wrappedKey, RelationView<?> relationView, ITuple seed, |
26 | return key == relationView && filter.equals(seed) && this.listener == listener; | 31 | IQueryRuntimeContextListener listener) { |
32 | return this.wrappedKey == wrappedKey && key == relationView && filter.equals(seed) && this.listener == listener; | ||
27 | } | 33 | } |
28 | 34 | ||
29 | public void processChange(ViewUpdate change) { | 35 | public void processChange(ViewUpdate change) { |
30 | listener.update(key, Tuples.flatTupleOf(change.tuple()), change.isInsertion()); | 36 | listener.update(wrappedKey, Tuples.flatTupleOf(change.tuple()), change.isInsertion()); |
31 | } | 37 | } |
32 | 38 | ||
39 | @SuppressWarnings("squid:S1168") | ||
33 | public Object[] isMatching(Tuple tuple, D value) { | 40 | public Object[] isMatching(Tuple tuple, D value) { |
34 | return isMatching(key.getWrappedKey().transform(tuple, value), filter); | 41 | if (!key.filter(tuple, value)) { |
42 | return null; | ||
43 | } | ||
44 | return isMatching(key.forwardMap(tuple, value), filter); | ||
35 | } | 45 | } |
36 | 46 | ||
37 | @SuppressWarnings("squid:S1168") | 47 | @SuppressWarnings("squid:S1168") |
diff --git a/subprojects/store/build.gradle b/subprojects/store/build.gradle index 8d091a81..370d094b 100644 --- a/subprojects/store/build.gradle +++ b/subprojects/store/build.gradle | |||
@@ -2,8 +2,3 @@ plugins { | |||
2 | id 'refinery-java-library' | 2 | id 'refinery-java-library' |
3 | id 'refinery-jmh' | 3 | id 'refinery-jmh' |
4 | } | 4 | } |
5 | |||
6 | dependencies { | ||
7 | implementation libs.ecore | ||
8 | implementation libs.viatra | ||
9 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/AbstractFilteredRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/AbstractFilteredRelationView.java new file mode 100644 index 00000000..a21a38ba --- /dev/null +++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/AbstractFilteredRelationView.java | |||
@@ -0,0 +1,44 @@ | |||
1 | package tools.refinery.store.query.view; | ||
2 | |||
3 | import tools.refinery.store.model.Model; | ||
4 | import tools.refinery.store.model.Tuple; | ||
5 | import tools.refinery.store.model.Tuple.Tuple1; | ||
6 | import tools.refinery.store.model.representation.Relation; | ||
7 | |||
8 | public abstract class AbstractFilteredRelationView<D> extends RelationView<D> { | ||
9 | protected AbstractFilteredRelationView(Relation<D> representation, String name) { | ||
10 | super(representation, name); | ||
11 | } | ||
12 | |||
13 | protected AbstractFilteredRelationView(Relation<D> representation) { | ||
14 | super(representation); | ||
15 | } | ||
16 | |||
17 | @Override | ||
18 | public Object[] forwardMap(Tuple key, D value) { | ||
19 | return toTuple1Array(key); | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public boolean get(Model model, Object[] tuple) { | ||
24 | int[] content = new int[tuple.length]; | ||
25 | for (int i = 0; i < tuple.length; i++) { | ||
26 | content[i] = ((Tuple1) tuple[i]).get(0); | ||
27 | } | ||
28 | Tuple key = Tuple.of(content); | ||
29 | D value = model.get(getRepresentation(), key); | ||
30 | return filter(key, value); | ||
31 | } | ||
32 | |||
33 | public int getArity() { | ||
34 | return this.getRepresentation().getArity(); | ||
35 | } | ||
36 | |||
37 | private static Object[] toTuple1Array(Tuple t) { | ||
38 | Object[] result = new Object[t.getSize()]; | ||
39 | for (int i = 0; i < t.getSize(); i++) { | ||
40 | result[i] = Tuple.of(t.get(i)); | ||
41 | } | ||
42 | return result; | ||
43 | } | ||
44 | } | ||
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java index 3531195a..bb5d0237 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java +++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/FilteredRelationView.java | |||
@@ -1,48 +1,34 @@ | |||
1 | package tools.refinery.store.query.view; | 1 | package tools.refinery.store.query.view; |
2 | 2 | ||
3 | import java.util.function.BiPredicate; | ||
4 | |||
5 | import tools.refinery.store.model.Model; | ||
6 | import tools.refinery.store.model.Tuple; | 3 | import tools.refinery.store.model.Tuple; |
7 | import tools.refinery.store.model.Tuple.Tuple1; | ||
8 | import tools.refinery.store.model.representation.Relation; | 4 | import tools.refinery.store.model.representation.Relation; |
9 | 5 | ||
10 | public class FilteredRelationView<D> extends RelationView<D>{ | 6 | import java.util.function.BiPredicate; |
11 | private final BiPredicate<Tuple,D> predicate; | 7 | import java.util.function.Predicate; |
12 | 8 | ||
13 | public FilteredRelationView(Relation<D> representation, BiPredicate<Tuple,D> predicate) { | 9 | public class FilteredRelationView<D> extends AbstractFilteredRelationView<D> { |
14 | super(representation); | 10 | private final BiPredicate<Tuple, D> predicate; |
11 | |||
12 | public FilteredRelationView(Relation<D> representation, String name, BiPredicate<Tuple, D> predicate) { | ||
13 | super(representation, name); | ||
15 | this.predicate = predicate; | 14 | this.predicate = predicate; |
16 | } | 15 | } |
17 | @Override | 16 | |
18 | protected Object[] forwardMap(Tuple key, D value) { | 17 | public FilteredRelationView(Relation<D> representation, BiPredicate<Tuple, D> predicate) { |
19 | return toTuple1Array(key); | 18 | super(representation); |
20 | } | 19 | this.predicate = predicate; |
21 | @Override | ||
22 | public boolean get(Model model, Object[] tuple) { | ||
23 | int[] content = new int[tuple.length]; | ||
24 | for(int i = 0; i<tuple.length; i++) { | ||
25 | content[i] =((Tuple1)tuple[i]).get(0); | ||
26 | } | ||
27 | Tuple key = Tuple.of(content); | ||
28 | D value = model.get(representation, key); | ||
29 | return filter(key, value); | ||
30 | } | 20 | } |
31 | 21 | ||
32 | public static Object[] toTuple1Array(Tuple t) { | 22 | public FilteredRelationView(Relation<D> representation, String name, Predicate<D> predicate) { |
33 | Object[] result = new Object[t.getSize()]; | 23 | this(representation, name, (k, v) -> predicate.test(v)); |
34 | for(int i = 0; i<t.getSize(); i++) { | ||
35 | result[i] = Tuple.of(t.get(i)); | ||
36 | } | ||
37 | return result; | ||
38 | } | 24 | } |
39 | 25 | ||
40 | @Override | 26 | public FilteredRelationView(Relation<D> representation, Predicate<D> predicate) { |
41 | public int getArity() { | 27 | this(representation, (k, v) -> predicate.test(v)); |
42 | return this.representation.getArity(); | ||
43 | } | 28 | } |
29 | |||
44 | @Override | 30 | @Override |
45 | protected boolean filter(Tuple key, D value) { | 31 | public boolean filter(Tuple key, D value) { |
46 | return this.predicate.test(key, value); | 32 | return this.predicate.test(key, value); |
47 | } | 33 | } |
48 | } | 34 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java index db9ba4b8..54baa050 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java +++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/FunctionalRelationView.java | |||
@@ -6,45 +6,48 @@ import tools.refinery.store.model.Tuple.Tuple1; | |||
6 | import tools.refinery.store.model.representation.Relation; | 6 | import tools.refinery.store.model.representation.Relation; |
7 | 7 | ||
8 | public class FunctionalRelationView<D> extends RelationView<D> { | 8 | public class FunctionalRelationView<D> extends RelationView<D> { |
9 | public FunctionalRelationView(Relation<D> representation, String name) { | ||
10 | super(representation, name); | ||
11 | } | ||
9 | 12 | ||
10 | public FunctionalRelationView(Relation<D> representation) { | 13 | public FunctionalRelationView(Relation<D> representation) { |
11 | super(representation); | 14 | super(representation); |
12 | } | 15 | } |
13 | 16 | ||
14 | @Override | 17 | @Override |
15 | protected boolean filter(Tuple key, D value) { | 18 | public boolean filter(Tuple key, D value) { |
16 | return true; | 19 | return true; |
17 | } | 20 | } |
18 | 21 | ||
19 | @Override | 22 | @Override |
20 | protected Object[] forwardMap(Tuple key, D value) { | 23 | public Object[] forwardMap(Tuple key, D value) { |
21 | return toTuple1ArrayPlusValue(key, value); | 24 | return toTuple1ArrayPlusValue(key, value); |
22 | } | 25 | } |
23 | 26 | ||
24 | @Override | 27 | @Override |
25 | public boolean get(Model model, Object[] tuple) { | 28 | public boolean get(Model model, Object[] tuple) { |
26 | int[] content = new int[tuple.length-1]; | 29 | int[] content = new int[tuple.length - 1]; |
27 | for(int i = 0; i<tuple.length-1; i++) { | 30 | for (int i = 0; i < tuple.length - 1; i++) { |
28 | content[i] =((Tuple1)tuple[i]).get(0); | 31 | content[i] = ((Tuple1) tuple[i]).get(0); |
29 | } | 32 | } |
30 | Tuple key = Tuple.of(content); | 33 | Tuple key = Tuple.of(content); |
31 | @SuppressWarnings("unchecked") | 34 | @SuppressWarnings("unchecked") |
32 | D valueInTuple = (D) tuple[tuple.length-1]; | 35 | D valueInTuple = (D) tuple[tuple.length - 1]; |
33 | D valueInMap = model.get(representation, key); | 36 | D valueInMap = model.get(getRepresentation(), key); |
34 | return valueInTuple.equals(valueInMap); | 37 | return valueInTuple.equals(valueInMap); |
35 | } | 38 | } |
36 | 39 | ||
37 | public static <D> Object[] toTuple1ArrayPlusValue(Tuple t, D value) { | 40 | @Override |
38 | Object[] result = new Object[t.getSize()+1]; | 41 | public int getArity() { |
39 | for(int i = 0; i<t.getSize(); i++) { | 42 | return getRepresentation().getArity() + 1; |
43 | } | ||
44 | |||
45 | private static <D> Object[] toTuple1ArrayPlusValue(Tuple t, D value) { | ||
46 | Object[] result = new Object[t.getSize() + 1]; | ||
47 | for (int i = 0; i < t.getSize(); i++) { | ||
40 | result[i] = Tuple.of(t.get(i)); | 48 | result[i] = Tuple.of(t.get(i)); |
41 | } | 49 | } |
42 | result[t.getSize()] = value; | 50 | result[t.getSize()] = value; |
43 | return result; | 51 | return result; |
44 | } | 52 | } |
45 | |||
46 | @Override | ||
47 | public int getArity() { | ||
48 | return this.representation.getArity()+1; | ||
49 | } | ||
50 | } | 53 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java index 6fa387a1..b9a9ed9f 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java +++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/KeyOnlyRelationView.java | |||
@@ -3,14 +3,18 @@ package tools.refinery.store.query.view; | |||
3 | import tools.refinery.store.model.Tuple; | 3 | import tools.refinery.store.model.Tuple; |
4 | import tools.refinery.store.model.representation.Relation; | 4 | import tools.refinery.store.model.representation.Relation; |
5 | 5 | ||
6 | public class KeyOnlyRelationView extends FilteredRelationView<Boolean>{ | 6 | public class KeyOnlyRelationView extends AbstractFilteredRelationView<Boolean> { |
7 | public static final String VIEW_NAME = "key"; | ||
8 | |||
9 | private final Boolean defaultValue; | ||
7 | 10 | ||
8 | public KeyOnlyRelationView(Relation<Boolean> representation) { | 11 | public KeyOnlyRelationView(Relation<Boolean> representation) { |
9 | super(representation, (k,v)->true); | 12 | super(representation, VIEW_NAME); |
13 | defaultValue = representation.getDefaultValue(); | ||
10 | } | 14 | } |
15 | |||
11 | @Override | 16 | @Override |
12 | protected boolean filter(Tuple key, Boolean value) { | 17 | public boolean filter(Tuple key, Boolean value) { |
13 | return !value.equals(representation.getDefaultValue()); | 18 | return !value.equals(defaultValue); |
14 | } | 19 | } |
15 | |||
16 | } | 20 | } |
diff --git a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java index fd55eed4..b8a54046 100644 --- a/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java +++ b/subprojects/store/src/main/java/tools/refinery/store/query/view/RelationView.java | |||
@@ -1,66 +1,51 @@ | |||
1 | package tools.refinery.store.query.view; | 1 | package tools.refinery.store.query.view; |
2 | 2 | ||
3 | import java.util.Objects; | ||
4 | |||
5 | import org.eclipse.viatra.query.runtime.matchers.context.common.BaseInputKeyWrapper; | ||
6 | |||
7 | import tools.refinery.store.map.CursorAsIterator; | 3 | import tools.refinery.store.map.CursorAsIterator; |
8 | import tools.refinery.store.model.Model; | 4 | import tools.refinery.store.model.Model; |
9 | import tools.refinery.store.model.Tuple; | 5 | import tools.refinery.store.model.Tuple; |
10 | import tools.refinery.store.model.representation.Relation; | 6 | import tools.refinery.store.model.representation.Relation; |
11 | 7 | ||
8 | import java.util.Objects; | ||
9 | import java.util.UUID; | ||
10 | |||
12 | /** | 11 | /** |
13 | * Represents a view of a {@link Relation} that can be queried. | 12 | * Represents a view of a {@link Relation} that can be queried. |
14 | * | ||
15 | * @author Oszkar Semerath | ||
16 | * | 13 | * |
17 | * @param <D> | 14 | * @param <D> |
15 | * @author Oszkar Semerath | ||
18 | */ | 16 | */ |
19 | public abstract class RelationView<D> extends BaseInputKeyWrapper<RelationView<D>> { | 17 | public abstract class RelationView<D> { |
20 | protected final Relation<D> representation; | 18 | private final Relation<D> representation; |
21 | 19 | ||
22 | protected RelationView(Relation<D> representation) { | 20 | private final String name; |
23 | super(null); | 21 | |
24 | this.wrappedKey = this; | 22 | protected RelationView(Relation<D> representation, String name) { |
25 | this.representation = representation; | 23 | this.representation = representation; |
24 | this.name = name; | ||
26 | } | 25 | } |
27 | 26 | ||
28 | @Override | 27 | protected RelationView(Relation<D> representation) { |
29 | public String getPrettyPrintableName() { | 28 | this(representation, UUID.randomUUID().toString()); |
30 | return representation.getName(); | ||
31 | } | 29 | } |
32 | 30 | ||
33 | @Override | 31 | public abstract int getArity(); |
34 | public String getStringID() { | ||
35 | return representation.getName() + this.getClass().getName(); | ||
36 | } | ||
37 | 32 | ||
38 | public Relation<D> getRepresentation() { | 33 | public Relation<D> getRepresentation() { |
39 | return representation; | 34 | return representation; |
40 | } | 35 | } |
41 | 36 | ||
42 | @Override | 37 | public String getName() { |
43 | public boolean isEnumerable() { | 38 | return representation.getName() + "#" + name; |
44 | return true; | ||
45 | } | 39 | } |
46 | 40 | ||
47 | protected abstract boolean filter(Tuple key, D value); | 41 | public abstract boolean filter(Tuple key, D value); |
48 | 42 | ||
49 | protected abstract Object[] forwardMap(Tuple key, D value); | 43 | public abstract Object[] forwardMap(Tuple key, D value); |
50 | 44 | ||
51 | public abstract boolean get(Model model, Object[] tuple); | 45 | public abstract boolean get(Model model, Object[] tuple); |
52 | |||
53 | @SuppressWarnings("squid:S1168") | ||
54 | public Object[] transform(Tuple tuple, D value) { | ||
55 | if (filter(tuple, value)) { | ||
56 | return forwardMap(tuple, value); | ||
57 | } else | ||
58 | return null; | ||
59 | } | ||
60 | 46 | ||
61 | public Iterable<Object[]> getAll(Model model) { | 47 | public Iterable<Object[]> getAll(Model model) { |
62 | return (() -> new CursorAsIterator<>(model.getAll(representation), (k, v) -> forwardMap(k, v), | 48 | return (() -> new CursorAsIterator<>(model.getAll(representation), this::forwardMap, this::filter)); |
63 | (k, v) -> filter(k, v))); | ||
64 | } | 49 | } |
65 | 50 | ||
66 | @Override | 51 | @Override |
@@ -81,5 +66,4 @@ public abstract class RelationView<D> extends BaseInputKeyWrapper<RelationView<D | |||
81 | RelationView<D> other = ((RelationView<D>) obj); | 66 | RelationView<D> other = ((RelationView<D>) obj); |
82 | return Objects.equals(representation, other.representation); | 67 | return Objects.equals(representation, other.representation); |
83 | } | 68 | } |
84 | |||
85 | } | 69 | } |