SlideShare ist ein Scribd-Unternehmen logo
1 von 40
PROLOG
Programación Lógica
Listas



    Usos
    •Listas
    •Composición de Programas Recursivos
    •Iteración


    Las listas son la estructura básica usada en la programación
    lógica. Son una estructura de datos recursivas, de modo que la
    recursión ocurre de manera natural en la definición de
    operaciones de varias listas.
Listas



   Cuando definimos operaciones en estructuras de datos recursivas,
   la definición con mucha frecuencia sigue de manera natural la
   definición recursiva de la estructura de datos.


   En el caso de las listas, la lista vacía es el caso base. Así que las
   operaciones sobre listas deben considerar el caso de la lista vacía.


   Los otros casos implican una lista que se compone de un elemento
   y una lista.
Listas
Aquí tenemos una definición recursiva de la estructura de datos
'Lista' como la encontramos en prolog:
Lista --> [ ]
Lista --> [Elemento|Lista]


Aquí hay algunos ejemplos de representaciones de listas, el
primero es la lista vacía:
Pair Syntax             Element Syntax
[]                      []
[a|[ ]]                 [a]
[a|b|[ ]]       [a,b]
[a|X]                   [a|X]
[a|b|X]                 [a,b|X]
Listas



Los predicados en la lista comúnmente se escriben usando
múltiples reglas. Una regla para la lista vacía (caso base) y una
segunda regla para listas no vacías. Por ejemplo, aquí está la
definición del predicado para la longitud de una lista.


% length(List,Number) <- Number is lenght of List


length([],0).
length([H|T],N) :- length(T,M), N is M+1
Listas



elemento de una lista


% member(Element,List) <- Element is an element of the list List


member(X,[X|List).
member(X,[Element|List]) :- member(X,List).
Listas



Prefijo de una lista


% prefix(Prefix,List) <- Prefix is a prefix of list List


prefix([],List).
prefix([X|Prefix],[X|List]) :- prefix(Prefix,List).
Listas



Sufijo de una lista


% suffix(Suffix,List) <- Suffix is a suffix of list List


suffix(Suffix,Suffix).
prefix(Suffix,[X|List]) :- suffix(Suffix,List).
Listas



Append (concatenar) dos listas.


% append(List1,List2,List1List2) <-
%   List1List2 is the result of concatenating List1 and List2.


append([],List,List).
append([Element|List1],List2,[Element|List1List2]) :-
append(List1,List2,List1List2).
Listas


         Iteración en listas
         Versión Iterativa de my_length
         % my_length(List,Number) <- Number is lenght of List
         % Iterative version.
         my_length(List,LenghtofList) :- my_length(List,0,LengthofList).
         % my_length(SufixList,LengthofPrefix,LengthofList) <-
         %      LengthofList is LengthofPrefix + length of SufixList
         my_length([],LenghtofPrefix,LengthofPrefix).
         my_length([Element|List],LengthofPrefix,LengthofList) :-
         PrefixPlus1 is LengthofPrefix + 1,
         my_length(List,PrefixPlus1,LengthofList).
Listas

Versión iterativa de Reversa


% reverse(List,ReversedList) <- ReversedList is List reversed.
% Iterative version.
reverse(List,RList) :- reverse(List,[],RList).
% length(SufixList,LengthofPrefix,LengthofList) <-
%        LengthofList is LengthofPrefix + length of SufixList
reverse([],RL,RL).
reverse([Element|List],RevPrefix,RL) :-
reverse(List,[Element|RevPrefix],RL).
Listas



Aquí tenemos algunos ejemplos simples de operaciones comunes
sobre listas definidas por comparación de patrones. La primera
suma los elementos de una lista y la seguna forma el producto de
los elementos de una lista.


sum([ ],0).
sum([X|L],Sum) :- sum(L,SL), Sum is X + SL.


product([ ],1).
product([X|L],Prod) :- product(L,PL), Prod is X * PL.
Listas



La relación de append es muy flexible. Puede usarse para
determinar si un objeto es un elemento de una lista, si una lista es
prefijo de una lista y si una lista es sufijo de una lista.


member(X,L) :- append(_,[X|_],L).
prefix(Pre,L) :- append(Prefix,_,L).
suffix(L,Suf) :- append(_,Suf,L).


El subguión '_' en las definiciones denota una variable anónima (o
'no importa') cuyo valor es irrelevante para la definición.
Listas



La relación member puede ser usado para derivar otras relaciones
útiles.


vowel(X) :- member(X,[a,e,i,o,u]).
digit(D) :- member(D,['0','1','2','3','4','5','6','7','8','9']).
Iteración



La recursión es el único método iterativo disponible en Prolog. Sin
embargo, la recursión de cola puede ser con frecuencia
implementada como iteración. La siguiente definición de la
función factorial es una definición iteratica porque es "recursiva
de cola".


Corresponde a una implementación usando un ciclo-while en un
lenguaje de programación imperativo.
Iteración



fac(0,1).
fac(N,F) :- N > 0, fac(N,1,F).


fac(1,F,F).
fac(N,PP,F) :- N > 1, NPp is N*PP, M is N-1, fac(M,NPp,F).


Note que el segundo argumento funciona como acumulador. El
acumulador se usa para almacenar productos parciales tal y como
se haría en un lenguaje procedural.
Iteración

Por ejemplo, en Pascal, una función factorial iterativa se podría
escribir asi:
function fac(N:integer) : integer;
var i : integer;
begin
  if N >= 0 then begin
       fac := 1
    for I := 1 to N do
         fac := fac * I
  end
end;
Iteración



En la solución Pascal 'fac' actua como una acumulador para
almacenar el producto parcial. La solución Prolog también ilustra
el hecho de que Prolog permite diferentes relaciones definidas
bajo el mismo nombre si el número de argumentos es diferente.


En este ejemplo las relaciones son fac/2 y fac/3. Como ejemplo
adicional del uso de acumuladores aquí tenemos la versión
iterativa de la función Fibonacci.
Iteración



ffib(0,1).
fib(1,1).
fib(N,F) :- N > 1, fib(N,1,1,F)


fib(2,F1,F2,F) :- F is F1 + F2.
fib(N,F1,F2,F) :- N > 2, N1 is N - 1, NF1 is F1 + F2,
  fib(N1,NF1,F1,F).
Iteradores, Generadores y Backtracking

Los siguientes hecho y regla se pueden usar para generar números
naturales


nat(0).
nat(N) :- nat(M), N is M + 1.


La sucesión de números se genera por 'backtracking'. Por ejemplo,
cuando la siguiente consulta se ejecuta, los números naturales
sucesivos se imprimen.


?- nat(N), write(N), nl, fail.
Iteradores, Generadores y Backtracking



El primer número natural se genera e imprime. Entonces, 'fail'
forza a que suceda el rastreo de retorno y la segunda regla se usa
para generar la sucesión de números naturales. El siguiente
código genera prefijos sucesivos de una lista infinita empezando
con N.


natlist(N,[N]).
natlist(N,[N|L]) :- N1 is N+1, natlist(N1,L).
Iteradores, Generadores y Backtracking

Como ejemplo final, aquí tenemos un código para la generación de
prefijos sucesivos de la lista de números primos.


primes(PL) :- natlist(2,L2), sieve(L2,PL).


sieve([ ],[ ]).
sieve([P|L],[P|IDL]) :- sieveP(P,L,PL), sieve(PL,IDL).


sieveP(P,[ ],[ ]).
sieveP(P,[N|L],[N|IDL]) :- N mod P > 0, sieveP(P,L,IDL).
sieveP(P,[N|L],      IDL) :- N mod P =:= 0, sieveP(P,L,IDL).
Iteradores, Generadores y Backtracking



Ocasionalmente el backtracking y las múltiples respuestas son
incómodas. Prolog nos permite usar el símbolo de corte (!) para
controlar el backtracking. El codigo siguiente define un predicado
donde el tercer argumento es el máximo de los primeros dos.
max(A,B,M) :- A < B, M = B.
max(A,B,M) :- A >= B, M = A.


El código se puede simplificar quitando las condiciones de la
segunda condición.
max(A,B,B) :- A < B.
max(A,B,A).
Iteradores, Generadores y Backtracking



Sin embargo, durante el backtracking, respuestas no correctas se
pueden sucitar, como a continuación se muestra:


?- max(3,4,M).


M = 4;


M=3
Iteradores, Generadores y Backtracking
Para impedir el rastreo de retorno en la segunda regla, el símbolo
de corte se pone en la primera regla.
max(A,B,B) :- A < B.!.
max(A,B,A).


Ahora la respuesta incorrecta no se va a generar.


Un consejo: Los cortes son similares a los 'goto's, en el hecho de
que tienden a incrementar la complejidad del código en lugar de
simplificarla. En general el uso de cortes debería ser evitado, y
sería mejor replantear las condiciones para que no se generen
resultados incorrectos.
Entrada y Salida



En archivos:


see(File)      La entrada actual ahora es File.
seeing(File) File se unifica con el nombre del archivo de entrada
actual
seen           Cierra el archivo de entrada actual
tell(File)     El archivo de salida actual es File
telling(File) File se unifica con el nombre del archivo de salida
actual
told           Cierra el archivo de salida actual
Entrada y Salida
Términos de entrada y salida
read(Term)
      Lee el término hasta el delimitador punto del flujo de
entrada actual, si encuentra eof regresa el átomo eof.
write(Term)
      Escribe un término al fluje de salida actual.
print(Term)
      Escribe un término al flujo de salida actual. Usa un
predicado portray/1 definido por el usuario para la escritura, o de
no existir, usa write.
writeq(Term)
      Escribe un término al flujo de salida actual en una forma
estándar de entrada para lectura.
Entrada y Salida
Caracter de entrada y salida
get(N)
      N es el código ASCII del siguiente caracter no nulo
imprimible en el flujo de entrada actual. Si es fin de archivo, se
retorna un -1
put(N)
       Pone el caracter correspondiente al código ASCII de N en el
flujo de salida actual.
nl
         Escribe una nueva línea
tab(N)
         N espacios se ponen en el flujo de salida
Acceso y manipulación de programas y sistema


     clause(Head,Body)
     assert(Clause)
           agrega la cláusula al final de la base de datos
     asserta(Clause)
     retract(Clause_Head)
     consult(File_Name)


     system(Command)
     Ejecuta Command en el sistema operativo
Aplicaciones



 Gramáticas Independientes de Contexto y Gramáticas de
 Cláusulas Definidas


 Prolog se originó de intentos de usar la lógica para expresar
 reglas gramaticales y formalizar los procesos de parseo. Prolog
 tiene reglas de sintáxis especiales llamadas Gramática de
 Cláusulas Definidas, que son una generalización de las gramáticas
 libres de contexto.
Aplicaciones


Los no terminales se expresan como átomos Prolog, los elementos
en el cuerpo se separan con comas y secuencias de símbolos
terminales se escriben como listas de átomos. Para cada no
terminal, S, una gramática define un lenguaje que se obtiene por la
aplicación no determinista de reglas gramaticales iniciando en S.




s --> [a],[b].
s --> [a],s,[b].
Aplicaciones
Una ilustración de como se usan estas DCGs, la cadena [a,a,b,b]
se le proporciona a la gramática para su parsing.




?- s([a,a,b,b],[]).
  yes




Vea los ejemplos anexos para la formación de oraciones, sin y con
control de número.
Aplicaciones
Estructuras de Datos incompletas.


Una estructura de datos incompleta es una estructura de datos
que contiene una variable. Tal estructura se dice estar
'parcialmente instanciada' o 'incompleta'. Aquí ilustramos la
programación con estructuras de datos incompletas modificando
el código para un árbol de búsqueda binaria. El código resultante
permite la relación inserted_in_is para definir tanto la relación de
inserción como la de membresía.
Aplicaciones
Programación de Meta Nivel


Los meta programas tratan otros programas como datos. Analizan,
transforman y simulan otros programas. Las cláusulas Prolog
pueden pasarse como argumentos, ser agregadas y eliminadas de
la base de datos, y ser construidas y ejecutadas por un programa
prolog. Las implementaciones pueden requerir que el functor y
aridad de la cláusula esté previamente declarado como tipo
dinámico
Aplicaciones




  Assert/Retract


  El siguiente ejemplo muestra como las cláusulas pueden ser
  agregadas y removidas de la base de datos Prolog. Muestra como
  simular una sentencia de asignación usando assert y retract para
  modificar la asociación entre una variable y un valor.
Aplicaciones
:- dynamic x/1 .% this may be required in some Prologs
x(0). % An initial value is required in this example
assign(X,V) :- Old =..[X,_], retract(Old), New =..[X,V], assert(New).


Aquí hay un ejemplo del uso del predicado assign
?- x(N).
N=0
yes
?- assign(x,5).
yes
?- x(N).
N=5
Aplicaciones
Sistemas expertos


Los sistemas expertos se pueden programar en uno de dos modos
en Prolog. Uno es construir una base de conocimiento usando
hechos y reglas Prolog y usar la máquina de inferencia empotrada
para responder consultas.


La otra es construir una máquina de inferencia más poderosa en
prolog y usarla para implementar un sistema experto.
Aplicaciones
Comparación de patrones: Diferenciación simbólica
d(X,X,1) :- !.
d(C,X,0) :- atomic(C).
d(-U,X,-A) :- d(U,X,A).
d(U+V,X,A+B) :- d(U,X,A), d(V,X,B).
d(U-V,X,A-B) :- d(U,X,A), d(V,X,B).
d(C*U,X,C*A) :- atomic(C), CX, d(U,X,A),!.
d(U*V,X,B*U+A*V) :- d(U,X,A), D(V,X,B).
d(U/V,X,A) :- d(U*V^-1,X,A)
d(U^C,X,C*U^(C-1)*W) :- atomic(C), CX, d(U,X,W).
d(log(U),X,A*U^(-1)) :- d(U,X,A).
Aplicaciones



Programación Orientada a Objetos.


Otra de las aplicaciones de prolog es la evaluación de estructuras
de datos de tipo objeto. Como sabemos un tipo objeto tiene
inherentes métodos y datos que se instancían en el momento de
su declaración.


En el ejemplo de prolog podemos ver una propuesta de la
definición de estas relaciones.
Gracias...

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

Listas Pilas Colas
Listas Pilas ColasListas Pilas Colas
Listas Pilas Colas
 
Prolog ejercicios resueltos
Prolog ejercicios resueltosProlog ejercicios resueltos
Prolog ejercicios resueltos
 
Estadística con Lenguaje R: Sesión 8
Estadística con Lenguaje R: Sesión 8Estadística con Lenguaje R: Sesión 8
Estadística con Lenguaje R: Sesión 8
 
Haskell - Intro
Haskell - IntroHaskell - Intro
Haskell - Intro
 
Algoritmos de ordeamiento
Algoritmos de ordeamientoAlgoritmos de ordeamiento
Algoritmos de ordeamiento
 
Blind X Path Injection
Blind X Path InjectionBlind X Path Injection
Blind X Path Injection
 
Curso de Python
Curso de PythonCurso de Python
Curso de Python
 
Lenguaje Lisp
Lenguaje LispLenguaje Lisp
Lenguaje Lisp
 
Python para principiantes
Python para principiantesPython para principiantes
Python para principiantes
 
Curso lisp
Curso lispCurso lisp
Curso lisp
 
Entrega de reporte no 1, lab 1
Entrega de reporte no 1, lab 1Entrega de reporte no 1, lab 1
Entrega de reporte no 1, lab 1
 
Algoritmo de listas simples completo
Algoritmo de listas simples  completoAlgoritmo de listas simples  completo
Algoritmo de listas simples completo
 
Practica i prolog
Practica i prologPractica i prolog
Practica i prolog
 
Listasenlazadas 100517143015-phpapp02
Listasenlazadas 100517143015-phpapp02Listasenlazadas 100517143015-phpapp02
Listasenlazadas 100517143015-phpapp02
 
Funcionamiento de un pila
Funcionamiento de un pilaFuncionamiento de un pila
Funcionamiento de un pila
 
Neo4j una guía rápida de devniel.com - parte ii
Neo4j   una guía rápida de devniel.com - parte iiNeo4j   una guía rápida de devniel.com - parte ii
Neo4j una guía rápida de devniel.com - parte ii
 
bibliotecas c++
bibliotecas c++bibliotecas c++
bibliotecas c++
 
Listas enlazadas
Listas enlazadasListas enlazadas
Listas enlazadas
 
Notación infija postfija
Notación infija postfijaNotación infija postfija
Notación infija postfija
 
Listas, pilas & colas
Listas, pilas & colasListas, pilas & colas
Listas, pilas & colas
 

Ähnlich wie Programación Lógica Listas (20)

Intro haskell
Intro haskellIntro haskell
Intro haskell
 
Ambiente
 Ambiente Ambiente
Ambiente
 
Ambiente de programación en pascal
Ambiente de programación en pascalAmbiente de programación en pascal
Ambiente de programación en pascal
 
Ambiente de programacin en pascal
Ambiente de programacin en pascalAmbiente de programacin en pascal
Ambiente de programacin en pascal
 
Ambiente de programación en pascal
Ambiente de programación en pascalAmbiente de programación en pascal
Ambiente de programación en pascal
 
Ambientedeprogramacinenpascal 111015091809-phpapp02
Ambientedeprogramacinenpascal 111015091809-phpapp02Ambientedeprogramacinenpascal 111015091809-phpapp02
Ambientedeprogramacinenpascal 111015091809-phpapp02
 
Argentina Programa Apendix parte 2.pdf
Argentina Programa Apendix parte 2.pdfArgentina Programa Apendix parte 2.pdf
Argentina Programa Apendix parte 2.pdf
 
Taller listasyeasygui
Taller listasyeasyguiTaller listasyeasygui
Taller listasyeasygui
 
Prolog
Prolog Prolog
Prolog
 
Scala en proyectos de vinculación Ancap-UR - 2013-03
Scala en proyectos de vinculación Ancap-UR - 2013-03Scala en proyectos de vinculación Ancap-UR - 2013-03
Scala en proyectos de vinculación Ancap-UR - 2013-03
 
EXPO PYTHON.pptx
EXPO PYTHON.pptxEXPO PYTHON.pptx
EXPO PYTHON.pptx
 
Cuaderno 1
Cuaderno 1Cuaderno 1
Cuaderno 1
 
Lab archivos
Lab archivosLab archivos
Lab archivos
 
02 introduccion a python
02 introduccion a python02 introduccion a python
02 introduccion a python
 
Haskell
HaskellHaskell
Haskell
 
Django y Python para todos
Django y Python para todosDjango y Python para todos
Django y Python para todos
 
Estructura de datos avanzada
Estructura de datos avanzadaEstructura de datos avanzada
Estructura de datos avanzada
 
Tipos de Datos Abstractos.
Tipos de Datos Abstractos.Tipos de Datos Abstractos.
Tipos de Datos Abstractos.
 
Curso prog sist
Curso prog sistCurso prog sist
Curso prog sist
 
Diapositivas matlab
Diapositivas matlabDiapositivas matlab
Diapositivas matlab
 

Programación Lógica Listas

  • 2. Listas Usos •Listas •Composición de Programas Recursivos •Iteración Las listas son la estructura básica usada en la programación lógica. Son una estructura de datos recursivas, de modo que la recursión ocurre de manera natural en la definición de operaciones de varias listas.
  • 3. Listas Cuando definimos operaciones en estructuras de datos recursivas, la definición con mucha frecuencia sigue de manera natural la definición recursiva de la estructura de datos. En el caso de las listas, la lista vacía es el caso base. Así que las operaciones sobre listas deben considerar el caso de la lista vacía. Los otros casos implican una lista que se compone de un elemento y una lista.
  • 4. Listas Aquí tenemos una definición recursiva de la estructura de datos 'Lista' como la encontramos en prolog: Lista --> [ ] Lista --> [Elemento|Lista] Aquí hay algunos ejemplos de representaciones de listas, el primero es la lista vacía: Pair Syntax Element Syntax [] [] [a|[ ]] [a] [a|b|[ ]] [a,b] [a|X] [a|X] [a|b|X] [a,b|X]
  • 5. Listas Los predicados en la lista comúnmente se escriben usando múltiples reglas. Una regla para la lista vacía (caso base) y una segunda regla para listas no vacías. Por ejemplo, aquí está la definición del predicado para la longitud de una lista. % length(List,Number) <- Number is lenght of List length([],0). length([H|T],N) :- length(T,M), N is M+1
  • 6. Listas elemento de una lista % member(Element,List) <- Element is an element of the list List member(X,[X|List). member(X,[Element|List]) :- member(X,List).
  • 7. Listas Prefijo de una lista % prefix(Prefix,List) <- Prefix is a prefix of list List prefix([],List). prefix([X|Prefix],[X|List]) :- prefix(Prefix,List).
  • 8. Listas Sufijo de una lista % suffix(Suffix,List) <- Suffix is a suffix of list List suffix(Suffix,Suffix). prefix(Suffix,[X|List]) :- suffix(Suffix,List).
  • 9. Listas Append (concatenar) dos listas. % append(List1,List2,List1List2) <- % List1List2 is the result of concatenating List1 and List2. append([],List,List). append([Element|List1],List2,[Element|List1List2]) :- append(List1,List2,List1List2).
  • 10. Listas Iteración en listas Versión Iterativa de my_length % my_length(List,Number) <- Number is lenght of List % Iterative version. my_length(List,LenghtofList) :- my_length(List,0,LengthofList). % my_length(SufixList,LengthofPrefix,LengthofList) <- % LengthofList is LengthofPrefix + length of SufixList my_length([],LenghtofPrefix,LengthofPrefix). my_length([Element|List],LengthofPrefix,LengthofList) :- PrefixPlus1 is LengthofPrefix + 1, my_length(List,PrefixPlus1,LengthofList).
  • 11. Listas Versión iterativa de Reversa % reverse(List,ReversedList) <- ReversedList is List reversed. % Iterative version. reverse(List,RList) :- reverse(List,[],RList). % length(SufixList,LengthofPrefix,LengthofList) <- % LengthofList is LengthofPrefix + length of SufixList reverse([],RL,RL). reverse([Element|List],RevPrefix,RL) :- reverse(List,[Element|RevPrefix],RL).
  • 12. Listas Aquí tenemos algunos ejemplos simples de operaciones comunes sobre listas definidas por comparación de patrones. La primera suma los elementos de una lista y la seguna forma el producto de los elementos de una lista. sum([ ],0). sum([X|L],Sum) :- sum(L,SL), Sum is X + SL. product([ ],1). product([X|L],Prod) :- product(L,PL), Prod is X * PL.
  • 13. Listas La relación de append es muy flexible. Puede usarse para determinar si un objeto es un elemento de una lista, si una lista es prefijo de una lista y si una lista es sufijo de una lista. member(X,L) :- append(_,[X|_],L). prefix(Pre,L) :- append(Prefix,_,L). suffix(L,Suf) :- append(_,Suf,L). El subguión '_' en las definiciones denota una variable anónima (o 'no importa') cuyo valor es irrelevante para la definición.
  • 14. Listas La relación member puede ser usado para derivar otras relaciones útiles. vowel(X) :- member(X,[a,e,i,o,u]). digit(D) :- member(D,['0','1','2','3','4','5','6','7','8','9']).
  • 15. Iteración La recursión es el único método iterativo disponible en Prolog. Sin embargo, la recursión de cola puede ser con frecuencia implementada como iteración. La siguiente definición de la función factorial es una definición iteratica porque es "recursiva de cola". Corresponde a una implementación usando un ciclo-while en un lenguaje de programación imperativo.
  • 16. Iteración fac(0,1). fac(N,F) :- N > 0, fac(N,1,F). fac(1,F,F). fac(N,PP,F) :- N > 1, NPp is N*PP, M is N-1, fac(M,NPp,F). Note que el segundo argumento funciona como acumulador. El acumulador se usa para almacenar productos parciales tal y como se haría en un lenguaje procedural.
  • 17. Iteración Por ejemplo, en Pascal, una función factorial iterativa se podría escribir asi: function fac(N:integer) : integer; var i : integer; begin if N >= 0 then begin fac := 1 for I := 1 to N do fac := fac * I end end;
  • 18. Iteración En la solución Pascal 'fac' actua como una acumulador para almacenar el producto parcial. La solución Prolog también ilustra el hecho de que Prolog permite diferentes relaciones definidas bajo el mismo nombre si el número de argumentos es diferente. En este ejemplo las relaciones son fac/2 y fac/3. Como ejemplo adicional del uso de acumuladores aquí tenemos la versión iterativa de la función Fibonacci.
  • 19. Iteración ffib(0,1). fib(1,1). fib(N,F) :- N > 1, fib(N,1,1,F) fib(2,F1,F2,F) :- F is F1 + F2. fib(N,F1,F2,F) :- N > 2, N1 is N - 1, NF1 is F1 + F2, fib(N1,NF1,F1,F).
  • 20. Iteradores, Generadores y Backtracking Los siguientes hecho y regla se pueden usar para generar números naturales nat(0). nat(N) :- nat(M), N is M + 1. La sucesión de números se genera por 'backtracking'. Por ejemplo, cuando la siguiente consulta se ejecuta, los números naturales sucesivos se imprimen. ?- nat(N), write(N), nl, fail.
  • 21. Iteradores, Generadores y Backtracking El primer número natural se genera e imprime. Entonces, 'fail' forza a que suceda el rastreo de retorno y la segunda regla se usa para generar la sucesión de números naturales. El siguiente código genera prefijos sucesivos de una lista infinita empezando con N. natlist(N,[N]). natlist(N,[N|L]) :- N1 is N+1, natlist(N1,L).
  • 22. Iteradores, Generadores y Backtracking Como ejemplo final, aquí tenemos un código para la generación de prefijos sucesivos de la lista de números primos. primes(PL) :- natlist(2,L2), sieve(L2,PL). sieve([ ],[ ]). sieve([P|L],[P|IDL]) :- sieveP(P,L,PL), sieve(PL,IDL). sieveP(P,[ ],[ ]). sieveP(P,[N|L],[N|IDL]) :- N mod P > 0, sieveP(P,L,IDL). sieveP(P,[N|L], IDL) :- N mod P =:= 0, sieveP(P,L,IDL).
  • 23. Iteradores, Generadores y Backtracking Ocasionalmente el backtracking y las múltiples respuestas son incómodas. Prolog nos permite usar el símbolo de corte (!) para controlar el backtracking. El codigo siguiente define un predicado donde el tercer argumento es el máximo de los primeros dos. max(A,B,M) :- A < B, M = B. max(A,B,M) :- A >= B, M = A. El código se puede simplificar quitando las condiciones de la segunda condición. max(A,B,B) :- A < B. max(A,B,A).
  • 24. Iteradores, Generadores y Backtracking Sin embargo, durante el backtracking, respuestas no correctas se pueden sucitar, como a continuación se muestra: ?- max(3,4,M). M = 4; M=3
  • 25. Iteradores, Generadores y Backtracking Para impedir el rastreo de retorno en la segunda regla, el símbolo de corte se pone en la primera regla. max(A,B,B) :- A < B.!. max(A,B,A). Ahora la respuesta incorrecta no se va a generar. Un consejo: Los cortes son similares a los 'goto's, en el hecho de que tienden a incrementar la complejidad del código en lugar de simplificarla. En general el uso de cortes debería ser evitado, y sería mejor replantear las condiciones para que no se generen resultados incorrectos.
  • 26. Entrada y Salida En archivos: see(File) La entrada actual ahora es File. seeing(File) File se unifica con el nombre del archivo de entrada actual seen Cierra el archivo de entrada actual tell(File) El archivo de salida actual es File telling(File) File se unifica con el nombre del archivo de salida actual told Cierra el archivo de salida actual
  • 27. Entrada y Salida Términos de entrada y salida read(Term) Lee el término hasta el delimitador punto del flujo de entrada actual, si encuentra eof regresa el átomo eof. write(Term) Escribe un término al fluje de salida actual. print(Term) Escribe un término al flujo de salida actual. Usa un predicado portray/1 definido por el usuario para la escritura, o de no existir, usa write. writeq(Term) Escribe un término al flujo de salida actual en una forma estándar de entrada para lectura.
  • 28. Entrada y Salida Caracter de entrada y salida get(N) N es el código ASCII del siguiente caracter no nulo imprimible en el flujo de entrada actual. Si es fin de archivo, se retorna un -1 put(N) Pone el caracter correspondiente al código ASCII de N en el flujo de salida actual. nl Escribe una nueva línea tab(N) N espacios se ponen en el flujo de salida
  • 29. Acceso y manipulación de programas y sistema clause(Head,Body) assert(Clause) agrega la cláusula al final de la base de datos asserta(Clause) retract(Clause_Head) consult(File_Name) system(Command) Ejecuta Command en el sistema operativo
  • 30. Aplicaciones Gramáticas Independientes de Contexto y Gramáticas de Cláusulas Definidas Prolog se originó de intentos de usar la lógica para expresar reglas gramaticales y formalizar los procesos de parseo. Prolog tiene reglas de sintáxis especiales llamadas Gramática de Cláusulas Definidas, que son una generalización de las gramáticas libres de contexto.
  • 31. Aplicaciones Los no terminales se expresan como átomos Prolog, los elementos en el cuerpo se separan con comas y secuencias de símbolos terminales se escriben como listas de átomos. Para cada no terminal, S, una gramática define un lenguaje que se obtiene por la aplicación no determinista de reglas gramaticales iniciando en S. s --> [a],[b]. s --> [a],s,[b].
  • 32. Aplicaciones Una ilustración de como se usan estas DCGs, la cadena [a,a,b,b] se le proporciona a la gramática para su parsing. ?- s([a,a,b,b],[]). yes Vea los ejemplos anexos para la formación de oraciones, sin y con control de número.
  • 33. Aplicaciones Estructuras de Datos incompletas. Una estructura de datos incompleta es una estructura de datos que contiene una variable. Tal estructura se dice estar 'parcialmente instanciada' o 'incompleta'. Aquí ilustramos la programación con estructuras de datos incompletas modificando el código para un árbol de búsqueda binaria. El código resultante permite la relación inserted_in_is para definir tanto la relación de inserción como la de membresía.
  • 34. Aplicaciones Programación de Meta Nivel Los meta programas tratan otros programas como datos. Analizan, transforman y simulan otros programas. Las cláusulas Prolog pueden pasarse como argumentos, ser agregadas y eliminadas de la base de datos, y ser construidas y ejecutadas por un programa prolog. Las implementaciones pueden requerir que el functor y aridad de la cláusula esté previamente declarado como tipo dinámico
  • 35. Aplicaciones Assert/Retract El siguiente ejemplo muestra como las cláusulas pueden ser agregadas y removidas de la base de datos Prolog. Muestra como simular una sentencia de asignación usando assert y retract para modificar la asociación entre una variable y un valor.
  • 36. Aplicaciones :- dynamic x/1 .% this may be required in some Prologs x(0). % An initial value is required in this example assign(X,V) :- Old =..[X,_], retract(Old), New =..[X,V], assert(New). Aquí hay un ejemplo del uso del predicado assign ?- x(N). N=0 yes ?- assign(x,5). yes ?- x(N). N=5
  • 37. Aplicaciones Sistemas expertos Los sistemas expertos se pueden programar en uno de dos modos en Prolog. Uno es construir una base de conocimiento usando hechos y reglas Prolog y usar la máquina de inferencia empotrada para responder consultas. La otra es construir una máquina de inferencia más poderosa en prolog y usarla para implementar un sistema experto.
  • 38. Aplicaciones Comparación de patrones: Diferenciación simbólica d(X,X,1) :- !. d(C,X,0) :- atomic(C). d(-U,X,-A) :- d(U,X,A). d(U+V,X,A+B) :- d(U,X,A), d(V,X,B). d(U-V,X,A-B) :- d(U,X,A), d(V,X,B). d(C*U,X,C*A) :- atomic(C), CX, d(U,X,A),!. d(U*V,X,B*U+A*V) :- d(U,X,A), D(V,X,B). d(U/V,X,A) :- d(U*V^-1,X,A) d(U^C,X,C*U^(C-1)*W) :- atomic(C), CX, d(U,X,W). d(log(U),X,A*U^(-1)) :- d(U,X,A).
  • 39. Aplicaciones Programación Orientada a Objetos. Otra de las aplicaciones de prolog es la evaluación de estructuras de datos de tipo objeto. Como sabemos un tipo objeto tiene inherentes métodos y datos que se instancían en el momento de su declaración. En el ejemplo de prolog podemos ver una propuesta de la definición de estas relaciones.