docs: def next_level(self):
          """
              Compute the next optimization level (starting from the
              current one). The procedure represents a loop, each
              iteration of which checks whether or not one of the
              conditions holds:
  
              - partial BLO condition
              - stratification condition
  
              If any of these holds, the loop stops.
          """
  
          if self.levl >= len(self.blop):
              self.levl = None
  
          while self.levl < len(self.blop) - 1:
              # number of selectors with weight less than current weight
              numc = sum([len(self.wstr[w]) for w in self.blop[(self.levl + 1):]])
  
              # sum of their weights
              sumw = sum([w * len(self.wstr[w]) for w in self.blop[(self.levl + 1):]])
  
              # partial BLO
              if self.blop[self.levl] > sumw and sumw != 0:
                  break
  
              # stratification
              if numc / float(len(self.blop) - self.levl - 1) > self.sdiv:
                  break
  
              self.levl += 1