aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/Alloy-Solver2/hu.bme.mit.inf.dlsreasoner.alloy.reasoner/src/hu/bme/mit/inf/dlsreasoner/alloy/reasoner/builder/Logic2AlloyLanguageMapper_Support.xtend
blob: 0b8d28572cc064f30cbd2e48d8503e14c7b85289 (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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
package hu.bme.mit.inf.dlsreasoner.alloy.reasoner.builder

import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSEquals
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSMultiplicity
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSReference
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSTerm
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSVariableDeclaration
import hu.bme.mit.inf.dslreasoner.alloyLanguage.AlloyLanguageFactory
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.BoolTypeReference
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.QuantifiedExpression
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Term
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.TypeReference
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.Variable
import java.util.ArrayList
import java.util.HashMap
import java.util.List
import java.util.Map
import org.eclipse.emf.ecore.util.EcoreUtil

class Logic2AlloyLanguageMapper_Support {
	private val extension AlloyLanguageFactory factory = AlloyLanguageFactory.eINSTANCE
	
	/// ID handling
	def protected String toIDMultiple(String... ids) {
		ids.map[it.split("\\s+").join("'")].join("'")
	}
	
	def protected  String toID(String ids) {
		ids.split("\\s+").join("'")
	}
	def protected  String toID(List<String> ids) {
		ids.map[it.split("\\s+").join("'")].join("'")
	}
	
	/// Support functions
	
	def protected getBooleanType(Logic2AlloyLanguageMapperTrace trace) {
		if(trace.boolType!=null) {
			return trace.boolType
		} else {
			trace.boolType = createALSEnumDeclaration => [
				it.name = toID(#["util","boolean"])
				trace.boolTrue = createALSEnumLiteral =>[it.name=toID(#["util","boolean","true"])]
				it.literal += trace.boolTrue
				trace.boolFalse = createALSEnumLiteral =>[it.name=toID(#["util","boolean","false"])]
				it.literal += trace.boolFalse
			]
			trace.specification.enumDeclarations+=trace.boolType
			return trace.boolType
		}
	}
	def protected getBooleanTrue(Logic2AlloyLanguageMapperTrace trace) {
		getBooleanType(trace)
		return trace.boolTrue	
	}
	def protected getBooleanFalse(Logic2AlloyLanguageMapperTrace trace) {
		getBooleanType(trace)
		return trace.boolFalse
	}
	
	def protected booleanToLogicValue(ALSTerm boolReference, Logic2AlloyLanguageMapperTrace trace) {
		//println((boolReference as ALSReference).referred)
		createALSEquals => [
			leftOperand = EcoreUtil.copy(boolReference)
			rightOperand = createALSReference => [referred = getBooleanTrue(trace)]
		]
	}
	def protected booleanToEnumValue(ALSTerm value, Logic2AlloyLanguageMapperTrace trace) {
		if(value instanceof ALSEquals) {
			val rightOperand = value.rightOperand
			if(rightOperand instanceof ALSReference) {
				if(rightOperand.referred == getBooleanTrue(trace)) {
					return value.leftOperand
				}
			}
		}
		return value;
	}
	def protected prepareParameterOfSymbolicReference(TypeReference type, ALSTerm term, Logic2AlloyLanguageMapperTrace trace) {
		if(type instanceof BoolTypeReference) {
			return booleanToEnumValue(term,trace)
		}
		else return term
	}
	def protected postprocessResultOfSymbolicReference(TypeReference type, ALSTerm term, Logic2AlloyLanguageMapperTrace trace) {
		if(type instanceof BoolTypeReference) {
			return booleanToLogicValue(term,trace)
		}
		else return term
	}
	 
	def protected ALSTerm unfoldAnd(List<? extends ALSTerm> operands) {
		if(operands.size == 1) { return operands.head }
		else if(operands.size > 1) { return createALSAnd=>[
			leftOperand=operands.head
			rightOperand=operands.subList(1,operands.size).unfoldAnd
		]}
		else throw new UnsupportedOperationException('''Logic operator with 0 operands!''')
	}
	
	def protected ALSTerm unfoldOr(List<? extends ALSTerm> operands, Logic2AlloyLanguageMapperTrace trace) {
		if(operands.size == 0) { return unfoldTrueStatement(trace)}
		else if(operands.size == 1) { return operands.head }
		else if(operands.size > 1) { return createALSOr=>[
			leftOperand=operands.head
			rightOperand=unfoldOr(operands.subList(1,operands.size),trace)
		]}
		//else throw new UnsupportedOperationException('''Logic operator with 0 operands!''')
	}
	
	protected def unfoldTrueStatement(Logic2AlloyLanguageMapperTrace trace) {
		createALSEquals => [
				it.leftOperand = createALSReference => [it.referred = getBooleanTrue(trace)]
				it.rightOperand = createALSReference => [it.referred = getBooleanTrue(trace)]
			]
	}
	
	protected def unfoldTFalseStatement(Logic2AlloyLanguageMapper m, Logic2AlloyLanguageMapperTrace trace) {
		createALSEquals => [
				it.leftOperand = createALSReference => [it.referred = getBooleanTrue(trace)]
				it.rightOperand = createALSReference => [it.referred = getBooleanTrue(trace)]
			]
	}
	
	def protected ALSTerm unfoldPlus(List<? extends ALSTerm> operands) {
		if(operands.size == 1) { return operands.head }
		else if(operands.size > 1) { return createALSPlus=>[
			leftOperand=operands.head
			rightOperand=operands.subList(1,operands.size).unfoldPlus
		]}
		else return createALSNone
	}
	
	def protected ALSTerm unfoldIntersection(List<? extends ALSTerm> operands) {
		if(operands.size == 1) { return operands.head }
		else if(operands.size > 1) { return createALSIntersection=>[
			leftOperand=operands.head
			rightOperand=operands.subList(1,operands.size).unfoldIntersection
		]}
		else throw new UnsupportedOperationException('''Logic operator with 0 operands!''')
	}
	
	def protected ALSTerm unfoldDistinctTerms(Logic2AlloyLanguageMapper m, List<Term> operands, Logic2AlloyLanguageMapperTrace trace, Map<Variable, ALSVariableDeclaration> variables) {
		if(operands.size == 1) { return m.transformTerm(operands.head,trace,variables) }
		else if(operands.size > 1) {
			val notEquals = new ArrayList<ALSTerm>(operands.size*operands.size/2)
			for(i:0..<operands.size) {
				for(j: i+1..<operands.size) {
					notEquals+=createALSNotEquals=>[
						leftOperand = m.transformTerm(operands.get(i),trace,variables)
						rightOperand = m.transformTerm(operands.get(j),trace,variables)
					]
				}
			}
			return notEquals.unfoldAnd
		 }
		else throw new UnsupportedOperationException('''Logic operator with 0 operands!''')
	}
	
	def protected ALSTerm unfoldReferenceDirectProduct(Logic2AlloyLanguageMapper m, List<TypeReference> references,Logic2AlloyLanguageMapperTrace trace) {
		if(references.size == 1) return m.transformTypeReference(references.head,trace)
		else if(references.size > 1) return createALSDirectProduct => [
			it.leftOperand = m.transformTypeReference(references.head,trace)
			it.rightOperand = unfoldReferenceDirectProduct(m,references.subList(1,references.size),trace)
		]
		else throw new UnsupportedOperationException
	}
	
	def protected ALSTerm unfoldDotJoin(Logic2AlloyLanguageMapper m, List<Term> elements, ALSTerm target, Logic2AlloyLanguageMapperTrace trace,
		Map<Variable, ALSVariableDeclaration> variables) {
		if (elements.size == 1) {
			return createALSJoin => [
				it.leftOperand = m.transformTerm(elements.head,trace, variables)
				it.rightOperand = target
			]
		} else if (elements.size > 1) {
			return createALSJoin => [
				it.leftOperand = m.transformTerm(elements.last,trace, variables)
				it.rightOperand = m.unfoldDotJoin(elements.subList(0, elements.size - 1), target, trace, variables)
			]
		} else
			throw new UnsupportedOperationException
	}
	
	def protected ALSTerm unfoldTermDirectProduct(Logic2AlloyLanguageMapper m, List<Term> references,Logic2AlloyLanguageMapperTrace trace,Map<Variable, ALSVariableDeclaration> variables) {
		if(references.size == 1) return m.transformTerm(references.head,trace,variables)
		else if(references.size > 1) return createALSDirectProduct => [
			it.leftOperand = m.transformTerm(references.head,trace,variables)
			it.rightOperand = unfoldTermDirectProduct(m,references.subList(1,references.size),trace, variables)
		]
		else throw new UnsupportedOperationException
	}
	
	def protected createQuantifiedExpression(Logic2AlloyLanguageMapper m, QuantifiedExpression q, ALSMultiplicity multiplicity, Logic2AlloyLanguageMapperTrace trace, Map<Variable, ALSVariableDeclaration> variables) {
		val variableMap = q.quantifiedVariables.toInvertedMap[v | createALSVariableDeclaration=> [
				it.name = toID(v.name)
				it.range = m.transformTypeReference(v.range,trace) ]]
			
		createALSQuantifiedEx=>[
			it.type = multiplicity
			it.variables += variableMap.values
			it.expression = m.transformTerm(q.expression,trace,variables.withAddition(variableMap))
		]
	}
	
	def protected withAddition(Map<Variable, ALSVariableDeclaration> v1, Map<Variable, ALSVariableDeclaration> v2) { new HashMap(v1) => [putAll(v2)] }
}