def dpll(clauses, symbols, model): """ Compute satisfiability in a partial model. Clauses is an array of conjuncts. >>> from diofant.abc import A, B, D >>> from diofant.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 test_pl_true_wrong_input(): pytest.raises(ValueError, lambda: pl_true('John Cleese')) pytest.raises(ValueError, lambda: pl_true(42 + pi + pi ** 2)) pytest.raises(ValueError, lambda: pl_true(42))
def test_pl_true(): 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_wrong_input(): from diofant import pi pytest.raises(ValueError, lambda: pl_true('John Cleese')) pytest.raises(ValueError, lambda: pl_true(42 + pi + pi ** 2)) pytest.raises(ValueError, lambda: pl_true(42))
def test_pl_true(): 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 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 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 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 pytest.raises(ValueError, lambda: pl_true('John Cleese')) pytest.raises(ValueError, lambda: pl_true(42 + pi)) pytest.raises(ValueError, lambda: pl_true(42))