X-Git-Url: https://scm.cri.ensmp.fr/git/linpy.git/blobdiff_plain/dedaed504aab41867667bb154b9eabfb7af0e881..b96bc9c75fe5a692898435e8fb12fda27566b1aa:/pypol/linear.py diff --git a/pypol/linear.py b/pypol/linear.py index 2e48a31..3939c71 100644 --- a/pypol/linear.py +++ b/pypol/linear.py @@ -1,4 +1,3 @@ -import ctypes, ctypes.util import functools import numbers @@ -12,7 +11,7 @@ __all__ = [ 'Expression', 'Constant', 'Symbol', 'symbols', 'eq', 'le', 'lt', 'ge', 'gt', 'Polyhedron', - 'empty', 'universe' + 'Empty', 'Universe' ] @@ -70,7 +69,7 @@ class Expression: self._coefficients = {} for symbol, coefficient in coefficients: if isinstance(symbol, Symbol): - symbol = str(symbol) + symbol = symbol.name elif not isinstance(symbol, str): raise TypeError('symbols must be strings or Symbol instances') if isinstance(coefficient, Constant): @@ -127,10 +126,6 @@ class Expression: yield self.coefficient(symbol) yield self.constant - @property - def symbol(self): - raise ValueError('not a symbol: {}'.format(self)) - def issymbol(self): return False @@ -331,26 +326,26 @@ class Symbol(Expression): def __new__(cls, name): if isinstance(name, Symbol): - name = name.symbol + name = name.name elif not isinstance(name, str): raise TypeError('name must be a string or a Symbol instance') self = object().__new__(cls) self._coefficients = {name: 1} self._constant = 0 self._symbols = tuple(name) - self._symbol = name + self._name = name self._dimension = 1 return self @property - def symbol(self): - return self._symbol + def name(self): + return self._name def issymbol(self): return True def __repr__(self): - return '{}({!r})'.format(self.__class__.__name__, self._symbol) + return '{}({!r})'.format(self.__class__.__name__, self._name) def symbols(names): if isinstance(names, str): @@ -528,7 +523,6 @@ class Polyhedron: other = other._toisl(symbols) difference = libisl.isl_set_subtract(bset, other) return difference - def __sub__(self, other): return self.difference(other) @@ -542,10 +536,15 @@ class Polyhedron: return '{{{}}}'.format(', '.join(constraints)) def __repr__(self): - equalities = list(self.equalities) - inequalities = list(self.inequalities) - return '{}(equalities={!r}, inequalities={!r})' \ - ''.format(self.__class__.__name__, equalities, inequalities) + if self.isempty(): + return 'Empty' + elif self.isuniverse(): + return 'Universe' + else: + equalities = list(self.equalities) + inequalities = list(self.inequalities) + return '{}(equalities={!r}, inequalities={!r})' \ + ''.format(self.__class__.__name__, equalities, inequalities) def _symbolunion(self, *others): symbols = set(self.symbols) @@ -556,37 +555,34 @@ class Polyhedron: def _toisl(self, symbols=None): if symbols is None: symbols = self.symbols - num_coefficients = len(symbols) - space = libisl.isl_space_set_alloc(_main_ctx, 0, num_coefficients) + dimension = len(symbols) + space = libisl.isl_space_set_alloc(_main_ctx, 0, dimension) bset = libisl.isl_basic_set_universe(libisl.isl_space_copy(space)) ls = libisl.isl_local_space_from_space(space) - #if there are equalities/inequalities, take each constant and coefficient and add as a constraint to the basic set - for eq in self.equalities: + for equality in self.equalities: ceq = libisl.isl_equality_alloc(libisl.isl_local_space_copy(ls)) - coeff_eq = dict(eq.coefficients()) - if eq.constant: - value = str(eq.constant).encode() - val = libisl.isl_val_read_from_str(_main_ctx, value) + for symbol, coefficient in equality.coefficients(): + val = str(coefficient).encode() + val = libisl.isl_val_read_from_str(_main_ctx, val) + dim = symbols.index(symbol) + ceq = libisl.isl_constraint_set_coefficient_val(ceq, libisl.isl_dim_set, dim, val) + if equality.constant != 0: + val = str(equality.constant).encode() + val = libisl.isl_val_read_from_str(_main_ctx, val) ceq = libisl.isl_constraint_set_constant_val(ceq, val) - for eq in coeff_eq: - number = str(coeff_eq.get(eq)).encode() - num = libisl.isl_val_read_from_str(_main_ctx, number) - iden = symbols.index(eq) - ceq = libisl.isl_constraint_set_coefficient_val(ceq, libisl.isl_dim_set, iden, num) #use 3 for type isl_dim_set - bset = libisl.isl_basic_set_add_constraint(bset, ceq) - for ineq in self.inequalities: + bset = libisl.isl_basic_set_add_constraint(bset, ceq) + for inequality in self.inequalities: cin = libisl.isl_inequality_alloc(libisl.isl_local_space_copy(ls)) - coeff_in = dict(ineq.coefficients()) - if ineq.constant: - value = str(ineq.constant).encode() - val = libisl.isl_val_read_from_str(_main_ctx, value) + for symbol, coefficient in inequality.coefficients(): + val = str(coefficient).encode() + val = libisl.isl_val_read_from_str(_main_ctx, val) + dim = symbols.index(symbol) + cin = libisl.isl_constraint_set_coefficient_val(cin, libisl.isl_dim_set, dim, val) + if inequality.constant != 0: + val = str(ineq.constant).encode() + val = libisl.isl_val_read_from_str(_main_ctx, val) cin = libisl.isl_constraint_set_constant_val(cin, val) - for ineq in coeff_in: - number = str(coeff_in.get(ineq)).encode() - num = libisl.isl_val_read_from_str(_main_ctx, number) - iden = symbols.index(ineq) - cin = libisl.isl_constraint_set_coefficient_val(cin, libisl.isl_dim_set, iden, num) #use 3 for type isl_dim_set - bset = libisl.isl_basic_set_add_constraint(bset, cin) + bset = libisl.isl_basic_set_add_constraint(bset, cin) bset = isl.BasicSet(bset) return bset @@ -602,12 +598,13 @@ class Polyhedron: our printer is giving form as: { [i0, i1] : 2i1 >= -2 - i0 } ''' -empty = None #eq(0,1) -universe = None #Polyhedron() +Empty = eq(0,1) +Universe = Polyhedron() if __name__ == '__main__': - ex1 = Expression(coefficients={'a': 6, 'b': 6}, constant= 3) #this is the expression that does not work (even without adding values) - ex2 = Expression(coefficients={'x': 4, 'y': 2}, constant= 3) - p = Polyhedron(equalities=[ex2]) - p2 = Polyhedron(equalities=[ex2]) - print(p._toisl()) # checking is values works for toisl + e1 = Expression(coefficients={'a': 2, 'b': 2}, constant= 1) + p1 = Polyhedron(equalities=[e1]) # empty + e2 = Expression(coefficients={'x': 3, 'y': 2}, constant= 3) + p2 = Polyhedron(equalities=[e2]) # not empty + print(p1._toisl()) + print(p2._toisl())