コード例 #1
0
    def test_passing_list_of_non_ints_assumptions(self):
        """Test an error is raised when non-ints are passed in assumptions."""
        with self.assertRaises(InvalidArgumentTypeError):
            sat_one([[1, -2], [-1]], assumptions=[1, 'string'])

        with self.assertRaises(InvalidArgumentTypeError):
            sat_all([[1, -2], [-1]], assumptions=[1, 'string'])
コード例 #2
0
    def test_passing_list_containing_zeroes_assumptions(self):
        """Test an error is rasied when zeroes are passed in assumptions."""
        with self.assertRaises(InvalidArgumentValueError):
            sat_one([[1, -2], [-1]], assumptions=[1, 2, 3, 0])

        with self.assertRaises(InvalidArgumentValueError):
            sat_all([[1, -2], [-1]], assumptions=[1, 2, 3, 0])
コード例 #3
0
    def test_passing_non_int_inner_list_clauses(self):
        """Test an error is raised when passing a non-int in clauses."""
        with self.assertRaises(InvalidArgumentTypeError):
            sat_one([[1, 2, 3], [-2], ['string']])

        with self.assertRaises(InvalidArgumentTypeError):
            sat_all([[1, 2, 3], [-2], ['string']])
コード例 #4
0
    def test_passing_zeroes_inner_list_clauses(self):
        """Test an error is raised when zeroes are passed in clauses."""
        with self.assertRaises(InvalidArgumentValueError):
            sat_one([[1, 0, 3], [2], [3]])

        with self.assertRaises(InvalidArgumentValueError):
            sat_all([[1, 0, 3], [2], [3]])
コード例 #5
0
    def test_passing_empty_inner_list_clauses(self):
        """Test an error is raised when passing an empty list of clauses."""
        with self.assertRaises(InvalidArgumentValueError):
            sat_one([[1], [], [2, 3]])

        with self.assertRaises(InvalidArgumentValueError):
            sat_all([[1], [], [2, 3]])
コード例 #6
0
    def test_passing_empty_list_assumptions(self):
        """Test passing an empty list as assumptions causes an error."""
        with self.assertRaises(InvalidArgumentValueError):
            sat_one([[1, 2]], assumptions=[])

        with self.assertRaises(InvalidArgumentValueError):
            sat_all([[1, 2]], assumptions=[])
コード例 #7
0
    def test_passing_empty_list_clauses(self):
        """Test passing an empty list as clauses causes an error."""
        with self.assertRaises(InvalidArgumentValueError):
            sat_one([])

        with self.assertRaises(InvalidArgumentValueError):
            sat_all([])
コード例 #8
0
    def test_passing_non_list_assumptions(self):
        """Test passing an invalid non-list as the assumptions argument."""
        with self.assertRaises(InvalidArgumentTypeError):
            sat_one([[1, 2, 3]], assumptions=float())

        with self.assertRaises(InvalidArgumentTypeError):
            sat_all([[1, 2, 3]], assumptions=float())
コード例 #9
0
    def test_passing_non_list_clauses(self):
        """Test passing a non-list as the clauses argument."""
        with self.assertRaises(InvalidArgumentTypeError):
            sat_one(None)

        with self.assertRaises(InvalidArgumentTypeError):
            sat_all(None)
コード例 #10
0
 def test_sat_all_without_assumptions_satisfiable_one_sol(self):
     """Test sat_all w/o assumptions that produces a single solution."""
     count = 0
     expected = [-1, -2, 3, 4]
     for solution in sat_all([[1, 2, 3], [-1], [-2], [-3, 4]]):
         self.assertEqual(expected, solution)
         count += 1
     self.assertEqual(1, count)
コード例 #11
0
 def test_sat_all_with_assumptions_satisfiable_multiple_sols(self):
     """Test sat_all w/ assumptions producing multiple solutions."""
     count = 0
     expected = [[1, -2, 3, -4, 5], [1, -2, 3, -4, -5]]
     for solution in sat_all([[1, 2, 3, 4, 5], [-1, -2], [-3, -4]],
                             assumptions=[1, 3]):
         self.assertIn(solution, expected)
         count += 1
     self.assertEqual(2, count)
コード例 #12
0
 def test_sat_all_with_assumptions_satisfiable_one_sol(self):
     """Test sat_all w/ assumptions producing a single solution."""
     count = 0
     expected = [-1, 2, -3, -4, 5]
     for solution in sat_all([[1, 2], [2, 3], [3, 4, 5]],
                             assumptions=[-1, -3, -4]):
         self.assertEqual(expected, solution)
         count += 1
     self.assertEqual(1, count)
コード例 #13
0
 def test_sat_all_without_assumptions_satisfiable_multiple_sols(self):
     """Test sat_all w/o assumptions producing multiple solutions."""
     count = 0
     expected = [[-1, -2, 3, -4], [-1, 2, -3, -4], [1, 2, -3, -4],
                 [1, -2, -3, -4]]
     for solution in sat_all([[1, 2, 3, 4], [-2, -3], [-4], [-1, -3]]):
         self.assertIn(solution, expected)
         count += 1
     self.assertEqual(4, count)
コード例 #14
0
ファイル: bexpr.py プロジェクト: GDApsy/tt
    def sat_all(self):
        """Find all combinations of inputs that satisfy this expression.

        Under the hood, this method is using the functionality exposed in tt's
        :mod:`satisfiability.picosat <tt.satisfiability.picosat>` module.

        Here's a simple example of iterating through a few SAT solutions::

            >>> from tt import BooleanExpression
            >>> b = BooleanExpression('(A xor B) and (C xor D)')
            >>> for solution in b.sat_all():
            ...     print(solution)
            ...
            A=1, B=0, C=1, D=0
            A=1, B=0, C=0, D=1
            A=0, B=1, C=0, D=1
            A=0, B=1, C=1, D=0

        We can also constrain away a few of those solutions::

            >>> with b.constrain(A=1, C=0):
            ...     for solution in b.sat_all():
            ...         print(solution)
            ...
            A=1, B=0, C=0, D=1

        :returns: An iterator of
            :func:`namedtuple <python:collections.namedtuple>`-like objects
            representing satisfying combinations of inputs; if no satisfying
            solutions exist, the iterator will be empty.
        :rtype: Iterator[:func:`namedtuple <python:collections.namedtuple>`
            -like objects]

        :raises NoEvaluationVariationError: If this is an expression of only
            constants.

        """
        if not self._symbols:
            raise NoEvaluationVariationError(
                'Cannot attempt to satisfy an expression of only constants')

        if not (self._symbol_set - self._constrained_symbol_set):
            # shortcut if all symbols are constrained
            if self.evaluate_unchecked(**self._constraints):
                yield self._symbol_vals_factory(**self._constraints)
            else:
                # empty iterator
                while False:
                    yield None
            return

        clauses, assumptions, symbol_to_index_map, index_to_symbol_map = \
            self._to_picosat_clauses_assumptions_and_symbol_mappings()
        if not assumptions:
            # cannot pass empty list of assumptions to picosat
            assumptions = None

        for picosat_sol in picosat.sat_all(clauses, assumptions=assumptions):
            result_dict = self._picosat_result_as_dict(picosat_sol,
                                                       symbol_to_index_map,
                                                       index_to_symbol_map)
            yield self._symbol_vals_factory(**result_dict)
コード例 #15
0
 def test_sat_all_with_assumptions_not_satisfiable(self):
     """Test sat_all w/ assumptions that produces no solutions."""
     count = 0
     for _ in sat_all([[1, 2, 3], [2, 3], [-1]], assumptions=[-2, -3]):
         count += 1
     self.assertEqual(0, count)
コード例 #16
0
 def test_sat_all_without_assumptions_not_satisfiable(self):
     """Test sat_all w/o assumptions that produces no solutions."""
     count = 0
     for _ in sat_all([[1, 2], [-1, -2], [1], [2]]):
         count += 1
     self.assertEqual(0, count)