code: def pretty(self, indent=0, debug=False):
          
          debug_details = ''
          if debug:
              debug_details += '<isliteral=%r, iscanonical=%r' % (self.isliteral, self.iscanonical)
              identity = getattr(self, 'identity', None)
              if identity is not None:
                  debug_details += ', identity=%r' % (identity)
  
              annihilator = getattr(self, 'annihilator', None)
              if annihilator is not None:
                  debug_details += ', annihilator=%r' % (annihilator)
  
              dual = getattr(self, 'dual', None)
              if dual is not None:
                  debug_details += ', dual=%r' % (dual)
              debug_details += '>'
          cls = self.__class__.__name__
          args = [a.pretty(indent=indent + 2, debug=debug) for a in self.args]
          pfargs = ',\n'.join(args)
          cur_indent = ' ' * indent
          new_line = '' if self.isliteral else '\n'
          return '{cur_indent}{cls}({debug_details}{new_line}{pfargs}\n{cur_indent})'.format(**locals())
docs: Return a pretty formatted representation of self as an indented tree.
  
          If debug is True, also prints debug information for each expression arg.
  
          For example:
          >>> print Expression().parse(u'not a and not b and not (a and ba and c) and c or c').pretty()
          OR(
            AND(
              NOT(Symbol('a')),
              NOT(Symbol('b')),
              NOT(
                AND(
                  Symbol('a'),
                  Symbol('ba'),
                  Symbol('c')
                )
              ),
              Symbol('c')
            ),
            Symbol('c')
          )