py_rete icon indicating copy to clipboard operation
py_rete copied to clipboard

Make boolean logic complete

Open scajanus opened this issue 1 year ago • 0 comments

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 to expression, 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)) and OR(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)) the AND(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 AND led 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)) or NOT(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.

scajanus avatar Nov 23 '24 16:11 scajanus