
    g#                         d Z ddlmZmZmZmZmZ ddlmZ ddl	m
Z
 ddlmZ d Zdd	Zd
 ZddZddZ G d d          Z G d de          ZdS )z Inference in propositional logic    )AndNot	conjunctsto_cnfBooleanFunction)ordered)sympify)import_modulec                     | du s| du r| S | j         r| S | j        rt          | j        d                   S t	          d          )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    Q/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/logic/inference.pyr   r   	   s[      $'U**		 @	 @gl1o...>???    NFc                    |r||dk    rt          d| d          d}||dk    r+t          d          }|d}n|dk    rt          d          d}|dk    rt          d          }|d}|d	k    rt          d	          }|d}|d
k    rddlm}  ||           S |dk    rddlm}  || ||          S |dk    rddlm}	  |	| |          S |dk    rddlm	}
  |
| ||          S |d	k    rddl
m}  || |          S t          )a  
    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

    N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%9mR[mmmnnn	I22	**!III%%!"ABBB  I+g&&=I$4  :IF@@@@@@%%%	g		AAAAAAjPPPP	i		NNNNNN""4444	k	!	!RRRRRR$$T:w???	d		DDDDDD~dJ///
r   c                 <    t          t          |                      S )ax  
    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    * 3t99%%%%r   c                    ddl m dfd| v r| S t          |           }  |           st          d| z            |si }fd|                                D             }|                     |          }|v rt          |          S |r`t                              |	                                d          }t          ||          rt          |          rdS nt          |          sdS d	S )
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                     t          |           s| v rdS t          | t                    sdS t          fd| j        D                       S )NTFc              3   .   K   | ]} |          V  d S N ).0arg	_validates     r   	<genexpr>z-pl_true.<locals>._validate.<locals>.<genexpr>   s+      77c99S>>777777r   )
isinstancer   allr   )r'   r/   r6   booleans    r   r6   zpl_true.<locals>._validate   s^    dF## 	tw4$00 	57777TY777777r   z$%s is not a valid boolean expressionc                 $    i | ]\  }}|v 	||S r3   r3   )r4   kvr:   s      r   
<dictcomp>zpl_true.<locals>.<dictcomp>   s$    <<<daqG||Q|||r   TFN)sympy.core.symbolr/   r	   r   itemssubsbooldictfromkeysatomspl_truer-   r+   )r'   modeldeepresultr/   r6   r:   s       @@@r   rF   rF      sA   P )(((((G8 8 8 8 8 8 8 w4==D9T?? H?$FGGG <<<<ekkmm<<<EYYuFF|| fllnnd3365!! 	V}} t v&& u4r   c                     |rt          |          }ng }|                    t          |                      t          t	          |            S )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      sP    2  ;''s4yy!!!3,----r   c                   B    e Zd ZdZddZd Zd Zd Zed             Z	dS )	KBz"Base class for all knowledge basesNc                 ^    t                      | _        |r|                     |           d S d S r2   )setclauses_tellselfsentences     r   __init__zKB.__init__   s7     	 IIh	  	 r   c                     t           r2   r&   rU   s     r   rT   zKB.tell      !!r   c                     t           r2   rZ   rV   querys     r   askzKB.ask  r[   r   c                     t           r2   rZ   rU   s     r   retractz
KB.retract	  r[   r   c                 D    t          t          | j                            S r2   )rK   r   rS   )rV   s    r   clausesz
KB.clauses  s    GDM**+++r   r2   )
__name__
__module____qualname____doc__rX   rT   r_   ra   propertyrc   r3   r   r   rP   rP      sv        ,,       
" " "" " "" " " , , X, , ,r   rP   c                   $    e Zd ZdZd Zd Zd ZdS )PropKBz=A KB for Propositional Logic.  Inefficient, with no indexing.c                 x    t          t          |                    D ]}| j                            |           dS )ai  Add 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   rS   addrV   rW   cs      r   rT   zPropKB.tell  sF    * 6(++,, 	! 	!AMa    	! 	!r   c                 ,    t          || j                  S )a8  Checks 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   rS   r]   s     r   r_   z
PropKB.ask,  s      udm,,,r   c                 x    t          t          |                    D ]}| j                            |           dS )am  Remove 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   rS   discardrm   s      r   ra   zPropKB.retract>  sF    * 6(++,, 	% 	%AM!!!$$$$	% 	%r   N)rd   re   rf   rg   rT   r_   ra   r3   r   r   rj   rj     sG        GG! ! !0- - -$% % % % %r   rj   )NFFF)NFr2   )rg   sympy.logic.boolalgr   r   r   r   r   sympy.core.sortingr   sympy.core.sympifyr	   sympy.external.importtoolsr
   r   r+   r-   rF   rN   rP   rj   r3   r   r   <module>rv      s9   & & L L L L L L L L L L L L L L & & & & & & & & & & & & 4 4 4 4 4 4@ @ @4T T T Tn& & &0F F F FR. . . .B, , , , , , , ,*C% C% C% C% C%R C% C% C% C% C%r   