<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def has_equal_ast( state, incorrect_msg="Check the {ast_path}. {extra}", sql=None, start=["expression", "subquery", "sql_script"][0], exact=None, ):
 """Test whether the student and solution code have identical AST representations Args: state: State instance describing student and solution code. Can be omitted if used with Ex(). incorrect_msg: feedback message if student and solution ASTs don't match sql : optional code to use instead of the solution ast that is zoomed in on. start: if ``sql`` arg is used, the parser rule to parse the sql code. One of 'expression' (the default), 'subquery', or 'sql_script'. exact: whether to require an exact match (True), or only that the student AST contains the solution AST. If not specified, this defaults to ``True`` if ``sql`` is not specified, and to ``False`` if ``sql`` is specified. You can always specify it manually. :Example: Example 1 - Suppose the solution code is :: SELECT * FROM cities and you want to verify whether the `FROM` part is correct: :: Ex().check_node('SelectStmt').from_clause().has_equal_ast() Example 2 - Suppose the solution code is :: SELECT * FROM b WHERE id > 1 AND name = 'filip' Then the following SCT makes sure ``id > 1`` was used somewhere in the WHERE clause.:: Ex().check_node('SelectStmt') \\/ .check_edge('where_clause') \\/ .has_equal_ast(sql = 'id > 1') """

    ast = state.ast_dispatcher.ast_mod
    sol_ast = state.solution_ast if sql is None else ast.parse(sql, start)

    # if sql is set, exact defaults to False.
    # if sql not set, exact defaults to True.
    if exact is None:
        exact = sql is None

    stu_rep = repr(state.student_ast)
    sol_rep = repr(sol_ast)

    def get_str(ast, code, sql):
        if sql:
            return sql
        if isinstance(ast, str):
            return ast
        try:
            return ast.get_text(code)
        except:
            return None

    sol_str = get_str(state.solution_ast, state.solution_code, sql)
    _msg = incorrect_msg.format(
        ast_path=state.get_ast_path() or "highlighted code",
        extra="The checker expected to find `{}` in there.".format(sol_str)
        if sol_str
        else "Something is missing.",
    )
    if (exact and (sol_rep != stu_rep)) or (not exact and (sol_rep not in stu_rep)):
        state.report(Feedback(_msg))

    return state