到目前为止,这对我想到的所有情况都有效(除了一个需要出现检查的情况,我还没有做):
def unify_var(self, var, val, subst):
if var in subst :
return self.unify(subst[var], val, subst)
elif isinstance(val, str) and val in subst :
return self.unify(var, subst[val], subst)
else :
subst[var] = val ; return subst
def unify(self, sym1, sym2, subst):
if subst is False : return False
elif isinstance(sym1, str) and isinstance(sym2, str) and sym1 == sym2 : return subst
elif isinstance(sym1, str) and is_var(sym1) : return self.unify_var(sym1, sym2, subst)
elif isinstance(sym2, str) and is_var(sym2) : return self.unify_var(sym2, sym1, subst)
elif isinstance(sym1, tuple) and isinstance(sym2, tuple) :
if len(sym1) == 0 and len(sym2) == 0 : return subst
if isinstance(sym1[0], str) and isinstance(sym2[0],str) and not (is_var(sym1[0]) or is_var(sym2[0])) and sym1[0] != sym2[0] : return False
return self.unify(sym1[1:],sym2[1:], self.unify(sym1[0], sym2[0], subst))
elif isinstance(sym1, list) and isinstance(sym2, list) :
if len(sym1) == 0 and len(sym2) == 0 : return subst
return self.unify(sym1[1:],sym2[1:], self.unify(sym1[0], sym2[0], subst))
else: return False
FAIL cases应该失败:
OK: a <=> a :
OK: X <=> a :
OK: ['a'] <=> ['a'] :
OK: ['X'] <=> ['a'] :
OK: ['a'] <=> ['X'] :
OK: ['X'] <=> ['X'] :
OK: ['X'] <=> ['Z'] :
OK: ['p', 'a'] <=> ['p', 'a'] :
OK: ['p', 'X'] <=> ['p', 'a'] :
OK: ['p', 'X'] <=> ['p', 'X'] :
OK: ['p', 'X'] <=> ['p', 'Z'] :
OK: ['X', 'X'] <=> ['p', 'X'] :
OK: ['p', 'X', 'Y'] <=> ['p', 'Y', 'X'] :
OK: ['p', 'X', 'Y', 'a'] <=> ['p', 'Y', 'X', 'X'] :
================= STRUCT cases ===================
OK: ['e', 'X', ('p', 'a')] <=> ['e', 'Y', ('p', 'a')] :
OK: ['e', 'X', ('p', 'a')] <=> ['e', 'Y', ('p', 'Z')] :
OK: ['e', 'X', ('p', 'a')] <=> ['e', 'Y', ('P', 'Z')] :
OK: [('p', 'a', 'X')] <=> [('p', 'Y', 'b')] :
OK: ['X', 'Y'] <=> [('p', 'a'), 'X'] :
OK: [('p', 'a')] <=> ['X'] :
-----
FAIL: ['e', 'X', ('p1', 'a')] <=> ['e', 'Y', ('p2', 'Z')] : False
FAIL: ['e', 'X', ('p1', 'a')] <=> ['e', 'Y', ('p1', 'b')] : False
FAIL: [('p', 'a', 'X', 'X')] <=> [('p', 'a', 'a', 'b')] : False
(should fail, occurs) OK: [('p1', 'X', 'X')] <=> [('p1', 'Y', ('p2', 'Y'))] :
================= LIST cases ===================
OK: ['e', 'X', ['e', 'a']] <=> ['e', 'Y', ['e', 'a']] :
OK: ['e', 'X', ['a', 'a']] <=> ['e', 'Y', ['a', 'Z']] :
OK: ['e', 'X', ['e', 'a']] <=> ['e', 'Y', ['E', 'Z']] :
OK: ['e', 'X', ['e1', 'a']] <=> ['e', 'Y', ['e1', 'a']] :
OK: [['e', 'a']] <=> ['X'] :
OK: ['X'] <=> [['e', 'a']] :
================= FAIL cases ===================
FAIL: ['a'] <=> ['b'] : False
FAIL: ['p', 'a'] <=> ['p', 'b'] : False
FAIL: ['X', 'X'] <=> ['p', 'b'] : False
[a | [b | [c | [] ]]]
- false