6#include <carl/formula/Constraint.h>
18namespace transformer {
20 bool keepStateValuations)
const {
21 auto data = transformTransitions(dtmc);
23 components.
stateLabeling = transformStateLabeling(dtmc, data);
25 components.
rewardModels.emplace(rewModel.first, transformRewardModel(dtmc, rewModel.second, data));
32 return std::make_shared<storm::models::sparse::Dtmc<RationalFunction>>(std::move(components.
transitionMatrix), std::move(components.
stateLabeling),
38 std::vector<storage::MatrixEntry<uint64_t, RationalFunction>>
row;
41typename BinaryDtmcTransformer::TransformationData BinaryDtmcTransformer::transformTransitions(
46 std::queue<StateWithRow> queue;
47 for (uint64_t state = 0; state < matrix.getRowCount(); ++state) {
48 std::vector<storage::MatrixEntry<uint64_t, RationalFunction>> diyRow;
49 for (
auto const& entry : matrix.getRow(state)) {
50 diyRow.push_back(entry);
57 uint64_t currAuxState = queue.size();
58 std::vector<uint64_t> origStates;
60 while (!queue.empty()) {
61 auto stateWithRow = std::move(queue.front());
64 std::set<RationalFunctionVariable> variablesInRow;
66 for (
auto const& entry : stateWithRow.row) {
67 for (
auto const& variable : entry.getValue().gatherVariables()) {
68 variablesInRow.emplace(variable);
72 if (variablesInRow.size() == 0) {
74 for (
auto const& entry : stateWithRow.row) {
75 builder.
addNextValue(currRow, entry.getColumn(), entry.getValue());
78 }
else if (variablesInRow.size() == 1) {
79 auto parameter = *variablesInRow.begin();
83 std::vector<storage::MatrixEntry<uint64_t, RationalFunction>> outgoing;
85 std::vector<storage::MatrixEntry<uint64_t, RationalFunction>> newStateLeft;
87 std::vector<storage::MatrixEntry<uint64_t, RationalFunction>> newStateRight;
92 for (
auto const& entry : stateWithRow.row) {
93 if (entry.getValue().isConstant()) {
94 outgoing.push_back(entry);
96 auto nominator = entry.getValue().nominator();
99 if (byP.remainder.isZero()) {
100 auto probability =
RationalFunction(carl::makePolynomial<Polynomial>(byP.quotient), denominator);
101 newStateLeft.push_back(storage::MatrixEntry<uint64_t, RationalFunction>(entry.getColumn(), probability));
102 sumOfLeftBranch += probability;
105 auto byOneMinusP =
RawPolynomial(nominator).divideBy(oneMinusParameter);
106 if (byOneMinusP.remainder.isZero()) {
107 auto probability =
RationalFunction(carl::makePolynomial<Polynomial>(byOneMinusP.quotient), denominator);
108 newStateRight.push_back(storage::MatrixEntry<uint64_t, RationalFunction>(entry.getColumn(), probability));
109 sumOfRightBranch += probability;
114 sumOfLeftBranch.simplify();
115 sumOfRightBranch.simplify();
116 for (
auto& entry : newStateLeft) {
117 entry.setValue(entry.getValue() / sumOfLeftBranch);
119 for (
auto& entry : newStateRight) {
120 entry.setValue(entry.getValue() / sumOfRightBranch);
123 queue.push(StateWithRow{currAuxState, newStateLeft});
124 outgoing.push_back(storage::MatrixEntry<uint64_t, RationalFunction>(
125 currAuxState, (sumOfLeftBranch)*
RationalFunction(carl::makePolynomial<Polynomial>(parameter))));
127 queue.push(StateWithRow{currAuxState, newStateRight});
128 outgoing.push_back(storage::MatrixEntry<uint64_t, RationalFunction>(
129 currAuxState, (sumOfRightBranch) * (utility::one<RationalFunction>() -
RationalFunction(carl::makePolynomial<Polynomial>(parameter)))));
132 for (
auto const& entry : outgoing) {
133 builder.
addNextValue(currRow, entry.getColumn(), entry.getValue());
139 origStates.push_back(stateWithRow.state);
141 TransformationData result;
142 result.simpleMatrix = builder.
build(currRow, currAuxState, currAuxState);
143 result.simpleStateToOriginalState = std::move(origStates);
148 TransformationData
const& data)
const {
150 for (
auto const& labelName : dtmc.getStateLabeling().getLabels()) {
152 newStates.
resize(data.simpleMatrix.getRowCount(),
false);
153 if (labelName !=
"init") {
154 for (uint64_t newState = dtmc.
getNumberOfStates(); newState < data.simpleMatrix.getRowCount(); ++newState) {
155 newStates.
set(newState, newStates[data.simpleStateToOriginalState[newState]]);
158 labeling.addLabel(labelName, std::move(newStates));
165 TransformationData
const& data)
const {
166 std::optional<std::vector<RationalFunction>> stateRewards, actionRewards;
170 stateRewards->resize(data.simpleMatrix.getRowCount(), storm::utility::zero<RationalFunction>());
This class represents a discrete-time Markov chain.
storm::storage::SparseMatrix< ValueType > const & getTransitionMatrix() const
Retrieves the matrix representing the transitions of the model.
std::unordered_map< std::string, RewardModelType > const & getRewardModels() const
Retrieves the reward models.
bool hasStateValuations() const
Retrieves whether this model was build with state valuations.
storm::storage::sparse::StateValuations const & getStateValuations() const
Retrieves the valuations of the states of the model.
storm::models::sparse::StateLabeling const & getStateLabeling() const
Returns the state labeling associated with this model.
virtual uint_fast64_t getNumberOfStates() const override
Returns the number of states of the model.
std::vector< ValueType > const & getStateRewardVector() const
Retrieves the state rewards of the reward model.
bool hasStateRewards() const
Retrieves whether the reward model has state rewards.
bool hasStateActionRewards() const
Retrieves whether the reward model has state-action rewards.
This class manages the labeling of the state space with a number of (atomic) labels.
storm::storage::BitVector const & getStates(std::string const &label) const
Returns the labeling of states associated with the given label.
A bit vector that is internally represented as a vector of 64-bit values.
void set(uint64_t index, bool value=true)
Sets the given truth value at the given index.
void resize(uint64_t newLength, bool init=false)
Resizes the bit vector to hold the given new number of bits.
A class that can be used to build a sparse matrix by adding value by value.
void addNextValue(index_type row, index_type column, value_type const &value)
Sets the matrix entry at the given row and column to the given value.
SparseMatrix< value_type > build(index_type overriddenRowCount=0, index_type overriddenColumnCount=0, index_type overriddenRowGroupCount=0)
StateValuations blowup(std::vector< uint64_t > const &mapNewToOld) const
#define STORM_LOG_ERROR(message)
#define STORM_LOG_THROW(cond, exception, message)
NumberTraits< RationalType >::IntegerType denominator(RationalType const &number)
carl::RationalFunction< Polynomial, true > RationalFunction
carl::MultivariatePolynomial< RationalFunctionCoefficient > RawPolynomial
std::optional< storm::storage::sparse::StateValuations > stateValuations
std::unordered_map< std::string, RewardModelType > rewardModels
storm::storage::SparseMatrix< ValueType > transitionMatrix
storm::models::sparse::StateLabeling stateLabeling