¡Esta es una revisión vieja del documento!
Parcial 1 (recuperatorio)
ejercicio 1 (prolog, no recursivo)
- Dada la siguiente base de conocimiento en prolog, que especifica tres ingredientes necesarios para cocinar un platillo y los que tengo en la casa, crear las reglas necesarias para saber si podremos cocinar un platillo.
ingredientes(tortilla,huevos,aceite,papa). ingredientes(pizza,prepizza,salsa,queso). ingredientes(ensalada,lechuga,tomate,aceitunas). tengo(huevos). tengo(aceite). tengo(papa).
Ejemplo: ''puedoCocinar(tortilla). true. puedoCocinar(pizza). false.''
solución
puedoCocinar(X) :- ingredientes(X,A,B,C) , tengo(A) , tengo(B) , tengo(C).
ejercicio 2 (haskell, no recursivo)
- Definir la función
sumaPar :: (Int,Int) → Bool
, que, dado un par de enteros, devuelve true si la suma de ambos es par.
Ejemplo: ''sumaPar (2,5) = false.''
solución
sumaPar :: (Int,Int) -> Bool sumaPar (x,y) = mod (x+y) 2 == 0
ejercicio 3 (recursivo)
- Definir la función
sumaMayoresQueN :: Int → [Int] → Int
, que, dado un enteron
y una lista de enteros, devuelve la suma de todos los elementos de la lista mayores quen
.
Ejemplo: ''sumaMayoresQueN 3 [3,5,2,4] = 9''.
solución
sumaMayoresQueN :: Int -> [Int] -> Int sumaMayoresQueN n [] = 0 sumaMayoresQueN n (x:xs) | x > n = x + sumaMayoresQueN n xs | otherwise = sumaMayoresQueN n xs
Parcial 2
ejercicio 1 (usando generalizaciones)
- Usando
map
,filter
yfoldr
, definir la funciónporCientoMayorQue :: Int → Int → [Int] → Int
, que dado un númeron
, otro númerom
y una lista de enteros, devuelve la suma de todos los porcentajes mayores quen
. Ayuda: definir una función auxiliarPorCiento :: Int → Int → Int
que use la funcióndiv
que devuelve la división entera de dos enteros.
Ejemplo: ''porCientoMayorQue 10 50 [22,4,30,10] = 26.''
solución
porCientoMayorQue :: Int -> Int -> [Int] -> Int porCientoMayorQue n m xs = foldr (+) 0 ( filter (>n) ( map (porCiento m) xs ) )
resolviendo problemas "de la vida real"
- Definir la parte del sistema de préstamos de una biblioteca que determina si un usuario puede tomar prestado un libro o, si ya está prestado, reservarlo, cumpliendo las siguientes condiciones:
- un usuario puede tener en préstamo un máximo de seis libros simultáneamente
- un usuario puede tener un máximo de tres reservas
- un libro se puede prestar si no está en préstamo ni está reservado por otro usuario
Para plantear el problema, deben definir dos funciones (o predicados) con la siguiente semántica:
''puedeTomarPrestado -> usuario -> libro -> Bool'' ''puedeReservar -> usuario -> libro -> Bool''
Para plantear el problema en haskell, deben definir las dos funciones principales y la estructura de funciones auxiliares, incluyendo sus signaturas de tipos. Fíjense que eso incluye también definir las estructuras de datos que representarán los libros, los usuarios y cómo se registran los préstamos.
Para plantear el problema en prolog, deben definir los hechos y las reglas. Fíjense que eso incluye definir los predicados para libros, usuarios y préstamos.
Deben plantear el problema en los dos lenguajes, y resolverlo completamente en uno de los dos.
solución
En este problema se pueden plantear muy distintas soluciones, ya que el problema es bien complejo y se puede ver de muchas formas.
Una posible solución en prolog:
%% definimos los usuarios como un predicado con tres argumentos: %% el nombre del usuario (o su identificador si el nombre no alcanza para hacerlos únicos) %% el número de libros que tiene en préstamo %% el número de libros que tiene reservado %% dejamos para otra regla la actualización de esos números % cuando alguien toma prestado o reserva un libro usuario(pepe,6,3). usuario(maría,5,2). usuario(carla,6,1). usuario(esteban,0,0). usuario(marisol,3,3). %% definimos los libros como un predicado con tres argumentos: %% el título del libro (o su identificador si el nombre no alcanza para hacerlos únicos) %% si está prestado o no %% si está reservado o no libro("la isla del tesoro",pres,nores). libro("el lazarillo de tormes",nopres,nores). libro("los hombres que no amaban a las mujeres",pres,res). libro("la chica que soñaba con una cerilla y un bidón de gasolina",nopres,res). %% después de los hechos, definimos las reglas puedeTomarPrestado(Usuario,Libro) :- usuario(Usuario,Prestados,_), libro(Libro,nopres,nores), Prestados < 6. puedeReservar(Usuario,_) :- usuario(Usuario,_,Reservados), Reservados < 3.
Una posible solución en haskell:
puedeTomarPrestado :: (String,Int,Int) -> (String,Bool,Bool) -> Bool puedeTomarPrestado (_,lp,_) (_,p,r) = lp < 6 && not(p) && not(r) puedeReservar :: (String,Int,Int) -> (String,Bool,Bool) -> Bool puedeReservar (_,_,lr) _ = lr < 3
ejercicio extra (para ayudar a aprobar)
Bonus Track: Definir la función tieneSegmentoOrdenado :: Int → [Int] → Bool
, que dado un entero n
y una lista de enteros, determina si la lista tiene un segmento de longitud mayor o igual a n
cuyos elementos están ordenados de menor a mayor.
Ejemplo: ''tieneSegmentoOrdenado 3 [5,1,4,11,3,2] = true'' ''tieneSegmentoOrdenado 4 [5,1,4,11,3,2] = false.''
solución
tieneSegmentoOrdenado :: Int -> [Int] -> Bool tieneSegmentoOrdenado n xs = cuantosOrdenados 1 n xs cuantosOrdenados :: Int -> Int -> [Int] -> Bool cuantosOrdenados c n xs | c == n = True | otherwise = cuentaOrdenado c n xs cuentaOrdenado :: Int -> Int -> [Int] -> Bool cuentaOrdenado c n [] = False cuentaOrdenado c n [x] = False cuentaOrdenado c n (x:y:xs) | x <= y = cuantosOrdenados (c+1) n (y:xs) | otherwise = cuentaOrdenado 1 n (y:xs)