def dpll(clauses, symbols, model): """See if the clauses are true in a partial model. http://en.wikipedia.org/wiki/DPLL_algorithm """ unknown_clauses = [] ## clauses with an unknown truth value for c in clauses: val = pl_true(c, model) if val == False: return False if val != True: unknown_clauses.append(c) if not unknown_clauses: return model P, value = find_pure_symbol(symbols, unknown_clauses) if P: model_1 = model.copy() model_1.update({P: value}) syms = [x for x in symbols if x != P] return dpll(clauses, syms, model_1) P, value = find_unit_clause(unknown_clauses, model) if P: model_1 = model.copy() model_1.update({P: value}) syms = [x for x in symbols if x != P] return dpll(clauses, syms, model_1) P = symbols.pop() model_1, model_2 = model.copy(), model.copy() model_1.update({P: True}) model_2.update({P: False}) return dpll(clauses, symbols, model_1) or dpll(clauses, symbols, model_2)
def dpll(clauses, symbols, model): """ 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 """ # compute DP kernel P, value = find_unit_clause(clauses, model) while P: model.update({P: value}) symbols.remove(P) if not value: P = ~P clauses = unit_propagate(clauses, P) P, value = find_unit_clause(clauses, model) P, value = find_pure_symbol(symbols, clauses) while P: model.update({P: value}) symbols.remove(P) if not value: P = ~P clauses = unit_propagate(clauses, P) P, value = find_pure_symbol(symbols, clauses) # end DP kernel unknown_clauses = [] for c in clauses: val = pl_true(c, model) if val is False: return False if val is not True: unknown_clauses.append(c) if not unknown_clauses: return model if not clauses: return model P = symbols.pop() model_copy = model.copy() model.update({P: True}) model_copy.update({P: False}) symbols_copy = symbols[:] return dpll(unit_propagate(unknown_clauses, P), symbols, model) or dpll( unit_propagate(unknown_clauses, Not(P)), symbols_copy, model_copy )
def dpll(clauses, symbols, model): """ 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 """ # compute DP kernel P, value = find_unit_clause(clauses, model) while P: model.update({P: value}) symbols.remove(P) if not value: P = ~P clauses = unit_propagate(clauses, P) P, value = find_unit_clause(clauses, model) P, value = find_pure_symbol(symbols, clauses) while P: model.update({P: value}) symbols.remove(P) if not value: P = ~P clauses = unit_propagate(clauses, P) P, value = find_pure_symbol(symbols, clauses) # end DP kernel unknown_clauses = [] for c in clauses: val = pl_true(c, model) if val is False: return False if val is not True: unknown_clauses.append(c) if not unknown_clauses: return model if not clauses: return model P = symbols.pop() model_copy = model.copy() model.update({P: True}) model_copy.update({P: False}) symbols_copy = symbols[:] return (dpll(unit_propagate(unknown_clauses, P), symbols, model) or dpll( unit_propagate(unknown_clauses, Not(P)), symbols_copy, model_copy))
def dpll(clauses, symbols, model): """ Compute satisfiability in a partial model. Clauses is an array of conjuncts. >>> from sympy import symbols >>> A, B, C = symbols('A B C') >>> dpll([A, B, C], [A, B], {C: False}) False """ # compute DP kernel P, value = find_unit_clause(clauses, model) while P: model.update({P: value}) symbols.remove(P) if not value: P = ~P clauses = unit_propagate(clauses, P) P, value = find_unit_clause(clauses, model) P, value = find_pure_symbol(symbols, clauses) while P: model.update({P: value}) symbols.remove(P) if not value: P = ~P clauses = unit_propagate(clauses, P) P, value = find_pure_symbol(symbols, clauses) # end DP kernel unknown_clauses = [] for c in clauses: val = pl_true(c, model) if val == False: return False if val != True: unknown_clauses.append(c) if not unknown_clauses: return model if not clauses: return model P = symbols.pop() model_copy = model.copy() model.update({P: True}) model_copy.update({P: False}) symbols_copy = symbols[:] return (dpll(clauses, symbols, model) or dpll(clauses, symbols_copy, model_copy))
def dpll(clauses, symbols, model): """Compute satisfiability in a partial model""" # compute DP kernel P, value = find_unit_clause(clauses, model) while P: model.update({P: value}) assert P in model symbols.remove(P) if not value: P = ~P clauses = unit_propagate(clauses, P) P, value = find_unit_clause(clauses, model) P, value = find_pure_symbol(symbols, clauses) while P: model.update({P: value}) symbols.remove(P) if not value: P = ~P clauses = unit_propagate(clauses, P) P, value = find_pure_symbol(symbols, clauses) # end DP kernel unknown_clauses = [] for c in clauses: val = pl_true(c, model) if val == False: return False if val != True: unknown_clauses.append(c) if not unknown_clauses: return model if not clauses: return model P = symbols.pop() model_copy = model.copy() model.update({P: True}) model_copy.update({P: False}) symbols_copy = symbols[:] return (dpll(clauses, symbols, model) or dpll(clauses, symbols_copy, model_copy))
def test_pl_true_wrong_input(): from sympy import pi raises(ValueError, lambda: pl_true('John Cleese')) raises(ValueError, lambda: pl_true(42 + pi + pi ** 2)) raises(ValueError, lambda: pl_true(42))
def test_pl_true(): A, B, C = symbols('A,B,C') assert pl_true(True) is True assert pl_true( A & B, {A: True, B: True}) is True assert pl_true( A | B, {A: True}) is True assert pl_true( A | B, {B: True}) is True assert pl_true( A | B, {A: None, B: True}) is True assert pl_true( A >> B, {A: False}) is True assert pl_true( A | B | ~C, {A: False, B: True, C: True}) is True assert pl_true(Equivalent(A, B), {A: False, B: False}) is True # test for false assert pl_true(False) is False assert pl_true( A & B, {A: False, B: False}) is False assert pl_true( A & B, {A: False}) is False assert pl_true( A & B, {B: False}) is False assert pl_true( A | B, {A: False, B: False}) is False #test for None assert pl_true(B, {B: None}) is None assert pl_true( A & B, {A: True, B: None}) is None assert pl_true( A >> B, {A: True, B: None}) is None assert pl_true(Equivalent(A, B), {A: None}) is None assert pl_true(Equivalent(A, B), {A: True, B: None}) is None
def test_pl_true_wrong_input(): from sympy import pi raises(ValueError, lambda: pl_true('John Cleese')) raises(ValueError, lambda: pl_true(42 + pi + pi**2)) raises(ValueError, lambda: pl_true(42))
def test_pl_true(): A, B, C = symbols('A,B,C') assert pl_true(True) is True assert pl_true(A & B, {A: True, B: True}) is True assert pl_true(A | B, {A: True}) is True assert pl_true(A | B, {B: True}) is True assert pl_true(A | B, {A: None, B: True}) is True assert pl_true(A >> B, {A: False}) is True assert pl_true(A | B | ~C, {A: False, B: True, C: True}) is True assert pl_true(Equivalent(A, B), {A: False, B: False}) is True # test for false assert pl_true(False) is False assert pl_true(A & B, {A: False, B: False}) is False assert pl_true(A & B, {A: False}) is False assert pl_true(A & B, {B: False}) is False assert pl_true(A | B, {A: False, B: False}) is False #test for None assert pl_true(B, {B: None}) is None assert pl_true(A & B, {A: True, B: None}) is None assert pl_true(A >> B, {A: True, B: None}) is None assert pl_true(Equivalent(A, B), {A: None}) is None assert pl_true(Equivalent(A, B), {A: True, B: None}) is None # Test for deep assert pl_true(A | B, {A: False}, deep=True) is None assert pl_true(~A & ~B, {A: False}, deep=True) is None assert pl_true(A | B, {A: False, B: False}, deep=True) is False assert pl_true(A & B & (~A | ~B), {A: True}, deep=True) is False assert pl_true((C >> A) >> (B >> A), {C: True}, deep=True) is True
def test_pl_true(): A, B, C = symbols('A,B,C') assert pl_true(True) is True assert pl_true(A & B, {A: True, B: True}) is True assert pl_true(A | B, {A: True}) is True assert pl_true(A | B, {B: True}) is True assert pl_true(A | B, {A: None, B: True}) is True assert pl_true(A >> B, {A: False}) is True assert pl_true(A | B | ~C, {A: False, B: True, C: True}) is True assert pl_true(Equivalent(A, B), {A: False, B: False}) is True # test for false assert pl_true(False) is False assert pl_true(A & B, {A: False, B: False}) is False assert pl_true(A & B, {A: False}) is False assert pl_true(A & B, {B: False}) is False assert pl_true(A | B, {A: False, B: False}) is False #test for None assert pl_true(B, {B: None}) is None assert pl_true(A & B, {A: True, B: None}) is None assert pl_true(A >> B, {A: True, B: None}) is None assert pl_true(Equivalent(A, B), {A: None}) is None assert pl_true(Equivalent(A, B), {A: True, B: None}) is None
def test_pl_true(): A, B, C = symbols('A,B,C') assert pl_true(True) is True assert pl_true( A & B, {A: True, B: True}) is True assert pl_true( A | B, {A: True}) is True assert pl_true( A | B, {B: True}) is True assert pl_true( A | B, {A: None, B: True}) is True assert pl_true( A >> B, {A: False}) is True assert pl_true( A | B | ~C, {A: False, B: True, C: True}) is True assert pl_true(Equivalent(A, B), {A: False, B: False}) is True # test for false assert pl_true(False) is False assert pl_true( A & B, {A: False, B: False}) is False assert pl_true( A & B, {A: False}) is False assert pl_true( A & B, {B: False}) is False assert pl_true( A | B, {A: False, B: False}) is False #test for None assert pl_true(B, {B: None}) is None assert pl_true( A & B, {A: True, B: None}) is None assert pl_true( A >> B, {A: True, B: None}) is None assert pl_true(Equivalent(A, B), {A: None}) is None assert pl_true(Equivalent(A, B), {A: True, B: None}) is None # Test for deep assert pl_true(A | B, {A: False}, deep=True) is None assert pl_true(~A & ~B, {A: False}, deep=True) is None assert pl_true(A | B, {A: False, B: False}, deep=True) is False assert pl_true(A & B & (~A | ~B), {A: True}, deep=True) is False assert pl_true((C >> A) >> (B >> A), {C: True}, deep=True) is True