You are on page 1of 74

PARADIGMA.

Thomas Kuhn : " muestras aceptadas de mtodos


prcticos en la ciencia

Adam Smith : "Un conjunto compartido de hechos


asumidos. Agua para el pez, el paradigma explica el
mundo y permite predecir su comportamiento. Estando en
medio del paradigma, es difcil imaginar otro".
PARADIGMA
Willis Hartman : " la manera bsica de percibir, pensar,
valorar y hacer cosas asociadas con una visin particular
de la realidad."

Marilyn Ferguson : " un marco de pensamiento un


esquema para entender y explicar ciertos aspectos de la
realidad".
PARADIGMA
Joel Barker : " un conjunto de reglas que definen
lmites, y establecen lo debido para tener xito dentro de
esos lmites".

Para tener en cuenta: Los seres humanos tenemos


paradigmas con POCAS reglas, y una tendencia FUERTE a
aferrarnos a ellas.
SWI PROLOG
Qu es Prolog?

Prolog = PROgramming in LOGic.


Desarrollado a partir de trabajos en demostracin
automtica de teoremas
Aplicado inicialmente en problemas de Procesamiento
del Lenguaje Natural
Permite un prototipado ms rpido que con muchos
lenguajes porque es mucho ms proximo a la
especificacin lgica del programa.
Qu es Prolog?

Lenguaje de Programacin

Computacin simblica y no-numrica

Para resolver problemas que involucran

OBJETOS

RELACIONES
Para programar en Prolog:

Declarar hechos sobre objetos y sus relaciones

Declarar reglas sobre los objetos y sus relaciones

Hacer preguntas sobre los objetos y sus relaciones


Hechos

Raquel es hija de teresa


es_hija (raquel, teresa).

Objetos: raquel, teresa.


Relacin: hija

Observar:

Minsculas
El punto final
pedro maria
Ejemplo:

progenitor (pedro, teresa).


progenitor (maria, teresa). teresa elena
progenitor (maria, elena).
progenitor (teresa, jorge).
jorge raquel
progenitor (teresa, raquel).
progenitor (raquel, miguel).

miguel
clusulas
?- progenitor (teresa, raquel). pedro maria
Yes

?- progenitor (jorge, miguel).


No
teresa elena
?- progenitor (X, raquel).
X = teresa ;
No
jorge raquel
?- progenitor (teresa, Y).
Y = jorge ;
Y = raquel ;
No miguel
pedro maria
?- progenitor (X, Y).
X = pedro
Y = teresa ;
X = maria
Y = teresa ; teresa elena
X = maria
Y = elena ;
X = teresa
Y = jorge ;
jorge raquel
X = teresa
Y = raquel ;
X = raquel
Y = miguel ; miguel
No
pedro maria
Quin es abuelo de jorge?

?- progenitor (PoM, jorge),


progenitor (Abuelo, PoM).
teresa elena
PoM = teresa
Abuelo = pedro ;

PoM = teresa jorge raquel


Abuelo = maria ;

No
miguel
pedro maria
Quin es nieto de pedro?

?- progenitor (pedro, Hijo),


progenitor (Hijo, Nieto).
teresa elena
Hijo = teresa
Nieto = jorge ;

Hijo = teresa jorge raquel


Nieto = raquel ;

No
miguel
pedro maria
Quin es abuelo de jorge?

?- progenitor (X, jorge),


progenitor (Y, X).
teresa elena
X = teresa
Y = pedro ;

X = teresa jorge raquel


Y = maria ;

No
miguel
Paso 1.
Quin es abuelo de jorge?

?- progenitor (X, jorge), progenitor (Y, X).


teresa).

progenitor (pedro, teresa).


progenitor (maria, teresa).
X = teresa progenitor (maria, elena).
progenitor (teresa, jorge).
progenitor (teresa, raquel).
progenitor (raquel, miguel).

La base de hechos
Paso 2.
Quin es abuelo de jorge?

?- progenitor (X, jorge), progenitor (Y, teresa).

Y = pedro progenitor (pedro, teresa).


progenitor (maria, teresa).
progenitor (maria, elena).
progenitor (teresa, jorge).
progenitor (teresa, raquel).
Respuesta progenitor (raquel, miguel).
X = teresa, Y = pedro
La base de hechos
Paso 3.
Quin es abuelo de jorge?

?- progenitor (X, jorge), progenitor (Y, teresa).

progenitor (pedro, teresa).


Y = maria
progenitor (maria, teresa).
progenitor (maria, elena).
progenitor (teresa, jorge).
progenitor (teresa, raquel).
Respuesta progenitor (raquel, miguel).
X = teresa, Y = maria
La base de hechos
Paso 4.
Quin es abuelo de jorge?

?- progenitor (X, jorge), progenitor (Y, X).


teresa).

progenitor (pedro, teresa).


progenitor (maria, teresa).
progenitor (maria, elena).
progenitor (teresa, jorge).
progenitor (teresa, raquel).
progenitor (raquel, miguel).
Backtrack
La base de hechos
Paso 5.
Quin es abuelo de jorge?

?- progenitor (X, jorge), progenitor (Y, X).

progenitor (pedro, teresa).


progenitor (maria, teresa).
progenitor (maria, elena).
Aqu progenitor (teresa, jorge).
progenitor (teresa, raquel).
progenitor (raquel, miguel).
No
La base de hechos
Reglas
Para todos X e Y, X
X es descendiente de Y SI
Y es progenitor de X. progenitor descendiente

descendiente(X,Y) :- progenitor(Y,X). Y

cabeza cuerpo
Para todos X e Y,
SI Y es progenitor de X
Entonces X es descendiente de Y.
Ejemplo: la relacin madre
Para todos X y W,
mujer X
X es madre de W SI
X es progenitor de W Y
progenitor madre
X es mujer

madre (X, W) :- W
progenitor(X, W),
mujer(X).
La coma significa
Relacin unaria conjuncin (Y)
Ejemplo: la relacin abuelo
Para todos X y Z,
hombre X

X es abuelo de Z SI
progenitor
X es progenitor de W y
W es progenitor de Z y
W abuelo
X es hombre

abuelo (X, Z) :-
progenitor
progenitor (X, W),
progenitor (W, Z),
Z
hombre (X).
Ejemplo: la relacin hermana

Para todos X y W, Z
progenitor progenitor
X es hermana de W SI
Z es progenitor de X y W, y
X es mujer X W
hermana
mujer
hermana (X, W) :-
progenitor(Z, X), progenitor(Z, W),
mujer(X).
Aadimos estos hechos. pedro maria

hombre(pedro).
mujer(maria).
mujer(elena).
mujer(teresa). teresa elena
hombre(jorge).
mujer(raquel).
hombre(miguel).
jorge raquel
Quin es hermana de jorge?

?- hermana(X, jorge).
X = raquel ;
miguel
No
Un pequeo problema ... pedro maria
Quin es hermana de teresa?

?- hermana(X, teresa).
X = teresa ; teresa elena
X = teresa ;
X = elena ;
No
jorge raquel

miguel
Programa: pedro maria
progenitor(pedro, teresa).
progenitor(maria, teresa).
progenitor(maria, elena).
progenitor(teresa, jorge).
progenitor(teresa, raquel).
progenitor(raquel, miguel). teresa elena
hombre(pedro).
mujer(maria).
mujer(elena).
mujer(teresa).
hombre(jorge). jorge raquel
mujer(raquel).
hombre(miguel).

hermana(X, W) :-
progenitor(Z, X), progenitor(Z, W), miguel
mujer(X).
Ejemplo: la relacin antepasado X

Para todos X y Z, progenitor


antepasado
X es antepasado de Z SI
W
X es progenitor de W y
W es antepasado de Z y

antepasado (X, Z) :-
antepasado
progenitor (X, W),
antepasado (W, Z). ...

Una definicin recursiva Z


Ejemplo: la relacin antepasado X

?- antepasado(X, jorge). progenitor


antepasado
No
W

antepasado
antepasado (X, Z) :-
progenitor (X, W), ...
antepasado (W, Z).

Z
Ejemplo: la relacin antepasado X

?- antepasado(X, jorge). progenitor


antepasado
X = teresa ;
X = pedro ;
X = maria ; W
No

antepasado(X, Z) :-
progenitor(X, Z).
antepasado
antepasado (X, Z) :-
...
progenitor (X, W),
antepasado (W, Z).
Z
pedro maria

Ejercicios
Definir las relaciones tia,
teresa elena juan
tio, sobrino, sobrina,
primos, ...
y ensayarla sobre jorge raquel jose
la base de datos
de la figura
miguel
Tipos de datos
Datos

Trminos simples Estructuras

Constantes Variables

tomos Nmeros
Tipos de datos Cadenas de caracteres y
nmeros y _, que
Datos
comiencen con minscula
Cadenas de caracteres
pepe especiales
Trminos simples Estructuras
mausculas:
nil <-->A, B, ... Z
x25 Cadenas
minsculas: a, b, dez caracteres
...
===>
encerrados entre
Nmeros nmeros:
a_EDcomillas
0, 1, 2, ... 9
simples
Constantes Variables :-:
Enteros: 1, 3 10000 car. miss_jones
especiales:
Ojo con+ predefinidos,
Pepe - * / <> = : . & _ ~
Reales: 1.00, -0.093 x_ Ana Zapana
p.e. :-
tomos Nmeros
Ali Catari
1 ?- [user].
Tipos de datos Variables:
|: con_hijo(X) :- progenitor(X, Y).
Warning: (user://1:9):
Datosde caracteres,
Cadenas
Singleton variables: [Y]
nmeros y _,
El contexto lxico deque
unacomiencen
con mayscula o _
La variable annima: cuando una variable aparece
Trminosvariable
simples es la clusula.
Estructuras
una sola vez no es necesario
_pepe inventarnos un
nombre para ella.
Nil
con_hijo(X) :- progenitor(X, Y).
Constantes _x25
Variables
con_hijo(X) :- progenitor(X, _).
A_ED
_234
tomos Nmeros
Tipos de datos
Datos

Trminos simples Estructuras

Constantes Variables
Estructuras:
Objetos que contienen datos
como componentes.
tomos Nmeros Functores
Listas
Cualquier da de
Functor
octubre de 1998:

Functor:
fecha( Dia, octubre, 1998)
Ejemplo: una estructura para
representar la fecha.
fecha( 13, octubre, 1998)
fecha

Functor Argumentos 13 octubre 1998


Ejemplo:
ficha( identidad( 'Luis', 'Perez', 'Martinez'), ficha( identidad( 'Maria', 'Garca', 'Martinez'),
nacimiento( fecha( 10, 5, 1970), nacimiento( fecha( 1, 2, 1956),
lugar(Ayaviri', Puno')), lugar(Puno', Puno')),
direccion( calle( San Martn', 241), direccion( calle( Los Alamos', 124),
poblacion( Juliaca')), poblacion( Juliaca')),
datos( 42232787, estudiante, 128234)). datos( 89234347, ingeniero, 92823)).
ficha( identidad( 'Javier', 'Galindo', 'Mamani'),
nacimiento( fecha( 1, 5, 1978),
lugar(Azngaro', Puno')),
direccion( calle( Los Andes', 421),
poblacion( Juliaca')),
datos( 42234347, estudiante, 128234)).
Ejemplo:
?- ficha( identidad( N, A1, A2),
| nacimiento( _, lugar( Ayaviri', Puno')),
| _, _).

N = 'Luis'
A1 = 'Perez'
A2 = 'Martinez' ;
No

ficha( identidad( 'Luis', 'Perez', 'Martinez'),


nacimiento( fecha( 10, 5, 1970),
El nombre y apellidos de las personas nacidas en
lugar(Ayaviri', Puno')),
Ayaviri, Puno
direccion( calle( San Martn', 241),
poblacion( Juliaca')),
datos( 42232787, estudiante, 128234)).
A efectos de eficacia, resulta conveniente simplificar la
estructura de representacin

ficha( 5123, identidad( 'Luis', 'Perez', 'Martinez')).

nacimiento( 5123, fecha( 10, 5, 1970),


lugar('Ayaviri', Puno')).

direccion( 5123, calle( San Martn', 241),


poblacion( Juliaca')).

datos( 5123, 42232787, estudiante, 128234)).


ficha ( 5123, identidad( 'Luis', 'Perez', 'Martinez')).

ficha

localizador identidad

nombre apellido1 apellido2


Ejemplo (cont.):
El nombre y apellidos de las personas nacidas en
(cualquier) Ayaviri
y que residan en Juliaca
?- ficha( X, identidad( N, A1, A2)),
| nacimiento( X, _, lugar( Ayaviri', _)),
| direccion( X, _, poblacion(Juliaca')).

X = 5183
N = 'Luis'
A1 = 'Perez'
A2 = 'Martinez' ;

No
Listas
. (a, . ( b, . ( c, [ ] )))
.

a . . (Cabeza, Cola )

b .

c []
Listas (cont.) ?- Lista1 = [a, b, c],
| Lista2 = .(a, .(b, .(c, []))).

. (a, . ( b, . ( c, [ ] ))) Lista1 = [a, b, c]


Lista2 = [a, b, c]
.
Yes
a .
[a, b, c ] = []

b .
a b c

c []
Listas (cont.)
[a, [b, c ], d ] = []

a [] d

b c

?- display( [a, [b, c], d]).


.(a, .(.(b, .(c, [])), .(d, [])))
Yes
Listas (cont.)
Las listas se manipulan dividindolas en cabeza y cola

Lista Cabeza Cola

[a,b,c] a [ b,c ]
[a] a []
[] no tiene no tiene
[[el, gato], maulla ] [el, gato] [maulla]
[maulla, [el, gato ]] maulla [[el, gato]]
Listas (cont.)
Las listas se manipulan dividindolas en cabeza y cola

Lista

[a,b,c] ?-?-[X|Y] ==[a, b, c].


[X|Y] [a].
[a] ?- [X|Y] = [].
?-?-[X|Y] ==[[el, gato],[el,
maulla].
XX==a a [X|Y] [maulla, gato]].
[]
YY=No=X[b, c]
X =[el,
= gato]
[[el, gato], maulla ] [] maulla
YY==[maulla]
[maulla, [el, gato ]] Yes [[el, gato]]
Yes
Yes
Yes
Listas (cont.)
Una operacin bsica: unificacin de listas

Lista1 Lista2 Unificacin

[ X, Y, Z] [ se, ha, ido] X = unificables


No se
gato
yo
el
a
[ gato ] [X|Y] Y=b
[ha]
bebo
ratn
[X, Y | Z ] [yo, bebo, vino ] Z = [ido
vino
se,
c ] fue
] ]
[[el, Y], Z ] [[X, ratn], [se, fu ]] U=u
[ X, [ Y| Z ], U ] [ a, [ b, c], u]
[ X, Y, X ] [ a, b, c ]
Listas (cont.)

Cadenas de caracteres

como listas de cdigos

ASCII ?- name( lgica, X).


X = [108, 243, 103, 105, 99, 97]
Yes

?- name(X, [108,243,103,105,99,97]).
X = lgica
Yes
Operaciones elementales en Listas
El predicado eslista es cierto si su argumento

es una lista.

?- eslista([ ]).
Definicin Yes

eslista( [ ] ). ?- eslista( [a | [b , d]] ).


eslista( [ _ | _ ] ). Yes
Operaciones elementales en Listas
El predicado pertenece es cierto si su primer

argumento pertenece a la lista que aparece como

segundo argumento.
?- pertenece(a, [x,y,a,z]).
Definicin Yes

pertenece ( X, [X | _ ] ). ?- pertenece(X, [a,b,c]).


pertenece ( X, [ _ | Y] ) :- X=a;
pertenece (X, Y). X=b;
X=c;
No
?- trace(pertenece).
pertenece ( X, [X | _ ] ). pertenece/2: call redo exit fail

pertenece ( X, [ _ | Y] ) :- Yes
pertenece (X, Y). ?- pertenece(a,[x,y,a,z]).
T Call: ( 8) pertenece(a, [x, y, a, z])
T Call: ( 9) pertenece(a, [y, a, z])
T Call: ( 10) pertenece(a, [a, z])
T Exit: ( 10) pertenece(a, [a, z])
T Exit: ( 9) pertenece(a, [y, a, z])
T Exit: ( 8) pertenece(a, [x, y, a, z])

Yes
?- trace(pertenece).
pertenece/2: call redo exit fail
pertenece ( X, [X | _ ] ).
Yes
pertenece ( X, [ _ | Y] ) :- ?- pertenece(a,[s,d,e]).
pertenece (X, Y). T Call: ( 7) pertenece(a, [s, d, e])
T Call: ( 8) pertenece(a, [d, e])
T Call: ( 9) pertenece(a, [e])
T Call: ( 10) pertenece(a, [])
T Fail: ( 10) pertenece(a, [])
T Fail: ( 9) pertenece(a, [e])
T Fail: ( 8) pertenece(a, [d, e])
T Fail: ( 7) pertenece(a, [s, d, e])

No
?- trace(pertenece).
pertenece(a,[f,a,c]).
pertenece/2: call redo exit fail
Ojo: Mal definido Yes

pertenece ( X, [ _ | Y] ) :- ?- pertenece(a,[f,a,c]).
pertenece (X, Y). T Call: (6) pertenece(a, [f, a, c])
T Call: (7) pertenece(a, [a, c])
pertenece ( X, [X | _ ] ). T Call: (8) pertenece(a, [c])
T Call: (9) pertenece(a, [])
T Fail: (9) pertenece(a, [])
T Redo: (8) pertenece(a, [c])
T Fail: (8) pertenece(a, [c])
T Redo: (7) pertenece(a, [a, c])
T Exit: (7) pertenece(a, [a, c])
T Exit: (6) pertenece(a, [f, a, c])

Yes
Operaciones elementales en Listas
El predicado incluir proporciona una lista que es

concatenacin de otras dos.


?- ?-
incluir(
incluir(
X,[yo,
[soy,no],
pepe],
[soy,[yo,
pepe],
soy, L).
pepe]).

X=
L [yo]
= [yo, no, soy, pepe]

Definicin YesYes

incluir ( [] , L, L).
incluir ( [X | L1], L2, [ X | L3] ) :-
incluir (L1, L2, L3).
?- incluir([yo],[soy, pepe],L).
T Call: ( 7) incluir([yo], [soy, pepe], _G242)
T Call: ( 8) incluir([], [soy, pepe], _G344)
T Exit: ( 8) incluir([], [soy, pepe], [soy, pepe])
T Exit: ( 7) incluir([yo], [soy, pepe], [yo, soy, pepe])

L = [yo, soy, pepe]


Yes

Definicin

incluir ( [] , L, L).
incluir ( [X | L1], L2, [ X | L3] ) :-
incluir (L1, L2, L3).

incluir/3 es equivalente al predicado predefinido append/3


Operaciones elementales en Listas
El predicado cuenta devuelve el nmero de ocurrencias

de un elemento en una lista simple (sin estructura).

?- cuenta( a, [t,r,a,g,a], N).


N=2;

Definicin No

cuenta( _, [], 0).


cuenta(X, [X | Y], N) :- cuenta(X,Y,Z), N is Z+1.
cuenta(X, [W| Y], Z) :- X \== W, cuenta(X,Y,Z).
Es necesario ?
cuenta( _, [], 0).
cuenta(X, [X | Y], N) :- cuenta(X,Y,Z), N is Z+1.
cuenta(X, [W| Y], Z) :- X \== W, cuenta(X,Y,Z).
?- cuenta( a, [t,r,a,g,a], N).
N=2;
No
cuenta( _, [], 0).
cuenta(X, [X | Y], N) :- cuenta(X,Y,Z), N is Z+1.
cuenta(X, [W| Y], Z) :- cuenta(X,Y,Z).
?- cuenta( a, [t,r,a,g,a], N).
N=2;
N=1;
N=1;
N=0;
No
Operaciones elementales en Listas
El predicado elimina elimina todas las ocurrencias

de un elemento en una lista simple (sin estructura).

?- elimina( i, [e,l,i,m,i,n,a], R).


R = [e, l, m, n, a]

Definicin Yes

elimina( _ , [ ], [ ]).
elimina( X, [X | Y], R) :- elimina( X, Y, R).
elimina( X, [W| Y], [W | R]) :- X \== W, elimina( X, Y, R).
Operaciones elementales en Listas
El predicado sustituye todas las ocurrencias de un elemento

(1er arg.) por el 2 argumento en una lista simple

(sin estructura).
?- sustituye( i, a, [e,l,i,m,i,n,a], R).
R = [e, l, a, m, a, n, a]

Definicin Yes

sustituye( _ , _ , [ ], [ ]).
sustituye( X, Y, [X | U], [Y | V]) :- sustituye( X, Y, U, V).
sustituye( X, Y, [Z | U], [Z | V]) :- X \== Z, sustituye( X, Y, U, V).
Operaciones elementales en Listas
El predicado reverso devuelve la lista inversa de una

dada.

?- reverso( [1,2,3,4,5], R).


R = [5, 4, 3, 2, 1]

Definicin Yes

reverso( L1, L2):- rev( L1, [ ], L2).


rev( [ ], L, L).
rev( [X | Y], L1, L2) :- rev( Y, [X | L1], L2).
reverso( L1, L2):- ?- reverso([1,2,3,4,5],R).
?- trace(rev), trace(reverso).
rev( L1, [ ], L2). T Call: ( 8) reverso([1, 2, 3, 4, 5], _G217)
rev/3:
T Call: ( 9) call
rev([1, redo
2, 3, 4, 5],exit fail
[], _G217)
reverso/2:
T Call: ( 10) rev([2, 3, call
4, 5],redo exit fail
[1], _G217)
rev( [ ], L, L). Yes( 11) rev([3, 4, 5], [2, 1], _G217)
T Call:
T Call: ( 12) rev([4, 5], [3, 2, 1], _G217)
rev( [X | Y], L1, L2) :- T Call: ( 13) rev([5], [4, 3, 2, 1], _G217)
rev( Y, [X | L1], L2). T Call: ( 14) rev([], [5, 4, 3, 2, 1], _G217)
T Exit: ( 14) rev([], [5, 4, 3, 2, 1], [5, 4, 3, 2, 1])
T Exit: ( 13) rev([5], [4, 3, 2, 1], [5, 4, 3, 2, 1])
T Exit: ( 12) rev([4, 5], [3, 2, 1], [5, 4, 3, 2, 1])
T Exit: ( 11) rev([3, 4, 5], [2, 1], [5, 4, 3, 2, 1])
T Exit: ( 10) rev([2, 3, 4, 5], [1], [5, 4, 3, 2, 1])
T Exit: ( 9) rev([1, 2, 3, 4, 5], [], [5, 4, 3, 2, 1])
T Exit: ( 8) reverso([1, 2, 3, 4, 5], [5, 4, 3, 2, 1])
R = [5, 4, 3, 2, 1]
Yes
Operaciones elementales en Listas
El predicado sublista que comprueba si una lista (1er arg.)

es parte de otra dada (2 arg.).

?- sublista( [a,s,f], [b,e,a,s,f,g,h]).

Yes

Definicin
L
sublista( S, L):-
append( _,L1,L2,
L2,L),
L), L1 S L3
append(S, _,L3,L2).
L2). L2
sublista( S, L):-
append( _, L2, L),
append(S, _, L2).

?- sublista( [a,s,f], [b,e,a,s,f,g,h]).


[debug] ?- sublista( [a,s,f], [b,e,a,s,f,g,h]).
T Call: (6) sublista([a, s, f], [b, e, a, s, f, g, h])
Call: (6) sublista([a, s, f], [b, e, a, s, f, g, h]) ? creep
Call: (7) append(_G598, _G599, [b, e, a, s, f, g, h]) ? creep
Exit: (7) append([], [b, e, a, s, f, g, h], [b, e, a, s, f, g, h]) ? creep
Call: (7) append([a, s, f], _G599, [b, e, a, s, f, g, h]) ? creep
Fail: (7) append([a, s, f], _G599, [b, e, a, s, f, g, h]) ? creep
Exit: (7) append([b], [e, a, s, f, g, h], [b, e, a, s, f, g, h]) ? creep
Call: (7) append([a, s, f], _G602, [e, a, s, f, g, h]) ? creep
Fail: (7) append([a, s, f], _G602, [e, a, s, f, g, h]) ? creep
Exit: (7) append([b, e], [a, s, f, g, h], [b, e, a, s, f, g, h]) ? creep
Call: (7) append([a, s, f], _G605, [a, s, f, g, h]) ? creep
Exit: (7) append([a, s, f], [g, h], [a, s, f, g, h]) ? creep
T Exit: (6) sublista([a, s, f], [b, e, a, s, f, g, h])
Exit: (6) sublista([a, s, f], [b, e, a, s, f, g, h]) ? creep
Yes
Operaciones elementales en Listas
El predicado aplana transforma una lista compleja, que

puede contener a otras listas como elementos, en una

lista sin estructura. ?- aplana([a, [ [b], c] ], L).


Definicin L = [a, b, c]

aplana([H|T], Lp):- Yes


aplana(H, Hp),
aplana(T, Tp),
append(Hp, Tp, Lp).

aplana([], []).
aplana(X, [X]).
2 ?- trace(aplana).
% aplana/2: [call, redo, exit, fail]

Esta definicin produce Yes


basura en el backtracking. [debug] 3 ?- aplana([a,[b]],Lp).

T Call: (7) aplana([a, [b]], _G486)


T Call: (8) aplana(a, _L171)
aplana([H|T], Lp):- T Exit: (8) aplana(a, [a])
T Call: (8) aplana([[b]], _L172)
aplana(H, Hp), T Call: (9) aplana([b], _L192)
aplana(T, Tp), T Call: (10) aplana(b, _L213)
T Exit: (10) aplana(b, [b])
append(Hp, Tp, Lp). T Call: (10) aplana([], _L214)
T Exit: (10) aplana([], [])
T Exit: (9) aplana([b], [b])
T Call: (9) aplana([], _L193)
aplana([], []). T Exit: (9) aplana([], [])
aplana(X, [X]). T Exit: (8) aplana([[b]], [b])
T Exit: (7) aplana([a, [b]], [a, b])

Lp = [a, b] ;
Adems, el uso de append/3
hace que sea muy ineficiente. T Redo: (9) aplana([], _L193)
T Exit: (9) aplana([], [[]])
T Exit: (8) aplana([[b]], [b, []])
T Exit: (7) aplana([a, [b]], [a, b, []])

Lp = [a, b, []] ;

2 ?- trace(aplana2).
% aplana2/2: [call, redo, exit, fail]
Una nueva definicin que es
ms eficiente.
[debug] 11 ?- aplana2([a,[b]],Lp).
T Call: (8) aplana2([a, [b]], _G501)
T Call: (9) aplana2([a, [b]], [], _G501)
T Call: (10) aplana2(a, [], _L189)
aplana2(L,LP):- T Exit: (10) aplana2(a, [], [a])
T Call: (10) aplana2([[b]], [a], _G501)
aplana2(L,[],LP). T Call: (11) aplana2([b], [a], _L210)
T Call: (12) aplana2(b, [a], _L231)
aplana2([H|T],A,LP):- T Exit: (12) aplana2(b, [a], [b, a])
T Call: (12) aplana2([], [b, a], _L210)
aplana2(H,A,HA), T Exit: (12) aplana2([], [b, a], [b, a])
aplana2(T,HA,LP). T Exit: (11) aplana2([b], [a], [b, a])
T Call: (11) aplana2([], [b, a], _G501)
T Exit: (11) aplana2([], [b, a], [b, a])
aplana2([],A,A). T Exit: (10) aplana2([[b]], [a], [b, a])
T Exit: (9) aplana2([a, [b]], [], [b, a])
aplana2(X,A,[X|A]). T Exit: (8) aplana2([a, [b]], [b, a])

Lp = [b, a] ;
T Redo: (11) aplana2([], [b, a], _G501)
Problema: La lista resulta invertida T Exit: (11) aplana2([], [b, a], [[], b, a])
T Exit: (10) aplana2([[b]], [a], [[], b, a])
T Exit: (9) aplana2([a, [b]], [], [[], b, a])
T Exit: (8) aplana2([a, [b]], [[], b, a])

Lp = [[], b, a]

% Execution Aborted
12 ?- trace(aplana3).
Un pequeo arreglo es suficiente % aplana3/2: [call, redo, exit, fail]
% aplana3/3: [call, redo, exit, fail]

aplana3(L,LP):- Yes
aplana3(L,[],LP). [debug] 13 ?- aplana3([a,[b]],Lp).
T Call: (8) aplana3([a, [b]], _G501)
T Call: (9) aplana3([a, [b]], [], _G501)
aplana3([H|T],A,LP):- T Call: (10) aplana3([[b]], [], _L189)
T Call: (11) aplana3([], [], _L210)
aplana3(T,A,HA), T Exit: (11) aplana3([], [], [])
aplana3(H,HA,LP). T Call: (11) aplana3([b], [], _L189)
T Call: (12) aplana3([], [], _L249)
T Exit: (12) aplana3([], [], [])
aplana3([ ],A,A). T Call: (12) aplana3(b, [], _L189)
aplana3(X,A,[X|A]). T Exit: (12) aplana3(b, [], [b])
T Exit: (11) aplana3([b], [], [b])
T Exit: (10) aplana3([[b]], [], [b])
para que la lista salga en el orden T Call: (10) aplana3(a, [b], _G501)
T Exit: (10) aplana3(a, [b], [a, b])
correcto. T Exit: (9) aplana3([a, [b]], [], [a, b])
T Exit: (8) aplana3([a, [b]], [a, b])

Lp = [a, b] ;

Lp = [a, b, []]