You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
10 KiB

  1. #pragma once
  2. #include <memory>
  3. #include <boost/filesystem.hpp>
  4. #include <boost/dll/import.hpp>
  5. #include <boost/function.hpp>
  6. #include "cpptempl.h"
  7. #include "storm/adapters/CarlAdapter.h"
  8. #include "storm/storage/jani/Model.h"
  9. #include "storm/storage/jani/ParallelComposition.h"
  10. #include "storm/storage/expressions/ToCppVisitor.h"
  11. #include "storm/builder/BuilderOptions.h"
  12. #include "storm/builder/jit/JitModelBuilderInterface.h"
  13. #include "storm/builder/jit/ModelComponentsBuilder.h"
  14. namespace storm {
  15. namespace models {
  16. namespace sparse {
  17. template <typename ValueType, typename RewardModelType>
  18. class Model;
  19. template <typename ValueType>
  20. class StandardRewardModel;
  21. }
  22. }
  23. namespace builder {
  24. namespace jit {
  25. typedef uint32_t IndexType;
  26. template <typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>>
  27. class ExplicitJitJaniModelBuilder {
  28. public:
  29. typedef JitModelBuilderInterface<IndexType, ValueType>* (CreateFunctionType)(ModelComponentsBuilder<IndexType, ValueType>& modelComponentsBuilder);
  30. typedef boost::function<CreateFunctionType> ImportCreateFunctionType;
  31. /*!
  32. * Creates a model builder for the given model. The provided options are used to determine which part of
  33. * the model is built.
  34. */
  35. ExplicitJitJaniModelBuilder(storm::jani::Model const& model, storm::builder::BuilderOptions const& options = storm::builder::BuilderOptions());
  36. /*!
  37. * Builds and returns the sparse model.
  38. */
  39. std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> build();
  40. /*!
  41. * Performs some checks that can help debug why the model builder does not work. Returns true if the
  42. * general infrastructure for the model builder appears to be working.
  43. */
  44. bool doctor() const;
  45. private:
  46. // Helper methods for the doctor() procedure.
  47. bool checkTemporaryFileWritable() const;
  48. bool checkCompilerWorks() const;
  49. bool checkCompilerFlagsWork() const;
  50. bool checkBoostAvailable() const;
  51. bool checkBoostDllAvailable() const;
  52. bool checkStormHeadersAvailable() const;
  53. bool checkCarlAvailable() const;
  54. /*!
  55. * Executes the given command. If the command fails with a non-zero error code, the error stream content
  56. * is returned and boost::none otherwise.
  57. */
  58. static boost::optional<std::string> execute(std::string command);
  59. /*!
  60. * Writes the given content to a temporary file. The temporary file is created to have the provided suffix.
  61. */
  62. static boost::filesystem::path writeToTemporaryFile(std::string const& content, std::string const& suffix = ".cpp");
  63. /*!
  64. * Assembles the information of the model such that it can be put into the source skeleton.
  65. */
  66. cpptempl::data_map generateModelData();
  67. void generateVariables(cpptempl::data_map& modelData);
  68. cpptempl::data_map generateBooleanVariable(storm::jani::BooleanVariable const& variable);
  69. cpptempl::data_map generateBoundedIntegerVariable(storm::jani::BoundedIntegerVariable const& variable);
  70. cpptempl::data_map generateUnboundedIntegerVariable(storm::jani::UnboundedIntegerVariable const& variable);
  71. cpptempl::data_map generateRealVariable(storm::jani::RealVariable const& variable);
  72. cpptempl::data_map generateLocationVariable(storm::jani::Automaton const& automaton);
  73. void generateInitialStates(cpptempl::data_map& modelData);
  74. void generateRewards(cpptempl::data_map& modelData);
  75. void generateLocations(cpptempl::data_map& modelData);
  76. void generateLabels(cpptempl::data_map& modelData);
  77. void generateTerminalExpressions(cpptempl::data_map& modelData);
  78. void generateParameters(cpptempl::data_map& modelData);
  79. // Functions related to the generation of edge data.
  80. void generateEdges(cpptempl::data_map& modelData);
  81. cpptempl::data_map generateSynchronizationVector(cpptempl::data_map& modelData, storm::jani::ParallelComposition const& parallelComposition, storm::jani::SynchronizationVector const& synchronizationVector, uint64_t synchronizationVectorIndex);
  82. cpptempl::data_list generateLevels(storm::jani::OrderedAssignments const& assignments);
  83. cpptempl::data_map generateEdge(storm::jani::Automaton const& automaton, uint64_t edgeIndex, storm::jani::Edge const& edge);
  84. cpptempl::data_map generateDestination(uint64_t destinationIndex, storm::jani::EdgeDestination const& destination, boost::optional<storm::expressions::Expression> const& rate = boost::none);
  85. template <typename ValueTypePrime>
  86. cpptempl::data_map generateAssignment(storm::jani::Variable const& variable, ValueTypePrime value) const;
  87. cpptempl::data_map generateLocationAssignment(storm::jani::Automaton const& automaton, uint64_t value) const;
  88. cpptempl::data_map generateAssignment(storm::jani::Assignment const& assignment);
  89. // Auxiliary functions that perform regularly needed steps.
  90. std::string const& getVariableName(storm::expressions::Variable const& variable) const;
  91. std::string const& registerVariable(storm::expressions::Variable const& variable, bool transient = false);
  92. storm::expressions::Variable const& getLocationVariable(storm::jani::Automaton const& automaton) const;
  93. storm::expressions::Expression shiftVariablesWrtLowerBound(storm::expressions::Expression const& expression);
  94. // Conversion functions.
  95. template <typename ValueTypePrime>
  96. std::string asString(ValueTypePrime value) const;
  97. std::string asString(bool value) const;
  98. /*!
  99. * Creates the source code for the shared library that performs the model generation.
  100. *
  101. * @param modelData The assembled data of the model to be put into the blueprint. Note that this is not
  102. * modified in this function, but the data needs to be passed as non-const to cpptempl.
  103. */
  104. std::string createSourceCodeFromSkeleton(cpptempl::data_map& modelData);
  105. /*!
  106. * Compiles the provided source file to a shared library and returns a path object to the resulting
  107. * binary file.
  108. */
  109. boost::filesystem::path compileToSharedLibrary(boost::filesystem::path const& sourceFile);
  110. /*!
  111. * Loads the given shared library and creates the builder from it.
  112. */
  113. void createBuilder(boost::filesystem::path const& dynamicLibraryPath);
  114. /// The options to use for model building.
  115. storm::builder::BuilderOptions options;
  116. /// The model specification that is to be built.
  117. storm::jani::Model model;
  118. /// A vector of automata that is to be put in parallel. The automata are references from the model specification.
  119. std::vector<std::reference_wrapper<storm::jani::Automaton const>> parallelAutomata;
  120. /// An object that is responsible for building the components of the model. The shared library gets this
  121. /// as a mechanism to perform a callback in order to register transitions that were found.
  122. ModelComponentsBuilder<IndexType, ValueType> modelComponentsBuilder;
  123. /// The function that was loaded from the shared library. We have to keep this function around, because
  124. /// otherwise the shared library gets unloaded.
  125. typename ExplicitJitJaniModelBuilder<ValueType, RewardModelType>::ImportCreateFunctionType jitBuilderCreateFunction;
  126. /// The pointer to the builder object created via the shared library.
  127. std::unique_ptr<JitModelBuilderInterface<IndexType, ValueType>> builder;
  128. // Members that store information about the model. They are used in the process of assembling the model
  129. // data that is used in the skeleton.
  130. std::unordered_map<storm::expressions::Variable, std::string> variableToName;
  131. std::map<std::string, storm::expressions::Variable> automatonToLocationVariable;
  132. storm::expressions::ToCppVisitor expressionTranslator;
  133. std::map<storm::expressions::Variable, storm::expressions::Expression> lowerBoundShiftSubstitution;
  134. std::map<storm::expressions::Variable, int_fast64_t> lowerBounds;
  135. std::set<storm::expressions::Variable> transientVariables;
  136. std::set<storm::expressions::Variable> nontransientVariables;
  137. std::set<storm::expressions::Variable> realVariables;
  138. std::unordered_map<storm::expressions::Variable, std::string> variablePrefixes;
  139. /// The compiler binary.
  140. std::string compiler;
  141. /// The flags passed to the compiler.
  142. std::string compilerFlags;
  143. /// The include directory of boost.
  144. std::string boostIncludeDirectory;
  145. /// The include directory of storm.
  146. std::string stormIncludeDirectory;
  147. /// The include directory of carl.
  148. std::string carlIncludeDirectory;
  149. /// A cache that is used by carl.
  150. std::shared_ptr<carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>> cache;
  151. };
  152. }
  153. }
  154. }