
    sg                    |   d dl 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 d dlmZmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dl m!Z"m#Z#m$Z%  G d de      Z& G d de&      Z! G d de&      Z' G d de&      Z( G d de&      Z) G d de&      Z* G d de&      Z+e*Z,e+Z- G d de&      Z.y)    )annotations)reduce)SsympifyDummyMod)cacheit)FunctionArgumentIndexError	PoleError)	fuzzy_and)IntegerpiI)Eq)gmpy)sieve)binomial_mod)Poly)	factorialprodsqrtc                      e Zd ZdZd Zy)CombinatorialFunctionz(Base class for combinatorial functions. c                ^    ddl m}  ||       }|d   } ||      |d    ||       z  k  r|S | S )Nr   )combsimpmeasureratio)sympy.simplify.combsimpr   )selfkwargsr   exprr   s        [/var/www/html/venv/lib/python3.12/site-packages/sympy/functions/combinatorial/factorials.py_eval_simplifyz$CombinatorialFunction._eval_simplify   s=    4 ~#4=F7OGDM99K    N)__name__
__module____qualname____doc__r$    r%   r#   r   r      s
    2r%   r   c                      e Zd ZU dZddZg dZg Zded<   ed        Z	ed        Z
ed        Zd	 Zd
 ZddZd Zd Zd Zd Zd Zd ZddZy)r   a  Implementation of factorial function over nonnegative integers.
       By convention (consistent with the gamma function and the binomial
       coefficients), factorial of a negative integer is complex infinity.

       The factorial is very important in combinatorics where it gives
       the number of ways in which `n` objects can be permuted. It also
       arises in calculus, probability, number theory, etc.

       There is strict relation of factorial with gamma function. In
       fact `n! = gamma(n+1)` for nonnegative integers. Rewrite of this
       kind is very useful in case of combinatorial simplification.

       Computation of the factorial is done using two algorithms. For
       small arguments a precomputed look up table is used. However for bigger
       input algorithm Prime-Swing is used. It is the fastest algorithm
       known and computes `n!` via prime factorization of special class
       of numbers, called here the 'Swing Numbers'.

       Examples
       ========

       >>> from sympy import Symbol, factorial, S
       >>> n = Symbol('n', integer=True)

       >>> factorial(0)
       1

       >>> factorial(7)
       5040

       >>> factorial(-2)
       zoo

       >>> factorial(n)
       factorial(n)

       >>> factorial(2*n)
       factorial(2*n)

       >>> factorial(S(1)/2)
       factorial(1/2)

       See Also
       ========

       factorial2, RisingFactorial, FallingFactorial
    c                    ddl m}m} |dk(  r2 || j                  d   dz          |d| j                  d   dz         z  S t	        | |      )Nr   )gamma	polygamma   )'sympy.functions.special.gamma_functionsr-   r.   argsr   )r    argindexr-   r.   s       r#   fdiffzfactorial.fdiffU   sJ    Nq=1)*9Q		!q8H+III$T844r%   )!r/   r/   r/      r4         #   r7   i;  ?   i     i  i  #  r:   iS i{/  i! im  i isX iU iP
 ioik iIi/L iSi} #r;   z	list[int]_small_factorialsc                   |dk  r| j                   |   S t        t        |            g }}t        j                  d|dz         D ]8  }d|}}	 ||z  }|dkD  r|dz  dk(  r||z  }nn|dkD  s(|j                  |       : t        j                  |dz   |dz  dz         D ]  }||z  dz  dk(  s|j                  |       ! t        t        j                  |dz  dz   |dz               }t        |      }||z  S )N!   r4   r/   r      )_small_swingint_sqrtr   
primerangeappendr   )	clsnNprimesprimepq	L_product	R_products	            r#   _swingzfactorial._swingd   s   r6##A&&E!HrvA))!QU3 %!1%KA1uq5A:JA  q5MM!$% ))!a%A: )J!#q(MM%() U--adQhA>?IVIY&&r%   c                `    |dk  ry| j                  |dz        dz  | j                  |      z  S )Nr?   r/   )
_recursiverN   )rE   rF   s     r#   rP   zfactorial._recursive   s1    q5NN1a4(!+SZZ]::r%   c                   t        |      }|j                  r9|j                  rt        j                  S |t        j
                  u rt        j
                  S |j                  r|j                  rt        j                  S |j                  }|dk  r\| j                  s3d}t        dd      D ]"  }||z  }| j                  j                  |       $ | j                  |dz
     }t%        |      S t         t        j                  |      }t%        |      S t        |      j!                  d      }| j#                  |      d||z
  z  z  }t%        |      S y y )N   r/   1r?   )r   	is_Numberis_zeror   OneInfinity
is_Integeris_negativeComplexInfinityrJ   r<   rangerD   _gmpyfacbincountrP   r   )rE   rF   resultibitss        r#   evalzfactorial.eval   s)   AJ;;yyuuajjzz!==,,,A2v"44%&F%*1b\ E &! # 5 5 < <V DE "%!6!6qs!;$ #6?* *!&1 #6?*  #1v||C0!$!21q4x=!@"6?*=  r%   c                r   dt        t        |            }}dg|z  }d}t        j                  d|dz         D ]D  }|dkD  rd||z  }}|r||z  }||z  }|r||k  r||   |z  |z  ||<   2|t	        |||      z  |z  }F t        |      D ]*  \  }	}
|	dk(  s|
dk(  r|
dk(  r y|t	        |
|	|      z  |z  }, |S )Nr/   r?   r   )rA   rB   r   rC   pow	enumerate)r    rF   rK   resrG   pwmrI   yexbss              r#   _facmodzfactorial._facmod   s    CaMQ SU%%aQ/ 		/E1u!u*1FA%KA  1u1ea1#eQ**Q.		/  m 	)FBQw"'Qwc"b!n$q(C	) 
r%   c                J   | j                   d   }|j                  r|j                  r|j                  rt        |      }||z
  }|j                  rt
        j                  S |j                  }|dk(  r,|rd|z  S |du r |dz
  j                  rt
        j                  S y y |j                  rw|j                  rjt        t        |||f      \  }}}|r:|dz
  |k  r2| j                  |dz
  |      }t        ||dz
  |      }|dz  r| }||z  S | j                  ||      }||z  S y y y y y )Nr   r/   F   r?   )r1   
is_integeris_nonnegativeabsis_nonpositiver   Zerois_primerX   maprA   rm   re   )r    rK   rF   aqdisprimefcs          r#   	_eval_Modzfactorial._eval_Mod   s)   IIaL<<A,,QBQAvv++6
 !Av E)rAv.E.E vv /F)\\all"3Ar
3HAq"AEAI!\\!a%4 R!VR0Q3"$B 6M "\\!R06M '3\! 2>,<r%   c                $    ddl m}  ||dz         S Nr   r-   r/   r0   r-   )r    rF   	piecewiser!   r-   s        r#   _eval_rewrite_as_gammaz factorial._eval_rewrite_as_gamma   s    AQU|r%   c                t    ddl m} |j                  r&|j                  rt	        dd      } |||d|f      S y y )Nr   )Productra   T)integerr/   )sympy.concrete.productsr   rr   rq   r   )r    rF   r!   r   ra   s        r#   _eval_rewrite_as_Productz"factorial._eval_rewrite_as_Product   s;    3c4(A1q!Qi(( !-r%   c                l    | j                   d   j                  r| j                   d   j                  ryy y Nr   Tr1   rq   rr   r    s    r#   _eval_is_integerzfactorial._eval_is_integer   /    99Q<""tyy|'B'B (C"r%   c                l    | j                   d   j                  r| j                   d   j                  ryy y r   r   r   s    r#   _eval_is_positivezfactorial._eval_is_positive   r   r%   c                r    | j                   d   }|j                  r|j                  r|dz
  j                  S y y )Nr   r?   r   r    xs     r#   _eval_is_evenzfactorial._eval_is_even  5    IIaL<<A,,E))) -<r%   c                r    | j                   d   }|j                  r|j                  r|dz
  j                  S y y )Nr   r4   r   r   s     r#   _eval_is_compositezfactorial._eval_is_composite  r   r%   c                T    | j                   d   }|j                  s|j                  ryy r   )r1   rr   is_nonintegerr   s     r#   _eval_is_realzfactorial._eval_is_real  s&    IIaLq  /r%   Nc                    | j                   d   j                  |      }|j                  |d      }|j                  rt        j
                  S |j                  s| j                  |      S t        d| z        )Nr   zCannot expand %s around 0)	r1   as_leading_termsubsrU   r   rV   is_infinitefuncr   )r    r   logxcdirargarg0s         r#   _eval_as_leading_termzfactorial._eval_as_leading_term  sa    iil**1-xx1~<<55L!!99S>!3t<==r%   r/   TNr   )r&   r'   r(   r)   r3   r@   r<   __annotations__classmethodrN   rP   rc   rm   r|   r   r   r   r   r   r   r   r   r*   r%   r#   r   r   $   s    .`5L $&y%' '< ; ; &+ &+P<"<)*
*

>r%   r   c                      e Zd Zy)MultiFactorialN)r&   r'   r(   r*   r%   r#   r   r     s    r%   r   c                  f    e Zd ZdZeed               Zed        Zd Zd Z	d Z
ddZd Zd	 Zd
 Zy)subfactoriala  The subfactorial counts the derangements of $n$ items and is
    defined for non-negative integers as:

    .. math:: !n = \begin{cases} 1 & n = 0 \\ 0 & n = 1 \\
                    (n-1)(!(n-1) + !(n-2)) & n > 1 \end{cases}

    It can also be written as ``int(round(n!/exp(1)))`` but the
    recursive definition with caching is implemented for this function.

    An interesting analytic expression is the following [2]_

    .. math:: !x = \Gamma(x + 1, -1)/e

    which is valid for non-negative integers `x`. The above formula
    is not very useful in case of non-integers. `\Gamma(x + 1, -1)` is
    single-valued only for integral arguments `x`, elsewhere on the positive
    real axis it has an infinite number of branches none of which are real.

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Subfactorial
    .. [2] https://mathworld.wolfram.com/Subfactorial.html

    Examples
    ========

    >>> from sympy import subfactorial
    >>> from sympy.abc import n
    >>> subfactorial(n + 1)
    subfactorial(n + 1)
    >>> subfactorial(5)
    44

    See Also
    ========

    factorial, uppergamma,
    sympy.utilities.iterables.generate_derangements
    c                    |st         j                  S |dk(  rt         j                  S d\  }}t        d|dz         D ]  }||dz
  ||z   z  }} |S )Nr/   )r/   r   r?   )r   rV   ru   r[   )r    rF   z1z2ra   s        r#   _evalzsubfactorial._evalG  s]     55L!V66MFB1a!e_ /a!eb2g.B/Ir%   c                    |j                   rn|j                  r|j                  r| j                  |      S |t        j
                  u rt        j
                  S |t        j                  u rt        j                  S y y N)rT   rX   rr   r   r   NaNrW   )rE   r   s     r#   rc   zsubfactorial.evalT  sZ    ==~~#"4"4yy~%uu

"zz! # r%   c                l    | j                   d   j                  r| j                   d   j                  ryy y r   )r1   is_oddrr   r   s    r#   r   zsubfactorial._eval_is_even^  s.    99Q<499Q<#>#> $?r%   c                l    | j                   d   j                  r| j                   d   j                  ryy y r   r   r   s    r#   r   zsubfactorial._eval_is_integerb  r   r%   c                    ddl m} t        d      }t        j                  |z  t        |      z  }t        |       |||d|f      z  S )Nr   )	summationra   )sympy.concrete.summationsr   r   r   NegativeOner   )r    r   r!   r   ra   fs         r#   _eval_rewrite_as_factorialz'subfactorial._eval_rewrite_as_factorialf  sA    7#JMM1y|+~	!aC[ 999r%   c                    ddl m} ddlm}m} t
        j                  |dz   z   |t         t        z  |z        z   ||dz   d      z   ||dz         z    |d      z  S )Nr   )exp)r-   
lowergammar/   ro   )	&sympy.functions.elementary.exponentialr   r0   r-   r   r   r   r   r   )r    r   r   r!   r   r-   r   s          r#   r   z#subfactorial._eval_rewrite_as_gammal  s\    >Oa(aRU3Y7
37B8OOa.!"%b'* 	*r%   c                H    ddl m}  ||dz   d      t        j                  z  S )Nr   )
uppergammar/   ro   )r0   r   r   Exp1)r    r   r!   r   s       r#   _eval_rewrite_as_uppergammaz(subfactorial._eval_rewrite_as_uppergammar  s    F#'2&qvv--r%   c                l    | j                   d   j                  r| j                   d   j                  ryy y r   r   r   s    r#   _eval_is_nonnegativez!subfactorial._eval_is_nonnegativev  r   r%   c                l    | j                   d   j                  r| j                   d   j                  ryy y r   )r1   is_evenrr   r   s    r#   _eval_is_oddzsubfactorial._eval_is_oddz  s/    99Q<DIIaL$?$? %@r%   Nr   )r&   r'   r(   r)   r   r	   r   rc   r   r   r   r   r   r   r   r*   r%   r#   r   r     s[    'R 	  	 " ":*.r%   r   c                  @    e Zd ZdZed        Zd Zd Zd Zd Z	d	dZ
y)

factorial2aA  The double factorial `n!!`, not to be confused with `(n!)!`

    The double factorial is defined for nonnegative integers and for odd
    negative integers as:

    .. math:: n!! = \begin{cases} 1 & n = 0 \\
                    n(n-2)(n-4) \cdots 1 & n\ \text{positive odd} \\
                    n(n-2)(n-4) \cdots 2 & n\ \text{positive even} \\
                    (n+2)!!/(n+2) & n\ \text{negative odd} \end{cases}

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Double_factorial

    Examples
    ========

    >>> from sympy import factorial2, var
    >>> n = var('n')
    >>> n
    n
    >>> factorial2(n + 1)
    factorial2(n + 1)
    >>> factorial2(5)
    15
    >>> factorial2(-1)
    1
    >>> factorial2(-5)
    1/3

    See Also
    ========

    factorial, RisingFactorial, FallingFactorial
    c                Z   |j                   r|j                  st        d      |j                  r<|j                  r|dz  }d|z  t        |      z  S t        |      t        |dz
        z  S |j                  r)|t        j                  d|z
  dz  z  z  t        |       z  S t        d      y )Nz<argument must be nonnegative integer or negative odd integerr?   r/   )
rT   rX   
ValueErrorrr   r   r   r   r   r   r   )rE   r   ks      r#   rc   zfactorial2.eval  s     ==>>  "> ? ?
 !!;;aAa4)A,.. ~
37(;;; zzAMMa#gq[99Jt<LLL : ; ;! r%   c                    | j                   d   }|j                  r5|j                  ry|j                  r|j                  ry|j
                  ryy y y )Nr   FT)r1   rq   r   r   is_positiverU   r    rF   s     r#   r   zfactorial2._eval_is_even  sJ    IIaL<<xxyy==99    r%   c                    | j                   d   }|j                  r,|dz   j                  ry|j                  r|dz   j                  S y y )Nr   r/   Tr4   )r1   rq   rr   r   r   s     r#   r   zfactorial2._eval_is_integer  sI     IIaL<<A%%xxA---  r%   c                    | j                   d   }|j                  r|dz   j                  S |j                  r|j                  ry|j
                  ryy y )Nr   r4   FT)r1   r   rr   r   r   rU   r   s     r#   r   zfactorial2._eval_is_odd  sM     IIaL88E)))99}}yy  r%   c                    | j                   d   }|j                  r/|dz   j                  ry|j                  r|dz   dz  j                  S y y )Nr   r/   Tr?   )r1   rq   rr   r   r   r   s     r#   r   zfactorial2._eval_is_positive  sM     IIaL<<A%%xxQ!,,,  r%   c                    ddl m} ddlm} ddlm} d|dz  z   ||dz  dz         z   |dt        t        |d      d      f |dt        z        t        t        |d      d      f      z  S )Nr   )r   	Piecewiser   r?   r/   )	(sympy.functions.elementary.miscellaneousr   $sympy.functions.elementary.piecewiser   r0   r-   r   r   r   )r    rF   r   r!   r   r   r-   s          r#   r   z!factorial2._eval_rewrite_as_gamma  si    ABA1Q3xacAg&Ar#a)Q7G3HadRAq	1-.*0 0 	0r%   Nr   )r&   r'   r(   r)   r   rc   r   r   r   r   r   r*   r%   r#   r   r     s5    #J ; ;.
!.
	-0r%   r   c                  H    e Zd ZdZed        Zd
dZd Zd Zd Z	ddZ
d	 Zy)RisingFactorialap  
    Rising factorial (also called Pochhammer symbol [1]_) is a double valued
    function arising in concrete mathematics, hypergeometric functions
    and series expansions. It is defined by:

    .. math:: \texttt{rf(y, k)} = (x)^k = x \cdot (x+1) \cdots (x+k-1)

    where `x` can be arbitrary expression and `k` is an integer. For
    more information check "Concrete mathematics" by Graham, pp. 66
    or visit https://mathworld.wolfram.com/RisingFactorial.html page.

    When `x` is a `~.Poly` instance of degree $\ge 1$ with a single variable,
    `(x)^k = x(y) \cdot x(y+1) \cdots x(y+k-1)`, where `y` is the
    variable of `x`. This is as described in [2]_.

    Examples
    ========

    >>> from sympy import rf, Poly
    >>> from sympy.abc import x
    >>> rf(x, 0)
    1
    >>> rf(1, 5)
    120
    >>> rf(x, 5) == x*(1 + x)*(2 + x)*(3 + x)*(4 + x)
    True
    >>> rf(Poly(x**3, x), 2)
    Poly(x**6 + 3*x**5 + 3*x**4 + x**3, x, domain='ZZ')

    Rewriting is complicated unless the relationship between
    the arguments is known, but rising factorial can
    be rewritten in terms of gamma, factorial, binomial,
    and falling factorial.

    >>> from sympy import Symbol, factorial, ff, binomial, gamma
    >>> n = Symbol('n', integer=True, positive=True)
    >>> R = rf(n, n + 2)
    >>> for i in (rf, ff, factorial, binomial, gamma):
    ...  R.rewrite(i)
    ...
    RisingFactorial(n, n + 2)
    FallingFactorial(2*n + 1, n + 2)
    factorial(2*n + 1)/factorial(n - 1)
    binomial(2*n + 1, n + 2)*factorial(n + 2)
    gamma(2*n + 2)/gamma(n)

    See Also
    ========

    factorial, factorial2, FallingFactorial

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Pochhammer_symbol
    .. [2] Peter Paule, "Greatest Factorial Factorization and Symbolic
           Summation", Journal of Symbolic Computation, vol. 20, pp. 235-268,
           1995.

    c                   t              t        |      }t        j                  u s|t        j                  u rt        j                  S t        j                  u rt	        |      S |j
                  r|j                  rt        j                  S |j                  rىt        j                  u rt        j                  S t        j                  u r,|j                  rt        j                  S t        j                  S t        t              rGj                  }t        |      dk7  rt        d      t!        fdt#        t%        |            d      S t!        fdt#        t%        |            d      S t        j                  u rt        j                  S t        j                  u rt        j                  S t        t              rWj                  }t        |      dk7  rt        d      dt!        fdt#        dt'        t%        |            dz         d      z  S dt!        fdt#        dt'        t%        |            dz         d      z  S |j(                  dk(  r*j(                  rj*                  rt        j,                  S y y y )Nr/   0rf only defined for polynomials on one generatorc                ,    | j                  |      z  S r   shiftrra   r   s     r#   <lambda>z&RisingFactorial.eval.<locals>.<lambda>Q  s    ./n r%   c                    | |z   z  S r   r*   r   s     r#   r   z&RisingFactorial.eval.<locals>.<lambda>U      q!a%y r%   c                .    | j                  |       z  S r   r   r   s     r#   r   z&RisingFactorial.eval.<locals>.<lambda>d  s    01177A2; r%   c                    | |z
  z  S r   r*   r   s     r#   r   z&RisingFactorial.eval.<locals>.<lambda>h  s    ,-q1uI r%   F)r   r   r   rV   r   rX   rU   r   rW   NegativeInfinityr   
isinstancer   genslenr   r   r[   rA   rs   rq   rY   ru   rE   r   r   r   s    `  r#   rc   zRisingFactorial.eval5  s   AJAJ:aee55L!%%ZQ<\\yyuu==AJJ zz)a00088#$#5#55#$::-%a.#$66D"4y1}&0 2K 'L !L (. /=.3CFmQ(@ !@ $**@*/A-$< < AJJ zz)a000 zz)%a.#$66D"4y1}&0 2K 'L !L () 1@05aSVq0I1*N (N !N $%V -6,1!SQ[1_,Eq&J $J J <<5 ||vv !.| !r%   c                R   ddl m} ddlm} |sK|dk  dk(  r/t        j
                  |z   |d|z
        z   || |z
  dz         z  S  |||z          ||      z  S  | |||z          ||      z  |dkD  ft        j
                  |z   |d|z
        z   || |z
  dz         z  df      S Nr   r   r   Tr/   r   r   r0   r-   r   r   r    r   r   r   r!   r   r-   s          r#   r   z&RisingFactorial._eval_rewrite_as_gammap  s    BAQ4}}a'a!e4uaR!VaZ7HHHQ<%(**1q5\E!H$a!e,]]AeAEl*UA26A:->>EG 	Gr%   c                &    t        ||z   dz
  |      S Nr/   )FallingFactorialr    r   r   r!   s       r#   !_eval_rewrite_as_FallingFactorialz1RisingFactorial._eval_rewrite_as_FallingFactorial{  s    A	1--r%   c                    ddl m} |j                  ri|j                  r\ |t        ||z   dz
        t        |dz
        z  |dkD  ft        j
                  |z  t        |       z  t        | |z
        z  df      S y y Nr   r   r/   Tr   r   rq   r   r   r   r    r   r   r!   r   s        r#   r   z*RisingFactorial._eval_rewrite_as_factorial~  s{    B<<ALL1q519%iA&66A>!)QB-/	1"q&0AA4HJ J )<r%   c                X    |j                   rt        |      t        ||z   dz
  |      z  S y r   rq   r   binomialr   s       r#   _eval_rewrite_as_binomialz)RisingFactorial._eval_rewrite_as_binomial  s,    <<Q<(1q519a"888 r%   Nc                   ddl m} |r|j                  |t        j                        }|t        j                  u r% |||z         j                  dd       ||      z  S |t        j                  u r@t        j                  |z   |d|z
        z   || |z
  dz         j                  dd      z  S | j                  |      j                  dd      S Nr   r   	tractableT)deepr/   )r0   r-   r   r   rW   rewriter   r   r    r   r   limitvarr!   r-   k_lims          r#   _eval_rewrite_as_tractablez*RisingFactorial._eval_rewrite_as_tractable  s    AFF8QZZ0E

"a!e,,[t,DuQxOP!,,,q(q1u5qb1fqj8I8Q8QR]dh8Q8iij||E"**;T*BBr%   c                    t        | j                  d   j                  | j                  d   j                  | j                  d   j                  f      S Nr   r/   r   r1   rq   rr   r   s    r#   r   z RisingFactorial._eval_is_integer  E    $))A,11499Q<3J3J))A,557 8 	8r%   r   r   )r&   r'   r(   r)   r   rc   r   r   r   r   r  r   r*   r%   r#   r   r     s>    ;z 8 8t	G.J9C8r%   r   c                  H    e Zd ZdZed        Zd
dZd Zd Zd Z	ddZ
d	 Zy)r   a0  
    Falling factorial (related to rising factorial) is a double valued
    function arising in concrete mathematics, hypergeometric functions
    and series expansions. It is defined by

    .. math:: \texttt{ff(x, k)} = (x)_k = x \cdot (x-1) \cdots (x-k+1)

    where `x` can be arbitrary expression and `k` is an integer. For
    more information check "Concrete mathematics" by Graham, pp. 66
    or [1]_.

    When `x` is a `~.Poly` instance of degree $\ge 1$ with single variable,
    `(x)_k = x(y) \cdot x(y-1) \cdots x(y-k+1)`, where `y` is the
    variable of `x`. This is as described in

    >>> from sympy import ff, Poly, Symbol
    >>> from sympy.abc import x
    >>> n = Symbol('n', integer=True)

    >>> ff(x, 0)
    1
    >>> ff(5, 5)
    120
    >>> ff(x, 5) == x*(x - 1)*(x - 2)*(x - 3)*(x - 4)
    True
    >>> ff(Poly(x**2, x), 2)
    Poly(x**4 - 2*x**3 + x**2, x, domain='ZZ')
    >>> ff(n, n)
    factorial(n)

    Rewriting is complicated unless the relationship between
    the arguments is known, but falling factorial can
    be rewritten in terms of gamma, factorial and binomial
    and rising factorial.

    >>> from sympy import factorial, rf, gamma, binomial, Symbol
    >>> n = Symbol('n', integer=True, positive=True)
    >>> F = ff(n, n - 2)
    >>> for i in (rf, ff, factorial, binomial, gamma):
    ...  F.rewrite(i)
    ...
    RisingFactorial(3, n - 2)
    FallingFactorial(n, n - 2)
    factorial(n)/2
    binomial(n, n - 2)*factorial(n - 2)
    gamma(n + 1)/2

    See Also
    ========

    factorial, factorial2, RisingFactorial

    References
    ==========

    .. [1] https://mathworld.wolfram.com/FallingFactorial.html
    .. [2] Peter Paule, "Greatest Factorial Factorization and Symbolic
           Summation", Journal of Symbolic Computation, vol. 20, pp. 235-268,
           1995.

    c                   t              t        |      }t        j                  u s|t        j                  u rt        j                  S |j                  r|k(  rt	              S |j
                  r|j                  rt        j                  S |j                  rىt        j                  u rt        j                  S t        j                  u r,|j                  rt        j                  S t        j                  S t        t              rGj                  }t        |      dk7  rt!        d      t#        fdt%        t'        |            d      S t#        fdt%        t'        |            d      S t        j                  u rt        j                  S t        j                  u rt        j                  S t        t              rWj                  }t        |      dk7  rt!        d      dt#        fdt%        dt)        t'        |            dz         d      z  S dt#        fdt%        dt)        t'        |            dz         d      z  S y )Nr/   z0ff only defined for polynomials on one generatorc                .    | j                  |       z  S r   r   r   s     r#   r   z'FallingFactorial.eval.<locals>.<lambda>  s    ./!o r%   c                    | |z
  z  S r   r*   r   s     r#   r   z'FallingFactorial.eval.<locals>.<lambda>  r   r%   r   c                ,    | j                  |      z  S r   r   r   s     r#   r   z'FallingFactorial.eval.<locals>.<lambda>  s    011771: r%   c                    | |z   z  S r   r*   r   s     r#   r   z'FallingFactorial.eval.<locals>.<lambda>	  s    AE r%   )r   r   r   rq   r   rX   rU   rV   r   rW   r   r   r   r   r   r   r   r   r[   rA   rs   r   s    `  r#   rc   zFallingFactorial.eval  s   AJAJ:aee55L\\a1fQ<\\yyuu==AJJ zz)a00088#$#5#55#$::-%a.#$66D"4y1}&0 2K 'L !L (. />.3CFmQ(@ !@ $**@*/A-$< < AJJ zz)a000 zz)%a.#$66D"4y1}&0 2K 'L !L () 1?05aSVq0I1*N (N !N $%V,B,1!SQ[1_,Eq&J $J JS r%   c                R   ddl m} ddlm} |sK|dk  dk(  r)t        j
                  |z   |||z
        z   ||       z  S  ||dz          |||z
  dz         z  S  | ||dz          |||z
  dz         z  |dk\  ft        j
                  |z   |||z
        z   ||       z  df      S r   r   r   s          r#   r   z'FallingFactorial._eval_rewrite_as_gamma  s    BAA$}}a'a!e4uaRy@@Q<%A	"2221q5\E!a%!),,a1f5]]AeAEl*UA2Y6=? 	?r%   c                &    t        ||z
  dz   |      S r   )rfr   s       r#    _eval_rewrite_as_RisingFactorialz1FallingFactorial._eval_rewrite_as_RisingFactorial  s    !a%!)Qr%   c                L    |j                   rt        |      t        ||      z  S y r   r   r   s       r#   r   z*FallingFactorial._eval_rewrite_as_binomial  s#    <<Q<(1a.00 r%   c                    ddl m} |j                  ri|j                  r\ |t        |      t        | |z         z  |dk\  ft        j
                  |z  t        ||z
  dz
        z  t        | dz
        z  df      S y y r   r   r   s        r#   r   z+FallingFactorial._eval_rewrite_as_factorial  s{    B<<ALL1iQ//a8!)AEAI"66y!a7HH$OQ Q )<r%   Nc                   ddl m} |r|j                  |t        j                        }|t        j                  u r:t        j
                  |z   |||z
        j                  dd      z   ||       z  S |t        j                  u r+ ||dz          |||z
  dz         j                  dd      z  S | j                  |      j                  dd      S r   )r0   r-   r   r   rW   r   r  r   r  s          r#   r  z+FallingFactorial._eval_rewrite_as_tractable%  s    AFF8QZZ0E

"q(q1u)=)=kPT)=)UUX]_`^`Xaab!,,,a!euQUQY'7'?'?RV'?'WWX||E"**;T*BBr%   c                    t        | j                  d   j                  | j                  d   j                  | j                  d   j                  f      S r  r	  r   s    r#   r   z!FallingFactorial._eval_is_integer/  r
  r%   r   r   )r&   r'   r(   r)   r   rc   r   r  r   r   r  r   r*   r%   r#   r   r     s?    <| 2J 2Jh	? 1QC8r%   r   c                  t    e Zd ZdZddZed        Zed        Zd Zd Z	d Z
ddZdd
Zd Zd Zd ZddZy	)r   a  Implementation of the binomial coefficient. It can be defined
    in two ways depending on its desired interpretation:

    .. math:: \binom{n}{k} = \frac{n!}{k!(n-k)!}\ \text{or}\
                \binom{n}{k} = \frac{(n)_k}{k!}

    First, in a strict combinatorial sense it defines the
    number of ways we can choose `k` elements from a set of
    `n` elements. In this case both arguments are nonnegative
    integers and binomial is computed using an efficient
    algorithm based on prime factorization.

    The other definition is generalization for arbitrary `n`,
    however `k` must also be nonnegative. This case is very
    useful when evaluating summations.

    For the sake of convenience, for negative integer `k` this function
    will return zero no matter the other argument.

    To expand the binomial when `n` is a symbol, use either
    ``expand_func()`` or ``expand(func=True)``. The former will keep
    the polynomial in factored form while the latter will expand the
    polynomial itself. See examples for details.

    Examples
    ========

    >>> from sympy import Symbol, Rational, binomial, expand_func
    >>> n = Symbol('n', integer=True, positive=True)

    >>> binomial(15, 8)
    6435

    >>> binomial(n, -1)
    0

    Rows of Pascal's triangle can be generated with the binomial function:

    >>> for N in range(8):
    ...     print([binomial(N, i) for i in range(N + 1)])
    ...
    [1]
    [1, 1]
    [1, 2, 1]
    [1, 3, 3, 1]
    [1, 4, 6, 4, 1]
    [1, 5, 10, 10, 5, 1]
    [1, 6, 15, 20, 15, 6, 1]
    [1, 7, 21, 35, 35, 21, 7, 1]

    As can a given diagonal, e.g. the 4th diagonal:

    >>> N = -4
    >>> [binomial(N, i) for i in range(1 - N)]
    [1, -4, 10, -20, 35]

    >>> binomial(Rational(5, 4), 3)
    -5/128
    >>> binomial(Rational(-5, 4), 3)
    -195/128

    >>> binomial(n, 3)
    binomial(n, 3)

    >>> binomial(n, 3).expand(func=True)
    n**3/6 - n**2/2 + n/3

    >>> expand_func(binomial(n, 3))
    n*(n - 2)*(n - 1)/6

    In many cases, we can also compute binomial coefficients modulo a
    prime p quickly using Lucas' Theorem [2]_, though we need to include
    `evaluate=False` to postpone evaluation:

    >>> from sympy import Mod
    >>> Mod(binomial(156675, 4433, evaluate=False), 10**5 + 3)
    28625

    Using a generalisation of Lucas's Theorem given by Granville [3]_,
    we can extend this to arbitrary n:

    >>> Mod(binomial(10**18, 10**12, evaluate=False), (10**5 + 3)**2)
    3744312326

    References
    ==========

    .. [1] https://www.johndcook.com/blog/binomial_coefficients/
    .. [2] https://en.wikipedia.org/wiki/Lucas%27s_theorem
    .. [3] Binomial coefficients modulo prime powers, Andrew Granville,
        Available: https://web.archive.org/web/20170202003812/http://www.dms.umontreal.ca/~andrew/PDF/BinCoeff.pdf
    c                   ddl m} |dk(  r8| j                  \  }}t        ||       |d|dz          |d||z
  dz         z
  z  S |dk(  r8| j                  \  }}t        ||       |d||z
  dz          |d|dz         z
  z  S t	        | |      )Nr   )r.   r/   r?   )r0   r.   r1   r   r   )r    r2   r.   rF   r   s        r#   r3   zbinomial.fdiff  s    Eq=99DAqAq>9QA#6!QUQY'$( ) )]99DAqAq>9QA	#:!QU#$$ % % %T844r%   c                   |j                   r|j                   r|dk\  rt        |      t        |      }}||kD  rt        j                  S ||dz  kD  r||z
  }t        t        t	        j                  ||            S ||z
  d}}t        d|dz         D ]  }|dz  }||z  |z  } t        |      S ||z
  d}}t        d|dz         D ]  }|dz  }||z  } |t        |      z  S y )Nr   r?   r/   )	rX   rA   r   ru   r\   r   bincoefr[   
_factorial)r    rF   r   ry   r`   ra   s         r#   r   zbinomial._eval  s    <<||Q1vs1v1q566MaZAA
 $"5==A#677E16q!a% -AFA#aZ1_F- v&E16q!a%  AFAaKF  
1--3 r%   c                   t        t        ||f      \  }}||z
  }|j                  |j                  }}|j                  s|s|du r|j                  rt
        j                  S |dz
  j                  s|s|du r|dz
  j                  r|S |j                  ra|j                  s|r|r|j                  rt
        j                  S |j                  r(| j                  ||      }|r|j                  d      S |S y |du r|rt
        j                  S |j                  r,ddlm}  ||dz          ||dz          |||z
  dz         z  z  S y )NFr/   T)basicr   r   )rw   r   rr   rq   rU   r   rV   rY   ru   	is_numberr   expandrZ   r0   r-   )rE   rF   r   ry   n_nonnegn_isintrg   r-   s           r#   rc   zbinomial.eval  s   7QF#1E,,all'99(g&6II55LE??Gu,<UOOH<<}}g!--vvii1o14szzz-=#=  7$$$[[EQ<q1ueAEAI.>!>?? r%   c                   | j                   \  }}t        d |||fD              rt        d      t        d |||fD              r-t	        t
        ||f      \  }}t        |      d}}|dk  rt        j                  S |dk  r| |z   dz
  }|dz  rdnd}||kD  rt        j                  S |j                  }t        |      }|r||k  r3||}}|s|r|t        ||z  ||z        z  |z  }||z  ||z  }}|r%|r(nk||z
  }	||	kD  r|	|}	}d}
t        d|dz         D ]
  }|
|z  |z  }
 |
}t        |dz   |	dz         D ]
  }||z  |z  } ||z  }t        |	dz   |dz         D ]
  }||z  |z  } |t        |
|z  |z  |dz
  |      z  }||z  }nt        |      |k  r|dk7  rt        |||      }nt        t        |            }t        j                   d|dz         D ]  }|||z
  kD  r	||z  |z  }||dz  kD  r||kD  r||z  ||z  k  s.||z  |z  }7||}}dx}}|dkD  r,t        ||z  ||z  |z   k        }||z  ||z  }}||z  }|dkD  r,|dkD  sv|t        |||      z  }||z  } t        ||z        S y )Nc              3  8   K   | ]  }|j                   d u   yw)FN)rq   .0r   s     r#   	<genexpr>z%binomial._eval_Mod.<locals>.<genexpr>  s     8q||u$8s   z"Integers expected for binomial Modc              3  4   K   | ]  }|j                     y wr   )rX   r&  s     r#   r(  z%binomial._eval_Mod.<locals>.<genexpr>  s     /q||/s   r/   r   r?   ro   )r1   anyr   allrw   rA   rs   r   ru   rv   r   r[   re   rB   r   r   rC   )r    rK   rF   r   rx   rg   rz   rG   Kry   kfra   dfMrI   r   as                    r#   r|   zbinomial._eval_Mod  s	   yy18q!Qi88ABB/aAY//sQF#DAq!faB 1uvv1uBFQJaCbQ 1uvvkkGRB6aqAq!(1r61r6"::R? BwR1 q AA1u !1B"1a!e_ 'TBY'B"1q5!a%0 'TBY'2IC"1q5!a%0 )!!ebj) 3r"urz26266C2ICqA!q&"1a+ aM"--aQ7 &Eq1u}!%i"na u9q5y0"%e)b.C !1"#a!e #QY1u9q=$A BA#$:qEzqA1HC  !e
 73uc2#66C2IC'&* S1W:W 0r%   c                   | j                   d   }|j                  rt        | j                    S | j                   d   }||z
  j                  r||z
  }|j                  rv|j                  rt
        j                  S |j                  rt
        j                  S | j                   d   d}}t        d|dz         D ]  }|||z
  |z   z  } |t        |      z  S t        | j                    S )z
        Function to expand binomial(n, k) when m is positive integer
        Also,
        n is self.args[0] and k is self.args[1] while using binomial(n, k)
        r   r/   )r1   rT   r   rX   rU   r   rV   rY   ru   r[   r  )r    hintsrF   r   r`   ra   s         r#   _eval_expand_funczbinomial._eval_expand_func3  s     IIaL;;TYY''IIaLaCAA<<yyuuvv IIaL!6q!a% (Aa!eai'F(
1--TYY''r%   c                N    t        |      t        |      t        ||z
        z  z  S r   )r   r    rF   r   r!   s       r#   r   z#binomial._eval_rewrite_as_factorialN  s#    |Yq\)AE*::;;r%   c                Z    ddl m}  ||dz          ||dz          |||z
  dz         z  z  S r~   r   )r    rF   r   r   r!   r-   s         r#   r   zbinomial._eval_rewrite_as_gammaQ  s2    AQU|U1q5\%A	*::;;r%   Nc                D    | j                  ||      j                  d      S )Nr   )r   r  )r    rF   r   r  r!   s        r#   r  z#binomial._eval_rewrite_as_tractableU  s     **1a088EEr%   c                L    |j                   rt        ||      t        |      z  S y r   )rq   ffr   r5  s       r#   r   z*binomial._eval_rewrite_as_FallingFactorialX  s#    <<a8il** r%   c                r    | j                   \  }}|j                  r|j                  ry|j                  du ryy NTF)r1   rq   r    rF   r   s      r#   r   zbinomial._eval_is_integer\  s3    yy1<<ALL\\U" #r%   c                    | j                   \  }}|j                  rB|j                  r5|j                  s|j                  s|j                  ry|j                  du ryy y y r;  )r1   rq   rr   rY   r   r<  s      r#   r   zbinomial._eval_is_nonnegativec  sO    yy1<<ALL1==AIIe# $ )<r%   c                T    ddl m} | j                  |      j                  |||      S )Nr   r   )r   r   )r0   r-   r  r   )r    r   r   r   r-   s        r#   r   zbinomial._eval_as_leading_termk  s&    A||E"88D8QQr%   r   r   r   r   )r&   r'   r(   r)   r3   r   r   rc   r|   r3  r   r   r  r   r   r   r   r*   r%   r#   r   r   <  si    [z5 . .< @ @.Qf(6<<F+Rr%   r   N)/
__future__r   	functoolsr   
sympy.corer   r   r   r   sympy.core.cacher	   sympy.core.functionr
   r   r   sympy.core.logicr   sympy.core.numbersr   r   r   sympy.core.relationalr   sympy.external.gmpyr   r\   sympy.ntheoryr   sympy.ntheory.residue_ntheoryr   sympy.polys.polytoolsr   mathr   r  r   r   rB   r   r   r   r   r   r   r  r9  r   r*   r%   r#   <module>rL     s    "  - - $ G G & - - $ -  6 & = =H &s>% s>j	* 	_( _Dp0& p0p^8+ ^8BY8, Y8x qR$ qRr%   