@staticmethod
    def reduce(args):
        from sympy.simplify.simplify import clear_coefficients

        # ===== Global Rules =====
        # If any EmptySets return EmptySet
        if any(s.is_EmptySet for s in args):
            return S.EmptySet

        # Handle Finite sets
        rv = Intersection._handle_finite_sets(args)
        if rv is not None:
            # simplify symbolic intersection between a FiniteSet
            # and an interval
            if isinstance(rv, Intersection) and len(rv.args) == 2:
                ivl, s = rv.args
                if isinstance(s, FiniteSet) and len(s) == 1 and isinstance(ivl, Interval):
                    e = list(s)[0]
                    if e.free_symbols:
                        rhs = Dummy()
                        e, r = clear_coefficients(e, rhs)
                        if r != rhs:
                            iargs = list(ivl.args)
                            iargs[0] = r.subs(rhs, ivl.start)
                            iargs[1] = r.subs(rhs, ivl.end)
                            if iargs[0] > iargs[1]:
                                iargs = iargs[:2][::-1] + iargs[-2:][::-1]
                            rv = Intersection(FiniteSet(e), Interval(*iargs), evaluate=False)
            return rv

        # If any of the sets are unions, return a Union of Intersections
        for s in args:
            if s.is_Union:
                other_sets = set(args) - set((s,))
                if len(other_sets) > 0:
                    other = Intersection(other_sets)
                    return Union(Intersection(arg, other) for arg in s.args)
                else:
                    return Union(arg for arg in s.args)

        for s in args:
            if s.is_Complement:
                args.remove(s)
                other_sets = args + [s.args[0]]
                return Complement(Intersection(*other_sets), s.args[1])

        # At this stage we are guaranteed not to have any
        # EmptySets, FiniteSets, or Unions in the intersection

        # ===== Pair-wise Rules =====
        # Here we depend on rules built into the constituent sets
        args = set(args)
        new_args = True
        while(new_args):
            for s in args:
                new_args = False
                for t in args - set((s,)):
                    new_set = s._intersect(t)
                    # This returns None if s does not know how to intersect
                    # with t. Returns the newly intersected set otherwise
                    if new_set is not None:
                        new_args = (args - set((s, t))).union(set((new_set, )))
                        break
                if new_args:
                    args = new_args
                    break

        if len(args) == 1:
            return args.pop()
        else:
            return Intersection(args, evaluate=False)
Return a simplified intersection by applying rules.
dataset/ETHPy150Open sympy/sympy/sympy/sets/sets.py/Intersection.reduce