aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/Alloy-Solver/hu.bme.mit.inf.dlsreasoner.alloy.reasoner/src/hu/bme/mit/inf/dlsreasoner/alloy/reasoner/builder/Logic2AlloyLanguageMapper_RelationMapper.xtend
blob: 9dd4da2fe2d9bd4f88b731c3356d2a015c5919ad (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
package hu.bme.mit.inf.dlsreasoner.alloy.reasoner.builder

import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSMultiplicity
import hu.bme.mit.inf.dslreasoner.alloyLanguage.ALSSignatureBody
import hu.bme.mit.inf.dslreasoner.alloyLanguage.AlloyLanguageFactory
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.ComplexTypeReference
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDeclaration
import hu.bme.mit.inf.dslreasoner.logic.model.logiclanguage.RelationDefinition
import java.util.HashMap

import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*

class Logic2AlloyLanguageMapper_RelationMapper {	
	private val extension AlloyLanguageFactory factory = AlloyLanguageFactory.eINSTANCE
	private val Logic2AlloyLanguageMapper_Support support = new Logic2AlloyLanguageMapper_Support;
	val Logic2AlloyLanguageMapper base;
	public new(Logic2AlloyLanguageMapper base) {
		this.base = base
	}
		
	def dispatch protected void  transformRelation(RelationDeclaration r, Logic2AlloyLanguageMapperTrace trace) {
		if(!trace.relationDefinitions.containsKey(r)) {
			if(r.transformToHostedField(trace)) {
				transformRelationDeclarationToHostedField(r,trace)
			} else {
				transformRelationDeclarationToGlobalField(r,trace)
			}
		}
	}
	
	def protected transformToHostedField(RelationDeclaration r, Logic2AlloyLanguageMapperTrace trace) {
		val first = r.parameters.get(0)
		if(r.parameters.size == 2) {
			if(first instanceof ComplexTypeReference) {
				val types = base.typeMapper.transformTypeReference(first.referred,base,trace)
				if(types.size == 1) {
					return true
				}
			}
		}
		return false
	}
	
	def protected transformRelationDeclarationToHostedField(RelationDeclaration r, Logic2AlloyLanguageMapperTrace trace) {
		val hostType = (r.parameters.head as ComplexTypeReference).referred
		
		val targetBody = base.typeMapper.transformTypeReference(hostType,base,trace).get(0).eContainer as ALSSignatureBody
		val field = createALSFieldDeclaration => [
			it.name = support.toID(r.getName)
			it.multiplicity = ALSMultiplicity.SET
			it.type = base.transformTypeReference(r.parameters.get(1),trace)
		]
		targetBody.fields += field
		trace.relationDeclaration2Field.put(r,field)
		
	}
	
	def protected transformRelationDeclarationToGlobalField(RelationDeclaration r, Logic2AlloyLanguageMapperTrace trace) {
		val field = createALSFieldDeclaration => [
			it.name = support.toID(r.name)
			it.type = support.unfoldReferenceDirectProduct(base,r.parameters,trace)
		]
		trace.logicLanguageBody.fields += field
		trace.relationDeclaration2Global.put(r, field)
	}

	def dispatch protected void transformRelation(RelationDefinition r, Logic2AlloyLanguageMapperTrace trace) {
		val res = createALSRelationDefinition => [
			name = support.toID(r.name)
			// fill the variables later
			// fill the expression later
		]
		
		trace.relationDefinition2Predicate.put(r,res)
		trace.specification.relationDefinitions+=res;
	}
	
	def protected void transformRelationDefinitionSpecification(RelationDefinition r, Logic2AlloyLanguageMapperTrace trace) {
		val predicate = r.lookup(trace.relationDefinition2Predicate)
		if(predicate !== null) {
			val variableMap = new HashMap
			for(variable : r.variables) {
				val v = createALSVariableDeclaration => [
					it.name = support.toID(variable.name)
					it.range = base.transformTypeReference(variable.range,trace)
				]
				predicate.variables+=v
				variableMap.put(variable,v)
			}
			predicate.value = base.transformTerm(r.value,trace,variableMap)
		}
	}
	
	def public transformRelationReference(RelationDeclaration relation, Logic2AlloyLanguageMapperTrace trace) {
		if(relation.transformToHostedField(trace)) {
			return createALSReference => [it.referred = relation.lookup(trace.relationDeclaration2Field) ]
		} else {
			return createALSJoin => [
				leftOperand = createALSReference => [referred = trace.logicLanguage]
				rightOperand = createALSReference => [ referred = relation.lookup(trace.relationDeclaration2Global) ]]
		}
	}
	
	def public getRelationReference(RelationDeclaration relation, Logic2AlloyLanguageMapperTrace trace) {
		if(relation.transformToHostedField(trace)) {
			return relation.lookup(trace.relationDeclaration2Field)
		} else {
			return relation.lookup(trace.relationDeclaration2Global)
		}
	}
}