42 std::map<uint64_t, std::map<detail::ObsActPair, std::vector<uint64_t>>> predecessorInfo;
43 std::map<detail::ObsActPair, std::map<uint64_t, std::set<uint64_t>>> obsPredInfo;
44 std::set<detail::ObsActPair> obsactpairs;
46 for (uint64_t state = 0; state < pomdp.getNumberOfStates(); ++state) {
47 predecessorInfo[state] = {};
51 for (uint64_t state = 0; state < pomdp.getNumberOfStates(); ++state) {
53 for (uint64_t act = 0; act < pomdp.getNumberOfChoices(state); ++act) {
55 obsactpairs.insert(oap);
56 if (obsPredInfo.count(oap) == 0) {
57 obsPredInfo[oap] = std::map<uint64_t, std::set<uint64_t>>();
59 for (
auto const& entry : pomdp.getTransitionMatrix().getRow(state, act)) {
60 if (predecessorInfo[entry.getColumn()].count(oap) == 0) {
61 predecessorInfo[entry.getColumn()][oap] = {state};
63 predecessorInfo[entry.getColumn()][oap].push_back(state);
65 uint64_t newObs = pomdp.getObservation(entry.getColumn());
66 if (obsPredInfo[oap].
count(newObs) == 0) {
67 obsPredInfo[oap][newObs] = {state};
69 obsPredInfo[oap][newObs].insert(state);
74 uint64_t initialObs = pomdp.getObservation(*(pomdp.getInitialStates().begin()));
79 std::map<uint64_t, const jani::Variable*> stateVariables;
82 false, exprManager.
integer(0), exprManager.
integer(pomdp.getNrObservations())));
85 false, exprManager.
integer(0), exprManager.
integer(obsactpairs.size())));
87 for (uint64_t i = 0; i < pomdp.getNumberOfStates(); ++i) {
88 std::string name =
"s" + std::to_string(i);
89 bool isInitial = pomdp.getInitialStates().get(i);
91 exprManager.
boolean(isInitial),
false)));
94 std::map<detail::ObsActPair, uint64_t> actionIndices;
95 for (
auto const& oap : obsactpairs) {
96 std::string actname =
"act" + std::to_string(oap.action) +
"from" + std::to_string(oap.observation);
97 uint64_t actindex = model.addAction(
jani::Action(actname));
98 actionIndices[oap] = actindex;
101 for (uint64_t i = 0; i < pomdp.getNumberOfStates(); ++i) {
102 std::string name =
"aut-s" + std::to_string(i);
106 for (
auto const& oaps : actionIndices) {
107 if (obsPredInfo[oaps.first].count(pomdp.getObservation(i)) == 0 && pomdp.getObservation(i) != oaps.first.observation) {
110 std::shared_ptr<jani::TemplateEdge> tedge = std::make_shared<jani::TemplateEdge>(exprManager.
boolean(
true));
112 std::vector<storm::expressions::Expression> exprVec;
113 for (
auto const& pred : predecessorInfo[i][oaps.first]) {
114 exprVec.push_back(stateVariables.at(pred)->getExpressionVariable().getExpression());
116 if (exprVec.empty()) {
123 tedge->addDestination(edgedest);
124 aut.
addEdge(
jani::Edge(primeloc, oaps.second, boost::none, tedge, {primeloc}, {exprManager.rational(1.0)}));
126 model.addAutomaton(aut);
129 auto const& targetVar = model.addVariable(
131 std::vector<storm::expressions::Expression> notTargetExpression;
132 for (
auto const state : ~targetStates) {
133 notTargetExpression.push_back(!stateVariables.at(state)->getExpressionVariable().getExpression());
137 std::vector<storm::expressions::Expression> badExpression;
138 for (
auto const state : badStates) {
139 badExpression.push_back(stateVariables.at(state)->getExpressionVariable().getExpression());
144 primeLocation.addTransientAssignment(
146 uint64_t primeloc = obsAut.
addLocation(primeLocation);
150 for (
auto const& oaps : actionIndices) {
151 std::shared_ptr<jani::TemplateEdge> tedge =
153 std::vector<uint64_t> destLocs;
154 std::vector<storm::expressions::Expression> probs;
156 for (
auto const& obsAndPredStates : obsPredInfo[oaps.first]) {
161 tedge->addDestination(tedgedest);
163 destLocs.push_back(secloc);
164 std::vector<storm::expressions::Expression> predExpressions;
165 for (
auto predstate : obsAndPredStates.second) {
166 predExpressions.push_back(stateVariables.at(predstate)->getExpressionVariable().getExpression());
174 for (
auto const& oaps : obsactpairs) {
175 std::shared_ptr<jani::TemplateEdge> tedge =
180 tedge->addDestination(tedgedest);
181 jani::Edge edge(secloc, actionIndices[oaps], boost::none, tedge, {primeloc}, {exprManager.
rational(1.0)});
184 model.addAutomaton(obsAut);
185 model.setStandardSystemComposition();
195 auto mdp = storm::api::buildSymbolicModel<storm::dd::DdType::Sylvan, ValueType>(symdesc, {
property.getRawFormula()});
197 std::unique_ptr<modelchecker::CheckResult> result =
199 std::unique_ptr<storm::modelchecker::CheckResult> filter;
202 filter = std::make_unique<storm::modelchecker::SymbolicQualitativeCheckResult<storm::dd::DdType::Sylvan>>(mdp->getReachableStates(),
203 mdp->getInitialStates());
207 storm::api::verifyWithDdEngine<storm::dd::DdType::Sylvan, ValueType>(env, mdp, storm::api::createTask<ValueType>(relstates.getRawFormula(),
false));
209 if (result && filter) {
210 result->filter(filter->asQualitativeCheckResult());
213 if (result && !onlyInitial) {
214 auto vars = result->asSymbolicQualitativeCheckResult<
storm::dd::DdType::Sylvan>().getTruthValuesVector().getContainedMetaVariables();
217 initialIsWinning = result->asQualitativeCheckResult().existsTrue();