code: def distribute_and_over_or(s):
      
      if s.op == '|':
          s = associate('|', s.args)
          if s.op != '|':
              return distribute_and_over_or(s)
          if len(s.args) == 0:
              return FALSE
          if len(s.args) == 1:
              return distribute_and_over_or(s.args[0])
          conj = find_if((lambda d: d.op == '&'), s.args)
          if not conj:
              return s
          others = [a for a in s.args if a is not conj]
          rest = associate('|', others)
          return associate('&', [distribute_and_over_or(c|rest)
                                 for c in conj.args])
      elif s.op == '&':
          return associate('&', map(distribute_and_over_or, s.args))
      else:
          return s
docs: Given a sentence s consisting of conjunctions and disjunctions
      of literals, return an equivalent sentence in CNF.
      >>> distribute_and_over_or((A & B) | C)
      ((A | C) & (B | C))