diff options
author | 20001LastOrder <boqi.chen@mail.mcgill.ca> | 2020-11-04 01:33:58 -0500 |
---|---|---|
committer | 20001LastOrder <boqi.chen@mail.mcgill.ca> | 2020-11-04 01:33:58 -0500 |
commit | a20af4d0dbf5eab84ee271d426528aabb5a8ac3b (patch) | |
tree | a9ab772ee313125aaf3a941d66e131b408d949ba /Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/rules | |
parent | changes in settings of measurements (diff) | |
parent | merge with current master, comment numerical solver related logging (diff) | |
download | VIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.tar.gz VIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.tar.zst VIATRA-Generator-a20af4d0dbf5eab84ee271d426528aabb5a8ac3b.zip |
fix merging issue
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, 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 @@ | |||
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.viatrasolver.logic2viatra.MultiplicityGoalConstraintCalculator | 3 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion |
4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type | ||
6 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem | ||
7 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.MultiplicityGoalConstraintCalculator | ||
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns | 8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns |
5 | import java.util.ArrayList | 9 | import java.util.ArrayList |
10 | import java.util.HashMap | ||
11 | import java.util.LinkedList | ||
12 | import java.util.List | ||
13 | import java.util.Map | ||
6 | 14 | ||
7 | class GoalConstraintProvider { | 15 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules | 1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.rules |
2 | 2 | ||
3 | import com.google.common.collect.ImmutableList | ||
4 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.InverseRelationAssertion | ||
5 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.LowerMultiplicityAssertion | ||
6 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference | ||
7 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference | ||
3 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement | 8 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.DefinedElement |
9 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference | ||
4 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguageFactory | 10 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.LogiclanguageFactory |
11 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.PrimitiveTypeReference | ||
12 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation | 13 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation |
6 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration | 14 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration |
15 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringTypeReference | ||
7 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type | 16 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Type |
17 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem | ||
8 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics | 18 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics |
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ScopePropagator | 19 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.ScopePropagator |
10 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns | 20 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.GeneratedPatterns |
11 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ObjectCreationPrecondition | 21 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns.ObjectCreationPrecondition |
22 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialBooleanInterpretation | ||
12 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation | 23 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation |
24 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialIntegerInterpretation | ||
13 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation | 25 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation |
26 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRealInterpretation | ||
14 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation | 27 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation |
28 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialStringInterpretation | ||
29 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation | ||
15 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory | 30 | import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationFactory |
31 | import java.lang.reflect.Field | ||
32 | import java.util.HashMap | ||
33 | import java.util.Iterator | ||
16 | import java.util.LinkedHashMap | 34 | import java.util.LinkedHashMap |
35 | import java.util.LinkedList | ||
36 | import java.util.List | ||
37 | import java.util.Map | ||
38 | import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine | ||
17 | import org.eclipse.viatra.query.runtime.api.GenericPatternMatch | 39 | import org.eclipse.viatra.query.runtime.api.GenericPatternMatch |
40 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
18 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification | 41 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification |
42 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine | ||
19 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | 43 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher |
44 | import org.eclipse.viatra.query.runtime.emf.EMFScope | ||
45 | import org.eclipse.viatra.query.runtime.rete.matcher.ReteBackendFactory | ||
20 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule | 46 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRule |
21 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory | 47 | import org.eclipse.viatra.transformation.runtime.emf.rules.batch.BatchTransformationRuleFactory |
48 | import org.eclipse.xtend.lib.annotations.Data | ||
49 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
50 | import org.eclipse.xtext.xbase.lib.Functions.Function0 | ||
22 | 51 | ||
23 | class RefinementRuleProvider { | 52 | class 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 | ||
736 | class 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 | } |