diff options
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.xtend | 154 |
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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.ecore2logic.ecore2logicannotations.UpperMultiplicityAssertion | ||
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.RelationDeclaration | ||
7 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeReference | ||
8 | import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem | ||
9 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality | ||
10 | import java.util.HashMap | ||
11 | import java.util.List | ||
12 | import java.util.Map | ||
13 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery | ||
14 | |||
15 | import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* | ||
16 | |||
17 | class 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 | ||