def METHOD_NAME(self, parts, words, results):
    if not parts and not words:
        return True
    if not parts or (not words and parts != ["*"]):
        return False
    if parts[0] == "*":
        for index in range(len(words), -1, -1):
            results.append(words[:index])
            if self.METHOD_NAME(parts[1:], words[index:], results):
                return True
            results.pop()
        return False
    elif parts[0].startswith("@"):
        root = parts[0][1:]
        if root not in self.synons:
            raise ValueError("Unknown synonym root {}".format(root))
        if not words[0].lower() in self.synons[root]:
            return False
        results.append([words[0]])
        return self.METHOD_NAME(parts[1:], words[1:], results)
    elif parts[0].lower() != words[0].lower():
        return False
    else:
        return self.METHOD_NAME(parts[1:], words[1:], results)