Es importante conocer este concepto para poder aplicar todas las reglas posteriores de recursión y listas. Teniendo una base de hechos como por ejemplo:
% hecho(Nombre, Género, Año_de_estreno, Calificación).
movie('Inception', science_fiction, 2010, 8.8).
movie('The Godfather', drama, 1972, 9.2).
movie('Toy Story', animated, 1995, 8.3).
movie('The Dark Knight', action, 2008, 9.0).
movie('Pulp Fiction', drama, 1994, 8.9).
movie('Interstellar', science_fiction, 2014, 8.6).
movie('The Matrix', science_fiction, 1999, 8.7).
Si quisieramos operar sobre el atributo Calificación de todos los hechos para, por ejemplo, calcular el promedio, debemos convertir los hechos en una lista.
Utilizamos findall
findall(Rating, movie(_, _, _, Rating), Ratings)
donde:
Rating
(singular) es el nombre que le damos al atributo/campomovie
es el hecho._
son campos que no nos interesan incluir en la lista.Ratings
(plural) es el nombre de la lista resultantefindall(Rating, movie(_, _, _, Rating), Ratings)
Ratings = [8.8, 9.2, 8.3, 9.0, 8.9, 8.6, 8.7]
Obtenemos una lista con las calificaciones de las peliculas. De esta manera, podremos aplicar reglas como Sumatoria y Longitud de una lista sobre la base de hechos definida, para luego calcular el promedio.
longitud([], 0).
longitud([_|B], X):-
longitud(B, N1), X is N1 + 1.
?- longitud([1, 2, 3, a, 5],Longitud)
Longitud = 5
sumatoria([], 0).
sumatoria([Cabeza | Resto], Suma) :-
sumatoria(Resto, SumaResto),
Suma is Cabeza + SumaResto.
promedioCalificaciones(Promedio):-
findall(Rating, movie(_, _, _, Rating), Ratings),
longitud(Ratings, Longitud),
sumatoria(Ratings, Total),
Promedio is (Total / Longitud).
promedioCalificaciones(Promedio)
Promedio = 8.785714285714286
sumatoria([], 0).
sumatoria([Cabeza | Resto], Suma) :-
sumatoria(Resto, SumaResto),
Suma is Cabeza + SumaResto.
Consulta
?-sumatoria([1, 2, 3], Resultado).
Resultado = 6
% Caso base
suma([], [], 0).
% Caso con segunda lista vacía
suma([Cabeza1 | Resto1], [], Suma) :-
suma(Resto1, [], SumaResto),
Suma is Cabeza1 + SumaResto.
% Caso con primera lista vacía
suma([], [Cabeza2 | Resto2], Suma) :-
suma([], Resto2, SumaResto),
Suma is Cabeza2 + SumaResto.
% Caso con ambas listas con elementos
suma([Cabeza1 | Resto1], [Cabeza2 | Resto2], Suma) :-
suma(Resto1, Resto2, SumaResto),
Suma is Cabeza1 + Cabeza2 + SumaResto.
Consulta Esta implementación permite sumar listas con diferente cantidad de elementos, incluso con una de ellas vacía.
?- suma([1, 2, 3], [1], Resultado). % Resultado = 7
?- suma([1, 2, 3], [1, 2], Resultado). % Resultado = 9
?- suma([1, 2, 3], [1, 2, 3], Resultado). % Resultado = 12
?- suma([1], [1, 2, 3], Resultado). % Resultado = 7
?- suma([1, 2], [1, 2, 3], Resultado). % Resultado = 9
?- suma([1, 2, 3], [1, 2, 3], Resultado). % Resultado = 12
suma([1, 2, 3], [], Resultado). % Resultado = 6
suma([], [1, 2, 3], Resultado). % Resultado = 6
member(X, [X|_]).
member(X, [_|Y]):- member(X, Y).
member(X, [X|_])
: verifica si el elemento X es el primer elemento de la lista. Si esto es verdadero devuelve true
.
member(X, [_|Y]) :- member(X, Y).
: verifica si X está en el resto de la lista Y.
concatenar([], L, L). % Caso base: concatenar una lista vacía con L da como resultado L.
concatenar([X|Resto], L, [X|Resultado]) :-
concatenar(Resto, L, Resultado). % Caso recursivo: agrega el primer elemento de la primera lista a Resultado y llama recursivamente.
concatenar([1, a], [4, 5, 6], Resultado).
Resultado = [1, a, 4, 5, 6]
longitud([], 0).
longitud([_|B], X):- longitud(B, N1), X is N1 + 1.
longitud([1,2, [a]], A)
A = 3
concatenar([], L, L). % Caso base: si la primera lista es vacía, el resultado es la segunda lista.
concatenar([X|Resto], L, [X|Resultado]) :-
concatenar(Resto, L, Resultado). % Caso recursivo: agrega el primer elemento de la primera lista a Resultado y llama recursivamente.
?- concatenar([a1, a2, a3], [b1, b2, b3], Resultado).
Resultado = [a1, a2, a3, b1, b2, b3]
✍️ Autor: Emilio Giordano
🔗 Más resúmenes de Programación Declarativa en el repositorio