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
194 lines
10 KiB
#pragma once
|
|
|
|
#include <memory>
|
|
|
|
#include <boost/filesystem.hpp>
|
|
#include <boost/dll/import.hpp>
|
|
#include <boost/function.hpp>
|
|
|
|
#include "cpptempl.h"
|
|
|
|
#include "storm/adapters/CarlAdapter.h"
|
|
|
|
#include "storm/storage/jani/Model.h"
|
|
#include "storm/storage/jani/ParallelComposition.h"
|
|
#include "storm/storage/expressions/ToCppVisitor.h"
|
|
|
|
#include "storm/builder/BuilderOptions.h"
|
|
#include "storm/builder/jit/JitModelBuilderInterface.h"
|
|
#include "storm/builder/jit/ModelComponentsBuilder.h"
|
|
|
|
namespace storm {
|
|
namespace models {
|
|
namespace sparse {
|
|
template <typename ValueType, typename RewardModelType>
|
|
class Model;
|
|
|
|
template <typename ValueType>
|
|
class StandardRewardModel;
|
|
}
|
|
}
|
|
|
|
namespace builder {
|
|
namespace jit {
|
|
|
|
typedef uint32_t IndexType;
|
|
|
|
template <typename ValueType, typename RewardModelType = storm::models::sparse::StandardRewardModel<ValueType>>
|
|
class ExplicitJitJaniModelBuilder {
|
|
public:
|
|
typedef JitModelBuilderInterface<IndexType, ValueType>* (CreateFunctionType)(ModelComponentsBuilder<IndexType, ValueType>& modelComponentsBuilder);
|
|
typedef boost::function<CreateFunctionType> ImportCreateFunctionType;
|
|
|
|
/*!
|
|
* Creates a model builder for the given model. The provided options are used to determine which part of
|
|
* the model is built.
|
|
*/
|
|
ExplicitJitJaniModelBuilder(storm::jani::Model const& model, storm::builder::BuilderOptions const& options = storm::builder::BuilderOptions());
|
|
|
|
/*!
|
|
* Builds and returns the sparse model.
|
|
*/
|
|
std::shared_ptr<storm::models::sparse::Model<ValueType, RewardModelType>> build();
|
|
|
|
/*!
|
|
* Performs some checks that can help debug why the model builder does not work. Returns true if the
|
|
* general infrastructure for the model builder appears to be working.
|
|
*/
|
|
bool doctor() const;
|
|
|
|
private:
|
|
// Helper methods for the doctor() procedure.
|
|
bool checkTemporaryFileWritable() const;
|
|
bool checkCompilerWorks() const;
|
|
bool checkCompilerFlagsWork() const;
|
|
bool checkBoostAvailable() const;
|
|
bool checkBoostDllAvailable() const;
|
|
bool checkStormHeadersAvailable() const;
|
|
bool checkCarlAvailable() const;
|
|
|
|
/*!
|
|
* Executes the given command. If the command fails with a non-zero error code, the error stream content
|
|
* is returned and boost::none otherwise.
|
|
*/
|
|
static boost::optional<std::string> execute(std::string command);
|
|
|
|
/*!
|
|
* Writes the given content to a temporary file. The temporary file is created to have the provided suffix.
|
|
*/
|
|
static boost::filesystem::path writeToTemporaryFile(std::string const& content, std::string const& suffix = ".cpp");
|
|
|
|
/*!
|
|
* Assembles the information of the model such that it can be put into the source skeleton.
|
|
*/
|
|
cpptempl::data_map generateModelData();
|
|
|
|
void generateVariables(cpptempl::data_map& modelData);
|
|
cpptempl::data_map generateBooleanVariable(storm::jani::BooleanVariable const& variable);
|
|
cpptempl::data_map generateBoundedIntegerVariable(storm::jani::BoundedIntegerVariable const& variable);
|
|
cpptempl::data_map generateUnboundedIntegerVariable(storm::jani::UnboundedIntegerVariable const& variable);
|
|
cpptempl::data_map generateRealVariable(storm::jani::RealVariable const& variable);
|
|
cpptempl::data_map generateLocationVariable(storm::jani::Automaton const& automaton);
|
|
|
|
void generateInitialStates(cpptempl::data_map& modelData);
|
|
void generateRewards(cpptempl::data_map& modelData);
|
|
void generateLocations(cpptempl::data_map& modelData);
|
|
void generateLabels(cpptempl::data_map& modelData);
|
|
void generateTerminalExpressions(cpptempl::data_map& modelData);
|
|
void generateParameters(cpptempl::data_map& modelData);
|
|
|
|
// Functions related to the generation of edge data.
|
|
void generateEdges(cpptempl::data_map& modelData);
|
|
cpptempl::data_map generateSynchronizationVector(cpptempl::data_map& modelData, storm::jani::ParallelComposition const& parallelComposition, storm::jani::SynchronizationVector const& synchronizationVector, uint64_t synchronizationVectorIndex);
|
|
cpptempl::data_list generateLevels(storm::jani::OrderedAssignments const& assignments);
|
|
cpptempl::data_map generateEdge(storm::jani::Automaton const& automaton, uint64_t edgeIndex, storm::jani::Edge const& edge);
|
|
cpptempl::data_map generateDestination(uint64_t destinationIndex, storm::jani::EdgeDestination const& destination, boost::optional<storm::expressions::Expression> const& rate = boost::none);
|
|
template <typename ValueTypePrime>
|
|
cpptempl::data_map generateAssignment(storm::jani::Variable const& variable, ValueTypePrime value) const;
|
|
cpptempl::data_map generateLocationAssignment(storm::jani::Automaton const& automaton, uint64_t value) const;
|
|
cpptempl::data_map generateAssignment(storm::jani::Assignment const& assignment);
|
|
|
|
// Auxiliary functions that perform regularly needed steps.
|
|
std::string const& getVariableName(storm::expressions::Variable const& variable) const;
|
|
std::string const& registerVariable(storm::expressions::Variable const& variable, bool transient = false);
|
|
storm::expressions::Variable const& getLocationVariable(storm::jani::Automaton const& automaton) const;
|
|
storm::expressions::Expression shiftVariablesWrtLowerBound(storm::expressions::Expression const& expression);
|
|
|
|
// Conversion functions.
|
|
template <typename ValueTypePrime>
|
|
std::string asString(ValueTypePrime value) const;
|
|
std::string asString(bool value) const;
|
|
|
|
/*!
|
|
* Creates the source code for the shared library that performs the model generation.
|
|
*
|
|
* @param modelData The assembled data of the model to be put into the blueprint. Note that this is not
|
|
* modified in this function, but the data needs to be passed as non-const to cpptempl.
|
|
*/
|
|
std::string createSourceCodeFromSkeleton(cpptempl::data_map& modelData);
|
|
|
|
/*!
|
|
* Compiles the provided source file to a shared library and returns a path object to the resulting
|
|
* binary file.
|
|
*/
|
|
boost::filesystem::path compileToSharedLibrary(boost::filesystem::path const& sourceFile);
|
|
|
|
/*!
|
|
* Loads the given shared library and creates the builder from it.
|
|
*/
|
|
void createBuilder(boost::filesystem::path const& dynamicLibraryPath);
|
|
|
|
/// The options to use for model building.
|
|
storm::builder::BuilderOptions options;
|
|
|
|
/// The model specification that is to be built.
|
|
storm::jani::Model model;
|
|
|
|
/// A vector of automata that is to be put in parallel. The automata are references from the model specification.
|
|
std::vector<std::reference_wrapper<storm::jani::Automaton const>> parallelAutomata;
|
|
|
|
/// An object that is responsible for building the components of the model. The shared library gets this
|
|
/// as a mechanism to perform a callback in order to register transitions that were found.
|
|
ModelComponentsBuilder<IndexType, ValueType> modelComponentsBuilder;
|
|
|
|
/// The function that was loaded from the shared library. We have to keep this function around, because
|
|
/// otherwise the shared library gets unloaded.
|
|
typename ExplicitJitJaniModelBuilder<ValueType, RewardModelType>::ImportCreateFunctionType jitBuilderCreateFunction;
|
|
|
|
/// The pointer to the builder object created via the shared library.
|
|
std::unique_ptr<JitModelBuilderInterface<IndexType, ValueType>> builder;
|
|
|
|
// Members that store information about the model. They are used in the process of assembling the model
|
|
// data that is used in the skeleton.
|
|
std::unordered_map<storm::expressions::Variable, std::string> variableToName;
|
|
std::map<std::string, storm::expressions::Variable> automatonToLocationVariable;
|
|
storm::expressions::ToCppVisitor expressionTranslator;
|
|
std::map<storm::expressions::Variable, storm::expressions::Expression> lowerBoundShiftSubstitution;
|
|
std::map<storm::expressions::Variable, int_fast64_t> lowerBounds;
|
|
std::set<storm::expressions::Variable> transientVariables;
|
|
std::set<storm::expressions::Variable> nontransientVariables;
|
|
std::set<storm::expressions::Variable> realVariables;
|
|
std::unordered_map<storm::expressions::Variable, std::string> variablePrefixes;
|
|
|
|
/// The compiler binary.
|
|
std::string compiler;
|
|
|
|
/// The flags passed to the compiler.
|
|
std::string compilerFlags;
|
|
|
|
/// The include directory of boost.
|
|
std::string boostIncludeDirectory;
|
|
|
|
/// The include directory of storm.
|
|
std::string stormIncludeDirectory;
|
|
|
|
/// The include directory of carl.
|
|
std::string carlIncludeDirectory;
|
|
|
|
/// A cache that is used by carl.
|
|
std::shared_ptr<carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>> cache;
|
|
};
|
|
|
|
}
|
|
}
|
|
}
|