docs: def extend(self, lits=[], ubound=None, top_id=None):
          """
              Extends the list of literals in the sum and (if needed) increases a
              potential upper bound that can be imposed on the complete list of
              literals in the sum of an existing :class:`ITotalizer` object to a
              new value.
  
              :param lits: additional literals to be included in the sum.
              :param ubound: a new upper bound.
              :param top_id: a new top variable identifier.
  
              :type lits: iterable(int)
              :type ubound: int
              :type top_id: integer or None
  
              The top identifier ``top_id`` applied only if it is greater than
              the one used in ``self``.
  
              This method creates additional clauses encoding the existing
              totalizer tree augmented with new literals in the sum and updating
              the upper bound. As a result, it appends the new clauses to the
              list of clauses of :class:`.CNF` ``self.cnf``. The number of newly
              created clauses is stored in variable ``self.nof_new``.
  
              Also, if the upper bound is updated, a list of bounds ``self.rhs``
              gets increased and its length becomes ``ubound+1``. Otherwise, it
              is updated with new values.
  
              The method can be used in the following way:
  
              .. code-block:: python
  
                  >>> from pysat.card import ITotalizer
                  >>> t = ITotalizer(lits=[1, 2], ubound=1)
                  >>> print t.cnf.clauses
                  [[-2, 3], [-1, 3], [-1, -2, 4]]
                  >>> print t.rhs
                  [3, 4]
                  >>>
                  >>> t.extend(lits=[5], ubound=2)
                  >>> print t.cnf.clauses
                  [[-2, 3], [-1, 3], [-1, -2, 4], [-5, 6], [-3, 6], [-4, 7], [-3, -5, 7], [-4, -5, 8]]
                  >>> print t.cnf.clauses[-t.nof_new:]
                  [[-5, 6], [-3, 6], [-4, 7], [-3, -5, 7], [-4, -5, 8]]
                  >>> print t.rhs
                  [6, 7, 8]
                  >>> t.delete()
          """
  
          # preparing a new list of distinct input literals
          lits = list(set(lits).difference(set(self.lits)))
  
          if not lits:
              # nothing to merge with -> just increase the bound
              if ubound:
                  self.increase(ubound=ubound, top_id=top_id)
  
              return
  
          self.top_id = max(map(lambda x: abs(x), self.lits + [self.top_id, top_id if top_id != None else 0]))
          self.ubound = max(self.ubound, ubound if ubound != None else 0)
  
          # saving default SIGINT handler
          def_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_DFL)
  
          # updating the object and adding more variables and clauses
          self.tobj, clauses, self.rhs, self.top_id = pycard.itot_ext(self.tobj,
                  lits, self.ubound, self.top_id)
  
          # recovering default SIGINT handler
          def_sigint_handler = signal.signal(signal.SIGINT, def_sigint_handler)
  
          # saving the result
          self.cnf.clauses.extend(clauses)
          self.cnf.nv = self.top_id
          self.lits.extend(lits)
  
          # for convenience, keeping the number of new clauses
          self.nof_new = len(clauses)