{"id":4596,"date":"2014-11-17T13:02:41","date_gmt":"2014-11-17T12:02:41","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=4596"},"modified":"2014-11-18T13:04:13","modified_gmt":"2014-11-18T12:04:13","slug":"i1m2014-ejercicios-sobre-funciones-de-orden-superior-y-plegados","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2014-ejercicios-sobre-funciones-de-orden-superior-y-plegados\/","title":{"rendered":"I1M2014: Ejercicios sobre funciones de orden superior y plegados"},"content":{"rendered":"<p>En la clase de hoy del curso <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-14\">Inform\u00e1tica (de 1\u00ba de Grado en Matem\u00e1ticas)<\/a> se han comentado las soluciones de los ejercicios de la 8\u00aa relaci\u00f3n. En los ejercicios se piden definiciones de funciones de orden superior y con plegados.<\/p>\n<p>Los ejercicios y soluciones se muestran a continuaci\u00f3n<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\n-- ---------------------------------------------------------------------\n-- Importaci\u00f3n de librer\u00edas auxiliares                                --\n-- ---------------------------------------------------------------------\n\nimport Data.List\nimport Test.QuickCheck\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1.1. Definir, por recursi\u00f3n, la funci\u00f3n\n--    takeWhileR :: (a -> Bool) -> [a] -> [a]\n-- tal que (takeWhileR p xs) es la lista de los elemento de xs hasta el\n-- primero que no cumple la propiedad p. Por ejemplo,\n--    takeWhileR (<7) [2,3,9,4,5]  ==  [2,3]\n-- ---------------------------------------------------------------------\n\ntakeWhileR :: (a -> Bool) -> [a] -> [a]\ntakeWhileR _ [] = []\ntakeWhileR p (x:xs) \n    | p x       = x : takeWhileR p xs\n    | otherwise = []\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1.2. Comprobar con QuickCheck que, para cualquier lista de\n-- enteros xs, se verifica que (takeWhileR even xs) es igual que \n-- (takeWhile even xs)\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_takeWhileR :: [Int] -> Bool\nprop_takeWhileR xs =\n    takeWhileR even xs == takeWhile even xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_takeWhile\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1.3. Comprobar con QuickCheck que, para cualquier lista de\n-- enteros xs, se verifica que todos los elementos de (takeWhileR even xs)\n-- son pares.\n-- ---------------------------------------------------------------------\n\nprop_takeWhileTodos :: [Int] -> Bool\nprop_takeWhileTodos xs =\n    all even (takeWhileR even xs)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.1. Definir por recursi\u00f3n la funci\u00f3n\n--    dropWhileR :: (a -> Bool) -> [a] -> [a]\n-- tal que (dropWhileR p xs) es la lista de eliminando los elemento de xs\n-- hasta el primero que cumple la propiedad p. Por ejemplo,\n--    dropWhileR (<7) [2,3,9,4,5]  ==  [9,4,5]\n-- ---------------------------------------------------------------------\n\ndropWhileR :: (a -> Bool) -> [a] -> [a]\ndropWhileR _ [] = []\ndropWhileR p (x:xs)\n    | p x       = dropWhileR p xs\n    | otherwise = x:xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 2.2. Comprobar con QuickCheck que, para cualquier lista de\n-- enteros xs, se verifica que la concatenaci\u00f3n de (takeWhileR even xs)\n-- y (dropWhileR even xs) es igual a xs.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_takeDrop :: [Int] -> Bool\nprop_takeDrop xs =\n    takeWhileR even xs ++ dropWhileR even xs == xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_takeDrop\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.1. La funci\u00f3n \n--    divideMedia :: [Double] -> ([Double],[Double])\n-- dada una lista num\u00e9rica, xs, calcula el par (ys,zs), donde ys \n-- contiene los elementos de xs estrictamente menores que la media, \n-- mientras que zs contiene los elementos de xs estrictamente mayores \n-- que la media. Por ejemplo, \n--    divideMedia [6,7,2,8,6,3,4] ==  ([2.0,3.0,4.0],[6.0,7.0,8.0,6.0])\n--    divideMedia [1,2,3]         ==  ([1.0],[3.0])\n-- Definir la funci\u00f3n divideMedia por filtrado, comprensi\u00f3n y\n-- recursi\u00f3n. \n-- ---------------------------------------------------------------------\n\n-- La definici\u00f3n por filtrado es\ndivideMediaF :: [Double] -> ([Double],[Double])\ndivideMediaF xs = (filter (<m) xs, filter (>m) xs)\n    where m = media xs\n\n-- (media xs) es la media de xs. Por ejemplo,\n--    media [1,2,3]       ==  2.0\n--    media [1,-2,3.5,4]  ==  1.625 \n-- Nota: En la definici\u00f3n de media se usa la funci\u00f3n fromIntegral tal\n-- que (fromIntegral x) es el n\u00famero real correspondiente al n\u00famero\n-- entero x. \nmedia :: [Double] -> Double\nmedia xs = (sum xs) \/ fromIntegral (length xs)\n\n-- La definici\u00f3n por comprensi\u00f3n es\ndivideMediaC :: [Double] -> ([Double],[Double])\ndivideMediaC xs = ([x | x <- xs, x < m], [x | x <- xs, x > m])\n    where m = media xs\n\n-- La definici\u00f3n por recursi\u00f3n es\ndivideMediaR :: [Double] -> ([Double],[Double])\ndivideMediaR xs = divideMediaR' xs\n    where m = media xs\n          divideMediaR' [] = ([],[])\n          divideMediaR' (x:xs) | x < m  = (x:ys, zs)\n                               | x == m = (ys, zs)\n                               | x > m  = (ys, x:zs)\n                               where (ys, zs) = divideMediaR' xs\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.2. Comprobar con QuickCheck que las tres definiciones\n-- anteriores divideMediaF, divideMediaC y divideMediaR son\n-- equivalentes.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_divideMedia :: [Double] -> Bool\nprop_divideMedia xs =\n    divideMediaC xs == d &&\n    divideMediaR xs == d\n    where d = divideMediaF xs \n    \n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_divideMedia\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.3. Comprobar con QuickCheck que si (ys,zs) es el par\n-- obtenido aplic\u00e1ndole la funci\u00f3n divideMediaF a xs, entonces la suma\n-- de las longitudes de ys y zs es menor o igual que la longitud de xs.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_longitudDivideMedia :: [Double] -> Bool\nprop_longitudDivideMedia xs =\n    length ys + length zs <= length xs\n    where (ys,zs) = divideMediaF xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_longitudDivideMedia\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.4. Comprobar con QuickCheck que si (ys,zs) es el par\n-- obtenido aplic\u00e1ndole la funci\u00f3n divideMediaF a xs, entonces todos los\n-- elementos de ys son menores que todos los elementos de zs.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_divideMediaMenores :: [Double] -> Bool\nprop_divideMediaMenores xs =\n    and [y < z | y <- ys, z <- zs]\n    where (ys,zs) = divideMediaF xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_divideMediaMenores\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3.5. Comprobar con QuickCheck que si (ys,zs) es el par\n-- obtenido aplic\u00e1ndole la funci\u00f3n divideMediaF a xs, entonces la\n-- media de xs no pertenece a ys ni a zs.\n-- \n-- Nota: Usar la funci\u00f3n notElem tal que (notElem x ys) se verifica si y\n-- no pertenece a ys.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_divideMediaSinMedia :: [Double] -> Bool\nprop_divideMediaSinMedia xs =\n    notElem m (ys ++ zs)\n    where  m       = media xs\n           (ys,zs) = divideMediaF xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_divideMediaSinMedia\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4. Definir la funci\u00f3n\n--    segmentos :: (a -> Bool) -> [a] -> [a]\n-- tal que (segmentos p xs) es la lista de los segmentos de xs cuyos\n-- elementos verifican la propiedad p. Por ejemplo,\n--    segmentos even [1,2,0,4,5,6,48,7,2]  ==  [[],[2,0,4],[6,48],[2]]\n-- ---------------------------------------------------------------------\n\nsegmentos :: (a -> Bool) -> [a] -> [[a]]\nsegmentos _ [] = []\nsegmentos p xs = \n    takeWhile p xs : (segmentos p (dropWhile (not.p) (dropWhile p xs)))\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5. Definir la funci\u00f3n\n--    relacionados :: (a -> a -> Bool) -> [a] -> Bool\n-- tal que (relacionados r xs) se verifica si para todo par (x,y) de\n-- elementos consecutivos de xs se cumple la relaci\u00f3n r. Por ejemplo,\n--    relacionados (<) [2,3,7,9]                ==  True\n--    relacionados (<) [2,3,1,9]                ==  False\n-- ---------------------------------------------------------------------\n\n-- 1\u00aa definici\u00f3n (por recursi\u00f3n):\nrelacionados :: (a -> a -> Bool) -> [a] -> Bool\nrelacionados r (x:y:zs) = (r x y) && relacionados r (y:zs)\nrelacionados _ _ = True\n\n-- 2\u00aa definici\u00f3n (por comprensi\u00f3n):\nrelacionados2 :: (a -> a -> Bool) -> [a] -> Bool\nrelacionados2 r xs = and [r x y | (x,y) <- zip xs (tail xs)]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6.1. Definir la funci\u00f3n\n--    agrupa :: Eq a => [[a]] -> [[a]]\n-- tal que (agrupa xss) es la lista de las listas obtenidas agrupando\n-- los primeros elementos, los segundos, ... Por ejemplo, \n--    agrupa [[1..6],[7..9],[10..20]]  ==  [[1,7,10],[2,8,11],[3,9,12]]\n--    agrupa []                        ==  []\n-- ---------------------------------------------------------------------\n\nagrupa :: Eq a => [[a]] -> [[a]]\nagrupa []  = []\nagrupa xss\n    | [] `elem` xss = []\n    | otherwise     = primeros xss : agrupa (restos xss)\n    where primeros = map head\n          restos   = map tail\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 6.2. Comprobar con QuickChek que la longitud de todos los\n-- elementos de (agrupa xs) es igual a la longitud de xs.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_agrupa :: [[Int]] -> Bool\nprop_agrupa xss =\n    and [length xs == n | xs <- agrupa xss]\n    where n = length xss\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_agrupa\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.1. Definir por recursi\u00f3n la funci\u00f3n\n--    superpar :: Int -> Bool\n-- tal que (superpar n) se verifica si n es un n\u00famero par tal que todos\n-- sus d\u00edgitos son pares. Por ejemplo,\n--    superpar 426  ==  True\n--    superpar 456  ==  False\n-- ---------------------------------------------------------------------\n\nsuperpar :: Int -> Bool\nsuperpar n | n < 10    = even n\n           | otherwise = even n &#038;&#038; superpar (n `div` 10)\n\n-- Otra forma equivalente es\nsuperpar_2 :: Int -> Bool\nsuperpar_2 0 = True\nsuperpar_2 n = even n && superpar_2 (div n 10)  \n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.2. Definir por comprensi\u00f3n la funci\u00f3n\n--    superpar2 :: Int -> Bool\n-- tal que (superpar2 n) se verifica si n es un n\u00famero par tal que todos\n-- sus d\u00edgitos son pares. Por ejemplo,\n--    superpar2 426  ==  True\n--    superpar2 456  ==  False\n-- ---------------------------------------------------------------------\n\nsuperpar2 :: Int -> Bool\nsuperpar2 n = and [even d | d <- digitos n]\n\ndigitos :: Int -> [Int]\ndigitos n = [read [d] | d <- show n]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.3. Definir, por recursi\u00f3n sobre los d\u00edgitos, la funci\u00f3n\n--    superpar3 :: Int -> Bool\n-- tal que (superpar3 n) se verifica si n es un n\u00famero par tal que todos\n-- sus d\u00edgitos son pares. Por ejemplo,\n--    superpar3 426  ==  True\n--    superpar3 456  ==  False\n-- ---------------------------------------------------------------------\n\nsuperpar3 :: Int -> Bool\nsuperpar3 n = sonPares (digitos n)\n    where sonPares []     = True\n          sonPares (d:ds) = even d && sonPares ds\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.4. Definir, usando all, la funci\u00f3n\n--    superpar4 :: Int -> Bool\n-- tal que (superpar4 n) se verifica si n es un n\u00famero par tal que todos\n-- sus d\u00edgitos son pares. Por ejemplo,\n--    superpar4 426  ==  True\n--    superpar4 456  ==  False\n-- ---------------------------------------------------------------------\n\nsuperpar4 :: Int -> Bool\nsuperpar4 n = all even (digitos n)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7.5. Definir, usando filter, la funci\u00f3n\n--    superpar5 :: Int -> Bool\n-- tal que (superpar5 n) se verifica si n es un n\u00famero par tal que todos\n-- sus d\u00edgitos son pares. Por ejemplo,\n--    superpar5 426  ==  True\n--    superpar5 456  ==  False\n-- ---------------------------------------------------------------------\n\nsuperpar5 :: Int -> Bool\nsuperpar5 n = filter even (digitos n) == digitos n\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.1. Definir, por recursi\u00f3n, la funci\u00f3n \n--    concatR :: [[a]] -> [a]\n-- tal que (concatR xss) es la concatenaci\u00f3n de las listas de xss. Por\n-- ejemplo, \n--    concatR [[1,3],[2,4,6],[1,9]]  ==  [1,3,2,4,6,1,9]\n-- ---------------------------------------------------------------------\n\n-- La definici\u00f3n por recursi\u00f3n es \nconcatR :: [[a]] -> [a]\nconcatR []       = []\nconcatR (xs:xss) = xs ++ concatR xss\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.2. Definir, usando foldr, la funci\u00f3n \n--    concatP :: [[a]] -> [a]\n-- tal que (concatP xss) es la concatenaci\u00f3n de las listas de xss. Por\n-- ejemplo, \n--    concatP [[1,3],[2,4,6],[1,9]]  ==  [1,3,2,4,6,1,9]\n-- ---------------------------------------------------------------------\n\nconcatP :: [[a]] -> [a]\nconcatP = foldr (++) []\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.3. Comprobar con QuickCheck que la funciones concatR,\n-- concatP y concat son equivalentes.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_concat :: [[Int]] -> Bool\nprop_concat xss =\n    concatR xss == ys && concatP xss == ys\n    where ys = concat xss\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_concat\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8.4. Comprobar con QuickCheck que la longitud de \n-- (concatP xss) es la suma de las longitudes de los elementos de xss.\n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_longConcat :: [[Int]] -> Bool\nprop_longConcat xss =\n    length (concatP xss) == sum [length xs | xs <- xss]\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_longConcat\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9. Se considera la funci\u00f3n \n--    filtraAplica :: (a -> b) -> (a -> Bool) -> [a] -> [b]\n-- tal que (filtraAplica f p xs) es la lista obtenida aplic\u00e1ndole a los\n-- elementos de xs que cumplen el predicado p la funci\u00f3n f. Por ejemplo,\n--    filtraAplica (4+) (<3) [1..7]  =>  [5,6]\n-- Se pide, definir la funci\u00f3n\n-- 1. por comprensi\u00f3n,\n-- 2. usando map y filter,\n-- 3. por recursi\u00f3n y\n-- 4. por plegado (con foldr).\n-- ---------------------------------------------------------------------\n\n-- La definici\u00f3n con lista de comprensi\u00f3n es\nfiltraAplicaC :: (a -> b) -> (a -> Bool) -> [a] -> [b]\nfiltraAplicaC f p xs = [f x | x <- xs, p x]\n\n-- La definici\u00f3n con map y filter es\nfiltraAplicaA :: (a -> b) -> (a -> Bool) -> [a] -> [b]\nfiltraAplicaA f p xs = map f (filter p xs)\n\n-- La definici\u00f3n por recursi\u00f3n es\nfiltraAplicaR :: (a -> b) -> (a -> Bool) -> [a] -> [b]\nfiltraAplicaR f p [] = []\nfiltraAplicaR f p (x:xs) | p x       = f x : filtraAplicaR f p xs\n                         | otherwise = filtraAplicaR f p xs\n\n-- La definici\u00f3n por plegado es\nfiltraAplicaP :: (a -> b) -> (a -> Bool) -> [a] -> [b]\nfiltraAplicaP f p = foldr g []\n    where g x y | p x       = f x : y\n                | otherwise = y\n\n-- La definici\u00f3n por plegado usando lambda es\nfiltraAplicaP2 :: (a -> b) -> (a -> Bool) -> [a] -> [b]\nfiltraAplicaP2 f p = \n    foldr (\\x y -> if p x then (f x : y) else y) []\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10.1. Definir, mediante recursi\u00f3n, la funci\u00f3n\n--    maximumR :: Ord a => [a] -> a\n-- tal que (maximumR xs) es el m\u00e1ximo de la lista xs. Por ejemplo,\n--    maximumR [3,7,2,5]                  ==  7\n--    maximumR [\"todo\",\"es\",\"falso\"]      ==  \"todo\"\n--    maximumR [\"menos\",\"alguna\",\"cosa\"]  ==  \"menos\"\n-- Nota: La funci\u00f3n maximumR es equivalente a la predefinida maximum.\n-- ---------------------------------------------------------------------\n\nmaximumR :: Ord a => [a] -> a\nmaximumR [x]      = x\nmaximumR (x:y:ys) = max x (maximumR (y:ys))\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10.2. La funci\u00f3n de plegado foldr1 est\u00e1 definida por \n--    foldr1 :: (a -> a -> a) -> [a] -> a\n--    foldr1 _ [x]    =  x\n--    foldr1 f (x:xs) =  f x (foldr1 f xs)\n-- \n-- Definir, mediante plegado con foldr1, la funci\u00f3n\n--    maximumP :: Ord a => [a] -> a\n-- tal que (maximumR xs) es el m\u00e1ximo de la lista xs. Por ejemplo,\n--    maximumP [3,7,2,5]                  ==  7\n--    maximumP [\"todo\",\"es\",\"falso\"]      ==  \"todo\"\n--    maximumP [\"menos\",\"alguna\",\"cosa\"]  ==  \"menos\"\n-- Nota: La funci\u00f3n maximumP es equivalente a la predefinida maximum.\n-- ---------------------------------------------------------------------\n\nmaximumP :: Ord a => [a] -> a\nmaximumP = foldr1 max\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10.3. Comprobar con QuickCheck que, para cualquier lista no\n-- vac\u00eda xs, (maximumP xs) es un elemento de xs que es mayor o igual que\n-- todos los elementos de xs. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_maximumP :: [Int] -> Property\nprop_maximumP xs = \n    xs \/= [] ==> m `elem` xs && all (<=m) xs\n    where m = maximumP xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_maximumP\n--    +++ OK, passed 100 tests.\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.1. Definir, mediante plegado con foldr1, la funci\u00f3n\n--    minimunP :: Ord a => [a] -> a\n-- tal que (minimunR xs) es el m\u00e1ximo de la lista xs. Por ejemplo,\n--    minimunP [3,7,2,5]                  ==  2\n--    minimumP [\"todo\",\"es\",\"falso\"]      ==  \"es\"\n--    minimumP [\"menos\",\"alguna\",\"cosa\"]  ==  \"alguna\"\n-- \n-- Nota: La funci\u00f3n minimunP es equivalente a la predefinida minimun.\n-- ---------------------------------------------------------------------\n\nminimumP :: Ord a => [a] -> a\nminimumP = foldr1 min\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11.2. Comprobar con QuickCheck que, para cualquier lista no\n-- vac\u00eda xs, (minimumP xs) es un elemento de xs que es menor o igual que\n-- todos los elementos de xs. \n-- ---------------------------------------------------------------------\n\n-- La propiedad es\nprop_minimumP :: [Int] -> Property\nprop_minimumP xs = \n    xs \/= [] ==> m `elem` xs && all (>=m) xs\n    where m = minimumP xs\n\n-- La comprobaci\u00f3n es\n--    ghci> quickCheck prop_minimumP\n--    +++ OK, passed 100 tests.\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En la clase de hoy del curso Inform\u00e1tica (de 1\u00ba de Grado en Matem\u00e1ticas) se han comentado las soluciones de los ejercicios de la 8\u00aa relaci\u00f3n. En los ejercicios se piden definiciones de funciones de orden superior y con plegados. Los ejercicios y soluciones se muestran a continuaci\u00f3n<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","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":[238],"tags":[270,305,126],"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\/4596"}],"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=4596"}],"version-history":[{"count":2,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4596\/revisions"}],"predecessor-version":[{"id":4598,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/4596\/revisions\/4598"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=4596"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=4596"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=4596"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}