def is_stable_or_dead(protocol, valuation, disabled):
    # Dead?
    dead = True

    for t in protocol.transitions:
        p, q = tuple(t.pre)

        if (not t.silent() and (t.pre not in disabled)
                and (valuation[Var(p)] is not False)
                and (valuation[Var(q)] is not False)):
            dead = False
            break

    if dead:
        return True

    # Stable?
    V = protocol.states - valuation.absent_states()
    out = {protocol.output(q) for q in V}

    if len(out) > 1:
        return False
    else:
        x = out.pop()
        R = set()

        for t in protocol.transitions:
            for q in t.post:
                if protocol.output(q) != x:
                    R.add(t.pre)

        formula = Formula(valuation, disabled)

        return formula.implies_all_absent_tautology_check(R)
def new_stage(protocol, stage, valuation, mem):
    new_valuation = new_stage_valuation(protocol, valuation, stage.disabled)

    if is_stable_or_dead(protocol, new_valuation, stage.disabled):
        return Stage(Formula(new_valuation),
                     new_valuation,
                     stage.disabled,
                     speed=Speed.ZERO,
                     parent=stage)

    F, J = eventually_disabled(protocol, new_valuation, stage.disabled, mem)

    # Compute new_formula (Φ) and new_disabled (T)
    if len(F) > 0:
        if len(J) > 0:
            new_disabled = set(stage.disabled) | set(J)
            new_formula = Formula(new_valuation, new_disabled)

            if v_disabled(J, valuation):
                new_formula.assert_valuation(valuation)
            elif v_enabled(J, valuation):
                K = posts_from_pres(protocol, new_valuation, J)
                new_formula.assert_some_pair_present(K)

            # Compute speed
            if is_very_fast(protocol, new_valuation, stage.disabled):
                new_speed = Speed.QUADRATIC
            elif is_fast(protocol, new_valuation, stage.disabled):
                new_speed = Speed.QUADRATIC_LOG
            else:
                new_speed = Speed.CUBIC
        else:
            new_disabled = set(stage.disabled) | set(F)
            new_formula = Formula(new_valuation, new_disabled)
            new_speed = Speed.POLYNOMIAL
    else:
        new_disabled = set(stage.disabled)
        new_formula = Formula(new_valuation, new_disabled)
        new_speed = Speed.EXPONENTIAL

        I = compute_I(protocol, new_valuation, stage.disabled)

        if any(valuation[Var(q)] is True for q in I):
            L = compute_L(protocol, new_valuation, stage.disabled, I)

            new_formula.assert_all_states_absent(I)
            new_formula.assert_some_pair_present(L)
        elif all(valuation[Var(q)] is False for q in I):
            new_formula.assert_valuation(valuation)
        else:
            new_formula.assert_all_states_absent(I)

    return Stage(new_formula,
                 new_valuation,
                 new_disabled,
                 speed=new_speed,
                 parent=stage)
def v_enabled(pairs, valuation):
    for pair in pairs:
        p, q = tuple(pair)

        if ((p != q and
             (valuation[Var(p)] is True and valuation[Var(q)] is True))
                or (p == q and (valuation[Var(p)] is True
                                and valuation[Var(p, True)] is False))):
            return True

    return False
 def ai_move(self, delta_x):
     if not self.gameover and not self.paused:  # 게임 종료, 정지 상태가 아니라면
         new_x = self.stone_x + delta_x  # 새로운 x 좌표는   기존의 stone의 x좌표 + 이동좌표수
         if new_x < Var.board_start_x:  # 새로운 좌표가 0보다 작다면
             new_x = Var.board_start_x  # 새로운 좌표는 0 ( 변경 없음 )
         if new_x > self.board.width - len(Var.piece_length(
                 self.stone)):  # 새로운 좌표 > 열의개수(10) - 블럭의 x축 길이
             new_x = self.board.width - len(Var.piece_length(
                 self.stone))  # 이동 불가 (변경 없음)
         if not self.board.ai_check_collision(
                 self.ai_board, self.stone,
             (new_x, self.stone_y)):  # 벽과 부딪히지 않는 다면
             self.stone_x = new_x  # 새로운 좌표로 이동
def compute_J(protocol, valuation, disabled, F, mem, graph, vertices):
    key = (valuation, frozenset(disabled))

    if key in mem:
        return mem[key]

    newM = set()
    M = set()
    sF = set(F)
    distance = shortest_distance(graph, directed=True)
    while not (len(newM) == len(sF)):
        newM = nextH(newM, sF.difference(newM), distance, vertices)
        M = newM
        stable = (len(M) == 0)

        while not stable:
            to_remove = set()

            for pair in M:  # AB
                constraints = []

                for t in protocol.transitions:
                    if (t.post == pair):
                        constraints.append(([], [], t.pre))
                    elif len(set(pair) & t.postset) == 1:
                        p = tuple(set(pair) & t.postset)[0]  # E
                        q = pair.other(p)  # F
                        q_ = t.post.other(p)  # G

                        if (q_ != q):  # G != F
                            if p != q:  # E != F
                                constraints.append(([Var(q)], [Var(p)], t.pre))
                            elif p not in t.pre:  # E = F and E not in AB
                                constraints.append(([Var(p, True)], [], t.pre))

                formula = Formula(valuation, disabled | M)

                if not formula.tautology_check(constraints):
                    to_remove.add(pair)

            if len(to_remove) > 0:
                M -= to_remove
            else:
                stable = True
        if len(M) > 0:
            break

    mem[key] = M

    return M
Beispiel #6
0
 def projectPieceDown(self, piece, offsetX, workingPieceIndex):
     if offsetX + len(Var.piece_length(
             piece)) > self.width or offsetX < Var.board_start_x:
         return None
     # result = copy.deepcopy(self)
     offsetY = self.height
     for y in range(Var.board_start_y, self.height):
         if Ai.check_collision(self.field, piece, (offsetX, y)):
             offsetY = y
             break
     for x in range(Var.block_start_index, len(Var.piece_length(piece))):
         for y in range(Var.block_start_index, len(piece)):
             value = piece[y][x]
             if value > Var.board_empty_state:
                 self.field[offsetY - Var.for_index_var +
                            y][offsetX + x] = -workingPieceIndex
     return self
def transformation_graph(protocol, valuation, disabled, stable=False):
    V = protocol.states - valuation.absent_states()
    T = {
        t
        for t in protocol.transitions if (not t.silent()) and (
            t.preset <= V) and (t.postset <= V) and (t.pre not in disabled)
    }

    graph = Graph(directed=True)
    vertices = {v: i for (i, v) in enumerate(V)}
    edges = dict()

    def add_edge(p, q, t):
        graph.add_edge(vertices[p], vertices[q])

        if (p, q) in edges:
            edges[p, q].add(t)
        else:
            edges[p, q] = {t}

    graph.add_vertex(len(V))

    for t in T:
        common_states = t.preset & t.postset

        # Case: AB -> AC, AA -> AC, AB -> AA
        if len(common_states) == 1:
            p = tuple(common_states)[0]
            q = t.pre.other(p)
            q_ = t.post.other(p)

            if not stable or valuation[Var(p)] is True:
                add_edge(q, q_, t)
        # Case: AA -> BB, AA -> BC, AB -> CC, AB -> CD
        elif len(common_states) == 0:
            if stable:
                continue
            new_edges = {(p, q) for p in t.preset for q in t.postset}

            for (p, q) in new_edges:
                p_ = t.pre.other(p)

                if not stable or valuation[Var(p_)] is True:
                    add_edge(p, q, t)

    return (graph, vertices, edges, V)
def compute_J(protocol, valuation, disabled, F, mem):
    key = (valuation, frozenset(disabled))

    if key in mem:
        return mem[key]

    M = set(F)
    stable = (len(M) == 0)

    while not stable:
        to_remove = set()

        for pair in M:  # AB
            constraints = []

            for t in protocol.transitions:
                if (t.post == pair):
                    constraints.append(([], [], t.pre))
                elif len(set(pair) & t.postset) == 1:
                    p = tuple(set(pair) & t.postset)[0]  # E
                    q = pair.other(p)  # F
                    q_ = t.post.other(p)  # G

                    if (q_ != q):  # G != F
                        if p != q:  # E != F
                            constraints.append(([Var(q)], [Var(p)], t.pre))
                        elif p not in t.pre:  # E = F and E not in AB
                            constraints.append(([Var(p, True)], [], t.pre))

            formula = Formula(valuation, disabled | M)

            if not formula.tautology_check(constraints):
                to_remove.add(pair)

        if len(to_remove) > 0:
            M -= to_remove
        else:
            stable = True

    mem[key] = M

    return M
Beispiel #9
0
    def _states_constraints(states):
        conjuncts = []
        domain = set()

        for q in states:
            var = Var(q)

            conjuncts.append(z3.Not(Formula._id(var)))
            domain.add(var)

        return (z3.And(conjuncts), domain)
Beispiel #10
0
    def _states_constraints_or(states, unique_states):
        conjuncts = []
        domain = set()

        for q in states:
            var = Var(q, unique=unique_states)

            conjuncts.append(z3.Not(Formula._id(var)))
            domain.add(var)

        return (z3.Or(conjuncts), domain)
 def ai_new_stone(self):
     self.stone = self.next_stone[:]
     self.next_stone = Var.ai_tetris_shapes[random.randint(
         Var.ai_block_choice_start,
         Var.ai_block_choice_end)]  # 다음 블럭 랜덤으로 고르기 0~6 사이의 랜덤 숫자를 통해 고르기
     self.stone_x = int(
         (self.board.width - len(Var.piece_length(self.stone))) *
         Var.ai_stone_start_x_rate)  # self.width 기준 스톤의 위치 x
     self.stone_y = Var.ai_stone_start_y
     if self.board.ai_check_collision(self.ai_board, self.stone,
                                      (self.stone_x, self.stone_y)):
         self.gameover = True  # 블럭이 부딪히는 판단, 새점로 생성한 블럭이 벽에 부딪히면은 게임 종료
def compute_L(protocol, valuation, disabled, I):
    V = protocol.states - valuation.absent_states()
    L = set()

    for t in protocol.transitions:
        take = (t.preset <= V) and (t.postset <= V)
        take = take and (t.pre not in disabled)
        take = take and (len(t.preset & I) > 0) and (len(t.postset & I) == 0)
        take = take and (len(t.preset) != 1
                         or valuation[Var(t.pre.some(), True)] is not True)

        if take:
            L.add(t.post)

    return L
Beispiel #13
0
    def _pairs_constraints(pairs):
        conjuncts = []
        domain = set()

        for pair in pairs:
            p, q = tuple(pair)

            if p != q:
                domain |= {Var(p), Var(q)}
                conjuncts.append(
                    z3.Or(z3.Not(Formula._id(Var(p))),
                          z3.Not(Formula._id(Var(q)))))
            else:
                domain |= {Var(p), Var(p, True)}
                conjuncts.append(
                    z3.Or(z3.Not(Formula._id(Var(p))),
                          Formula._id(Var(p, True))))

        return (z3.And(conjuncts), domain)
def new_stage_valuation(protocol, valuation, disabled):
    def f(M, N):
        M_, N_ = set(M), set(N)

        def cannot_occur(t):
            return (len(t.preset & M) > 0 or (t.pre in disabled)
                    or (len(t.preset) == 1 and t.pre.some() in N))

        for q in M:
            T = {t for t in protocol.transitions if q in t.post}
            to_remove = any(not cannot_occur(t) for t in T)

            if to_remove:
                M_.remove(q)

        for q in N:
            S = {
                t
                for t in protocol.transitions if (q in t.pre) and (
                    t.pre.other(q) != q) and (not t.unchanged(q))
            }
            T = {t for t in protocol.transitions if q not in t.pre}

            to_remove = any(not ((t.pre.other(q) in M) or (t.pre in disabled))
                            for t in S)
            to_remove = to_remove or any(not cannot_occur(t) for t in T)

            if to_remove:
                N_.remove(q)

        return (M_, N_)

    # Compute greatest fixed point (M, N) of f
    M, N = valuation.absent_states(), valuation.unique_states()
    M_, N_ = f(M, N)

    while (M, N) != (M_, N_):
        M, N = M_, N_
        M_, N_ = f(M, N)

    # Compute E
    E = set()
    P = valuation.present_states()

    for q in P:
        T = {
            t
            for t in protocol.transitions if (q in t.pre and q not in t.post)
        }

        if all((t.pre.other(q) in M) or (t.pre in disabled) or (
                t.pre.other(q) == q and q in N) for t in T):
            E.add(q)

    # Construct new valuation
    new_valuation = Valuation()

    for q in M:
        new_valuation[Var(q)] = False
    for q in E:
        new_valuation[Var(q)] = True
    for q in N:
        new_valuation[Var(q, True)] = True

    return new_valuation
Beispiel #15
0
 def rotate_clockwise(shape):  # 회전 시킨 모양 만들어 주기
     return [[shape[y][x] for y in range(len(shape))] for x in range(
         len(Var.piece_length(shape)) - Var.for_index_var,
         Var.search_rotate_next_index, Var.last_rotate_index_prev)]