py_rete
py_rete copied to clipboard
Make boolean logic complete
We use this package in a production system. When I was writing some more complex boolean logic, I noticed some combinations of boolean operators did not work as expected, and some conditions were being silently dropped.
Fixes:
NOT:
NOT(NOT(expression))was not expanded toexpression, but evaluated into an empty list[[]]. Empty list was evaluated as a condition that raised an alert.NOT(AND(A, B))was not expanded, so logically equivalent expressions:NOT(AND(A, B))andOR(NOT(A), NOT(B))caused different number of activations.- Top-level OR'd conditions should cause an alert for each, and are de-duplicated later
NOT(Filter())caused either false positives or an exception, depending on the value of the filter expression
AND/OR:
- In expressions like
(A & B | C)or(A | B & C)the right/left-hand branch respectively was ignored, resulting in an expression like[[A], []]or[[], [C]]. Again, an alert was always triggered for the empty list. - Similarly, for expression like
AND(A, AND(B, C))theAND(B, C)branch was ignored, though(A & (B & C))worked as expected (due to parenthesis expansion happening early, due to operator precedence rules). - Due to the above, any generic expression containing a nested
ANDled to branches that were either silently ignored or caused false positives.
Changes:
- Ambiguous
NOT(A, B)is not allowed, must use either(NOT(OR(A,B))orNOT(AND(A,B))or the equivalents~(A | B),~(A & B) NOT(Filter()is explicitly not supported, and you should write the boolean inversion into the filter function logic.