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