Skip to content

packages/engine/scram-node/src/instruction.h

Model and event tree modifier instructions.

Namespaces

Name
scram
scram::mef

Classes

Name
classscram::mef::Instruction <br>Instructions and rules for event tree paths.
classscram::mef::Visitable <br>Default visit for instruction type of T.
classscram::mef::SetHouseEvent <br>The operation to change house-events.
classscram::mef::CollectExpression <br>The operation of collecting expressions for event tree sequences.
classscram::mef::CollectFormula <br>The operation of connecting fault tree events into the event tree.
classscram::mef::IfThenElse <br>Conditional application of instructions.
classscram::mef::Block <br>Compound instructions.
classscram::mef::Rule <br>A reusable collection of instructions.
classscram::mef::Link <br>A link to another event tree in end-states only.
classscram::mef::InstructionVisitor <br>The base abstract class for instruction visitors.
classscram::mef::NullVisitor <br>Visits only instructions and ignores non-instructions.

Source code

cpp
/*
 * Copyright (C) 2014-2018 Olzhas Rakhimov
 * Copyright (C) 2023 OpenPRA ORG Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#pragma once

#include <memory>
#include <string>
#include <vector>

#include <boost/noncopyable.hpp>

#include "element.h"
#include "event.h"
#include "expression.h"

namespace scram::mef {

class InstructionVisitor;

class Instruction : private boost::noncopyable {
 public:
  virtual ~Instruction() = default;

  virtual void Accept(InstructionVisitor* visitor) const = 0;
};

template <class T>
class Visitable : public Instruction {
 public:
  void Accept(InstructionVisitor* visitor) const final;
};

class SetHouseEvent : public Visitable<SetHouseEvent> {
 public:
  SetHouseEvent(std::string name, bool state)
      : name_(std::move(name)), state_(state) {}

  const std::string& name() const { return name_; }

  bool state() const { return state_; }

 private:
  std::string name_;  
  bool state_;  
};

class CollectExpression : public Visitable<CollectExpression> {
 public:
  explicit CollectExpression(Expression* expression)
      : expression_(expression) {}

  Expression& expression() const { return *expression_; }

 private:
  Expression* expression_;  
};

class CollectFormula : public Visitable<CollectFormula> {
 public:
  explicit CollectFormula(std::unique_ptr<Formula> formula)
      : formula_(std::move(formula)) {}

  Formula& formula() const { return *formula_; }

 private:
  std::unique_ptr<Formula> formula_;  
};

class IfThenElse : public Visitable<IfThenElse> {
 public:
  IfThenElse(Expression* expression, Instruction* then_instruction,
             Instruction* else_instruction = nullptr)
      : expression_(expression),
        then_instruction_(std::move(then_instruction)),
        else_instruction_(std::move(else_instruction)) {}

  Expression* expression() const { return expression_; }

  Instruction* then_instruction() const { return then_instruction_; }

  Instruction* else_instruction() const { return else_instruction_; }

 private:
  Expression* expression_;  
  Instruction* then_instruction_;  
  Instruction* else_instruction_;  
};

class Block : public Visitable<Block> {
 public:
  explicit Block(std::vector<Instruction*> instructions)
      : instructions_(std::move(instructions)) {}

  const std::vector<Instruction*>& instructions() const {
    return instructions_;
  }

 private:
  std::vector<Instruction*> instructions_;  
};

class Rule : public Element,
             public Visitable<Rule>,
             public NodeMark,
             public Usage {
 public:
  static constexpr const char* kTypeString = "rule";  

  using Element::Element;

  void instructions(std::vector<Instruction*> instructions) {
    assert(!instructions.empty());
    instructions_ = std::move(instructions);
  }

  const std::vector<Instruction*>& instructions() const {
    return instructions_;
  }

 private:
  std::vector<Instruction*> instructions_;  
};

class EventTree;  // The target of the Link (avoid dependency cycle).

class Link : public Visitable<Link>, public NodeMark {
 public:
  explicit Link(const EventTree& event_tree) : event_tree_(event_tree) {}

  const EventTree& event_tree() const { return event_tree_; }

 private:
  const EventTree& event_tree_;  
};

class InstructionVisitor {
 public:
  virtual ~InstructionVisitor() = default;

  virtual void Visit(const SetHouseEvent*) = 0;
  virtual void Visit(const CollectExpression*) = 0;
  virtual void Visit(const CollectFormula*) = 0;
  virtual void Visit(const Link*) = 0;
  virtual void Visit(const IfThenElse* ite) {
    if (ite->expression()->value()) {
      ite->then_instruction()->Accept(this);
    } else if (ite->else_instruction()) {
      ite->else_instruction()->Accept(this);
    }
  }
  virtual void Visit(const Block* block) {
    for (const Instruction* instruction : block->instructions())
      instruction->Accept(this);
  }
  virtual void Visit(const Rule* rule) {
    for (const Instruction* instruction : rule->instructions())
      instruction->Accept(this);
  }
};

class NullVisitor : public InstructionVisitor {
 public:
  void Visit(const SetHouseEvent*) override {}
  void Visit(const CollectExpression*) override {}
  void Visit(const CollectFormula*) override {}
  void Visit(const Link*) override {}
  void Visit(const IfThenElse* ite) override {
    ite->then_instruction()->Accept(this);
    if (ite->else_instruction())
      ite->else_instruction()->Accept(this);
  }
};

template <class T>
void Visitable<T>::Accept(InstructionVisitor* visitor) const {
  visitor->Visit(static_cast<const T*>(this));
}

}  // namespace scram::mef

Updated on 2025-11-11 at 16:51:08 +0000