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 test_find_pure_symbol(): A, B, C = symbols('ABC') assert find_pure_symbol([A], [A]) == (A, True) assert find_pure_symbol([A, B], [~A | B, ~B | A]) == (None, None) assert find_pure_symbol([A, B, C], [ A | ~B, ~B | ~C, C | A]) == (A, True) assert find_pure_symbol([A, B, C], [~A | B, B | ~C, C | A]) == (B, True) assert find_pure_symbol([A, B, C], [~A | ~B, ~B | ~C, C | A]) == (B, False) assert find_pure_symbol([A, B, C], [~A | B, ~B | ~C, C | A]) == (None, None)