Skip to content

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

A facility that processes input files into analysis constructs.

Namespaces

Name
scram
scram::mef

Classes

Name
classscram::mef::Initializer <br>This class operates on input files to initialize analysis constructs like models, fault trees, and events.

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 <functional>
#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>
#include <utility>
#include <variant>
#include <vector>

#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/noncopyable.hpp>

#include "alignment.h"
#include "ccf_group.h"
#include "element.h"
#include "event.h"
#include "event_tree.h"
#include "expression.h"
#include "expression/constant.h"
#include "fault_tree.h"
#include "instruction.h"
#include "model.h"
#include "parameter.h"
#include "settings.h"
#include "substitution.h"
#include "xml.h"

namespace scram::mef {

class Initializer : private boost::noncopyable {
 public:
  Initializer(const std::vector<std::string>& xml_files,
              core::Settings settings, bool allow_extern = false,
              xml::Validator* extra_validator = nullptr);

  std::unique_ptr<Model> model() && { return std::move(model_); }

 private:
  using ExtractorFunction = std::unique_ptr<Expression> (*)(
      const xml::Element::Range&, const std::string&, Initializer*);
  using ExtractorMap = std::unordered_map<std::string_view, ExtractorFunction>;
  template <class... Ts>
  using TbdContainer =
      std::vector<std::pair<std::variant<Ts*...>, xml::Element>>;
  template <typename T>
  using PathTable = boost::multi_index_container<
      T*, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<
              boost::multi_index::const_mem_fun<Id, std::string_view,
                                                &Id::full_path>,
              std::hash<std::string_view>>>>;

  template <class T, int N>
  struct Extractor;

  static const ExtractorMap kExpressionExtractors_;

  template <class T>
  static std::unique_ptr<Expression> Extract(const xml::Element::Range& args,
                                             const std::string& base_path,
                                             Initializer* init);

  void CheckFileExistence(const std::vector<std::string>& xml_files);

  void CheckDuplicateFiles(const std::vector<std::string>& xml_files);

  void ProcessInputFiles(const std::vector<std::string>& xml_files);

  void ProcessInputFile(const xml::Document& document);

  void ProcessTbdElements();

  template <class T>
  void Register(std::unique_ptr<T> element, const xml::Element& xml_element);

  template <class T>
  T* Register(const xml::Element& xml_node, const std::string& base_path,
              RoleSpecifier base_role);

  template <class T>
  void Define(const xml::Element& xml_node, T* element);

  void DefineEventTree(const xml::Element& et_node);

  void DefineFaultTree(const xml::Element& ft_node);

  std::unique_ptr<Component> DefineComponent(const xml::Element& component_node,
                                             const std::string& base_path,
                                             RoleSpecifier container_role);

  void RegisterFaultTreeData(const xml::Element& ft_node,
                             const std::string& base_path,
                             Component* component);

  void ProcessModelData(const xml::Element& model_data);

  std::unique_ptr<Formula> GetFormula(const xml::Element& formula_node,
                                      const std::string& base_path);

  template <class SinglePassRange>
  void DefineBranch(const SinglePassRange& xml_nodes, EventTree* event_tree,
                    Branch* branch);

  void DefineBranchTarget(const xml::Element& target_node,
                          EventTree* event_tree, Branch* branch);

  Instruction* GetInstruction(const xml::Element& xml_element);

  Expression* GetExpression(const xml::Element& expr_element,
                            const std::string& base_path);

  Expression* GetParameter(const std::string_view& expr_type,
                           const xml::Element& expr_element,
                           const std::string& base_path);

  void ProcessCcfMembers(const xml::Element& members_node, CcfGroup* ccf_group);

  void DefineCcfFactor(const xml::Element& factor_node, CcfGroup* ccf_group);

  Parameter* GetParameter(std::string_view entity_reference,
                          const std::string& base_path);
  HouseEvent* GetHouseEvent(std::string_view entity_reference,
                            const std::string& base_path);
  BasicEvent* GetBasicEvent(std::string_view entity_reference,
                            const std::string& base_path);
  Gate* GetGate(std::string_view entity_reference,
                const std::string& base_path);
  Formula::ArgEvent GetEvent(std::string_view entity_reference,
                             const std::string& base_path);

  template <class P, class T = typename P::element_type>
  T* GetEntity(std::string_view entity_reference, const std::string& base_path,
               const TableRange<IdTable<P>>& container,
               const TableRange<PathTable<T>>& path_container);

  void DefineExternLibraries(const xml::Element& xml_node);

  void DefineExternFunction(const xml::Element& xml_element);

  void ValidateInitialization();

  void CheckFunctionalEventOrder(const Branch& branch);

  void EnsureLinksOnlyInSequences(const Branch& branch);

  void EnsureHomogeneousEventTree(const Branch& branch);

  void EnsureNoSubstitutionConflicts();

  void ValidateExpressions();

  void SetupForAnalysis();

  void EnsureNoCcfSubstitutions();

  void EnsureSubstitutionsWithApproximations();

  std::unique_ptr<Model> model_;  
  core::Settings settings_;  
  bool allow_extern_;  
  xml::Validator* extra_validator_;  

  std::vector<xml::Document> documents_;

  TbdContainer<Parameter, BasicEvent, Gate, CcfGroup, Sequence, EventTree,
               InitiatingEvent, Rule, Alignment, Substitution>
      tbd_;

  std::vector<std::pair<Expression*, xml::Element>> expressions_;
  std::vector<Link*> links_;

  PathTable<Gate> path_gates_;
  PathTable<BasicEvent> path_basic_events_;
  PathTable<HouseEvent> path_house_events_;
  PathTable<Parameter> path_parameters_;
};

}  // namespace scram::mef

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