Acciones

Diferencia entre revisiones de «Relación 16»

De Informática de 1º de Matemáticas [Curso 2021-22, Grupo 3]

(Página creada con «<source lang='haskell'> -- I1M 2021-22: Relación 16 -- El TAD de las pilas. -- Departamento de Ciencias de la Computación e I.A. -- Universidad de Sevilla -- ============…»)
 
Línea 40: Línea 40:


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


filtraPila :: (a -> Bool) -> Pila a -> Pila a
filtraPila :: (a -> Bool) -> Pila a -> Pila a
filtraPila = undefined
filtraPila f p | esVacia p = vacia
              | f c = apila c (filtraPila f (desapila p))
              | otherwise = filtraPila f (desapila p)
                where c = cima p


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 52: Línea 57:
--    8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|-
--    8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|-
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


mapPila :: (a -> a) -> Pila a -> Pila a
mapPila :: (a -> a) -> Pila a -> Pila a
mapPila = undefined
mapPila f p | esVacia p = vacia
            | otherwise = apila (f (cima p)) (mapPila f (desapila p))


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 64: Línea 73:
--    pertenecePila 70 ejP1 == False
--    pertenecePila 70 ejP1 == False
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


pertenecePila :: (Eq a) => a -> Pila a -> Bool
pertenecePila :: (Eq a) => a -> Pila a -> Bool
pertenecePila = undefined
pertenecePila n p | esVacia p = False
                  | n == cima p = True
                  | otherwise = pertenecePila n (desapila p)
                    
                    
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 76: Línea 89:
--    contenidaPila ejP1 ejP2 == False
--    contenidaPila ejP1 ejP2 == False
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


contenidaPila :: (Eq a) => Pila a -> Pila a -> Bool
contenidaPila :: (Eq a) => Pila a -> Pila a -> Bool
contenidaPila = undefined
contenidaPila p1 p2 | esVacia p1 = True
                    | pertenecePila (cima p1) p2 = contenidaPila (desapila p1) p2
                    | otherwise = False


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 88: Línea 105:
--    prefijoPila ejP5 ejP1 == True
--    prefijoPila ejP5 ejP1 == True
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


prefijoPila :: (Eq a) => Pila a -> Pila a -> Bool
prefijoPila :: (Eq a) => Pila a -> Pila a -> Bool
prefijoPila = undefined
prefijoPila p1 p2 | esVacia p1 = True
                  | cima p1 == cima p2 = prefijoPila (desapila p1) (desapila p2)
                  | otherwise = False


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 100: Línea 121:
--    subPila ejP3 ejP1 == True
--    subPila ejP3 ejP1 == True
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


subPila :: (Eq a) => Pila a -> Pila a -> Bool
subPila :: (Eq a) => Pila a -> Pila a -> Bool
subPila = undefined
subPila p1 p2 | esVacia p2 = False
              | prefijoPila p1 p2 = True
              | otherwise = subPila p1 (desapila p2)


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 112: Línea 137:
--    ordenadaPila ejP4 == False
--    ordenadaPila ejP4 == False
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


ordenadaPila :: (Ord a) => Pila a -> Bool
ordenadaPila :: (Ord a) => Pila a -> Bool
ordenadaPila = undefined
ordenadaPila p | esVacia p = True
              | esVacia (desapila p) = True
              | cima p < cima (desapila p) = ordenadaPila (desapila p)
              | otherwise = False


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 123: Línea 153:
--    lista2Pila [1..6] == 1|2|3|4|5|6|-
--    lista2Pila [1..6] == 1|2|3|4|5|6|-
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


lista2Pila :: [a] -> Pila a
lista2Pila :: [a] -> Pila a
lista2Pila = undefined
lista2Pila xs | null xs = vacia
              | otherwise = apila (head xs) (lista2Pila (tail xs))


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 134: Línea 167:
--    pila2Lista ejP2 == [2,5,8,11,14,17]
--    pila2Lista ejP2 == [2,5,8,11,14,17]
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


pila2Lista :: Pila a -> [a]
pila2Lista :: Pila a -> [a]
pila2Lista = undefined
pila2Lista p | esVacia p = []
            | otherwise = (cima p):(pila2Lista (desapila p))


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 142: Línea 178:
-- la inversa de lista2Pila, y recíprocamente.
-- la inversa de lista2Pila, y recíprocamente.
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


prop_pila2Lista :: Pila Int -> Bool
prop_pila2Lista :: Pila Int -> Bool
prop_pila2Lista p = undefined
prop_pila2Lista p = lista2Pila (pila2Lista p) == p


-- ghci> quickCheck prop_pila2Lista
-- ghci> quickCheck prop_pila2Lista
-- +++ OK, passed 100 tests.
-- +++ OK, passed 100 tests.
-- Álvaro Galisteo:


prop_lista2Pila :: [Int] -> Bool
prop_lista2Pila :: [Int] -> Bool
prop_lista2Pila xs = undefined
prop_lista2Pila xs = pila2Lista (lista2Pila xs) == xs


-- ghci> quickCheck prop_lista2Pila
-- ghci> quickCheck prop_lista2Pila
Línea 163: Línea 203:
--    -1|0|3|3|3|4|4|7|8|10|-
--    -1|0|3|3|3|4|4|7|8|10|-
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


ordenaInserPila :: (Ord a) => Pila a -> Pila a
ordenaInserPila :: (Ord a) => Pila a -> Pila a
ordenaInserPila = undefined
ordenaInserPila p | esVacia p = vacia
                  | esVacia (desapila p) = p
                  | otherwise = ordenaInserPila' (apila (cima p) vacia) (desapila p)
 
ordenaInserPila' :: (Ord a) => Pila a -> Pila a -> Pila a
ordenaInserPila' p1 p2 | esVacia p2 = apila (cima p1) (ordenaInserPila (desapila p1))
                      | (cima p2) <= (cima p1) = ordenaInserPila' (apila (cima p2) p1) (desapila p2)
                      | otherwise = ordenaInserPila' (apila (cima p1) (apila (cima p2) (desapila p1))) (desapila p2)


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 171: Línea 220:
---    (ordenaInserPila p)  
---    (ordenaInserPila p)  
-- está ordenada correctamente.
-- está ordenada correctamente.
-- Álvaro Galisteo:


prop_ordenaInserPila :: Pila Int -> Bool
prop_ordenaInserPila :: Pila Int -> Bool
prop_ordenaInserPila p = undefined
prop_ordenaInserPila p = pila2Lista (ordenaInserPila p) == sort (pila2Lista p)


-- ghci> quickCheck prop_ordenaInserPila
-- ghci> quickCheck prop_ordenaInserPila
Línea 188: Línea 239:
--    -1|7|8|10|0|3|4|-
--    -1|7|8|10|0|3|4|-
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


nubPila :: (Eq a) => Pila a -> Pila a
nubPila :: (Eq a) => Pila a -> Pila a
nubPila = undefined
nubPila p | esVacia p = vacia
          | pertenecePila (cima p) (desapila p) = nubPila (desapila p)
          | otherwise = apila (cima p) (nubPila (desapila p))


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 199: Línea 254:
-- verifique la propiedad.
-- verifique la propiedad.
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


-- La propiedad es
-- La propiedad es
prop_nubPila :: Pila Int -> Bool
prop_nubPila :: Pila Int -> Bool
prop_nubPila p = undefined
prop_nubPila p = pila2Lista (nubPila' p) == nub (pila2Lista p)
 
nubPila' :: (Eq a) => Pila a -> Pila a
nubPila' p | esVacia p = p
          | esVacia (desapila p) = p
          | otherwise = apila (cima p) (nubPila'' (apila (cima p) vacia) (desapila p))
 
nubPila'' :: (Eq a) => Pila a -> Pila a -> Pila a
nubPila'' p1 p2 | esVacia p2 = vacia
                | pertenecePila (cima p2) p1 = nubPila'' p1 (desapila p2)
                | otherwise = apila (cima p2) (nubPila'' (apila (cima p2) p1) (desapila p2))


-- La comprobación es
-- La comprobación es
-- *Main> quickCheck prop_nubPila
-- +++ OK, passed 100 tests.


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 216: Línea 286:
--    10
--    10
-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
-- Álvaro Galisteo:


maxPila :: (Ord a) => Pila a -> a
maxPila :: (Ord a) => Pila a -> a
maxPila = undefined
maxPila p | esVacia (desapila p) = cima p
          | cima p <= cima (desapila p) = maxPila (desapila p)
          | otherwise = maxPila (apila (cima p) (desapila (desapila p)))


-- ---------------------------------------------------------------------
-- ---------------------------------------------------------------------
Línea 244: Línea 318:
instance (Arbitrary a, Num a) => Arbitrary (Pila a) where
instance (Arbitrary a, Num a) => Arbitrary (Pila a) where
     arbitrary = genPila
     arbitrary = genPila
</source>
</source>

Revisión del 00:15 8 feb 2022

-- I1M 2021-22: Relación 16
-- El TAD de las pilas.
-- Departamento de Ciencias de la Computación e I.A.
-- Universidad de Sevilla
-- =====================================================================

-- ---------------------------------------------------------------------
-- Importación de librerías                                           --
-- ---------------------------------------------------------------------

import Data.List
import Test.QuickCheck

-- Hay que elegir una implementación del TAD pilas.
import PilaConTipoDeDatoAlgebraico
--import PilaConListas

-- ---------------------------------------------------------------------
-- A lo largo de la relación de ejercicios usaremos los siguientes
-- ejemplos de pilas:
-- ---------------------------------------------------------------------

ejP1, ejP2, ejP3, ejP4, ejP5 :: Pila Int
ejP1 = foldr apila vacia [1..20]
ejP2 = foldr apila vacia [2,5..18]
ejP3 = foldr apila vacia [3..10]
ejP4 = foldr apila vacia [4,-1,7,3,8,10,0,3,3,4]
ejP5 = foldr apila vacia [1..5]

-- ---------------------------------------------------------------------
-- Ejercicio 1: Definir la función
--    filtraPila :: (a -> Bool) -> Pila a -> Pila a
-- tal que (filtraPila p pila) es la pila con los elementos de pila
-- que verifican el predicado p, en el mismo orden. Por ejemplo,
--    ghci> ejP1
--    1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|-
--    ghci> filtraPila even ejP1
--    2|4|6|8|10|12|14|16|18|20|-

-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

filtraPila :: (a -> Bool) -> Pila a -> Pila a
filtraPila f p | esVacia p = vacia
               | f c = apila c (filtraPila f (desapila p))
               | otherwise = filtraPila f (desapila p)
                 where c = cima p

-- ---------------------------------------------------------------------
-- Ejercicio 2: Definir la función
--    mapPila :: (a -> a) -> Pila a -> Pila a
-- tal que (mapPila f pila) es la pila formada con las imágenes por f de
-- los elementos de pila, en el mismo orden. Por ejemplo,
--    ghci> mapPila (+7) ejP1
--    8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|-
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

mapPila :: (a -> a) -> Pila a -> Pila a
mapPila f p | esVacia p = vacia
            | otherwise = apila (f (cima p)) (mapPila f (desapila p))
 

-- ---------------------------------------------------------------------
-- Ejercicio 3: Definir la función
--    pertenecePila :: (Eq a) => a -> Pila a -> Bool
-- tal que (pertenecePila y p) se verifica si y sólo si y es un elemento
-- de la pila p. Por ejemplo,
--    pertenecePila 7 ejP1  == True
--    pertenecePila 70 ejP1 == False
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

pertenecePila :: (Eq a) => a -> Pila a -> Bool
pertenecePila n p | esVacia p = False
                  | n == cima p = True
                  | otherwise = pertenecePila n (desapila p)
                   
-- ---------------------------------------------------------------------
-- Ejercicio 4: definir la función
--    contenidaPila :: (Eq a) => Pila a -> Pila a -> Bool
-- tal que (contenidaPila p1 p2) se verifica si y sólo si todos los
-- elementos de p1 son elementos de p2. Por ejemplo,
--    contenidaPila ejP2 ejP1 == True
--    contenidaPila ejP1 ejP2 == False
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

contenidaPila :: (Eq a) => Pila a -> Pila a -> Bool
contenidaPila p1 p2 | esVacia p1 = True
                    | pertenecePila (cima p1) p2 = contenidaPila (desapila p1) p2
                    | otherwise = False

-- ---------------------------------------------------------------------
-- Ejercicio 4: Defiir la función
--    prefijoPila :: (Eq a) => Pila a -> Pila a -> Bool
-- tal que (prefijoPila p1 p2) se verifica si la pila p1 es justamente
-- un prefijo de la pila p2. Por ejemplo,
--    prefijoPila ejP3 ejP2 == False
--    prefijoPila ejP5 ejP1 == True
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

prefijoPila :: (Eq a) => Pila a -> Pila a -> Bool
prefijoPila p1 p2 | esVacia p1 = True
                  | cima p1 == cima p2 = prefijoPila (desapila p1) (desapila p2)
                  | otherwise = False

-- ---------------------------------------------------------------------
-- Ejercicio 5: Definir la función
--    subPila :: (Eq a) => Pila a -> Pila a -> Bool
-- tal que (subPila p1 p2) se verifica si p1 es una subpila de p2.
-- Por ejemplo, 
--    subPila ejP2 ejP1 == False
--    subPila ejP3 ejP1 == True
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

subPila :: (Eq a) => Pila a -> Pila a -> Bool
subPila p1 p2 | esVacia p2 = False
              | prefijoPila p1 p2 = True
              | otherwise = subPila p1 (desapila p2) 

-- ---------------------------------------------------------------------
-- Ejercicio 6: Definir la función
--    ordenadaPila :: (Ord a) => Pila a -> Bool
-- tal que (ordenadaPila p) se verifica si los elementos de la pila p
-- están ordenados en orden creciente. Por ejemplo,
--    ordenadaPila ejP1 == True
--    ordenadaPila ejP4 == False
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

ordenadaPila :: (Ord a) => Pila a -> Bool
ordenadaPila p | esVacia p = True
               | esVacia (desapila p) = True
               | cima p < cima (desapila p) = ordenadaPila (desapila p)
               | otherwise = False

-- ---------------------------------------------------------------------
-- Ejercicio 7.1: Definir una función
--    lista2Pila :: [a] -> Pila a
-- tal que (lista2Pila xs) es una pila formada por los elementos de xs.
-- Por ejemplo,
--    lista2Pila [1..6] == 1|2|3|4|5|6|-
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

lista2Pila :: [a] -> Pila a
lista2Pila xs | null xs = vacia
              | otherwise = apila (head xs) (lista2Pila (tail xs))

-- ---------------------------------------------------------------------
-- Ejercicio 7.2: Definir una función
--  pila2Lista :: Pila a -> [a]
-- tal que (pila2Lista p) es la lista formada por los elementos de p.
-- Por ejemplo,
--    pila2Lista ejP2 == [2,5,8,11,14,17]
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

pila2Lista :: Pila a -> [a]
pila2Lista p | esVacia p = []
             | otherwise = (cima p):(pila2Lista (desapila p))

-- ---------------------------------------------------------------------
-- Ejercicio 7.3: Comprobar con QuickCheck que la función pila2Lista es
-- la inversa de lista2Pila, y recíprocamente.
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

prop_pila2Lista :: Pila Int -> Bool
prop_pila2Lista p = lista2Pila (pila2Lista p) == p

-- ghci> quickCheck prop_pila2Lista
-- +++ OK, passed 100 tests.

-- Álvaro Galisteo: 

prop_lista2Pila :: [Int] -> Bool
prop_lista2Pila xs = pila2Lista (lista2Pila xs) == xs

-- ghci> quickCheck prop_lista2Pila
-- +++ OK, passed 100 tests.

-- ---------------------------------------------------------------------
-- Ejercicio 8.1: Definir la función 
--    ordenaInserPila :: (Ord a) => Pila a -> Pila a
-- tal que (ordenaInserPila p) es una pila con los elementos de la pila
-- p, ordenados por inserción. Por ejemplo,
--    ghci> ordenaInserPila ejP4
--    -1|0|3|3|3|4|4|7|8|10|-
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

ordenaInserPila :: (Ord a) => Pila a -> Pila a
ordenaInserPila p | esVacia p = vacia
                  | esVacia (desapila p) = p
                  | otherwise = ordenaInserPila' (apila (cima p) vacia) (desapila p)

ordenaInserPila' :: (Ord a) => Pila a -> Pila a -> Pila a
ordenaInserPila' p1 p2 | esVacia p2 = apila (cima p1) (ordenaInserPila (desapila p1))
                       | (cima p2) <= (cima p1) = ordenaInserPila' (apila (cima p2) p1) (desapila p2)
                       | otherwise = ordenaInserPila' (apila (cima p1) (apila (cima p2) (desapila p1))) (desapila p2)

-- ---------------------------------------------------------------------
-- Ejercicio 8.2: Comprobar con QuickCheck que la pila 
---    (ordenaInserPila p) 
-- está ordenada correctamente.

-- Álvaro Galisteo: 

prop_ordenaInserPila :: Pila Int -> Bool
prop_ordenaInserPila p = pila2Lista (ordenaInserPila p) == sort (pila2Lista p)

-- ghci> quickCheck prop_ordenaInserPila
-- +++ OK, passed 100 tests.

-- ---------------------------------------------------------------------
-- Ejercicio 9.1: Definir la función
--    nubPila :: (Eq a) => Pila a -> Pila a
-- tal que (nubPila p) es una pila con los elementos de p sin
-- repeticiones. Por ejemplo,
--    ghci> ejP4
--    4|-1|7|3|8|10|0|3|3|4|-
--    ghci> nubPila ejP4
--    -1|7|8|10|0|3|4|-
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

nubPila :: (Eq a) => Pila a -> Pila a
nubPila p | esVacia p = vacia
          | pertenecePila (cima p) (desapila p) = nubPila (desapila p)
          | otherwise = apila (cima p) (nubPila (desapila p))

-- ---------------------------------------------------------------------
-- Ejercicio 9.2: Definir la propiedad siguiente: "las composición de
-- las funciones nub y pila2Lista coincide con la composición de las
-- funciones pila2Lista y nubPila", y comprobarla con quickCheck.
-- En caso de ser falsa, redefinir la función nubPila para que se
-- verifique la propiedad.
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

-- La propiedad es
prop_nubPila :: Pila Int -> Bool
prop_nubPila p = pila2Lista (nubPila' p) == nub (pila2Lista p) 

nubPila' :: (Eq a) => Pila a -> Pila a
nubPila' p | esVacia p = p
           | esVacia (desapila p) = p
           | otherwise = apila (cima p) (nubPila'' (apila (cima p) vacia) (desapila p))

nubPila'' :: (Eq a) => Pila a -> Pila a -> Pila a
nubPila'' p1 p2 | esVacia p2 = vacia
                | pertenecePila (cima p2) p1 = nubPila'' p1 (desapila p2)
                | otherwise = apila (cima p2) (nubPila'' (apila (cima p2) p1) (desapila p2))

-- La comprobación es

-- *Main> quickCheck prop_nubPila
-- +++ OK, passed 100 tests.

-- ---------------------------------------------------------------------
-- Ejercicio 10: Definir la función 
--    maxPila :: (Ord a) => Pila a -> a
-- tal que (maxPila p) sea el mayor de los elementos de la pila p. Por
-- ejemplo, 
--    ghci> ejP4
--    4|-1|7|3|8|10|0|3|3|4|-
--    ghci> maxPila ejP4
--    10
-- ---------------------------------------------------------------------

-- Álvaro Galisteo: 

maxPila :: (Ord a) => Pila a -> a
maxPila p | esVacia (desapila p) = cima p
          | cima p <= cima (desapila p) = maxPila (desapila p)
          | otherwise = maxPila (apila (cima p) (desapila (desapila p)))

-- ---------------------------------------------------------------------
-- Generador de pilas                                                 --
-- ---------------------------------------------------------------------

-- genPila es un generador de pilas. Por ejemplo,
--    ghci> sample genPila
--    -
--    0|0|-
--    -
--    -6|4|-3|3|0|-
--    -
--    9|5|-1|-3|0|-8|-5|-7|2|-
--    -3|-10|-3|-12|11|6|1|-2|0|-12|-6|-
--    2|-14|-5|2|-
--    5|9|-
--    -1|-14|5|-
--    6|13|0|17|-12|-7|-8|-19|-14|-5|10|14|3|-18|2|-14|-11|-6|-
genPila :: (Arbitrary a, Num a) => Gen (Pila a)
genPila = do xs <- listOf arbitrary
             return (foldr apila vacia xs)
  
-- El tipo pila es una instancia del arbitrario. 
instance (Arbitrary a, Num a) => Arbitrary (Pila a) where
    arbitrary = genPila