Acciones

Relación 7

De Razonamiento automático (2010-11)

header {* 7ª relación de ejercicios *}

theory Relacion_7_sol
imports Main Efficient_Nat
begin

section {* Contador de occurrencias *}

text {*
  --------------------------------------------------------------------- 
  Ejercicio 1. Definir la función 
     veces :: "'a ⇒ 'a list ⇒ nat"
  tal que (veces x ys) es el número de occurrencias del elemento x en la
  lista ys. Por ejemplo, 
    veces (2::nat) [2,1,2,5,2] = 3
  --------------------------------------------------------------------- 
*}



primrec veces :: "'a ⇒ 'a list ⇒ nat" where
  "veces x [] = 0"
| "veces x (y#ys) = (if x = y then 1 + veces x ys else veces x ys)"



text {* 
  --------------------------------------------------------------------- 
  Ejercicio 2. Demostrar o refutar:
     veces a (xs @ ys) = veces a xs + veces a ys
  --------------------------------------------------------------------- 
*} 


lemma "veces a (xs @ ys) = veces a xs + veces a ys"
by (induct xs) auto

 

text {* 
  --------------------------------------------------------------------- 
  Ejercicio 3. Demostrar o refutar:
     veces a xs = veces a (rev xs)
  --------------------------------------------------------------------- 
*} 

text {* 
  --------------------------------------------------------------------- 
  Ejercicio 4. Demostrar o refutar:
    "veces a xs ≤ length xs".
  --------------------------------------------------------------------- 
*}


lemma "veces a xs ≤ length xs"
by (induct xs) auto


text {* 
  --------------------------------------------------------------------- 
  Ejercicio 5. Sabiendo que la función map aplica una función a todos los
  elementos de una lista: 
     map f [x\<^isub>1,…,x\<^isub>n] = [f x\<^isub>1,…,f x\<^isub>n], 
  demostrar o refutar
     veces a (map f xs) = veces (f a) xs
  --------------------------------------------------------------------- 
*}

lemma "veces a (map f xs) = veces (f a) xs"
quickcheck
oops

text{*
El contraejemplo encontrado es el siguiente:
xs = [1]
f = (λx. 0)(1 := 0, 0 := 0)
a = 0

Esto es: 0 = f(1) pero f(0) ≠ 1
*}

text {* 
  --------------------------------------------------------------------- 
  Ejercicio 6. La función 
     filter :: "('a ⇒ bool) ⇒ 'a list ⇒ 'a list" 
  está definida por
     filter P []       = []
     filter P (x # xs) = (if P x then x # filter P xs else filter P xs)
  Encontrar una expresión e que no contenga filter tal que se verifique
  la siguiente propiedad: 
     veces a (filter P xs) = e
  --------------------------------------------------------------------- 
*}

lemma "veces a (filter P xs) = (if P a then veces a xs else 0)"
by (induct xs) auto

text {* 
  --------------------------------------------------------------------- 
  Ejercicio 7. Usando veces, definir la función 
     borraDups :: "'a list ⇒ bool"
  tal que (borraDups xs) es la lista obtenida eliminando los elementos
  duplicados de la lista xs. Por ejemplo,  
     borraDups [1::nat,2,4,2,3] = [1,4,2,3]

  Nota: La función borraDups es equivalente a la predefinida remdups. 
  --------------------------------------------------------------------- 
*}


text {* 
  El tipo correspondiente al conjunto imagen de la función definida
  no coincide con el indicado en la declaración de tipos del enunciado,
  dado que en él aparece erróneamente la salida de tipo bool, mientras
  que del resto del texto se deduce que la salida es una lista de
  elementos de tipo 'a. 
*}



primrec borraDups :: "'a list ⇒ 'a list" where
  "borraDups [] = []"
| "borraDups (x#xs) = (if veces x xs > 0 then borraDups xs else (x#borraDups xs))"



text {*
Nota: para que no muestre error la función de evaluación
    hay que indicarle el tipo de los elementos de la lista.
    Por ejemplo:
          value "borraDups [1::nat,2,4,2,3]"
*}



text {* 
  --------------------------------------------------------------------- 
  Ejercicio 8. Encontrar una expresión e que no contenga la función
  borraDups tal que se verifique 
     veces x (borraDups xs) = e
  --------------------------------------------------------------------- 
*}

lemma "veces x (borraDups xs) = (if (veces x xs) >= 1 then 1 else 0)"
by (induct xs) auto

text {* 
  --------------------------------------------------------------------- 
  Ejercicio 9. Usando la función "veces", definir la función 
     distintos :: "'a list ⇒ bool"
  tal que (distintos xs) se verifica si cada elemento de xs aparece tan
  solo una vez. Por ejemplo, 
     distintos [1,4,3]
     ¬ distintos [1,4,1]

  Nota: La función "distintos" es equivalente a la predefinida "distinct".
  --------------------------------------------------------------------- 
*}


primrec distintos :: "'a list ⇒ bool" where
  "distintos [] = True"
| "distintos (x#xs) = (if veces x xs > 0 then False else distintos xs)"



text {*
Nota: para que no muestre error la función de evaluación
    hay que indicarle el tipo de los elementos de la lista.
    Por ejemplo:
           value "distintos [1::nat,4,1]"
*}





text {* 
  --------------------------------------------------------------------- 
  Ejercicio 10. Demostrar que el valor de "borraDups" verifica "distintos". 
  --------------------------------------------------------------------- 
*}


lemma "(distintos xs) ⟶ ((length xs) = (length (borraDups xs)))"
by (induct xs) auto

text{*
Si xs verifica el predicado distintos, entonces el tamaño de xs debe de ser el mismo
antes y despues de borrar los duplcados.
*}
 

end