Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
dbc44ef
Add revised POMDP belief exploration
AlexBork Aug 11, 2026
559db6a
Fixes for issues uncovered by CI
AlexBork Aug 12, 2026
8936942
Additional fixes for CI
AlexBork Aug 12, 2026
70c9678
Formatting
AlexBork Aug 12, 2026
87ca9a0
Linter and hash fixes
AlexBork Aug 12, 2026
82d87e1
Merge branch 'refs/heads/master' into revised-belief-merge
AlexBork Aug 13, 2026
b099b5c
Remove deprecated belief exploration
AlexBork Aug 13, 2026
562198b
Changes to Storm for revised belief exploration
AlexBork Aug 18, 2026
9461797
Change boost::optional to std::optional in BoundedUntilFormula
AlexBork Aug 20, 2026
51f9fd0
Add comment about conversion to std::optional
AlexBork Aug 20, 2026
89a1fb5
Merge branch 'bounded-until-optional' into revbel-storm
AlexBork Aug 20, 2026
7351f26
Adjust get*BoundAsOptionalTimeBound
AlexBork Aug 21, 2026
f12c61c
Merge branch 'revbel-storm' into revised-belief-merge
AlexBork Aug 21, 2026
25f95bf
Adjust to change to std::optional in BoundedUntilFormula
AlexBork Aug 21, 2026
708f1f9
Change valuetype transformer to only rational-to-double
AlexBork Aug 21, 2026
0a30576
Merge branch 'revbel-storm' into revised-belief-merge
AlexBork Aug 21, 2026
9adb1f1
Change valuetype transformer to only rational-to-double
AlexBork Aug 21, 2026
f31dd95
Add potential normalisation
AlexBork Aug 24, 2026
d3d2ce4
Change precision to be an input parameter
AlexBork Aug 25, 2026
aac224e
Add tests
AlexBork Aug 25, 2026
6573133
Merge branch 'master' into revbel-storm
AlexBork Aug 25, 2026
cd3254a
Merge revbel-storm into revised-belief-merge
AlexBork Aug 25, 2026
24f1c10
Adjust to transformer changes
AlexBork Aug 25, 2026
8347494
Remove normalisation test
AlexBork Aug 25, 2026
c5ea70e
Add interval instantiations
AlexBork Aug 26, 2026
8a42f9d
Add test cases for intervals
AlexBork Aug 26, 2026
1180d00
Merge branch 'revbel-storm' into revised-belief-merge
AlexBork Aug 27, 2026
76134fc
Merge branch 'master' into revised-belief-merge
AlexBork Aug 27, 2026
72bf3ae
fix missing handling of clipping for minimal probability properties
AlexBork Sep 2, 2026
9f2f3dc
Change clipping behaviour for unexpected solution values to throw an …
AlexBork Sep 4, 2026
acf6022
Increase precision in exception message
AlexBork Sep 4, 2026
d3245c4
Merge branch 'master' into revised-belief-merge
AlexBork Sep 22, 2026
502307e
Add support for extended number types
AlexBork Sep 22, 2026
014b9f2
Cleanup
AlexBork Sep 22, 2026
dacdff2
put result structs in separate header
AlexBork Sep 22, 2026
484dd01
clean tests
AlexBork Sep 22, 2026
706373c
remove superfluous type aliases
AlexBork Sep 22, 2026
f3d1018
Fix handling of non-existent reward model names
AlexBork Sep 23, 2026
43e68af
Add missing typename
AlexBork Sep 23, 2026
9280b92
Remove superfluous header
AlexBork Sep 23, 2026
afd9ebd
Change assertion to catch
AlexBork Sep 23, 2026
b4fc0bb
Add warnings about non-preserved components
AlexBork Sep 23, 2026
a619066
Handle optional reward model name correctly
AlexBork Sep 23, 2026
c2d777a
Change numeric comparisons
AlexBork Sep 23, 2026
89cd5d3
Add warning about non-preservation
AlexBork Sep 23, 2026
6ad2c4e
Handle unnamed, unambiguous reward model
AlexBork Sep 23, 2026
ebf6a78
Add handling for unhandled cases
AlexBork Sep 23, 2026
4cc700e
add tests
AlexBork Sep 23, 2026
ee7779a
Add test file
AlexBork Sep 23, 2026
52d5d49
Handle optional reward model name correctly
AlexBork Sep 23, 2026
2f470e0
Fix preservation of named unique model
AlexBork Sep 23, 2026
45ec4c1
Revert unnecessary check
AlexBork Sep 23, 2026
3e97136
Formatting
AlexBork Sep 23, 2026
77b6952
Additional handling in formula classes
AlexBork Sep 24, 2026
c54073c
Merge branch 'unnamed-reward-model-handling' into revised-belief-merge
AlexBork Sep 24, 2026
4819385
Add info to generate choice labeling
AlexBork Sep 24, 2026
45f8374
Document that belief exploration with reward-bounded property does no…
AlexBork Sep 24, 2026
ae0013a
Extend description
AlexBork Sep 24, 2026
5f88155
Remove result header
AlexBork Sep 25, 2026
4c45def
Add reference
AlexBork Sep 25, 2026
4eb06d8
Throw for unsupported models
AlexBork Sep 25, 2026
2466031
FIx handling of negative thresholds
AlexBork Sep 25, 2026
610e024
Change indices to use local action indices
AlexBork Sep 25, 2026
b35e2bd
Add tests
AlexBork Sep 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions resources/examples/testfiles/pomdp/simple.prism
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module main
[alpha] s>0 & s<5 -> (1-slippery): (s'=s+2) + slippery: true;
[beta] s=3 -> (1-slippery): (s'=6) + slippery: true;
[beta] s=4 -> (1-slippery): (s'=5) + slippery: true;
[alpha] s=5 | s=6 -> 1: true;
endmodule

rewards
Expand Down
22 changes: 22 additions & 0 deletions resources/examples/testfiles/pomdp/simple_unit_rewards.prism
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
pomdp

observable "start" = s<3;
observable "end" = s>4;

const double slippery;

module main
s : [0..6] init 0;
[alpha] s=0 -> (1-slippery) * 0.7: (s'=1) + (1-slippery) * 0.3: (s'=2) + slippery: true;
[alpha] s>0 & s<5 -> (1-slippery): (s'=s+2) + slippery: true;
[beta] s=3 -> (1-slippery): (s'=6) + slippery: true;
[beta] s=4 -> (1-slippery): (s'=5) + slippery: true;
[alpha] s=5 | s=6 -> 1: true;
endmodule

rewards
[alpha] true : 1;
[beta] true : 1;
endrewards

label "goal" = s=5;
254 changes: 40 additions & 214 deletions src/storm-pomdp-cli/settings/modules/BeliefExplorationSettings.cpp

Large diffs are not rendered by default.

52 changes: 7 additions & 45 deletions src/storm-pomdp-cli/settings/modules/BeliefExplorationSettings.h
Original file line number Diff line number Diff line change
@@ -1,24 +1,8 @@
#pragma once

#include "storm-config.h"
#include "storm/settings/modules/ModuleSettings.h"

namespace storm {
namespace builder {
template<typename PomdpType, typename BeliefValueType>
class BeliefMdpExplorer;
}
namespace pomdp {
namespace modelchecker {
template<typename ValueType>
struct BeliefExplorationPomdpModelCheckerOptions;
}

enum BeliefNumberType { Default, Float, Rational };
} // namespace pomdp

namespace settings {
namespace modules {
namespace storm::settings::modules {

/*!
* This class represents the settings for POMDP model checking.
Expand All @@ -33,56 +17,34 @@ class BeliefExplorationSettings : public ModuleSettings {
virtual ~BeliefExplorationSettings() = default;

bool isCutZeroGapSet() const;
bool isRefineSet() const;
double getRefinePrecision() const;
uint64_t getRefineStepLimit() const;

uint64_t getExplorationTimeLimit() const;

/// Discretization Resolution
uint64_t getResolutionInit() const;
double getResolutionFactor() const;

/// Clipping Grid Resolution
uint64_t getClippingGridResolution() const;

/// The maximal number of newly expanded MDP states in a refinement step
uint64_t getSizeThresholdInit() const;
double getSizeThresholdFactor() const;

/// Controls how large the gap between known lower- and upper bounds at a beliefstate needs to be in order to explore
double getGapThresholdInit() const;
double getGapThresholdFactor() const;

/// Controls whether "almost optimal" choices will be considered optimal
double getOptimalChoiceValueThresholdInit() const;
double getOptimalChoiceValueThresholdFactor() const;

/// Controls which observations are refined.
double getObservationScoreThresholdInit() const;
double getObservationScoreThresholdFactor() const;

/// Used to determine whether two beliefs are equal
bool isNumericPrecisionSetFromDefault() const;
double getNumericPrecision() const;

bool isDynamicTriangulationModeSet() const;
bool isStaticTriangulationModeSet() const;

/// Controls if (grid) clipping is to be used
/// Controls if grid clipping is to be used
bool isUseClippingSet() const;

bool isStateEliminationCutoffSet() const;
bool isBeliefMDPNumberTypeDouble() const;
bool isBeliefMDPNumberTypeRational() const;
bool isBeliefMDPNumberTypeMatch() const;

template<typename ValueType>
void setValuesInOptionsStruct(storm::pomdp::modelchecker::BeliefExplorationPomdpModelCheckerOptions<ValueType>& options) const;
bool isInexactPreprocessingSet() const;

// The name of the module.
static const std::string moduleName;

private:
};

} // namespace modules
} // namespace settings
} // namespace storm
} // namespace storm::settings::modules
49 changes: 41 additions & 8 deletions src/storm-pomdp-cli/settings/modules/POMDPSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const std::string memoryPatternOption = "memorypattern";
const std::vector<std::string> memoryPatterns = {"trivial", "fixedcounter", "selectivecounter", "ring", "fixedring", "settablebits", "full"};
const std::string checkFullyObservableOption = "check-fully-observable";
const std::string isQualitativeOption = "qualitative-analysis";
const std::string isBoundedToUnboundedReachabilityTransformationOption = "unfold-reward-bound";
const std::string isRewardObservableOption = "reward-aware";

POMDPSettings::POMDPSettings() : ModuleSettings(moduleName) {
this->addOption(storm::settings::OptionBuilder(moduleName, noCanonicOption, false,
Expand Down Expand Up @@ -52,17 +54,29 @@ POMDPSettings::POMDPSettings() : ModuleSettings(moduleName) {
.setDefaultValueString("full")
.build())
.build());
this->addOption(
storm::settings::OptionBuilder(moduleName, beliefExplorationOption, false, "Analyze the POMDP by exploring the belief state-space.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument("mode", "Sets whether lower, upper, or interval result bounds are computed.")
.addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(beliefExplorationModes))
.setDefaultValueString("both")
.makeOptional()
.build())
.build());
this->addOption(storm::settings::OptionBuilder(moduleName, beliefExplorationOption, false, "Analyze the POMDP by exploring the belief space.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument(
"mode", "Sets whether lower bounds, upper bounds, or interval bounds are computed.")
.addValidatorString(ArgumentValidatorFactory::createMultipleChoiceValidator(beliefExplorationModes))
.setDefaultValueString("both")
.makeOptional()
.build())
.build());
this->addOption(
storm::settings::OptionBuilder(moduleName, checkFullyObservableOption, false, "Performs standard model checking on the underlying MDP").build());
this->addOption(storm::settings::OptionBuilder(moduleName, isQualitativeOption, false, "Sets the option qualitative analysis").build());
this->addOption(storm::settings::OptionBuilder(
moduleName, isBoundedToUnboundedReachabilityTransformationOption, false,
"Sets the option that reward bounded reachability properties are transformed to an unbounded problem on an unfolded POMDP.")
.build());
this->addOption(storm::settings::OptionBuilder(moduleName, isRewardObservableOption, false,
"Sets the option that rewards are observable for bounded reachability properties.")
.addArgument(storm::settings::ArgumentBuilder::createStringArgument(
"levelwidths", "comma separated list of (unsigned integer) width of reward levels.")
.setDefaultValueString("")
.makeOptional()
.build())
.build());
}

bool POMDPSettings::isNoCanonicSet() const {
Expand Down Expand Up @@ -111,6 +125,25 @@ bool POMDPSettings::isQualitativeAnalysisSet() const {
return this->getOption(isQualitativeOption).getHasOptionBeenSet();
}

bool POMDPSettings::isBoundedToUnboundedReachabilityTransformationSet() const {
return this->getOption(isBoundedToUnboundedReachabilityTransformationOption).getHasOptionBeenSet();
}

bool POMDPSettings::isRewardObservableSet() const {
return this->getOption(isRewardObservableOption).getHasOptionBeenSet();
}

std::vector<uint64_t> POMDPSettings::getLevelWidthForBoundedReachability() const {
auto const input = this->getOption(isRewardObservableOption).getArgumentByName("levelwidths").getValueAsString();
if (input.empty()) {
return {};
}
// split the string by comma
auto result = input | std::ranges::views::split(',') |
std::ranges::views::transform([](auto&& r) -> uint64_t { return std::stoull(std::string(r.begin(), r.end())); });
return {result.begin(), result.end()};
}

uint64_t POMDPSettings::getMemoryBound() const {
return this->getOption(memoryBoundOption).getArgumentByName("bound").getValueAsUnsignedInteger();
}
Expand Down
3 changes: 3 additions & 0 deletions src/storm-pomdp-cli/settings/modules/POMDPSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class POMDPSettings : public ModuleSettings {
bool isSelfloopReductionSet() const;
bool isCheckFullyObservableSet() const;
bool isQualitativeAnalysisSet() const;
bool isBoundedToUnboundedReachabilityTransformationSet() const;
std::vector<uint64_t> getLevelWidthForBoundedReachability() const;
bool isRewardObservableSet() const;
uint64_t getMemoryBound() const;

storm::storage::PomdpMemoryPattern getMemoryPattern() const;
Expand Down
Loading
Loading