package edu.stanford.nlp.semparse.open.model.tree;
import java.util.*;
public class KNodeUtils {
/**
* @return The lowest common ancestor of all specified nodes.
*/
public static KNode lowestCommonAncestor(Collection<KNode> nodes) {
int minDepth = Integer.MAX_VALUE;
for (KNode node : nodes)
minDepth = Math.min(minDepth, node.depth);
Set<KNode> sameDepthAncestors = new HashSet<>();
for (KNode node : nodes) {
while (node.depth != minDepth) node = node.parent;
sameDepthAncestors.add(node);
}
while (sameDepthAncestors.size() != 1) {
if (minDepth == 0) return null;
Set<KNode> newSameDepthAncestors = new HashSet<>();
for (KNode node : sameDepthAncestors) newSameDepthAncestors.add(node.parent);
sameDepthAncestors = newSameDepthAncestors;
}
return sameDepthAncestors.iterator().next();
}
public static boolean isDescendantOf(KNode allegedDescendant, KNode node) {
KNode currentNode = allegedDescendant;
while (currentNode != null) {
if (currentNode == node) return true;
currentNode = currentNode.parent;
}
return false;
}
/**
* Print the tree to standard error. Useful for debugging.
*/
public static void printTree(KNode node) { printTree(node, 0); }
public static void printTree(KNode node, int indent) {
if ("text".equals(node.value)) {
String text = node.fullText;
if (text == null) text = "...";
System.err.printf("%s%s\n", new String(new char[indent]).replace('\0', ' '), text);
return;
}
System.err.printf("%s<%s>\n", new String(new char[indent]).replace('\0', ' '), node.value);
for (KNode child : node.getChildren()) {
printTree(child, indent + 2);
}
System.err.printf("%s</%s>\n", new String(new char[indent]).replace('\0', ' '), node.value);
}
/**
* Copy a KNode and its subtree to a new parent.
*/
public static KNode copyTree(KNode node, KNode newParent) {
KNode newNode = newParent.createChild(node);
for (KNode x : node.getChildren()) copyTree(x, newNode);
for (KNode x : node.getAttributes()) copyTree(x, newNode);
return newNode;
}
}