X-Git-Url: https://scm.cri.ensmp.fr/git/linpy.git/blobdiff_plain/966727e8d6a1bcbb27dfb1586daa233b006b4fca..f431ff9e62582cf7a4f12d17fb198c2fdaf47044:/pypol/linear.py diff --git a/pypol/linear.py b/pypol/linear.py index de6f4ca..be30fad 100644 --- a/pypol/linear.py +++ b/pypol/linear.py @@ -1,7 +1,8 @@ import functools import numbers +import json import ctypes, ctypes.util -from pypol import isl +from pypol import isl, islhelper from fractions import Fraction, gcd @@ -17,8 +18,28 @@ __all__ = [ 'empty', 'universe' ] - -_CONTEXT = isl.Context() +''' +def symbolToInt(self): + make dictionary of key:value (letter:integer) + iterate through the dictionary to find matching symbol + return the given integer value + d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6, 'g': 7, 'h': 8, 'i': 6, 'j': 10, 'k': 11, 'l': 12, 'm': 13, 'n': 14, + 'o': 15, 'p': 16, 'q': 17, 'r': 18, 's': 19, 't': 20, 'u': 21, 'v': 22, 'w': 23, 'x': 24, 'y': 25, 'z': 26} + if self in d: + num = d.get(self) + return num +''' + +ids = {} + +def get_ids(co): + if co in ids: + return ids.get(co) + else: + idd = len(ids) + ids[co] = idd + print(ids) + return idd def _polymorphic_method(func): @functools.wraps(func) @@ -44,6 +65,28 @@ def _polymorphic_operator(func): raise TypeError('arguments must be linear expressions') return wrapper +class Context: + + __slots__ = ('_ic') + + def __init__(self): + self._ic = libisl.isl_ctx_alloc() + + @property + def _as_parameter_(self): + return self._ic + + #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): + return False + return self._ic == other._ic + + + class Expression: """ @@ -158,7 +201,8 @@ class Expression: constant = self.constant - other.constant return Expression(coefficients, constant) - __rsub__ = __sub__ + def __rsub__(self, other): + return -(self - other) @_polymorphic_method def __mul__(self, other): @@ -296,7 +340,7 @@ class Expression: def constant(numerator=0, denominator=None): if denominator is None and isinstance(numerator, numbers.Rational): - return Expression(constant=numerator) + return Expression(constant=3) else: return Expression(constant=Fraction(numerator, denominator)) @@ -358,11 +402,16 @@ class Polyhedron: if value.denominator != 1: raise TypeError('non-integer constraint: ' '{} <= 0'.format(constraint)) - self._inequalities.append(constraint) + self._inequalities.append(constraint) self._bset = self.to_isl() - return self._bset - - + #print(self._bset) + #put this here just to test from isl method + #from_isl = self.from_isl(self._bset) + #print(from_isl) + #rint(self) + return self._bset + + @property def equalities(self): yield from self._equalities @@ -370,15 +419,15 @@ 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)) @@ -392,13 +441,7 @@ class Polyhedron: for constraint in self.constraints(): s.update(constraint.symbols) 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()) @@ -409,7 +452,7 @@ class Polyhedron: return False else: return True - + def __contains__(self, value): # is the value in the polyhedron? @@ -441,9 +484,9 @@ class Polyhedron: # test whether every element in other is in the polyhedron for value in other: if value == self.constraints(): - return True + return True else: - return False + return False raise NotImplementedError def __ge__(self, other): @@ -500,56 +543,58 @@ class Polyhedron: @classmethod def fromstring(cls, string): raise NotImplementedError - - def printer(self): - - ip = libisl.isl_printer_to_str(_CONTEXT) - ip = libisl.isl_printer_print_val(ip, self) #self should be value - string = libisl.isl_printer_get_str(ip).decode() - print(string) - return string - - + def to_isl(self): - space = libisl.isl_space_set_alloc(_CONTEXT, 0, len(self.symbol_count())) + #d = Expression().__dict__ #write expression values to dictionary in form {'_constant': value, '_coefficients': value} + d = {'_constant': 2, '_coefficients': {'b':1}} + coeff = d.get('_coefficients') + num_coefficients = len(coeff) + space = libisl.isl_space_set_alloc(Context(), 0, num_coefficients) bset = libisl.isl_basic_set_empty(libisl.isl_space_copy(space)) ls = libisl.isl_local_space_from_space(libisl.isl_space_copy(space)) ceq = libisl.isl_equality_alloc(libisl.isl_local_space_copy(ls)) cin = libisl.isl_inequality_alloc(libisl.isl_local_space_copy(ls)) - dict_ex = Expression().__dict__ - print(dict_ex) - ''' - if there are equalities/inequalities, take each constant and coefficient and add as a constraint to the basic set - need to change the symbols method to a lookup table for the integer value for each letter that could be a symbol - ''' - if self.equalities: - for _constant in dict_ex: - value = dict_ex.get('_constant') - ceq = libisl.isl_constraint_set_constant_val(ceq, value) - for _coefficients in dict_ex: - value_co = dict_ex.get('_coefficients') - if value_co: - ceq = libisl.isl_constraint_set_coefficient_si(ceq, libisl.isl_set_dim, self.symbols(), value_co) - bset = libisl.isl_set_add_constraint(bset, ceq) - bset = libisl.isl_basic_set_project_out(bset, libisl.isl_set_dim, 1, 1); - elif self.inequalities: - for _constant in dict_ex: - value = dict_ex.get('_constant') - cin = libisl.isl_constraint_set_constant_val(cin, value) - for _coefficients in dict_ex: - value_co = dict_ex.get('_coefficients') - if value_co: - cin = libisl.isl_constraint_set_coefficient_si(cin, libisl.isl_set_dim, self.symbols(), value_co) - bset = libisl.isl_set_add_contraint(bset, cin) - - string = libisl.isl_printer_print_basic_set(bset) - print('here') - print(bset) - print(self) - #print(string) - return bset - -empty = eq(1, 1) + '''if there are equalities/inequalities, take each constant and coefficient and add as a constraint to the basic set + need to change the symbols method to a lookup table for the integer value for each letter that could be a symbol''' + if self._equalities: + if '_constant' in d: + value = d.get('_constant') + ceq = libisl.isl_constraint_set_constant_si(ceq, value) + if '_coefficients' in d: + value_co = d.get('_coefficients') + for co in value_co: + num = value_co.get(co) + ceq = libisl.isl_constraint_set_coefficient_si(ceq, islhelper.isl_dim_set, get_ids(co), num) + bset = libisl.isl_set_add_constraint(bset, ceq) + + if self._inequalities: + if '_constant' in d: + value = d.get('_constant') + cin = libisl.isl_constraint_set_constant_si(cin, value) + if '_coefficients' in d: + value_co = d.get('_coefficients') + for co in value_co: + num = value_co.get(co) + if value_co: #if dictionary not empty add coefficient as to constraint + cin = libisl.isl_constraint_set_coefficient_si(cin, islhelper.isl_dim_set, get_ids(co), num) + bset = libisl.isl_set_add_constraint(bset, cin) + ip = libisl.isl_printer_to_str(Context()) #create string printer + ip = libisl.isl_printer_print_set(ip, bset) #print set to printer + string = libisl.isl_printer_get_str(ip) #get string from printer + string = str(string) + print(string) + return string + + + def from_isl(self, bset): + '''takes basic set in isl form and puts back into python version of polyhedron + isl example code gives idl form as: + "{[i] : exists (a : i = 2a and i >= 10 and i <= 42)}");''' + + poly = 0 + return poly + +empty = eq(1,1) universe = Polyhedron()