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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
package hu.bme.mit.inf.dslreasoner.application.execution
import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.AllPatternEntry
import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.ConfigurationScript
import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.PatternElement
import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.PatternEntry
import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.PatternSpecification
import hu.bme.mit.inf.dslreasoner.application.applicationConfiguration.ViatraImport
import hu.bme.mit.inf.dslreasoner.viatra2logic.ViatraQuerySetDescriptor
import java.util.HashMap
import java.util.LinkedHashSet
import java.util.List
import java.util.Set
import org.eclipse.emf.ecore.EClass
import org.eclipse.emf.ecore.EPackage
import org.eclipse.viatra.query.patternlanguage.emf.specification.SpecificationBuilder
import org.eclipse.viatra.query.patternlanguage.emf.vql.Pattern
import org.eclipse.viatra.query.patternlanguage.emf.vql.PatternCompositionConstraint
import org.eclipse.viatra.query.patternlanguage.emf.vql.PatternModel
import org.eclipse.viatra.query.runtime.api.IQuerySpecification
import org.eclipse.xtext.EcoreUtil2
import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
import org.eclipse.viatra.query.patternlanguage.emf.vql.PatternCall
import org.eclipse.viatra.query.runtime.api.IPatternMatch
import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
import java.util.LinkedHashMap
import java.util.LinkedList
class QueryLoader {
//val parser = new VQLParser
val builder = new SpecificationBuilder
def loadQueries(PatternSpecification specification) {
val patterns = new LinkedHashSet
for(entry: specification.entries) {
patterns += getPatterns(entry)
}
//val errors = patterns.map[eResource].toSet.map[errors]
//errors.forEach[println(it)]
val allConcernedPatterns = patterns.allReferredPatterns
val pattern2Specification = allConcernedPatterns.translatePatterns()
val List<IQuerySpecification<?>> patternsToTranslate =
pattern2Specification.values.toList
val Set<IQuerySpecification<?>> validationPatterns =
patterns.filter[it.annotations.exists[it.name.equals("Constraint")]]
.map[lookup(pattern2Specification)]
.toSet
val derivedFeatures = calculateDerivedFeatures(patterns.referredEcoreModels,patterns.map[it.lookup(pattern2Specification)])
// patternsToTranslate.forEach[println(it.fullyQualifiedName)]
// if (true) throw new Exception
return new ViatraQuerySetDescriptor(
patternsToTranslate,
validationPatterns,
derivedFeatures
) -> allConcernedPatterns
}
def dispatch List<Pattern> getPatterns(AllPatternEntry entry) {
val excluded = entry.exclusuion.map[getPatterns]
val referredPatternModels = allPatternsWithSamePackage(entry,entry.package as PatternModel).toSet
val patterns = referredPatternModels.map[patterns].flatten
return patterns.filter[!excluded.contains(it)].toList
}
def dispatch List<Pattern> getPatterns(PatternElement entry) {
return #[entry.pattern]
}
def private allPatternsWithSamePackage(PatternEntry entry, PatternModel model) {
val packageURI = model.packageName
val document = EcoreUtil2.getContainerOfType(entry,ConfigurationScript)
val viatraImportsWithSamePackage = document.imports
.filter(ViatraImport)
.map[it.importedViatra]
.filterNull
.filter[packageName.equals(packageURI)]
return viatraImportsWithSamePackage
}
/**
* Adds all referred patterns to a given set of patterns.
*/
def private Set<Pattern> allReferredPatterns(Set<Pattern> patterns) {
val res = new LinkedHashSet
res+=patterns
var boolean changed
do{
changed = false
val newElements = res.map[directlyReferredPatterns].flatten.filter[!res.contains(it)]
if(!newElements.empty) {
changed = true
res.addAll(newElements)
}
} while(changed)
return res
}
def private directlyReferredPatterns(Pattern pattern) {
return pattern
.bodies
.map[constraints]
.flatten
.filter(PatternCompositionConstraint)
.map[(call as PatternCall).patternRef].toSet
}
def private referredEcoreModels(Set<Pattern> patterns) {
patterns.map[eContainer as PatternModel].map[it.importPackages.packageImport.map[it.EPackage].filterNull].flatten.toSet
}
def private translatePatterns(Set<Pattern> xtextPattern) {
val res = new LinkedHashMap<Pattern,IQuerySpecification<?>>
val patterns = new LinkedList<IQuerySpecification<?>>
for(pattern : xtextPattern) {
val querySpecification = builder.getOrCreateSpecification(pattern,patterns,true)
res.put(pattern,querySpecification)
patterns += querySpecification
}
return res
}
def private calculateDerivedFeatures(Set<EPackage> packages, Iterable<IQuerySpecification<?>> patterns) {
val features = packages.map[EClassifiers].flatten.filter(EClass).map[it.EStructuralFeatures].flatten
val res = new HashMap
for(feature : features) {
/*
val QBFAnnotation = feature.EAnnotations.filter[it.source.equals("org.eclipse.viatra.query.querybasedfeature")].head
if(QBFAnnotation !== null) {
val targetFQN = QBFAnnotation.details.get("patternFQN")
val referredPattern = patterns.filter[
val fqn = it.fullyQualifiedName
fqn.equals(targetFQN)
].head
if(referredPattern!== null) {
res.put(referredPattern, feature)
}
}
*/
if (feature.derived){
//TODO we can check if feature is not from the ECORE MM
//TODO we can check that the found pattern has a "@QueryBasedFeature" annotation
val referredPattern = patterns.filter[
val fqnSplit = it.fullyQualifiedName.split("\\.")
val patName = fqnSplit.get(fqnSplit.length - 1)
patName.equals(feature.name)
].head
if(referredPattern!== null) {
res.put(referredPattern, feature)
}
}
}
// if (!res.empty) {
// println("Derived Features")
// res.entrySet.forEach[println(it)]
// }
return res
}
}
|