def pattern_match(pattern, input): # pattern could be a list, which is split from 'I need a X_X' # or pattern could be a element which is the element of a list. if len(pattern) == 0 and len(input) == 0: return [] elif is_variable(pattern): return True elif is_atom(pattern) and is_atom(input): return pattern == input else: return all(pattern_match(p, i) for p, i in zip(pattern, input))
def first_match_pos(pat1, input, start): if is_atom(pat1) and not is_variable(pat1): pos = input[start:].index(pat1) if pat1 in input[start:] else None return pos elif start < len(input): return start else: return None
def pattern_match_l_buggy(pattern, input): # pattern match returns a list rather than True or False # the problems of this are: # 1. the is_atom(pattern) and is_atom(input) may return True, which is not a list; # 2. pattern_match_l return [], which should means Failure, but not append as a list. # 3. We want the binding of variables to agree - if ?X is used twice in the pattern, we don't # 4. We don't have indicator to show that math failure; # 5. If the pattern.first and input.first don't match, should not go on. # want it to match two different values in the input. if len(pattern) == 0 and len(input) == 0: return [] elif is_variable(pattern): return [pattern, input] elif is_atom(pattern) and is_atom(input): return pattern == input else: return pattern_match_l_buggy(pattern[0], input[0]) + pattern_match_l_buggy( pattern[1:], input[1:])
def pattern_match_l(pattern, input, bindings=None): # print('bindings', bindings) bindings = bindings or defaultdict(lambda: None) # if len(pattern) == 0 or len(input) == 0: return None if bindings == fail: return None elif is_variable(pattern): return match_variable(pattern, input, bindings) elif is_atom(pattern): if pattern == input: return bindings else: return fail elif is_segment_pattern(pattern): return segment_match(pattern, input, bindings) elif is_tokens(pattern) and is_tokens(input): peak_p, peak_input = pattern[0], input[0] if len( pattern) > 1 else ' '.join(input[0:]) return pattern_match_l(pattern[1:], input[1:], bindings=pattern_match_l(peak_p, peak_input, bindings=bindings)) elif len(input) == 0 and len(pattern) != 0: return fail else: return bindings