diff options
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.xtend | 344 |
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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules |
2 | 2 | ||
3 | import com.google.common.collect.ImmutableList | ||
3 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.InverseRelationAssertion | 4 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.InverseRelationAssertion |
4 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion | 5 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion |
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference | 6 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference |
@@ -29,12 +30,14 @@ import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.par | |||
29 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory | 30 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory |
30 | import java.lang.reflect.Field | 31 | import java.lang.reflect.Field |
31 | import java.util.HashMap | 32 | import java.util.HashMap |
33 | import java.util.Iterator | ||
32 | import java.util.LinkedHashMap | 34 | import java.util.LinkedHashMap |
33 | import java.util.LinkedList | 35 | import java.util.LinkedList |
34 | import java.util.List | 36 | import java.util.List |
35 | import java.util.Map | 37 | import java.util.Map |
36 | import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine | 38 | import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine |
37 | import org.eclipse.viatra.query.runtime.api.GenericPatternMatch | 39 | import org.eclipse.viatra.query.runtime.api.GenericPatternMatch |
40 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
38 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | 41 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification |
39 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine | 42 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine |
40 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | 43 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher |
@@ -43,6 +46,7 @@ import org.eclipse.viatra.query.runtime.rete.matcher.ReteBackendFactory | |||
43 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule | 46 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule |
44 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory | 47 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory |
45 | import org.eclipse.xtend.lib.annotations.Data | 48 | import org.eclipse.xtend.lib.annotations.Data |
49 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
46 | import org.eclipse.xtext.xbase.lib.Functions.Function0 | 50 | import org.eclipse.xtext.xbase.lib.Functions.Function0 |
47 | 51 | ||
48 | class RefinementRuleProvider { | 52 | class 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 | } |