K i#dZddlmZddlmZmZmZmZmZm Z m Z ddl m Z ddl mZmZdZdZdZifd Zd Zd Zd Zd ZdZdZy)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)OrNot conjuncts disjunctsto_cnf to_int_repr_find_predicates)CNF)pl_trueliteral_symbolclt|tstt|}n |j}d|vryt t |t}ttdt|dz}t||}t||i}|s|Si}|D]}|j||dz ||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 rrclausessortedr rsetrangelenr dpll_int_reprupdate)exprrsymbolssymbols_int_reprclauses_int_reprresultoutputrs a/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/logic/algorithms/dpll.pydpll_satisfiabler s dC F4L),, %d+1ABG5CL1$456"7G4 +-=r BF  F7 wsQw'567 Mct||\}}|rG|j||i|j||s|}t||}t||\}}|rGt ||\}}|rG|j||i|j||s|}t||}t ||\}}|rGg}|D]*}t ||}|dury|dus|j |,|s|S|s|S|j}|j}|j|di|j|di|dd} tt||||xs tt|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_clauserremoveunit_propagatefind_pure_symbolr appendpopcopydpllr rrmodelPvalueunknown_clausescval model_copy symbols_copys rr*r*1s /HAu  aZ qA !,#GU35  1HAu  aZ qA !,#GW55 O &a %< d?  " "1 % &    AJ LL!Tq%j!1:L 3We D T Q8, SUr!ct||\}}|rG|j||i|j||s| }t||}t||\}}|rGt ||\}}|rG|j||i|j||s| }t||}t ||\}}|rGg}|D]*}t ||}|dury|dus|j |,|s|S|j}|j}|j|di|j|di|j} tt||||xstt|| | |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_reprrr$unit_propagate_int_reprfind_pure_symbol_int_reprpl_true_int_reprr'r(r)rr+s rrrbs)%8HAu  aZ qA)'15,We<5 )':HAu  aZ qA)'15,Wg>5 O &q%( %< d?  " "1 % &   AJ LL!Tq%j!<<>L 1/1EwPU V b 1/A2F V` acr!cd}|D];}|dkr|j| }|| }n|j|}|dury|:d}=|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 FrNT)get)clauser,rlitps rr8r8sbF  7 3$A}E #A 9 YF  Mr!c :g}|D]}|jtk7r|j|(|jD]G}||k(r8|jt|jDcgc] }||k7s | c}u||k(sG}|j||Scc}w)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] )funcrr'args)rsymbolrr0argxs rr%r%s"F   66R< MM!  66 Cvg~ baff"EfW 1"EFGf}   MM!   M #Fs B,BcD| h}|Dcgc] }||vs||z c}Scc}w)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}] )rsnegatedr;s rr6r6s,rdG+2 FavoFW  FF Fs c|D]F}d\}}|D]/}|s|t|vrd}|rt|t|vs.d}1||k7sB||fcSy)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) )FFTNN)rr)rr/sym found_pos found_negr0s rr&r&so"+ 9  !A ! !4 SYq\!9  !  ! > !" r!ctj|}|j|}|j|Dcgc]}| c}}|D] }| |vs |dfcS|D]}| |vs | dfcSycc}w)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) TFrI)runion intersection)rr/ all_symbolsrKrFrLr=s rr7r7s#%++/K((1I((g)>1")>?I  2Y d7N 2Y 2u9  *?s A/c|D]G}d}t|D]*}t|}||vs|dz }|t|t }},|dk(sCfcSy)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) rrrI)rr rr)rr,r;num_not_in_modelliteralrJr-r.s rr#r# su ( =G )C% A% Jw$< <5  = q e8O r!ct||Dchc]}| c}z}|D]7}||z }t|dk(s|j}|dkr| dfcS|dfcSycc}w)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) rrFTrI)rrr()rr,rJboundr;unboundr=s rr5r5 st J%033$0 0E5. w<1  A1ur5y $w 1s AN)__doc__sympy.core.sortingrsympy.logic.boolalgrrrrrr r sympy.assumptions.cnfr sympy.logic.inferencer r r r*rr8r%r6r&r7r#r5rEr!rr\sa0"""%9>.Ub+c`$&6B G..,r!