I have 2 functions, apply_rule
and match
. Each is defined independently - they don't belong to any class.
match
takes two required paramters, and an optional parameter, called pairs
. It defaults to an empty dictionary. Below is the code for apply_rule
and for match
. Note that match
is called, and the optional parameter pairs
isn't specified.
def apply_rule(pat, rule):
if not isrule(rule):
return "Not a valid rule"
subs = match(lhs(rule), pat)
if subs == {}:
return pat
else:
return substitute(rhs(rule), subs)
def match(pat, lst, pairs={}):
if pat == [] and lst == []:
return pairs
elif isvariable(pat[0]):
if pat[0] not in pairs.keys():
pairs[pat[0]] = lst[0]
elif pat[0] in pairs.keys() and lst[0] != pairs[pat[0]]:
return False
elif pat[0] != lst[0]:
return False
return match(pat[1:], lst[1:], pairs)
Right now, the unittest for match
fails, because it "remembers" pairs
, as defined in the test for apply_rule
.
However, if I change the 3rd line in apply_rule
to subs = match(lhs(rule), pat, {})
then the tests pass. Do you know why? As far as I can tell, there shouldn't be any way that match
remembers the value of pairs
from when it was called in other tests.
Below are the unit tests, for reference.
def test_match(self):
self.assertEqual({}, match(['a', 'b', 'c'], ['a', 'b', 'c']))
self.assertEqual(self.dict_with_x, match(['a', '_X', 'c'], ['a', '5', 'c']))
self.assertEqual(self.dict_with_x, match(self.pat_with_xx, self.list_with_55))
self.assertEqual(self.dict_with_xy, match(self.pat_with_xy, self.list_with_5hi))
self.assertFalse(match(self.pat_with_xx, ['a', 'b', 'c', 'd']))
self.assertFalse(match(['a', 'b', 'c'], ['a', 'b', 'd']))
def test_apply_and_firerule(self):
pattern1 = "my mother thinks I am fat".split(' ')
expected = "do you think you are fat ?".split(' ')
self.assertEqual(apply_rule(pattern1, self.r1), expected)
And the failure message...
Traceback (most recent call last):
File "pattern_matcher_tests.py", line 65, in test_match
self.assertEqual({}, match(['a', 'b', 'c'], ['a', 'b', 'c']))
AssertionError: {} != {'_Y': 'fat', '_X': 'mother'}
- {}
+ {'_X': 'mother', '_Y': 'fat'}