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