# Path: soap/expression/common.py
# def is_variable(e):
# def is_variable_tuple(e):
# def is_expression(e):
# def is_arith_expr(e):
# def is_bool_expr(e):
# def concat_multi_expr(*expr_args):
# def split_multi_expr(e):
# def expression_factory(op, *args):
#     def __init__(self, *arg, **kwargs):
#     def _set_default_method(self, name, value):
#     def generic_execute(self, expr, *args, **kwargs):
#     def _execute_atom(self, expr, *args, **kwargs):
#     def _execute_expression(self, expr, *args, **kwargs):
#     def _execute_mapping(self, meta_state, *args, **kwargs):
#     def generic_execute(self, expr):
#     def _execute_atom(self, expr):
#     def _execute_expression(self, expr):
#     def execute_tuple(self, expr):
#     def execute_numeral(self, expr):
#     def execute_FixExpr(self, expr):
#     def generic_execute(self, expr):
#     def _execute_atom(self, expr):
#     def _execute_expression(self, expr):
#     def execute_FixExpr(self, expr):
#     def _execute_mapping(self, expr):
# def fix_expr_has_inner_loop(expr):
# class GenericExecuter(base_dispatcher()):
# class VariableSetGenerator(GenericExecuter):
# class HasInnerLoop(GenericExecuter):
# 
# Path: soap/expression/linalg.py
# class Subscript(Expression):
#     __slots__ = ()
#     _str_brackets = False
# 
#     def __init__(self, *subscript):
#         super().__init__(SUBSCRIPT_OP, *subscript)
# 
#     def __iter__(self):
#         return iter(self.args)
# 
#     def format(self):
#         return ''.join('[' + a.format() + ']' for a in self.args)
# 
#     def __repr__(self):
#         return '{}({!r})'.format(self.__class__.__name__, self.args)
# 
# class AccessExpr(
#         ArithmeticMixin, BooleanMixin, BinaryExpression, _TrueVarMixin):
#     __slots__ = ()
#     _str_brackets = False
# 
#     def __init__(self, var, subscript):
#         from soap.semantics.label import Label
#         if not isinstance(subscript, Label):
#             subscript = Subscript(*subscript)
#         super().__init__(INDEX_ACCESS_OP, var, subscript)
# 
#     @property
#     def var(self):
#         return self.a1
# 
#     @property
#     def subscript(self):
#         return self.a2
# 
#     def format(self):
#         var, subscript = self._args_to_str()
#         return '{}{}'.format(var, subscript)
# 
#     def __repr__(self):
#         return '{cls}({var!r}, {subscript!r})'.format(
#             cls=self.__class__.__name__, var=self.var,
#             subscript=self.subscript)
# 
# class UpdateExpr(
#         ArithmeticMixin, BooleanMixin, TernaryExpression, _TrueVarMixin):
#     __slots__ = ()
#     _str_brackets = False
# 
#     def __init__(self, var, subscript, expr):
#         from soap.semantics.label import Label
#         if not isinstance(subscript, Label):
#             subscript = Subscript(*subscript)
#         super().__init__(INDEX_UPDATE_OP, var, subscript, expr)
# 
#     @property
#     def var(self):
#         return self.a1
# 
#     @property
#     def subscript(self):
#         return self.a2
# 
#     @property
#     def expr(self):
#         return self.a3
# 
#     def format(self):
#         var, subscript, expr = (a.format() for a in self.args)
#         args = '{}, \n{}, \n{}'.format(var, subscript, expr)
#         return 'update(\n{})'.format(indent(args))
# 
#     def __repr__(self):
#         return '{cls}({var!r}, {subscript!r}, {expr!r})'.format(
#             cls=self.__class__.__name__, var=self.var,
#             subscript=self.subscript, expr=self.expr)


import itertools
import islpy
from soap.expression import (
    expression_factory, expression_variables, AccessExpr, UpdateExpr,
    Subscript, GenericExecuter
)
        return expr.__class__({
            var: self(var_expr) for var, var_expr in expr.items()})


class IndexCollector(GenericExecuter):
    def _execute_atom(self, expr, indices):
        return indices

    execute_PartitionLabel = execute_PreUnrollExpr = _execute_atom

    def _execute_expression(self, expr, indices):
        for arg in expr.args:
            indices = self(arg, indices)
        return indices

    def execute_Subscript(self, expr, indices):
        for index in expr.args:
            indices.add(index)
        return indices

    def _execute_mapping(self, expr, indices):
        for var_expr in expr.values():
            indices = self(var_expr, indices)
        return indices

    def __call__(self, expr, indices=None):
        indices = indices or set()
        return super().__call__(expr, indices)



# Path: soap/expression/common.py
# def is_variable(e):
# def is_variable_tuple(e):
# def is_expression(e):
# def is_arith_expr(e):
# def is_bool_expr(e):
# def concat_multi_expr(*expr_args):
# def split_multi_expr(e):
# def expression_factory(op, *args):
#     def __init__(self, *arg, **kwargs):
#     def _set_default_method(self, name, value):
#     def generic_execute(self, expr, *args, **kwargs):
#     def _execute_atom(self, expr, *args, **kwargs):
#     def _execute_expression(self, expr, *args, **kwargs):
#     def _execute_mapping(self, meta_state, *args, **kwargs):
#     def generic_execute(self, expr):
#     def _execute_atom(self, expr):
#     def _execute_expression(self, expr):
#     def execute_tuple(self, expr):
#     def execute_numeral(self, expr):
#     def execute_FixExpr(self, expr):
#     def generic_execute(self, expr):
#     def _execute_atom(self, expr):
#     def _execute_expression(self, expr):
#     def execute_FixExpr(self, expr):
#     def _execute_mapping(self, expr):
# def fix_expr_has_inner_loop(expr):
# class GenericExecuter(base_dispatcher()):
# class VariableSetGenerator(GenericExecuter):
# class HasInnerLoop(GenericExecuter):
# 
# Path: soap/expression/linalg.py
# class Subscript(Expression):
#     __slots__ = ()
#     _str_brackets = False
# 
#     def __init__(self, *subscript):
#         super().__init__(SUBSCRIPT_OP, *subscript)
# 
#     def __iter__(self):
#         return iter(self.args)
# 
#     def format(self):
#         return ''.join('[' + a.format() + ']' for a in self.args)
# 
#     def __repr__(self):
#         return '{}({!r})'.format(self.__class__.__name__, self.args)
# 
# class AccessExpr(
#         ArithmeticMixin, BooleanMixin, BinaryExpression, _TrueVarMixin):
#     __slots__ = ()
#     _str_brackets = False
# 
#     def __init__(self, var, subscript):
#         from soap.semantics.label import Label
#         if not isinstance(subscript, Label):
#             subscript = Subscript(*subscript)
#         super().__init__(INDEX_ACCESS_OP, var, subscript)
# 
#     @property
#     def var(self):
#         return self.a1
# 
#     @property
#     def subscript(self):
#         return self.a2
# 
#     def format(self):
#         var, subscript = self._args_to_str()
#         return '{}{}'.format(var, subscript)
# 
#     def __repr__(self):
#         return '{cls}({var!r}, {subscript!r})'.format(
#             cls=self.__class__.__name__, var=self.var,
#             subscript=self.subscript)
# 
# class UpdateExpr(
#         ArithmeticMixin, BooleanMixin, TernaryExpression, _TrueVarMixin):
#     __slots__ = ()
#     _str_brackets = False
# 
#     def __init__(self, var, subscript, expr):
#         from soap.semantics.label import Label
#         if not isinstance(subscript, Label):
#             subscript = Subscript(*subscript)
#         super().__init__(INDEX_UPDATE_OP, var, subscript, expr)
# 
#     @property
#     def var(self):
#         return self.a1
# 
#     @property
#     def subscript(self):
#         return self.a2
# 
#     @property
#     def expr(self):
#         return self.a3
# 
#     def format(self):
#         var, subscript, expr = (a.format() for a in self.args)
#         args = '{}, \n{}, \n{}'.format(var, subscript, expr)
#         return 'update(\n{})'.format(indent(args))
# 
#     def __repr__(self):
#         return '{cls}({var!r}, {subscript!r}, {expr!r})'.format(
#             cls=self.__class__.__name__, var=self.var,
#             subscript=self.subscript, expr=self.expr)


# Path: soap/transformer/linalg.py
import itertools
import islpy
from soap.expression import (
    expression_factory, expression_variables, AccessExpr, UpdateExpr,
    Subscript, GenericExecuter
)

        return expr.__class__({
            var: self(var_expr) for var, var_expr in expr.items()})


class IndexCollector(GenericExecuter):
    def _execute_atom(self, expr, indices):
        return indices

    execute_PartitionLabel = execute_PreUnrollExpr = _execute_atom

    def _execute_expression(self, expr, indices):
        for arg in expr.args:
            indices = self(arg, indices)
        return indices

    def execute_Subscript(self, expr, indices):
        for index in expr.args:
            indices.add(index)
        return indices

    def _execute_mapping(self, expr, indices):
        for var_expr in expr.values():
            indices = self(var_expr, indices)
        return indices

    def __call__(self, expr, indices=None):
        indices = indices or set()
        return super().__call__(expr, indices)



class SubscriptSimplifier(GenericExecuter):