590 likes | 992 Views
PROLOG Programación Lógica (II). Mar Mejía Murillo. CONTENIDO. Introducción Sintáxis Tipos Expresiones Unificación Funciones Listas Iteración Backtracking. Aplicaciones. Negación y Cortes Cláusulas de Gramáticas definidas Estructuras de datos incompletas Programación de Meta Nivel
E N D
PROLOG Programación Lógica (II) Mar Mejía Murillo
CONTENIDO • Introducción • Sintáxis • Tipos • Expresiones • Unificación • Funciones • Listas • Iteración • Backtracking • Aplicaciones • Negación y Cortes • Cláusulas de Gramáticas definidas • Estructuras de datos incompletas • Programación de Meta Nivel • Programación de Segundo Orden • Bases de Datos • Sistemas Expertos • Programación Orientada a Objetos
Recapitulando • Estructura de Programas en Prolog • Un programa consiste en una base de datos de hechos, reglas y consultas. • Hecho 1. • Hecho 2. • Regla 1 :- Condiciones 1. • Regla 2 :- Condiciones 2. • Regla 3 :- Condiciones 3. • Consulta ?- Consulta. • Variable1 • Variable2 • constante1 • 'Constante 2'
Recapitulando Definiciones inductivas: Casos Base e Inductivo Torres de Hanoi Mover N discos de tamaños consecutivos desde un pin 'a' a un pin 'b' usando un pin intermedio 'c'. La regla es que no puede haber un disco de mayor tamaño arriba de otro de menor tamaño. hanoi(N) :- hanoi(N, a, b, c). hanoi(0,_,_,_). hanoi(N,FromPin,ToPin,UsingPin) :- M is N-1, hanoi(M,FromPin,UsingPin,ToPin), move(FromPin,ToPin), hanoi(M,UsingPin,ToPin,FromPin). move(From,To) :- write([move, disk, from, pin, From, to, pin, ToPin]), nl.
Recapitulando Listas: append, member list([]). list([X|L]) :- [list(L). Abbrev: [X1|[...[Xn|[]...] = [X1,...Xn] append([],L,L). append([X|L1],L2,[X|L12]) :- append(L1,L2,L12). member(X,L) :- concat(_,[X|_],L).
Recapitulando Ancestros ancestor(A,D) :- parent(A,B). ancestor(A,D) :- parent(A,C),ancestor(C,D). pero no: ancestor(A,D) :- ancestor(A,P), parent(P,D). Porque puede producirse una recursión infinita
Recapitulando Búsqueda de 'Primero el más profundo' Una base de datos de arcos (asumimos que son arcos dirijidos) de la forma: a(node_i,node_j). Reglas para la búsqueda del grafo: go(From,To,Trail). go(From,To,Trail) :- a(From,In), not visited(In,Trail), go(In,To,[In|Trail]). visited(A,T) :- member(A,T).
Recapitulando Entrada/Salida Términos, caracteres, archivos, analizador léxico -read(T), write(T), nl. -get0(N), put(N): valor ascii del caracter -name(Name,Ascii_list). -see(F), seeing(F), seen, tell(F), telling(F), told.
Recapitulando Procesamiento de lenguaje natural: Las gramáticas libres de contexto pueden ser representadas como reglas de Prolog. Por ejemplo la regla sentence ::= noun_clause verb_clause Se puede implementar en Prolog como sentence(S) :- append(NC,VC,S), noun_clause(NC), verb_clause(VC). Note que aparecen 2 argumentos en la consulta. Ambos son listas y la primera es la oración a parsear, la segunda, los elementos restantes de la lista, que en este caso es vacía.
Recapitulando Un programa de Prolog consiste en una base de datos de hechos y reglas. No hay imposición de estructura en un programa Prolog, no hay procedimiento principal, y no hay anidamiento de definiciones. Todos los hechos y reglas son globales en alcance, y el alcance de una variable es el hecho o la regla donde aparece. La legibilidad de un programa Prolog se le adosa al programador. Un programa en Prolog se ejecuta realizando una pregunta. La pregunta se llama consulta. Los hechos, reglas y consultas se llaman cláusulas.
Sintaxis Hechos Un hecho es simplemente eso, un hecho. Un hecho en el lenguaje cotidiano es frecuentemente una proposición como "Está soleado" o "Es verano". En Prolog, tales hechos se representan como sigue: 'Está soleado'. 'Es verano'. Consultas Una consulta en prolog es la acción de preguntarle al programa sobre información contenida en la base de datos. Luego entonces, las consultas usualmente ocurren en el modo interactivo. Después de cargar un programa, se tiene un símbolo de consulta, ?-
Sintaxis Consultas Un Yes significa que la información en la base de datos es consistente con el tema de la consulta. Otra manera de expresar esto es que el programa es capaz de probar la consulta como verdadera con la información disponible en la base de datos. Si un hecho no es deducible de la base de datos, el sistema responde No, lo que significa que basados en la información disponible (Asumiendo un mundo cerrado), el hecho no es deducible.Si la base de datos no contiene información suficiente para responder la consulta, dice 'No': ?- 'Hace frío'. No ?-
Sintaxis Reglas Las reglas extienden las capacidades de un programa lógico. Son las que le permiten a Prolog de hacer su proceso de toma de decisiones. El siguiente programa contiene dos reglas de temperatura. La primera se lee "Hace calor si es verano y está soleado". La segunda como "Hace frío si es invierno y está nevando". 'Está soleado'. 'Es verano'. 'Hace calor' :- 'Es verano', 'Está soleado'. 'Hace frío' :- 'Es invierno', 'Está nevando'. ?- 'Hace calor'. Yes ?-
Tipos Prolog tiene definiciones de números, átomos, listas, tuplas y patrones. Los tipos de objetos que pueden ser pasados como argumentos se definen en esta sección. Tipos simples Son dependientes de implementación en Prolog, sin embargo, la mayoría de las implementaciones proveen de los tipos simples resumidos en esta tabla TIPO VALORES boolean true, fail integer enteros real números de punto flotante variable variables atom secuencias de caracteres
Tipos Las constantes booleanas no son usualmente pasadas como parámetros, sino que son proposiciones. La constante fail es útil para forzar la generación de todas las soluciones. Las variables son cadenas de caracteres empezando con letra mayúscula. Los átomos son o bien cadenas de caracteres entre apóstrofes, o bien palabras empezando con una letra pequeña.
Tipos Tipos compuestos En prolog, la diferencia entre programas y datos es ambigua. Los hechos y las reglas son usados como datos y los datos usualmente son pasados como argumentos a los predicados. Las listas son la estructura de datos más común en Prolog. Se parecen mucho a los arreglos en el hecho de que son listas secuenciales de elementos, y a las pilas en que solo puede acceder a los elementos de manera secuencial, eso es, desde el final solamente, y no en orden aleatorio.
Tipos Además de las listas, Prolog permite patrones arbitrarios como datos. Los patrones se pueden usar para representar tuplas. Prolog no tiene el tipo 'array'. Pero los arreglos pueden ser representados como una lista, y los arreglos multidimensionales como listas de listas. Una representación alternativa es hacerlo como un grupo de hechos en la base de datos. TIPO REPRESENTACIÓN lista [secuencia de ítems separados por coma] patrón secuenca de ítems
Tipos Una lista en Prolog se designa por los corchetes[]. Un ejemplo de lista es [perro, gato, ratón] Lo que significa que la lista contiene los elementos perro, gato y ratón, en ese orden. Los elementos en una lista prolog están ordenados, aunque no hay índices.
Tipos Los registros o tuplas se representan como patrones: libro(autor(aaby,anthony),título(labManual),data(1991)) Los elementos de una tupla se accesan por comparación de patrón. book(Titulo,Autor,Publicador,Fecha). autor(Paterno,Materno,Nombre). publicador(Compañía,Ciudad). libro(T,A,publicador(C,roma),Date).
Tipos Predicados de Tipo Puesto que Prolog es un lenguaje débilmente tipificado, es importante que el usuario determine el tipo de un parámetro. Los siguientes predicados ya incluidos se usan para determinar el tipo de un parámetro: PREDICATE CHECK IF var(V) V is a variable nonvar(NV) NV is not a variable atom(A) A is an atom integer(I) I is an integer real(R) R is a floating point number number(N) N is an integer or real atomic(A) A is an atom or a number functor(T,F,A) T is a term with functor F and arity A T =..L T is a term, L is a list (see example below). clause(H,T) H :- T is a rule in the program
Tipos Los últimos 3 son útiles en la manipulación de programa (metalógica o meta-programación) y requieren una explicación adicional. clause(H,T) se usa para checar los contenidos de la base de datos. functor(T,F,A) y T=..L se usan para la manipulación de términos, Los functores se usan así: functor(T,F,A) T es un término, F es un functor, A es la aridad.
Tipos Ejemplo: ?- functor(t(a,b,c),F,A). F = t A = 3 yes t es el functor del término t(a,b,c), y 3 es la aridad (número de argumentos) del término.
Tipos El predicado =.. (univ) Se usa para componer y descomponer términos. Ejemplo: ?- t(a,b,c) =..L. L = [t,a,b,c] yes ?- T =..[t,a,b,c]. T = t(a,b,c) yes
Expresiones Las expresiones aritméticas son evaluadas con el predicado 'is', que se usa como un operador infijo de la siguiente forma: variable is expression Ejemplo: ?- X is 3*4 X=12
Expresiones Operadores aritméticos Prolog provee de los operadores aritméticos estándar resumidos en la siguiente tabla: SYMBOL OPERATION + addition - subtraction * multiplication / real division // integer division mod modulus ** power
Expresiones Predicados Booleanos Además de los predicados booleanos usuales, Prolog tiene operadores de comparación más generales, que permiten comparar términos y predicados para probar unificabilidad y si los términos son idénticos.
Expresiones SYMBOL OPERATION ACTION A ?= B unifiable A and B are unifiable but does not unify A and B A = B unify unifys A and B if possible A \= B not unifiable A == B identical does not unify A and B A \== B not identical A =:= B equal (value) evaluates A and B to determine if equal A =\= B not equal (value) A < B less than (numeric) A =< B less or equal (numeric) A > B greater than (numeric) A >= B greater or equal (numeric) A @< B less than (terms) A @=< B less or equal (terms) A @> B greater than (terms) A @>= B greater or equal (terms)
Expresiones Por ejemplo, todos los siguientes son true 3 @< 4 3 @< a a @< abc6 abc6 @< t(c,d) t(c,d) @< t(c,d,X)
Expresiones Definición en programación lógica de un número natural. % natural_number(N) <- N es un número natural. natural_number(0). natural_number(s(N)) :- natural_number(N). Definición en Prolog de un número natural. natural_number(N) :- integer(N), N >= 0.
Expresiones Definición en programación lógica de desigualdades % less_than(M,N) <- M es menos que N less_than(0,s(M)) :- natural_number(M). less_than(s(M),s(N)) :- less_than(M,N). % less_than_or_equal(M,N) <- M is less than or equal to N less_than_or_equal(0,N) :- natural_number(N). less_than_or_equal(s(M),s(N)) :- less_than_or_equal(M,N). Definición en Prolog de una desigualdad. M =< N.
Expresiones Definición en programación lógica de suma/resta % plus(X,Y,Z) <- Z is X + Y plus(0,N,N) :- natural_number(N). plus(s(M),N,s(Z)) :- plus(M,N,Z). Definición en prolog de suma/resta plus(M,N,Sum) :- Sum is M+N. susbtraction(M,N,Subs) :- Subs is M-N.
Expresiones Definición en programación lógica de multiplicación % times(X,Y,Z) <- Z is X*Y times(0,N,0) :- natural_number(N). times(s(M),N,Z) :- times(M,N,W), plus(W,N,Z). Definición en Prolog de multiplicación times(M,N,Product) :- Product is M*N.
Expresiones Operadores Lógicos. Los predicados son funciones que regresan un valor booleano. Por tanto, los operadores lógicos están incluidos en el lenguaje. La coma al lado derecho de una regla es una conjunción lógica (and). El símbolo :- es la implicación lógica (if). Además, Prolog tiene operadores de negación (not) y disyunción (or).
Expresiones Los operadores lógicos se usan en la definición de reglas, por tanto: a :- b. % a if b a :- b,c. % a if b and c. a :- b;c. % a if b or c. a :- \+ b. % a if b is not provable a :- not b. % a if b fails a :- b -> c;d. % a if (if b then c else d)
Expresiones Esta tabla resume los operadores lógicos SYMBOL OPERATION not negation \+ not provable , logical conjunction ; logical disjunction :- logical implication -> if-then-else
Unificación y Comparación de Patrones Los argumentos en una consulta son comparados (o unificados, en terminología prolog) para seleccionar la regla apropiada. Aquí hay un ejemplo que hace un uso extensivo de la comparación de patrones. Las reglas para calcular las derivadas de expresiones polinomiales se pueden escribir como reglas de prolog. Una expresión polinomial dada se compara contra el primer argumento de la regla, y la derivada correspondiente se retorna.
Unificación y Comparación de Patrones % deriv(Polynomial, variable, derivative) % dc/dx = 0 deriv(C,X,0) :- number(C). % dx/dx} = 1 deriv(X,X,1). % d(cv)/dx = c(dv/dx) deriv(C*U,X,C*DU) :- number(C), deriv(U,X,DU). % d(u v)/dx = u(dv/dx) + v(du/dx) deriv(U*V,X,U*DV + V*DU) :- deriv(U,X,DU), deriv(V,X,DV). % d(u ± v)/dx = du/dx ± dv/dx deriv(U+V,X,DU+DV) :- deriv(U,X,DU), deriv(V,X,DV). deriv(U-V,X,DU-DV) :- deriv(U,X,DU), deriv(V,X,DV). % du^n/dx = nu^{n-1}(du/dx) deriv(U^+N,X,N*U^+N1*DU) :- N1 is N-1, deriv(U,X,DU).
Unificación y Comparación de Patrones El código prolog es con frecuencia bidireccional. En código bidireccional, los argumentos se pueden usar o bien como entrada o bien como salida. Por ejemplo, este código puede usarse tanto para diferenciación como para integración con consultas de la forma: ?- deriv(Integral,X,Derivada). Donde se pueden instanciar cualquiera, Derivada o Integral (Únicamente considere que la integral puede resultar más difícil de comparar, porque se pierden datos al derivar, que se necesitan al integrar).
Funciones Prolog no tiene un tipo para las funciones, por tanto, se tienen que definir como relaciones. Eso significa, que ambos, los argumentos de la función y el resultado, deben ser parámetros de la relación. En otras palabras, la composición de dos funciones no se puede construir. Como ejemplo, aquí tenemos la definición de factorial en Prolog, en forma de relación. Note que la definición requiere 2 valores, uno para el caso base y otro para el inductivo. fac(0,1). fac(N,F) :- N > 0, M is N - 1, fac(M,Fm), F is N * Fm.
Funciones La segunda regla establece que si N>0, M=N-1, Fm es (N-1)! y F=N*Fm, entonces, F es N!. Tome en cuenta cómo se utiliza 'is'. En éste ejemplo, se refiere a un operador de asignación, sin embargo, no se puede usar para reasignar una variable a un nuevo valor. En el sentido lógico, el orden de las cláusulas en el cuerpo de una regla son irrelevantes, sin embargo, el orden puede importar en un sentido práctico. M no debe ser una variable en la llamada recursiva o vamos a tener un ciclo infinito.
Funciones Muchas de las torpezas de esta definición vienen del hecho de que fac se define como una relación y por tanto, no se puede usar en una expresión. Las relaciones comúnmente se definen usando múltiples reglas y el orden de las reglas puede determinar el resultado. En este caso, el orden de las reglas es irrelevante, puesto que para cada valor de N solo una regla es aplicable. Veamos ahora los equivalentes en Prolog a las funciones gcd (máximo común divisor) y serie Fibonacci.
Funciones gcd(A,B,GCD) :- A = B, GCD = A. gcd(A,B,GCD) :- A < B, NB is B - A, gcd(A,NB,GCD). gcd(A,B,GCD) :- A > B, NA is A - B, gcd(NA,B,GCD). fib(0,1). fib(1,1). fib(N,F) :- N > 1, N1 is N - 1, N2 is N - 2, fib(N1,F1), fib(N2,F2), F is F1 + F2.
Funciones Definición en Prolog del menor. minimum(M,N,M) :- M =< N. minimum(M,N,N) :- N =< M.
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).