FaultTreeUtils.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package org.osate.aadl2.errormodel.FaultTree.util;
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.osate.aadl2.DirectionType;
import org.osate.aadl2.Element;
import org.osate.aadl2.NamedElement;
import org.osate.aadl2.errormodel.FaultTree.Event;
import org.osate.aadl2.errormodel.FaultTree.EventType;
import org.osate.aadl2.errormodel.FaultTree.FaultTree;
import org.osate.aadl2.errormodel.FaultTree.FaultTreeFactory;
import org.osate.aadl2.errormodel.FaultTree.FaultTreeType;
import org.osate.aadl2.errormodel.FaultTree.LogicOperation;
import org.osate.aadl2.instance.ComponentInstance;
import org.osate.aadl2.instance.ConnectionInstance;
import org.osate.aadl2.instance.InstanceObject;
import org.osate.aadl2.instance.SystemInstance;
import org.osate.xtext.aadl2.errormodel.errorModel.CompositeState;
import org.osate.xtext.aadl2.errormodel.errorModel.ConditionExpression;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorBehaviorState;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorBehaviorTransition;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorDetection;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorEvent;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorPropagation;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorSource;
import org.osate.xtext.aadl2.errormodel.errorModel.ErrorTypes;
import org.osate.xtext.aadl2.errormodel.errorModel.OutgoingPropagationCondition;
import org.osate.xtext.aadl2.errormodel.errorModel.TypeSet;
import org.osate.xtext.aadl2.errormodel.errorModel.TypeToken;
import org.osate.xtext.aadl2.errormodel.util.EMV2Properties;
import org.osate.xtext.aadl2.errormodel.util.EMV2Util;
public class FaultTreeUtils {
private static String buildName(ConnectionInstance conni, NamedElement namedElement, TypeToken type) {
String identifier;
identifier = conni.getName();
if (namedElement == null) {
identifier += "-unidentified";
} else {
String name = EMV2Util.getDirectionName(namedElement);
if (!name.isEmpty()) {
identifier += "-" + name;
}
}
if (type != null) {
identifier += "-" + EMV2Util.getName(type);
}
identifier = identifier.replaceAll("\\{", "").replaceAll("\\}", "").toLowerCase();
return identifier;
}
public static String buildName(ComponentInstance component, NamedElement namedElement, TypeToken type) {
String identifier;
if (component == null) {
return "Null Component Reference";
}
identifier = component instanceof SystemInstance
? component.getComponentClassifier().getQualifiedName().replaceAll("::", "_").replaceAll("\\.", "_")
: component.getComponentInstancePath();
if (namedElement == null) {
identifier += "-unidentified";
} else {
String name = EMV2Util.getDirectionName(namedElement);
if (!name.isEmpty()) {
identifier += "-" + name;
}
}
if (type != null) {
identifier += "-" + EMV2Util.getName(type);
}
identifier = identifier.replaceAll("\\{", "").replaceAll("\\}", "").toLowerCase();
return identifier;
}
private static void redoCount(FaultTree ftaModel) {
for (Event ev : ftaModel.getEvents()) {
ev.setReferenceCount(0);
}
doCount(ftaModel.getRoot());
}
private static void doCount(Event ev) {
ev.setReferenceCount(ev.getReferenceCount() + 1);
for (Event subev : ev.getSubEvents()) {
doCount(subev);
}
}
public static void removeEventOrphans(FaultTree ftaModel) {
redoCount(ftaModel);
List<Event> toRemove = new LinkedList<Event>();
for (Event ev : ftaModel.getEvents()) {
if (ev.getReferenceCount() == 0) {
toRemove.add(ev);
}
}
ftaModel.getEvents().removeAll(toRemove);
}
public static boolean hasSharedEvents(FaultTree ftaModel) {
for (Event ev : ftaModel.getEvents()) {
if (isASharedEvent(ev)) {
return true;
}
}
return false;
}
public static boolean isASharedEvent(Event event) {
return event.getReferenceCount() > 1;
}
/**
* create a BASIC event with the specified component, error model element, and type name
* @param component
* @param namedElement
* @param type
* @return Event
*/
public static Event createBasicEvent(FaultTree ftaModel, ComponentInstance component, NamedElement namedElement,
TypeToken type) {
String name = buildName(component, namedElement, type);
Event result = findEvent(ftaModel, name);
if (result != null) {
return result;
}
Event newEvent = FaultTreeFactory.eINSTANCE.createEvent();
ftaModel.getEvents().add(newEvent);
newEvent.setName(name);
newEvent.setType(EventType.BASIC);
newEvent.setRelatedInstanceObject(component);
newEvent.setRelatedEMV2Object(namedElement);
newEvent.setRelatedErrorType(type);
return newEvent;
}
public static void addBasicEvent(Event parent, ComponentInstance component, NamedElement namedElement,
TypeToken type) {
Event newEvent = createBasicEvent((FaultTree) parent.eContainer(), component, namedElement, type);
parent.getSubEvents().add(newEvent);
}
public static Event createBasicEvent(FaultTree ftaModel, ConnectionInstance conni, NamedElement namedElement,
TypeToken type) {
String name = buildName(conni, namedElement, type);
Event result = findEvent(ftaModel, name);
if (result != null) {
return result;
}
Event newEvent = FaultTreeFactory.eINSTANCE.createEvent();
ftaModel.getEvents().add(newEvent);
newEvent.setName(name);
newEvent.setType(EventType.BASIC);
newEvent.setRelatedInstanceObject(conni);
newEvent.setRelatedEMV2Object(namedElement);
newEvent.setRelatedErrorType(type);
return newEvent;
}
public static void addBasicEvent(Event parent, ConnectionInstance conni, NamedElement namedElement,
TypeToken type) {
Event newEvent = createBasicEvent((FaultTree) parent.eContainer(), conni, namedElement, type);
parent.getSubEvents().add(newEvent);
}
/**
* create a INTERMEDIATE event with the specified component, error model element, and type name
* @param component
* @param namedElement
* @param type
* @return Event
*/
public static Event createIntermediateEvent(FaultTree ftaModel, ComponentInstance component, EObject element,
TypeToken type) {
return createIntermediateEvent(ftaModel, component, element, type, false);
}
public static Event createUniqueIntermediateEvent(FaultTree ftaModel, ComponentInstance component, EObject element,
TypeToken type) {
return createIntermediateEvent(ftaModel, component, element, type, true);
}
/**
* create a generic intermediate Event
* @return
*/
private static int count = 1;
public static void resetIntermediateEventCount() {
count = 1;
}
private static Event createIntermediateEvent(FaultTree ftaModel, ComponentInstance component, EObject element,
TypeToken type, boolean unique) {
String name;
if (element instanceof NamedElement && !unique && ((NamedElement) element).getName() != null) {
name = buildName(component, (NamedElement) element, type);
Event result = findEvent(ftaModel, name);
if (result != null && result.getType() == EventType.INTERMEDIATE) {
return result;
}
} else {
name = "Intermediate" + count++;
}
Event newEvent = FaultTreeFactory.eINSTANCE.createEvent();
ftaModel.getEvents().add(newEvent);
newEvent.setName(name);
newEvent.setType(EventType.INTERMEDIATE);
newEvent.setRelatedInstanceObject(component);
newEvent.setRelatedEMV2Object(element);
newEvent.setRelatedErrorType(type);
return newEvent;
}
public static Event findEvent(FaultTree ftaModel, String eventName) {
for (Event event : ftaModel.getEvents()) {
if (event.getName().equalsIgnoreCase(eventName)) {
return event;
}
}
return null;
}
public static Event findSharedSubtree(FaultTree ftaModel, List<EObject> subEvents, LogicOperation optype,
ComponentInstance component, Element ne, TypeToken type) {
for (Event event : ftaModel.getEvents()) {
if (event.getRelatedInstanceObject() == component && event.getRelatedEMV2Object() == ne
&& event.getRelatedErrorType() == type) {
if (!event.getSubEvents().isEmpty() && event.getSubEventLogic() == optype
&& event.getSubEvents().size() == subEvents.size()
&& subEvents.containsAll(event.getSubEvents())) {
return event;
}
}
}
return null;
}
public static List<Event> copy(FaultTree ftaModel, List<Event> alts) {
LinkedList<Event> altscopy = new LinkedList<Event>();
for (Event alt : alts) {
Event newalt = EcoreUtil.copy(alt);
altscopy.add(newalt);
ftaModel.getEvents().add(newalt);
}
return altscopy;
}
public static boolean sameEvent(Event e1, Event e2) {
return e1.getName().equalsIgnoreCase(e2.getName());
}
public static void fillProbability(Event event) {
if (!(event.getRelatedEMV2Object() instanceof NamedElement)) {
return;
}
InstanceObject io = (InstanceObject) event.getRelatedInstanceObject();
NamedElement ne = (NamedElement) event.getRelatedEMV2Object();
TypeToken type = (TypeToken) event.getRelatedErrorType();
event.setAssignedProbability(
new BigDecimal(EMV2Properties.getProbability(io, ne, type), MathContext.UNLIMITED));
}
public static String getName(ComponentInstance component) {
return (component instanceof SystemInstance ? component.getComponentClassifier().getName()
: component.getComponentInstancePath());
}
public static String getDescription(Event event) {
return getInstanceDescription(event) + " " + getEMV2ElementDescription(event);
}
public static String getEventDescription(Event event) {
return getInstanceDescription(event);
}
public static String getErrorDescription(Event event) {
return getEMV2ElementDescription(event);
}
public static String getInstanceDescription(Event event) {
InstanceObject io = (InstanceObject) event.getRelatedInstanceObject();
String description = "";
if (io instanceof ComponentInstance) {
description = "'" + getName((ComponentInstance) io) + "'";
} else if (io instanceof ConnectionInstance) {
description = "Connection '" + ((ConnectionInstance) io).getName() + "'";
}
EObject errorModelArtifact = event.getRelatedEMV2Object();
if (errorModelArtifact instanceof ErrorSource) {
ErrorSource errorSource = (ErrorSource) errorModelArtifact;
description += " source '" + EMV2Util.getName(errorSource) + "'";
}
if (errorModelArtifact instanceof ErrorEvent) {
ErrorEvent errorSource = (ErrorEvent) errorModelArtifact;
description += " event '" + EMV2Util.getName(errorSource) + "'";
}
if (errorModelArtifact instanceof ErrorPropagation) {
ErrorPropagation ep = (ErrorPropagation) errorModelArtifact;
String directionLabel = ep.getDirection() == DirectionType.IN ? " incoming " : " outgoing ";
description += directionLabel + "'" + EMV2Util.getName(ep) + "'";
}
return description;
}
public static String getEMV2ElementDescription(Event event) { // JH looks like the code to do the boxes in FTA
EObject errorModelArtifact = event.getRelatedEMV2Object();
TypeToken type = (TypeToken) event.getRelatedErrorType();
String description;
description = "";
if (errorModelArtifact instanceof ErrorSource) {
ErrorSource errorSource = (ErrorSource) errorModelArtifact;
description = (type != null ? "{" + EMV2Util.getName(type) + "} from " : "") + "error source '"
+ EMV2Util.getName(errorSource) + "'";
}
if (errorModelArtifact instanceof ErrorEvent) {
ErrorEvent ee = (ErrorEvent) errorModelArtifact;
if (type != null) {
description += "{" + EMV2Util.getName(type) + "} from ";
}
description += "error event '" + EMV2Util.getName(ee) + "'";
}
if (errorModelArtifact instanceof ErrorBehaviorState) {
if (type != null) {
description += "{" + EMV2Util.getName(type) + "} from ";
}
description += "error state '" + ((ErrorBehaviorState) errorModelArtifact).getName() + "'";
}
if (errorModelArtifact instanceof ErrorPropagation) {
String boundaryLabel = "";
if (event.getType() == EventType.EXTERNAL) {
boundaryLabel = "external";
} else if (event.getType() == EventType.UNDEVELOPED) {
boundaryLabel = "undeveloped";
}
if (type != null) {
description = "{" + EMV2Util.getName(type) + "}";
if (!boundaryLabel.isEmpty()) {
description += " from " + boundaryLabel;
}
} else {
description = boundaryLabel;
}
}
if (errorModelArtifact instanceof ConditionExpression) {
// TODO
errorModelArtifact = EMV2Util.getConditionExpressionContext(errorModelArtifact);
String opcontext = "";
if (type instanceof TypeSet) {
opcontext = " on type set " + EMV2Util.getPrintName((TypeSet) type);
} else if (errorModelArtifact instanceof ErrorBehaviorTransition) {
String branch = ((ErrorBehaviorTransition) errorModelArtifact).getDestinationBranches().isEmpty() ? ""
: "branch ";
opcontext = " in transition " + branch + EMV2Util.getName(errorModelArtifact);
} else if (errorModelArtifact instanceof OutgoingPropagationCondition) {
opcontext = " in outgoing propagation condition " + EMV2Util.getName(errorModelArtifact);
} else if (errorModelArtifact instanceof ErrorDetection) {
opcontext = " in error detection " + EMV2Util.getName(errorModelArtifact);
} else if (errorModelArtifact instanceof CompositeState) {
opcontext = " in composite state " + EMV2Util.getName(errorModelArtifact);
}
if (event.getSubEventLogic() == LogicOperation.KORMORE) {
description = "'" + event.getSubEventLogic() + "' with k =" + event.getK() + opcontext;
} else {
description = "'" + event.getSubEventLogic() + "'" + opcontext;
}
}
return description;
}
public static final BigDecimal BigZero = new BigDecimal(0.0);
public static final BigDecimal BigOne = new BigDecimal(1.0);
/**
* return computed & spec probability - if computed is zero then only spec.
* @param context
* @return
*/
// to do pass param num of digits to display
public static String getProbability(EObject context) {
Event ev = (Event) context;
String specProb = "";
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(context.eResource().getURI().segment(1));
String precisionPref = "." + FaultTreeModel.getPrecision(project) + "e";
if (ev.getComputedProbability() != null && ev.getComputedProbability().compareTo(BigZero) != 0
&& ev.getAssignedProbability() != null && ev.getAssignedProbability().compareTo(BigZero) != 0) {
specProb = String.format(" (Spec %1$" + precisionPref + ")", ev.getAssignedProbability());
}
return String.format("%1$" + precisionPref + "%2$s", ev.getProbability(), specProb) + getScale(context);
}
/**
* return spec probability, i.e., probability assigned by property
* @param context
* @return
*/
public static String getAssignedProbability(EObject context) {
Event ev = (Event) context;
if (ev.getAssignedProbability() == null || ev.getAssignedProbability().compareTo(BigZero) == 0) {
return "";
}
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(context.eResource().getURI().segment(1));
String specProb = String.format("%1$." + FaultTreeModel.getPrecision(project) + "e",
ev.getAssignedProbability());
return specProb + getScale(context);
}
/**
* return computed probability
* @param context
* @return
*/
public static String getComputedProbability(EObject context) {
Event ev = (Event) context;
if (ev.getComputedProbability() == null || ev.getComputedProbability().compareTo(BigZero) == 0) {
return "";
}
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(context.eResource().getURI().segment(1));
String specProb = String.format("%1$." + FaultTreeModel.getPrecision(project) + "e",
ev.getComputedProbability());
return specProb + getScale(context);
}
// return scaling factor if different from 1.0, otherwise empty string
public static String getScale(EObject context) {
Event ev = (Event) context;
if (ev.getScale() == null || ev.getScale().compareTo(BigOne) == 0) {
return "";
}
return String.format(" * %1$.1f", ev.getScale());
}
public static String getDescriptionAndProbability(EObject context) {
if (context instanceof Event) {
Event ev = (Event) context;
FaultTree ft = (FaultTree) ev.eContainer();
String labeltext = ft.getFaultTreeType().equals(FaultTreeType.MINIMAL_CUT_SET)
? FaultTreeUtils.getCutsetLabel(ev)
: FaultTreeUtils.getInstanceDescription(ev);
if (labeltext == null || labeltext.isEmpty()) {
labeltext = ev.getName();
}
String emv2label = FaultTreeUtils.getEMV2ElementDescription(ev);
String ftmsg = ft.getMessage();
if (ftmsg != null) {
return "ERROR: " + ftmsg + "\n" + labeltext;
}
// String msg = ev.getMessage() != null ? "NOTE: " + ev.getMessage() : " ";
// String fullText = String.format("%1$s\n%2$s\n%4$s(%3$.3E)", labeltext, emv2label, val, msg);
String fullText = String.format("%1$s \n%2$s \n%3$s", labeltext, emv2label, getProbability(ev));
if (ev == ft.getRoot()) {
// mark probability with star if shared events are involved
if (FaultTreeUtils.hasSharedEvents(ft)) {
return fullText + "*";
} else {
return fullText;
}
} else if (isASharedEvent(ev)) {
return "*" + fullText;
} else {
return fullText;
}
}
return "";
}
public static String getCutsetLabel(EObject context) {
Event event = (Event) context;
FaultTree ft = (FaultTree) event.eContainer();
if (ft.getRoot().getSubEvents().contains(event)) {
return event.getName();
}
return FaultTreeUtils.getDescription((Event) context);
}
public static String getHazardDescription(EObject context) {
if (context instanceof Event) {
Event ev = (Event) context;
String hazardDescription = EMV2Properties.getHazardDescription(
(InstanceObject) ev.getRelatedInstanceObject(), (NamedElement) ev.getRelatedEMV2Object(),
(ErrorTypes) ev.getRelatedErrorType());
return hazardDescription;
}
return "";
}
public static String getHazardDescriptionAndProbability(EObject context) {
if (context instanceof Event) {
Event ev = (Event) context;
FaultTree ft = (FaultTree) ev.eContainer();
String hazardDescription = EMV2Properties.getHazardDescription(
(InstanceObject) ev.getRelatedInstanceObject(), (NamedElement) ev.getRelatedEMV2Object(),
(ErrorTypes) ev.getRelatedErrorType());
String labeltext = FaultTreeUtils.getDescription(ev);
if (labeltext == null || labeltext.isEmpty()) {
labeltext = ((Event) context).getName();
}
String msg = ev.getMessage() != null ? "\nMessage: " + ev.getMessage() : "";
String problabel = "";
if (isASharedEvent(ev)) {
labeltext = "Dependent event: " + labeltext;
} else if (ev == ft.getRoot()) {
// mark probability with star if shared events are involved
if (FaultTreeUtils.hasSharedEvents(ft)) {
problabel = " (incl. dependent event probabilities)";
}
}
if (hazardDescription == null) {
return String.format("%1$s%4$s\nOccurrence probability %2$s%3$s", labeltext,
getProbability(ev),
problabel, msg);
} else {
return String.format("%1$s\n%3$s%5$s\nOccurrence probability %2$s%4$s", labeltext,
getProbability(ev),
"Hazard: " + hazardDescription, problabel, msg);
}
}
return "";
}
/**
* return sum of probabilities of direct subevents.
* @param event
* @return double
*/
public static BigDecimal getSubeventProbabilities(Event event) {
if (!event.getSubEvents().isEmpty()) {
switch (event.getSubEventLogic()) {
case AND: {
return pANDEvents(event);
}
case PRIORITY_AND: {
// TODO need to adjust for ordered events
return pANDEvents(event);
}
case XOR: {
// P(1of(A,B,..) = SUM (PEi)*P(Ek k <>i k in 1..n)
return p1OFEvents(event);
}
case OR: {
return pOREvents(event);
}
case KORMORE: {
return pORMOREEvents(event);
}
default: {
System.out.println("[Utils] Unsupported operator for now: " + event.getSubEventLogic());
return BigOne;
}
}
} else {
return getScaledProbability(event);
}
}
public static BigDecimal pOREvents(Event event) {
// From equation (VI-17) from NRC guide, Fault Tree Handbook NUREG-0492
// P (E1 or E2 or E3 .. En) = 1 - ( (1-P(E1)) * (1-P(E2)) * (1-P(E3)) * ... * (1-P(En)) )
BigDecimal inverseProb = BigOne;
for (Event subEvent : event.getSubEvents()) {
inverseProb = inverseProb.multiply((BigOne.subtract(getScaledProbability(subEvent))));
}
return BigOne.subtract(inverseProb);
}
public static BigDecimal pORMOREEvents(Event event) {
// For this computation, we use the algorithm presented in
// "Computing k-out-of-n System Reliability", by R. E. Barlow and K. D. Heidtmann
// in IEEE Transactions on Reliability, Vol R-33, No 4, October 1984
//
// The general intuition of this algorithm goes as follows, using LaTex notation for the equations
// Conventions:
// $q_i$ is the failure rate of component i
// $p_i$ is the reliability rate of component i, $p_i = 1 - q_i$
// Re(k, n) is the probability that there are exactly k working components out of n
//
// Borderline cases as managed by the following conventions:
// $\forall j \in \{1 .. n\}, Re(-1, j) = Re(j+1, j) = 0$
// $Re(0, 0) = 0$
//
// Barlow and Heidtmann propose the following generating function
//
// g(z)=\prod_{i=1}^n (q_i + p_i z)
//
// By recurrence, one can establish that $g(z)=\prod_{i=1}^n (q_i + p_i z)=\sum_{i=0}^ n Re(i,n) z^i$
// using $Re(i,j) = q_j * Re(i, j - 1) + p_j * Re(i-1, j-1)$.
//
// It follows that computing $Re(k, n)$ for some $k \leq n$ is equivalent to computing the k-th element in the polynom
// g (z) = \sum_{i=0}^ n g_i z^i$ and perform term identification
// For simplicity, we implement PROGRAM 1
// Note: to match the original algorithm, we start with index at 1, up-to index n + 1
int n = event.getSubEvents().size();
BigDecimal[] probabilities = new BigDecimal[n + 2];
Arrays.fill(probabilities, BigDecimal.ZERO);
BigDecimal[] A = new BigDecimal[n + 2];
Arrays.fill(A, BigDecimal.ZERO);
A[1] = BigOne;
int k = 1;
for (Event subEvent : event.getSubEvents()) {
probabilities[k] = BigOne.subtract(getScaledProbability(subEvent));
k++;
}
for (int j = 1; j <= n; j++) {
for (int i = j + 1; i >= 1; i--) {
// At each step, we perform A(i) = A(i) + P(j) * (A(i - 1) - A(i))
A[i] = A[i].add(probabilities[j].multiply(A[i - 1].subtract(A[i])));
}
}
// The associated failure probability of k or more is $1 - \Sum_{j=k}^n Re(j, n)$
BigDecimal R = BigZero;
for (int j = event.getK() + 1; j <= n + 1; j++) {
R = R.add(A[j]);
}
R = BigOne.subtract(R);
return R;
}
public static BigDecimal pANDEvents(Event event) {
BigDecimal result = BigOne;
for (Event subEvent : event.getSubEvents()) {
result = result.multiply(getScaledProbability(subEvent));
}
return result;
}
// Sum P(Xi)*P(!Xk) for k <> i k in 1..n
public static BigDecimal p1OFEvents(Event event) {
BigDecimal result = BigZero;
for (Event subEvent : event.getSubEvents()) {
BigDecimal subresult = BigOne;
for (Event notEvent : event.getSubEvents()) {
if (subEvent == notEvent) {
subresult = subresult.multiply(getScaledProbability(subEvent));
} else {
subresult = subresult.multiply((BigOne.subtract(getScaledProbability(subEvent))));
}
}
result = result.add(subresult);
}
return result;
}
public static BigDecimal getScaledProbability(Event event) {
return event.getProbability().multiply(event.getScale());
}
public static void fillProbabilities(FaultTree ftaModel) {
for (Event event : ftaModel.getEvents()) {
EObject element = event.getRelatedEMV2Object();
if (element instanceof NamedElement) {
FaultTreeUtils.fillProbability(event);
}
}
}
public static void computeProbabilities(Event event) {
if (!event.getSubEvents().isEmpty()) {
for (Event e : event.getSubEvents()) {
computeProbabilities(e);
}
BigDecimal subtotalprobability = getSubeventProbabilities(event);
event.setComputedProbability(subtotalprobability);
}
}
}