#Tree Transducer Language Membership

class TreeTransducer:
    def __init__(self, rules):
        self.rules = rules

    def apply_transducer(self, input_tree):
        return self.apply_rules(input_tree)

    def apply_rules(self, tree):
        if isinstance(tree, str):
            return tree  # Leaf node, return the label as is

        nonterminal = tree[0]
        children = tree[1:]

        if nonterminal in self.rules:
            for rule in self.rules[nonterminal]:
                if len(rule) == len(children):
                    # Check if the rule matches the children of the current node
                    new_children = []
                    for i, child in enumerate(children):
                        new_child = self.apply_rules(child)
                        if new_child is None or new_child != rule[i]:
                            break  # Rule doesn't match, move to the next rule
                        new_children.append(new_child)
                    else:
                        # All children matched, apply the rule and return the resulting tree
                        return [nonterminal] + new_children

        return None  # No rule matches, return None

# Example usage
rules = {
    'S': [['A', 'B'], ['C']],
    'A': [['x']],
    'B': [['y']],
    'C': [['z']]
}

transducer = TreeTransducer(rules)

input_tree1 = ['S', ['x'], ['y']]
input_tree2 = ['S', ['z']]

result1 = transducer.apply_transducer(input_tree1)
result2 = transducer.apply_transducer(input_tree2)

print(f"Input Tree 1 Result: {result1}")
print(f"Input Tree 2 Result: {result2}")
