
    g#                         d Z ddlmZ ddlmZmZmZmZmZm	Z	m
Z
 ddlmZ ddlmZmZ d Zd Zd Zi fd	Zd
 Zd Zd Zd Zd Zd ZdS )a&  Implementation of DPLL algorithm

Further improvements: eliminate calls to pl_true, implement branching rules,
efficient unit propagation.

References:
  - https://en.wikipedia.org/wiki/DPLL_algorithm
  - https://www.researchgate.net/publication/242384772_Implementations_of_the_DPLL_Algorithm
    )default_sort_key)OrNot	conjuncts	disjunctsto_cnfto_int_repr_find_predicates)CNF)pl_trueliteral_symbolc                    t          | t                    st          t          |                     }n| j        }d|v rdS t          t          |           t                    }t          t          dt          |          dz                       }t          ||          }t          ||i           }|s|S i }|D ](}|                    ||dz
           ||         i           )|S )a>  
    Check satisfiability of a propositional sentence.
    It returns a model rather than True when it succeeds

    >>> from sympy.abc import A, B
    >>> from sympy.logic.algorithms.dpll import dpll_satisfiable
    >>> dpll_satisfiable(A & ~B)
    {A: True, B: False}
    >>> dpll_satisfiable(A & ~A)
    False

    F)key   )
isinstancer   r   r   clausessortedr
   r   setrangelenr	   dpll_int_reprupdate)exprr   symbolssymbols_int_reprclauses_int_reprresultoutputr   s           W/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/logic/algorithms/dpll.pydpll_satisfiabler       s     dC   F4LL)),u%d++1ABBBG5CLL1$45566"7G44+-=rBBF F 7 7wsQw'56666M    c                    t          | |          \  }}|rV|                    ||i           |                    |           |s| }t          | |          } t          | |          \  }}|Vt	          ||           \  }}|rV|                    ||i           |                    |           |s| }t          | |          } t	          ||           \  }}|Vg }| D ]2}t          ||          }|du r dS |dur|                    |           3|s|S | s|S |                                }|                                }|                    |di           |                    |di           |dd         }	t          t          ||          ||          p+t          t          |t          |                    |	|          S )z
    Compute satisfiability in a partial model.
    Clauses is an array of conjuncts.

    >>> from sympy.abc import A, B, D
    >>> from sympy.logic.algorithms.dpll import dpll
    >>> dpll([A, B, D], [A, B], {D: False})
    False

    FTN)find_unit_clauser   removeunit_propagatefind_pure_symbolr   appendpopcopydpllr   
r   r   modelPvalueunknown_clausescval
model_copysymbols_copys
             r   r*   r*   1   s     //HAu
 4aZ   q 	A !,,#GU335  4  11HAu
 6aZ   q 	A !,,#GW555  6 O & &a%<<55d??""1%%%  AJ	LL!Tq%j!!!111:L33WeDD TQ88,
SSUr!   c                 v   t          | |          \  }}|rV|                    ||i           |                    |           |s| }t          | |          } t          | |          \  }}|Vt	          ||           \  }}|rV|                    ||i           |                    |           |s| }t          | |          } t	          ||           \  }}|Vg }| D ]2}t          ||          }|du r dS |dur|                    |           3|s|S |                                }|                                }|                    |di           |                    |di           |                                }	t          t          ||          ||          pt          t          ||           |	|          S )z
    Compute satisfiability in a partial model.
    Arguments are expected to be in integer representation

    >>> from sympy.logic.algorithms.dpll import dpll_int_repr
    >>> dpll_int_repr([{1}, {2}, {3}], {1, 2}, {3: False})
    False

    FT)
find_unit_clause_int_reprr   r$   unit_propagate_int_reprfind_pure_symbol_int_reprpl_true_int_reprr'   r(   r)   r   r+   s
             r   r   r   b   s    )%88HAu
 =aZ   q 	A)'155,We<<5  = )'::HAu
 ?aZ   q 	A)'155,Wg>>5  ? O & &q%((%<<55d??""1%%% AJ	LL!Tq%j!!!<<>>L1/1EEwPUVV b1/A2FFV`aacr!   c                     d}| D ]D}|dk     r|                     |           }|| }n|                     |          }|du r dS |d}E|S )af  
    Lightweight version of pl_true.
    Argument clause represents the set of args of an Or clause. This is used
    inside dpll_int_repr, it is not meant to be used directly.

    >>> from sympy.logic.algorithms.dpll import pl_true_int_repr
    >>> pl_true_int_repr({1, 2}, {1: False})
    >>> pl_true_int_repr({1, 2}, {1: False, 2: False})
    False

    Fr   NT)get)clauser,   r   litps        r   r8   r8      sn     F 
 
77		3$A}E		#A9944YFMr!   c                    g }| D ]}|j         t          k    r|                    |           (|j        D ]@}| k    r/|                    t          fd|j        D                          n|k    r nA|                    |           |S )a  
    Returns an equivalent set of clauses
    If a set of clauses contains the unit clause l, the other clauses are
    simplified by the application of the two following rules:

      1. every clause containing l is removed
      2. in every clause that contains ~l this literal is deleted

    Arguments are expected to be in CNF.

    >>> from sympy.abc import A, B, D
    >>> from sympy.logic.algorithms.dpll import unit_propagate
    >>> unit_propagate([A | B, D | ~B, B], B)
    [D, B]

    c                 "    g | ]}| k    	|S  r@   ).0xsymbols     r   
<listcomp>z"unit_propagate.<locals>.<listcomp>   s     "E"E"EfW1r!   )funcr   r'   args)r   rC   r   r0   args    `   r   r%   r%      s    " F  6R<<MM!6 	 	Cvg~~b"E"E"E"Eaf"E"E"EFGGGf}}  MM!Mr!   c                 ,     hfd| D             S )z
    Same as unit_propagate, but arguments are expected to be in integer
    representation

    >>> from sympy.logic.algorithms.dpll import unit_propagate_int_repr
    >>> unit_propagate_int_repr([{1, 2}, {3, -2}, {2}], 2)
    [{3}]

    c                 "    g | ]}|v|z
  S r@   r@   )rA   r;   negatedss     r   rD   z+unit_propagate_int_repr.<locals>.<listcomp>   s#    FFFavooFWooor!   r@   )r   rK   rJ   s    `@r   r6   r6      s,     rdGFFFFF7FFFFr!   c                     | D ]O}d\  }}|D ]9}|s|t          |          v rd}|s t          |          t          |          v rd}:||k    r||fc S PdS )a#  
    Find a symbol and its value if it appears only as a positive literal
    (or only as a negative) in clauses.

    >>> from sympy.abc import A, B, D
    >>> from sympy.logic.algorithms.dpll import find_pure_symbol
    >>> find_pure_symbol([A, B, D], [A|~B,~B|~D,D|A])
    (A, True)

    )FFTNN)r   r   )r   r/   sym	found_pos	found_negr0   s         r   r&   r&      s      " "+	9  	! 	!A !	!!4!4 	 !SYq\\!9!9 		!!	>!!! ":r!   c                      t                      j        | }|                    |           }|                    d | D                       }|D ]}| |vr|dfc S |D ]}| |vr| dfc S dS )a  
    Same as find_pure_symbol, but arguments are expected
    to be in integer representation

    >>> from sympy.logic.algorithms.dpll import find_pure_symbol_int_repr
    >>> find_pure_symbol_int_repr({1,2,3},
    ...     [{1, -2}, {-2, -3}, {3, 1}])
    (1, True)

    c                     g | ]}| S r@   r@   )rA   rK   s     r   rD   z-find_pure_symbol_int_repr.<locals>.<listcomp>   s    )>)>)>1")>)>)>r!   TFrM   )r   unionintersection)r   r/   all_symbolsrO   rP   r=   s         r   r7   r7      s     #%%+/K((11I(()>)>g)>)>)>??I  2Yd7NNN   2Y2u9 :r!   c                     | D ]R}d}t          |          D ]2}t          |          }||vr|dz  }|t          |t                     }}3|dk    r||fc S SdS )a  
    A unit clause has only 1 variable that is not bound in the model.

    >>> from sympy.abc import A, B, D
    >>> from sympy.logic.algorithms.dpll import find_unit_clause
    >>> find_unit_clause([A | B | D, B | ~D, A | ~B], {A:True})
    (B, False)

    r   r   rM   )r   r   r   r   )r   r,   r;   num_not_in_modelliteralrN   r-   r.   s           r   r#   r#   
  s        (( 	= 	=G ))C% A% Jw$<$< <5q  e8OOO !:r!   c                     t          |          d |D             z  }| D ]A}||z
  }t          |          dk    r'|                                }|dk     r| dfc S |dfc S BdS )a  
    Same as find_unit_clause, but arguments are expected to be in
    integer representation.

    >>> from sympy.logic.algorithms.dpll import find_unit_clause_int_repr
    >>> find_unit_clause_int_repr([{1, 2, 3},
    ...     {2, -3}, {1, -2}], {1: True})
    (2, False)

    c                     h | ]}| S r@   r@   )rA   rN   s     r   	<setcomp>z,find_unit_clause_int_repr.<locals>.<setcomp>+  s    00033$000r!   r   r   FTrM   )r   r   r(   )r   r,   boundr;   unboundr=   s         r   r5   r5      s     JJ00%0000E  5.w<<1A1uur5y   $w  :r!   N)__doc__sympy.core.sortingr   sympy.logic.boolalgr   r   r   r   r   r	   r
   sympy.assumptions.cnfr   sympy.logic.inferencer   r   r    r*   r   r8   r%   r6   r&   r7   r#   r5   r@   r!   r   <module>rc      s]    0 / / / / /" " " " " " " " " " " " " " " " " " % % % % % % 9 9 9 9 9 9 9 9  >.U .U .Ub+c +c +c` $&    6  BG G G  .  .  ,    r!   