A first circuit¶
From a source checkout, install the Python package with Rust available:
python -m pip install ./bindings/python
Once installed, ordinary use needs only Python. A vtree groups the variables
that your circuits will share. Here we have three Boolean variables and the
function (x ∧ y) ∨ z:
>>> from tididi import Vtree, literal
>>> vtree = Vtree.balanced(3)
>>> x = literal(vtree, 1)
>>> y = literal(vtree, 2)
>>> z = literal(vtree, 3)
>>> f = (x & y) | z
>>> print(f.model_count())
5
There are four assignments with z true and one more with both x and
y true while z is false. All variables in the vtree participate in
counting, including ones a function leaves free.
Use &, |, ^, and ~ for conjunction, disjunction, exclusive-or,
and negation. Parenthesize compound expressions. Python’s and, or, and
not test an object’s truth value and cannot construct circuits; tididi
raises TypeError if a circuit is used that way.
Operations consume their circuit operands. The result f above is usable;
x, y, and z are consumed. Querying a circuit leaves it usable, and
copy() makes an explicit copy for a transformation:
>>> complement = ~f.copy()
>>> print(f.model_count(), complement.model_count())
5 3
Use the same vtree for circuits you intend to combine. literal(vtree, -2)
builds the negation of variable 2. For named choices that you can pass repeatedly
to construction and observation operations, use tididi.Literal:
>>> from tididi import Literal
>>> enabled = Literal(2)
>>> disabled = ~enabled
>>> print(enabled.variable, enabled.sign, int(disabled))
2 True -2
Continue with Configuration rules to build and query a complete set of rules, or read Using and reusing circuits for copying, aliasing, and error behavior.