Implementación de Algoritmos Clásicos en Prolog: Triángulo de Pascal, Conjetura de Goldbach y Manipulación de Listas
Colección de Predicados Fundamentales en Prolog
Este documento presenta una colección de implementaciones en Prolog para resolver problemas clásicos de matemáticas y manipulación de estructuras de datos (listas), utilizando la potencia de la programación lógica y la recursividad.
Implementación del Triángulo de Pascal
Predicados para generar el nivel N del Triángulo de Pascal.
nivel_pascal(1, [1]).
nivel_pascal(2, [1, 1]).
nivel_pascal(N, Nivel) :-
N > 2,
N1 is N - 1,
nivel_pascal(N1, NivelAnterior),
siguiente_nivel(NivelAnterior, Nivel).
siguiente_nivel([1], [1, 1]).
siguiente_nivel([X|T], [1|R]) :-
siguiente_nivel_aux([X|T], R).
siguiente_nivel_aux([1], [1]).
siguiente_nivel_aux([X,Y|T], [S|R]) :-
S is X + Y,
siguiente_nivel_aux([Y|T], R).
fila(N, Fila) :-
nivel_pascal(N, Fila).Operaciones de Conjuntos: Cálculo de la No Intersección
Predicados para encontrar los elementos que no son comunes entre dos listas (diferencia simétrica implícita, calculada en dos pasos).
Verificación de Pertenencia
miembro(X,[X|_]).
miembro(X,[_|Y]):-
miembro(X,Y).Cálculo de la No Intersección
nointer([],_,[]).
nointer([X|Y],L2,[X|R]):-
\+miembro(X,L2),
nointer(Y,L2,R).
nointer([X|Y],L2,R):-
miembro(X,L2),
nointer(Y,L2,R).
nointercomp(L1,L2,R):-
nointer(L1,L2,R1),
nointer(L2,L1,R2),
concatenar(R1,R2,R).Teoría de Números y Predicados Primos
Conjetura de Goldbach
Implementación para encontrar dos números primos (P1 y P2) cuya suma sea igual a un número par N (mayor que 2).
goldbach(N,P1,P2):-
N>2,
0 is N mod 2,
P2aux is N-2,
auxgoldbach(N,P1,P2,2,P2aux).
auxgoldbach(N,P1,P2,P1aux,P2aux):-
primo(P1aux),
primo(P2aux),
P1 is P1aux,
P2 is P2aux.
auxgoldbach(N,P1,P2,P1aux,P2aux):-
P1aux2 is P1aux+1,
P2aux2 is P2aux-1,
P2aux2>=2,
auxgoldbach(N,P1,P2,P1aux2,P2aux2).Verificación de Números Primos
primo(X):-
X>1,
nodiv(2,X).
nodiv(N,N).
nodiv(N,X):-
0 =\= X mod N,
N1 is N+1,
nodiv(N1,X).Obtener Primos por Debajo de un Número
primos(N,X):-
es_primo(2,N,X).
es_primo(I,S,X):-
I=Reducción de Cadenas (Run-Length Encoding)
Predicado redcad para comprimir una lista de elementos consecutivos, indicando el elemento y su conteo (similar a la codificación Run-Length Encoding).
redcad([],[]).
redcad([X],[X,1]).
redcad([X,X|Y],[X,C|Y2]):-
redcad([X|Y],[X,C1|Y2]),
C is C1+1.
redcad([X,Y|Z],[X,1|R]):-
X\=Y,
redcad([Y|Z],R).Implementación de la Sucesión de Collatz
Predicados para calcular la longitud de la secuencia de Collatz para un número dado o para un rango de números.
collatz(S,S,S,NP):-
conjetura(S,0,NP).
collatz(I,S,N,NP):-
I1,
0 is N mod 2,
D is N/2,
C1 is Cont+1,
conjetura(D,C1,R).
conjetura(N,Cont,R):-
N>1,
D is (3*N)+1,
C1 is Cont+1,
conjetura(D,C1,R).Predicados Fundamentales para la Manipulación de Listas
Concatenación de Listas
concatenar([],L,L).
concatenar([X|L1],L2,[X|L3]):-
concatenar(L1,L2,L3).Obtener Primeros Elementos (Todos menos el Último)
primeros([_],[]).
primeros([X|Y],[X|Y2]):-
primeros(Y,Y2).Obtener Último Elemento de una Lista
ultimo([X],X).
ultimo([_|X],U):-
ultimo(X,U).Eliminación de Elementos Repetidos de una Lista
borrar_repes([],[]).
borrar_repes([X|Y],[X|L]):-
borrartodos(X,Y,L1),
borrar_repes(L1,L).
borrartodos(X,[],[]).
borrartodos(X,[X|Y],Y2):-
borrartodos(X,Y,Y2).
borrartodos(X,[Y|Z],[Y|Y2]):-
X\=Y,
borrartodos(X,Z,Y2).Aplanar una Lista
Nota: Esta implementación parece incompleta o incorrecta para aplanar listas anidadas de forma general, ya que la segunda cláusula aplanar([X|Y],[X|Y]) detiene la recursión prematuramente.
aplanar([],[]).
aplanar([X|Y],[X|Y]).
aplanar([L,Y|L1],C):-
concatenar(L,[Y],C),
aplanar(L1,C).Prefijos y Sufijos de una Lista
Predicados para generar o verificar prefijos y sufijos.
Prefijos
prefijo([_|_],[]).
prefijo([X],[X]).
prefijo([X|Y],[X|Y2]):-
prefijo(Y,Y2).Sufijos
sufijo([_],[]).
sufijo([X|Y],[X|Y]).
sufijo([_|Y],L):-
sufijo(Y,L).Rotación de Listas N Posiciones a la Derecha
rotarNderecha(L,0,L).
rotarNderecha(L,1,R):-
rotar_derecha(L,R).
rotarNderecha(L,N,R):-
N>1,
N1 is N-1,
rotar_derecha(L,R1),
rotarNderecha(R1,N1,R).
rotar_derecha(L,R):-
primeros(L,P),
ultimo(L,U),
concatenar([U],P,R).