¡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 enterony 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,filteryfoldr, definir la funciónporCientoMayorQue :: Int → Int → [Int] → Int, que dado un númeron, otro númeromy una lista de enteros, devuelve la suma de todos los porcentajes mayores quen. Ayuda: definir una función auxiliarPorCiento :: Int → Int → Intque use la funcióndivque 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,Reservados),
libro(Libro,nopres,nores),
Prestados < 6.
puedeReservar(Usuario) :-
usuario(Usuario,Prestados,Reservados),
Reservados < 3.
Una posible solución en haskell:
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)
