a
    RG5dk,                     @   s   d 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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 Zdd Zdd Zdd Zedd ZdS )z0Tools for constructing domains for expressions.     )prod)sympify)pure_complex)ordered)ZZQQZZ_IQQ_IEX)ComplexField)	RealField)build_options)parallel_dict_from_basic)publicc                    s  d } } }}g }|j du r(dd }ndd }| D ]}|jrJ|jsd}q4|jrj|rZ dS d}|| q4t|}	|	rd}|	\}
}|
jr|jr|
jr|js4d}q4qd}|
jr||
 |jr|| q4||r|r dS d}q4 dS q4|r tdd |D nd	}|rt| |\ }nh|r2|r2t|d
 n>|rDt	|d
 n,|sR|j
rb|r\tnt n|rltnt  fdd| D } |fS )z?Handle simple domains, e.g.: ZZ, QQ, RR and algebraic domains. FTc                 S   s   | j o
| jS N	is_numberis_algebraiccoeff r   S/var/www/html/django/DPS/env/lib/python3.9/site-packages/sympy/polys/constructor.py<lambda>       z#_construct_simple.<locals>.<lambda>c                 S   s   dS )NFr   r   r   r   r   r      r   Nc                 s   s   | ]}|j V  qd S r   _prec.0cr   r   r   	<genexpr>>   r   z$_construct_simple.<locals>.<genexpr>5   precc                    s   g | ]}  |qS r   )
from_sympy)r   r   domainr   r   
<listcomp>L   r   z%_construct_simple.<locals>.<listcomp>)	extensionis_Rational
is_Integeris_Floatappendr   max_construct_algebraicr   r   fieldr	   r   r   r   )coeffsopt	rationalsfloats	complexesZ
algebraicsfloat_numbersr   r   
is_complexxymax_precresultr   r$   r   _construct_simple   sX    


r:   c           	         s   ddl m} t  fdd  | }tt|ddd\}}tdd t|D }t|fj	j	 fd	d|D }t
t|fd
dfdd|D }|fS )zDWe know that coefficients are algebraic so construct the extension. r   )primitive_elementc                    sp   g }| D ]b}|j r"dt|f}n>|jr8d |jf}n(|jrNd |jf}nd|f}| || q|S )NQ+*e)r(   r   r#   is_Addargsis_Muladdr+   )rA   treesatree)build_treesextsr   r   rG   W   s    
z)_construct_algebraic.<locals>.build_treesT)expolysc                 S   s   g | ]\}}|| qS r   r   )r   sextr   r   r   r&   j   r   z(_construct_algebraic.<locals>.<listcomp>c                    s   g | ]} j |tqS r   )dtype	from_listr   )r   h)r%   gr   r   r&   n   r   c                    sz   | \}}|dkr"j |gtS |dkrDt fdd|D jS |dkrbt fdd|D S |dkrr| S td S )Nr<   r=   c                 3   s   | ]} |V  qd S r   r   r   rE   convert_treer   r   r   v   r   z=_construct_algebraic.<locals>.convert_tree.<locals>.<genexpr>r>   c                 3   s   | ]} |V  qd S r   r   rQ   rR   r   r   r   x   r   r?   )rM   rN   r   sumzeror   RuntimeError)rF   oprA   )rS   r%   exts_maprP   r   r   rS   q   s    z*_construct_algebraic.<locals>.convert_treec                    s   g | ]} |qS r   r   )r   rF   rR   r   r   r&   ~   r   )sympy.polys.numberfieldsr;   setlistr   rT   zipr   algebraic_fieldrepdict)	r/   r0   r;   rD   spanHrootZexts_domr9   r   )rG   rS   r%   rH   rX   rP   r   r-   Q   s    r-   c                 C   s  g g  }}| D ]$}|  \}}|| || qt|| \}}|sLdS |jdu rtdd |D rldS t }	|D ] }
|
j}|	|@ r dS |	|O }	qvt|}t|d }|d| }||d }|jrd}n8dd|  }}|D ]$}t|dk s||vrd} qqt } |sbt	||D ]@\}}|| }|
 D ]$\}}|| }| | |||< q6qn:t	||D ].\}}| t|  | t|  qld } }}g }| D ]}|jr|jsNd}n|jrd}|| nlt|}|durd}|\}}|jr&|jr&|jr |jsNd}n(d}|jr<|| |jr|| q|rjtd	d |D nd
}|r|rt|d}n:|rt|d}n(|r|rt}nt}n|rt}nt}g }|s|j| }|D ]6}|
 D ]\}}||||< q||| qnv|j| }t	||D ]`\}}|
 D ]\}}||||< q6|
 D ]\}}||||< qX||||f q&||fS )z<Handle composite domains, e.g.: ZZ[X], QQ[X], ZZ(X), QQ(X). Nc                 s   s   | ]}|j o|jV  qd S r   r   )r   genr   r   r   r      r   z'_construct_composite.<locals>.<genexpr>   TF)r      c                 s   s   | ]}|j V  qd S r   r   r   r   r   r   r      r   r    r!   )as_numer_denomr+   r   	compositeanyrZ   free_symbolslenr.   r\   itemsrC   updater[   valuesr(   r)   r*   r   r,   r   r   r	   r   r   r   	poly_ringr#   
frac_field)r/   r0   numersdenomsr   numerdenomrJ   gensZall_symbolsrc   symbolsnk	fractionszerosmonomr1   r2   r3   r4   r5   r6   r7   r8   groundr9   r%   r   r   r   _construct_composite   s    








r|   c                 C   s,   t g  }}| D ]}||| q||fS )z6The last resort case, i.e. use the expression domain. )r
   r+   r#   )r/   r0   r%   r9   r   r   r   r   _construct_expression   s    
r}   c                 K   s  t |}t| drLt| trF| s,g g  }}qJttt|   \}}qR| }n| g}ttt|}t	||}|dur|dur|\}}qt
||\}}n:|jdu rd}n
t||}|dur|\}}nt
||\}}t| drt| tr|ttt||fS ||fS n||d fS dS )aT	  Construct a minimal domain for a list of expressions.

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

    Given a list of normal SymPy expressions (of type :py:class:`~.Expr`)
    ``construct_domain`` will find a minimal :py:class:`~.Domain` that can
    represent those expressions. The expressions will be converted to elements
    of the domain and both the domain and the domain elements are returned.

    Parameters
    ==========

    obj: list or dict
        The expressions to build a domain for.

    **args: keyword arguments
        Options that affect the choice of domain.

    Returns
    =======

    (K, elements): Domain and list of domain elements
        The domain K that can represent the expressions and the list or dict
        of domain elements representing the same expressions as elements of K.

    Examples
    ========

    Given a list of :py:class:`~.Integer` ``construct_domain`` will return the
    domain :ref:`ZZ` and a list of integers as elements of :ref:`ZZ`.

    >>> from sympy import construct_domain, S
    >>> expressions = [S(2), S(3), S(4)]
    >>> K, elements = construct_domain(expressions)
    >>> K
    ZZ
    >>> elements
    [2, 3, 4]
    >>> type(elements[0])  # doctest: +SKIP
    <class 'int'>
    >>> type(expressions[0])
    <class 'sympy.core.numbers.Integer'>

    If there are any :py:class:`~.Rational` then :ref:`QQ` is returned
    instead.

    >>> construct_domain([S(1)/2, S(3)/4])
    (QQ, [1/2, 3/4])

    If there are symbols then a polynomial ring :ref:`K[x]` is returned.

    >>> from sympy import symbols
    >>> x, y = symbols('x, y')
    >>> construct_domain([2*x + 1, S(3)/4])
    (QQ[x], [2*x + 1, 3/4])
    >>> construct_domain([2*x + 1, y])
    (ZZ[x,y], [2*x + 1, y])

    If any symbols appear with negative powers then a rational function field
    :ref:`K(x)` will be returned.

    >>> construct_domain([y/x, x/(1 - y)])
    (ZZ(x,y), [y/x, -x/(y - 1)])

    Irrational algebraic numbers will result in the :ref:`EX` domain by
    default. The keyword argument ``extension=True`` leads to the construction
    of an algebraic number field :ref:`QQ(a)`.

    >>> from sympy import sqrt
    >>> construct_domain([sqrt(2)])
    (EX, [EX(sqrt(2))])
    >>> construct_domain([sqrt(2)], extension=True)  # doctest: +SKIP
    (QQ<sqrt(2)>, [ANP([1, 0], [1, 0, -2], QQ)])

    See also
    ========

    Domain
    Expr
    __iter__NFr   )r   hasattr
isinstancer_   r[   r\   rk   mapr   r:   r}   rg   r|   )objrA   r0   monomsr/   r9   r%   r   r   r   construct_domain
  s2    S








r   N)__doc__mathr   
sympy.corer   sympy.core.evalfr   sympy.core.sortingr   sympy.polys.domainsr   r   r   r	   r
   Z sympy.polys.domains.complexfieldr   Zsympy.polys.domains.realfieldr   Zsympy.polys.polyoptionsr   sympy.polys.polyutilsr   sympy.utilitiesr   r:   r-   r|   r}   r   r   r   r   r   <module>   s    B2}
