Example #1
0
 def over_post_bdd(self, src_states_bdd, sys_strat=None):
     """ Over-approximated version of concrete post which can be done even
     without the transition relation """
     strat = BDD.true()
     if sys_strat is not None:
         strat &= sys_strat
     # to do this, we use an over-simplified transition relation, EXu,Xc
     b = BDD.true()
     for x in self.iterate_latches():
         temp = BDD.make_eq(BDD(self.get_primed_var(x.lit)),
                            self.lit2bdd(x.next))
         b &= temp.and_abstract(
             strat,
             BDD.make_cube(
                 imap(funcomp(BDD, symbol_lit),
                      self.iterate_controllable_inputs())))
         b = b.restrict(src_states_bdd)
     b &= src_states_bdd
     b = b.exist_abstract(
         BDD.make_cube(
             imap(
                 funcomp(BDD, symbol_lit),
                 chain(self.iterate_latches(),
                       self.iterate_uncontrollable_inputs()))))
     return self.unprime_latches_in_bdd(b)
Example #2
0
 def lit2bdd(self, lit):
     """ Convert AIGER lit into BDD """
     # query cache
     if lit in self.lit_to_bdd:
         return self.lit_to_bdd[lit]
     # get stripped lit
     stripped_lit = strip_lit(lit)
     (intput, latch, and_gate) = self.get_lit_type(stripped_lit)
     # is it an input, latch, gate or constant
     if intput or latch:
         result = BDD(stripped_lit)
     elif and_gate:
         result = (self.lit2bdd(and_gate.rhs0)
                   & self.lit2bdd(and_gate.rhs1))
     else:  # 0 literal, 1 literal and errors
         result = BDD.false()
     # cache result
     self.lit_to_bdd[stripped_lit] = result
     self.bdd_to_lit[result] = stripped_lit
     # check for negation
     if lit_is_negated(lit):
         result = ~result
         self.lit_to_bdd[lit] = result
         self.bdd_to_lit[result] = lit
     return result
Example #3
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])
Example #4
0
 def trans_rel_bdd(self):
     # check cache
     if self._cached_transition is not None:
         return self._cached_transition
     b = BDD.true()
     for x in self.iterate_latches():
         b &= BDD.make_eq(BDD(self.get_primed_var(x.lit)),
                          self.lit2bdd(x.next))
     self._cached_transition = b
     log.BDD_DMP(b, "Composed and cached the concrete transition relation.")
     return b
Example #5
0
    def extract_output_funs(self, strategy, care_set=None):
        """
        Calculate BDDs for output functions given non-deterministic winning
        strategy.
        """
        if care_set is None:
            care_set = BDD.true()

        output_models = dict()
        all_outputs = [BDD(x.lit) for x in self.iterate_controllable_inputs()]
        for c_symb in self.iterate_controllable_inputs():
            c = BDD(c_symb.lit)
            others = set(set(all_outputs) - set([c]))
            if others:
                others_cube = BDD.make_cube(others)
                c_arena = strategy.exist_abstract(others_cube)
            else:
                c_arena = strategy
            # pairs (x,u) in which c can be true
            can_be_true = c_arena.cofactor(c)
            # pairs (x,u) in which c can be false
            can_be_false = c_arena.cofactor(~c)
            must_be_true = (~can_be_false) & can_be_true
            must_be_false = (~can_be_true) & can_be_false
            local_care_set = care_set & (must_be_true | must_be_false)
            # Restrict operation:
            #   on care_set: must_be_true.restrict(care_set) <-> must_be_true
            c_model = min([
                must_be_true.safe_restrict(local_care_set),
                (~must_be_false).safe_restrict(local_care_set)
            ],
                          key=lambda x: x.dag_size())
            output_models[c_symb.lit] = c_model
            log.DBG_MSG("Size of function for " + str(c.get_index()) + " = " +
                        str(c_model.dag_size()))
            strategy &= BDD.make_eq(c, c_model)
        return output_models
Example #6
0
 def cpost(self, s):
     assert isinstance(s, tuple)
     q = s[0]
     au = s[1]
     if s in self.succ_cache:
         L = self.succ_cache[s]
     else:
         L = BDD.make_cube(
             imap(lambda x: BDD.make_eq(BDD(x.lit),
                                        self.aig.lit2bdd(x.next)
                                        .and_abstract(q & au,
                                                      self.latch_cube &
                                                      self.uinputs_cube)),
                  self.aig.iterate_latches()))\
             .exist_abstract(self.cinputs_cube)
         self.succ_cache[s] = L
     M = set()
     while L != BDD.false():
         l = L.get_one_minterm(self.latches)
         L &= ~l
         self.Venv[l] = True
         M.add(l)
     log.DBG_MSG("Cpost |M| = " + str(len(M)))
     return iter(M)
Example #7
0
 def init_state_bdd(self):
     b = BDD.true()
     for x in self.iterate_latches():
         b &= ~BDD(x.lit)
     return b