public static PredicateTreeAnalyzerResult analyzePredicateTree(Predicate predicate) {
        AnalyzerContext context = new AnalyzerContext();
        int treeSize = aggregatePredicateStatistics(predicate, false, context);
        int minFeature = ((int)Math.ceil(findMinFeature(predicate, false, context))) + (context.hasNegationPredicate ? 1 : 0);
        return new PredicateTreeAnalyzerResult(minFeature, treeSize, context.subTreeSizes);
    }
@Test
    void require_that_minfeature_is_min_for_or() {
        Predicate p =
                or(
                        and(
                                feature("foo").inSet("bar"),
                                feature("baz").inSet("qux"),
                                feature("quux").inSet("corge")),
                        and(
                                feature("grault").inSet("garply"),
                                feature("waldo").inSet("fred")));
        PredicateTreeAnalyzerResult r = PredicateTreeAnalyzer.analyzePredicateTree(p);
        assertEquals(2, r.minFeature);
        assertEquals(5, r.treeSize);
        assertEquals(5, r.sizeMap.size());
        assertSizeMapContains(r, pred(p).child(0).child(0), 1);
        assertSizeMapContains(r, pred(p).child(0).child(1), 1);
        assertSizeMapContains(r, pred(p).child(0).child(2), 1);
        assertSizeMapContains(r, pred(p).child(1).child(0), 1);
        assertSizeMapContains(r, pred(p).child(1).child(1), 1);
    }