240 likes | 445 Views
IV. Aritmética en Prolog. Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria. Índice. Operadores Aritmética Sumario. ?- display(2 + 2). +(2, 2) ?- display(3 * 4 + 6). +(*(3, 4), 6) ?- display(3 * (4 + 6)).
E N D
IV. Aritmética en Prolog Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria Prolog IV
Índice. • Operadores • Aritmética • Sumario Prolog IV
?- display(2 + 2). +(2, 2) ?- display(3 * 4 + 6). +(*(3, 4), 6) ?- display(3 * (4 + 6)). *(3, +(4, 6)) Operadores. La posibilidad de definir operadores en Prolog debe entenderse como un recurso que permite al programador habilitar una sintaxis más adecuada. P.e.: la operación 2 + 3 * 4 - 5 debería escribirse -(+(2, *(3, 4)), 5) donde -, +, * son functores y 2,3,4,5 sus argumentos Prolog IV
Operadores. :- op(500, yfx, +). Precedencia: 500 Tipo: yfx Nombre: + - Notación Prefija -(+(2, *(3, 4)), 5) Notación Infija 2 + 3 * 4 - 5 + 5 2 * :- op(500, yfx, +). :- op(500, yfx, -). :- op(400, yfx, *). 3 4 directivas Prolog IV
Tipos de Operadores Un operador se define por su precedencia, tipo y nombre infijo (3 tipos): xfx, xfy, yfx Ejemplo: 3 + 4 prefijo (2 tipos): fx, fy Ejemplo: -7 sufijo (2 tipos): xf, yf Ejemplo: 8 factorial Prolog IV
El Tipo de un Operador. y f x y f x y f x y f x :- op( 500, yfx, -). - - c y : Asociatividad a la izquierda x : No Asociatividad a la derecha a b a - b - c Prolog IV
yfx xfy - - - c a - a b b c Precedencia 500 Precedencia 500 a - b - c ¡ No ! (a - b) - c a - (b - c) Prolog IV
El Tipo de un Operador. Infijo: xfx no es asociativo xfy de derecha a izquierda yfx de izquierda a derecha Prefijo: fx no es asociativo fy de izquierda a derecha Sufijo: xf no es asociativo yf de derecha a izquierda Prolog IV
Operadores predefinidos en SWI-Prolog 1200 xfx -->, :- 1200 fx :-, ?- 1150 fx dynamic, multifile, module_transparent, discontiguous, volatile, initialization 1100 xfy ;, | 1050 xfy -> 1000 xfy , 954 xfy \ 900 fy \+ 900 fx ~ 700 xfx <, =, =.., =@=, =:=, =<, ==, =\=, >, >=, @<, @=<, @>, @>=, \=, \==, is 600 xfy : 500 yfx +, -, /\, \/, xor 500 fx +, -, ?, \ 400 yfx *, /, //, <<, >>, mod, rem 200 xfx ** 200 xfy ^ La precedencia puede estar entre 1200 y 1 Se evalúan antes los operadores de menor precedencia Prolog IV
?- X is 2^3. X = 8 Yes ?- X is 2^2^3, Y is (2^2)^3. X = 256 Y = 64 Yes 200 xfx ** 200 xfy ^ ?- X is 2**2**3. [WARNING: Syntax error: Operator `**' conflicts with `**' X is 2** ** here ** 2**3 . ] ?- X is 2**3. X = 8 Yes Prolog IV
¿Se puede saber si un operador está definido y cómo? current_op(?Precedencia, ?Tipo, ?Nombre) Es verdadero si el operador Nombre está definido como operador de tipo Tipo con precedencia Precedencia ?- current_op(Precedencia, Tipo, \+). Precedencia = 900 Tipo = fy Yes Prolog IV
900 fy \+ Como el operador \+ (not) está definido como: fy \+ \+ p es legal. Si se hubiese definido como: fx \+ \+ p sería ilegal porque el argumento del primer \+ es \+ p, que tiene la misma predecencia que \+ Prolog IV
is_in(apple, room(kitchen)). Definimos is_in/2 como operador infijo de precedencia arbitraria 35. ?- op(35, xfx, is_in). Ahora podemos preguntar: ?- apple is_in X. X = room(kitchen) o ?- X is_in room(kitchen). X = apple Podemos incluso añadir hechos al programa utilizando la sintaxis del operador. banana is_in room(kitchen). Para verificar que Prolog trata por igual ambas sintaxis intentamos su unificación. ?- is_in(banana, room(kitchen)) = banana is_in room(kitchen). yes Por medio de display/1 es posible ver en qué se traduce la nueva sintaxis. ?- display(banana is_in room(kitchen)). is_in(banana, room(kitchen)) Prolog IV (Tutorial de Amzi Prolog, Cap. 12)
Aritmética en Prolog Prolog provee ciertos predicados predefinidos para realizar operaciones aritméticas básicas. + Adición - Sustracción * Multiplicación / División mod Módulo div División entera . . . . . . Prolog IV
Aritmética en Prolog Conflicto: evaluación aritmética vs. unificación ?- X = 1+2. X = 1+2 Yes ?- X = 1 + 2, display(X). +(1, 2) X = 1+2 Yes ?- X = 1 + 2, display(X), Y is X. +(1, 2) X = 1+2 Y = 3 Yes Término: 1+2 functor: + argumentos: 1, 2 El predicado predefinido is fuerza la evaluación Prolog IV
Aritmética en Prolog Operadores relacionales predefinidos X > Y X es mayor que Y X < Y X es menor que Y X >= Y X es mayor o igual que Y X =< Y X es menor o igual que Y X =:= Y Los valores de X e Y son iguales X =\= Y Los valores de X e Y no son iguales Prolog IV
Aritmética en Prolog ?- 3 + 4 =:= 5 + 2. Yes ?- 1 + 2 = 1 + 2. Yes ?- 1 + 2 = 2 + 1. No ?- 1 + A = B + 2. A = 2 B = 1 Yes ?- 1+A =:= B+2. [WARNING: Arguments are not sufficiently instantiated] Exception: ( 8) 1+_G124=:=_G126+2 ? creep [WARNING: Unhandled exception] Prolog IV
Aritmética en SWI-Prolog - +Expr Resultado = -Expr +Expr1 + +Expr2 Resultado = Expr1 + Expr2 +Expr1 - +Expr2 Resultado = Expr1 - Expr2 +Expr1 * +Expr2 Resultado = Expr1 × Expr2 +Expr1 / +Expr2 Resultado = Expr1/Expr2 +IntExpr1 mod +IntExpr2 Resultado = Expr1 mod Expr2 +IntExpr1 rem +IntExpr2 Resultado = Expr1 rem Expr2 +IntExpr1 // +IntExpr2 Resultado = Expr1 divExpr2 (div. entera) +Expr1 ** +Expr2 Resultado = Expr1**Expr2 max(+Expr1, +Expr2) Devuelve el mayor de Expr1 y Expr2. min(+Expr1, +Expr2) Devuelve el menor de Expr1 y Expr2. Prolog IV
Aritmética en SWI-Prolog +IntExpr1 >> +IntExpr2 Desplazamiento binario a la dcha de IntExpr1 en IntExpr2 bits +IntExpr << +IntExpr Idem a la izda +IntExpr \/ +IntExpr Or binario entre IntExpr1 y IntExpr2 +IntExpr /\ +IntExpr And binario entre IntExpr1 y IntExpr2. +IntExpr xor +IntExpr Or exclusivo \ +IntExpr Inversión de bits Prolog IV
Aritmética en SWI-Prolog abs(+Expr) Evalúa Expr y devuelve su valor absoluto sign(+Expr) Devuelve -1 si Expr < 0, 1 si Expr > 0 y 0 si Expr=0. round(+Expr) Evalúa Expr y redondea al entero más próximo integer(+Expr) Lo mismo que round\1 float(+Expr) Se traduce el resultado de la evaluación a un formato de coma flotante. float_fractional_part(+Expr) Parte fraccionaria de un número en coma flotante. Negativo si Expr es negativo, 0 si Expr es entero. float_integer_part(+Expr) Parte entera de un número en coma flotante. truncate(+Expr) Trunca Expr a un entero. Equivalente a float_integer_part/1. Prolog IV
Ejemplo: factorial. factorial(N, F) :- N > 0, N1 is N - 1, factorial(N1, F1), F is N*F1. factorial(0,1). factorial(N, F) :- factorial(0, N, 1, F). factorial(I, N, T, F) :- I < N, I1 is I+1, T1 is T*I1, factorial(I1, N, T1, F). factorial(N, N, F, F). Prolog IV
Ejemplo: sumar una lista. sumar_lista( [I | Is], Sum) :- sumar_lista( Is, IsSum), Sum is I + IsSum. sumar_lista([ ],0). sumar_lista( Is, IsSum) :- sumar_lista(Is, 0, IsSum). sumar_lista( [I | Is], Temp, Sum) :- Temp1 is Temp + I, sumar_lista( Is, Temp1, Sum). sumar_lista([ ], Sum, Sum). Prolog IV
1 ?- [user]. :- arithmetic_function(mean/2). mean(A, B, C) :- C is (A+B)/2. user compiled, 0.07 sec, 440 bytes. Yes 2 ?- A is mean(4, 5). A = 4.500000 arithmetic_function(+Head) Registra un predicado Prolog como una función aritmética (ver is/2, >/2 , etc.). El predicado Prolog debería tener un argumento adicional que lo especificado por Head, el cuál puede indicarse como un término en forma de Nombre/Aridad, como átomo, o como término complejo. Este último argumento es una variable no instanciada en el momento de la llamada y deberá ser instanciada como un número entero o de coma flotante. Los otros argumentos son parámetros. Esta declaración sólo es válida para el contexto del módulo donde se realiza, a menos que se declare desde el módulo ‘user’. 1 ?- [user]. :- arithmetic_function(factorial/1). factorial(N, F) :- factorial(0, N, 1, F). factorial(I, N, T, F) :- I < N, I1 is I+1, T1 is T*I1, factorial(I1, N, T1, F). factorial(N, N, F, F). user compiled, 0.01 sec, 676 bytes. Yes 2 ?- A is factorial(4). A = 24 Prolog IV
Sumario. • El uso de operadores aumenta la legibilidad de los • programas. Pueden ser infijos, prefijos o sufijos. • El programador puede definir sus propios • operadores. • Un operador se define mediante una directiva que • especifica su precedencia, tipo y nombre. • El predicado is provoca la evaluación de operadores • aritméticos. • Para evaluar una operación aritmética todos los • argumentos deben estar instanciados a números. • Los operadores de relación (<, =<, =:=, ...) fuerzan la • evaluación de sus argumentos. Prolog IV