Lógica: Funciones Varias (Paradigmas)

De Cuba-Wiki
Saltar a: navegación, buscar
Back.png Volver a la página de la materia

Funciones Varias[editar]

%repeat(-Elemento, -Lista).
% Requiere: true.
% Asegura: Lista es una lista que contiene solamente a Elem (cero o mas veces).

repeat(_, []). 
repeat(Elem, [Elem | Tail]) :- repeat(Elem, Tail). 

%multi_length(-Lista_de_Listas, -Lista_de_Longuitudes).
% Requiere: Lista_de_Listas es una lista de listas, y Lista_de_Longuitudes es una lista de naturales.
% Asegura: Lista_de_Longuitudes es una lista que contiene las longuitudes de los elementos de Lista_de_Listas.

multi_length([], []). 
multi_length([X | XS], [L | LS]) :- length(X, L), multi_length(XS, LS). 

%multi_append(-Lista_de_Listas, -Listas_Unidas).
% Requiere: Lista_de_Listas no contiene ninguna lista vacia, pero ella si puede ser la lista vacia.
% Asegura: Listas_Unidas son todas las listas de la listas unidas,
% en el orden en que aparecian en la lista de listas.

multi_append([], []). 
multi_append([[X] | YS], [X | ZS]) :- multi_append(YS, ZS). 
multi_append([[X1, X2 | XS] | YS], [X1 | ZS]) :- multi_append([[X2 | XS] | YS], ZS). 

%particion_doble(-Parte1, -Parte2, -Lista).
% Requiere: true.
% Asegura: Parte1 y Parte2 son una particion de Lista en dos listas,
% preservando en ellas el orden relativo original de los elementos.

particion_doble([], [], []). 
particion_doble([X | XS], [], [X | XS]). 
particion_doble([], [Y | YS], [Y | YS]). 
particion_doble([X | XS], [Y | YS], [X | ZS]) :- particion_doble(XS, [Y | YS], ZS). 
particion_doble([X | XS], [Y | YS], [Y | ZS]) :- particion_doble([X | XS], YS, ZS). 

%particion_doble_sin_vacio(-Parte1, -Parte2, -Lista).
% Requiere: true.
% Asegura: Parte1 y Parte2 son una particion de Lista en dos listas (ninguna vacia),
% preservando en ellas el orden relativo original de los elementos.

particion_doble_sin_vacio([X], [Y | YS], [X, Y | YS]). 
particion_doble_sin_vacio([X1, X2 | XS], [Y | YS], [X1 | ZS]) :- particion_doble_sin_vacio([X2 | XS], [Y | YS], ZS). 
particion_doble_sin_vacio([X1, X2 | XS], [Y | YS], [X1 | ZS]) :- particion_doble_sin_vacio([Y | YS], [X2 | XS], ZS). 

%particion(-ListaDeSublistas, +Lista).
% Requiere: Lista es una Lista, ListaDeSublistas una lista de listas.
% Asegura: ListaDeSublistas es una lista de sublistas disjuntas que forman Lista.

particion([], []). 
particion( XS, [X | XS]). 
particion([[X | XS], Y | YS], ZS) :- particion_doble_sin_vacio([X | XS], PS, ZS). 

%particion_de_longuitud_n(+Lista, +Longuitud, -ListaDeSublistas)
% Requiere: Lista es una Lista de longuitud multiplo de Longuitud, ListaDeSublistas una lista de listas.
% Asegura: ListaDeSublistas es una lista de sublistas disjuntas que forman Lista cada una de longuitud Longuitud.

particion_de_longuitud_n(Lista, Longuitud, ListaDeSublistas) :- particion(ListaDeSublistas, Lista), 
length(Lista, Length_Lista), Cantidad is Length_Lista // Longuitud, 
repeat(Longuitud, Lista_Longs), length(Lista_Longs, Cantidad), 
multi_length(ListaDeSublistas, Lista_Longs). 

%lista_de_grupos(+Lista_de_Paises_en_Grupos, +Ids, -Grupos).

lista_de_grupos([], [], []). 
lista_de_grupos([P | PS], [I | IS], [grupo(I, P) | GS]) :- lista_de_grupos(PS, IS, GS). 

% Requiere: length(Lista_de_Paises_en_Grupos) == length(Ids).
% Asegura: Grupos es la formacion de grupos asignando un id a cada grupo de paises de la lista.
%mesclar_particiones_de_listas(-Particiones, +Listas_de_Listas).

grupos(Ps, Ids, Grupos) :- lista_de_grupos(Lista_de_Paises_en_Grupos, Ids, Grupos). 

%grupos(+Ps, +Ids, -Grupos)

grupos(Ps, Ids, Grupos) :- lista_de_grupos(Lista_de_Paises_en_Grupos, Ids, Grupos). 

paises([[argentina, brasil], [mejico,canada], 
[sudafrica, egipto]]). 
listas([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]). 
listas2([1, 2, 3]).

Funciones de Numeros[editar]

%es_natural(-Numero).

es_natural(0). 
es_natural(N) :- es_natural(N1), N is N1 + 1. 

%es_positivo(-Numero).

es_positivo(1). 
es_positivo(N) :- es_natural(N1), N is N1 + 1. 

%es_negativo(-Numero).

es_negativo(-1). 
es_negativo(N) :- es_negativo(N1), N is N1 - 1. 

%diferencia_con_siguiente_entero(-Signo, +Numero).

diferencia_con_siguiente_entero(1, 0). 
diferencia_con_siguiente_entero(1, N) :- N > 0. 
diferencia_con_siguiente_entero(0, N) :- N < 0. 

%es_entero(-Signo, +Numero).

es_entero(0). 
es_entero(N) :- es_entero(M), NM is -M, diferencia_con_siguiente_entero(S, NM), 
N is NM + S. 

%signo_aux(-Signo, +Numero).

signo_aux(0, 0). 
signo_aux(1, N) :- N > 0. 
signo_aux(-1, N) :- N < 0. 

%signo(-Signo, -Numero).

signo(0, 0). 
signo(S, N) :- es_entero(N), N \= 0, signo_aux(S, N). 

%en_rango(-Numero, +Desde, +Hasta).

en_rango(D, D, H) :- D =< H. 
en_rango(N, D, H) :- D =< H, ND is D + 1, en_rango(N, ND, H). 

%desde(-Numero, +Desde).

desde(D, D). 
desde(N, D) :- DD is D+1, desde(N, DD).

%entre(+A, +B, -X)

entre(A, B, A) :- number(A), number(B), B >= A.
entre(A, B, X) :- AA is A+1, B >= AA, entre(AA, B, X).

Funciones de Arboles[editar]

%es_arbol_de_altura(-Arbol, +Altura).

es_arbol_de_altura(nil, 0). 
es_arbol_de_altura(bin(I, _, D), H) :- H > 0, H1 is H - 1, 
en_rango(HI, 0, H1), 
en_rango(HD, 0, H1), H1 is max(HD, HI), 
es_arbol_de_altura(I, HI), es_arbol_de_altura(D, HD). 

%altura(-Arbol, -Altura).

altura(A, H) :- es_natural(H), es_arbol_de_altura(A, H). 

%preorder_de_arboles(-Nodos, -Arbol).

preorder_de_arboles([], []). 
preorder_de_arboles(L, [nil | AS]) :- preorder_de_arboles(L, AS). 
preorder_de_arboles([X | XS], [bin(I, X, D) | AS]) :- preorder_de_arboles(XS, [I, D | AS]). 

%preorder(-Nodos, -Arbol).

preorder(L, A) :- preorder_de_arboles(L, [A]). 

Funciones de Listas[editar]

% map_tomar_uno_de_lista(-Reordenado, -Resto, +ListaDeListas)
% Requiere: true.
% Asegura: Reordenado es una lista formada agarrando un elemento de cada sublista
% de ListaDeListas y Resto es lo que queda despues de sacar eso.
% Uso:

map_tomar_uno_de_lista([], [], []). 
map_tomar_uno_de_lista([H | T], [R | RS], [L | LS]) :- particion_doble_unicas_vacia([H], R, L), 
map_tomar_uno_de_lista(T, RS, LS). 

% particion(-ListaDeSublistas, +Lista).
% Requiere: true.
% Asegura: ListaDeSublistas es una lista de sublistas disjuntas que forman Lista.

particion( XS, [X | XS]).
particion([[X | XS], Y | YS], ZS) :- particion_doble_unicas([X | XS], WS, ZS), particion(Y | YS, WS). 

% particion_doble_unicas(-Parte1, -Parte2, -Lista).
% Requiere: true.
% Asegura: Parte1 y Parte2 son una particion de Lista en dos listas (ninguna vacia),
% preservando en ellas el orden relativo original de los elementos.

particion_doble_unicas([X], [Y | YS], [X, Y | YS]). 
particion_doble_unicas([X1, X2 | XS], [Y | YS], [X1 | ZS]) :- particion_doble_unicas([X2 | XS], [Y | YS], ZS). 
particion_doble_unicas([X1, X2 | XS], [Y | YS], [X1 | ZS]) :- particion_doble_unicas([Y | YS], [X2 | XS], ZS). 

% particiones_de_longuitud_n(-ListaDeSublistas, +Longuitud, +Lista)
% Requiere: true.
% Asegura: ListaDeSublistas es una lista de sublistas disjuntas que forman Lista cada una de longuitud Longuitud.

particiones_de_longuitud_n([XS], L, XS) :- length(XS, L). 
particiones_de_longuitud_n([X | XS], L, ZS) :- not(length(ZS, L)), particion_doble_unicas(X, YS, ZS), length(X, L), 
particiones_de_longuitud_n(XS, L, YS). 

% map_particiones_de_longuitud_n(-Sublistas, +CantidadDeGrupos, +Listas)
% Requiere: true.
% Asegura: similar a Haskell: map particiones_de_longuitud_n.

map_particiones_de_longuitud_n([], N, []) :- N > 0. 
map_particiones_de_longuitud_n([X | XS], N, [Y | YS]) :- map_particiones_de_longuitud_n(XS, N, YS), 
particiones_de_longuitud_n(X, N, Y). 

% iesimos_elementos(-Iesimos, +Indice, -ListaDeListas)
% Requiere: true.
% Asegura: Iesimos son los iesimos elementos de cada lista de ListaDeListas.

iesimos_elementos([], N, []) :- N >= 0. 
iesimos_elementos([E | XS], I, [Y | YS]) :- nth0(I, Y, E), iesimos_elementos(XS, I, YS). 

% generar_listas_tomando_de_listas_entre_iesimos(-Reordenado, +Desde, +Hasta, +ListaDeListas)

generar_listas_tomando_de_listas_entre_iesimos([], D, H, L) :- D > H, is_list(L). 
generar_listas_tomando_de_listas_entre_iesimos([X | XS], D, H, YS) :- D =< H, D1 is D + 1, iesimos_elementos(X, D, YS), 
generar_listas_tomando_de_listas_entre_iesimos(XS, D1, H, YS). 

% last(+N, -Tail, -Lista).
% Requiere: true.
% Asegura: Tail son los ultimos n elementos de Lista.

last(N, Tail, Lista) :- length(Tail, N), append(_, Tail, Lista). 

% sin_iesimo(-ListaSinIesimo, -Indice, -Lista)
% Requiere: true
% Asegura: ListaSinIesimo es la lista sin el elemento en la posicion Indice de Lista.

sin_iesimo(NL, I, L) :- append(Init, [_ | Tail], L), length(Init, I), append(Init, Tail, NL). 

% sin_primera_aparicion(-ListaSinElemento, -Elemento, -Lista)
% Requiere: true.
% Asegura: ListaSinElemento es igual a Lista sin la primera aparicion del elemento.

sin_primera_aparicion(ZS, E, L) :- append(ZS1, [E | ZS2], L), append(ZS1, ZS2, ZS), not(member(E, ZS1)). 

% concat(-Lista_de_Listas, -Listas_Unidas).
% Requiere: true.
% Asegura: Listas_Unidas son todas las listas de la listas unidas,
% en el orden en que aparecian en la lista de listas.

concat([], []). 
concat([[X] | YS], [X | ZS]) :- concat(YS, ZS). 
concat([[X1, X2 | XS] | YS], [X1 | ZS]) :- concat([[X2 | XS] | YS], ZS). 

% map_concat(-ListaDeListasDeListas, +ListasMappeadas)
% Requiere: true.
% Asegura: similar a Haskell: map concat

map_concat([], []). 
map_concat([X | XS], [Y | YS]) :- concat(X, Y), map_concat(XS, YS). 

% take(+N, -Tail, -Lista).
% Requiere: true.
% Asegura: Tail son los elementos que quedan luego de sacar los n primeros
% elementos a Lista.

drop(N, Tail, Lista) :- length(Init, N), append(Init, Tail, Lista). 

% pertenece(-Elemento, -Lista)
% Requiere: true
% Asegura: Elemento pertenece a Lista.

pertenece(E, L) :- append(_, [E | _], L). 

% sin_un_elemento(-ListaSinElemento, -Elemento, -Lista)
% Requiere: true.
% Asegura: ListaSinElemento es igual a Lista sin una vez ese elemento.

sin_un_elemento(ZS, E, L) :- append(ZS1, [E | ZS2], L), append(ZS1, ZS2, ZS). 

% sin_elemento(-ListaSinElementos, +Elemento, +Lista)
% Requiere: true.
% Asegura: ListaSinElementos es igual a Lista sin todas las apariciones del elemento.

sin_elemento([], _, []). 
sin_elemento(L, H, [H | T]) :- sin_elemento(L, H, T). 
sin_elemento([H | L], E, [H | T]) :- E \= H, sin_elemento(L, E, T). 

% iesimo(-Elemento, -Indice, -Lista)
% Requiere: true
% Asegura: Elemento es el elemento en la posicion Indice de Lista.

iesimo(E, I, L) :- append(Init, [E | _], L), length(Init, I). 

% interseccion(-Interseccion, +ListaL, +ListaR)
% Requiere: true.
% Asegura: Interseccion es la interseccion sin duplicados de ListaL y ListaR
% manteniendo el orden de los elementos en ListaL.

interseccion([], [], []). 
interseccion([E | ZS], [E | LL], LRE) :- member(E, LRE), delete(LRE, E, LR), 
interseccion(ZS, LL, LR). 
interseccion(ZS, [E | LL], LR) :- not(member(E, LR)), interseccion(ZS, LL, LR). 

% sin_repetidos(-ListaSinRepetidos, +Lista).
% Requiere: true.
% Asegura: ListaSinRepetidos es igual a Lista solo que no tiene repetidos.

sin_repetidos([], []). 
sin_repetidos([E | XS], [E | YS]) :- not(member(E, YS)), sin_repetidos(XS, YS). 
sin_repetidos(XS, [E | YS]) :- member(E, YS), sin_repetidos(XS, YS). 
sin_repetidos([E | XS], [E | YS]) :- member(E, YS), sin_repetidos(XSE, YS), 
select(E, XSE, XS).