code: def to_cnf(s):
      
      if isinstance(s, str): s = expr(s)
      s = eliminate_implications(s) # Steps 1, 2 from p. 253
      s = move_not_inwards(s) # Step 3
      return distribute_and_over_or(s)
docs: Convert a propositional logical sentence s to conjunctive normal form.
      That is, to the form ((A | ~B | ...) & (B | C | ...) & ...) [p. 253]
      >>> to_cnf("~(B|C)")
      (~B & ~C)
      >>> to_cnf("B <=> (P1|P2)")
      ((~P1 | B) & (~P2 | B) & (P1 | P2 | ~B))
      >>> to_cnf("a | (b & c) | d")
      ((b | a | d) & (c | a | d))
      >>> to_cnf("A & (B | (D & E))")
      (A & (D | B) & (E | B))
      >>> to_cnf("A | (B | (C | (D & E)))")
      ((D | A | B | C) & (E | A | B | C))