code: def complement(self):
          
          # case 1
          if self.is_empty:
              return StridedInterval.top(self.bits)
          # case 2
          if self.is_top:
              return StridedInterval.empty(self.bits)
          # case 3
          y_plus_1 = StridedInterval._modular_add(self.upper_bound, 1, self.bits)
          x_minus_1 = StridedInterval._modular_sub(self.lower_bound, 1, self.bits)
  
          # the new stride has to be the GCD between the old stride and the distance
          # between the new lower bound and the new upper bound. This assure that in
          # the new interval the boundaries are valid solution when the SI is
          # evaluated.
          dist = StridedInterval._wrapped_cardinality(y_plus_1, x_minus_1, self.bits) - 1
  
          # the new SI is an integer
          if dist < 0:
              new_stride = 0
          elif self._stride == 0:
              new_stride = 1
          else:
              new_stride = fractions.gcd(self._stride, dist)
          return StridedInterval(lower_bound=y_plus_1,
                                 upper_bound=x_minus_1,
                                 bits=self.bits,
                                 stride=new_stride,
                                 uninitialized=self.uninitialized)
docs: Return the complement of the interval
          Refer section 3.1 augmented for managing strides
  
          :return: