Browse Source

Intermediate commit: fixed parsing bug and started reward generation (DD).

Former-commit-id: a27c815831
tempestpy_adaptions
dehnert 10 years ago
parent
commit
7c2f60175e
  1. 110
      src/builder/DdPrismModelBuilder.cpp
  2. 4
      src/builder/DdPrismModelBuilder.h
  3. 50
      src/parser/FormulaParser.cpp
  4. 7
      src/parser/FormulaParser.h

110
src/builder/DdPrismModelBuilder.cpp

@ -377,6 +377,19 @@ namespace storm {
return ModuleDecisionDiagram(independentActionDd, actionIndexToDdMap, generationInfo.moduleToIdentityMap.at(module.getName()), numberOfUsedNondeterminismVariables);
}
template <storm::dd::DdType Type>
storm::dd::Dd<Type> DdPrismModelBuilder<Type>::getSynchronizationDecisionDiagram(GenerationInformation& generationInfo, boost::optional<uint_fast64_t> const& synchronizationAction) {
storm::dd::Dd<Type> synchronization = generationInfo.manager->getOne(true);
for (uint_fast64_t i = 0; i < generationInfo.synchronizationMetaVariables.size(); ++i) {
if (synchronizationAction && synchronizationAction.get() == i) {
synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 1, true);
} else {
synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 0, true);
}
}
return synchronization;
}
template <storm::dd::DdType Type>
storm::dd::Dd<Type> DdPrismModelBuilder<Type>::createSystemFromModule(GenerationInformation& generationInfo, ModuleDecisionDiagram const& module) {
// If the model is an MDP, we need to encode the nondeterminism using additional variables.
@ -405,24 +418,10 @@ namespace storm {
}
// Add variables for synchronization.
storm::dd::Dd<Type> synchronization = generationInfo.manager->getOne(true);
for (uint_fast64_t i = 0; i < generationInfo.synchronizationMetaVariables.size(); ++i) {
synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 0, true);
}
result *= synchronization;
result *= getSynchronizationDecisionDiagram(generationInfo);
for (auto& synchronizingAction : synchronizingActionToDdMap) {
synchronization = generationInfo.manager->getOne(true);
for (uint_fast64_t i = 0; i < generationInfo.synchronizationMetaVariables.size(); ++i) {
if (i == synchronizingAction.first) {
synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 1, true);
} else {
synchronization *= generationInfo.manager->getEncoding(generationInfo.synchronizationMetaVariables[i], 0, true);
}
}
synchronizingAction.second *= synchronization;
synchronizingAction.second *= getSynchronizationDecisionDiagram(generationInfo, synchronizingAction.first);
}
// Now, we can simply add all synchronizing actions to the result.
@ -516,6 +515,64 @@ namespace storm {
return std::make_pair(result, system);
}
template <storm::dd::DdType Type>
std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>> DdPrismModelBuilder<Type>::createRewardDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, storm::dd::Dd<Type> transitionMatrix) {
// Start by creating the state reward vector.
storm::dd::Dd<Type> stateRewards = generationInfo.manager->getZero();
for (auto const& stateReward : rewardModel.getStateRewards()) {
storm::dd::Dd<Type> states = generationInfo.rowExpressionAdapter->translateExpression(stateReward.getStatePredicateExpression());
storm::dd::Dd<Type> rewards = generationInfo.rowExpressionAdapter->translateExpression(stateReward.getRewardValueExpression());
// Restrict the rewards to those states that satisfy the condition.
rewards = states * rewards;
// Perform some sanity checks.
STORM_LOG_WARN_COND(rewards.getMin() >= 0, "The reward model assigns negative rewards to some states.");
STORM_LOG_WARN_COND(!rewards.isZero(), "The reward model does not assign any non-zero rewards.");
// Add the rewards to the global state reward vector.
stateRewards += rewards;
}
// Then build the transition reward matrix.
storm::dd::Dd<Type> transitionRewards = generationInfo.manager->getZero();
for (auto const& transitionReward : rewardModel.getTransitionRewards()) {
storm::dd::Dd<Type> states = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getStatePredicateExpression());
storm::dd::Dd<Type> rewards = generationInfo.rowExpressionAdapter->translateExpression(transitionReward.getRewardValueExpression());
storm::dd::Dd<Type> synchronization;
if (transitionReward.isLabeled()) {
synchronization = getSynchronizationDecisionDiagram(generationInfo);
} else {
synchronization = getSynchronizationDecisionDiagram(generationInfo, transitionReward.getActionIndex());
}
storm::dd::Dd<Type> transitionRewardDd = synchronization * states * rewards;
if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::MDP) {
transitionRewardDd += transitionMatrix.notZero() * transitionRewardDd;
} else {
transitionRewardDd += transitionMatrix * transitionRewardDd;
}
// Perform some sanity checks.
STORM_LOG_WARN_COND(transitionRewardDd.getMin() >= 0, "The reward model assigns negative rewards to some states.");
STORM_LOG_WARN_COND(!transitionRewardDd.isZero(), "The reward model does not assign any non-zero rewards.");
// Add the rewards to the global transition reward matrix.
transitionRewards += transitionRewardDd;
}
// Scale transition rewards for DTMCs
if (generationInfo.program.getModelType() == storm::prism::Program::ModelType::DTMC) {
for (uint_fast64_t i = 0; i < generationInfo.program.getRewardModels().size(); ++i){
// Divide transition rewards through transition matrix
transitionRewardsDds[i] = transitionRewardsDds[i] / systemDds.independentActionDd.commandsDd;
}
}
return std::make_pair(stateRewards, transitionRewards);
}
template <storm::dd::DdType Type>
std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>> DdPrismModelBuilder<Type>::translateProgram(storm::prism::Program const& program, Options const& options) {
// There might be nondeterministic variables. In that case the program must be prepared before translating.
@ -597,6 +654,25 @@ namespace storm {
}
std::cout << reachableStates.getNonZeroCount() << " states and " << transitionMatrix.getNonZeroCount() << " transitions." << std::endl;
// Finally, we build the DDs for a reward structure, if requested.
boost::optional<std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>>> stateAndTransitionRewards;
if (options.buildRewards) {
// If a specific reward model was selected or one with the empty name exists, select it.
storm::prism::RewardModel rewardModel = storm::prism::RewardModel();
if (options.rewardModelName) {
rewardModel = preparedProgram.getRewardModel(options.rewardModelName.get());
} else if (preparedProgram.hasRewardModel("")) {
rewardModel = preparedProgram.getRewardModel("");
} else if (preparedProgram.hasRewardModel()) {
// Otherwise, we select the first one.
rewardModel = preparedProgram.getRewardModel(0);
}
STORM_LOG_TRACE("Building reward structure.");
stateAndTransitionRewards = createRewardDecisionDiagrams(generationInfo, rewardModel, transitionMatrix);
}
return std::make_pair(reachableStates, transitionMatrix);
}
@ -1670,7 +1746,7 @@ namespace storm {
// transitionRewardsDds[i] = transitionRewardsDds[i] / systemDds.independentActionDd.commandsDd;
// }
// }
//
//
// // Pair to store state and transition rewards
// return std::make_pair(stateRewardsDds, transitionRewardsDds);
// }

4
src/builder/DdPrismModelBuilder.h

@ -295,8 +295,12 @@ namespace storm {
static ModuleDecisionDiagram createModuleDecisionDiagram(GenerationInformation& generationInfo, storm::prism::Module const& module, std::map<uint_fast64_t, uint_fast64_t> const& synchronizingActionToOffsetMap);
static storm::dd::Dd<Type> getSynchronizationDecisionDiagram(GenerationInformation& generationInfo, boost::optional<uint_fast64_t> const& synchronizationAction = boost::optional<uint_fast64_t>());
static storm::dd::Dd<Type> createSystemFromModule(GenerationInformation& generationInfo, ModuleDecisionDiagram const& module);
static std::pair<storm::dd::Dd<Type>, storm::dd::Dd<Type>>createRewardDecisionDiagrams(GenerationInformation& generationInfo, storm::prism::RewardModel const& rewardModel, storm::dd::Dd<Type> transitionMatrix);
static std::pair<storm::dd::Dd<Type>, ModuleDecisionDiagram> createSystemDecisionDiagram(GenerationInformation& generationInfo);
static storm::dd::Dd<Type> createInitialStatesDecisionDiagram(GenerationInformation& generationInfo);

50
src/parser/FormulaParser.cpp

@ -44,36 +44,27 @@ namespace storm {
notStateFormula = (-unaryBooleanOperator_ >> atomicStateFormula)[qi::_val = phoenix::bind(&FormulaParser::createUnaryBooleanStateFormula, phoenix::ref(*this), qi::_2, qi::_1)];
notStateFormula.name("negation formula");
eventuallyFormula = (qi::lit("F") >> simpleFormula)[qi::_val = phoenix::bind(&FormulaParser::createEventuallyFormula, phoenix::ref(*this), qi::_1)];
eventuallyFormula = (qi::lit("F") >> -(qi::lit("<=") >> qi::uint_) >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParser::createEventuallyFormula, phoenix::ref(*this), qi::_1, qi::_2)];
eventuallyFormula.name("eventually formula");
globallyFormula = (qi::lit("G") >> simpleFormula)[qi::_val = phoenix::bind(&FormulaParser::createGloballyFormula, phoenix::ref(*this), qi::_1)];
globallyFormula = (qi::lit("G") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParser::createGloballyFormula, phoenix::ref(*this), qi::_1)];
globallyFormula.name("globally formula");
nextFormula = (qi::lit("X") >> simpleFormula)[qi::_val = phoenix::bind(&FormulaParser::createNextFormula, phoenix::ref(*this), qi::_1)];
nextFormula = (qi::lit("X") >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParser::createNextFormula, phoenix::ref(*this), qi::_1)];
nextFormula.name("next formula");
boundedUntilFormula = (simpleFormula >> (qi::lit("U<=") >> qi::uint_ >> simpleFormula))[qi::_val = phoenix::bind(&FormulaParser::createBoundedUntilFormula, phoenix::ref(*this), qi::_1, qi::_2, qi::_3)];
boundedUntilFormula.name("bounded until formula");
pathFormulaWithoutUntil = eventuallyFormula | globallyFormula | nextFormula | stateFormula;
pathFormulaWithoutUntil.name("path formula");
untilFormula = (simpleFormula >> (qi::lit("U") >> simpleFormula))[qi::_val = phoenix::bind(&FormulaParser::createUntilFormula, phoenix::ref(*this), qi::_1, qi::_2)];
untilFormula = pathFormulaWithoutUntil[qi::_val = qi::_1] >> *(qi::lit("U") >> -(qi::lit("<=") >> qi::uint_) >> pathFormulaWithoutUntil)[qi::_val = phoenix::bind(&FormulaParser::createUntilFormula, phoenix::ref(*this), qi::_val, qi::_1, qi::_2)];
untilFormula.name("until formula");
simplePathFormula = eventuallyFormula | globallyFormula | nextFormula | boundedUntilFormula | untilFormula;
simplePathFormula.name("simple path formula");
conditionalFormula = (simplePathFormula >> (qi::lit("||") > simplePathFormula))[qi::_val = phoenix::bind(&FormulaParser::createConditionalFormula, phoenix::ref(*this), qi::_1, qi::_2)];
conditionalFormula = untilFormula[qi::_val = qi::_1] >> *(qi::lit("||") >> untilFormula)[qi::_val = phoenix::bind(&FormulaParser::createConditionalFormula, phoenix::ref(*this), qi::_val, qi::_1)];
conditionalFormula.name("conditional formula");
pathFormula = conditionalFormula | simplePathFormula;
pathFormula = conditionalFormula;
pathFormula.name("path formula");
simpleFormula = stateFormula | simplePathFormula;
simpleFormula.name("simple formula");
formula = stateFormula | pathFormula;
formula.name("formula");
operatorInformation = (-optimalityOperator_[qi::_a = qi::_1] >> ((relationalOperator_[qi::_b = qi::_1] > qi::double_[qi::_c = qi::_1]) | (qi::lit("=") > qi::lit("?"))))[qi::_val = phoenix::construct<std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>>>(qi::_a, qi::_b, qi::_c)];
operatorInformation.name("operator information");
@ -104,14 +95,13 @@ namespace storm {
/*!
* Enable the following lines to print debug output for most the rules.
debug(start);
debug(comments);
debug(stateFormula);
debug(orStateFormula);
debug(andStateFormula);
debug(probabilityOperator);
debug(rewardOperator);
debug(steadyStateOperator);
debug(formula);
debug(pathFormulaWithoutUntil);
debug(pathFormula);
debug(conditionalFormula);
debug(nextFormula);
@ -136,7 +126,7 @@ namespace storm {
qi::on_error<qi::fail>(rewardOperator, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(steadyStateOperator, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(operatorInformation, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(formula, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(pathFormulaWithoutUntil, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(pathFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(conditionalFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4));
qi::on_error<qi::fail>(untilFormula, handler(qi::_1, qi::_2, qi::_3, qi::_4));
@ -203,8 +193,12 @@ namespace storm {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::AtomicLabelFormula(label));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createEventuallyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::EventuallyFormula(subformula));
std::shared_ptr<storm::logic::Formula> FormulaParser::createEventuallyFormula(boost::optional<unsigned> const& stepBound, std::shared_ptr<storm::logic::Formula> const& subformula) const {
if (stepBound) {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::BoundedUntilFormula(createBooleanLiteralFormula(true), subformula, static_cast<uint_fast64_t>(stepBound.get())));
} else {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::EventuallyFormula(subformula));
}
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const {
@ -215,12 +209,12 @@ namespace storm {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::NextFormula(subformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::UntilFormula(leftSubformula, rightSubformula));
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createBoundedUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, unsigned stepBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::BoundedUntilFormula(leftSubformula, rightSubformula, static_cast<uint_fast64_t>(stepBound)));
std::shared_ptr<storm::logic::Formula> FormulaParser::createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<unsigned> const& stepBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula) {
if (stepBound) {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::BoundedUntilFormula(leftSubformula, rightSubformula, static_cast<uint_fast64_t>(stepBound.get())));
} else {
return std::shared_ptr<storm::logic::Formula>(new storm::logic::UntilFormula(leftSubformula, rightSubformula));
}
}
std::shared_ptr<storm::logic::Formula> FormulaParser::createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const {

7
src/parser/FormulaParser.h

@ -126,10 +126,10 @@ namespace storm {
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> expectedTimeOperator;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> steadyStateOperator;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> formula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> simpleFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> stateFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> pathFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> pathFormulaWithoutUntil;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> simplePathFormula;
qi::rule<Iterator, std::shared_ptr<storm::logic::Formula>(), Skipper> atomicStateFormula;
qi::rule<Iterator, std::string(), Skipper> label;
@ -160,11 +160,10 @@ namespace storm {
std::shared_ptr<storm::logic::Formula> createAtomicExpressionFormula(storm::expressions::Expression const& expression) const;
std::shared_ptr<storm::logic::Formula> createBooleanLiteralFormula(bool literal) const;
std::shared_ptr<storm::logic::Formula> createAtomicLabelFormula(std::string const& label) const;
std::shared_ptr<storm::logic::Formula> createEventuallyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createEventuallyFormula(boost::optional<unsigned> const& stepBound, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createGloballyFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createNextFormula(std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula);
std::shared_ptr<storm::logic::Formula> createBoundedUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, unsigned stepBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const;
std::shared_ptr<storm::logic::Formula> createUntilFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, boost::optional<unsigned> const& stepBound, std::shared_ptr<storm::logic::Formula> const& rightSubformula);
std::shared_ptr<storm::logic::Formula> createConditionalFormula(std::shared_ptr<storm::logic::Formula> const& leftSubformula, std::shared_ptr<storm::logic::Formula> const& rightSubformula) const;
std::shared_ptr<storm::logic::Formula> createLongRunAverageOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;
std::shared_ptr<storm::logic::Formula> createRewardOperatorFormula(std::tuple<boost::optional<storm::logic::OptimalityType>, boost::optional<storm::logic::ComparisonType>, boost::optional<double>> const& operatorInformation, std::shared_ptr<storm::logic::Formula> const& subformula) const;

Loading…
Cancel
Save