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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy