Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e5204f6

Browse files
alessandrocudaantmarakis
authored andcommitted
Fix for unify algorithm in logic.py (aimacode#1101)
* Fix issue aimacode#1053 Unify algorithm fixed by performing a perform a cascade substitution when a new mapping is added This issue was already known and fixed in the aima-java repo. * added two more test in test_logic.py updated documentation for cascade_substitution function in logic.py * Fixed brackets missing in test_logic.py for the new test * Fixed typo error, missing space and double quotes for docstrings * comments changed to cascade_substitution function in logic.py
1 parent 0ad4c07 commit e5204f6

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

logic.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,7 @@ def parse_definite_clause(s):
193193

194194

195195
# Useful constant Exprs used in examples and code:
196-
A, B, C, D, E, F, G, P, Q, x, y, z = map(Expr, 'ABCDEFGPQxyz')
197-
196+
A, B, C, D, E, F, G, P, Q, a, x, y, z, u = map(Expr, 'ABCDEFGPQaxyzu')
198197

199198
# ______________________________________________________________________________
200199

@@ -1370,7 +1369,9 @@ def unify_var(var, x, s):
13701369
elif occur_check(var, x, s):
13711370
return None
13721371
else:
1373-
return extend(s, var, x)
1372+
new_s = extend(s, var, x)
1373+
cascade_substitution(new_s)
1374+
return new_s
13741375

13751376

13761377
def occur_check(var, x, s):
@@ -1415,6 +1416,33 @@ def subst(s, x):
14151416
else:
14161417
return Expr(x.op, *[subst(s, arg) for arg in x.args])
14171418

1419+
def cascade_substitution(s):
1420+
"""This method allows to return a correct unifier in normal form
1421+
and perform a cascade substitution to s.
1422+
For every mapping in s perform a cascade substitution on s.get(x)
1423+
and if it is replaced with a function ensure that all the function
1424+
terms are correct updates by passing over them again.
1425+
1426+
This issue fix: https://github.com/aimacode/aima-python/issues/1053
1427+
unify(expr('P(A, x, F(G(y)))'), expr('P(z, F(z), F(u))'))
1428+
must return {z: A, x: F(A), u: G(y)} and not {z: A, x: F(z), u: G(y)}
1429+
1430+
>>> s = {x: y, y: G(z)}
1431+
>>> cascade_substitution(s)
1432+
>>> print(s)
1433+
{x: G(z), y: G(z)}
1434+
1435+
Parameters
1436+
----------
1437+
s : Dictionary
1438+
This contain a substution
1439+
"""
1440+
1441+
for x in s:
1442+
s[x] = subst(s, s.get(x))
1443+
if isinstance(s.get(x), Expr) and not is_variable(s.get(x)):
1444+
# Ensure Function Terms are correct updates by passing over them again.
1445+
s[x] = subst(s, s.get(x))
14181446

14191447
def standardize_variables(sentence, dic=None):
14201448
"""Replace all the variables in sentence with new variables."""

tests/test_logic.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,13 @@ def test_unify():
163163
assert unify(x & 4 & y, 6 & y & 4, {}) == {x: 6, y: 4}
164164
assert unify(expr('A(x)'), expr('A(B)')) == {x: B}
165165
assert unify(expr('American(x) & Weapon(B)'), expr('American(A) & Weapon(y)')) == {x: A, y: B}
166+
assert unify(expr('P(F(x,z), G(u, z))'), expr('P(F(y,a), y)')) == {x: G(u, a), z: a, y: G(u, a)}
166167

168+
# test for https://github.com/aimacode/aima-python/issues/1053
169+
# unify(expr('P(A, x, F(G(y)))'), expr('P(z, F(z), F(u))'))
170+
# must return {z: A, x: F(A), u: G(y)} and not {z: A, x: F(z), u: G(y)}
171+
assert unify(expr('P(A, x, F(G(y)))'), expr('P(z, F(z), F(u))')) == {z: A, x: F(A), u: G(y)}
172+
assert unify(expr('P(x, A, F(G(y)))'), expr('P(F(z), z, F(u))')) == {x: F(A), z: A, u: G(y)}
167173

168174
def test_pl_fc_entails():
169175
assert pl_fc_entails(horn_clauses_KB, expr('Q'))

0 commit comments

Comments
 (0)