diff options
author | Oszkar Semerath <semerath@mit.bme.hu> | 2020-05-01 01:45:22 +0200 |
---|---|---|
committer | Oszkar Semerath <semerath@mit.bme.hu> | 2020-05-01 01:45:22 +0200 |
commit | 7c7e26beb80073d049eb5e4b896fa290c016b0c9 (patch) | |
tree | 266dc048006251b230d668c87df5d98c9aede4f8 /Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver | |
parent | UnitPropagationProvider added to the generated patterns (diff) | |
download | VIATRA-Generator-7c7e26beb80073d049eb5e4b896fa290c016b0c9.tar.gz VIATRA-Generator-7c7e26beb80073d049eb5e4b896fa290c016b0c9.tar.zst VIATRA-Generator-7c7e26beb80073d049eb5e4b896fa290c016b0c9.zip |
missing commit
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver')
-rw-r--r-- | Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules/RefinementRuleProvider.xtend | 459 |
1 files changed, 376 insertions, 83 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 20d24b77..013da873 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,71 +1,94 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules |
2 | 2 | ||
3 | 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.logic.model.logiclanguage.BoolTypeReference | ||
6 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference | ||
3 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement | 7 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement |
8 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference | ||
4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguageFactory | 9 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguageFactory |
10 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.PrimitiveTypeReference | ||
11 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation | 12 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation |
6 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration | 13 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration |
14 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringTypeReference | ||
7 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type | 15 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type |
16 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem | ||
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics | 17 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics |
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator | 18 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator |
10 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns | 19 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns |
11 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ObjectCreationPrecondition | 20 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ObjectCreationPrecondition |
21 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialBooleanInterpretation | ||
12 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation | 22 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation |
23 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialIntegerInterpretation | ||
13 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | 24 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation |
25 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRealInterpretation | ||
14 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation | 26 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation |
27 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialStringInterpretation | ||
28 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation | ||
15 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory | 29 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory |
30 | import java.util.HashMap | ||
16 | import java.util.LinkedHashMap | 31 | import java.util.LinkedHashMap |
32 | import java.util.LinkedList | ||
33 | import java.util.List | ||
34 | import java.util.Map | ||
17 | import org.eclipse.viatra.query.runtime.api.GenericPatternMatch | 35 | import org.eclipse.viatra.query.runtime.api.GenericPatternMatch |
18 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | 36 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification |
19 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | 37 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher |
20 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule | 38 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule |
21 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory | 39 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory |
40 | import org.eclipse.xtend.lib.annotations.Data | ||
41 | import org.eclipse.xtext.xbase.lib.Functions.Function0 | ||
22 | 42 | ||
23 | class RefinementRuleProvider { | 43 | class RefinementRuleProvider { |
24 | private extension BatchTransformationRuleFactory factory = new BatchTransformationRuleFactory | 44 | val extension BatchTransformationRuleFactory factory = new BatchTransformationRuleFactory |
25 | private extension PartialinterpretationFactory factory2 = PartialinterpretationFactory.eINSTANCE | 45 | val extension PartialinterpretationFactory factory2 = PartialinterpretationFactory.eINSTANCE |
26 | private extension LogiclanguageFactory factory3 = LogiclanguageFactory.eINSTANCE | 46 | val extension LogiclanguageFactory factory3 = LogiclanguageFactory.eINSTANCE |
27 | 47 | ||
28 | def canonizeName(String name) { | 48 | def canonizeName(String name) { |
29 | return name.replace(' ','_') | 49 | return name.replace(' ','_') |
30 | } | 50 | } |
31 | 51 | ||
32 | def LinkedHashMap<ObjectCreationPrecondition, BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>>> | 52 | def LinkedHashMap<ObjectCreationPrecondition, BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>>> createObjectRefinementRules( |
33 | createObjectRefinementRules( | 53 | LogicProblem p, |
54 | PartialInterpretation i, | ||
34 | GeneratedPatterns patterns, | 55 | GeneratedPatterns patterns, |
35 | ScopePropagator scopePropagator, | 56 | ScopePropagator scopePropagator, |
36 | boolean nameNewElement, | 57 | boolean nameNewElement, |
37 | ModelGenerationStatistics statistics | 58 | ModelGenerationStatistics statistics |
38 | ) | 59 | ) |
39 | { | 60 | { |
40 | val res = new LinkedHashMap | 61 | val res = new LinkedHashMap |
62 | val recursiveObjectCreation = recursiveObjectCreation(p,i) | ||
41 | for(LHSEntry: patterns.refineObjectQueries.entrySet) { | 63 | for(LHSEntry: patterns.refineObjectQueries.entrySet) { |
42 | val containmentRelation = LHSEntry.key.containmentRelation | 64 | val containmentRelation = LHSEntry.key.containmentRelation |
43 | val inverseRelation = LHSEntry.key.inverseContainment | 65 | val inverseRelation = LHSEntry.key.inverseContainment |
44 | val type = LHSEntry.key.newType | 66 | val type = LHSEntry.key.newType |
45 | val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> | 67 | val lhs = LHSEntry.value as IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> |
46 | val rule = createObjectCreationRule(containmentRelation,inverseRelation,type,lhs,nameNewElement,scopePropagator,statistics) | 68 | val rule = createObjectCreationRule(p,containmentRelation,inverseRelation,type,recursiveObjectCreation.get(type),lhs,nameNewElement,scopePropagator,statistics) |
47 | res.put(LHSEntry.key,rule) | 69 | res.put(LHSEntry.key,rule) |
48 | } | 70 | } |
49 | return res | 71 | return res |
50 | } | 72 | } |
51 | 73 | ||
52 | def private createObjectCreationRule( | 74 | def private createObjectCreationRule( |
75 | LogicProblem p, | ||
53 | Relation containmentRelation, | 76 | Relation containmentRelation, |
54 | Relation inverseRelation, | 77 | Relation inverseRelation, |
55 | Type type, | 78 | Type type, |
79 | List<ObjectCreationInterpretationData> recursiceObjectCreations, | ||
56 | IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, | 80 | IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, |
57 | boolean nameNewElement, | 81 | boolean nameNewElement, |
58 | ScopePropagator scopePropagator, | 82 | ScopePropagator scopePropagator, |
59 | ModelGenerationStatistics statistics) | 83 | ModelGenerationStatistics statistics) |
60 | { | 84 | { |
61 | val name = '''addObject_«type.name.canonizeName»« | 85 | val name = '''addObject_«type.name.canonizeName»« |
62 | IF containmentRelation!=null»_by_«containmentRelation.name.canonizeName»«ENDIF»''' | 86 | IF containmentRelation!==null»_by_«containmentRelation.name.canonizeName»«ENDIF»''' |
63 | //println("Rule created: " + name + "> " + lhs.fullyQualifiedName) | ||
64 | val ruleBuilder = factory.createRule | 87 | val ruleBuilder = factory.createRule |
65 | .name(name) | 88 | .name(name) |
66 | .precondition(lhs) | 89 | .precondition(lhs) |
67 | if(containmentRelation != null) { | 90 | if(containmentRelation !== null) { |
68 | if(inverseRelation!= null) { | 91 | if(inverseRelation!== null) { |
69 | ruleBuilder.action[match | | 92 | ruleBuilder.action[match | |
70 | //println(name) | 93 | //println(name) |
71 | val startTime = System.nanoTime | 94 | val startTime = System.nanoTime |
@@ -76,30 +99,17 @@ class RefinementRuleProvider { | |||
76 | val typeInterpretation = match.get(4) as PartialComplexTypeInterpretation | 99 | val typeInterpretation = match.get(4) as PartialComplexTypeInterpretation |
77 | val container = match.get(5) as DefinedElement | 100 | val container = match.get(5) as DefinedElement |
78 | 101 | ||
79 | val newElement = createDefinedElement | 102 | createObjectActionWithContainmentAndInverse( |
80 | if(nameNewElement) { | 103 | nameNewElement, |
81 | newElement.name = '''new «interpretation.newElements.size»''' | 104 | interpretation, |
82 | } | 105 | typeInterpretation, |
83 | 106 | container, | |
84 | // Existence | 107 | relationInterpretation, |
85 | interpretation.newElements+=newElement | 108 | inverseRelationInterpretation, |
86 | /*interpretation.maxNewElements=interpretation.maxNewElements-1 | 109 | [createDefinedElement], |
87 | if(interpretation.minNewElements > 0) { | 110 | recursiceObjectCreations, |
88 | interpretation.minNewElements=interpretation.minNewElements-1 | 111 | scopePropagator |
89 | }*/ | 112 | ) |
90 | |||
91 | // Types | ||
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 | 113 | ||
104 | statistics.addExecutionTime(System.nanoTime-startTime) | 114 | statistics.addExecutionTime(System.nanoTime-startTime) |
105 | ] | 115 | ] |
@@ -113,27 +123,16 @@ class RefinementRuleProvider { | |||
113 | val typeInterpretation = match.get(3) as PartialComplexTypeInterpretation | 123 | val typeInterpretation = match.get(3) as PartialComplexTypeInterpretation |
114 | val container = match.get(4) as DefinedElement | 124 | val container = match.get(4) as DefinedElement |
115 | 125 | ||
116 | val newElement = createDefinedElement | 126 | createObjectActionWithContainment( |
117 | if(nameNewElement) { | 127 | nameNewElement, |
118 | newElement.name = '''new «interpretation.newElements.size»''' | 128 | interpretation, |
119 | } | 129 | typeInterpretation, |
120 | 130 | container, | |
121 | // Existence | 131 | relationInterpretation, |
122 | interpretation.newElements+=newElement | 132 | [createDefinedElement], |
123 | /*interpretation.maxNewElements=interpretation.maxNewElements-1 | 133 | recursiceObjectCreations, |
124 | if(interpretation.minNewElements > 0) { | 134 | scopePropagator |
125 | interpretation.minNewElements=interpretation.minNewElements-1 | 135 | ) |
126 | }*/ | ||
127 | |||
128 | // Types | ||
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 | 136 | ||
138 | statistics.addExecutionTime(System.nanoTime-startTime) | 137 | statistics.addExecutionTime(System.nanoTime-startTime) |
139 | ] | 138 | ] |
@@ -145,25 +144,14 @@ class RefinementRuleProvider { | |||
145 | val interpretation = match.get(1) as PartialInterpretation | 144 | val interpretation = match.get(1) as PartialInterpretation |
146 | val typeInterpretation = match.get(2) as PartialComplexTypeInterpretation | 145 | val typeInterpretation = match.get(2) as PartialComplexTypeInterpretation |
147 | 146 | ||
148 | val newElement = createDefinedElement | 147 | createObjectAction( |
149 | if(nameNewElement) { | 148 | nameNewElement, |
150 | newElement.name = '''new «interpretation.newElements.size»''' | 149 | interpretation, |
151 | } | 150 | typeInterpretation, |
152 | 151 | [createDefinedElement], | |
153 | // Existence | 152 | recursiceObjectCreations, |
154 | interpretation.newElements+=newElement | 153 | scopePropagator |
155 | /* | 154 | ) |
156 | interpretation.maxNewElements=interpretation.maxNewElements-1 | ||
157 | if(interpretation.minNewElements > 0) { | ||
158 | interpretation.minNewElements=interpretation.minNewElements-1 | ||
159 | }*/ | ||
160 | |||
161 | // Types | ||
162 | typeInterpretation.elements += newElement | ||
163 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] | ||
164 | |||
165 | // Scope propagation | ||
166 | scopePropagator.propagateAdditionToType(typeInterpretation) | ||
167 | 155 | ||
168 | statistics.addExecutionTime(System.nanoTime-startTime) | 156 | statistics.addExecutionTime(System.nanoTime-startTime) |
169 | ] | 157 | ] |
@@ -171,6 +159,137 @@ class RefinementRuleProvider { | |||
171 | return ruleBuilder.build | 159 | return ruleBuilder.build |
172 | } | 160 | } |
173 | 161 | ||
162 | def private recursiveObjectCreation(LogicProblem p, PartialInterpretation i) | ||
163 | { | ||
164 | val Map<Type,List<ObjectCreationInterpretationData>> recursiveObjectCreation = new HashMap | ||
165 | for(type : p.types) { | ||
166 | recursiveObjectCreation.put(type,new LinkedList) | ||
167 | } | ||
168 | |||
169 | val containmentReferences = p.containmentHierarchies.head.containmentRelations | ||
170 | |||
171 | for(relationInterpretation : i.partialrelationinterpretation) { | ||
172 | val relation = relationInterpretation.interpretationOf | ||
173 | val lowermultiplicities = p.annotations.filter(LowerMultiplicityAssertion).filter[it.relation === relation] | ||
174 | if((!lowermultiplicities.empty)) { | ||
175 | val number = lowermultiplicities.head.lower | ||
176 | if(number > 0) { | ||
177 | val sourceTypeInterpretation = getTypeInterpretation(i, relation, 0) as PartialComplexTypeInterpretation | ||
178 | |||
179 | if(containmentReferences.contains(relation)) { | ||
180 | val targetTypeInterpretation = getTypeInterpretation(i, relation, 1) | ||
181 | |||
182 | val inverseAnnotation = p.assertions.filter(InverseRelationAssertion).filter[it.inverseA === relation || it.inverseB === relation] | ||
183 | if(!inverseAnnotation.empty) { | ||
184 | val onlyInverseAnnotation = if(inverseAnnotation.head.inverseA===relation) { | ||
185 | inverseAnnotation.head.inverseB | ||
186 | } else { | ||
187 | inverseAnnotation.head.inverseA | ||
188 | } | ||
189 | val inverseRelationInterpretation = i.partialrelationinterpretation.filter[it.interpretationOf === onlyInverseAnnotation].head | ||
190 | for(var times=0; times<number; times++) { | ||
191 | recursiveObjectCreation.get(sourceTypeInterpretation.interpretationOf) += | ||
192 | new ObjectCreationInterpretationData( | ||
193 | i, | ||
194 | targetTypeInterpretation, | ||
195 | relationInterpretation, | ||
196 | inverseRelationInterpretation, | ||
197 | targetTypeInterpretation.getTypeConstructor | ||
198 | ) | ||
199 | } | ||
200 | |||
201 | } else { | ||
202 | for(var times=0; times<number; times++) { | ||
203 | recursiveObjectCreation.get(sourceTypeInterpretation.interpretationOf) += | ||
204 | new ObjectCreationInterpretationData( | ||
205 | i, | ||
206 | targetTypeInterpretation, | ||
207 | relationInterpretation, | ||
208 | null, | ||
209 | targetTypeInterpretation.getTypeConstructor | ||
210 | ) | ||
211 | } | ||
212 | } | ||
213 | } else if(relation.parameters instanceof PrimitiveTypeReference) { | ||
214 | val targetTypeInterpretation = getTypeInterpretation(i, relation, 1) | ||
215 | for(var times=0; times<number; times++) { | ||
216 | recursiveObjectCreation.get(sourceTypeInterpretation.interpretationOf) += | ||
217 | new ObjectCreationInterpretationData( | ||
218 | i, | ||
219 | targetTypeInterpretation, | ||
220 | relationInterpretation, | ||
221 | null, | ||
222 | targetTypeInterpretation.getTypeConstructor | ||
223 | ) | ||
224 | } | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | } | ||
229 | |||
230 | // Doing the recursion | ||
231 | var objectCreations = new LinkedList(recursiveObjectCreation.values.flatten.toList) | ||
232 | for(objectCreation : objectCreations) { | ||
233 | val newlyCreatedType = (objectCreation.typeInterpretation as PartialComplexTypeInterpretation).interpretationOf | ||
234 | if(recursiveObjectCreation.containsKey(newlyCreatedType)) { | ||
235 | val actionsWhenTypeCreated = recursiveObjectCreation.get(newlyCreatedType) | ||
236 | objectCreation.recursiveConstructors+=actionsWhenTypeCreated | ||
237 | } | ||
238 | } | ||
239 | |||
240 | // checking acyclicity | ||
241 | for(objectCreation : objectCreations) { | ||
242 | var reachable = objectCreation.recursiveConstructors | ||
243 | do { | ||
244 | if(reachable.contains(objectCreation)) { | ||
245 | throw new IllegalArgumentException('''Cicrle in the containment!''') | ||
246 | } else { | ||
247 | reachable = reachable.map[it.recursiveConstructors].flatten.toList | ||
248 | } | ||
249 | } while(reachable.empty) | ||
250 | } | ||
251 | |||
252 | return recursiveObjectCreation | ||
253 | } | ||
254 | |||
255 | private def getTypeInterpretation(PartialInterpretation i, RelationDeclaration relation, int index) { | ||
256 | val typeReference = relation.parameters.get(index) | ||
257 | return getTypeInterpretation(i,typeReference) | ||
258 | |||
259 | } | ||
260 | private dispatch def getTypeInterpretation(PartialInterpretation i, ComplexTypeReference reference) { | ||
261 | return i.partialtypeinterpratation | ||
262 | .filter(PartialComplexTypeInterpretation) | ||
263 | .filter[it.getInterpretationOf == reference.referred] | ||
264 | .head | ||
265 | } | ||
266 | private dispatch def getTypeInterpretation(PartialInterpretation i, BoolTypeReference reference) { | ||
267 | return i.partialtypeinterpratation | ||
268 | .filter(PartialBooleanInterpretation) | ||
269 | .head | ||
270 | } | ||
271 | private dispatch def getTypeInterpretation(PartialInterpretation i, IntTypeReference reference) { | ||
272 | return i.partialtypeinterpratation | ||
273 | .filter(PartialIntegerInterpretation) | ||
274 | .head | ||
275 | } | ||
276 | private dispatch def getTypeInterpretation(PartialInterpretation i, RealTypeReference reference) { | ||
277 | return i.partialtypeinterpratation | ||
278 | .filter(PartialRealInterpretation) | ||
279 | .head | ||
280 | } | ||
281 | private dispatch def getTypeInterpretation(PartialInterpretation i, StringTypeReference reference) { | ||
282 | return i.partialtypeinterpratation | ||
283 | .filter(PartialStringInterpretation) | ||
284 | .head | ||
285 | } | ||
286 | private dispatch def Function0<DefinedElement> getTypeConstructor(PartialComplexTypeInterpretation reference) { [createDefinedElement] } | ||
287 | private dispatch def Function0<DefinedElement> getTypeConstructor(PartialBooleanInterpretation reference) { [createBooleanElement] } | ||
288 | private dispatch def Function0<DefinedElement> getTypeConstructor(PartialIntegerInterpretation reference) { [createIntegerElement] } | ||
289 | private dispatch def Function0<DefinedElement> getTypeConstructor(PartialRealInterpretation reference) { [createRealElement] } | ||
290 | private dispatch def Function0<DefinedElement> getTypeConstructor(PartialStringInterpretation reference) { [createStringElement] } | ||
291 | |||
292 | |||
174 | def createRelationRefinementRules(GeneratedPatterns patterns, ModelGenerationStatistics statistics) { | 293 | def createRelationRefinementRules(GeneratedPatterns patterns, ModelGenerationStatistics statistics) { |
175 | val res = new LinkedHashMap | 294 | val res = new LinkedHashMap |
176 | for(LHSEntry: patterns.refinerelationQueries.entrySet) { | 295 | for(LHSEntry: patterns.refinerelationQueries.entrySet) { |
@@ -186,11 +305,11 @@ class RefinementRuleProvider { | |||
186 | def private BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>> | 305 | def private BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>> |
187 | createRelationRefinementRule(RelationDeclaration declaration, Relation inverseRelation, IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, ModelGenerationStatistics statistics) | 306 | createRelationRefinementRule(RelationDeclaration declaration, Relation inverseRelation, IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, ModelGenerationStatistics statistics) |
188 | { | 307 | { |
189 | val name = '''addRelation_«declaration.name.canonizeName»«IF inverseRelation != null»_and_«inverseRelation.name.canonizeName»«ENDIF»''' | 308 | val name = '''addRelation_«declaration.name.canonizeName»«IF inverseRelation !== null»_and_«inverseRelation.name.canonizeName»«ENDIF»''' |
190 | val ruleBuilder = factory.createRule | 309 | val ruleBuilder = factory.createRule |
191 | .name(name) | 310 | .name(name) |
192 | .precondition(lhs) | 311 | .precondition(lhs) |
193 | if (inverseRelation == null) { | 312 | if (inverseRelation === null) { |
194 | ruleBuilder.action [ match | | 313 | ruleBuilder.action [ match | |
195 | val startTime = System.nanoTime | 314 | val startTime = System.nanoTime |
196 | //println(name) | 315 | //println(name) |
@@ -199,8 +318,7 @@ class RefinementRuleProvider { | |||
199 | val relationInterpretation = match.get(2) as PartialRelationInterpretation | 318 | val relationInterpretation = match.get(2) as PartialRelationInterpretation |
200 | val src = match.get(3) as DefinedElement | 319 | val src = match.get(3) as DefinedElement |
201 | val trg = match.get(4) as DefinedElement | 320 | val trg = match.get(4) as DefinedElement |
202 | val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] | 321 | createRelationLinkAction(src, trg, relationInterpretation) |
203 | relationInterpretation.relationlinks += link | ||
204 | statistics.addExecutionTime(System.nanoTime-startTime) | 322 | statistics.addExecutionTime(System.nanoTime-startTime) |
205 | ] | 323 | ] |
206 | } else { | 324 | } else { |
@@ -213,14 +331,189 @@ class RefinementRuleProvider { | |||
213 | val inverseInterpretation = match.get(3) as PartialRelationInterpretation | 331 | val inverseInterpretation = match.get(3) as PartialRelationInterpretation |
214 | val src = match.get(4) as DefinedElement | 332 | val src = match.get(4) as DefinedElement |
215 | val trg = match.get(5) as DefinedElement | 333 | val trg = match.get(5) as DefinedElement |
216 | val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] | 334 | createRelationLinkWithInverse(src, trg, relationInterpretation, inverseInterpretation) |
217 | relationInterpretation.relationlinks += link | ||
218 | val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src] | ||
219 | inverseInterpretation.relationlinks += inverseLink | ||
220 | statistics.addExecutionTime(System.nanoTime-startTime) | 335 | statistics.addExecutionTime(System.nanoTime-startTime) |
221 | ] | 336 | ] |
222 | } | 337 | } |
223 | 338 | ||
224 | return ruleBuilder.build | 339 | return ruleBuilder.build |
225 | } | 340 | } |
341 | |||
342 | ///////////////////////// | ||
343 | // Actions | ||
344 | ///////////////////////// | ||
345 | |||
346 | protected def void createObjectAction(boolean nameNewElement, ObjectCreationInterpretationData data, DefinedElement container, ScopePropagator scopePropagator) { | ||
347 | if(data.containerInterpretation !== null) { | ||
348 | if(data.containerInverseInterpretation !== null) { | ||
349 | createObjectActionWithContainmentAndInverse( | ||
350 | nameNewElement, | ||
351 | data.interpretation, | ||
352 | data.typeInterpretation, | ||
353 | container, | ||
354 | data.containerInterpretation, | ||
355 | data.containerInverseInterpretation, | ||
356 | data.constructor, | ||
357 | data.recursiveConstructors, | ||
358 | scopePropagator | ||
359 | ) | ||
360 | } else { | ||
361 | createObjectActionWithContainment( | ||
362 | nameNewElement, | ||
363 | data.interpretation, | ||
364 | data.typeInterpretation, | ||
365 | container, | ||
366 | data.containerInterpretation, | ||
367 | data.constructor, | ||
368 | data.recursiveConstructors, | ||
369 | scopePropagator | ||
370 | ) | ||
371 | } | ||
372 | } else { | ||
373 | createObjectAction( | ||
374 | nameNewElement, | ||
375 | data.interpretation, | ||
376 | data.typeInterpretation, | ||
377 | data.constructor, | ||
378 | data.recursiveConstructors, | ||
379 | scopePropagator | ||
380 | ) | ||
381 | } | ||
382 | |||
383 | } | ||
384 | |||
385 | protected def createObjectActionWithContainmentAndInverse( | ||
386 | boolean nameNewElement, | ||
387 | PartialInterpretation interpretation, | ||
388 | PartialTypeInterpratation typeInterpretation, | ||
389 | DefinedElement container, | ||
390 | PartialRelationInterpretation relationInterpretation, | ||
391 | PartialRelationInterpretation inverseRelationInterpretation, | ||
392 | Function0<DefinedElement> constructor, | ||
393 | List<ObjectCreationInterpretationData> recursiceObjectCreations, | ||
394 | ScopePropagator scopePropagator | ||
395 | ) { | ||
396 | val newElement = constructor.apply | ||
397 | if(nameNewElement) { | ||
398 | newElement.name = '''new «interpretation.newElements.size»''' | ||
399 | } | ||
400 | |||
401 | // Existence | ||
402 | interpretation.newElements+=newElement | ||
403 | |||
404 | // Types | ||
405 | typeInterpretation.elements += newElement | ||
406 | if(typeInterpretation instanceof PartialComplexTypeInterpretation) { | ||
407 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] | ||
408 | } | ||
409 | // ContainmentRelation | ||
410 | val newLink1 = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] | ||
411 | relationInterpretation.relationlinks+=newLink1 | ||
412 | // Inverse Containment | ||
413 | val newLink2 = factory2.createBinaryElementRelationLink => [it.param1 = newElement it.param2 = container] | ||
414 | inverseRelationInterpretation.relationlinks+=newLink2 | ||
415 | |||
416 | // Do recursive object creation | ||
417 | for(newConstructor : recursiceObjectCreations) { | ||
418 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) | ||
419 | } | ||
420 | |||
421 | // Scope propagation | ||
422 | scopePropagator.propagateAdditionToType(typeInterpretation) | ||
423 | |||
424 | return newElement | ||
425 | } | ||
426 | |||
427 | protected def createObjectActionWithContainment( | ||
428 | boolean nameNewElement, | ||
429 | PartialInterpretation interpretation, | ||
430 | PartialTypeInterpratation typeInterpretation, | ||
431 | DefinedElement container, | ||
432 | PartialRelationInterpretation relationInterpretation, | ||
433 | Function0<DefinedElement> constructor, | ||
434 | List<ObjectCreationInterpretationData> recursiceObjectCreations, | ||
435 | ScopePropagator scopePropagator | ||
436 | ) { | ||
437 | val newElement = constructor.apply | ||
438 | if(nameNewElement) { | ||
439 | newElement.name = '''new «interpretation.newElements.size»''' | ||
440 | } | ||
441 | |||
442 | // Existence | ||
443 | interpretation.newElements+=newElement | ||
444 | |||
445 | // Types | ||
446 | typeInterpretation.elements += newElement | ||
447 | if(typeInterpretation instanceof PartialComplexTypeInterpretation) { | ||
448 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] | ||
449 | } | ||
450 | // ContainmentRelation | ||
451 | val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] | ||
452 | relationInterpretation.relationlinks+=newLink | ||
453 | |||
454 | // Do recursive object creation | ||
455 | for(newConstructor : recursiceObjectCreations) { | ||
456 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) | ||
457 | } | ||
458 | |||
459 | // Scope propagation | ||
460 | scopePropagator.propagateAdditionToType(typeInterpretation) | ||
461 | |||
462 | return newElement | ||
463 | } | ||
464 | |||
465 | protected def createObjectAction( | ||
466 | boolean nameNewElement, | ||
467 | PartialInterpretation interpretation, | ||
468 | PartialTypeInterpratation typeInterpretation, | ||
469 | Function0<DefinedElement> constructor, | ||
470 | List<ObjectCreationInterpretationData> recursiceObjectCreations, | ||
471 | ScopePropagator scopePropagator) | ||
472 | { | ||
473 | val newElement = constructor.apply | ||
474 | if(nameNewElement) { | ||
475 | newElement.name = '''new «interpretation.newElements.size»''' | ||
476 | } | ||
477 | |||
478 | // Existence | ||
479 | interpretation.newElements+=newElement | ||
480 | |||
481 | // Types | ||
482 | typeInterpretation.elements += newElement | ||
483 | if(typeInterpretation instanceof PartialComplexTypeInterpretation) { | ||
484 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] | ||
485 | } | ||
486 | |||
487 | // Do recursive object creation | ||
488 | for(newConstructor : recursiceObjectCreations) { | ||
489 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) | ||
490 | } | ||
491 | |||
492 | // Scope propagation | ||
493 | scopePropagator.propagateAdditionToType(typeInterpretation) | ||
494 | |||
495 | return newElement | ||
496 | } | ||
497 | |||
498 | protected def boolean createRelationLinkAction(DefinedElement src, DefinedElement trg, PartialRelationInterpretation relationInterpretation) { | ||
499 | val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] | ||
500 | relationInterpretation.relationlinks += link | ||
501 | } | ||
502 | |||
503 | protected def boolean createRelationLinkWithInverse(DefinedElement src, DefinedElement trg, PartialRelationInterpretation relationInterpretation, PartialRelationInterpretation inverseInterpretation) { | ||
504 | val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] | ||
505 | relationInterpretation.relationlinks += link | ||
506 | val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src] | ||
507 | inverseInterpretation.relationlinks += inverseLink | ||
508 | } | ||
509 | } | ||
510 | |||
511 | @Data | ||
512 | class ObjectCreationInterpretationData { | ||
513 | PartialInterpretation interpretation | ||
514 | PartialTypeInterpratation typeInterpretation | ||
515 | PartialRelationInterpretation containerInterpretation | ||
516 | PartialRelationInterpretation containerInverseInterpretation | ||
517 | Function0<DefinedElement> constructor | ||
518 | List<ObjectCreationInterpretationData> recursiveConstructors = new LinkedList | ||
226 | } | 519 | } |