Example #1
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=[])
Example #2
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([])
Example #3
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])
Example #4
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)
Example #5
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())
Example #6
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'])
Example #7
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]])
Example #8
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']])
Example #9
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]])
Example #10
0
File: bexpr.py Project: GDApsy/tt
    def sat_one(self):
        """Find a combination of inputs that satisfies 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 satisfying an expression::

            >>> from tt import BooleanExpression
            >>> b = BooleanExpression('A xor 1')
            >>> b.sat_one()
            <BooleanValues [A=0]>

        Don't forget about the utility provided by the :func:`constrain`
        context manager::

            >>> b = BooleanExpression('(A nand B) iff C')
            >>> with b.constrain(A=1, C=1):
            ...     b.sat_one()
            ...
            <BooleanValues [A=1, B=0, C=1]>

        Finally, here's an example when the expression cannot be satisfied::

            >>> with BooleanExpression('A xor 1').constrain(A=1) as b:
            ...     b.sat_one() is None
            ...
            True

        :returns: :func:`namedtuple <python:collections.namedtuple>`-like
            object representing a satisfying set of values (see
            :func:`boolean_variables_factory \
            <tt.definitions.operands.boolean_variables_factory>` for more
            information about the type of object returned); ``None``
            will be returned if no satisfiable set of inputs exists.
        :rtype: :func:`namedtuple <python:collections.namedtuple>`-like object
            or ``None``

        :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):
                return self._symbol_vals_factory(**self._constraints)
            else:
                return None

        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

        picosat_result = picosat.sat_one(clauses, assumptions=assumptions)
        if picosat_result is None:
            return None

        result_dict = self._picosat_result_as_dict(picosat_result,
                                                   symbol_to_index_map,
                                                   index_to_symbol_map)
        return self._symbol_vals_factory(**result_dict)
Example #11
0
 def test_sat_one_assumptions_not_in_clauses(self):
     """Test that assumptions not in clauses are still in the solution."""
     self.assertEqual([1, -2, 3, 4],
                      sat_one([[1, 2], [-2]], assumptions=[3, 4]))
Example #12
0
 def test_sat_one_multi_clauses_assumptions_not_satisfiable(self):
     """Test multi-clause sat with assumptions without a solution."""
     self.assertEqual(None, sat_one([[-1, -2], [1]], [2]))
Example #13
0
 def test_sat_one_multi_clauses_assumptions_satisfiable(self):
     """Test multi-clause sat with assumptions with a single solution."""
     self.assertEqual([-1, 2, 3], sat_one([[1, 2, 3], [-1, 2, 3]], [-1]))
Example #14
0
 def test_sat_one_multi_clauses_not_satisfiable(self):
     """Test multi-clause satisfiability without a solution."""
     self.assertEqual(None, sat_one([[1, 2], [-1, 2], [-2]]))
Example #15
0
 def test_sat_one_multi_clauses_satisfiable(self):
     """Test multi-clause satisfiability with a single solution."""
     self.assertEqual([-1, 2, 3], sat_one([[1, 2, 3], [-1, 2], [3]]))
Example #16
0
 def test_sat_one_assumptions_single_clause_not_satisfiable(self):
     """Assert no solution found for an infeasible assumption."""
     self.assertEqual(None, sat_one([[1]], [-1]))
     self.assertEqual(None, sat_one([[-1]], [1]))
Example #17
0
 def test_sat_one_single_clause_assumptions_satisfiable(self):
     """Test a single clause with assumptions, ensuring solution found."""
     self.assertEqual([1, 2, -3, -4],
                      sat_one([[1, 4], [2, 3], [1, -3], [-3]],
                              assumptions=[-4]))
Example #18
0
 def test_sat_one_single_clause_satisfiable(self):
     """Test a single clause and look for a satisfiable solution."""
     self.assertEqual([1], sat_one([[1]]))