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.xtend20
-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.xtend192
-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, 338 insertions, 3 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
index caaffc3c..a522654c 100644
--- 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
@@ -1,10 +1,24 @@
1package hu.bme.mit.inf.dslreasoner.faulttree.transformation.cft2ft 1package hu.bme.mit.inf.dslreasoner.faulttree.transformation.cft2ft
2 2
3import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentFaultTree 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
4 7
5class Cft2FtTransformation { 8class Cft2FtTransformation {
6 def createFaultTree(ComponentFaultTree componentFaultTree) { 9 def createFaultTree(ComponentFaultTree componentFaultTree) {
7 // TODO 10 val materializer = new EventMaterializer
8 throw new UnsupportedOperationException() 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 }
9 } 23 }
10} \ No newline at end of file 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
new file mode 100644
index 00000000..102dc57e
--- /dev/null
+++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/EventCollection.xtend
@@ -0,0 +1,90 @@
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
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}
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
new file mode 100644
index 00000000..0b0afea6
--- /dev/null
+++ b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft/FaultTreeBuilder.xtend
@@ -0,0 +1,39 @@
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}