aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra/src/hu/bme/mit/inf/dslreasoner/viatrasolver/logic2viatra/cardinality/TypeHierarchyScopePropagator.xtend
blob: d1704b39ae2cae09c71207a0efc6d1548cbc78f9 (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
package hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality

import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationStatistics
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.Scope

class TypeHierarchyScopePropagator extends ScopePropagator {

	new(PartialInterpretation p, ModelGenerationStatistics statistics) {
		super(p, statistics)
	}

	protected override doPropagateAllScopeConstraints() {
		var boolean hadChanged
		do {
			hadChanged = false
			for (superScopeEntry : superScopes.entrySet) {
				val sub = superScopeEntry.key
				hadChanged = propagateLowerLimitUp(sub, partialInterpretation) || hadChanged
				hadChanged = propagateUpperLimitDown(sub, partialInterpretation) || hadChanged
				for (sup : superScopeEntry.value) {
					hadChanged = propagateLowerLimitUp(sub, sup) || hadChanged
					hadChanged = propagateUpperLimitDown(sub, sup) || hadChanged
				}
			}
		} while (hadChanged)
	}

	private def propagateLowerLimitUp(Scope subScope, Scope superScope) {
		var changed = false
		if (subScope.minNewElements > superScope.minNewElements) {
			superScope.minNewElements = subScope.minNewElements
			changed = true
		}
		if (subScope.minNewElementsHeuristic > superScope.minNewElementsHeuristic) {
			superScope.minNewElementsHeuristic = subScope.minNewElementsHeuristic
			changed = true
		}
		changed
	}

	private def propagateUpperLimitDown(Scope subScope, Scope superScope) {
		if (superScope.maxNewElements >= 0 &&
			(superScope.maxNewElements < subScope.maxNewElements || subScope.maxNewElements < 0)) {
//			println('''
//			«(subScope.targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf.name» -> «(superScope.targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf.name»
//			subScope.maxNewElements «subScope.maxNewElements» = superScope.maxNewElements «superScope.maxNewElements»
//			''')
			subScope.maxNewElements = superScope.maxNewElements
			return true
		} else {
			return false
		}
	}

	private def propagateLowerLimitUp(Scope subScope, PartialInterpretation p) {
		var changed = false
		if (subScope.minNewElements > p.minNewElements) {
//			println('''
//			«(subScope.targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf.name» -> nodes
//			p.minNewElements «p.minNewElements» = subScope.minNewElements «subScope.minNewElements»
//			''')
			p.minNewElements = subScope.minNewElements
			changed = true
		}
		if (subScope.minNewElementsHeuristic > p.minNewElementsHeuristic) {
			p.minNewElementsHeuristic = subScope.minNewElementsHeuristic
			changed = true
		}
		changed
	}

	private def propagateUpperLimitDown(Scope subScope, PartialInterpretation p) {
		if (p.maxNewElements >= 0 && (p.maxNewElements < subScope.maxNewElements || subScope.maxNewElements < 0)) {
//			println('''
//			«(subScope.targetTypeInterpretation as PartialComplexTypeInterpretation).interpretationOf.name» -> nodes
//			subScope.maxNewElements «subScope.maxNewElements» = p.maxNewElements «p.maxNewElements»
//			''')
			subScope.maxNewElements = p.maxNewElements
			return true
		} else {
			return false
		}
	}
}