# Buggy code
def _simplify(self, seen=None):
    """
    Simplify a promotion type tree:

        promote(int_, float_)
            -> float_

        promote(deferred(x), promote(float_, double), int_, promote(<self>))
            -> promote(deferred(x), double)

        promote(deferred(x), deferred(y))
            -> promote(deferred(x), deferred(y))
    """
    if seen is None:
        seen = set()

    # Find all types in the type graph and eliminate nested promotion types
    types = self.find_types(seen)
    # types = self.find_simple(seen)

    resolved_types = [type for type in types if not type.is_unresolved]
    unresolved_types = [type for type in types if type.is_unresolved]
    self.get_partial_types(unresolved_types)

    self.variable.type = self
    if not resolved_types:
        # Everything is deferred
        self.resolved_type = None
        return False
    else:
        # Simplify as much as possible
        if self.assignment:
            result_type, unresolved_types = promote_for_assignment(
                self.context, resolved_types, unresolved_types, self.variable.name
            )
        else:
            result_type = promote_for_arithmetic(self.context, resolved_types)

        self.resolved_type = result_type
        if len(resolved_types) == len(types) or not unresolved_types:
            self.variable.type = result_type
            return True
        else:
            old_types = self.types
            self.types = set([result_type] + unresolved_types)
            return old_types != self.types


# Traceback (AssertionError)
Traceback (most recent call last):
File "./test_typeinfer_bug.py", line 26, in <module>
test()
File "./test_typeinfer_bug.py", line 23, in test
jenks_matrices(data)
File "numbawrapper.pyx", line 93, in numba.numbawrapper.NumbaSpecializingWrapper.__call__ (numba/numbawrapper.c:2827)
File "/Users/sklam/dev/numba/numba/decorators.py", line 211, in compile_function
compiled_function = dec(f)
File "/Users/sklam/dev/numba/numba/decorators.py", line 299, in _jit2_decorator
**kwargs)
File "/Users/sklam/dev/numba/numba/functions.py", line 222, in compile_function
ctypes=ctypes, **kwds)
File "/Users/sklam/dev/numba/numba/pipeline.py", line 397, in compile
context, func, restype, argtypes, codegen=True, **kwds)
File "/Users/sklam/dev/numba/numba/pipeline.py", line 365, in _infer_types
return run_pipeline(context, func, ast, func_signature, **kwargs)
File "/Users/sklam/dev/numba/numba/pipeline.py", line 359, in run_pipeline
return pipeline, pipeline.run_pipeline()
File "/Users/sklam/dev/numba/numba/pipeline.py", line 188, in run_pipeline
ast = getattr(self, method_name)(ast)
File "/Users/sklam/dev/numba/numba/pipeline.py", line 255, in type_infer
type_inference.TypeInferer, ast, **self.kwargs)
File "/Users/sklam/dev/numba/numba/pipeline.py", line 149, in make_specializer
**kwds)
File "/Users/sklam/dev/numba/numba/type_inference/infer.py", line 170, in __init__
self.init_locals()
File "/Users/sklam/dev/numba/numba/type_inference/infer.py", line 249, in init_locals
self.resolve_variable_types()
File "/Users/sklam/dev/numba/numba/type_inference/infer.py", line 495, in resolve_variable_types
self.remove_resolved_type(start_point)
File "/Users/sklam/dev/numba/numba/type_inference/infer.py", line 393, in remove_resolved_type
assert not type.is_scc
AssertionError

# Fixed code
def _simplify(self, seen=None):
    """
    Simplify a promotion type tree:

        promote(int_, float_)
            -> float_

        promote(deferred(x), promote(float_, double), int_, promote(<self>))
            -> promote(deferred(x), double)

        promote(deferred(x), deferred(y))
            -> promote(deferred(x), deferred(y))
    """
    if seen is None:
        seen = set()

    # Find all types in the type graph and eliminate nested promotion types
    types = self.find_types(seen)
    # types = self.find_simple(seen)

    resolved_types = [type for type in types if not type.is_unresolved]
    unresolved_types = [type for type in types if type.is_unresolved]
    self.get_partial_types(unresolved_types)

    self.variable.type = self
    if not resolved_types:
        # Everything is deferred
        self.resolved_type = None
        return False
    else:
        # Simplify as much as possible
        if self.assignment:
            result_type, unresolved_types = promote_for_assignment(
                self.context, resolved_types, unresolved_types, self.variable.name
            )
        else:
            result_type = promote_for_arithmetic(self.context, resolved_types)

        self.resolved_type = result_type
        if len(resolved_types) == len(types) or not unresolved_types:
            self.variable.type = result_type
            return True
        else:
            old_types = self.types
            self.types = oset.OrderedSet([result_type] + unresolved_types)
            return old_types != self.types