:- dynamic edge/2.

generar_grafo(N) :-
    retractall(edge(_,_)),
    Limite is N - 1,
    forall(
        between(0, Limite, X),
        (
            X < Limite ->
            Y is X + 1,
            assertz(edge(X,Y))
            ;
            true
        )
    ).

dfs(Nodo, Visitados, Resultado) :-
    member(Nodo, Visitados),
    Resultado = Visitados.

dfs(Nodo, Visitados, Resultado) :-
    \+ member(Nodo, Visitados),

    findall(
        Vecino,
        edge(Nodo,Vecino),
        Vecinos
    ),

    dfs_lista(
        Vecinos,
        [Nodo|Visitados],
        Resultado
    ).

dfs_lista([], Visitados, Visitados).

dfs_lista([H|T], Visitados, Resultado) :-
    dfs(H, Visitados, Temp),
    dfs_lista(T, Temp, Resultado).

ejecutar :-
    generar_grafo(10000),

    statistics(runtime,[T0|_]),

    dfs(0, [], Resultado),

    statistics(runtime,[T1|_]),

    statistics(memory, Memoria),

    Tiempo is T1 - T0,

    length(Resultado, Cantidad),

    format('Nodos visitados: ~w~n', [Cantidad]),
    format('Tiempo (ms): ~w~n', [Tiempo]),
    format('Memoria (bytes): ~w~n', [Memoria]).