1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
package tools.refinery.store.query.viatra;
import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification;
import tools.refinery.store.model.ModelDiffCursor;
import tools.refinery.store.model.ModelStore;
import tools.refinery.store.model.ModelStoreImpl;
import tools.refinery.store.model.RelationLike;
import tools.refinery.store.model.representation.AnyDataRepresentation;
import tools.refinery.store.model.representation.DataRepresentation;
import tools.refinery.store.query.DNF;
import tools.refinery.store.query.DNFAnd;
import tools.refinery.store.query.QueryableModel;
import tools.refinery.store.query.QueryableModelStore;
import tools.refinery.store.query.atom.*;
import tools.refinery.store.query.viatra.internal.RawPatternMatcher;
import tools.refinery.store.query.viatra.internal.ViatraQueryableModel;
import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery;
import tools.refinery.store.query.view.AnyRelationView;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class ViatraQueryableModelStore implements QueryableModelStore {
protected final ModelStore store;
protected final Set<AnyRelationView> relationViews;
protected final Map<DNF, GenericQuerySpecification<RawPatternMatcher>> predicates;
public ViatraQueryableModelStore(ModelStore store, Set<AnyRelationView> relationViews,
Set<DNF> predicates) {
this.store = store;
validateViews(store.getDataRepresentations(), relationViews);
this.relationViews = Collections.unmodifiableSet(relationViews);
validatePredicates(relationViews, predicates);
this.predicates = initPredicates(predicates);
}
public ViatraQueryableModelStore(Set<AnyDataRepresentation> dataRepresentations,
Set<AnyRelationView> relationViews, Set<DNF> predicates) {
this(new ModelStoreImpl(dataRepresentations), relationViews, predicates);
}
private void validateViews(Set<AnyDataRepresentation> dataRepresentations, Set<AnyRelationView> relationViews) {
for (var relationView : relationViews) {
if (!dataRepresentations.contains(relationView.getRepresentation())) {
throw new IllegalArgumentException("%s %s added to %s without a referred representation.".formatted(
DataRepresentation.class.getSimpleName(), relationView.getName(),
QueryableModelStore.class.getSimpleName()));
}
}
}
private void validatePredicates(Set<AnyRelationView> relationViews, Set<DNF> predicates) {
for (DNF dnfPredicate : predicates) {
for (DNFAnd clause : dnfPredicate.getClauses()) {
for (DNFAtom atom : clause.constraints()) {
if (atom instanceof RelationViewAtom relationViewAtom) {
validateRelationAtom(relationViews, dnfPredicate, relationViewAtom);
} else if (atom instanceof CallAtom<?> queryCallAtom) {
validatePredicateAtom(predicates, dnfPredicate, queryCallAtom);
} else if (!(atom instanceof EquivalenceAtom || atom instanceof ConstantAtom)) {
throw new IllegalArgumentException("Unknown constraint: " + atom.toString());
}
}
}
}
}
private void validateRelationAtom(Set<AnyRelationView> relationViews, DNF dnfPredicate,
RelationViewAtom relationViewAtom) {
if (!relationViews.contains(relationViewAtom.getTarget())) {
throw new IllegalArgumentException(
"%s %s contains reference to a view %s that is not in the model.".formatted(
DNF.class.getSimpleName(), dnfPredicate.getUniqueName(),
relationViewAtom.getTarget().getName()));
}
}
private void validatePredicateReference(Set<DNF> predicates, DNF dnfPredicate, RelationLike target) {
if (!(target instanceof DNF dnfTarget) || !predicates.contains(dnfTarget)) {
throw new IllegalArgumentException(
"%s %s contains reference to a predicate %s that is not in the model.".formatted(
DNF.class.getSimpleName(), dnfPredicate.getUniqueName(), target.getName()));
}
}
private void validatePredicateAtom(Set<DNF> predicates, DNF dnfPredicate, CallAtom<?> queryCallAtom) {
validatePredicateReference(predicates, dnfPredicate, queryCallAtom.getTarget());
}
private Map<DNF, GenericQuerySpecification<RawPatternMatcher>> initPredicates(Set<DNF> predicates) {
Map<DNF, GenericQuerySpecification<RawPatternMatcher>> result = new HashMap<>();
var dnf2PQuery = new DNF2PQuery();
for (DNF dnfPredicate : predicates) {
GenericQuerySpecification<RawPatternMatcher> query = dnf2PQuery.translate(dnfPredicate).build();
result.put(dnfPredicate, query);
}
return result;
}
@Override
public Set<AnyDataRepresentation> getDataRepresentations() {
return store.getDataRepresentations();
}
@Override
public Set<AnyRelationView> getViews() {
return this.relationViews;
}
@Override
public Set<DNF> getPredicates() {
return predicates.keySet();
}
@Override
public QueryableModel createModel() {
return new ViatraQueryableModel(this, this.store.createModel(), predicates);
}
@Override
public QueryableModel createModel(long state) {
return new ViatraQueryableModel(this, this.store.createModel(state), predicates);
}
@Override
public synchronized Set<Long> getStates() {
return this.store.getStates();
}
@Override
public synchronized ModelDiffCursor getDiffCursor(long from, long to) {
return this.store.getDiffCursor(from, to);
}
}
|