diff options
Diffstat (limited to 'Framework/hu.bme.mit.inf.dslreasoner.ecore2logic/src/hu/bme/mit/inf/dslreasoner/ecore2logic/EReferenceMapper.xtend')
-rw-r--r-- | Framework/hu.bme.mit.inf.dslreasoner.ecore2logic/src/hu/bme/mit/inf/dslreasoner/ecore2logic/EReferenceMapper.xtend | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/Framework/hu.bme.mit.inf.dslreasoner.ecore2logic/src/hu/bme/mit/inf/dslreasoner/ecore2logic/EReferenceMapper.xtend b/Framework/hu.bme.mit.inf.dslreasoner.ecore2logic/src/hu/bme/mit/inf/dslreasoner/ecore2logic/EReferenceMapper.xtend new file mode 100644 index 00000000..e5de6584 --- /dev/null +++ b/Framework/hu.bme.mit.inf.dslreasoner.ecore2logic/src/hu/bme/mit/inf/dslreasoner/ecore2logic/EReferenceMapper.xtend | |||
@@ -0,0 +1,154 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.ecore2logic | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.Ecore2logicannotationsFactory | ||
4 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicProblemBuilder | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Assertion | ||
6 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration | ||
7 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Term | ||
8 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TermDescription | ||
9 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem | ||
10 | import java.util.HashMap | ||
11 | import java.util.Map | ||
12 | import org.eclipse.emf.ecore.EClass | ||
13 | import org.eclipse.emf.ecore.EReference | ||
14 | |||
15 | interface EReferenceMapper{ | ||
16 | def void transformEReferences(Ecore2Logic_Trace trace, LogicProblem problem, Iterable<EReference> classes); | ||
17 | def Term IsInReference(Ecore2Logic_Trace trace, TermDescription source, TermDescription target, EReference type) | ||
18 | def RelationDeclaration relationOfReference(Ecore2Logic_Trace trace, EReference reference) | ||
19 | } | ||
20 | |||
21 | class EReferenceMapper_RelationsOverTypes_Trace implements Trace<EReferenceMapper_RelationsOverTypes> { | ||
22 | public var Map<EReference, RelationDeclaration> indicators; | ||
23 | public var Map<EReference, Assertion> typeCompliance | ||
24 | public var Map<EReference, Assertion> lowerMultiplicity | ||
25 | public var Map<EReference, Assertion> upperMultiplicity | ||
26 | public var Map<EReference, Assertion> inverseEdges | ||
27 | } | ||
28 | |||
29 | class EReferenceMapper_RelationsOverTypes implements EReferenceMapper{ | ||
30 | val extension LogicProblemBuilder builder = new LogicProblemBuilder | ||
31 | val extension Ecore2logicannotationsFactory builder2 = Ecore2logicannotationsFactory.eINSTANCE | ||
32 | val extension EClassMapper classMapper; | ||
33 | |||
34 | public new(EClassMapper classMapper) { | ||
35 | this.classMapper = classMapper | ||
36 | } | ||
37 | |||
38 | def asTrace(Trace<? extends EReferenceMapper> o) { o as EReferenceMapper_RelationsOverTypes_Trace } | ||
39 | |||
40 | override transformEReferences(Ecore2Logic_Trace trace, LogicProblem problem, Iterable<EReference> references) { | ||
41 | val newTrace = new EReferenceMapper_RelationsOverTypes_Trace | ||
42 | trace.referenceMapperTrace = newTrace | ||
43 | trace.createIndicatorDeclarations(problem,references) | ||
44 | trace.createMultiplicityConstraints(problem,references) | ||
45 | trace.createInverseReferenceConstraints(problem,references) | ||
46 | } | ||
47 | |||
48 | def protected void createIndicatorDeclarations(Ecore2Logic_Trace trace, LogicProblem problem, Iterable<EReference> references) { | ||
49 | trace.referenceMapperTrace.asTrace.indicators = new HashMap | ||
50 | for(reference : references) { | ||
51 | val relation = problem.add(RelationDeclaration( | ||
52 | '''inreference «reference.name» «reference.EContainingClass.name»''', | ||
53 | TypeofEClass(trace,reference.EContainingClass), | ||
54 | TypeofEClass(trace,reference.EType as EClass))) | ||
55 | trace.referenceMapperTrace.asTrace.indicators.put(reference,relation as RelationDeclaration) | ||
56 | } | ||
57 | } | ||
58 | |||
59 | def void createMultiplicityConstraints(Ecore2Logic_Trace trace, LogicProblem problem, Iterable<EReference> references) { | ||
60 | trace.referenceMapperTrace.asTrace.lowerMultiplicity = new HashMap | ||
61 | trace.referenceMapperTrace.asTrace.upperMultiplicity = new HashMap | ||
62 | |||
63 | for(reference : references) { | ||
64 | val sourceType = reference.EContainingClass | ||
65 | val targetType = reference.EType as EClass | ||
66 | val lower = reference.lowerBound | ||
67 | val upper = reference.upperBound | ||
68 | |||
69 | if (lower > 0) { | ||
70 | val assertion = Assertion('''lowerMultiplicity «reference.name» «sourceType.name»''', | ||
71 | Forall[ | ||
72 | val source = addVar('''src''', trace.TypeofEClass(sourceType)) | ||
73 | Exists[ context | | ||
74 | val targets = (1 .. lower).map[ | ||
75 | context.addVar('''trg «it»''', trace.TypeofEClass(targetType))].toList | ||
76 | val inReference = And(targets.map[IsInReference(trace, source, it, reference)]) | ||
77 | if(targets.size > 1) return Distinct(targets) && inReference | ||
78 | else return inReference | ||
79 | ] | ||
80 | ] | ||
81 | ) | ||
82 | val annotation = createLowerMultiplicityAssertion => [ | ||
83 | it.lower = lower | ||
84 | it.relation = trace.referenceMapperTrace.asTrace.indicators.get(reference) | ||
85 | ] | ||
86 | |||
87 | problem.add(assertion) | ||
88 | problem.annotations += annotation | ||
89 | assertion.annotations +=annotation | ||
90 | trace.referenceMapperTrace.asTrace.lowerMultiplicity.put(reference,assertion) | ||
91 | } | ||
92 | else trace.referenceMapperTrace.asTrace.lowerMultiplicity.put(reference,null) | ||
93 | |||
94 | if(upper != -1) { | ||
95 | val assertion = Assertion('''upperMultiplicity «reference.name» «sourceType.name»''', | ||
96 | Forall[ context | | ||
97 | val source = context.addVar('''src''', trace.TypeofEClass(sourceType)) | ||
98 | val targets = (1 .. upper+1).map[ | ||
99 | context.addVar('''trg «it»''', trace.TypeofEClass(targetType))].toList | ||
100 | And(targets.map[IsInReference(trace, source, it, reference)]) => ! Distinct(targets) | ||
101 | ]) | ||
102 | val annotation = createUpperMultiplicityAssertion => [ | ||
103 | it.upper = upper | ||
104 | it.relation = trace.referenceMapperTrace.asTrace.indicators.get(reference) | ||
105 | ] | ||
106 | |||
107 | problem.add(assertion) | ||
108 | problem.annotations += annotation | ||
109 | assertion.annotations += annotation | ||
110 | trace.referenceMapperTrace.asTrace.lowerMultiplicity.put(reference,assertion) | ||
111 | } | ||
112 | else trace.referenceMapperTrace.asTrace.upperMultiplicity.put(reference,null) | ||
113 | } | ||
114 | } | ||
115 | |||
116 | def createInverseReferenceConstraints(Ecore2Logic_Trace trace, LogicProblem problem, Iterable<EReference> references) { | ||
117 | trace.referenceMapperTrace.asTrace.inverseEdges = new HashMap | ||
118 | for(reference : references) { | ||
119 | if(reference.EOpposite!=null) { | ||
120 | val opposite = reference.EOpposite | ||
121 | if(trace.referenceMapperTrace.asTrace.inverseEdges.containsKey(opposite)) { | ||
122 | trace.referenceMapperTrace.asTrace.inverseEdges.put(reference,trace.referenceMapperTrace.asTrace.inverseEdges.get(opposite)) | ||
123 | } else { | ||
124 | val sourceType = reference.EContainingClass | ||
125 | val targetType = reference.EType as EClass | ||
126 | val assertion = Assertion('''oppositeReference «reference.name» «sourceType.name»''', | ||
127 | Forall[ | ||
128 | val src = addVar('''src''', trace.TypeofEClass(sourceType)) | ||
129 | val trg = addVar('''trg''', trace.TypeofEClass(targetType)) | ||
130 | IsInReference(trace,src,trg,reference) <=> IsInReference(trace,trg,src,opposite) | ||
131 | ] | ||
132 | ) | ||
133 | problem.add(assertion) | ||
134 | trace.referenceMapperTrace.asTrace.inverseEdges.put(reference,assertion) | ||
135 | val annotation = createInverseRelationAssertion => [ | ||
136 | it.target = assertion | ||
137 | it.inverseA = trace.referenceMapperTrace.asTrace.indicators.get(reference) | ||
138 | it.inverseB = trace.referenceMapperTrace.asTrace.indicators.get(reference.EOpposite) | ||
139 | ] | ||
140 | problem.annotations += annotation | ||
141 | } | ||
142 | } | ||
143 | else trace.referenceMapperTrace.asTrace.inverseEdges.put(reference,null) | ||
144 | } | ||
145 | } | ||
146 | |||
147 | override IsInReference(Ecore2Logic_Trace trace, TermDescription source, TermDescription target, EReference type) { | ||
148 | trace.referenceMapperTrace.asTrace.indicators.get(type).call(source,target) | ||
149 | } | ||
150 | |||
151 | override relationOfReference(Ecore2Logic_Trace trace, EReference reference) { | ||
152 | trace.referenceMapperTrace.asTrace.indicators.get(reference) | ||
153 | } | ||
154 | } \ No newline at end of file | ||