B
    [                 @   s  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
mZmZ d dlmZ d dlmZ d dlmZ d	gZed
ddfeddiffZeefZee
eefZdd ZefddZd%ddZeeddfddZdd ddfddZdZdd d!Zed"d d#defd$d	Zd#S )&    )print_functiondivision)Basic)Expr)Symbol)IntegerRationalFloat)default_sort_key)Add)MuldotprintZblueZellipse)colorshaper   Zblackc                st   t  tst S t tkr4 fdd jD }n"t tkrPt jt	d}n j}dt j
dtt|f S )z: A string that follows obj = type(obj)(*obj.args) exactly c                s   g | ]}t  |qS  )getattr).0Zslot)xr   1lib/python3.7/site-packages/sympy/printing/dot.py
<listcomp>   s    zpurestr.<locals>.<listcomp>)keyz%s(%s)z, )
isinstancer   strtypeslotClasses	__slots__sort_classessortedargsr
   __name__joinmappurestr)r   r   r   )r   r   r"      s    
r"   c             C   s0   t  }x$|D ]\}}t| |r|| qW |S )a   Merge style dictionaries in order

    >>> from sympy import Symbol, Basic, Expr
    >>> from sympy.printing.dot import styleof
    >>> styles = [(Basic, {'color': 'blue', 'shape': 'ellipse'}),
    ...           (Expr,  {'color': 'black'})]

    >>> styleof(Basic(1), styles)
    {'color': 'blue', 'shape': 'ellipse'}

    >>> x = Symbol('x')
    >>> styleof(x + 1, styles)  # this is an Expr
    {'color': 'black', 'shape': 'ellipse'}
    )dictr   update)exprstylesstyletypZstyr   r   r   styleof!   s
    
r)   , c             C   s   | dd t|  D S )z Print a dictionary of attributes

    >>> from sympy.printing.dot import attrprint
    >>> print(attrprint({'color': 'blue', 'shape': 'ellipse'}))
    "color"="blue", "shape"="ellipse"
    c             s   s   | ]}d | V  qdS )z	"%s"="%s"Nr   )r   itemr   r   r   	<genexpr>=   s    zattrprint.<locals>.<genexpr>)r    r   items)d	delimiterr   r   r   	attrprint6   s    r0   r   Tc             C   sd   t | |}t| tr(| js(t| jj}n|| }||d< t| }|rT|dt| 7 }d|t|f S )z String defining a node

    >>> from sympy.printing.dot import dotnode
    >>> from sympy.abc import x
    >>> print(dotnode(x))
    "Symbol(x)_()" ["color"="black", "label"="x", "shape"="ellipse"];
    labelz_%sz
"%s" [%s];)	r)   r   r   Zis_Atomr   	__class__r   r"   r0   )r%   r&   	labelfuncposrepeatr'   r1   expr_strr   r   r   dotnode?   s    
r7   c             C   s   t | t S )N)r   r   )r   r   r   r   <lambda>T   s    r8   c                sd   || rg S t |  dd | jD }|rN dt 7  fddt|D } fdd|D S dS )ao   List of strings for all expr->expr.arg pairs

    See the docstring of dotprint for explanations of the options.

    >>> from sympy.printing.dot import dotedges
    >>> from sympy.abc import x
    >>> for e in dotedges(x+2):
    ...     print(e)
    "Add(Integer(2), Symbol(x))_()" -> "Integer(2)_(0,)";
    "Add(Integer(2), Symbol(x))_()" -> "Symbol(x)_(1,)";
    c             S   s   g | ]}t |qS r   )r"   )r   argr   r   r   r   f   s    zdotedges.<locals>.<listcomp>z_%sc                s&   g | ]\}}|d t  |f   qS )z_%s)r   )r   iarg_str)r4   r   r   r   i   s    c                s   g | ]}d  |f qS )z"%s" -> "%s";r   )r   r;   )r6   r   r   r   j   s    N)r"   r   r   	enumerate)r%   atomr4   r5   Zarg_strsr   )r6   r4   r   dotedgesT   s    r>   z|digraph{

# Graph style
%(graphstyle)s

#########
# Nodes #
#########

%(nodes)s

#########
# Edges #
#########

%(edges)s
}ZTDout)ZrankdirZorderingc             C   s   t | t S )N)r   r   )r   r   r   r   r8      s   Nc          	      sd   t  }|| g g d fdd	| d tt|ddddd S )	aO  
    DOT description of a SymPy expression tree

    Options are

    ``styles``: Styles for different classes.  The default is::

        [(Basic, {'color': 'blue', 'shape': 'ellipse'}),
        (Expr, {'color': 'black'})]``

    ``atom``: Function used to determine if an arg is an atom.  The default is
          ``lambda x: not isinstance(x, Basic)``.  Another good choice is
          ``lambda x: not x.args``.

    ``maxdepth``: The maximum depth.  The default is None, meaning no limit.

    ``repeat``: Whether to different nodes for separate common subexpressions.
          The default is True.  For example, for ``x + x*y`` with
          ``repeat=True``, it will have two nodes for ``x`` and with
          ``repeat=False``, it will have one (warning: even if it appears
          twice in the same object, like Pow(x, x), it will still only appear
          only once.  Hence, with repeat=False, the number of arrows out of an
          object might not equal the number of args it has).

    ``labelfunc``: How to label leaf nodes.  The default is ``str``.  Another
          good option is ``srepr``. For example with ``str``, the leaf nodes
          of ``x + 1`` are labeled, ``x`` and ``1``.  With ``srepr``, they
          are labeled ``Symbol('x')`` and ``Integer(1)``.

    Additional keyword arguments are included as styles for the graph.

    Examples
    ========

    >>> from sympy.printing.dot import dotprint
    >>> from sympy.abc import x
    >>> print(dotprint(x+2)) # doctest: +NORMALIZE_WHITESPACE
    digraph{
    <BLANKLINE>
    # Graph style
    "ordering"="out"
    "rankdir"="TD"
    <BLANKLINE>
    #########
    # Nodes #
    #########
    <BLANKLINE>
    "Add(Integer(2), Symbol(x))_()" ["color"="black", "label"="Add", "shape"="ellipse"];
    "Integer(2)_(0,)" ["color"="black", "label"="2", "shape"="ellipse"];
    "Symbol(x)_(1,)" ["color"="black", "label"="x", "shape"="ellipse"];
    <BLANKLINE>
    #########
    # Edges #
    #########
    <BLANKLINE>
    "Add(Integer(2), Symbol(x))_()" -> "Integer(2)_(0,)";
    "Add(Integer(2), Symbol(x))_()" -> "Symbol(x)_(1,)";
    }

    r   c          	      s`    t| d r( kr(d S t| d  	fddt| jD  d S )N)r3   r4   r5   )r=   r4   r5   c                s.   g | ]&\}} |s|d  |f qS )   r   )r   r:   r9   )r=   depthr4   traverser   r   r      s    z.dotprint.<locals>.traverse.<locals>.<listcomp>)appendr7   extendr>   r<   r   )erA   r4   )r=   edgesr3   maxdepthnodesr5   r&   rB   )rA   r4   r   rB      s
    zdotprint.<locals>.traverser   
)r/   )
graphstylerH   rF   )r   )_graphstylecopyr$   templater0   r    )r%   r&   r=   rG   r5   r3   kwargsrJ   r   )r=   rF   r3   rG   rH   r5   r&   rB   r   r      s    A

)r*   ) Z
__future__r   r   Zsympy.core.basicr   Zsympy.core.exprr   Zsympy.core.symbolr   Zsympy.core.numbersr   r   r	   Zsympy.core.compatibilityr
   Zsympy.core.addr   Zsympy.core.mulr   __all__Zdefault_stylesr   r   r"   r)   r0   r   r7   r>   rM   rK   r   r   r   r   r   <module>   s*   
	)
