Esempio n. 1
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
Esempio n. 2
0
 def lit2formula(self, lit):
     if lit in self.lit_to_formula:
         return self.lit_to_formula[lit]
     # get stripped lit
     stripped_lit = strip_lit(lit)
     is_neg = lit_is_negated(lit)
     (input, latch, and_gate) = self.aig.get_lit_type(stripped_lit)
     # is it an input, latch, gate or constant
     if input or latch:
         # Boolean variables are encoded as 1-bit integers for now
         result = "({0})".format(self.name_of(stripped_lit))
     elif and_gate:
         if numeric_mode:
             result = ("({0} * {1})".format(self.lit2formula(and_gate.rhs0),
                                            self.lit2formula(
                                                and_gate.rhs1)))
         else:
             result = ("({0} && {1})".format(
                 self.lit2formula(and_gate.rhs0),
                 self.lit2formula(and_gate.rhs1)))
     else:  # 0 literal, 1 literal and errors
         result = "0"  # this means false
     # cache result
     self.lit_to_formula[stripped_lit] = result
     if is_neg:
         if result == "0":
             result = "1"
         else:
             if numeric_mode:
                 result = "(1-{0})".format(result)
             else:
                 result = "!{0}".format(result)
         self.lit_to_formula[lit] = result
     return result
Esempio n. 3
0
def get_bdd_for_aig_lit(lit):
    """ Convert AIGER lit into BDD.
    param lit: 'signed' value of gate
    returns: BDD representation of the input literal
    """
    # query cache
    if lit in lit_to_bdd:
        return lit_to_bdd[lit]
    # get stripped lit
    stripped_lit = aig.strip_lit(lit)
    if stripped_lit == error_fake_latch.lit:
        (intput, latch, and_gate) = (None, error_fake_latch, None)
    else:
        (intput, latch, and_gate) = aig.get_lit_type(stripped_lit)
    # is it an input, latch, gate or constant
    if intput or latch:
        result = bdd.BDD(stripped_lit)
    elif and_gate:
        result = (get_bdd_for_aig_lit(and_gate.rhs0) &
                  get_bdd_for_aig_lit(and_gate.rhs1))
    else:  # 0 literal, 1 literal and errors
        result = bdd.false()
    # cache result
    lit_to_bdd[stripped_lit] = result
    bdd_to_lit[result] = stripped_lit
    # check for negation
    if aig.lit_is_negated(lit):
        result = ~result
        lit_to_bdd[lit] = result
        bdd_to_lit[result] = lit
    return result
Esempio n. 4
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
Esempio n. 5
0
def get_bdd_for_aig_lit(lit):
    """ Convert AIGER lit into BDD.
    param lit: 'signed' value of gate
    returns: BDD representation of the input literal
    """
    # query cache
    if lit in lit_to_bdd:
        return lit_to_bdd[lit]
    # get stripped lit
    stripped_lit = aig.strip_lit(lit)
    if stripped_lit == error_fake_latch.lit:
        (intput, latch, and_gate) = (None, error_fake_latch, None)
    else:
        (intput, latch, and_gate) = aig.get_lit_type(stripped_lit)
    # is it an input, latch, gate or constant
    if intput or latch:
        result = bdd.BDD(stripped_lit)
    elif and_gate:
        result = (get_bdd_for_aig_lit(and_gate.rhs0)
                  & get_bdd_for_aig_lit(and_gate.rhs1))
    else:  # 0 literal, 1 literal and errors
        result = bdd.false()
    # cache result
    lit_to_bdd[stripped_lit] = result
    bdd_to_lit[result] = stripped_lit
    # check for negation
    if aig.lit_is_negated(lit):
        result = ~result
        lit_to_bdd[lit] = result
        bdd_to_lit[result] = lit
    return result
Esempio n. 6
0
def trans_rel_CNF():
    global cached_tr_cnf
    # we create a fake latch for the error
    introduce_error_latch()

    if cached_tr_cnf is not None:
        return cached_tr_cnf

    # per latch, handle the next function
    T = sat.CNF()
    for l in iterate_latches():
        # easy case, the latch just directly maps input or terminal
        (ii, ll, a) = get_lit_type(l.next)
        if not a:
            if l.next == 0 or l.next == 1:  # is it a terminal?
                T.add_mand(get_primed_var(l.lit), [l.next])
            else:  # otherwise
                x = strip_lit(l.next) * -1 if lit_is_negated(l.next)\
                    else strip_lit(l.next)
                T.add_mand(get_primed_var(l.lit), [x])
        else:  # complicated case, l.next is an AND
            if lit_is_negated(l.next):
                A = set([strip_lit(l.next) * -1])
                B = set([strip_lit(l.next)])
            else:
                (A, B) = get_mand(l.next)
            T.add_mand(get_primed_var(l.lit), A)
            pending = B
            # handle CNF for each pending gate
            while pending:
                cur = pending.pop()
                (A, B) = get_mand(cur)
                pending |= B
                T.add_mand(cur, A)
    # handle caching
    cached_tr_cnf = T
    return T
Esempio n. 7
0
def trans_rel_CNF():
    global cached_tr_cnf
    # we create a fake latch for the error
    introduce_error_latch()

    if cached_tr_cnf is not None:
        return cached_tr_cnf

    # per latch, handle the next function
    T = sat.CNF()
    for l in iterate_latches():
        # easy case, the latch just directly maps input or terminal
        (ii, ll, a) = get_lit_type(l.next)
        if not a:
            if l.next == 0 or l.next == 1:  # is it a terminal?
                T.add_mand(get_primed_var(l.lit), [l.next])
            else:  # otherwise
                x = strip_lit(l.next) * -1 if lit_is_negated(l.next)\
                    else strip_lit(l.next)
                T.add_mand(get_primed_var(l.lit), [x])
        else:  # complicated case, l.next is an AND
            if lit_is_negated(l.next):
                A = set([strip_lit(l.next) * -1])
                B = set([strip_lit(l.next)])
            else:
                (A, B) = get_mand(l.next)
            T.add_mand(get_primed_var(l.lit), A)
            pending = B
            # handle CNF for each pending gate
            while pending:
                cur = pending.pop()
                (A, B) = get_mand(cur)
                pending |= B
                T.add_mand(cur, A)
    # handle caching
    cached_tr_cnf = T
    return T
Esempio n. 8
0
def decompose(aig, argv):
    if argv.decomp == 1:
        if lit_is_negated(aig.error_fake_latch.next):
            log.DBG_MSG("Decomposition opt possible (BIG OR case)")
            (A, B) = aig.get_1l_land(strip_lit(aig.error_fake_latch.next))
            return imap(lambda a: ConcGame(
                BDDAIG(aig).short_error(a),
                use_trans=argv.use_trans),
                merge_some_signals(BDD.true(), A, aig, argv))
        else:
            (A, B) = aig.get_1l_land(aig.error_fake_latch.next)
            if not B:
                log.DBG_MSG("No decomposition opt possible")
                return None
            else:
                log.DBG_MSG("Decomposition opt possible (A ^ [C v D] case)")
                log.DBG_MSG(str(len(A)) + " AND leaves: " + str(A))
            # critical heuristic: which OR leaf do we distribute?
            # here I propose to choose the one with the most children
            b = B.pop()
            (C, D) = aig.get_1l_land(b)
            for bp in B:
                (Cp, Dp) = aig.get_1l_land(bp)
                if len(Cp) > len(C):
                    b = bp
                    C = Cp
            log.DBG_MSG("Chosen OR: " + str(b))
            rem_AND_leaves = filter(lambda x: strip_lit(x) != b, A)
            rdeps = set()
            for r in rem_AND_leaves:
                rdeps |= aig.get_lit_deps(strip_lit(r))
            log.DBG_MSG("Rem. AND leaves' deps: " + str(rdeps))
            cube = BDD.make_cube(map(aig.lit2bdd, rem_AND_leaves))
            log.DBG_MSG(str(len(C)) + " OR leaves: " +
                        str(map(aig.get_lit_name, C)))
            return imap(lambda a: ConcGame(
                BDDAIG(aig).short_error(a),
                use_trans=argv.use_trans), merge_some_signals(cube, C, aig,
                                                              argv))
    elif argv.decomp == 2:
        raise NotImplementedError
Esempio n. 9
0
def decompose(aig, argv):
    if argv.decomp == 1:
        if lit_is_negated(aig.error_fake_latch.next):
            log.DBG_MSG("Decomposition opt possible (BIG OR case)")
            (A, B) = aig.get_1l_land(strip_lit(aig.error_fake_latch.next))
            return imap(
                lambda a: ConcGame(BDDAIG(aig).short_error(a),
                                   use_trans=argv.use_trans),
                merge_some_signals(BDD.true(), A, aig, argv))
        else:
            (A, B) = aig.get_1l_land(aig.error_fake_latch.next)
            if not B:
                log.DBG_MSG("No decomposition opt possible")
                return None
            else:
                log.DBG_MSG("Decomposition opt possible (A ^ [C v D] case)")
                log.DBG_MSG(str(len(A)) + " AND leaves: " + str(A))
            # critical heuristic: which OR leaf do we distribute?
            # here I propose to choose the one with the most children
            b = B.pop()
            (C, D) = aig.get_1l_land(b)
            for bp in B:
                (Cp, Dp) = aig.get_1l_land(bp)
                if len(Cp) > len(C):
                    b = bp
                    C = Cp
            log.DBG_MSG("Chosen OR: " + str(b))
            rem_AND_leaves = filter(lambda x: strip_lit(x) != b, A)
            rdeps = set()
            for r in rem_AND_leaves:
                rdeps |= aig.get_lit_deps(strip_lit(r))
            log.DBG_MSG("Rem. AND leaves' deps: " + str(rdeps))
            cube = BDD.make_cube(map(aig.lit2bdd, rem_AND_leaves))
            log.DBG_MSG(
                str(len(C)) + " OR leaves: " + str(map(aig.get_lit_name, C)))
            return imap(
                lambda a: ConcGame(BDDAIG(aig).short_error(a),
                                   use_trans=argv.use_trans),
                merge_some_signals(cube, C, aig, argv))
    elif argv.decomp == 2:
        raise NotImplementedError
Esempio n. 10
0
def get_mand(lit):
    (A, B) = get_1l_land(lit)
    A2 = set(map(A, lambda x: strip_lit(x) * -1
                 if lit_is_negated(x)
                 else x))
    return (A2, B)
Esempio n. 11
0
def get_mand(lit):
    (A, B) = get_1l_land(lit)
    A2 = set(map(A, lambda x: strip_lit(x) * -1 if lit_is_negated(x) else x))
    return (A2, B)