12template<
typename ValueType,
typename StateType>
14 :
ImcaParserGrammar<ValueType, StateType>::base_type(start), numStates(0), numChoices(0), numTransitions(0), hasStateReward(false), hasActionReward(false) {
19template<
typename ValueType,
typename StateType>
21 value = qi::double_[qi::_val = qi::_1];
26 state = qi::as_string[qi::raw[qi::lexeme[(qi::alnum | qi::char_(
'_')) % qi::eps]]]
30 reward = (-qi::lit(
"R") >> value)[qi::_val = qi::_1];
31 reward.name(
"reward");
33 transition = (qi::lit(
"*") >> state >>
35 transition.name(
"transition");
37 choicelabel = qi::as_string[qi::raw[qi::lexeme[((qi::alpha | qi::char_(
'_')) >> *(qi::alnum | qi::char_(
'_')) | qi::lit(
"!"))]]];
38 choicelabel.name(
"choicelabel");
41 (state >> choicelabel >> -reward >>
44 choice.name(
"choice");
46 transitions = qi::lit(
"#TRANSITIONS") >> *(choice);
47 transitions.name(
"TRANSITIONS");
51 initials.name(
"INITIALS");
60template<
typename ValueType,
typename StateType>
61StateType ImcaParserGrammar<ValueType, StateType>::getStateIndex(std::string
const& stateString) {
62 auto it = stateIndices.find(stateString);
63 if (it == stateIndices.end()) {
64 this->stateIndices.emplace_hint(it, stateString, numStates);
66 initialStates.grow(numStates);
67 goalStates.grow(numStates);
68 markovianStates.grow(numStates);
69 stateBehaviors.resize(numStates);
76template<
typename ValueType,
typename StateType>
77std::pair<StateType, ValueType> ImcaParserGrammar<ValueType, StateType>::createStateValuePair(StateType
const& state, ValueType
const& value) {
78 return std::pair<StateType, ValueType>(state, value);
81template<
typename ValueType,
typename StateType>
82void ImcaParserGrammar<ValueType, StateType>::addInitialState(StateType
const& state) {
83 initialStates.set(state);
86template<
typename ValueType,
typename StateType>
87void ImcaParserGrammar<ValueType, StateType>::addGoalState(StateType
const& state) {
88 goalStates.set(state);
91template<
typename ValueType,
typename StateType>
92void ImcaParserGrammar<ValueType, StateType>::addChoiceToStateBehavior(StateType
const& state, std::string
const& label,
93 std::vector<std::pair<StateType, ValueType>>
const& transitions,
94 boost::optional<ValueType>
const& reward) {
95 bool isMarkovian = label ==
"!";
97 STORM_LOG_THROW(!transitions.empty(), storm::exceptions::WrongFormatException,
"Empty choice defined for state s" << state <<
".");
98 if (buildChoiceLabels && !isMarkovian) {
99 choice.addLabel(label);
101 if (reward && !isMarkovian) {
102 hasActionReward =
true;
103 choice.addReward(reward.get());
105 for (
auto const& t : transitions) {
106 STORM_LOG_THROW(t.second > storm::utility::zero<ValueType>(), storm::exceptions::WrongFormatException,
107 "Probabilities and rates have to be positive. got " << t.second <<
" at state s" << state <<
".");
108 choice.addProbability(t.first, t.second);
111 "Probability for choice " << label <<
" on state s" << state <<
" does not sum up to one.");
114 numTransitions += choice.size();
115 auto& behavior = stateBehaviors[state];
116 behavior.setExpanded(
true);
117 behavior.addChoice(std::move(choice));
119 markovianStates.set(state);
121 hasStateReward =
true;
122 behavior.addStateReward(reward.get());
127template<
typename ValueType,
typename StateType>
130 initialStates.resize(numStates);
131 goalStates.resize(numStates);
132 markovianStates.resize(numStates);
134 stateLabeling.addLabel(
"init", std::move(initialStates));
135 stateLabeling.addLabel(
"goal", std::move(goalStates));
138 assert(stateBehaviors.size() == numStates);
141 for (
auto& behavior : stateBehaviors) {
142 if (!behavior.wasExpanded()) {
144 choice.addProbability(state, storm::utility::one<ValueType>());
145 behavior.setExpanded(
true);
146 behavior.addChoice(std::move(choice));
147 markovianStates.set(state);
157 std::vector<ValueType> exitRates;
158 exitRates.reserve(numStates);
159 std::optional<std::vector<ValueType>> stateRewards, actionRewards;
160 if (hasStateReward) {
161 stateRewards = std::vector<ValueType>(numStates, storm::utility::zero<ValueType>());
163 if (hasActionReward) {
164 actionRewards = std::vector<ValueType>(numChoices, storm::utility::zero<ValueType>());
166 std::optional<storm::models::sparse::ChoiceLabeling> choiceLabeling;
167 if (buildChoiceLabels) {
172 for (
auto const& behavior : stateBehaviors) {
173 matrixBuilder.newRowGroup(row);
174 if (!behavior.getStateRewards().empty()) {
175 assert(behavior.getStateRewards().size() == 1);
176 stateRewards.value()[state] = behavior.getStateRewards().front();
178 if (markovianStates.get(state)) {
180 bool markovianChoiceFound =
false;
181 for (
auto const& choice : behavior) {
182 if (choice.isMarkovian()) {
183 STORM_LOG_THROW(!markovianChoiceFound, storm::exceptions::WrongFormatException,
184 "Multiple Markovian choices defined for state " << state <<
".");
185 markovianChoiceFound =
true;
186 if (!choice.getRewards().empty()) {
187 assert(choice.getRewards().size() == 1);
188 actionRewards.value()[row] = choice.getRewards().front();
190 if (buildChoiceLabels && choice.hasLabels()) {
191 assert(choice.getLabels().size() == 1);
192 std::string
const& label = *choice.getLabels().begin();
193 if (!choiceLabeling->containsLabel(label)) {
194 choiceLabeling->addLabel(label);
196 choiceLabeling->addLabelToChoice(label, row);
198 exitRates.push_back(choice.getTotalMass());
199 for (
auto const& transition : choice) {
200 matrixBuilder.addNextValue(row, transition.first,
static_cast<ValueType>(transition.second / exitRates.back()));
206 exitRates.push_back(storm::utility::zero<ValueType>());
209 for (
auto const& choice : behavior) {
210 if (!choice.isMarkovian()) {
211 if (!choice.getRewards().empty()) {
212 assert(choice.getRewards().size() == 1);
213 actionRewards.value()[row] = choice.getRewards().front();
215 if (buildChoiceLabels && choice.hasLabels()) {
216 assert(choice.getLabels().size() == 1);
217 std::string
const& label = *choice.getLabels().begin();
218 if (!choiceLabeling->containsLabel(label)) {
219 choiceLabeling->addLabel(label);
221 choiceLabeling->addLabelToChoice(label, row);
223 for (
auto const& transition : choice) {
224 matrixBuilder.addNextValue(row, transition.first, transition.second);
233 std::unordered_map<std::string, storm::models::sparse::StandardRewardModel<ValueType>> rewardModel;
234 if (hasStateReward || hasActionReward) {
238 std::move(markovianStates));
239 components.exitRates = std::move(exitRates);
240 components.choiceLabeling = std::move(choiceLabeling);
245template class ImcaParserGrammar<double>;
This class manages the labeling of the choice space with a number of (atomic) labels.
This class manages the labeling of the state space with a number of (atomic) labels.
A class that can be used to build a sparse matrix by adding value by value.
#define STORM_LOG_THROW(cond, exception, message)
SFTBDDChecker::ValueType ValueType
SettingsType const & getModule()
Get module.
bool isOne(ValueType const &a)