o
    oh#                     @   s   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d Zdd
dZdd ZdddZdddZG dd dZG dd deZdS )z Inference in propositional logic    )AndNot	conjunctsto_cnfBooleanFunction)ordered)sympify)import_modulec                 C   s:   | 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)literal r   i/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/logic/inference.pyr   	   s   r   NFc                 C   s8  |r|dur|dkrt d| dd}|du s|dkr1td}|dur'd}n
|dkr/tdd}|dkr?td}|du r?d}|d	krMtd	}|du rMd}|d
kr[ddlm} || S |dkrlddlm} || ||dS |dkr{ddlm}	 |	| |S |dkrddlm	}
 |
| ||S |d	krd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   r   r   r   satisfiable#   sF   *

r(   c                 C   s   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$   r   r   r   validz   s   r*   c                    s   ddl m  d fdd| v r| S t| } | s$td|  |s(i }fdd| D }| |}|v r@t|S |r]t|	 d	}t
||rWt|rUd	S dS 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                    s<   t |  s	| v rdS t | tsdS tfdd| jD S )NTFc                 3   s    | ]} |V  qd S Nr   ).0arg)	_validater   r   	<genexpr>   s    z-pl_true.<locals>._validate.<locals>.<genexpr>)
isinstancer   allr   r)   r+   r/   booleanr   r   r/      s
   
zpl_true.<locals>._validatez$%s is not a valid boolean expressionc                    s   i | ]\}}| v r||qS r   r   )r-   kv)r4   r   r   
<dictcomp>   s    zpl_true.<locals>.<dictcomp>TFN)sympy.core.symbolr+   r   r   itemssubsbooldictfromkeysatomspl_truer*   r(   )r$   modeldeepresultr   r3   r   r?      s.   (

r?   c                 C   s.   |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_setr   r   r   entails   s
   
rF   c                   @   s>   e Zd ZdZdddZdd Zdd Zd	d
 Zedd Z	dS )KBz"Base class for all knowledge basesNc                 C   s   t  | _|r| | d S d S r,   )setclauses_tellselfsentencer   r   r   __init__   s   zKB.__init__c                 C      t r,   r#   rK   r   r   r   rJ        zKB.tellc                 C   rO   r,   rP   rL   queryr   r   r   ask  rQ   zKB.askc                 C   rO   r,   rP   rK   r   r   r   retract	  rQ   z
KB.retractc                 C   s   t t| jS r,   )rC   r   rI   )rL   r   r   r   clauses  s   z
KB.clausesr,   )
__name__
__module____qualname____doc__rN   rJ   rT   rU   propertyrV   r   r   r   r   rG      s    
rG   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	PropKBz=A KB for Propositional Logic.  Inefficient, with no indexing.c                 C   "   t t|D ]}| j| q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   rI   addrL   rM   cr   r   r   rJ        zPropKB.tellc                 C   s   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

        )rF   rI   rR   r   r   r   rT   ,  s   z
PropKB.askc                 C   r]   )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   rI   discardr_   r   r   r   rU   >  ra   zPropKB.retractN)rW   rX   rY   rZ   rJ   rT   rU   r   r   r   r   r\     s
    r\   )NFFF)NFr,   )rZ   sympy.logic.boolalgr   r   r   r   r   sympy.core.sortingr   sympy.core.sympifyr   sympy.external.importtoolsr	   r   r(   r*   r?   rF   rG   r\   r   r   r   r   <module>   s    
W

I!