Acciones

Diferencia entre revisiones de «Relación 2»

De Razonamiento automático (2016-17)

m (Texto reemplazado: «isar» por «isabelle»)
 
(No se muestran 70 ediciones intermedias de 22 usuarios)
Línea 1: Línea 1:
<source lang="isar">
+
<source lang="isabelle">
 
chapter {* R2: Razonamiento sobre programas en Isabelle/HOL *}
 
chapter {* R2: Razonamiento sobre programas en Isabelle/HOL *}
  
Línea 15: Línea 15:
 
     sumaImpares 5  =  25
 
     sumaImpares 5  =  25
 
   ------------------------------------------------------------------ *}
 
   ------------------------------------------------------------------ *}
 +
 +
(* fracorjim1 *)
 +
fun sumaImpares0 :: "nat ⇒ nat" where
 +
  "sumaImpares0 0 = 0"
 +
| "sumaImpares0 n = (n mod 2)*n + sumaImpares(n-1)"
 +
 +
value "sumaImpares0 5 = 25"
 +
 +
(* Comentario: Debe de definirse usando como patrones los dos
 +
  constructores de nat: 0 y Suc *)
  
 
(* ivamenjim wilmorort*)
 
(* ivamenjim wilmorort*)
 
 
fun sumaImpares :: "nat ⇒ nat" where
 
fun sumaImpares :: "nat ⇒ nat" where
 
   "sumaImpares 0 = 0"
 
   "sumaImpares 0 = 0"
 
| "sumaImpares n = 2*(n-1) + 1 + sumaImpares (n-1)"
 
| "sumaImpares n = 2*(n-1) + 1 + sumaImpares (n-1)"
  
(*wilmorort*)
+
value "sumaImpares 5 = 25"
 +
 
 +
(* wilmorort *)
  
 
(*Notar: Por la propiedad de Gauss se puede deducir que:
 
(*Notar: Por la propiedad de Gauss se puede deducir que:
Línea 28: Línea 39:
 
         n y n-1 números consecutivos*)   
 
         n y n-1 números consecutivos*)   
 
fun suma :: "nat ⇒ nat" where
 
fun suma :: "nat ⇒ nat" where
    "suma 0 = 0"|
+
  "suma 0 = 0"
    "suma n = n + suma(n-1)"
+
| "suma n = n + suma(n-1)"
  
 
fun sumaImpares1 :: "nat ⇒ nat" where
 
fun sumaImpares1 :: "nat ⇒ nat" where
  "sumaImpares1 0 = 0" |
+
  "sumaImpares1 0 = 0"  
  "sumaImpares1 n = suma(n) + suma(n-1)"
+
| "sumaImpares1 n = suma(n) + suma(n-1)"
  
value "sumaImpares 5 = 25"
+
value "sumaImpares1 5 = 25"
  
(* fraortmoy *)
+
(* Comentario: La definición sumaImpares1 no es recursiva y, por tanto,
 +
  no es apropiada para demostraciones por inducción.
 +
 
 +
  Comentario: La definición sumaImpares1 no es recursiva pero la
 +
  demostración, está realizada por inducción, por lo tanto no se puede
 +
  concluir que: "Si una def. no es recuriva no se puede demostrar por
 +
  inducción"
 +
 
 +
  Comentario: Las definiciones no recursivas no generan esquemas de
 +
  inducción.
 +
*)  
  
 +
(* fraortmoy antsancab1 *)
 
fun sumaImpares2 :: "nat ⇒ nat" where
 
fun sumaImpares2 :: "nat ⇒ nat" where
 
   "sumaImpares2 0 = 0"
 
   "sumaImpares2 0 = 0"
| "sumaImpares2 (Suc(n)) = ((Suc(n)*2)-1)+sumaImpares2 n"
+
| "sumaImpares2 (Suc(n)) = ((Suc(n)*2)-1) + sumaImpares2 n"
  
 
value "sumaImpares2 5 = 25"
 
value "sumaImpares2 5 = 25"
  
(* anaprarod *)
+
(* anaprarod danrodcha crigomgom migtermor pabrodmac juacabsou *)
 
 
 
fun sumaImpares3 :: "nat ⇒ nat" where
 
fun sumaImpares3 :: "nat ⇒ nat" where
 
   "sumaImpares3 0 = 0"
 
   "sumaImpares3 0 = 0"
Línea 52: Línea 73:
  
 
value "sumaImpares3 5 = 25"
 
value "sumaImpares3 5 = 25"
 +
 +
(* manmorjim1 *)
 +
fun sumaImpares4 :: "nat ⇒ nat" where
 +
  "sumaImpares4 0 = 0"
 +
| "sumaImpares4 (Suc n) = (Suc (2 * n)) + (sumaImpares4 n)"
 +
 +
value "sumaImpares4 5 = 25"
 +
 +
(* pablucoto serrodcal marcarmor13 rubgonmar marpoldia1 jeamacpov*)
 +
fun sumaImpares5 :: "nat ⇒ nat" where
 +
  "sumaImpares5 0 = 0"
 +
| "sumaImpares5 n = (2*n-1) + sumaImpares5 (n-1) "
 +
 +
value "sumaImpares5 5 = 25"
 +
 +
(* ferrenseg paupeddeg josgarsan dancorgar *)
 +
 +
fun sumaImpares6 :: "nat ⇒ nat" where
 +
  "sumaImpares6 0 = 0"
 +
| "sumaImpares6 (Suc n) = (2 * (Suc n) - 1) + sumaImpares6 n"
 +
 +
value "sumaImpares6 5 = 25"
  
 
text {* ---------------------------------------------------------------  
 
text {* ---------------------------------------------------------------  
Línea 58: Línea 101:
 
   ------------------------------------------------------------------- *}
 
   ------------------------------------------------------------------- *}
  
(* ivamenjim wilmorort*)
+
(* ivamenjim wilmorort anaprarod crigomgom manmorjim1 pablucoto
 
+
  serrodcal marcarmor13 rubgonmar pabrodmac marpoldia1 josgarsan
 +
  jeamacpov dancorgar antsancab1 fracorjim1 juacabsou *)
 
lemma "sumaImpares n = n*n"
 
lemma "sumaImpares n = n*n"
 
apply (induct n)
 
apply (induct n)
Línea 65: Línea 109:
 
done
 
done
  
(*wilmorort*)
+
(* wilmorort *)
(*Demostración estructurada*)
+
(* Demostración estructurada *)
  
 
lemma aux1 : "suma(Suc n) + suma(n) = (n+1) + suma(n) + n + suma(n-1)"
 
lemma aux1 : "suma(Suc n) + suma(n) = (n+1) + suma(n) + n + suma(n-1)"
Línea 94: Línea 138:
  
 
(* fraortmoy *)
 
(* fraortmoy *)
(* la Demostración para la función sumaImpares2 es la misma que la de sumaImpares*)
+
(* La demostración para la función sumaImpares2 es la misma que la de
 +
  sumaImpares*)  
  
 
lemma "sumaImpares2 n = n*n"
 
lemma "sumaImpares2 n = n*n"
Línea 100: Línea 145:
 
apply auto
 
apply auto
 
done
 
done
 +
 +
(* danrodcha migtermor paupeddeg *)
 +
lemma "sumaImpares n = n*n"
 +
by (induct n) auto
 +
 +
(* danrodcha *)
 +
lemma "sumaImpares n = n*n" (is "?P n")
 +
proof (induct n)
 +
  show "?P 0" by simp
 +
next
 +
  fix n assume "?P n"
 +
  thus "?P (Suc n)" by simp
 +
qed
 +
 +
(* ferrenseg *)
 +
lemma "sumaImpares3 n = n*n"
 +
by (induct n) simp_all
  
 
text {* ---------------------------------------------------------------  
 
text {* ---------------------------------------------------------------  
Línea 110: Línea 172:
 
   ------------------------------------------------------------------ *}
 
   ------------------------------------------------------------------ *}
  
(* wilmorort ivamenjim *)
+
(* wilmorort ivamenjim pablucoto serrodcal ferrenseg rubgonmar
 
+
  pabrodmac *)
 
fun sumaPotenciasDeDosMasUno :: "nat ⇒ nat" where
 
fun sumaPotenciasDeDosMasUno :: "nat ⇒ nat" where
   "sumaPotenciasDeDosMasUno 0 = 2"|
+
   "sumaPotenciasDeDosMasUno 0 = 2"
  "sumaPotenciasDeDosMasUno n = 2^(n) + sumaPotenciasDeDosMasUno (n-1) "
+
| "sumaPotenciasDeDosMasUno n = 2^n + sumaPotenciasDeDosMasUno (n-1)"
  
 
value "sumaPotenciasDeDosMasUno 3 = 16"
 
value "sumaPotenciasDeDosMasUno 3 = 16"
  
 
+
(* fraortmoy anaprarod danrodcha crigomgom migtermor manmorjim1
(* fraortmoy *)
+
  fracorjim1 paupeddeg josgarsan dancorgar antsancab1 juacabsou *)  
 
fun sumaPotenciasDeDosMasUno2 :: "nat ⇒ nat" where
 
fun sumaPotenciasDeDosMasUno2 :: "nat ⇒ nat" where
 
   "sumaPotenciasDeDosMasUno2 0 = 2"
 
   "sumaPotenciasDeDosMasUno2 0 = 2"
| "sumaPotenciasDeDosMasUno2 (Suc(n)) = (2^(Suc(n)))+sumaPotenciasDeDosMasUno2 n"
+
| "sumaPotenciasDeDosMasUno2 (Suc(n)) =  
 +
    (2^(Suc n)) + sumaPotenciasDeDosMasUno2 n"
  
 
value "sumaPotenciasDeDosMasUno2 3 = 16"
 
value "sumaPotenciasDeDosMasUno2 3 = 16"
  
 +
(* marcarmor13 jeamacpov *)
 +
fun sumaPotenciasDeDosMasUno3 :: "nat ⇒ nat" where
 +
  "sumaPotenciasDeDosMasUno3 0 = 2"
 +
| "sumaPotenciasDeDosMasUno3 n = 2*sumaPotenciasDeDosMasUno3 (n-1)"
 +
 +
value "sumaPotenciasDeDosMasUno3 3 = 16"
  
 
text {* ---------------------------------------------------------------  
 
text {* ---------------------------------------------------------------  
Línea 132: Línea 201:
 
   ------------------------------------------------------------------- *}
 
   ------------------------------------------------------------------- *}
  
(* wilmorort ivamenjim fraortmoy *)
+
(* wilmorort ivamenjim fraortmoy anaprarod crigomgom pablucoto serrodcal
 +
  manmorjim1 marcarmor13 rubgonmar pabrodmac josgarsan jeamacpov
 +
  dancorgar antsancab1 juacabsou *)
 
(* esta demostración funciona con sumaPotenciasDeDosMasUno2 *)
 
(* esta demostración funciona con sumaPotenciasDeDosMasUno2 *)
  
Línea 139: Línea 210:
 
apply auto
 
apply auto
 
done
 
done
 +
 +
(* danrodcha migtermor ferrenseg fracorjim1 paupeddeg *)
 +
lemma "sumaPotenciasDeDosMasUno n = 2^(n+1)"
 +
by (induct n) auto
 +
 +
(* danrodcha *)
 +
lemma "sumaPotenciasDeDosMasUno n = 2^(n+1)" (is "?P n")
 +
proof (induct n)
 +
  show "?P 0" by simp
 +
next
 +
  fix n assume "?P n"
 +
  thus "?P (Suc n)"by simp
 +
qed
  
 
text {* ---------------------------------------------------------------  
 
text {* ---------------------------------------------------------------  
Línea 147: Línea 231:
 
     copia 3 x = [x,x,x]
 
     copia 3 x = [x,x,x]
 
   ------------------------------------------------------------------ *}
 
   ------------------------------------------------------------------ *}
 
(* ivamenjim wilmorort*)
 
  
 +
(* ivamenjim wilmorort pablucoto rubgonmar marcarmor13 jeamacpov *)
 
fun copia :: "nat ⇒ 'a ⇒ 'a list" where
 
fun copia :: "nat ⇒ 'a ⇒ 'a list" where
 
   "copia 0 x = [] "  
 
   "copia 0 x = [] "  
 
| "copia n x = x # (copia (n-1) x)"
 
| "copia n x = x # (copia (n-1) x)"
  
(* wilmorort*)
+
(* wilmorort anaprarod *)
 +
fun copia1 :: "nat ⇒ 'a ⇒ 'a list" where
 +
  "copia1 0 x = []"
 +
| "copia1 (Suc n) x = [x] @ (copia1 n x) "
 +
 
 +
(* Comentario: La dedinición copia1 se puede simplificar eliminando @ *)
  
fun copia1 :: "nat ⇒ 'a ⇒ 'a list" where
+
(* danrodcha crigomgom migtermor manmorjim1 fracorjim1 pabrodmac
   "copia1 0 x = []" |
+
  paupeddeg josgarsan dancorgar antsancab1 juacabsou *)
  "copia1 (Suc n) x = [x] @ (copia1 n x) "
+
fun copia2 :: "nat ⇒ 'a ⇒ 'a list" where
 +
   "copia2 0 x = []"
 +
| "copia2 (Suc n) x = x # copia2 n x"
  
 +
(* serrodcal ferrenseg *)
 +
fun copia3 :: "nat ⇒ 'a ⇒ 'a list" where
 +
  "copia3 0 x = []"
 +
| "copia3 n x = [x] @ copia3 (n-1) x"
  
 
value "copia 3 x = [x,x,x]"
 
value "copia 3 x = [x,x,x]"
  
 +
(* Comentario: La definición copia3 se puede simplificar eliminando @ *)
  
 
text {* ---------------------------------------------------------------  
 
text {* ---------------------------------------------------------------  
Línea 174: Línea 269:
 
   ----------------------------------------------------------------- *}
 
   ----------------------------------------------------------------- *}
  
(*wilmorort*)
+
(* wilmorort *)
 +
fun todos :: "('a ⇒ bool) ⇒ 'a list ⇒ bool" where
 +
  "todos p []    = True"
 +
| "todos p (x#xs) = (p x = True ∧ todos p xs) "
  
fun todos :: "('a ⇒ bool) ⇒ 'a list ⇒ bool" where
+
(* Comentario: La definición todos se puede simplificar eliminando True
  "todos p [] = True"|
+
*)  
  "todos p (x#xs) = (p x = True ∧ todos p xs) "
 
  
 
value "todos (λx. x>(1::nat)) [2,6,4] = True"
 
value "todos (λx. x>(1::nat)) [2,6,4] = True"
 
value "todos (λx. x>(2::nat)) [2,6,4] = False"
 
value "todos (λx. x>(2::nat)) [2,6,4] = False"
  
 
+
(* fraortmoy anaprarod danrodcha crigomgom migtermor ivamenjim serrodcal
(* fraortmoy *)
+
  pablucoto ferrenseg rubgonmar pabrodmac paupeddeg marcarmor13
 
+
  jeamacpov dancorgar josgarsan antsancab1 fracorjim1 juacabsou *)  
 
fun todos1 :: "('a ⇒ bool) ⇒ 'a list ⇒ bool" where
 
fun todos1 :: "('a ⇒ bool) ⇒ 'a list ⇒ bool" where
   "todos1 p [] = True"
+
   "todos1 p []     = True"
 
| "todos1 p (x#xs) = (p x ∧ todos1 p xs )"
 
| "todos1 p (x#xs) = (p x ∧ todos1 p xs )"
  
Línea 193: Línea 290:
 
value "todos1 (λx. x>(2::nat)) [2,6,4] = False"
 
value "todos1 (λx. x>(2::nat)) [2,6,4] = False"
  
 +
(* manmorjim1 *)
 +
fun todos2 :: "('a ⇒ bool) ⇒ 'a list ⇒ bool" where
 +
  "todos2 p xs = ((filter p xs) = xs)"
 +
 +
value "todos2 (λx. x>(1::nat)) [2,6,4] = True"
 +
value "todos2 (λx. x>(2::nat)) [2,6,4] = False"
  
 
text {* ---------------------------------------------------------------  
 
text {* ---------------------------------------------------------------  
Línea 198: Línea 301:
 
   iguales a x.  
 
   iguales a x.  
 
   ------------------------------------------------------------------- *}
 
   ------------------------------------------------------------------- *}
(*wilmorort fraortmoy *)
 
  
 +
(* wilmorort fraortmoy anaprarod crigomgom ivamenjim serrodcal
 +
  manmorjim1 pablucoto rubgonmar pabrodmac marcarmor13 dancorgar
 +
  josgarsan antsancab1 juacabsou *) 
 
lemma "todos (λy. y=x) (copia n x)"
 
lemma "todos (λy. y=x) (copia n x)"
 
apply (induct n)
 
apply (induct n)
 
apply auto
 
apply auto
 
done
 
done
 +
 +
(* danrodcha ferrenseg paupeddeg jeamacpov *)
 +
lemma "todos (λy. y=x) (copia n x)"
 +
by (induct n) auto
 +
 +
(* danrodcha *)
 +
lemma "todos (λy. y=x) (copia n x)" (is "?P n")
 +
proof (induct n)
 +
  show "?P 0" by simp
 +
next
 +
  fix n assume "?P n"
 +
  thus "?P (Suc n)" by simp
 +
qed
 +
 +
(* fracorjim1 *)
 +
lemma "todos (λy. y = x)(copia n x) = True"
 +
apply (induct n)
 +
apply auto
 +
done
  
 
text {* ---------------------------------------------------------------  
 
text {* ---------------------------------------------------------------  
Línea 213: Línea 337:
 
   ------------------------------------------------------------------ *}
 
   ------------------------------------------------------------------ *}
  
(*wilmorort fraortmoy *)
+
(* wilmorort fraortmoy anaprarod crigomgom migtermor ivamenjim serrodcal
 
+
  manmorjim1 pablucoto ferrenseg rubgonmar pabrodmac paupeddeg
 +
  marcarmor13 jeamacpov dancorgar josgarsan antsancab1 fracorjim1 juacabsou *)
 
fun amplia :: "'a list ⇒ 'a ⇒ 'a list" where
 
fun amplia :: "'a list ⇒ 'a ⇒ 'a list" where
  "amplia [] y =[y] "|
+
  "amplia [] y     = [y] "
  "amplia (x#xs) y = x # amplia(xs) y"
+
| "amplia (x#xs) y = x # amplia xs y"
  
 
value "amplia [d,a] t = [d,a,t]"
 
value "amplia [d,a] t = [d,a,t]"
Línea 226: Línea 351:
 
   ------------------------------------------------------------------- *}
 
   ------------------------------------------------------------------- *}
  
(*wilmorort fraortmoy *)
+
(* wilmorort fraortmoy anaprarod crigomgom ivamenjim serrodcal
 
+
  manmorjim1 pablucoto rubgonmar pabrodmac marcarmor13 jeamacpov
 +
  dancorgar josgarsan antsancab1 fracorjim1 juacabsou *)  
 
lemma "amplia xs y = xs @ [y]"
 
lemma "amplia xs y = xs @ [y]"
 
apply (induct xs)
 
apply (induct xs)
 
apply auto
 
apply auto
 
done
 
done
 +
 +
(* danrodcha migtermor ferrenseg paupeddeg *)
 +
lemma "amplia xs y = xs @ [y]"
 +
by (induct xs) auto
 +
 +
(* danrodcha *)
 +
lemma "amplia xs y = xs @ [y]" (is "?P xs")
 +
proof (induct xs)
 +
  show "?P []" by simp
 +
next
 +
  fix a xs assume "?P xs"
 +
  thus "?P (a#xs)" by simp
 +
qed
 +
 
end
 
end
 
</source>
 
</source>

Revisión actual del 13:11 16 jul 2018

chapter {* R2: Razonamiento sobre programas en Isabelle/HOL *}

theory R2_Razonamiento_automatico_sobre_programas
imports Main 
begin

declare [[names_short]]

text {* --------------------------------------------------------------- 
  Ejercicio 1.1. Definir la función
     sumaImpares :: nat ⇒ nat
  tal que (sumaImpares n) es la suma de los n primeros números
  impares. Por ejemplo,
     sumaImpares 5  =  25
  ------------------------------------------------------------------ *}

(* fracorjim1 *)
fun sumaImpares0 :: "nat ⇒ nat" where
  "sumaImpares0 0 = 0"
| "sumaImpares0 n = (n mod 2)*n + sumaImpares(n-1)"

value "sumaImpares0 5 = 25"

(* Comentario: Debe de definirse usando como patrones los dos 
   constructores de nat: 0 y Suc *)

(* ivamenjim wilmorort*)
fun sumaImpares :: "nat ⇒ nat" where
  "sumaImpares 0 = 0"
| "sumaImpares n = 2*(n-1) + 1 + sumaImpares (n-1)"

value "sumaImpares 5 = 25"

(* wilmorort *)

(*Notar: Por la propiedad de Gauss se puede deducir que:
         la suma de los n números impares es igual a la suma de los 
         n y n-1 números consecutivos*)   
fun suma :: "nat ⇒ nat" where
  "suma 0 = 0"
| "suma n = n + suma(n-1)"

fun sumaImpares1 :: "nat ⇒ nat" where
  "sumaImpares1 0 = 0" 
| "sumaImpares1 n = suma(n) + suma(n-1)"

value "sumaImpares1 5 = 25"

(* Comentario: La definición sumaImpares1 no es recursiva y, por tanto,
   no es apropiada para demostraciones por inducción. 
   
   Comentario: La definición sumaImpares1 no es recursiva pero la
   demostración, está realizada por inducción, por lo tanto no se puede
   concluir que: "Si una def. no es recuriva no se puede demostrar por
   inducción" 
   
   Comentario: Las definiciones no recursivas no generan esquemas de
   inducción.
 *) 

(* fraortmoy antsancab1 *)
fun sumaImpares2 :: "nat ⇒ nat" where
  "sumaImpares2 0 = 0"
| "sumaImpares2 (Suc(n)) = ((Suc(n)*2)-1) + sumaImpares2 n"

value "sumaImpares2 5 = 25"

(* anaprarod danrodcha crigomgom migtermor pabrodmac juacabsou *)
fun sumaImpares3 :: "nat ⇒ nat" where
  "sumaImpares3 0 = 0"
 |"sumaImpares3 (Suc n) = (2*n +1) + (sumaImpares3 n)"

value "sumaImpares3 5 = 25"

(* manmorjim1 *)
fun sumaImpares4 :: "nat ⇒ nat" where
  "sumaImpares4 0 = 0"
| "sumaImpares4 (Suc n) = (Suc (2 * n)) + (sumaImpares4 n)"

value "sumaImpares4 5 = 25"

(* pablucoto serrodcal marcarmor13 rubgonmar marpoldia1 jeamacpov*)
fun sumaImpares5 :: "nat ⇒ nat" where
  "sumaImpares5 0 = 0"
| "sumaImpares5 n = (2*n-1) + sumaImpares5 (n-1) "

value "sumaImpares5 5 = 25"

(* ferrenseg paupeddeg josgarsan dancorgar *)

fun sumaImpares6 :: "nat ⇒ nat" where
  "sumaImpares6 0 = 0"
| "sumaImpares6 (Suc n) = (2 * (Suc n) - 1) + sumaImpares6 n"
 
value "sumaImpares6 5 = 25"

text {* --------------------------------------------------------------- 
  Ejercicio 1.2. Demostrar que 
     sumaImpares n = n*n
  ------------------------------------------------------------------- *}

(* ivamenjim wilmorort anaprarod crigomgom manmorjim1 pablucoto
   serrodcal marcarmor13 rubgonmar pabrodmac marpoldia1 josgarsan
   jeamacpov dancorgar antsancab1 fracorjim1 juacabsou *)  
lemma "sumaImpares n = n*n"
apply (induct n)
apply auto
done

(* wilmorort *)
(* Demostración estructurada *)

lemma aux1 : "suma(Suc n) + suma(n) = (n+1) + suma(n) + n + suma(n-1)"
apply (induct n)
apply auto
done

lemma aux2: "(n+1) + suma(n) + n + suma(n-1) = (n+1) + n + sumaImpares1 n "
apply (induct n)
apply auto
done

lemma "sumaImpares1 n = n*n"
proof (induct n)
show "sumaImpares1 0 = 0*0" by simp
next 
 fix n
 assume HI:"sumaImpares1 n = n*n"
 have "sumaImpares1 (Suc n) = suma(Suc n) + suma(n)" by simp
 have "suma(Suc n) + suma(n) = (n+1) + suma(n) + n + suma(n-1)"  using
 "aux1" by simp
 also have "... = (n+1) + n + sumaImpares1 n " using "aux2" by simp
 also have "... = 2*n +1 + n*n" using HI by simp
 also have "... = (n+1)*(n+1)" by simp
 finally show "sumaImpares1 (Suc n) = Suc n * Suc n" by simp
 qed

(* fraortmoy *)
(* La demostración para la función sumaImpares2 es la misma que la de
   sumaImpares*) 

lemma "sumaImpares2 n = n*n"
apply (induct n)
apply auto
done

(* danrodcha migtermor paupeddeg *)
lemma "sumaImpares n = n*n"
by (induct n) auto

(* danrodcha *)
lemma "sumaImpares n = n*n" (is "?P n")
proof (induct n)
  show "?P 0" by simp
next
  fix n assume "?P n"
  thus "?P (Suc n)" by simp
qed

(* ferrenseg *)
lemma "sumaImpares3 n = n*n"
by (induct n) simp_all

text {* --------------------------------------------------------------- 
  Ejercicio 2.1. Definir la función
     sumaPotenciasDeDosMasUno :: nat ⇒ nat
  tal que 
     (sumaPotenciasDeDosMasUno n) = 1 + 2^0 + 2^1 + 2^2 + ... + 2^n. 
  Por ejemplo, 
     sumaPotenciasDeDosMasUno 3  =  16
  ------------------------------------------------------------------ *}

(* wilmorort ivamenjim pablucoto serrodcal ferrenseg rubgonmar 
   pabrodmac *)
fun sumaPotenciasDeDosMasUno :: "nat ⇒ nat" where
  "sumaPotenciasDeDosMasUno 0 = 2"
| "sumaPotenciasDeDosMasUno n = 2^n + sumaPotenciasDeDosMasUno (n-1)"

value "sumaPotenciasDeDosMasUno 3 = 16"

(* fraortmoy anaprarod danrodcha crigomgom migtermor manmorjim1
   fracorjim1 paupeddeg josgarsan dancorgar antsancab1 juacabsou *) 
fun sumaPotenciasDeDosMasUno2 :: "nat ⇒ nat" where
  "sumaPotenciasDeDosMasUno2 0 = 2"
| "sumaPotenciasDeDosMasUno2 (Suc(n)) = 
    (2^(Suc n)) + sumaPotenciasDeDosMasUno2 n"

value "sumaPotenciasDeDosMasUno2 3 = 16"

(* marcarmor13 jeamacpov *)
fun sumaPotenciasDeDosMasUno3 :: "nat ⇒ nat" where
  "sumaPotenciasDeDosMasUno3 0 = 2"
| "sumaPotenciasDeDosMasUno3 n = 2*sumaPotenciasDeDosMasUno3 (n-1)"

value "sumaPotenciasDeDosMasUno3 3 = 16"

text {* --------------------------------------------------------------- 
  Ejercicio 2.2. Demostrar que 
     sumaPotenciasDeDosMasUno n = 2^(n+1)
  ------------------------------------------------------------------- *}

(* wilmorort ivamenjim fraortmoy anaprarod crigomgom pablucoto serrodcal
   manmorjim1 marcarmor13 rubgonmar pabrodmac josgarsan jeamacpov
   dancorgar antsancab1 juacabsou *)  
(* esta demostración funciona con sumaPotenciasDeDosMasUno2 *)

lemma "sumaPotenciasDeDosMasUno n = 2^(n+1)"
apply (induct n)
apply auto
done

(* danrodcha migtermor ferrenseg fracorjim1 paupeddeg *)
lemma "sumaPotenciasDeDosMasUno n = 2^(n+1)"
by (induct n) auto

(* danrodcha *)
lemma "sumaPotenciasDeDosMasUno n = 2^(n+1)" (is "?P n")
proof (induct n)
  show "?P 0" by simp
next
  fix n assume "?P n"
  thus "?P (Suc n)"by simp
qed

text {* --------------------------------------------------------------- 
  Ejercicio 3.1. Definir la función
     copia :: nat ⇒ 'a ⇒ 'a list
  tal que (copia n x) es la lista formado por n copias del elemento
  x. Por ejemplo, 
     copia 3 x = [x,x,x]
  ------------------------------------------------------------------ *}

(* ivamenjim wilmorort pablucoto rubgonmar marcarmor13 jeamacpov *)
fun copia :: "nat ⇒ 'a ⇒ 'a list" where
  "copia 0 x = [] " 
| "copia n x = x # (copia (n-1) x)"

(* wilmorort anaprarod *)
fun copia1 :: "nat ⇒ 'a ⇒ 'a list" where
  "copia1 0 x = []" 
| "copia1 (Suc n) x = [x] @ (copia1 n x) "

(* Comentario: La dedinición copia1 se puede simplificar eliminando @ *)

(* danrodcha crigomgom migtermor manmorjim1 fracorjim1 pabrodmac
   paupeddeg josgarsan dancorgar antsancab1 juacabsou *) 
fun copia2 :: "nat ⇒ 'a ⇒ 'a list" where
  "copia2 0 x = []"
| "copia2 (Suc n) x = x # copia2 n x"

(* serrodcal ferrenseg *)
fun copia3 :: "nat ⇒ 'a ⇒ 'a list" where
  "copia3 0 x = []" 
| "copia3 n x = [x] @ copia3 (n-1) x"

value "copia 3 x = [x,x,x]"

(* Comentario: La definición copia3 se puede simplificar eliminando @ *)

text {* --------------------------------------------------------------- 
  Ejercicio 3.2. Definir la función
     todos :: ('a ⇒ bool) ⇒ 'a list ⇒ bool
  tal que (todos p xs) se verifica si todos los elementos de xs cumplen
  la propiedad p. Por ejemplo,
     todos (λx. x>(1::nat)) [2,6,4] = True
     todos (λx. x>(2::nat)) [2,6,4] = False
  Nota: La conjunción se representa por ∧
  ----------------------------------------------------------------- *}

(* wilmorort *)
fun todos :: "('a ⇒ bool) ⇒ 'a list ⇒ bool" where
  "todos p []     = True"
| "todos p (x#xs) = (p x = True ∧ todos p xs) "

(* Comentario: La definición todos se puede simplificar eliminando True
*) 

value "todos (λx. x>(1::nat)) [2,6,4] = True"
value "todos (λx. x>(2::nat)) [2,6,4] = False"

(* fraortmoy anaprarod danrodcha crigomgom migtermor ivamenjim serrodcal
   pablucoto ferrenseg rubgonmar pabrodmac paupeddeg marcarmor13
   jeamacpov dancorgar josgarsan antsancab1 fracorjim1 juacabsou *) 
fun todos1 :: "('a ⇒ bool) ⇒ 'a list ⇒ bool" where
  "todos1 p []     = True"
| "todos1 p (x#xs) = (p x ∧ todos1 p xs )"

value "todos1 (λx. x>(1::nat)) [2,6,4] = True"
value "todos1 (λx. x>(2::nat)) [2,6,4] = False"

(* manmorjim1 *)
fun todos2 :: "('a ⇒ bool) ⇒ 'a list ⇒ bool" where
  "todos2 p xs = ((filter p xs) = xs)"

value "todos2 (λx. x>(1::nat)) [2,6,4] = True"
value "todos2 (λx. x>(2::nat)) [2,6,4] = False"

text {* --------------------------------------------------------------- 
  Ejercicio 3.3. Demostrar que todos los elementos de (copia n x) son
  iguales a x. 
  ------------------------------------------------------------------- *}

(* wilmorort fraortmoy anaprarod crigomgom ivamenjim serrodcal
   manmorjim1 pablucoto rubgonmar pabrodmac marcarmor13 dancorgar
   josgarsan antsancab1 juacabsou *)  
lemma "todos (λy. y=x) (copia n x)"
apply (induct n)
apply auto
done

(* danrodcha ferrenseg paupeddeg jeamacpov *)
lemma "todos (λy. y=x) (copia n x)"
by (induct n) auto

(* danrodcha *)
lemma "todos (λy. y=x) (copia n x)" (is "?P n")
proof (induct n)
  show "?P 0" by simp
next
  fix n assume "?P n"
  thus "?P (Suc n)" by simp
qed

(* fracorjim1 *)
lemma "todos (λy. y = x)(copia n x) = True"
apply (induct n)
apply auto
done 

text {* --------------------------------------------------------------- 
  Ejercicio 4.1. Definir, recursivamente y sin usar (@), la función
     amplia :: 'a list ⇒ 'a ⇒ 'a list
  tal que (amplia xs y) es la lista obtenida añadiendo el elemento y al
  final de la lista xs. Por ejemplo,
     amplia [d,a] t = [d,a,t]
  ------------------------------------------------------------------ *}

(* wilmorort fraortmoy anaprarod crigomgom migtermor ivamenjim serrodcal
   manmorjim1 pablucoto ferrenseg rubgonmar pabrodmac paupeddeg
   marcarmor13 jeamacpov dancorgar josgarsan antsancab1 fracorjim1 juacabsou *)  
fun amplia :: "'a list ⇒ 'a ⇒ 'a list" where
   "amplia [] y     = [y] "
|  "amplia (x#xs) y = x # amplia xs y"

value "amplia [d,a] t = [d,a,t]"

text {* --------------------------------------------------------------- 
  Ejercicio 4.2. Demostrar que 
     amplia xs y = xs @ [y]
  ------------------------------------------------------------------- *}

(* wilmorort fraortmoy anaprarod crigomgom ivamenjim serrodcal
   manmorjim1 pablucoto rubgonmar pabrodmac marcarmor13 jeamacpov
   dancorgar josgarsan antsancab1 fracorjim1 juacabsou *) 
lemma "amplia xs y = xs @ [y]"
apply (induct xs)
apply auto
done

(* danrodcha migtermor ferrenseg paupeddeg *)
lemma "amplia xs y = xs @ [y]"
by (induct xs) auto

(* danrodcha *)
lemma "amplia xs y = xs @ [y]" (is "?P xs")
proof (induct xs)
  show "?P []" by simp
next
  fix a xs assume "?P xs"
  thus "?P (a#xs)" by simp
qed

end