Hello everyone!
Maintaining the quality and consistency of your FMEA (Failure Mode and Effects Analysis) or general Cause-Effect nets is crucial for accurate Safety Analysis. Today, we present two advanced OCL rules designed to catch common structural issues that often lead to inaccurate results.
For practical reasons, due to the complexity of the topic, let's use as a reference a three-level cause-effect network like the one below and from time to time we add the bad relationship to then understand how it could be captured and possibly eliminated.

Context for both OCL Rules: safetyModel::Failure
Rule 1: Preventing Redundant Causality Chains
This rule checks for a specific type of redundant causality where a failure's ultimate root cause links back to the failure itself, bypassing intermediate steps.
The goal is to avoid the following scenario where CAUSE is directly linked to the same EFFECT that is already effect of the intermediary one:

The goal of the detection is:
Note: at the bottom of the article, we also present a JS code that could help to automatically detect and delete all the redundant relations (type A→C when the first one already exists)
OCL rule
inv:
-- Find all Failures that start an an Effect chain
let effectConnections : Set(Failure) = self->select(failure | failure.effectRelations->notEmpty())
in
-- Iterate over each failure in the set
effectConnections->forAll(failure |
-- Check the chain: Failure -> Effect -> Cause -> Cause-Cause
failure.effectRelations->forAll(relation |
relation.effect.causedBy->forAll(cause |
cause.causedBy->forAll(causeCause |
-- The Cause-Cause should not be the same as the original Cause element
causeCause <> relation.cause
)
)
)
)
Rule 2: Checking for Causality Loops (2 variants)
This vital check prevents structural inconsistencies in your Cause-Effect nets where a failure mode participates in a causal loop. Such loops are illogical and risk creating infinite recursion in analysis. We distinguish between two scenarios:
Variant 1: Direct Two-Way Loop (A<-->B)
This variant specifically prevents a failure mode from having a cause that is simultaneously an effect of that same failure mode. The check is direct, focusing on an immediate reciprocal relationship between only two failures (e.g., A causes B, and B causes A).
To avoid the scenario below:

OCL rule (variant 1):
inv:
not self.causedBy->exists(ce | ce.causedBy->exists(ce2 | ce2 = self))
Explanation: The rule ensures that there is no element (ce) that is a cause of the current failure (self), and that element (ce) is not also caused by the current failure (self.causedBy).
Variant 2: Arbitrarily Long Chain Loop (A -->B --> C --> ... --> A)
This variant implements a broader check to prevent any arbitrary length loop within the entire cause/effect chain. The goal is to ensure that no single failure can ever lead back to itself through any sequence of downstream effects, ensuring the model remains acyclic.
To avoid the scenario below:

Note: in this variant all the failures that are part of the loop chain will be intercepted by the OCL constraint.
OCL rule (variant 2):
inv NoEffectCycles:
not self.effectRelations->collect(r | r.effect)
->closure(e | e.effectRelations->collect(r | r.effect))
->includes(self)
Explanation: This OCL rule checks that no failure can eventually lead back to itself through effect relations. It does this by:
- Taking all failures that are direct effects of self.
- Following all effect → effect → effect chains using closure.
- Checking whether self appears again in that reachable set.
If self is found again, there is a cycle, and the invariant fails.
Enforcement Note: Medini natively alerts users against creating cause/effect loops from scratch; however, the tool permits the user to override this warning (perhaps unknowingly). Critically, this native mechanism does not cover project model or FMEA import scenarios. This is why the OCL rules described above are essential for maintaining model consistency.
________________________________________________________ ________________________________________________________ ________________________________________________________ _________________________
For Rule 1, we provide a JavaScript Derived Property (code attached). This script not only validates consistency but also includes logic to automatically delete the redundant cause relation to enforce the structural integrity of your FMEA model.
⚠️ WARNING: This JS script involves invasive model modification (deletion). Use caution, as it will automatically fix the structural inconsistency by removing the redundant causal element.
________________________________________________________ ________________________________________________________ ________________________________________________________ _________________________
If you have any questions about implementing these or other OCL rules or derived JS properties, please don't hesitate to leave a comment below or contact us directly.
Happy Scripting!
Michele