Skip to content

Commit 33f370e

Browse files
committed
Corrections part 2
1 parent e95dd93 commit 33f370e

File tree

1 file changed

+61
-59
lines changed

1 file changed

+61
-59
lines changed

other/dpll.py

Lines changed: 61 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"""
1010

1111
import random
12+
from typing import List, Dict
1213

1314

1415
class Clause:
@@ -31,15 +32,15 @@ class Clause:
3132
True
3233
"""
3334

34-
def __init__(self, literals):
35+
def __init__(self, literals: List[int]) -> None:
3536
"""
3637
Represent the literals and an assignment in a clause."
3738
"""
3839
# Assign all literals to None initially
3940
self.literals = {literal: None for literal in literals}
4041
self.no_of_literals = len(self.literals)
4142

42-
def __str__(self):
43+
def __str__(self) -> str:
4344
"""
4445
To print a clause as in CNF.
4546
Variable clause holds the string representation.
@@ -53,7 +54,7 @@ def __str__(self):
5354

5455
return clause
5556

56-
def assign(self, model):
57+
def assign(self, model: Dict[str, bool]) -> None:
5758
"""
5859
Assign values to literals of the clause as given by model.
5960
"""
@@ -72,7 +73,7 @@ def assign(self, model):
7273
self.literals[list(self.literals.keys())[i]] = val
7374
i += 1
7475

75-
def evaluate(self, model):
76+
def evaluate(self, model: Dict[str, bool]) -> bool:
7677
"""
7778
Evaluates the clause with the assignments in model.
7879
This has the following steps:
@@ -81,23 +82,21 @@ def evaluate(self, model):
8182
3. Return None(unable to complete evaluation) if a literal has no assignment.
8283
4. Compute disjunction of all values assigned in clause.
8384
"""
84-
for literal in list(self.literals.keys()):
85+
for literal in self.literals:
8586
if len(literal) == 2:
8687
symbol = literal + "'"
87-
if symbol in list(self.literals.keys()):
88+
if symbol in self.literals:
8889
return True
8990
else:
9091
symbol = literal[:2]
91-
if symbol in list(self.literals.keys()):
92+
if symbol in self.literals:
9293
return True
9394

9495
self.assign(model)
9596
result = False
9697
for j in self.literals.values():
97-
if j is True:
98-
return True
99-
elif j is None:
100-
return None
98+
if j in (True, None):
99+
return j
101100
for j in self.literals.values():
102101
result = result or j
103102
return result
@@ -111,37 +110,39 @@ class Formula:
111110
{{A1, A2, A3'}, {A5', A2', A1}} is ((A1 v A2 v A3') and (A5' v A2' v A1))
112111
113112
Create two clauses and a formula with them
114-
>>> c1 = Clause(["A1", "A2'", "A3"])
115-
>>> c2 = Clause(["A5'", "A2'", "A1"])
113+
>>> clause1 = Clause(["A1", "A2'", "A3"])
114+
>>> clause2 = Clause(["A5'", "A2'", "A1"])
116115
117-
>>> f = Formula([c1, c2])
118-
>>> print(f)
119-
{ { A1 , A2' , A3 } , { A5' , A2' , A1 } }
116+
>>> formula = Formula([clause1, clause2])
117+
>>> print(formula)
118+
{{ A1 , A2' , A3 } , { A5' , A2' , A1 }}
120119
"""
121120

122-
def __init__(self, clauses):
121+
def __init__(self, clauses: List[Clause]) -> None:
123122
"""
124123
Represent the number of clauses and the clauses themselves.
125124
"""
126125
self.clauses = [c for c in clauses]
127126
self.no_of_clauses = len(self.clauses)
128127

129-
def __str__(self):
128+
def __str__(self) -> str:
130129
"""
131130
To print a formula as in CNF.
132131
Variable formula holds the string representation.
133132
"""
134-
formula = "{ "
135-
for i in range(0, self.no_of_clauses):
136-
formula += str(self.clauses[i]) + " "
137-
if i != self.no_of_clauses - 1:
138-
formula += ", "
133+
formula = "{"
134+
clause_repr = " , "
135+
clauses_as_strings = [str(clause) for clause in self.clauses]
136+
137+
clause_repr = clause_repr.join(clauses_as_strings)
138+
139+
formula += clause_repr
139140
formula += "}"
140141

141142
return formula
142143

143144

144-
def generate_clause():
145+
def generate_clause() -> Clause:
145146
"""
146147
Randomly generate a clause.
147148
All literals have the name Ax, where x is an integer from 1 to 5.
@@ -161,11 +162,10 @@ def generate_clause():
161162
else:
162163
literals.append(var_name)
163164
i += 1
164-
clause = Clause(literals)
165-
return clause
165+
return Clause(literals)
166166

167167

168-
def generate_formula():
168+
def generate_formula() -> Formula:
169169
"""
170170
Randomly generate a formula.
171171
"""
@@ -179,40 +179,41 @@ def generate_formula():
179179
else:
180180
clauses.append(clause)
181181
i += 1
182-
formula = Formula(set(clauses))
183-
return formula
182+
return Formula(set(clauses))
184183

185184

186-
def generate_parameters(formula):
185+
def generate_parameters(formula: Formula) -> (List[Clause], List[str]):
187186
"""
188187
Return the clauses and symbols from a formula.
189188
A symbol is the uncomplemented form of a literal.
190189
For example,
191190
Symbol of A3 is A3.
192191
Symbol of A5' is A5.
193192
194-
>>> c1 = Clause(["A1", "A2'", "A3"])
195-
>>> c2 = Clause(["A5'", "A2'", "A1"])
193+
>>> clause1 = Clause(["A1", "A2'", "A3"])
194+
>>> clause2 = Clause(["A5'", "A2'", "A1"])
196195
197-
>>> f = Formula([c1, c2])
198-
>>> c, s = generate_parameters(f)
199-
>>> l = [str(i) for i in c]
200-
>>> print(l)
196+
>>> formula = Formula([clause1, clause2])
197+
>>> clauses, symbols = generate_parameters(formula)
198+
>>> clauses_list = [str(i) for i in clauses]
199+
>>> print(clauses_list)
201200
["{ A1 , A2' , A3 }", "{ A5' , A2' , A1 }"]
202-
>>> print(s)
201+
>>> print(symbols)
203202
['A1', 'A2', 'A3', 'A5']
204203
"""
205204
clauses = formula.clauses
206205
symbols_set = []
207206
for clause in formula.clauses:
208-
for literal in clause.literals.keys():
207+
for literal in clause.literals:
209208
symbol = literal[:2]
210209
if symbol not in symbols_set:
211210
symbols_set.append(symbol)
212211
return clauses, symbols_set
213212

214213

215-
def find_pure_symbols(clauses, symbols, model):
214+
def find_pure_symbols(
215+
clauses: List[Clause], symbols: List[str], model: Dict[str, bool]
216+
) -> (List[str], Dict[str, bool]):
216217
"""
217218
Return pure symbols and their values to satisfy clause.
218219
Pure symbols are symbols in a formula that exist only
@@ -226,15 +227,15 @@ def find_pure_symbols(clauses, symbols, model):
226227
3. Assign value True or False depending on whether the symbols occurs
227228
in normal or complemented form respectively.
228229
229-
>>> c1 = Clause(["A1", "A2'", "A3"])
230-
>>> c2 = Clause(["A5'", "A2'", "A1"])
230+
>>> clause1 = Clause(["A1", "A2'", "A3"])
231+
>>> clause2 = Clause(["A5'", "A2'", "A1"])
231232
232-
>>> f = Formula([c1, c2])
233-
>>> c, s = generate_parameters(f)
233+
>>> formula = Formula([clause1, clause2])
234+
>>> clauses, symbols = generate_parameters(formula)
234235
235236
>>> model = {}
236-
>>> p, v = find_pure_symbols(c, s, model)
237-
>>> print(p, v)
237+
>>> pure_symbols, values = find_pure_symbols(clauses, symbols, model)
238+
>>> print(pure_symbols, values)
238239
['A1', 'A2', 'A3', 'A5'] {'A1': True, 'A2': False, 'A3': True, 'A5': False}
239240
"""
240241
pure_symbols = []
@@ -244,7 +245,7 @@ def find_pure_symbols(clauses, symbols, model):
244245
for clause in clauses:
245246
if clause.evaluate(model) is True:
246247
continue
247-
for literal in clause.literals.keys():
248+
for literal in clause.literals:
248249
literals.append(literal)
249250

250251
for s in symbols:
@@ -264,7 +265,9 @@ def find_pure_symbols(clauses, symbols, model):
264265
return pure_symbols, assignment
265266

266267

267-
def find_unit_clauses(clauses, model):
268+
def find_unit_clauses(
269+
clauses: List[Clause], model: Dict[str, bool]
270+
) -> (List[str], Dict[str, bool]):
268271
"""
269272
Returns the unit symbols and their values to satisfy clause.
270273
Unit symbols are symbols in a formula that are:
@@ -276,17 +279,17 @@ def find_unit_clauses(clauses, model):
276279
3. Assign True or False depending on whether the symbols occurs in
277280
normal or complemented form respectively.
278281
279-
>>> c1 = Clause(["A4", "A3", "A5'", "A1", "A3'"])
280-
>>> c2 = Clause(["A4"])
281-
>>> c3 = Clause(["A3"])
282+
>>> clause1 = Clause(["A4", "A3", "A5'", "A1", "A3'"])
283+
>>> clause2 = Clause(["A4"])
284+
>>> clause3 = Clause(["A3"])
282285
283-
>>> f = Formula([c1, c2, c3])
284-
>>> c, s = generate_parameters(f)
286+
>>> formula = Formula([clause1, clause2, clause3])
287+
>>> clauses, symbols = generate_parameters(formula)
285288
286289
>>> model = {}
287-
>>> u, v = find_unit_clauses(c, model)
290+
>>> unit_clauses, values = find_unit_clauses(clauses, model)
288291
289-
>>> print(u, v)
292+
>>> print(unit_clauses, values)
290293
['A4', 'A3'] {'A4': True, 'A3': True}
291294
"""
292295
unit_symbols = []
@@ -306,16 +309,15 @@ def find_unit_clauses(clauses, model):
306309
assignment = dict()
307310
for i in unit_symbols:
308311
symbol = i[:2]
309-
if len(i) == 2:
310-
assignment[symbol] = True
311-
else:
312-
assignment[symbol] = False
312+
assignment[symbol] = len(i) == 2
313313
unit_symbols = [i[:2] for i in unit_symbols]
314314

315315
return unit_symbols, assignment
316316

317317

318-
def dpll_algorithm(clauses, symbols, model):
318+
def dpll_algorithm(
319+
clauses: List[Clause], symbols: List[str], model: Dict[str, bool]
320+
) -> (bool, Dict[str, bool]):
319321
"""
320322
Returns the model if the formula is satisfiable, else None
321323
This has the following steps:

0 commit comments

Comments
 (0)