aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <marussy@mit.bme.hu>2020-08-28 18:58:37 +0200
committerLibravatar Kristóf Marussy <marussy@mit.bme.hu>2020-08-28 18:58:37 +0200
commit4fe7fce97aedbd516109ef81afc33e00112b7b68 (patch)
tree7eaa7c4e9b31b2a1488e49de48721b4dbad31fae /Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules
parentMoDeS3 unit propagation WIP (diff)
downloadVIATRA-Generator-4fe7fce97aedbd516109ef81afc33e00112b7b68.tar.gz
VIATRA-Generator-4fe7fce97aedbd516109ef81afc33e00112b7b68.tar.zst
VIATRA-Generator-4fe7fce97aedbd516109ef81afc33e00112b7b68.zip
Must unit propagation
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend338
1 files changed, 241 insertions, 97 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 699b095d..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,57 +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
370 // val interpretation = match.get(1) as PartialInterpretation
371 val relationInterpretation = match.get(2) as PartialRelationInterpretation
372 val src = match.get(3) as DefinedElement
373 val trg = match.get(4) as DefinedElement
374
375 val startTime = System.nanoTime 355 val startTime = System.nanoTime
376 createRelationLinkAction(src, trg, relationInterpretation) 356 createRelationLinkAction(match, unitRulePropagator)
377 statistics.addExecutionTime(System.nanoTime - startTime) 357 statistics.addExecutionTime(System.nanoTime - startTime)
378 358
379 // Scope propagation 359 unitRulePropagator.propagate
380 if (scopePropagator.isPropagationNeededAfterAdditionToRelation(declaration)) {
381 flushQueryEngine(scopePropagator)
382
383 val propagatorStartTime = System.nanoTime
384 scopePropagator.propagateAllScopeConstraints()
385 statistics.addScopePropagationTime(System.nanoTime - propagatorStartTime)
386 }
387 ] 360 ]
388 } else { 361 } else {
389 ruleBuilder.action [ match | 362 ruleBuilder.action [ match |
390 statistics.incrementTransformationCount 363 statistics.incrementTransformationCount
391// println(name) 364// println(name)
392 // val problem = match.get(0) as LogicProblem
393 // val interpretation = match.get(1) as PartialInterpretation
394 val relationInterpretation = match.get(2) as PartialRelationInterpretation
395 val inverseInterpretation = match.get(3) as PartialRelationInterpretation
396 val src = match.get(4) as DefinedElement
397 val trg = match.get(5) as DefinedElement
398
399 val startTime = System.nanoTime 365 val startTime = System.nanoTime
400 createRelationLinkWithInverse(src, trg, relationInterpretation, inverseInterpretation) 366 createRelationLinkWithInverse(match, unitRulePropagator)
401 statistics.addExecutionTime(System.nanoTime - startTime) 367 statistics.addExecutionTime(System.nanoTime - startTime)
402 368
403 // Scope propagation 369 unitRulePropagator.propagate
404 if (scopePropagator.isPropagationNeededAfterAdditionToRelation(declaration)) {
405 flushQueryEngine(scopePropagator)
406
407 val propagatorStartTime = System.nanoTime
408 scopePropagator.propagateAllScopeConstraints()
409 statistics.addScopePropagationTime(System.nanoTime - propagatorStartTime)
410 }
411 ] 370 ]
412 } 371 }
413 372
@@ -418,7 +377,7 @@ class RefinementRuleProvider {
418 // Actions 377 // Actions
419 // /////////////////////// 378 // ///////////////////////
420 protected def void createObjectAction(boolean nameNewElement, ObjectCreationInterpretationData data, 379 protected def void createObjectAction(boolean nameNewElement, ObjectCreationInterpretationData data,
421 DefinedElement container, ScopePropagator scopePropagator) { 380 DefinedElement container, UnitRulePropagator unitRulePropagator) {
422 if (data.containerInterpretation !== null) { 381 if (data.containerInterpretation !== null) {
423 if (data.containerInverseInterpretation !== null) { 382 if (data.containerInverseInterpretation !== null) {
424 createObjectActionWithContainmentAndInverse( 383 createObjectActionWithContainmentAndInverse(
@@ -430,7 +389,7 @@ class RefinementRuleProvider {
430 data.containerInverseInterpretation, 389 data.containerInverseInterpretation,
431 data.constructor, 390 data.constructor,
432 data.recursiveConstructors, 391 data.recursiveConstructors,
433 scopePropagator 392 unitRulePropagator
434 ) 393 )
435 } else { 394 } else {
436 createObjectActionWithContainment( 395 createObjectActionWithContainment(
@@ -441,7 +400,7 @@ class RefinementRuleProvider {
441 data.containerInterpretation, 400 data.containerInterpretation,
442 data.constructor, 401 data.constructor,
443 data.recursiveConstructors, 402 data.recursiveConstructors,
444 scopePropagator 403 unitRulePropagator
445 ) 404 )
446 } 405 }
447 } else { 406 } else {
@@ -451,7 +410,7 @@ class RefinementRuleProvider {
451 data.typeInterpretation, 410 data.typeInterpretation,
452 data.constructor, 411 data.constructor,
453 data.recursiveConstructors, 412 data.recursiveConstructors,
454 scopePropagator 413 unitRulePropagator
455 ) 414 )
456 } 415 }
457 416
@@ -466,7 +425,7 @@ class RefinementRuleProvider {
466 PartialRelationInterpretation inverseRelationInterpretation, 425 PartialRelationInterpretation inverseRelationInterpretation,
467 Function0<DefinedElement> constructor, 426 Function0<DefinedElement> constructor,
468 List<ObjectCreationInterpretationData> recursiceObjectCreations, 427 List<ObjectCreationInterpretationData> recursiceObjectCreations,
469 ScopePropagator scopePropagator 428 UnitRulePropagator unitRulePropagator
470 ) { 429 ) {
471 val newElement = constructor.apply 430 val newElement = constructor.apply
472 if (nameNewElement) { 431 if (nameNewElement) {
@@ -486,14 +445,16 @@ class RefinementRuleProvider {
486 inverseRelationInterpretation.relationlinks += newLink2 445 inverseRelationInterpretation.relationlinks += newLink2
487 446
488 // Scope propagation 447 // Scope propagation
489 scopePropagator.decrementTypeScope(typeInterpretation) 448 unitRulePropagator.decrementTypeScope(typeInterpretation)
449 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
450 unitRulePropagator.addedToRelation(inverseRelationInterpretation.interpretationOf)
490 451
491 // Existence 452 // Existence
492 interpretation.newElements += newElement 453 interpretation.newElements += newElement
493 454
494 // Do recursive object creation 455 // Do recursive object creation
495 for (newConstructor : recursiceObjectCreations) { 456 for (newConstructor : recursiceObjectCreations) {
496 createObjectAction(nameNewElement, newConstructor, newElement, scopePropagator) 457 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
497 } 458 }
498 459
499 return newElement 460 return newElement
@@ -507,7 +468,7 @@ class RefinementRuleProvider {
507 PartialRelationInterpretation relationInterpretation, 468 PartialRelationInterpretation relationInterpretation,
508 Function0<DefinedElement> constructor, 469 Function0<DefinedElement> constructor,
509 List<ObjectCreationInterpretationData> recursiceObjectCreations, 470 List<ObjectCreationInterpretationData> recursiceObjectCreations,
510 ScopePropagator scopePropagator 471 UnitRulePropagator unitRulePropagator
511 ) { 472 ) {
512 val newElement = constructor.apply 473 val newElement = constructor.apply
513 if (nameNewElement) { 474 if (nameNewElement) {
@@ -522,16 +483,17 @@ class RefinementRuleProvider {
522 // ContainmentRelation 483 // ContainmentRelation
523 val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] 484 val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement]
524 relationInterpretation.relationlinks += newLink 485 relationInterpretation.relationlinks += newLink
486 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
525 487
526 // Scope propagation 488 // Scope propagation
527 scopePropagator.decrementTypeScope(typeInterpretation) 489 unitRulePropagator.decrementTypeScope(typeInterpretation)
528 490
529 // Existence 491 // Existence
530 interpretation.newElements += newElement 492 interpretation.newElements += newElement
531 493
532 // Do recursive object creation 494 // Do recursive object creation
533 for (newConstructor : recursiceObjectCreations) { 495 for (newConstructor : recursiceObjectCreations) {
534 createObjectAction(nameNewElement, newConstructor, newElement, scopePropagator) 496 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
535 } 497 }
536 498
537 return newElement 499 return newElement
@@ -539,7 +501,7 @@ class RefinementRuleProvider {
539 501
540 protected def createObjectAction(boolean nameNewElement, PartialInterpretation interpretation, 502 protected def createObjectAction(boolean nameNewElement, PartialInterpretation interpretation,
541 PartialTypeInterpratation typeInterpretation, Function0<DefinedElement> constructor, 503 PartialTypeInterpratation typeInterpretation, Function0<DefinedElement> constructor,
542 List<ObjectCreationInterpretationData> recursiceObjectCreations, ScopePropagator scopePropagator) { 504 List<ObjectCreationInterpretationData> recursiceObjectCreations, UnitRulePropagator unitRulePropagator) {
543 val newElement = constructor.apply 505 val newElement = constructor.apply
544 if (nameNewElement) { 506 if (nameNewElement) {
545 newElement.name = '''new «interpretation.newElements.size»''' 507 newElement.name = '''new «interpretation.newElements.size»'''
@@ -552,38 +514,220 @@ class RefinementRuleProvider {
552 } 514 }
553 515
554 // Scope propagation 516 // Scope propagation
555 scopePropagator.decrementTypeScope(typeInterpretation) 517 unitRulePropagator.decrementTypeScope(typeInterpretation)
556 518
557 // Existence 519 // Existence
558 interpretation.newElements += newElement 520 interpretation.newElements += newElement
559 521
560 // Do recursive object creation 522 // Do recursive object creation
561 for (newConstructor : recursiceObjectCreations) { 523 for (newConstructor : recursiceObjectCreations) {
562 createObjectAction(nameNewElement, newConstructor, newElement, scopePropagator) 524 createObjectAction(nameNewElement, newConstructor, newElement, unitRulePropagator)
563 } 525 }
564 526
565 return newElement 527 return newElement
566 } 528 }
567 529
568 protected def boolean createRelationLinkAction(DefinedElement src, DefinedElement trg, 530 protected def createRelationLinkAction(IPatternMatch match, UnitRulePropagator unitRulePropagator) {
569 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) {
570 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] 541 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg]
571 relationInterpretation.relationlinks += link 542 relationInterpretation.relationlinks += link
543 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
572 } 544 }
573 545
574 protected def boolean createRelationLinkWithInverse(DefinedElement src, DefinedElement trg, 546 protected def void createRelationLinkWithInverse(IPatternMatch match, UnitRulePropagator unitRulePropagator) {
575 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) {
576 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] 559 val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg]
577 relationInterpretation.relationlinks += link 560 relationInterpretation.relationlinks += link
578 val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src] 561 val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src]
579 inverseInterpretation.relationlinks += inverseLink 562 inverseInterpretation.relationlinks += inverseLink
563 unitRulePropagator.addedToRelation(relationInterpretation.interpretationOf)
564 unitRulePropagator.addedToRelation(inverseInterpretation.interpretationOf)
580 } 565 }
581 566
582 protected def flushQueryEngine(ScopePropagator scopePropagator) { 567 static class UnitRulePropagator {
583 if (scopePropagator.queryEngineFlushRequiredBeforePropagation && queryEngine.updatePropagationDelayed) { 568 val LogicProblem p
584 delayMessageDelivery.setBoolean(queryEngine, false) 569 val PartialInterpretation i
585 queryEngine.getQueryBackend(ReteBackendFactory.INSTANCE).flushUpdates 570 val RefinementRuleProvider refinementRuleProvider
586 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 }
587 } 731 }
588 } 732 }
589} 733}