def substitution(system, symbols, result=[{}], known_symbols=[], exclude=[], all_symbols=None):
    "\n     Solves the `system` using substitution method. It is used in\n     `nonlinsolve`. This will be called from `nonlinsolve` when any\n     equation(s) is non polynomial equation.\n\n    Parameters\n    ==========\n\n    system : list of equations\n        The target system of equations\n    symbols : list of symbols to be solved.\n        The variable(s) for which the system is solved\n    known_symbols : list of solved symbols\n        Values are known for these variable(s)\n    result : An empty list or list of dict\n        If No symbol values is known then empty list otherwise\n        symbol as keys and corresponding value in dict.\n    exclude : Set of expression.\n        Mostly denominator expression(s) of the equations of the system.\n        Final solution should not satisfy these expressions.\n    all_symbols : known_symbols + symbols(unsolved).\n\n    Returns\n    =======\n\n    A FiniteSet of ordered tuple of values of `all_symbols` for which the\n    `system` has solution. Order of values in the tuple is same as symbols\n    present in the parameter `all_symbols`. If parameter `all_symbols` is None\n    then same as symbols present in the parameter `symbols`.\n\n    Please note that general FiniteSet is unordered, the solution returned\n    here is not simply a FiniteSet of solutions, rather it is a FiniteSet of\n    ordered tuple, i.e. the first & only argument to FiniteSet is a tuple of\n    solutions, which is ordered, & hence the returned solution is ordered.\n\n    Also note that solution could also have been returned as an ordered tuple,\n    FiniteSet is just a wrapper `{}` around the tuple. It has no other\n    significance except for the fact it is just used to maintain a consistent\n    output format throughout the solveset.\n\n    Raises\n    ======\n\n    ValueError\n        The input is not valid.\n        The symbols are not given.\n    AttributeError\n        The input symbols are not `Symbol` type.\n\n    Examples\n    ========\n\n    >>> from sympy.core.symbol import symbols\n    >>> x, y = symbols('x, y', real=True)\n    >>> from sympy.solvers.solveset import substitution\n    >>> substitution([x + y], [x], [{y: 1}], [y], set([]), [x, y])\n    {(-1, 1)}\n\n    * when you want soln should not satisfy eq `x + 1 = 0`\n\n    >>> substitution([x + y], [x], [{y: 1}], [y], set([x + 1]), [y, x])\n    EmptySet()\n    >>> substitution([x + y], [x], [{y: 1}], [y], set([x - 1]), [y, x])\n    {(1, -1)}\n    >>> substitution([x + y - 1, y - x**2 + 5], [x, y])\n    {(-3, 4), (2, -1)}\n\n    * Returns both real and complex solution\n\n    >>> x, y, z = symbols('x, y, z')\n    >>> from sympy import exp, sin\n    >>> substitution([exp(x) - sin(y), y**2 - 4], [x, y])\n    {(log(sin(2)), 2), (ImageSet(Lambda(_n, I*(2*_n*pi + pi) +\n        log(sin(2))), Integers()), -2), (ImageSet(Lambda(_n, 2*_n*I*pi +\n        Mod(log(sin(2)), 2*I*pi)), Integers()), 2)}\n\n    >>> eqs = [z**2 + exp(2*x) - sin(y), -3 + exp(-y)]\n    >>> substitution(eqs, [y, z])\n    {(-log(3), -sqrt(-exp(2*x) - sin(log(3)))),\n    (-log(3), sqrt(-exp(2*x) - sin(log(3)))),\n    (ImageSet(Lambda(_n, 2*_n*I*pi + Mod(-log(3), 2*I*pi)), Integers()),\n    ImageSet(Lambda(_n, -sqrt(-exp(2*x) + sin(2*_n*I*pi +\n    Mod(-log(3), 2*I*pi)))), Integers())),\n    (ImageSet(Lambda(_n, 2*_n*I*pi + Mod(-log(3), 2*I*pi)), Integers()),\n    ImageSet(Lambda(_n, sqrt(-exp(2*x) + sin(2*_n*I*pi +\n        Mod(-log(3), 2*I*pi)))), Integers()))}\n\n    "
    from sympy import Complement
    from sympy.core.compatibility import is_sequence
    if (not system):
        return S.EmptySet
    if (not symbols):
        msg = 'Symbols must be given, for which solution of the system is to be found.'
        raise ValueError(filldedent(msg))
    if (not is_sequence(symbols)):
        msg = 'symbols should be given as a sequence, e.g. a list.Not type %s: %s'
        raise TypeError(filldedent((msg % (type(symbols), symbols))))
    try:
        sym = symbols[0].is_Symbol
    except AttributeError:
        sym = False
    if (not sym):
        msg = 'Iterable of symbols must be given as second argument, not type %s: %s'
        raise ValueError(filldedent((msg % (type(symbols[0]), symbols[0]))))
    if (all_symbols is None):
        all_symbols = symbols
    old_result = result
    complements = {}
    intersections = {}
    total_conditionset = (- 1)
    total_solveset_call = (- 1)

    def _unsolved_syms(eq, sort=False):
        'Returns the unsolved symbol present\n        in the equation `eq`.\n        '
        free = eq.free_symbols
        unsolved = ((free - set(known_symbols)) & set(all_symbols))
        if sort:
            unsolved = list(unsolved)
            unsolved.sort(key=default_sort_key)
        return unsolved
    eqs_in_better_order = list(ordered(system, (lambda _: len(_unsolved_syms(_)))))

    def add_intersection_complement(result, sym_set, **flags):
        final_result = []
        for res in result:
            res_copy = res
            for (key_res, value_res) in res.items():
                intersection_true = flags.get('Intersection', True)
                complements_true = flags.get('Complement', True)
                for (key_sym, value_sym) in sym_set.items():
                    if (key_sym == key_res):
                        if intersection_true:
                            new_value = Intersection(FiniteSet(value_res), value_sym)
                            if (new_value is not S.EmptySet):
                                res_copy[key_res] = new_value
                        if complements_true:
                            new_value = Complement(FiniteSet(value_res), value_sym)
                            if (new_value is not S.EmptySet):
                                res_copy[key_res] = new_value
            final_result.append(res_copy)
        return final_result

    def _extract_main_soln(sol, soln_imageset):
        "separate the Complements, Intersections, ImageSet lambda expr\n            and it's base_set.\n            "
        if isinstance(sol, Complement):
            complements[sym] = sol.args[1]
            sol = sol.args[0]
        if isinstance(sol, Intersection):
            if (sol.args[0] != Interval((- oo), oo)):
                intersections[sym] = sol.args[0]
            sol = sol.args[1]
        if isinstance(sol, ImageSet):
            soln_imagest = sol
            expr2 = sol.lamda.expr
            sol = FiniteSet(expr2)
            soln_imageset[expr2] = soln_imagest
        if isinstance(sol, Union):
            sol_args = sol.args
            sol = S.EmptySet
            for sol_arg2 in sol_args:
                if isinstance(sol_arg2, FiniteSet):
                    sol += sol_arg2
                else:
                    sol += FiniteSet(sol_arg2)
        if (not isinstance(sol, FiniteSet)):
            sol = FiniteSet(sol)
        return (sol, soln_imageset)

    def _check_exclude(rnew, imgset_yes):
        rnew_ = rnew
        if imgset_yes:
            rnew_copy = rnew.copy()
            dummy_n = imgset_yes[0]
            for (key_res, value_res) in rnew_copy.items():
                rnew_copy[key_res] = value_res.subs(dummy_n, 0)
            rnew_ = rnew_copy
        try:
            satisfy_exclude = any((checksol(d, rnew_) for d in exclude))
        except TypeError:
            satisfy_exclude = None
        return satisfy_exclude

    def _restore_imgset(rnew, original_imageset, newresult):
        restore_sym = (set(rnew.keys()) & set(original_imageset.keys()))
        for key_sym in restore_sym:
            img = original_imageset[key_sym]
            rnew[key_sym] = img
        if (rnew not in newresult):
            newresult.append(rnew)

    def _append_eq(eq, result, res, delete_soln, n=None):
        u = Dummy('u')
        if n:
            eq = eq.subs(n, 0)
        satisfy = checksol(u, u, eq, minimal=True)
        if (satisfy is False):
            delete_soln = True
            res = {}
        else:
            result.append(res)
        return (result, res, delete_soln)

    def _append_new_soln(rnew, sym, sol, imgset_yes, soln_imageset, original_imageset, newresult, eq=None):
        'If `rnew` (A dict <symbol: soln>) contains valid soln\n        append it to `newresult` list.\n        `imgset_yes` is (base, dummy_var) if there was imageset in previously\n         calculated result(otherwise empty tuple). `original_imageset` is dict\n         of imageset expr and imageset from this result.\n        `soln_imageset` dict of imageset expr and imageset of new soln.\n        '
        satisfy_exclude = _check_exclude(rnew, imgset_yes)
        delete_soln = False
        if (not satisfy_exclude):
            local_n = None
            if imgset_yes:
                local_n = imgset_yes[0]
                base = imgset_yes[1]
                if (sym and sol):
                    dummy_list = list(sol.atoms(Dummy))
                    local_n_list = [local_n for i in range(0, len(dummy_list))]
                    dummy_zip = zip(dummy_list, local_n_list)
                    lam = Lambda(local_n, sol.subs(dummy_zip))
                    rnew[sym] = ImageSet(lam, base)
                if (eq is not None):
                    (newresult, rnew, delete_soln) = _append_eq(eq, newresult, rnew, delete_soln, local_n)
            elif (eq is not None):
                (newresult, rnew, delete_soln) = _append_eq(eq, newresult, rnew, delete_soln)
            elif soln_imageset:
                rnew[sym] = soln_imageset[sol]
                _restore_imgset(rnew, original_imageset, newresult)
            else:
                newresult.append(rnew)
        elif satisfy_exclude:
            delete_soln = True
            rnew = {}
        _restore_imgset(rnew, original_imageset, newresult)
        return (newresult, delete_soln)

    def _new_order_result(result, eq):
        first_priority = []
        second_priority = []
        for res in result:
            if (not any((isinstance(val, ImageSet) for val in res.values()))):
                if (eq.subs(res) == 0):
                    first_priority.append(res)
                else:
                    second_priority.append(res)
        if (first_priority or second_priority):
            return (first_priority + second_priority)
        return result

    def _solve_using_known_values(result, solver):
        'Solves the system using already known solution\n        (result contains the dict <symbol: value>).\n        solver is `solveset_complex` or `solveset_real`.\n        '
        soln_imageset = {}
        total_solvest_call = 0
        total_conditionst = 0
        for (index, eq) in enumerate(eqs_in_better_order):
            newresult = []
            original_imageset = {}
            imgset_yes = False
            result = _new_order_result(result, eq)
            for res in result:
                got_symbol = set()
                if soln_imageset:
                    for (key_res, value_res) in res.items():
                        if isinstance(value_res, ImageSet):
                            res[key_res] = value_res.lamda.expr
                            original_imageset[key_res] = value_res
                            dummy_n = value_res.lamda.expr.atoms(Dummy).pop()
                            base = value_res.base_set
                            imgset_yes = (dummy_n, base)
                eq2 = eq.subs(res)
                unsolved_syms = _unsolved_syms(eq2, sort=True)
                if (not unsolved_syms):
                    if res:
                        (newresult, delete_res) = _append_new_soln(res, None, None, imgset_yes, soln_imageset, original_imageset, newresult, eq2)
                        if delete_res:
                            result.remove(res)
                    continue
                depen = eq2.as_independent(unsolved_syms)[0]
                if (depen.has(Abs) and (solver == solveset_complex)):
                    continue
                soln_imageset = {}
                for sym in unsolved_syms:
                    not_solvable = False
                    try:
                        soln = solver(eq2, sym)
                        total_solvest_call += 1
                        soln_new = S.EmptySet
                        if isinstance(soln, Complement):
                            complements[sym] = soln.args[1]
                            soln = soln.args[0]
                        if isinstance(soln, Intersection):
                            if (soln.args[0] != Interval((- oo), oo)):
                                intersections[sym] = soln.args[0]
                            soln_new += soln.args[1]
                        soln = (soln_new if soln_new else soln)
                        if ((index > 0) and (solver == solveset_real)):
                            if (not isinstance(soln, (ImageSet, ConditionSet))):
                                soln += solveset_complex(eq2, sym)
                    except NotImplementedError:
                        continue
                    if isinstance(soln, ConditionSet):
                        soln = S.EmptySet
                        not_solvable = True
                        total_conditionst += 1
                    if (soln is not S.EmptySet):
                        (soln, soln_imageset) = _extract_main_soln(soln, soln_imageset)
                    for sol in soln:
                        (sol, soln_imageset) = _extract_main_soln(sol, soln_imageset)
                        sol = set(sol).pop()
                        free = sol.free_symbols
                        if (got_symbol and any([(ss in free) for ss in got_symbol])):
                            continue
                        rnew = res.copy()
                        for (k, v) in res.items():
                            if isinstance(v, Expr):
                                rnew[k] = v.subs(sym, sol)
                        if soln_imageset:
                            imgst = soln_imageset[sol]
                            rnew[sym] = imgst.lamda(*[0 for i in range(0, len(imgst.lamda.variables))])
                        else:
                            rnew[sym] = sol
                        (newresult, delete_res) = _append_new_soln(rnew, sym, sol, imgset_yes, soln_imageset, original_imageset, newresult)
                        if delete_res:
                            result.remove(res)
                    if (not not_solvable):
                        got_symbol.add(sym)
            if newresult:
                result = newresult
        return (result, total_solvest_call, total_conditionst)
    (new_result_real, solve_call1, cnd_call1) = _solve_using_known_values(old_result, solveset_real)
    (new_result_complex, solve_call2, cnd_call2) = _solve_using_known_values(old_result, solveset_complex)
    total_conditionset += (cnd_call1 + cnd_call2)
    total_solveset_call += (solve_call1 + solve_call2)
    if ((total_conditionset == total_solveset_call) and (total_solveset_call != (- 1))):
        return _return_conditionset(eqs_in_better_order, all_symbols)
    result = (new_result_real + new_result_complex)
    result_all_variables = []
    result_infinite = []
    for res in result:
        if (not res):
            continue
        if (len(res) < len(all_symbols)):
            solved_symbols = res.keys()
            unsolved = list(filter((lambda x: (x not in solved_symbols)), all_symbols))
            for unsolved_sym in unsolved:
                res[unsolved_sym] = unsolved_sym
            result_infinite.append(res)
        if (res not in result_all_variables):
            result_all_variables.append(res)
    if result_infinite:
        result_all_variables = result_infinite
    if (intersections and complements):
        result_all_variables = add_intersection_complement(result_all_variables, intersections, Intersection=True, Complement=True)
    elif intersections:
        result_all_variables = add_intersection_complement(result_all_variables, intersections, Intersection=True)
    elif complements:
        result_all_variables = add_intersection_complement(result_all_variables, complements, Complement=True)
    result = S.EmptySet
    for r in result_all_variables:
        temp = [r[symb] for symb in all_symbols]
        result += FiniteSet(tuple(temp))
    return result
Solves the `system` using substitution method. It is used in
 `nonlinsolve`. This will be called from `nonlinsolve` when any
 equation(s) is non polynomial equation.

Parameters
==========

system : list of equations
    The target system of equations
symbols : list of symbols to be solved.
    The variable(s) for which the system is solved
known_symbols : list of solved symbols
    Values are known for these variable(s)
result : An empty list or list of dict
    If No symbol values is known then empty list otherwise
    symbol as keys and corresponding value in dict.
exclude : Set of expression.
    Mostly denominator expression(s) of the equations of the system.
    Final solution should not satisfy these expressions.
all_symbols : known_symbols + symbols(unsolved).

Returns
=======

A FiniteSet of ordered tuple of values of `all_symbols` for which the
`system` has solution. Order of values in the tuple is same as symbols
present in the parameter `all_symbols`. If parameter `all_symbols` is None
then same as symbols present in the parameter `symbols`.

Please note that general FiniteSet is unordered, the solution returned
here is not simply a FiniteSet of solutions, rather it is a FiniteSet of
ordered tuple, i.e. the first & only argument to FiniteSet is a tuple of
solutions, which is ordered, & hence the returned solution is ordered.

Also note that solution could also have been returned as an ordered tuple,
FiniteSet is just a wrapper `{}` around the tuple. It has no other
significance except for the fact it is just used to maintain a consistent
output format throughout the solveset.

Raises
======

ValueError
    The input is not valid.
    The symbols are not given.
AttributeError
    The input symbols are not `Symbol` type.

Examples
========

>>> from sympy.core.symbol import symbols
>>> x, y = symbols('x, y', real=True)
>>> from sympy.solvers.solveset import substitution
>>> substitution([x + y], [x], [{y: 1}], [y], set([]), [x, y])
{(-1, 1)}

* when you want soln should not satisfy eq `x + 1 = 0`

>>> substitution([x + y], [x], [{y: 1}], [y], set([x + 1]), [y, x])
EmptySet()
>>> substitution([x + y], [x], [{y: 1}], [y], set([x - 1]), [y, x])
{(1, -1)}
>>> substitution([x + y - 1, y - x**2 + 5], [x, y])
{(-3, 4), (2, -1)}

* Returns both real and complex solution

>>> x, y, z = symbols('x, y, z')
>>> from sympy import exp, sin
>>> substitution([exp(x) - sin(y), y**2 - 4], [x, y])
{(log(sin(2)), 2), (ImageSet(Lambda(_n, I*(2*_n*pi + pi) +
    log(sin(2))), Integers()), -2), (ImageSet(Lambda(_n, 2*_n*I*pi +
    Mod(log(sin(2)), 2*I*pi)), Integers()), 2)}

>>> eqs = [z**2 + exp(2*x) - sin(y), -3 + exp(-y)]
>>> substitution(eqs, [y, z])
{(-log(3), -sqrt(-exp(2*x) - sin(log(3)))),
(-log(3), sqrt(-exp(2*x) - sin(log(3)))),
(ImageSet(Lambda(_n, 2*_n*I*pi + Mod(-log(3), 2*I*pi)), Integers()),
ImageSet(Lambda(_n, -sqrt(-exp(2*x) + sin(2*_n*I*pi +
Mod(-log(3), 2*I*pi)))), Integers())),
(ImageSet(Lambda(_n, 2*_n*I*pi + Mod(-log(3), 2*I*pi)), Integers()),
ImageSet(Lambda(_n, sqrt(-exp(2*x) + sin(2*_n*I*pi +
    Mod(-log(3), 2*I*pi)))), Integers()))}
def substitution(system, symbols, result=[{}], known_symbols=[], exclude=[], all_symbols=None):
    "\n     Solves the `system` using substitution method. It is used in\n     `nonlinsolve`. This will be called from `nonlinsolve` when any\n     equation(s) is non polynomial equation.\n\n    Parameters\n    ==========\n\n    system : list of equations\n        The target system of equations\n    symbols : list of symbols to be solved.\n        The variable(s) for which the system is solved\n    known_symbols : list of solved symbols\n        Values are known for these variable(s)\n    result : An empty list or list of dict\n        If No symbol values is known then empty list otherwise\n        symbol as keys and corresponding value in dict.\n    exclude : Set of expression.\n        Mostly denominator expression(s) of the equations of the system.\n        Final solution should not satisfy these expressions.\n    all_symbols : known_symbols + symbols(unsolved).\n\n    Returns\n    =======\n\n    A FiniteSet of ordered tuple of values of `all_symbols` for which the\n    `system` has solution. Order of values in the tuple is same as symbols\n    present in the parameter `all_symbols`. If parameter `all_symbols` is None\n    then same as symbols present in the parameter `symbols`.\n\n    Please note that general FiniteSet is unordered, the solution returned\n    here is not simply a FiniteSet of solutions, rather it is a FiniteSet of\n    ordered tuple, i.e. the first & only argument to FiniteSet is a tuple of\n    solutions, which is ordered, & hence the returned solution is ordered.\n\n    Also note that solution could also have been returned as an ordered tuple,\n    FiniteSet is just a wrapper `{}` around the tuple. It has no other\n    significance except for the fact it is just used to maintain a consistent\n    output format throughout the solveset.\n\n    Raises\n    ======\n\n    ValueError\n        The input is not valid.\n        The symbols are not given.\n    AttributeError\n        The input symbols are not `Symbol` type.\n\n    Examples\n    ========\n\n    >>> from sympy.core.symbol import symbols\n    >>> x, y = symbols('x, y', real=True)\n    >>> from sympy.solvers.solveset import substitution\n    >>> substitution([x + y], [x], [{y: 1}], [y], set([]), [x, y])\n    {(-1, 1)}\n\n    * when you want soln should not satisfy eq `x + 1 = 0`\n\n    >>> substitution([x + y], [x], [{y: 1}], [y], set([x + 1]), [y, x])\n    EmptySet()\n    >>> substitution([x + y], [x], [{y: 1}], [y], set([x - 1]), [y, x])\n    {(1, -1)}\n    >>> substitution([x + y - 1, y - x**2 + 5], [x, y])\n    {(-3, 4), (2, -1)}\n\n    * Returns both real and complex solution\n\n    >>> x, y, z = symbols('x, y, z')\n    >>> from sympy import exp, sin\n    >>> substitution([exp(x) - sin(y), y**2 - 4], [x, y])\n    {(log(sin(2)), 2), (ImageSet(Lambda(_n, I*(2*_n*pi + pi) +\n        log(sin(2))), Integers()), -2), (ImageSet(Lambda(_n, 2*_n*I*pi +\n        Mod(log(sin(2)), 2*I*pi)), Integers()), 2)}\n\n    >>> eqs = [z**2 + exp(2*x) - sin(y), -3 + exp(-y)]\n    >>> substitution(eqs, [y, z])\n    {(-log(3), -sqrt(-exp(2*x) - sin(log(3)))),\n    (-log(3), sqrt(-exp(2*x) - sin(log(3)))),\n    (ImageSet(Lambda(_n, 2*_n*I*pi + Mod(-log(3), 2*I*pi)), Integers()),\n    ImageSet(Lambda(_n, -sqrt(-exp(2*x) + sin(2*_n*I*pi +\n    Mod(-log(3), 2*I*pi)))), Integers())),\n    (ImageSet(Lambda(_n, 2*_n*I*pi + Mod(-log(3), 2*I*pi)), Integers()),\n    ImageSet(Lambda(_n, sqrt(-exp(2*x) + sin(2*_n*I*pi +\n        Mod(-log(3), 2*I*pi)))), Integers()))}\n\n    "
    from sympy import Complement
    from sympy.core.compatibility import is_sequence
    if (not system):
        return S.EmptySet
    if (not symbols):
        msg = 'Symbols must be given, for which solution of the system is to be found.'
        raise ValueError(filldedent(msg))
    if (not is_sequence(symbols)):
        msg = 'symbols should be given as a sequence, e.g. a list.Not type %s: %s'
        raise TypeError(filldedent((msg % (type(symbols), symbols))))
    try:
        sym = symbols[0].is_Symbol
    except AttributeError:
        sym = False
    if (not sym):
        msg = 'Iterable of symbols must be given as second argument, not type %s: %s'
        raise ValueError(filldedent((msg % (type(symbols[0]), symbols[0]))))
    if (all_symbols is None):
        all_symbols = symbols
    old_result = result
    complements = {}
    intersections = {}
    total_conditionset = (- 1)
    total_solveset_call = (- 1)

    def _unsolved_syms(eq, sort=False):
        'Returns the unsolved symbol present\n        in the equation `eq`.\n        '
        free = eq.free_symbols
        unsolved = ((free - set(known_symbols)) & set(all_symbols))
        if sort:
            unsolved = list(unsolved)
            unsolved.sort(key=default_sort_key)
        return unsolved
    eqs_in_better_order = list(ordered(system, (lambda _: len(_unsolved_syms(_)))))

    def add_intersection_complement(result, sym_set, **flags):
        final_result = []
        for res in result:
            res_copy = res
            for (key_res, value_res) in res.items():
                intersection_true = flags.get('Intersection', True)
                complements_true = flags.get('Complement', True)
                for (key_sym, value_sym) in sym_set.items():
                    if (key_sym == key_res):
                        if intersection_true:
                            new_value = Intersection(FiniteSet(value_res), value_sym)
                            if (new_value is not S.EmptySet):
                                res_copy[key_res] = new_value
                        if complements_true:
                            new_value = Complement(FiniteSet(value_res), value_sym)
                            if (new_value is not S.EmptySet):
                                res_copy[key_res] = new_value
            final_result.append(res_copy)
        return final_result

    def _extract_main_soln(sol, soln_imageset):
        "separate the Complements, Intersections, ImageSet lambda expr\n            and it's base_set.\n            "
        if isinstance(sol, Complement):
            complements[sym] = sol.args[1]
            sol = sol.args[0]
        if isinstance(sol, Intersection):
            if (sol.args[0] != Interval((- oo), oo)):
                intersections[sym] = sol.args[0]
            sol = sol.args[1]
        if isinstance(sol, ImageSet):
            soln_imagest = sol
            expr2 = sol.lamda.expr
            sol = FiniteSet(expr2)
            soln_imageset[expr2] = soln_imagest
        if isinstance(sol, Union):
            sol_args = sol.args
            sol = S.EmptySet
            for sol_arg2 in sol_args:
                if isinstance(sol_arg2, FiniteSet):
                    sol += sol_arg2
                else:
                    sol += FiniteSet(sol_arg2)
        if (not isinstance(sol, FiniteSet)):
            sol = FiniteSet(sol)
        return (sol, soln_imageset)

    def _check_exclude(rnew, imgset_yes):
        rnew_ = rnew
        if imgset_yes:
            rnew_copy = rnew.copy()
            dummy_n = imgset_yes[0]
            for (key_res, value_res) in rnew_copy.items():
                rnew_copy[key_res] = value_res.subs(dummy_n, 0)
            rnew_ = rnew_copy
        try:
            satisfy_exclude = any((checksol(d, rnew_) for d in exclude))
        except TypeError:
            satisfy_exclude = None
        return satisfy_exclude

    def _restore_imgset(rnew, original_imageset, newresult):
        restore_sym = (set(rnew.keys()) & set(original_imageset.keys()))
        for key_sym in restore_sym:
            img = original_imageset[key_sym]
            rnew[key_sym] = img
        if (rnew not in newresult):
            newresult.append(rnew)

    def _append_eq(eq, result, res, delete_soln, n=None):
        u = Dummy('u')
        if n:
            eq = eq.subs(n, 0)
        satisfy = checksol(u, u, eq, minimal=True)
        if (satisfy is False):
            delete_soln = True
            res = {}
        else:
            result.append(res)
        return (result, res, delete_soln)

    def _append_new_soln(rnew, sym, sol, imgset_yes, soln_imageset, original_imageset, newresult, eq=None):
        'If `rnew` (A dict <symbol: soln>) contains valid soln\n        append it to `newresult` list.\n        `imgset_yes` is (base, dummy_var) if there was imageset in previously\n         calculated result(otherwise empty tuple). `original_imageset` is dict\n         of imageset expr and imageset from this result.\n        `soln_imageset` dict of imageset expr and imageset of new soln.\n        '
        satisfy_exclude = _check_exclude(rnew, imgset_yes)
        delete_soln = False
        if (not satisfy_exclude):
            local_n = None
            if imgset_yes:
                local_n = imgset_yes[0]
                base = imgset_yes[1]
                if (sym and sol):
                    dummy_list = list(sol.atoms(Dummy))
                    local_n_list = [local_n for i in range(0, len(dummy_list))]
                    dummy_zip = zip(dummy_list, local_n_list)
                    lam = Lambda(local_n, sol.subs(dummy_zip))
                    rnew[sym] = ImageSet(lam, base)
                if (eq is not None):
                    (newresult, rnew, delete_soln) = _append_eq(eq, newresult, rnew, delete_soln, local_n)
            elif (eq is not None):
                (newresult, rnew, delete_soln) = _append_eq(eq, newresult, rnew, delete_soln)
            elif soln_imageset:
                rnew[sym] = soln_imageset[sol]
                _restore_imgset(rnew, original_imageset, newresult)
            else:
                newresult.append(rnew)
        elif satisfy_exclude:
            delete_soln = True
            rnew = {}
        _restore_imgset(rnew, original_imageset, newresult)
        return (newresult, delete_soln)

    def _new_order_result(result, eq):
        first_priority = []
        second_priority = []
        for res in result:
            if (not any((isinstance(val, ImageSet) for val in res.values()))):
                if (eq.subs(res) == 0):
                    first_priority.append(res)
                else:
                    second_priority.append(res)
        if (first_priority or second_priority):
            return (first_priority + second_priority)
        return result

    def _solve_using_known_values(result, solver):
        'Solves the system using already known solution\n        (result contains the dict <symbol: value>).\n        solver is `solveset_complex` or `solveset_real`.\n        '
        soln_imageset = {}
        total_solvest_call = 0
        total_conditionst = 0
        for (index, eq) in enumerate(eqs_in_better_order):
            newresult = []
            original_imageset = {}
            imgset_yes = False
            result = _new_order_result(result, eq)
            for res in result:
                got_symbol = set()
                if soln_imageset:
                    for (key_res, value_res) in res.items():
                        if isinstance(value_res, ImageSet):
                            res[key_res] = value_res.lamda.expr
                            original_imageset[key_res] = value_res
                            dummy_n = value_res.lamda.expr.atoms(Dummy).pop()
                            base = value_res.base_set
                            imgset_yes = (dummy_n, base)
                eq2 = eq.subs(res)
                unsolved_syms = _unsolved_syms(eq2, sort=True)
                if (not unsolved_syms):
                    if res:
                        (newresult, delete_res) = _append_new_soln(res, None, None, imgset_yes, soln_imageset, original_imageset, newresult, eq2)
                        if delete_res:
                            result.remove(res)
                    continue
                depen = eq2.as_independent(unsolved_syms)[0]
                if (depen.has(Abs) and (solver == solveset_complex)):
                    continue
                soln_imageset = {}
                for sym in unsolved_syms:
                    not_solvable = False
                    try:
                        soln = solver(eq2, sym)
                        total_solvest_call += 1
                        soln_new = S.EmptySet
                        if isinstance(soln, Complement):
                            complements[sym] = soln.args[1]
                            soln = soln.args[0]
                        if isinstance(soln, Intersection):
                            if (soln.args[0] != Interval((- oo), oo)):
                                intersections[sym] = soln.args[0]
                            soln_new += soln.args[1]
                        soln = (soln_new if soln_new else soln)
                        if ((index > 0) and (solver == solveset_real)):
                            if (not isinstance(soln, (ImageSet, ConditionSet))):
                                soln += solveset_complex(eq2, sym)
                    except NotImplementedError:
                        continue
                    if isinstance(soln, ConditionSet):
                        soln = S.EmptySet
                        not_solvable = True
                        total_conditionst += 1
                    if (soln is not S.EmptySet):
                        (soln, soln_imageset) = _extract_main_soln(soln, soln_imageset)
                    for sol in soln:
                        (sol, soln_imageset) = _extract_main_soln(sol, soln_imageset)
                        sol = set(sol).pop()
                        free = sol.free_symbols
                        if (got_symbol and any([(ss in free) for ss in got_symbol])):
                            continue
                        rnew = res.copy()
                        for (k, v) in res.items():
                            if isinstance(v, Expr):
                                rnew[k] = v.subs(sym, sol)
                        if soln_imageset:
                            imgst = soln_imageset[sol]
                            rnew[sym] = imgst.lamda(*[0 for i in range(0, len(imgst.lamda.variables))])
                        else:
                            rnew[sym] = sol
                        (newresult, delete_res) = _append_new_soln(rnew, sym, sol, imgset_yes, soln_imageset, original_imageset, newresult)
                        if delete_res:
                            result.remove(res)
                    if (not not_solvable):
                        got_symbol.add(sym)
            if newresult:
                result = newresult
        return (result, total_solvest_call, total_conditionst)
    (new_result_real, solve_call1, cnd_call1) = _solve_using_known_values(old_result, solveset_real)
    (new_result_complex, solve_call2, cnd_call2) = _solve_using_known_values(old_result, solveset_complex)
    total_conditionset += (cnd_call1 + cnd_call2)
    total_solveset_call += (solve_call1 + solve_call2)
    if ((total_conditionset == total_solveset_call) and (total_solveset_call != (- 1))):
        return _return_conditionset(eqs_in_better_order, all_symbols)
    result = (new_result_real + new_result_complex)
    result_all_variables = []
    result_infinite = []
    for res in result:
        if (not res):
            continue
        if (len(res) < len(all_symbols)):
            solved_symbols = res.keys()
            unsolved = list(filter((lambda x: (x not in solved_symbols)), all_symbols))
            for unsolved_sym in unsolved:
                res[unsolved_sym] = unsolved_sym
            result_infinite.append(res)
        if (res not in result_all_variables):
            result_all_variables.append(res)
    if result_infinite:
        result_all_variables = result_infinite
    if (intersections and complements):
        result_all_variables = add_intersection_complement(result_all_variables, intersections, Intersection=True, Complement=True)
    elif intersections:
        result_all_variables = add_intersection_complement(result_all_variables, intersections, Intersection=True)
    elif complements:
        result_all_variables = add_intersection_complement(result_all_variables, complements, Complement=True)
    result = S.EmptySet
    for r in result_all_variables:
        temp = [r[symb] for symb in all_symbols]
        result += FiniteSet(tuple(temp))
    return result