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))
    def _assert_positive_path(self, switch_var=None, position_var=None):
        switch_var = self._active_switch if switch_var is None else switch_var
        position_var = self._position_reachable if position_var is None \
                       else position_var

        if self.m == 1 or self.n == 1:
            upper = self._upper_path_bound()
            for i in range(1, self.m + 1):
                for j in range(1, self.n + 1):
                    yield expr.Implies(position_var(i, j, upper),
                                       switch_var(i, j)).to_cnf()
            if self.n == 1:
                for i in range(1, self.m):
                    yield expr.Implies(position_var(i + 1, 1, upper),
                                       position_var(i, 1, upper)).to_cnf()
        else:
            for i in range(1, self.m + 1):
                for j in range(1, self.n + 1):
                    reachable = position_var(i, j, 0)
                    if i == 1: yield reachable
                    else: yield ~reachable

            for rnd in range(1, self._upper_path_bound() + 1):
                for i in range(1, self.m + 1):
                    for j in range(1, self.n + 1):
                        reachable = position_var(i, j, rnd)
                        elements = [position_var(i_, j_, rnd - 1) & \
                                    switch_var(i_, j_)
                                    for (i_, j_) in self._adjacent_4(i, j)]
                        elements.append(position_var(i, j, rnd - 1))
                        yield expr.Implies(reachable,
                                           expr.Or(*elements)).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)
    def test_at_most_one_zero(self):
        self.function = ~expr.Or(*self.neg)

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

        self.assertIsNotNone(sat)
def at_least_one(inputs, equivalent=None):
    assert inputs, "inputs must not be empty"
    constraint = expr.Or(*inputs)
    if equivalent is None:
        yield constraint
    else:
        yield expr.Implies(equivalent, constraint).to_cnf()
        yield expr.Implies(constraint, equivalent).to_cnf()
 def _assert_lattice_on_negative_path(self, assignment, path_var):
     for i in range(1, self.m + 1):
         for j in range(1, self.n + 1):
             elements = list(
                 self._literal_at_position_is(i, j, inp)
                 for inp in self._input_literals()
                 if inp.compose(assignment).simplify().is_zero())
             assert elements, "list of literal variables must not be empty"
             yield expr.Implies(path_var(i, j), expr.Or(*elements)).to_cnf()
    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)
    def test_not_at_least_one_not_equivalent(self):
        self.function = ~expr.Or(*self.neg)

        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)
Beispiel #9
0
 def recurse(expression):
     if expression.ASTOP == "or":
         return expr.And(*(recurse(e) for e in expression.xs))
     if expression.ASTOP == "and":
         return expr.Or(*(recurse(e) for e in expression.xs))
     elif expression.ASTOP == "lit":
         return expression
     elif expression.is_one() or expression.is_zero():
         return ~expression
     else:
         raise NotImplementedError(str(expression))
    def _assert_lattice_on_negative_path(self):
        def _set(i, j, inp):
            return self._literal_at_position_is(i, j, inp) & ~inp

        def _negated(i, j, inp):
            return self._literal_at_position_is(i, j, ~inp) & inp

        for i in range(1, self.m + 1):
            for j in range(1, self.n + 1):
                auxiliaries = list()
                for inp in self._inputs_plus():
                    aux = self._next_aux("on_neg_path")
                    on_neg_path = _set(i, j, inp) | _negated(i, j, inp)
                    auxiliaries.append(aux)
                    yield expr.Implies(aux, on_neg_path).to_cnf()
                yield expr.Implies(self._negative_path_var(i, j),
                                   expr.Or(*auxiliaries)).to_cnf()
Beispiel #11
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))
Beispiel #12
0
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)
Beispiel #13
0
 def _assert_negative_path_exists_if_function_true(self):
     elements = (self._inactive_switch(i, self.n) & \
                 self._position_unreachable(i, self.n, self._upper_path_bound())
                 for i in range(1, self.m + 1))
     yield expr.Implies(self.function, expr.Or(*elements)).to_cnf()
Beispiel #14
0
 def _cover_to_expression(cover):
     inputs = (inp for (inp, outputs) in cover if outputs == (1, ))
     terms = (expr.And(*Function._vector_to_vars(v)) for v in inputs)
     return expr.Or(*terms)
Beispiel #15
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 _assert_negative_path_exists_if_function_false(self, path_var):
     elements = (path_var(i, self.n) for i in range(1, self.m + 1))
     yield expr.Or(*elements)
 def _assert_path_exists_if_function_true(self, path_var):
     elements = (path_var(self.m, j) for j in range(1, self.n + 1))
     yield expr.Or(*elements)
Beispiel #18
0
 def _merger_recursive_clauses(self, d, e, c, sequence_length):
     for i in range(1, sequence_length + 1):
         yield expr.Or(~d[i], ~e[i - 1], c[2 * i])
         yield expr.Or(~d[i], c[2 * i - 1])
         yield expr.Or(~e[i - 1], c[2 * i - 1])
Beispiel #19
0
 def _merger_basic_clauses(self, c1, c2, sequence_a, sequence_b):
     (a, b) = sequence_a + sequence_b
     yield expr.Or(~a, ~b, c2)
     yield expr.Or(~a, c1)
     yield expr.Or(~b, c1)
 def _assert_negative_path_exists_if_function_false(self):
     elements = (self._negative_path_var(i, self.n)
                 for i in range(1, self.m + 1))
     yield expr.Implies(~self.function, expr.Or(*elements)).to_cnf()
Beispiel #21
0
 def _assert_path_exists_if_function_true(self, switch_var, position_var):
     elements = (switch_var(self.m, j) & \
                 position_var(self.m, j, self._upper_path_bound())
                 for j in range(1, self.n + 1))
     yield expr.Or(*elements).to_cnf()
 def _assert_path_exists_if_function_true(self):
     elements = (self._path_var(self.m, j) for j in range(1, self.n + 1))
     yield expr.Implies(self.function, expr.Or(*elements)).to_cnf()
Beispiel #23
0
 def _assert_negative_path_exists_if_function_false(self, switch_var,
                                                    position_var):
     elements = (switch_var(i, self.n) & \
                 position_var(i, self.n, self._upper_path_bound())
                 for i in range(1, self.m + 1))
     yield expr.Or(*elements).to_cnf()
Beispiel #24
0
 def _assert_path_exists_if_function_false(self):
     elements = (self._active_switch(self.m, j) & \
                 self._position_reachable(self.m, j, self._upper_path_bound())
                 for j in range(1, self.n + 1))
     yield expr.Implies(~self.function, expr.Or(*elements)).to_cnf()