# Path: soap/datatype.py
# class TypeBase(object):
# class AutoType(TypeBase):
# class BoolType(TypeBase):
# class IntType(TypeBase):
# class FloatingPointType(TypeBase):
# class FloatType(FloatingPointType):
# class DoubleType(FloatingPointType):
# class FunctionType(TypeBase):
# class ArrayType(TypeBase):
# class IntegerArrayType(ArrayType):
# class FloatArrayType(ArrayType):
#     def __repr__(self):
#     def __eq__(self, other):
#     def __hash__(self):
#     def __str__(self):
#     def __str__(self):
#     def __str__(self):
#     def __str__(self):
#     def __str__(self):
#     def __str__(self):
#     def __str__(self):
#     def __init__(self, shape):
#     def __str__(self):
#     def __eq__(self, other):
#     def __hash__(self):
# def type_of(value):
# def type_cast(dtype, value=None, top=False, bottom=False):
# 
# Path: soap/expression/arithmetic.py
# class ArithmeticMixin(object):
# 
#     def __add__(self, other):
#         return BinaryArithExpr(ADD_OP, self, other)
# 
#     def __sub__(self, other):
#         return BinaryArithExpr(SUBTRACT_OP, self, other)
# 
#     def __mul__(self, other):
#         return BinaryArithExpr(MULTIPLY_OP, self, other)
# 
#     def __div__(self, other):
#         return BinaryArithExpr(DIVIDE_OP, self, other)
# 
#     def __neg__(self):
#         return UnaryArithExpr(UNARY_SUBTRACT_OP, self)
# 
# Path: soap/expression/base.py
# class Expression(Flyweight):
#     """A base class for expressions."""
# 
#     __slots__ = ('_op', '_args', '_hash')
#     _str_brackets = True
# 
#     def __init__(self, op, *args):
#         super().__init__()
#         if not args and not all(args):
#             raise ValueError('There is no arguments.')
#         self._op = op
#         self._args = args
#         self._hash = None
# 
#     def __setstate__(self, state):
#         self._hash = None
#         state = state[1]
#         self._op = state['_op']
#         self._args = state['_args']
# 
#     @property
#     def op(self):
#         return self._op
# 
#     @property
#     def args(self):
#         return self._args
# 
#     @property
#     def arity(self):
#         return len(self.args)
# 
#     def vars(self):
#         return expression_variables(self)
# 
#     def _args_to_str(self):
#         def format(expr):
#             if is_numeral(expr):
#                 brackets = False
#             else:
#                 brackets = getattr(expr, '_str_brackets', True)
#             if is_expression(expr):
#                 expr = expr.format()
#             text = '({})' if brackets else '{}'
#             return text.format(expr)
#         return [format(a) for a in self.args]
# 
#     def __repr__(self):
#         args = ', '.join('a{}={!r}'.format(i + 1, a)
#                          for i, a in enumerate(self.args))
#         return "{name}(op={op!r}, {args})".format(
#             name=self.__class__.__name__, op=self.op, args=args)
# 
#     def format(self):
#         raise NotImplementedError(
#             'Override this method for {}'.format(self.__class__))
# 
#     def __str__(self):
#         return self.format().replace('    ', '').replace('\n', '').strip()
# 
#     def _attr(self):
#         return (self.op, self.args)
# 
#     def __eq__(self, other):
#         if not isinstance(other, Expression):
#             return False
#         if id(self) == id(other):
#             return True
#         if type(self) is not type(other) or hash(self) != hash(other):
#             return False
#         return self._attr() == other._attr()
# 
#     def __ne__(self, other):
#         return not self == other
# 
#     def __hash__(self):
#         if self._hash:
#             return self._hash
#         self._hash = hash(self._attr())
#         return self._hash
# 
# class BinaryExpression(Expression):
#     """A binary expression class. Instance has two arguments."""
# 
#     __slots__ = ()
# 
#     def __init__(self, op, a1, a2):
#         super().__init__(op, a1, a2)
# 
#     @property
#     def a1(self):
#         return self.args[0]
# 
#     @property
#     def a2(self):
#         return self.args[1]
# 
#     def format(self):
#         a1, a2 = self._args_to_str()
#         return '{a1} {op} {a2}'.format(op=self.op, a1=a1, a2=a2)
# 
# Path: soap/expression/boolean.py
# class BooleanMixin(object):
# 
#     def __invert__(self):
#         return UnaryBoolExpr(operators.UNARY_NEGATION_OP, self)
# 
#     def __and__(self, other):
#         return BinaryBoolExpr(operators.AND_OP, self, other)
# 
#     def __or__(self, other):
#         return BinaryBoolExpr(operators.OR_OP, self, other)
# 
# Path: soap/expression/operators.py
# EXTERNAL_OP = 'extern'
# 
# VARIABLE_OP = 'v'


import collections
from soap.datatype import auto_type
from soap.expression.arithmetic import ArithmeticMixin
from soap.expression.base import Expression, BinaryExpression
from soap.expression.boolean import BooleanMixin
from soap.expression.operators import EXTERNAL_OP, VARIABLE_OP
"""
.. module:: soap.expression.variable
    :synopsis: The class of variables.
"""



class Variable(ArithmeticMixin, BooleanMixin, BinaryExpression):
    """The variable class."""
    __slots__ = ()
    _str_brackets = False


# Path: soap/datatype.py
# class TypeBase(object):
# class AutoType(TypeBase):
# class BoolType(TypeBase):
# class IntType(TypeBase):
# class FloatingPointType(TypeBase):
# class FloatType(FloatingPointType):
# class DoubleType(FloatingPointType):
# class FunctionType(TypeBase):
# class ArrayType(TypeBase):
# class IntegerArrayType(ArrayType):
# class FloatArrayType(ArrayType):
#     def __repr__(self):
#     def __eq__(self, other):
#     def __hash__(self):
#     def __str__(self):
#     def __str__(self):
#     def __str__(self):
#     def __str__(self):
#     def __str__(self):
#     def __str__(self):
#     def __str__(self):
#     def __init__(self, shape):
#     def __str__(self):
#     def __eq__(self, other):
#     def __hash__(self):
# def type_of(value):
# def type_cast(dtype, value=None, top=False, bottom=False):
# 
# Path: soap/expression/arithmetic.py
# class ArithmeticMixin(object):
# 
#     def __add__(self, other):
#         return BinaryArithExpr(ADD_OP, self, other)
# 
#     def __sub__(self, other):
#         return BinaryArithExpr(SUBTRACT_OP, self, other)
# 
#     def __mul__(self, other):
#         return BinaryArithExpr(MULTIPLY_OP, self, other)
# 
#     def __div__(self, other):
#         return BinaryArithExpr(DIVIDE_OP, self, other)
# 
#     def __neg__(self):
#         return UnaryArithExpr(UNARY_SUBTRACT_OP, self)
# 
# Path: soap/expression/base.py
# class Expression(Flyweight):
#     """A base class for expressions."""
# 
#     __slots__ = ('_op', '_args', '_hash')
#     _str_brackets = True
# 
#     def __init__(self, op, *args):
#         super().__init__()
#         if not args and not all(args):
#             raise ValueError('There is no arguments.')
#         self._op = op
#         self._args = args
#         self._hash = None
# 
#     def __setstate__(self, state):
#         self._hash = None
#         state = state[1]
#         self._op = state['_op']
#         self._args = state['_args']
# 
#     @property
#     def op(self):
#         return self._op
# 
#     @property
#     def args(self):
#         return self._args
# 
#     @property
#     def arity(self):
#         return len(self.args)
# 
#     def vars(self):
#         return expression_variables(self)
# 
#     def _args_to_str(self):
#         def format(expr):
#             if is_numeral(expr):
#                 brackets = False
#             else:
#                 brackets = getattr(expr, '_str_brackets', True)
#             if is_expression(expr):
#                 expr = expr.format()
#             text = '({})' if brackets else '{}'
#             return text.format(expr)
#         return [format(a) for a in self.args]
# 
#     def __repr__(self):
#         args = ', '.join('a{}={!r}'.format(i + 1, a)
#                          for i, a in enumerate(self.args))
#         return "{name}(op={op!r}, {args})".format(
#             name=self.__class__.__name__, op=self.op, args=args)
# 
#     def format(self):
#         raise NotImplementedError(
#             'Override this method for {}'.format(self.__class__))
# 
#     def __str__(self):
#         return self.format().replace('    ', '').replace('\n', '').strip()
# 
#     def _attr(self):
#         return (self.op, self.args)
# 
#     def __eq__(self, other):
#         if not isinstance(other, Expression):
#             return False
#         if id(self) == id(other):
#             return True
#         if type(self) is not type(other) or hash(self) != hash(other):
#             return False
#         return self._attr() == other._attr()
# 
#     def __ne__(self, other):
#         return not self == other
# 
#     def __hash__(self):
#         if self._hash:
#             return self._hash
#         self._hash = hash(self._attr())
#         return self._hash
# 
# class BinaryExpression(Expression):
#     """A binary expression class. Instance has two arguments."""
# 
#     __slots__ = ()
# 
#     def __init__(self, op, a1, a2):
#         super().__init__(op, a1, a2)
# 
#     @property
#     def a1(self):
#         return self.args[0]
# 
#     @property
#     def a2(self):
#         return self.args[1]
# 
#     def format(self):
#         a1, a2 = self._args_to_str()
#         return '{a1} {op} {a2}'.format(op=self.op, a1=a1, a2=a2)
# 
# Path: soap/expression/boolean.py
# class BooleanMixin(object):
# 
#     def __invert__(self):
#         return UnaryBoolExpr(operators.UNARY_NEGATION_OP, self)
# 
#     def __and__(self, other):
#         return BinaryBoolExpr(operators.AND_OP, self, other)
# 
#     def __or__(self, other):
#         return BinaryBoolExpr(operators.OR_OP, self, other)
# 
# Path: soap/expression/operators.py
# EXTERNAL_OP = 'extern'
# 
# VARIABLE_OP = 'v'


# Path: soap/expression/variable.py
import collections
from soap.datatype import auto_type
from soap.expression.arithmetic import ArithmeticMixin
from soap.expression.base import Expression, BinaryExpression
from soap.expression.boolean import BooleanMixin
from soap.expression.operators import EXTERNAL_OP, VARIABLE_OP

"""
.. module:: soap.expression.variable
    :synopsis: The class of variables.
"""



class Variable(ArithmeticMixin, BooleanMixin, BinaryExpression):
    """The variable class."""
    __slots__ = ()
    _str_brackets = False


    def __init__(self, name, dtype=auto_type):