def buchi_solver_gen(bdd, g): # Iterate over all 1-priority for prio_f_index in range(g.k): for curr_prio in range(g.d[prio_f_index] + 1): if curr_prio % 2 == 1 and not g.gamma[prio_f_index][ curr_prio] == bdd.false: u = g.gamma[prio_f_index][curr_prio] u_bis = g.sup_prio_expr_even(bdd, curr_prio, prio_f_index) w = attractors.attractor( bdd, g, 1, buchi.buchi_inter_safety(bdd, g, 1, u, u_bis)) if not w == bdd.false: ind_game = g.induced_game(bdd, ~w) (z0, z1) = buchi_solver_gen(bdd, ind_game) return z0, z1 | w even_priorities = [[] for _ in range(g.k)] for prio_f_index in range(g.k): for curr_prio in range(0, g.d[prio_f_index] + 1, 2): if not g.gamma[prio_f_index][curr_prio] == bdd.false: even_priorities[prio_f_index].append(curr_prio) all_combinations = product(*even_priorities) # Iterate over all 0-priority vectors for curr_comb in all_combinations: u = [g.gamma[l][curr_comb[l]] for l in range(g.k)] u_bis = g.sup_one_prio_odd(bdd, curr_comb) w = attractors.attractor( bdd, g, 0, buchi.buchi_inter_safety_gen(bdd, g, u, u_bis)) if not w == bdd.false: ind_game = g.induced_game(bdd, ~w) (z0, z1) = buchi_solver_gen(bdd, ind_game) return z0 | w, z1 return bdd.false, bdd.false
def ziel_with_psolver(bdd, g, psolver): psolver_solved = False if g.phi_0 == bdd.false and g.phi_1 == bdd.false: return bdd.false, bdd.false, psolver_solved (z_0, z_1) = psolver(bdd, g) g_bar = g.induced_game(bdd, ~(z_0 | z_1)) if (g_bar.phi_0 | g_bar.phi_1) == bdd.false: psolver_solved = True return z_0, z_1, psolver_solved p_max, p_max_expr = g_bar.get_max_prio(bdd) i = p_max % 2 x = attractor(bdd, g_bar, i, p_max_expr) g_ind = g_bar.induced_game(bdd, ~x) (win_0, win_1, _) = ziel_with_psolver(bdd, g_ind, psolver) if i == 0: win_i = win_0 win_i_bis = win_1 else: win_i = win_1 win_i_bis = win_0 if win_i_bis == bdd.false: if i == 0: return z_0 | win_i | x, z_1, psolver_solved else: return z_0, z_1 | win_i | x, psolver_solved else: x = attractor(bdd, g_bar, 1 - i, win_i_bis) g_ind = g_bar.induced_game(bdd, ~x) (win_0, win_1, _) = ziel_with_psolver(bdd, g_ind, psolver) if i == 0: return z_0 | win_0, z_1 | win_1 | x, psolver_solved else: return z_0 | win_0 | x, z_1 | win_1, psolver_solved
def zielonka(bdd, g): if g.phi_0 == bdd.false and g.phi_1 == bdd.false: return bdd.false, bdd.false p_max, p_max_expr = g.get_max_prio(bdd) i = p_max % 2 x = attractor(bdd, g, i, p_max_expr) g_bar = g.induced_game(bdd, ~x) (win_0, win_1) = zielonka(bdd, g_bar) if i == 0: win_i = win_0 win_i_bis = win_1 else: win_i = win_1 win_i_bis = win_0 if win_i_bis == bdd.false: if i == 0: return win_i | x, bdd.false else: return bdd.false, win_i | x else: x = attractor(bdd, g, 1 - i, win_i_bis) g_bar = g.induced_game(bdd, ~x) (win_0, win_1) = zielonka(bdd, g_bar) if i == 0: return win_0, win_1 | x else: return win_0 | x, win_1
def good_ep_solver_gen_r(bdd, g): # Search for winning vertices for player 1 for prio_f_index in range(g.k): c_tau_e = compute_tau_ext(bdd, g, prio_f_index) w = good_ep(bdd, g, 1, c_tau_e, prio_f_index) if not w == bdd.false: x = attractors.attractor(bdd, g, 1, w) ind_game = g.induced_game(bdd, ~x) ind_game.m_vars = g.m_vars ind_game.m_vars_bis = g.m_vars_bis ind_game.mapping_bis = g.mapping_bis (z0, z1) = good_ep_solver_gen_r(bdd, ind_game) return z0, z1 | x # Search for winning vertices for player 0 tau_e = compute_full_tau_ext(bdd, g) w = good_ep_full(bdd, g, 0, tau_e) if not w == bdd.false: x = attractors.attractor(bdd, g, 0, w) ind_game = g.induced_game(bdd, ~x) ind_game.m_vars = g.m_vars ind_game.m_vars_bis = g.m_vars_bis ind_game.mapping_bis = g.mapping_bis (z0, z1) = good_ep_solver_gen_r(bdd, ind_game) return z0 | x, z1 return bdd.false, bdd.false
def disj_par_win(bdd, g, max_values): if all(value == 1 for value in max_values) or (g.phi_0 | g.phi_1) == bdd.false: return g.phi_0 | g.phi_1, bdd.false for curr_f in range(g.k): if max_values[curr_f] != 1: a0 = attractor(bdd, g, 0, g.gamma[curr_f][max_values[curr_f]]) g_bar = g.induced_game(bdd, ~a0) a1 = attractor(bdd, g_bar, 1, g_bar.gamma[curr_f][max_values[curr_f] - 1]) h = g_bar.induced_game(bdd, ~a1) while True: copy_max_values = copy.copy(max_values) copy_max_values[curr_f] -= 2 w0, w1 = disj_par_win(bdd, h, copy_max_values) if g_bar.phi_0 | g_bar.phi_1 == bdd.false or w1 == (h.phi_0 | h.phi_1): break a0 = attractor(bdd, g_bar, 0, w0) g_bar = g_bar.induced_game(bdd, ~a0) a1 = attractor(bdd, g_bar, 1, g_bar.gamma[curr_f][max_values[curr_f] - 1]) h = g_bar.induced_game(bdd, ~a1) q_bar = g_bar.phi_0 | g_bar.phi_1 if w1 == (h.phi_0 | h.phi_1) and not q_bar == bdd.false: a1 = attractor(bdd, g, 1, q_bar) w0_bis, w1_bis = disj_par_win(bdd, g.induced_game(bdd, ~a1), max_values) return w0_bis, a1 | w1_bis return g.phi_0 | g.phi_1, bdd.false
def lay_solver_gen(bdd, g): if g.phi_0 | g.phi_1 == bdd.false: return bdd.false, bdd.false # Search for winning vertices for player 1 for prio_f_index in range(g.k): if g.d[prio_f_index] % 2 == 1: init_prio = g.d[prio_f_index] else: init_prio = g.d[prio_f_index] - 1 for min_prio in range(init_prio, -1, -2): w = lay_ep_1(bdd, g, min_prio, prio_f_index) if not w == bdd.false: x = attractors.attractor(bdd, g, 1, w) ind_game = g.induced_game(bdd, ~x) (z0, z1) = lay_solver_gen(bdd, ind_game) return z0, z1 | x # Search for winning vertices for player 0 min_even_prio = [[] for _ in range(g.k)] for prio_f_index in range(g.k): if g.d[prio_f_index] % 2 == 0: init_prio = g.d[prio_f_index] else: init_prio = g.d[prio_f_index] - 1 for curr_prio in range(init_prio, -1, -2): min_even_prio[prio_f_index].append(curr_prio) all_combinations = product(*min_even_prio) init_ext_game_infos(bdd, g) for comb in all_combinations: w = lay_ep_full_0(bdd, g, comb) if not w == bdd.false: x = attractors.attractor(bdd, g, 0, w) ind_game = g.induced_game(bdd, ~x) (z0, z1) = lay_solver_gen(bdd, ind_game) return z0 | x, z1 return bdd.false, bdd.false
def lay_solver(bdd, g): for min_prio in range(g.d, -1, -1): i = min_prio % 2 w = lay_ep(bdd, g, min_prio) if not w == bdd.false: x = attractors.attractor(bdd, g, i, w) ind_game = g.induced_game(bdd, ~x) (z_0, z_1) = lay_solver(bdd, ind_game) if i == 0: return z_0 | x, z_1 else: return z_0, z_1 | x return bdd.false, bdd.false
def good_ep_solver_r(bdd, g): tau_e = compute_tau_ext(bdd, g) for i in [0, 1]: w = good_ep(bdd, g, i, tau_e) if not w == bdd.false: x = attractors.attractor(bdd, g, i, w) ind_game = g.induced_game(bdd, ~x) ind_game.m_vars = g.m_vars ind_game.m_vars_bis = g.m_vars_bis ind_game.mapping_bis = g.mapping_bis (win_0, win_1) = good_ep_solver_r(bdd, ind_game) if i == 0: return win_0 | x, win_1 else: return win_0, win_1 | x return bdd.false, bdd.false
def psolB(bdd, g): for curr_p in range(0, g.d + 1): player = curr_p % 2 x = g.gamma[curr_p] & (g.phi_0 | g.phi_1) f_old = bdd.false while not (x == bdd.false or x == f_old): f_old = x m_attr_x = monotone_attractor(bdd, g, player, x, curr_p) if (m_attr_x | x) == m_attr_x: attr_ma = attractors.attractor(bdd, g, player, m_attr_x) ind_game = g.induced_game(bdd, ~attr_ma) (w_0, w_1) = psolB(bdd, ind_game) if player == 0: w_0 = w_0 | attr_ma else: w_1 = w_1 | attr_ma return w_0, w_1 else: x = x & m_attr_x return bdd.false, bdd.false