-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkb.py
More file actions
58 lines (43 loc) · 1.9 KB
/
kb.py
File metadata and controls
58 lines (43 loc) · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
from kb_parser import conjuncts, to_cnf, is_definite_clause
from utils import first
class KB:
def __init__(self, sentence=None):
if sentence:
self.tell(sentence)
def tell(self, sentence):
"""Add the sentence to the KB."""
raise NotImplementedError
def ask(self, query):
"""Return a substitution that makes the query true, or, failing that, return False."""
return first(self.ask_generator(query), default=False)
def ask_generator(self, query):
"""Yield all the substitutions that make query true."""
raise NotImplementedError
def retract(self, sentence):
"""Remove sentence from the KB."""
raise NotImplementedError
class PropKB(KB):
"""A KB for propositional logic. Inefficient, with no indexing."""
def __init__(self, sentence=None):
super().__init__(sentence)
self.clauses = []
def tell(self, sentence):
"""Add the sentence's clauses to the KB."""
self.clauses.extend(conjuncts(to_cnf(sentence)))
def retract(self, sentence):
"""Remove the sentence's clauses from the KB."""
for c in conjuncts(to_cnf(sentence)):
if c in self.clauses:
self.clauses.remove(c)
class PropDefiniteKB(PropKB):
"""A KB of propositional definite clauses."""
def tell(self, sentence):
"""Add a definite clause to this KB."""
assert is_definite_clause(sentence), "Must be definite clause"
self.clauses.append(sentence)
def clauses_with_premise(self, p):
"""Return a list of the clauses in KB that have p in their premise."""
return [c for c in self.clauses if c.op == '==>' and p in conjuncts(c.args[0])]
def clauses_with_goal(self, p):
"""Return a list of the clauses in KB that have p as their goal."""
return [c for c in self.clauses if c.op == '==>' and p in conjuncts(c.args[1])]