'Simplify a :class:`Union` using known rules
We first start with global rules like
\'Merge all FiniteSets\'
Then we iterate through all pairs and ask the constituent sets if they
can simplify themselves with any other constituent'

@staticmethod
def reduce(args):

    finite_sets = [x for x in args if x.is_FiniteSet]
    if (len(finite_sets) > 1):
        a = (x for set in finite_sets for x in set)
        finite_set = FiniteSet(*a)
        args = ([finite_set] + [x for x in args if (not x.is_FiniteSet)])
    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._union(t)
                if (new_set is not None):
                    if (not isinstance(new_set, set)):
                        new_set = set((new_set,))
                    new_args = (args - set((s, t))).union(new_set)
                    break
            if new_args:
                args = new_args
                break
    if (len(args) == 1):
        return args.pop()
    else:
        return Union(args, evaluate=False)
