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)
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