def example_getting_started_02(): path = stormpy.examples.files.prism_dtmc_die prism_program = stormpy.parse_prism_program(path) model = stormpy.build_model(prism_program) print("Number of states: {}".format(model.nr_states)) print("Number of transitions: {}".format(model.nr_transitions)) print("Labels in the model: {}".format(model.labeling.get_labels())) formula_str = "P=? [F s=2]" properties = stormpy.parse_properties_for_prism_program( formula_str, prism_program) model_for_formula = stormpy.build_model(prism_program, properties) print("Number of states: {}".format(model_for_formula.nr_states)) print("Number of transitions: {}".format(model_for_formula.nr_transitions)) print("Labels in the model: {}".format( model_for_formula.labeling.get_labels())) formula_str_2 = "P=? [F s=7 & d=2]" properties_2 = stormpy.parse_properties_for_prism_program( formula_str_2, prism_program) model_for_formula_2 = stormpy.build_model(prism_program, properties_2) print("Number of states: {}".format(model_for_formula_2.nr_states)) print("Number of transitions: {}".format( model_for_formula_2.nr_transitions)) print("Labels in the model: {}".format( model_for_formula_2.labeling.get_labels()))
def test_parameters(self): program = stormpy.parse_prism_program( get_example_path("pdtmc", "brp16_2.pm")) formulas = stormpy.parse_properties_for_prism_program( "P=? [F s=5]", program) model = stormpy.build_parametric_model(program, formulas) model_parameters = model.collect_probability_parameters() reward_parameters = model.collect_reward_parameters() all_parameters = model.collect_all_parameters() assert len(model_parameters) == 2 assert len(reward_parameters) == 0 assert len(all_parameters) == 2 program_reward = stormpy.parse_prism_program( get_example_path("pdtmc", "brp_rewards16_2.pm")) formulas_reward = stormpy.parse_properties_for_prism_program( "Rmin=? [ F \"target\" ]", program_reward) model = stormpy.build_parametric_model(program_reward, formulas_reward) model_parameters = model.collect_probability_parameters() reward_parameters = model.collect_reward_parameters() all_parameters = model.collect_all_parameters() assert len(model_parameters) == 2 assert len(reward_parameters) == 2 assert len(all_parameters) == 4 model = stormpy.build_symbolic_parametric_model(program, formulas) assert len(model.get_parameters()) == 4 model = stormpy.build_symbolic_parametric_model( program_reward, formulas_reward) assert len(model.get_parameters()) == 4
def _load_properties(self, program, properties, constant_str=""): """ Load properties to be checked via model checking :param properties: :return: """ self.properties = [] self.qualitative_properties = [] self.quantitative_properties = [] for p in properties: # prop = self._load_property_for_sketch(p, constant_str)[0] for prop in stormpy.parse_properties_for_prism_program(p, program): # prop = prp.property assert prop.raw_formula.has_bound # print(prop.raw_formula) if True: # prop.raw_formula.is_probability_operator and prop.raw_formula.threshold > 0 and prop.raw_formula.threshold < 1: self.properties.append(prop) for prop2 in stormpy.parse_properties_for_prism_program( p, program): assert prop2.raw_formula.has_bound prop2.raw_formula.remove_bound() self.quantitative_properties.append(prop2) _constants_map = self._constants_map(constant_str, program)
def test_prism_to_jani_repetitive(self): program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) orig_properties = stormpy.parse_properties_for_prism_program("P=? [F \"two\"]", program) jani_model, new_properties = program.to_jani(orig_properties) assert len(new_properties) == len(orig_properties) orig_properties = stormpy.parse_properties_for_prism_program("P=? [F s=7]", program) jani_model, new_properties = program.to_jani(orig_properties, suffix = "2") assert len(new_properties) == len(orig_properties)
def test_model_checking_dtmc_all_labels(self): program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) formulas = stormpy.parse_properties_for_prism_program("P=? [ F \"one\" ]", program) model = stormpy.build_model(program) assert model.nr_states == 13 assert model.nr_transitions == 20 assert len(model.initial_states) == 1 initial_state = model.initial_states[0] assert initial_state == 0 result = stormpy.model_checking(model, formulas[0]) assert math.isclose(result.at(initial_state), 1 / 6) formulas = stormpy.parse_properties_for_prism_program("P=? [ F \"two\" ]", program) result = stormpy.model_checking(model, formulas[0]) assert math.isclose(result.at(initial_state), 1 / 6)
def test_bisimulation(self): program = stormpy.parse_prism_program( get_example_path("dtmc", "crowds5_5.pm")) assert program.nr_modules == 1 assert program.model_type == stormpy.PrismModelType.DTMC prop = "P=? [F \"observe0Greater1\"]" properties = stormpy.parse_properties_for_prism_program(prop, program) model = stormpy.build_model(program, properties) assert model.nr_states == 7403 assert model.nr_transitions == 13041 assert model.model_type == stormpy.ModelType.DTMC assert not model.supports_parameters initial_state = model.initial_states[0] assert initial_state == 0 result = stormpy.model_checking(model, properties[0]) model_bisim = stormpy.perform_bisimulation( model, properties, stormpy.BisimulationType.STRONG) assert model_bisim.nr_states == 64 assert model_bisim.nr_transitions == 104 assert model_bisim.model_type == stormpy.ModelType.DTMC assert not model_bisim.supports_parameters result_bisim = stormpy.model_checking(model_bisim, properties[0]) initial_state_bisim = model_bisim.initial_states[0] assert initial_state_bisim == 34 assert math.isclose(result.at(initial_state), result_bisim.at(initial_state_bisim), rel_tol=1e-4)
def test_parametric_bisimulation(self): program = stormpy.parse_prism_program( get_example_path("pdtmc", "brp16_2.pm")) assert program.nr_modules == 5 assert program.model_type == stormpy.PrismModelType.DTMC assert program.has_undefined_constants assert program.undefined_constants_are_graph_preserving prop = "P=? [F s=5]" properties = stormpy.parse_properties_for_prism_program(prop, program) model = stormpy.build_parametric_model(program, properties) assert model.nr_states == 613 assert model.nr_transitions == 803 assert model.model_type == stormpy.ModelType.DTMC assert model.has_parameters initial_state = model.initial_states[0] assert initial_state == 0 result = stormpy.model_checking(model, properties[0]) ratFunc = result.at(initial_state) model_bisim = stormpy.perform_bisimulation( model, properties, stormpy.BisimulationType.STRONG) assert model_bisim.nr_states == 324 assert model_bisim.nr_transitions == 452 assert model_bisim.model_type == stormpy.ModelType.DTMC assert model_bisim.has_parameters result_bisim = stormpy.model_checking(model_bisim, properties[0]) initial_state_bisim = model_bisim.initial_states[0] assert initial_state_bisim == 316 ratFunc_bisim = result_bisim.at(initial_state_bisim) assert ratFunc == ratFunc_bisim
def test_explicit_builder(self): path = stormpy.examples.files.prism_dtmc_die prism_program = stormpy.parse_prism_program(path) formula_str = "P=? [F s=7 & d=2]" properties = stormpy.parse_properties_for_prism_program(formula_str, prism_program) # Fix variables in the program. module = prism_program.modules[0] s_var = module.get_integer_variable("s").expression_variable d_var = module.get_integer_variable("d").expression_variable # Construct the model options = stormpy.BuilderOptions([p.raw_formula for p in properties]) options.set_build_state_valuations() model_builder = stormpy.make_sparse_model_builder(prism_program, options) model = model_builder.build() # and export the model from building state_mapping = model_builder.export_lookup() #lookup 1 state = { s_var : prism_program.expression_manager.create_integer(3), d_var : prism_program.expression_manager.create_integer(0)} id = state_mapping.lookup(state) assert model.state_valuations.get_integer_value(id, s_var) == 3 assert model.state_valuations.get_integer_value(id, d_var) == 0 #lookup 2 state = { s_var : prism_program.expression_manager.create_integer(7), d_var : prism_program.expression_manager.create_integer(3)} id = state_mapping.lookup(state) assert model.state_valuations.get_integer_value(id, s_var) == 7 assert model.state_valuations.get_integer_value(id, d_var) == 3
def example_building_models_03(): path = stormpy.examples.files.prism_pdtmc_brp prism_program = stormpy.parse_prism_program(path) formula_str = "P=? [F s=5]" properties = stormpy.parse_properties_for_prism_program( formula_str, prism_program) options = stormpy.BuilderOptions([p.raw_formula for p in properties]) options.set_build_state_valuations() model = stormpy.build_sparse_parametric_model_with_options( prism_program, options) valuations = model.state_valuations values2 = json.loads(str(valuations.get_json(2))) print(values2) integer_variables = [] for module in prism_program.modules: print("module {}".format(module.name)) integer_variables += module.integer_variables print(", ".join([ "{}: {}".format( str(iv.name), valuations.get_integer_value(2, iv.expression_variable)) for iv in integer_variables ]))
def test_scheduler_ma_via_mdp(self): program = stormpy.parse_prism_program(get_example_path("ma", "simple.ma"), False, True) formulas = stormpy.parse_properties_for_prism_program("Tmin=? [ F s=4 ]", program) ma = stormpy.build_model(program, formulas) assert ma.nr_states == 5 assert ma.nr_transitions == 8 assert ma.model_type == stormpy.ModelType.MA # Convert MA to MDP mdp, mdp_formulas = stormpy.transform_to_discrete_time_model(ma, formulas) assert mdp.nr_states == 5 assert mdp.nr_transitions == 8 assert mdp.model_type == stormpy.ModelType.MDP assert len(mdp.initial_states) == 1 initial_state = mdp.initial_states[0] assert initial_state == 0 result = stormpy.model_checking(mdp, mdp_formulas[0], extract_scheduler=True) assert math.isclose(result.at(initial_state), 0.08333333333) assert result.has_scheduler scheduler = result.scheduler assert scheduler.memoryless assert scheduler.memory_size == 1 assert scheduler.deterministic for state in mdp.states: choice = scheduler.get_choice(state) assert choice.defined assert choice.deterministic action = choice.get_deterministic_choice() if state.id == 0: assert action == 1 else: assert action == 0
def example_parametric_models_02(): # Check support for parameters if not config.storm_with_pars: print("Support parameters is missing. Try building storm-pars.") return import stormpy.pars from pycarl.formula import FormulaType, Relation if stormpy.info.storm_ratfunc_use_cln(): import pycarl.cln.formula else: import pycarl.gmp.formula path = stormpy.examples.files.prism_pdtmc_die prism_program = stormpy.parse_prism_program(path) formula_str = "P=? [F s=7 & d=2]" properties = stormpy.parse_properties_for_prism_program(formula_str, prism_program) model = stormpy.build_parametric_model(prism_program, properties) initial_state = model.initial_states[0] result = stormpy.model_checking(model, properties[0]) print("Result: {}".format(result.at(initial_state))) collector = stormpy.ConstraintCollector(model) print("Well formed constraints:") for formula in collector.wellformed_constraints: print(formula.get_constraint()) print("Graph preserving constraints:") for formula in collector.graph_preserving_constraints: print(formula.get_constraint())
def test_initial_states(self): program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) formulas = stormpy.parse_properties_for_prism_program("P=? [ F \"one\" ]", program) model = stormpy.build_model(program, formulas) initial_states = model.initial_states assert len(initial_states) == 1 assert 0 in initial_states
def example_parametric_models_01(): # Check support for parameters if not config.storm_with_pars: print("Support parameters is missing. Try building storm-pars.") return import stormpy.pars path = stormpy.examples.files.prism_pdtmc_die prism_program = stormpy.parse_prism_program(path) formula_str = "P=? [F s=7 & d=3]" properties = stormpy.parse_properties_for_prism_program(formula_str, prism_program) model = stormpy.build_parametric_model(prism_program, properties) print("Model supports parameters: {}".format(model.supports_parameters)) parameters = model.collect_probability_parameters() assert len(parameters) == 2 instantiator = stormpy.pars.PDtmcInstantiator(model) point = dict() for x in parameters: print(x.name) point[x] = stormpy.RationalRF(0.0) instantiated_model = instantiator.instantiate(point) result = stormpy.model_checking(instantiated_model, properties[0]) print(result)
def test_transform_continuous_to_discrete_time_model_ma(self): program = stormpy.parse_prism_program( get_example_path("ma", "simple.ma"), False, True) formulas = stormpy.parse_properties_for_prism_program( "Tmin=? [ F s=4 ]", program) ma = stormpy.build_model(program, formulas) assert ma.nr_states == 5 assert ma.nr_transitions == 8 assert ma.model_type == stormpy.ModelType.MA assert len(ma.initial_states) == 1 initial_state = ma.initial_states[0] assert initial_state == 0 result = stormpy.model_checking(ma, formulas[0]) assert math.isclose(result.at(initial_state), 0.08333333333) mdp, mdp_formulas = stormpy.transform_to_discrete_time_model( ma, formulas) assert mdp.nr_states == 5 assert mdp.nr_transitions == 8 assert mdp.model_type == stormpy.ModelType.MDP assert len(mdp.initial_states) == 1 initial_state = mdp.initial_states[0] assert initial_state == 0 result = stormpy.model_checking(mdp, mdp_formulas[0]) assert math.isclose(result.at(initial_state), 0.08333333333)
def example_exploration_02(): """ Example to exploration of POMDPs. :return: """ program = stormpy.parse_prism_program( stormpy.examples.files.prism_pomdp_maze) prop = "R=? [F \"goal\"]" properties = stormpy.parse_properties_for_prism_program( prop, program, None) model = stormpy.build_model(program, properties) print(model.model_type) # Internally, POMDPs are just MDPs with additional observation information. # Thus, data structure exploration for MDPs can be applied as before. initial_state = model.initial_states[0] for state in model.states: if state.id in model.initial_states: print(state) for action in state.actions: for transition in action.transitions: print( "From state {} by action {}, with probability {}, go to state {}" .format(state, action, transition.value(), transition.column)) print(model.nr_observations) for state in model.states: print("State {} has observation id {}".format( state.id, model.observations[state.id]))
def test_pla(self): program = stormpy.parse_prism_program( get_example_path("pdtmc", "brp16_2.pm")) prop = "P<=0.84 [F s=5 ]" formulas = stormpy.parse_properties_for_prism_program(prop, program) model = stormpy.build_parametric_model(program, formulas) assert model.nr_states == 613 assert model.nr_transitions == 803 assert model.model_type == stormpy.ModelType.DTMC assert model.has_parameters env = stormpy.Environment() checker = stormpy.pars.create_region_checker(env, model, formulas[0].raw_formula) parameters = model.collect_probability_parameters() assert len(parameters) == 2 region = stormpy.pars.ParameterRegion.create_from_string( "0.7<=pL<=0.9,0.75<=pK<=0.95", parameters, splitting_threshold=None) result = checker.check_region(env, region) assert result == stormpy.pars.RegionResult.ALLSAT region = stormpy.pars.ParameterRegion.create_from_string( "0.4<=pL<=0.65,0.75<=pK<=0.95", parameters, splitting_threshold=None) result = checker.check_region( env, region, stormpy.pars.RegionResultHypothesis.UNKNOWN, stormpy.pars.RegionResult.UNKNOWN, True) assert result == stormpy.pars.RegionResult.EXISTSBOTH region = stormpy.pars.ParameterRegion.create_from_string( "0.1<=pL<=0.73,0.2<=pK<=0.715", parameters, splitting_threshold=None) result = checker.check_region(env, region) assert result == stormpy.pars.RegionResult.ALLVIOLATED
def test_apply_scheduler_mdp(self): program = stormpy.parse_prism_program( get_example_path("mdp", "coin2-2.nm")) formulas = stormpy.parse_properties_for_prism_program( "Pmin=? [ F \"finished\" & \"all_coins_equal_1\"]", program) model = stormpy.build_model(program, formulas) assert model.nr_states == 272 assert model.nr_transitions == 492 assert len(model.initial_states) == 1 initial_state = model.initial_states[0] assert initial_state == 0 result = stormpy.model_checking(model, formulas[0], extract_scheduler=True) assert result.has_scheduler scheduler = result.scheduler assert scheduler.memoryless assert scheduler.memory_size == 1 assert scheduler.deterministic assert not scheduler.partial intermediate = model.apply_scheduler(scheduler, True) assert intermediate.model_type == stormpy.ModelType.DTMC assert intermediate.nr_states == 126 assert intermediate.nr_transitions == 156 for state in intermediate.states: assert len(state.actions) == 1
def test_scheduler_mdp(self): program = stormpy.parse_prism_program( get_example_path("mdp", "coin2-2.nm")) formulas = stormpy.parse_properties_for_prism_program( "Pmin=? [ F \"finished\" & \"all_coins_equal_1\"]", program) model = stormpy.build_model(program, formulas) assert model.nr_states == 272 assert model.nr_transitions == 492 assert len(model.initial_states) == 1 initial_state = model.initial_states[0] assert initial_state == 0 result = stormpy.model_checking(model, formulas[0], extract_scheduler=True) assert result.has_scheduler scheduler = result.scheduler assert scheduler.memoryless assert scheduler.memory_size == 1 assert scheduler.deterministic for state in model.states: choice = scheduler.get_choice(state) assert choice.defined assert choice.deterministic action = choice.get_deterministic_choice() assert 0 <= action assert action < len(state.actions) distribution = choice.get_choice() assert str(distribution).startswith("{[1:")
def _load_optimality(self, path, program): logger.debug("Loading optimality info.") direction = None epsilon = None with open(path) as file: for line in file: if line.startswith("//"): continue if line.rstrip() == "min": direction = "min" elif line.rstrip() == "max": direction = "max" elif line.startswith("relative"): epsilon = float(line.split()[1]) else: logger.debug("Criterion {}".format(line)) optimality_criterion = stormpy.parse_properties_for_prism_program( line, program)[0] logger.debug("Done parsing optimality file.") if direction is None: raise ValueError("direction not set") if epsilon is None: raise ValueError("epsilon not set") if not optimality_criterion: raise ValueError("optimality criterion not set") self._optimality_setting = OptimalitySetting(optimality_criterion, direction, epsilon)
def test_apply_scheduler_ma(self): program = stormpy.parse_prism_program( get_example_path("ma", "simple.ma"), False, True) formulas = stormpy.parse_properties_for_prism_program( "Tmin=? [ F s=4 ]", program) ma = stormpy.build_model(program, formulas) assert ma.nr_states == 5 assert ma.nr_transitions == 8 assert ma.model_type == stormpy.ModelType.MA initial_state = ma.initial_states[0] assert initial_state == 0 result = stormpy.model_checking(ma, formulas[0], extract_scheduler=True) assert math.isclose(result.at(initial_state), 0.08333333333) assert result.has_scheduler scheduler = result.scheduler assert scheduler.memoryless assert scheduler.memory_size == 1 assert scheduler.deterministic intermediate = ma.apply_scheduler(scheduler) assert intermediate.model_type == stormpy.ModelType.MA assert intermediate.nr_states == 3 assert intermediate.nr_transitions == 4 for state in intermediate.states: assert len(state.actions) == 1
def test_change_parametric_matrix_modelchecking(self): import stormpy.logic program = stormpy.parse_prism_program( get_example_path("pdtmc", "brp16_2.pm")) formulas = stormpy.parse_properties_for_prism_program( "P=? [ F s=5 ]", program) model = stormpy.build_parametric_model(program, formulas) initial_state = model.initial_states[0] assert initial_state == 0 matrix = model.transition_matrix # Check matrix one_pol = stormpy.RationalRF(1) one_pol = stormpy.FactorizedPolynomial(one_pol) one = stormpy.FactorizedRationalFunction(one_pol, one_pol) for e in matrix: assert e.value() == one or len(e.value().gather_variables()) > 0 # First model checking result = stormpy.model_checking(model, formulas[0]) ratFunc = result.at(initial_state) assert len(ratFunc.gather_variables()) > 0 # Change probabilities two_pol = stormpy.RationalRF(2) two_pol = stormpy.FactorizedPolynomial(two_pol) new_val = stormpy.FactorizedRationalFunction(one_pol, two_pol) for e in matrix: if len(e.value().gather_variables()) > 0: e.set_value(new_val) for e in matrix: assert e.value() == new_val or e.value() == one # Second model checking result = stormpy.model_checking(model, formulas[0]) ratFunc = result.at(initial_state) assert len(ratFunc.gather_variables()) == 0
def example_schedulers_02(): path = stormpy.examples.files.prism_ma_simple formula_str = "Tmin=? [ F s=4 ]" program = stormpy.parse_prism_program(path, False, True) formulas = stormpy.parse_properties_for_prism_program(formula_str, program) ma = stormpy.build_model(program, formulas) assert ma.model_type == stormpy.ModelType.MA # Convert MA to MDP mdp, mdp_formulas = stormpy.transform_to_discrete_time_model(ma, formulas) assert mdp.model_type == stormpy.ModelType.MDP initial_state = mdp.initial_states[0] assert initial_state == 0 result = stormpy.model_checking(mdp, mdp_formulas[0], extract_scheduler=True) assert result.has_scheduler scheduler = result.scheduler print(scheduler) assert scheduler.memoryless assert scheduler.deterministic for state in mdp.states: choice = scheduler.get_choice(state) action = choice.get_deterministic_choice() print("In state {} choose action {}".format(state, action))
def test_build_ma(self): program = stormpy.parse_prism_program(get_example_path("ma", "simple.ma"), False, True) formulas = stormpy.parse_properties_for_prism_program("Pmax=? [ F<=2 s=2 ]", program) model = stormpy.build_model(program, formulas) assert model.nr_states == 4 assert model.nr_transitions == 7 assert model.model_type == stormpy.ModelType.MA assert not model.supports_parameters assert type(model) is stormpy.SparseMA
def test_build_mdp(self): program = stormpy.parse_prism_program(get_example_path("mdp", "two_dice.nm")) formulas = stormpy.parse_properties_for_prism_program("P=? [ F \"two\" ]", program) model = stormpy.build_model(program, formulas) assert model.nr_states == 169 assert model.nr_transitions == 435 assert model.model_type == stormpy.ModelType.MDP assert not model.supports_parameters assert type(model) is stormpy.SparseMdp
def test_build_ctmc(self): program = stormpy.parse_prism_program(get_example_path("ctmc", "polling2.sm"), True) formulas = stormpy.parse_properties_for_prism_program("P=? [ F<=3 \"target\" ]", program) model = stormpy.build_symbolic_model(program, formulas) assert model.nr_states == 12 assert model.nr_transitions == 21 assert model.model_type == stormpy.ModelType.CTMC assert not model.supports_parameters assert type(model) is stormpy.SymbolicSylvanCtmc
def test_model_checking_only_initial(self): program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) formulas = stormpy.parse_properties_for_prism_program("Pmax=? [F{\"coin_flips\"}<=3 \"one\"]", program) model = stormpy.build_model(program, formulas) assert len(model.initial_states) == 1 initial_state = model.initial_states[0] assert initial_state == 0 result = stormpy.model_checking(model, formulas[0], only_initial_states=True) assert not result.result_for_all_states assert math.isclose(result.at(initial_state), 1 / 8)
def test_model_checking_all_dtmc(self): program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) formulas = stormpy.parse_properties_for_prism_program("P=? [ F \"one\" ]", program) model = stormpy.build_model(program, formulas) assert model.nr_states == 13 assert model.nr_transitions == 20 result = stormpy.model_checking(model, formulas[0]) assert result.result_for_all_states reference = [1 / 6, 1 / 3, 0, 2 / 3, 0, 0, 0, 1, 0, 0, 0, 0, 0] assert all(map(math.isclose, result.get_values(), reference))
def __init__(self): self.target_label = "one" program_path = get_example_path("dtmc", "die.pm") raw_formula = "P=? [ F \"" + self.target_label + "\" ]" program = stormpy.parse_prism_program(program_path) formulas = stormpy.parse_properties_for_prism_program( raw_formula, program) self.model = stormpy.build_model(program, formulas)
def test_reduce_to_state_based_rewards(self): program = stormpy.parse_prism_program(get_example_path("dtmc", "die.pm")) prop = "R=? [F \"done\"]" properties = stormpy.parse_properties_for_prism_program(prop, program, None) model = stormpy.build_symbolic_model(program, properties) model.reduce_to_state_based_rewards() assert len(model.reward_models) == 1 assert model.reward_models["coin_flips"].has_state_rewards assert not model.reward_models["coin_flips"].has_state_action_rewards assert not model.reward_models["coin_flips"].has_transition_rewards
def test_mdp_simplification(self): program = stormpy.parse_prism_program(get_example_path("pmdp", "two_dice.nm")) formulas = stormpy.parse_properties_for_prism_program("Pmin=? [ F \"two\" ]", program) formula = formulas[0].raw_formula model = stormpy.build_parametric_model(program, formulas) assert model.nr_states == 169 assert model.nr_transitions == 435 model, formula = stormpy.pars.simplify_model(model, formula) assert model.nr_states == 17 assert model.nr_transitions == 50