Hi Jan,
I want to have a constraint, that checks, if each malfunction has a hazardous event assigned. How could this look like?
btw: is it possible to check not the complete project?
Hi Sven,
for the first point (each malfunction has a hazardous event assigned) there would be first the question whether you really want to see whether each malfunction has a hazardous event associated or whether some malfunction which is an effect of the malfunction has a hazardous event assigne (i.e. taking into account the cause-effect chains).
For the first option the constraint is rather simple:
However, that may deliver a lot of error messages in case you mainly have the malfunctions of the toplevel functions in HARA.
Another option would be to follow some style as in the BestPracticeTemplate/ESL example where we have a dedicated profile property for malfunction which shows (transititvely) all HE related to a malfunction:
In that case you could have also a dynamic constraint for malfunction that checks whether this list is empty - i.e.:
inv:self.user_hazardous_events->collect(oclAsType(hazard::HazardousEvent))->size()>0
Best regards,
Eckhardt
I know that I have that constraint somewhere, need to search for it.
The last question ... in principle a constraint may work only on a scope but its difficult to define that scope since validation is not interactive, However, validation can be done for a complete project or the selected scope only if that is what you mean.
Happy Scripting
Jan
I found the OCL and it has quite some "history" as you can see in the code. The constraint covers several situation which allow the user to "argue" why a malfunction is not in the HARA, you can choose yourself whether any of them make sense to you, otherwise just remove:
inv:let -- we use "effects" and references from RA effects : Sequence(Failure) = self.effects, events : Sequence(OclAny) = self.mediniGetOpposites('malfunctions'), -- option 1: "effects" is set option1 : Boolean = effects->notEmpty(), -- option 2: malfunction is analyzed in RA option2 : Boolean = not (events->isEmpty() or events->first().oclIsUndefined()), -- option 3: description contains predefined text (obsolete) option3 : Boolean = self.description.toLower().indexOf('this malfunction does not lead to any hazard') <> -1, -- option 4: malfunction is traced to a safety goal (obsolete) traces : Sequence(traceability::Trace) =traceability::TraceSet.allInstances().traces, myTraces : Sequence(traceability::Trace) = traces->select(trace|trace.sourceElements->includes(self)), option4 : Boolean = myTraces.targetElements->exists(x|x.oclIsKindOf(safetygoals::SafetyGoal)), -- option 5, 6: special field is used (as replacement for 3 and 4) reasoning : Sequence(String) = self.getProfilePropertyValue('notConsideredBecause'), firstGoal : safetygoals::SafetyGoal = self.getProfilePropertyValue('safetyGoal')->first().oclAsType(safetygoals::SafetyGoal), option5 : Boolean = reasoning->exists(x|x.trim().toLower().indexOf('this malfunction does not lead to any hazard') <> -1), option6 : Boolean = reasoning->exists(x|x.trim().toLower().indexOf('this malfunction has been accessed in another project') <> -1), and (not firstGoal.oclIsUndefined()), -- show ID in message MessageArg1: String = self.idin option1 or option2 or option3 or option4 or option5 or option6
Number 1 is special. If the malfunction is in a failure net, only the root of the net is supposed to be analyzed. Maybe that applies to you as well.