Skip to content

Commit 940f0c9

Browse files
Chipe1norvig
authored andcommitted
Tests for fol_fc_ask() (aimacode#543)
* Added test for fol_fc_ask() * Optimization of fol_fc_ask() * Faster fol_fc_ask() * Removed subst for rules in KB
1 parent 235d012 commit 940f0c9

File tree

2 files changed

+26
-16
lines changed

2 files changed

+26
-16
lines changed

logic.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -914,11 +914,11 @@ def fetch_rules_for_goal(self, goal):
914914
def fol_fc_ask(KB, alpha):
915915
"""A simple forward-chaining algorithm. [Figure 9.3]"""
916916
# TODO: Improve efficiency
917-
def enum_subst(KB):
918-
kb_vars = list({v for clause in KB.clauses for v in variables(clause)})
919-
kb_consts = list({c for clause in KB.clauses for c in constant_symbols(clause)})
920-
for assignment_list in itertools.product(kb_consts, repeat=len(kb_vars)):
921-
theta = {x: y for x, y in zip(kb_vars, assignment_list)}
917+
kb_consts = list({c for clause in KB.clauses for c in constant_symbols(clause)})
918+
def enum_subst(p):
919+
query_vars = list({v for clause in p for v in variables(clause)})
920+
for assignment_list in itertools.product(kb_consts, repeat=len(query_vars)):
921+
theta = {x: y for x, y in zip(query_vars, assignment_list)}
922922
yield theta
923923

924924
# check if we can answer without new inferences
@@ -931,16 +931,13 @@ def enum_subst(KB):
931931
new = []
932932
for rule in KB.clauses:
933933
p, q = parse_definite_clause(rule)
934-
for theta in enum_subst(KB):
935-
if any([set(subst(theta, p)) == set(subst(theta, p_))
936-
for p_ in itertools.combinations(KB.clauses, len(p))]):
934+
for theta in enum_subst(p):
935+
if set(subst(theta, p)).issubset(set(KB.clauses)):
937936
q_ = subst(theta, q)
938937
if all([unify(x, q_, {}) is None for x in KB.clauses + new]):
939-
print('Added', q_)
940938
new.append(q_)
941939
phi = unify(q_, alpha, {})
942940
if phi is not None:
943-
print(q_, alpha)
944941
yield phi
945942
if not new:
946943
break
@@ -1000,6 +997,16 @@ def fol_bc_and(KB, goals, theta):
1000997
'Enemy(Nono, America)'
1001998
]))
1002999

1000+
smalltest_kb = FolKB(
1001+
map(expr, ['Human(Mary)',
1002+
'Female(x) ==> Likes(x, Chocolate)',
1003+
'Male(x) ==> Likes(x, IceCream)',
1004+
'Wife(x, y) & Human(x) ==> Female(x)',
1005+
'Wife(y, x) & Human(x) ==> Male(x)',
1006+
'Human(John)',
1007+
'Wife(Mary, John)'
1008+
]))
1009+
10031010
# ______________________________________________________________________________
10041011

10051012
# Example application (not in the book).

tests/test_logic.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -261,22 +261,25 @@ def test_ask(query, kb=None):
261261
assert repr(test_ask('Human(x)')) == '[{x: Mac}, {x: MrsMac}]'
262262
assert repr(test_ask('Rabbit(x)')) == '[{x: MrsRabbit}, {x: Pete}]'
263263
assert repr(test_ask('Criminal(x)', crime_kb)) == '[{x: West}]'
264+
assert repr(test_ask('Likes(x, Chocolate)', smalltest_kb)) == '[{x: Mary}]'
265+
assert repr(test_ask('Likes(x, IceCream)', smalltest_kb)) == '[{x: John}]'
264266

265267

266268
def test_fol_fc_ask():
267269
def test_ask(query, kb=None):
268270
q = expr(query)
269271
test_variables = variables(q)
270272
answers = fol_fc_ask(kb or test_kb, q)
271-
print(answers)
272273
return sorted(
273274
[dict((x, v) for x, v in list(a.items()) if x in test_variables)
274275
for a in answers], key=repr)
275-
## Take too long to run
276-
#assert repr(test_ask('Farmer(x)')) == '[{x: Mac}]'
277-
#assert repr(test_ask('Human(x)')) == '[{x: Mac}, {x: MrsMac}]'
278-
#assert repr(test_ask('Rabbit(x)')) == '[{x: MrsRabbit}, {x: Pete}]'
279-
#assert repr(test_ask('Criminal(x)', crime_kb)) == '[{x: West}]'
276+
assert repr(test_ask('Likes(x, Chocolate)', smalltest_kb)) == '[{x: Mary}]'
277+
assert repr(test_ask('Likes(x, IceCream)', smalltest_kb)) == '[{x: John}]'
278+
assert repr(test_ask('Criminal(x)', crime_kb)) == '[{x: West}]'
279+
assert repr(test_ask('Enemy(x, America)', crime_kb)) == '[{x: Nono}]'
280+
assert repr(test_ask('Farmer(x)')) == '[{x: Mac}]'
281+
assert repr(test_ask('Human(x)')) == '[{x: Mac}, {x: MrsMac}]'
282+
assert repr(test_ask('Rabbit(x)')) == '[{x: MrsRabbit}, {x: Pete}]'
280283

281284

282285
def test_d():

0 commit comments

Comments
 (0)