o
    ohm,                     @   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                    sz  d } } }}g }|j du rdd }ndd }| D ]W}|jr%|js$d}q|jr5|r- dS d}|| qt|}	|	rcd}|	\}
}|
jrP|jrP|
jrM|jsOd}qd}|
jrZ||
 |jrb|| q||ro|rl dS d}q dS |r}tdd |D nd	}|rt| |\ } |fS |r|rt|d
 n|rt	|d
 n|s|j
r|rtnt n|rt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   k/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/polys/constructor.py<lambda>   s    z#_construct_simple.<locals>.<lambda>c                 S   s   dS )NFr   r   r   r   r   r      s    Nc                 s       | ]}|j V  qd S r   _prec.0cr   r   r   	<genexpr>>       z$_construct_simple.<locals>.<genexpr>5   precc                    s   g | ]}  |qS r   )
from_sympy)r   r   domainr   r   
<listcomp>L   s    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	complexes
algebraicsfloat_numbersr   r   
is_complexxymax_precresultr   r%   r   _construct_simple   s^   




r<   c           	         s   ddl m} t  fdd  | }tt|ddd\}}tdd t|D }t|f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 ]1}|j rdt|f}n|jrd |jf}n|jr'd |jf}n	d|f}| || q|S )NQ+*e)r)   r   r$   is_Addargsis_Muladdr,   )rC   treesatree)build_treesextsr   r   rI   W   s   
z)_construct_algebraic.<locals>.build_treesT)expolysc                 s   s    | ]	\}}|| V  qd S r   r   )r   sextr   r   r   r   j       z'_construct_algebraic.<locals>.<genexpr>c                    s   g | ]
} j |tqS r   )dtype	from_listr   )r   h)r&   gr   r   r'   n   s    z(_construct_algebraic.<locals>.<listcomp>c                    sv   | \}}|dkrj |gtS |dkr"t fdd|D jS |dkr1t fdd|D S |dkr9| S t)Nr>   r?   c                 3       | ]} |V  qd S r   r   r   rG   convert_treer   r   r   v       z=_construct_algebraic.<locals>.convert_tree.<locals>.<genexpr>r@   c                 3   rT   r   r   rU   rV   r   r   r   x   rX   rA   )rP   rQ   r   sumzeror   RuntimeError)rH   oprC   )rW   r&   exts_maprS   r   r   rW   q   s   z*_construct_algebraic.<locals>.convert_treec                    s   g | ]} |qS r   r   )r   rH   rV   r   r   r'   ~   s    )sympy.polys.numberfieldsr=   setlistr   rY   zipr   algebraic_fieldrepto_listdict)	r0   r1   r=   rF   spanHrootexts_domr;   r   )rI   rW   r&   rJ   r]   rS   r   r.   Q   s   r.   c                 C   s  g g }}| D ]}|  \}}|| || qt|| \}}|s&dS |jdu rLtdd |D r6dS t }	|D ]}
|
j}|	|@ rG dS |	|O }	q;t|}t|d }|d| }||d }|jrhd}ndd| }}|D ]}t|dks}||vrd} nqqt } |st	||D ]\}}|| }|
 D ]\}}|| }| | |||< qqnt	||D ]\}}| t|  | t|  qd } }}g }| D ]L}|jr|jsd}q|jrd}|| qt|}|durd}|\}}|jr
|jr
|jr|js	d}qd}|jr|| |jr|| q|r+td	d |D nd
}|r9|r9t|d}n|rBt|d}n|rN|rKt}nt}n|rTt}nt}g }|s|j| }|D ]}|
 D ]\}}||||< qh||| qb||fS |j| }t	||D ]0\}}|
 D ]\}}||||< q|
 D ]\}}||||< q||||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      rO   z'_construct_composite.<locals>.<genexpr>   TF)r      c                 s   r   r   r   r   r   r   r   r      r    r!   r"   )as_numer_denomr,   r   	compositeanyr_   free_symbolslenr/   ra   itemsrE   updater`   valuesr)   r*   r+   r   r-   r   r   r	   r   r   r   	poly_ringr$   
frac_field)r0   r1   numersdenomsr   numerdenomrL   gensall_symbolsrj   symbolsnk	fractionszerosmonomr2   r3   r4   r6   r7   r8   r9   r:   groundr;   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$   )r0   r1   r&   r;   r   r   r   r   _construct_expression   s   
r   c                 K   s  t |}t| dr&t| tr#| sg g }}nttt|   \}}n| }n| g}ttt|}t	||}|durJ|durB|\}}n%t
||\}}n|jdu rRd}nt||}|dur`|\}}nt
||\}}t| drt| tr||ttt||fS ||fS ||d f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
isinstancere   r`   ra   rr   mapr   r<   r   rn   r   )objrC   r1   monomsr0   r;   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
    sympy.polys.domains.complexfieldr   sympy.polys.domains.realfieldr   sympy.polys.polyoptionsr   sympy.polys.polyutilsr   sympy.utilitiesr   r<   r.   r   r   r   r   r   r   r   <module>   s"    B2}
