示例#1
0
def test_path_negation():
    levels = {'c1': 0, 'a1': 1, 'c2': 2, 'a2': 3}
    manager = BDD(levels)
    manager.configure(reordering=False)

    c1, a1, c2, a2 = map(manager.var, ['c1', 'a1', 'c2', 'a2'])
    bexpr = ((c1 & a1) | (~c1 & ~a1)) & ((c2 & a2) | (~c2 & ~a2))

    assert bexpr.low.negated
    assert not bexpr.high.negated

    assert len(list(path(bexpr, (True, False, False, False)))) == 3
    assert len(list(path(bexpr, (True, True, True, True)))) == 5

    def merge(ctx, val, acc):
        if ctx.is_leaf:
            return ctx.path_negated ^ ctx.node_val
        return None

    def evaluate(vals):
        return fold_path(merge, bexpr, vals, initial=[])

    for val in product(*(4 * [[False, True]])):
        expected = (val[0] == val[1]) and (val[2] == val[3])
        assert evaluate(val) == expected
示例#2
0
def to_bdd(circ_or_expr, output=None, manager=None, renamer=None, levels=None):
    if renamer is None:
        _count = 0

        def renamer(*_):
            nonlocal _count
            _count += 1
            return f"x{_count}"

    if not isinstance(circ_or_expr, aiger.BoolExpr):
        circ = aiger.to_aig(circ_or_expr, allow_lazy=True)
        assert len(circ.latches) == 0

        if output is None:
            assert len(circ.outputs) == 1
            output = fn.first(circ.outputs)

        expr = aiger.BoolExpr(circ)
    else:
        expr = circ_or_expr

    manager = BDD() if manager is None else manager
    input_refs_to_var = {
        ref: renamer(i, ref)
        for i, ref in enumerate(expr.inputs)
    }

    manager.declare(*input_refs_to_var.values())
    if levels is not None:
        assert set(manager.vars.keys()) <= set(levels.keys())
        levels = fn.project(levels, manager.vars.keys())
        levels = fn.walk_keys(input_refs_to_var.get, levels)

        manager.reorder(levels)
        manager.configure(reordering=False)

    def lift(obj):
        if isinstance(obj, bool):
            return manager.true if obj else manager.false
        return obj

    inputs = {i: manager.var(input_refs_to_var[i]) for i in expr.inputs}
    out = expr(inputs, lift=lift)
    return out, out.bdd, bidict(input_refs_to_var)
示例#3
0
def create_manager():
    manager = BDD()
    manager.declare('x', 'y')
    manager.reorder({'x': 1, 'y': 0})
    manager.configure(reordering=False)
    return manager