U
    ZÊ¹j#  ã                   @   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ks| dkr| S | j r| S | jr2t| jd ƒS tdƒ‚dS )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.N)Z	is_SymbolZis_NotÚliteral_symbolÚargsÚ
ValueError)Úliteral© r   úT/var/www/html/bwave/python/venv/lib/python3.8/site-packages/sympy/logic/inference.pyr
   	   s    r
   NFc                 C   s@  |r(|dk	r$|dkr$t d|› d�ƒ‚d}|dks8|dkrbtdƒ}|dk	rNd}n|dkr^tdƒ‚d}|dkr~tdƒ}|dkr~d}|d	krštd	ƒ}|dkršd}|d
kr¶ddlm} || ƒS |dkrØddlm} || ||d�S |dkröddlm}	 |	| |ƒS |dk�rddlm	}
 |
| ||ƒS |d	k�r8ddl
m} || |ƒS t‚dS )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

    NZdpll2z2Currently only dpll2 can handle using lra theory. z is not handled.Úpycosatzpycosat module is not presentZ	minisat22ÚpysatÚz3Zdpllr   )Údpll_satisfiable)Úuse_lra_theory)Úpycosat_satisfiable)Úminisat22_satisfiable)Úz3_satisfiable)r   r	   ÚImportErrorZsympy.logic.algorithms.dpllr   Zsympy.logic.algorithms.dpll2Z&sympy.logic.algorithms.pycosat_wrapperr   Z(sympy.logic.algorithms.minisat22_wrapperr   Z!sympy.logic.algorithms.z3_wrapperr   ÚNotImplementedError)ÚexprÚ	algorithmZ
all_modelsZ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„‰| ˆkr,| S t| ƒ} ˆ| ƒsHtd|  ƒ‚|sPi }‡fdd„| ¡ D ƒ}|  |¡}|ˆk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                    s<   t | ˆ ƒs| ˆk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 | ]\}}|ˆ kr||“qS r   r   )r!   ÚkÚv)r(   r   r   Ú
<dictcomp>Ì   s       zpl_true.<locals>.<dictcomp>TFN)Zsympy.core.symbolr   r   r   ÚitemsÚsubsÚboolÚdictÚfromkeysZatomsÚpl_truer   r   )r   ÚmodelÚdeepÚresultr   r'   r   r1   ’   s,    (

r1   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   Zformula_setr   r   r   ÚentailsÛ   s
    
r7   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 r    )ÚsetÚclauses_Útell©ÚselfÚsentencer   r   r   Ú__init__þ   s    zKB.__init__c                 C   s   t ‚d S r    ©r   r<   r   r   r   r;     s    zKB.tellc                 C   s   t ‚d S r    r@   ©r=   Úqueryr   r   r   Úask  s    zKB.askc                 C   s   t ‚d S r    r@   r<   r   r   r   Úretract	  s    z
KB.retractc                 C   s   t t| jƒƒS r    )r5   r   r:   )r=   r   r   r   Úclauses  s    z
KB.clauses)N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r?   r;   rC   rD   ÚpropertyrE   r   r   r   r   r8   ü   s   
r8   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   s"   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   r:   Úadd©r=   r>   Úcr   r   r   r;     s    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

        )r7   r:   rA   r   r   r   rC   ,  s    z
PropKB.askc                 C   s"   t t|ƒƒD ]}| j |¡ q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   r:   ÚdiscardrM   r   r   r   rD   >  s    zPropKB.retractN)rF   rG   rH   rI   r;   rC   rD   r   r   r   r   rK     s   rK   )NFFF)NF)N)rI   Zsympy.logic.boolalgr   r   r   r   r   Zsympy.core.sortingr   Zsympy.core.sympifyr   Zsympy.external.importtoolsr	   r
   r   r   r1   r7   r8   rK   r   r   r   r   Ú<module>   s   
W
I
!