o
    8Vae1                     @   s   d Z ddlmZmZ ddlmZmZmZmZm	Z	m
Z
mZ ddlmZmZmZmZmZmZ ddlmZmZmZmZ ddlmZ G dd dZG d	d
 d
ZG dd dZi fddZdd ZG dd dZG dd dZdS )a
  
The classes used here are for the internal use of assumptions system
only and should not be used anywhere else as these don't possess the
signatures common to SymPy objects. For general use of logic constructs
please refer to sympy.logic classes And, Or, Not, etc.
    )combinationsproduct)SNorNandXorImplies
EquivalentITE)EqNeGtLtGeLe)OrAndNotXnor)zip_longestc                       sZ   e Zd ZdZd fdd	Zedd Zdd Zd	d
 Zdd Z	e	Z
dd Zdd Z  ZS )Literala{  
    The smallest element of a CNF object.

    Parameters
    ==========

    lit : Boolean expression

    is_Not : bool

    Examples
    ========

    >>> from sympy import Q
    >>> from sympy.assumptions.cnf import Literal
    >>> from sympy.abc import x
    >>> Literal(Q.even(x))
    Literal(Q.even(x), False)
    >>> Literal(~Q.even(x))
    Literal(Q.even(x), True)
    Fc                    sT   t |tr|jd }d}nt |tttfr|r| S |S t | }||_||_	|S )Nr   T)

isinstancer   argsANDORr   super__new__litis_Not)clsr   r   obj	__class__ 7/usr/lib/python3/dist-packages/sympy/assumptions/cnf.pyr   %   s   

zLiteral.__new__c                 C      | j S Nr   selfr#   r#   r$   arg0      zLiteral.argc                 C   sV   t | jr| |}nz| j|}W n ty"   | j|}Y nw t| || jS r&   )callabler   ZapplyAttributeErrorrcalltyper   )r)   exprr   r#   r#   r$   r.   4   s   
zLiteral.rcallc                 C   s   | j  }t| j|S r&   )r   r   r   )r)   r   r#   r#   r$   
__invert__>   s   zLiteral.__invert__c                 C   s   d t| j| j| jS )Nz
{}({}, {}))formatr/   __name__r   r   r(   r#   r#   r$   __str__B      zLiteral.__str__c                 C   s   | j |j ko| j|jkS r&   )r*   r   r)   otherr#   r#   r$   __eq__G   r5   zLiteral.__eq__c                 C   s   t t| j| j| jf}|S r&   )hashr/   r3   r*   r   )r)   hr#   r#   r$   __hash__J   s   zLiteral.__hash__)F)r3   
__module____qualname____doc__r   propertyr*   r.   r1   r4   __repr__r8   r;   __classcell__r#   r#   r!   r$   r      s    

r   c                   @   sP   e Zd ZdZdd Zedd Zdd Zdd	 Zd
d Z	dd Z
dd ZeZdS )r   z+
    A low-level implementation for Or
    c                 G   
   || _ d S r&   _argsr)   r   r#   r#   r$   __init__S      
zOR.__init__c                 C      t | jtdS N)keysortedrD   strr(   r#   r#   r$   r   V      zOR.argsc                       t |  fdd| jD  S )Nc                       g | ]}|  qS r#   r.   .0r*   r0   r#   r$   
<listcomp>[       zOR.rcall.<locals>.<listcomp>r/   rD   r)   r0   r#   rT   r$   r.   Z      zOR.rcallc                 C      t dd | jD  S )Nc                 S      g | ]}| qS r#   r#   rR   r#   r#   r$   rU   `       z!OR.__invert__.<locals>.<listcomp>)r   rD   r(   r#   r#   r$   r1   _      zOR.__invert__c                 C      t t| jft| j S r&   r9   r/   r3   tupler   r(   r#   r#   r$   r;   b      zOR.__hash__c                 C      | j |j kS r&   r   r6   r#   r#   r$   r8   e      z	OR.__eq__c                 C   "   dd dd | jD  d }|S )N( | c                 S      g | ]}t |qS r#   rM   rR   r#   r#   r$   rU   i       zOR.__str__.<locals>.<listcomp>)joinr   r)   sr#   r#   r$   r4   h      z
OR.__str__N)r3   r<   r=   r>   rF   r?   r   r.   r1   r;   r8   r4   r@   r#   r#   r#   r$   r   O   s    
r   c                   @   sP   e Zd ZdZdd Zdd Zedd Zdd	 Zd
d Z	dd Z
dd ZeZdS )r   z,
    A low-level implementation for And
    c                 G   rB   r&   rC   rE   r#   r#   r$   rF   s   rG   zAND.__init__c                 C   rZ   )Nc                 S   r[   r#   r#   rR   r#   r#   r$   rU   w   r\   z"AND.__invert__.<locals>.<listcomp>)r   rD   r(   r#   r#   r$   r1   v   r]   zAND.__invert__c                 C   rH   rI   rK   r(   r#   r#   r$   r   y   rN   zAND.argsc                    rO   )Nc                    rP   r#   rQ   rR   rT   r#   r$   rU   ~   rV   zAND.rcall.<locals>.<listcomp>rW   rX   r#   rT   r$   r.   }   rY   z	AND.rcallc                 C   r^   r&   r_   r(   r#   r#   r$   r;      ra   zAND.__hash__c                 C   rb   r&   rc   r6   r#   r#   r$   r8      rd   z
AND.__eq__c                 C   re   )Nrf    & c                 S   rh   r#   ri   rR   r#   r#   r$   rU      rj   zAND.__str__.<locals>.<listcomp>rk   rl   rn   r#   r#   r$   r4      rp   zAND.__str__N)r3   r<   r=   r>   rF   r1   r?   r   r.   r;   r8   r4   r@   r#   r#   r#   r$   r   o   s    
r   c                    sd  ddl m} ddlm}m} t|jt|jt	|j
t|jt|jt|ji}t| |v r3|t|  }|| j } t| trE| jd }t| }| S t| trXt fddt| D  S t| trkt fddt| D  S t| trt fdd| jD  }| S t| trt fdd| jD  }| S t| trg }	tdt| jd	 d
D ]}
t | j|
D ] fdd| jD }|	!t|  qqt|	 S t| t"rg }	tdt| jd	 d
D ]}
t | j|
D ] fdd| jD }|	!t|  qqt|	  S t| t#rt| jd  t| jd	  }}t| |S t| t$rNg }	t%| j| jd	d | jd dD ]\}}t| }t| }|	!t| | q1t|	 S t| t&rxt| jd  }t| jd	  }t| jd
  }tt| |t||S t| |r| j'| j(}} )|d}|durt|j*|  S t| |r )| d}|durt| S t+| S )a  
    Generates the Negation Normal Form of any boolean expression in terms
    of AND, OR, and Literal objects.

    Examples
    ========

    >>> from sympy import Q, Eq
    >>> from sympy.assumptions.cnf import to_NNF
    >>> from sympy.abc import x, y
    >>> expr = Q.even(x) & ~Q.positive(x)
    >>> to_NNF(expr)
    (Literal(Q.even(x), False) & Literal(Q.positive(x), True))

    Supported boolean objects are converted to corresponding predicates.

    >>> to_NNF(Eq(x, y))
    Literal(Q.eq(x, y), False)

    If ``composite_map`` argument is given, ``to_NNF`` decomposes the
    specified predicate into a combination of primitive predicates.

    >>> cmap = {Q.nonpositive: Q.negative | Q.zero}
    >>> to_NNF(Q.nonpositive, cmap)
    (Literal(Q.negative, False) | Literal(Q.zero, False))
    >>> to_NNF(Q.nonpositive(x), cmap)
    (Literal(Q.negative(x), False) | Literal(Q.zero(x), False))
    r   )Q)AppliedPredicate	Predicatec                       g | ]}t | qS r#   to_NNFrS   xcomposite_mapr#   r$   rU          zto_NNF.<locals>.<listcomp>c                    ru   r#   rv   rx   rz   r#   r$   rU      r|   c                    ru   r#   rv   rx   rz   r#   r$   rU      r|   c                    ru   r#   rv   rx   rz   r#   r$   rU      r|         c                    *   g | ]}|v rt |  nt | qS r#   rv   rS   ro   r{   negr#   r$   rU          "c                    r   r#   rv   r   r   r#   r$   rU      r   N)	fillvalue),Zsympy.assumptions.askrr   Zsympy.assumptions.assumers   rt   r   eqr   ner   gtr   ltr   ger   ler/   r   r   r   rw   r   r   Z	make_argsr   r   r   r   r   rangelenr   appendr   r   r	   r   r
   functionZ	argumentsgetr.   r   )r0   r{   rr   rs   rt   ZbinrelpredsZpredr*   tmpcnfsiclauseLRabMr   Znewpredr#   r   r$   rw      s   (










"(




rw   c                 C   sp   t | ttfst }|t| f t|S t | tr&tjdd | jD  S t | tr6tj	dd | jD  S dS )z
    Distributes AND over OR in the NNF expression.
    Returns the result( Conjunctive Normal Form of expression)
    as a CNF object.
    c                 S   rh   r#   distribute_AND_over_ORrR   r#   r#   r$   rU         z*distribute_AND_over_OR.<locals>.<listcomp>c                 S   rh   r#   r   rR   r#   r#   r$   rU   	  r   N)
r   r   r   setadd	frozensetCNFall_orrD   all_and)r0   r   r#   r#   r$   r      s   



r   c                   @   s   e Zd ZdZd%ddZdd Zdd Zd	d
 Zdd Zdd Z	e
dd Zdd Zdd Zdd Zdd Zdd Zdd Ze
dd Ze
dd  Ze
d!d" Ze
d#d$ ZdS )&r   a  
    Class to represent CNF of a Boolean expression.
    Consists of set of clauses, which themselves are stored as
    frozenset of Literal objects.

    Examples
    ========

    >>> from sympy import Q
    >>> from sympy.assumptions.cnf import CNF
    >>> from sympy.abc import x
    >>> cnf = CNF.from_prop(Q.real(x) & ~Q.zero(x))
    >>> cnf.clauses
    {frozenset({Literal(Q.zero(x), True)}),
    frozenset({Literal(Q.negative(x), False),
    Literal(Q.positive(x), False), Literal(Q.zero(x), False)})}
    Nc                 C   s   |st  }|| _d S r&   r   clausesr)   r   r#   r#   r$   rF     s   
zCNF.__init__c                 C   s   t |j}| | d S r&   )r   to_CNFr   add_clauses)r)   propr   r#   r#   r$   r   $  s   zCNF.addc                 C   s   d dd | jD }|S )Nrq   c                 S   s(   g | ]}d d dd |D  d qS )rf   rg   c                 S   rh   r#   ri   )rS   r   r#   r#   r$   rU   *  rj   z*CNF.__str__.<locals>.<listcomp>.<listcomp>rk   )rm   rS   r   r#   r#   r$   rU   *  s     zCNF.__str__.<locals>.<listcomp>)rm   r   rn   r#   r#   r$   r4   (  s   zCNF.__str__c                 C   s   |D ]}|  | q| S r&   r   )r)   Zpropspr#   r#   r$   extend/  s   z
CNF.extendc                 C   s   t t| jS r&   )r   r   r   r(   r#   r#   r$   copy4  s   zCNF.copyc                 C   s   |  j |O  _ d S r&   )r   r   r#   r#   r$   r   7     zCNF.add_clausesc                 C   s   |  }| | |S r&   r   )r   r   resr#   r#   r$   	from_prop:  s   
zCNF.from_propc                 C   s   |  |j | S r&   )r   r   r6   r#   r#   r$   __iand__@  s   zCNF.__iand__c                 C   s(   t  }| jD ]}|dd |D O }q|S )Nc                 S   s   h | ]}|j qS r#   r'   rR   r#   r#   r$   	<setcomp>G  r\   z%CNF.all_predicates.<locals>.<setcomp>r   )r)   Z
predicatescr#   r#   r$   all_predicatesD  s   
zCNF.all_predicatesc                 C   sP   t  }t| j|jD ]\}}t |}|D ]}|| q|t| q
t|S r&   )r   r   r   r   r   r   )r)   cnfr   r   r   r   tr#   r#   r$   _orJ  s   zCNF._orc                 C   s   | j |j }t|S r&   )r   unionr   r)   r   r   r#   r#   r$   _andS  s   zCNF._andc                 C   s~   t | j}t }|d D ]}|t| f qt|}|d d D ]}t }|D ]}|t| f q)|t|}q"|S )N)listr   r   r   r   r   r   )r)   ZclssZllry   restr   r#   r#   r$   _notW  s   
zCNF._notc                    sB   t  }| jD ]} fdd|D }|t|  qt|  t S )Nc                    rP   r#   rQ   rR   rT   r#   r$   rU   h  r|   zCNF.rcall.<locals>.<listcomp>)r   r   r   r   r   r   )r)   r0   Zclause_listr   Zlitsr#   rT   r$   r.   e  s   
z	CNF.rcallc                 G   ,   |d   }|dd  D ]}||}q|S Nr   r}   )r   r   r   r   r   r   r#   r#   r$   r   m     z
CNF.all_orc                 G   r   r   )r   r   r   r#   r#   r$   r   t  r   zCNF.all_andc                 C   s$   ddl m} t|| }t|}|S )Nr   )get_composite_predicates)Zsympy.assumptions.factsr   rw   r   )r   r0   r   r#   r#   r$   r   {  s   z
CNF.to_CNFc                    s    dd  t  fdd|jD  S )zm
        Converts CNF object to SymPy's boolean expression
        retaining the form of expression.
        c                 S   s   | j rt| jS | jS r&   )r   r   r   )r*   r#   r#   r$   remove_literal  s   z&CNF.CNF_to_cnf.<locals>.remove_literalc                 3   s&    | ]}t  fd d|D  V  qdS )c                 3   s    | ]} |V  qd S r&   r#   rR   r   r#   r$   	<genexpr>  s    z+CNF.CNF_to_cnf.<locals>.<genexpr>.<genexpr>N)r   r   r   r#   r$   r     s   $ z!CNF.CNF_to_cnf.<locals>.<genexpr>)r   r   )r   r   r#   r   r$   
CNF_to_cnf  s   zCNF.CNF_to_cnfr&   )r3   r<   r=   r>   rF   r   r4   r   r   r   classmethodr   r   r   r   r   r   r.   r   r   r   r   r#   r#   r#   r$   r     s0    

	


r   c                   @   sb   e Zd ZdZdddZdd Zedd Zed	d
 Zdd Z	dd Z
dd Zdd Zdd ZdS )
EncodedCNFz0
    Class for encoding the CNF expression.
    Nc                 C   s2   |s
|s
t  }t }|| _|| _t | | _d S r&   )r   dictdataencodingkeys_symbols)r)   r   r   r#   r#   r$   rF     s   zEncodedCNF.__init__c              	      sV   t |  _t j}tt t jt td|d  _ fdd|jD  _	d S )Nr}   c                       g | ]}  |qS r#   encoder   r(   r#   r$   rU     r|   z'EncodedCNF.from_cnf.<locals>.<listcomp>)
r   r   r   r   r   zipr   r   r   r   )r)   r   nr#   r(   r$   from_cnf  s   
$zEncodedCNF.from_cnfc                 C   r%   r&   )r   r(   r#   r#   r$   symbols  r+   zEncodedCNF.symbolsc                 C   s   t dt| jd S Nr}   )r   r   r   r(   r#   r#   r$   	variables  s   zEncodedCNF.variablesc                 C   s    dd | j D }t|t| jS )Nc                 S   rh   r#   )r   r   r#   r#   r$   rU     rj   z#EncodedCNF.copy.<locals>.<listcomp>)r   r   r   r   )r)   Znew_datar#   r#   r$   r     s   zEncodedCNF.copyc                 C   s   t |}| | d S r&   )r   r   add_from_cnf)r)   r   r   r#   r#   r$   add_prop  s   
zEncodedCNF.add_propc                    s&    fdd|j D }  j|7  _d S )Nc                    r   r#   r   r   r(   r#   r$   rU     r|   z+EncodedCNF.add_from_cnf.<locals>.<listcomp>)r   r   r   r#   r(   r$   r     s   zEncodedCNF.add_from_cnfc                 C   sT   |j }| j|d }|d u r"t| j}| j| |d  }| j|< |jr(| S |S r   )r   r   r   r   r   r   r   )r)   r*   literalvaluer   r#   r#   r$   
encode_arg  s   
zEncodedCNF.encode_argc                    s    fdd|D S )Nc                    s&   h | ]}|j tjks |nd qS )r   )r   r   Zfalser   rR   r(   r#   r$   r     s   & z$EncodedCNF.encode.<locals>.<setcomp>r#   )r)   r   r#   r(   r$   r     r   zEncodedCNF.encode)NN)r3   r<   r=   r>   rF   r   r?   r   r   r   r   r   r   r   r#   r#   r#   r$   r     s    


r   N) r>   	itertoolsr   r   Zsympyr   r   r   r   r   r	   r
   Zsympy.core.relationalr   r   r   r   r   r   Zsympy.logic.boolalgr   r   r   r   r   r   r   r   rw   r   r   r   r#   r#   r#   r$   <module>   s    $ A  j 