Skip to content

Commit

Permalink
Remove INHIBIT & CONDITIONAL flavor format
Browse files Browse the repository at this point in the history
The current approach is not optimal due to being a special case
with the abuse of the MEF attributes mechanism.
INHIBIT gate must be implemented properly with dynamic analysis.
The changes are backward compatible
since these flavors had no effect on the analysis.

Issue #28
Issue #29
  • Loading branch information
rakhimov committed Jan 31, 2018
1 parent 21f82d2 commit 24c62ca
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 86 deletions.
32 changes: 7 additions & 25 deletions doc/fault_tree_analysis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ Supported Gate Types
- NAND
- XOR
- NULL
- INHIBIT
- ATLEAST


Expand All @@ -56,7 +55,6 @@ Supported Event Types
- Basic
- House
- Undeveloped
- Conditional

.. note:: Top and intermediate events are gates of an acyclic "fault-tree" graph ([PDAG]_).

Expand All @@ -67,34 +65,18 @@ Supported Event Types
since the "fault-tree" is properly treated as a graph/container.


Representation of INHIBIT, Undeveloped, and Conditional
=======================================================
Representation of Undeveloped
=============================

These gate and event types are not directly supported
by the input format based on the Open-PSA [MEF]_.
Indeed, these types are treated just like AND gate and Basic event respectively;
therefore, the description of these types
can be given through the Open-PSA MEF "attribute" element for gates and events.
The attribute name "flavor" is used to indicate
the different representation of an event as shown in the description bellow.


INHIBIT
-------

Add this XML line to AND gate description:
:literal:`<attributes> <attribute name="flavor" value="inhibit"/> </attributes>`
SCRAM currently "abuses" the Open-PSA [MEF]_ attributes mechanism
to add inessential (for analysis) meta-information.
This approach still ensures that the input file is portable across tools.
Attribute "flavor" is used to indicate
different representations of an event as shown in the description bellow.


Undeveloped
-----------

Add this XML line to basic event description:
:literal:`<attributes> <attribute name="flavor" value="undeveloped"/> </attributes>`


Conditional
-----------

Add this XML line to basic event description:
:literal:`<attributes> <attribute name="flavor" value="conditional"/> </attributes>`
29 changes: 0 additions & 29 deletions src/event.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,35 +44,6 @@ void BasicEvent::Validate() const {
EnsureProbability(expression_, Event::name());
}

void Gate::Validate() const {
assert(formula_ && "The gate formula is missing.");
// Detect inhibit flavor.
if (formula_->connective() != kAnd || !Element::HasAttribute("flavor") ||
Element::GetAttribute("flavor").value != "inhibit") {
return;
}
if (formula_->args().size() != 2) {
SCRAM_THROW(ValidityError(Element::name() +
"INHIBIT gate must have only 2 arguments"));
}
int num_conditional =
boost::count_if(formula_->args(), [](const Formula::Arg& arg) {
if (arg.complement)
return false;

if (BasicEvent* const* basic_event =
std::get_if<BasicEvent*>(&arg.event)) {
return (*basic_event)->HasAttribute("flavor") &&
(*basic_event)->GetAttribute("flavor").value == "conditional";
}

return false;
});
if (num_conditional != 1)
SCRAM_THROW(ValidityError(Element::name() + " : INHIBIT gate must have" +
" exactly one conditional event."));
}

void Formula::ArgSet::Add(ArgEvent event, bool complement) {
Event* base = ext::as<Event*>(event);
if (ext::any_of(args_, [&base](const Arg& arg) {
Expand Down
7 changes: 0 additions & 7 deletions src/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,6 @@ class Gate : public Event, public NodeMark {
return formula;
}

/// Checks if a gate is initialized correctly.
///
/// @pre The gate formula is set.
///
/// @throws ValidityError Errors in the gate's logic or setup.
void Validate() const;

private:
FormulaPtr formula_; ///< Boolean formula of this gate.
};
Expand Down
6 changes: 0 additions & 6 deletions src/initializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -429,12 +429,6 @@ void Initializer::Define(const xml::Element& gate_node, Gate* gate) {
assert(!formulas.empty() && ++formulas.begin() == formulas.end());
assert(!gate->HasFormula() && "Resetting gate formula");
gate->formula(GetFormula(*formulas.begin(), gate->base_path()));
try {
gate->Validate();
} catch (ValidityError& err) {
err << boost::errinfo_at_line(gate_node.line());
throw;
}
}

template <>
Expand Down
19 changes: 0 additions & 19 deletions tests/event_tests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -285,25 +285,6 @@ TEST_CASE("FormulaTest.Validate", "[mef::event]") {
}
}

TEST_CASE("MEFGateTest.Inhibit", "[mef::event]") {
BasicEvent arg_one("a");
BasicEvent arg_two("b");
BasicEvent arg_three("c");
// INHIBIT Gate tests.
Gate top("top");
top.AddAttribute({"flavor", "inhibit"});
top.formula(FormulaPtr(new Formula(kAnd, {&arg_one, &arg_two})));
CHECK_THROWS_AS(top.Validate(), ValidityError);
arg_one.AddAttribute({"flavor", "conditional"});
CHECK_NOTHROW(top.Validate());
arg_two.AddAttribute({"flavor", "conditional"});
CHECK_THROWS_AS(top.Validate(), ValidityError);
arg_two.RemoveAttribute("flavor");
CHECK_NOTHROW(top.Validate());
top.formula(FormulaPtr(new Formula(kAnd, {&arg_one, &arg_two, &arg_three})));
CHECK_THROWS_AS(top.Validate(), ValidityError);
}

TEST_CASE("PrimaryEventTest.HouseProbability", "[mef::event]") {
// House primary event.
HouseEvent primary("valve");
Expand Down

0 comments on commit 24c62ca

Please sign in to comment.