diff options
Diffstat (limited to 'Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/cft2ft')
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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.cft2ft | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentFaultTree | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.ConstantEvent | ||
5 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.FtFactory | ||
6 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.RandomEvent | ||
7 | |||
8 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.cft2ft | ||
2 | |||
3 | import com.google.common.collect.ImmutableSet | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.ConstantEvent | ||
5 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.Event | ||
6 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.RandomEvent | ||
7 | import java.util.Set | ||
8 | import org.eclipse.xtend.lib.annotations.Data | ||
9 | |||
10 | @Data | ||
11 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.cft2ft | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.AndGateDefinition | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.BasicEventDefinition | ||
5 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Component | ||
6 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.EventDeclaration | ||
7 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.GateDefinition | ||
8 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.InputEvent | ||
9 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.KOfMGateDefinition | ||
10 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.OrGateDefinition | ||
11 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Output | ||
12 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.ConstantEvent | ||
13 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.Event | ||
14 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.FtFactory | ||
15 | import java.util.LinkedHashSet | ||
16 | import java.util.Map | ||
17 | import org.eclipse.emf.ecore.util.EcoreUtil | ||
18 | import org.eclipse.xtend.lib.annotations.Data | ||
19 | |||
20 | import static extension hu.bme.mit.inf.dslreasoner.faulttree.model.util.CftExtensions.* | ||
21 | |||
22 | class 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 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.cft2ft | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.FtFactory | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.Gate | ||
5 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.RandomEvent | ||
6 | import java.util.Collection | ||
7 | import org.eclipse.xtend.lib.annotations.Accessors | ||
8 | |||
9 | class 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 | } | ||