logical module
Callable subclass of the built-in tuple
type for representing
logical operators and connectives based on their truth tables.
The two nullary, four unary, and sixteen binary operators are available as
attributes of the logical
class, and also as constants. Likewise, the
four sets of operators logical.nullary
, logical.unary
,
logical.binary
, and logical.every
are available both as attributes
of logical
and as exported top-level constants.
- class logical.logical.logical(iterable)[source]
Bases:
tuple
Each instance of this class represents a boolean function of
n
inputs by specifying its output values across all possible inputs. In other words, an instance represents the output column of a truth table for a function (under the assumption that the input vectors to which each output value corresponds are sorted in ascending order). Each instance representing a function that acceptsn
inputs must have length2 ** n
.For example, consider the truth table below for a boolean function f that accepts two inputs:
x
y
f (x, y)
0
0
1
0
1
0
1
0
1
1
1
0
The entire function f can be represented using the right-most column. For the example function f defined by the table above, this can be done in the manner illustrated below.
>>> f = logical((1, 0, 1, 0)) >>> f(0, 1) 0 >>> f(1, 0) 1
Pre-defined instances are defined for all nullary, unary and binary functions, and are available as attributes of this class and as top-level constants:
()
=logical.undef_
represents UNDEFINED (i.e., no inputs and no defined output)(0,)
=logical.nf_
represents NULLARY FALSE (i.e., no inputs and a constant output)(1,)
=logical.nt_
represents NULLARY TRUE (i.e., no inputs and a constant output)(0, 0)
=logical.uf_
represents UNARY FALSE (i.e., a constant output for any one input)(0, 1)
=logical.id_
represents IDENTITY(1, 0)
=logical.not_
represents NOT(1, 1)
=logical.ut_
represents UNARY TRUE (i.e., a constant output for any one input)(0, 0, 0, 0)
=logical.bf_
represents BINARY FALSE(0, 0, 0, 1)
=logical.and_
represents AND(0, 0, 1, 0)
=logical.nimp_
represents NIMP (i.e.,>
)(0, 0, 1, 1)
=logical.fst_
represents FST (i.e., first/left-hand input)(0, 1, 0, 0)
=logical.nif_
represents NIF (i.e.,<
)(0, 1, 0, 1)
=logical.snd_
represents SND (i.e., second/right-hand input)(0, 1, 1, 0)
=logical.xor_
represents XOR (i.e.,!=
)(0, 1, 1, 1)
=logical.or_
represents OR(1, 0, 0, 0)
=logical.nor_
represents NOR(1, 0, 0, 1)
=logical.xnor_
represents XNOR (i.e.,==
)(1, 0, 1, 0)
=logical.nsnd_
represents NSND (i.e., negation of second input)(1, 0, 1, 1)
=logical.if_
represents IF (i.e.,>=
)(1, 1, 0, 0)
=logical.nfst_
represents NFST (i.e., negation of first input)(1, 1, 0, 1)
=logical.imp_
represents IMP (i.e.,<=
)(1, 1, 1, 0)
=logical.nand_
represents NAND(1, 1, 1, 1)
=logical.bt_
represents BINARY TRUE
>>> logical.xor_(1, 0) 1 >>> and_(1, 0) 0
Because this class is derived from the
tuple
type, all methods and functions that operate on tuples also work with instances of this class.>>> logical((1, 0)) == logical((1, 0)) True >>> logical((1, 0)) == logical((0, 1)) False >>> logical((1, 0))[1] 0
If an attempt is made to create an instance using an iterable that cannot be interpreted as a truth table, an exception is raised.
>>> logical(('a', 'b')) Traceback (most recent call last): ... TypeError: all entries in supplied truth table must be integers >>> logical((-1, 2)) Traceback (most recent call last): ... ValueError: all integers in supplied truth table must be 0 or 1 >>> logical((1, 0, 1)) Traceback (most recent call last): ... ValueError: number of elements in supplied truth table must be zero or a power of 2
- names: dict = {(): 'undef', (0,): 'nf', (0, 0): 'uf', (0, 0, 0, 0): 'bf', (0, 0, 0, 1): 'and', (0, 0, 1, 0): 'nimp', (0, 0, 1, 1): 'fst', (0, 1): 'id', (0, 1, 0, 0): 'nif', (0, 1, 0, 1): 'snd', (0, 1, 1, 0): 'xor', (0, 1, 1, 1): 'or', (1,): 'nt', (1, 0): 'not', (1, 0, 0, 0): 'nor', (1, 0, 0, 1): 'xnor', (1, 0, 1, 0): 'nsnd', (1, 0, 1, 1): 'if', (1, 1): 'ut', (1, 1, 0, 0): 'nfst', (1, 1, 0, 1): 'imp', (1, 1, 1, 0): 'nand', (1, 1, 1, 1): 'bt'}
Typical concise names for all nullary, unary, and binary operators.
- binary: frozenset = frozenset({(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 1, 0), (0, 0, 1, 1), (0, 1, 0, 0), (0, 1, 0, 1), (0, 1, 1, 0), (0, 1, 1, 1), (1, 0, 0, 0), (1, 0, 0, 1), (1, 0, 1, 0), (1, 0, 1, 1), (1, 1, 0, 0), (1, 1, 0, 1), (1, 1, 1, 0), (1, 1, 1, 1)})
Set of all binary operators.
- every: frozenset = frozenset({(0,), (0, 0), (0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 1, 0), (0, 0, 1, 1), (0, 1), (0, 1, 0, 0), (0, 1, 0, 1), (0, 1, 1, 0), (0, 1, 1, 1), (1,), (1, 0), (1, 0, 0, 0), (1, 0, 0, 1), (1, 0, 1, 0), (1, 0, 1, 1), (1, 1), (1, 1, 0, 0), (1, 1, 0, 1), (1, 1, 1, 0), (1, 1, 1, 1)})
Set of all nullary, unary, and binary operators.
- __call__(*arguments: Union[Tuple[int, ...], Tuple[Iterable[int]]]) int [source]
Apply the function represented by this instance to zero or more integer arguments (where the arguments collectively represent an individual input row within a truth table) or to a single iterable of integers (where the entries of the iterable represent an individual input row within a truth table).
>>> logical((1,))() 1 >>> logical((1, 0))(1) 0 >>> logical((1, 0, 0, 1))(0, 0) 1 >>> logical((1, 0, 0, 1))(1, 1) 1 >>> logical((1, 0, 0, 1))(1, 0) 0 >>> logical((1, 0, 0, 1))(0, 1) 0 >>> logical((1, 0, 0, 1, 0, 1, 0, 1))(1, 1, 0) 0 >>> logical((1, 0, 0, 1, 0, 1, 0, 1))([1, 1, 0]) 0 >>> logical((1, 0, 0, 1, 0, 1, 0, 1))((1, 1, 0)) 0 >>> logical((1, 0, 0, 1, 0, 1, 0, 1))((1, 1, 0)) 0
The supplied iterable of integers can be an iterator, as well.
>>> t = iter([1, 1, 0]) >>> logical((1, 0, 0, 1, 0, 1, 0, 1))(t) 0
The instance corresponding to the nullary function with no defined output raises an exception when applied to an input.
>>> logical(())() Traceback (most recent call last): ... ValueError: no defined output
Any attempt to apply an instance to an invalid input raises an exception.
>>> logical((1, 0))(2.3) Traceback (most recent call last): ... TypeError: expecting zero or more integers or a single iterable of integers >>> logical((1, 0))(['abc']) Traceback (most recent call last): ... TypeError: expecting zero or more integers or a single iterable of integers >>> logical((1, 0))(2) Traceback (most recent call last): ... ValueError: expecting an integer that is 0 or 1
- name() str [source]
Return the typical concise name for this operator.
>>> logical((0,)).name() 'nf' >>> logical((1, 0, 0, 1)).name() 'xnor' >>> len([o.name for o in logical.nullary]) 2 >>> len([o.name for o in logical.unary]) 4 >>> len([o.name for o in logical.binary]) 16
- arity() int [source]
Return the arity of this operator.
>>> logical(()).arity() 0 >>> logical((1,)).arity() 0 >>> logical((1, 0)).arity() 1 >>> logical((1, 0, 0, 1)).arity() 2
- compiled() logical.logical.logical [source]
Return a new instance (representing the same logical function) that has a new
function
attribute corresponding to a compiled version of the logical function it represents.>>> (logical((1,)).compiled()).function() 1 >>> (logical((1, 0)).compiled()).function(1) 0 >>> f = logical((1, 0, 0, 1)) >>> g = f.compiled() >>> g.function(1, 1) 1 >>> f = logical((1, 0, 0, 1, 0, 1, 0, 1)) >>> g = f.compiled() >>> g.function(0, 0, 0) 1 >>> g.function(1, 1, 0) 0
The function is constructed by translating the truth table into an abstract syntax tree of a corresponding Python function definition (using the
ast
module), compiling that function definition (using the built-incompile
function), executing that function definition (usingexec
), and then assigning that function to thefunction
attribute.While the compiled function increases the amount of memory consumed by an instance, the execution time of the compiled function on an input is usually at most half of the execution time of the
__call__
method.
- undef_: logical.logical.logical = ()
Nullary operation with no defined output.
- nf_: logical.logical.logical = (0,)
Nullary FALSE (constant) operation.
nf_()
0
- nt_: logical.logical.logical = (1,)
Nullary TRUE (constant) operation.
nt_()
1
- uf_: logical.logical.logical = (0, 0)
Unary FALSE (constant) operation.
x
uf_(x)
0
0
1
0
- id_: logical.logical.logical = (0, 1)
Unary IDENTITY operation.
x
id_(x)
0
0
1
1
- not_: logical.logical.logical = (1, 0)
Unary NOT operation (i.e., negation).
x
not_(x)
0
1
1
0
- ut_: logical.logical.logical = (1, 1)
Unary TRUE (constant) operation.
x
ut_(x)
0
1
1
1
- bf_: logical.logical.logical = (0, 0, 0, 0)
Binary FALSE (constant) operation.
(x, y)
bf_(x, y)
(0, 0)
0
(0, 1)
0
(1, 0)
0
(1, 1)
0
- and_: logical.logical.logical = (0, 0, 0, 1)
Binary AND operation (i.e., conjunction).
(x, y)
and_(x, y)
(0, 0)
0
(0, 1)
0
(1, 0)
0
(1, 1)
1
- nimp_: logical.logical.logical = (0, 0, 1, 0)
Binary NIMP operation (i.e.,
>
).(x, y)
nimp_(x, y)
(0, 0)
0
(0, 1)
0
(1, 0)
1
(1, 1)
0
- fst_: logical.logical.logical = (0, 0, 1, 1)
Binary FST operation (i.e., first/left-hand input).
(x, y)
fst_(x, y)
(0, 0)
0
(0, 1)
0
(1, 0)
1
(1, 1)
1
- nif_: logical.logical.logical = (0, 1, 0, 0)
Binary NIF operation (i.e.,
<
).(x, y)
nif_(x, y)
(0, 0)
0
(0, 1)
1
(1, 0)
0
(1, 1)
0
- snd_: logical.logical.logical = (0, 1, 0, 1)
Binary SND operation (i.e., second/right-hand input).
(x, y)
snd_(x, y)
(0, 0)
0
(0, 1)
1
(1, 0)
0
(1, 1)
1
- xor_: logical.logical.logical = (0, 1, 1, 0)
Binary XOR operation (i.e.,
!=
).(x, y)
xor_(x, y)
(0, 0)
0
(0, 1)
1
(1, 0)
1
(1, 1)
0
- or_: logical.logical.logical = (0, 1, 1, 1)
Binary OR operation (i.e., disjunction).
(x, y)
or_(x, y)
(0, 0)
0
(0, 1)
1
(1, 0)
1
(1, 1)
1
- nor_: logical.logical.logical = (1, 0, 0, 0)
Binary NOR operation.
(x, y)
nor_(x, y)
(0, 0)
1
(0, 1)
0
(1, 0)
0
(1, 1)
0
- xnor_: logical.logical.logical = (1, 0, 0, 1)
Binary XNOR operation (i.e.,
==
).(x, y)
xnor_(x, y)
(0, 0)
1
(0, 1)
0
(1, 0)
0
(1, 1)
1
- nsnd_: logical.logical.logical = (1, 0, 1, 0)
Binary NSND operation (i.e., negation of second/right-hand input).
(x, y)
nsnd_(x, y)
(0, 0)
1
(0, 1)
0
(1, 0)
1
(1, 1)
0
- if_: logical.logical.logical = (1, 0, 1, 1)
Binary IF operation.
(x, y)
if_(x, y)
(0, 0)
1
(0, 1)
0
(1, 0)
1
(1, 1)
1
- nfst_: logical.logical.logical = (1, 1, 0, 0)
Binary NFST operation (i.e., negation of first/left-hand input).
(x, y)
nfst_(x, y)
(0, 0)
1
(0, 1)
1
(1, 0)
0
(1, 1)
0
- imp_: logical.logical.logical = (1, 1, 0, 1)
Binary IMP operation (i.e., implication or
<=
).(x, y)
imp_(x, y)
(0, 0)
1
(0, 1)
1
(1, 0)
0
(1, 1)
1
- nand_: logical.logical.logical = (1, 1, 1, 0)
Binary NAND operation (i.e., negation of conjunction).
(x, y)
nand_(x, y)
(0, 0)
1
(0, 1)
1
(1, 0)
1
(1, 1)
0
- bt_: logical.logical.logical = (1, 1, 1, 1)
Binary TRUE (constant) operation.
(x, y)
bt_(x, y)
(0, 0)
1
(0, 1)
1
(1, 0)
1
(1, 1)
1