aboutsummaryrefslogtreecommitdiffstats
path: root/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventMaterializer.xtend
diff options
context:
space:
mode:
Diffstat (limited to 'Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventMaterializer.xtend')
-rw-r--r--Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventMaterializer.xtend192
1 files changed, 192 insertions, 0 deletions
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventMaterializer.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventMaterializer.xtend
new file mode 100644
index 00000000..85396e4d
--- /dev/null
+++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventMaterializer.xtend
@@ -0,0 +1,192 @@
1package hu.bme.mit.inf.dslreasoner.faulttree.transformation.cft2ft
2
3import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.AndGateDefinition
4import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.BasicEventDefinition
5import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Component
6import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.EventDeclaration
7import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.GateDefinition
8import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.InputEvent
9import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.KOfMGateDefinition
10import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.OrGateDefinition
11import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Output
12import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.ConstantEvent
13import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.Event
14import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.FtFactory
15import java.util.LinkedHashSet
16import java.util.Map
17import org.eclipse.emf.ecore.util.EcoreUtil
18import org.eclipse.xtend.lib.annotations.Data
19
20class EventMaterializer {
21 extension val FtFactory = FtFactory.eINSTANCE
22
23 val Map<EventKey<EventDeclaration>, Event> materializationCache = newHashMap
24 val Map<EventKey<InputEvent>, EventCollection> multipleInputCache = newHashMap
25 val ConstantEvent falseEvent
26 val ConstantEvent trueEvent
27 val path = new LinkedHashSet<EventKey<? extends EventDeclaration>>
28
29 new() {
30 falseEvent = createConstantEvent => [
31 failed = false
32 ]
33 trueEvent = createConstantEvent => [
34 failed = true
35 ]
36 }
37
38 def getOrMaterialize(Output output) {
39 getOrMaterialize(output.component, output.eventDeclaration)
40 }
41
42 def Event getOrMaterialize(Component component, EventDeclaration eventDeclaration) {
43 val eventKey = new EventKey(component, eventDeclaration)
44 pushEventKey(eventKey)
45 try {
46 materializationCache.computeIfAbsent(eventKey)[materialize(it.component, it.event)]
47 } finally {
48 popEventKey(eventKey)
49 }
50 }
51
52 protected def materialize(Component component, EventDeclaration eventDeclaration) {
53 val eventName = component.name + "_" + eventDeclaration.name
54 val event = switch (eventDeclaration) {
55 InputEvent:
56 return materializeConnectedEvent(component, eventDeclaration)
57 BasicEventDefinition: {
58 val basicEvent = createBasicEvent
59 basicEvent.distribution = EcoreUtil.copy(eventDeclaration.distribution)
60 basicEvent
61 }
62 GateDefinition: {
63 val inputs = collectInputs(component, eventDeclaration)
64 val gate = switch (eventDeclaration) {
65 AndGateDefinition:
66 if (inputs.containsFalseEvent) {
67 return falseEvent
68 } else if (inputs.empty) {
69 return trueEvent
70 } else if (inputs.containsExactlyOneRandomEvent) {
71 return inputs.toSingleRandomEvent
72 } else {
73 createAndGate
74 }
75 OrGateDefinition:
76 if (inputs.containsTrueEvent) {
77 return trueEvent
78 } else if (inputs.empty) {
79 return falseEvent
80 } else if (inputs.containsExactlyOneRandomEvent) {
81 return inputs.toSingleRandomEvent
82 } else {
83 createOrGate
84 }
85 KOfMGateDefinition: {
86 val requiredTrueInputs = inputs.count * eventDeclaration.k / eventDeclaration.m
87 val k = requiredTrueInputs - inputs.getTrueEventCount
88 val m = inputs.variableEventCount
89 if (k == 0) {
90 return trueEvent
91 } else if (k > m) {
92 return falseEvent
93 } else if (inputs.containsExactlyOneRandomEvent) {
94 return inputs.toSingleRandomEvent
95 } else if (k == 1) {
96 createOrGate
97 } else if (k == m) {
98 createAndGate
99 } else {
100 val kOfMGate = createKOfMGate
101 kOfMGate.k = k
102 kOfMGate
103 }
104 }
105 default:
106 throw new IllegalArgumentException("Unknown gate definition: " + eventDeclaration)
107 }
108 gate.inputEvents.addAll(inputs.getRandomEvents)
109 gate
110 }
111 default:
112 throw new IllegalArgumentException("Unknown event declaration: " + eventDeclaration)
113 }
114 event.name = eventName
115 event
116 }
117
118 protected def materializeConnectedEvent(Component component, InputEvent inputEvent) {
119 if (inputEvent.multiple) {
120 throw new IllegalArgumentException('''Cannot materialize multiple nput «component.name»_«inputEvent.name»''')
121 }
122 val input = findInput(component, inputEvent)
123 val incomingConnections = input.incomingConnections
124 if (incomingConnections.size != 1) {
125 throw new IllegalArgumentException('''Input «component.name»_«inputEvent.name» has «incomingConnections.size» connections instead of 1''')
126 }
127 val output = incomingConnections.head.output
128 getOrMaterialize(output.component, output.eventDeclaration)
129 }
130
131 protected def collectInputs(Component component, GateDefinition gateDefinition) {
132 val builder = EventCollection.builder
133 for (inputEventDeclaration : gateDefinition.inputEvents) {
134 switch (inputEventDeclaration) {
135 InputEvent case inputEventDeclaration.multiple: {
136 val materializedEvents = getOrMaterializeConnectedEvents(component, inputEventDeclaration)
137 builder.addAll(materializedEvents)
138 }
139 default:
140 builder.add(getOrMaterialize(component, inputEventDeclaration))
141 }
142 }
143 builder.build
144 }
145
146 protected def getOrMaterializeConnectedEvents(Component component, InputEvent inputEvent) {
147 val inputKey = new EventKey(component, inputEvent)
148 pushEventKey(inputKey)
149 try {
150 multipleInputCache.computeIfAbsent(inputKey)[materializeConnectedEvents(it.component, it.event)]
151 } finally {
152 popEventKey(inputKey)
153 }
154 }
155
156 protected def materializeConnectedEvents(Component component, InputEvent inputEvent) {
157 val input = findInput(component, inputEvent)
158 val builder = EventCollection.builder
159 for (connection : input.incomingConnections) {
160 val materializedEvent = getOrMaterialize(connection.output)
161 builder.add(materializedEvent)
162 }
163 builder.build
164 }
165
166 protected def findInput(Component component, InputEvent inputEvent) {
167 val input = component.inputs.findFirst[it.inputEvent == inputEvent]
168 if (input === null) {
169 throw new IllegalArgumentException('''No input «inputEvent» in component «component»''')
170 }
171 return input
172 }
173
174 private def pushEventKey(EventKey<? extends EventDeclaration> eventKey) {
175 if (!path.add(eventKey)) {
176 throw new IllegalStateException(
177 '''Circular dependency [«FOR ancestor : path»«ancestor», «ENDFOR»«eventKey»] detected''')
178 }
179 }
180
181 private def popEventKey(EventKey<? extends EventDeclaration> eventKey) {
182 path.remove(eventKey)
183 }
184
185 @Data
186 protected static class EventKey<T extends EventDeclaration> {
187 val Component component
188 val T event
189
190 override toString() '''«component.name»_«event.name»'''
191 }
192}