Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
6922fea
Implemented support for reachability probabilities, reach-reward and …
plindnercs Nov 12, 2025
13d40bc
Applied code formatting
plindnercs Nov 12, 2025
71705ff
Check for Z3 being available on certain tests
plindnercs Nov 12, 2025
8acb6f7
Merge remote-tracking branch 'upstream/master' into imc-reachability-…
plindnercs Nov 17, 2025
6d37341
Merge remote-tracking branch 'upstream/master' into imc-reachability-…
plindnercs Nov 18, 2025
2b76334
Merge remote-tracking branch 'upstream/master' into imc-reachability-…
plindnercs Nov 21, 2025
6765a8a
Merge remote-tracking branch 'upstream/master' into imc-reachability-…
plindnercs Dec 8, 2025
072f87a
Implemented explicit flag 'uncertainty-resolution' to decide how the …
plindnercs Dec 10, 2025
eddd5be
fixed warnings
plindnercs Dec 16, 2025
c2cff21
merged incoming changes
plindnercs Dec 29, 2025
5858817
Merge remote-tracking branch 'upstream/master' into imc-reachability-…
plindnercs Dec 29, 2025
dee5cad
incorporated feedback of @tquatmann
plindnercs Jan 3, 2026
4e0ccd8
added optimization direction handling for IDTMCs
plindnercs Jan 3, 2026
94f95c5
Avoid include of IntervalAdapter.h in ConstantsComparator.h
volkm Jan 5, 2026
fcb6a03
Merge from branch 'master'
volkm Jan 6, 2026
3e5bd6b
API: createTask for interval models now explicitly requires an uncert…
tquatmann Jan 9, 2026
f3d75e1
Suppress unused lambda capture warning.
tquatmann Jan 9, 2026
9655aa7
IMDPs: Improved support for reachability rewards and reachability pro…
tquatmann Jan 9, 2026
83ff3bd
Fix test case.
tquatmann Jan 10, 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
145 changes: 145 additions & 0 deletions resources/examples/testfiles/idtmc/brp-32-2-intervals.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// bounded retransmission protocol [D'AJJL01]
// gxn/dxp 23/05/2001
// DTMC with interval probabilities for channels (Storm IMDP/IDTMC extension)

dtmc

// number of chunks
const int N = 32;
// maximum number of retransmissions
const int MAX = 2;

module sender

s : [0..6];
// 0 idle
// 1 next_frame
// 2 wait_ack
// 3 retransmit
// 4 success
// 5 error
// 6 wait sync
srep : [0..3];
// 0 bottom
// 1 not ok (nok)
// 2 do not know (dk)
// 3 ok (ok)
nrtr : [0..MAX];
i : [0..N];
bs : bool;
s_ab : bool;
fs : bool;
ls : bool;

// idle
[NewFile] (s=0) -> (s'=1) & (i'=1) & (srep'=0);
// next_frame
[aF] (s=1) -> (s'=2) & (fs'=(i=1)) & (ls'=(i=N)) & (bs'=s_ab) & (nrtr'=0);
// wait_ack
[aB] (s=2) -> (s'=4) & (s_ab'=!s_ab);
[TO_Msg] (s=2) -> (s'=3);
[TO_Ack] (s=2) -> (s'=3);
// retransmit
[aF] (s=3) & (nrtr<MAX) -> (s'=2) & (fs'=(i=1)) & (ls'=(i=N)) & (bs'=s_ab) & (nrtr'=nrtr+1);
[] (s=3) & (nrtr=MAX) & (i<N) -> (s'=5) & (srep'=1);
[] (s=3) & (nrtr=MAX) & (i=N) -> (s'=5) & (srep'=2);
// success
[] (s=4) & (i<N) -> (s'=1) & (i'=i+1);
[] (s=4) & (i=N) -> (s'=0) & (srep'=3);
// error
[SyncWait] (s=5) -> (s'=6);
// wait sync
[SyncWait] (s=6) -> (s'=0) & (s_ab'=false);

endmodule

module receiver

r : [0..5];
// 0 new_file
// 1 fst_safe
// 2 frame_received
// 3 frame_reported
// 4 idle
// 5 resync
rrep : [0..4];
// 0 bottom
// 1 fst
// 2 inc
// 3 ok
// 4 nok
fr : bool;
lr : bool;
br : bool;
r_ab : bool;
recv : bool;

// new_file
[SyncWait] (r=0) -> (r'=0);
[aG] (r=0) -> (r'=1) & (fr'=fs) & (lr'=ls) & (br'=bs) & (recv'=true);
// fst_safe_frame
[] (r=1) -> (r'=2) & (r_ab'=br);
// frame_received
[] (r=2) & (r_ab=br) & (fr=true) & (lr=false) -> (r'=3) & (rrep'=1);
[] (r=2) & (r_ab=br) & (fr=false) & (lr=false) -> (r'=3) & (rrep'=2);
[] (r=2) & (r_ab=br) & (fr=false) & (lr=true) -> (r'=3) & (rrep'=3);
[aA] (r=2) & !(r_ab=br) -> (r'=4);
// frame_reported
[aA] (r=3) -> (r'=4) & (r_ab'=!r_ab);
// idle
[aG] (r=4) -> (r'=2) & (fr'=fs) & (lr'=ls) & (br'=bs) & (recv'=true);
[SyncWait] (r=4) & (ls=true) -> (r'=5);
[SyncWait] (r=4) & (ls=false) -> (r'=5) & (rrep'=4);
// resync
[SyncWait] (r=5) -> (r'=0) & (rrep'=0);

endmodule

module checker // prevents more than one frame being set

T : bool;

[NewFile] (T=false) -> (T'=true);

endmodule

// ------------------------------------------------------------------
// Channels with interval probabilities (IMDP-style ranges)
// These match the spirit of the DRN ranges like [0.98,1] and [0.0001,0.02]
// ------------------------------------------------------------------

module channelK

k : [0..2];

// idle -- message transfer may succeed or be lost
// (success prob in [0.98, 1], loss prob in [0.0001, 0.02])
[aF] (k=0) -> [0.98, 1] : (k'=1) + [0.0001, 0.02] : (k'=2);

// sending
[aG] (k=1) -> (k'=0);
// lost
[TO_Msg] (k=2) -> (k'=0);

endmodule

module channelL

l : [0..2];

// idle -- ack transfer may succeed or be lost
// (success prob in [0.99, 1], loss prob in [0.0001, 0.01])
[aA] (l=0) -> [0.99, 1] : (l'=1) + [0.0001, 0.01] : (l'=2);

// sending
[aB] (l=1) -> (l'=0);
// lost
[TO_Ack] (l=2) -> (l'=0);

endmodule

rewards
[aF] i=1 : 1;
endrewards

label "error" = s=5;
29 changes: 29 additions & 0 deletions resources/examples/testfiles/idtmc/die-intervals.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Knuth's model of a fair die using unfair coins, where the bias is controlled by nature.
dtmc

module die

// local state
s : [0..7] init 0;
// value of the dice
d : [0..6] init 0;

[] s=0 -> [1/3, 2/3] : (s'=1) + [1/3, 2/3] : (s'=2);
[] s=1 -> [1/3, 2/3] : (s'=3) + [1/3, 2/3] : (s'=4);
[] s=2 -> [1/3, 2/3] : (s'=5) + [1/3, 2/3] : (s'=6);
[] s=3 -> [1/3, 2/3] : (s'=1) + [1/3, 2/3] : (s'=7) & (d'=1);
[] s=4 -> [1/3, 2/3] : (s'=7) & (d'=2) + [1/3, 2/3] : (s'=7) & (d'=3);
[] s=5 -> [1/3, 2/3] : (s'=7) & (d'=4) + [1/3, 2/3] : (s'=7) & (d'=5);
[] s=6 -> [1/3, 2/3] : (s'=2) + [1/3, 2/3] : (s'=7) & (d'=6);
[] s=7 -> 1: (s'=7);

endmodule

rewards "coin_flips"
[] s<7 : 1;
endrewards

label "one" = s=7&d=1;
label "two" = s=7&d=2;
label "three" = s=7&d=3;
label "done" = s=7;
20 changes: 20 additions & 0 deletions resources/examples/testfiles/idtmc/tiny-01.drn
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@type: DTMC
@parameters

@reward_models

@nr_states
3
@nr_choices
3
@model
state 0 init
action 0
1 : [0.3, 0.5]
2 : [0.5, 0.7]
state 1 target
action 0
1 : [1, 1]
state 2
action 0
2 : [1, 1]
20 changes: 20 additions & 0 deletions resources/examples/testfiles/idtmc/tiny-02.drn
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@type: DTMC
@parameters

@reward_models

@nr_states
3
@nr_choices
3
@model
state 0 init target
action 0
1 : [0.3, 0.5]
2 : [0.5, 0.7]
state 1
action 0
1 : [1, 1]
state 2 target
action 0
2 : [1, 1]
23 changes: 23 additions & 0 deletions resources/examples/testfiles/idtmc/tiny-03.drn
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@type: DTMC
@parameters

@reward_models
cost
@nr_states
4
@nr_choices
4
@model
state 0 init [0]
action 0
1 : [0.3, 0.7]
2 : [0.3, 0.7]
state 1 [5]
action 0
3 : [1, 1]
state 2 [10]
action 0
3 : [1, 1]
state 3 target [0]
action 0
3 : [1, 1]
26 changes: 26 additions & 0 deletions resources/examples/testfiles/idtmc/tiny-04.drn
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@type: DTMC
@parameters

@reward_models
cost
@nr_states
5
@nr_choices
5
@model
state 0 init [0]
action 0
1 : [0.3, 0.7]
2 : [0.3, 0.7]
state 1 [5]
action 0
3 : [1, 1]
state 2 [10]
action 0
4 : [1, 1]
state 3 target [0]
action 0
3 : [1, 1]
state 4 [1]
action 0
4 : [1, 1]
23 changes: 15 additions & 8 deletions src/storm-cli-utilities/model-handling.h
Original file line number Diff line number Diff line change
Expand Up @@ -1295,8 +1295,18 @@ void verifyModel(std::shared_ptr<storm::models::sparse::Model<ValueType>> const&
auto const& ioSettings = storm::settings::getModule<storm::settings::modules::IOSettings>();
auto verificationCallback = [&sparseModel, &ioSettings, &mpi](std::shared_ptr<storm::logic::Formula const> const& formula,
std::shared_ptr<storm::logic::Formula const> const& states) {
auto createTask = [&ioSettings](auto const& f, bool onlyInitialStates) {
(void)ioSettings; // suppress unused lambda capture warning. [[maybe_unused]] doesn't work for lambda captures.
if constexpr (storm::IsIntervalType<ValueType>) {
STORM_LOG_THROW(ioSettings.isUncertaintyResolutionModeSet(), storm::exceptions::InvalidSettingsException,
"Uncertainty resolution mode required for uncertain (interval) models.");
return storm::api::createTask<ValueType>(f, storm::solver::convert(ioSettings.getUncertaintyResolutionMode()), onlyInitialStates);
} else {
return storm::api::createTask<ValueType>(f, onlyInitialStates);
}
};
bool filterForInitialStates = states->isInitialFormula();
auto task = storm::api::createTask<ValueType>(formula, filterForInitialStates);
auto task = createTask(formula, states->isInitialFormula());
if (ioSettings.isExportSchedulerSet()) {
task.setProduceSchedulers(true);
}
Expand All @@ -1306,7 +1316,7 @@ void verifyModel(std::shared_ptr<storm::models::sparse::Model<ValueType>> const&
if (filterForInitialStates) {
filter = std::make_unique<storm::modelchecker::ExplicitQualitativeCheckResult>(sparseModel->getInitialStates());
} else if (!states->isTrueFormula()) { // No need to apply filter if it is the formula 'true'
filter = storm::api::verifyWithSparseEngine<ValueType>(mpi.env, sparseModel, storm::api::createTask<ValueType>(states, false));
filter = storm::api::verifyWithSparseEngine<ValueType>(mpi.env, sparseModel, createTask(states, false));
}
if (result && filter) {
result->filter(filter->asQualitativeCheckResult());
Expand Down Expand Up @@ -1337,12 +1347,9 @@ void verifyModel(std::shared_ptr<storm::models::sparse::Model<ValueType>> const&
"--buildchoicelab or --buildchoiceorig.");
}
if (result->isExplicitQuantitativeCheckResult()) {
if constexpr (storm::IsIntervalType<ValueType>) {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Scheduler export for interval models is not supported.");
} else {
storm::api::exportScheduler(sparseModel, result->template asExplicitQuantitativeCheckResult<ValueType>().getScheduler(),
schedulerExportPath.string());
}
storm::api::exportScheduler(sparseModel,
result->template asExplicitQuantitativeCheckResult<storm::IntervalBaseType<ValueType>>().getScheduler(),
schedulerExportPath.string());
} else if (result->isExplicitParetoCurveCheckResult()) {
if constexpr (std::is_same_v<ValueType, storm::RationalFunction> || storm::IsIntervalType<ValueType>) {
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Scheduler export for models of this value type is not supported.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "storm/modelchecker/results/ExplicitQuantitativeCheckResult.h"
#include "storm/models/sparse/Dtmc.h"
#include "storm/solver/OptimizationDirection.h"
#include "storm/solver/UncertaintyResolutionMode.h"
#include "storm/solver/multiplier/Multiplier.h"
#include "storm/storage/BitVector.h"
#include "storm/utility/constants.h"
Expand Down Expand Up @@ -437,7 +438,7 @@ std::vector<ConstantType> SparseDtmcParameterLiftingModelChecker<SparseModelType
solver->setHasUniqueSolution();
solver->setHasNoEndComponents();
// Uncertainty is not robust (=adversarial)
solver->setUncertaintyIsRobust(false);
solver->setUncertaintyResolutionMode(UncertaintyResolutionMode::Cooperative);
if (lowerResultBound)
solver->setLowerBound(lowerResultBound.value());
if (upperResultBound) {
Expand Down
4 changes: 2 additions & 2 deletions src/storm/api/export.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ void exportSymbolicModelAsDot(std::shared_ptr<storm::models::symbolic::Model<Typ
model->writeDotToFile(filename);
}

template<typename ValueType>
void exportScheduler(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, storm::storage::Scheduler<ValueType> const& scheduler,
template<typename ValueType, typename SolutionType = ValueType>
void exportScheduler(std::shared_ptr<storm::models::sparse::Model<ValueType>> const& model, storm::storage::Scheduler<SolutionType> const& scheduler,
std::string const& filename) {
std::ofstream stream;
storm::io::openFile(filename, stream);
Expand Down
Loading
Loading