diff options
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend')
-rw-r--r-- | Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend | 243 |
1 files changed, 243 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/PConstraintTransformer.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend new file mode 100644 index 00000000..a421d1fd --- /dev/null +++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PConstraintTransformer.xtend | |||
@@ -0,0 +1,243 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.viatra2logic.XExpressionExtractor | ||
4 | import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.Modality | ||
5 | import org.eclipse.emf.ecore.EAttribute | ||
6 | import org.eclipse.emf.ecore.EEnumLiteral | ||
7 | import org.eclipse.emf.ecore.EReference | ||
8 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey | ||
9 | import org.eclipse.viatra.query.runtime.emf.types.EDataTypeInSlotsKey | ||
10 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey | ||
11 | import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint | ||
12 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable | ||
13 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality | ||
14 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter | ||
15 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExpressionEvaluation | ||
16 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality | ||
17 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall | ||
18 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.TypeFilterConstraint | ||
19 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure | ||
20 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.ConstantValue | ||
21 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall | ||
22 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint | ||
23 | import hu.bme.mit.inf.dslreasoner.viatra2logic.viatra2logicannotations.VariableMapping | ||
24 | import java.util.List | ||
25 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeReference | ||
26 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.PrimitiveTypeReference | ||
27 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.StringTypeReference | ||
28 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference | ||
29 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.IntTypeReference | ||
30 | import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference | ||
31 | |||
32 | class PConstraintTransformer { | ||
33 | val extension RelationDefinitionIndexer relationDefinitionIndexer; | ||
34 | val expressionExtractor = new XExpressionExtractor | ||
35 | val expressionGenerator = new PExpressionGenerator | ||
36 | |||
37 | new(RelationDefinitionIndexer relationDefinitionIndexer) { | ||
38 | this.relationDefinitionIndexer = relationDefinitionIndexer | ||
39 | } | ||
40 | |||
41 | dispatch def transformConstraint(TypeConstraint constraint, Modality modality, List<VariableMapping> variableMapping) { | ||
42 | val touple = constraint.variablesTuple | ||
43 | if(touple.size == 1) { | ||
44 | val inputKey = constraint.equivalentJudgement.inputKey | ||
45 | if(inputKey instanceof EClassTransitiveInstancesKey) { | ||
46 | return relationDefinitionIndexer.base.typeIndexer.referInstanceOf(inputKey.emfKey,modality.toMustMay, | ||
47 | constraint.getVariableInTuple(0).canonizeName) | ||
48 | } else if(inputKey instanceof EDataTypeInSlotsKey){ | ||
49 | return '''// type constraint is enforced by construction''' | ||
50 | } | ||
51 | |||
52 | } else if(touple.size == 2){ | ||
53 | val key = (constraint.equivalentJudgement.inputKey as EStructuralFeatureInstancesKey).emfKey | ||
54 | if(key instanceof EReference) { | ||
55 | return base.referRelationByName( | ||
56 | key, | ||
57 | constraint.getVariableInTuple(0).canonizeName, | ||
58 | constraint.getVariableInTuple(1).canonizeName, | ||
59 | modality.toMustMay) | ||
60 | } else if (key instanceof EAttribute) { | ||
61 | return base.referAttributeByName(key, | ||
62 | constraint.getVariableInTuple(0).canonizeName, | ||
63 | constraint.getVariableInTuple(1).canonizeName, | ||
64 | modality.toMustMay) | ||
65 | } else throw new UnsupportedOperationException('''unknown key: «key.class»''') | ||
66 | } else { | ||
67 | throw new UnsupportedOperationException('''Unsupported touple size: «touple.size»''') | ||
68 | } | ||
69 | } | ||
70 | dispatch def transformConstraint(TypeFilterConstraint constraint, Modality modality, List<VariableMapping> variableMapping) { | ||
71 | val touple = constraint.variablesTuple | ||
72 | if(touple.size == 1) { | ||
73 | val inputKey = constraint.equivalentJudgement.inputKey | ||
74 | if(inputKey instanceof EClassTransitiveInstancesKey) { | ||
75 | return base.typeIndexer.referInstanceOf(inputKey.emfKey,modality.toMustMay, | ||
76 | (constraint.getVariablesTuple.get(0) as PVariable).canonizeName) | ||
77 | } else if(inputKey instanceof EDataTypeInSlotsKey){ | ||
78 | return '''// type constraint is enforced by construction''' | ||
79 | } | ||
80 | |||
81 | } else if(touple.size == 2){ | ||
82 | val key = (constraint.equivalentJudgement.inputKey as EStructuralFeatureInstancesKey).emfKey | ||
83 | if(key instanceof EReference) { | ||
84 | return base.referRelationByName( | ||
85 | key, | ||
86 | (constraint.getVariablesTuple.get(0) as PVariable).canonizeName, | ||
87 | (constraint.getVariablesTuple.get(1) as PVariable).canonizeName, | ||
88 | modality.toMustMay) | ||
89 | } else if (key instanceof EAttribute) { | ||
90 | return base.referAttributeByName(key, | ||
91 | (constraint.getVariablesTuple.get(0) as PVariable).canonizeName, | ||
92 | (constraint.getVariablesTuple.get(1) as PVariable).canonizeName, | ||
93 | modality.toMustMay) | ||
94 | } else throw new UnsupportedOperationException('''unknown key: «key.class»''') | ||
95 | } else { | ||
96 | throw new UnsupportedOperationException('''Unsupported touple size: «touple.size»''') | ||
97 | } | ||
98 | } | ||
99 | |||
100 | dispatch def transformConstraint(Equality equality, Modality modality, List<VariableMapping> variableMapping) { | ||
101 | val a = equality.who | ||
102 | val b = equality.withWhom | ||
103 | transformEquality(modality.toMustMay, a, b) | ||
104 | } | ||
105 | |||
106 | private def CharSequence transformEquality(Modality modality, PVariable a, PVariable b) { | ||
107 | if(modality.isMustOrCurrent) '''find mustEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);''' | ||
108 | else '''find mayEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);''' | ||
109 | } | ||
110 | |||
111 | dispatch def transformConstraint(Inequality inequality, Modality modality, List<VariableMapping> variableMapping) { | ||
112 | val a = inequality.who | ||
113 | val b = inequality.withWhom | ||
114 | if(modality.isCurrent) { | ||
115 | return '''neg find mustEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);''' | ||
116 | } else if(modality.isMust) { | ||
117 | return '''neg find mayEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);''' | ||
118 | } else { // modality.isMay | ||
119 | return '''neg find mustEquivalent(problem, interpretation, «a.canonizeName», «b.canonizeName»);''' | ||
120 | } | ||
121 | } | ||
122 | |||
123 | dispatch def transformConstraint(NegativePatternCall pcall, Modality modality, List<VariableMapping> variableMapping) { | ||
124 | val params = (0..<pcall.actualParametersTuple.size).map[index | | ||
125 | val variable = pcall.actualParametersTuple.get(index) as PVariable | ||
126 | return variable.canonizeName | ||
127 | ] | ||
128 | return referPattern(pcall.referredQuery,params,modality.dual,false,false) | ||
129 | } | ||
130 | |||
131 | dispatch def transformConstraint(PositivePatternCall pcall, Modality modality, List<VariableMapping> variableMapping) { | ||
132 | val params = (0..<pcall.variablesTuple.size).map[index | | ||
133 | val variable = pcall.variablesTuple.get(index) as PVariable | ||
134 | return variable.canonizeName | ||
135 | ] | ||
136 | return referPattern(pcall.referredQuery,params,modality,true,false) | ||
137 | } | ||
138 | dispatch def transformConstraint(BinaryTransitiveClosure pcall, Modality modality, List<VariableMapping> variableMapping) { | ||
139 | val params = (0..1).map[index | | ||
140 | val variable = pcall.getVariableInTuple(index) as PVariable | ||
141 | return variable.canonizeName | ||
142 | ] | ||
143 | return referPattern(pcall.referredQuery,params,modality,true,true) | ||
144 | } | ||
145 | dispatch def transformConstraint(ExportedParameter e, Modality modality, List<VariableMapping> variableMapping) { | ||
146 | return '''// «e.parameterName» is exported''' | ||
147 | } | ||
148 | dispatch def transformConstraint(ConstantValue c, Modality modality, List<VariableMapping> variableMapping) { | ||
149 | val target = c.supplierKey | ||
150 | |||
151 | var String targetString; | ||
152 | var String additionalDefinition; | ||
153 | if(target instanceof EEnumLiteral) { | ||
154 | targetString = '''const_«target.name»_«target.EEnum.name»''' | ||
155 | additionalDefinition = '''DefinedElement.name(«targetString»,"«target.name» «target.EEnum.name»"); //LogicProblem.elements(problem,«targetString»);''' | ||
156 | } else if(target instanceof Integer) { | ||
157 | targetString = '''const_«target»_Integer''' | ||
158 | additionalDefinition = '''PrimitiveElement.valueSet(«targetString»,true); IntegerElement.value(«targetString»,«target»);''' | ||
159 | } else if(target instanceof Boolean) { | ||
160 | targetString = '''const_«target»_Boolean''' | ||
161 | additionalDefinition = '''PrimitiveElement.valueSet(«targetString»,true); BooleanElement.value(«targetString»,«target»);''' | ||
162 | } else if(target instanceof String) { | ||
163 | targetString = '''const_«target»_String''' | ||
164 | additionalDefinition = '''PrimitiveElement.valueSet(«targetString»,true); StringElement.value(«targetString»,"«target»");''' | ||
165 | } else if(target instanceof Double) { | ||
166 | targetString = '''const_«target»_Real''' | ||
167 | additionalDefinition = '''PrimitiveElement.valueSet(«targetString»,true); RealElement.value(«targetString»,«target»);''' | ||
168 | } else if(target instanceof Float) { | ||
169 | targetString = '''const_«target»_Real''' | ||
170 | additionalDefinition = '''PrimitiveElement.valueSet(«targetString»,true); RealElement.value(«targetString»,«target»);''' | ||
171 | } else { | ||
172 | throw new UnsupportedOperationException('''Unknown constant type: «target.class»''') | ||
173 | } | ||
174 | |||
175 | val source = c.variablesTuple | ||
176 | var String sourceName | ||
177 | if(source.size == 1) | ||
178 | sourceName = (source.get(0) as PVariable).canonizeName | ||
179 | else throw new UnsupportedOperationException("unknown source") | ||
180 | return '''«sourceName» == «targetString»;«additionalDefinition»'''; | ||
181 | } | ||
182 | |||
183 | protected def valueVariable(PVariable v) { | ||
184 | "value_"+v.canonizeName | ||
185 | } | ||
186 | protected def valueSetted(PVariable v) { | ||
187 | "setted_"+v.canonizeName | ||
188 | } | ||
189 | def hasValue(PVariable v, String target, Modality m, List<VariableMapping> variableMapping) { | ||
190 | val typeReference = variableMapping.filter[it.sourcePVariable === v].head.targetLogicVariable.range as PrimitiveTypeReference | ||
191 | if(m.isMay) { | ||
192 | '''PrimitiveElement.valueSet(«v.canonizeName»,«v.valueSetted»); «hasValueExpression(typeReference,v,v.valueVariable)» check(!«v.valueSetted»||«v.valueVariable»==«target»));''' | ||
193 | } else { // Must or current | ||
194 | '''PrimitiveElement.valueSet(«v.canonizeName»,true);«hasValueExpression(typeReference,v,target)»''' | ||
195 | } | ||
196 | } | ||
197 | |||
198 | private def hasValueExpression(List<VariableMapping> variableMapping, PVariable v, String target) { | ||
199 | hasValueExpression( | ||
200 | variableMapping.filter[it.sourcePVariable === v].head.targetLogicVariable.range, | ||
201 | v, | ||
202 | target | ||
203 | ) | ||
204 | } | ||
205 | private def dispatch hasValueExpression(BoolTypeReference typeReference, PVariable v, String target) '''BooleanElement.value(«v.canonizeName»,«target»);''' | ||
206 | private def dispatch hasValueExpression(IntTypeReference typeReference, PVariable v, String target) '''IntegerElement.value(«v.canonizeName»,«target»);''' | ||
207 | private def dispatch hasValueExpression(RealTypeReference typeReference, PVariable v, String target) '''RealElement.value(«v.canonizeName»,«target»);''' | ||
208 | private def dispatch hasValueExpression(StringTypeReference typeReference, PVariable v, String target) '''StringElement.value(«v.canonizeName»,«target»);''' | ||
209 | private def dispatch hasValueExpression(TypeReference typeReference, PVariable v, String target) { | ||
210 | throw new UnsupportedOperationException('''Unsupported primitive type reference: «typeReference.class»''') | ||
211 | } | ||
212 | |||
213 | dispatch def transformConstraint(ExpressionEvaluation e, Modality modality, List<VariableMapping> variableMapping) { | ||
214 | if(e.outputVariable!==null) { | ||
215 | throw new UnsupportedOperationException('''Only check expressions are supported "«e.class.name»"!''') | ||
216 | } else { | ||
217 | val expression = expressionExtractor.extractExpression(e.evaluator) | ||
218 | if(modality.isMay) { | ||
219 | return ''' | ||
220 | «FOR variable: e.affectedVariables» | ||
221 | PrimitiveElement.valueSet(«variable.canonizeName»,«variable.valueSetted»); «hasValueExpression(variableMapping,variable,variable.valueVariable)» | ||
222 | «ENDFOR» | ||
223 | check( | ||
224 | «FOR variable: e.affectedVariables SEPARATOR " || "»!«variable.valueSetted»«ENDFOR» | ||
225 | || | ||
226 | («expressionGenerator.translateExpression(expression,e.affectedVariables.toInvertedMap[valueVariable])») | ||
227 | ); | ||
228 | ''' | ||
229 | } else { // Must or Current | ||
230 | return ''' | ||
231 | «FOR variable: e.affectedVariables» | ||
232 | PrimitiveElement.valueSet(«variable.canonizeName»,true); «hasValueExpression(variableMapping,variable,variable.valueVariable)» | ||
233 | «ENDFOR» | ||
234 | check(«expressionGenerator.translateExpression(expression,e.affectedVariables.toInvertedMap[valueVariable])»); | ||
235 | ''' | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | |||
240 | dispatch def transformConstraint(PConstraint c, Modality modality, List<VariableMapping> variableMapping) { | ||
241 | throw new UnsupportedOperationException('''Unknown constraint type: "«c.class.name»"!''') | ||
242 | } | ||
243 | } \ No newline at end of file | ||