X-Git-Url: https://scm.cri.ensmp.fr/git/linpy.git/blobdiff_plain/841943174bb4d3b602e8e055592d8b54d1bb086d..bec8e9379d875b91dd49058aeae0075bda66d6d8:/pypol/isl.py diff --git a/pypol/isl.py b/pypol/isl.py index 758fb79..f1e63dc 100644 --- a/pypol/isl.py +++ b/pypol/isl.py @@ -1,19 +1,34 @@ +""" +note: for islpy +isl format: basic set: ("{[x, y] : x >= 0 and x < 5 and y >= 0 and y < x+4 }") +""" import ctypes, ctypes.util import math import numbers import operator import re +import functools + from decimal import Decimal from fractions import Fraction from functools import wraps - libisl = ctypes.CDLL(ctypes.util.find_library('isl')) libisl.isl_printer_get_str.restype = ctypes.c_char_p +def _polymorphic_method(func): + @functools.wraps(func) + def wrapper(self, other): + if isinstance(other, Value): + return func(self, other) + if isinstance(other, numbers.Rational): + other = Value(self.context, other) + return func(self, other) + raise TypeError('operand should be a Value or a Rational') + return wrapper class Context: @@ -25,9 +40,10 @@ class Context: @property def _as_parameter_(self): return self._ic - - def __del__(self): - libisl.isl_ctx_free(self) + + #comment out so does not delete itself after being created + #def __del__(self): + # libisl.isl_ctx_free(self) def __eq__(self, other): if not isinstance(other, Context): @@ -104,12 +120,19 @@ class Value: 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) + self._iv = libisl.isl_val_div(numerator, denominator) 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) @@ -124,40 +147,29 @@ class Value: @property def denominator(self): if self._denominator is None: - raise ValueError('not a rational number') + raise ValueError('not a rational number') return self._denominator def __bool__(self): return not bool(libisl.isl_val_is_zero(self)) - def _polymorphic(func): - @wraps(func) - def wrapper(self, other): - if isinstance(other, Value): - return func(self, other) - if isinstance(other, numbers.Rational): - other = Value(self.context, other) - return func(self, other) - raise TypeError('operand should be a Value or a Rational') - return wrapper - - @_polymorphic + @_polymorphic_method def __lt__(self, other): return bool(libisl.isl_val_lt(self, other)) - @_polymorphic + @_polymorphic_method def __le__(self, other): return bool(libisl.isl_val_le(self, other)) - @_polymorphic + @_polymorphic_method def __gt__(self, other): return bool(libisl.isl_val_gt(self, other)) - @_polymorphic + @_polymorphic_method def __ge__(self, other): return bool(libisl.isl_val_ge(self, other)) - @_polymorphic + @_polymorphic_method def __eq__(self, other): return bool(libisl.isl_val_eq(self, other)) @@ -192,7 +204,7 @@ class Value: val = libisl.isl_val_trunc(val) return self.__class__(self.context, self._ptr(val)) - @_polymorphic + @_polymorphic_method def __add__(self, other): val1 = libisl.isl_val_copy(self) val2 = libisl.isl_val_copy(other) @@ -201,7 +213,7 @@ class Value: __radd__ = __add__ - @_polymorphic + @_polymorphic_method def __sub__(self, other): val1 = libisl.isl_val_copy(self) val2 = libisl.isl_val_copy(other) @@ -210,7 +222,7 @@ class Value: __rsub__ = __sub__ - @_polymorphic + @_polymorphic_method def __mul__(self, other): val1 = libisl.isl_val_copy(self) val2 = libisl.isl_val_copy(other) @@ -219,7 +231,7 @@ class Value: __rmul__ = __mul__ - @_polymorphic + @_polymorphic_method def __truediv__(self, other): val1 = libisl.isl_val_copy(self) val2 = libisl.isl_val_copy(other) @@ -246,7 +258,7 @@ class Value: return bool(libisl.isl_val_is_infty(self) or libisl.isl_val_is_neginfty(self)) - def is_nan(self): + def is_nan(self): return bool(libisl.isl_val_is_nan(self)) def __str__(self):