<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def ast_from_value(value: Any, type_: GraphQLInputType) -> Optional[ValueNode]: """Produce a GraphQL Value AST given a Python value. A GraphQL type must be provided, which will be used to interpret different Python values. | JSON Value | GraphQL Value | | Object | Input Object | | Array | List | | Boolean | Boolean | | String | String / Enum Value | | Number | Int / Float | | Mixed | Enum Value | | null | NullValue | """

    if is_non_null_type(type_):
        type_ = cast(GraphQLNonNull, type_)
        ast_value = ast_from_value(value, type_.of_type)
        if isinstance(ast_value, NullValueNode):
            return None
        return ast_value

    # only explicit None, not INVALID or NaN
    if value is None:
        return NullValueNode()

    # INVALID or NaN
    if is_invalid(value):
        return None

    # Convert Python list to GraphQL list. If the GraphQLType is a list, but the value
    # is not a list, convert the value using the list's item type.
    if is_list_type(type_):
        type_ = cast(GraphQLList, type_)
        item_type = type_.of_type
        if isinstance(value, Iterable) and not isinstance(value, str):
            value_nodes = [
                ast_from_value(item, item_type) for item in value  # type: ignore
            ]
            return ListValueNode(values=value_nodes)
        return ast_from_value(value, item_type)  # type: ignore

    # Populate the fields of the input object by creating ASTs from each value in the
    # Python dict according to the fields in the input type.
    if is_input_object_type(type_):
        if value is None or not isinstance(value, Mapping):
            return None
        type_ = cast(GraphQLInputObjectType, type_)
        field_nodes: List[ObjectFieldNode] = []
        append_node = field_nodes.append
        for field_name, field in type_.fields.items():
            if field_name in value:
                field_value = ast_from_value(value[field_name], field.type)
                if field_value:
                    append_node(
                        ObjectFieldNode(
                            name=NameNode(value=field_name), value=field_value
                        )
                    )
        return ObjectValueNode(fields=field_nodes)

    if is_leaf_type(type_):
        # Since value is an internally represented value, it must be serialized to an
        # externally represented value before converting into an AST.
        serialized = type_.serialize(value)  # type: ignore
        if is_nullish(serialized):
            return None

        # Others serialize based on their corresponding Python scalar types.
        if isinstance(serialized, bool):
            return BooleanValueNode(value=serialized)

        # Python ints and floats correspond nicely to Int and Float values.
        if isinstance(serialized, int):
            return IntValueNode(value=f"{serialized:d}")
        if isinstance(serialized, float):
            return FloatValueNode(value=f"{serialized:g}")

        if isinstance(serialized, str):
            # Enum types use Enum literals.
            if is_enum_type(type_):
                return EnumValueNode(value=serialized)

            # ID types can use Int literals.
            if type_ is GraphQLID and _re_integer_string.match(serialized):
                return IntValueNode(value=serialized)

            return StringValueNode(value=serialized)

        raise TypeError(f"Cannot convert value to AST: {inspect(serialized)}")

    # Not reachable. All possible input types have been considered.
    raise TypeError(f"Unexpected input type: '{inspect(type_)}'.")