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_unit_clause(): A, B, C = symbols('ABC') assert find_unit_clause([A], {}) == (A, True) assert find_unit_clause([A | B], {A: True}) == (B, True) assert find_unit_clause([A | B], {B: True}) == (A, True) assert find_unit_clause([A | B | C, B | ~C, A | ~B], {A:True}) == (B, False) assert find_unit_clause([A | B | C, B | ~C, A | B], {A:True}) == (B, True) assert find_unit_clause([A | B | C, B | ~C, A ], {}) == (A, True)