@Override public Builder literal(TruthValue truth) { ExpressionTree parent = currentTree.getFirst(); parent.getChildren().add(new ExpressionTree(truth)); return this; }
/** * Recursively explore the tree to find the leaves that are still reachable * after optimizations. * @param tree the node to check next * @param next the next available leaf id * @param leafReorder * @return the next available leaf id */ static int compactLeaves(ExpressionTree tree, int next, int[] leafReorder) { if (tree.getOperator() == ExpressionTree.Operator.LEAF) { int oldLeaf = tree.getLeaf(); if (leafReorder[oldLeaf] == -1) { leafReorder[oldLeaf] = next++; } } else if (tree.getChildren() != null){ for(ExpressionTree child: tree.getChildren()) { next = compactLeaves(child, next, leafReorder); } } return next; }
@Override public Builder end() { ExpressionTree current = currentTree.removeFirst(); if (current.getChildren().size() == 0) { throw new IllegalArgumentException("Can't create expression " + root + " with no children."); } if (current.getOperator() == ExpressionTree.Operator.NOT && current.getChildren().size() != 1) { throw new IllegalArgumentException("Can't create not expression " + current + " with more than 1 child."); } return this; }
if (expr.getChildren() != null) { for(int i=0; i < expr.getChildren().size(); ++i) { ExpressionTree child = foldMaybe(expr.getChildren().get(i)); if (child.getConstant() == TruthValue.YES_NO_NULL) { switch (expr.getOperator()) { case AND: expr.getChildren().remove(i); i -= 1; break; expr.getChildren().set(i, child); if (expr.getChildren().isEmpty()) { return new ExpressionTree(TruthValue.YES_NO_NULL);
/** * Rewrite expression tree to update the leaves. * @param root the root of the tree to fix * @param leafReorder a map from old leaf ids to new leaf ids * @return the fixed root */ static ExpressionTree rewriteLeaves(ExpressionTree root, int[] leafReorder) { // The leaves could be shared in the tree. Use Set to remove the duplicates. Set<ExpressionTree> leaves = new HashSet<ExpressionTree>(); Queue<ExpressionTree> nodes = new LinkedList<ExpressionTree>(); nodes.add(root); while(!nodes.isEmpty()) { ExpressionTree node = nodes.remove(); if (node.getOperator() == ExpressionTree.Operator.LEAF) { leaves.add(node); } else { if (node.getChildren() != null){ nodes.addAll(node.getChildren()); } } } // Update the leaf in place for(ExpressionTree leaf : leaves) { leaf.setLeaf(leafReorder[leaf.getLeaf()]); } return root; }
if (root.getChildren() != null) { int size = root.getChildren().size(); for(int i=0; i < size; ++i) { root.getChildren().set(i, convertToCNF(root.getChildren().get(i))); if (root.getOperator() == ExpressionTree.Operator.OR) { for(ExpressionTree child: root.getChildren()) { if (child.getOperator() == ExpressionTree.Operator.AND) { andList.add(child); } else if (child.getOperator() == ExpressionTree.Operator.OR) { for(ExpressionTree grandkid: child.getChildren()) { nonAndList.add(grandkid); root = new ExpressionTree(ExpressionTree.Operator.AND); generateAllCombinations(root.getChildren(), andList, nonAndList); } else { root = new ExpressionTree(TruthValue.YES_NO_NULL);
private static boolean checkCombinationsThreshold(List<ExpressionTree> andList) { int numComb = 1; for (ExpressionTree tree : andList) { numComb *= tree.getChildren().size(); if (numComb > CNF_COMBINATIONS_THRESHOLD) { return false; } } return true; }
ExpressionTree(ExpressionTree other) { this.operator = other.operator; if (other.children == null) { this.children = null; } else { this.children = new ArrayList<ExpressionTree>(); for(ExpressionTree child: other.children) { children.add(new ExpressionTree(child)); } } this.leaf = other.leaf; this.constant = other.constant; }
@Override public TruthValue evaluate(TruthValue[] leaves) { return expression == null ? TruthValue.YES : expression.evaluate(leaves); }
if (root.getOperator() == ExpressionTree.Operator.NOT) { ExpressionTree child = root.getChildren().get(0); switch (child.getOperator()) { case NOT: return pushDownNot(child.getChildren().get(0)); case CONSTANT: return new ExpressionTree(child.getConstant().not()); case AND: root = new ExpressionTree(ExpressionTree.Operator.OR); for(ExpressionTree kid: child.getChildren()) { root.getChildren().add(pushDownNot(new ExpressionTree(ExpressionTree.Operator.NOT, kid))); root = new ExpressionTree(ExpressionTree.Operator.AND); for(ExpressionTree kid: child.getChildren()) { root.getChildren().add(pushDownNot(new ExpressionTree (ExpressionTree.Operator.NOT, kid))); break; } else if (root.getChildren() != null) { for(int i=0; i < root.getChildren().size(); ++i) { root.getChildren().set(i, pushDownNot(root.getChildren().get(i)));
if (root.getChildren() != null) { for(int i=0; i < root.getChildren().size(); ++i) { ExpressionTree child = flatten(root.getChildren().get(i)); if (child.getOperator() == root.getOperator() && child.getOperator() != ExpressionTree.Operator.NOT) { boolean first = true; for(ExpressionTree grandkid: child.getChildren()) { root.getChildren().set(i, grandkid); } else { root.getChildren().add(++i, grandkid); root.getChildren().set(i, child); if ((root.getOperator() == ExpressionTree.Operator.OR || root.getOperator() == ExpressionTree.Operator.AND) && root.getChildren().size() == 1) { return root.getChildren().get(0);
/** * Rewrite expression tree to update the leaves. * @param root the root of the tree to fix * @param leafReorder a map from old leaf ids to new leaf ids * @return the fixed root */ static ExpressionTree rewriteLeaves(ExpressionTree root, int[] leafReorder) { // The leaves could be shared in the tree. Use Set to remove the duplicates. Set<ExpressionTree> leaves = new HashSet<ExpressionTree>(); Queue<ExpressionTree> nodes = new LinkedList<ExpressionTree>(); nodes.add(root); while(!nodes.isEmpty()) { ExpressionTree node = nodes.remove(); if (node.getOperator() == ExpressionTree.Operator.LEAF) { leaves.add(node); } else { if (node.getChildren() != null){ nodes.addAll(node.getChildren()); } } } // Update the leaf in place for(ExpressionTree leaf : leaves) { leaf.setLeaf(leafReorder[leaf.getLeaf()]); } return root; }
if (root.getChildren() != null) { int size = root.getChildren().size(); for(int i=0; i < size; ++i) { root.getChildren().set(i, convertToCNF(root.getChildren().get(i))); if (root.getOperator() == ExpressionTree.Operator.OR) { for(ExpressionTree child: root.getChildren()) { if (child.getOperator() == ExpressionTree.Operator.AND) { andList.add(child); } else if (child.getOperator() == ExpressionTree.Operator.OR) { for(ExpressionTree grandkid: child.getChildren()) { nonAndList.add(grandkid); root = new ExpressionTree(ExpressionTree.Operator.AND); generateAllCombinations(root.getChildren(), andList, nonAndList); } else { root = new ExpressionTree(TruthValue.YES_NO_NULL);
private static boolean checkCombinationsThreshold(List<ExpressionTree> andList) { int numComb = 1; for (ExpressionTree tree : andList) { numComb *= tree.getChildren().size(); if (numComb > CNF_COMBINATIONS_THRESHOLD) { return false; } } return true; }
private ExpressionTree and(ExpressionTree... arg) { return new ExpressionTree(ExpressionTree.Operator.AND, arg); }
public SearchArgument.TruthValue evaluate(SearchArgument.TruthValue[] leaves ) { SearchArgument.TruthValue result = null; switch (operator) { case OR: for(ExpressionTree child: children) { result = child.evaluate(leaves).or(result); } return result; case AND: for(ExpressionTree child: children) { result = child.evaluate(leaves).and(result); } return result; case NOT: return children.get(0).evaluate(leaves).not(); case LEAF: return leaves[leaf]; case CONSTANT: return constant; default: throw new IllegalStateException("Unknown operator: " + operator); } }
@Override public Builder startOr() { ExpressionTree node = new ExpressionTree(ExpressionTree.Operator.OR); currentTree.getFirst().getChildren().add(node); currentTree.addFirst(node); return this; }
MessageType schema) throws Exception { FilterPredicate p = null; switch (root.getOperator()) { case OR: for(ExpressionTree child: root.getChildren()) { FilterPredicate childPredicate = translate(child, leaves, columns, schema); if (childPredicate == null) { for(ExpressionTree child: root.getChildren()) { if (p == null) { p = translate(child, leaves, columns, schema); FilterPredicate op = translate(root.getChildren().get(0), leaves, columns, schema); if (op != null) { PredicateLeaf leaf = leaves.get(root.getLeaf()); default: throw new IllegalStateException("Unknown operator: " + root.getOperator());
if (expr.getChildren() != null) { for(int i=0; i < expr.getChildren().size(); ++i) { ExpressionTree child = foldMaybe(expr.getChildren().get(i)); if (child.getConstant() == TruthValue.YES_NO_NULL) { switch (expr.getOperator()) { case AND: expr.getChildren().remove(i); i -= 1; break; expr.getChildren().set(i, child); if (expr.getChildren().isEmpty()) { return new ExpressionTree(TruthValue.YES_NO_NULL);