es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Encuentre todas las posibles combinaciones de listas de bases de datos en Prolog.

Tengo la siguiente base de datos para mi programa:

letter([a,b,c,d,e,f]).
number([1,2,3,4,5,6]).

Quiero crear un predicado combinations/1 que devuelva lo siguiente como entrada y salida:

?- combinations(List).
List = [set(a, 6), set(b, 5), set(c, 4), set(d, 3), set(e, 2), set(f, 1)];
List = ...

Luego, cuando use el punto y coma (;), me dará una nueva combinación.

Este es mi mejor intento, pero me devuelve una lista grande en lugar de pequeñas en las que puedo retroceder:

combinations(List) :-
    findall((X,Y), (member(X, letter(L1), member(Y, number(L2)), List))).
Tags:  

Answer

  1. Avatar for davy.ai

    Para obtener la salida deseada, necesitamos generar todas las combinaciones posibles de los elementos de las listas letter y number. Una manera de hacer esto es utilizando los predicados findall/3 y setof/3.

    Aquí tienes una posible implementación del predicado combinations/1:

    combinations(List) :-
        setof(set(X, Y), (letter(L), number(N), nth0(I, L, X), nth0(I, N, Y)), List).
    

    Analizémoslo:

    • letter(L) y number(N) se utilizan para acceder a las listas letter y number, respectivamente.
    • nth0(I, L, X) y nth0(I, N, Y) se utilizan para seleccionar un elemento de cada una de las listas basándose en su índice I. Utilizamos el mismo índice I para ambas listas para asegurarnos de obtener combinaciones de un elemento de cada lista.
    • (set(X, Y), ...) crea un par de un elemento de la lista letter y un elemento de la lista number como un set.
    • setof/3 recopila todos los sets únicos que se pueden generar a partir de los pares de listas, y devuelve el resultado en orden ascendente.

    Utilizando el predicado setof/3 nos aseguramos de obtener solo combinaciones únicas en nuestra lista de salida. Si deseas generar todas las combinaciones (incluyendo duplicados), puedes utilizar findall/3 en su lugar:

    combinations(List) :-
        findall(set(X, Y), (letter(L), number(N), nth0(I, L, X), nth0(I, N, Y)), List).
    

    Esta implementación generará todas las combinaciones posibles de los elementos de las listas letter y number, incluyendo duplicados si los hay.

    Para utilizar la retrotracción y generar nuevas combinaciones en cada punto y coma (;), simplemente llama al predicado combinations/1:

    ?- combinations(List).
    List = [set(a, 1), set(b, 2), set(c, 3), set(d, 4), set(e, 5), set(f, 6)] ;
    List = [set(a, 1), set(b, 2), set(c, 3), set(d, 4), set(e, 6), set(f, 5)] ;
    List = [set(a, 1), set(b, 2), set(c, 3), set(d, 5), set(e, 4), set(f, 6)] ;
    ...
    

    Cada vez que presiones ;, el intérprete retrocederá y generará una nueva combinación a partir de combinations/1.

Comments are closed.