Contenido Ingeniería Informática Ingeniería Técnica en Informática de Sistemas 1. Predicados extra-lógicos 2. Predicados aritméticos 3. Entrada/salida de términos 4. Unificación y no unificación 5. Comparación de términos 6. Declaración de operadores Departamento de Lenguajes y Ciencias de la Computación Universidad de Málaga 2 Prolog = Programación lógica Base teórica: Prolog puro se basa exclusivamente en la lógica de Horn Programa (cláusulas de Horn) Motor de Inferencia (SLD-Resolución) consultas respuestas computadas Ventajas: análisis y transformación de programas Inconvenientes: acceso a recursos hardware/software 4
Prolog = Programación lógica + Extra-lógica Aplicación práctica: extendemos extra-lógicamente el lenguaje para dar acceso a ciertos recursos (aritmética, entrada/salida ) Predicados extra-lógicos (I) Características comunes: están predefinidos por el sistema Prolog (bibliotecas) Programa (cláusulas de Horn) Motor de Inferencia (SLD-Resolución) + Evaluador Extra-lógico consultas respuestas computadas se resuelven al margen de la SLD-Resolución, aprovechando el hardware/software de la plataforma tienen asociado un algoritmo de evaluación cuya ejecución termina en éxito o fracaso, o bien genera un error suelen ser deterministas (respuesta única) y soportar sólo algunos usos Ventajas: aplicación práctica, expresividad, eficiencia Inconvenientes: dificulta análisis y transformación de programas 5 6 Predicados extra-lógicos (y II) Sólo estudiaremos algunos predicados extra-lógicos: aritméticos entrada/salida comparación de términos declaración de operadores Predicados Aritméticos Anotaremos las cabeceras de los predicados extra-lógicos con los usos posibles (+ entrada, - salida,? entrada o salida): is(?x,+y) read(-x) write(+x) 7
Predicados aritméticos Permiten evaluar expresiones aritméticas: (1 + sqrt(5)) / 2 = 1.61803 Operadores Prolog Definición: un operador Prolog es un functor de aridad 1 o 2 que puede escribirse de forma prefija, postfija o infija, prescindiendo de los paréntesis Para incorporar expresiones aritméticas a Prolog es necesario: extender la sintaxis para soportar operadores X + Y +(X,Y) % +/2, infijo - X -(X) % -/1, prefijo (1 + sqrt(5)) / 2 añadir funciones aritméticas predefinidas (sqrt,sin, ) añadir un predicado extra-lógico que solicite la evaluación de expresiones aritméticas (Prolog no evalúa términos) son un mecanismo exclusivamente sintáctico, no tienen asociada ninguna operación (semántica) para evitar ambigüedades, se definen prioridades y asociatividad pueden ser predefinidos o declarados por el usuario 9 10 Operadores aritméticos Funciones aritméticas básicas Prolog predefine los siguientes operadores aritméticos: Prolog predefine las siguientes funciones aritméticas básicas: X + Y suma X Y resta - X menos unario X * Y producto X / Y cociente X // Y cociente división entera X mod Y resto división entera X ** Y potencia al escribir 5 + 3 * 7 Prolog entiende +(5, *(3,7)) Prolog no evalúa los términos: +(5, *(3,7)) 26 abs(x) valor absoluto sign(x) signo (-1, 0, 1) max(x,y) máximo min(x,y) mínimo random(x) entero aleatorio entre 0 y X-1 sqrt(x) raíz cuadrada floor(x) techo ceiling(x) suelo round(x) redondeo truncate(x) truncamiento 11 12
Otras funciones aritméticas trigonométricas: sin(x), cos(x), tan(x) asin(x,y), acos(x), atan(x), atan(x,y) Expresión aritmética Definición: un término Prolog es un expresión aritmética si 1) sus functores son operadores o funciones aritméticas 2) sus constantes son funciones aritméticas o números 3) sus variables están instanciadas a expresiones aritméticas logarítmicas y exponenciales: log(x), log10(x) exp(x) 2.0 * (pi + sin(x)) X libre, no es expresión aritmética cos(a)**2 no es una expresión aritmética 5 + Y {Y/b}, no es una expresión aritmética 2.0 * (pi + sin(x)) {X/2*5} una expresión aritmética constantes: pi, e una expresión aritmética no contiene variables libres una expresión aritmética es un término no se evalúa por defecto 13 14 El predicado aritmético is/2 Usos del predicado is/2 se utiliza para evaluar expresiones aritméticas is(?x,+y) X debe ser una variable libre o un número Y debe ser una expresión aritmética algoritmo is(x,y) 1. v = evaluar(y) (si hay error, se eleva una excepción) 2. unificar X con v, acabando en éxito o fracaso el predicado is/2 puede instanciar la variable X el functoris/2 es un operador: is(x,y) = X is Y?- 9 is 2*4+1.?- X is 2*4+1. X = 9 ;?- Y = 2*4, X is Y+1. X = 9 ;?- Phi is (1+sqrt(5))/2. Phi = 1.61803 ;?- X is 2/(1-1). ERROR: Arithmetic: evaluation error: `zero_divisor 15 16
Errores comunes al usar is/2?- X is Y+1. ERROR: Arguments are not sufficiently instantiated?- X is y+1. ERROR: Arithmetic: `y/0' is not a function?- 8+1 is 2*4+1.?- X = 0, X is X+1. Operadores relacionales aritméticos Se emplean para comparar expresiones aritméticas: +X =:= +Y +X < +Y +X =< +Y +X =\= +Y +X > +Y +X >= +Y X e Y deben ser expresiones aritméticas algoritmo X comp Y 1.vx= evaluar(x), vy= evaluar(y) (si hay error, elevar excepción) 2.res=vx compvy 3. si res es cierto acabar con éxito, sino acabar con fracaso donde comp {=:=, =\=, <, >, =<, >=} 17 18 Uso de la comparación aritmética Programando con predicados extra-lógicos Sólo se puede usar como test(+,+), pues no hay variables libres:?- 2.0 =:= 1.0 + 1.0.?- 2 =:= 1.0 + 1.0.?- 3 < 6 < 9. ERROR: Syntax error: Operator priority clash?- X is (3 < 9). ERROR: Arithmetic: `(<)/2' is not a function Las técnicas de programación básicas siguen disponibles: recursión recursión de cola generar/comprobar pero su aplicación esconde algunos matices Definiremos versiones extra-lógicas de los predicados sobre naturales 19 20
Predicados extra-lógicos y usos posibles Predicados extra-lógicos y recursión % menor(+x,+y) menor(x,y) :- X < Y. % minimo(+x,+y,?z) minimo(x,y,x) :- X =< Y. minimo(x,y,y) :- Y < X. factorial(0,1). factorial(x,f) :- X > 0, X1 is X-1, factorial(x1,t), F is X*T. % guarda % reducción % composición % suma(+x,+y,?z) suma(x,y,z) :- Z is X+Y. Ventajas: simplicidad, eficiencia Inconvenientes: menos usos posibles (no son relacionales) La unificación pierde potencia: no basta para distinguir casos base y recursivo no puede reducir el problema ni componer la solución 21 22 Predicados extra-lógicos y recursión de cola Predicados extra-lógicos y generadores factorial(x,f) :- fact_cola(x,1,f). fact_cola(0,f,f). fact_cola(x,ac,f) :- X > 0, X1 is X-1, % guarda % reducción entre(i,j,i) :- I =< J. entre(i,j,k) :- I < J, I1 is I+1, entre(i1,j,k). Ac1 is X*Ac, % actualización fact_cola(x1,ac1,f). La unificación pierde potencia: no basta para distinguir casos base y recursivo no puede reducir el problema ni actualizar acumulador Uso Comportamiento Significado (+,+,+) test comprueba I K J (+,+,-) generador acotado genera K= I,,J Los casos base y recursivo no son excluyentes generación 23 24
Predicados extra-lógicos y generar/comprobar Problema: descomponer un natural N en suma de dos pares X e Y Aplicación: puzzles cripto-aritméticos Problema: Dada la suma de letras % es_par(+x) es_par(x) :- X mod 2 =:= 0. C A M A + M E S A % en_pares(+n,?x,?y) en_pares(n,x,y) :- es_par(n), entre(0,n,x), es_par(x), Y is N-X. % comprobar % generar (acotado) % comprobar % generar (único) V I C I O asignar a cada letra un dígito distinto entre 0 y 9 de manera que la suma resultante cuadre Sugerencia: aplicar el paradigma generar/comprobar 25 26 Ejercicios Ejercicios Define los siguientes predicados: 9. Resuelve el puzzle cripto-aritmético: 1.es_natural(X), genera los naturales X = 0,1,2,3, 2.es_entero(X), genera los enteros X = 0,-1,1,-2,2, 3.num_digitos(X,Y), el entero X tiene Y digitos 4.dig_iesimo(X,I,D), D es el I-ésimo dígito del entero X 5.mcd(X,Y,Z), Z es el máximo común divisor de X e Y 6.pascal(I,J,X), X es el elemento (I,J) del triángulo de Pascal 7.fibonacci(N,F), F es el N-ésimo Fibonacci 8.biseccion(F,A,B,R), R es una raíz de la función F en el intervalo [A,B] S E N D + M O R E M O N E Y 10. Dada la matriz de orden 3 A B C D E F G H I asigna a cada letra un dígito distinto, de manera que las filas, columnas y diagonales principales sumen 15 27 28
Periféricos y flujos La entrada/salida de Prolog está basada en flujos: Entrada/Salida de Términos los flujos permiten tratar uniformemente una variedad de periféricos, como una secuencia de información un flujo es un tipo abstracto que soporta, entre otras, operaciones de apertura, cierre, lectura y escritura un flujo puede estar en cuatro modos de operación: entrada, salida, concatenación y actualización un flujo soporta tres tipos de información: binarios, texto y términos 30 Flujos de términos y entrada/salida estándar un flujo de términos es una secuencia de términos Prolog terminados en un punto y separados por blancos (espacios, tabuladores y saltos de línea) t(h(x), a). f(a,1+2). 4*pi. s(s(s(c))). s(s(a)). sólo se pueden leer y escribir términos completos para simplificar, emplearemos flujos de términos asociados a la entrada y salida estándar (por defecto, teclado y pantalla) Términos Prolog y salida estándar write(+x) escribe el término X en la salida estándar nl escribe un fin de línea en la salida estándar tab(+n) escribe N espacios en la salida estándar (N es una expresión aritmética entera) display(+x) escribe el término X en la salida estándar (sin tener en cuenta las declaraciones de operadores) 31 32
Ejemplos de salida estándar?- write(2*5+1). % Prolog no evalúa los términos 2*5+1?- write(s(s(x))). % X está libre s(s(_g278))?- display(2*5+1). % tal y como lo entiende Prolog +(*(2,5),1)?- tab(3+5), write(a). % tab/1 es aritmético a Términos Prolog y entrada estándar read(-x) lee el siguiente término de la entrada estándar y lo unifica con X, acabando en éxito o fracaso. Aunque es un generador único, cada reevaluación puede generar una respuesta distinta (efecto lateral)? read(x).?- read(fecha(d,m,a)). : f(a,2*pi). : fecha(2,febrero). X = f(_g275,2*pi) Prolog muestra el cursor : cuando espera datos por teclado 33 34 una calculadora simple (I) una calculadora simple (y II) Escribir un programa Prolog que acepte por teclado expresiones aritméticas sin variables y muestre el resultado de evaluarlas. El programa debe terminar al introducir la palabra fin.?- calc. >> 2+3*5. 17 >> sin(pi) + cos(pi). -1 >> fin. calc :- write('>> '), read(exp), evalua(exp). evalua(fin). evalua(exp) :- Exp \= fin, % Exp y fin no unifican R is Exp, write_ln(r), % write + nl calc. 35 36
Unificación y no unificación Unificación y Unificación?X =?Y unifica X con Y, instanciando variables (test o generador único) no tiene en cuenta el test de ocurrencia +X \= +Y comprueba que X e Y no unifican (test, no instancia variables) no tiene en cuenta el test de ocurrencia unify_with_occurs_check(?x,?y) unifica X con Y, instanciando variables (test o generador único) tiene en cuenta el test de ocurrencia son extra-lógicos 38 Orden estándar de los términos Prolog define una relación de orden total sobre los términos: Comparación de Términos 1. variables < números < átomos < estructuras 2. las variables se comparan por la edad : antigua < nueva 3. los números se comparan por su valor 4. los átomos se comparan alfabéticamente 5. las estructuras se comparan: primero, numéricamente por la aridad, después, alfabéticamente por el átomo del functor recursivamente, argumento a argumento de izq. a der. Los términos Prolog satisfacen la propiedad de tricotomía 40
Comparación de términos Prolog Prolog predefine los siguientes operadores: +X == +Y +X \== +Y +X @< +Y +X @> +Y +X @=< +Y +X @>= +Y todos son tests(+,+), no instancian variables el evaluador extra-lógico ejecuta la comparación según el orden estándar, dando lugar a un éxito o un fracaso Ejemplos de comparación de términos?- 1 + 2 == 1 + 2.?- 1 + 2 == 2 + 1. % no evalúa?- 1 + 2 =:= 2 + 1.?- f(x) == f(y). % no instancia?- f(x) = f(y). X = Y = _G251 41 42 Operadores Prolog Declaración de Operadores mejoran la legibilidad, permitiendo prescindir de los paréntesis son una mera facilidad sintáctica, no tienen asociada ninguna operación (semántica) 2 + 3 * 5 = +(2,*(3,5)) la precedencia y asociatividad evitan ambigüedades que resultan al prescindir de los paréntesis X ** 3 mod 13 = (X**3) mod 13 1+2-3+4-5 = (((1+2)-3)+4)-5 44
Precedencia de operadores cada operador tiene asignada una precedencia (1..1200) Dado un término Prolog, su precedencia es: si es compuesto la de su functor principal si no es compuesto (constante o variable) 0 si está entre paréntesis 0 2 + A * 3 % prec: + 500 * 400 + 500 2 * 400 mayor precedencia Asociatividad de operadores se aplica cuando coinciden las precedencias un operador puede ser: asociativo a la izquierda: su argumento izquierdo puede tener menor o igual precedencia asociativo a la derecha: su argumento derecho puede tener menor o igual precedencia no asociativo: sus argumentos deben tener menor precedencia A * B / 2 % *,/ 400, asoc. izq. 400 / 400 * 2 A 3 menor precedencia A B 45 46 La directiva op/3 El programador puede declarar sus propios operadores: :- op(+precedencia, +Tipo, +mbre). Precedencia: un entero entre 1 y 1200 Tipo: indica posición (f) y asociatividad (y) o no (x) yfx infijo, asociativo a la izquierda xfy infijo, asociativo a la derecha xfx infijo, no asociativo fy prefijo, asociativo fx prefijo, no asociativo yf postfijo, asociativo xf postfijo, no asociativo mbre: átomo El predicado current_op/3 Permite consultar qué operadores hay predefinidos y declarados: current_op(?precedencia,?tipo,?mbre)?- current_op(p,t,-). P = 500 T = fx ; P = 500 T = yfx ; 47 48
quién habla qué? Operador: :- op(800,xfx,habla). Predicado: % habla/2: persona habla idioma. elena habla ingles. elena habla frances. juan habla ingles. francisco habla ingles. francisco habla aleman. marisa habla esperanto. marisa habla italiano. Objetivos:?- Quien habla ingles.?- elena habla Que.?- Quien habla Que. Aritmética de Peano y operadores (I) Objetos: declaramos un operador para representar naturales :- op(100,fy,s). s s s s c s(s(s(s(c)))) Definición de dominio: declaramos un operador es_natural :- op(800, fx, es_natural). es_natural c. es_natural s X :- es_natural X. 49 50 Aritmética de Peano y operadores (II) Aritmética de Peano y operadores (y III) Relaciones aritméticas: los operadores aritméticos están predefinidos (+,*,**, ) podemos escribir s s s c + s s c Problema: los operadores aritméticos son binarios (+/2), y las relaciones aritméticas son ternarias (suma/3) % suma/3 c + Y??? :- s X + Y??? :- Cómo lo resolvemos? Solución: introducimos un operador que conecte una operación aritmética básica con su resultado :- op(800,xfx,= ). El predicado = /2 es una versión lógica (simplificada) de is/2 A = B B es el natural que resulta de la operación aritmética A % = /2, operación + c + Y = Y :- es_natural Y. s X + Y = s Z :- X + Y = Z. 51 52
Ejercicios 1. Define otros predicados de la aritmética natural mediante operadores (producto, potencia, factorial, ). Aplica recursión de cola cuando sea conveniente. 2. Declara operadores cm y m para representar medidas de longitud expresadas en centímetros y metros: 37.5 cm 4 m Declara un operador := y define un predicado que permita sumar longitudes, expresando el resultado en la mayor unidad, tal y como muestran los objetivos:?- 1 cm + 3 cm := 4 cm.?- 37.5 cm + 4 m := X. X = 4.375 m 53