
    wgP                        d Z ddlmZ ddlmZmZmZmZmZm	Z	m
Z
mZmZ ddlmZ ddlmZmZmZmZmZmZmZ ddlmZ ddlmZmZmZmZ ddlmZ dd	l m!Z!m"Z"m#Z# dd
l$m%Z%m&Z& ddl'm(Z(m)Z) ddlm*Z* ddl+m,Z, ddl-m.Z/m0Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7m8Z8m9Z9m:Z: ddl;m<Z<m=Z= ddl>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZN ddlOmPZP ddlQmRZRmSZSmTZTmUZU ddlVmWZWmXZXmYZYmZZZm[Z[m\Z\m]Z]m^Z^m_Z_m`Z`maZambZbmcZc ddldmeZe ddlfmgZg ddlhmiZimjZj ddlkmlZlmmZmmnZnmoZompZpmqZqmrZrmsZsmtZt ddlumvZvmwZw ddlxmyZymzZzm{Z{ ddl|m}Z} ddl~mZmZ ddlmZmZmZmZmZmZmZm0Z0m.Z. dd lmZ dd!lmZmZmZ dd"lmZmZmZ dd#l2mZ dd$lmZmZmZmZmZ dd%lmZ dd&lmZ dd'lmZmZmZmZ dd(lmZmZmZ dd)lmZ  G d* d+e      Zd, ZejX                  fd-ZeZd. Zd/ Zd0ad0ad1 Zd2 Zd3 Zd4 Zd5 Zd6 ZejX                  fd7Zd8 Zd9 Z G d: d;e      Zd< Zd= Zd> ZejX                  fd?Zd@ ZdA ZdB Zd`dDZdE ZdF ZdG ZdH ZdI ZdJ ZdK ZdL ZdM ZdN Zd0ejX                  fdOZdP ZdQ ZdR ZdS ZdCdTdUZdV ZdW ZdX Zi gg g d0fdYZdZ Zd[ Zd\ Zd] Zd^ Zd_ Zy0)aa  
This module contains functions to:

    - solve a single equation for a single variable, in any domain either real or complex.

    - solve a single transcendental equation for a single variable in any domain either real or complex.
      (currently supports solving in real domain only)

    - solve a system of linear equations with N variables and M equations.

    - solve a system of Non Linear Equations with N variables and M equations
    )sympify)	SPowDummypiExprWildMulAddBasic)Tuple)Lambdaexpand_complexAppliedUndef
expand_log_mexpandexpand_trignfloat)Mod)INumberRationaloo)integer_log)EqNe
Relational)default_sort_keyordered)Symbol_uniquely_named_symbol)_sympify)preorder_traversal)gcdlcm)_linear_eq_to_dict)UnsolvableFactorError)simplifyfractiontrigsimp	nsimplify)	powdenest
logcombine)logtancotsincosseccscexpacosasinatanacotacscasecpiecewise_fold	Piecewise)totient)Absargreim)HyperbolicFunctionsinhcoshtanhcothsechcschasinhacoshatanhacothasechacsch)	real_root)TrigonometricFunction)AndBooleanTrue)		FiniteSetimagesetIntervalIntersectionUnionConditionSetImageSet
ComplementContains)Set
ProductSet)zerosMatrix
MatrixBase)divisors)discrete_lognthroot_mod)	rootsPolydegreetogetherPolynomialErrorRootOffactorr%   r$   )CoercionFailed)invertgroebnerpoly)sympy_eqs_to_ringsolve_lin_sysPolyNonlinearError)	_linsolve)checksoldenomsunrad_simple_densrecast_to_symbols)solve_poly_system)
filldedent)numbered_symbolshas_dupsis_sequenceiterable)periodicitycontinuous_domainfunction_range)GeneratorTypec                       e Zd ZdZy)NonlinearErrorz9Raised when unexpectedly encountering nonlinear equationsN__name__
__module____qualname____doc__     [/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/sympy/solvers/solveset.pyr   r   D   s    Cr   r   c                 V   t        dt        d      }g }t         | j                  |       D ]4  }|D ]  } |j                  | } |j                  |t        |      f       6 t        |      D ]!  \  }\  }}| j	                  ||      } ||f||<   # t        t        |            }| |fS )a
  Return ``f``, with all objects given by ``atoms`` replaced with
    Dummy symbols, ``d``, and the list of replacements, ``(d, e)``,
    where ``e`` is an object of type given by ``atoms`` in which
    any other instances of atoms have been recursively replaced with
    Dummy symbols, too. The tuples are ordered so that if they are
    applied in sequence, the origin ``f`` will be restored.

    Examples
    ========

    >>> from sympy import cos
    >>> from sympy.abc import x
    >>> from sympy.solvers.solveset import _masked

    >>> f = cos(cos(x) + 1)
    >>> f, reps = _masked(cos(1 + cos(x)), cos)
    >>> f
    _a1
    >>> reps
    [(_a1, cos(_a0 + 1)), (_a0, cos(x))]
    >>> for d, e in reps:
    ...     f = f.xreplace({d: e})
    >>> f
    cos(cos(x) + 1)
    aT)clsreal)
r{   r   r   atomsreplaceappendnext	enumeratelistreversed)fr   symmaskr   ions           r   _maskedr   I   s    4 3E
5CDWQWWe_% $ 	A		1A	QS	N#$ t_ 	6AqIIaOa&Q Dd7Nr   c                 P   t        |      }|j                  st        d      t        |       } || j                  vrt        d      t        |      }||j                  v rt        d      |j	                  t
        j                        rt        | t        |      |      \  }}nt        | t        |      |      \  }}||k7  r||fS |t
        j                  u r||fS t        |t              r||j                  |      fS |t
        j                  u r||fS ||j                  |      fS )a  
    Reduce the complex valued equation $f(x) = y$ to a set of equations

    $$\left\{g(x) = h_1(y),\  g(x) = h_2(y),\ \dots,\  g(x) = h_n(y) \right\}$$

    where $g(x)$ is a simpler function than $f(x)$.  The return value is a tuple
    $(g(x), \mathrm{set}_h)$, where $g(x)$ is a function of $x$ and $\mathrm{set}_h$ is
    the set of function $\left\{h_1(y), h_2(y), \dots, h_n(y)\right\}$.
    Here, $y$ is not necessarily a symbol.

    $\mathrm{set}_h$ contains the functions, along with the information
    about the domain in which they are valid, through set
    operations. For instance, if :math:`y = |x| - n` is inverted
    in the real domain, then $\mathrm{set}_h$ is not simply
    $\{-n, n\}$ as the nature of `n` is unknown; rather, it is:

    $$ \left(\left[0, \infty\right) \cap \left\{n\right\}\right) \cup
                       \left(\left(-\infty, 0\right] \cap \left\{- n\right\}\right)$$

    By default, the complex domain is used which means that inverting even
    seemingly simple functions like $\exp(x)$ will give very different
    results from those obtained in the real domain.
    (In the case of $\exp(x)$, the inversion via $\log$ is multi-valued
    in the complex domain, having infinitely many branches.)

    If you are working with real values only (or you are not sure which
    function to use) you should probably set the domain to
    ``S.Reals`` (or use ``invert_real`` which does that automatically).


    Examples
    ========

    >>> from sympy.solvers.solveset import invert_complex, invert_real
    >>> from sympy.abc import x, y
    >>> from sympy import exp

    When does exp(x) == y?

    >>> invert_complex(exp(x), y, x)
    (x, ImageSet(Lambda(_n, I*(2*_n*pi + arg(y)) + log(Abs(y))), Integers))
    >>> invert_real(exp(x), y, x)
    (x, Intersection({log(y)}, Reals))

    When does exp(x) == 1?

    >>> invert_complex(exp(x), 1, x)
    (x, ImageSet(Lambda(_n, 2*_n*I*pi), Integers))
    >>> invert_real(exp(x), 1, x)
    (x, {0})

    See Also
    ========
    invert_real, invert_complex
    zx must be a symbolz*Inverse of constant function doesn't existzy should be independent of x )r   	is_Symbol
ValueErrorfree_symbols	is_subsetr   Reals_invert_realrT   _invert_complex	Complexes
isinstance	intersect)f_xyxdomainx1ss         r   _invertr   p   s   p 	
A;;-..
#,C   EFF
AANN899 S)A,2AYq\15A 	a1u 1u!Y1;;v&&& 1u1;;v&&&r   c                 :    t        | ||t        j                        S )z
    Inverts a real-valued function. Same as :func:`invert_complex`, but sets
    the domain to ``S.Reals`` before inverting.
    )r   r   r   )r   r   r   s      r   invert_realr      s    
 31agg&&r   c                 F	   | |k(  s|t         j                  u r||fS t        dd      }t        | t              s)| j
                  rQ| j                  t         j                  k(  r4t        | j                  t        t        |t        |            |      |      S t        | d      r| j                         {t        | t        t        f      set!        | j"                        dkD  rt%        d      t        | j"                  d   t        t        | | j                         |            |      |      S t        | t&              rt)        | j"                  d   ||      S | j*                  rJ| j-                  |      \  }}|t         j.                  ur$t        |t        t        |||z
        |      |      S | j0                  rJ| j-                  |      \  }}|t         j2                  ur$t        |t        t        |||z        |      |      S | j
                  rl| j"                  \  }}|j5                  |      }|j5                  |      }	|	sC|j6                  r|j9                         \  }
}|dz  dk(  r_|
dz  dk(  rW|j:                  d	u rIt        |t=        ||            }|t?        dt@              z  }t        ||      }t        |||      \  }}||fS |dz  dk(  rt        |t=        ||            }t        ||      }|
dz  dk(  r't        t        ||       |      }t        |||z   |      S |
dz  dk(  r\t        |||      S |jB                  rBt        |t=        ||            }|t?        dt@              z  }t        ||      }t        |||      S 	 |s|j"                  d   }|jD                  r-t        |t        t        |t        ||d	
            |      |      S |jF                  r9tI        ||      \  }}|rt        |tK        |      |      S |t         j                  fS |j:                  rZtM        |d      }|t         jN                  k(  rt        |tK        d      |      S |t         jP                  k(  r|t         j                  fS t        | t        t        f      rtS        | ||      S | |fS )Helper function for _invert.r   Tr   inverse   /Only functions with one argument are supported.r      Fevaluate)*r   EmptySetr   r   r5   is_PowbaseExp1r   rU   r   r.   hasattrr   rQ   rC   lenargsr   r?   _invert_absis_Addas_independentZerois_MulOnehasis_rationalas_numer_denomis_zerorP   rV   r   is_irrationalis_positiveis_negativer   rT   r   truefalse_invert_trig_hyp_real)r   g_yssymbolr   ghr   expobase_has_symexpo_has_symnumdenrootg_ys_posres_inv_setneg_resrhsr   bones                         r   r   r      s    	F{dajj(~cA!Sahh166QVV+;AEE$VAs1v%6="$ 	$ q)!8A!P B qvv;?NOOAFF1I$VA{qyy{1~%>E"$ 	$ !S166!9dF33xx'1AFF?8F1a!e,<d#CVLLxx'1AEE>8F1acND#A6JJxxVV
dxx'xx'..0S7a<C!GqLS[[E5I "!Yq$%78D#hq"o5H"42C!-dC!@JD$ $<'7a<!!Yq$%78D"4.CQw!|"*6!aR=#">+D#-HHQw!|+D#v>>##a1d!34(1b/1tX.#D#v66
 ))A,C#DVAs1dU'CDdKVU U!!"3-1'ilFCC !**--aj!&&='ilFCCAGG^ !**--!+-?@A%av6	6t9r   Nc                 4   	
 t         t              r	t        dd      	t         t              r.t	         j
                  d   t        	t        	      |            S t         t              r|j                  t        dt                    }t        |t              rt        |t              r|}n |fS t	         j
                  d   t        t        	t        	      |      t        	t        	       |                  S t         t               r|j                  t        j"                  dd            }t        |t              rt        |t              r|}n |fS t	         j
                  d   t        t        	t%        	      |      t        	t%        	       |                  S t         t&              rz|j                  t        j(                  dd            }t        |t              rt        |t              r|}n |fS t	         j
                  d   t        	t+        	      |            S t         t,              rd|t        dd      z
  }t        |t.              rt        |t              r|}n |fS t	         j
                  d   t        	t1        	      |            S t         t2              rc|t        d      z
  }t        |t.              rt        |t              r|}n |fS t	         j
                  d   t        	t5        	      |            S y
t         t6              r`t        |t              rPd } | j8                        \  
t        dd      	 	
fd	}t        |D cg c]
  } ||       c} }|fS  |fS c c}w )ai  Helper function for inverting trigonometric and hyperbolic functions.

    This helper only handles inversion over the reals.

    For trigonometric functions only finite `g_ys` sets are implemented.

    For hyperbolic functions the set `g_ys` is checked against the domain of the
    respective inverse functions. Infinite `g_ys` sets are also supported.
    r   Tr   r   r   c                 "   t          t        t        d fdt        z  t	        dd      ft
        t        d fdt        z  t	        dd      ft        t        ft        t        j                  ft        t        ft        t        j                  ft        t        d fdt        z  t        t	        t          d      t	        dt                     ft"        t$        d fdt        z  t        t	        t          d      t	        dt                     fia t         |    S )Nc                 &    t         t        |       z
  S N)r   r7   r   s    r   <lambda>zC_invert_trig_hyp_real.<locals>._get_trig_inverses.<locals>.<lambda>      BtAwJ r   r   r   r   c                     t        |        S r   )r6   r   s    r   r   zC_invert_trig_hyp_real.<locals>._get_trig_inverses.<locals>.<lambda>      T!WH r   c                     t        |        S r   )r;   r   s    r   r   zC_invert_trig_hyp_real.<locals>._get_trig_inverses.<locals>.<lambda>  r   r   c                 &    t         t        |       z
  S r   )r   r:   r   s    r   r   zC_invert_trig_hyp_real.<locals>._get_trig_inverses.<locals>.<lambda>  r   r   )_trig_inversesr1   r7   r   rV   r2   r6   r/   r8   r   r   r0   r9   r3   r;   rX   r   r4   r:   funcs    r   _get_trig_inversesz1_invert_trig_hyp_real.<locals>._get_trig_inverses  s    %D"672xAOD"45qtXb!_MD7B0D7B0D"45qthsB/!RACD"672hsB/!RAC"D "$''r   integerc                 N   t        D cg c])  }t        	z   ||       z   t        j                        + c} }t	        j
                  d   |      \  }}|k(  r
j                  |       }t        ||      S t        t        |       t        j                        S c c}w Nr   )
rX   rU   r   Integersr   r   containsrY   r   r   )r   invinvsimginv_finv_g_yscondsr   invsr   periodrngr   s         r   create_return_setz0_invert_trig_hyp_real.<locals>.create_return_set  s    FJL?BF1Hs1v-qzz:L MG*166!9gvFOE8Q#FE8<<#FBq!Hagg>>Ls   .B"N)r   rC   r   rD   r   r   rU   rJ   rE   r   rV   r   rW   rT   rX   rK   rH   LopenrN   rF   openrL   rG   r[   rM   rI   rO   rQ   r   )r   r   r   g_ys_domr   r  r   retsetr   r   r  r  s   ` `     @@@@r   r   r   M  s     !'(#D!aq	8AuQx+FOOa~~hq"o6H(L1dI.  $Ht9$q	5E!Hh/U1XIx0,239; ; a~~hnnQ&:;H(L1dI.#Ht9$q	5E!Hh/U1XIx0,239; ; a~~hmmB&:;H(L1dI.#Ht9$q	E!Hh/9 9 ahr1o-H(J/dI.#Ht9$q	E!Hh/9 9 ail*H(J/dI.#Ht9$q	E!Hh/9 9  
A,	-*T92M	( /qvv6fc#t$		? 		? t<!*1-<= 4y	 =s   :Nc                 ^   	
 t         t              rt        |t              rfd}t        dd      t        j
                  
 |       D ]C  }
t        |D cg c],  }t        t         ||            t        j                        . c} z  
E t         j                  d   
      S t         t              r`t        |t              rPd } | j                        \  
	t        dd      	 
fd}t        |D cg c]
  } ||       c} }|fS  |fS c c}w c c}w )aR  Helper function for inverting trigonometric and hyperbolic functions.

    This helper only handles inversion over the complex numbers.
    Only finite `g_ys` sets are implemented.

    Handling of singularities is only implemented for hyperbolic equations.
    In case of a symbolic element g in g_ys a ConditionSet may be returned.
    c                 <    t         t        t        f      r(t         t              rt        nt        fdfdfS t         t
        t        f      r(t         t
              rt        nt        fdfdfS t         t        t        f      r fdfS y )Nc                 .    dz  t         z   |       z   S Nr   r   r   Fr   s    r   r   z7_invert_trig_hyp_complex.<locals>.inv.<locals>.<lambda>      ac"fqtm r   c                 <    dz  t         z  t         z    |       z
  S r  r  r  s    r   r   z7_invert_trig_hyp_complex.<locals>.inv.<locals>.<lambda>  s    ac"frkAaD0 r   c                 .    dz  t         z   |       z   S r  r  r  s    r   r   z7_invert_trig_hyp_complex.<locals>.inv.<locals>.<lambda>  r  r   c                 .    dz  t         z   |       z
  S r  r  r  s    r   r   z7_invert_trig_hyp_complex.<locals>.inv.<locals>.<lambda>  r  r   c                 D    t         z   j                         |       z   S r   )r   r   )r   r   trigs    r   r   z7_invert_trig_hyp_complex.<locals>.inv.<locals>.<lambda>  s    !B$):": r   )r   r1   r4   r7   r:   r2   r3   r6   r;   r/   r0   )r  r  r   s   `@r   r   z%_invert_trig_hyp_complex.<locals>.inv  s    $c
+&tS1Dt+02 2 $c
+&tS1Dt++- - $c
+:<< ,r   r   Tr   r   c                 x   t         t        t        d fdt        z  t        z  dft
        t        d fdt        z  t        z  dft        t        ft        t        z  dft        t        ft        t        z  dft        t        d fdt        z  t        z  dft        t        d fdt        z  t        z  dfia t         |    S )	Nc                 4    t         t        z  t        |       z
  S r   )r   r   rJ   r   s    r   r   zE_invert_trig_hyp_complex.<locals>._get_hyp_inverses.<locals>.<lambda>      ad58m r   r   r   c                     t        |        S r   )rK   r   s    r   r   zE_invert_trig_hyp_complex.<locals>._get_hyp_inverses.<locals>.<lambda>      uQxi r   )r   r   c                     t        |        S r   )rN   r   s    r   r   zE_invert_trig_hyp_complex.<locals>._get_hyp_inverses.<locals>.<lambda>  r  r   )r   c                 4    t         t        z  t        |       z
  S r   )r   r   rO   r   s    r   r   zE_invert_trig_hyp_complex.<locals>._get_hyp_inverses.<locals>.<lambda>  r  r   )_hyp_inversesrD   rJ   r   r   rE   rK   rF   rL   rG   rM   rH   rN   rI   rO   r   s    r   _get_hyp_inversesz3_invert_trig_hyp_complex.<locals>._get_hyp_inverses  s    $U$;<ac"fbIU$78!A#b&"EUHadG4UHadG4U$78!A#b&%HU$;<ac"feL!N !&&r   c                 v   t        	D cg c])  }t        

z   ||       z   t        j                        + c} }t	        j
                  d   |      \  }}|k(  r-t        D cg c]  }t        | |       c} }t        ||      S t        t        |       t        j                        S c c}w c c}w r   )rX   rU   r   r   r   r   rR   r   rY   r   r   )r   r   r   r   r   er   exclr   r   r   r  r   s          r   r  z3_invert_trig_hyp_complex.<locals>.create_return_set  s    FJL?BF1Hs1v-qzz:L MG-affQi&IOE851bAh56#FE8<<#FBq!HakkBBL 6s   .B1(B6)r   rQ   rT   r   r   r   rX   rU   r   r   r   r   rC   r   )r   r   r   r   Lr   r  r  r  r   r   r   r  s   ` `      @@@@r   _invert_trig_hyp_complexr"    s    !*+
40K	= #t$zzQ 	RAE4PaHVAqt_ajjAPQQD	Rqvvay$77	A)	*z$	/J
	' /qvv6fd#t$		C 		C t<!*1-<= 4yW QN =s   1D%
D*c                    | |k(  s|t         j                  u r||fS t        d      }| j                  rJ| j	                  |      \  }}|t         j
                  ur$t        |t        t        |||z
        |      |      S | j                  r| j	                  |      \  }}|t         j                  urg|t         j                  t         j                  t         j                  hv r|t         j                  fS t        |t        t        |||z        |      |      S | j                  rB| j                  \  }}|j                   r'|t#        d      k(  r|j$                  rt        |||      S t'        | d      r| j)                         t+        | t,              st+        | t.              sut+        | t0              set3        | j                        dkD  rt5        d      t        | j                  d   t        t        | | j)                         |            |      |      S t+        | t0              s+| j                  r| j6                  t         j8                  k(  r|t+        |t:              r|j<                  j>                  }|j<                  j@                  }	t        djC                  t3        |	                  }
|
f|	z   }tE        t        t        |ftF        d|
z  tH        z  tK        |      z   z  tM        tO        |            z         t         jP                  t3        |      z        g }t        | j0                  ||      S t+        |t"              rtE        |D cg c]]  }|dk7  rVt        t        |tF        d|z  tH        z  tK        |      z   z  tM        tO        |            z         t         jP                        _ c} }t        | j0                  ||      S t+        | t,        t.        f      rtS        | ||      S | |fS c c}w )r   r   r   r   r   r   zk{}r   )*r   r   r   r   r   r   r   rU   r   r   r   NegativeInfinityComplexInfinityInfinityr   r   is_RationalrT   r   r   r   r   rQ   rC   r5   r   r   r   r   rZ   lamdaexpr	variablesformatrX   r   r   r@   r.   r?   r   r"  )r   r   r   r   r   r   r   r   	g_ys_expr	g_ys_varskg_ys_vars_1exp_invsg_ys                 r   r   r     s@    	F{dajj(~c
Axx'1AFF?"1hvaQ/?&FOOxx'1AEE>Q''):):AJJGG1::&"1hva1~t&DfMMxxVV
d 	! 4&tT6::q)!8a./a+,aqvv;?NOOqvvay'q+!))+a.(A4H&R 	R !Sahh166QVV+;dH% 

I

,,Iell3y>23A$*Kx~1Q3r6CPYNCZ@[+.s9~+>A? )ABC**sS^O_B` b c dH"155(F;;i(*.<#&#(  (q!QqSVc#h5F2G/23s8}3= )>?@zz K < =H #155(F;;!+-?@A(D&9	9t9<s   A"O3c                    |j                   sgt        |t        dt        j                              }t        | ||      }t        |  ||      }|d   |d   k7  rt        |d   t        |d   |d         fS g }|j                  D ]P  }|j                  r|j                  n|j                  }||j                  |       ;|r>|t        j                  fc S  |r/t        |D 	cg c]  }	t        |	t        dt                      c}	 }
nd}
t#        dd      }t        | t        t%        t'        ||      |      t%        t'        ||       |            |      \  }}|t)        ||
|      fS c c}	w )a  Helper function for inverting absolute value functions.

    Returns the complete result of inverting an absolute value
    function along with the conditions which must also be satisfied.

    If it is certain that all these conditions are met, a :class:`~.FiniteSet`
    of all possible solutions is returned. If any condition cannot be
    satisfied, an :class:`~.EmptySet` is returned. Otherwise, a
    :class:`~.ConditionSet` of the solutions, with all the required conditions
    specified, is returned.

    r   r   Tr   r   )is_FiniteSetrW   rV   r   r&  r   NotImplementedErrorrX   r   	is_Numberis_nonnegativer   r   r   rR   r\   r   r   rU   r   rY   )r   r   r   pospargnargunknownr   okr   
conditionsr   g_xvaluess                 r   r   r   G  sj     4!QZZ!89AsF+QBV,7d1g%%Awd1gtAw/// GYY &!"Q!--:NN11::%%&  $Ax27  
 
cA q%1t$A2%#'(.0KC S*f555s    !E'c                 b    t        |       t        |      }} |j                  ryt        | ||      S )aX  Returns False if point p is infinite or any subexpression of f
    is infinite or becomes so after replacing symbol with p. If none of
    these conditions is met then True will be returned.

    Examples
    ========

    >>> from sympy import Mul, oo
    >>> from sympy.abc import x
    >>> from sympy.solvers.solveset import domain_check
    >>> g = 1/(1 + (1/(x + 1))**2)
    >>> domain_check(g, x, -1)
    False
    >>> domain_check(x**2, x, 0)
    True
    >>> domain_check(1/x, x, oo)
    False

    * The function relies on the assumption that the original form
      of the equation has not been changed by automatic simplification.

    >>> domain_check(x/x, x, 0) # x/x is automatically simplified to 1
    True

    * To deal with automatic evaluations use evaluate=False:

    >>> domain_check(Mul(x, 1/x, evaluate=False), x, 0)
    False
    F)r   is_infinite_domain_check)r   r   ps      r   domain_checkrC  x  s.    < 1:wqzqA}}FA&&r   c                    | j                   r| j                  ry| j                        j                  ryt	        | t
              r\| j                  D ]L  \  }}|j                        }|t        j                  u r+|t        j                  u rt        |      c S  y y t        fd| j                  D              S )NTFc              3   8   K   | ]  }t        |        y wr   )rA  ).0r   rB  r   s     r   	<genexpr>z _domain_check.<locals>.<genexpr>  s"      $ !FA. $   )is_Atom	is_finitesubsr@  r   r=   r   r   r   r   rA  all)r   r   rB  r)  condcondsubss    ``   r   rA  rA    s    yyQ[[	
		&	&	Ay	! && 	JD$yy+H177"QVV#$T6155 	"  $FF$ $ 	$r   c                     fd}| j                   D ci c]  }|t        di  ||       }}| j                  |      j                  S c c}w )a'  
    Return True if the given expression is finite. For symbols that
    do not assign a value for `complex` and/or `real`, the domain will
    be used to assign a value; symbols that do not assign a value
    for `finite` will be made finite. All other assumptions are
    left unmodified.
    c                     | j                   }|j                  d|j                  dd             j                  t        j
                        r|j                  dd       |S |j                  dd       |S )NfiniteTr   complex)assumptions0
setdefaultgetr   r   r   )r   Ar   s     r   assumptionsz0_is_finite_with_finite_vars.<locals>.assumptions  sa    NN	XquuXt45AGG$LL&
  LLD)r   r   )r   r   xreplacerJ  )r   r   rW  r   repss    `   r   _is_finite_with_finite_varsrZ    sM    
 12?1Au&{1~&&?D?::d%%% @s   Ac                     |j                   s|j                  rt         fd|j                  D              S |j                  r3|j
                  j                        st         |j                        S y|j                        syt        |       r-	 t        |j                  d         }|j                         dk  S y# t        $ r Y yw xY w)aq   Tests whether the equation is an equation of the given function class.

    The given equation belongs to the given function class if it is
    comprised of functions of the function class which are multiplied by
    or added to expressions independent of the symbol. In addition, the
    arguments of all such functions must be linear in the symbol as well.

    Examples
    ========

    >>> from sympy.solvers.solveset import _is_function_class_equation
    >>> from sympy import tan, sin, tanh, sinh, exp
    >>> from sympy.abc import x
    >>> from sympy.functions.elementary.trigonometric import TrigonometricFunction
    >>> from sympy.functions.elementary.hyperbolic import HyperbolicFunction
    >>> _is_function_class_equation(TrigonometricFunction, exp(x) + tan(x), x)
    False
    >>> _is_function_class_equation(TrigonometricFunction, tan(x) + sin(x), x)
    True
    >>> _is_function_class_equation(TrigonometricFunction, tan(x**2), x)
    False
    >>> _is_function_class_equation(TrigonometricFunction, tan(x + 2), x)
    True
    >>> _is_function_class_equation(HyperbolicFunction, tanh(x) + sinh(x), x)
    True
    c              3   8   K   | ]  }t        |        y wr   )_is_function_class_equation)rF  r@   
func_classr   s     r   rG  z._is_function_class_equation.<locals>.<genexpr>  s"      & /z3G &rH  FTr   r   )r   r   rL  r   r   r5   r   r]  r   r   rf   rg   ri   )r^  r   r   r   s   ` ` r   r]  r]    s    6 	xx188 &ff& & 	& 	xxuuyy .z1666JJ55=!Z 	QVVAY'A88:?"   		s   +C 	CCc                 J   t        t        | d      d      } t        |       \  }}|j                  |      s	 t	        |||      S t        |||      }t        |||      }||z
  S # t
        $ r t        |t        | d      |      cY S t        $ r t        j                  cY S w xY w)z solve rational functionsT)	recursive)deepr   )rh   r   r)   r   _solve_as_polyr4  rY   r   rl   r   r   	_solveset)r   r   r   r   r   valid_solnsinvalid_solnss          r   _solve_as_rationalrf    s    !t,48AA;DAq55=		!!VV44  662!!VV4]** # 	:  1a&99 	::	s   A% % B"B"!B"c                       e Zd ZdZy)_SolveTrig1Errorz0Raised when _solve_trig1 heuristics do not applyNr   r   r   r   rh  rh    s    :r   rh  c           
         d\  }}t        |       D ]C  }t        |t        t        f      s|j	                  |      s,|s|d}}3||k(  r|dz  }>d\  }} n |dk(  rt        | d||      \  }}||k(  rd}|j                  |hz
  re|j                  d   j                  |d      \  }	}
|
j                  |d      \  }}
|j                         \  }}t        |d      t        |d      z  }t        |||      S t        |t        | d      |      S |r^t        d      }| j                  ||      }t        |||      }t        |t               r$t#        |D cg c]  }t%        ||z
  ||       c} S d	}	 t'        | ||      }|S c c}w # t(        $ r3 	 t+        | ||      }Y |S # t,        $ r t/        t1        d
            w xY ww xY w)z@Function to call other helpers to solve trigonometric equations r   r   )Fr   r   Tas_AddFr   Nzj
                Solution to this kind of trigonometric equations
                is yet to be implemented)r#   r   rQ   rC   r   r   r   r   r   r   r   rY   r   r   rK  solvesetrT   rX   _solve_trig_solve_trig1rh  _solve_trig2r   r4  rz   )r   r   r   	trig_exprcountr)  r   solrM  r   r   mr   r   r   f_covsol_covr   s                     r   rm  rm    s    Iu"1% 	d2.0 159XXf5E#'5	"
#+ 	5	 zAvv.3;D%%0 ~~a(77t7L1''u'=1++-S#qzBsAJ.c221a&99	#Jy!$5!V,gy)DKLq+ik66:LN N C
.1ff- J M  .	.q&&1C
 J	  	.%j 2, '- . .	.	.s$   E?0F 	G FF<<G c           
         t        d      }t        t        |       r7t        |      }|j	                  t
        j                        rt        nt        }nt        t        |z        }t        }t        |       } | }| j                  t        t              }|D cg c]  }|j                  d    }	}t        fd|	D              st        ||      S g }
g }|	D ]  }	 t!        |      }|j'                         dkD  rt%        d      |j'                         dk(  rB|j)                         d   }|j+                  t-        |      d          |
j+                  t-        |      d           t/        |
      t1        |      z  }| j3                  ||z        } | j5                  t              } t7        |       } t-        |       \  }}t        d      }|j9                         |j9                         }}|j3                  ||      |j3                  ||      }}|j;                  |      s|j;                  |      rt%        d      t=        ||      t=        ||      z
  }t?        |t@              rt%        d	      t?        |tB              rt        d
 |D              rt%        d      |j3                  ||z        }tE        |D cg c]  } |||      d    c} }|j;                  tF              rn|j                  tF              }t-        |      \  }} |jH                  |ddid   } |jH                  |ddid   }tK        tM        |d      tM        |d            }nd}|t
        jN                  u rtA        ||      S tA        |tQ        ||            S |t
        jR                  u rt
        jR                  S t%        d      c c}w # t"        $ r t%        d      w xY wc c}w )a  Primary solver for trigonometric and hyperbolic equations

    Returns either the solution set as a ConditionSet (auto-evaluated to a
    union of ImageSets if no variables besides 'symbol' are involved) or
    raises _SolveTrig1Error if f == 0 cannot be solved.

    Notes
    =====
    Algorithm:
    1. Do a change of variable x -> mu*x in arguments to trigonometric and
    hyperbolic functions, in order to reduce them to small integers. (This
    step is crucial to keep the degrees of the polynomials of step 4 low.)
    2. Rewrite trigonometric/hyperbolic functions as exponentials.
    3. Proceed to a 2nd change of variable, replacing exp(I*x) or exp(x) by y.
    4. Solve the resulting rational equation.
    5. Use invert_complex or invert_real to return to the original variable.
    6. If the coefficients of 'symbol' were symbolic in nature, add the
    necessary consistency conditions in a ConditionSet.

    r   r   c              3   @   K   | ]  }|j                          y wr   )r   )rF  r   r   s     r   rG  z_solve_trig1.<locals>.<genexpr>|  s     5quuV}5   z!trig argument is not a polynomialr   z&degree of variable must not exceed oner   zchange of variable not possiblez$polynomial has ConditionSet solutionc              3   <   K   | ]  }t        |t                y wr   )r   rj   rF  r   s     r   rG  z_solve_trig1.<locals>.<genexpr>  s     4z!V$4   z#polynomial results in RootOf objectrk  FTz(polynomial solutions must form FiniteSet)*r   r]  rC   r5   r   r   r   r   invert_complexr   r*   r   rQ   r   anyrl  rf   ri   rh  rg   
all_coeffsr   r)   r%   r$   rK  rewriterh   expandr   solveset_complexr   rY   rT   rX   r    r   rR   r   r   rW   r   )r   r   r   r   covinverter
f_originaltrig_functionsr  trig_argumentsdenominators
numeratorsarpoly_arcmur   r   r   solnsr   resultsymsmunummudencondnumconddenrM  s    `                          r   rn  rn  X  sq   , 	c
A"#5q&A!f"("2"2177";;!A#h!AJWW24FGN)78AaffQi8N8 5n55
FF33LJ ,	H2v&G >>a"#KLL>>q  #(1+a.)HQKN+, 
\	3z?	*B	vr!tA			#AAA;DAqc
A88:qxxzqA66#q>166#q>qAuuQx1558@AAQ"%5a%;;E%&EFF%#4e44"#HIIhhq&)$eD#q&1!4DE 66&>::f%D#B<LE5*e**D??BG*e**D??BGr'1~r'1~6DD Q[[   f55l66.JKK	!**	zzIJJA 9  	H"#FGG	H< Es   N>O>OOc                    t        |       } | }| j                  t        t        t        t
        t        t              }|D cg c]  }|j                  d    }}g }g }|st        |t        |d      |      S |D ]  }		 t        |	|      }
|
j                         dkD  rt        d      |
j                         dk(  rB|
j                         d   }	 |j!                  t#        |      j$                         |j!                  t#        |      j&                          t+        d      }t#        d      t-        | z  t/        | z  }| j1                  |||z        } | j3                  t              } t5        |       } t7        |       } t9        |       \  }}t+        d      }|j;                         |j;                         }}|j1                  t	        |      |      |j1                  t	        |      |      }}|j=                  |      s|j=                  |      rt        |t        |d      |      S t?        ||t@        jB                        t?        ||t@        jB                        z
  }tE        |tF              rtI        |D cg c]  }tK        t	        ||z        ||      d     c} }tK        t	        ||z        tL        |      d   }t        |      t        |      kD  rtI        ||      }tO        ||      S |t@        jP                  u rt@        jP                  S t        |t        |d      t@        jB                        S c c}w # t        $ r t        d      w xY w# t(        $ r t        |t        |d      |      cY c S w xY wc c}w )zVSecondary helper to solve trigonometric equations,
    called when first helper fails r   z9give up, we cannot solve if this is not a polynomial in xr   z:degree of variable inside polynomial should not exceed oner   r   r   ))r*   r   r1   r2   r/   r3   r0   r4   r   rY   r   rf   ri   r   rg   r~  r   r   rB  q	TypeErrorr   
number_lcm
number_gcdrK  r  r   rh   r)   r  r   rl  r   r   r   rT   rX   r   r   rW   r   )r   r   r   r  r  r  r  r  r  r  r  r  r   r  r   r   r   r  r   r  dsols                        r   ro  ro    s    	AJWWS#sCc:N)78AaffQi8N8LJ
 FBz1$5v>>
  C	Z2v&G >>aYZZ>>q  #	Chqkmm,.C  	c
A	!Z.	.z:/F	FB	vr!tA			#AAAAA;DAqc
A88:qxxzqA66#a&!affSVQ/qAuuQx1558FBz1$5v>>Q177#hq!QWW&==E%# %' %S^Q?B ' (3vby>2v6q9!9vay 64(FFF++	!**	zzFBz1$5qww??q 9   	ZXYY	Z  	C:q(96BB	C*'s+    L4;L9AM7#M99M M65M6c           	         d}| j                  |      rt        | |dddd      }t        |j                               }t	        | |      |k  rt        |j                          }nNt        | |      } |j                         } |j                         t        |      k  r
t        | }n
t        |t        | d      |      }nt        |       }|t        |t        | d      |      }|j                  D cg c]  }|j                  |      s| }}t        |      dk(  r|t        ||d         }|j                  }	 |j                         }
t         |j                         |j                  d      }t        t        |ddd      j                          }t        |      |
k  rt        |t        | d      |      }|	|k7  rt!        d	      }|j#                  t$        j&                        rt(        nt*        } ||	||      \  }}||k(  r|t-        |D cg c]  }|j/                  ||       c} }t1        |t
              rut1        |	t2              re|	j4                  j6                  rOt        |D cg c]  }t9        |       c} }n/t        |t        | d      |      }nt        |t        | d      |      }|t1        |t
              r<t;        d
 |D              r*t!        d      }t=        t?        |tA        |            |      }t1        |t
              r$|t$        jB                  k7  r|jE                  |      }|S t        |t        | d      |      S c c}w c c}w c c}w )z
    Solve the equation using polynomial techniques if it already is a
    polynomial equation or, with a change of variables, can be made so.
    NTEX)cubicsquarticsquinticsr   r   r   )	composite)r  r  r  r   c              3      K   | ]<  }|j                  t        t              t               k(  xr t	        |t
                > y wr   )r   r    r   setr   rj   rz  s     r   rG  z!_solve_as_poly.<locals>.<genexpr>5  s=      $ 776<0CE9W*QPVBW>WW $s   AAr   )#is_polynomialre   sumr>  rg   rT   keysrf   	all_rootsr   rY   r   gensr   genas_exprr   r   r   r   r   r|  rX   rK  r   r   r   r'  r   rL  rU   r   r   r   intersection)r   r   r   r  r  	num_rootsro   r   r  r  deg
poly_solnsr   r  lhsrhs_sr   r   s                     r   rb  rb    s   
 Fvat#D2'	!V	)

-F6?D"DNN$Et{{}E
*"E*%fbAh?Aw<!&"Q(F;F996af66t9>d1g&D((C$++-CDAD"E$td37%99=AJ :$%fbAh?f}#J*0*:*:177*C;%c1f5
U&="z$J!UZZ1%5$JKF!&)4C :"%(("6"6!*F,KqZ],K!L)&"Q(FCF!&"Q(F;Ffi(
  $"$ $#J!&N1,=">Gfi(Vq{{-B ((0FFBq!Hf55W 7$ %K -Ls   4MMM-Mc                     |}|r|n g f\  }}|s2 ||      t        t               D cg c]  } ||       c} z
  }n|\  }	}
 ||	t        z
  |	      s5t        dd      }|
j	                  |	|i      }
|j	                  |	|i      }|}	 ||
      } |||	      }t        |D cg c]  }t        t        |	|      |       c} } fdfd |      }|S c c}w c c}w )z2 Helper function to solve equations with radicals yrealTr   c                     g }g }| D ]2  }t        |      r|j                  |       "|j                  |       4 t        | t        t	        d      t        |       z   S r   )rt   r   rT   rY   r   )	solutionsf_setc_setr   r   r   s       r   check_finitesetz'_solve_radical.<locals>.check_finitesetU  sd     	 A61%QQ		 
 % <1a)UBS#TTTr   c                 \   | t         j                  u r| S t        | t              r| S t        | t              r |       S t        | t
              r!| j                  \  }}t         |      |      S t        | t              r&t        | j                  D cg c]
  } |       c} S | S c c}w r   )r   r   r   rY   rT   r[   r   rX   )r  rV  Br   r  	check_sets       r   r  z!_solve_radical.<locals>.check_set_  s    

"	<0	9-"9--	:.>>DAqilA..	5)@A9Q<@AA 	 As   B))rX   ru   r   r   rX  rU   r   )r   unradfr   solveset_solverr   eqr  r   r  r   yeqr  g_y_sf_y_solsr1  solution_setr  r  s   ` `             @@r   _solve_radicalr  B  s   
Ccq"gGB V,q&8IJ1OAv.JKL 3q1ua('-E,,5z*CaZ(BAV,"2q)$)+  "&C.(; + ,U$ V$LW K+s   C"
+C'c                    |j                  t        j                        st        t	        d            t        d      t        d      t        d      }}}| j                  |t        |      z  |z         xs i }|||fD cg c]"  }|j                  |t        j                        $ c}\  }}	}
|j                  s|	j                  st        |	||      }ddlm}  ||	dk\  |d|d	
      }|j                  |      }t        ||	z  |
z   |      j!                  |      }t        ||	 z  |
z   |      j!                  |      }t#        ||      S t%        |t'        | d      |      S c c}w )zE Helper function to solve equation involving absolute value function zR
            Absolute values cannot be inverted in the
            complex domain.rB  r  rr   solve_univariate_inequalityr   FT)
relationalr   
continuous)r   r   r   r   rz   r	   matchr?   rU  r   r   r   inequalitiesr  
complementsolveset_realr   rX   rY   r   )r   r   r   rB  r  r  pattern_matchr   f_pf_qf_rr  
q_pos_cond
q_neg_cond
sols_q_pos
sols_q_negs                   r   
_solve_absr  v  sP   AGG$ %   ! 	! 3icDI!qAGGAc!fHqL)/RM<=q!9Ea]&&q!&&1EMCcKK3;;"37=06<A&]ac
**62
"3s7S=+133<9Z3H 	"3:#3+133<9Z3H 	Z,,FBq!Hf55 Fs    'E c           
         ddl m}  || |      }t        d      }|D ]  }t        |||      }t	        ||      }t
        j                  }t        |t              r6|D ]/  }	t        t        ||	      ||      }
t        |
t              r+||
z  }1 n0t        |t              r|f}nAt        |t              r|j                  }n$|t
        j                  u rt
        j                  c S D ]  }t        t        |j                  j                  |      ||      }t!        |j                  j                  j"                        d   }|j$                  \  }t        |t              r|}n<t        |t              r,t        |j                  d   t              r|j                  d   }D ]  }|t        t'        ||      |      z  }  |t
        j                  u rt        |t        | d      |      c S |} |S )a  
    Function to solve equations via the principle of "Decomposition
    and Rewriting".

    Examples
    ========
    >>> from sympy import exp, sin, Symbol, pprint, S
    >>> from sympy.solvers.solveset import solve_decomposition as sd
    >>> x = Symbol('x')
    >>> f1 = exp(2*x) - 3*exp(x) + 2
    >>> sd(f1, x, S.Reals)
    {0, log(2)}
    >>> f2 = sin(x)**2 + 2*sin(x) + 1
    >>> pprint(sd(f2, x, S.Reals), use_unicode=False)
              3*pi
    {2*n*pi + ---- | n in Integers}
               2
    >>> f3 = sin(x + 2)
    >>> pprint(sd(f3, x, S.Reals), use_unicode=False)
    {2*n*pi - 2 | n in Integers} U {2*n*pi - 2 + pi | n in Integers}

    r   )
decompogenr   )sympy.solvers.decompogenr  rT   r   rW   r   r   r   rl  r   rY   rZ   rX   r   r(  r)  tupler   	base_setsr   )r   r   r   r  g_sy_sr   franger  r   r  	iter_isetisetnew_solutions	dummy_varbase_set	new_exprsnew_exprs                     r   solve_decompositionr    s   . 4
Q
C A,C '66263'c9% ($R1Xvv>	!)\:i'F( #x( F	C'HH	

" zz!! N (DJJOOQ)? P!$**//">">?B	"nnmY7 -I|<!-"4"4Q"7C$1$6$6q$9	 ) NHhvi'BHMMFNN QZZ1a&99O'R Jr   Fc           
         ddl m} t        | t              rS | }| j                  rS| j                  |d      \  }} |t        j                  t        j                  t        j                  hv rt        |      } n~| j                  rr| j                  |      \  }}|j                  |d      \  }	}|	t        j                  t        j                  t        j                  t        j                  hvr||	z  |z   } fd}
fd}t        j                  }| j                         j                  rS | j!                  |      st        j                  S | j                  rGt#        fd| j$                  D              r)t'        | j$                  D 	cg c]  }	 |
|	|       c}	 }n/t)        t*        | |      st)        t,        | |      rt/        | |      }nt        | t0              rH| j$                  d   }t3        t5        t7        |      dkD  |      t5        t9        |      |            }n| j:                  rH| j=                        }|D ]0  \  }}|j>                  r|jA                         } |
|||      }||z  }2 nRt        | tB              r- |
tE        | jF                  | jH                   d      |      }n| j>                  rd	d
l%m&} 	  || |d      }|S tS        | |      rtU        | |      }n || d|      \  }}||k(  rDt        |tV              r0tW        |D cg c]  }tY         ||      j[                            c} }|}nt        |tV              rI|D cg c]  }||z
  	 c}D ]1  }|| k(  rt]        | |      }|r|t_        ||||
      z  }*|j!                  t`              r|tc        | |      z  }Pte        ||      }t        |tP              s||z  }stg        ||      }t        |tP              r|ji                         }|j                  rs||k7  rn|j                  |      \  }}|j                  sNg }tY        jj                  |      D ],  }|j!                  |      s|jm                   |
||             . t'        | }||z  }&| |
||      z  }4 n)|t        j                  urtQ        |tC        | d            }t        |tP              rct        | tn              rS| jq                         \  }} | j!                  |      r/t5        ||      }!t        |!tP              st5        | |      }"|!|"z
  }|rt        |tP              r|S t        |tn              r-|j                  |d      d	   }#|#j                  |d      d	   }#n|}#t        |tV              r3tW        |D $cg c]!  }$t        |$tr              stu        |#||$      r|$# c}$ }|S c c}	w # tN        $ r tQ        ||       }Y |S w xY wc c}w c c}w c c}$w )zHelper for solveset to return a result from an expression
    that has already been sympify'ed and is known to contain the
    given symbol.r   )signsimpFrj  c                     t        | ||      S r   )rc  )r   r   r   s      r   r   z_solveset.<locals>.<lambda>  s    1a)@ r   c                      t        | ||      S r   )r   )r   r   r   r   s      r   r   z_solveset.<locals>.<lambda>  s    gaff&E r   c              3   6   K   | ]  }t        |        y wr   )rZ  )rF  rs  r   s     r   rG  z_solveset.<locals>.<genexpr>  s        6a@    r   r   r  )r   r  T);sympy.simplify.simplifyr  r   rS   r   r   r   r%  r$  r&  rh   r   r   r   r  r   r   rL  r   rX   r]  rQ   rC   rm  r@   rW   rc  rA   rB   is_Piecewiseas_expr_set_pairsis_Relationalas_setr   r   r  r   r  r  r4  rY   _is_modular_solve_modularrT   r
   as_content_primitiverv   r  r?   r  rf  
_transolverk   	make_argsr   r   r   rj   rC  )%r   r   r   _checkr  orig_fcoeffr   r   rs  solverr  r  expr_set_pairsr)  in_setr  r  r  r  r   r   equationuresult_rationalt_resultfactored_dep	t_resultsfacr   r   _resultsingularitiesfxr   s%     `                                  r   rc  rc    s   
 1![!Fxx##F5#9qQ&&(:(:AJJGG A	
'1u51Q&&

002 2!aA "(@FEHZZFxxzUU6]zz	
c VV  AFF;q6*;<
%&;Q
G'(:AvFQ/	As	FF1Ii1	66B'1vv>@	
,,V4, 	NT6##40EeOF		
 
Ar	AEEAEE6E:FFK	
=	50vf8F 	Q	662aF+
U&= %+!"$$ %(QK446%8 $$ % Fy)2783S3Y8 %7q=a(A.11717#9 9 "c**Q"??*<Xvv*V)/<H"o5F (2(FF'KH)(LA ,4??+<#+??x87K-5-D-DV-LFAs+.:: 57	36==3J )VC/2wwv090@0@VAT0U)V 49)3D"h.FfXv66FK%7N !**$!&"Q(F;F&,'a'')HCwwv#C8!'<8$-c66$BM$}4Ffl+ M fd#&&vd&;A>B""6%"8;BBfi(F !6q#Av.%b&!4 "# !6 7F Mi <. # 	5!&!V4F	5 $$ 9F!6s*   WW" $#W?$X1&X	"W<;W<c                 T   | j                  t              syt        | j                  t                    }t	        |      dk(  xre |d   j
                  d   j                  |      xrB |d   j
                  d   j                  xr$ t        d t        t        |             D              S )aA  
    Helper function to check below mentioned types of modular equations.
    ``A - Mod(B, C) = 0``

    A -> This can or cannot be a function of symbol.
    B -> This is surely a function of symbol.
    C -> It is an integer.

    Parameters
    ==========

    f : Expr
        The equation to be checked.

    symbol : Symbol
        The concerned variable for which the equation is to be checked.

    Examples
    ========

    >>> from sympy import symbols, exp, Mod
    >>> from sympy.solvers.solveset import _is_modular as check
    >>> x, y = symbols('x y')
    >>> check(Mod(x, 3) - 1, x)
    True
    >>> check(Mod(x, 3) - 1, y)
    False
    >>> check(Mod(x, 3)**2 - 5, x)
    False
    >>> check(Mod(x, 3)**2 - y, x)
    False
    >>> check(exp(Mod(x, 3)) - 1, x)
    False
    >>> check(Mod(3, y) - 1, y)
    False
    Fr   r   c              3   <   K   | ]  }t        |t                y wr   )r   r   rF  terms     r   rG  z_is_modular.<locals>.<genexpr>  s      0 4% 0r{  )	r   r   r   r   r   r   
is_integerr}  _term_factors)r   r   modtermss      r   r  r  {  s    L 55: AGGCL!HMQ 0QKQ##F+0QKQ**0  0]1-.0 0r   c           
      F   | j                   \  }}|j                  du r|t        j                  fS |j                  du s$t        d t        t        |            D              r| |fS t        |      t        |      k\  r|t        j                  fS ||k(  r,|t        t        |||z  |z         t        j                        fS |j                  rW|j                  |      \  }}|t        j                  ur1|t        ||      z
  }t!        t        ||      t        ||      ||      S |j"                  rW|j                  |      \  }}|t        j$                  ur1|t'        ||      z  }t!        t        ||      t        ||      ||      S |j(                  r|j                   \  }	}
|
j+                  |      r-|	j+                  |      s|j,                  s&|j,                  r|j.                  j,                  r| |fS |j0                  t3        |j0                  |j0                        z  }	 t5        ||j0                  |j.                  j0                        }t9        |      }t;        |      D ]K  }t=        |j.                  ||t3        |j0                  |j.                  j0                        z        dk(  sI|} n |
t        t        |||z  |z         t        j>                        fS |	j+                  |      r|
j+                  |      sp	 tA        ||
|d      }|g k(  r|t        j                  fS 	 t        j                  }|D ]/  }|t        t        |||z  |z         t        j                        z  }1 |	|fS | |fS # t6        $ r | |fcY S w xY w# t6        tB        f$ r | |fcY S w xY w)a
  
    Helper function to invert modular equation.
    ``Mod(a, m) - rhs = 0``

    Generally it is inverted as (a, ImageSet(Lambda(n, m*n + rhs), S.Integers)).
    More simplified form will be returned if possible.

    If it is not invertible then (modterm, rhs) is returned.

    The following cases arise while inverting equation ``Mod(a, m) - rhs = 0``:

    1. If a is symbol then  m*n + rhs is the required solution.

    2. If a is an instance of ``Add`` then we try to find two symbol independent
       parts of a and the symbol independent part gets transferred to the other
       side and again the ``_invert_modular`` is called on the symbol
       dependent part.

    3. If a is an instance of ``Mul`` then same as we done in ``Add`` we separate
       out the symbol dependent and symbol independent parts and transfer the
       symbol independent part to the rhs with the help of invert and again the
       ``_invert_modular`` is called on the symbol dependent part.

    4. If a is an instance of ``Pow`` then two cases arise as following:

        - If a is of type (symbol_indep)**(symbol_dep) then the remainder is
          evaluated with the help of discrete_log function and then the least
          period is being found out with the help of totient function.
          period*n + remainder is the required solution in this case.
          For reference: (https://en.wikipedia.org/wiki/Euler's_theorem)

        - If a is of type (symbol_dep)**(symbol_indep) then we try to find all
          primitive solutions list with the help of nthroot_mod function.
          m*n + rem is the general solution where rem belongs to solutions list
          from nthroot_mod function.

    Parameters
    ==========

    modterm, rhs : Expr
        The modular equation to be inverted, ``modterm - rhs = 0``

    symbol : Symbol
        The variable in the equation to be inverted.

    n : Dummy
        Dummy variable for output g_n.

    Returns
    =======

    A tuple (f_x, g_n) is being returned where f_x is modular independent function
    of symbol and g_n being set of values f_x can have.

    Examples
    ========

    >>> from sympy import symbols, exp, Mod, Dummy, S
    >>> from sympy.solvers.solveset import _invert_modular as invert_modular
    >>> x, y = symbols('x y')
    >>> n = Dummy('n')
    >>> invert_modular(Mod(exp(x), 7), S(5), n, x)
    (Mod(exp(x), 7), 5)
    >>> invert_modular(Mod(x, 7), S(5), n, x)
    (x, ImageSet(Lambda(_n, 7*_n + 5), Integers))
    >>> invert_modular(Mod(3*x + 8, 7), S(5), n, x)
    (x, ImageSet(Lambda(_n, 7*_n + 6), Integers))
    >>> invert_modular(Mod(x**4, 7), S(5), n, x)
    (x, EmptySet)
    >>> invert_modular(Mod(2**(x**2 + x + 1), 7), S(2), n, x)
    (x**2 + x + 1, ImageSet(Lambda(_n, 3*_n + 1), Naturals0))

    Fc              3   8   K   | ]  }|j                   d u   yw)FN)is_realr  s     r   rG  z"_invert_modular.<locals>.<genexpr>  s!      #0 $(<<5#8 #0s   r   T)r  )"r   r
  r   r   r  r}  r   r  absrZ   r   r   r   r   r   r   _invert_modularr   r   rm   r   r   
is_Integerr   rB  r  rc   r   r>   rb   pow	Naturals0rd   r4  )modtermr   r   r   r   rs  r   r   x_indep_termr   r   mdiv	remainderr  rB  remainder_listg_nrems                     r   r  r    s4   T <<DAq
~~qzz!!
{{es #0]1-.#0  0 |
3x3q6qzz!!F{xq!A#) 4ajjAAAxx'1AFF?Q?L"3q!9c,.BAvNNxx'1AEE>va|+L"3q!9c,.BAvNNxxVV
d88FDHHV$4 <<CNNqvv7H7H|#33*QSS#%%00D$(suuaffhh?	 QZFf% qvvq!jaffhh&?"?@AEF	 &F1Hy,@"A1;;OOOXXfdhhv&6$!,S$T!J!R'!1::-- ( **C% Bxq!A#) 4ajjAAB9C<9  $|#$*  34 $|#$s$   &+M7 %N
 7NN
N N c                    t        |t        | d      |      }t        | j                  t                    d   }t
        j                   | j                  |t
        j                        z  }| j                         |   j                  r|t
        j                   z  }|j                  t
        j                        s|S |j                  |      r|S t        dd      }t        ||||      \  }}||k(  r||k(  r|S ||k(  r%|t
        j                  ur|j!                  |      S |S t#        |t$              r|j&                  j(                  }	|j&                  j*                  }
|j,                  }t/        ||	z
  |t
        j                        }t#        |t0              r3t
        j2                  }|D ]  }|t%        t5        |
|      g| z  } |}nt%        t5        |
|      g| }|j!                  |      S |S )a_  
    Helper function for solving modular equations of type ``A - Mod(B, C) = 0``,
    where A can or cannot be a function of symbol, B is surely a function of
    symbol and C is an integer.

    Currently ``_solve_modular`` is only able to solve cases
    where A is not a function of symbol.

    Parameters
    ==========

    f : Expr
        The modular equation to be solved, ``f = 0``

    symbol : Symbol
        The variable in the equation to be solved.

    domain : Set
        A set over which the equation is solved. It has to be a subset of
        Integers.

    Returns
    =======

    A set of integer solutions satisfying the given modular equation.
    A ``ConditionSet`` if the equation is unsolvable.

    Examples
    ========

    >>> from sympy.solvers.solveset import _solve_modular as solve_modulo
    >>> from sympy import S, Symbol, sin, Intersection, Interval, Mod
    >>> x = Symbol('x')
    >>> solve_modulo(Mod(5*x - 8, 7) - 3, x, S.Integers)
    ImageSet(Lambda(_n, 7*_n + 5), Integers)
    >>> solve_modulo(Mod(5*x - 8, 7) - 3, x, S.Reals)  # domain should be subset of integers.
    ConditionSet(x, Eq(Mod(5*x + 6, 7) - 3, 0), Reals)
    >>> solve_modulo(-7 + Mod(x, 5), x, S.Integers)
    EmptySet
    >>> solve_modulo(Mod(12**x, 21) - 18, x, S.Integers)
    ImageSet(Lambda(_n, 6*_n + 2), Naturals0)
    >>> solve_modulo(Mod(sin(x), 7) - 3, x, S.Integers) # not solvable
    ConditionSet(x, Eq(Mod(sin(x), 7) - 3, 0), Integers)
    >>> solve_modulo(3 - Mod(x, 5), x, Intersection(S.Integers, Interval(0, 100)))
    Intersection(ImageSet(Lambda(_n, 5*_n + 3), Integers), Range(0, 101, 1))
    r   r   Tr   )rY   r   r   r   r   r   r   rK  r   as_coefficients_dictr   r   r   r   r   r  r   r   rZ   r(  r)  r*  r  rc  rT   r   r   )r   r   r   unsolved_resultr  r   r   r   r  
lamda_expr
lamda_varsr  sol_settmp_solrr  s                  r   r  r  C  s   ` #62a8V<O1773< #G55&!&&!&&)
*C(44vAJJ'
wwv c4 AwQ7HC
g~#*
f}###C((
#x YY^^
YY((
MM	C*,fajjAgy)jjG I8F:s$;HiHHIGz7 ;HiHG((r   c              #   ~   K   t        j                  |       D ]  }t        j                  |      E d{    ! y7 w)a  
    Iterator to get the factors of all terms present
    in the given equation.

    Parameters
    ==========
    f : Expr
        Equation that needs to be addressed

    Returns
    =======
    Factors of all terms present in the equation.

    Examples
    ========

    >>> from sympy import symbols
    >>> from sympy.solvers.solveset import _term_factors
    >>> x = symbols('x')
    >>> list(_term_factors(-2 - x**2 + x*(x + 1)))
    [-2, -1, x**2, x, x + 1]
    N)r   r  r
   )r   add_args     r   r  r    s5     . ==# *==)))*)s   1=;=c           
      (   t        |t        | |z
  d      |      }t        |       }| |k7  r#t        ||z
        }|| |z
  k7  rt	        |||      S t        | t              rt        | j                        dk(  s|S |dk7  r|S t        t        | j                              \  }}|j                  |      d   }	|j                  |      d   }
|	j                         \  }}|
j                         \  }}|j                  t        j                        r;t!        |dkD  |dkD  t        t#        |      d      t        t#        |      d            }n t!        t%        |d      t%        |d            }d || fD        \  }}t	        ||z
  ||      }t        |||      S )a  
    Helper function for solving (supported) exponential equations.

    Exponential equations are the sum of (currently) at most
    two terms with one or both of them having a power with a
    symbol-dependent exponent.

    For example

    .. math:: 5^{2x + 3} - 5^{3x - 1}

    .. math:: 4^{5 - 9x} - e^{2 - x}

    Parameters
    ==========

    lhs, rhs : Expr
        The exponential equation to be solved, `lhs = rhs`

    symbol : Symbol
        The variable in which the equation is solved

    domain : Set
        A set over which the equation is solved.

    Returns
    =======

    A set of solutions satisfying the given equation.
    A ``ConditionSet`` if the equation is unsolvable or
    if the assumptions are not properly defined, in that case
    a different style of ``ConditionSet`` is returned having the
    solution(s) of the equation with the desired assumptions.

    Examples
    ========

    >>> from sympy.solvers.solveset import _solve_exponential as solve_expo
    >>> from sympy import symbols, S
    >>> x = symbols('x', real=True)
    >>> a, b = symbols('a b')
    >>> solve_expo(2**x + 3**x - 5**x, 0, x, S.Reals)  # not solvable
    ConditionSet(x, Eq(2**x + 3**x - 5**x, 0), Reals)
    >>> solve_expo(a**x - b**x, 0, x, S.Reals)  # solvable but incorrect assumptions
    ConditionSet(x, (a > 0) & (b > 0), {0})
    >>> solve_expo(3**(2*x) - 2**(x + 3), 0, x, S.Reals)
    {-3*log(2)/(-2*log(3) + log(2))}
    >>> solve_expo(2**x - 4**x, 0, x, S.Reals)
    {0}

    * Proof of correctness of the method

    The logarithm function is the inverse of the exponential function.
    The defining relation between exponentiation and logarithm is:

    .. math:: {\log_b x} = y \enspace if \enspace b^y = x

    Therefore if we are given an equation with exponent terms, we can
    convert every term to its corresponding logarithmic form. This is
    achieved by taking logarithms and expanding the equation using
    logarithmic identities so that it can easily be handled by ``solveset``.

    For example:

    .. math:: 3^{2x} = 2^{x + 3}

    Taking log both sides will reduce the equation to

    .. math:: (2x)\log(3) = (x + 3)\log(2)

    This form can be easily handed by ``solveset``.
    r   r   r   c              3   H   K   | ]  }t        t        |      d         yw)TforceN)r   r.   rF  r   s     r   rG  z%_solve_exponential.<locals>.<genexpr>$  s     <qJs1vT**<s    ")rY   r   r,   rk   rc  r   r   r   r   r   r   r   as_base_expr   r   r   rR   rB   r   )r  r   r   r   r  newlhsneweqr   r   a_termb_terma_basea_expb_baseb_expr<  r!  Rr  s                      r   _solve_exponentialr4    s   R #62cCi+;VDOs^F
f}v|$S3YUFF33sC S]a%7 
ax!"DAqf%a(Ff%a(F&&(MFE&&(MFE QJQJr%y!r%y!	
 vqMvqM
 =QG<DAq!a%0I
I66r   c                     d}t        |       D ]M  }||j                  vrt        |t              r||j                  j                  vst        |t
              rd}M y |S )a  
    Return ``True`` if one or more terms contain ``symbol`` only in
    exponents, else ``False``.

    Parameters
    ==========

    f : Expr
        The equation to be checked

    symbol : Symbol
        The variable in which the equation is checked

    Examples
    ========

    >>> from sympy import symbols, cos, exp
    >>> from sympy.solvers.solveset import _is_exponential as check
    >>> x, y = symbols('x y')
    >>> check(y, y)
    False
    >>> check(x**y - 1, y)
    True
    >>> check(x**y*2**y - 1, y)
    True
    >>> check(exp(x + 3) + 3**x, x)
    True
    >>> check(cos(2**x), x)
    False

    * Philosophy behind the helper

    The function extracts each term of the equation and checks if it is
    of exponential form w.r.t ``symbol``.
    FT)r  r   r   r   r   r5   )r   r   rvexpr_args       r   _is_exponentialr8  *  sd    H 
B!!$ ...x%333h$B Ir   c                 @    t        | d      }||z
  }t        |||      S )a1  
    Helper to solve logarithmic equations which are reducible
    to a single instance of `\log`.

    Logarithmic equations are (currently) the equations that contains
    `\log` terms which can be reduced to a single `\log` term or
    a constant using various logarithmic identities.

    For example:

    .. math:: \log(x) + \log(x - 4)

    can be reduced to:

    .. math:: \log(x(x - 4))

    Parameters
    ==========

    lhs, rhs : Expr
        The logarithmic equation to be solved, `lhs = rhs`

    symbol : Symbol
        The variable in which the equation is solved

    domain : Set
        A set over which the equation is solved.

    Returns
    =======

    A set of solutions satisfying the given equation.
    A ``ConditionSet`` if the equation is unsolvable.

    Examples
    ========

    >>> from sympy import symbols, log, S
    >>> from sympy.solvers.solveset import _solve_logarithm as solve_log
    >>> x = symbols('x')
    >>> f = log(x - 3) + log(x + 3)
    >>> solve_log(f, 0, x, S.Reals)
    {-sqrt(10), sqrt(10)}

    * Proof of correctness

    A logarithm is another way to write exponent and is defined by

    .. math:: {\log_b x} = y \enspace if \enspace b^y = x

    When one side of the equation contains a single logarithm, the
    equation can be solved by rewriting the equation as an equivalent
    exponential equation as defined above. But if one side contains
    more than one logarithm, we need to use the properties of logarithm
    to condense it into a single logarithm.

    Take for example

    .. math:: \log(2x) - 15 = 0

    contains single logarithm, therefore we can directly rewrite it to
    exponential form as

    .. math:: x = \frac{e^{15}}{2}

    But if the equation has more than one logarithm as

    .. math:: \log(x - 3) + \log(x + 3) = 0

    we use logarithmic identities to convert it into a reduced form

    Using,

    .. math:: \log(a) + \log(b) = \log(ab)

    the equation becomes,

    .. math:: \log((x - 3)(x + 3))

    This equation contains one logarithm and can be solved by rewriting
    to exponents.
    Tr'  )r-   rc  )r  r   r   r   new_lhsnew_fs         r   _solve_logarithmr<  [  s)    f D)GcMEUFF++r   c                     d}t        j                  |       D ]L  }d}t        j                  |      D ]+  }||j                  vrt	        |t
              r|r  yd}*  y |sKd}N |S )ae  
    Return ``True`` if the equation is in the form
    `a\log(f(x)) + b\log(g(x)) + ... + c` else ``False``.

    Parameters
    ==========

    f : Expr
        The equation to be checked

    symbol : Symbol
        The variable in which the equation is checked

    Returns
    =======

    ``True`` if the equation is logarithmic otherwise ``False``.

    Examples
    ========

    >>> from sympy import symbols, tan, log
    >>> from sympy.solvers.solveset import _is_logarithmic as check
    >>> x, y = symbols('x y')
    >>> check(log(x + 2) - log(x + 3), x)
    True
    >>> check(tan(log(2*x)), x)
    False
    >>> check(x*log(x), x)
    False
    >>> check(x + log(x), x)
    False
    >>> check(y + log(x), x)
    True

    * Philosophy behind the helper

    The function extracts each term and checks whether it is
    logarithmic w.r.t ``symbol``.
    FT)r   r  r
   r   r   r.   )r   r   r6  r	  saw_logterm_args         r   _is_logarithmicr@    sy    R 
Ba  d+ 	HX222(C( 	 B Ir   c           	         t        t        | j                                     }t        |D cg c]  } |j                        s| c}      }t        |D cg c]  } |j                  t
        t              r|! c}      }| j                  rG|dk\  rBt        t
        t        ft        fd|D              r||k  ryyt        fd|D              ryyc c}w c c}w )a  
    If this returns ``False`` then the Lambert solver (``_solve_lambert``) will not be called.

    Explanation
    ===========

    Quick check for cases that the Lambert solver might be able to handle.

    1. Equations containing more than two operands and `symbol`s involving any of
       `Pow`, `exp`, `HyperbolicFunction`,`TrigonometricFunction`, `log` terms.

    2. In `Pow`, `exp` the exponent should have `symbol` whereas for
       `HyperbolicFunction`,`TrigonometricFunction`, `log` should contain `symbol`.

    3. For `HyperbolicFunction`,`TrigonometricFunction` the number of trigonometric functions in
       equation should be less than number of symbols. (since `A*cos(x) + B*sin(x) - c`
       is not the Lambert type).

    Some forms of lambert equations are:
        1. X**X = C
        2. X*(B*log(X) + D)**A = C
        3. A*log(B*X + A) + d*X = C
        4. (B*X + A)*exp(d*X + g) = C
        5. g*exp(B*X + h) - B*X = C
        6. A*D**(E*X + g) - B*X = C
        7. A*cos(X) + B*sin(X) - D*X = C
        8. A*cosh(X) + B*sinh(X) - D*X = C

    Where X is any variable,
          A, B, C, D, E are any constants,
          g, h are linear functions or log terms.

    Parameters
    ==========

    f : Expr
        The equation to be checked

    symbol : Symbol
        The variable in which the equation is checked

    Returns
    =======

    If this returns ``False`` then the Lambert solver (``_solve_lambert``) will not be called.

    Examples
    ========

    >>> from sympy.solvers.solveset import _is_lambert
    >>> from sympy import symbols, cosh, sinh, log
    >>> x = symbols('x')

    >>> _is_lambert(3*log(x) - x*log(3), x)
    True
    >>> _is_lambert(log(log(x - 3)) + log(x-3), x)
    True
    >>> _is_lambert(cosh(x) - sinh(x), x)
    False
    >>> _is_lambert((x**2 - 2*x + 1).subs(x, (log(x) + 3*x)**2 - 1), x)
    True

    See Also
    ========

    _solve_lambert

    r   c              3   Z   K   | ]"  } |j                         rt        |       $ y wr   )r   r   )rF  r@   lambert_funcsr   s     r   rG  z_is_lambert.<locals>.<genexpr>?  s,      8wswwv #}- 8s   (+Tc              3      K   | ]=  } |j                          d    j                        rt        |t        t        f       ? yw)r   N)r*  r   r   r   r5   )rF  r@   r   s     r   rG  z_is_lambert.<locals>.<genexpr>D  sA      K(9!(<'A'A&'I C#s, Ks   AAF)
r   r  r  r   r   rC   rQ   r   r.   r}  )r   r   term_factorsr@   no_of_symbols
no_of_trigrC  s    `    @r   _is_lambertrH    s    J ahhj12L HHIM\ ?c377%'<=  ? @J 	xxMQ& 02GH 8#8 8-
   K#K K# I?s   CC$Cc                    d }t        |t        | d      |      }t        | d||      \  }}t        |t              rBt        |j                        dk(  sJ |j                  d   }|j                  r |||||      }|S |}|S )ay  
    Function to solve transcendental equations. It is a helper to
    ``solveset`` and should be used internally. ``_transolve``
    currently supports the following class of equations:

        - Exponential equations
        - Logarithmic equations

    Parameters
    ==========

    f : Any transcendental equation that needs to be solved.
        This needs to be an expression, which is assumed
        to be equal to ``0``.

    symbol : The variable for which the equation is solved.
        This needs to be of class ``Symbol``.

    domain : A set over which the equation is solved.
        This needs to be of class ``Set``.

    Returns
    =======

    Set
        A set of values for ``symbol`` for which ``f`` is equal to
        zero. An ``EmptySet`` is returned if ``f`` does not have solutions
        in respective domain. A ``ConditionSet`` is returned as unsolved
        object if algorithms to evaluate complete solution are not
        yet implemented.

    How to use ``_transolve``
    =========================

    ``_transolve`` should not be used as an independent function, because
    it assumes that the equation (``f``) and the ``symbol`` comes from
    ``solveset`` and might have undergone a few modification(s).
    To use ``_transolve`` as an independent function the equation (``f``)
    and the ``symbol`` should be passed as they would have been by
    ``solveset``.

    Examples
    ========

    >>> from sympy.solvers.solveset import _transolve as transolve
    >>> from sympy.solvers.solvers import _tsolve as tsolve
    >>> from sympy import symbols, S, pprint
    >>> x = symbols('x', real=True) # assumption added
    >>> transolve(5**(x - 3) - 3**(2*x + 1), x, S.Reals)
    {-(log(3) + 3*log(5))/(-log(5) + 2*log(3))}

    How ``_transolve`` works
    ========================

    ``_transolve`` uses two types of helper functions to solve equations
    of a particular class:

    Identifying helpers: To determine whether a given equation
    belongs to a certain class of equation or not. Returns either
    ``True`` or ``False``.

    Solving helpers: Once an equation is identified, a corresponding
    helper either solves the equation or returns a form of the equation
    that ``solveset`` might better be able to handle.

    * Philosophy behind the module

    The purpose of ``_transolve`` is to take equations which are not
    already polynomial in their generator(s) and to either recast them
    as such through a valid transformation or to solve them outright.
    A pair of helper functions for each class of supported
    transcendental functions are employed for this purpose. One
    identifies the transcendental form of an equation and the other
    either solves it or recasts it into a tractable form that can be
    solved by  ``solveset``.
    For example, an equation in the form `ab^{f(x)} - cd^{g(x)} = 0`
    can be transformed to
    `\log(a) + f(x)\log(b) - \log(c) - g(x)\log(d) = 0`
    (under certain assumptions) and this can be solved with ``solveset``
    if `f(x)` and `g(x)` are in polynomial form.

    How ``_transolve`` is better than ``_tsolve``
    =============================================

    1) Better output

    ``_transolve`` provides expressions in a more simplified form.

    Consider a simple exponential equation

    >>> f = 3**(2*x) - 2**(x + 3)
    >>> pprint(transolve(f, x, S.Reals), use_unicode=False)
        -3*log(2)
    {------------------}
     -2*log(3) + log(2)
    >>> pprint(tsolve(f, x), use_unicode=False)
         /   3     \
         | --------|
         | log(2/9)|
    [-log\2         /]

    2) Extensible

    The API of ``_transolve`` is designed such that it is easily
    extensible, i.e. the code that solves a given class of
    equations is encapsulated in a helper and not mixed in with
    the code of ``_transolve`` itself.

    3) Modular

    ``_transolve`` is designed to be modular i.e, for every class of
    equation a separate helper for identification and solving is
    implemented. This makes it easy to change or modify any of the
    method implemented directly in the helpers without interfering
    with the actual structure of the API.

    4) Faster Computation

    Solving equation via ``_transolve`` is much faster as compared to
    ``_tsolve``. In ``solve``, attempts are made computing every possibility
    to get the solutions. This series of attempts makes solving a bit
    slow. In ``_transolve``, computation begins only after a particular
    type of equation is identified.

    How to add new class of equations
    =================================

    Adding a new class of equation solver is a three-step procedure:

    - Identify the type of the equations

      Determine the type of the class of equations to which they belong:
      it could be of ``Add``, ``Pow``, etc. types. Separate internal functions
      are used for each type. Write identification and solving helpers
      and use them from within the routine for the given type of equation
      (after adding it, if necessary). Something like:

      .. code-block:: python

        def add_type(lhs, rhs, x):
            ....
            if _is_exponential(lhs, x):
                new_eq = _solve_exponential(lhs, rhs, x)
        ....
        rhs, lhs = eq.as_independent(x)
        if lhs.is_Add:
            result = add_type(lhs, rhs, x)

    - Define the identification helper.

    - Define the solving helper.

    Apart from this, a few other things needs to be taken care while
    adding an equation solver:

    - Naming conventions:
      Name of the identification helper should be as
      ``_is_class`` where class will be the name or abbreviation
      of the class of equation. The solving helper will be named as
      ``_solve_class``.
      For example: for exponential equations it becomes
      ``_is_exponential`` and ``_solve_expo``.
    - The identifying helpers should take two input parameters,
      the equation to be checked and the variable for which a solution
      is being sought, while solving helpers would require an additional
      domain parameter.
    - Be sure to consider corner cases.
    - Add tests for each helper.
    - Add a docstring to your helper that describes the method
      implemented.
      The documentation of the helpers should identify:

      - the purpose of the helper,
      - the method used to identify and solve the equation,
      - a proof of correctness
      - the return values of the helpers
    c                     t        |t        | |z
  d      |      }t        | |      rt        | |||      }|S t	        | |      rt        | |||      }|S )z
        Helper for ``_transolve`` to handle equations of
        ``Add`` type, i.e. equations taking the form as
        ``a*f(x) + b*g(x) + .... = c``.
        For example: 4**x + 8**x = 0
        r   )rY   r   r8  r4  r@  r<  )r  r   r   r   r  s        r   add_typez_transolve.<locals>.add_type  sa     fbsA&6? 3''S&&AF
  S&)%c3?Fr   r   r   )rY   r   r|  r   rT   r   r   r   )r   r   r   rK  r  r  r  r   s           r   r  r  J  s    f$ &"Q(F3F  1ff5JC%#EJJA%%%jjm::c37F M Mr   c                 J   t        |       } t        |      }| t        j                  u r|S | t        j                  u rt        j                  S t        | t        t        t        f      st        d| z        t        |t        t        f      s|t        |d      t        |t              st        d|z        | j                  }| j                  t              rt        |       } |[|sYt        | d      }|t        j                  u r|S |t        j                  u rt        j                  S t!        t#        d|z              |5t%        |      dk(  r|j'                         }nZ|rXt        t#        d            t        |t(              s4t+        | g|g      \  } }}t-        | d   |d   |      j/                  |      S d}|j1                  t        j2                        r|j4                  d	d
ik7  rKt7        dd
      }n=|j1                  t        j8                        r|j4                  dd
ik7  rt7        dd
      }|Gt-        | j/                  ||i      ||      }	 |j/                  ||i      }	|j=                  |	      r|	}|S t?        | t@              \  } }
| jC                  t              } |
D ]I  \  }}|jE                  |jF                  d   jC                  t                    }| j/                  ||i      } K t        |       } tI        | ||d
      S # t:        $ r |}	Y w xY w)a  Solves a given inequality or equation with set as output

    Parameters
    ==========

    f : Expr or a relational.
        The target equation or inequality
    symbol : Symbol
        The variable for which the equation is solved
    domain : Set
        The domain over which the equation is solved

    Returns
    =======

    Set
        A set of values for `symbol` for which `f` is True or is equal to
        zero. An :class:`~.EmptySet` is returned if `f` is False or nonzero.
        A :class:`~.ConditionSet` is returned as unsolved object if algorithms
        to evaluate complete solution are not yet implemented.

    ``solveset`` claims to be complete in the solution set that it returns.

    Raises
    ======

    NotImplementedError
        The algorithms to solve inequalities in complex domain  are
        not yet implemented.
    ValueError
        The input is not valid.
    RuntimeError
        It is a bug, please report to the github issue tracker.


    Notes
    =====

    Python interprets 0 and 1 as False and True, respectively, but
    in this function they refer to solutions of an expression. So 0 and 1
    return the domain and EmptySet, respectively, while True and False
    return the opposite (as they are assumed to be solutions of relational
    expressions).


    See Also
    ========

    solveset_real: solver for real domain
    solveset_complex: solver for complex domain

    Examples
    ========

    >>> from sympy import exp, sin, Symbol, pprint, S, Eq
    >>> from sympy.solvers.solveset import solveset, solveset_real

    * The default domain is complex. Not specifying a domain will lead
      to the solving of the equation in the complex domain (and this
      is not affected by the assumptions on the symbol):

    >>> x = Symbol('x')
    >>> pprint(solveset(exp(x) - 1, x), use_unicode=False)
    {2*n*I*pi | n in Integers}

    >>> x = Symbol('x', real=True)
    >>> pprint(solveset(exp(x) - 1, x), use_unicode=False)
    {2*n*I*pi | n in Integers}

    * If you want to use ``solveset`` to solve the equation in the
      real domain, provide a real domain. (Using ``solveset_real``
      does this automatically.)

    >>> R = S.Reals
    >>> x = Symbol('x')
    >>> solveset(exp(x) - 1, x, R)
    {0}
    >>> solveset_real(exp(x) - 1, x)
    {0}

    The solution is unaffected by assumptions on the symbol:

    >>> p = Symbol('p', positive=True)
    >>> pprint(solveset(p**2 - 4))
    {-2, 2}

    When a :class:`~.ConditionSet` is returned, symbols with assumptions that
    would alter the set are replaced with more generic symbols:

    >>> i = Symbol('i', imaginary=True)
    >>> solveset(Eq(i**2 + i*sin(i), 1), i, domain=S.Reals)
    ConditionSet(_R, Eq(_R**2 + _R*sin(_R) - 1, 0), Reals)

    * Inequalities can be solved over the real domain only. Use of a complex
      domain leads to a NotImplementedError.

    >>> solveset(exp(x) > 1, x, R)
    Interval.open(0, oo)

    z"%s is not a valid SymPy expressionNz is not a valid SymPy symbolz%s is not a valid domainr   z@
                relationship between value and 0 is unknown: %sr   zh
                The independent variable must be specified for a
                multivariate equation.r   Tr3  r   rR  C)rR  )r  )%r   r   r   r   r   r   r   r   r   r   r]   r   r   r=   r<   r   r4  rz   r   popr    rx   rl  rX  r   r   _assumptions_origr   r   r  dummy_eqr   r?   r  r   r   rc  )r   r   r   r   r   r   swapnewsymr6  _rvr   dr  s                r   rl  rl  !	  s   J 	
AV_FAFF{AGG|zza$
F34=ABBftZ01v7IVEFFfc"3f=>>>>LuuY1~lq!H;M!''\::%j 2CEF2G 'H I I ~|!!%%'FZ )* + , , '&sVH5
1d!adF+44T:: F ##~53T*F			!++	&##	4'883-Fajj&&!12FFC	++vv./C ;;sB	 aoGAt			)A 1FF166!9$$Y/0JJ1v 	qAQt44)  	C	s   L L"!L"c                 8    t        | |t        j                        S r   )rl  r   r   r   r   s     r   r  r  	  s    Avqww''r   c                 8    t        | |t        j                        S r   )rl  r   r   rV  s     r   r  r  	  s    Avq{{++r   c           
         i }t        |      D ]2  \  }}|t        j                  u st        |j                  d      ||<   4 | D cg c]  }|j                  |       } }D cg c]  }|j                  |       c}t              t        |       dk(  rt        | S t              dk(  rRd   }|d   }| D cg c]  }t        |||       }}t        | }	t        t        |f|f      |	      j                         S t        | fd      } t        |       D ]  \  }
}g }d}D ]  }|j                   vrt        |||j#                  |               }t%        |t&              rj#                  |      }d| |dz   d z   }|d| ||dz   d z   }| d|
 | |
dz   d z   }|D ]q  }|D cg c]  }|j                  ||       }}t)        |||      }t        |f|d| |fz   ||d z         }|j+                  t        ||      j                                s d} |st-        | c S  yc c}w c c}w c c}w c c}w )	ziBasic implementation of a multivariate solveset.

    For internal use (not ready for public consumption)Tr   r   r   c                 F    t        | j                  t              z        S r   )r   r   r  )r  r  s    r   r   z!_solveset_multi.<locals>.<lambda>	  s    S3t9)D%E r   keyNF)zipr   r   r    namerK  r  r   r^   rl  rW   rZ   r   doitsortedr   r   indexr   rT   _solveset_multir   rX   )eqsr  domainsrepr   domr  r   solsetssolsetr   solsall_handledrr  r   symspdomainspeqspr   eqsp_sub
sol_othersfuns    `                    r   ra  ra  	  sn   
 Cg& 3S!''>chhT2CH3 #&
&B2773<
&C
&%)*cCHHSM*D;D
3x1}7##
4yA~1g7:;8BV,;;w'vv.7<<>>
E
FC3  2 	$C"//)2sGDJJsO$<=C#y)JJsORa4!:-"2A;162AwQqST* BA:>?BQ?H?!05(!KJ %5!9t+;eABi+GHCKKj 9 > > @A	B $!	$" $<+ # '* <(  @s   	H2'H7?H<0I
c           
      N   t        | ||      }d}|t        j                  u rg }|S t        |t              rt        d      t        |t              rt        |      }|S t        | |      }|t        j                  }d}t        |t              r|f}n8t        |t              r(t        d |j                  D              r|j                  }|D ]"  }||j                  t        d|dd            z  }$ t        |t              rt        |      }|S |j                  |      }t        |t              r[t        d |j                  D              r>|j                  D 	
cg c]%  }	|	j                  D ]  }
t        |	t              r|
 ' }}	}
|S yt        |t              r||z  }|S c c}
}	w )	a  Solves an equation using solveset and returns the solution in accordance
    with the `solve` output API.

    Returns
    =======

    We classify the output based on the type of solution returned by `solveset`.

    Solution    |    Output
    ----------------------------------------
    FiniteSet   | list

    ImageSet,   | list (if `f` is periodic)
    Union       |

    Union       | list (with FiniteSet)

    EmptySet    | empty list

    Others      | None


    Raises
    ======

    NotImplementedError
        A ConditionSet is the input.

    Examples
    ========

    >>> from sympy.solvers.solveset import solvify
    >>> from sympy.abc import x
    >>> from sympy import S, tan, sin, exp
    >>> solvify(x**2 - 9, x, S.Reals)
    [-3, 3]
    >>> solvify(sin(x) - 1, x, S.Reals)
    [pi/2]
    >>> solvify(tan(x), x, S.Reals)
    [0]
    >>> solvify(exp(x) - 1, x, S.Complexes)

    >>> solvify(exp(x) - 1, x, S.Reals)
    [0]

    Nz*solveset is unable to solve this equation.r   c              3   <   K   | ]  }t        |t                y wr   r   rZ   r)  s     r   rG  zsolvify.<locals>.<genexpr>T
  s     J1z!X.Jr{  r   FTc              3   <   K   | ]  }t        |t                y wr   )r   rT   r)  s     r   rG  zsolvify.<locals>.<genexpr>b
  s     GAz!Y/Gr{  )rl  r   r   r   rY   r4  rT   r   r   rZ   rX   rL  r   r   rV   r}  )r   r   r   r  r  r  r  iter_solutionssolutionsolnrr  s              r   solvifyrw  
  s   ^ Avv.LFqzz!N MK 
L,	/!"NOO	L)	,l#B M= Q'

IN,1".L%0J8I8IJJ%1%6%6N* RX//FE40PQQ	R )Y/i  M $--f5H(E* GGG.6mm Id $		IZY-G " Ic IF I M  Hi0("MIs   *F!)dictc                &   t        |       } t        |      dk(  r,t        |d         rt        |d   t              st        d      t        |      }t        |      t        |      k7  rt        d      	 t        | g|      \  }}|d   }|d   }|r|r||t        j                  <   |S t        j                  gt        |      dz   z  }||d<   t        |      D ]  \  }}	|	|vr||	   ||<    |S # t        $ r}t        t        |            d}~ww xY w)a  Return a list whose elements are the coefficients of the
    corresponding symbols in the sum of terms in  ``eq``.
    The additive constant is returned as the last element of the
    list.

    Raises
    ======

    NonlinearError
        The equation contains a nonlinear term
    ValueError
        duplicate or unordered symbols are passed

    Parameters
    ==========

    dict - (default False) when True, return coefficients as a
        dictionary with coefficients keyed to syms that were present;
        key 1 gives the constant term

    Examples
    ========

    >>> from sympy.solvers.solveset import linear_coeffs
    >>> from sympy.abc import x, y, z
    >>> linear_coeffs(3*x + 2*y - 1, x, y)
    [3, 2, -1]

    It is not necessary to expand the expression:

        >>> linear_coeffs(x + y*(z*(x*3 + 2) + 3), x)
        [3*y*z + 1, y*(2*z + 3)]

    When nonlinear is detected, an error will be raised:

        * even if they would cancel after expansion (so the
        situation does not pass silently past the caller's
        attention)

        >>> eq = 1/x*(x - 1) + 1/x
        >>> linear_coeffs(eq.expand(), x)
        [0, 1]
        >>> linear_coeffs(eq, x)
        Traceback (most recent call last):
        ...
        NonlinearError:
        nonlinear in given generators

        * when there are cross terms

        >>> linear_coeffs(x*(y + 1), x, y)
        Traceback (most recent call last):
        ...
        NonlinearError:
        symbol-dependent cross-terms encountered

        * when there are terms that contain an expression
        dependent on the symbols that is not linear

        >>> linear_coeffs(x**2, x)
        Traceback (most recent call last):
        ...
        NonlinearError:
        nonlinear in given generators
    r   r   z!expecting unpacked symbols, *symsduplicate symbols givenNr   )r"   r   r~   r   r   r   r  r&   rr   r   strr   r   r   r   )
r  rx  r  symsetrT  r  errr6  r   r.  s
             r   linear_coeffsr~  s
  s   D 
"B
4yA~(47+JtAw4N<==YF
6{c$i233'!2$/1aDaD AaeeH
&&3t9q=	!BBrF$ 1A:!1 I  'SX&&'s   4C. .	D7DDc                    |st        t        d            t        |d   t              rt	        d      t        |d   d      r|d   }t        |      rt        d      t        |       } t        | t              rt        |       } n9t        | t        t        f      r| g} nt        |       st        t        d            	 t        | |      \  }}t#        |      t#        |      fx\  }}}t%        t'        |t)        |                  }t+        | }	t-        |      D ]  \  }
}|D ]  }||   }||   |	|
|f<     t/        |d|D cg c]  }|  c}      }|	|fS # t        $ r}t        t!        |            d}~ww xY wc c}w )	a  
    Converts a given System of Equations into Matrix form.
    Here `equations` must be a linear system of equations in
    `symbols`. Element ``M[i, j]`` corresponds to the coefficient
    of the jth symbol in the ith equation.

    The Matrix form corresponds to the augmented matrix form.
    For example:

    .. math:: 4x + 2y + 3z  = 1
    .. math:: 3x +  y +  z  = -6
    .. math:: 2x + 4y + 9z  = 2

    This system will return $A$ and $b$ as:

    $$ A = \left[\begin{array}{ccc}
        4 & 2 & 3 \\
        3 & 1 & 1 \\
        2 & 4 & 9
        \end{array}\right] \ \  b = \left[\begin{array}{c}
        1 \\ -6 \\ 2
        \end{array}\right] $$

    The only simplification performed is to convert
    ``Eq(a, b)`` $\Rightarrow a - b$.

    Raises
    ======

    NonlinearError
        The equations contain a nonlinear term.
    ValueError
        The symbols are not given or are not unique.

    Examples
    ========

    >>> from sympy import linear_eq_to_matrix, symbols
    >>> c, x, y, z = symbols('c, x, y, z')

    The coefficients (numerical or symbolic) of the symbols will
    be returned as matrices:

        >>> eqns = [c*x + z - 1 - c, y + z, x - y]
        >>> A, b = linear_eq_to_matrix(eqns, [x, y, z])
        >>> A
        Matrix([
        [c,  0, 1],
        [0,  1, 1],
        [1, -1, 0]])
        >>> b
        Matrix([
        [c + 1],
        [    0],
        [    0]])

    This routine does not simplify expressions and will raise an error
    if nonlinearity is encountered:

            >>> eqns = [
            ...     (x**2 - 3*x)/(x - 3) - 3,
            ...     y**2 - 3*y - y*(y - 4) + x - 4]
            >>> linear_eq_to_matrix(eqns, [x, y])
            Traceback (most recent call last):
            ...
            NonlinearError:
            symbol-dependent term can be ignored using `strict=False`

        Simplifying these equations will discard the removable singularity
        in the first and reveal the linear structure of the second:

            >>> [e.simplify() for e in eqns]
            [x - 3, x + y - 4]

        Any such simplification needed to eliminate nonlinear terms must
        be done *before* calling this routine.
    zd
            Symbols must be given, for which coefficients
            are to be found.
            r   z;Unordered 'set' type is not supported as input for symbols.__iter__zSymbols must be uniquezb
            Equation(s) must be given as a sequence, Expr,
            Eq or Matrix.
            Nr   )r   rz   r   r  r  r   r|   r   ra   r   r   r   r}   r&   rr   r   r{  r   rx  r\  ranger_   r   r`   )	equationssymbolsr  r  r}  r   rs  shapeixrV  rowrT  r.  colr   r   s                   r   linear_eq_to_matrixr  
  s   \  %   	 '!*c"IK 	K wqz:&!*122	"I)Z(O		Ibz	*K	# %   	'"9g6A r7CL((DAq5	c'58$	%BuAB- Q 	AQ%CA$Ac3hK	 	q!!_Qqb_%Aa4K  'SX&&' %s    E 
E>	E;"E66E;c                 h   | st         j                  S |rt        |d   d      r|d   }t        |t              }d}d}t        | d      rt        |       dk(  rt        | d   t              r| \  }}t        | d   t              s|s|st        t        d            t        t        |            t        |      k7  rt        |      | }|D cg c]  }t        |       }}	 t        ||      t         j                  S t        t!        fd|D               S t        | t              r;|r#t        |t              st        |d   t              s| ddddf   | ddddf   }}|t        d	      |rt#        j$                        D 	cg c]  }	t'        |       }}	t        |      }
t)        |
|j*                  |j*                  z  z        r3t        t        d
|d   j,                  j/                  d      z              t        |
      t        |      k7  rt        |      |sQt#        j$                        D cg c]  }t1                }}t3        d||fd       j,                  }t5        |      }nd}g }j7                         }t9        ||      D ]R  \  }}t9        ||      D cg c]  \  }}|s	||z   }}}|j;                  |        |j;                  t=        |        T t?        ||      \  }}tA        ||d      t         j                  S t        t!        fd|D               |;j*                  }|D ci c]  }||v s|t'        |       }}jC                  |      S c c}w # t        $ r}t        t        |            d}~ww xY wc c}	w c c}w c c}}w c c}w )a  
    Solve system of $N$ linear equations with $M$ variables; both
    underdetermined and overdetermined systems are supported.
    The possible number of solutions is zero, one or infinite.
    Zero solutions throws a ValueError, whereas infinite
    solutions are represented parametrically in terms of the given
    symbols. For unique solution a :class:`~.FiniteSet` of ordered tuples
    is returned.

    All standard input formats are supported:
    For the given set of equations, the respective input types
    are given below:

    .. math:: 3x + 2y -   z = 1
    .. math:: 2x - 2y + 4z = -2
    .. math:: 2x -   y + 2z = 0

    * Augmented matrix form, ``system`` given below:

    $$ \text{system} = \left[{array}{cccc}
        3 &  2 & -1 &  1\\
        2 & -2 &  4 & -2\\
        2 & -1 &  2 &  0
        \end{array}\right] $$

    ::

        system = Matrix([[3, 2, -1, 1], [2, -2, 4, -2], [2, -1, 2, 0]])

    * List of equations form

    ::

        system  =  [3x + 2y - z - 1, 2x - 2y + 4z + 2, 2x - y + 2z]

    * Input $A$ and $b$ in matrix form (from $Ax = b$) are given as:

    $$ A = \left[\begin{array}{ccc}
        3 &  2 & -1 \\
        2 & -2 &  4 \\
        2 & -1 &  2
        \end{array}\right] \ \  b = \left[\begin{array}{c}
        1 \\ -2 \\ 0
        \end{array}\right] $$

    ::

        A = Matrix([[3, 2, -1], [2, -2, 4], [2, -1, 2]])
        b = Matrix([[1], [-2], [0]])
        system = (A, b)

    Symbols can always be passed but are actually only needed
    when 1) a system of equations is being passed and 2) the
    system is passed as an underdetermined matrix and one wants
    to control the name of the free variables in the result.
    An error is raised if no symbols are used for case 1, but if
    no symbols are provided for case 2, internally generated symbols
    will be provided. When providing symbols for case 2, there should
    be at least as many symbols are there are columns in matrix A.

    The algorithm used here is Gauss-Jordan elimination, which
    results, after elimination, in a row echelon form matrix.

    Returns
    =======

    A FiniteSet containing an ordered tuple of values for the
    unknowns for which the `system` has a solution. (Wrapping
    the tuple in FiniteSet is used to maintain a consistent
    output format throughout solveset.)

    Returns EmptySet, if the linear system is inconsistent.

    Raises
    ======

    ValueError
        The input is not valid.
        The symbols are not given.

    Examples
    ========

    >>> from sympy import Matrix, linsolve, symbols
    >>> x, y, z = symbols("x, y, z")
    >>> A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 10]])
    >>> b = Matrix([3, 6, 9])
    >>> A
    Matrix([
    [1, 2,  3],
    [4, 5,  6],
    [7, 8, 10]])
    >>> b
    Matrix([
    [3],
    [6],
    [9]])
    >>> linsolve((A, b), [x, y, z])
    {(-1, 2, 0)}

    * Parametric Solution: In case the system is underdetermined, the
      function will return a parametric solution in terms of the given
      symbols. Those that are free will be returned unchanged. e.g. in
      the system below, `z` is returned as the solution for variable z;
      it can take on any value.

    >>> A = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    >>> b = Matrix([3, 6, 9])
    >>> linsolve((A, b), x, y, z)
    {(z - 1, 2 - 2*z, z)}

    If no symbols are given, internally generated symbols will be used.
    The ``tau0`` in the third position indicates (as before) that the third
    variable -- whatever it is named -- can take on any value:

    >>> linsolve((A, b))
    {(tau0 - 1, 2 - 2*tau0, tau0)}

    * List of equations as input

    >>> Eqns = [3*x + 2*y - z - 1, 2*x - 2*y + 4*z + 2, - x + y/2 - z]
    >>> linsolve(Eqns, x, y, z)
    {(1, -2, -2)}

    * Augmented matrix as input

    >>> aug = Matrix([[2, 1, 3, 1], [2, 6, 8, 3], [6, 8, 18, 5]])
    >>> aug
    Matrix([
    [2, 1,  3, 1],
    [2, 6,  8, 3],
    [6, 8, 18, 5]])
    >>> linsolve(aug, x, y, z)
    {(3/10, 2/5, 0)}

    * Solve for symbolic coefficients

    >>> a, b, c, d, e, f = symbols('a, b, c, d, e, f')
    >>> eqns = [a*x + b*y - c, d*x + e*y - f]
    >>> linsolve(eqns, x, y)
    {((-b*f + c*e)/(a*e - b*d), (a*f - c*d)/(a*e - b*d))}

    * A degenerate system returns solution as set of given
      symbols.

    >>> system = Matrix(([0, 0, 0], [0, 0, 0], [0, 0, 0]))
    >>> linsolve(system, x, y)
    {(x, y)}

    * For an empty system linsolve returns empty set

    >>> linsolve([], x)
    EmptySet

    * An error is raised if any nonlinearity is detected, even
      if it could be removed with expansion

    >>> linsolve([x*(1/x - 1)], x)
    Traceback (most recent call last):
    ...
    NonlinearError: nonlinear term: 1/x

    >>> linsolve([x*(y + 1)], x, y)
    Traceback (most recent call last):
    ...
    NonlinearError: nonlinear cross-term: x*(y + 1)

    >>> linsolve([x**2 - 1], x)
    Traceback (most recent call last):
    ...
    NonlinearError: nonlinear term: x**2
    r   r  rz  Nr   z
                    When passing a system of equations, the explicit
                    symbols for which a solution is being sought must
                    be given as a sequence, too.
                c              3   B   K   | ]  }j                  ||        y wr   rU  rF  r   rr  s     r   rG  zlinsolve.<locals>.<genexpr>%  s     #I#CGGC$5#I   r   zInvalid argumentsa  
                At least one of the symbols provided
                already appears in the system to be solved.
                One way to avoid this is to use Dummy symbols in
                the generator, e.g. numbered_symbols('%s', cls=Dummy)
            
1234567890tauc                 6    t        |       j                  d      S )Nr  )r{  rstrip)r   s    r   r   zlinsolve.<locals>.<lambda>@  s    c!fmmL9 r   )compareF)_rawc              3   B   K   | ]  }j                  ||        y wr   r  r  s     r   rG  zlinsolve.<locals>.<genexpr>R  s     A#CGGC-Ar  )"r   r   r   r   r   r   ra   r   rz   r  r   rs   rr   r   r{  rT   r   r  colsr   r}  r   r]  r  r   r!   r{   tolistr\  r   r   rp   rq   rK  )systemr  sym_gendup_msgr   rV  rb  r  excr   r|  r  r]  r  rowsrowibielemr   termsringsolsymrd  rr  s                          @r   linsolver  I  s   Z zz 771:z2!*-0G'G 	A vz" v;!
6!9j ADAq &)Z0g  - "  
 3w< CL0 )) C),-272;-C-/W-
 {zz!E#I#IJKCJ	FJ	'Jw>wqz:.a"f~vaf~1y,--*/-8Q4=88Wv!..89:Z )
 !*//((6)7 8 9 9 [CL(W%%$)!&&M2q5722%eaV9;;?4 	% C88:DaL  b-0w-?H	c4HHbS

3; 
 "#w/IC
T
.C
{zz
EAAB
CC
!!)0B#C6MsDI~BBhhsmJ} . & /$SX../& 9 3 I CsB   M5!M: N>N$-
N)8N)	N/N/:	NNNc                 ~    d | D        } t        t        | t        |  t        j                  t        |      z        }|S )Nc              3   4   K   | ]  }t        |d         yw)r   N)r   )rF  r  s     r   rG  z'_return_conditionset.<locals>.<genexpr>c  s     
%#2c1:
%   )rY   r   rR   r   r   r   )rb  r  condition_sets      r   _return_conditionsetr  a  s8    
%
%C wcAKKW$=?Mr   c           
         !"#$%&'( | st         j                  S t        |       D ]2  \  }}t        |t              s|j
                  |j                  z
  | |<   4 |sd}t        t        |            t        |      s$d}t        t        |t        |      |fz              t        |d   dd      s*d}t        t        |t        |d         |d   fz              ||}	i %i 'd}
d}dfd	$t        t        | $fd	            &d
 }%'fd"fd!d #dd	 d!#fd	 d } "$%&'fd} ||	t              \  }}} ||	t               \  }}}|
||z   z  }
|||z   z  }|
|k(  r|dk7  rt#        &      S g }t        |      D ]  }t        |      D ]^  }|j%                         |j%                         k7  r%t'        d t)        |j+                         |j+                               D              s^ n |j-                  |        ||z   }g }g }|D ]w  }|st/        |      t/              k  rE|j%                         (t        t1        (fd            }|D ]  }|||<   	 |j-                  |       ||vsg|j-                  |       y |r|}'s%r
 ||'%      }t         j                  }|D ]+  }D cg c]  }||   	 }}|t3        t5        |            z  }- |S c c}w )a  
    Solves the `system` using substitution method. It is used in
    :func:`~.nonlinsolve`. This will be called from :func:`~.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 :class:`~.Symbol` type.

    Examples
    ========

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

    * When you want a soln not satisfying $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])
    {(ImageSet(Lambda(_n, I*(2*_n*pi + pi) + log(sin(2))), Integers), -2),
     (ImageSet(Lambda(_n, 2*_n*I*pi + log(sin(2))), 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 - log(3)), Integers),
      ImageSet(Lambda(_n, -sqrt(-exp(2*x) + sin(2*_n*I*pi - log(3)))), Integers)),
     (ImageSet(Lambda(_n, 2*_n*I*pi - log(3)), Integers),
      ImageSet(Lambda(_n, sqrt(-exp(2*x) + sin(2*_n*I*pi - log(3)))), Integers))}

    GSymbols must be given, for which solution of the system is to be found.zBsymbols should be given as a sequence, e.g. a list.Not type %s: %sr   r   FzEIterable of symbols must be given as second argument, not type %s: %sr   c                     | j                   }|t              z
  t              z  }|r!t        |      }|j                  t               |S )zJReturns the unsolved symbol present
        in the equation `eq`.
        rZ  )r   r  r   sortr   )r  r  freeunsolvedall_symbolsknown_symbolss       r   _unsolved_symsz$substitution.<locals>._unsolved_syms  sG     3}--[1AAH~HMM.M/r   c                 &    t         |             S r   )r   )r  r  s    r   r   zsubstitution.<locals>.<lambda>  s    #nQ&7"8 r   c                 $   g }| D ]  }|}|j                         D ]  \  }}d\  }}	|j                         D ]  \  }
}|
|k(  s|} |j                         D ]  \  }
}|
|k(  s|}	 |s|	sPt        |      }|r|t        j                  k7  rt	        ||      }|	rt        ||	      }|t        j                  u rd } n>|j                  r+t        |      dk(  rt        |      j                         ||<   |||<    ||j                  |       
 |S )N)NNr   )itemsrT   r   r   rW   r[   r   r3  r   r  rN  r   )r  intersection_dictcomplement_dictfinal_resultr   res_copykey_res	value_resintersect_setcomplement_setkey_sym	value_sym	new_values                r   add_intersection_complementz1substitution.<locals>.add_intersection_complement  s8     	.CH&)iik 6"0:-~*;*A*A*C 2&GY')(12 +:*?*?*A 3&GY'))23 !N )) 4I$!++)E$0M$J	%$.y.$I	 AJJ.#'"//C	Na4G,/	N,>,>,@),5))6, ###H-3	.4 r   c                    t        |t              r|j                  }t        |t              r!|j                  d   | <   |j                  d   }t        |t
              rG|j                  }t        j                  }|D ]&  }t        |t              r||z  }|t        |      z  }( t        |t              rP|j                  d   t        j                  t        j                  fvr|j                  d   | <   |j                  d   }t        |t              r(|}|j                  j                  }t        |      }|||<   t        |t              st        |      }||fS )a  Separate the Complements, Intersections, ImageSet lambda expr and
        its base_set. This function returns the unmasked sol from different classes
        of sets and also returns the appended ImageSet elements in a
        soln_imageset dict: `{unmasked element: ImageSet}`.
        r   r   )r   rY   r  r[   r   rX   r   r   rT   rW   r   r   rZ   r(  r)  )	r   rr  soln_imagesetsol_argssol_arg2soln_imagestexpr2complementsintersectionss	          r   _extract_main_solnz(substitution.<locals>._extract_main_soln  s.    c<(,,Cc:&"xx{K((1+C c5!xxH**C % /h	28OC 9X..C/ c<(xx{177AKK"88 &)XXa[c"((1+C c8$LIINNEE"C#/M% #y)C.CM!!r   c                     | |rD| j                         }|d   }|j                         D ]  \  }}|j                  |d      ||<    |	 t        fdD              }|S # t        $ r d }Y |S w xY w)Nr   c              3   6   K   | ]  }t        |        y wr   rt   )rF  rT  rnew_s     r   rG  z7substitution.<locals>._check_exclude.<locals>.<genexpr>\  s      "5'(E""5r  )copyr  rK  r}  r  )	rnew
imgset_yes	rnew_copydummy_nr  r  satisfy_excluder  excludes	          @r   _check_excludez$substitution.<locals>._check_excludeK  s     		I mG&/oo&7 @"%.^^GQ%?	'"@E	#
 " "5,3"5 5O   	#"O	#s   A" "A10A1c                     t        | j                               t        |j                               z  }|D ]  }||   }|| |<    | |vr|j                  |        y y r   )r  r  r   )r  original_imageset	newresultrestore_symr  imgs         r   _restore_imgsetz%substitution.<locals>._restore_imgsetb  sh    $))+&!&&()*" 	 G#G,CDM	  y T" !r   c                     t        d      }|r| j                  |d      } | dv r| nt        ||| d      }|du rd}i }n|j                  |       |||fS )Nr  r   )TFT)minimalF)r   rK  rt   r   )r  r  r   delete_solnr   r  satisfys          r   
_append_eqz substitution.<locals>._append_eqk  sa    #JABm+"!QD1QeKCMM#sK''r   c                     | |      }d}	|sd}
|r|d   }
|d   }|rx|rvt        |j                  t                    }t        dt	        |            D cg c]  }|
 }}t        ||      }t        |
|j                  |            }t        ||      | |<   |` ||| |	|
      \  }} }	nO| ||| |	      \  }} }	n=||j                         v r||   | |<    | ||       n|j                  |        n|rd}	i }  | ||       ||	fS c c}w )a  If `rnew` (A dict <symbol: soln>) contains valid soln
        append it to `newresult` list.
        `imgset_yes` is (base, dummy_var) if there was imageset in previously
         calculated result(otherwise empty tuple). `original_imageset` is dict
         of imageset expr and imageset from this result.
        `soln_imageset` dict of imageset expr and imageset of new soln.
        FNr   r   T)r   r   r   r  r   r\  r   rK  rZ   r  r   )r  r   rr  r  r  r  r  r  r  r  local_nr   
dummy_listr   local_n_list	dummy_ziplamr  r  r  s                    r   _append_new_solnz&substitution.<locals>._append_new_solnw  sO    )z:G$Q-!!}3
 "&cii&6!7J */s:*0$1$%$1L $1 !$J =I #((9*=>C (d 3DI>3=It['4C0It[/9	406,	4**,,)#.S	&7C  &KD/;+%%/$1s   	Dc                     g }g }| D ]Z  }t        d |j                         D              r$|j                  |      dk(  r|j                  |       J|j                  |       \ |s|r||z   S | S )Nc              3   <   K   | ]  }t        |t                y wr   rr  )rF  vals     r   rG  z:substitution.<locals>._new_order_result.<locals>.<genexpr>  s     ISz#x0Ir{  r   )r}  r>  rK  r   )r  r  first_prioritysecond_priorityr   s        r   _new_order_resultz'substitution.<locals>._new_order_result  st      	0CICJJLII773<1$"))#.#**3/	0 _!O33r   c                    i }d}d}t        "      D ]7  \  }}g }d}| D ]!  }	i }
t               }|	j                         D ]  \  }}t        |t              rg|j
                  j                  |	|<   ||
|<   |j
                  j                  j                  t              j                         }|j                  \  }||f}t        |t              sJ  |j                  |	      j                         }|r|j                  |d         sd}  |d      }|s)|	r% |	dd|||
||      \  }}|r| j                  |	        |j                   | \  }}|j                  t"              s|j                  t"              r|t$        k(  rdi }|D ]  }d}	  |||      }|dz  }t&        j(                  }t        |t*              r!|j,                  d   !|<   |j,                  d   }t        |t.              rI|j,                  d   t1        t2         t2              k7  r|j,                  d   #|<   ||j,                  d   z  }|r|n|}|dkD  r.|t4        k(  r%t        |t        t6        f      s|t%        ||      z  }t        |t6              rP|j<                  t&        j>                  t&        j@                  fv rt&        j(                  }d}|dz  }n|j<                  }|t&        j(                  ur |||      \  }}|D ]5  } |||      \  }}t        |      j                         }|jB                  |rtE        fd|D              rM|	jG                         }|	j                         D ]<  \  }}t        |tH              st        |tH              s(|j                  ||      ||<   > ||jK                         v rM||   } |j
                  tM        dtO        |j
                  jP                              D cg c]  }d c} ||<   n|||<    ||||||
|      \  }}|s%| j                  |	       8 |r|jS                  |        $ |s6|} : | ||fS # t8        t:        f$ r Y w xY wc c}w )zSolves the system using already known solution
        (result contains the dict <symbol: value>).
        solver is :func:`~.solveset_complex` or :func:`~.solveset_real`.
        r   FT)r  Nr   c              3   &   K   | ]  }|v  
 y wr   r   )rF  ssr  s     r   rG  zBsubstitution.<locals>._solve_using_known_values.<locals>.<genexpr>&  s      .+-B$J.s   )*r   r  r  r   rZ   r(  r)  r   r   rN  r  rT   rK  r  r   remover   r?   r  r   r   r[   r   rW   rV   r   r  rY   r4  r   r  r   r   r   r}  r  r   r  r  r   r*  add)$r  r  r  total_solvest_calltotal_conditionstr`  r  r  r  r   r  
got_symbolr.  vr  r   eq2unsolved_syms
delete_resdepen1depen2r   not_solvablerv  soln_newrr  r  imgstr   r  r  r  r  r  eqs_in_better_orderr  s$                                @r   _solve_using_known_valuesz/substitution.<locals>._solve_using_known_values  s     ##67 D	#IE2IJ },$&! U
IIK 8DAq!!X.!"A/0)!,"#'',,"4"4U";"?"?"A"#++&-t_
)!Y7778 ggcl))+cggjm&< "'J .s >$0@tZ-y#1?-	: &
 #MM#.!3!3!3]!CJJsOvzz#FFV<V  "( S,C#(L!%c3/*a/*#$::%dJ7/3yy|K,#'99Q<D%dL9#yy|xR/@@ 6:YYq\c 2$		!4H+3x 19=)@ $.dX|4L#M $(8c(B B
 "$5==QWWakk,BB#$::D ,0L-2-#'==D1::-.@}/6+m  $ %/ .@m.5*]!#hlln"//%# .1;. +
 %"xxz %(IIK ;DAq)!T2z#t7L +,&&c*:Q	; -"4"4"66$1#$6E(3-21c$)KK$9$97; .< "=! "=)>DI ),DI0@ #sJ-y1:-	: & #MM#.K%/N ("s+gS,U},~ "ID	#J )+<<<} 0< ! !!Z"=s   C!Q,	Q*Q'	&Q'	c              3      K   | ]8  \  }}t        |t              rt        |t              s|j                  |       : y wr   )r   intrP  )rF  r   r   s      r   rG  zsubstitution.<locals>.<genexpr>a  s8      DTQ"1c*z!S/A ::a= Ds   >A c                     | vS r   r   )r   solved_symbolss    r   r   zsubstitution.<locals>.<lambda>u  s    !>1 r   Fr   )r   r   r   r   r   r  r   r   rz   r}   r  typegetattrr   r   r  r  r  r  rL  r\  r>  r   r   filterrT   r  ))r  r  r  r  r  r  r   r  msg
old_resulttotal_conditionsettotal_solveset_callr  r  r  new_result_realsolve_call1	cnd_call1new_result_complexsolve_call2	cnd_call2filtered_complexjresult_all_variablesresult_infiniter   r  unsolved_symr  symbtempr  r  r  r  r  r  r  r  r  r  s)      ```                         @@@@@@@@@@r   substitutionr  i  s\   n zz&! &1aF1I& (C))w!
3$w-)A#ABCC71:{E22C4
+;WQZ*H$HIJJ JKM 	 89;@5"n.#
( ;?1&f Q= Q=f /HM/#+O[)1J$2&.Y 9y01K+56005HB5N#$7EE $% 'o& 	'Avvx1668# DSQXXZ-H D D	' ##A&' //FO - s8c+&& XXZNF1;@ AH ( 1$0L!1""3'** '',-"   /: - > ZZF! )$/0D$00)E$K(() M 1s    K)c                     t        | d   |d         }t        |t              rt        |D cg c]  }|f c} }|S t        t        t        |                  S c c}w r   )rl  r   rT   r  )r  r  rv  r   _solns        r   _solveset_workr    sU    F1Iwqz*D$	"$/QQD/0y/00 0s   
Ac                     ddl m} t        |      }|j                  t                || |d      }g }|D ]!  }|j                  |j                                # i g}t        |||g |      }|S )Nr   )rn   rZ  T)polys)sympy.polys.polytoolsrn   r   r  r   r   r  r  )	r  r  r  rn   _symbolsbasis
new_systempoly_eqr  s	            r   _handle_positive_dimensionalr$    sx    .G}HMM&M'UHD1EJ -'//+,-TFGVRF Mr   c           	          t        | g| }t        j                  }|D ]C  }t        t	        t        ||                  t        fd|D              s6|t        |      z  }E |S )Nc              3   6   K   | ]  }t        |        y wr   r  )rF  r  dict_sym_values     r   rG  z+_handle_zero_dimensional.<locals>.<genexpr>  s     =xN+=r  )ry   r   r   rx  r   r\  rL  rT   )r  r  r  r  result_updater   r'  s         @r   _handle_zero_dimensionalr)    sf    u/w/F JJM ,d3w#456=f==Ys^+M, r   c                 V   g }g }g }g }t               }d }| D ]	  }|j                  t        ||             t        |t              r|j
                  |j                  z
  }t        t        |      g| }	|	r|j                  |       |	\  }
}|s|
}t        |t              r&|j                         d   } |j                  |ddi}nt        |      j                  r|2|j                  |       |j                   |j                                |j                  |        |||||fS )Nr   	extensionT)r  updaterw   r   r   r  r   rv   r(   r   r   r   as_poly	is_numberr  )r  r  r  
polys_exprnonpolysunrad_changedr  ro   r  without_radicalseq_unradr  s               r   _separate_poly_nonpolyr4    s"   EJH M5LD  LW56b""&&B "88  $,MHcb$""$Q'B2::w7$7Db\##LLldlln-OOB- . *hmCCr   c           	      h   i g}g }g }t        d | D              }|r#| D cg c]  }t        t        |d             } }t        | |dd      }d|v r|}|}	||	fS |j                  rc|j                  d      }|r|D cg c]  }t        |       }}	 t        |g|d	di}
|
D cg c]  }t        t        ||             }}|}	||	fS |}t        t        | |dd            }	|r|	D cg c]  }t        |       }	}||	fS c c}w c c}w c c}w # t        $ r |}t        |      }	Y ||	fS w xY wc c}w )
Nc              3   J   K   | ]  }|j                   j                     y wr   )r   is_Exact)rF  rB  s     r   rG  z_handle_poly.<locals>.<genexpr>  s     7Aahh'''7s   !#T)rationalgrevlexF)orderr  r   lexstrict)r}  ro   r+   rn   is_zero_dimensionalfglmr   ry   rx  r\  r'   r   )r  r  no_informationno_solutionsno_equationsinexactrB  r!  poly_solpoly_eqsr  r   s               r   _handle_polyrE    s    TNL L777G =BBqiD12BB UG9EBE
 	Ez  d X[ 
	"	" 

5! (-.1VAY.E.	$&uDwDtDF <BBCS#./BHB#H$ X "uEJK+34aq	4H4XC C8 /$ C % 	# &HE{H0 X9	#4 5s)   D=DD %D)D/D,+D,c           	      |   | st         j                  S sd}t        t        |            t	        d   d      rd   t              rsd}t        t        |            t        t        t                    t        |       \  } r4t        |       }t        |D cg c]  }t        fd|D               c} S t        |       dk(  rt              dk(  rt        |       S t!        |       \  }}}}}	g }
i g}|rut#        |      \  }}
|rd|d   r_ t%               j&                  d |D         } t%               j&                  d |	D         }||k(  r|	r|D cg c]  }t)        |	|      s| }}|
|z   }fd}|st        t        ||       S t+        |||	      }t-        |t              s|S |	rn|j.                  D cg c]  }t1        t3        |             }}|D cg c]%  }t5        d
 |D              st)        |	|      dk7  r|' }}t        t        ||       S |S c c}w c c}w c c}w c c}w )a/  
    Solve system of $N$ nonlinear equations with $M$ variables, which means both
    under and overdetermined systems are supported. Positive dimensional
    system is also supported (A system with infinitely many solutions is said
    to be positive-dimensional). In a positive dimensional system the solution will
    be dependent on at least one symbol. Returns both real solution
    and complex solution (if they exist).

    Parameters
    ==========

    system : list of equations
        The target system of equations
    symbols : list of Symbols
        symbols should be given as a sequence eg. list

    Returns
    =======

    A :class:`~.FiniteSet` of ordered tuple of values of `symbols` for which the `system`
    has solution. Order of values in the tuple is same as symbols present in
    the parameter `symbols`.

    Please note that general :class:`~.FiniteSet` is unordered, the solution
    returned here is not simply a :class:`~.FiniteSet` of solutions, rather it
    is a :class:`~.FiniteSet` of ordered tuple, i.e. the first and only
    argument to :class:`~.FiniteSet` is a tuple of solutions, which is
    ordered, and, 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.

    For the given set of equations, the respective input types
    are given below:

    .. math:: xy - 1 = 0
    .. math:: 4x^2 + y^2 - 5 = 0

    ::

       system  = [x*y - 1, 4*x**2 + y**2 - 5]
       symbols = [x, y]

    Raises
    ======

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

    Examples
    ========

    >>> from sympy import symbols, nonlinsolve
    >>> x, y, z = symbols('x, y, z', real=True)
    >>> nonlinsolve([x*y - 1, 4*x**2 + y**2 - 5], [x, y])
    {(-1, -1), (-1/2, -2), (1/2, 2), (1, 1)}

    1. Positive dimensional system and complements:

    >>> from sympy import pprint
    >>> from sympy.polys.polytools import is_zero_dimensional
    >>> a, b, c, d = symbols('a, b, c, d', extended_real=True)
    >>> eq1 =  a + b + c + d
    >>> eq2 = a*b + b*c + c*d + d*a
    >>> eq3 = a*b*c + b*c*d + c*d*a + d*a*b
    >>> eq4 = a*b*c*d - 1
    >>> system = [eq1, eq2, eq3, eq4]
    >>> is_zero_dimensional(system)
    False
    >>> pprint(nonlinsolve(system, [a, b, c, d]), use_unicode=False)
      -1       1               1      -1
    {(---, -d, -, {d} \ {0}), (-, -d, ---, {d} \ {0})}
       d       d               d       d
    >>> nonlinsolve([(x+y)**2 - 4, x + y - 2], [x, y])
    {(2 - y, y)}

    2. If some of the equations are non-polynomial then `nonlinsolve`
    will call the ``substitution`` function and return real and complex solutions,
    if present.

    >>> from sympy import exp, sin
    >>> nonlinsolve([exp(x) - sin(y), y**2 - 4], [x, y])
    {(ImageSet(Lambda(_n, I*(2*_n*pi + pi) + log(sin(2))), Integers), -2),
     (ImageSet(Lambda(_n, 2*_n*I*pi + log(sin(2))), Integers), 2)}

    3. If system is non-linear polynomial and zero-dimensional then it
    returns both solution (real and complex solutions, if present) using
    :func:`~.solve_poly_system`:

    >>> from sympy import sqrt
    >>> nonlinsolve([x**2 - 2*y**2 -2, x*y - 2], [x, y])
    {(-2, -1), (2, 1), (-sqrt(2)*I, sqrt(2)*I), (sqrt(2)*I, -sqrt(2)*I)}

    4. ``nonlinsolve`` can solve some linear (zero or positive dimensional)
    system (because it uses the :func:`sympy.polys.polytools.groebner` function to get the
    groebner basis and then uses the ``substitution`` function basis as the
    new `system`). But it is not recommended to solve linear system using
    ``nonlinsolve``, because :func:`~.linsolve` is better for general linear systems.

    >>> nonlinsolve([x + 2*y -z - 3, x - y - 4*z + 9, y + z - 4], [x, y, z])
    {(3*z - 5, 4 - z, z)}

    5. System having polynomial equations and only real solution is
    solved using :func:`~.solve_poly_system`:

    >>> e1 = sqrt(x**2 + y**2) - 10
    >>> e2 = sqrt(y**2 + (-x + 10)**2) - 3
    >>> nonlinsolve((e1, e2), (x, y))
    {(191/20, -3*sqrt(391)/20), (191/20, 3*sqrt(391)/20)}
    >>> nonlinsolve([x**2 + 2/y - 2, x + y - 3], [x, y])
    {(1, 2), (1 - sqrt(5), 2 + sqrt(5)), (1 + sqrt(5), 2 - sqrt(5))}
    >>> nonlinsolve([x**2 + 2/y - 2, x + y - 3], [y, x])
    {(2, 1), (2 - sqrt(5), 1 + sqrt(5)), (2 + sqrt(5), 1 - sqrt(5))}

    6. It is better to use symbols instead of trigonometric functions or
    :class:`~.Function`. For example, replace $\sin(x)$ with a symbol, replace
    $f(x)$ with a symbol and so on. Get a solution from ``nonlinsolve`` and then
    use :func:`~.solveset` to get the value of $x$.

    How nonlinsolve is better than old solver ``_solve_system`` :
    =============================================================

    1. A positive dimensional system solver: nonlinsolve can return
    solution for positive dimensional system. It finds the
    Groebner Basis of the positive dimensional system(calling it as
    basis) then we can start solving equation(having least number of
    variable first in the basis) using solveset and substituting that
    solved solutions into other equation(of basis) to get solution in
    terms of minimum variables. Here the important thing is how we
    are substituting the known values and in which equations.

    2. Real and complex solutions: nonlinsolve returns both real
    and complex solution. If all the equations in the system are polynomial
    then using :func:`~.solve_poly_system` both real and complex solution is returned.
    If all the equations in the system are not polynomial equation then goes to
    ``substitution`` method with this polynomial and non polynomial equation(s),
    to solve for unsolved variables. Here to solve for particular variable
    solveset_real and solveset_complex is used. For both real and complex
    solution ``_solve_using_known_values`` is used inside ``substitution``
    (``substitution`` will be called when any non-polynomial equation is present).
    If a solution is valid its general solution is added to the final result.

    3. :class:`~.Complement` and :class:`~.Intersection` will be added:
    nonlinsolve maintains dict for complements and intersections. If solveset
    find complements or/and intersections with any interval or set during the
    execution of ``substitution`` function, then complement or/and
    intersection for that variable is added before returning final solution.

    r  r   r  c              3   @   K   | ]  }|j                          y wr   )rX  )rF  r   rQ  s     r   rG  znonlinsolve.<locals>.<genexpr>  s      =aD!1 =rx  r   c              3   4   K   | ]  }|j                     y wr   r   rF  r  s     r   rG  znonlinsolve.<locals>.<genexpr>  s     %F"boo%Fr  c              3   4   K   | ]  }|j                     y wr   rI  rJ  s     r   rG  znonlinsolve.<locals>.<genexpr>  s     &O2r&Or  c                 .     t         fdD              S )Nc              3   (   K   | ]	  }|     y wr   r   )rF  r   rr  s     r   rG  z0nonlinsolve.<locals>.<lambda>.<locals>.<genexpr>   s      9AQ 9s   )r  )rr  r  s   `r   r   znonlinsolve.<locals>.<lambda>   s    5 9 99 r   )r  r  c              3   <   K   | ]  }t        |t                y wr   )r   r]   )rF  r  s     r   rG  znonlinsolve.<locals>.<genexpr>  s     8YPQAs9K8Yr{  F)r   r   r   rz   r   r}   
IndexErrorr   mapr"   rx   nonlinsolverT   r  r   r  r4  rE  r  unionrt   r  r   r   rx  r\  r}  )r  r  r  rv  r   r  r/  r0  r  r1  rD  rC  	poly_syms
unrad_symsrr  	remainingto_tuplesubs_resr  correct_solsrQ  s    `                  @r   rQ  rQ  4  sX   v zz(C))wqz:&!*ww(C))3x)*G-fg>FGT67+tL!5 =1 ==LMM
6{aCLA-fg..
 	vw/ =E:x} HtH)%9(#%F%FGI$&O&OPJY&= ,4TCxs7SCTT 8#I :H #h122  	78\Z(I.O 9AG#d3w,-GFG+1 FCS8YUX8Y5Y's;uD   FL Fc(L9::Os M* U> HFs   $H*!H/3H/H4**H9r  )r   sympy.core.sympifyr   
sympy.corer   r   r   r   r   r	   r
   r   r   sympy.core.containersr   sympy.core.functionr   r   r   r   r   r   r   sympy.core.modr   sympy.core.numbersr   r   r   r   sympy.core.intfuncr   sympy.core.relationalr   r   r   sympy.core.sortingr   r   sympy.core.symbolr    r!   r"   sympy.core.traversalr#   sympy.external.gmpyr$   r  r%   r  sympy.polys.matrices.linsolver&   sympy.polys.polyrootsr'   r  r(   r)   r*   r+   sympy.simplifyr,   r-   sympy.functionsr.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   %sympy.functions.combinatorial.numbersr>   $sympy.functions.elementary.complexesr?   r@   rA   rB   %sympy.functions.elementary.hyperbolicrC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   (sympy.functions.elementary.miscellaneousrP   (sympy.functions.elementary.trigonometricrQ   sympy.logic.boolalgrR   rS   
sympy.setsrT   rU   rV   rW   rX   rY   rZ   r[   r\   sympy.sets.setsr]   r^   sympy.matricesr_   r`   ra   sympy.ntheory.factor_rb   sympy.ntheory.residue_ntheoryrc   rd   sympy.polysre   rf   rg   rh   ri   rj   rk   sympy.polys.polyerrorsrl   r  rm   rn   ro   sympy.polys.solversrp   rq   rr   rs   sympy.solvers.solversrt   ru   rv   rw   rx   sympy.solvers.polysysry   sympy.utilitiesrz   sympy.utilities.iterablesr{   r|   r}   r~   sympy.calculus.utilr   r   r   typesr   r   r   r   r   r   r|  r   r   r   r  r   r"  r   r   rC  rA  rZ  r]  rf  	Exceptionrh  rm  rn  ro  rb  r  r  r  rc  r  r  r  r  r4  r8  r<  r@  rH  r  rl  r  r  ra  rw  r~  r  r  r  r  r  r$  r)  r4  rE  rQ  r   r   r   <module>r~     s   '$ $ $ 'K K K  6 6 * 4 4 8 < ' 3 D < 7 K K 08 8 8 8 8 : A AF F F F ? J 0M M M + 4 4 * C3 3 3 1 8 8  3% % 3 &> > N N  	Z 	
$N  kk ['| 'mb m`GT=@.6b!'H$> +,++ &0/d+*;y ;8vaKH>@B &'[[ B6J1h64IX\~1hQhXv*6n7b.bV,r7tYxTn AKK t5n(,/ dYB #( XvxvPp +-RaH1 !DHYxhr   