X-Git-Url: https://svn.cri.ensmp.fr/git/linpy.git/blobdiff_plain/98d00e8b628b571e133bcfa494c0e8f0ab781234..6120eb04e9422574814570d653e6ac19b057727f:/pypol/linear.py?ds=sidebyside diff --git a/pypol/linear.py b/pypol/linear.py index fabf2a2..d1aa882 100644 --- a/pypol/linear.py +++ b/pypol/linear.py @@ -1,9 +1,17 @@ +''' +VERY MESSY, made notes on where I will change things +''' import functools import numbers +import ctypes, ctypes.util +from pypol import isl from fractions import Fraction, gcd +libisl = ctypes.CDLL(ctypes.util.find_library('isl')) + +libisl.isl_printer_get_str.restype = ctypes.c_char_p __all__ = [ 'Expression', @@ -14,6 +22,8 @@ __all__ = [ ] +_CONTEXT = isl.Context() + def _polymorphic_method(func): @functools.wraps(func) def wrapper(a, b): @@ -26,13 +36,14 @@ def _polymorphic_method(func): return wrapper def _polymorphic_operator(func): + # A polymorphic operator should call a polymorphic method, hence we just + # have to test the left operand. @functools.wraps(func) def wrapper(a, b): if isinstance(a, numbers.Rational): a = constant(a) - if isinstance(b, numbers.Rational): - b = constant(b) - if isinstance(a, Expression) and isinstance(b, Expression): + return func(a, b) + elif isinstance(a, Expression): return func(a, b) raise TypeError('arguments must be linear expressions') return wrapper @@ -67,6 +78,7 @@ class Expression: self._constant = constant return self + def symbols(self): yield from sorted(self._coefficients) @@ -102,6 +114,12 @@ class Expression: yield self.coefficient(symbol) yield self.constant + def values_int(self): + for symbol in self.symbols(): + return self.coefficient(symbol) + return int(self.constant) + + def symbol(self): if not self.issymbol(): raise ValueError('not a symbol: {}'.format(self)) @@ -176,7 +194,7 @@ class Expression: return NotImplemented def __rtruediv__(self, other): - if isinstance(other, Rational): + if isinstance(other, self): if self.isconstant(): constant = Fraction(other, self.constant) return Expression(constant=constant) @@ -344,9 +362,14 @@ class Polyhedron: if value.denominator != 1: raise TypeError('non-integer constraint: ' '{} <= 0'.format(constraint)) - self._inequalities.append(constraint) - return self - + self._inequalities.append(constraint) + print('in polyhedron') + #print(self.constraints()) + self._bset = self.to_isl() + #print(self._bset) + return self + + @property def equalities(self): yield from self._equalities @@ -354,24 +377,46 @@ class Polyhedron: @property def inequalities(self): yield from self._inequalities + + @property + def constant(self): + return self._constant + + def isconstant(self): + return len(self._coefficients) == 0 + + + def isempty(self): + return bool(libisl.isl_basic_set_is_empty(self._bset)) def constraints(self): yield from self.equalities yield from self.inequalities + def symbols(self): s = set() for constraint in self.constraints(): s.update(constraint.symbols) - yield from sorted(s) - + yield from sorted(s) + + def symbol_count(self): + s = [] + for constraint in self.constraints(): + s.append(constraint.symbols) + return s + @property def dimension(self): return len(self.symbols()) def __bool__(self): # return false if the polyhedron is empty, true otherwise - raise NotImplementedError + if self._equalities or self._inequalities: + return False + else: + return True + def __contains__(self, value): # is the value in the polyhedron? @@ -380,8 +425,8 @@ class Polyhedron: def __eq__(self, other): raise NotImplementedError - def isempty(self): - return self == empty + def is_empty(self): + return def isuniverse(self): return self == universe @@ -401,6 +446,11 @@ class Polyhedron: def issuperset(self, other): # test whether every element in other is in the polyhedron + for value in other: + if value == self.constraints(): + return True + else: + return False raise NotImplementedError def __ge__(self, other): @@ -457,8 +507,36 @@ class Polyhedron: @classmethod def fromstring(cls, string): raise NotImplementedError + + def to_isl(self): + space = libisl.isl_space_set_alloc(_CONTEXT, 0, len(self.symbol_count())) + bset = libisl.isl_basic_set_universe(libisl.isl_space_copy(space)) + copy = libisl.isl_basic_set_copy(bset) + ls = libisl.isl_local_space_from_space(libisl.isl_space_copy(space)) + ceq = libisl.isl_equality_alloc(libisl.isl_local_space_copy(ls)) + for value in self.equalities: + for value in self.equalities: + #need method to get expression value + if self._equalities: + value = self._equalities.method_get_value_from_expression() + ceq = libisl.isl_constraint_set_constant_val(ceq, value ) + #ceq = libisl.isl_constraint_set_coefficient_si(ceq, libisl.isl_set_dim, self.symbols(), value) + ''' + cin = libisl.isl_inequality_alloc(libisl.isl_local_space_copy(ls)) + for item in self.inequalities: + for item in self.inequalities: + if isinstance(item, int): + cin = libisl.isl_constraint_set_constant_si(cin, item) + else: + cin = libisl.isl_constraint_set_coefficient_si(cin, libisl.isl_set_dim, self.symbols(), item) + ''' + bsetfinal = libisl.isl_basic_set_add_contraint(copy, ceq) + #bsetfinal = libisl.isl_basic_set_add_contraint(copy, cin) + string = libisl.isl_printer_print_basic_set(bsetfinal) + print(string) + return self +empty = eq(1, 1) -empty = le(1, 0) universe = Polyhedron()