Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f7a1202

Browse files
committed
Fix issue 35
1 parent 03e6861 commit f7a1202

File tree

1 file changed

+41
-20
lines changed

1 file changed

+41
-20
lines changed

logic.py

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ def parse_definite_clause(s):
309309

310310
## Useful constant Exprs used in examples and code:
311311
TRUE, FALSE, ZERO, ONE, TWO = map(Expr, ['TRUE', 'FALSE', 0, 1, 2])
312-
A, B, C, F, G, P, Q, x, y, z = map(Expr, 'ABCFGPQxyz')
312+
A, B, C, D, E, F, G, P, Q, x, y, z = map(Expr, 'ABCDEFGPQxyz')
313313

314314
#______________________________________________________________________________
315315

@@ -683,33 +683,50 @@ def find_pure_symbol(symbols, clauses):
683683
return None, None
684684

685685
def find_unit_clause(clauses, model):
686-
"""A unit clause has only 1 variable that is not bound in the model.
687-
>>> find_unit_clause([A|B|C, B|~C, A|~B], {A:True})
686+
"""Find a forced assignment if possible from a clause with only 1
687+
variable not bound in the model.
688+
>>> find_unit_clause([A|B|C, B|~C, ~A|~B], {A:True})
688689
(B, False)
689690
"""
690691
for clause in clauses:
691-
num_not_in_model = 0
692-
for literal in disjuncts(clause):
693-
sym = literal_symbol(literal)
694-
if sym not in model:
695-
num_not_in_model += 1
696-
P, value = sym, (literal.op != '~')
697-
if num_not_in_model == 1:
698-
return P, value
692+
P, value = unit_clause_assign(clause, model)
693+
if P: return P, value
699694
return None, None
700695

701-
702-
def literal_symbol(literal):
703-
"""The symbol in this literal (without the negation).
704-
>>> literal_symbol(P)
705-
P
706-
>>> literal_symbol(~P)
707-
P
696+
def unit_clause_assign(clause, model):
697+
"""Return a single variable/value pair that makes clause true in
698+
the model, if possible.
699+
>>> unit_clause_assign(A|B|C, {A:True})
700+
(None, None)
701+
>>> unit_clause_assign(B|~C, {A:True})
702+
(None, None)
703+
>>> unit_clause_assign(~A|~B, {A:True})
704+
(B, False)
705+
"""
706+
P, value = None, None
707+
for literal in disjuncts(clause):
708+
sym, positive = inspect_literal(literal)
709+
if sym in model:
710+
if model[sym] == positive:
711+
return None, None # clause already True
712+
elif P:
713+
return None, None # more than 1 unbound variable
714+
else:
715+
P, value = sym, positive
716+
return P, value
717+
718+
def inspect_literal(literal):
719+
"""The symbol in this literal, and the value it should take to
720+
make the literal true.
721+
>>> inspect_literal(P)
722+
(P, True)
723+
>>> inspect_literal(~P)
724+
(P, False)
708725
"""
709726
if literal.op == '~':
710-
return literal.args[0]
727+
return literal.args[0], False
711728
else:
712-
return literal
729+
return literal, True
713730

714731
#______________________________________________________________________________
715732
# Walk-SAT [Fig. 7.18]
@@ -1153,6 +1170,10 @@ class logicTest: """
11531170
>>> tt_true(A & B)
11541171
False
11551172
1173+
### An earlier version of the code failed on this:
1174+
>>> dpll_satisfiable(A & ~B & C & (A | ~D) & (~E | ~D) & (C | ~D) & (~A | ~F) & (E | ~F) & (~D | ~F) & (B | ~C | D) & (A | ~E | F) & (~A | E | D))
1175+
{B: False, C: True, A: True, F: False, D: True, E: False}
1176+
11561177
### [Fig. 7.13]
11571178
>>> alpha = expr("~P12")
11581179
>>> to_cnf(Fig[7,13] & ~alpha)

0 commit comments

Comments
 (0)