Remove non-existent outputs from each MatchQuery in the given CompoundMatchQuery.

    Each of the 2^n MatchQuery objects (except one) has been pruned to exclude some Traverse blocks,
    For each of these, remove the outputs (that have been implicitly pruned away) from each
    corresponding ConstructResult block.

    Args:
        compound_match_query: CompoundMatchQuery object containing 2^n pruned MatchQuery objects
                              (see convert_optional_traversals_to_compound_match_query)

    Returns:
        CompoundMatchQuery with pruned ConstructResult blocks for each of the 2^n MatchQuery objects

def prune_non_existent_outputs(compound_match_query):
    """Remove non-existent outputs from each MatchQuery in the given CompoundMatchQuery.

    Each of the 2^n MatchQuery objects (except one) has been pruned to exclude some Traverse blocks,
    For each of these, remove the outputs (that have been implicitly pruned away) from each
    corresponding ConstructResult block.

    Args:
        compound_match_query: CompoundMatchQuery object containing 2^n pruned MatchQuery objects
                              (see convert_optional_traversals_to_compound_match_query)

    Returns:
        CompoundMatchQuery with pruned ConstructResult blocks for each of the 2^n MatchQuery objects
    """
    if len(compound_match_query.match_queries) == 1:
        return compound_match_query
    elif len(compound_match_query.match_queries) == 0:
        raise AssertionError(u'Received CompoundMatchQuery with '
                             u'an empty list of MatchQuery objects.')
    else:
        match_queries = []
        for match_query in compound_match_query.match_queries:
            match_traversals = match_query.match_traversals
            output_block = match_query.output_block

            present_locations_tuple = _get_present_locations(match_traversals)
            present_locations, present_non_optional_locations = present_locations_tuple

            new_output_fields = {}
            for output_name, expression in six.iteritems(output_block.fields):
                if isinstance(expression, OutputContextField):
                    # An OutputContextField as an output Expression indicates that we are not
                    # within an @optional scope. Therefore, the location this output uses must
                    # be in present_locations, and the output is never pruned.
                    location_name, _ = expression.location.get_location_name()
                    if location_name not in present_locations:
                        raise AssertionError(u'Non-optional output location {} was not found in '
                                             u'present_locations: {}'
                                             .format(expression.location, present_locations))
                    new_output_fields[output_name] = expression
                elif isinstance(expression, FoldedContextField):
                    # A FoldedContextField as an output Expression indicates that we are not
                    # within an @optional scope. Therefore, the location this output uses must
                    # be in present_locations, and the output is never pruned.
                    base_location = expression.fold_scope_location.base_location
                    location_name, _ = base_location.get_location_name()
                    if location_name not in present_locations:
                        raise AssertionError(u'Folded output location {} was found in '
                                             u'present_locations: {}'
                                             .format(base_location, present_locations))
                    new_output_fields[output_name] = expression
                elif isinstance(expression, TernaryConditional):
                    # A TernaryConditional indicates that this output is within some optional scope.
                    # This may be pruned away based on the contents of present_locations.
                    location_name, _ = expression.if_true.location.get_location_name()
                    if location_name in present_locations:
                        if location_name in present_non_optional_locations:
                            new_output_fields[output_name] = expression.if_true
                        else:
                            new_output_fields[output_name] = expression
                else:
                    raise AssertionError(u'Invalid expression of type {} in output block: '
                                         u'{}'.format(type(expression).__name__, output_block))

            match_queries.append(
                MatchQuery(
                    match_traversals=match_traversals,
                    folds=match_query.folds,
                    output_block=ConstructResult(new_output_fields),
                    where_block=match_query.where_block,
                )
            )

        return CompoundMatchQuery(match_queries=match_queries)