
    \h-                         S r SSKJr  SSKJr  SSKJrJr  SSKJ	r	J
r
  SSKJrJr  SSKJr  SSKJr  SS	KJr  SS
KJrJr  SSKJr  S\S\4S jrS rSS jrS rSS jrS\4S jrg)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                 L   [         R                  " U 5      n[         R                  " U ) 5      n[         R                  " U5      n[        5       nU(       a  UR                  U5      n[        XQUX4S9nUR	                  U5        U(       a  UR	                  U5        [        XVU5      $ )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	            P/var/www/auris/envauris/lib/python3.13/site-packages/sympy/assumptions/satask.pysataskr!      s    d MM+&E]]K<(F--,K%K!((1
 ['@C[!%s33    c                 B   UR                  5       nUR                  5       nUR                  U 5        UR                  U5        [        U5      n[        U5      nU(       a  U(       a  g U(       a  U(       d  gU(       d  U(       a  gU(       d  U(       d  [        S5      eg g )NTFzInconsistent assumptions)copyr   r   
ValueError)prop_propfactbasesat_true	sat_falsecan_be_truecan_be_falses          r    r   r   U   sz    }}HI$5!h'Ky)L|<<| 344	  ,;r"   Nc                    [        U 5      nU R                  5       n[        5       nU(       a  XQR                  5       -  nU(       a  XRR                  5       -  nU[        R                  [        R
                  1-
  nSnU[        5       :w  aL  [        5       nU H$  n[        U5      n	X-  [        5       :w  d  M   Xy-  nM&     Xs-
  nX6-  nU[        5       :w  a  ML  XE Vs1 s H!  n[        U5      U-  [        5       :w  d  M  UiM#     sn-  n[        5       n
U HC  n[        U[        5      (       a  U
[        UR                  5      -  n
M2  U
R                  U5        ME     U
$ s  snf )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)}

N)
find_symbolsall_predicatessetr   truefalse
isinstancer
   	argumentsadd)r   r   r   req_keyskeyslkeystmp_keystmplsymsexprskeys               r    extract_predargsr?   m   s2   8 K(H%%'DEE++--''))QVVQWW%%EH
ce
eA?DCE)  > ce
 	E1a8!;su!DQEEDEEc+,,S''EIIcN	 
 L Fs   E=Ec                     [        U [        5      (       a1  [        5       nU R                  5        H  nU[	        U5      -  nM     U$ U R                  [        5      $ )zo
Find every :obj:`~.Symbol` in *pred*.

Parameters
==========

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

)r3   r   r0   r/   r.   atomsr   )predsymbolsas      r    r.   r.      sM     $%$$&A|A&G '::fr"   c                 T   U(       d
  [        5       n[        5       nU  H  n[        U5       Hp  n[         R                  " U5      nUR	                  U5      nUR                  5        H2  n[        U[        5      (       d  M  U[        UR                  5      -  nM4     Mr     M     X -
  U4$ )a^  
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   r0   r   to_CNF_andr/   r3   r
   r4   )r=   relevant_factsnewexprsexprfactnewfactr>   s          r    get_relevant_clsfactsrM      s    L uH'-Djj&G+009N--/c#344CMM 22H 0 .  ^++r"   c                 h  ^ Sn[        5       n[        5       n US:X  a  [        XU5      nUW-  n[        X5      u  pUS-  nXT:  a  O
U(       d  OM9  U(       Ga8  [        5       n	[	        S U 5       5      (       a  U	R                  [        5       5        [	        S U 5       5      (       a  U	R                  [        5       5        [        5       n
U
R                  U	5        S mU4S jn/ n/ n[        U
R                  5      n[        U5       HA  u  p_XR                   Vs/ s H  nU" U5      PM     sn-  nX" U
R                  X^-  5      -  nMC     [        [        [!        U[#        S[        U5      S-   5      5      5      5      n[        UU5      nO
[        5       nUR%                  U5        U$ s  snf )a  
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      c              3   X   #    U  H   oR                   [        [        5      :H  v   M"     g 7fN)kindr   r   .0rJ   s     r    	<genexpr>)get_all_relevant_facts.<locals>.<genexpr>R  s     IytyyJz22ys   (*c              3   z   #    U  H1  oR                   [        :H  =(       d    UR                   [        :H  v   M3     g 7frQ   )rR   r   r   rS   s     r    rU   rV   U  s*     aW`tj(Idii=.HIW`s   9;c                     U S:  a  X-   $ X-
  $ )Nr    )litdeltas     r    translate_literal1get_all_relevant_facts.<locals>.translate_literal[  s    Qw{"{"r"   c                 p   > U  VVs/ s H  o" Vs1 s H  nT" X15      iM     snPM     snn$ s  snf s  snnf rQ   rY   )datar[   clauseir\   s       r    translate_data.get_all_relevant_facts.<locals>.translate_dataa  s5    PTUPTf&A&Q&q0&APTUUAUs   	2-22)r   r0   r?   rM   anyadd_clausesr   r   r   from_cnflenrC   	enumerater_   dictlistzipranger   )r   r   r   r   r   ra   rH   	all_exprsr=   known_facts_CNF
kf_encodedrb   r_   rC   n_litrJ   rB   encodingctxr\   s                      @r    r   r     s   h 	
AUNI
6$[wGEU	 5e L	Q?  %IyIII''(B(DEaW`aaa''(B(DE\
O,	#	VJ&&' +GA/A/AB/AtT
/ABBGN:??AI>>D , S%3w<>*BCDEx(l^$J Cs   F/)NNrQ   )__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   r?   r.   rM   r   rY   r"   r    <module>r~      sb    # $ 5 b I =  - 1 * %)2DA4H507r$R,l dr"   