<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def validate(pfeed, *, as_df=True, include_warnings=True):
 """ Check whether the given pfeed satisfies the ProtoFeed spec. Parameters pfeed : ProtoFeed as_df : boolean If ``True``, then return the resulting report as a DataFrame; otherwise return the result as a list include_warnings : boolean If ``True``, then include problems of types ``'error'`` and ``'warning'``; otherwise, only return problems of type ``'error'`` Returns ------- list or DataFrame Run all the table-checking functions: :func:`check_agency`, :func:`check_calendar`, etc. This yields a possibly empty list of items [problem type, message, table, rows]. If ``as_df``, then format the error list as a DataFrame with the columns - ``'type'``: 'error' or 'warning'; 'error' means the ProtoFeed spec is violated; 'warning' means there is a problem but it's not a ProtoFeed spec violation - ``'message'``: description of the problem - ``'table'``: table in which problem occurs, e.g. 'routes' - ``'rows'``: rows of the table's DataFrame where problem occurs Return early if the pfeed is missing required tables or required columns. """

    problems = []

    # Check for invalid columns and check the required tables
    checkers = [
      'check_frequencies',
      'check_meta',
      'check_service_windows',
      'check_shapes',
      'check_stops',
    ]
    for checker in checkers:
        problems.extend(globals()[checker](pfeed,
          include_warnings=include_warnings))

    return gt.format_problems(problems, as_df=as_df)