
~9\c        e   @   s  d  Z  d d l Z d d l Z d d l Z d d l m Z m Z m Z m Z d d l	 m
 Z
 d d l m Z m Z d d l m Z d e f d     YZ d	   Z e d
 d d d d d d d d d d d d d d d d d d d d d d d  d! d  d" d# d$ d# d% d& d' d( d) d* d+ d, d- d. d/ d0 d1 d2 d3 d4 d5 d6 d7 d6 d8 d9 d: d9 d; d< d= d< d> d? d@ dA dB dC dD dE dF dG dH dI dJ dK dL dM dN dO dP dQ dR dS dT dU dV dW dX dY dZ d[ d\ d] d^ d_ d` da db dc dd dc de df  2Z i dg dh 6di dj 6Z i dk dl 6dm dn 6Z do dp dq dr ds dt du dv dw dx dy dz d{ d| d} d~ d d d d d d d d d d dw dy d d g Z d   Z d   Z i  d  Z i  d  Z g  d d  Z d d  Z e g  e d  Z g  d  Z  d   Z! d   Z" d   Z# d   Z$ d   Z% d   Z& d   Z' d   Z( d d d  Z) d S(   s  
Parser for FullForm[Downvalues[]] of Mathematica rules.

This parser is customised to parse the output in MatchPy rules format. Multiple
`Constraints` are divided into individual `Constraints` because it helps the
MatchPy's `ManyToOneReplacer` to backtrack earlier and improve the speed.

Parsed output is formatted into readable format by using `sympify` and print the
expression using `sstr`. This replaces `And`, `Mul`, 'Pow' by their respective
symbols.

Mathematica
===========

To get the full form from Wolfram Mathematica, type:
```
ShowSteps = False
Import["RubiLoader.m"]
Export["output.txt", ToString@FullForm@DownValues@Int]
```

The file ``output.txt`` will then contain the rules in parseable format.

References
==========
[1] http://reference.wolfram.com/language/ref/FullForm.html
[2] http://reference.wolfram.com/language/ref/DownValues.html
[3] https://gist.github.com/Upabjojr/bc07c49262944f9c1eb0
iN(   t   sympifyt   Functiont   Sett   Symbol(   t   string_types(   t   sstrt
   StrPrinter(   t   debugt   RubiStrPrinterc           B   s   e  Z d    Z RS(   c         C   s   d |  j  | j d  S(   Ns   Not(%s)i    (   t   _printt   args(   t   selft   expr(    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt
   _print_Not'   s    (   t   __name__t
   __module__R   (    (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyR   &   s   c         K   s   t  |  j |   S(   N(   R   t   doprint(   R   t   settings(    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt   rubi_printer*   s    t   Timest   Mult   Plust   Addt   Powert   Powt   Logt   logt   Expt   expt   Sqrtt   sqrtt   Cost   cost   Sint   sint   Tant   tant   Cots   1/tant   cott   Secs   1/cost   sect   Cscs   1/sint   csct   ArcSint   asint   ArcCost   acost   ArcCott   acott   ArcSect   asect   ArcCsct   acsct   Sinht   sinht   Cosht   cosht   Tanht   tanht   Coths   1/tanht   cotht   Sechs   1/cosht   secht   Cschs   1/sinht   cscht   ArcSinht   asinht   ArcCosht   acosht   ArcTanht   atanht   ArcCotht   acotht   ArcSecht   asecht   ArcCscht   acscht   Expandt   expandt   Imt   imt   Ret   ret   Flattent   flattent   Polylogt   polylogt   Cancelt   cancelt
   TrigExpandt   expand_trigt   Signt   signt   Simplifyt   simplifyt   Defert   UnevaluatedExprt   Identityt   St   Sumt   Sum_doitt   Modulet   Witht   Blockt   Nullt   Nonet   _gcdt   gcdt   _jnt   jnt
   ImaginaryIs   \[ImaginaryI]t	   _UseGammas	   $UseGammat   BinomialPartst   BinomialDegreet   TrinomialPartst   GeneralizedBinomialPartst   GeneralizedTrinomialPartst   PseudoBinomialPartst   PerfectPowerTestt   SquareFreeFactorTestt*   SubstForFractionalPowerOfQuotientOfLinearst"   FractionalPowerOfQuotientOfLinearst"   InverseFunctionOfQuotientOfLinearst   FractionalPowerOfSquareQt   FunctionOfLineart   FunctionOfInverseLineart   FunctionOfTrigt   FindTrigFactort   FunctionOfLogt   PowerVariableExpnt   FunctionOfSquareRootOfQuadratict   SubstForFractionalPowerOfLineart   FractionalPowerOfLineart   InverseFunctionOfLineart   Dividest   DerivativeDividest
   TrigSquaret   SplitProductt   FunctionOfHyperbolict   SplitSumc         C   s   t  |  t  r3 x |  D] } t |  r t Sq Wnm t |   t d  k sc t |   t d  k r x: t D] } |  j t |   rj t Sqj Wn |  t k r t St S(   s   
    This function returns whether an expression contains functions which have different return types in
    diiferent cases.
    Rf   Re   (	   t
   isinstancet   listt   contains_diff_return_typet   Truet   typeR   t   f_diff_return_typet   hast   False(   t   at   i(    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyR   w   s    0c   	      C   s[  g  } | g } t  j d |   } d } x)| D]!} | d k rD Pn  | j   } |  | | !j d d  j d d  j d d  j   } | j   d k r | d k rC| d j |  qCn | j   d k r| d k r | d j |  n  | j   | d } n> | j   d k rC| d j | g  | j | d d  n  | j	   } q. W| d S(	   s@   
    Parses FullForm[Downvalues[]] generated by Mathematica
    s   [\[\],]i    t   ,t    t   ]t   [iN(
   RR   t   finditerRi   t   startt   replacet   stript   groupt   appendt   popt   end(	   t   wmexprt   outt   stackt	   generatort   last_post   matcht   positiont	   last_exprt   current_pos(    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt   parse_full_form   s,    	7
c         C   s4  t  |  t  s | S|  d d k r` x: |  d D]+ } | d d k r. d | | d d <q. q. Wn  |  d d k r x: |  d D]+ } | d d k r{ d | | d d <q{ q{ Wn  |  d d k r x: |  d D]+ } | d d k r d | | d d <q q Wn  t |   d k r| Sx |  D] } t | |  } qW| S(   sD   
    Returns Optional variables and their values in the pattern
    i    R   i   t   OptionalR   R   (   R   R   t   lent   get_default_values(   t   parsedt   default_valuesR   (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyR      s&    c         C   s(  g  } d } t  j | |   } xM | D]E } |  j | d d j | d | | d   }  | j | d  q% Wd } t  j | |   } x= | D]5 } |  j | d | d d  }  | j | d  q Wd } t  j | |   } x= | D]5 } |  j | d | d d  }  | j | d  q W|  | f S(   su   
    Replaces `Pattern(variable)` by `variable` in `string`.
    Returns the free symbols present in the string.
    s%   (Optional\(Pattern\((\w+), Blank\)\))i    s   WC('{}', S({}))i   s   (Pattern\((\w+), Blank\))t   _s#   (Pattern\((\w+), Blank\(Symbol\)\))(   RR   t   findallR   t   formatR   (   t   stringt   optionalt   symbolst   pt   matchesR   (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt   add_wildcards   s"    .c         C   s   |  d d k rQ t  |  d  d k r6 |  d g } n |  d d } |  d } n4 x1 |  d D]% } t | | |  \ } } | | f SW| | f S(   s+   
    Returns list of symbols in FreeQ.
    i    t   FreeQi   i   (   R   t   seperate_freeq(   t   st	   variablest   xR   (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyR      s    c            s4  g  } d } x|  D]} t  | t  r d j | |      | j   k r | d 7} d j | | |  }	 |	   7}	 |	 d j | d j |   7}	 d j |  }
   | |
 <qd }	 t   f d   | j   D  }
 n t  | t  rt t t | |    } d	 j	 |  } d j t
 |  |      | j   k r| d 7} d
 j | |  }	 |	   7}	 |	 d j | d j |   7}	 d j |  }
   | |
 <qd }	 t   f d   | j   D  }
 n  |
 | k r| j |
  n  | j |
  | |	 7} q W| g  k r'd	 d	 j	 |  | | f Sd | | f S(   s<   
    Converts FreeQ constraints into MatchPy constraint
    R   s           return FreeQ({}, {})i   s   
    def cons_f{}({}, {}):
s$   

    cons{} = CustomConstraint({})
s   cons_f{}s   cons{}c         3   s'   |  ] \ } } |   k r | Vq d  S(   N(    (   t   .0t   keyt   value(   t   r(    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pys	   <genexpr>  s    s   , s   
    def cons_f{}({}):
c         3   s'   |  ] \ } } |   k r | Vq d  S(   N(    (   R   R   R   (   R   (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pys	   <genexpr>  s    (   R   R   R   t   valuest   nextt   itemsR   t   sett   get_free_symbolst   joint   generate_sympy_from_parsedR   (   t   lR   t
   cons_indext	   cons_dictt   cons_importR   t   rest   consR   t   ct	   cons_nameR   (    (   R   sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt   parse_freeq   sD    

%

%c      
   C   s  d } t  |  t  s[ y t |   d j |   SWn n X|  | k rW | rW |  d Sn  |  S|  d d k r d j t |  d d | d	 | d
 | t |  d d | d	 | d
 |  S|  d t k r | t |  d 7} n1 |  d d k r | r | d 7} n | |  d 7} t |   d k r| Sg  |  d D]$ } t | d | d	 | d
 | ^ q*} d | k rp| j d  n  | d 7} | d j |  7} | d 7} | S(   s   
    Parses list into Python syntax.

    Parameters
    ==========
    wild : When set to True, the symbols are replaced as wild symbols.
    symbols : Symbols already present in the pattern.
    replace_Int: when set to True, `Int` is replaced by `Integral`(used to parse pattern).
    R   s   S({})R   i    t   Rationals   S({})/S({})i   t   wildR   t   replace_Inti   t   Intt   Integralt   (s   , t   )(	   R   R   t   floatR   R   t   replacementsR   t   removeR   (   R   R   R   R   R   R   t   result(    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyR     s6    

H5

c         C   sV   t  |  t  s/ |  | k r+ | j |   n  | Sx  |  D] } t | | |  } q6 W| S(   s.   
    Returns free_symbols present in `s`.
    (   R   R   R   R   (   R   R   t   free_symbolsR   (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyR   J  s    c         C   s  g  } d } t  |  t  r|  d d k ri|  } t | i   } t | d t } t | d | \ } } t t |   } t | d i t d  d 6t d  d 6t d	  d	 6} | j	 d
 j	 d } | j	 d
 j	 d
 }	 t
 | d t } t |  } d j | d j |  |	  } | d j | |  7} | d j | |  7} | d j | j	 d  7} d | f SxZ |  D]O }
 t  |
 t  rt |
 |  } | j | d  | d
 } qp| j |
  qpWn  | | f S(   s]   
    Takes care of the case, when a pattern matching has to be done inside a constraint.
    R   i    t   MatchQR   R   t   localst   Ort   Andt   Noti   t   sympy_integerss2           def _cons_f_{}({}):
            return {}
s   , s0           _cons_{} = CustomConstraint(_cons_f_{})
s8           pat = Pattern(UtilityOperator({}, x), _cons_{})
s=           result_matchq = is_match(UtilityOperator({}, x), pat)t   result_matchq(   R   R   R   R   R   R   R   R    R   R
   R   t   setWCR   R   t   set_matchq_in_constraintR   (   R   R   t   lstR   R   R   R   R   t   patternR   R   (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyR   X  s4    9
c   
   	      s  t  t t |  | g     } t |   } t | d i t d  d 6t d  d 6t d  d 6} | j t d   r t |  |  } | d     d j t	 t t | d  d i t d  d 6t d  d 6t d  d 6d	 t
  7  nE t |   rd
 j t	 | d	 t
    n d j t	 | d	 t
      | j   k r| d 7} d j | d j |   } d | k r| d 7} n  |   7} | d j | d j |   7} d j |  }	   | |	 <n( d } t   f d   | j   D  }	 |	 | k r| j |	  n  |	 | | f S(   NR   R   R   R   R   i   s   
        return {}i    R   sg           try:
            return {}
        except (TypeError, AttributeError):
            return Falses           return {}s   
    def cons_f{}({}):
s   , R   sQ           if isinstance(x, (int, Integer, float, Float)):
            return False
s$   

    cons{} = CustomConstraint({})
s   cons_f{}s   cons{}R   c         3   s'   |  ] \ } } |   k r | Vq d  S(   N(    (   R   R   R   (   R   (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pys	   <genexpr>  s    (   R   R   R   R   R    R   R   R   R   R   R   R   R   R   R   R   R   (
   R   R   R   R   R   t   lambda_symbolsR   t	   match_resR   R   (    (   R   sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt   _divide_constriant{  s0    9
_

"c   
      C   s  g  } d } |  d d k r x |  d D]Z } | d d k r' t  | | | | |  } | j | d  | | d 7} | d } q' q' WnA t  |  | | | |  } | j | d  | | d 7} | d } d g }	 x* | D]" } | d k r |	 j |  q q Wd j |	  | | f S(   s   
    Divides multiple constraints into smaller constraints.

    Parameters
    ==========
    s : constraint as list
    symbols : all the symbols present in the expression
    R   i    R   i   R   i   s   , (   R   R   R   (
   R   R   R   R   R   R   R   R   R   R   (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt   divide_constraint  s$    	
	c         C   sW   d } t  j | |   } x8 | D]0 } |  j | d d j | d | d   }  q W|  S(   s0   
    Replaces `WC(a, b)` by `WC('a', S(b))`
    s   (WC\((\w+), S\(([-+]?\d)\)\))i    s   WC('{}', S({}))i   i   (   RR   R   R   R   (   R   R   R   R   (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyR     s
    .c   	   	   C   s  t  |  d  } d } t } d } t |  t d  k sR t |  t d  k rxH| j D]:} x_ | j D]T } t | t  rl | | k rl | d j | j d t | j d d t	  7} ql ql Wt |  t d  t d	  f k r| j
 t d	   r| } t	 } q\ t |  t d	  k r;| j d
 } t	 } q\ t | j d  t d	  k r\ | j d } d j | j | j d
 | j d  } t	 } q\ q\ Wn  | | | f S(   s]   
    Functions like `Set`, `With` and `CompoundExpression` has to be taken special care.
    i   R   Rf   Re   s   
        {} = {}i    R   t   Listt   CompoundExpressionis
   {}({}, {})(   R    R   R   R   R
   R   R   R   R   R   R   t   func(	   t   a1t   LR   R   t	   processedt   return_valueR   R   t   C(    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt   process_return_type  s(    07:		&c         C   sj   g  } t  |  t  r1 |  | k r1 | j |   n5 y+ x$ |  j D] } | t | |  7} q> WWn n X| S(   s4   
    this function extracts all `Set` functions
    (   R   R   R   R
   t   extract_set(   R   R   R   R   (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyR     s    c            s  d } d } t |   t d  k s< t |   t d  k rd } d j | d j     } t |  j d  t d  k r t |  j d j  } n |  j d g } g  } x( |  j d	 D] }	 | t |	 |  7} q W| | 7} xx | D]p }	 t |	 t	  r/| d
 j |	 j d t
 |	 j d	 d t  7} q t |	 t  r | d j |	 |	  7} q q Wt |  j d	  t d  k r|  j d	 }
 | | 7} t |
 j d t	  r| d
 j |
 j d j d |
 j d j d	  7} n  | d j | t
 |
 j d	 d t  7} | | | f St |  j d	  t d  k r|  j d	 }
 t |
 j  d k rt   f d   g  |
 j D] }	 t |	  ^ qlD  r| | 7} | d j | t
 |
 j d d t  7} qd   k r| d 7} n  t |   r8| j d d  } | d j | t
 |
 j d	 d t  7} | d 7} | d 7} n0 | | 7} | d j t
 |
 j d	 d t  7} | t
 |
 j d d t f } t | |  } | d r| | d t
 | d	  f } n  | d 7} | d 7} n  d j |  } | | | f St |  j d	  t d  k s2t |  j d	  t d  k r|  j d	 }
 | | 7} | t
 |
 d t f } t | |  } | d r| | d t
 | d	  f } n  | | d 7} | d j | t
 | d	   7} | | d f S|  j d	 j t d   r|  j d	 j d }
 | | 7} t |
 j d t	  r[| d
 j |
 j d j d |
 j d j d	  7} n  | d j |  j d	 j |
 j d |  j d	 j d	  7} | | d f S| | 7} | d j | t
 |  j d	 d t  7} | | | f St
 |  d t d | f Sd S(    s:   
    Replaces `With` and `Module by python functions`
    R   Rf   Re   t    s       def With{}({}):s   , i    R   i   s   
        {} = {}R   s   
        {} = Symbol('{}')R   s*   
        rubi.append({})
        return {}t	   Conditioni   c         3   s   |  ] } |   k Vq d  S(   N(    (   R   t   j(   R   (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pys	   <genexpr>  s    R   sQ   
        if isinstance(x, (int, Integer, float, Float)):
            return Falses   
s   
    s$   
        try:{}
            res = {}sE   
        except (TypeError, AttributeError):
            return Falses   
        if res:s   
        if {}:s   
            return Trues   
        return Falses   , CustomConstraint(With{})s   
        return {}({}, {})iN(   Ri   R   R   R   R   R
   R   R   R   R   R   R   R   R   t   allR   t   strR   R   R   R   R   (   R   R   t   indext   return_typet
   with_valuet   constraintsR   R   R   R   R   t   n_with_valuet   return_type1(    (   R   sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt   replaceWith  s    0
3
5)8
,)

&
!
>

! 
58
)c         C   s  d } d } d } g  } x|  D]}	 t  d j |  j |	  d   |	 d d d d k rx |	 d d d j   }
 n |	 d d j   }
 t |
 i   } t |
 j   d t } t | d	 | \ } } t t	 |   } |	 d
 d d k r]t
 |	 d
 d
 | | | |  \ } } } t |	 d
 d
 j    \ } } t |	 d
 d j   d | } n5 d } d } g  g  } } t |	 d
 j   d | } t | | | | | |  \ } } } t | d i t d  d 6t d  d 6t d  d 6} t | d t } t |  } t | d i t d  d 6t d  d 6t d  d 6} | | } | | 7} | d 7} t |  t d  k st |  t d  k rt | | |  \ } } } | d) k r>| d j |  7} | d t |  d | d | d | d 7} | d* t |  d d t | d t d j |  d 7} q| d j |  7} | d t |  d | d | d | | d 7} | d j | d j |   | d d j |  | d 7} | d+ t |  d d t | d t d  j |  d 7} n t | d t } | d! t |  d | d | d | d 7} | d" j | d j |  |  | 7} | d, t |  d d t | d t d  j |  d 7} | d# j |  7} q W| d$ 7} | d% | d& 7} | d' d j d(   | D  7} | | } | | | | f S(-   sp   
    Function which generates parsed rules by substituting all possible
    combinations of default values.
    R   s   

R   s   parsing rule {}i   i    R   R   R   i   R   R   R   R   R   R   Rf   Re   s   {}s   
    patterns    = Pattern(R   s   
    t   rules    = ReplacementRule(R   s   , With{}s   )
s   
    def replacement{}({}):
s   , s(   
        rubi.append({})
        return s   , replacement{}s       patternsC   
    def replacement{}({}):
        rubi.append({})
        return s   rule{}, R   s       return s   
s1       from sympy.integrals.rubi.constraints import c         s   s   |  ] } | Vq d  S(   N(    (   R   t   word(    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pys	   <genexpr>  s    Ns	   
    rules	   
    rules	   
    rule(   R   R   R   t   copyR   R   R   R   R   R   R   R   R   R    R   R   R   R   R  Ri   R   R   (   R   t   headerR   R   R   t   rulesR   R   R   R   R   R   R   R   t
   constriantt   constraint_deft
   FreeQ_varst   FreeQ_xt   transformedt   FreeQ_constraintt   free_cons_deft   With_constraintsR   (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt   downvalues_rulesI  sb     ) #$99


00@4<@0&=
!
t   rubi_objectc         C   s  | d k ro t j j t j j t j t j      } t t j j	 | d  d  j
   } | j |  } n  i  } d } d } d } x$ t D] } |  j | t |  }  q Wx$ t D] } |  j | t |  }  q Wg  }	 x4 t |   D]& } | d d k r |	 j |  q q Wt |	 | | | |  }
 |
 d j   d } |
 d } | |
 d 7} |
 d	 } x: t D]2 } | j t | |  } | j t | |  } qgWd j	 | j d  d
   d | } | | f S(   s  
    Parses rules in MatchPy format.

    Parameters
    ==========
    fullform : FullForm of the rule as string.
    header : Header imports for the file. Uses default imports if None.
    module_name : name of RUBI module

    References
    ==========
    [1] http://reference.wolfram.com/language/ref/FullForm.html
    [2] http://reference.wolfram.com/language/ref/DownValues.html
    [3] https://gist.github.com/Upabjojr/bc07c49262944f9c1eb0
    s   header.py.txtR   i    R   t   RuleDelayeds   
i   i   i   iN(   Ri   t   ost   patht   dirnamet   abspatht   inspectt   getfilet   currentframet   openR   t   readR   t   temporary_variable_replacementR   t   permanent_variable_replacementR   R   R  R   t   split(   t   fullformR  t   module_namet   path_headerR   R   R   R   R   R  R   R   (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt   rubi_rule_parser  s4    -$

$(*   t   __doc__RR   R  R  t   sympyR    R   R   R   t   sympy.core.compatibilityR   t   sympy.printingR   R   t   sympy.utilities.miscR   R   R   t   dictR   R  R  R   R   R   R   R   Ri   R   R   R   R   R   R   R   R   R   R   R   R  R  R#  (    (    (    sD   lib/python2.7/site-packages/sympy/integrals/rubi/parsetools/parse.pyt   <module>   s   "		

		..	#	!	 				W	D