a
    t@8b1                     @   s   d Z ddlmZmZ ddl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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d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 do not 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)
EquivalentITEImpliesNandNorXor)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r8|r4| S |S t | }||_||_	|S )Nr   T)

isinstancer   argsANDORr   super__new__litis_Not)clsr   r   obj	__class__ 4lib/python3.9/site-packages/sympy/assumptions/cnf.pyr   &   s    

zLiteral.__new__c                 C   s   | j S Nr   selfr#   r#   r$   arg1   s    zLiteral.argc                 C   sV   t | jr| |}n0z| j|}W n tyD   | j|}Y n0 t| || jS r%   )callabler   ZapplyAttributeErrorrcalltyper   )r(   exprr   r#   r#   r$   r,   5   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__C   s    zLiteral.__str__c                 C   s   | j |j ko| j|jkS r%   )r)   r   r(   otherr#   r#   r$   __eq__H   s    zLiteral.__eq__c                 C   s   t t| j| j| jf}|S r%   )hashr-   r1   r)   r   )r(   hr#   r#   r$   __hash__K   s    zLiteral.__hash__)F)r1   
__module____qualname____doc__r   propertyr)   r,   r/   r2   __repr__r5   r8   __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   s
   || _ d S r%   _argsr(   r   r#   r#   r$   __init__T   s    zOR.__init__c                 C   s   t | jtdS N)keysortedr@   strr'   r#   r#   r$   r   W   s    zOR.argsc                    s   t |  fdd| jD  S )Nc                    s   g | ]}|  qS r#   r,   .0r)   r.   r#   r$   
<listcomp>\   s   zOR.rcall.<locals>.<listcomp>r-   r@   r(   r.   r#   rK   r$   r,   [   s    zOR.rcallc                 C   s   t dd | jD  S )Nc                 S   s   g | ]
}| qS r#   r#   rI   r#   r#   r$   rL   a       z!OR.__invert__.<locals>.<listcomp>)r   r@   r'   r#   r#   r$   r/   `   s    zOR.__invert__c                 C   s   t t| jft| j S r%   r6   r-   r1   tupler   r'   r#   r#   r$   r8   c   s    zOR.__hash__c                 C   s   | j |j kS r%   r   r3   r#   r#   r$   r5   f   s    z	OR.__eq__c                 C   s"   dd dd | jD  d }|S )N( | c                 S   s   g | ]}t |qS r#   rG   rI   r#   r#   r$   rL   j   rO   zOR.__str__.<locals>.<listcomp>)joinr   r(   sr#   r#   r$   r2   i   s    z
OR.__str__N)r1   r9   r:   r;   rB   r<   r   r,   r/   r8   r5   r2   r=   r#   r#   r#   r$   r   P   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   s
   || _ d S r%   r?   rA   r#   r#   r$   rB   t   s    zAND.__init__c                 C   s   t dd | jD  S )Nc                 S   s   g | ]
}| qS r#   r#   rI   r#   r#   r$   rL   x   rO   z"AND.__invert__.<locals>.<listcomp>)r   r@   r'   r#   r#   r$   r/   w   s    zAND.__invert__c                 C   s   t | jtdS rC   rE   r'   r#   r#   r$   r   z   s    zAND.argsc                    s   t |  fdd| jD  S )Nc                    s   g | ]}|  qS r#   rH   rI   rK   r#   r$   rL      s   zAND.rcall.<locals>.<listcomp>rM   rN   r#   rK   r$   r,   ~   s    z	AND.rcallc                 C   s   t t| jft| j S r%   rP   r'   r#   r#   r$   r8      s    zAND.__hash__c                 C   s   | j |j kS r%   rR   r3   r#   r#   r$   r5      s    z
AND.__eq__c                 C   s"   dd dd | jD  d }|S )NrS    & c                 S   s   g | ]}t |qS r#   rU   rI   r#   r#   r$   rL      rO   zAND.__str__.<locals>.<listcomp>rV   rW   rY   r#   r#   r$   r2      s    zAND.__str__N)r1   r9   r:   r;   rB   r/   r<   r   r,   r8   r5   r2   r=   r#   r#   r#   r$   r   p   s   
r   Nc                    s  ddl m} ddlm}m}  du r*t  t|jt|j	t
|jt|jt|jt|ji}t| |v rt|t|  }|| j } t| tr| jd }t| }| S t| trt fddt| D  S t| trt fddt| D  S t| trt fdd| jD  }| S t| tr8t 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|  qnq^t|	 S t| t#rg }	tdt | jd
 dD ]>}
t!| j|
D ]* fdd| jD }|	"t|  qܐqt|	  S t| t$rPt| jd  t| jd
   }}t| |S t| t%rg }	t&| j| jd
d | jd dD ]0\}}t| }t| }|	"t| | qt|	 S t| t'rt| jd  }t| jd
  }t| jd  }tt| |t||S t| |rN| j(| j) }} *|d}|durNt|j+|  S t| |rz *| d}|durzt| 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	PredicateNc                    s   g | ]}t | qS r#   to_NNFrJ   xcomposite_mapr#   r$   rL      rO   zto_NNF.<locals>.<listcomp>c                    s   g | ]}t | qS r#   r_   ra   rc   r#   r$   rL      rO   c                    s   g | ]}t | qS r#   r_   ra   rc   r#   r$   rL      rO   c                    s   g | ]}t | qS r#   r_   ra   rc   r#   r$   rL      rO         c                    s*   g | ]"}|v rt |  nt | qS r#   r_   rJ   rZ   rd   negr#   r$   rL      s   c                    s*   g | ]"}|v rt |  nt | qS r#   r_   rg   rh   r#   r$   rL      s   )	fillvalue)-Zsympy.assumptions.askr\   Zsympy.assumptions.assumer]   r^   dictr   eqr   ner   gtr   ltr   ger   ler-   r   r   r   r`   r   r   Z	make_argsr   r   r   r	   r
   rangelenr   appendr   r   r   r   r   ZfunctionZ	argumentsgetr,   r   )r.   rd   r\   r]   r^   ZbinrelpredsZpredr)   tmpcnfsiclauseLRabMr   Znewpredr#   rh   r$   r`      s    (






"(




r`   c                 C   sp   t | ttfs,t }|t| f t|S t | trLtjdd | jD  S t | trlt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   s   g | ]}t |qS r#   distribute_AND_over_ORrI   r#   r#   r$   rL   
  s   z*distribute_AND_over_OR.<locals>.<listcomp>c                 S   s   g | ]}t |qS r#   r   rI   r#   r#   r$   rL     s   N)
r   r   r   setadd	frozensetCNFall_orr@   all_and)r.   rv   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$   rB   $  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 )Nr[   c                 S   s(   g | ] }d d dd |D  d qS )rS   rT   c                 S   s   g | ]}t |qS r#   rU   )rJ   r   r#   r#   r$   rL   /  rO   z*CNF.__str__.<locals>.<listcomp>.<listcomp>rV   )rX   rJ   ry   r#   r#   r$   rL   /  s   zCNF.__str__.<locals>.<listcomp>)rX   r   rY   r#   r#   r$   r2   -  s    zCNF.__str__c                 C   s   |D ]}|  | q| S r%   r   )r(   Zpropspr#   r#   r$   extend4  s    z
CNF.extendc                 C   s   t t| jS r%   )r   r   r   r'   r#   r#   r$   copy9  s    zCNF.copyc                 C   s   |  j |O  _ d S r%   )r   r   r#   r#   r$   r   <  s    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   r3   r#   r#   r$   __iand__E  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&   rI   r#   r#   r$   	<setcomp>L  rO   z%CNF.all_predicates.<locals>.<setcomp>r   )r(   Z
predicatescr#   r#   r$   all_predicatesI  s    
zCNF.all_predicatesc                 C   sP   t  }t| j|jD ]2\}}t |}|D ]}|| q(|t| qt|S r%   )r   r   r   r   r   r   )r(   cnfr   r|   r}   rv   tr#   r#   r$   _orO  s    zCNF._orc                 C   s   | j |j }t|S r%   )r   unionr   r(   r   r   r#   r#   r$   _andX  s    zCNF._andc                 C   s~   t | j}t }|d D ]}|t| f qt|}|d d D ]4}t }|D ]}|t| f qR|t|}qD|S )N)listr   r   r   r   r   r   )r(   ZclssZllrb   restr   r#   r#   r$   _not\  s    
zCNF._notc                    sB   t  }| jD ]$} fdd|D }|t|  qt|  t S )Nc                    s   g | ]}|  qS r#   rH   rI   rK   r#   r$   rL   m  rO   zCNF.rcall.<locals>.<listcomp>)r   r   rt   r   r   r   )r(   r.   Zclause_listry   Zlitsr#   rK   r$   r,   j  s    
z	CNF.rcallc                 G   s,   |d   }|dd  D ]}||}q|S Nr   re   )r   r   r   rw   r}   r   r#   r#   r$   r   r  s    z
CNF.all_orc                 G   s,   |d   }|dd  D ]}||}q|S r   )r   r   r   r#   r#   r$   r   y  s    zCNF.all_andc                 C   s$   ddl m} t|| }t|}|S )Nr   )get_composite_predicates)Zsympy.assumptions.factsr   r`   r   )r   r.   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#   rI   r   r#   r$   	<genexpr>  rO   z+CNF.CNF_to_cnf.<locals>.<genexpr>.<genexpr>N)r   r   r   r#   r$   r     rO   z!CNF.CNF_to_cnf.<locals>.<genexpr>)r   r   )r   r   r#   r   r$   
CNF_to_cnf  s    zCNF.CNF_to_cnf)N)r1   r9   r:   r;   rB   r   r2   r   r   r   classmethodr   r   r   r   r   r   r,   r   r   r   r   r#   r#   r#   r$   r     s.   

	


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   rk   dataencodingkeys_symbols)r(   r   r   r#   r#   r$   rB     s    zEncodedCNF.__init__c              	      sV   t |  _t j}tt t jt td|d  _ fdd|jD  _	d S )Nre   c                    s   g | ]}  |qS r#   encoder   r'   r#   r$   rL     rO   z'EncodedCNF.from_cnf.<locals>.<listcomp>)
r   r   r   rs   rk   ziprr   r   r   r   )r(   r   nr#   r'   r$   from_cnf  s    
$zEncodedCNF.from_cnfc                 C   s   | j S r%   )r   r'   r#   r#   r$   symbols  s    zEncodedCNF.symbolsc                 C   s   t dt| jd S Nre   )rr   rs   r   r'   r#   r#   r$   	variables  s    zEncodedCNF.variablesc                 C   s    dd | j D }t|t| jS )Nc                 S   s   g | ]}t |qS r#   )r   r   r#   r#   r$   rL     rO   z#EncodedCNF.copy.<locals>.<listcomp>)r   r   rk   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                    s   g | ]}  |qS r#   r   r   r'   r#   r$   rL     rO   z+EncodedCNF.add_from_cnf.<locals>.<listcomp>)r   r   r   r#   r'   r$   r     s    zEncodedCNF.add_from_cnfc                 C   sX   |j }| j|d }|d u rDt| j}| j| |d  }| j|< |jrP| S |S d S r   )r   r   ru   rs   r   rt   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   rI   r'   r#   r$   r     rO   z$EncodedCNF.encode.<locals>.<setcomp>r#   )r(   ry   r#   r'   r$   r     s    zEncodedCNF.encode)NN)r1   r9   r:   r;   rB   r   r<   r   r   r   r   r   r   r   r#   r#   r#   r$   r     s   


r   )N) r;   	itertoolsr   r   Zsympy.core.singletonr   Zsympy.logic.boolalgr   r   r   r   r	   r
   Zsympy.core.relationalr   r   r   r   r   r   r   r   r   r   r   r   r   r   r`   r   r   r   r#   r#   r#   r$   <module>   s     A  
n 