diff options
Diffstat (limited to 'Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu')
17 files changed, 0 insertions, 1108 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 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentFaultTreeTrace.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentFaultTreeTrace.xtend deleted file mode 100644 index 10c91fb4..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentFaultTreeTrace.xtend +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.CftFactory | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentDefinition | ||
5 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Modality | ||
6 | import java.util.Map | ||
7 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
8 | import org.eclipse.xtend.lib.annotations.Accessors | ||
9 | |||
10 | class ComponentFaultTreeTrace { | ||
11 | @Accessors val componentFaultTree = CftFactory.eINSTANCE.createComponentFaultTree | ||
12 | |||
13 | val nameGenerator = new ComponentNameGenerator | ||
14 | val Map<IPatternMatch, ComponentInstanceTrace> componentInstancesMap = newHashMap | ||
15 | |||
16 | def instantiateComponent(IPatternMatch patternMatch, ComponentDefinition componenDefinition) { | ||
17 | instantiateComponent(patternMatch, componenDefinition, Modality.MUST, false) | ||
18 | } | ||
19 | |||
20 | def instantiateComponent(IPatternMatch patternMatch, ComponentDefinition componenDefinition, Modality exists, | ||
21 | boolean allowMultiple) { | ||
22 | if (componentInstancesMap.containsKey(patternMatch)) { | ||
23 | throw new IllegalArgumentException("Already instantiated component for match: " + patternMatch) | ||
24 | } | ||
25 | val componentTrace = new ComponentInstanceTrace(componentFaultTree, componenDefinition, nameGenerator, | ||
26 | exists, allowMultiple) | ||
27 | componentInstancesMap.put(patternMatch, componentTrace) | ||
28 | componentTrace | ||
29 | } | ||
30 | |||
31 | def setTopLevel(ComponentInstanceTrace trace) { | ||
32 | if (componentFaultTree.topEvent !== null) { | ||
33 | throw new IllegalArgumentException("Top level component already set") | ||
34 | } | ||
35 | val outputs = trace.outputs | ||
36 | if (outputs.size !== 1) { | ||
37 | throw new IllegalArgumentException("Top level component must have 1 output, got " + outputs.size + | ||
38 | " instead") | ||
39 | } | ||
40 | if (!trace.appearsExactlyOnce) { | ||
41 | throw new IllegalArgumentException("Top level must appear in the fault tree exactly once") | ||
42 | } | ||
43 | componentFaultTree.topEvent = outputs.head | ||
44 | } | ||
45 | |||
46 | def lookup(IPatternMatch patternMatch) { | ||
47 | componentInstancesMap.get(patternMatch) | ||
48 | } | ||
49 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentInstanceTrace.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentInstanceTrace.xtend deleted file mode 100644 index 158ab2e1..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentInstanceTrace.xtend +++ /dev/null | |||
@@ -1,65 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft | ||
2 | |||
3 | import com.google.common.collect.Maps | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.CftFactory | ||
5 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentDefinition | ||
6 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentFaultTree | ||
7 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.EventDeclaration | ||
8 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.InputEvent | ||
9 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Modality | ||
10 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Output | ||
11 | import java.util.Map | ||
12 | |||
13 | import static extension hu.bme.mit.inf.dslreasoner.faulttree.model.util.CftExtensions.* | ||
14 | |||
15 | class ComponentInstanceTrace { | ||
16 | val componentInstance = CftFactory.eINSTANCE.createComponent | ||
17 | val Map<InputEvent, InputTrace> inputEventsMap | ||
18 | val Map<EventDeclaration, Output> outputEventsMap | ||
19 | |||
20 | protected new(ComponentFaultTree faultTree, ComponentDefinition componentDefinition, | ||
21 | ComponentNameGenerator nameGenerator, Modality exists, boolean multipleAllowed) { | ||
22 | componentInstance.componentDefinition = componentDefinition | ||
23 | componentInstance.name = nameGenerator.nextName(componentDefinition) | ||
24 | componentInstance.exists = exists | ||
25 | componentInstance.multipleAllowed = multipleAllowed | ||
26 | inputEventsMap = Maps.newHashMapWithExpectedSize(componentDefinition.inputEvents.size) | ||
27 | for (inputEvent : componentDefinition.inputEvents) { | ||
28 | val inputTrace = new InputTrace(componentInstance, inputEvent) | ||
29 | inputEventsMap.put(inputEvent, inputTrace) | ||
30 | } | ||
31 | outputEventsMap = Maps.newHashMapWithExpectedSize(componentDefinition.outputEvents.size) | ||
32 | for (outputEvent : componentDefinition.outputEvents) { | ||
33 | val output = CftFactory.eINSTANCE.createOutput | ||
34 | output.eventDeclaration = outputEvent | ||
35 | componentInstance.outputs += output | ||
36 | outputEventsMap.put(outputEvent, output) | ||
37 | } | ||
38 | faultTree.components += componentInstance | ||
39 | } | ||
40 | |||
41 | def void assign(EventDeclaration inputEvent, ComponentInstanceTrace sourceComponent, EventDeclaration outputEvent) { | ||
42 | assign(inputEvent, sourceComponent, outputEvent, Modality.MUST) | ||
43 | } | ||
44 | |||
45 | def void assign(EventDeclaration inputEvent, ComponentInstanceTrace sourceComponent, EventDeclaration outputEvent, | ||
46 | Modality exists) { | ||
47 | val inputTrace = inputEventsMap.get(inputEvent) | ||
48 | if (inputTrace === null) { | ||
49 | throw new IllegalArgumentException("Unknown input: " + inputEvent) | ||
50 | } | ||
51 | val output = sourceComponent.outputEventsMap.get(outputEvent) | ||
52 | if (output === null) { | ||
53 | throw new IllegalArgumentException("Unknown output: " + outputEvent) | ||
54 | } | ||
55 | inputTrace.assign(output, exists) | ||
56 | } | ||
57 | |||
58 | protected def getOutputs() { | ||
59 | componentInstance.outputs | ||
60 | } | ||
61 | |||
62 | protected def appearsExactlyOnce() { | ||
63 | componentInstance.appearsExactlyOnce | ||
64 | } | ||
65 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentNameGenerator.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentNameGenerator.xtend deleted file mode 100644 index 71d40a9b..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/ComponentNameGenerator.xtend +++ /dev/null | |||
@@ -1,16 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.ComponentDefinition | ||
4 | import java.util.Map | ||
5 | |||
6 | class ComponentNameGenerator { | ||
7 | static val DEFAULT_NAME = "__unnamed" | ||
8 | |||
9 | val Map<ComponentDefinition, Integer> instanceCounts = newHashMap | ||
10 | |||
11 | def nextName(ComponentDefinition componentDefinition) { | ||
12 | val instanceCount = instanceCounts.getOrDefault(componentDefinition, 0) | ||
13 | instanceCounts.put(componentDefinition, instanceCount + 1) | ||
14 | (componentDefinition.name ?: DEFAULT_NAME) + instanceCount | ||
15 | } | ||
16 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/Ecore2CftTransformation.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/Ecore2CftTransformation.xtend deleted file mode 100644 index 062de3df..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/Ecore2CftTransformation.xtend +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.TransformationDefinition | ||
5 | import java.util.List | ||
6 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine | ||
7 | |||
8 | class Ecore2CftTransformation { | ||
9 | val List<MappingHandler> mappingHandlers | ||
10 | |||
11 | new(TransformationDefinition transformationDefinition, ViatraQueryEngine viatraQueryEngine) { | ||
12 | val mappingQueries = new MappingQueries(transformationDefinition, viatraQueryEngine) | ||
13 | mappingHandlers = ImmutableList.copyOf(transformationDefinition.mappingDefinitions.map [ mappingDefinition | | ||
14 | new MappingHandler(mappingDefinition, mappingQueries) | ||
15 | ]) | ||
16 | } | ||
17 | |||
18 | def createComponentFaultTree() { | ||
19 | val trace = new ComponentFaultTreeTrace | ||
20 | for (handler : mappingHandlers) { | ||
21 | handler.instantiateComponents(trace) | ||
22 | } | ||
23 | for (handler : mappingHandlers) { | ||
24 | handler.instantiateConnections(trace) | ||
25 | } | ||
26 | trace.componentFaultTree | ||
27 | } | ||
28 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/InputTrace.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/InputTrace.xtend deleted file mode 100644 index b892eff1..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/InputTrace.xtend +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.CftFactory | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Component | ||
5 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Connection | ||
6 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Input | ||
7 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.InputEvent | ||
8 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Modality | ||
9 | import hu.bme.mit.inf.dslreasoner.faulttree.model.cft.Output | ||
10 | import java.util.Map | ||
11 | |||
12 | import static extension hu.bme.mit.inf.dslreasoner.faulttree.model.util.CftExtensions.* | ||
13 | |||
14 | class InputTrace { | ||
15 | val Input input = CftFactory.eINSTANCE.createInput | ||
16 | val Map<Output, Connection> connectionsMap = newHashMap | ||
17 | |||
18 | protected new(Component component, InputEvent inputEvent) { | ||
19 | input.inputEvent = inputEvent | ||
20 | component.inputs += input | ||
21 | } | ||
22 | |||
23 | def void assign(Output output, Modality exists) { | ||
24 | val connection = connectionsMap.get(output) | ||
25 | if (connection === null) { | ||
26 | val newConnection = CftFactory.eINSTANCE.createConnection | ||
27 | newConnection.output = output | ||
28 | newConnection.exists = exists | ||
29 | input.incomingConnections += newConnection | ||
30 | connectionsMap.put(output, newConnection) | ||
31 | } else if (exists.isMoreConcreteThan(connection.exists)) { | ||
32 | connection.exists = exists | ||
33 | } | ||
34 | } | ||
35 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/LookupHandler.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/LookupHandler.xtend deleted file mode 100644 index 3a06dcc3..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/LookupHandler.xtend +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.LookupDefinition | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.MappingDefinition | ||
5 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
6 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
7 | |||
8 | class LookupHandler { | ||
9 | val int[] argumentIndices | ||
10 | val ViatraQueryMatcher<? extends IPatternMatch> lookedUpMatcher | ||
11 | |||
12 | new(MappingDefinition mappingDefinition, LookupDefinition lookupDefinition, | ||
13 | ViatraQueryMatcher<? extends IPatternMatch> lookedUpMatcher) { | ||
14 | if (lookupDefinition.eContainer != mappingDefinition) { | ||
15 | throw new IllegalArgumentException("lookupDefinition must be contained in mappingDefinition") | ||
16 | } | ||
17 | val argumentCount = lookupDefinition.arguments.size | ||
18 | if (argumentCount != lookedUpMatcher.parameterNames.length) { | ||
19 | throw new IllegalArgumentException( | ||
20 | "lookupDefinition (name: " + lookupDefinition.mapping?.pattern?.name + | ||
21 | ") must have as many arguments as lookedUpMatcher (name: " + lookedUpMatcher.patternName + ")") | ||
22 | } | ||
23 | argumentIndices = newIntArrayOfSize(argumentCount) | ||
24 | for (var int i = 0; i < argumentCount; i++) { | ||
25 | val argument = lookupDefinition.arguments.get(i) | ||
26 | val argumentIndex = mappingDefinition.parameters.indexOf(argument) | ||
27 | argumentIndices.set(i, argumentIndex) | ||
28 | } | ||
29 | this.lookedUpMatcher = lookedUpMatcher | ||
30 | } | ||
31 | |||
32 | def lookupForMatch(ComponentFaultTreeTrace faultTreeTrace, IPatternMatch match) { | ||
33 | val lookedUpMatch = createLookedUpMatch(match) | ||
34 | faultTreeTrace.lookup(lookedUpMatch) | ||
35 | } | ||
36 | |||
37 | private def createLookedUpMatch(IPatternMatch match) { | ||
38 | val lookedUpMatch = lookedUpMatcher.newEmptyMatch | ||
39 | val argumentCount = argumentIndices.length | ||
40 | for (var int i = 0; i < argumentCount; i++) { | ||
41 | val argumentIndex = argumentIndices.get(i) | ||
42 | var argumentValue = match.get(argumentIndex) | ||
43 | lookedUpMatch.set(i, argumentValue) | ||
44 | } | ||
45 | lookedUpMatch | ||
46 | } | ||
47 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingHandler.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingHandler.xtend deleted file mode 100644 index 643af5c4..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingHandler.xtend +++ /dev/null | |||
@@ -1,91 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft | ||
2 | |||
3 | import com.google.common.collect.ImmutableMap | ||
4 | import com.google.common.collect.Maps | ||
5 | import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.LookupDefinition | ||
6 | import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.MappingDefinition | ||
7 | import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.Variable | ||
8 | import java.util.Map | ||
9 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
10 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
11 | |||
12 | class MappingHandler { | ||
13 | val ViatraQueryMatcher<? extends IPatternMatch> matcher | ||
14 | val MappingDefinition mappingDefinition | ||
15 | val Map<LookupDefinition, LookupHandler> lookupHandlers | ||
16 | |||
17 | new(MappingDefinition mappingDefinition, MappingQueries mappingQueries) { | ||
18 | matcher = mappingQueries.getMatcher(mappingDefinition) | ||
19 | this.mappingDefinition = mappingDefinition | ||
20 | val variables = newHashSet | ||
21 | for (assignment : mappingDefinition.assignments) { | ||
22 | variables += assignment.input.component | ||
23 | variables += assignment.output.component | ||
24 | } | ||
25 | lookupHandlers = ImmutableMap.copyOf(variables.filter(LookupDefinition).toMap([it], [ lookupDefinition | | ||
26 | mappingQueries.createLookupHandler(mappingDefinition, lookupDefinition) | ||
27 | ])) | ||
28 | } | ||
29 | |||
30 | def instantiateComponents(ComponentFaultTreeTrace faultTreeTrace) { | ||
31 | if (!hasComponentInstace) { | ||
32 | return | ||
33 | } | ||
34 | matcher.forEachMatch [ match | | ||
35 | val componentTrace = faultTreeTrace.instantiateComponent(match, componentDefinition) | ||
36 | if (isTopLevel) { | ||
37 | faultTreeTrace.topLevel = componentTrace | ||
38 | } | ||
39 | ] | ||
40 | } | ||
41 | |||
42 | def instantiateConnections(ComponentFaultTreeTrace faultTreeTrace) { | ||
43 | if (!hasConnections) { | ||
44 | return | ||
45 | } | ||
46 | matcher.forEachMatch [ match | | ||
47 | val lookedUpComponents = lookupComponents(faultTreeTrace, match) | ||
48 | for (assignment : mappingDefinition.assignments) { | ||
49 | val input = assignment.input | ||
50 | val inputComponent = lookedUpComponents.get(input.component) | ||
51 | val output = assignment.output | ||
52 | val outputComponent = lookedUpComponents.get(output.component) | ||
53 | if (inputComponent !== null && outputComponent !== null) { | ||
54 | inputComponent.assign(input.event, outputComponent, output.event) | ||
55 | } | ||
56 | } | ||
57 | ] | ||
58 | } | ||
59 | |||
60 | private def Map<Variable, ComponentInstanceTrace> lookupComponents(ComponentFaultTreeTrace faultTreeTrace, | ||
61 | IPatternMatch match) { | ||
62 | val lookedUpComponents = Maps.newHashMapWithExpectedSize(lookupHandlers.size + 1) | ||
63 | if (hasComponentInstace) { | ||
64 | val componentInstance = faultTreeTrace.lookup(match) | ||
65 | lookedUpComponents.put(mappingDefinition.componentInstance, componentInstance) | ||
66 | } | ||
67 | for (pair : lookupHandlers.entrySet) { | ||
68 | val componentInstance = pair.value.lookupForMatch(faultTreeTrace, match) | ||
69 | if (componentInstance !== null) { | ||
70 | lookedUpComponents.put(pair.key, componentInstance) | ||
71 | } | ||
72 | } | ||
73 | lookedUpComponents | ||
74 | } | ||
75 | |||
76 | private def getComponentDefinition() { | ||
77 | mappingDefinition.componentInstance?.componentType | ||
78 | } | ||
79 | |||
80 | private def hasComponentInstace() { | ||
81 | componentDefinition !== null | ||
82 | } | ||
83 | |||
84 | private def isTopLevel() { | ||
85 | mappingDefinition.topLevel | ||
86 | } | ||
87 | |||
88 | private def hasConnections() { | ||
89 | !mappingDefinition.assignments.empty | ||
90 | } | ||
91 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingQueries.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingQueries.xtend deleted file mode 100644 index 6683b3f8..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ecore2cft/MappingQueries.xtend +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ecore2cft | ||
2 | |||
3 | import com.google.common.collect.ImmutableMap | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.LookupDefinition | ||
5 | import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.MappingDefinition | ||
6 | import hu.bme.mit.inf.dslreasoner.faulttree.components.cftLanguage.TransformationDefinition | ||
7 | import java.util.Map | ||
8 | import org.eclipse.viatra.query.patternlanguage.emf.specification.SpecificationBuilder | ||
9 | import org.eclipse.viatra.query.runtime.api.GenericQueryGroup | ||
10 | import org.eclipse.viatra.query.runtime.api.IPatternMatch | ||
11 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine | ||
12 | import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher | ||
13 | |||
14 | class MappingQueries { | ||
15 | val Map<MappingDefinition, ViatraQueryMatcher<? extends IPatternMatch>> matchersMap | ||
16 | |||
17 | new(TransformationDefinition transformationDefinition, ViatraQueryEngine viatraQueryEngine) { | ||
18 | val specificationBuilder = new SpecificationBuilder | ||
19 | val querySpecificationsMap = transformationDefinition.mappingDefinitions.toMap([it], [ | ||
20 | specificationBuilder.getOrCreateSpecification(pattern) | ||
21 | ]) | ||
22 | GenericQueryGroup.of(querySpecificationsMap.values).prepare(viatraQueryEngine) | ||
23 | matchersMap = ImmutableMap.copyOf(querySpecificationsMap.mapValues[getMatcher(viatraQueryEngine)]) | ||
24 | } | ||
25 | |||
26 | def getMatcher(MappingDefinition mappingDefinition) { | ||
27 | val matcher = matchersMap.get(mappingDefinition) | ||
28 | if (matcher === null) { | ||
29 | throw new IllegalArgumentException("Unknown mapping definition: " + mappingDefinition) | ||
30 | } | ||
31 | matcher | ||
32 | } | ||
33 | |||
34 | def createLookupHandler(MappingDefinition mappingDefinition, LookupDefinition lookupDefinition) { | ||
35 | val lookedUpMatcher = getMatcher(lookupDefinition.mapping) | ||
36 | new LookupHandler(mappingDefinition, lookupDefinition, lookedUpMatcher) | ||
37 | } | ||
38 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ft2galileo/Ft2GalileoTransformation.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ft2galileo/Ft2GalileoTransformation.xtend deleted file mode 100644 index 4a19e2cd..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/ft2galileo/Ft2GalileoTransformation.xtend +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.ft2galileo | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.AndGate | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.BasicEvent | ||
5 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.ConstantDistribution | ||
6 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.Distribution | ||
7 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.ExponentialDistribution | ||
8 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.FaultTree | ||
9 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.Gate | ||
10 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.KOfMGate | ||
11 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.OrGate | ||
12 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.RandomEvent | ||
13 | import org.eclipse.xtend2.lib.StringConcatenationClient | ||
14 | |||
15 | class Ft2GalileoTransformation { | ||
16 | def toGalileo(FaultTree faultTree) ''' | ||
17 | toplevel "«faultTree.topEvent.name»"; | ||
18 | «FOR event : faultTree.events» | ||
19 | "«event.name»" «defineEvent(event)»; | ||
20 | «ENDFOR» | ||
21 | ''' | ||
22 | |||
23 | protected dispatch def defineEvent(BasicEvent basicEvent) { | ||
24 | // ft-diet (https://moves.rwth-aachen.de/ft-diet/) needs a dormancy factor. | ||
25 | '''«defineDistribution(basicEvent.distribution)» dorm=0.0''' | ||
26 | } | ||
27 | |||
28 | protected dispatch def StringConcatenationClient defineDistribution(ConstantDistribution distribution) { | ||
29 | '''p=«distribution.p»''' | ||
30 | } | ||
31 | |||
32 | protected dispatch def StringConcatenationClient defineDistribution(ExponentialDistribution distribution) { | ||
33 | '''lambda=«distribution.lambda»''' | ||
34 | } | ||
35 | |||
36 | protected dispatch def StringConcatenationClient defineDistribution(Distribution distribution) { | ||
37 | throw new IllegalArgumentException("Unknown distribution: " + distribution) | ||
38 | } | ||
39 | |||
40 | protected dispatch def StringConcatenationClient defineEvent(Gate gate) { | ||
41 | '''«defineGate(gate)» «FOR input : gate.inputEvents SEPARATOR " "»"«input.name»"«ENDFOR»''' | ||
42 | } | ||
43 | |||
44 | protected dispatch def StringConcatenationClient defineGate(AndGate gate) '''and''' | ||
45 | |||
46 | protected dispatch def StringConcatenationClient defineGate(OrGate gate) '''or''' | ||
47 | |||
48 | protected dispatch def StringConcatenationClient defineGate(KOfMGate gate) '''«gate.k»of«gate.inputEvents.size»''' | ||
49 | |||
50 | protected dispatch def StringConcatenationClient defineGate(Gate gate) { | ||
51 | throw new IllegalArgumentException("Unknown gate: " + gate) | ||
52 | } | ||
53 | |||
54 | protected dispatch def StringConcatenationClient defineEvent(RandomEvent randomEvent) { | ||
55 | throw new IllegalArgumentException("Unknown random even: " + randomEvent) | ||
56 | } | ||
57 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/ReliabilityResult.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/ReliabilityResult.xtend deleted file mode 100644 index 19c3d17d..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/ReliabilityResult.xtend +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.solver | ||
2 | |||
3 | import org.eclipse.xtend.lib.annotations.Data | ||
4 | import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor | ||
5 | |||
6 | abstract class ReliabilityResult { | ||
7 | public static val TIMEOUT = new Unknown("Solver timed out") | ||
8 | public static val MEMOUT = new Unknown("Solver out of memory") | ||
9 | |||
10 | abstract def Solution getOrThrow() | ||
11 | |||
12 | @Data | ||
13 | static final class Solution extends ReliabilityResult { | ||
14 | val double lowerBound | ||
15 | val double upperBound | ||
16 | |||
17 | new(double value) { | ||
18 | this(value, value) | ||
19 | } | ||
20 | |||
21 | new(double lowerBound, double upperBound) { | ||
22 | if (lowerBound > upperBound) { | ||
23 | throw new IllegalArgumentException("lowerBound must not be larger than upperBound") | ||
24 | } | ||
25 | this.lowerBound = lowerBound | ||
26 | this.upperBound = upperBound | ||
27 | } | ||
28 | |||
29 | override getOrThrow() { | ||
30 | this | ||
31 | } | ||
32 | } | ||
33 | |||
34 | @Data | ||
35 | static final class Unknown extends ReliabilityResult { | ||
36 | val String message | ||
37 | val Throwable cause | ||
38 | |||
39 | @FinalFieldsConstructor | ||
40 | new() { | ||
41 | } | ||
42 | |||
43 | new(String message) { | ||
44 | this(message, null) | ||
45 | } | ||
46 | |||
47 | override getOrThrow() { | ||
48 | throw new RuntimeException(message, cause) | ||
49 | } | ||
50 | } | ||
51 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/StormDftConfiguration.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/StormDftConfiguration.xtend deleted file mode 100644 index d9059bfc..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/StormDftConfiguration.xtend +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.solver | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.SolverConfiguration | ||
4 | |||
5 | final class StormDftConfiguration extends SolverConfiguration { | ||
6 | public static val DEFAULT_SOLVER_PATH = "storm-dft" | ||
7 | |||
8 | public double precision = 1e-6 | ||
9 | |||
10 | public boolean bisimulation = true | ||
11 | |||
12 | public boolean symmetryReduction = true | ||
13 | |||
14 | public boolean modularization = true | ||
15 | |||
16 | public boolean dontCarePropagation = true | ||
17 | |||
18 | public double approximation = 0 | ||
19 | |||
20 | public var approximationHeuristic = ApproximationHeuristic.NONE | ||
21 | |||
22 | public FtAnalysisObjective objective | ||
23 | |||
24 | def isApproximationInUse() { | ||
25 | approximationHeuristic != ApproximationHeuristic.NONE | ||
26 | } | ||
27 | } | ||
28 | |||
29 | abstract class FtAnalysisObjective { | ||
30 | public static val MTTF = new FtAnalysisObjective { | ||
31 | } | ||
32 | |||
33 | private new() { | ||
34 | } | ||
35 | |||
36 | static final class TimeBound extends FtAnalysisObjective { | ||
37 | public double timeBound = 0 | ||
38 | } | ||
39 | } | ||
40 | |||
41 | enum ApproximationHeuristic { | ||
42 | NONE, | ||
43 | DEPTH | ||
44 | // See https://github.com/moves-rwth/storm/issues/35 for additional approximation heuristics. | ||
45 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/StormDftHandler.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/StormDftHandler.xtend deleted file mode 100644 index a250a955..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/StormDftHandler.xtend +++ /dev/null | |||
@@ -1,182 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.solver | ||
2 | |||
3 | import com.google.common.collect.ImmutableList | ||
4 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel | ||
5 | import hu.bme.mit.inf.dslreasoner.logic.model.builder.SolverConfiguration | ||
6 | import java.io.BufferedReader | ||
7 | import java.io.IOException | ||
8 | import java.io.InputStream | ||
9 | import java.io.InputStreamReader | ||
10 | import java.util.regex.Pattern | ||
11 | |||
12 | class StormDftException extends RuntimeException { | ||
13 | new(String s) { | ||
14 | super(s) | ||
15 | } | ||
16 | |||
17 | new(String s, Exception e) { | ||
18 | super(s, e) | ||
19 | } | ||
20 | } | ||
21 | |||
22 | class StormDftHandler { | ||
23 | static val DOUBLE_REGEX = "[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?" | ||
24 | static val SINGLE_RESULT_GROUP = "single" | ||
25 | static val LOWER_BOUND_GROUP = "lower" | ||
26 | static val UPPER_BOUND_GROUP = "upper" | ||
27 | static val RESULT_REGEX = '''^Result:\s*\[(?:(?<«SINGLE_RESULT_GROUP»>«DOUBLE_REGEX»)|\((?<«LOWER_BOUND_GROUP»>«DOUBLE_REGEX»),\s*(?<«UPPER_BOUND_GROUP»>«DOUBLE_REGEX»)\))\]''' | ||
28 | static val RESULT_PATTERN = Pattern.compile(RESULT_REGEX) | ||
29 | |||
30 | static val SIGNAL_EXIT_VALUE_OFFSET = 0x80 | ||
31 | static val SIGXCPU = 24 | ||
32 | static val SIGXFSZ = 25 | ||
33 | |||
34 | static val STORM_GENERAL_ERROR = (-1).bitwiseAnd(0xff) | ||
35 | static val STORM_TIMEOUT = (-2).bitwiseAnd(0xff) | ||
36 | static val STORM_MEMOUT = (-3).bitwiseAnd(0xff) | ||
37 | |||
38 | def callSolver(String dftFilePath, StormDftConfiguration configuration) { | ||
39 | val commandLine = configuration.toCommandLine(dftFilePath) | ||
40 | val documentationLevel = configuration.documentationLevel | ||
41 | val printOutput = documentationLevel == DocumentationLevel.NORMAL || | ||
42 | documentationLevel == DocumentationLevel.FULL | ||
43 | val processBuilder = new ProcessBuilder().command(commandLine) | ||
44 | var Process process = null | ||
45 | try { | ||
46 | try { | ||
47 | process = processBuilder.start | ||
48 | process.outputStream.close | ||
49 | val result = readOutput(process.inputStream, printOutput) | ||
50 | val error = readError(process.errorStream, printOutput) | ||
51 | val exitValue = process.waitFor | ||
52 | if (result === null) { | ||
53 | interpretExitStatus(exitValue, error) | ||
54 | } else { | ||
55 | result | ||
56 | } | ||
57 | } catch (IOException e) { | ||
58 | throw new StormDftException("Error during input/output handling of the stochastic solver.", e) | ||
59 | } | ||
60 | } catch (Exception e) { | ||
61 | if (process !== null) { | ||
62 | process.destroyForcibly.waitFor | ||
63 | } | ||
64 | throw e | ||
65 | } | ||
66 | } | ||
67 | |||
68 | private def toCommandLine(extension StormDftConfiguration configuration, String dftFilePath) { | ||
69 | extension val optionsBuilder = ImmutableList.builder | ||
70 | add(solverPath ?: StormDftConfiguration.DEFAULT_SOLVER_PATH) | ||
71 | if (runtimeLimit != SolverConfiguration.Unlimited) { | ||
72 | add("--timeout", runtimeLimit.toString) | ||
73 | } | ||
74 | add("--precision", precision.toString) | ||
75 | if (bisimulation) { | ||
76 | add("--bisimulation") | ||
77 | } | ||
78 | if (symmetryReduction) { | ||
79 | add("--symmetryreduction") | ||
80 | } | ||
81 | if (modularization) { | ||
82 | add("--modularisation") | ||
83 | } | ||
84 | if (!dontCarePropagation) { | ||
85 | add("--disabledc") | ||
86 | } | ||
87 | if (approximationInUse) { | ||
88 | val heuristicName = switch (approximationHeuristic) { | ||
89 | case DEPTH: | ||
90 | "depth" | ||
91 | default: | ||
92 | throw new IllegalArgumentException("Unknown approximation heuristic: " + approximationHeuristic) | ||
93 | } | ||
94 | add("--approximation", approximation.toString, "--approximationheuristic", heuristicName) | ||
95 | } | ||
96 | add("--dftfile", dftFilePath) | ||
97 | switch (objective) { | ||
98 | case FtAnalysisObjective.MTTF: | ||
99 | add("--expectedtime") | ||
100 | FtAnalysisObjective.TimeBound: | ||
101 | add("--timebound") | ||
102 | default: | ||
103 | throw new IllegalArgumentException("Unknown analysis objective: " + objective) | ||
104 | } | ||
105 | if (documentationLevel == DocumentationLevel.FULL) { | ||
106 | add("--verbose") | ||
107 | } | ||
108 | build | ||
109 | } | ||
110 | |||
111 | private def readOutput(InputStream inputStream, boolean printOutput) { | ||
112 | val bufferedReader = new BufferedReader(new InputStreamReader(inputStream)) | ||
113 | try { | ||
114 | var String line | ||
115 | while ((line = bufferedReader.readLine) !== null) { | ||
116 | if (printOutput) { | ||
117 | println(line) | ||
118 | } | ||
119 | val matcher = RESULT_PATTERN.matcher(line) | ||
120 | if (matcher.find) { | ||
121 | try { | ||
122 | val single = matcher.group(SINGLE_RESULT_GROUP) | ||
123 | if (single !== null) { | ||
124 | val singleValue = Double.parseDouble(single) | ||
125 | return new ReliabilityResult.Solution(singleValue) | ||
126 | } | ||
127 | val lower = matcher.group(LOWER_BOUND_GROUP) | ||
128 | val upper = matcher.group(UPPER_BOUND_GROUP) | ||
129 | if (lower !== null && upper !== null) { | ||
130 | val lowerValue = Double.parseDouble(lower) | ||
131 | val upperValue = Double.parseDouble(upper) | ||
132 | return new ReliabilityResult.Solution(lowerValue, upperValue) | ||
133 | } | ||
134 | throw new StormDftException("Inconsistent stochastic solver output: " + line) | ||
135 | } catch (NumberFormatException e) { | ||
136 | throw new StormDftException("Malformatted number from stochastic solver.", e) | ||
137 | } | ||
138 | } | ||
139 | } | ||
140 | } finally { | ||
141 | bufferedReader.close | ||
142 | } | ||
143 | null | ||
144 | } | ||
145 | |||
146 | private def readError(InputStream inputStream, boolean printOutput) { | ||
147 | val bufferedReader = new BufferedReader(new InputStreamReader(inputStream)) | ||
148 | try { | ||
149 | val lines = newArrayList | ||
150 | var String line | ||
151 | while ((line = bufferedReader.readLine) !== null) { | ||
152 | if (printOutput) { | ||
153 | System.err.println(line) | ||
154 | } | ||
155 | lines += line | ||
156 | } | ||
157 | lines.join("\n") | ||
158 | } finally { | ||
159 | bufferedReader.close | ||
160 | } | ||
161 | } | ||
162 | |||
163 | private def interpretExitStatus(int exitValue, String error) { | ||
164 | switch (exitValue) { | ||
165 | case STORM_GENERAL_ERROR: | ||
166 | throw new StormDftException("Storm error: " + error) | ||
167 | case STORM_TIMEOUT, | ||
168 | case SIGNAL_EXIT_VALUE_OFFSET + SIGXCPU: | ||
169 | ReliabilityResult.TIMEOUT | ||
170 | case STORM_MEMOUT, | ||
171 | case SIGNAL_EXIT_VALUE_OFFSET + SIGXFSZ: | ||
172 | ReliabilityResult.MEMOUT | ||
173 | default: { | ||
174 | if (exitValue > SIGNAL_EXIT_VALUE_OFFSET) { | ||
175 | val signalNumber = exitValue - SIGNAL_EXIT_VALUE_OFFSET | ||
176 | throw new StormDftException("Storm unexpectedly killed by signal " + signalNumber + ": " + error) | ||
177 | } | ||
178 | throw new StormDftException("Storm unexpectedly exit with status " + exitValue + ": " + error) | ||
179 | } | ||
180 | } | ||
181 | } | ||
182 | } | ||
diff --git a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/StormDftSolver.xtend b/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/StormDftSolver.xtend deleted file mode 100644 index 931b9f39..00000000 --- a/Stochastic/hu.bme.mit.inf.dslreasoner.faulttree.transformation/src/hu/bme/mit/inf/dslreasoner/faulttree/transformation/solver/StormDftSolver.xtend +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | package hu.bme.mit.inf.dslreasoner.faulttree.transformation.solver | ||
2 | |||
3 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.ConstantModel | ||
4 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.FaultTree | ||
5 | import hu.bme.mit.inf.dslreasoner.faulttree.model.ft.ReliabilityModel | ||
6 | import hu.bme.mit.inf.dslreasoner.faulttree.transformation.ft2galileo.Ft2GalileoTransformation | ||
7 | import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace | ||
8 | |||
9 | class StormDftSolver { | ||
10 | static val DFT_FILE_NAME = "ft.dft" | ||
11 | |||
12 | val ft2Galileo = new Ft2GalileoTransformation | ||
13 | val handler = new StormDftHandler | ||
14 | |||
15 | def solve(ReliabilityModel reliabilityModel, StormDftConfiguration configuration, | ||
16 | ReasonerWorkspace reasonerWorkspace) { | ||
17 | switch (reliabilityModel) { | ||
18 | FaultTree: | ||
19 | solve(reliabilityModel, configuration, reasonerWorkspace) | ||
20 | ConstantModel: { | ||
21 | val result = if (reliabilityModel.failed) { | ||
22 | 0 | ||
23 | } else { | ||
24 | switch (objective : configuration.objective) { | ||
25 | case FtAnalysisObjective.MTTF: Double.POSITIVE_INFINITY | ||
26 | FtAnalysisObjective.TimeBound: 1 | ||
27 | default: throw new IllegalArgumentException("Unknown objective: " + objective) | ||
28 | } | ||
29 | } | ||
30 | new ReliabilityResult.Solution(result) | ||
31 | } | ||
32 | default: | ||
33 | throw new IllegalArgumentException("Unknown reliability model: " + reliabilityModel) | ||
34 | } | ||
35 | } | ||
36 | |||
37 | def solve(FaultTree faultTree, StormDftConfiguration configuration, ReasonerWorkspace reasonerWorkspace) { | ||
38 | val galileo = ft2Galileo.toGalileo(faultTree) | ||
39 | reasonerWorkspace.writeText(DFT_FILE_NAME, galileo) | ||
40 | val dftFilePath = reasonerWorkspace.getFile(DFT_FILE_NAME).absolutePath | ||
41 | handler.callSolver(dftFilePath, configuration) | ||
42 | } | ||
43 | } | ||