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.xtend344
1 files changed, 243 insertions, 101 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 f7fe97a3..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
@@ -29,12 +30,14 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.par
29import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory 30import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory
30import java.lang.reflect.Field 31import java.lang.reflect.Field
31import java.util.HashMap 32import java.util.HashMap
33import java.util.Iterator
32import java.util.LinkedHashMap 34import java.util.LinkedHashMap
33import java.util.LinkedList 35import java.util.LinkedList
34import java.util.List 36import java.util.List
35import java.util.Map 37import java.util.Map
36import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine 38import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine
37import org.eclipse.viatra.query.runtime.api.GenericPatternMatch 39import org.eclipse.viatra.query.runtime.api.GenericPatternMatch
40import org.eclipse.viatra.query.runtime.api.IPatternMatch
38import org.eclipse.viatra.query.runtime.api.IQuerySpecification 41import org.eclipse.viatra.query.runtime.api.IQuerySpecification
39import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine 42import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
40import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher 43import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
@@ -43,6 +46,7 @@ import org.eclipse.viatra.query.runtime.rete.matcher.ReteBackendFactory
43import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule 46import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule
44import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory 47import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory
45import org.eclipse.xtend.lib.annotations.Data 48import org.eclipse.xtend.lib.annotations.Data
49import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
46import org.eclipse.xtext.xbase.lib.Functions.Function0 50import org.eclipse.xtext.xbase.lib.Functions.Function0
47 51
48class RefinementRuleProvider { 52class RefinementRuleProvider {
@@ -50,57 +54,55 @@ class RefinementRuleProvider {
50 val extension PartialinterpretationFactory factory2 = PartialinterpretationFactory.eINSTANCE 54 val extension PartialinterpretationFactory factory2 = PartialinterpretationFactory.eINSTANCE
51 val extension LogiclanguageFactory factory3 = LogiclanguageFactory.eINSTANCE 55 val extension LogiclanguageFactory factory3 = LogiclanguageFactory.eINSTANCE
52 56
53 var AdvancedViatraQueryEngine queryEngine
54 var Field delayMessageDelivery
55
56 def canonizeName(String name) { 57 def canonizeName(String name) {
57 return name.replace(' ', '_') 58 return name.replace(' ', '_')
58 } 59 }
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)
64 }
65
60 def LinkedHashMap<ObjectCreationPrecondition, BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>>> createObjectRefinementRules( 66 def LinkedHashMap<ObjectCreationPrecondition, BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>>> createObjectRefinementRules(
61 LogicProblem p, 67 LogicProblem p,
62 PartialInterpretation i, 68 PartialInterpretation i,
63 GeneratedPatterns patterns, 69 GeneratedPatterns patterns,
64 ScopePropagator scopePropagator, 70 UnitRulePropagator unitRulePropagator,
65 boolean nameNewElement, 71 boolean nameNewElement,
66 ModelGenerationStatistics statistics 72 ModelGenerationStatistics statistics
67 ) { 73 ) {
68 val res = new LinkedHashMap 74 val res = new LinkedHashMap
69 val recursiveObjectCreation = recursiveObjectCreation(p, i) 75 val recursiveObjectCreation = recursiveObjectCreation(p, i)
70 queryEngine = ViatraQueryEngine.on(new EMFScope(i)) as AdvancedViatraQueryEngine
71 delayMessageDelivery = queryEngine.class.getDeclaredField("delayMessageDelivery")
72 delayMessageDelivery.accessible = true
73 for (LHSEntry : patterns.refineObjectQueries.entrySet) { 76 for (LHSEntry : patterns.refineObjectQueries.entrySet) {
74 val containmentRelation = LHSEntry.key.containmentRelation 77 val containmentRelation = LHSEntry.key.containmentRelation
75 val inverseRelation = LHSEntry.key.inverseContainment 78 val inverseRelation = LHSEntry.key.inverseContainment
76 val type = LHSEntry.key.newType 79 val type = LHSEntry.key.newType
77 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> 80 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>>
78 val rule = createObjectCreationRule(p, containmentRelation, inverseRelation, type, 81 val rule = createObjectCreationRule(p, containmentRelation, inverseRelation, type,
79 recursiveObjectCreation.get(type), lhs, nameNewElement, scopePropagator, statistics) 82 recursiveObjectCreation.get(type), lhs, nameNewElement, unitRulePropagator, statistics)
80 res.put(LHSEntry.key, rule) 83 res.put(LHSEntry.key, rule)
81 } 84 }
82 return res 85 return res
83 } 86 }
84 87
85 def private createObjectCreationRule(LogicProblem p, Relation containmentRelation, Relation inverseRelation, 88 def private createObjectCreationRule(LogicProblem p, Relation containmentRelation, Relation inverseRelation,
86 Type type, List<ObjectCreationInterpretationData> recursiceObjectCreations, 89 Type type, List<ObjectCreationInterpretationData> recursiveObjectCreations,
87 IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, boolean nameNewElement, 90 IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, boolean nameNewElement,
88 ScopePropagator scopePropagator, ModelGenerationStatistics statistics) { 91 UnitRulePropagator unitRulePropagator, ModelGenerationStatistics statistics) {
89 val name = '''addObject_«type.name.canonizeName»«IF containmentRelation!==null»_by_«containmentRelation.name.canonizeName»«ENDIF»''' 92 val name = '''addObject_«type.name.canonizeName»«IF containmentRelation!==null»_by_«containmentRelation.name.canonizeName»«ENDIF»'''
90 val ruleBuilder = factory.createRule(lhs).name(name) 93 val ruleBuilder = factory.createRule(lhs).name(name)
91 if (containmentRelation !== null) { 94 if (containmentRelation !== null) {
92 if (inverseRelation !== null) { 95 if (inverseRelation !== null) {
93 ruleBuilder.action [ match | 96 ruleBuilder.action [ match |
94 statistics.incrementTransformationCount 97 statistics.incrementTransformationCount
95// println(name) 98// println(name)
99 val startTime = System.nanoTime
96 // val problem = match.get(0) as LogicProblem 100 // val problem = match.get(0) as LogicProblem
97 val interpretation = match.get(1) as PartialInterpretation 101 val interpretation = match.get(1) as PartialInterpretation
98 val relationInterpretation = match.get(2) as PartialRelationInterpretation 102 val relationInterpretation = match.get(2) as PartialRelationInterpretation
99 val inverseRelationInterpretation = match.get(3) as PartialRelationInterpretation 103 val inverseRelationInterpretation = match.get(3) as PartialRelationInterpretation
100 val typeInterpretation = match.get(4) as PartialComplexTypeInterpretation 104 val typeInterpretation = match.get(4) as PartialComplexTypeInterpretation
101 val container = match.get(5) as DefinedElement 105 val container = match.get(5) as DefinedElement
102
103 val startTime = System.nanoTime
104 createObjectActionWithContainmentAndInverse( 106 createObjectActionWithContainmentAndInverse(
105 nameNewElement, 107 nameNewElement,
106 interpretation, 108 interpretation,
@@ -109,29 +111,24 @@ class RefinementRuleProvider {
109 relationInterpretation, 111 relationInterpretation,
110 inverseRelationInterpretation, 112 inverseRelationInterpretation,
111 [createDefinedElement], 113 [createDefinedElement],
112 recursiceObjectCreations, 114 recursiveObjectCreations,
113 scopePropagator 115 unitRulePropagator
114 ) 116 )
115 statistics.addExecutionTime(System.nanoTime - startTime) 117 statistics.addExecutionTime(System.nanoTime - startTime)
116 118
117 flushQueryEngine(scopePropagator) 119 unitRulePropagator.propagate
118
119 // Scope propagation
120 val propagatorStartTime = System.nanoTime
121 scopePropagator.propagateAllScopeConstraints()
122 statistics.addScopePropagationTime(System.nanoTime - propagatorStartTime)
123 ] 120 ]
124 } else { 121 } else {
125 ruleBuilder.action [ match | 122 ruleBuilder.action [ match |
126 statistics.incrementTransformationCount 123 statistics.incrementTransformationCount
127// println(name) 124// println(name)
125 val startTime = System.nanoTime
128 // val problem = match.get(0) as LogicProblem 126 // val problem = match.get(0) as LogicProblem
129 val interpretation = match.get(1) as PartialInterpretation 127 val interpretation = match.get(1) as PartialInterpretation
130 val relationInterpretation = match.get(2) as PartialRelationInterpretation 128 val relationInterpretation = match.get(2) as PartialRelationInterpretation
131 val typeInterpretation = match.get(3) as PartialComplexTypeInterpretation 129 val typeInterpretation = match.get(3) as PartialComplexTypeInterpretation
132 val container = match.get(4) as DefinedElement 130 val container = match.get(4) as DefinedElement
133 131
134 val startTime = System.nanoTime
135 createObjectActionWithContainment( 132 createObjectActionWithContainment(
136 nameNewElement, 133 nameNewElement,
137 interpretation, 134 interpretation,
@@ -139,44 +136,34 @@ class RefinementRuleProvider {
139 container, 136 container,
140 relationInterpretation, 137 relationInterpretation,
141 [createDefinedElement], 138 [createDefinedElement],
142 recursiceObjectCreations, 139 recursiveObjectCreations,
143 scopePropagator 140 unitRulePropagator
144 ) 141 )
145 statistics.addExecutionTime(System.nanoTime - startTime) 142 statistics.addExecutionTime(System.nanoTime - startTime)
146 143
147 flushQueryEngine(scopePropagator) 144 unitRulePropagator.propagate
148
149 // Scope propagation
150 val propagatorStartTime = System.nanoTime
151 scopePropagator.propagateAllScopeConstraints()
152 statistics.addScopePropagationTime(System.nanoTime - propagatorStartTime)
153 ] 145 ]
154 } 146 }
155 } else { 147 } else {
156 ruleBuilder.action [ match | 148 ruleBuilder.action [ match |
157 statistics.incrementTransformationCount 149 statistics.incrementTransformationCount
158// println(name) 150// println(name)
151 val startTime = System.nanoTime
159 // val problem = match.get(0) as LogicProblem 152 // val problem = match.get(0) as LogicProblem
160 val interpretation = match.get(1) as PartialInterpretation 153 val interpretation = match.get(1) as PartialInterpretation
161 val typeInterpretation = match.get(2) as PartialComplexTypeInterpretation 154 val typeInterpretation = match.get(2) as PartialComplexTypeInterpretation
162 155
163 val startTime = System.nanoTime
164 createObjectAction( 156 createObjectAction(
165 nameNewElement, 157 nameNewElement,
166 interpretation, 158 interpretation,
167 typeInterpretation, 159 typeInterpretation,
168 [createDefinedElement], 160 [createDefinedElement],
169 recursiceObjectCreations, 161 recursiveObjectCreations,
170 scopePropagator 162 unitRulePropagator
171 ) 163 )
172 statistics.addExecutionTime(System.nanoTime - startTime) 164 statistics.addExecutionTime(System.nanoTime - startTime)
173 165
174 flushQueryEngine(scopePropagator) 166 unitRulePropagator.propagate
175
176 // Scope propagation
177 val propagatorStartTime = System.nanoTime
178 scopePropagator.propagateAllScopeConstraints()
179 statistics.addScopePropagationTime(System.nanoTime - propagatorStartTime)
180 ] 167 ]
181 } 168 }
182 return ruleBuilder.build 169 return ruleBuilder.build
@@ -342,14 +329,14 @@ class RefinementRuleProvider {
342 [createStringElement] 329 [createStringElement]
343 } 330 }
344 331
345 def createRelationRefinementRules(GeneratedPatterns patterns, ScopePropagator scopePropagator, 332 def createRelationRefinementRules(GeneratedPatterns patterns, UnitRulePropagator unitRulePropagator,
346 ModelGenerationStatistics statistics) { 333 ModelGenerationStatistics statistics) {
347 val res = new LinkedHashMap 334 val res = new LinkedHashMap
348 for (LHSEntry : patterns.refinerelationQueries.entrySet) { 335 for (LHSEntry : patterns.refineRelationQueries.entrySet) {
349 val declaration = LHSEntry.key.key 336 val declaration = LHSEntry.key.key
350 val inverseReference = LHSEntry.key.value 337 val inverseReference = LHSEntry.key.value
351 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> 338 val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>>
352 val rule = createRelationRefinementRule(declaration, inverseReference, lhs, scopePropagator, statistics) 339 val rule = createRelationRefinementRule(declaration, inverseReference, lhs, unitRulePropagator, statistics)
353 res.put(LHSEntry.key, rule) 340 res.put(LHSEntry.key, rule)
354 } 341 }
355 return res 342 return res
@@ -357,59 +344,29 @@ class RefinementRuleProvider {
357 344
358 def private BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>> createRelationRefinementRule( 345 def private BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>> createRelationRefinementRule(
359 RelationDeclaration declaration, Relation inverseRelation, 346 RelationDeclaration declaration, Relation inverseRelation,
360 IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, ScopePropagator scopePropagator, 347 IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, UnitRulePropagator unitRulePropagator,
361 ModelGenerationStatistics statistics) { 348 ModelGenerationStatistics statistics) {
362 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»'''
363 val ruleBuilder = factory.createRule(lhs).name(name) 350 val ruleBuilder = factory.createRule(lhs).name(name)
364 if (inverseRelation === null) { 351 if (inverseRelation === null) {
365 ruleBuilder.action [ match | 352 ruleBuilder.action [ match |
366 statistics.incrementTransformationCount 353 statistics.incrementTransformationCount
367
368// println(name) 354// println(name)
369 // val problem = match.get(0) as LogicProblem 355 val startTime = System.nanoTime
370 // val interpretation = match.get(1) as PartialInterpretation 356 createRelationLinkAction(match, unitRulePropagator)
371 val relationInterpretation = match.get(2) as PartialRelationInterpretation 357 statistics.addExecutionTime(System.nanoTime - startTime)
372 val src = match.get(3) as DefinedElement
373 val trg = match.get(4) as DefinedElement
374
375 queryEngine.delayUpdatePropagation [
376 val startTime = System.nanoTime
377 createRelationLinkAction(src, trg, relationInterpretation)
378 statistics.addExecutionTime(System.nanoTime - startTime)
379 ]
380 358
381 // Scope propagation 359 unitRulePropagator.propagate
382 if (scopePropagator.isPropagationNeededAfterAdditionToRelation(declaration)) {
383 queryEngine.delayUpdatePropagation [
384 val propagatorStartTime = System.nanoTime
385 scopePropagator.propagateAllScopeConstraints()
386 statistics.addScopePropagationTime(System.nanoTime - propagatorStartTime)
387 ]
388 }
389 ] 360 ]
390 } else { 361 } else {
391 ruleBuilder.action [ match | 362 ruleBuilder.action [ match |
392 statistics.incrementTransformationCount 363 statistics.incrementTransformationCount
393// println(name) 364// println(name)
394 // val problem = match.get(0) as LogicProblem
395 // val interpretation = match.get(1) as PartialInterpretation
396 val relationInterpretation = match.get(2) as PartialRelationInterpretation
397 val inverseInterpretation = match.get(3) as PartialRelationInterpretation
398 val src = match.get(4) as DefinedElement
399 val trg = match.get(5) as DefinedElement
400
401 val startTime = System.nanoTime 365 val startTime = System.nanoTime
402 createRelationLinkWithInverse(src, trg, relationInterpretation, inverseInterpretation) 366 createRelationLinkWithInverse(match, unitRulePropagator)
403 statistics.addExecutionTime(System.nanoTime - startTime) 367 statistics.addExecutionTime(System.nanoTime - startTime)
404 368
405 // Scope propagation 369 unitRulePropagator.propagate
406 if (scopePropagator.isPropagationNeededAfterAdditionToRelation(declaration)) {
407 flushQueryEngine(scopePropagator)
408
409 val propagatorStartTime = System.nanoTime
410 scopePropagator.propagateAllScopeConstraints()
411 statistics.addScopePropagationTime(System.nanoTime - propagatorStartTime)
412 }
413 ] 370 ]
414 } 371 }
415 372
@@ -420,7 +377,7 @@ class RefinementRuleProvider {
420 // Actions 377 // Actions
421 // /////////////////////// 378 // ///////////////////////
422 protected def void createObjectAction(boolean nameNewElement, ObjectCreationInterpretationData data, 379 protected def void createObjectAction(boolean nameNewElement, ObjectCreationInterpretationData data,
423 DefinedElement container, ScopePropagator scopePropagator) { 380 DefinedElement container, UnitRulePropagator unitRulePropagator) {
424 if (data.containerInterpretation !== null) { 381 if (data.containerInterpretation !== null) {
425 if (data.containerInverseInterpretation !== null) { 382 if (data.containerInverseInterpretation !== null) {
426 createObjectActionWithContainmentAndInverse( 383 createObjectActionWithContainmentAndInverse(
@@ -432,7 +389,7 @@ class RefinementRuleProvider {
432 data.containerInverseInterpretation, 389 data.containerInverseInterpretation,
433 data.constructor, 390 data.constructor,
434 data.recursiveConstructors, 391 data.recursiveConstructors,
435 scopePropagator 392 unitRulePropagator
436 ) 393 )
437 } else { 394 } else {
438 createObjectActionWithContainment( 395 createObjectActionWithContainment(
@@ -443,7 +400,7 @@ class RefinementRuleProvider {
443 data.containerInterpretation, 400 data.containerInterpretation,
444 data.constructor, 401 data.constructor,
445 data.recursiveConstructors, 402 data.recursiveConstructors,
446 scopePropagator 403 unitRulePropagator
447 ) 404 )
448 } 405 }
449 } else { 406 } else {
@@ -453,7 +410,7 @@ class RefinementRuleProvider {
453 data.typeInterpretation, 410 data.typeInterpretation,
454 data.constructor, 411 data.constructor,
455 data.recursiveConstructors, 412 data.recursiveConstructors,
456 scopePropagator 413 unitRulePropagator
457 ) 414 )
458 } 415 }
459 416
@@ -468,7 +425,7 @@ class RefinementRuleProvider {
468 PartialRelationInterpretation inverseRelationInterpretation, 425 PartialRelationInterpretation inverseRelationInterpretation,
469 Function0<DefinedElement> constructor, 426 Function0<DefinedElement> constructor,
470 List<ObjectCreationInterpretationData> recursiceObjectCreations, 427 List<ObjectCreationInterpretationData> recursiceObjectCreations,
471 ScopePropagator scopePropagator 428 UnitRulePropagator unitRulePropagator
472 ) { 429 ) {
473 val newElement = constructor.apply 430 val newElement = constructor.apply
474 if (nameNewElement) { 431 if (nameNewElement) {
@@ -488,14 +445,16 @@ class RefinementRuleProvider {
488 inverseRelationInterpretation.relationlinks += newLink2 445 inverseRelationInterpretation.relationlinks += newLink2
489 446
490 // Scope propagation 447 // Scope propagation
491 scopePropagator.decrementTypeScope(typeInterpretation) 448 unitRulePropagator.decrementTypeScope(typeInterpretation)
449 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
450 unitRulePropagator.addedToRelation(inverseRelationInterpretation.interpretationOf)
492 451
493 // Existence 452 // Existence
494 interpretation.newElements += newElement 453 interpretation.newElements += newElement
495 454
496 // Do recursive object creation 455 // Do recursive object creation
497 for (newConstructor : recursiceObjectCreations) { 456 for (newConstructor : recursiceObjectCreations) {
498 createObjectAction(nameNewElement, newConstructor, newElement, scopePropagator) 457 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
499 } 458 }
500 459
501 return newElement 460 return newElement
@@ -509,7 +468,7 @@ class RefinementRuleProvider {
509 PartialRelationInterpretation relationInterpretation, 468 PartialRelationInterpretation relationInterpretation,
510 Function0<DefinedElement> constructor, 469 Function0<DefinedElement> constructor,
511 List<ObjectCreationInterpretationData> recursiceObjectCreations, 470 List<ObjectCreationInterpretationData> recursiceObjectCreations,
512 ScopePropagator scopePropagator 471 UnitRulePropagator unitRulePropagator
513 ) { 472 ) {
514 val newElement = constructor.apply 473 val newElement = constructor.apply
515 if (nameNewElement) { 474 if (nameNewElement) {
@@ -524,16 +483,17 @@ class RefinementRuleProvider {
524 // ContainmentRelation 483 // ContainmentRelation
525 val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] 484 val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement]
526 relationInterpretation.relationlinks += newLink 485 relationInterpretation.relationlinks += newLink
486 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
527 487
528 // Scope propagation 488 // Scope propagation
529 scopePropagator.decrementTypeScope(typeInterpretation) 489 unitRulePropagator.decrementTypeScope(typeInterpretation)
530 490
531 // Existence 491 // Existence
532 interpretation.newElements += newElement 492 interpretation.newElements += newElement
533 493
534 // Do recursive object creation 494 // Do recursive object creation
535 for (newConstructor : recursiceObjectCreations) { 495 for (newConstructor : recursiceObjectCreations) {
536 createObjectAction(nameNewElement, newConstructor, newElement, scopePropagator) 496 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
537 } 497 }
538 498
539 return newElement 499 return newElement
@@ -541,7 +501,7 @@ class RefinementRuleProvider {
541 501
542 protected def createObjectAction(boolean nameNewElement, PartialInterpretation interpretation, 502 protected def createObjectAction(boolean nameNewElement, PartialInterpretation interpretation,
543 PartialTypeInterpratation typeInterpretation, Function0<DefinedElement> constructor, 503 PartialTypeInterpratation typeInterpretation, Function0<DefinedElement> constructor,
544 List<ObjectCreationInterpretationData> recursiceObjectCreations, ScopePropagator scopePropagator) { 504 List<ObjectCreationInterpretationData> recursiceObjectCreations, UnitRulePropagator unitRulePropagator) {
545 val newElement = constructor.apply 505 val newElement = constructor.apply
546 if (nameNewElement) { 506 if (nameNewElement) {
547 newElement.name = '''new «interpretation.newElements.size»''' 507 newElement.name = '''new «interpretation.newElements.size»'''
@@ -554,38 +514,220 @@ class RefinementRuleProvider {
554 } 514 }
555 515
556 // Scope propagation 516 // Scope propagation
557 scopePropagator.decrementTypeScope(typeInterpretation) 517 unitRulePropagator.decrementTypeScope(typeInterpretation)
558 518
559 // Existence 519 // Existence
560 interpretation.newElements += newElement 520 interpretation.newElements += newElement
561 521
562 // Do recursive object creation 522 // Do recursive object creation
563 for (newConstructor : recursiceObjectCreations) { 523 for (newConstructor : recursiceObjectCreations) {
564 createObjectAction(nameNewElement, newConstructor, newElement, scopePropagator) 524 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
565 } 525 }
566 526
567 return newElement 527 return newElement
568 } 528 }
569 529
570 protected def boolean createRelationLinkAction(DefinedElement src, DefinedElement trg, 530 protected def createRelationLinkAction(IPatternMatch match, UnitRulePropagator unitRulePropagator) {
571 PartialRelationInterpretation relationInterpretation) { 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) {
572 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] 541 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg]
573 relationInterpretation.relationlinks += link 542 relationInterpretation.relationlinks += link
543 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
574 } 544 }
575 545
576 protected def boolean createRelationLinkWithInverse(DefinedElement src, DefinedElement trg, 546 protected def void createRelationLinkWithInverse(IPatternMatch match, UnitRulePropagator unitRulePropagator) {
577 PartialRelationInterpretation relationInterpretation, PartialRelationInterpretation inverseInterpretation) { 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) {
578 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] 559 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg]
579 relationInterpretation.relationlinks += link 560 relationInterpretation.relationlinks += link
580 val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src] 561 val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src]
581 inverseInterpretation.relationlinks += inverseLink 562 inverseInterpretation.relationlinks += inverseLink
563 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
564 unitRulePropagator.addedToRelation(inverseInterpretation.interpretationOf)
582 } 565 }
583 566
584 protected def flushQueryEngine(ScopePropagator scopePropagator) { 567 static class UnitRulePropagator {
585 if (scopePropagator.queryEngineFlushRequiredBeforePropagation && queryEngine.updatePropagationDelayed) { 568 val LogicProblem p
586 delayMessageDelivery.setBoolean(queryEngine, false) 569 val PartialInterpretation i
587 queryEngine.getQueryBackend(ReteBackendFactory.INSTANCE).flushUpdates 570 val RefinementRuleProvider refinementRuleProvider
588 delayMessageDelivery.setBoolean(queryEngine, true) 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 }
589 } 731 }
590 } 732 }
591} 733}