Source code for jaclearn.nlp.tree.node
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# File : node.py
# Author : Jiayuan Mao
# Email : maojiayuan@gmail.com
# Date : 07/04/2018
#
# This file is part of Jacinle.
# Distributed under terms of the MIT license.
"""
The definition for tree Nodes.
"""
from copy import deepcopy
__all__ = ['Node']
[docs]
class Node(object):
[docs]
def __init__(self, vtype, etype=None):
self.vtype = vtype
self.etype = etype
self.children = []
self.father = None
self.sibling_ind = -1
@property
def nr_children(self):
return len(self.children)
@property
def size(self):
return 1 + sum(c.size for c in self.children)
@property
def nr_leaves(self):
if self.is_leaf:
return 1
return sum(c.nr_leaves for c in self.children)
@property
def is_leaf(self):
return len(self.children) == 0
@property
def lson(self):
assert len(self.children) == 2
return self.childre[0]
@property
def rson(self):
assert len(self.children) == 2
return self.children[1]
@property
def depth(self):
"""
Depth is defined as the number of nodes on the maximum distance with the root of nodes + 1.
(Thus a single nodes will have depth 1.)
"""
if self.is_leaf:
return 1
return max([c.depth for c in self.children]) + 1
@property
def breadth(self):
"""
Breadth is defined as the maximum number of children of nodes in the tree.
"""
if self.is_leaf:
return 1
return max(max([c.breath for c in self.children]), len(self.children))
[docs]
def clone(self):
return deepcopy(self)
[docs]
def insert_child(self, pos, node):
node.father = self
self.children.insert(pos, node)
self._refresh_sibling_inds()
return node
[docs]
def remove_child(self, node):
assert self.children[node.sibling_ind] == node
self.children.remove(node)
self._refresh_sibling_inds()
rv = node.father, node.sibling_ind
node.father = None
node.sibling_ind = -1
return rv
[docs]
def append_child(self, node):
node.father = self
node.sibling_ind = len(self.children)
self.children.append(node)
return node
[docs]
def attach(self, father, sibling_ind=-1):
"""
Attach to a new father.
"""
if sibling_ind == -1:
return father.append_child(self)
return father.insert_child(sibling_ind, self)
[docs]
def detach(self):
"""
Detach from the father.
"""
return self.father.remove_child(self)
def _refresh_sibling_inds(self):
for i, c in enumerate(self.children):
c.sibling_ind = i
def __str_node__(self):
if self.etype is not None:
return 'VType: {} EType: {}'.format(self.vtype, self.etype)
return 'VType: {}'.format(self.vtype)
def __str__(self):
results = [self.__str_node__()]
for c in self.children:
lines = str(c).split('\n')
results.extend([' ' + l for l in lines])
return '\n'.join(results)
def __repr__(self):
return str(self)