aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend
diff options
context:
space:
mode:
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend154
1 files changed, 154 insertions, 0 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend
new file mode 100644
index 00000000..e6d92cc6
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDeclarationIndexer.xtend
@@ -0,0 +1,154 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2
3import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.UpperMultiplicityAssertion
4import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference
5import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Relation
6import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
7import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeReference
8import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
9import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
10import java.util.HashMap
11import java.util.List
12import java.util.Map
13import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
14
15import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
16
17class RelationDeclarationIndexer {
18 val PatternGenerator base;
19
20 new(PatternGenerator base) {
21 this.base = base
22 }
23
24 public def generateRelationIndexers(LogicProblem problem, Iterable<RelationDeclaration> relations, Map<String,PQuery> fqn2PQuery) {
25 val upperMultiplicities = new HashMap
26 problem.annotations.filter(UpperMultiplicityAssertion).forEach[
27 upperMultiplicities.put(it.relation,it.upper)
28 ]
29
30 return '''
31 «FOR relation : relations»
32 «IF base.isDerived(relation)»
33 «generateDerivedMustRelation(problem,relation,base.getDerivedDefinition(relation).patternFullyQualifiedName.lookup(fqn2PQuery))»
34 «generateDerivedMayRelation(problem,relation,base.getDerivedDefinition(relation).patternFullyQualifiedName.lookup(fqn2PQuery))»
35 «ELSE»
36 «generateMustRelation(problem,relation)»
37 «generateMayRelation(problem,relation,upperMultiplicities,base.getContainments(problem),base.getInverseRelations(problem),fqn2PQuery)»
38 «ENDIF»
39 «ENDFOR»
40 '''
41 }
42
43 def private patternName(RelationDeclaration r, Modality modality) {
44 '''«modality.name.toLowerCase»InRelation«base.canonizeName(r.name)»'''
45 }
46
47 public def referRelation(
48 RelationDeclaration referred,
49 String sourceVariable,
50 String targetVariable,
51 Modality modality)
52 '''find «referred.patternName(modality)»(problem,interpretation,«sourceVariable»,«targetVariable»);'''
53
54 def generateMustRelation(LogicProblem problem, RelationDeclaration relation) '''
55 /**
56 * Matcher for detecting tuples t where []«relation.name»(source,target)
57 */
58 private pattern «relation.patternName(Modality.MUST)»(
59 problem:LogicProblem, interpretation:PartialInterpretation,
60 source: DefinedElement, target:DefinedElement)
61 {
62 find interpretation(problem,interpretation);
63 PartialInterpretation.partialrelationinterpretation(interpretation,relationIterpretation);
64 PartialRelationInterpretation.interpretationOf.name(relationIterpretation,"«relation.name»");
65 PartialRelationInterpretation.relationlinks(relationIterpretation,link);
66 BinaryElementRelationLink.param1(link,source);
67 BinaryElementRelationLink.param2(link,target);
68 }
69 '''
70 def generateMayRelation(LogicProblem problem, RelationDeclaration relation,
71 Map<Relation, Integer> upperMultiplicities,
72 List<Relation> containments,
73 HashMap<Relation, Relation> inverseRelations,
74 Map<String,PQuery> fqn2PQuery)
75 {
76 return '''
77 /**
78 * Matcher for detecting tuples t where <>«relation.name»(source,target)
79 */
80 private pattern «relation.patternName(Modality.MAY)»(
81 problem:LogicProblem, interpretation:PartialInterpretation,
82 source: DefinedElement, target:DefinedElement)
83 {
84 find interpretation(problem,interpretation);
85 // The two endpoint of the link have to exist
86 find mayExist(problem, interpretation, source);
87 find mayExist(problem, interpretation, target);
88 // Type consistency
89 «transformTypeConsistency(relation.parameters.get(0),"source")»
90 «transformTypeConsistency(relation.parameters.get(1),"target")»
91 «IF upperMultiplicities.containsKey(relation)»
92 // There are "numberOfExistingReferences" currently existing instances of the reference from the source,
93 // the upper bound of the multiplicity should be considered.
94 numberOfExistingReferences == count «referRelation(relation,"source","_",Modality.MUST)»
95 check(numberOfExistingReferences < «upperMultiplicities.get(relation)»);
96 «ENDIF»
97 «IF inverseRelations.containsKey(relation) && upperMultiplicities.containsKey(inverseRelations.get(relation))»
98 // There are "numberOfExistingReferences" currently existing instances of the reference to the target,
99 // the upper bound of the opposite reference multiplicity should be considered.
100 numberOfExistingOppositeReferences == count «base.referRelation(inverseRelations.get(relation),"target","_",Modality.MUST,fqn2PQuery)»
101 check(numberOfExistingOppositeReferences < «upperMultiplicities.get(inverseRelations.get(relation))»);
102 «ENDIF»
103 «IF containments.contains(relation)»
104 // The reference is containment, then a new reference cannot be create if:
105 // 1. Multiple parents
106 neg «base.containmentIndexer.referMustContaint("_","target")»
107 // 2. Circle in the containment hierarchy
108 neg «base.containmentIndexer.referTransitiveMustContains("target","source")»
109 «ENDIF»
110 «IF inverseRelations.containsKey(relation) && containments.contains(inverseRelations.get(relation))»
111 // The eOpposite of the reference is containment, then a referene cannot be created if
112 // 1. Multiple parents
113 neg «base.containmentIndexer.referMustContaint("source","_")»
114 // 2. Circle in the containment hierarchy
115 neg «base.containmentIndexer.referTransitiveMustContains("source","target")»
116 «ENDIF»
117 } or {
118 «relation.referRelation("source","target",Modality.MUST)»
119 }
120 '''
121 }
122
123 def generateDerivedMustRelation(LogicProblem problem, RelationDeclaration relation, PQuery definition) '''
124 /**
125 * Matcher for detecting tuples t where []«relation.name»(source,target)
126 */
127 private pattern «relation.patternName(Modality.MUST)»(
128 problem:LogicProblem, interpretation:PartialInterpretation,
129 source: DefinedElement, target:DefinedElement)
130 {
131 «base.relationDefinitionIndexer.referPattern(definition,#["source","target"],Modality::MUST,true,false)»
132 }
133 '''
134 def generateDerivedMayRelation(LogicProblem problem, RelationDeclaration relation, PQuery definition) '''
135 /**
136 * Matcher for detecting tuples t where []«relation.name»(source,target)
137 */
138 private pattern «relation.patternName(Modality.MAY)»(
139 problem:LogicProblem, interpretation:PartialInterpretation,
140 source: DefinedElement, target:DefinedElement)
141 {
142 «base.relationDefinitionIndexer.referPattern(definition,#["source","target"],Modality::MAY,true,false)»
143 }
144 '''
145
146 protected def CharSequence transformTypeConsistency(TypeReference reference, String name) {
147 if(reference instanceof ComplexTypeReference) {
148 this.base.typeIndexer.referInstanceOf(reference.referred,Modality.MAY,name)
149 } else {
150 return '''// Primitive type of «name» is already enforced'''
151 }
152
153 }
154} \ No newline at end of file