diff options
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules')
2 files changed, 412 insertions, 90 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 b6fdbe06..238ade5b 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,26 @@ | |||
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.logic.model.logicproblem.LogicProblem | ||
3 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.MultiplicityGoalConstraintCalculator | 4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.MultiplicityGoalConstraintCalculator |
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns | 5 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns |
5 | import java.util.ArrayList | 6 | import java.util.ArrayList |
6 | 7 | ||
7 | class GoalConstraintProvider { | 8 | class GoalConstraintProvider { |
8 | def public getUnfinishedMultiplicityQueries(GeneratedPatterns patterns) { | 9 | |
9 | val multiplicityQueries = patterns.unfinishedMulticiplicityQueries | 10 | def getUnfinishedMultiplicityQueries(LogicProblem p, GeneratedPatterns patterns) { |
10 | val res = new ArrayList(multiplicityQueries.size) | 11 | val res = new ArrayList() |
11 | for(multiplicityQuery : multiplicityQueries.entrySet) { | 12 | for (entry : patterns.multiplicityConstraintQueries.entrySet) { |
12 | val targetRelationName = multiplicityQuery.key.name | 13 | val constraint = entry.key |
13 | val query = multiplicityQuery.value | 14 | if (constraint.constrainsUnfinished) { |
14 | res += new MultiplicityGoalConstraintCalculator(targetRelationName,query); | 15 | val queries = entry.value |
16 | val targetRelationName = constraint.relation.name | ||
17 | val query = queries.unfinishedMultiplicityQuery | ||
18 | val minValue = constraint.lowerBound | ||
19 | val containment = constraint.containment | ||
20 | res += new MultiplicityGoalConstraintCalculator(targetRelationName, query, minValue, containment, 1) | ||
21 | } | ||
15 | } | 22 | } |
16 | return res | 23 | return res |
17 | } | 24 | } |
25 | |||
18 | } \ No newline at end of file | 26 | } \ No newline at end of file |
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 7891ebd8..0b8a9019 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,93 @@ | |||
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.cardinality.ScopePropagator | 18 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.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) | 87 | val ruleBuilder = factory.createRule(lhs) |
64 | val ruleBuilder = factory.createRule | ||
65 | .name(name) | 88 | .name(name) |
66 | .precondition(lhs) | 89 | if(containmentRelation !== null) { |
67 | if(containmentRelation != null) { | 90 | if(inverseRelation!== null) { |
68 | if(inverseRelation!= null) { | ||
69 | ruleBuilder.action[match | | 91 | ruleBuilder.action[match | |
70 | statistics.incrementTransformationCount | 92 | statistics.incrementTransformationCount |
71 | // println(name) | 93 | // println(name) |
@@ -77,33 +99,23 @@ class RefinementRuleProvider { | |||
77 | val typeInterpretation = match.get(4) as PartialComplexTypeInterpretation | 99 | val typeInterpretation = match.get(4) as PartialComplexTypeInterpretation |
78 | val container = match.get(5) as DefinedElement | 100 | val container = match.get(5) as DefinedElement |
79 | 101 | ||
80 | val newElement = createDefinedElement | 102 | createObjectActionWithContainmentAndInverse( |
81 | if(nameNewElement) { | 103 | nameNewElement, |
82 | newElement.name = '''new «interpretation.newElements.size»''' | 104 | interpretation, |
83 | } | 105 | typeInterpretation, |
84 | 106 | container, | |
85 | // Existence | 107 | relationInterpretation, |
86 | interpretation.newElements+=newElement | 108 | inverseRelationInterpretation, |
87 | /*interpretation.maxNewElements=interpretation.maxNewElements-1 | 109 | [createDefinedElement], |
88 | if(interpretation.minNewElements > 0) { | 110 | recursiceObjectCreations, |
89 | interpretation.minNewElements=interpretation.minNewElements-1 | 111 | scopePropagator |
90 | }*/ | 112 | ) |
91 | |||
92 | // Types | ||
93 | typeInterpretation.elements += newElement | ||
94 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] | ||
95 | // ContainmentRelation | ||
96 | val newLink1 = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] | ||
97 | relationInterpretation.relationlinks+=newLink1 | ||
98 | // Inverse Containment | ||
99 | val newLink2 = factory2.createBinaryElementRelationLink => [it.param1 = newElement it.param2 = container] | ||
100 | inverseRelationInterpretation.relationlinks+=newLink2 | ||
101 | 113 | ||
102 | val propagatorStartTime = System.nanoTime | 114 | val propagatorStartTime = System.nanoTime |
103 | statistics.addExecutionTime(propagatorStartTime-startTime) | 115 | statistics.addExecutionTime(propagatorStartTime-startTime) |
104 | 116 | ||
105 | // Scope propagation | 117 | // Scope propagation |
106 | scopePropagator.propagateAdditionToType(typeInterpretation) | 118 | scopePropagator.propagateAllScopeConstraints() |
107 | statistics.addScopePropagationTime(System.nanoTime-propagatorStartTime) | 119 | statistics.addScopePropagationTime(System.nanoTime-propagatorStartTime) |
108 | ] | 120 | ] |
109 | } else { | 121 | } else { |
@@ -117,30 +129,22 @@ class RefinementRuleProvider { | |||
117 | val typeInterpretation = match.get(3) as PartialComplexTypeInterpretation | 129 | val typeInterpretation = match.get(3) as PartialComplexTypeInterpretation |
118 | val container = match.get(4) as DefinedElement | 130 | val container = match.get(4) as DefinedElement |
119 | 131 | ||
120 | val newElement = createDefinedElement | 132 | createObjectActionWithContainment( |
121 | if(nameNewElement) { | 133 | nameNewElement, |
122 | newElement.name = '''new «interpretation.newElements.size»''' | 134 | interpretation, |
123 | } | 135 | typeInterpretation, |
124 | 136 | container, | |
125 | // Existence | 137 | relationInterpretation, |
126 | interpretation.newElements+=newElement | 138 | [createDefinedElement], |
127 | /*interpretation.maxNewElements=interpretation.maxNewElements-1 | 139 | recursiceObjectCreations, |
128 | if(interpretation.minNewElements > 0) { | 140 | scopePropagator |
129 | interpretation.minNewElements=interpretation.minNewElements-1 | 141 | ) |
130 | }*/ | ||
131 | |||
132 | // Types | ||
133 | typeInterpretation.elements += newElement | ||
134 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] | ||
135 | // ContainmentRelation | ||
136 | val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] | ||
137 | relationInterpretation.relationlinks+=newLink | ||
138 | 142 | ||
139 | val propagatorStartTime = System.nanoTime | 143 | val propagatorStartTime = System.nanoTime |
140 | statistics.addExecutionTime(propagatorStartTime-startTime) | 144 | statistics.addExecutionTime(propagatorStartTime-startTime) |
141 | 145 | ||
142 | // Scope propagation | 146 | // Scope propagation |
143 | scopePropagator.propagateAdditionToType(typeInterpretation) | 147 | scopePropagator.propagateAllScopeConstraints() |
144 | statistics.addScopePropagationTime(System.nanoTime-propagatorStartTime) | 148 | statistics.addScopePropagationTime(System.nanoTime-propagatorStartTime) |
145 | ] | 149 | ] |
146 | } | 150 | } |
@@ -148,40 +152,175 @@ class RefinementRuleProvider { | |||
148 | ruleBuilder.action[match | | 152 | ruleBuilder.action[match | |
149 | statistics.incrementTransformationCount | 153 | statistics.incrementTransformationCount |
150 | // println(name) | 154 | // println(name) |
151 | |||
152 | val startTime = System.nanoTime | 155 | val startTime = System.nanoTime |
153 | //val problem = match.get(0) as LogicProblem | 156 | //val problem = match.get(0) as LogicProblem |
154 | val interpretation = match.get(1) as PartialInterpretation | 157 | val interpretation = match.get(1) as PartialInterpretation |
155 | val typeInterpretation = match.get(2) as PartialComplexTypeInterpretation | 158 | val typeInterpretation = match.get(2) as PartialComplexTypeInterpretation |
156 | 159 | ||
157 | val newElement = createDefinedElement | 160 | createObjectAction( |
158 | if(nameNewElement) { | 161 | nameNewElement, |
159 | newElement.name = '''new «interpretation.newElements.size»''' | 162 | interpretation, |
160 | } | 163 | typeInterpretation, |
161 | 164 | [createDefinedElement], | |
162 | // Existence | 165 | recursiceObjectCreations, |
163 | interpretation.newElements+=newElement | 166 | scopePropagator |
164 | /* | 167 | ) |
165 | interpretation.maxNewElements=interpretation.maxNewElements-1 | ||
166 | if(interpretation.minNewElements > 0) { | ||
167 | interpretation.minNewElements=interpretation.minNewElements-1 | ||
168 | }*/ | ||
169 | |||
170 | // Types | ||
171 | typeInterpretation.elements += newElement | ||
172 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] | ||
173 | 168 | ||
174 | val propagatorStartTime = System.nanoTime | 169 | val propagatorStartTime = System.nanoTime |
175 | statistics.addExecutionTime(propagatorStartTime-startTime) | 170 | statistics.addExecutionTime(propagatorStartTime-startTime) |
176 | 171 | ||
177 | // Scope propagation | 172 | // Scope propagation |
178 | scopePropagator.propagateAdditionToType(typeInterpretation) | 173 | scopePropagator.propagateAllScopeConstraints() |
179 | statistics.addScopePropagationTime(System.nanoTime-propagatorStartTime) | 174 | statistics.addScopePropagationTime(System.nanoTime-propagatorStartTime) |
180 | ] | 175 | ] |
181 | } | 176 | } |
182 | return ruleBuilder.build | 177 | return ruleBuilder.build |
183 | } | 178 | } |
184 | 179 | ||
180 | def private recursiveObjectCreation(LogicProblem p, PartialInterpretation i) { | ||
181 | val Map<Type,List<ObjectCreationInterpretationData>> recursiveObjectCreation = new HashMap | ||
182 | for(type : p.types) { | ||
183 | recursiveObjectCreation.put(type,new LinkedList) | ||
184 | } | ||
185 | |||
186 | val containmentReferences = p.containmentHierarchies.head.containmentRelations | ||
187 | |||
188 | for(relationInterpretation : i.partialrelationinterpretation) { | ||
189 | val relation = relationInterpretation.interpretationOf | ||
190 | val lowermultiplicities = p.annotations.filter(LowerMultiplicityAssertion).filter[it.relation === relation] | ||
191 | if((!lowermultiplicities.empty)) { | ||
192 | val number = lowermultiplicities.head.lower | ||
193 | if(number > 0) { | ||
194 | val sourceTypeInterpretation = getTypeInterpretation(i, relation, 0) as PartialComplexTypeInterpretation | ||
195 | val subtypeInterpretations = i.partialtypeinterpratation.filter(PartialComplexTypeInterpretation).filter[ | ||
196 | it === sourceTypeInterpretation || | ||
197 | it.supertypeInterpretation.contains(sourceTypeInterpretation) | ||
198 | ] | ||
199 | |||
200 | if(containmentReferences.contains(relation)) { | ||
201 | val targetTypeInterpretation = getTypeInterpretation(i, relation, 1) | ||
202 | val targetType = (targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf | ||
203 | if((!targetType.isIsAbstract) && (targetType.supertypes.empty)) { | ||
204 | val inverseAnnotation = p.annotations.filter(InverseRelationAssertion).filter[it.inverseA === relation || it.inverseB === relation] | ||
205 | if(!inverseAnnotation.empty) { | ||
206 | val onlyInverseAnnotation = if(inverseAnnotation.head.inverseA===relation) { | ||
207 | inverseAnnotation.head.inverseB | ||
208 | } else { | ||
209 | inverseAnnotation.head.inverseA | ||
210 | } | ||
211 | val inverseRelationInterpretation = i.partialrelationinterpretation.filter[it.interpretationOf === onlyInverseAnnotation].head | ||
212 | for(subTypeInterpretation : subtypeInterpretations) { | ||
213 | for(var times=0; times<number; times++) { | ||
214 | recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) += | ||
215 | new ObjectCreationInterpretationData( | ||
216 | i, | ||
217 | targetTypeInterpretation, | ||
218 | relationInterpretation, | ||
219 | inverseRelationInterpretation, | ||
220 | targetTypeInterpretation.getTypeConstructor | ||
221 | ) | ||
222 | } | ||
223 | } | ||
224 | } else { | ||
225 | for(subTypeInterpretation : subtypeInterpretations) { | ||
226 | for(var times=0; times<number; times++) { | ||
227 | recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) += | ||
228 | new ObjectCreationInterpretationData( | ||
229 | i, | ||
230 | targetTypeInterpretation, | ||
231 | relationInterpretation, | ||
232 | null, | ||
233 | targetTypeInterpretation.getTypeConstructor | ||
234 | ) | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | } else if(relation.parameters.get(1) instanceof PrimitiveTypeReference) { | ||
240 | val targetTypeInterpretation = getTypeInterpretation(i, relation, 1) | ||
241 | for(subTypeInterpretation : subtypeInterpretations) { | ||
242 | for(var times=0; times<number; times++) { | ||
243 | recursiveObjectCreation.get(subTypeInterpretation.interpretationOf) += | ||
244 | new ObjectCreationInterpretationData( | ||
245 | i, | ||
246 | targetTypeInterpretation, | ||
247 | relationInterpretation, | ||
248 | null, | ||
249 | targetTypeInterpretation.getTypeConstructor | ||
250 | ) | ||
251 | } | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | |||
258 | // Doing the recursion | ||
259 | var objectCreations = new LinkedList(recursiveObjectCreation.values.flatten.toList) | ||
260 | for(objectCreation : objectCreations) { | ||
261 | val newInterpretation = objectCreation.typeInterpretation | ||
262 | if(newInterpretation instanceof PartialComplexTypeInterpretation) { | ||
263 | val newlyCreatedType = newInterpretation.interpretationOf | ||
264 | if(recursiveObjectCreation.containsKey(newlyCreatedType)) { | ||
265 | val actionsWhenTypeCreated = recursiveObjectCreation.get(newlyCreatedType) | ||
266 | objectCreation.recursiveConstructors+=actionsWhenTypeCreated | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | |||
271 | // checking acyclicity | ||
272 | for(objectCreation : objectCreations) { | ||
273 | var reachable = objectCreation.recursiveConstructors | ||
274 | do { | ||
275 | if(reachable.contains(objectCreation)) { | ||
276 | throw new IllegalArgumentException('''Cicrle in the containment!''') | ||
277 | } else { | ||
278 | reachable = reachable.map[it.recursiveConstructors].flatten.toList | ||
279 | } | ||
280 | } while(!reachable.empty) | ||
281 | } | ||
282 | |||
283 | return recursiveObjectCreation | ||
284 | } | ||
285 | |||
286 | private def getTypeInterpretation(PartialInterpretation i, RelationDeclaration relation, int index) { | ||
287 | val typeReference = relation.parameters.get(index) | ||
288 | return getTypeInterpretation(i,typeReference) | ||
289 | |||
290 | } | ||
291 | private dispatch def getTypeInterpretation(PartialInterpretation i, ComplexTypeReference reference) { | ||
292 | return i.partialtypeinterpratation | ||
293 | .filter(PartialComplexTypeInterpretation) | ||
294 | .filter[it.getInterpretationOf == reference.referred] | ||
295 | .head | ||
296 | } | ||
297 | private dispatch def getTypeInterpretation(PartialInterpretation i, BoolTypeReference reference) { | ||
298 | return i.partialtypeinterpratation | ||
299 | .filter(PartialBooleanInterpretation) | ||
300 | .head | ||
301 | } | ||
302 | private dispatch def getTypeInterpretation(PartialInterpretation i, IntTypeReference reference) { | ||
303 | return i.partialtypeinterpratation | ||
304 | .filter(PartialIntegerInterpretation) | ||
305 | .head | ||
306 | } | ||
307 | private dispatch def getTypeInterpretation(PartialInterpretation i, RealTypeReference reference) { | ||
308 | return i.partialtypeinterpratation | ||
309 | .filter(PartialRealInterpretation) | ||
310 | .head | ||
311 | } | ||
312 | private dispatch def getTypeInterpretation(PartialInterpretation i, StringTypeReference reference) { | ||
313 | return i.partialtypeinterpratation | ||
314 | .filter(PartialStringInterpretation) | ||
315 | .head | ||
316 | } | ||
317 | private dispatch def Function0<DefinedElement> getTypeConstructor(PartialComplexTypeInterpretation reference) { [createDefinedElement] } | ||
318 | private dispatch def Function0<DefinedElement> getTypeConstructor(PartialBooleanInterpretation reference) { [createBooleanElement] } | ||
319 | private dispatch def Function0<DefinedElement> getTypeConstructor(PartialIntegerInterpretation reference) { [createIntegerElement] } | ||
320 | private dispatch def Function0<DefinedElement> getTypeConstructor(PartialRealInterpretation reference) { [createRealElement] } | ||
321 | private dispatch def Function0<DefinedElement> getTypeConstructor(PartialStringInterpretation reference) { [createStringElement] } | ||
322 | |||
323 | |||
185 | def createRelationRefinementRules(GeneratedPatterns patterns, ScopePropagator scopePropagator, ModelGenerationStatistics statistics) { | 324 | def createRelationRefinementRules(GeneratedPatterns patterns, ScopePropagator scopePropagator, ModelGenerationStatistics statistics) { |
186 | val res = new LinkedHashMap | 325 | val res = new LinkedHashMap |
187 | for(LHSEntry: patterns.refinerelationQueries.entrySet) { | 326 | for(LHSEntry: patterns.refinerelationQueries.entrySet) { |
@@ -197,11 +336,10 @@ class RefinementRuleProvider { | |||
197 | def private BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>> | 336 | def private BatchTransformationRule<GenericPatternMatch, ViatraQueryMatcher<GenericPatternMatch>> |
198 | createRelationRefinementRule(RelationDeclaration declaration, Relation inverseRelation, IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, ScopePropagator scopePropagator, ModelGenerationStatistics statistics) | 337 | createRelationRefinementRule(RelationDeclaration declaration, Relation inverseRelation, IQuerySpecification<ViatraQueryMatcher<GenericPatternMatch>> lhs, ScopePropagator scopePropagator, ModelGenerationStatistics statistics) |
199 | { | 338 | { |
200 | val name = '''addRelation_«declaration.name.canonizeName»«IF inverseRelation != null»_and_«inverseRelation.name.canonizeName»«ENDIF»''' | 339 | val name = '''addRelation_«declaration.name.canonizeName»«IF inverseRelation !== null»_and_«inverseRelation.name.canonizeName»«ENDIF»''' |
201 | val ruleBuilder = factory.createRule | 340 | val ruleBuilder = factory.createRule(lhs) |
202 | .name(name) | 341 | .name(name) |
203 | .precondition(lhs) | 342 | if (inverseRelation === null) { |
204 | if (inverseRelation == null) { | ||
205 | ruleBuilder.action [ match | | 343 | ruleBuilder.action [ match | |
206 | statistics.incrementTransformationCount | 344 | statistics.incrementTransformationCount |
207 | val startTime = System.nanoTime | 345 | val startTime = System.nanoTime |
@@ -211,8 +349,8 @@ class RefinementRuleProvider { | |||
211 | val relationInterpretation = match.get(2) as PartialRelationInterpretation | 349 | val relationInterpretation = match.get(2) as PartialRelationInterpretation |
212 | val src = match.get(3) as DefinedElement | 350 | val src = match.get(3) as DefinedElement |
213 | val trg = match.get(4) as DefinedElement | 351 | val trg = match.get(4) as DefinedElement |
214 | val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] | 352 | |
215 | relationInterpretation.relationlinks += link | 353 | createRelationLinkAction(src, trg, relationInterpretation) |
216 | 354 | ||
217 | val propagatorStartTime = System.nanoTime | 355 | val propagatorStartTime = System.nanoTime |
218 | statistics.addExecutionTime(propagatorStartTime-startTime) | 356 | statistics.addExecutionTime(propagatorStartTime-startTime) |
@@ -232,10 +370,8 @@ class RefinementRuleProvider { | |||
232 | val inverseInterpretation = match.get(3) as PartialRelationInterpretation | 370 | val inverseInterpretation = match.get(3) as PartialRelationInterpretation |
233 | val src = match.get(4) as DefinedElement | 371 | val src = match.get(4) as DefinedElement |
234 | val trg = match.get(5) as DefinedElement | 372 | val trg = match.get(5) as DefinedElement |
235 | val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] | 373 | |
236 | relationInterpretation.relationlinks += link | 374 | createRelationLinkWithInverse(src, trg, relationInterpretation, inverseInterpretation) |
237 | val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src] | ||
238 | inverseInterpretation.relationlinks += inverseLink | ||
239 | 375 | ||
240 | val propagatorStartTime = System.nanoTime | 376 | val propagatorStartTime = System.nanoTime |
241 | statistics.addExecutionTime(propagatorStartTime-startTime) | 377 | statistics.addExecutionTime(propagatorStartTime-startTime) |
@@ -248,4 +384,182 @@ class RefinementRuleProvider { | |||
248 | 384 | ||
249 | return ruleBuilder.build | 385 | return ruleBuilder.build |
250 | } | 386 | } |
387 | |||
388 | ///////////////////////// | ||
389 | // Actions | ||
390 | ///////////////////////// | ||
391 | |||
392 | protected def void createObjectAction(boolean nameNewElement, ObjectCreationInterpretationData data, DefinedElement container, ScopePropagator scopePropagator) { | ||
393 | if(data.containerInterpretation !== null) { | ||
394 | if(data.containerInverseInterpretation !== null) { | ||
395 | createObjectActionWithContainmentAndInverse( | ||
396 | nameNewElement, | ||
397 | data.interpretation, | ||
398 | data.typeInterpretation, | ||
399 | container, | ||
400 | data.containerInterpretation, | ||
401 | data.containerInverseInterpretation, | ||
402 | data.constructor, | ||
403 | data.recursiveConstructors, | ||
404 | scopePropagator | ||
405 | ) | ||
406 | } else { | ||
407 | createObjectActionWithContainment( | ||
408 | nameNewElement, | ||
409 | data.interpretation, | ||
410 | data.typeInterpretation, | ||
411 | container, | ||
412 | data.containerInterpretation, | ||
413 | data.constructor, | ||
414 | data.recursiveConstructors, | ||
415 | scopePropagator | ||
416 | ) | ||
417 | } | ||
418 | } else { | ||
419 | createObjectAction( | ||
420 | nameNewElement, | ||
421 | data.interpretation, | ||
422 | data.typeInterpretation, | ||
423 | data.constructor, | ||
424 | data.recursiveConstructors, | ||
425 | scopePropagator | ||
426 | ) | ||
427 | } | ||
428 | |||
429 | } | ||
430 | |||
431 | protected def createObjectActionWithContainmentAndInverse( | ||
432 | boolean nameNewElement, | ||
433 | PartialInterpretation interpretation, | ||
434 | PartialTypeInterpratation typeInterpretation, | ||
435 | DefinedElement container, | ||
436 | PartialRelationInterpretation relationInterpretation, | ||
437 | PartialRelationInterpretation inverseRelationInterpretation, | ||
438 | Function0<DefinedElement> constructor, | ||
439 | List<ObjectCreationInterpretationData> recursiceObjectCreations, | ||
440 | ScopePropagator scopePropagator | ||
441 | ) { | ||
442 | val newElement = constructor.apply | ||
443 | if(nameNewElement) { | ||
444 | newElement.name = '''new «interpretation.newElements.size»''' | ||
445 | } | ||
446 | |||
447 | // Types | ||
448 | typeInterpretation.elements += newElement | ||
449 | if(typeInterpretation instanceof PartialComplexTypeInterpretation) { | ||
450 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] | ||
451 | } | ||
452 | // ContainmentRelation | ||
453 | val newLink1 = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] | ||
454 | relationInterpretation.relationlinks+=newLink1 | ||
455 | // Inverse Containment | ||
456 | val newLink2 = factory2.createBinaryElementRelationLink => [it.param1 = newElement it.param2 = container] | ||
457 | inverseRelationInterpretation.relationlinks+=newLink2 | ||
458 | |||
459 | // Scope propagation | ||
460 | scopePropagator.decrementTypeScope(typeInterpretation) | ||
461 | |||
462 | // Existence | ||
463 | interpretation.newElements+=newElement | ||
464 | |||
465 | // Do recursive object creation | ||
466 | for(newConstructor : recursiceObjectCreations) { | ||
467 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) | ||
468 | } | ||
469 | |||
470 | return newElement | ||
471 | } | ||
472 | |||
473 | protected def createObjectActionWithContainment( | ||
474 | boolean nameNewElement, | ||
475 | PartialInterpretation interpretation, | ||
476 | PartialTypeInterpratation typeInterpretation, | ||
477 | DefinedElement container, | ||
478 | PartialRelationInterpretation relationInterpretation, | ||
479 | Function0<DefinedElement> constructor, | ||
480 | List<ObjectCreationInterpretationData> recursiceObjectCreations, | ||
481 | ScopePropagator scopePropagator | ||
482 | ) { | ||
483 | val newElement = constructor.apply | ||
484 | if(nameNewElement) { | ||
485 | newElement.name = '''new «interpretation.newElements.size»''' | ||
486 | } | ||
487 | |||
488 | // Types | ||
489 | typeInterpretation.elements += newElement | ||
490 | if(typeInterpretation instanceof PartialComplexTypeInterpretation) { | ||
491 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] | ||
492 | } | ||
493 | // ContainmentRelation | ||
494 | val newLink = factory2.createBinaryElementRelationLink => [it.param1 = container it.param2 = newElement] | ||
495 | relationInterpretation.relationlinks+=newLink | ||
496 | |||
497 | // Scope propagation | ||
498 | scopePropagator.decrementTypeScope(typeInterpretation) | ||
499 | |||
500 | // Existence | ||
501 | interpretation.newElements+=newElement | ||
502 | |||
503 | // Do recursive object creation | ||
504 | for(newConstructor : recursiceObjectCreations) { | ||
505 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) | ||
506 | } | ||
507 | |||
508 | return newElement | ||
509 | } | ||
510 | |||
511 | protected def createObjectAction( | ||
512 | boolean nameNewElement, | ||
513 | PartialInterpretation interpretation, | ||
514 | PartialTypeInterpratation typeInterpretation, | ||
515 | Function0<DefinedElement> constructor, | ||
516 | List<ObjectCreationInterpretationData> recursiceObjectCreations, | ||
517 | ScopePropagator scopePropagator) | ||
518 | { | ||
519 | val newElement = constructor.apply | ||
520 | if(nameNewElement) { | ||
521 | newElement.name = '''new «interpretation.newElements.size»''' | ||
522 | } | ||
523 | |||
524 | // Types | ||
525 | typeInterpretation.elements += newElement | ||
526 | if(typeInterpretation instanceof PartialComplexTypeInterpretation) { | ||
527 | typeInterpretation.supertypeInterpretation.forEach[it.elements += newElement] | ||
528 | } | ||
529 | |||
530 | // Scope propagation | ||
531 | scopePropagator.decrementTypeScope(typeInterpretation) | ||
532 | |||
533 | // Existence | ||
534 | interpretation.newElements+=newElement | ||
535 | |||
536 | // Do recursive object creation | ||
537 | for(newConstructor : recursiceObjectCreations) { | ||
538 | createObjectAction(nameNewElement,newConstructor,newElement,scopePropagator) | ||
539 | } | ||
540 | |||
541 | return newElement | ||
542 | } | ||
543 | |||
544 | protected def boolean createRelationLinkAction(DefinedElement src, DefinedElement trg, PartialRelationInterpretation relationInterpretation) { | ||
545 | val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] | ||
546 | relationInterpretation.relationlinks += link | ||
547 | } | ||
548 | |||
549 | protected def boolean createRelationLinkWithInverse(DefinedElement src, DefinedElement trg, PartialRelationInterpretation relationInterpretation, PartialRelationInterpretation inverseInterpretation) { | ||
550 | val link = createBinaryElementRelationLink => [it.param1 = src it.param2 = trg] | ||
551 | relationInterpretation.relationlinks += link | ||
552 | val inverseLink = createBinaryElementRelationLink => [it.param1 = trg it.param2 = src] | ||
553 | inverseInterpretation.relationlinks += inverseLink | ||
554 | } | ||
555 | } | ||
556 | |||
557 | @Data | ||
558 | class ObjectCreationInterpretationData { | ||
559 | PartialInterpretation interpretation | ||
560 | PartialTypeInterpratation typeInterpretation | ||
561 | PartialRelationInterpretation containerInterpretation | ||
562 | PartialRelationInterpretation containerInverseInterpretation | ||
563 | Function0<DefinedElement> constructor | ||
564 | List<ObjectCreationInterpretationData> recursiveConstructors = new LinkedList | ||
251 | } | 565 | } |