aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.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/RelationDefinitionIndexer.xtend')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend185
1 files changed, 185 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/RelationDefinitionIndexer.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend
new file mode 100644
index 00000000..7792eccb
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/RelationDefinitionIndexer.xtend
@@ -0,0 +1,185 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns
2
3import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDefinition
4import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
5import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.TransfomedViatraQuery
6import java.util.Map
7import org.eclipse.emf.ecore.EAttribute
8import org.eclipse.emf.ecore.EReference
9import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey
10import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey
11import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
12import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable
13import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality
14import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter
15import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality
16import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall
17import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure
18import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.ConstantValue
19import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall
20import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint
21import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery
22
23import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
24import org.eclipse.viatra.query.runtime.emf.types.EDataTypeInSlotsKey
25import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality
26
27class RelationDefinitionIndexer {
28 val PatternGenerator base;
29
30 new(PatternGenerator base) {
31 this.base = base
32 }
33
34 public def generateRelationDefinitions(
35 LogicProblem problem,
36 Iterable<RelationDefinition> relations,
37 Map<String,PQuery> fqn2PQuery) {
38 val relation2PQuery = relations.toInvertedMap[
39 annotations.filter(TransfomedViatraQuery).head.patternFullyQualifiedName.lookup(fqn2PQuery)
40 ]
41
42 return '''
43 «FOR relation : relations»
44 // Must, May and Current queries for «relation.name»
45 «relation.transformPattern(relation.lookup(relation2PQuery), Modality.MUST)»
46 «relation.transformPattern(relation.lookup(relation2PQuery), Modality.MAY)»
47 «relation.transformPattern(relation.lookup(relation2PQuery), Modality.CURRENT)»
48 «ENDFOR»
49 '''
50 }
51
52 private def relationDefinitionName(RelationDefinition relation, Modality modality)
53 '''«modality.name.toLowerCase»InRelation_«base.canonizeName(relation.name)»'''
54
55 private def canonizeName(PVariable v) {
56 return '''«IF v.referringConstraints.size == 1»_«ENDIF»var_«v.name.replaceAll("\\W","")»'''
57 }
58
59 private def transformPattern(RelationDefinition relation, PQuery p, Modality modality) {
60 try {
61 return '''
62 private pattern «relationDefinitionName(relation,modality)»(
63 problem:LogicProblem, interpretation:PartialInterpretation,
64 «FOR param : p.parameters SEPARATOR ', '»var_«param.name»«ENDFOR»)
65 «FOR body : p.disjunctBodies.bodies SEPARATOR "or"»{
66 find interpretation(problem,interpretation);
67 «FOR constraint : body.constraints»
68 «constraint.transformConstraint(modality)»
69 «ENDFOR»
70 }«ENDFOR»
71 '''
72 } catch(UnsupportedOperationException e) {
73 throw new UnsupportedOperationException('''Can not transform pattern "«p.fullyQualifiedName»"!''',e)
74 }
75 }
76
77 private def toMustMay(Modality modality) {
78 if(modality == Modality::MAY) return Modality::MAY
79 else return Modality::MUST
80 }
81
82 def public referPattern(PQuery p, String[] variables, Modality modality, boolean positive, boolean transitive) '''
83 «IF !positive»neg «ENDIF»find «modality.name.toLowerCase»InRelation_pattern_«p.fullyQualifiedName.replace('.','_')»«IF transitive»+«ENDIF»(problem,interpretation,«variables.join(',')»);
84 '''
85
86 private dispatch def transformConstraint(TypeConstraint constraint, Modality modality) {
87 val touple = constraint.variablesTuple
88 if(touple.size == 1) {
89 val inputKey = constraint.equivalentJudgement.inputKey
90 if(inputKey instanceof EClassTransitiveInstancesKey) {
91 return base.typeIndexer.referInstanceOf(inputKey.emfKey,modality.toMustMay,
92 constraint.getVariableInTuple(0).canonizeName)
93 } else if(inputKey instanceof EDataTypeInSlotsKey){
94 return '''// type constraint is enforced by construction'''
95 }
96
97 } else if(touple.size == 2){
98 val key = (constraint.equivalentJudgement.inputKey as EStructuralFeatureInstancesKey).emfKey
99 if(key instanceof EReference) {
100 return base.referRelationByName(
101 key,
102 constraint.getVariableInTuple(0).canonizeName,
103 constraint.getVariableInTuple(1).canonizeName,
104 modality.toMustMay)
105 } else if (key instanceof EAttribute) {
106 return '''// attribute reference omitted'''//base.referRelationByName()
107 } else throw new UnsupportedOperationException('''unknown key: «key.class»''')
108 } else {
109 throw new UnsupportedOperationException()
110 }
111 }
112
113 private dispatch def transformConstraint(Equality equality, Modality modality) {
114 val a = equality.who
115 val b = equality.withWhom
116 transformEquality(modality.toMustMay, a, b)
117 }
118
119 private def CharSequence transformEquality(Modality modality, PVariable a, PVariable b) {
120 if(modality.isMustOrCurrent) '''«a.canonizeName» == «b.canonizeName»;'''
121 else '''find mayEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
122 }
123
124 private dispatch def transformConstraint(Inequality inequality, Modality modality) {
125 val a = inequality.who
126 val b = inequality.withWhom
127 if(modality.isCurrent) {
128 return '''«a.canonizeName» != «b.canonizeName»;'''
129 } else if(modality.isMust) {
130 return '''neg find mayEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);'''
131 } else {
132 return '''«a.canonizeName» != «b.canonizeName»;'''
133 }
134 }
135
136 private dispatch def transformConstraint(NegativePatternCall pcall, Modality modality) {
137 val params = (0..<pcall.actualParametersTuple.size).map[index |
138 val variable = pcall.actualParametersTuple.get(index) as PVariable
139 return variable.canonizeName
140 ]
141 return referPattern(pcall.referredQuery,params,modality.dual,false,false)
142 }
143
144 private dispatch def transformConstraint(PositivePatternCall pcall, Modality modality) {
145 val params = (0..<pcall.variablesTuple.size).map[index |
146 val variable = pcall.variablesTuple.get(index) as PVariable
147 return variable.canonizeName
148 ]
149 return referPattern(pcall.referredQuery,params,modality,true,false)
150 }
151 private dispatch def transformConstraint(BinaryTransitiveClosure pcall, Modality modality) {
152 val params = (0..1).map[index |
153 val variable = pcall.getVariableInTuple(index) as PVariable
154 return variable.canonizeName
155 ]
156 return referPattern(pcall.referredQuery,params,modality,true,true)
157 }
158 private dispatch def transformConstraint(ExportedParameter e, Modality modality) {
159 return '''// «e.parameterName» is exported'''
160 }
161 private dispatch def transformConstraint(ConstantValue c, Modality modality) {
162 val target = c.supplierKey
163
164 var String targetString;
165 var String additionalDefinition;
166 if(target instanceof Enum<?>) {
167 targetString = '''const_«target.name»_«target.declaringClass.simpleName»'''
168 additionalDefinition = '''DefinedElement.name(«targetString»,"«target.name» «target.declaringClass.simpleName»"); LogicProblem.elements(problem,«targetString»);'''
169 } else if(target instanceof Integer) {
170 targetString = target.toString
171 additionalDefinition = ''''''
172 } else throw new UnsupportedOperationException('''Unknown constant type: «target.class»''')
173
174 val source = c.variablesTuple
175 var String sourceName
176 if(source.size == 1)
177 sourceName = (source.get(0) as PVariable).canonizeName
178 else throw new UnsupportedOperationException("unknown source")
179 return '''«sourceName» == «targetString»;«additionalDefinition»''';
180 }
181
182 private dispatch def transformConstraint(PConstraint c, Modality modality) {
183 throw new UnsupportedOperationException('''Unknown constraint type: "«c.class.name»"!''')
184 }
185} \ No newline at end of file