§
    OŠtjá-  ã                   óÊ   — d Z ddlmZ ddlmZ ddlmZmZ ddlm	Z	m
Z
 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 ddlmZ dedefd„Zd„ Zdd„Zd„ Zdd„Zdefd„ZdS )zJ
Module to evaluate the proposition with assumptions using SAT algorithm.
é    )ÚS)ÚSymbol)Ú
NumberKindÚUndefinedKind)Úget_all_known_matrix_factsÚget_all_known_number_facts)Úglobal_assumptionsÚAppliedPredicate)Úclass_fact_registry)Úoo)Úsatisfiable)ÚCNFÚ
EncodedCNF)Ú
MatrixKindTc                 óh  — t          j        | ¦  «        }t          j        |  ¦  «        }t          j        |¦  «        }t          ¦   «         }|r|                     |¦  «        }t          |||||¬¦  «        }|                     |¦  «         |r|                     |¦  «         t          |||¦  «        S )a  
    Function to evaluate the proposition with assumptions using SAT algorithm.

    This function extracts every fact relevant to the expressions composing
    proposition and assumptions. For example, if a predicate containing
    ``Abs(x)`` is proposed, then ``Q.zero(Abs(x)) | Q.positive(Abs(x))``
    will be found and passed to SAT solver because ``Q.nonnegative`` is
    registered as a fact for ``Abs``.

    Proposition is evaluated to ``True`` or ``False`` if the truth value can be
    determined. If not, ``None`` is returned.

    Parameters
    ==========

    proposition : Any boolean expression.
        Proposition which will be evaluated to boolean value.

    assumptions : Any boolean expression, optional.
        Local assumptions to evaluate the *proposition*.

    context : AssumptionsContext, optional.
        Default assumptions to evaluate the *proposition*. By default,
        this is ``sympy.assumptions.global_assumptions`` variable.

    use_known_facts : bool, optional.
        If ``True``, facts from ``sympy.assumptions.ask_generated``
        module are passed to SAT solver as well.

    iterations : int, optional.
        Number of times that relevant facts are recursively extracted.
        Default is infinite times until no new fact is found.

    Returns
    =======

    ``True``, ``False``, or ``None``

    Examples
    ========

    >>> from sympy import Abs, Q
    >>> from sympy.assumptions.satask import satask
    >>> from sympy.abc import x
    >>> satask(Q.zero(Abs(x)), Q.zero(x))
    True

    )Úuse_known_factsÚ
iterations)r   Ú	from_propÚextendÚget_all_relevant_factsÚadd_from_cnfÚcheck_satisfiability)	ÚpropositionÚassumptionsÚcontextr   r   ÚpropsÚ_propsÚcontext_cnfÚsats	            úV/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/sympy/assumptions/satask.pyÚsataskr!      s¼   € õd ŒM˜+Ñ&Ô&€EÝŒ]˜K˜<Ñ(Ô(€Få”- Ñ,Ô,€Kå‘%”%€KØð 2Ø!×(Ò(¨Ñ1Ô1ˆå
  ¨°[Ø'°Jð@ñ @ô @€Cà×Ò�[Ñ!Ô!Ð!Øð &Ø×Ò˜Ñ%Ô%Ð%å  v¨sÑ3Ô3Ð3ó    c                 ó4  — |                      ¦   «         }|                      ¦   «         }|                     | ¦  «         |                     |¦  «         t          |¦  «        }t          |¦  «        }|r|rd S |r|sdS |s|rdS |s|st          d¦  «        ‚d S d S )NTFzInconsistent assumptions)Úcopyr   r   Ú
ValueError)ÚpropÚ_propÚfactbaseÚsat_trueÚ	sat_falseÚcan_be_trueÚcan_be_falses          r    r   r   U   sÎ   € Ø�}Š}‰Œ€HØ—’‘”€IØ×Ò˜$ÑÔÐØ×Ò˜5Ñ!Ô!Ð!Ý˜hÑ'Ô'€KÝ˜yÑ)Ô)€Làð �|ð Øˆtàð ˜<ð Øˆtàð ˜<ð Øˆuàð 5˜|ð 5õ Ð3Ñ4Ô4Ð4ð	5ð 5ð 5ð 5r"   Nc                 ó¨  ‡— t          | ¦  «        Š|                      ¦   «         }t          ¦   «         }|r||                     ¦   «         z  }|r||                     ¦   «         z  }|t          j        t          j        hz
  }d}|t          ¦   «         k    rXt          ¦   «         }|D ]+}t          |¦  «        }|‰z  t          ¦   «         k    r||z  }Œ,|‰z
  }‰|z  Š|t          ¦   «         k    °X|ˆfd„|D ¦   «         z  }t          ¦   «         }	|D ]D}
t          |
t          ¦  «        r|	t          |
j        ¦  «        z  }	Œ/|	 	                    |
¦  «         ŒE|	S )aÍ  
    Extract every expression in the argument of predicates from *proposition*,
    *assumptions* and *context*.

    Parameters
    ==========

    proposition : sympy.assumptions.cnf.CNF

    assumptions : sympy.assumptions.cnf.CNF, optional.

    context : sympy.assumptions.cnf.CNF, optional.
        CNF generated from assumptions context.

    Examples
    ========

    >>> from sympy import Q, Abs
    >>> from sympy.assumptions.cnf import CNF
    >>> from sympy.assumptions.satask import extract_predargs
    >>> from sympy.abc import x, y
    >>> props = CNF.from_prop(Q.zero(Abs(x*y)))
    >>> assump = CNF.from_prop(Q.zero(x) & Q.zero(y))
    >>> extract_predargs(props, assump)
    {x, y, Abs(x*y)}

    Nc                 óX   •— h | ]&}t          |¦  «        ‰z  t          ¦   «         k    ¯$|’Œ'S © )Úfind_symbolsÚset)Ú.0ÚlÚreq_keyss     €r    ú	<setcomp>z#extract_predargs.<locals>.<setcomp>œ   s2   ø€ ÐEÐEÐE�1¥¨a¡¤°8Ñ!;½s¹u¼uÒ!DÐ!DˆQÐ!DÐ!DÐ!Dr"   )
r0   Úall_predicatesr1   r   ÚtrueÚfalseÚ
isinstancer
   Ú	argumentsÚadd)r   r   r   ÚkeysÚlkeysÚtmp_keysÚtmpr3   ÚsymsÚexprsÚkeyr4   s              @r    Úextract_predargsrC   m   sk  ø€ õ8 ˜KÑ(Ô(€HØ×%Ò%Ñ'Ô'€Då‰EŒE€EØð .Ø�×+Ò+Ñ-Ô-Ñ-ˆØð *Ø�×'Ò'Ñ)Ô)Ñ)ˆà•Q”V�QœWÐ%Ñ%€EØ€HØ
•c‘e”eÒ
Ð
Ý‰eŒeˆØð 	ð 	ˆAÝ ‘?”?ˆDØ�x‘¥C¡E¤EÒ)Ð)Ø�t‘�øØ˜‘>ˆØ�HÑˆð •c‘e”eÒ
Ð
ð 	ÐEÐEÐEÐE˜ÐEÑEÔEÑE€Då‰EŒE€EØð ð ˆÝ�cÕ+Ñ,Ô,ð 	Ø•S˜œÑ'Ô'Ñ'ˆEˆEà�IŠI�c‰NŒNˆNˆNØ€Lr"   c                 óÒ   — t          | t          ¦  «        r9t          ¦   «         }|                      ¦   «         D ]}|t	          |¦  «        z  }Œ|S |                      t          ¦  «        S )zƒ
    Find every :obj:`~.Symbol` in *pred*.

    Parameters
    ==========

    pred : sympy.assumptions.cnf.CNF, or any Expr.

    )r9   r   r1   r6   r0   Úatomsr   )ÚpredÚsymbolsÚas      r    r0   r0   ¦   sc   € õ �$�ÑÔð Ý‘%”%ˆØ×$Ò$Ñ&Ô&ð 	'ð 	'ˆAØ•| A‘”Ñ&ˆGˆGØˆØ�:Š:•fÑÔÐr"   c                 óR  — |st          ¦   «         }t          ¦   «         }| D ]€}t          |¦  «        D ]n}t          j        |¦  «        }|                     |¦  «        }|                     ¦   «         D ].}t          |t          ¦  «        r|t          |j        ¦  «        z  }Œ/ŒoŒ�|| z
  |fS )a2	  
    Extract relevant facts from the items in *exprs*. Facts are defined in
    ``assumptions.sathandlers`` module.

    This function is recursively called by ``get_all_relevant_facts()``.

    Parameters
    ==========

    exprs : set
        Expressions whose relevant facts are searched.

    relevant_facts : sympy.assumptions.cnf.CNF, optional.
        Pre-discovered relevant facts.

    Returns
    =======

    exprs : set
        Candidates for next relevant fact searching.

    relevant_facts : sympy.assumptions.cnf.CNF
        Updated relevant facts.

    Examples
    ========

    Here, we will see how facts relevant to ``Abs(x*y)`` are recursively
    extracted. On the first run, set containing the expression is passed
    without pre-discovered relevant facts. The result is a set containing
    candidates for next run, and ``CNF()`` instance containing facts
    which are relevant to ``Abs`` and its argument.

    >>> from sympy import Abs
    >>> from sympy.assumptions.satask import get_relevant_clsfacts
    >>> from sympy.abc import x, y
    >>> exprs = {Abs(x*y)}
    >>> exprs, facts = get_relevant_clsfacts(exprs)
    >>> exprs
    {x*y}
    >>> facts.clauses #doctest: +SKIP
    {frozenset({Literal(Q.odd(Abs(x*y)), False), Literal(Q.odd(x*y), True)}),
    frozenset({Literal(Q.zero(Abs(x*y)), False), Literal(Q.zero(x*y), True)}),
    frozenset({Literal(Q.even(Abs(x*y)), False), Literal(Q.even(x*y), True)}),
    frozenset({Literal(Q.zero(Abs(x*y)), True), Literal(Q.zero(x*y), False)}),
    frozenset({Literal(Q.even(Abs(x*y)), False),
                Literal(Q.odd(Abs(x*y)), False),
                Literal(Q.odd(x*y), True)}),
    frozenset({Literal(Q.even(Abs(x*y)), False),
                Literal(Q.even(x*y), True),
                Literal(Q.odd(Abs(x*y)), False)}),
    frozenset({Literal(Q.positive(Abs(x*y)), False),
                Literal(Q.zero(Abs(x*y)), False)})}

    We pass the first run's results to the second run, and get the expressions
    for next run and updated facts.

    >>> exprs, facts = get_relevant_clsfacts(exprs, relevant_facts=facts)
    >>> exprs
    {x, y}

    On final run, no more candidate is returned thus we know that all
    relevant facts are successfully retrieved.

    >>> exprs, facts = get_relevant_clsfacts(exprs, relevant_facts=facts)
    >>> exprs
    set()

    )	r   r1   r   Úto_CNFÚ_andr6   r9   r
   r:   )rA   Úrelevant_factsÚnewexprsÚexprÚfactÚnewfactrB   s          r    Úget_relevant_clsfactsrQ   ¸   sÆ   € ðL ð Ý™œˆå‰uŒu€HØð 3ð 3ˆÝ'¨Ñ-Ô-ð 	3ð 	3ˆDÝ”j Ñ&Ô&ˆGØ+×0Ò0°Ñ9Ô9ˆNØ×-Ò-Ñ/Ô/ð 3ð 3�Ý˜cÕ#3Ñ4Ô4ð 3Ø¥ C¤MÑ 2Ô 2Ñ2�Høð3ð	3ð �eÑ˜^Ð+Ð+r"   c                 óÒ  ‡‡— d}t          ¦   «         }t          ¦   «         }	 |dk    rt          | ||¦  «        }||z  }t          ||¦  «        \  }}|dz  }||k    rn|snŒ?|�r`t          ¦   «         }	t	          d„ |D ¦   «         ¦  «        r!|	                     t          ¦   «         ¦  «         t	          d„ |D ¦   «         ¦  «        r!|	                     t          ¦   «         ¦  «         t          ¦   «         }
|
 	                    |	¦  «         d„ Šˆfd„}g }g }t          |
j        ¦  «        }t          |¦  «        D ]2\  }Š|ˆfd„|
j        D ¦   «         z  }| ||
j        ||z  ¦  «        z  }Œ3t          t          t!          |t#          dt          |¦  «        dz   ¦  «        ¦  «        ¦  «        ¦  «        }t          ||¦  «        }nt          ¦   «         }|                     |¦  «         |S )	al  
    Extract all relevant facts from *proposition* and *assumptions*.

    This function extracts the facts by recursively calling
    ``get_relevant_clsfacts()``. Extracted facts are converted to
    ``EncodedCNF`` and returned.

    Parameters
    ==========

    proposition : sympy.assumptions.cnf.CNF
        CNF generated from proposition expression.

    assumptions : sympy.assumptions.cnf.CNF
        CNF generated from assumption expression.

    context : sympy.assumptions.cnf.CNF
        CNF generated from assumptions context.

    use_known_facts : bool, optional.
        If ``True``, facts from ``sympy.assumptions.ask_generated``
        module are encoded as well.

    iterations : int, optional.
        Number of times that relevant facts are recursively extracted.
        Default is infinite times until no new fact is found.

    Returns
    =======

    sympy.assumptions.cnf.EncodedCNF

    Examples
    ========

    >>> from sympy import Q
    >>> from sympy.assumptions.cnf import CNF
    >>> from sympy.assumptions.satask import get_all_relevant_facts
    >>> from sympy.abc import x, y
    >>> props = CNF.from_prop(Q.nonzero(x*y))
    >>> assump = CNF.from_prop(Q.nonzero(x))
    >>> context = CNF.from_prop(Q.nonzero(y))
    >>> get_all_relevant_facts(props, assump, context) #doctest: +SKIP
    <sympy.assumptions.cnf.EncodedCNF at 0x7f09faa6ccd0>

    r   Té   c              3   óP   K  — | ]!}|j         t          t          ¦  «        k    V — Œ"d S ©N)Úkindr   r   ©r2   rN   s     r    ú	<genexpr>z)get_all_relevant_facts.<locals>.<genexpr>R  s1   è è € ÐIÐI°tˆtŒy�J¥zÑ2Ô2Ò2ÐIÐIÐIÐIÐIÐIr"   c              3   óV   K  — | ]$}|j         t          k    p|j         t          k    V — Œ%d S rU   )rV   r   r   rW   s     r    rX   z)get_all_relevant_facts.<locals>.<genexpr>U  s5   è è € ÐaÐaÈt�”�jÒ(ÐI¨d¬i½=Ò.HÐaÐaÐaÐaÐaÐar"   c                 ó"   — | dk    r| |z   S | |z
  S )Nr   r/   )ÚlitÚdeltas     r    Útranslate_literalz1get_all_relevant_facts.<locals>.translate_literal[  s   € Ø�QŠwˆwØ˜U‘{Ð"à˜U‘{Ð"r"   c                 ó$   •‡— ˆˆfd„| D ¦   «         S )Nc                 ó.   •— g | ]}ˆˆfd „|D ¦   «         ‘ŒS )c                 ó(   •— h | ]} ‰|‰¦  «        ’ŒS r/   r/   )r2   Úir\   r]   s     €€r    r5   zLget_all_relevant_facts.<locals>.translate_data.<locals>.<listcomp>.<setcomp>b  s'   ø€ ÐAÐAÐA°QÐ&Ð& q¨%Ñ0Ô0ÐAÐAÐAr"   r/   )r2   Úclauser\   r]   s     €€r    ú
<listcomp>zBget_all_relevant_facts.<locals>.translate_data.<locals>.<listcomp>b  s1   ø€ ÐUÐUÐUÀfÐAÐAÐAÐAÐA¸&ÐAÑAÔAÐUÐUÐUr"   r/   )Údatar\   r]   s    `€r    Útranslate_dataz.get_all_relevant_facts.<locals>.translate_dataa  s"   øø€ ØUÐUÐUÐUÐUÐPTÐUÑUÔUÐUr"   c                 ó&   •— g | ]} |‰¦  «        ‘ŒS r/   r/   )r2   rF   rN   s     €r    rc   z*get_all_relevant_facts.<locals>.<listcomp>g  s!   ø€ ÐBÐBÐB t˜˜˜T™
œ
ÐBÐBÐBr"   )r   r1   rC   rQ   ÚanyÚadd_clausesr   r   r   Úfrom_cnfÚlenrG   Ú	enumeraterd   ÚdictÚlistÚzipÚranger   )r   r   r   r   r   ra   rL   Ú	all_exprsrA   Úknown_facts_CNFÚ
kf_encodedre   rd   rG   Ún_litÚencodingÚctxrN   r]   s                    @@r    r   r     s/  øø€ ðh 	
€AÝ‘U”U€NÝ‘”€Ið	Ø�Š6ˆ6Ý$ [°+¸wÑGÔGˆEØ�UÑˆ	Ý 5°e¸^Ñ LÔ LÑˆˆ~Ø	ˆQ‰ˆØ�
Š?ˆ?ØØð 	Øð	ð ñ Ý™%œ%ˆåÐIÐI¸yÐIÑIÔIÑIÔIð 	FØ×'Ò'Õ(BÑ(DÔ(DÑEÔEÐEåÐaÐaÐW`ÐaÑaÔaÑaÔað 	FØ×'Ò'Õ(BÑ(DÔ(DÑEÔEÐEå‘\”\ˆ
Ø×Ò˜OÑ,Ô,Ð,ð	#ð 	#ð 	#ð	Vð 	Vð 	Vð 	Vð 	VàˆØˆÝ�JÔ&Ñ'Ô'ˆÝ  Ñ+Ô+ð 	?ð 	?‰GˆAˆtØÐBÐBÐBÐB¨zÔ/AÐBÑBÔBÑBˆGØ�N�N :¤?°A¸±IÑ>Ô>Ñ>ˆDˆDå��S ­%°µ3°w±<´<À±>Ñ*BÔ*BÑCÔCÑDÔDÑEÔEˆÝ˜˜xÑ(Ô(ˆˆå‰lŒlˆà×Ò�^Ñ$Ô$Ð$à€Jr"   )NNrU   )Ú__doc__Úsympy.core.singletonr   Úsympy.core.symbolr   Úsympy.core.kindr   r   Úsympy.assumptions.ask_generatedr   r   Úsympy.assumptions.assumer	   r
   Úsympy.assumptions.sathandlersr   Ú
sympy.corer   Úsympy.logic.inferencer   Úsympy.assumptions.cnfr   r   Úsympy.matrices.kindr   r!   r   rC   r0   rQ   r   r/   r"   r    ú<module>r�      sz  ððð ð #Ð "Ð "Ð "Ð "Ð "Ø $Ð $Ð $Ð $Ð $Ð $Ø 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ð 5Ø bÐ bÐ bÐ bÐ bÐ bÐ bÐ bØ IÐ IÐ IÐ IÐ IÐ IÐ IÐ IØ =Ð =Ð =Ð =Ð =Ð =Ø Ð Ð Ð Ð Ð Ø -Ð -Ð -Ð -Ð -Ð -Ø 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ð 1Ø *Ð *Ð *Ð *Ð *Ð *ð %)Ð2DØ¨ðA4ð A4ð A4ð A4ðH5ð 5ð 5ð07ð 7ð 7ð 7ðrð ð ð$R,ð R,ð R,ð R,ðl ¨ðdð dð dð dð dð dr"   