-- I1M 2008-09: Relación 15 (15 de febrero de 2010)
-- Departamento de Ciencias de la Computación e I.A.
-- Universidad de Sevilla
-- =====================================================================

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

import Test.QuickCheck

-- ---------------------------------------------------------------------
-- Ejercicio 1a. Definir por recursión la función
--    sumaImpares :: Int -> Int
-- tal que (sumaImpares n) es la suma de los n primeros números
-- impares. Por ejemplo,
--    *Main> sumaImpares 5  =>  25
-- ---------------------------------------------------------------------

sumaImpares :: Int -> Int
sumaImpares = undefined

-- ---------------------------------------------------------------------
-- Ejercicio 1b. Definir, sin usar recursión, la función
--    sumaImpares' :: Int -> Int
-- tal que (sumaImpares' n) es la suma de los n primeros números
-- impares. Por ejemplo,
--    *Main> sumaImpares' 5  =>  25
-- ---------------------------------------------------------------------

sumaImpares' :: Int -> Int
sumaImpares' n = undefined

-- ---------------------------------------------------------------------
-- Ejercicio 1c. Definir la función
--    sumaImparesIguales :: Int -> Int -> Bool
-- tal que (sumaImparesIguales m n) se verifica si para todo x entre m y
-- n se tiene que (sumaImpares x) y (sumaImpares' x) son iguales.
-- 
-- Comprobar que (sumaImpares x) y (sumaImpares' x) son iguales para
-- todos los números x entre 1 y 100.
-- ---------------------------------------------------------------------

-- La definición es
sumaImparesIguales :: Int -> Int -> Bool
sumaImparesIguales m n = undefined

-- La comprobación es

-- ---------------------------------------------------------------------
-- Ejercicio 1d. Definir la función 
--    grafoSumaImpares :: Int -> Int -> [(Int,Int)]
-- tal que (grafoSumaImpares m n) es la lista formadas por los números x
-- entre m y n y los valores de (sumaImpares x).
--
-- Calcular (grafoSumaImpares 1 9).
-- ---------------------------------------------------------------------

-- La definición es
grafoSumaImpares :: Int -> Int -> [(Int,Int)]
grafoSumaImpares m n = undefined

-- El cálculo es

-- ---------------------------------------------------------------------
-- Ejercicio 1e. Demostrar por inducción que para todo n, 
-- (sumaImpares n) es igual a n^2.
-- ---------------------------------------------------------------------

{-
 Demostración:
-} 

-- ---------------------------------------------------------------------
-- Ejercicio 2a. Definir por recursión la función
--    sumaPotenciasDeDosMasUno :: Int -> Int
-- tal que 
--    (sumaPotenciasDeDosMasUno n) = 1 + 2^0 + 2^1 + 2^2 + ... + 2^n. 
-- Por ejemplo, 
--    sumaPotenciasDeDosMasUno 3  =>  16
-- ---------------------------------------------------------------------

sumaPotenciasDeDosMasUno :: Int -> Int
sumaPotenciasDeDosMasUno = undefined

-- ---------------------------------------------------------------------
-- Ejercicio 2b. Definir por comprensión la función
--    sumaPotenciasDeDosMasUno' :: Int -> Int
-- tal que 
--    (sumaPotenciasDeDosMasUno' n) = 1 + 2^0 + 2^1 + 2^2 + ... + 2^n. 
-- Por ejemplo, 
--    sumaPotenciasDeDosMasUno' 3  =>  16
-- ---------------------------------------------------------------------

sumaPotenciasDeDosMasUno' :: Int -> Int
sumaPotenciasDeDosMasUno' n = undefined

-- ---------------------------------------------------------------------
-- Ejercicio 2c. Demostrar por inducción que
--    sumaPotenciasDeDosMasUno n = 2^(n+1)
-- ---------------------------------------------------------------------

{-
  Demostración:
-}

-- ---------------------------------------------------------------------
-- Ejercicio 3a. Definir por recursión la función
--    copia :: Int -> a -> [a]
-- tal que (copia n x) es la lista formado por n copias del elemento
-- x. Por ejemplo, 
--    copia 3 2  =>  [2,2,2]
-- ---------------------------------------------------------------------
 
copia :: Int -> a -> [a]
copia = undefined

-- ---------------------------------------------------------------------
-- Ejercicio 3b. Definir por recursión la función 
--    todos :: (a -> Bool) -> [a] -> Bool
-- tal que (all p xs) se verifica si todos los elementos de xs cumplen
-- la propiedad p. Por ejemplo,
--    todos even [2,6,4]  ==>  True
--    todos even [2,5,4]  ==>  False
-- ---------------------------------------------------------------------

todos :: (a -> Bool) -> [a] -> Bool
todos = undefined

-- ---------------------------------------------------------------------
-- Ejercicio 3c. Comprobar con QuickCheck que todos los elementos de 
-- (copia n x) son iguales a x.
-- ---------------------------------------------------------------------

-- La propiedad es
prop_copia :: Eq a => Int -> a -> Bool
prop_copia n x = undefined

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

-- ---------------------------------------------------------------------
-- Ejercicio 3d. Demostrar, por inducción en n, que todos los elementos
-- de (copia n x) son iguales a x.
-- ---------------------------------------------------------------------

{-
  Demostración:
-}

-- ---------------------------------------------------------------------
-- Ejercicio 4. Definir la función
--    traspuesta :: [[a]] -> [[a]]
-- tal que (traspuesta m) es la traspuesta de la matriz m. Por ejemplo,
--    traspuesta [[1,2,3],[4,5,6]]    =>  [[1,4],[2,5],[3,6]]
--    traspuesta [[1,4],[2,5],[3,6]]  =>  [[1,2,3],[4,5,6]]
-- ---------------------------------------------------------------------

traspuesta :: [[a]] -> [[a]]
traspuesta = undefined

