def create_new_symbol(
    name: Optional[str] = None,
    values: Optional[List[int]] = None,
    check_duplicate: bool = False,
) -> sympy.Symbol:
    """
    Creates and memoizing symbols.

    Parameters
    ----------
    name : Optional[str]
        The symbol name that is going to be used. If None is provided, an unused
        name would be created.
    values : Optional[List[int]]
        The values for IntVar, which indicates the range of which the symbol could
        represent.
    check_duplicate : bool
        If set as True and name is provided, we check whether the name and values
        provided matches the corresponding symbol recorded.
    """
    global _k_symbolic_index
    global _k_symbolic_value

    if name is None:
        while True:
            name = f"_sym_{_k_symbolic_index}"
            _k_symbolic_index += 1

            if name not in _k_symbolic_value:
                break

    values = sorted(set(values)) if values is not None else values
    if (
        check_duplicate
        and name in _k_symbolic_value
        and _k_symbolic_value[name] != values
    ):
        raise ValueError(
            f"Symbol ({name}) has different values! New value is {values}, stored value is {_k_symbolic_value[name]}"
        )

    _k_symbolic_value[name] = values
    return sympy.Symbol(name)

    Creates and memoizing symbols.

    Parameters
    ----------
    name : Optional[str]
        The symbol name that is going to be used. If None is provided, an unused
        name would be created.
    values : Optional[List[int]]
        The values for IntVar, which indicates the range of which the symbol could
        represent.
    check_duplicate : bool
        If set as True and name is provided, we check whether the name and values
        provided matches the corresponding symbol recorded.
    
python/aitemplate/compiler/symbolic.py