private static void replace(Tree code, String data, Tree replacement) { System.out.println("Trying to replace" + data + " with " + replacement + " in " + code); if (code.getData().equals(data)) { System.out.println("Replacing " + data + " with " + replacement); code.removeChildren(false); for (Tree t : replacement.getChildren()) { code.addChild(new Tree(t), false); } code.setData(replacement.getData()); } else if (code.getData().equals(FUN)) { // Shadowing Vector<Tree> fn = code.getChildren(); Vector<Tree> args = fn.get(0).getChildren(); for (Tree t : args) { if (t.getData().equals(data)) { return; } } // If we made it here, the replacement term is not in the args replace(fn.get(1), data, replacement); } else { for (Tree t : code.getChildren()) { replace(t, data, replacement); } } }
/** * Get Last Root Child Forest -------------------------- Returns the children of the last root as * a forest. Let v be the last root. This method returns F(v). */ public Forest getLastRootChildForest() { Tree lastRoot = getLastRoot(); if (lastRoot == null) { return null; } List<Tree> children = lastRoot.getChildren(); if (children.isEmpty()) { return null; } return new Forest(lastRoot.getChildren()); }
private static <L> Tree<L> deepCopy(Tree<L> tree) { List<Tree<L>> childrenCopies = new ArrayList<Tree<L>>(); for (Tree<L> child : tree.getChildren()) { childrenCopies.add(deepCopy(child)); } return new Tree<L>(tree.getLabel(), childrenCopies); }
private static <L> void traversalHelper(Tree<L> tree, List<Tree<L>> traversal, boolean preOrder) { if (preOrder) traversal.add(tree); for (Tree<L> child : tree.getChildren()) { traversalHelper(child, traversal, preOrder); } if (!preOrder) traversal.add(tree); }
/** * Recursively transforms each node of <code>tree</code> parameter according to the passed in * <code>LabelFactory</code>. None of the structure of the <code>Tree</code> is altered only the * information stored in the Label at each node. * * @param <S> Original Tree label type * @param <T> Output tree label type * @param tree * @param labelFactory * @return Tree with transformed labels according to <code>labelFactory</code> */ public static <S, T> Tree<T> transformTreeLabels(Tree<S> tree, LabelFactory<S, T> labelFactory) { T newLabel = labelFactory.newLabel(tree); List<Tree<T>> newChildren = new ArrayList<Tree<T>>(); for (Tree<S> node : tree.getChildren()) { Tree<T> newNode = transformTreeLabels(node, labelFactory); newChildren.add(newNode); } return new Tree<T>(newLabel, newChildren); }
private static String toLispString(Tree<?> tree) { final String value = String.valueOf(tree.getValue()); if (tree.isLeaf()) { return value; } else { return String.format( "(%s %s)", value, tree.getChildren().map(Node::toLispString).mkString(" ")); } }
private static <L> void appendPreTerminalYield(Tree<L> tree, List<L> yield) { if (tree.isPreTerminal()) { yield.add(tree.getLabel()); return; } for (Tree<L> child : tree.getChildren()) { appendPreTerminalYield(child, yield); } }
private static <L> List<Tree<L>> spliceNodesHelper(Tree<L> tree, Filter<L> filter) { List<Tree<L>> splicedChildren = new ArrayList<Tree<L>>(); for (Tree<L> child : tree.getChildren()) { List<Tree<L>> splicedChildList = spliceNodesHelper(child, filter); splicedChildren.addAll(splicedChildList); } if (filter.accept(tree.getLabel())) return splicedChildren; return Collections.singletonList(new Tree<L>(tree.getLabel(), splicedChildren)); }
private static <L> Tree<L> pruneNodesHelper(Tree<L> tree, Filter<L> filter) { if (filter.accept(tree.getLabel())) return null; List<Tree<L>> prunedChildren = new ArrayList<Tree<L>>(); for (Tree<L> child : tree.getChildren()) { Tree<L> prunedChild = pruneNodesHelper(child, filter); if (prunedChild != null) prunedChildren.add(prunedChild); } if (prunedChildren.isEmpty() && !tree.isLeaf()) return null; return new Tree<L>(tree.getLabel(), prunedChildren); }
private static <L> int toConstituentCollectionHelper( Tree<L> tree, int start, List<Constituent<L>> constituents) { if (tree.isLeaf() || tree.isPreTerminal()) return 1; int span = 0; for (Tree<L> child : tree.getChildren()) { span += toConstituentCollectionHelper(child, start + span, constituents); } constituents.add(new Constituent<L>(tree.getLabel(), start, start + span)); return span; }
private static <L> void renderFlat(Tree<L> tree, StringBuilder sb) { if (tree.isLeaf()) { sb.append(tree.getLabel().toString()); return; } sb.append('('); sb.append(tree.getLabel().toString()); sb.append(' '); sb.append(tree.getChildren().get(0).getLabel().toString()); sb.append(')'); }
static <T> Stream<T> levelOrder(Tree<T> tree) { Stream<T> result = Stream.empty(); final java.util.Queue<Tree<T>> queue = new java.util.LinkedList<>(); queue.add(tree); while (!queue.isEmpty()) { final Tree<T> next = queue.remove(); result = result.prepend(next.getValue()); queue.addAll(next.getChildren().toJavaList()); } return result.reverse(); }
public Tree<String> transformTree(Tree<String> tree) { String transformedLabel = transformLabel(tree); if (tree.isLeaf()) { return new Tree<String>(transformedLabel); } List<Tree<String>> transformedChildren = new ArrayList<Tree<String>>(); for (Tree<String> child : tree.getChildren()) { transformedChildren.add(transformTree(child)); } return new Tree<String>(transformedLabel, transformedChildren); }
static <T> Stream<T> inOrder(Tree<T> tree) { if (tree.isLeaf()) { return Stream.of(tree.getValue()); } else { final List<Node<T>> children = tree.getChildren(); return children .tail() .foldLeft(Stream.<T>empty(), (acc, child) -> acc.appendAll(inOrder(child))) .prepend(tree.getValue()) .prependAll(inOrder(children.head())); } }
Tree parse(String code) throws CompilationException { if (code == null || code.isEmpty()) return null; // Base Case if (code.charAt(0) != '(') return new Tree(code); // Recursive Case ArrayList<String> chunks = findChunks(code); List<Tree> kids = new LinkedList<Tree>(); for (String chunk : chunks) { kids.add(parse(chunk)); } if (!kids.isEmpty() && isReserved(kids.get(0).getData())) { // Now we need to make special Trees based on what kind of special thing // this is Tree first = kids.get(0); if (first.getChildren() != null && first.getChildren().size() > 0) return new Tree(kids); kids.remove(0); String word = first.getData(); if (word.equals(FUN)) { // (FUN (arg1 arg2 [...]) body) ; note that args are optional if (kids.size() <= 1) throw new CompilationException(code); if (kids.get(1).getChildren() == null) throw new CompilationException(code); return new Tree(FUN, kids); } else if (word.equals(IF)) { // (if cond then else) if (kids.size() != 3) throw new CompilationException(code); return new Tree(IF, kids); } else { return new Tree(word, kids); } } else { return new Tree(kids); } }
public Tree<E> transformTree(Tree<E> tree) { E label = tree.getLabel(); List<Tree<E>> children = tree.getChildren(); while (children.size() == 1 && !children.get(0).isLeaf() && label.equals(children.get(0).getLabel())) { children = children.get(0).getChildren(); } List<Tree<E>> transformedChildren = new ArrayList<Tree<E>>(); for (Tree<E> child : children) { transformedChildren.add(transformTree(child)); } return new Tree<E>(label, transformedChildren); }
/** * Get Forest Minus Last Root -------------------------- Let F be the forest and v is the lass * root. This method returns F - v. Note that this is different than F - T(v). The children of v * are promoted to be roots. */ public Forest getForestMinusLastRoot() { List<Tree> newRoots = new ArrayList<Tree>(); // Add all the previous roots newRoots.addAll(roots.subList(0, roots.size() - 1)); // Add the last roots children Tree lastRoot = getLastRoot(); newRoots.addAll(lastRoot.getChildren()); if (newRoots.isEmpty()) { return null; } return new Forest(newRoots); }
@SuppressWarnings("unchecked") static <T, U> Tree<U> apply( Node<T> node, Function<? super T, ? extends Iterable<? extends U>> mapper) { final Tree<U> mapped = Tree.ofAll(mapper.apply(node.getValue())); if (mapped.isEmpty()) { return Tree.empty(); } else { final List<Node<U>> children = (List<Node<U>>) (Object) node.getChildren() .map(child -> FlatMap.apply(child, mapper)) .filter(Tree::isDefined); return Tree.of(mapped.getValue(), children.prependAll(mapped.getChildren())); } }
/** * Get All Suffix Subforests ------------------------- What is a suffix subforest you may ask? Is * all the right most nodes in a forest, plus all the suffix subforests of each root. Its useful * for the recursive definition of distance with equivalence between two queries. If there are n * nodes in a forest, there are exactly n suffix subforests. */ public List<Forest> getAllSuffixSubforests() { List<Forest> subforests = new ArrayList<Forest>(); for (int i = 0; i < roots.size(); i++) { List<Tree> suffixRoots = roots.subList(i, roots.size()); subforests.add(new Forest(suffixRoots)); } for (Tree root : roots) { List<Tree> children = root.getChildren(); if (!children.isEmpty()) { Forest childForest = new Forest(children); subforests.addAll(childForest.getAllSuffixSubforests()); } } return subforests; }
public Tree<String> transformTree(Tree<String> tree) { String label = tree.getLabel(); if (label.equals("-NONE-")) { return null; } if (tree.isLeaf()) { return new Tree<String>(label); } List<Tree<String>> children = tree.getChildren(); List<Tree<String>> transformedChildren = new ArrayList<Tree<String>>(); for (Tree<String> child : children) { Tree<String> transformedChild = transformTree(child); if (transformedChild != null) transformedChildren.add(transformedChild); } if (transformedChildren.size() == 0) return null; return new Tree<String>(label, transformedChildren); }
public Tree<String> transformTree(Tree<String> tree) { String label = tree.getLabel(); Matcher matcher = punctuationPattern.matcher(label); if (matcher.matches()) { return null; } if (tree.isLeaf()) { return new Tree<String>(label); } List<Tree<String>> children = tree.getChildren(); List<Tree<String>> transformedChildren = new ArrayList<Tree<String>>(); for (Tree<String> child : children) { Tree<String> transformedChild = transformTree(child); if (transformedChild != null) transformedChildren.add(transformedChild); } if (transformedChildren.size() == 0) return null; return new Tree<String>(label, transformedChildren); }
/** Display a node, implementing Penn Treebank style layout */ private static <L> void renderTree( Tree<L> tree, int indent, boolean parentLabelNull, boolean firstSibling, boolean leftSiblingPreTerminal, boolean topLevel, StringBuilder sb) { // the condition for staying on the same line in Penn Treebank boolean suppressIndent = (parentLabelNull || (firstSibling && tree.isPreTerminal()) || (leftSiblingPreTerminal && tree.isPreTerminal() && (tree.getLabel() == null || !tree.getLabel().toString().startsWith("CC")))); if (suppressIndent) { sb.append(' '); } else { if (!topLevel) { sb.append('\n'); } for (int i = 0; i < indent; i++) { sb.append(" "); } } if (tree.isLeaf() || tree.isPreTerminal()) { renderFlat(tree, sb); return; } sb.append('('); sb.append(tree.getLabel()); renderChildren( tree.getChildren(), indent + 1, tree.getLabel() == null || tree.getLabel().toString() == null, sb); sb.append(')'); }
private boolean step(Tree code) { if (code.getData().equals(FUN)) return false; if (code.getData().equals("") && code.getChildren().size() >= 1 && code.getChild(0).getData().equals(FUN)) { // This is an APPLY -- make sure it works. Tree fn = code.getChild(0); Vector<Tree> fnargs = fn.getChildren(); Tree body = fnargs.get(1); fnargs = fnargs.get(0).getChildren(); Vector<Tree> inargs = code.getChildren(); inargs.remove(0); for (Tree t : inargs) { if (step(t)) return true; } if (fnargs.size() != inargs.size()) { return false; } for (int i = 0; i < fnargs.size(); i++) { replace(body, fnargs.get(i).getData(), inargs.get(i)); } code.removeChildren(false); for (Tree t : body.getChildren()) { code.addChild(t, false); } code.setData(body.getData()); return true; } else if (code.getData().equals(IF)) { // IF Vector<Tree> ifargs = code.getChildren(); if (step(ifargs.get(0))) return true; if (ifargs.get(0).getData().equals("0")) { // "0" is our only false value System.out.println("FALSE IF"); code.removeChildren(false); for (Tree kkid : ifargs.get(2).getChildren()) { code.addChild(kkid, false); } code.setData(ifargs.get(2).getData()); } else { System.out.println("TRUE IF: " + ifargs.get(0)); code.removeChildren(false); for (Tree kkid : ifargs.get(1).getChildren()) { code.addChild(kkid, false); } code.setData(ifargs.get(1).getData()); } return true; } for (Tree kid : code.getChildren()) { if (step(kid)) { System.out.println("stepped " + kid); return true; } } if (code.getData().equals("<")) { Vector<Tree> ltargs = code.getChildren(); Double left = Double.parseDouble(ltargs.get(0).getData()); Double right = Double.parseDouble(ltargs.get(1).getData()); code.removeChildren(false); if (left < right) { code.setData("1"); } else { code.setData("0"); } return true; } else if (code.getData().equals(">")) { Vector<Tree> ltargs = code.getChildren(); Double left = Double.parseDouble(ltargs.get(0).getData()); Double right = Double.parseDouble(ltargs.get(1).getData()); code.removeChildren(false); if (left > right) { code.setData("1"); } else { code.setData("0"); } return true; } else if (code.getData().equals("=")) { Vector<Tree> ltargs = code.getChildren(); Double left = Double.parseDouble(ltargs.get(0).getData()); Double right = Double.parseDouble(ltargs.get(1).getData()); code.removeChildren(false); if (left.equals(right)) { code.setData("1"); } else { code.setData("0"); } return true; } else if (code.getData().equals("+")) { Vector<Tree> ltargs = code.getChildren(); Double left = Double.parseDouble(ltargs.get(0).getData()); Double right = Double.parseDouble(ltargs.get(1).getData()); code.removeChildren(false); code.setData("" + (left + right)); return true; } else if (code.getData().equals("-")) { Vector<Tree> ltargs = code.getChildren(); Double left = Double.parseDouble(ltargs.get(0).getData()); Double right = Double.parseDouble(ltargs.get(1).getData()); code.removeChildren(false); code.setData("" + (left - right)); return true; } else if (code.getData().equals("*")) { Vector<Tree> ltargs = code.getChildren(); Double left = Double.parseDouble(ltargs.get(0).getData()); Double right = Double.parseDouble(ltargs.get(1).getData()); code.removeChildren(false); code.setData("" + (left * right)); return true; } else if (code.getData().equals("/")) { Vector<Tree> ltargs = code.getChildren(); Double left = Double.parseDouble(ltargs.get(0).getData()); Double right = Double.parseDouble(ltargs.get(1).getData()); code.removeChildren(false); code.setData("" + (left / right)); return true; } else if (code.getData().equals("^")) { Vector<Tree> ltargs = code.getChildren(); Double left = Double.parseDouble(ltargs.get(0).getData()); Double right = Double.parseDouble(ltargs.get(1).getData()); code.removeChildren(false); code.setData("" + Math.pow(left, right)); return true; } System.out.println("Couldn't step: " + code.getData()); return false; }
static <T> Stream<T> postOrder(Tree<T> tree) { return tree.getChildren() .foldLeft(Stream.<T>empty(), (acc, child) -> acc.appendAll(postOrder(child))) .append(tree.getValue()); }
static <T> Stream<T> preOrder(Tree<T> tree) { return tree.getChildren() .foldLeft(Stream.of(tree.getValue()), (acc, child) -> acc.appendAll(preOrder(child))); }