- _RE_FRACTION = re.compile(r'^(?P<num>[-+]?\d+)(/(?P<den>\d+))?$')
-
- __slots__ = ('context', '_iv', '_numerator', '_denominator')
-
- def __new__(cls, context, numerator=0, denominator=None):
- self = super().__new__(cls)
- if not isinstance(context, Context):
- raise TypeError('first argument should be a context')
- self.context = context
- if isinstance(numerator, cls._ptr):
- assert denominator is None
- self._iv = numerator
- if libisl.isl_val_is_rat(self):
- # retrieve numerator and denominator as strings to avoid integer
- # overflows
- ip = libisl.isl_printer_to_str(self.context)
- ip = libisl.isl_printer_print_val(ip, self)
- string = libisl.isl_printer_get_str(ip).decode()
- libisl.isl_printer_free(ip)
- m = self._RE_FRACTION.match(string)
- assert m is not None
- self._numerator = int(m.group('num'))
- self._denominator = int(m.group('den')) if m.group('den') else 1
- else:
- self._numerator = None
- self._denominator = None
- return self
- if isinstance(numerator, str) and denominator is None:
- m = self._RE_NONFINITE.match(numerator)
- if m is not None:
- self._numerator = None
- self._denominator = None
- if m.group('inf'):
- if m.group('sign') == '-':
- self._iv = libisl.isl_val_neginfty(context)
- else:
- self._iv = libisl.isl_val_infty(context)
- else:
- assert m.group('nan')
- self._iv = libisl.isl_val_nan(context)
- return self
- try:
- frac = Fraction(numerator, denominator)
- except ValueError:
- raise ValueError('invalid literal for {}: {!r}'.format(
- cls.__name__, numerator))
- self._numerator = frac.numerator
- self._denominator = frac.denominator
- # values passed as strings to avoid integer overflows
- if frac.denominator == 1:
- numerator = str(frac.numerator).encode()
- self._iv = libisl.isl_val_read_from_str(context, numerator)
- else:
- numerator = str(frac.numerator).encode()
- numerator = libisl.isl_val_read_from_str(context, numerator)
- denominator = str(frac.denominator).encode()
- denominator = libisl.isl_val_read_from_str(context, denominator)
- self._iv = libisl.isl_val_div(numerator, denominator)
- print('in isl')
- return self
-
-
- @property
- def _as_parameter_(self):
- return self._iv
-
- def symbols(self):
- s = set()
- for constraint in self.constraints():
- s.update(constraint.symbols)
- yield from sorted(s)
-
- def __del__(self):
- libisl.isl_val_free(self)
- self.context # prevents context from being GC'ed before the value
-
- @property
- def numerator(self):
- if self._numerator is None:
- raise ValueError('not a rational number')
- return self._numerator
-
- @property
- def denominator(self):
- if self._denominator is None:
- raise ValueError('not a rational number')
- return self._denominator