示例#1
0
    def upost(self, q):
        assert isinstance(q, BDD)
        if q in self.succ_cache:
            return iter(self.succ_cache[q])
        A = BDD.true()
        M = set()
        while A != BDD.false():
            a = A.get_one_minterm(self.uinputs)
            trans = BDD.make_cube(
                imap(
                    lambda x: BDD.make_eq(
                        BDD(self.aig.get_primed_var(x.lit)),
                        self.aig.lit2bdd(x.next).and_abstract(
                            q, self.latch_cube)), self.aig.iterate_latches()))
            lhs = trans & a
            rhs = self.aig.prime_all_inputs_in_bdd(trans)
            simd = BDD.make_impl(lhs, rhs).univ_abstract(self.platch_cube)\
                .exist_abstract(self.pcinputs_cube)\
                .univ_abstract(self.cinputs_cube)
            simd = self.aig.unprime_all_inputs_in_bdd(simd)

            A &= ~simd
            Mp = set()
            for m in M:
                if not (BDD.make_impl(m, simd) == BDD.true()):
                    Mp.add(m)
            M = Mp
            M.add(a)
        log.DBG_MSG("Upost |M| = " + str(len(M)))
        self.succ_cache[q] = map(lambda x: (q, x), M)
        return iter(self.succ_cache[q])
示例#2
0
    def upost(self, q):
        assert isinstance(q, BDD)
        if q in self.succ_cache:
            return iter(self.succ_cache[q])
        A = BDD.true()
        M = set()
        while A != BDD.false():
            a = A.get_one_minterm(self.uinputs)
            trans = BDD.make_cube(
                imap(lambda x: BDD.make_eq(BDD(self.aig.get_primed_var(x.lit)),
                                           self.aig.lit2bdd(x.next)
                                           .and_abstract(q, self.latch_cube)),
                     self.aig.iterate_latches()))
            lhs = trans & a
            rhs = self.aig.prime_all_inputs_in_bdd(trans)
            simd = BDD.make_impl(lhs, rhs).univ_abstract(self.platch_cube)\
                .exist_abstract(self.pcinputs_cube)\
                .univ_abstract(self.cinputs_cube)
            simd = self.aig.unprime_all_inputs_in_bdd(simd)

            A &= ~simd
            Mp = set()
            for m in M:
                if not (BDD.make_impl(m, simd) == BDD.true()):
                    Mp.add(m)
            M = Mp
            M.add(a)
        log.DBG_MSG("Upost |M| = " + str(len(M)))
        self.succ_cache[q] = map(lambda x: (q, x), M)
        return iter(self.succ_cache[q])
示例#3
0
 def strat_is_inductive(self, strat, use_trans=False):
     strat_dom = strat.exist_abstract(
         BDD.make_cube(imap(funcomp(BDD, symbol_lit),
                            chain(self.iterate_controllable_inputs(),
                                  self.iterate_uncontrollable_inputs()))))
     p_bdd = self.substitute_latches_next(strat_dom, use_trans=use_trans)
     return BDD.make_impl(strat, p_bdd) == BDD.true()
示例#4
0
 def strat_is_inductive(self, strat, use_trans=False):
     strat_dom = strat.exist_abstract(
         BDD.make_cube(
             imap(
                 funcomp(BDD, symbol_lit),
                 chain(self.iterate_controllable_inputs(),
                       self.iterate_uncontrollable_inputs()))))
     p_bdd = self.substitute_latches_next(strat_dom, use_trans=use_trans)
     return BDD.make_impl(strat, p_bdd) == BDD.true()
示例#5
0
def comp_synth4(games, gen_game):
    s = None
    cum_s = None
    cum_w = None
    cnt = 0
    triple_list = []
    for game in games:
        assert isinstance(game, BackwardGame)
        w = backward_safety_synth(game)
        cnt += 1
        # short-circuit a negative response
        if w is None:
            log.DBG_MSG("Short-circuit exit 1 after sub-game #" + str(cnt))
            return None
        s = game.cpre(w, get_strat=True)
        if cum_s is None:
            cum_s = s
            cum_w = w
        else:
            cum_s &= s
            cum_w &= w
        # another short-circuit exit
        if (not cum_s or not game.init() & cum_s):
            log.DBG_MSG("Short-circuit exit 2 after sub-game #" + str(cnt))
            return None
        triple_list.append((game, s, w))
    log.DBG_MSG("Solved " + str(cnt) + " sub games.")
    # lets simplify transition functions
    gen_game.aig.restrict_latch_next_funs(cum_s)
    # what comes next is a fixpoint computation using a UPRE
    # step at a time in the global game and using it to get more
    # information from the local sub-games
    lose = BDD.true()
    lose_next = ~cum_w | gen_game.error()
    while lose_next != lose:
        lose = lose_next
        log.DBG_MSG("Doing global UPRE")
        lose_next = lose | gen_game.upre(lose)
        for i in range(len(triple_list)):
            wt = triple_list[i][2]
            gamet = triple_list[i][0]
            local_deps = set([x.lit for x in gamet.aig.iterate_latches()])
            rem_lats = gen_game.aig.get_bdd_latch_deps(lose_next) - local_deps
            pt = lose_next
            if rem_lats:
                pt = lose_next.univ_abstract(
                    BDD.make_cube(map(BDD, rem_lats)))
            # log.BDD_DMP(lose_next, "global losing area iterate")
            # log.BDD_DMP(pt, "new losing area")
            assert BDD.make_impl(~wt, pt) == BDD.true()
            if BDD.make_impl(pt, ~wt) != BDD.true():
                gamet.short_error = pt
                wt = backward_safety_synth(gamet)
                if (wt is None or not gamet.init() & wt):
                    log.DBG_MSG("Short-circuit exit 3")
                    return None
                st = gamet.cpre(wt, get_strat=True)
                gen_game.aig.restrict_latch_next_funs(wt)
                triple_list[i] = (gamet, st, wt)
        for t in triple_list:
            lose_next |= ~t[2]
    # after the fixpoint has been reached we can compute the error
    win = ~lose
    if (not win or not gen_game.init() & win):
        return None
    else:
        return win
示例#6
0
def comp_synth4(games, gen_game):
    s = None
    cum_s = None
    cum_w = None
    cnt = 0
    triple_list = []
    for game in games:
        assert isinstance(game, BackwardGame)
        w = backward_safety_synth(game)
        cnt += 1
        # short-circuit a negative response
        if w is None:
            log.DBG_MSG("Short-circuit exit 1 after sub-game #" + str(cnt))
            return None
        s = game.cpre(w, get_strat=True)
        if cum_s is None:
            cum_s = s
            cum_w = w
        else:
            cum_s &= s
            cum_w &= w
        # another short-circuit exit
        if (not cum_s or not game.init() & cum_s):
            log.DBG_MSG("Short-circuit exit 2 after sub-game #" + str(cnt))
            return None
        triple_list.append((game, s, w))
    log.DBG_MSG("Solved " + str(cnt) + " sub games.")
    # lets simplify transition functions
    gen_game.aig.restrict_latch_next_funs(cum_s)
    # what comes next is a fixpoint computation using a UPRE
    # step at a time in the global game and using it to get more
    # information from the local sub-games
    lose = BDD.true()
    lose_next = ~cum_w | gen_game.error()
    while lose_next != lose:
        lose = lose_next
        log.DBG_MSG("Doing global UPRE")
        lose_next = lose | gen_game.upre(lose)
        for i in range(len(triple_list)):
            wt = triple_list[i][2]
            gamet = triple_list[i][0]
            local_deps = set([x.lit for x in gamet.aig.iterate_latches()])
            rem_lats = gen_game.aig.get_bdd_latch_deps(lose_next) - local_deps
            pt = lose_next
            if rem_lats:
                pt = lose_next.univ_abstract(BDD.make_cube(map(BDD, rem_lats)))
            # log.BDD_DMP(lose_next, "global losing area iterate")
            # log.BDD_DMP(pt, "new losing area")
            assert BDD.make_impl(~wt, pt) == BDD.true()
            if BDD.make_impl(pt, ~wt) != BDD.true():
                gamet.short_error = pt
                wt = backward_safety_synth(gamet)
                if (wt is None or not gamet.init() & wt):
                    log.DBG_MSG("Short-circuit exit 3")
                    return None
                st = gamet.cpre(wt, get_strat=True)
                gen_game.aig.restrict_latch_next_funs(wt)
                triple_list[i] = (gamet, st, wt)
        for t in triple_list:
            lose_next |= ~t[2]
    # after the fixpoint has been reached we can compute the error
    win = ~lose
    if (not win or not gen_game.init() & win):
        return None
    else:
        return win