booleancombinationssympy

How to resolve complex boolean expressions into all possible combinations


I'm trying to solve the following problem. I have a set of logical operations and I would like to resolve them into all possible combinations. For example:

"((A | X) & B & C) | (C | E) & A & ~Y"

Should result in the following solutions:

"A & B & C" "X & B & C" "C & A & ~Y" "E & A & ~Y"

In the past i got help with a similar porblem here which came back with the solution:

from sympy.parsing.sympy_parser import parse_expr
from sympy.logic.boolalg import to_dnf

lst = ['(a | b) & (c & d)', '(e & f) | (g | h)', '(i | j) | k']
    
comb = set()

for exp in lst:
    log_expr = str(to_dnf(parse_expr(exp)))
    for e in log_expr.split('|'):
        comb.add(str(parse_expr(e)))

print(comb)

This code works till the additional OR clause. How would a efficient approach to this look like? The expressions can get quite complex, with multiple levels of parentheses, "and", "or", and "not" operations.


Solution

  • Don't use string methods like .split('|') for symbolic manipulation. I don't know who recommended that to you before but it is bad advice.

    Put the result into DNF and then Or.make_args can separate the clauses:

    In [55]: from sympy import *
    
    In [56]: expr1 = parse_expr("((a | x) & b & c) | (c | e) & a & ~y")
    
    In [57]: for expr2 in Or.make_args(to_dnf(expr1)): print(expr2)
    a & b & c
    a & c & ~y
    b & c & x
    a & e & ~y
    

    For your other case:

    In [70]: lst = ['(a | b) & (c & d)', '(e & f) | (g | h)', '(i | j) | k']
    
    In [71]: expr1 = And(*map(parse_expr, lst))
    
    In [72]: expr1
    Out[72]: c ∧ d ∧ (a ∨ b) ∧ (g ∨ h ∨ (e ∧ f)) ∧ (i ∨ j ∨ k)
    
    In [73]: for expr2 in Or.make_args(to_dnf(expr1)): print(expr2)
    a & c & d & h & i
    a & c & d & e & f & j
    a & c & d & e & f & i
    a & c & d & g & k
    b & c & d & g & k
    a & c & d & h & j
    b & c & d & h & j
    b & c & d & g & i
    a & c & d & g & i
    b & c & d & e & f & k
    b & c & d & e & f & i
    a & c & d & e & f & k
    b & c & d & g & j
    a & c & d & g & j
    b & c & d & h & k
    a & c & d & h & k
    b & c & d & e & f & j
    b & c & d & h & i