def test_prmin_prmax(): for dtmc in dtmcs: reach_form ,_,_ = ReachabilityForm.reduce(dtmc,"init","target") for solver in solvers: m_z_st = reach_form.max_z_state(solver=solver) m_z_st_act = reach_form.max_z_state_action(solver=solver) m_y_st_act = reach_form.max_y_state_action(solver=solver) m_y_st = reach_form.max_y_state(solver=solver) for vec in [m_z_st,m_z_st_act,m_y_st,m_y_st_act]: assert (vec >= -1e-8).all() for vec in [m_z_st,m_z_st_act]: assert (vec <= 1+1e-8).all() pr_min = reach_form.pr_min() pr_max = reach_form.pr_max() for vec in [pr_min,pr_max]: assert (vec <= 1).all() and (vec >= 0).all() assert (pr_min == pr_max).all() pr_min_at_init = pr_min[reach_form.initial] pr_max_at_init = pr_max[reach_form.initial] # we find farkas certificates for pr_min and pr_max fark_cert_min = generate_farkas_certificate( reach_form,"min",">=",pr_min_at_init - 1e-8) fark_cert_max = generate_farkas_certificate( reach_form,"max",">=",pr_max_at_init - 1e-8) assert (fark_cert_min is not None) and (fark_cert_max is not None)
def test_heuristics(): initializers = [qsparam.AllOnesInitializer, qsparam.InverseReachabilityInitializer, qsparam.InverseFrequencyInitializer] for dtmc in dtmcs: reach_form ,_,_ = ReachabilityForm.reduce(dtmc,"init","target") instances = [ QSHeur(iterations=3,initializertype=init,solver=solver)\ for (solver,init) in zip(solvers,initializers) ] for threshold in [0.1, 0.2, 0.3, 0.4, 0.5, 0.66, 0.7, 0.88, 0.9, 0.999, 1,0.9999999999]: print(dtmc) print(threshold) results = [] for mode in ["min", "max"]: for instance in instances: results.append(instance.solve(reach_form,threshold,mode)) # either the status of all results is optimal, or of none of them positive_results = [result for result in results if result.status == "optimal"] assert len(positive_results) == len(results) or len(positive_results) == 0 # test the construction of the resulting subsystems for r in results: if r.status == "optimal": assert r.value >= 0 ss_mask = r.subsystem.subsystem_mask ss_reach_form = r.subsystem.reachability_form super_reach_form = r.subsystem.supersys_reachability_form ss_model = r.subsystem.model
def test_label_based_exact_min(): ex_mdp = toy_mdp2() reach_form, _, _ = ReachabilityForm.reduce(ex_mdp, "init", "target") instances = [MILPExact(solver) for solver in milp_solvers] for threshold in [ 0.0001, 0.1, 0.2, 0.3, 0.4, 0.5, 0.66, 0.7, 0.88, 0.9, 0.999, 1, 0.9999999999 ]: min_results, max_results = [], [] for instance in instances: min_results.append( instance.solve(reach_form, threshold, "min", labels=["blue"])) max_results.append( instance.solve(reach_form, threshold, "max", labels=["blue"])) # either the status of all results is optimal, or of none of them min_positive_results = [ result for result in min_results if result.status == "optimal" ] assert len(min_positive_results) == len(min_results) or len( min_positive_results) == 0 max_positive_results = [ result for result in max_results if result.status == "optimal" ] assert len(max_positive_results) == len(max_results) or len( max_positive_results) == 0 if min_results[0].status == "optimal": # if the result was optimal, tha values of all results should be the same assert len(set([result.status for result in min_results])) == 1 assert max_results[0].status == "optimal" assert max_results[0].value <= min_results[0].value elif max_results[0].status == "optimal": assert len(set([result.status for result in max_results])) == 1
def test_label_based_exact_min(): ex_dtmc = toy_dtmc2() reach_form, _, _ = ReachabilityForm.reduce(ex_dtmc, "init", "target") instances = [MILPExact(solver) for solver in milp_solvers] for threshold in [ 0.0001, 0.1, 0.2, 0.3, 0.4, 0.5, 0.66, 0.7, 0.88, 0.9, 0.999, 1, 0.9999999999 ]: results = [] for mode in ["min", "max"]: for instance in instances: results.append( instance.solve(reach_form, threshold, mode, labels=["group1", "group3"], timeout=20)) # either the status of all results is optimal, or of none of them positive_results = [ result for result in results if result.status == "optimal" ] assert len(positive_results) == len(results) or len( positive_results) == 0 if results[0].status == "optimal": # if the result was optimal, tha values of all results should be the same assert len(set([result.status for result in results])) == 1
def test_minimal_witnesses(): for dtmc in dtmcs: reach_form, _, _ = ReachabilityForm.reduce(dtmc, "init", "target") instances = [MILPExact(solver) for solver in milp_solvers] for threshold in [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.66, 0.7, 0.88, 0.9, 0.999, 1, 0.9999999999 ]: print(dtmc) print(threshold) results = [] for mode in ["min", "max"]: for instance in instances: results.append( instance.solve(reach_form, threshold, mode, timeout=20)) # either the status of all results is optimal, or of none of them positive_results = [ result for result in results if result.status == "optimal" ] assert len(positive_results) == len(results) or len( positive_results) == 0 if results[0].status == "optimal": # if the result was optimal, tha values of all results should be the same assert len(set([result.status for result in results])) == 1
def test_certificates(): for dtmc in dtmcs: reach_form, _, _ = ReachabilityForm.reduce(dtmc, "init", "target") for sense in ["<", "<=", ">", ">="]: for threshold in [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.66, 0.7, 0.88, 0.9, 0.999, 1, 0.9999999999 ]: fark_cert_min = generate_farkas_certificate( reach_form, "min", sense, threshold) fark_cert_max = generate_farkas_certificate( reach_form, "max", sense, threshold) assert (fark_cert_max is None) == (fark_cert_min is None) if fark_cert_max is not None: check_min = check_farkas_certificate(reach_form, "min", sense, threshold, fark_cert_min, tol=1e-5) check_max = check_farkas_certificate(reach_form, "max", sense, threshold, fark_cert_max, tol=1e-5) assert check_min assert check_max
def test_certificates(): for mdp in mdps: reach_form, _, _ = ReachabilityForm.reduce(mdp, "init", "target") for sense in ["<", "<=", ">", ">="]: for threshold in [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.66, 0.7, 0.88, 0.9, 0.999, 1 ]: print(mdp) print(threshold) fark_cert_min = generate_farkas_certificate( reach_form, "min", sense, threshold) fark_cert_max = generate_farkas_certificate( reach_form, "max", sense, threshold) # if the sense is >= or > and there is a certificate for pr_min, then there is one for pr_max if sense in [">", ">="]: assert (fark_cert_min is None) or (fark_cert_max is not None) # and dually: if sense in ["<", "<="]: assert (fark_cert_max is None) or (fark_cert_min is not None) if sense in [">", ">="] and fark_cert_min is not None: check_min = check_farkas_certificate(reach_form, "min", sense, threshold, fark_cert_min, tol=1e-5) check_max = check_farkas_certificate(reach_form, "max", sense, threshold, fark_cert_max, tol=1e-5) assert check_min assert check_max if sense in ["<", "<="] and fark_cert_max is not None: check_min = check_farkas_certificate(reach_form, "min", sense, threshold, fark_cert_min, tol=1e-5) check_max = check_farkas_certificate(reach_form, "max", sense, threshold, fark_cert_max, tol=1e-5) assert check_min assert check_max
def construct_conflicts(self, family, assignment, dtmc, conflict_requests, ce_generator): conflicts = [] for request in conflict_requests: index,prop,member_result,family_result = request if prop.minimizing: # safety threshold = prop.threshold target_label = str(prop.property.raw_formula.subformula.subformula) else: # liveness: flip threshold threshold = 1 - prop.threshold target_label = "target" # construct a labeled SWITSS DTMC switss_dtmc = SWITSS_DTMC.from_stormpy(dtmc.model) for i,state in enumerate(dtmc.model.states): # copy labels for label in state.labels: switss_dtmc.add_label(i, label) # label fail states if not prop.minimizing and not member_result.result.at(i) > 0.0: switss_dtmc.add_label(i, "target") # label states by relevant holes id for dtmc_state in range(dtmc.states): mdp_state = dtmc.quotient_state_map[dtmc_state] for hole in dtmc.quotient_container.coloring.state_to_holes[mdp_state]: switss_dtmc.add_label(dtmc_state, str(hole)) switss_dtmc_rf,_,_ = ReachabilityForm.reduce(switss_dtmc, "init", target_label) results = list(ce_generator.solveiter(switss_dtmc_rf, threshold, "max")) # get last result witnessing_subsystem = results[-1].subsystem.subsys.system conflict = set([int(label) for label in witnessing_subsystem.states_by_label.keys() if label.isnumeric()]) conflict = list(conflict) scheduler_selection = None if family_result is not None: scheduler_selection = family_result.primary_selection conflict = self.generalize_conflict(assignment, conflict, scheduler_selection) conflicts.append(conflict) return conflicts
def test_minimal_witnesses(): # only test the first 2 examples, as the others are too large for mdp in mdps[:1]: reach_form, _, _ = ReachabilityForm.reduce(mdp, "init", "target") instances = [MILPExact(solver) for solver in milp_solvers] for threshold in [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.66, 0.7, 0.88, 0.9, 0.999, 1, 0.9999999999 ]: print(mdp) print(threshold) max_results, min_results = [], [] for instance in instances: min_results.append(instance.solve(reach_form, threshold, "min")) max_results.append(instance.solve(reach_form, threshold, "max")) # either the status of all results is optimal, or of none of them # and this should hold for min and max min_positive_results = [ result for result in min_results if result.status == "optimal" ] assert len(min_positive_results) == len(min_results) or len( min_positive_results) == 0 max_positive_results = [ result for result in max_results if result.status == "optimal" ] assert len(max_positive_results) == len(max_results) or len( max_positive_results) == 0 if min_results[0].status == "optimal": assert len(set([result.status for result in min_results])) == 1 assert max_results[0].status == "optimal" assert len(set([result.status for result in max_results])) == 1 assert max_results[0].value <= min_results[0].value elif max_results[0].status == "optimal": assert max_results[0].status == "optimal" assert len(set([result.status for result in max_results])) == 1
def test_create_reach_form(): for dtmc in dtmcs: print(dtmc) reach_form ,_,_ = ReachabilityForm.reduce(dtmc,"init","target")
def test_mec_free(): for mdp in mdps: rf, _, _ = ReachabilityForm.reduce(mdp, "init", "target") rf._check_mec_freeness()
def test_create_reach_form(): for mdp in mdps: print(mdp) reach_form, _, _ = ReachabilityForm.reduce(mdp, "init", "target")