aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend
diff options
context:
space:
mode:
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend663
1 files changed, 436 insertions, 227 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend
index 23ea118b..dca10baf 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend
@@ -1,5 +1,6 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules 1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules
2 2
3import com.google.common.collect.ImmutableList
3import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.InverseRelationAssertion 4import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.InverseRelationAssertion
4import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion 5import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference 6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference
@@ -15,7 +16,7 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringTypeReference
15import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type 16import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type
16import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem 17import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
17import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics 18import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics
18import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator 19import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagator
19import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns 20import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns
20import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ObjectCreationPrecondition 21import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ObjectCreationPrecondition
21import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialBooleanInterpretation 22import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialBooleanInterpretation
@@ -27,78 +28,81 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.par
27import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialStringInterpretation 28import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialStringInterpretation
28import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation 29import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation
29import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory 30import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory
31import java.lang.reflect.Field
30import java.util.HashMap 32import java.util.HashMap
33import java.util.Iterator
31import java.util.LinkedHashMap 34import java.util.LinkedHashMap
32import java.util.LinkedList 35import java.util.LinkedList
33import java.util.List 36import java.util.List
34import java.util.Map 37import java.util.Map
38import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine
35import org.eclipse.viatra.query.runtime.api.GenericPatternMatch 39import org.eclipse.viatra.query.runtime.api.GenericPatternMatch
40import org.eclipse.viatra.query.runtime.api.IPatternMatch
36import org.eclipse.viatra.query.runtime.api.IQuerySpecification 41import org.eclipse.viatra.query.runtime.api.IQuerySpecification
42import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
37import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher 43import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
44import org.eclipse.viatra.query.runtime.emf.EMFScope
45import org.eclipse.viatra.query.runtime.rete.matcher.ReteBackendFactory
38import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule 46import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule
39import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory 47import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory
40import org.eclipse.xtend.lib.annotations.Data 48import org.eclipse.xtend.lib.annotations.Data
49import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
41import org.eclipse.xtext.xbase.lib.Functions.Function0 50import org.eclipse.xtext.xbase.lib.Functions.Function0
42 51
43class RefinementRuleProvider { 52class RefinementRuleProvider {
44 val extension BatchTransformationRuleFactory factory = new BatchTransformationRuleFactory 53 val extension BatchTransformationRuleFactory factory = new BatchTransformationRuleFactory
45 val extension PartialinterpretationFactory factory2 = PartialinterpretationFactory.eINSTANCE 54 val extension PartialinterpretationFactory factory2 = PartialinterpretationFactory.eINSTANCE
46 val extension LogiclanguageFactory factory3 = LogiclanguageFactory.eINSTANCE 55 val extension LogiclanguageFactory factory3 = LogiclanguageFactory.eINSTANCE
47 56
48 def canonizeName(String name) { 57 def canonizeName(String name) {
49 return name.replace(' ','_') 58 return name.replace(' ', '_')
59 }
60
61 def createUnitPrulePropagator(LogicProblem p, PartialInterpretation i, GeneratedPatterns patterns,
62 ScopePropagator scopePropagator, ModelGenerationStatistics statistics) {
63 new UnitRulePropagator(p, i, this, scopePropagator, patterns.mustRelationPropagationQueries, statistics)
50 } 64 }
51 65
52 def LinkedHashMap<ObjectCreationPrecondition, BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>>> createObjectRefinementRules( 66 def LinkedHashMap<ObjectCreationPrecondition, BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>>> createObjectRefinementRules(
53 LogicProblem p, 67 LogicProblem p,
54 PartialInterpretation i, 68 PartialInterpretation i,
55 GeneratedPatterns patterns, 69 GeneratedPatterns patterns,
56 ScopePropagator scopePropagator, 70 UnitRulePropagator unitRulePropagator,
57 boolean nameNewElement, 71 boolean nameNewElement,
58 ModelGenerationStatistics statistics 72 ModelGenerationStatistics statistics
59 ) 73 ) {
60 {
61 val res = new LinkedHashMap 74 val res = new LinkedHashMap
62 val recursiveObjectCreation = recursiveObjectCreation(p,i) 75 val recursiveObjectCreation = recursiveObjectCreation(p, i)
63 for(LHSEntry: patterns.refineObjectQueries.entrySet) { 76 for (LHSEntry : patterns.refineObjectQueries.entrySet) {
64 val containmentRelation = LHSEntry.key.containmentRelation 77 val containmentRelation = LHSEntry.key.containmentRelation
65 val inverseRelation = LHSEntry.key.inverseContainment 78 val inverseRelation = LHSEntry.key.inverseContainment
66 val type = LHSEntry.key.newType 79 val type = LHSEntry.key.newType
67 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> 80 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>>
68 val rule = createObjectCreationRule(p,containmentRelation,inverseRelation,type,recursiveObjectCreation.get(type),lhs,nameNewElement,scopePropagator,statistics) 81 val rule = createObjectCreationRule(p, containmentRelation, inverseRelation, type,
69 res.put(LHSEntry.key,rule) 82 recursiveObjectCreation.get(type), lhs, nameNewElement, unitRulePropagator, statistics)
83 res.put(LHSEntry.key, rule)
70 } 84 }
71 return res 85 return res
72 } 86 }
73 87
74 def private createObjectCreationRule( 88 def private createObjectCreationRule(LogicProblem p, Relation containmentRelation, Relation inverseRelation,
75 LogicProblem p, 89 Type type, List<ObjectCreationInterpretationData> recursiveObjectCreations,
76 Relation containmentRelation, 90 IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, boolean nameNewElement,
77 Relation inverseRelation, 91 UnitRulePropagator unitRulePropagator, ModelGenerationStatistics statistics) {
78 Type type, 92 val name = '''addObject_«type.name.canonizeName»«IF containmentRelation!==null»_by_«containmentRelation.name.canonizeName»«ENDIF»'''
79 List<ObjectCreationInterpretationData> recursiceObjectCreations, 93 val ruleBuilder = factory.createRule(lhs).name(name)
80 IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, 94 if (containmentRelation !== null) {
81 boolean nameNewElement, 95 if (inverseRelation !== null) {
82 ScopePropagator scopePropagator, 96 ruleBuilder.action [ match |
83 ModelGenerationStatistics statistics) 97 statistics.incrementTransformationCount
84 { 98// println(name)
85 val name = '''addObject_«type.name.canonizeName»«
86 IF containmentRelation!==null»_by_«containmentRelation.name.canonizeName»«ENDIF»'''
87 val ruleBuilder = factory.createRule
88 .name(name)
89 .precondition(lhs)
90 if(containmentRelation !== null) {
91 if(inverseRelation!== null) {
92 ruleBuilder.action[match |
93 //println(name)
94 val startTime = System.nanoTime 99 val startTime = System.nanoTime
95 //val problem = match.get(0) as LogicProblem 100 // val problem = match.get(0) as LogicProblem
96 val interpretation = match.get(1) as PartialInterpretation 101 val interpretation = match.get(1) as PartialInterpretation
97 val relationInterpretation = match.get(2) as PartialRelationInterpretation 102 val relationInterpretation = match.get(2) as PartialRelationInterpretation
98 val inverseRelationInterpretation = match.get(3) as PartialRelationInterpretation 103 val inverseRelationInterpretation = match.get(3) as PartialRelationInterpretation
99 val typeInterpretation = match.get(4) as PartialComplexTypeInterpretation 104 val typeInterpretation = match.get(4) as PartialComplexTypeInterpretation
100 val container = match.get(5) as DefinedElement 105 val container = match.get(5) as DefinedElement
101
102 createObjectActionWithContainmentAndInverse( 106 createObjectActionWithContainmentAndInverse(
103 nameNewElement, 107 nameNewElement,
104 interpretation, 108 interpretation,
@@ -107,22 +111,24 @@ class RefinementRuleProvider {
107 relationInterpretation, 111 relationInterpretation,
108 inverseRelationInterpretation, 112 inverseRelationInterpretation,
109 [createDefinedElement], 113 [createDefinedElement],
110 recursiceObjectCreations, 114 recursiveObjectCreations,
111 scopePropagator 115 unitRulePropagator
112 ) 116 )
113 117 statistics.addExecutionTime(System.nanoTime - startTime)
114 statistics.addExecutionTime(System.nanoTime-startTime) 118
119 unitRulePropagator.propagate
115 ] 120 ]
116 } else { 121 } else {
117 ruleBuilder.action[match | 122 ruleBuilder.action [ match |
118 //println(name) 123 statistics.incrementTransformationCount
124// println(name)
119 val startTime = System.nanoTime 125 val startTime = System.nanoTime
120 //val problem = match.get(0) as LogicProblem 126 // val problem = match.get(0) as LogicProblem
121 val interpretation = match.get(1) as PartialInterpretation 127 val interpretation = match.get(1) as PartialInterpretation
122 val relationInterpretation = match.get(2) as PartialRelationInterpretation 128 val relationInterpretation = match.get(2) as PartialRelationInterpretation
123 val typeInterpretation = match.get(3) as PartialComplexTypeInterpretation 129 val typeInterpretation = match.get(3) as PartialComplexTypeInterpretation
124 val container = match.get(4) as DefinedElement 130 val container = match.get(4) as DefinedElement
125 131
126 createObjectActionWithContainment( 132 createObjectActionWithContainment(
127 nameNewElement, 133 nameNewElement,
128 interpretation, 134 interpretation,
@@ -130,72 +136,80 @@ class RefinementRuleProvider {
130 container, 136 container,
131 relationInterpretation, 137 relationInterpretation,
132 [createDefinedElement], 138 [createDefinedElement],
133 recursiceObjectCreations, 139 recursiveObjectCreations,
134 scopePropagator 140 unitRulePropagator
135 ) 141 )
136 142 statistics.addExecutionTime(System.nanoTime - startTime)
137 statistics.addExecutionTime(System.nanoTime-startTime) 143
144 unitRulePropagator.propagate
138 ] 145 ]
139 } 146 }
140 } else { 147 } else {
141 ruleBuilder.action[match | 148 ruleBuilder.action [ match |
142 //println(name) 149 statistics.incrementTransformationCount
150// println(name)
143 val startTime = System.nanoTime 151 val startTime = System.nanoTime
144 //val problem = match.get(0) as LogicProblem 152 // val problem = match.get(0) as LogicProblem
145 val interpretation = match.get(1) as PartialInterpretation 153 val interpretation = match.get(1) as PartialInterpretation
146 val typeInterpretation = match.get(2) as PartialComplexTypeInterpretation 154 val typeInterpretation = match.get(2) as PartialComplexTypeInterpretation
147 155
148 createObjectAction( 156 createObjectAction(
149 nameNewElement, 157 nameNewElement,
150 interpretation, 158 interpretation,
151 typeInterpretation, 159 typeInterpretation,
152 [createDefinedElement], 160 [createDefinedElement],
153 recursiceObjectCreations, 161 recursiveObjectCreations,
154 scopePropagator 162 unitRulePropagator
155 ) 163 )
156 164 statistics.addExecutionTime(System.nanoTime - startTime)
157 statistics.addExecutionTime(System.nanoTime-startTime) 165
166 unitRulePropagator.propagate
158 ] 167 ]
159 } 168 }
160 return ruleBuilder.build 169 return ruleBuilder.build
161 } 170 }
162 171
163 def private recursiveObjectCreation(LogicProblem p, PartialInterpretation i) 172 def private recursiveObjectCreation(LogicProblem p, PartialInterpretation i) {
164 { 173 val Map<Type, List<ObjectCreationInterpretationData>> recursiveObjectCreation = new HashMap
165 val Map<Type,List<ObjectCreationInterpretationData>> recursiveObjectCreation = new HashMap 174 for (type : p.types) {
166 for(type : p.types) { 175 recursiveObjectCreation.put(type, new LinkedList)
167 recursiveObjectCreation.put(type,new LinkedList)
168 } 176 }
169 177
170 val containmentReferences = p.containmentHierarchies.head.containmentRelations 178 val containmentReferences = p.containmentHierarchies.head.containmentRelations
171 179
172 for(relationInterpretation : i.partialrelationinterpretation) { 180 for (relationInterpretation : i.partialrelationinterpretation) {
173 val relation = relationInterpretation.interpretationOf 181 val relation = relationInterpretation.interpretationOf
174 val lowermultiplicities = p.annotations.filter(LowerMultiplicityAssertion).filter[it.relation === relation] 182 val lowermultiplicities = p.annotations.filter(LowerMultiplicityAssertion).filter[it.relation === relation]
175 if((!lowermultiplicities.empty)) { 183 if ((!lowermultiplicities.empty)) {
176 val number = lowermultiplicities.head.lower 184 val number = lowermultiplicities.head.lower
177 if(number > 0) { 185 if (number > 0) {
178 val sourceTypeInterpretation = getTypeInterpretation(i, relation, 0) as PartialComplexTypeInterpretation 186 val sourceTypeInterpretation = getTypeInterpretation(i, relation,
179 val subtypeInterpretations = i.partialtypeinterpratation.filter(PartialComplexTypeInterpretation).filter[ 187 0) as PartialComplexTypeInterpretation
180 it === sourceTypeInterpretation || 188 val subtypeInterpretations = i.partialtypeinterpratation.filter(PartialComplexTypeInterpretation).
181 it.supertypeInterpretation.contains(sourceTypeInterpretation) 189 filter [
182 ] 190 it === sourceTypeInterpretation ||
183 191 it.supertypeInterpretation.contains(sourceTypeInterpretation)
184 if(containmentReferences.contains(relation)) { 192 ]
193
194 if (containmentReferences.contains(relation)) {
185 val targetTypeInterpretation = getTypeInterpretation(i, relation, 1) 195 val targetTypeInterpretation = getTypeInterpretation(i, relation, 1)
186 val targetType = (targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf 196 val targetType = (targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf
187 if((!targetType.isIsAbstract) && (targetType.supertypes.empty)) { 197 if ((!targetType.isIsAbstract) && (targetType.supertypes.empty)) {
188 val inverseAnnotation = p.annotations.filter(InverseRelationAssertion).filter[it.inverseA === relation || it.inverseB === relation] 198 val inverseAnnotation = p.annotations.filter(InverseRelationAssertion).filter [
189 if(!inverseAnnotation.empty) { 199 it.inverseA === relation || it.inverseB === relation
190 val onlyInverseAnnotation = if(inverseAnnotation.head.inverseA===relation) { 200 ]
191 inverseAnnotation.head.inverseB 201 if (!inverseAnnotation.empty) {
192 } else { 202 val onlyInverseAnnotation = if (inverseAnnotation.head.inverseA === relation) {
193 inverseAnnotation.head.inverseA 203 inverseAnnotation.head.inverseB
194 } 204 } else {
195 val inverseRelationInterpretation = i.partialrelationinterpretation.filter[it.interpretationOf === onlyInverseAnnotation].head 205 inverseAnnotation.head.inverseA
196 for(subTypeInterpretation : subtypeInterpretations) { 206 }
197 for(var times=0; times<number; times++) { 207 val inverseRelationInterpretation = i.partialrelationinterpretation.filter [
198 recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) += 208 it.interpretationOf === onlyInverseAnnotation
209 ].head
210 for (subTypeInterpretation : subtypeInterpretations) {
211 for (var times = 0; times < number; times++) {
212 recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) +=
199 new ObjectCreationInterpretationData( 213 new ObjectCreationInterpretationData(
200 i, 214 i,
201 targetTypeInterpretation, 215 targetTypeInterpretation,
@@ -206,9 +220,9 @@ class RefinementRuleProvider {
206 } 220 }
207 } 221 }
208 } else { 222 } else {
209 for(subTypeInterpretation : subtypeInterpretations) { 223 for (subTypeInterpretation : subtypeInterpretations) {
210 for(var times=0; times<number; times++) { 224 for (var times = 0; times < number; times++) {
211 recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) += 225 recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) +=
212 new ObjectCreationInterpretationData( 226 new ObjectCreationInterpretationData(
213 i, 227 i,
214 targetTypeInterpretation, 228 targetTypeInterpretation,
@@ -220,11 +234,11 @@ class RefinementRuleProvider {
220 } 234 }
221 } 235 }
222 } 236 }
223 } else if(relation.parameters.get(1) instanceof PrimitiveTypeReference) { 237 } else if (relation.parameters.get(1) instanceof PrimitiveTypeReference) {
224 val targetTypeInterpretation = getTypeInterpretation(i, relation, 1) 238 val targetTypeInterpretation = getTypeInterpretation(i, relation, 1)
225 for(subTypeInterpretation : subtypeInterpretations) { 239 for (subTypeInterpretation : subtypeInterpretations) {
226 for(var times=0; times<number; times++) { 240 for (var times = 0; times < number; times++) {
227 recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) += 241 recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) +=
228 new ObjectCreationInterpretationData( 242 new ObjectCreationInterpretationData(
229 i, 243 i,
230 targetTypeInterpretation, 244 targetTypeInterpretation,
@@ -238,129 +252,134 @@ class RefinementRuleProvider {
238 } 252 }
239 } 253 }
240 } 254 }
241 255
242 // Doing the recursion 256 // Doing the recursion
243 var objectCreations = new LinkedList(recursiveObjectCreation.values.flatten.toList) 257 var objectCreations = new LinkedList(recursiveObjectCreation.values.flatten.toList)
244 for(objectCreation : objectCreations) { 258 for (objectCreation : objectCreations) {
245 val newInterpretation = objectCreation.typeInterpretation 259 val newInterpretation = objectCreation.typeInterpretation
246 if(newInterpretation instanceof PartialComplexTypeInterpretation) { 260 if (newInterpretation instanceof PartialComplexTypeInterpretation) {
247 val newlyCreatedType = newInterpretation.interpretationOf 261 val newlyCreatedType = newInterpretation.interpretationOf
248 if(recursiveObjectCreation.containsKey(newlyCreatedType)) { 262 if (recursiveObjectCreation.containsKey(newlyCreatedType)) {
249 val actionsWhenTypeCreated = recursiveObjectCreation.get(newlyCreatedType) 263 val actionsWhenTypeCreated = recursiveObjectCreation.get(newlyCreatedType)
250 objectCreation.recursiveConstructors+=actionsWhenTypeCreated 264 objectCreation.recursiveConstructors += actionsWhenTypeCreated
251 } 265 }
252 } 266 }
253 } 267 }
254 268
255 // checking acyclicity 269 // checking acyclicity
256 for(objectCreation : objectCreations) { 270 for (objectCreation : objectCreations) {
257 var reachable = objectCreation.recursiveConstructors 271 var reachable = objectCreation.recursiveConstructors
258 do { 272 do {
259 if(reachable.contains(objectCreation)) { 273 if (reachable.contains(objectCreation)) {
260 throw new IllegalArgumentException('''Cicrle in the containment!''') 274 throw new IllegalArgumentException('''Cicrle in the containment!''')
261 } else { 275 } else {
262 reachable = reachable.map[it.recursiveConstructors].flatten.toList 276 reachable = reachable.map[it.recursiveConstructors].flatten.toList
263 } 277 }
264 } while(!reachable.empty) 278 } while (!reachable.empty)
265 } 279 }
266 280
267 return recursiveObjectCreation 281 return recursiveObjectCreation
268 } 282 }
269 283
270 private def getTypeInterpretation(PartialInterpretation i, RelationDeclaration relation, int index) { 284 private def getTypeInterpretation(PartialInterpretation i, RelationDeclaration relation, int index) {
271 val typeReference = relation.parameters.get(index) 285 val typeReference = relation.parameters.get(index)
272 return getTypeInterpretation(i,typeReference) 286 return getTypeInterpretation(i, typeReference)
273 287
274 } 288 }
289
275 private dispatch def getTypeInterpretation(PartialInterpretation i, ComplexTypeReference reference) { 290 private dispatch def getTypeInterpretation(PartialInterpretation i, ComplexTypeReference reference) {
276 return i.partialtypeinterpratation 291 return i.partialtypeinterpratation.filter(PartialComplexTypeInterpretation).filter [
277 .filter(PartialComplexTypeInterpretation) 292 it.getInterpretationOf == reference.referred
278 .filter[it.getInterpretationOf == reference.referred] 293 ].head
279 .head
280 } 294 }
295
281 private dispatch def getTypeInterpretation(PartialInterpretation i, BoolTypeReference reference) { 296 private dispatch def getTypeInterpretation(PartialInterpretation i, BoolTypeReference reference) {
282 return i.partialtypeinterpratation 297 return i.partialtypeinterpratation.filter(PartialBooleanInterpretation).head
283 .filter(PartialBooleanInterpretation)
284 .head
285 } 298 }
299
286 private dispatch def getTypeInterpretation(PartialInterpretation i, IntTypeReference reference) { 300 private dispatch def getTypeInterpretation(PartialInterpretation i, IntTypeReference reference) {
287 return i.partialtypeinterpratation 301 return i.partialtypeinterpratation.filter(PartialIntegerInterpretation).head
288 .filter(PartialIntegerInterpretation)
289 .head
290 } 302 }
303
291 private dispatch def getTypeInterpretation(PartialInterpretation i, RealTypeReference reference) { 304 private dispatch def getTypeInterpretation(PartialInterpretation i, RealTypeReference reference) {
292 return i.partialtypeinterpratation 305 return i.partialtypeinterpratation.filter(PartialRealInterpretation).head
293 .filter(PartialRealInterpretation)
294 .head
295 } 306 }
307
296 private dispatch def getTypeInterpretation(PartialInterpretation i, StringTypeReference reference) { 308 private dispatch def getTypeInterpretation(PartialInterpretation i, StringTypeReference reference) {
297 return i.partialtypeinterpratation 309 return i.partialtypeinterpratation.filter(PartialStringInterpretation).head
298 .filter(PartialStringInterpretation)
299 .head
300 } 310 }
301 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialComplexTypeInterpretation reference) { [createDefinedElement] } 311
302 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialBooleanInterpretation reference) { [createBooleanElement] } 312 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialComplexTypeInterpretation reference) {
303 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialIntegerInterpretation reference) { [createIntegerElement] } 313 [createDefinedElement]
304 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialRealInterpretation reference) { [createRealElement] } 314 }
305 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialStringInterpretation reference) { [createStringElement] } 315
306 316 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialBooleanInterpretation reference) {
307 317 [createBooleanElement]
308 def createRelationRefinementRules(GeneratedPatterns patterns, ModelGenerationStatistics statistics) { 318 }
319
320 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialIntegerInterpretation reference) {
321 [createIntegerElement]
322 }
323
324 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialRealInterpretation reference) {
325 [createRealElement]
326 }
327
328 private dispatch def Function0<DefinedElement> getTypeConstructor(PartialStringInterpretation reference) {
329 [createStringElement]
330 }
331
332 def createRelationRefinementRules(GeneratedPatterns patterns, UnitRulePropagator unitRulePropagator,
333 ModelGenerationStatistics statistics) {
309 val res = new LinkedHashMap 334 val res = new LinkedHashMap
310 for(LHSEntry: patterns.refinerelationQueries.entrySet) { 335 for (LHSEntry : patterns.refineRelationQueries.entrySet) {
311 val declaration = LHSEntry.key.key 336 val declaration = LHSEntry.key.key
312 val inverseReference = LHSEntry.key.value 337 val inverseReference = LHSEntry.key.value
313 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> 338 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>>
314 val rule = createRelationRefinementRule(declaration,inverseReference,lhs,statistics) 339 val rule = createRelationRefinementRule(declaration, inverseReference, lhs, unitRulePropagator, statistics)
315 res.put(LHSEntry.key,rule) 340 res.put(LHSEntry.key, rule)
316 } 341 }
317 return res 342 return res
318 } 343 }
319 344
320 def private BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>> 345 def private BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>> createRelationRefinementRule(
321 createRelationRefinementRule(RelationDeclaration declaration, Relation inverseRelation, IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, ModelGenerationStatistics statistics) 346 RelationDeclaration declaration, Relation inverseRelation,
322 { 347 IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, UnitRulePropagator unitRulePropagator,
348 ModelGenerationStatistics statistics) {
323 val name = '''addRelation_«declaration.name.canonizeName»«IF inverseRelation !== null»_and_«inverseRelation.name.canonizeName»«ENDIF»''' 349 val name = '''addRelation_«declaration.name.canonizeName»«IF inverseRelation !== null»_and_«inverseRelation.name.canonizeName»«ENDIF»'''
324 val ruleBuilder = factory.createRule 350 val ruleBuilder = factory.createRule(lhs).name(name)
325 .name(name)
326 .precondition(lhs)
327 if (inverseRelation === null) { 351 if (inverseRelation === null) {
328 ruleBuilder.action [ match | 352 ruleBuilder.action [ match |
329 val startTime = System.nanoTime 353 statistics.incrementTransformationCount
330 //println(name) 354// println(name)
331 // val problem = match.get(0) as LogicProblem 355 val startTime = System.nanoTime
332 // val interpretation = match.get(1) as PartialInterpretation 356 createRelationLinkAction(match, unitRulePropagator)
333 val relationInterpretation = match.get(2) as PartialRelationInterpretation 357 statistics.addExecutionTime(System.nanoTime - startTime)
334 val src = match.get(3) as DefinedElement 358
335 val trg = match.get(4) as DefinedElement 359 unitRulePropagator.propagate
336 createRelationLinkAction(src, trg, relationInterpretation)
337 statistics.addExecutionTime(System.nanoTime-startTime)
338 ] 360 ]
339 } else { 361 } else {
340 ruleBuilder.action [ match | 362 ruleBuilder.action [ match |
341 val startTime = System.nanoTime 363 statistics.incrementTransformationCount
342 //println(name) 364// println(name)
343 // val problem = match.get(0) as LogicProblem 365 val startTime = System.nanoTime
344 // val interpretation = match.get(1) as PartialInterpretation 366 createRelationLinkWithInverse(match, unitRulePropagator)
345 val relationInterpretation = match.get(2) as PartialRelationInterpretation 367 statistics.addExecutionTime(System.nanoTime - startTime)
346 val inverseInterpretation = match.get(3) as PartialRelationInterpretation 368
347 val src = match.get(4) as DefinedElement 369 unitRulePropagator.propagate
348 val trg = match.get(5) as DefinedElement
349 createRelationLinkWithInverse(src, trg, relationInterpretation, inverseInterpretation)
350 statistics.addExecutionTime(System.nanoTime-startTime)
351 ] 370 ]
352 } 371 }
353 372
354 return ruleBuilder.build 373 return ruleBuilder.build
355 } 374 }
356 375
357 ///////////////////////// 376 // ///////////////////////
358 // Actions 377 // Actions
359 ///////////////////////// 378 // ///////////////////////
360 379 protected def void createObjectAction(boolean nameNewElement, ObjectCreationInterpretationData data,
361 protected def void createObjectAction(boolean nameNewElement, ObjectCreationInterpretationData data, DefinedElement container, ScopePropagator scopePropagator) { 380 DefinedElement container, UnitRulePropagator unitRulePropagator) {
362 if(data.containerInterpretation !== null) { 381 if (data.containerInterpretation !== null) {
363 if(data.containerInverseInterpretation !== null) { 382 if (data.containerInverseInterpretation !== null) {
364 createObjectActionWithContainmentAndInverse( 383 createObjectActionWithContainmentAndInverse(
365 nameNewElement, 384 nameNewElement,
366 data.interpretation, 385 data.interpretation,
@@ -370,7 +389,7 @@ class RefinementRuleProvider {
370 data.containerInverseInterpretation, 389 data.containerInverseInterpretation,
371 data.constructor, 390 data.constructor,
372 data.recursiveConstructors, 391 data.recursiveConstructors,
373 scopePropagator 392 unitRulePropagator
374 ) 393 )
375 } else { 394 } else {
376 createObjectActionWithContainment( 395 createObjectActionWithContainment(
@@ -381,7 +400,7 @@ class RefinementRuleProvider {
381 data.containerInterpretation, 400 data.containerInterpretation,
382 data.constructor, 401 data.constructor,
383 data.recursiveConstructors, 402 data.recursiveConstructors,
384 scopePropagator 403 unitRulePropagator
385 ) 404 )
386 } 405 }
387 } else { 406 } else {
@@ -391,12 +410,12 @@ class RefinementRuleProvider {
391 data.typeInterpretation, 410 data.typeInterpretation,
392 data.constructor, 411 data.constructor,
393 data.recursiveConstructors, 412 data.recursiveConstructors,
394 scopePropagator 413 unitRulePropagator
395 ) 414 )
396 } 415 }
397 416
398 } 417 }
399 418
400 protected def createObjectActionWithContainmentAndInverse( 419 protected def createObjectActionWithContainmentAndInverse(
401 boolean nameNewElement, 420 boolean nameNewElement,
402 PartialInterpretation interpretation, 421 PartialInterpretation interpretation,
@@ -406,39 +425,41 @@ class RefinementRuleProvider {
406 PartialRelationInterpretation inverseRelationInterpretation, 425 PartialRelationInterpretation inverseRelationInterpretation,
407 Function0<DefinedElement> constructor, 426 Function0<DefinedElement> constructor,
408 List<ObjectCreationInterpretationData> recursiceObjectCreations, 427 List<ObjectCreationInterpretationData> recursiceObjectCreations,
409 ScopePropagator scopePropagator 428 UnitRulePropagator unitRulePropagator
410 ) { 429 ) {
411 val newElement = constructor.apply 430 val newElement = constructor.apply
412 if(nameNewElement) { 431 if (nameNewElement) {
413 newElement.name = '''new «interpretation.newElements.size»''' 432 newElement.name = '''new «interpretation.newElements.size»'''
414 } 433 }
415 434
416 // Types 435 // Types
417 typeInterpretation.elements += newElement 436 typeInterpretation.elements += newElement
418 if(typeInterpretation instanceof PartialComplexTypeInterpretation) { 437 if (typeInterpretation instanceof PartialComplexTypeInterpretation) {
419 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] 438 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement]
420 } 439 }
421 // ContainmentRelation 440 // ContainmentRelation
422 val newLink1 = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] 441 val newLink1 = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement]
423 relationInterpretation.relationlinks+=newLink1 442 relationInterpretation.relationlinks += newLink1
424 // Inverse Containment 443 // Inverse Containment
425 val newLink2 = factory2.createBinaryElementRelationLink => [it.param1 = newElement it.param2 = container] 444 val newLink2 = factory2.createBinaryElementRelationLink => [it.param1 = newElement it.param2 = container]
426 inverseRelationInterpretation.relationlinks+=newLink2 445 inverseRelationInterpretation.relationlinks += newLink2
427 446
428 // Scope propagation 447 // Scope propagation
429 scopePropagator.propagateAdditionToType(typeInterpretation) 448 unitRulePropagator.decrementTypeScope(typeInterpretation)
430 449 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
450 unitRulePropagator.addedToRelation(inverseRelationInterpretation.interpretationOf)
451
431 // Existence 452 // Existence
432 interpretation.newElements+=newElement 453 interpretation.newElements += newElement
433 454
434 // Do recursive object creation 455 // Do recursive object creation
435 for(newConstructor : recursiceObjectCreations) { 456 for (newConstructor : recursiceObjectCreations) {
436 createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) 457 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
437 } 458 }
438 459
439 return newElement 460 return newElement
440 } 461 }
441 462
442 protected def createObjectActionWithContainment( 463 protected def createObjectActionWithContainment(
443 boolean nameNewElement, 464 boolean nameNewElement,
444 PartialInterpretation interpretation, 465 PartialInterpretation interpretation,
@@ -447,79 +468,267 @@ class RefinementRuleProvider {
447 PartialRelationInterpretation relationInterpretation, 468 PartialRelationInterpretation relationInterpretation,
448 Function0<DefinedElement> constructor, 469 Function0<DefinedElement> constructor,
449 List<ObjectCreationInterpretationData> recursiceObjectCreations, 470 List<ObjectCreationInterpretationData> recursiceObjectCreations,
450 ScopePropagator scopePropagator 471 UnitRulePropagator unitRulePropagator
451 ) { 472 ) {
452 val newElement = constructor.apply 473 val newElement = constructor.apply
453 if(nameNewElement) { 474 if (nameNewElement) {
454 newElement.name = '''new «interpretation.newElements.size»''' 475 newElement.name = '''new «interpretation.newElements.size»'''
455 } 476 }
456 477
457 // Types 478 // Types
458 typeInterpretation.elements += newElement 479 typeInterpretation.elements += newElement
459 if(typeInterpretation instanceof PartialComplexTypeInterpretation) { 480 if (typeInterpretation instanceof PartialComplexTypeInterpretation) {
460 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] 481 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement]
461 } 482 }
462 // ContainmentRelation 483 // ContainmentRelation
463 val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] 484 val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement]
464 relationInterpretation.relationlinks+=newLink 485 relationInterpretation.relationlinks += newLink
465 486 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
487
466 // Scope propagation 488 // Scope propagation
467 scopePropagator.propagateAdditionToType(typeInterpretation) 489 unitRulePropagator.decrementTypeScope(typeInterpretation)
468 490
469 // Existence 491 // Existence
470 interpretation.newElements+=newElement 492 interpretation.newElements += newElement
471 493
472 // Do recursive object creation 494 // Do recursive object creation
473 for(newConstructor : recursiceObjectCreations) { 495 for (newConstructor : recursiceObjectCreations) {
474 createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) 496 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
475 } 497 }
476 498
477 return newElement 499 return newElement
478 } 500 }
479 501
480 protected def createObjectAction( 502 protected def createObjectAction(boolean nameNewElement, PartialInterpretation interpretation,
481 boolean nameNewElement, 503 PartialTypeInterpratation typeInterpretation, Function0<DefinedElement> constructor,
482 PartialInterpretation interpretation, 504 List<ObjectCreationInterpretationData> recursiceObjectCreations, UnitRulePropagator unitRulePropagator) {
483 PartialTypeInterpratation typeInterpretation,
484 Function0<DefinedElement> constructor,
485 List<ObjectCreationInterpretationData> recursiceObjectCreations,
486 ScopePropagator scopePropagator)
487 {
488 val newElement = constructor.apply 505 val newElement = constructor.apply
489 if(nameNewElement) { 506 if (nameNewElement) {
490 newElement.name = '''new «interpretation.newElements.size»''' 507 newElement.name = '''new «interpretation.newElements.size»'''
491 } 508 }
492 509
493 // Types 510 // Types
494 typeInterpretation.elements += newElement 511 typeInterpretation.elements += newElement
495 if(typeInterpretation instanceof PartialComplexTypeInterpretation) { 512 if (typeInterpretation instanceof PartialComplexTypeInterpretation) {
496 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] 513 typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement]
497 } 514 }
498 515
499 // Scope propagation 516 // Scope propagation
500 scopePropagator.propagateAdditionToType(typeInterpretation) 517 unitRulePropagator.decrementTypeScope(typeInterpretation)
501 518
502 // Existence 519 // Existence
503 interpretation.newElements+=newElement 520 interpretation.newElements += newElement
504 521
505 // Do recursive object creation 522 // Do recursive object creation
506 for(newConstructor : recursiceObjectCreations) { 523 for (newConstructor : recursiceObjectCreations) {
507 createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) 524 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
508 } 525 }
509 526
510 return newElement 527 return newElement
511 } 528 }
512 529
513 protected def boolean createRelationLinkAction(DefinedElement src, DefinedElement trg, PartialRelationInterpretation relationInterpretation) { 530 protected def createRelationLinkAction(IPatternMatch match, UnitRulePropagator unitRulePropagator) {
531 // val problem = match.get(0) as LogicProblem
532 // val interpretation = match.get(1) as PartialInterpretation
533 val relationInterpretation = match.get(2) as PartialRelationInterpretation
534 val src = match.get(3) as DefinedElement
535 val trg = match.get(4) as DefinedElement
536 createRelationLinkAction(src, trg, relationInterpretation, unitRulePropagator)
537 }
538
539 protected def void createRelationLinkAction(DefinedElement src, DefinedElement trg,
540 PartialRelationInterpretation relationInterpretation, UnitRulePropagator unitRulePropagator) {
514 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] 541 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg]
515 relationInterpretation.relationlinks += link 542 relationInterpretation.relationlinks += link
543 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
516 } 544 }
517 545
518 protected def boolean createRelationLinkWithInverse(DefinedElement src, DefinedElement trg, PartialRelationInterpretation relationInterpretation, PartialRelationInterpretation inverseInterpretation) { 546 protected def void createRelationLinkWithInverse(IPatternMatch match, UnitRulePropagator unitRulePropagator) {
547 // val problem = match.get(0) as LogicProblem
548 // val interpretation = match.get(1) as PartialInterpretation
549 val relationInterpretation = match.get(2) as PartialRelationInterpretation
550 val inverseInterpretation = match.get(3) as PartialRelationInterpretation
551 val src = match.get(4) as DefinedElement
552 val trg = match.get(5) as DefinedElement
553 createRelationLinkWithInverse(src, trg, relationInterpretation, inverseInterpretation, unitRulePropagator)
554 }
555
556 protected def void createRelationLinkWithInverse(DefinedElement src, DefinedElement trg,
557 PartialRelationInterpretation relationInterpretation, PartialRelationInterpretation inverseInterpretation,
558 UnitRulePropagator unitRulePropagator) {
519 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] 559 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg]
520 relationInterpretation.relationlinks += link 560 relationInterpretation.relationlinks += link
521 val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src] 561 val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src]
522 inverseInterpretation.relationlinks += inverseLink 562 inverseInterpretation.relationlinks += inverseLink
563 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
564 unitRulePropagator.addedToRelation(inverseInterpretation.interpretationOf)
565 }
566
567 static class UnitRulePropagator {
568 val LogicProblem p
569 val PartialInterpretation i
570 val RefinementRuleProvider refinementRuleProvider
571 var AdvancedViatraQueryEngine queryEngine
572 var Field delayMessageDelivery
573 val ScopePropagator scopePropagator
574 val List<AbstractMustRelationPropagator<? extends IPatternMatch>> propagators
575 val ModelGenerationStatistics statistics
576
577 new(LogicProblem p, PartialInterpretation i, RefinementRuleProvider refinementRuleProvider,
578 ScopePropagator scopePropagator,
579 Map<Pair<RelationDeclaration, Relation>, IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> mustRelationPropagationQueries,
580 ModelGenerationStatistics statistics) {
581 this.p = p
582 this.i = i
583 this.refinementRuleProvider = refinementRuleProvider
584 queryEngine = ViatraQueryEngine.on(new EMFScope(i)) as AdvancedViatraQueryEngine
585 delayMessageDelivery = queryEngine.class.getDeclaredField("delayMessageDelivery")
586 delayMessageDelivery.accessible = true
587 this.scopePropagator = scopePropagator
588 propagators = ImmutableList.copyOf(mustRelationPropagationQueries.entrySet.map [ entry |
589 val matcher = queryEngine.getMatcher(entry.value)
590 getPropagator(entry.key.key, entry.key.value, matcher)
591 ])
592 this.statistics = statistics
593 }
594
595 def decrementTypeScope(PartialTypeInterpratation partialTypeInterpratation) {
596 scopePropagator.decrementTypeScope(partialTypeInterpratation)
597 }
598
599 def addedToRelation(Relation r) {
600 scopePropagator.addedToRelation(r)
601 }
602
603 def propagate() {
604 var boolean changed
605 do {
606 val scopeChanged = propagateScope()
607 val mustChanged = propagateMustRelations()
608 changed = scopeChanged || mustChanged
609 } while (changed)
610 }
611
612 protected def flushQueryEngine() {
613 if (queryEngine.updatePropagationDelayed) {
614 delayMessageDelivery.setBoolean(queryEngine, false)
615 queryEngine.getQueryBackend(ReteBackendFactory.INSTANCE).flushUpdates
616 delayMessageDelivery.setBoolean(queryEngine, true)
617 }
618 }
619
620 protected def propagateScope() {
621 if (scopePropagator.scopePropagationNeeded) {
622 if (scopePropagator.queryEngineFlushRequiredBeforePropagation) {
623 flushQueryEngine()
624 }
625 val propagatorStartTime = System.nanoTime
626 scopePropagator.propagateAllScopeConstraints()
627 statistics.addScopePropagationTime(System.nanoTime - propagatorStartTime)
628 true
629 } else {
630 false
631 }
632 }
633
634 protected def propagateMustRelations() {
635 if (propagators.empty) {
636 return false
637 }
638 flushQueryEngine()
639 val propagatorStartTime = System.nanoTime
640 var changed = false
641 for (propagator : propagators) {
642 changed = propagator.propagate(p, i, refinementRuleProvider, this) || changed
643 }
644 statistics.addMustRelationPropagationTime(System.nanoTime - propagatorStartTime)
645 changed
646 }
647
648 private static def <T extends IPatternMatch> getPropagator(Relation relation, Relation inverseRelation,
649 ViatraQueryMatcher<T> matcher) {
650 if (inverseRelation === null) {
651 new MustRelationPropagator(matcher)
652 } else if (relation == inverseRelation) {
653 new MustRelationPropagatorWithSelfInverse(matcher)
654 } else {
655 new MustRelationPropagatorWithInverse(matcher)
656 }
657 }
658
659 @FinalFieldsConstructor
660 private static abstract class AbstractMustRelationPropagator<T extends IPatternMatch> {
661 val ViatraQueryMatcher<T> matcher
662
663 def propagate(LogicProblem p, PartialInterpretation i, RefinementRuleProvider refinementRuleProvider,
664 UnitRulePropagator unitRulePropagator) {
665 val iterator = getIterator(p, i)
666 if (!iterator.hasNext) {
667 return false
668 }
669 iterate(iterator, refinementRuleProvider, unitRulePropagator)
670 true
671 }
672
673 def iterate(Iterator<T> iterator, RefinementRuleProvider refinementRuleProvider,
674 UnitRulePropagator unitRulePropagator) {
675 while (iterator.hasNext) {
676 doPropagate(iterator.next, refinementRuleProvider, unitRulePropagator)
677 }
678 }
679
680 protected def getIterator(LogicProblem p, PartialInterpretation i) {
681 val partialMatch = matcher.newEmptyMatch
682 partialMatch.set(0, p)
683 partialMatch.set(1, i)
684 matcher.streamAllMatches(partialMatch).iterator
685 }
686
687 protected def void doPropagate(T match, RefinementRuleProvider refinementRuleProvider,
688 UnitRulePropagator unitRulePropagator)
689 }
690
691 private static class MustRelationPropagator<T extends IPatternMatch> extends AbstractMustRelationPropagator<T> {
692 new(ViatraQueryMatcher<T> matcher) {
693 super(matcher)
694 }
695
696 override protected doPropagate(T match, RefinementRuleProvider refinementRuleProvider,
697 UnitRulePropagator unitRulePropagator) {
698 refinementRuleProvider.createRelationLinkAction(match, unitRulePropagator)
699 }
700 }
701
702 private static class MustRelationPropagatorWithInverse<T extends IPatternMatch> extends AbstractMustRelationPropagator<T> {
703 new(ViatraQueryMatcher<T> matcher) {
704 super(matcher)
705 }
706
707 override protected doPropagate(T match, RefinementRuleProvider refinementRuleProvider,
708 UnitRulePropagator unitRulePropagator) {
709 refinementRuleProvider.createRelationLinkWithInverse(match, unitRulePropagator)
710 }
711 }
712
713 private static class MustRelationPropagatorWithSelfInverse<T extends IPatternMatch> extends MustRelationPropagatorWithInverse<T> {
714 new(ViatraQueryMatcher<T> matcher) {
715 super(matcher)
716 }
717
718 override iterate(Iterator<T> iterator, RefinementRuleProvider refinementRuleProvider,
719 UnitRulePropagator unitRulePropagator) {
720 val pairs = newHashSet
721 while (iterator.hasNext) {
722 val match = iterator.next
723 val src = match.get(4) as DefinedElement
724 val trg = match.get(5) as DefinedElement
725 if (!pairs.contains(trg -> src)) {
726 pairs.add(src -> trg)
727 doPropagate(match, refinementRuleProvider, unitRulePropagator)
728 }
729 }
730 }
731 }
523 } 732 }
524} 733}
525 734