Esempio n. 1
0
def attractor(bdd, g, i, f):
    k = 0
    attr_old = f
    while True:
        # Code non-optimized
        # f_1 = g.tau & bdd.let(g.mapping_bis, attr_old)
        # f_1 = bdd.exist(g.bis_vars, f_1)
        f_1 = _bdd.and_exists(g.tau, bdd.let(g.mapping_bis, attr_old),
                              g.bis_vars)

        # Code non-optimized
        # f_2 = g.tau & bdd.let(g.mapping_bis, (~attr_old))
        # f_2 = ~(bdd.exist(g.bis_vars, f_2))

        f_2 = ~_bdd.and_exists(g.tau, bdd.let(g.mapping_bis, ~attr_old),
                               g.bis_vars)

        if i == 0:
            f_1 = g.phi_0 & f_1
            f_2 = g.phi_1 & f_2
        else:
            f_1 = g.phi_1 & f_1
            f_2 = g.phi_0 & f_2

        attr_new = attr_old | f_1 | f_2
        if attr_new == attr_old:
            break
        attr_old = attr_new
        k = k + 1
    return attr_old
Esempio n. 2
0
def monotone_attractor(arena, s, priority, manager):
    """
    Computes the monotone attractor of the target set, meaning the attractor without visiting bigger priorities than
    the one of the target set.
    :param arena: the arena in which we compute the attractor
    :type arena: Arena
    :param s: the set for which we compute the attractor
    :type s: dd.cudd.Function
    :param priority: the priority of vertices in s
    :type priority: int
    :param manager: the BDD manager
    :type manager: dd.cudd.BDD
    :return: the computed attractor
    :rtype: dd.cudd.Function
    """

    player = priority % 2  # the player for which we compute the attractor

    old_attractor = manager.true
    new_attractor = manager.false  # at first attractor only contains s

    vertices_smaller_priority = manager.false
    for prio, bdd in arena.priorities[0].items():
        if prio <= priority:
            vertices_smaller_priority = vertices_smaller_priority | bdd

    # while a fixpoint is not reached
    while old_attractor != new_attractor:

        old_attractor = new_attractor

        # BDD representing the old attractor set, using prime variables
        old_attractor_prime = manager.let(arena.mapping_bis, old_attractor | s)

        # BDD representing vertices with at least one successor in the old attractor
        vertices_one_succ = bdd_func.and_exists(arena.edges,
                                                old_attractor_prime,
                                                arena.vars_bis)

        # BDD representing vertices with at least one successor outside the previous attractor
        vertices_all_succ = ~bdd_func.and_exists(
            arena.edges, ~old_attractor_prime, arena.vars_bis)

        # if we compute the attractor for player 0
        if not player:
            player0_vertices_attractor = arena.player0_vertices & vertices_one_succ
            player1_vertices_attractor = arena.player1_vertices & vertices_all_succ
        else:
            player0_vertices_attractor = arena.player0_vertices & vertices_all_succ
            player1_vertices_attractor = arena.player1_vertices & vertices_one_succ

        # we impose that the computed predecessors have smaller or equal priority
        new_attractor = (old_attractor | player0_vertices_attractor | player1_vertices_attractor) & \
                        vertices_smaller_priority

    return new_attractor
Esempio n. 3
0
def test_and_exists():
    bdd = cudd.BDD()
    for var in ['x', 'y']:
        bdd.add_var(var)
    # (\E x:  x /\ y) \equiv y
    x = bdd.add_expr('x')
    y = bdd.add_expr('y')
    qvars = ['x']
    r = cudd.and_exists(x, y, qvars)
    assert r == y, (r, y)
    # (\E x:  x /\ ~ x) \equiv FALSE
    not_x = bdd.apply('not', x)
    r = cudd.and_exists(x, not_x, qvars)
    assert r == bdd.false
Esempio n. 4
0
def test_and_exists():
    bdd = cudd.BDD()
    for var in ['x', 'y']:
        bdd.add_var(var)
    # (\E x:  x /\ y) \equiv y
    x = bdd.add_expr('x')
    y = bdd.add_expr('y')
    qvars = ['x']
    r = cudd.and_exists(x, y, qvars)
    assert r == y, (r, y)
    # (\E x:  x /\ ~ x) \equiv FALSE
    not_x = bdd.apply('not', x)
    r = cudd.and_exists(x, not_x, qvars)
    assert r == bdd.false
Esempio n. 5
0
def test_and_exists():
    bdd = cudd.BDD()
    for var in ['x', 'y']:
        bdd.add_var(var)
    # \E x: x & y = y
    x = bdd.add_expr('x')
    y = bdd.add_expr('y')
    qvars = ['x']
    r = cudd.and_exists(x, y, qvars, bdd)
    assert r == y, (r, y)
    # \E x: x & !x = 0
    not_x = bdd.apply('not', x)
    r = cudd.and_exists(x, not_x, qvars, bdd)
    assert r == bdd.false
Esempio n. 6
0
def p_safe_attractor_full(bdd, g, i, tau_e, u, avoid):
    # Non-optimized code
    # f_1 = (tau_e & bdd.let(g.mapping_bis, u)) & ~avoid
    # f_1 = bdd.exist(g.bis_vars + g.em_vars_bis, f_1)
    f_1 = _bdd.and_exists(tau_e,
                          bdd.let(g.mapping_bis, u) & ~avoid,
                          g.bis_vars + g.em_vars_bis)

    # Non-optimized code
    # f_2 = tau_e & bdd.let(g.mapping_bis, ~u)
    # f_2 = ~ bdd.exist(g.bis_vars + g.em_vars_bis, f_2) & ~avoid
    f_2 = ~_bdd.and_exists(tau_e, bdd.let(g.mapping_bis, ~u),
                           g.bis_vars + g.em_vars_bis) & ~avoid

    if i == 0:
        f_1 = g.phi_0 & f_1
        f_2 = g.phi_1 & f_2
    else:
        f_1 = g.phi_1 & f_1
        f_2 = g.phi_0 & f_2

    attr_old = f_1 | f_2
    while True:
        # Non-optimized code
        # f_1 = (tau_e & bdd.let(g.mapping_bis, attr_old)) & ~avoid
        # f_1 = bdd.exist(g.bis_vars + g.em_vars_bis, f_1)
        f_1 = _bdd.and_exists(tau_e,
                              bdd.let(g.mapping_bis, attr_old) & ~avoid,
                              g.bis_vars + g.em_vars_bis)

        # Non-optimized code
        # f_2 = tau_e & bdd.let(g.mapping_bis, ~(attr_old | u))
        # f_2 = ~ bdd.exist(g.bis_vars + g.em_vars_bis, f_2) & ~avoid
        f_2 = ~_bdd.and_exists(tau_e, bdd.let(g.mapping_bis, ~(attr_old | u)),
                               g.bis_vars + g.em_vars_bis) & ~avoid

        if i == 0:
            f_1 = g.phi_0 & f_1
            f_2 = g.phi_1 & f_2
        else:
            f_1 = g.phi_1 & f_1
            f_2 = g.phi_0 & f_2

        attr_new = attr_old | f_1 | f_2
        if attr_new == attr_old:
            break
        attr_old = attr_new

    return attr_old
Esempio n. 7
0
def test_and_exists():
    bdd = cudd.BDD()
    for var in ['x', 'y']:
        bdd.add_var(var)
    # \E x: x & y = y
    x = bdd.add_expr('x')
    y = bdd.add_expr('y')
    qvars = ['x']
    r = cudd.and_exists(x, y, qvars, bdd)
    assert r == y, (r, y)
    # \E x: x & !x = 0
    not_x = bdd.apply('not', x)
    r = cudd.and_exists(x, not_x, qvars, bdd)
    assert r == bdd.false
    del x, not_x, y, r
Esempio n. 8
0
def attractor_cudd(arena, s, player, manager):
    """
    Computes the attractor of set s for player in the arena. This version uses cudd-specific functions.
    :param arena: the arena in which we compute the attractor
    :type arena: Arena
    :param s: the set for which we compute the attractor
    :type s: dd.cudd.Function
    :param player: the player for which we compute the attractor
    :type player: int
    :param manager: the BDD manager
    :type manager: dd.cudd.BDD
    :return: the computed attractor
    :rtype: dd.cudd.Function
    """

    old_attractor = manager.false
    new_attractor = s  # at first attractor only contains s

    # while a fixpoint is not reached
    while old_attractor != new_attractor:

        old_attractor = new_attractor

        # BDD representing the old attractor set, using prime variables
        old_attractor_prime = manager.let(arena.mapping_bis, old_attractor)

        # BDD representing vertices with at least one successor in the old attractor
        vertices_one_succ = bdd_func.and_exists(arena.edges,
                                                old_attractor_prime,
                                                arena.vars_bis)

        # BDD representing vertices with at least one successor outside the previous attractor
        vertices_all_succ = ~bdd_func.and_exists(
            arena.edges, ~old_attractor_prime, arena.vars_bis)

        # if we compute the attractor for player 0
        if not player:
            # vertices in vertices_all_succ, which is a negation, that don't exist are ignored since they dont belong to
            # arena.player0_vertices
            player0_vertices_attractor = arena.player0_vertices & vertices_one_succ
            player1_vertices_attractor = arena.player1_vertices & vertices_all_succ
        else:
            player0_vertices_attractor = arena.player0_vertices & vertices_all_succ
            player1_vertices_attractor = arena.player1_vertices & vertices_one_succ

        new_attractor = old_attractor | player0_vertices_attractor | player1_vertices_attractor

    return new_attractor
Esempio n. 9
0
def good_ep(bdd, g, i, tau_e):
    f_old = g.phi_0 | g.phi_1
    while True:
        if i == 0:
            t = f_old & ~bdd.var(g.m_vars[0])
        else:
            t = f_old & bdd.var(g.m_vars[0])

        attr_t = attractor_pos_ext(bdd, g, i, t, tau_e)
        f = f_old & attr_t

        # For a vertice (v,m) check that m = P(v)
        id_prio_m = bdd.false
        for curr_p in range(g.d + 1):
            curr_p_point = num_to_map(curr_p, g.m_vars)
            curr_p_bdd = bdd.cube(curr_p_point)
            id_prio_m = id_prio_m | (g.gamma[curr_p] & curr_p_bdd)

        # Non-optimized code
        # f = f & id_prio_m
        # f = bdd.exist(g.m_vars, f)
        f = _bdd.and_exists(f, id_prio_m, g.m_vars)

        if f == f_old:
            break
        f_old = f

    return f
Esempio n. 10
0
def good_ep_full(bdd, g, i, tau_e):
    f_old = g.phi_0 | g.phi_1
    flat_m_vars_bis = [c_var for sublist in g.m_vars_bis for c_var in sublist]
    flat_m_vars = [c_var for sublist in g.m_vars for c_var in sublist]
    while True:
        t = f_old
        for prio_f_index in range(g.k):
            if i == 0:
                t = t & ~bdd.var(g.m_vars[prio_f_index][0])
            else:
                t = t & bdd.var(g.m_vars[prio_f_index][0])
        attr_t = attractor_pos_ext(bdd, g, i, t, tau_e, flat_m_vars_bis)
        f = f_old & attr_t
        # For a vertice (v,m_0, ..., m_k-1) check that m_l = P_l(v)
        id_prio_m = bdd.true
        for prio_f_index in range(g.k):
            curr_prio_m = bdd.false
            for curr_p in range(g.d[prio_f_index] + 1):
                curr_p_point = num_to_map(curr_p, g.m_vars[prio_f_index])
                curr_p_bdd = bdd.cube(curr_p_point)
                curr_prio_m = curr_prio_m | (g.gamma[prio_f_index][curr_p]
                                             & curr_p_bdd)
            id_prio_m = id_prio_m & curr_prio_m

        # Non-optimized code
        # f = f & id_prio_m
        # f = bdd.exist(flat_m_vars, f)
        f = _bdd.and_exists(f, id_prio_m, flat_m_vars)

        if f == f_old:
            break
        f_old = f
    return f
Esempio n. 11
0
def p_safe_attractor(bdd, g, i, u, avoid):
    # Code non-optimized
    # f_1 = (g.tau & bdd.let(g.mapping_bis, u)) & ~avoid
    # f_1 = bdd.exist(g.bis_vars, f_1)
    f_1 = _bdd.and_exists(g.tau,
                          bdd.let(g.mapping_bis, u) & ~avoid, g.bis_vars)

    # Code non-optimized
    # f_2 = g.tau & bdd.let(g.mapping_bis, ~u)
    # f_2 = ~ bdd.exist(g.bis_vars, f_2) & ~ avoid
    f_2 = ~_bdd.and_exists(g.tau, bdd.let(g.mapping_bis, ~u),
                           g.bis_vars) & ~avoid
    if i == 0:
        f_1 = g.phi_0 & f_1
        f_2 = g.phi_1 & f_2
    else:
        f_1 = g.phi_1 & f_1
        f_2 = g.phi_0 & f_2

    attr_old = f_1 | f_2
    while True:
        # Code non-optimized
        # f_1 = g.tau & bdd.let(g.mapping_bis, attr_old) & ~avoid
        # f_1 = bdd.exist(g.bis_vars, f_1)
        f_1 = _bdd.and_exists(g.tau,
                              bdd.let(g.mapping_bis, attr_old) & ~avoid,
                              g.bis_vars)

        # Code non-optimized
        # f_2 = g.tau & bdd.let(g.mapping_bis, ~(attr_old | u))
        # f_2 = ~bdd.exist(g.bis_vars, f_2) & ~avoid
        f_2 = ~_bdd.and_exists(g.tau, bdd.let(g.mapping_bis, ~(attr_old | u)),
                               g.bis_vars) & ~avoid

        if i == 0:
            f_1 = g.phi_0 & f_1
            f_2 = g.phi_1 & f_2
        else:
            f_1 = g.phi_1 & f_1
            f_2 = g.phi_0 & f_2

        attr_new = attr_old | f_1 | f_2
        if attr_new == attr_old:
            break
        attr_old = attr_new

    return attr_old
Esempio n. 12
0
def attractor_pos(bdd, g, i, f):
    k = 1

    # Code non-optimized
    # f_1 = (g.tau & bdd.let(g.mapping_bis, f))
    # f_1 = bdd.exist(g.bis_vars, f_1)
    f_1 = bdd_func.and_exists(g.edges, bdd.let(g.mapping_bis, f), g.vars_bis)

    # Code non-optimized
    # f_2 = g.tau & bdd.let(g.mapping_bis, ~f)
    # f_2 = ~(bdd.exist(g.bis_vars, f_2))
    f_2 = ~bdd_func.and_exists(g.edges, bdd.let(g.mapping_bis, ~f), g.vars_bis)
    if i == 0:
        f_1 = g.player0_vertices & f_1
        f_2 = g.player1_vertices & f_2
    else:
        f_1 = g.player1_vertices & f_1
        f_2 = g.player0_vertices & f_2

    attr_old = f_1 | f_2
    while True:
        # Code non-optimized
        # f_1 = (g.tau & bdd.let(g.mapping_bis, attr_old))
        # f_1 = (bdd.exist(g.bis_vars, f_1))
        f_1 = bdd_func.and_exists(g.edges, bdd.let(g.mapping_bis, attr_old),
                                  g.vars_bis)

        # Code non-optimized
        # f_2 = g.tau & bdd.let(g.mapping_bis, ~(attr_old | f))
        # f_2 = ~(bdd.exist(g.bis_vars, f_2))
        f_2 = ~bdd_func.and_exists(
            g.edges, bdd.let(g.mapping_bis, ~(attr_old | f)), g.vars_bis)

        if i == 0:
            f_1 = g.player0_vertices & f_1
            f_2 = g.player1_vertices & f_2
        else:
            f_1 = g.player1_vertices & f_1
            f_2 = g.player0_vertices & f_2

        attr_new = attr_old | f_1 | f_2
        if attr_new == attr_old:
            break
        attr_old = attr_new
        k = k + 1
    return attr_old
Esempio n. 13
0
def attractor_pos_ext(bdd, g, i, f, tau_e):
    # Non-optimized code
    # f_1 = (tau_e & bdd.let(g.mapping_bis, f))
    # f_1 = bdd.exist(g.bis_vars + g.m_vars_bis, f_1)
    f_1 = _bdd.and_exists(tau_e, bdd.let(g.mapping_bis, f),
                          g.bis_vars + g.m_vars_bis)

    # Non-optimized code
    # f_2 = tau_e & bdd.let(g.mapping_bis, ~f)
    # f_2 = ~(bdd.exist(g.bis_vars + g.m_vars_bis, f_2))
    f_2 = ~_bdd.and_exists(tau_e, bdd.let(g.mapping_bis, ~f),
                           g.bis_vars + g.m_vars_bis)

    if i == 0:
        f_1 = g.phi_0 & f_1
        f_2 = g.phi_1 & f_2
    else:
        f_1 = g.phi_1 & f_1
        f_2 = g.phi_0 & f_2

    attr_old = f_1 | f_2
    while True:
        # Non-optimized code
        # f_1 = tau_e & bdd.let(g.mapping_bis, attr_old)
        # f_1 = bdd.exist(g.bis_vars + g.m_vars_bis, f_1)
        f_1 = _bdd.and_exists(tau_e, bdd.let(g.mapping_bis, attr_old),
                              g.bis_vars + g.m_vars_bis)

        # Non-optimized code
        # f_2 = tau_e & bdd.let(g.mapping_bis, ~(attr_old | f))
        # f_2 = ~(bdd.exist(g.bis_vars + g.m_vars_bis, f_2))
        f_2 = ~_bdd.and_exists(tau_e, bdd.let(g.mapping_bis, ~(attr_old | f)),
                               g.bis_vars + g.m_vars_bis)

        if i == 0:
            f_1 = g.phi_0 & f_1
            f_2 = g.phi_1 & f_2
        else:
            f_1 = g.phi_1 & f_1
            f_2 = g.phi_0 & f_2

        attr_new = attr_old | f_1 | f_2
        if attr_new == attr_old:
            break
        attr_old = attr_new
    return attr_old