def visit(node, sofar): assert tb.is_phrasal(node) label = tb.tree_label(node) assert is_pair(label) A, X = pair_categories(label) children = tb.tree_children(node) assert len(children) > 0 assert tb.is_preterminal(children[0]) if len(children) == 1: assert is_flagged(children[0]) xf = cat_c(A, X, unflag(children[0])) elif len(children) == 2: if is_flagged(children[0]): A1, B = pair_categories(tb.tree_label(children[1])) assert A1 == A xf = cat_b(A, X, B, unflag(children[0])) else: C, a = pair_categories(tb.tree_label(children[1])) assert a == tb.tree_label(children[0]), \ "error in label of node.children[1] a = {}, node = {}".format(a, node) xf = cat_e(A, X, C, children[0]) elif len(children) == 3: assert not is_flagged(children[0]) C, a = pair_categories(tb.tree_label(children[1])) A1, B = pair_categories(tb.tree_label(children[2])) assert A == A1 xf = cat_d(A, X, B, C, children[0]) else: sys.exit("error: ill-formed subtree {}\n in tree {}".format( node, xtree)) sofar.append(xf) for child in children[1:]: sofar = visit(child, sofar) return sofar
def rightbranch(tree): """ Transform a subtree lying on a right branch. """ def leftbranch(subtree, transformed_right): """ Transform a subtree lying on a left branch. transformed_right is transformed right material between this node and Anc. """ if tb.is_preterminal(subtree): return [subtree, transformed_right] else: left, right = tb.tree_children(subtree) return leftbranch( left, tb.make_nonterminal( make_pair(Anc, tb.tree_label(left)), rightbranch(right) + [transformed_right])) if tb.is_preterminal(tree): return [flag(tree)] else: Anc = tb.tree_label(tree) left, right = tb.tree_children(tree) return leftbranch( left, tb.make_nonterminal(make_pair(Anc, tb.tree_label(left)), rightbranch(right)))
def leftbranch(subtree, continuation): if tb.is_preterminal(subtree): return [subtree] + continuation else: left, right = tb.tree_children(subtree) return leftbranch(left, [ tb.make_nonterminal(make_pair(Anc, tb.tree_label(left)), rightbranch(right) + continuation) ])
def leftbranch(subtree, continuation, X1): if tb.is_preterminal(subtree): return [relabel(subtree, X1)] + continuation else: left, right = tb.tree_children(subtree) X2 = tb.tree_label(left) + '>' return leftbranch(left, [ tb.make_nonterminal(make_pair(Anc, tb.tree_label(left)), rightbranch(right, X2) + continuation) ], X1)
def lcx0(t): """ lcx0() maps a binary tree into its left-corner transform as in my 1996 paper. """ def _lcx(s, cont): if tb.is_preterminal(s): return [A, s] + cont else: return _lcx(s[1], [[make_pair(A, s[1][0]), lcx0(s[2])] + cont]) if tb.is_preterminal(t): return t else: A = t[0] return _lcx(t, [])
def lcx(root): """lcx() maps a binary tree into the left-corner transform of my 1996 paper.""" def rightbranch(tree): def leftbranch(subtree, continuation): if tb.is_preterminal(subtree): return [subtree] + continuation else: left, right = tb.tree_children(subtree) return leftbranch(left, [ tb.make_nonterminal(make_pair(Anc, tb.tree_label(left)), rightbranch(right) + continuation) ]) Anc = tb.tree_label(tree) return leftbranch(tree, []) if tb.is_preterminal(root): return root else: return tb.make_nonterminal(tb.tree_label(root), rightbranch(root))
def lct(root): """ lct() implements the same transform as lcx(), but it also relabels the preterminal labels to implement the transduction in my 1996 paper. It isn't complete, i.e., it doesn't implement the relabelling. """ def relabel(tree, label): return tb.make_nonterminal(tree[0] + ' ' + label, tb.tree_children(tree)) def rightbranch(tree, X0): def leftbranch(subtree, continuation, X1): if tb.is_preterminal(subtree): return [relabel(subtree, X1)] + continuation else: left, right = tb.tree_children(subtree) X2 = tb.tree_label(left) + '>' return leftbranch(left, [ tb.make_nonterminal(make_pair(Anc, tb.tree_label(left)), rightbranch(right, X2) + continuation) ], X1) if tb.is_preterminal(tree): return [relabel(tree, X0 + '<' + tb.tree_label(tree) + ']')] else: Anc = tb.tree_label(tree) left, right = tb.tree_children(tree) X2 = tb.tree_label(left) + '>' return leftbranch(left, [ tb.make_nonterminal(make_pair(Anc, tb.tree_label(left)), rightbranch(right, X2)) ], X0) if tb.is_preterminal(root): return root else: return tb.make_nonterminal(tb.tree_label(root), rightbranch(root, ''))
def lcx2(root): """ lcx2() maps a binary tree into the left-corner transform of my 1996 paper. Preterminals that are right children, i.e., generated under schema (11b) and (11c), are flagged. This permits us to distinguish schema (11b) and (11e). """ def rightbranch(tree): """ Transform a subtree lying on a right branch. """ def leftbranch(subtree, transformed_right): """ Transform a subtree lying on a left branch. transformed_right is transformed right material between this node and Anc. """ if tb.is_preterminal(subtree): return [subtree, transformed_right] else: left, right = tb.tree_children(subtree) return leftbranch( left, tb.make_nonterminal( make_pair(Anc, tb.tree_label(left)), rightbranch(right) + [transformed_right])) if tb.is_preterminal(tree): return [flag(tree)] else: Anc = tb.tree_label(tree) left, right = tb.tree_children(tree) return leftbranch( left, tb.make_nonterminal(make_pair(Anc, tb.tree_label(left)), rightbranch(right))) if tb.is_preterminal(root): return root else: return tb.make_nonterminal(tb.tree_label(root), rightbranch(root))
def _lcx(s, cont): if tb.is_preterminal(s): return [A, s] + cont else: return _lcx(s[1], [[make_pair(A, s[1][0]), lcx0(s[2])] + cont])