Ingeniería Informática Ingeniería Técnica en Informática de Sistemas Departamento de Lenguajes y Ciencias de la Computación Universidad de Málaga Contenido 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 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) consultas respuestas computadas Motor de Inferencia (SLD-Resolución) 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 ) Programa (cláusulas de Horn) consultas respuestas computadas Motor de Inferencia (SLD-Resolución) + Evaluador Extra-lógico 5 Predicados extra-lógicos (I) Características comunes: están predefinidos por el sistema Prolog (bibliotecas) 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 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 Anotaremos las cabeceras de los predicados extra-lógicos con los usos posibles (+ entrada, - salida,? entrada o salida): Ejemplo: is(?x,+y) read(-x) write(+x) 7 Predicados Aritméticos
Predicados aritméticos Permiten evaluar expresiones aritméticas: (1 + sqrt(5)) / 2 = 1.61803 Para incorporar expresiones aritméticas a Prolog es necesario: extender la sintaxis para soportar operadores (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) 9 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 Ejemplo: X + Y +(X,Y) % +/2, infijo - X -(X) % -/1, prefijo 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 10
Operadores aritméticos Prolog predefine los siguientes operadores aritméticos: 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 11 Funciones aritméticas básicas Prolog predefine las siguientes funciones aritméticas básicas: 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 12
Otras funciones aritméticas trigonométricas: sin(x), cos(x), tan(x) asin(x,y), acos(x), atan(x), atan(x,y) logarítmicas y exponenciales: log(x), log10(x) exp(x) constantes: pi, e 13 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 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 una expresión aritmética no contiene variables libres una expresión aritmética es un término no se evalúa por defecto 14
El predicado aritmético 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 15 Usos del predicado is/2?- 9 is 2*4+1. Yes?- X is 2*4+1. X = 9 ; No?- Y = 2*4, X is Y+1. X = 9 ; No?- Phi is (1+sqrt(5))/2. Phi = 1.61803 ; No?- X is 2/(1-1). ERROR: Arithmetic: evaluation error: `zero_divisor 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. No?- X = 0, X is X+1. No 17 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 {=:=, =\=, <, >, =<, >=} 18
Uso de la comparación aritmética Sólo se puede usar como test(+,+), pues no hay variables libres:?- 2.0 =:= 1.0 + 1.0. Yes?- 2 =:= 1.0 + 1.0. Yes?- 3 < 6 < 9. ERROR: Syntax error: Operator priority clash?- X is (3 < 9). ERROR: Arithmetic: `(<)/2' is not a function 19 Programando con predicados extra-lógicos 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 20
Predicados extra-lógicos y usos posibles % menor(+x,+y) menor(x,y) :- X < Y. % minimo(+x,+y,?z) minimo(x,y,x) :- X =< Y. minimo(x,y,y) :- Y < X. % suma(+x,+y,?z) suma(x,y,z) :- Z is X+Y. Ventajas: simplicidad, eficiencia Inconvenientes: menos usos posibles (no son relacionales) 21 Predicados extra-lógicos y recursión factorial(0,1). factorial(x,f) :- X > 0, X1 is X-1, factorial(x1,t), F is X*T. % guarda % reducción % composición La unificación pierde potencia: no basta para distinguir casos base y recursivo no puede reducir el problema ni componer la solución 22
Predicados extra-lógicos y recursión de cola factorial(x,f) :- fact_cola(x,1,f). fact_cola(0,f,f). fact_cola(x,ac,f) :- X > 0, % guarda X1 is X-1, % reducción 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 23 Predicados extra-lógicos y generadores entre(i,j,i) :- I =< J. entre(i,j,k) :- I < J, I1 is I+1, entre(i1,j,k). Uso Comportamiento Significado (+,+,+) test comprueba I K J (+,+,-) generador acotado genera K= I,,J Los casos base y recursivo no son excluyentes generación 24
Predicados extra-lógicos y generar/comprobar Problema: descomponer un natural N en suma de dos pares X e Y % es_par(+x) es_par(x) :- X mod 2 =:= 0. % 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) 25 Aplicación: puzzles cripto-aritméticos Problema: Dada la suma de letras C A M A + M E S A 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 26
Ejercicios Define los siguientes predicados: 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] 27 Ejercicios 9. Resuelve el puzzle cripto-aritmético: 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 28
Entrada/Salida de Términos Periféricos y flujos La entrada/salida de Prolog está basada en flujos: 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) Ejemplo: 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) 31 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) 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 33 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) Ejemplo:? read(x).?- read(fecha(d,m,a)). : f(a,2*pi). : fecha(2,febrero). X = f(_g275,2*pi) No Yes Prolog muestra el cursor : cuando espera datos por teclado 34
Ejemplo: una calculadora simple (I) 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. Ejemplo:?- calc. >> 2+3*5. 17 >> sin(pi) + cos(pi). -1 >> fin. Yes 35 Ejemplo: una calculadora simple (y II) 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. 36
Unificación y No Unificación Unificación y no 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 No son extra-lógicos 38
Comparación de Términos Orden estándar de los términos Prolog define una relación de orden total sobre los 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 41 Ejemplos de comparación de términos?- 1 + 2 == 1 + 2. Yes?- 1 + 2 == 2 + 1. % no evalúa No?- 1 + 2 =:= 2 + 1. Yes?- f(x) == f(y). % no instancia No?- f(x) = f(y). X = Y = _G251 42
Declaración de Operadores Operadores Prolog mejoran la legibilidad, permitiendo prescindir de los paréntesis son una mera facilidad sintáctica, no tienen asociada ninguna operación (semántica) Ejemplo: 2 + 3 * 5 = +(2,*(3,5)) la precedencia y asociatividad evitan ambigüedades que resultan al prescindir de los paréntesis Ejemplo: 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 Ejemplo: 2 + A * 3 % prec: + 500 * 400 + 500 mayor precedencia 2 * 400 A 3 menor precedencia 45 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 Ejemplo: A * B / 2 % *,/ 400, asoc. izq. 400 / 400 * 2 A B 46
La directiva op/3 El programador puede declarar sus propios operadores: :- op(+precedencia, +Tipo, +Nombre). 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 Nombre: átomo 47 El predicado current_op/3 Permite consultar qué operadores hay predefinidos y declarados: Ejemplo: current_op(?precedencia,?tipo,?nombre)?- current_op(p,t,-). P = 500 T = fx ; P = 500 T = yfx ; No 48
Ejemplo: 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. 49 Aritmética de Peano y operadores (I) Objetos: declaramos un operador para representar naturales :- op(100,fy,s). Ejemplo: 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. 50
Aritmética de Peano y operadores (II) Relaciones aritméticas: los operadores aritméticos están predefinidos (+,*,**, ) Ejemplo: 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? 51 Aritmética de Peano y operadores (y III) 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 Ejemplo: % = /2, operación + c + Y = Y :- es_natural Y. s X + Y = s Z :- X + Y = Z. 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. Yes?- 37.5 cm + 4 m := X. X = 4.375 m 53