aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/patterns/PExpressionGenerator.xtend
blob: 62ff92b214bccbf0dbf2b368f1c746d00d91e785 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.patterns

import java.util.Map
import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable
import org.eclipse.xtext.xbase.XBinaryOperation
import org.eclipse.xtext.xbase.XExpression
import org.eclipse.xtext.xbase.XFeatureCall
import org.eclipse.xtext.xbase.XMemberFeatureCall
import org.eclipse.xtext.xbase.XNumberLiteral
import org.eclipse.xtext.xbase.XUnaryOperation
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.PrimitiveTypeReference
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RealTypeReference

class PExpressionGenerator {
	static val N_Base = "org.eclipse.xtext.xbase.lib."
	
	static val N_PLUS1 = "operator_plus"
	static val N_MINUS1 = "operator_minus"
	
	static val N_MINUS2 = "operator_minus"
	static val N_PLUS2 = "operator_plus"
	static val N_POWER = "operator_power"
	static val N_MULTIPLY = "operator_multiply"
	static val N_DIVIDE = "operator_divide"
	static val N_MODULO = "operator_modulo"
	static val N_LESSTHAN = "operator_lessThan"
	static val N_LESSEQUALSTHAN = "operator_lessEqualsThan"
	static val N_GREATERTHAN = "operator_greaterThan"
	static val N_GREATEREQUALTHAN = "operator_greaterEqualsThan"
	static val N_EQUALS = "operator_equals"
	static val N_NOTEQUALS = "operator_notEquals"
	static val N_EQUALS3 = "operator_tripleEquals"
	static val N_NOTEQUALS3 = "operator_tripleNotEquals"
	
	protected def isN(String name, String s) {
		val res = name.startsWith(N_Base) && name.endsWith(s)
		//println('''[«res»] «name» ?= «N_Base»*«s»''')
		return res
	}
	
	static val N_POWER2 = "java.lang.Math.pow"
	
	def dispatch CharSequence translateExpression(XBinaryOperation e, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) {
		val left = e.leftOperand.translateExpression(valueName,variable2Type)
		val right = e.rightOperand.translateExpression(valueName,variable2Type)
		val feature = e.feature.qualifiedName
		     if(feature.isN(N_MINUS2)) { return '''(«left»-«right»)'''}
		else if(feature.isN(N_PLUS2)) { return '''(«left»+«right»)''' }
		else if(feature.isN(N_POWER)) { return '''(«left»^«right»)'''  }
		else if(feature.isN(N_MULTIPLY)) { return '''(«left»*«right»)''' }
		else if(feature.isN(N_DIVIDE)) { return '''(«left»/«right»)''' }
		else if(feature.isN(N_MODULO)) { return '''(«left»%«right»)''' }
		else if(feature.isN(N_LESSTHAN)) { return '''(«left»<«right»)''' }
		else if(feature.isN(N_LESSEQUALSTHAN)) { return '''(«left»<=«right»)''' }
		else if(feature.isN(N_GREATERTHAN)) { return '''(«left»>«right»)''' }
		else if(feature.isN(N_GREATEREQUALTHAN)) { return '''(«left»>=«right»)''' }
		else if(feature.isN(N_EQUALS)) { return '''(«left»==«right»)''' }
		else if(feature.isN(N_NOTEQUALS)) { return '''(«left»!=«right»)''' }
		else if(feature.isN(N_EQUALS3)) { return '''(«left»===«right»)''' }
		else if(feature.isN(N_NOTEQUALS3)) { return '''(«left»!==«right»)''' }
		else {
			println("-> " + e.feature+","+e.class)
			println("-> " + e.leftOperand)
			println("-> " + e.rightOperand)
			println("-> " + e.feature.qualifiedName)
			throw new UnsupportedOperationException('''Unsupported binary operator feature: "«e.feature.class.simpleName»" - «e»''')
		}
	}
	
	def dispatch CharSequence translateExpression(XUnaryOperation e, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) {
		val operand = e.operand.translateExpression(valueName,variable2Type)
		val feature = e.feature.qualifiedName
		if(feature.isN(N_MINUS1)) { return '''(-«operand»)'''}
		else if(feature.isN(N_PLUS1)) { return '''(+«operand»)'''}
		else{
			println("-> " + e.feature+","+e.class)
			println("-> " + e.operand)
			println("-> " + e.feature.qualifiedName)
			throw new UnsupportedOperationException('''Unsupported unary operator feature: "«e.feature.class.simpleName»" - «e»''')
		}
	}
	
	def dispatch CharSequence translateExpression(XMemberFeatureCall e, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) {
		val transformedArguments = e.actualArguments.map[translateExpression(valueName,variable2Type)]
		val feature = e.feature.qualifiedName
		if(feature == N_POWER2) {
			return '''Math.pow(«transformedArguments.get(0)»,«transformedArguments.get(1)»)'''
		}else {
			println(e.feature+","+e.class)
			println(e.actualArguments.join(", "))
			println(e.feature.qualifiedName)
			throw new UnsupportedOperationException('''Unsupported feature call: "«e.feature.qualifiedName»" - «e»''')
		}
	}
	
	def dispatch CharSequence translateExpression(XFeatureCall e, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) {
		val featureName = e.feature.qualifiedName
		val type = variable2Type.entrySet.filter[it.key.name===featureName].head.value
		val entryWithName = valueName.entrySet.filter[it.key.name == featureName].head
		if(entryWithName !== null) {
			if(type instanceof RealTypeReference) {
				return '''(«entryWithName.value».doubleValue)'''
			} else {
				return entryWithName.value
			}
		} else {
			throw new IllegalArgumentException('''Feature call reference to unavailable variable "«featureName»"''')
		}
	}
	
	def dispatch CharSequence translateExpression(XNumberLiteral l, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) '''«l.value»'''
	
	def dispatch CharSequence translateExpression(XExpression expression, Map<PVariable,String> valueName, Map<PVariable, PrimitiveTypeReference> variable2Type) {
		throw new UnsupportedOperationException('''Unsupported expression in check or eval: «expression.class.name», «expression»"''')
	}
}