41 std::map<uint64_t, std::map<detail::ObsActPair, std::vector<uint64_t>>> predecessorInfo;
42 std::map<detail::ObsActPair, std::map<uint64_t, std::set<uint64_t>>> obsPredInfo;
43 std::set<detail::ObsActPair> obsactpairs;
45 for (uint64_t state = 0; state < pomdp.getNumberOfStates(); ++state) {
46 predecessorInfo[state] = {};
50 for (uint64_t state = 0; state < pomdp.getNumberOfStates(); ++state) {
52 for (uint64_t act = 0; act < pomdp.getNumberOfChoices(state); ++act) {
54 obsactpairs.insert(oap);
55 if (obsPredInfo.count(oap) == 0) {
56 obsPredInfo[oap] = std::map<uint64_t, std::set<uint64_t>>();
58 for (
auto const& entry : pomdp.getTransitionMatrix().getRow(state, act)) {
59 if (predecessorInfo[entry.getColumn()].count(oap) == 0) {
60 predecessorInfo[entry.getColumn()][oap] = {state};
62 predecessorInfo[entry.getColumn()][oap].push_back(state);
64 uint64_t newObs = pomdp.getObservation(entry.getColumn());
65 if (obsPredInfo[oap].
count(newObs) == 0) {
66 obsPredInfo[oap][newObs] = {state};
68 obsPredInfo[oap][newObs].insert(state);
73 uint64_t initialObs = pomdp.getObservation(*(pomdp.getInitialStates().begin()));
78 std::map<uint64_t, const jani::Variable*> stateVariables;
81 false, exprManager.
integer(0), exprManager.
integer(pomdp.getNrObservations())));
84 false, exprManager.
integer(0), exprManager.
integer(obsactpairs.size())));
86 for (uint64_t i = 0; i < pomdp.getNumberOfStates(); ++i) {
87 std::string name =
"s" + std::to_string(i);
88 bool isInitial = pomdp.getInitialStates().get(i);
90 exprManager.
boolean(isInitial),
false)));
93 std::map<detail::ObsActPair, uint64_t> actionIndices;
94 for (
auto const& oap : obsactpairs) {
95 std::string actname =
"act" + std::to_string(oap.action) +
"from" + std::to_string(oap.observation);
96 uint64_t actindex = model.addAction(
jani::Action(actname));
97 actionIndices[oap] = actindex;
100 for (uint64_t i = 0; i < pomdp.getNumberOfStates(); ++i) {
101 std::string name =
"aut-s" + std::to_string(i);
105 for (
auto const& oaps : actionIndices) {
106 if (obsPredInfo[oaps.first].count(pomdp.getObservation(i)) == 0 && pomdp.getObservation(i) != oaps.first.observation) {
109 std::shared_ptr<jani::TemplateEdge> tedge = std::make_shared<jani::TemplateEdge>(exprManager.
boolean(
true));
111 std::vector<storm::expressions::Expression> exprVec;
112 for (
auto const& pred : predecessorInfo[i][oaps.first]) {
113 exprVec.push_back(stateVariables.at(pred)->getExpressionVariable().getExpression());
115 if (exprVec.empty()) {
122 tedge->addDestination(edgedest);
123 aut.
addEdge(
jani::Edge(primeloc, oaps.second, boost::none, tedge, {primeloc}, {exprManager.rational(1.0)}));
125 model.addAutomaton(aut);
128 auto const& targetVar = model.addVariable(
130 std::vector<storm::expressions::Expression> notTargetExpression;
131 for (
auto const state : ~targetStates) {
132 notTargetExpression.push_back(!stateVariables.at(state)->getExpressionVariable().getExpression());
136 std::vector<storm::expressions::Expression> badExpression;
137 for (
auto const state : badStates) {
138 badExpression.push_back(stateVariables.at(state)->getExpressionVariable().getExpression());
143 primeLocation.addTransientAssignment(
145 uint64_t primeloc = obsAut.
addLocation(primeLocation);
149 for (
auto const& oaps : actionIndices) {
150 std::shared_ptr<jani::TemplateEdge> tedge =
152 std::vector<uint64_t> destLocs;
153 std::vector<storm::expressions::Expression> probs;
155 for (
auto const& obsAndPredStates : obsPredInfo[oaps.first]) {
160 tedge->addDestination(tedgedest);
162 destLocs.push_back(secloc);
163 std::vector<storm::expressions::Expression> predExpressions;
164 for (
auto predstate : obsAndPredStates.second) {
165 predExpressions.push_back(stateVariables.at(predstate)->getExpressionVariable().getExpression());
173 for (
auto const& oaps : obsactpairs) {
174 std::shared_ptr<jani::TemplateEdge> tedge =
179 tedge->addDestination(tedgedest);
180 jani::Edge edge(secloc, actionIndices[oaps], boost::none, tedge, {primeloc}, {exprManager.
rational(1.0)});
183 model.addAutomaton(obsAut);
184 model.setStandardSystemComposition();
194 auto mdp = storm::api::buildSymbolicModel<storm::dd::DdType::Sylvan, ValueType>(symdesc, {
property.getRawFormula()});
196 std::unique_ptr<modelchecker::CheckResult> result =
198 std::unique_ptr<storm::modelchecker::CheckResult> filter;
201 filter = std::make_unique<storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::Sylvan>>(mdp->getReachableStates(),
202 mdp->getInitialStates());
206 storm::api::verifyWithDdEngine<storm::dd::DdType::Sylvan, ValueType>(env, mdp, storm::api::createTask<ValueType>(relstates.getRawFormula(),
false));
208 if (result && filter) {
209 result->filter(filter->asQualitativeCheckResult());
212 if (result && !onlyInitial) {
213 auto vars = result->asSymbolicQualitativeCheckResult<
storm::dd::DdType::Sylvan>().getTruthValuesVector().getContainedMetaVariables();
216 initialIsWinning = result->asQualitativeCheckResult().existsTrue();