aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage/src/hu/bme/mit/inf/dslreasoner/viatrasolver/partialinterpretationlanguage/statecoder/AbstractNeighborhoodBasedStateCoderFactory.xtend
blob: 089880b10d1be0971a71ed4566acd338ae0ada33 (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
package hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder

import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodOptions
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialComplexTypeInterpretation
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialPrimitiveInterpretation
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialRelationInterpretation
import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialinterpretationPackage
import java.util.LinkedList
import java.util.List
import org.eclipse.emf.common.notify.Notifier
import org.eclipse.emf.ecore.EClass
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EStructuralFeature
import org.eclipse.viatra.dse.statecode.IStateCoder
import org.eclipse.viatra.dse.statecode.IStateCoderFactory
import org.eclipse.viatra.query.runtime.api.IPatternMatch
import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine
import org.eclipse.viatra.query.runtime.base.api.FeatureListener
import org.eclipse.viatra.query.runtime.base.api.IndexingLevel
import org.eclipse.viatra.query.runtime.base.api.InstanceListener
import org.eclipse.viatra.query.runtime.emf.EMFBaseIndexWrapper
import org.eclipse.viatra.query.runtime.emf.EMFScope
import org.eclipse.xtend.lib.annotations.Accessors

abstract class AbstractNeighbourhoodBasedStateCoderFactory implements IStateCoderFactory {
	val List<AbstractNeighbourhoodBasedPartialInterpretationStateCoder> statecoders = new LinkedList

	val NeighbourhoodOptions options

	protected new() {
		this(NeighbourhoodOptions.DEFAULT)
	}

	protected new(NeighbourhoodOptions options) {
		this.options = options
	}

	synchronized override createStateCoder() {
		val res = doCreateStateCoder(options)
		statecoders += res
		return res
	}

	protected def AbstractNeighbourhoodBasedPartialInterpretationStateCoder doCreateStateCoder(
		NeighbourhoodOptions options)

	def getSumStatecoderRuntime() {
		statecoders.map[statecoderRuntime].reduce[p1, p2|p1 + p2]
	}
}

abstract class AbstractNeighbourhoodBasedPartialInterpretationStateCoder implements IStateCoder {
	val NeighbourhoodOptions options

	var PartialInterpretation target

	protected new(NeighbourhoodOptions options) {
		this.options = options
	}

	@Accessors(PUBLIC_GETTER) var long statecoderRuntime = 0

	synchronized private def refreshStateCodes() {
		if (refreshNeeded) {
			val startTime = System.nanoTime
			doRefreshStateCodes(target, options)
			statecoderRuntime += (System.nanoTime - startTime)
		}
	}

	protected def boolean isRefreshNeeded()

	protected def void doRefreshStateCodes(PartialInterpretation target, NeighbourhoodOptions options)

	synchronized override createActivationCode(IPatternMatch match) {
		refreshStateCodes
		val startTime = System.nanoTime
		val code = doCreateActivationCode(match)
		statecoderRuntime += (System.nanoTime - startTime)
		code
	}

	protected def Object doCreateActivationCode(IPatternMatch match)

	synchronized override createStateCode() {
		refreshStateCodes
		doCreateStateCode
	}

	protected def Object doCreateStateCode()

	override init(Notifier notifier) {
		this.target = notifier as PartialInterpretation
		val queryEngine = ViatraQueryEngine.on(new EMFScope(notifier))
		val baseIndex = queryEngine.getBaseIndex() as EMFBaseIndexWrapper
		val navigationHelper = baseIndex.getNavigationHelper();

		val classes = PartialinterpretationPackage.eINSTANCE.EClassifiers.filter(EClass).toSet
		val features = classes.map[it.EAllStructuralFeatures].flatten.toSet
		navigationHelper.registerObservedTypes(classes, null, features, IndexingLevel.FULL);

		navigationHelper.addFeatureListener(features, new FeatureListener() {
			override void featureInserted(EObject host, EStructuralFeature feature, Object value) { invalidate }

			override void featureDeleted(EObject host, EStructuralFeature feature, Object value) { invalidate }
		})
		navigationHelper.addInstanceListener(classes, new InstanceListener() {
			override void instanceInserted(EClass clazz, EObject instance) { invalidate }

			override void instanceDeleted(EClass clazz, EObject instance) { invalidate }
		})
	}

	synchronized def invalidate() {
		doInvalidate
	}

	protected def void doInvalidate()

	def protected getFallbackCode(Object o) {
		switch (o) {
			PartialInterpretation,
			LogicProblem:
				null
			PartialRelationInterpretation:
				o.interpretationOf.name
			PartialPrimitiveInterpretation:
				o.class.simpleName.hashCode
			PartialComplexTypeInterpretation:
				o.interpretationOf.name.hashCode
			default:
				throw new UnsupportedOperationException('''Unsupported type: «o.class.simpleName»''')
		}
	}
}