welchbj / tt

a Pythonic toolkit for working with Boolean expressions
https://tt.brianwel.ch
MIT License
218 stars 12 forks source link
boolean boolean-algebra boolean-expression python sat sat-solver satisfiability transformations truth-table

|pypi| |pyversions| |docs| |nixbuild| |winbuild|

Synopsis

tt (t\ ruth t\ able) is a library aiming to provide a Pythonic toolkit for working with Boolean expressions and truth tables. Please see the project site for guides and documentation, or check out bool.tools for a simple web application powered by this library.

Installation

tt is tested on CPython 3.6, 3.7, and 3.8. You can get the latest release from PyPI with::

pip install ttable

Features

Parse expressions::

>>> from tt import BooleanExpression
>>> b = BooleanExpression('A impl not (B nand C)')
>>> b.tokens
['A', 'impl', 'not', '(', 'B', 'nand', 'C', ')']
>>> print(b.tree)
impl
`----A
`----not
     `----nand
          `----B
          `----C

Evaluate expressions::

>>> b = BooleanExpression('(A /\ B) -> (C \/ D)')
>>> b.evaluate(A=1, B=1, C=0, D=0)
False
>>> b.evaluate(A=1, B=1, C=1, D=0)
True

Interact with expression structure::

>>> b = BooleanExpression('(A and ~B and C) or (~C and D) or E')
>>> b.is_dnf
True
>>> for clause in b.iter_dnf_clauses():
...     print(clause)
...
A and ~B and C
~C and D
E

Apply expression transformations::

>>> from tt import to_primitives, to_cnf
>>> to_primitives('A xor B')
<BooleanExpression "(A and not B) or (not A and B)">
>>> to_cnf('(A nand B) impl (C or D)')
<BooleanExpression "(A or C or D) and (B or C or D)">

Or create your own::

>>> from tt import tt_compose, apply_de_morgans, coalesce_negations, twice
>>> b = BooleanExpression('not (not (A or B))')
>>> f = tt_compose(apply_de_morgans, twice)
>>> f(b)
<BooleanExpression "not not A or not not B">
>>> g = tt_compose(f, coalesce_negations)
>>> g(b)
<BooleanExpression "A or B">

Exhaust SAT solutions::

>>> b = BooleanExpression('~(A or B) xor C')
>>> for sat_solution in b.sat_all():
...     print(sat_solution)
...
A=0, B=1, C=1
A=1, B=0, C=1
A=1, B=1, C=1
A=0, B=0, C=0

Find just a few::

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

Or just one::

>>> b.sat_one()
<BooleanValues [A=0, B=1, C=1]>

Build truth tables::

>>> from tt import TruthTable
>>> t = TruthTable('A iff B')
>>> print(t)
+---+---+---+
| A | B |   |
+---+---+---+
| 0 | 0 | 1 |
+---+---+---+
| 0 | 1 | 0 |
+---+---+---+
| 1 | 0 | 0 |
+---+---+---+
| 1 | 1 | 1 |
+---+---+---+

And much more_!

License

tt uses the MIT License_.

.. _MIT License: https://opensource.org/licenses/MIT .. _project site: https://tt.brianwel.ch .. _bool.tools: http://www.bool.tools .. _much more: https://tt.brianwel.ch/en/stable/user_guide.html

.. |pypi| image:: https://img.shields.io/pypi/v/ttable.svg?style=flat-square&label=pypi :target: https://pypi.python.org/pypi/ttable :alt: tt's PyPI page

.. |pyversions| image:: https://img.shields.io/pypi/pyversions/ttable.svg?style=flat-square :target: https://pypi.python.org/pypi/ttable :alt: tt runs on Python 3.6, 3.7, and 3.8

.. |docs| image:: https://img.shields.io/badge/docs-latest-c944ff.svg?style=flat-square :target: https://tt.brianwel.ch/en/latest/ :alt: tt documentation site

.. |nixbuild| image:: https://img.shields.io/travis/welchbj/tt/develop.svg?style=flat-square&label=linux%20build :target: https://travis-ci.org/welchbj/tt :alt: Linux build on Travis CI

.. |winbuild| image:: https://img.shields.io/appveyor/ci/welchbj/tt/develop.svg?style=flat-square&label=windows%20build :target: https://ci.appveyor.com/project/welchbj/tt :alt: Windows build on AppVeyor