PEP 532: Rework De Morgan's Laws section
This commit is contained in:
parent
b171bc0f79
commit
65b178826a
45
pep-0532.txt
45
pep-0532.txt
|
@ -778,37 +778,40 @@ combination of ``not`` operations.
|
||||||
|
|
||||||
For ``and`` and ``or`` in Python, these invariants can be described as follows::
|
For ``and`` and ``or`` in Python, these invariants can be described as follows::
|
||||||
|
|
||||||
assert (A and B) == (not (not A or not B))
|
assert bool(A and B) == bool(not (not A or not B))
|
||||||
assert (A or B) == (not (not A and not B))
|
assert bool(A or B) == bool(not (not A and not B))
|
||||||
|
|
||||||
That is, if you take one of the operators, invert both operands, switch to the
|
That is, if you take one of the operators, invert both operands, switch to the
|
||||||
other operator, and then invert the overall result, you'll get the same
|
other operator, and then invert the overall result, you'll get the same
|
||||||
answer as you did from the original operator. (This may seem redundant,
|
answer (in a boolean sense) as you did from the original operator. (This may
|
||||||
but in many situations it actually lets you eliminate double negatives and find
|
seem redundant, but in many situations it actually lets you eliminate double
|
||||||
tautologically true or false subexpressions, thus reducing the overall
|
negatives and find tautologically true or false subexpressions, thus reducing
|
||||||
expression size).
|
the overall expression size).
|
||||||
|
|
||||||
For circuit breakers, defining a suitable invariant is complicated by the
|
For circuit breakers, defining a suitable invariant is complicated by the
|
||||||
fact that they're designed to eliminate themselves from the expression result
|
fact that they're often going to be designed to eliminate themselves from the
|
||||||
when they're short-circuited, which is an inherently asymmetric behaviour.
|
expression result when they're short-circuited, which is an inherently
|
||||||
Accordingly, that inherent asymmetry needs to be corrected for when mapping
|
asymmetric behaviour. Accordingly, that inherent asymmetry needs to be
|
||||||
De Morgan's Laws to the expected behaviour of symmetric circuit breakers.
|
accounted for when mapping De Morgan's Laws to the expected behaviour of
|
||||||
|
symmetric circuit breakers.
|
||||||
|
|
||||||
|
One way this complication can be addressed is to wrap the operand that would
|
||||||
|
otherwise short-circuit in ``operator.true``, ensuring that when ``bool`` is
|
||||||
|
applied to the overall result, it uses the same definition of truth that was
|
||||||
|
used to decide which branch to evaluate, rather than applying ``bool`` directly
|
||||||
|
to the circuit breaker's input value.
|
||||||
|
|
||||||
Specifically, for the new short-circuiting operators, the following properties
|
Specifically, for the new short-circuiting operators, the following properties
|
||||||
would be reasonably expected to hold for any well-behaved symmetric circuit
|
would be reasonably expected to hold for any well-behaved symmetric circuit
|
||||||
breaker that implements all of ``__bool__``, ``__not__``, ``__then__``, and
|
breaker that implements both ``__bool__`` and ``__not__``::
|
||||||
``__else__``:
|
|
||||||
|
|
||||||
cb_A = to_cb(A)
|
assert bool(B if true(A)) == bool(not (true(not A) else not B))
|
||||||
cb_B = to_cb(B)
|
assert bool(true(A) else B) == bool(not (not B if true(not A)))
|
||||||
assert (B if cb_A) is short_circuit(not (not cb_A else not cb_B))
|
|
||||||
assert (cb_A else B) is short_circuit(not (not cb_B if not cb_A))
|
|
||||||
|
|
||||||
Where ``to_cb`` returns a symmetric circuit breaker that produces the supplied
|
Note the order of operations on the right hand side (applying ``true``
|
||||||
value when short-circuited, and ``short_circuit`` is defined as::
|
*after* inverting the input circuit breaker) - this ensures that an
|
||||||
|
assertion is actually being made about ``type(A).__not__``, rather than
|
||||||
def short_circuit(expr):
|
merely being about the behaviour of ``type(true(A)).__not__``.
|
||||||
return expr if expr else expr
|
|
||||||
|
|
||||||
At the very least, ``types.CircuitBreaker`` instances would respect this
|
At the very least, ``types.CircuitBreaker`` instances would respect this
|
||||||
logic, allowing existing boolean expression optimisations (like double
|
logic, allowing existing boolean expression optimisations (like double
|
||||||
|
|
Loading…
Reference in New Issue