A polyhedral library based on ISL.
"""
-from .linexprs import Expression, Constant, Symbol, symbols
+from .linexprs import Expression, Symbol, symbols, Rational
from .polyhedra import Polyhedron, Eq, Ne, Le, Lt, Ge, Gt, Ne, Empty, Universe
from .domains import Domain, And, Or, Not
__all__ = [
- 'Expression', 'Constant', 'Symbol', 'symbols',
+ 'Expression', 'Symbol', 'symbols', 'Rational',
'Polyhedron', 'Eq', 'Ne', 'Le', 'Lt', 'Ge', 'Gt', 'Empty', 'Universe',
'Domain', 'And', 'Or', 'Not',
]
__all__ = [
'Expression',
'Symbol', 'symbols',
- 'Constant',
+ 'Rational',
]
if isinstance(right, Expression):
return func(left, right)
elif isinstance(right, numbers.Rational):
- right = Constant(right)
+ right = Rational(right)
return func(left, right)
return NotImplemented
return wrapper
raise TypeError('too many arguments')
return Expression.fromstring(coefficients)
if coefficients is None:
- return Constant(constant)
+ return Rational(constant)
if isinstance(coefficients, dict):
coefficients = coefficients.items()
for symbol, coefficient in coefficients:
coefficients = [(symbol, coefficient)
for symbol, coefficient in coefficients if coefficient != 0]
if len(coefficients) == 0:
- return Constant(constant)
+ return Rational(constant)
if len(coefficients) == 1 and constant == 0:
symbol, coefficient = coefficients[0]
if coefficient == 1:
self._coefficients = OrderedDict()
for symbol, coefficient in sorted(coefficients,
key=lambda item: item[0].name):
- if isinstance(coefficient, Constant):
+ if isinstance(coefficient, Rational):
coefficient = coefficient.constant
if not isinstance(coefficient, numbers.Rational):
raise TypeError('coefficients must be rational numbers '
- 'or Constant instances')
+ 'or Rational instances')
self._coefficients[symbol] = coefficient
- if isinstance(constant, Constant):
+ if isinstance(constant, Rational):
constant = constant.constant
if not isinstance(constant, numbers.Rational):
raise TypeError('constant must be a rational number '
- 'or a Constant instance')
+ 'or a Rational instance')
self._constant = constant
self._symbols = tuple(self._coefficients)
self._dimension = len(self._symbols)
@_polymorphic
def __add__(self, other):
- coefficients = defaultdict(Constant, self.coefficients())
+ coefficients = defaultdict(Rational, self.coefficients())
for symbol, coefficient in other.coefficients():
coefficients[symbol] += coefficient
constant = self.constant + other.constant
@_polymorphic
def __sub__(self, other):
- coefficients = defaultdict(Constant, self.coefficients())
+ coefficients = defaultdict(Rational, self.coefficients())
for symbol, coefficient in other.coefficients():
coefficients[symbol] -= coefficient
constant = self.constant - other.constant
if other.isconstant():
coefficients = dict(self.coefficients())
for symbol in coefficients:
- coefficients[symbol] = Constant(coefficients[symbol], other.constant)
- constant = Constant(self.constant, other.constant)
+ coefficients[symbol] = Rational(coefficients[symbol], other.constant)
+ constant = Rational(self.constant, other.constant)
return Expression(coefficients, constant)
if isinstance(other, Expression):
raise ValueError('non-linear expression: '
def __rtruediv__(self, other):
if isinstance(other, self):
if self.isconstant():
- return Constant(other, self.constant)
+ return Rational(other, self.constant)
else:
raise ValueError('non-linear expression: '
'{} / {}'.format(other._parenstr(), self._parenstr()))
elif isinstance(node, ast.Name):
return Symbol(node.id)
elif isinstance(node, ast.Num):
- return Constant(node.n)
+ return Rational(node.n)
elif isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub):
return -cls._fromast(node.operand)
elif isinstance(node, ast.BinOp):
return tuple(Symbol(name) for name in names)
-class Constant(Expression):
+class Rational(Expression):
__slots__ = (
'_constant',
def __new__(cls, numerator=0, denominator=None):
self = object().__new__(cls)
- if denominator is None and isinstance(numerator, Constant):
+ if denominator is None and isinstance(numerator, Rational):
self._constant = numerator.constant
else:
self._constant = Fraction(numerator, denominator)
@_polymorphic
def __eq__(self, other):
- return isinstance(other, Constant) and self.constant == other.constant
+ return isinstance(other, Rational) and self.constant == other.constant
def __bool__(self):
return self.constant != 0
def fromstring(cls, string):
if not isinstance(string, str):
raise TypeError('string must be a string instance')
- return Constant(Fraction(string))
+ return Rational(Fraction(string))
@classmethod
def fromsympy(cls, expr):
import sympy
if isinstance(expr, sympy.Rational):
- return Constant(expr.p, expr.q)
+ return Rational(expr.p, expr.q)
elif isinstance(expr, numbers.Rational):
- return Constant(expr)
+ return Rational(expr)
else:
raise TypeError('expr must be a sympy.Rational instance')
def test_new(self):
self.assertIsInstance(self.x, Symbol)
- self.assertIsInstance(self.pi, Constant)
+ self.assertIsInstance(self.pi, Rational)
self.assertNotIsInstance(self.x + self.pi, Symbol)
- self.assertNotIsInstance(self.x + self.pi, Constant)
+ self.assertNotIsInstance(self.x + self.pi, Rational)
xx = Expression({self.x: 2})
self.assertNotIsInstance(xx, Symbol)
with self.assertRaises(TypeError):
self.assertListEqual(list(symbols(['x', 'y'])), [self.x, self.y])
-class TestConstant(unittest.TestCase):
+class TestRational(unittest.TestCase):
def setUp(self):
- self.zero = Constant(0)
- self.one = Constant(1)
- self.pi = Constant(Fraction(22, 7))
+ self.zero = Rational(0)
+ self.one = Rational(1)
+ self.pi = Rational(Fraction(22, 7))
def test_new(self):
- self.assertEqual(Constant(), self.zero)
- self.assertEqual(Constant(1), self.one)
- self.assertEqual(Constant(self.pi), self.pi)
- self.assertEqual(Constant('22/7'), self.pi)
+ self.assertEqual(Rational(), self.zero)
+ self.assertEqual(Rational(1), self.one)
+ self.assertEqual(Rational(self.pi), self.pi)
+ self.assertEqual(Rational('22/7'), self.pi)
def test_isconstant(self):
self.assertTrue(self.zero.isconstant())
self.assertTrue(self.pi)
def test_fromstring(self):
- self.assertEqual(Constant.fromstring('22/7'), self.pi)
+ self.assertEqual(Rational.fromstring('22/7'), self.pi)
with self.assertRaises(ValueError):
- Constant.fromstring('a')
+ Rational.fromstring('a')
with self.assertRaises(TypeError):
- Constant.fromstring(1)
+ Rational.fromstring(1)
def test_repr(self):
self.assertEqual(repr(self.zero), '0')
@requires_sympy
def test_fromsympy(self):
import sympy
- self.assertEqual(Constant.fromsympy(sympy.Rational(22, 7)), self.pi)
+ self.assertEqual(Rational.fromsympy(sympy.Rational(22, 7)), self.pi)
with self.assertRaises(TypeError):
- Constant.fromsympy(sympy.Symbol('x'))
+ Rational.fromsympy(sympy.Symbol('x'))