aboutsummaryrefslogtreecommitdiffstats
path: root/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft
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')
-rw-r--r--Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/Cft2FtTransformation.xtend24
-rw-r--r--Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventCollection.xtend90
-rw-r--r--Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventMaterializer.xtend208
-rw-r--r--Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/FaultTreeBuilder.xtend39
4 files changed, 0 insertions, 361 deletions
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/Cft2FtTransformation.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/Cft2FtTransformation.xtend
deleted file mode 100644
index a522654c..00000000
--- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/Cft2FtTransformation.xtend
+++ /dev/null
@@ -1,24 +0,0 @@
1package hu.bme.mit.inf.dslreasoner.faulttree.transformation.cft2ft
2
3import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentFaultTree
4import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.ConstantEvent
5import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.FtFactory
6import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.RandomEvent
7
8class Cft2FtTransformation {
9 def createFaultTree(ComponentFaultTree componentFaultTree) {
10 val materializer = new EventMaterializer
11 val topEvent = materializer.getOrMaterialize(componentFaultTree.topEvent)
12 switch (topEvent) {
13 ConstantEvent:
14 FtFactory.eINSTANCE.createConstantModel => [
15 failed = topEvent.failed
16 ]
17 RandomEvent: {
18 val builder = new FaultTreeBuilder
19 builder.addTopLevel(topEvent)
20 builder.faultTree
21 }
22 }
23 }
24}
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventCollection.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventCollection.xtend
deleted file mode 100644
index 102dc57e..00000000
--- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventCollection.xtend
+++ /dev/null
@@ -1,90 +0,0 @@
1package hu.bme.mit.inf.dslreasoner.faulttree.transformation.cft2ft
2
3import com.google.common.collect.ImmutableSet
4import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.ConstantEvent
5import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.Event
6import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.RandomEvent
7import java.util.Set
8import org.eclipse.xtend.lib.annotations.Data
9
10@Data
11class EventCollection {
12 val int falseEventCount
13 val int trueEventCount
14 val Set<RandomEvent> randomEvents
15
16 def containsFalseEvent() {
17 falseEventCount >= 1
18 }
19
20 def containsTrueEvent() {
21 trueEventCount >= 1
22 }
23
24 def getVariableEventCount() {
25 randomEvents.size
26 }
27
28 def containsRandomEvent() {
29 variableEventCount >= 1
30 }
31
32 def getCount() {
33 falseEventCount + trueEventCount + variableEventCount
34 }
35
36 def isEmpty() {
37 !containsFalseEvent && !containsTrueEvent && !containsRandomEvent
38 }
39
40 def containsExactlyOneRandomEvent() {
41 !containsFalseEvent && !containsTrueEvent && variableEventCount == 1
42 }
43
44 def toSingleRandomEvent() {
45 if (!containsExactlyOneRandomEvent) {
46 throw new IllegalStateException("Input collection is not a single random event")
47 }
48 randomEvents.head
49 }
50
51 static def builder() {
52 new Builder()
53 }
54
55 static class Builder {
56 var falseEventCount = 0
57 var trueEventCount = 0
58 val randomEventsBuilder = ImmutableSet.<RandomEvent>builder
59
60 private new() {
61 }
62
63 def add(Event event) {
64 switch (event) {
65 ConstantEvent:
66 if (event.failed) {
67 trueEventCount++
68 } else {
69 falseEventCount++
70 }
71 RandomEvent:
72 randomEventsBuilder.add(event)
73 default:
74 throw new IllegalArgumentException("Unknown event: " + event)
75 }
76 this
77 }
78
79 def addAll(EventCollection materializedEvens) {
80 falseEventCount += materializedEvens.falseEventCount
81 trueEventCount += materializedEvens.trueEventCount
82 randomEventsBuilder.addAll(materializedEvens.randomEvents)
83 this
84 }
85
86 def build() {
87 new EventCollection(falseEventCount, trueEventCount, randomEventsBuilder.build)
88 }
89 }
90}
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
deleted file mode 100644
index 6b3ed0d0..00000000
--- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventMaterializer.xtend
+++ /dev/null
@@ -1,208 +0,0 @@
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
20import static extension hu.bme.mit.inf.dslreasoner.faulttree.model.util.CftExtensions.*
21
22class EventMaterializer {
23 extension val FtFactory = FtFactory.eINSTANCE
24
25 val Map<EventKey<EventDeclaration>, Event> materializationCache = newHashMap
26 val Map<EventKey<InputEvent>, EventCollection> multipleInputCache = newHashMap
27 val ConstantEvent falseEvent
28 val ConstantEvent trueEvent
29 val path = new LinkedHashSet<EventKey<? extends EventDeclaration>>
30
31 new() {
32 falseEvent = createConstantEvent => [
33 failed = false
34 ]
35 trueEvent = createConstantEvent => [
36 failed = true
37 ]
38 }
39
40 def getOrMaterialize(Output output) {
41 getOrMaterialize(output.component, output.eventDeclaration)
42 }
43
44 def Event getOrMaterialize(Component component, EventDeclaration eventDeclaration) {
45 val eventKey = new EventKey(component, eventDeclaration)
46 pushEventKey(eventKey)
47 try {
48 // computeIfAbsent cannot be used recursively, so we must manually cache the event.
49 var event = materializationCache.get(eventKey)
50 if (event === null) {
51 event = materialize(component, eventDeclaration)
52 materializationCache.put(eventKey, event)
53 }
54 event
55 } finally {
56 popEventKey(eventKey)
57 }
58 }
59
60 protected def materialize(Component component, EventDeclaration eventDeclaration) {
61 val eventName = component.name + "_" + eventDeclaration.name
62 val event = switch (eventDeclaration) {
63 InputEvent:
64 return materializeConnectedEvent(component, eventDeclaration)
65 BasicEventDefinition: {
66 val basicEvent = createBasicEvent
67 basicEvent.distribution = EcoreUtil.copy(eventDeclaration.distribution)
68 basicEvent
69 }
70 GateDefinition: {
71 val inputs = collectInputs(component, eventDeclaration)
72 val gate = switch (eventDeclaration) {
73 AndGateDefinition:
74 if (inputs.containsFalseEvent) {
75 return falseEvent
76 } else if (inputs.empty) {
77 return trueEvent
78 } else if (inputs.containsExactlyOneRandomEvent) {
79 return inputs.toSingleRandomEvent
80 } else {
81 createAndGate
82 }
83 OrGateDefinition:
84 if (inputs.containsTrueEvent) {
85 return trueEvent
86 } else if (inputs.empty) {
87 return falseEvent
88 } else if (inputs.containsExactlyOneRandomEvent) {
89 return inputs.toSingleRandomEvent
90 } else {
91 createOrGate
92 }
93 KOfMGateDefinition: {
94 val requiredTrueInputs = inputs.count * eventDeclaration.k / eventDeclaration.m
95 val k = requiredTrueInputs - inputs.getTrueEventCount
96 val m = inputs.variableEventCount
97 if (k == 0) {
98 return trueEvent
99 } else if (k > m) {
100 return falseEvent
101 } else if (inputs.containsExactlyOneRandomEvent) {
102 return inputs.toSingleRandomEvent
103 } else if (k == 1) {
104 createOrGate
105 } else if (k == m) {
106 createAndGate
107 } else {
108 val kOfMGate = createKOfMGate
109 kOfMGate.k = k
110 kOfMGate
111 }
112 }
113 default:
114 throw new IllegalArgumentException("Unknown gate definition: " + eventDeclaration)
115 }
116 gate.inputEvents.addAll(inputs.getRandomEvents)
117 gate
118 }
119 default:
120 throw new IllegalArgumentException("Unknown event declaration: " + eventDeclaration)
121 }
122 event.name = eventName
123 event
124 }
125
126 protected def materializeConnectedEvent(Component component, InputEvent inputEvent) {
127 if (inputEvent.multiple) {
128 throw new IllegalArgumentException('''Cannot materialize multiple nput «component.name»_«inputEvent.name»''')
129 }
130 val input = findInput(component, inputEvent)
131 val incomingConnections = input.incomingConnections
132 if (incomingConnections.size != 1) {
133 throw new IllegalArgumentException('''Input «component.name»_«inputEvent.name» has «incomingConnections.size» connections instead of 1''')
134 }
135 val output = incomingConnections.head.output
136 getOrMaterialize(output.component, output.eventDeclaration)
137 }
138
139 protected def collectInputs(Component component, GateDefinition gateDefinition) {
140 val builder = EventCollection.builder
141 for (inputEventDeclaration : gateDefinition.inputEvents) {
142 switch (inputEventDeclaration) {
143 InputEvent case inputEventDeclaration.multiple: {
144 val materializedEvents = getOrMaterializeConnectedEvents(component, inputEventDeclaration)
145 builder.addAll(materializedEvents)
146 }
147 default:
148 builder.add(getOrMaterialize(component, inputEventDeclaration))
149 }
150 }
151 builder.build
152 }
153
154 protected def getOrMaterializeConnectedEvents(Component component, InputEvent inputEvent) {
155 val inputKey = new EventKey(component, inputEvent)
156 pushEventKey(inputKey)
157 try {
158 // computeIfAbsent cannot be used recursively, so we must manually cache the event.
159 var eventCollection = multipleInputCache.get(inputKey)
160 if (eventCollection === null) {
161 eventCollection = materializeConnectedEvents(component, inputEvent)
162 multipleInputCache.put(inputKey, eventCollection)
163 }
164 eventCollection
165 } finally {
166 popEventKey(inputKey)
167 }
168 }
169
170 protected def materializeConnectedEvents(Component component, InputEvent inputEvent) {
171 val input = findInput(component, inputEvent)
172 val builder = EventCollection.builder
173 for (connection : input.incomingConnections) {
174 if (connection.isCurrentlyConnected) {
175 val materializedEvent = getOrMaterialize(connection.output)
176 builder.add(materializedEvent)
177 }
178 }
179 builder.build
180 }
181
182 protected def findInput(Component component, InputEvent inputEvent) {
183 val input = component.inputs.findFirst[it.inputEvent == inputEvent]
184 if (input === null) {
185 throw new IllegalArgumentException('''No input «inputEvent» in component «component»''')
186 }
187 return input
188 }
189
190 private def pushEventKey(EventKey<? extends EventDeclaration> eventKey) {
191 if (!path.add(eventKey)) {
192 throw new IllegalStateException(
193 '''Circular dependency [«FOR ancestor : path»«ancestor», «ENDFOR»«eventKey»] detected''')
194 }
195 }
196
197 private def popEventKey(EventKey<? extends EventDeclaration> eventKey) {
198 path.remove(eventKey)
199 }
200
201 @Data
202 protected static class EventKey<T extends EventDeclaration> {
203 val Component component
204 val T event
205
206 override toString() '''«component.name»_«event.name»'''
207 }
208}
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/FaultTreeBuilder.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/FaultTreeBuilder.xtend
deleted file mode 100644
index 0b0afea6..00000000
--- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/FaultTreeBuilder.xtend
+++ /dev/null
@@ -1,39 +0,0 @@
1package hu.bme.mit.inf.dslreasoner.faulttree.transformation.cft2ft
2
3import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.FtFactory
4import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.Gate
5import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.RandomEvent
6import java.util.Collection
7import org.eclipse.xtend.lib.annotations.Accessors
8
9class FaultTreeBuilder {
10 @Accessors
11 val faultTree = FtFactory.eINSTANCE.createFaultTree
12
13 def addTopLevel(RandomEvent event) {
14 if (faultTree.topEvent !== null) {
15 throw new IllegalStateException("Top event was already set")
16 }
17 add(event)
18 faultTree.topEvent = event
19 }
20
21 protected def void add(RandomEvent event) {
22 if (faultTree.eContainer == faultTree) {
23 return
24 }
25 if (faultTree.eContainer !== null) {
26 throw new IllegalStateException("Event is already in a different fault tree")
27 }
28 faultTree.events += event
29 if (event instanceof Gate) {
30 addAll(event.inputEvents)
31 }
32 }
33
34 protected def addAll(Collection<RandomEvent> events) {
35 for (event : events) {
36 add(event)
37 }
38 }
39}