<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def process_filter_directive(filter_operation_info, location, context):
 """Return a Filter basic block that corresponds to the filter operation in the directive. Args: filter_operation_info: FilterOperationInfo object, containing the directive and field info of the field where the filter is to be applied. location: Location where this filter is used. context: dict, various per-compilation data (e.g. declared tags, whether the current block is optional, etc.). May be mutated in-place in this function! Returns: a Filter basic block that performs the requested filtering operation """

    op_name, operator_params = _get_filter_op_name_and_values(filter_operation_info.directive)

    non_comparison_filters = {
        u'name_or_alias': _process_name_or_alias_filter_directive,
        u'between': _process_between_filter_directive,
        u'in_collection': _process_in_collection_filter_directive,
        u'has_substring': _process_has_substring_filter_directive,
        u'contains': _process_contains_filter_directive,
        u'intersects': _process_intersects_filter_directive,
        u'has_edge_degree': _process_has_edge_degree_filter_directive,
    }
    all_recognized_filters = frozenset(non_comparison_filters.keys()) | COMPARISON_OPERATORS
    if all_recognized_filters != ALL_OPERATORS:
        unrecognized_filters = ALL_OPERATORS - all_recognized_filters
        raise AssertionError(u'Some filtering operators are defined but do not have an associated '
                             u'processing function. This is a bug: {}'.format(unrecognized_filters))

    if op_name in COMPARISON_OPERATORS:
        process_func = partial(_process_comparison_filter_directive, operator=op_name)
    else:
        process_func = non_comparison_filters.get(op_name, None)

    if process_func is None:
        raise GraphQLCompilationError(u'Unknown op_name for filter directive: {}'.format(op_name))

    # Operators that do not affect the inner scope require a field name to which they apply.
    # There is no field name on InlineFragment ASTs, which is why only operators that affect
    # the inner scope make semantic sense when applied to InlineFragments.
    # Here, we ensure that we either have a field name to which the filter applies,
    # or that the operator affects the inner scope.
    if (filter_operation_info.field_name is None and
            op_name not in INNER_SCOPE_VERTEX_FIELD_OPERATORS):
        raise GraphQLCompilationError(u'The filter with op_name "{}" must be applied on a field. '
                                      u'It may not be applied on a type coercion.'.format(op_name))

    fields = ((filter_operation_info.field_name,) if op_name != 'name_or_alias'
              else ('name', 'alias'))

    context['metadata'].record_filter_info(
        location,
        FilterInfo(fields=fields, op_name=op_name, args=tuple(operator_params))
    )

    return process_func(filter_operation_info, location, context, operator_params)