o
    *ήcd                      @   sn  d dl mZ d dlmZ d dl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 d d
lmZ d dlmZ d dlZd dlZd dlmZ edZerd dlmZmZ d dlm Z m!Z!m"Z" d dl#m$Z$m%Z% edddd Z&e!eZ'G dd dZ(edddd Z)edddd Z*eddd$ddZ+eddd%d d!Z,eddd"d# Z-dS )&    )import_module)doctest_depends_on)IntegerFloat)Add)Function)Mul)E)Pow)S)Integral)expN)powsimpmatchpy)ManyToOneReplacerManyToOneMatcher)rubi_exprubi_unevaluated_exprprocess_trig)op_iterop_len)r   )modulesc                  C   s  ddl m}  ddlm} ddlm} ddlm} ddlm	} ddl
m} ddlm} dd	lm} dd
lm} ddlm}	 ddlm}
 ddlm} ddlm} ddlm} ddlm} ddlm} ddl m!} g }||  7 }|| 7 }|| 7 }|| 7 }|| 7 }|| 7 }|| 7 }|| 7 }|| 7 }|| 7 }||	 7 }||
 7 }|| 7 }|| 7 }|| 7 }|| 7 }|| 7 }t"| }||fS )a9  
        Returns rubi ManyToOneReplacer by adding all rules from different modules.

        Uncomment the lines to add integration capabilities of that module.

        Currently, there are parsing issues with special_function,
        derivative and miscellaneous_integration. Hence they are commented.
        r   )integrand_simplification)linear_products)quadratic_products)binomial_products)trinomial_products)miscellaneous_algebraic)exponential)
logarithms)sine)tangent)secant)miscellaneous_trig)inverse_trig)
hyperbolic)inverse_hyperbolic)special_functions)miscellaneous_integration)#3sympy.integrals.rubi.rules.integrand_simplificationr   *sympy.integrals.rubi.rules.linear_productsr   -sympy.integrals.rubi.rules.quadratic_productsr   ,sympy.integrals.rubi.rules.binomial_productsr   -sympy.integrals.rubi.rules.trinomial_productsr   2sympy.integrals.rubi.rules.miscellaneous_algebraicr   &sympy.integrals.rubi.rules.exponentialr   %sympy.integrals.rubi.rules.logarithmsr   sympy.integrals.rubi.rules.siner    "sympy.integrals.rubi.rules.tangentr!   !sympy.integrals.rubi.rules.secantr"   -sympy.integrals.rubi.rules.miscellaneous_trigr#   'sympy.integrals.rubi.rules.inverse_trigr$   %sympy.integrals.rubi.rules.hyperbolicr%   -sympy.integrals.rubi.rules.inverse_hyperbolicr&   ,sympy.integrals.rubi.rules.special_functionsr'   4sympy.integrals.rubi.rules.miscellaneous_integrationr(   r   )r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   rulesrubi r<   D/tmp/pip-target-vg8gfxp4/lib/python/sympy/integrals/rubi/rubimain.pyget_rubi_object   sJ   

















r>   c                   @   sD   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dS )LoadRubiReplacerz-
    Class trick to load RUBI only once.
    Nc                 C   sD   t d u r
td d S tjd urtjS t| }d |_d |_|t_|S )NzMatchPy library not found)r   printr?   	_instanceobject__new___rubi_rules)clsobjr<   r<   r=   rC   X   s   

zLoadRubiReplacer.__new__c                 C   s*   | j d ur| j S t \}}|| _ || _|S N)rD   r>   rE   )selfr;   r:   r<   r<   r=   loadd   s   

zLoadRubiReplacer.loadc                 C   L   dd l }|  }t|d}||| W d    d S 1 sw   Y  d S Nr   wb)picklerJ   opendump)rI   filenamerN   r;   foutr<   r<   r=   	to_picklel   
   "zLoadRubiReplacer.to_picklec                 C   rK   rL   )dillrJ   rO   rP   )rI   rQ   rU   r;   rR   r<   r<   r=   to_dillr   rT   zLoadRubiReplacer.to_dillc                 C   H   dd l }t|d}||| _W d    | jS 1 sw   Y  | jS Nr   rb)rN   rO   rJ   rD   )rI   rQ   rN   finr<   r<   r=   from_picklex      
zLoadRubiReplacer.from_picklec                 C   rW   rX   )rU   rO   rJ   rD   )rI   rQ   rU   rZ   r<   r<   r=   	from_dill~   r\   zLoadRubiReplacer.from_dill)__name__
__module____qualname____doc__rA   rC   rJ   rS   rV   r[   r]   r<   r<   r<   r=   r?   Q   s    r?   c                 C   s   |  tr| tt} | S )a  
    Rubi's `rubi_exp` need to be replaced back to SymPy's general `exp`.

    Examples
    ========
    >>> from sympy import Function, E, Integral
    >>> from sympy.integrals.rubi.rubimain import process_final_integral
    >>> from sympy.integrals.rubi.utility_function import rubi_unevaluated_expr
    >>> from sympy.abc import a, x
    >>> _E = rubi_unevaluated_expr(E)
    >>> process_final_integral(Integral(a, x))
    Integral(a, x)
    >>> process_final_integral(_E**5)
    exp(5)

    )has_Ereplacer	   )exprr<   r<   r=   process_final_integral   s   
rf   c                 C   s\   g }g }t | tr,| jD ]}t |tttfr|| q|| qtt| t|  S | S )a@  
    This function is needed to preprocess an expression as done in matchpy
    `x^a*x^b` in matchpy auotmatically transforms to `x^(a+b)`

    Examples
    ========

    >>> from sympy.integrals.rubi.rubimain import rubi_powsimp
    >>> from sympy.abc import a, b, x
    >>> rubi_powsimp(x**a*x**b)
    x**(a + b)

    )
isinstancer   argsr
   r   sym_expappendr   )re   lst_powlst_non_powir<   r<   r=   rubi_powsimp   s   

rn   Fc                 C   s   t   }| tt} t| } t| } t| tt	t
tfr"t| | S t| tr=d}| jD ]}||t||7 }q,t|S tt| |}t|S )aW  
    Rule based algorithm for integration. Integrates the expression by applying
    transformation rules to the expression.

    Returns `Integrate` if an expression cannot be integrated.

    Parameters
    ==========
    expr : integrand expression
    var : variable of integration

    Returns Integral object if unable to integrate.
    r   )r?   rJ   rd   ri   r   r   rn   rg   intr   floatr   r   r   rh   r   rf   util_rubi_integrate)re   var	showstepsr;   resultsexr<   r<   r=   rubi_integrate   s   


rv   
   c                    sX   t    t| } | tt} t|D ]}| dd  fdd}| |kr)|  S q|S )Nc                 S   s
   t | tS rH   )rg   r   xr<   r<   r=   <lambda>   s   
 z%util_rubi_integrate.<locals>.<lambda>c                    s    j | ddS )Nrw   )	max_count)rd   rx   r;   r<   r=   rz      s    )r?   rJ   r   rd   ri   r   range)re   rs   max_looprm   rt   r<   r|   r=   rq      s   

rq   c           
      C   s   t  }|j}|t| |}|D ]C\}}td tt| t|\}}td| td| td t	t
d|d d}	t|j|	d   t| t  qdS )	z
    Prints the list or rules which match to `expr`.

    Parameters
    ==========
    expr : integrand expression
    var : variable of integration
    zRule matching: z	On line: 
zPattern matching: z^\s*rule(\d+)r      N)r?   matchermatchr   r@   inspectgetsourcefilegetsourcelinesjoinro   regrouppatterns)
re   rr   r;   r   miterfunecodelinenopattnor<   r<   r=   get_matching_rule_definition   s   

r   )F)Frw   ).sympy.externalr   sympy.utilities.decoratorr   
sympy.corer   r   sympy.core.addr   sympy.core.functionr   sympy.core.mulr   sympy.core.numbersr	   sympy.core.powerr
   sympy.core.singletonr   sympy.integrals.integralsr   sympy.functionsr   ri   r   r   sympy.simplify.powsimpr   r   r   r   %sympy.integrals.rubi.utility_functionr   r   r   !sympy.utilities.matchpy_connectorr   r   r>   rc   r?   rf   rn   rv   rq   r   r<   r<   r<   r=   <module>   sB    
44

