{"id":5413,"date":"2016-04-20T17:12:48","date_gmt":"2016-04-20T15:12:48","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=5413"},"modified":"2016-04-30T07:13:59","modified_gmt":"2016-04-30T05:13:59","slug":"i1m2015-el-tad-de-los-polinomios-en-haskell","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2015-el-tad-de-los-polinomios-en-haskell\/","title":{"rendered":"I1M2015: El TAD de los polinomios en Haskell"},"content":{"rendered":"<p>En la clase de hoy de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-15\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> hemos estudiado el tipo abstracto de los polinomios y su implementaci\u00f3n en Haskell.<\/p>\n<p>Comenzamos la clase analizando las posibles representaciones de los polinomios y, como consecuencia, establecer la signatura y las propiedades del TAD de los polinomios.<\/p>\n<p>A continuaci\u00f3n, estudiamos tres prosibles representaciones del TAD de los polinomios mediante tipos algebraicos, mediantes listas dispersas y mediante listas densas y sus implementaciones en Haskell<\/p>\n<p>Finalmente, hemos estudiado las operaciones con los polinomios usando el TAD de los polinomios.<\/p>\n<p>Las transparencias usadas en la clase son las del <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-15\/temas\/tema-21.html\">tema 21<\/a><\/p>\n<p>El c\u00f3digo del TAD de polinomios mediante tipo algebraico es<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\nmodule PolRepTDA\n  ( Polinomio,\n    polCero,   -- Polinomio a                                         \n    esPolCero, -- Num a =>  Polinomio a -> Bool                       \n    consPol,   -- (Num a) => Int -> a -> Polinomio a -> Polinomio a   \n    grado,     -- Polinomio a -> Int                                  \n    coefLider, -- Num t => Polinomio t -> t                           \n    restoPol   -- Polinomio t -> Polinomio t                          \n  ) where\n\n-- ---------------------------------------------------------------------\n-- TAD de los polinomios mediante un tipo de dato algebraico.         --\n-- ---------------------------------------------------------------------\n\n-- Representamos un polinomio mediante los constructores ConsPol y\n-- PolCero. Por ejemplo, el polinomio \n--    6x^4 -5x^2 + 4x -7 \n-- se representa por \n--    ConsPol 4 6 (ConsPol 2 (-5) (ConsPol 1 4 (ConsPol 0 (-7) PolCero)))\n\ndata Polinomio a = PolCero \n                 | ConsPol Int a (Polinomio a)\n                 deriving Eq\n             \n-- ---------------------------------------------------------------------\n-- Escritura de los polinomios                                        --\n-- ---------------------------------------------------------------------\n\ninstance Num a => Show (Polinomio a) where\n    show PolCero               = \"0\"\n    show (ConsPol 0 b PolCero) = show b\n    show (ConsPol 0 b p)       = concat [show b, \" + \", show p] \n    show (ConsPol 1 b PolCero) = concat [show b, \"*x\"]\n    show (ConsPol 1 b p)       = concat [show b, \"*x + \", show p] \n    show (ConsPol n 1 PolCero) = concat [\"x^\", show n] \n    show (ConsPol n b PolCero) = concat [show b, \"*x^\", show n] \n    show (ConsPol n 1 p)       = concat [\"x^\", show n, \" + \", show p] \n    show (ConsPol n b p)       = concat [show b, \"*x^\", show n, \" + \", show p] \n\n-- ---------------------------------------------------------------------\n-- Ejemplos de polinomios                                             --\n-- ---------------------------------------------------------------------\n\n-- Ejemplos de polinomios con coeficientes enteros:\nejPol1, ejPol2, ejPol3:: Polinomio Int\nejPol1 = consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero))\nejPol2 = consPol 5 1 (consPol 2 5 (consPol 1 4 polCero))\nejPol3 = consPol 4 6 (consPol 1 2 polCero)\n\n-- Comprobaci\u00f3n de escritura:\n--    > ejPol1\n--    3*x^4 + -5*x^2 + 3\n--    > ejPol2\n--    x^5 + 5*x^2 + 4*x\n--    > ejPol3\n--    6*x^4 + 2*x\n\n-- Ejemplos de polinomios con coeficientes reales:\nejPol5, ejPol6, ejPol7:: Polinomio Float\nejPol5 = consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero))\nejPol6 = consPol 5 1 (consPol 2 5 (consPol 1 4 polCero))\nejPol7 = consPol 1 2 (consPol 4 6 polCero)\n\n-- Comprobaci\u00f3n de escritura:\n--    > ejPol5\n--    3.0*x^4 + -5.0*x^2 + 3.0\n--    > ejPol6\n--    x^5 + 5.0*x^2 + 4.0*x\n--    > ejPol7\n--    6.0*x^4 + 2.0*x\n\n-- ---------------------------------------------------------------------\n-- Implementaci\u00f3n de la especificaci\u00f3n                                --\n-- ---------------------------------------------------------------------\n\n-- polCero es el polinomio cero. Por ejemplo,\n--    > polCero\n--    0\npolCero :: Polinomio a\npolCero = PolCero\n\n-- (esPolCero p) se verifica si p es el polinomio cero. Por ejemplo,\n--    esPolCero polCero  ==  True\n--    esPolCero ejPol1   ==  False\nesPolCero :: Polinomio a -> Bool\nesPolCero PolCero = True\nesPolCero _       = False\n\n-- (consPol n b p) es el polinomio bx^n+p. Por ejemplo,\n--    ejPol2               ==  x^5 + 5*x^2 + 4*x\n--    consPol 3 0 ejPol2   ==  x^5 + 5*x^2 + 4*x\n--    consPol 3 2 polCero  ==  2*x^3\n--    consPol 6 7 ejPol2   ==  7*x^6 + x^5 + 5*x^2 + 4*x\n--    consPol 4 7 ejPol2   ==  x^5 + 7*x^4 + 5*x^2 + 4*x\n--    consPol 5 7 ejPol2   ==  8*x^5 + 5*x^2 + 4*x\nconsPol :: Num a => Int -> a -> Polinomio a -> Polinomio a  \nconsPol _ 0 p = p\nconsPol n b PolCero = ConsPol n b PolCero\nconsPol n b (ConsPol m c p) \n    | n > m      = ConsPol n b (ConsPol m c p)\n    | n < m      = ConsPol m c (consPol n b p)\n    | b+c == 0   = p\n    | otherwise  = ConsPol n (b+c) p\n\n-- (grado p) es el grado del polinomio p. Por ejemplo,\n--    ejPol3        ==  6*x^4 + 2*x\n--    grado ejPol3  ==  4\ngrado:: Polinomio a -> Int\ngrado PolCero         = 0\ngrado (ConsPol n _ _) = n\n\n-- (coefLider p) es el coeficiente l\u00edder del polinomio p. Por ejemplo,\n--    ejPol3            ==  6*x^4 + 2*x\n--    coefLider ejPol3  ==  6\ncoefLider:: Num t => Polinomio t -> t\ncoefLider PolCero         = 0\ncoefLider (ConsPol _ b _) = b\n\n-- (restoPol p) es el resto del polinomio p. Por ejemplo,\n--    ejPol3           ==  6*x^4 + 2*x\n--    restoPol ejPol3  ==  2*x\n--    ejPol2           ==  x^5 + 5*x^2 + 4*x\n--    restoPol ejPol2  ==  5*x^2 + 4*x\nrestoPol :: Polinomio t -> Polinomio t\nrestoPol PolCero         = PolCero\nrestoPol (ConsPol _ _ p) = p\n<\/pre>\n<p>El c\u00f3digo del TAD de polinomios mediante listas dispersas es<\/p>\n<pre lang=\"haskell\">\nmodule PolRepDispersa\n  ( Polinomio,\n    polCero,   -- Polinomio a                                         \n    esPolCero, -- Num a =>  Polinomio a -> Bool                       \n    consPol,   -- (Num a) => Int -> a -> Polinomio a -> Polinomio a   \n    grado,     -- Polinomio a -> Int                                  \n    coefLider, -- Num a => Polinomio a -> a                           \n    restoPol   -- Polinomio a -> Polinomio a                          \n  ) where\n\n-- ---------------------------------------------------------------------\n-- TAD de los polinomios mediante listas dispersas                    --\n-- ---------------------------------------------------------------------\n\n-- Representaremos un polinomio por la lista de sus coeficientes ordenados\n-- en orden decreciente seg\u00fan el grado. Por ejemplo, el polinomio \n-- 6x^4 -5x^2 + 4x -7 se representa por [6,0,-2,4,-7]. \n\ndata Polinomio a = Pol [a] \n                   deriving Eq\n\n-- ---------------------------------------------------------------------\n-- Escritura de los polinomios                                        --\n-- ---------------------------------------------------------------------\n\ninstance Num a => Show (Polinomio a) where\n  show pol \n      | esPolCero pol         = \"0\"\n      | n == 0 && esPolCero p = show a \n      | n == 0                = concat [show a, \" + \", show p] \n      | n == 1 && esPolCero p = concat [show a, \"*x\"]\n      | n == 1                = concat [show a, \"*x + \", show p] \n      | a == 1 && esPolCero p = concat [\"x^\", show n] \n      | esPolCero p           = concat [show a, \"*x^\", show n] \n      | a == 1                = concat [\"x^\", show n, \" + \", show p] \n      | otherwise             = concat [show a, \"*x^\", show n, \" + \", show p] \n     where n = grado pol\n           a = coefLider pol\n           p = restoPol pol\n\n-- ---------------------------------------------------------------------\n-- Ejemplos de polinomios                                             --\n-- ---------------------------------------------------------------------\n\n-- Ejemplos de polinomios con coeficientes enteros:\nejPol1, ejPol2, ejPol3:: Polinomio Int\nejPol1 = consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero))\nejPol2 = consPol 5 1 (consPol 2 5 (consPol 1 4 polCero))\nejPol3 = consPol 4 6 (consPol 1 2 polCero)\n\n-- Comprobaci\u00f3n de escritura:\n--    > ejPol1\n--    3*x^4 + -5*x^2 + 3\n--    > ejPol2\n--    x^5 + 5*x^2 + 4*x\n--    > ejPol3\n--    6*x^4 + 2*x\n\n-- ---------------------------------------------------------------------\n-- Implementaci\u00f3n de la especificaci\u00f3n                                --\n-- ---------------------------------------------------------------------\n\n-- polCero es el polinomio cero. Por ejemplo,\n--    ghci> polCero\n--    0\npolCero :: Polinomio a\npolCero = Pol []\n\n-- (esPolCero p) se verifica si p es el polinomio cero. Por ejemplo,\n--    esPolCero polCero  ==  True\n--    esPolCero ejPol1   ==  False\nesPolCero :: Polinomio a -> Bool\nesPolCero (Pol []) = True\nesPolCero _        = False\n\n-- (consPol n b p) es el polinomio bx^n+p. Por ejemplo,\n--    ejPol2               ==  x^5 + 5*x^2 + 4*x\n--    consPol 3 0 ejPol2   ==  x^5 + 5*x^2 + 4*x\n--    consPol 3 2 polCero  ==  2*x^3\n--    consPol 6 7 ejPol2   ==  7*x^6 + x^5 + 5*x^2 + 4*x\n--    consPol 4 7 ejPol2   ==  x^5 + 7*x^4 + 5*x^2 + 4*x\n--    consPol 5 7 ejPol2   ==  8*x^5 + 5*x^2 + 4*x\nconsPol :: Num a => Int -> a -> Polinomio a -> Polinomio a\nconsPol _ 0 p = p\nconsPol n b p@(Pol xs) \n    | esPolCero p = Pol (b:replicate n 0)\n    | n > m       = Pol (b:(replicate (n-m-1) 0)++xs)\n    | n < m       = consPol m c (consPol n b (restoPol p))\n    | b+c == 0    = Pol (dropWhile (==0) (tail xs))\n    | otherwise   = Pol ((b+c):tail xs)\n    where \n      c = coefLider p\n      m = grado p\n   \n-- (grado p) es el grado del polinomio p. Por ejemplo,\n--    ejPol3        ==  6*x^4 + 2*x\n--    grado ejPol3  ==  4\ngrado:: Polinomio a -> Int\ngrado (Pol []) = 0\ngrado (Pol xs) = length xs - 1\n\n-- (coefLider p) es el coeficiente l\u00edder del polinomio p. Por ejemplo,\n--    ejPol3            ==  6*x^4 + 2*x\n--    coefLider ejPol3  ==  6\ncoefLider:: Num t => Polinomio t -> t\ncoefLider (Pol [])    = 0\ncoefLider (Pol (a:_)) = a \n\n-- (restoPol p) es el resto del polinomio p. Por ejemplo,\n--    ejPol3           ==  6*x^4 + 2*x\n--    restoPol ejPol3  ==  2*x\n--    ejPol2           ==  x^5 + 5*x^2 + 4*x\n--    restoPol ejPol2  ==  5*x^2 + 4*x\nrestoPol :: Num t => Polinomio t -> Polinomio t\nrestoPol (Pol [])     = polCero\nrestoPol (Pol [_])    = polCero\nrestoPol (Pol (_:b:as)) \n    | b == 0    = Pol (dropWhile (==0) as)\n    | otherwise = Pol (b:as)\n<\/pre>\n<p>El c\u00f3digo de la representaci\u00f3n densa del TAD de los polinomios es<\/p>\n<pre lang=\"haskell\">\nmodule PolRepDensa\n  ( Polinomio,\n    polCero,   -- Polinomio a                                         \n    esPolCero, -- Num a =>  Polinomio a -> Bool                       \n    consPol,   -- Num a => Int -> a -> Polinomio a -> Polinomio a   \n    grado,     -- Polinomio a -> Int                                  \n    coefLider, -- Num a => Polinomio a -> a                           \n    restoPol   -- Polinomio a -> Polinomio a                          \n  ) where\n\n-- ---------------------------------------------------------------------\n-- TAD de los polinomios mediante listas densas.                      --\n-- ---------------------------------------------------------------------\n\n-- Representaremos un polinomio mediante una lista de pares (grado,coef),\n-- ordenados en orden decreciente seg\u00fan el grado. Por ejemplo, el\n-- polinomio \n--    6x^4 -5x^2 + 4x -7 \n-- se representa por\n--    [(4,6),(2,-5),(1,4),(0,-7)]. \n\ndata Polinomio a = Pol [(Int,a)] \n                   deriving Eq\n    \n-- ---------------------------------------------------------------------\n-- Escritura de los polinomios                                        --\n-- ---------------------------------------------------------------------\n\ninstance (Num t, Show t, Eq t) => Show (Polinomio t) where\n  show pol \n      | esPolCero pol         = \"0\"\n      | n == 0 && esPolCero p = show a \n      | n == 0                = concat [show a, \" + \", show p] \n      | n == 1 && esPolCero p = concat [show a, \"*x\"]\n      | n == 1                = concat [show a, \"*x + \", show p] \n      | a == 1 && esPolCero p = concat [\"x^\", show n] \n      | esPolCero p           = concat [show a, \"*x^\", show n] \n      | a == 1                = concat [\"x^\", show n, \" + \", show p] \n      | otherwise             = concat [show a, \"*x^\", show n, \" + \", show p] \n     where n = grado pol\n           a = coefLider pol\n           p = restoPol pol\n\n-- ---------------------------------------------------------------------\n-- Ejemplos de polinomios                                             --\n-- ---------------------------------------------------------------------\n\n-- Ejemplos de polinomios con coeficientes enteros:\nejPol1, ejPol2, ejPol3:: Polinomio Int\nejPol1 = consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero))\nejPol2 = consPol 5 1 (consPol 2 5 (consPol 1 4 polCero))\nejPol3 = consPol 4 6 (consPol 1 2 polCero)\n\n-- Comprobaci\u00f3n de escritura:\n--    > ejPol1\n--    3*x^4 + -5*x^2 + 3\n--    > ejPol2\n--    x^5 + 5*x^2 + 4*x\n--    > ejPol3\n--    6*x^4 + 2*x\n\n-- ---------------------------------------------------------------------\n-- Implementaci\u00f3n de la especificaci\u00f3n                                --\n-- ---------------------------------------------------------------------\n\n-- polCero es el polinomio cero. Por ejemplo,\n--    ghci> polCero\n--    0\npolCero :: Num a => Polinomio a\npolCero = Pol []\n\n-- (esPolCero p) se verifica si p es el polinomio cero. Por ejemplo,\n--    esPolCero polCero  ==  True\n--    esPolCero ejPol1   ==  False\nesPolCero :: Num a => Polinomio a -> Bool\nesPolCero (Pol []) = True\nesPolCero _        = False\n\n-- (consPol n b p) es el polinomio bx^n+p. Por ejemplo,\n--    ejPol2               ==  x^5 + 5*x^2 + 4*x\n--    consPol 3 0 ejPol2   ==  x^5 + 5*x^2 + 4*x\n--    consPol 3 2 polCero  ==  2*x^3\n--    consPol 6 7 ejPol2   ==  7*x^6 + x^5 + 5*x^2 + 4*x\n--    consPol 4 7 ejPol2   ==  x^5 + 7*x^4 + 5*x^2 + 4*x\n--    consPol 5 7 ejPol2   ==  8*x^5 + 5*x^2 + 4*x\nconsPol :: (Num a, Eq a) => Int -> a -> Polinomio a -> Polinomio a\nconsPol _ 0 p = p\nconsPol n b p@(Pol xs) \n    | esPolCero p = Pol [(n,b)]\n    | n > m       = Pol ((n,b):xs)\n    | n < m       = consPol m c (consPol n b (Pol (tail xs)))\n    | b+c == 0    = Pol (tail xs)\n    | otherwise   = Pol ((n,b+c):(tail xs))\n    where \n      c = coefLider p\n      m = grado p\n\n-- (grado p) es el grado del polinomio p. Por ejemplo,\n--    ejPol3        ==  6*x^4 + 2*x\n--    grado ejPol3  ==  4\ngrado:: Polinomio a -> Int\ngrado (Pol [])        = 0\ngrado (Pol ((n,_):_)) = n\n\n-- (coefLider p) es el coeficiente l\u00edder del polinomio p. Por ejemplo,\n--    ejPol3            ==  6*x^4 + 2*x\n--    coefLider ejPol3  ==  6\ncoefLider:: Num t => Polinomio t -> t\ncoefLider (Pol [])        = 0\ncoefLider (Pol ((_,b):_)) = b\n\n-- (restoPol p) es el resto del polinomio p. Por ejemplo,\n--    ejPol3           ==  6*x^4 + 2*x\n--    restoPol ejPol3  ==  2*x\n--    ejPol2           ==  x^5 + 5*x^2 + 4*x\n--    restoPol ejPol2  ==  5*x^2 + 4*x\nrestoPol :: Num t => Polinomio t -> Polinomio t\nrestoPol (Pol [])     = polCero\nrestoPol (Pol [_])    = polCero\nrestoPol (Pol (_:xs)) = Pol xs\n<\/pre>\n<p>El c\u00f3digo de las operaciones con el TAD de los polinomios es<\/p>\n<pre lang=\"haskell\">\nmodule PolOperaciones (module Pol, module PolOperaciones) where\n\n-- ---------------------------------------------------------------------\n-- Importaci\u00f3n de librer\u00edas                                           --\n-- ---------------------------------------------------------------------\n\n-- Nota: Hay que elegir una implementaci\u00f3n del TAD de los polinomios.\nimport PolRepTDA as Pol\n-- import PolRepDispersa as Pol\n-- import PolRepDensa as Pol\n\nimport Test.QuickCheck\n\n-- ---------------------------------------------------------------------\n-- Ejemplos                                                           --\n-- ---------------------------------------------------------------------\n\n-- Ejemplos de polinomios con coeficientes enteros:\nejPol1, ejPol2, ejPol3, ejTerm:: Polinomio Int\nejPol1 = consPol 4 3 (consPol 2 (-5) (consPol 0 3 polCero))\nejPol2 = consPol 5 1 (consPol 2 5 (consPol 1 4 polCero))\nejPol3 = consPol 4 6 (consPol 1 2 polCero)\nejTerm = consPol 1 4 polCero\n\n-- ---------------------------------------------------------------------\n-- Generador de polinomios                                            --\n-- ---------------------------------------------------------------------\n\n-- (genPol n) es un generador de polinomios. Por ejemplo,\n--    ghci> sample (genPol 1)\n--    7*x^9 + 9*x^8 + 10*x^7 + -14*x^5 + -15*x^2 + -10\n--    -4*x^8 + 2*x\n--    -8*x^9 + 4*x^8 + 2*x^6 + 4*x^5 + -6*x^4 + 5*x^2 + -8*x\n--    -9*x^9 + x^5 + -7\n--    8*x^10 + -9*x^7 + 7*x^6 + 9*x^5 + 10*x^3 + -1*x^2\n--    7*x^10 + 5*x^9 + -5\n--    -8*x^10 + -7\n--    -5*x\n--    5*x^10 + 4*x^4 + -3\n--    3*x^3 + -4\n--    10*x\ngenPol :: (Arbitrary a, Num a, Eq a) => Int -> Gen (Polinomio a)\ngenPol 0 = return polCero\ngenPol n = do n <- choose (0,10)\n              b <- arbitrary\n              p <- genPol (div n 2)\n              return (consPol n b p) \n\ninstance (Arbitrary a, Num a, Eq a) => Arbitrary (Polinomio a) where\n    arbitrary = sized genPol\n\n-- ---------------------------------------------------------------------\n-- Funciones sobre t\u00e9rminos                                           --\n-- ---------------------------------------------------------------------\n\n-- (creaTermino n a) es el t\u00e9rmino a*x^n. Por ejemplo, \n--    creaTermino 2 5  ==  5*x^2\ncreaTermino:: (Num t, Eq t) => Int -> t -> Polinomio t\ncreaTermino n a = consPol n a polCero\n\n-- (termLider p) es el t\u00e9rmino l\u00edder del polinomio p. Por ejemplo,\n--    ejPol2            ==  x^5 + 5*x^2 + 4*x\n--    termLider ejPol2  ==  x^5\ntermLider:: (Num t, Eq t) => Polinomio t -> Polinomio t\ntermLider p = creaTermino (grado p) (coefLider p)\n\n-- ---------------------------------------------------------------------\n-- Suma de polinomios                                                 --\n-- ---------------------------------------------------------------------\n\n-- (sumaPol p q) es la suma de los polinomios p y q. Por ejemplo, \n--    ejPol1                 ==  3*x^4 + -5*x^2 + 3\n--    ejPol2                 ==  x^5 + 5*x^2 + 4*x\n--    sumaPol ejPol1 ejPol2  ==  x^5 + 3*x^4 + 4*x + 3\nsumaPol:: (Num a, Eq a) => Polinomio a -> Polinomio a -> Polinomio a\nsumaPol p q \n    | esPolCero p = q\n    | esPolCero q = p\n    | n1 > n2      = consPol n1 a1 (sumaPol r1 q)\n    | n1 < n2      = consPol n2 a2 (sumaPol p r2)\n    | a1+a2 \/= 0   = consPol n1 (a1+a2) (sumaPol r1 r2)\n    | otherwise    = sumaPol r1 r2\n    where n1 = grado p\n          a1 = coefLider p\n          r1 = restoPol p\n          n2 = grado q\n          a2 = coefLider q\n          r2 = restoPol q\n\n-- Propiedad. El polinomio cero es el elemento neutro de la suma.\nprop_neutroSumaPol :: Polinomio Int -> Bool\nprop_neutroSumaPol p = \n    sumaPol polCero p == p\n\n-- Comprobaci\u00f3n con QuickCheck.\n--    ghci> quickCheck prop_neutroSumaPol\n--    OK, passed 100 tests.\n\n-- Propiedad. La suma es conmutativa.\nprop_conmutativaSuma :: Polinomio Int -> Polinomio Int -> Bool\nprop_conmutativaSuma p q = \n    sumaPol p q == sumaPol q p\n\n-- Comprobaci\u00f3n:\n--    ghci> quickCheck prop_conmutativaSuma\n--    OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Producto de polinomios                                             --\n-- ---------------------------------------------------------------------\n\n-- (multPorTerm t p) es el producto del t\u00e9rmino t por el polinomio\n-- p. Por ejemplo,\n--    ejTerm                     ==  4*x\n--    ejPol2                     ==  x^5 + 5*x^2 + 4*x\n--    multPorTerm ejTerm ejPol2  ==  4*x^6 + 20*x^3 + 16*x^2\nmultPorTerm :: (Num t, Eq t) => Polinomio t -> Polinomio t -> Polinomio t\nmultPorTerm term pol \n    | esPolCero pol = polCero\n    | otherwise     = consPol (n+m) (a*b) (multPorTerm term r)\n    where n = grado term\n          a = coefLider term\n          m = grado pol\n          b = coefLider pol\n          r = restoPol pol    \n\n-- (multPol p q) es el producto de los polinomios p y q. Por\n-- ejemplo,\n--    ghci> ejPol1\n--    3*x^4 + -5*x^2 + 3\n--    ghci> ejPol2\n--    x^5 + 5*x^2 + 4*x\n--    ghci> multPol ejPol1 ejPol2\n--    3*x^9 + -5*x^7 + 15*x^6 + 15*x^5 + -25*x^4 + -20*x^3 + 15*x^2 + 12*x\nmultPol :: (Num a, Eq a) => Polinomio a -> Polinomio a -> Polinomio a\nmultPol p q\n    | esPolCero p = polCero\n    | otherwise    = sumaPol (multPorTerm (termLider p) q)\n                             (multPol (restoPol p) q)\n\n-- Propiedad. El producto de polinomios es conmutativo.\nprop_conmutativaProducto :: Polinomio Int -> Polinomio Int -> Bool\nprop_conmutativaProducto p q = \n    multPol p q == multPol q p\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_conmutativaProducto\n--    OK, passed 100 tests.\n\n-- El producto es distributivo respecto de la suma.\nprop_distributivaProductoSuma :: Polinomio Int -> Polinomio Int \n                                 -> Polinomio Int -> Bool\nprop_distributivaProductoSuma p q r =\n    multPol p (sumaPol q r) == sumaPol (multPol p q) (multPol p r)\n\n-- Comprobaci\u00f3n:\n--    ghci> quickCheck prop_distributivaProductoSuma\n--    OK, passed 100 tests.\n\n-- polUnidad es el polinomio unidad. Por ejemplo, \n--    ghci> polUnidad\n--    1\npolUnidad:: (Num t, Eq t) => Polinomio t\npolUnidad = consPol 0 1 polCero\n\n-- Propiedad. El polinomio unidad es el elemento neutro del producto.\nprop_polUnidad :: Polinomio Int -> Bool\nprop_polUnidad p = \n    multPol p polUnidad == p\n\n-- Comprobaci\u00f3n:\n--    ghci> quickCheck prop_polUnidad\n--    OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Valor de un polinomio en un punto                                  --\n-- ---------------------------------------------------------------------\n\n-- (valor p c) es el valor del polinomio p al sustituir su variable por\n-- c. Por ejemplo, \n--    ejPol1             ==  3*x^4 + -5*x^2 + 3\n--    valor ejPol1 0     ==  3\n--    valor ejPol1 1     ==  1\n--    valor ejPol1 (-2)  ==  31\nvalor:: (Num a, Eq a) => Polinomio a -> a -> a\nvalor p c \n    | esPolCero p = 0\n    | otherwise   =  b*c^n + valor r c\n    where n = grado p\n          b = coefLider p\n          r = restoPol p\n\n-- ---------------------------------------------------------------------\n-- Verificaci\u00f3n de raices de polinomios                               --\n-- ---------------------------------------------------------------------\n\n-- (esRaiz c p) se verifica si c es una raiz del polinomio p. por\n-- ejemplo, \n--    ejPol3           ==  6*x^4 + 2*x\n--    esRaiz 1 ejPol3  ==  False\n--    esRaiz 0 ejPol3  ==  True\nesRaiz:: (Num a, Eq a) => a -> Polinomio a -> Bool\nesRaiz c p = valor p c == 0\n\n-- ---------------------------------------------------------------------\n-- Derivaci\u00f3n de polinomios                                           --\n-- ---------------------------------------------------------------------\n\n-- (derivada p) es la derivada del polinomio p. Por ejemplo, \n--    ejPol2           ==  x^5 + 5*x^2 + 4*x\n--    derivada ejPol2  ==  5*x^4 + 10*x + 4\nderivada :: Polinomio Int -> Polinomio Int\nderivada p \n    | n == 0     = polCero\n    | otherwise  = consPol (n-1) (n*b) (derivada r)\n    where n = grado p\n          b = coefLider p\n          r = restoPol p\n\n-- Propiedad. La derivada de la suma es la suma de las derivadas.\nprop_derivada :: Polinomio Int -> Polinomio Int -> Bool\nprop_derivada p q =\n    derivada (sumaPol p q) == sumaPol (derivada p) (derivada q)\n\n-- Comprobaci\u00f3n\n--    ghci> quickCheck prop_derivada\n--    OK, passed 100 tests. \n\n-- ---------------------------------------------------------------------\n-- Resta de polinomios                                                --\n-- ---------------------------------------------------------------------\n\n-- (resta p q) es la el polinomio obtenido rest\u00e1ndole a p el q. Por\n-- ejemplo, \n--    ejPol1                  ==  3*x^4 + -5*x^2 + 3\n--    ejPol2                  ==  x^5 + 5*x^2 + 4*x\n--    restaPol ejPol1 ejPol2  ==  -1*x^5 + 3*x^4 + -10*x^2 + -4*x + 3\nrestaPol :: (Num a, Eq a) => Polinomio a -> Polinomio a -> Polinomio a\nrestaPol p q  = \n    sumaPol p (multPorTerm (creaTermino 0 (-1)) q)\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En la clase de hoy de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas hemos estudiado el tipo abstracto de los polinomios y su implementaci\u00f3n en Haskell. Comenzamos la clase analizando las posibles representaciones de los polinomios y, como consecuencia, establecer la signatura y las propiedades del TAD de los polinomios. A continuaci\u00f3n, estudiamos tres prosibles&#8230;<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[250],"tags":[270,310],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5413"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/comments?post=5413"}],"version-history":[{"count":1,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5413\/revisions"}],"predecessor-version":[{"id":5414,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5413\/revisions\/5414"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=5413"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=5413"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=5413"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}