code: def associate(op, args):
      
      args = dissociate(op, args)
      if len(args) == 0:
          return _op_identity[op]
      elif len(args) == 1:
          return args[0]
      else:
          return Expr(op, *args)
docs: Given an associative op, return an expression with the same
      meaning as Expr(op, *args), but flattened -- that is, with nested
      instances of the same op promoted to the top level.
      >>> associate('&', [(A&B),(B|C),(B&C)])
      (A & B & (B | C) & B & C)
      >>> associate('|', [A|(B|(C|(A&B)))])
      (A | B | C | (A & B))