Exemple #1
0
def test_misc():
    a, b, c = map(exprvar, 'abc')
    a0 = exprvar('a', 0)
    b0 = exprvar('b', 0)
    assert expr("a * b * c").equivalent(a * b * c)
    assert expr("a + b + c").equivalent(a + b + c)
    assert expr("a * (b + c)").equivalent(a * (b + c))
    assert expr("a + (b * c)").equivalent(a + b * c)
    assert expr("Or()").is_zero()
    assert expr("a[0] + b[0]").equivalent(a0 + b0)
Exemple #2
0
def test_misc():
    a, b, c = map(exprvar, 'abc')
    a0 = exprvar('a', 0)
    b0 = exprvar('b', 0)
    assert expr("a & b & c").equivalent(a & b & c)
    assert expr("a ^ b ^ c").equivalent(a ^ b ^ c)
    assert expr("a | b | c").equivalent(a | b | c)
    assert expr("a & (b | c)").equivalent(a & (b | c))
    assert expr("a | (b & c)").equivalent(a | b & c)
    assert expr("Or()").is_zero()
    assert expr("a[0] | b[0]").equivalent(a0 | b0)
    def test_not_at_most_one_not_equivalent(self):
        self.function = expr.And(self.pos, expr.exprvar("b"),
                                 ~expr.Or(*self.neg))

        at_most = expr.exprvar("at_most")
        cardinality = constraint.at_most_one(self.function.support, ~at_most)
        sat = expr.And(self.function, at_most,
                       *cardinality).to_cnf().satisfy_one()

        self.assertIsNotNone(sat)
        self.assertEqual(sat.get(at_most), 1)
Exemple #4
0
def test_misc():
    a, b, c = map(exprvar, 'abc')
    assert expr("a & b & c").equivalent(a & b & c)
    assert expr("a ^ b ^ c").equivalent(a ^ b ^ c)
    assert expr("a | b | c").equivalent(a | b | c)
    assert expr("a & (b | c)").equivalent(a & (b | c))
    assert expr("a | (b & c)").equivalent(a | b & c)
    assert expr("Or()").is_zero()

    a_0 = exprvar('a', 0)
    b_a = exprvar(('a', 'b'))
    a_0_1 = exprvar('a', (0, 1))
    b_a_0_1 = exprvar(('a', 'b'), (0, 1))
    assert expr("a[0] | b.a | a[0,1] | b.a[0,1]").equivalent(a_0 | b_a | a_0_1 | b_a_0_1)
Exemple #5
0
def test_misc():
    a, b, c = map(exprvar, 'abc')
    assert expr("a & b & c").equivalent(a & b & c)
    assert expr("a ^ b ^ c").equivalent(a ^ b ^ c)
    assert expr("a | b | c").equivalent(a | b | c)
    assert expr("a & (b | c)").equivalent(a & (b | c))
    assert expr("a | (b & c)").equivalent(a | b & c)
    assert expr("Or()").is_zero()

    a_0 = exprvar('a', 0)
    b_a = exprvar(('a', 'b'))
    a_0_1 = exprvar('a', (0, 1))
    b_a_0_1 = exprvar(('a', 'b'), (0, 1))
    assert expr("a[0] | b.a | a[0,1] | b.a[0,1]").equivalent(a_0 | b_a | a_0_1
                                                             | b_a_0_1)
def at_most_one(inputs, equivalent=None):
    assert inputs, "inputs must not be empty"
    count = next(_counter)

    def a(i):
        return expr.exprvar("sinz", (i, count))

    def clauses(variables):
        length = len(variables)
        (first, rest, last) = (variables[0], variables[1:-1], variables[-1])

        yield expr.Or(~first, a(1))
        yield expr.Or(~last, ~a(length - 1))

        for (i, x) in zip(range(2, length), rest):
            yield expr.Or(~x, a(i))
            yield expr.Or(~a(i - 1), a(i))
            yield expr.Or(~x, ~a(i - 1))

    if equivalent is None:
        yield from clauses(tuple(inputs))
    else:
        auxiliaries = list()
        for clause in clauses(tuple(inputs)):
            aux = expr.exprvar(("sinz", "eq"), next(_counter))
            yield expr.Implies(aux, clause).to_cnf()
            yield expr.Implies(clause, aux).to_cnf()
            auxiliaries.append(aux)
        constraint = expr.And(*auxiliaries)
        yield expr.Implies(constraint, equivalent).to_cnf()
        yield expr.Implies(equivalent, constraint).to_cnf()
    def test_not_at_most_one(self):
        self.function = expr.And(self.pos, expr.exprvar("b"),
                                 ~expr.Or(*self.neg))

        cardinality = constraint.at_most_one(self.function.support)
        sat = expr.And(self.function, *cardinality).to_cnf().satisfy_one()
        self.assertIsNone(sat)
Exemple #8
0
def bdd2expr(bdd, conj=False):
    """Convert a binary decision diagram into an expression.

    This function will always return an expression in two-level form.
    If *conj* is ``False``, return a sum of products (SOP).
    Otherwise, return a product of sums (POS).

    For example::

       >>> a, b = map(bddvar, 'ab')
       >>> bdd2expr(~a | b)
       Or(~a, And(a, b))
    """
    if conj:
        outer, inner = (And, Or)
        paths = _iter_all_paths(bdd.node, BDDNODEZERO)
    else:
        outer, inner = (Or, And)
        paths = _iter_all_paths(bdd.node, BDDNODEONE)
    terms = list()
    for path in paths:
        expr_point = {exprvar(v.names, v.indices): val
                      for v, val in _path2point(path).items()}
        terms.append(boolfunc.point2term(expr_point, conj))
    return outer(*[inner(*term) for term in terms])
Exemple #9
0
def edge_expr(edge_nodes, k, expr_var_names):
    """
    Get BDD expression from each set of nodes for any given edge; e.g.,
    first edge 0-->1, i.e., 00 --> 01
    r = ~x1 & ~x2 & ~y1 & y2
    """

    # Each BDD variable gets a unique id (w/in the pairs of nodes for the edge)
    var_id = 0

    # For each node of edge, convert each bit to a BDD variable in an expression
    r = None
    for n in edge_nodes:

        node_bin = "{0:0b}".format(n)
        node_bin = "0" * (k - len(node_bin)) + node_bin
        node_bin_list = list(node_bin)

        for node_var_str in node_bin_list:

            # Give each variable a unique name, "v[unique num]"
            uniq_var_id = expr_var_names[var_id]
            var_id += 1

            # Create variable from bit
            node_var = exprvar(uniq_var_id)
            if node_var_str == "0": node_var = ~node_var

            # Update the edge relation
            if r is None: r = node_var
            else: r &= node_var

    return r
Exemple #10
0
def espresso_tts(*tts):
    """Return a tuple of expressions optimized using Espresso."""
    for f in tts:
        if not isinstance(f, TruthTable):
            raise ValueError("expected a TruthTable instance")

    support = frozenset.union(*[f.support for f in tts])
    inputs = sorted(support)

    ninputs = len(inputs)
    noutputs = len(tts)

    cover = set()
    for i, point in enumerate(boolfunc.iter_points(inputs)):
        invec = [2 if point[v] else 1 for v in inputs]
        outvec = list()
        for f in tts:
            val = f.pcdata[i]
            if val == PC_ZERO:
                outvec.append(0)
            elif val == PC_ONE:
                outvec.append(1)
            elif val == PC_DC:
                outvec.append(2)
            else:
                raise ValueError("expected truth table entry in {0, 1, -}")
        cover.add((tuple(invec), tuple(outvec)))

    set_config(**CONFIG)

    cover = espresso(ninputs, noutputs, cover, intype=FTYPE|DTYPE|RTYPE)
    inputs = [exprvar(v.names, v.indices) for v in inputs]
    return _cover2exprs(inputs, noutputs, cover)
Exemple #11
0
def bdd2expr(bdd, conj=False):
    """Convert a binary decision diagram into an expression.

    This function will always return an expression in two-level form.
    If *conj* is ``False``, return a sum of products (SOP).
    Otherwise, return a product of sums (POS).

    For example::

       >>> a, b = map(bddvar, 'ab')
       >>> bdd2expr(~a | b)
       Or(~a, And(a, b))
    """
    if conj:
        outer, inner = (And, Or)
        paths = _iter_all_paths(bdd.node, BDDNODEZERO)
    else:
        outer, inner = (Or, And)
        paths = _iter_all_paths(bdd.node, BDDNODEONE)
    terms = list()
    for path in paths:
        expr_point = {
            exprvar(v.names, v.indices): val
            for v, val in _path2point(path).items()
        }
        terms.append(boolfunc.point2term(expr_point, conj))
    return outer(*[inner(*term) for term in terms])
def gen_vars(size):
    """Generates expression variables for every cell in the grid and returns
    them as rows and columns"""
    chars = AZ9[:size]
    rows_vars = tuple(
        tuple(exprvar("".join(p)) for p in product(char, chars))
        for char in chars)
    return rows_vars, list(zip(*rows_vars))
Exemple #13
0
 def test_not_equals_higher(self):
     equals = expr.exprvar("equals")
     cardinality = cardnet.equals(self.function.support,
                                  len(self.pos) + 1,
                                  ~equals)
     sat = expr.And(self.function, equals, *cardinality).to_cnf().satisfy_one()
     self.assertIsNotNone(sat)
     self.assertEqual(sat.get(equals), 1)
    def test_at_least_one_equivalent(self):
        at_least = expr.exprvar("at_least")
        cardinality = constraint.at_least_one(self.function.support, at_least)
        sat = expr.And(self.function, at_least,
                       *cardinality).to_cnf().satisfy_one()

        self.assertIsNotNone(sat)
        self.assertEqual(sat.get(at_least), 1)
Exemple #15
0
 def test_not_at_most_is_not_equivalent(self):
     at_most = expr.exprvar("at_most")
     cardinality = cardnet.at_most(self.function.support,
                                   len(self.pos) - 1,
                                   ~at_most)
     sat = expr.And(self.function, at_most, *cardinality).to_cnf().satisfy_one()
     self.assertIsNotNone(sat)
     self.assertEqual(sat.get(at_most), 1)
    def test_not_equals_one_not_equivalent(self):
        self.function = ~expr.Or(*self.neg)

        equals = expr.exprvar("equals")
        cardinality = constraint.equals_one(self.function.support, ~equals)
        sat = expr.And(self.function, equals,
                       *cardinality).to_cnf().satisfy_one()

        self.assertIsNotNone(sat)
        self.assertEqual(sat.get(equals), 1)
Exemple #17
0
def truthtable2expr(tt, conj=False):
    """Convert a truth table into an expression."""
    if conj:
        outer, inner = (And, Or)
        nums = tt.pcdata.iter_zeros()
    else:
        outer, inner = (Or, And)
        nums = tt.pcdata.iter_ones()
    inputs = [exprvar(v.names, v.indices) for v in tt.inputs]
    terms = [boolfunc.num2term(num, inputs, conj) for num in nums]
    return outer(*[inner(*term) for term in terms])
Exemple #18
0
    def _parse_position_variable(self, variable):
        (_literal, kind, *names) = variable.names
        (i, j, *indices) = variable.indices

        if tuple(names) == ("constant",):
            if kind == "positive": return (i, j, True)
            elif kind == "negated": return (i, j, False)
        else:
            var = expr.exprvar(tuple(names), tuple(indices))
            if kind == "positive": return (i, j, var)
            elif kind == "negated": return (i, j, ~var)
        raise ValueError("Unparseable variable ({})".format(variable))
Exemple #19
0
def bdd2expr(bdd, conj=False):
    """Convert a binary decision diagram into an expression."""
    if conj:
        outer, inner = (And, Or)
        paths = _iter_all_paths(bdd.node, BDDNODEZERO)
    else:
        outer, inner = (Or, And)
        paths = _iter_all_paths(bdd.node, BDDNODEONE)
    terms = list()
    for path in paths:
        expr_point = {exprvar(v.names, v.indices): val for v, val in path2point(path).items()}
        terms.append(boolfunc.point2term(expr_point, conj))
    return outer(*[inner(*term) for term in terms])
Exemple #20
0
def bitvec(name, *slices):
    """Return a BitVector with an arbitrary number of slices.

    Parameters
    ----------
    name : str
    slices : (int or (int, int))
        An int N means a slice from [0:N]
        A tuple (M, N) means a slice from [M:N]
    """
    if slices:
        return bfarray.exprvars(name, *slices)
    else:
        return expr.exprvar(name)
Exemple #21
0
def bitvec(name, *dims):
    """Return a new array of given dimensions, filled with Expressions.

    Parameters
    ----------
    name : str
    dims : (int or (int, int))
        An int N means a slice from [0:N]
        A tuple (M, N) means a slice from [M:N]
    """
    if dims:
        return bfarray.exprvars(name, *dims)
    else:
        return expr.exprvar(name)
    def test_at_least_one_not_equivalent(self, function):
        equivalent = expr.exprvar("equivalent")

        cardinality_a = constraint.at_least_one(function.support, ~equivalent)
        sat_a = expr.And(function, ~equivalent,
                         *cardinality_a).to_cnf().satisfy_one()

        cardinality_b = constraint.at_least(function.support, 1, ~equivalent)
        sat_b = expr.And(function, ~equivalent,
                         *cardinality_b).to_cnf().satisfy_one()

        self.assertEqual(sat_a is None, sat_b is None)
        if sat_a or sat_b:
            self.assertEqual(sat_a.get(equivalent), sat_b.get(equivalent))
Exemple #23
0
def espresso_tts(*tts):
    """Return a tuple of expressions optimized using Espresso.

    The variadic *tts* argument is a sequence of truth tables.

    For example::

       >>> from pyeda.boolalg.bfarray import exprvars
       >>> from pyeda.boolalg.table import truthtable
       >>> X = exprvars('x', 4)
       >>> f1 = truthtable(X, "0000011111------")
       >>> f2 = truthtable(X, "0001111100------")
       >>> f1m, f2m = espresso_tts(f1, f2)
       >>> f1m.equivalent(X[3] | X[0] & X[2] | X[1] & X[2])
       True
       >>> f2m.equivalent(X[2] | X[0] & X[1])
       True
    """
    for f in tts:
        if not isinstance(f, TruthTable):
            raise ValueError("expected a TruthTable instance")

    support = frozenset.union(*[f.support for f in tts])
    inputs = sorted(support)

    ninputs = len(inputs)
    noutputs = len(tts)

    cover = set()
    for i, point in enumerate(boolfunc.iter_points(inputs)):
        invec = [2 if point[v] else 1 for v in inputs]
        outvec = list()
        for f in tts:
            val = f.pcdata[i]
            if val == PC_ZERO:
                outvec.append(0)
            elif val == PC_ONE:
                outvec.append(1)
            elif val == PC_DC:
                outvec.append(2)
            else:
                raise ValueError("expected truth table entry in {0, 1, -}")
        cover.add((tuple(invec), tuple(outvec)))

    set_config(**CONFIG)

    cover = espresso(ninputs, noutputs, cover, intype=FTYPE | DTYPE | RTYPE)
    inputs = [exprvar(v.names, v.indices) for v in inputs]
    return _cover2exprs(inputs, noutputs, cover)
Exemple #24
0
def espresso_tts(*tts):
    """Return a tuple of expressions optimized using Espresso.

    The variadic *tts* argument is a sequence of truth tables.

    For example::

       >>> from pyeda.boolalg.bfarray import exprvars
       >>> from pyeda.boolalg.table import truthtable
       >>> X = exprvars('x', 4)
       >>> f1 = truthtable(X, "0000011111------")
       >>> f2 = truthtable(X, "0001111100------")
       >>> f1m, f2m = espresso_tts(f1, f2)
       >>> f1m.equivalent(X[3] | X[0] & X[2] | X[1] & X[2])
       True
       >>> f2m.equivalent(X[2] | X[0] & X[1])
       True
    """
    for f in tts:
        if not isinstance(f, TruthTable):
            raise ValueError("expected a TruthTable instance")

    support = frozenset.union(*[f.support for f in tts])
    inputs = sorted(support)

    ninputs = len(inputs)
    noutputs = len(tts)

    cover = set()
    for i, point in enumerate(boolfunc.iter_points(inputs)):
        invec = [2 if point[v] else 1 for v in inputs]
        outvec = list()
        for f in tts:
            val = f.pcdata[i]
            if val == PC_ZERO:
                outvec.append(0)
            elif val == PC_ONE:
                outvec.append(1)
            elif val == PC_DC:
                outvec.append(2)
            else:
                raise ValueError("expected truth table entry in {0, 1, -}")
        cover.add((tuple(invec), tuple(outvec)))

    set_config(**CONFIG)

    cover = espresso(ninputs, noutputs, cover, intype=FTYPE|DTYPE|RTYPE)
    inputs = [exprvar(v.names, v.indices) for v in inputs]
    return _cover2exprs(inputs, noutputs, cover)
def convert_to_pyeda(term):
    """Converts a term object to a PyEDA expression.

	Args:
		term (Term): A term object.
	
	Returns:
		expr: The corresponding PyEDA expression.
	
	"""
    if term.operator is None:
        return expr.exprvar(escape_var_name(term.operands[0]), None)
    elif term.operator == "NEG":
        return expr.Not(convert_to_pyeda(term.operands[0]), simplify=False)
    elif term.operator == "AND":
        return expr.And(
            *[convert_to_pyeda(operand) for operand in term.operands],
            simplify=False)
    elif term.operator == "OR":
        return expr.Or(
            *[convert_to_pyeda(operand) for operand in term.operands],
            simplify=False)
    elif term.operator == "IMP":
        return expr.Implies(convert_to_pyeda(term.operands[0]),
                            convert_to_pyeda(term.operands[0]),
                            simplify=False)
    elif term.operator == "EQV":
        return expr.Equal(
            *[convert_to_pyeda(operand) for operand in term.operands],
            simplify=False)
    elif term.operator == "ADD":
        return expr.exprvar(
            "___ADD___".join([
                escape_var_name(operand.operands[0])
                for operand in term.operands
            ]), None)
Exemple #26
0
def _bitvec(name, slices, indices):
    """Return a BitVector with an arbitrary number of slices.

    NOTE: This is a recursive helper function for 'bitvec'.
          Do not invoke this function directly.
    """
    fst, rst = slices[0], slices[1:]
    if rst:
        items = [_bitvec(name, rst, indices + (i, ))
                 for i in range(fst.start, fst.stop)]
        return Slicer(items, fst.start)
    else:
        vs = [exprvar(name, indices + (i, ))
              for i in range(fst.start, fst.stop)]
        return BitVector(vs, fst.start)
Exemple #27
0
    def test_qbf_forall_cardnet(self):
        equals = expr.exprvar("equals")
        cardinality = synth.constraint.equals(self.pos + self.neg,
                                              len(self.neg), equals)
        function = expr.Or(*self.neg, *(~n for n in self.neg), simplify=False)

        solver = self.get_solver()
        solver.exists([equals])
        solver.forall(self.neg)

        solver.add(function)
        for constraint in cardinality:
            solver.add(constraint)
        solver.add(equals)

        sat = solver.solve([equals])

        self.assertIsNotNone(sat)
        self.assertTrue(sat.get(equals))
def literals(draw):
    variables = tuple(expr.exprvar(x) for x in "abcdef")
    variable = draw(st.sampled_from(variables))
    negated = draw(st.booleans())
    if negated: return ~variable
    return variable
 def _inactive_switch(self, i, j):
     assert 1 <= i <= self.m
     assert 1 <= j <= self.n
     return expr.exprvar(("switch", "inactive"), (i, j))
Exemple #30
0
 def switch_var(i, j):
     assert 1 <= i <= self.m
     assert 1 <= j <= self.n
     return expr.exprvar("switch", (i, j, count))
Exemple #31
0
 def position_var(i, j, rnd):
     assert 1 <= i <= self.m
     assert 1 <= j <= self.n
     return expr.exprvar("reachable", (i, j, rnd, count))
 def _path_var(self, i, j):
     assert 1 <= i <= self.m
     assert 1 <= j <= self.n
     return expr.exprvar("path", (i, j))
 def _negative_path_var(self, i, j):
     assert 1 <= i <= self.m
     assert 1 <= j <= self.n
     return expr.exprvar(("path", "negative"), (i, j))
Exemple #34
0
 def _vector_to_vars(vector):
     for (num, inp) in enumerate(vector):
         if inp == table.PC_ONE:
             yield expr.exprvar("input", num)
         elif inp == table.PC_ZERO:
             yield ~expr.exprvar("input", num)
Exemple #35
0
 def _next_aux(name=None, index=None):
     count = next(Cardnet._counter)
     names = ("cardnet", name) if name else "cardnet"
     indices = (index, count) if index else count
     return expr.exprvar(names, indices)
Exemple #36
0
 def setUp(self):
     self.pos = tuple(expr.exprvar(p) for p in "abc")
     self.neg = tuple(expr.exprvar(p) for p in "uvwxyz")
     self.function = expr.And(*self.pos, ~expr.Or(*self.neg))
 def path_var(i, j):
     assert 1 <= i <= self.m
     assert 1 <= j <= self.n
     return expr.exprvar("path", (i, j, count))
 def a(i):
     return expr.exprvar("sinz", (i, count))
 def _position_unreachable(self, i, j, rnd):
     assert 1 <= i <= self.m
     assert 1 <= j <= self.n
     return expr.exprvar("unreachable", (i, j, rnd))
Exemple #40
0
 def setUp(self):
     super().setUp()
     self.pos = tuple(expr.exprvar(p) for p in "abcdef")
     self.neg = tuple(expr.exprvar(p) for p in "uvwxyz")