
    \h#                         S r SSKJrJrJrJrJr  SSKJr  SSK	J
r
  SSKJr  S rSS jrS	 rSS
 jrSS jr " S S5      r " S S\5      rg)z Inference in propositional logic    )AndNot	conjunctsto_cnfBooleanFunction)ordered)sympify)import_modulec                     U SL d  U SL a  U $ U R                   (       a  U $ U R                  (       a  [        U R                  S   5      $ [	        S5      e)z
The symbol in this literal (without the negation).

Examples
========

>>> from sympy.abc import A
>>> from sympy.logic.inference import literal_symbol
>>> literal_symbol(A)
A
>>> literal_symbol(~A)
A

TFr   z#Argument must be a boolean literal.)	is_Symbolis_Notliteral_symbolargs
ValueError)literals    M/var/www/auris/envauris/lib/python3.13/site-packages/sympy/logic/inference.pyr   r   	   sK      $'U*				gll1o..>??    Nc                    U(       a  Ub  US:w  a  [        SU S35      eSnUb  US:X  a$  [        S5      nUb  SnOUS:X  a  [        S5      eSnUS:X  a  [        S5      nUc  SnUS:X  a  [        S5      nUc  SnUS	:X  a  S
SKJn  U" U 5      $ US:X  a  S
SKJn  U" XUS9$ US:X  a  S
SKJn	  U	" X5      $ US:X  a  S
SKJ	n
  U
" XU5      $ US:X  a  S
SK
Jn  U" X5      $ [        e)aJ  
Check satisfiability of a propositional sentence.
Returns a model when it succeeds.
Returns {true: true} for trivially true expressions.

On setting all_models to True, if given expr is satisfiable then
returns a generator of models. However, if expr is unsatisfiable
then returns a generator containing the single element False.

Examples
========

>>> from sympy.abc import A, B
>>> from sympy.logic.inference import satisfiable
>>> satisfiable(A & ~B)
{A: True, B: False}
>>> satisfiable(A & ~A)
False
>>> satisfiable(True)
{True: True}
>>> next(satisfiable(A & ~A, all_models=True))
False
>>> models = satisfiable((A >> B) & B, all_models=True)
>>> next(models)
{A: False, B: True}
>>> next(models)
{A: True, B: True}
>>> def use_models(models):
...     for model in models:
...         if model:
...             # Do something with the model.
...             print(model)
...         else:
...             # Given expr is unsatisfiable.
...             print("UNSAT")
>>> use_models(satisfiable(A >> ~A, all_models=True))
{A: False}
>>> use_models(satisfiable(A ^ A, all_models=True))
UNSAT

dpll2z2Currently only dpll2 can handle using lra theory. z is not handled.pycosatzpycosat module is not present	minisat22pysatz3dpllr   )dpll_satisfiable)use_lra_theory)pycosat_satisfiable)minisat22_satisfiable)z3_satisfiable)r   r
   ImportErrorsympy.logic.algorithms.dpllr   sympy.logic.algorithms.dpll2&sympy.logic.algorithms.pycosat_wrapperr   (sympy.logic.algorithms.minisat22_wrapperr   !sympy.logic.algorithms.z3_wrapperr   NotImplementedError)expr	algorithm
all_modelsminimalr   r   r   r   r   r   r   r   s               r   satisfiabler+   #   s   T  Y'%9QR[Q\\lmnn	I2	*!II%!"ABB  I+g&=I$4 :IF@%%	g	APP	i	N"444	k	!R$Tw??	d	Dd//
r   c                 4    [        [        U 5      5      (       + $ )a@  
Check validity of a propositional sentence.
A valid propositional sentence is True under every assignment.

Examples
========

>>> from sympy.abc import A, B
>>> from sympy.logic.inference import valid
>>> valid(A | ~A)
True
>>> valid(A | B)
False

References
==========

.. [1] https://en.wikipedia.org/wiki/Validity

)r+   r   )r'   s    r   validr-   z   s    * 3t9%%%r   c                   ^^^ SSK Jm  SmUUU4S jmU T;   a  U $ [        U 5      n T" U 5      (       d  [        SU -  5      eU(       d  0 nUR	                  5        VVs0 s H  u  p4UT;   d  M  X4_M     nnnU R                  U5      nUT;   a  [        U5      $ U(       aX  [        R                  UR                  5       S5      n[        XQ5      (       a  [        U5      (       a  g g[        U5      (       d  ggs  snnf )	a  
Returns whether the given assignment is a model or not.

If the assignment does not specify the value for every proposition,
this may return None to indicate 'not obvious'.

Parameters
==========

model : dict, optional, default: {}
    Mapping of symbols to boolean values to indicate assignment.
deep: boolean, optional, default: False
    Gives the value of the expression under partial assignments
    correctly. May still return None to indicate 'not obvious'.


Examples
========

>>> from sympy.abc import A, B
>>> from sympy.logic.inference import pl_true
>>> pl_true( A & B, {A: True, B: True})
True
>>> pl_true(A & B, {A: False})
False
>>> pl_true(A & B, {A: True})
>>> pl_true(A & B, {A: True}, deep=True)
>>> pl_true(A >> (B >> A))
>>> pl_true(A >> (B >> A), deep=True)
True
>>> pl_true(A & ~A)
>>> pl_true(A & ~A, deep=True)
False
>>> pl_true(A & B & (~A | ~B), {A: True})
>>> pl_true(A & B & (~A | ~B), {A: True}, deep=True)
False

r   )Symbol)TFc                    > [        U T5      (       d  U T;   a  g[        U [        5      (       d  g[        U4S jU R                   5       5      $ )NTFc              3   4   >#    U  H  nT" U5      v   M     g 7fN ).0arg	_validates     r   	<genexpr>-pl_true.<locals>._validate.<locals>.<genexpr>   s     7Yc9S>>Ys   )
isinstancer   allr   )r'   r/   r6   booleans    r   r6   pl_true.<locals>._validate   s>    dF##tw$007TYY777r   z$%s is not a valid boolean expressionTFN)sympy.core.symbolr/   r	   r   itemssubsbooldictfromkeysatomspl_truer-   r+   )	r'   modeldeepkvresultr/   r6   r;   s	         @@@r   rD   rD      s    P )G8 w4=DT???$FGG#kkm<mdaqG|TQTmE<YYuFF|fllnd36!!V}} 
  v&& =s   C9.C9c                     U(       a  [        U5      nO/ nUR                  [        U 5      5        [        [	        U6 5      (       + $ )a  
Check whether the given expr_set entail an expr.
If formula_set is empty then it returns the validity of expr.

Examples
========

>>> from sympy.abc import A, B, C
>>> from sympy.logic.inference import entails
>>> entails(A, [A >> B, B >> C])
False
>>> entails(C, [A >> B, B >> C, A])
True
>>> entails(A >> B)
False
>>> entails(A >> (B >> A))
True

References
==========

.. [1] https://en.wikipedia.org/wiki/Logical_consequence

)listappendr   r+   r   )r'   formula_sets     r   entailsrN      s;    2 ;'s4y!3,---r   c                   D    \ rS rSrSrS
S jrS rS rS r\	S 5       r
S	rg)KB   z"Base class for all knowledge basesNc                 T    [        5       U l        U(       a  U R                  U5        g g r2   )setclauses_tellselfsentences     r   __init__KB.__init__   s    IIh r   c                     [         er2   r&   rV   s     r   rU   KB.tell      !!r   c                     [         er2   r\   rW   querys     r   askKB.ask  r^   r   c                     [         er2   r\   rV   s     r   retract
KB.retract	  r^   r   c                 >    [        [        U R                  5      5      $ r2   )rK   r   rT   )rW   s    r   clauses
KB.clauses  s    GDMM*++r   )rT   r2   )__name__
__module____qualname____firstlineno____doc__rY   rU   rb   re   propertyrh   __static_attributes__r3   r   r   rP   rP      s-    , 
""" , ,r   rP   c                   *    \ rS rSrSrS rS rS rSrg)PropKBi  z=A KB for Propositional Logic.  Inefficient, with no indexing.c                 p    [        [        U5      5       H  nU R                  R                  U5        M      g)zAdd the sentence's clauses to the KB

Examples
========

>>> from sympy.logic.inference import PropKB
>>> from sympy.abc import x, y
>>> l = PropKB()
>>> l.clauses
[]

>>> l.tell(x | y)
>>> l.clauses
[x | y]

>>> l.tell(y)
>>> l.clauses
[y, x | y]

N)r   r   rT   addrW   rX   cs      r   rU   PropKB.tell  s*    * 6(+,AMMa  -r   c                 ,    [        XR                  5      $ )zChecks if the query is true given the set of clauses.

Examples
========

>>> from sympy.logic.inference import PropKB
>>> from sympy.abc import x, y
>>> l = PropKB()
>>> l.tell(x & ~y)
>>> l.ask(x)
True
>>> l.ask(y)
False

)rN   rT   r`   s     r   rb   
PropKB.ask,  s      umm,,r   c                 p    [        [        U5      5       H  nU R                  R                  U5        M      g)zRemove the sentence's clauses from the KB

Examples
========

>>> from sympy.logic.inference import PropKB
>>> from sympy.abc import x, y
>>> l = PropKB()
>>> l.clauses
[]

>>> l.tell(x | y)
>>> l.clauses
[x | y]

>>> l.retract(x | y)
>>> l.clauses
[]

N)r   r   rT   discardru   s      r   re   PropKB.retract>  s*    * 6(+,AMM!!!$ -r   r3   N)	rj   rk   rl   rm   rn   rU   rb   re   rp   r3   r   r   rr   rr     s    G!0-$%r   rr   )NFFF)NFr2   )rn   sympy.logic.boolalgr   r   r   r   r   sympy.core.sortingr   sympy.core.sympifyr	   sympy.external.importtoolsr
   r   r+   r-   rD   rN   rP   rr   r3   r   r   <module>r      sN    & L L & & 4@4Tn&0FR.B, ,*C%R C%r   