Diferencia entre revisiones de «Relación 7»
De Razonamiento automático (2016-17)
| m (Texto reemplazado: «isar» por «isabelle») | |||
| (No se muestran 64 ediciones intermedias de 18 usuarios) | |||
| Línea 1: | Línea 1: | ||
| − | <source lang=" | + | <source lang="isabelle"> | 
| chapter {* R7: Árboles binarios completos *} | chapter {* R7: Árboles binarios completos *} | ||
| Línea 39: | Línea 39: | ||
| *} | *} | ||
| − | (* fraortmoy *) | + | (* fraortmoy marcarmor13 josgarsan fracorjim1 jeamacpov *) | 
| fun hojas :: "arbol => nat" where | fun hojas :: "arbol => nat" where | ||
| − |    "hojas H = Suc 0" | + |    "hojas H       = Suc 0" | 
| | "hojas (N a b) = hojas a + hojas b" | | "hojas (N a b) = hojas a + hojas b" | ||
| value "hojas (N (N H H) (N H H)) = 4" | value "hojas (N (N H H) (N H H)) = 4" | ||
| − | (* marpoldia1 anaprarod paupeddeg migtermor wilmorort pablucoto ivamenjim serrodcal *) | + | (* marpoldia1 anaprarod paupeddeg migtermor wilmorort pablucoto   | 
| + |    ivamenjim serrodcal crigomgom rubgonmar  danrodcha ferrenseg | ||
| + |    manmorjim1 juacabsou lucnovdos dancorgar bowma antsancab1 pabrodmac *) | ||
| (* Es muy parecida a la definición anterior *) | (* Es muy parecida a la definición anterior *) | ||
| fun hojas2 :: "arbol => nat" where | fun hojas2 :: "arbol => nat" where | ||
| − |    "hojas2 H = 1" | | + |    "hojas2 H       = 1"   | 
| − | + | | "hojas2 (N i d) = hojas2 i + hojas2 d" | |
| value "hojas2 (N (N H H) (N H H)) = 4" | value "hojas2 (N (N H H) (N H H)) = 4" | ||
| − | |||
| (* anaprarod *) | (* anaprarod *) | ||
| Línea 69: | Línea 70: | ||
| *} | *} | ||
| − | (* fraortmoy marpoldia1 anaprarod migtermor wilmorort*) | + | (* fraortmoy marpoldia1 anaprarod migtermor wilmorort marcarmor13 | 
| + |    dancorgar antsancab1 jeamacpov pabrodmac *)   | ||
| fun profundidad :: "arbol => nat" where | fun profundidad :: "arbol => nat" where | ||
|    "profundidad H = 0" |    "profundidad H = 0" | ||
| Línea 78: | Línea 80: | ||
| value "profundidad (N (N H H) (N H H)) = 2" | value "profundidad (N (N H H) (N H H)) = 2" | ||
| − | (* anaprarod wilmorort pablucoto ivamenjim serrodcal *) | + | (* anaprarod wilmorort pablucoto ivamenjim serrodcal crigomgom rubgonmar  | 
| + |    danrodcha ferrenseg josgarsan juacabsou lucnovdos bowma pabrodmac *) | ||
| fun profundidad2 :: "arbol => nat" where | fun profundidad2 :: "arbol => nat" where | ||
| − |    "profundidad2 H = 0" | + |    "profundidad2 H       = 0" | 
| − | + | | "profundidad2 (N i d) = 1 + (max (profundidad2 i) (profundidad2 d))" | |
| value "profundidad2 (N (N H H) (N H H)) = 2" | value "profundidad2 (N (N H H) (N H H)) = 2" | ||
| Línea 89: | Línea 92: | ||
| lemma "profundidad a= profundidad2 a" | lemma "profundidad a= profundidad2 a" | ||
| by (induct a) auto | by (induct a) auto | ||
| − | |||
| (* paupeddeg *) | (* paupeddeg *) | ||
| fun maximo :: "nat ×  nat => nat" where | fun maximo :: "nat ×  nat => nat" where | ||
| − |    "maximo (a,b) = (if a > b   | + |    "maximo (a,b) = (if a > b then a else b)" | 
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| + | fun profundidad3 :: "arbol => nat" where | ||
| + |   "profundidad3 H       = 0" | ||
| + | | "profundidad3 (N i d) = 1 + maximo (profundidad3 i, profundidad3 d)" | ||
| (* ivamenjim: llamando a la función anterior profundidad3 *) | (* ivamenjim: llamando a la función anterior profundidad3 *) | ||
| − | |||
| lemma "profundidad a = profundidad3 a" | lemma "profundidad a = profundidad3 a" | ||
| by (induct a) auto | by (induct a) auto | ||
| − | + | (* ivamenjim manmorjim1 fracorjim1 *) | |
| − | (* ivamenjim *) | ||
| fun profundidad4 :: "arbol => nat" where | fun profundidad4 :: "arbol => nat" where | ||
| − |    "profundidad4 H = 0" | + |    "profundidad4 H       = 0" | 
| − | | "profundidad4 (N i d) = Suc (max (profundidad4 i)(profundidad4 d))" | + | | "profundidad4 (N i d) = Suc (max (profundidad4 i) (profundidad4 d))" | 
| lemma "profundidad a = profundidad4 a" | lemma "profundidad a = profundidad4 a" | ||
| Línea 124: | Línea 122: | ||
|    ---------------------------------------------------------------------   |    ---------------------------------------------------------------------   | ||
| *} | *} | ||
| − | (* fraortmoy marpoldia1 anaprarod paupeddeg migtermor  wilmorort serrodcal *) | + | |
| + | (* fraortmoy marpoldia1 anaprarod paupeddeg migtermor  wilmorort   | ||
| + |    serrodcal crigomgom rubgonmar danrodcha ferrenseg josgarsan | ||
| + |    manmorjim1 juacabsou fracorjim1 lucnovdos dancorgar bowma antsancab1 pabrodmac *) | ||
| fun abc :: "nat ⇒ arbol" where | fun abc :: "nat ⇒ arbol" where | ||
| − |    "abc 0 = H" | + |    "abc 0       = H" | 
| | "abc (Suc n) = (N (abc n) (abc n))" | | "abc (Suc n) = (N (abc n) (abc n))" | ||
| value "abc 3 = N (N (N H H) (N H H)) (N (N H H) (N H H))" | value "abc 3 = N (N (N H H) (N H H)) (N (N H H) (N H H))" | ||
| − | (* ivamenjim pablucoto*) | + | (* ivamenjim pablucoto marcarmor13 jeamacpov *) | 
| fun abc2 :: "nat ⇒ arbol" where | fun abc2 :: "nat ⇒ arbol" where | ||
|    "abc2 0 = H" |    "abc2 0 = H" | ||
| Línea 156: | Línea 157: | ||
| *} | *} | ||
| − | (* fraortmoy anaprarod migtermor serrodcal *) | + | (* fraortmoy anaprarod migtermor serrodcal crigomgom rubgonmar  | 
| + |    danrodcha ferrenseg juacabsou josgarsan fracorjim1 lucnovdos bowma *) | ||
| fun es_abc :: "(arbol => 'a) => arbol => bool" where | fun es_abc :: "(arbol => 'a) => arbol => bool" where | ||
| − |    "es_abc _ H = True" | + |    "es_abc _ H       = True" | 
| | "es_abc f (N a b) = (es_abc f a ∧ es_abc f b ∧ (f a = f b))" | | "es_abc f (N a b) = (es_abc f a ∧ es_abc f b ∧ (f a = f b))" | ||
| − | + | (* marpoldia1 paupeddeg ivamenjim pablucoto marcarmor13 manmorjim1 | |
| − | (* marpoldia1 paupeddeg ivamenjim pablucoto*) | + |    dancorgar antsancab1 jeamacpov pabrodmac *)   | 
| fun es_abc2 :: "(arbol => 'a) => arbol => bool" where | fun es_abc2 :: "(arbol => 'a) => arbol => bool" where | ||
| − |    "es_abc2 f H = True" | | + |    "es_abc2 f H       = True"   | 
| − | + | | "es_abc2 f (N i d) = ((f i = f d) ∧ (es_abc2 f i) ∧ (es_abc2 f d))" | |
| (* anaprarod *) | (* anaprarod *) | ||
| Línea 198: | Línea 200: | ||
| *} | *} | ||
| − | (* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal *) | + | (* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal | 
| − | + |    fracorjim1 josgarsan lucnovdos bowma antsancab1 jeamacpov *)   | |
| lemma abc_prof_num_hojas: | lemma abc_prof_num_hojas: | ||
|    assumes "es_abc profundidad a" |    assumes "es_abc profundidad a" | ||
| − |    shows "hojas a = 2^(profundidad a)" | + |    shows   "hojas a = 2^(profundidad a)" | 
| using assms | using assms | ||
| by (induct a) auto | by (induct a) auto | ||
| (* Otra forma de escribir lo mismo *) | (* Otra forma de escribir lo mismo *) | ||
| − | (* anaprarod *) | + | (* anaprarod crigomgom ivamenjim paupeddeg juacabsou *) | 
| lemma AUX7: "es_abc profundidad a ⟶ (hojas a = 2^(profundidad a))" | lemma AUX7: "es_abc profundidad a ⟶ (hojas a = 2^(profundidad a))" | ||
| by (induct a) simp_all | by (induct a) simp_all | ||
| − | (* fraortmoy marpoldia1 migtermor anaprarod wilmorort serrodcal *) | + | (* Otra forma de escribir lo mismo *) | 
| + | (* danrodcha *) | ||
| + | lemma aux1: "es_abc profundidad (a::arbol) ⟹ (hojas a = 2^ (profundidad a))" | ||
| + | by (induct a) simp_all | ||
| + | |||
| + | (* fraortmoy marpoldia1 migtermor anaprarod wilmorort serrodcal | ||
| + |    crigomgom rubgonmar ivamenjim danrodcha marcarmor13 paupeddeg | ||
| + |    juacabsou bowma antsancab1 *)   | ||
| (* También funciona con AUX7 *) | (* También funciona con AUX7 *) | ||
| − | |||
| lemma lej7: "es_abc profundidad a = es_abc hojas a" | lemma lej7: "es_abc profundidad a = es_abc hojas a" | ||
| by (induct a) (auto simp add: abc_prof_num_hojas) | by (induct a) (auto simp add: abc_prof_num_hojas) | ||
| + | (* danrodcha *) | ||
| + | lemma 7: "es_abc profundidad a = es_abc hojas a" | ||
| + | apply (induct a)  | ||
| + | apply simp | ||
| + | apply (auto simp add: aux1) | ||
| + | done | ||
| + | |||
| + | (* ferrenseg *) | ||
| + | lemma [simp]: "es_abc profundidad a ⟶ hojas a = 2 ^ (profundidad a)" | ||
| + | by (induct a) auto | ||
| + | (* Comentario: Uso de la declaración simp *) | ||
| + | |||
| + | theorem es_abc_profundidad_hojas:  | ||
| + |   "es_abc profundidad a = es_abc hojas a" | ||
| + | by (induct a) auto | ||
| + | |||
| + | (* Comentario: Dependencia de la declaración simp. *) | ||
| + | |||
| + | (* dancorgar *) | ||
| + | lemma rel_hojas_prof: "es_abc hojas a ∧ es_abc profundidad a | ||
| + |       ⟹ hojas a = 2 ^ profundidad a" | ||
| + | by (induct a) (auto) | ||
| + | |||
| + | theorem "es_abc hojas a = es_abc profundidad a" | ||
| + | by (induct a) (auto simp add: rel_hojas_prof) | ||
| + | |||
| + | (* pabrodmac *) | ||
| + | lemma lemaaux1:"es_abc hojas a⟶(hojas a = 2^(profundidad a))" | ||
| + | by (induct a) auto | ||
| + | |||
| + | lemma 1:"es_abc profundidad a = es_abc hojas a " | ||
| + | by (induct a) (auto simp add: lemaaux1) | ||
| text {*    | text {*    | ||
| Línea 226: | Línea 266: | ||
| *} | *} | ||
| − | (* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal *) | + | (* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal | 
| − | + |    marcarmor13 josgarsan lucnovdos bowma antsancab1 jeamacpov *)   | |
| lemma abc_hojas_num_nodos: | lemma abc_hojas_num_nodos: | ||
|    assumes "es_abc hojas a" |    assumes "es_abc hojas a" | ||
| − |    shows "Suc(size a) = hojas a" | + |    shows   "Suc (size a) = hojas a" | 
| using assms | using assms | ||
| by (induct a) auto | by (induct a) auto | ||
| + | (* Comentario sobre orientación de igualdades. *) | ||
| (* Otra forma de escribir lo mismo *) | (* Otra forma de escribir lo mismo *) | ||
| − | (* anaprarod *) | + | (* anaprarod crigomgom paupeddeg juacabsou rubgonmar *) | 
| lemma AUX8: "es_abc hojas a ⟶ (hojas a = (Suc (size a)))" | lemma AUX8: "es_abc hojas a ⟶ (hojas a = (Suc (size a)))" | ||
| by (induct a) auto | by (induct a) auto | ||
| − | + | (* fraortmoy marpoldia1 migtermor anaprarod wilmorort pablucoto | |
| − | (* fraortmoy marpoldia1 migtermor anaprarod wilmorort pablucoto serrodcal *) | + |    serrodcal antsancab1 *)   | 
| − | |||
| lemma lej8: "es_abc hojas a = es_abc size a" | lemma lej8: "es_abc hojas a = es_abc size a" | ||
| by (induct a) (auto simp add:abc_hojas_num_nodos [symmetric]) | by (induct a) (auto simp add:abc_hojas_num_nodos [symmetric]) | ||
| − | (* anaprarod *) | + | (* Comentario sobre orientación de igualdades. *) | 
| + | |||
| + | (* anaprarod crigomgom paupeddeg juacabsou rubgonmar *) | ||
| (* Usando AUX8 *) | (* Usando AUX8 *) | ||
| − | lemma L8: "es_abc hojas a= es_abc size a" | + | lemma L8: "es_abc hojas a = es_abc size a" | 
| by (induct a) (auto simp add: AUX8) | by (induct a) (auto simp add: AUX8) | ||
| + | |||
| + | (* ivamenjim *) | ||
| + | (* Teorema auxiliar *) | ||
| + | lemma auxEj8: "hojas a = size a + 1" | ||
| + | by (induct a) auto | ||
| + | |||
| + | (* ivamenjim *) | ||
| + | lemma lej8b: "es_abc hojas a = es_abc size a" | ||
| + | by (induct a) (auto simp add: auxEj8) | ||
| + | |||
| + | (* danrodcha *) | ||
| + | lemma aux3: "es_abc hojas a ⟹ (hojas a = 1 + size a)" | ||
| + | by (induct a) simp_all | ||
| + | |||
| + | (* danrodcha *) | ||
| + | lemma 8: "es_abc hojas a = es_abc size a" | ||
| + | apply (induct a)  | ||
| + | apply simp | ||
| + | apply (auto simp add: aux3) | ||
| + | done | ||
| + | |||
| + | (* ferrenseg *) | ||
| + | lemma [simp]: "hojas a = size a + 1" | ||
| + | by (induct a) auto | ||
| + | |||
| + | theorem es_abc_hojas_size: "es_abc hojas a = es_abc size a" | ||
| + | by (induct a) auto | ||
| + | |||
| + | (* fracorjim1 *) | ||
| + | lemma aux10 : "hojas (a::arbol) = Suc(size a)" | ||
| + | apply (induct a) | ||
| + | apply auto | ||
| + | done | ||
| + | |||
| + | lemma es_abc_hojas_size_10 : "es_abc hojas (a::arbol) = es_abc size a" | ||
| + | apply (induct a) | ||
| + | apply (auto simp add: aux10) | ||
| + | done | ||
| + | |||
| + | (* dancorgar *) | ||
| + | lemma rel_hojas_size: "es_abc hojas a ∧ es_abc size a | ||
| + |       ⟹ hojas a = (size a) + 1" | ||
| + | by (induct a) (auto) | ||
| + | |||
| + | theorem "es_abc hojas a = es_abc size a" | ||
| + | by (induct a) (auto simp add: rel_hojas_size) | ||
| + | |||
| + | |||
| + | (* pabrodmac *) | ||
| + | |||
| + | lemma lemaaux2:"es_abc size a⟶(hojas a  = Suc(size a)) " | ||
| + | by (induct a) auto | ||
| + | |||
| + | lemma 2:"es_abc hojas a = es_abc size a " | ||
| + | by (induct a) (auto simp add: lemaaux2) | ||
| Línea 259: | Línea 356: | ||
| *} | *} | ||
| − | (* fraortmoy marpoldia1 migtermor anaprarod  wilmorort pablucoto serrodcal *) | + | (* fraortmoy marpoldia1 migtermor anaprarod  wilmorort pablucoto   | 
| − | + |    serrodcal crigomgom rubgonmar danrodcha ivamenjim marcarmor13 | |
| + |    paupeddeg juacabsou josgarsan bowma lucnovdos antsancab1 jeamacpov *) | ||
| lemma lej9:  "es_abc profundidad a = es_abc size a" | lemma lej9:  "es_abc profundidad a = es_abc size a" | ||
| by (simp add: lej7 lej8) | by (simp add: lej7 lej8) | ||
| + | |||
| + | (* ferrenseg *) | ||
| + | corollary es_abc_size_profundidad: "es_abc size a = es_abc profundidad a" | ||
| + | by (simp add: es_abc_profundidad_hojas es_abc_hojas_size) | ||
| + | |||
| + | (* pabrodmac *) | ||
| + | |||
| + | lemma lemaaux3:"es_abc profundidad a⟶(Suc(size a)= 2^(profundidad a)) " | ||
| + | by (induct a) auto | ||
| + | |||
| + | lemma "es_abc profundidad a = es_abc size a " | ||
| + | by (simp add: 1 2 ) | ||
| text {*    | text {*    | ||
| Línea 270: | Línea 380: | ||
| *} | *} | ||
| − | (* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal *) | + | (* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal | 
| − | + |    crigomgom marcarmor13 paupeddeg juacabsou dancorgar lucnovdos jeamacpov pabrodmac  *) | |
| lemma lej10: "es_abc profundidad (abc n)" | lemma lej10: "es_abc profundidad (abc n)" | ||
| by (induct n) auto | by (induct n) auto | ||
| − | + | (* anaprarod rubgonmar danrodcha ferrenseg ivamenjim | |
| − | (* anaprarod *) | + |    paupeddeg juacabsou bowma antsancab1 *) | 
| (* con un demostrador más débil *) | (* con un demostrador más débil *) | ||
| + | (* y en general para cualquier medida *) | ||
| lemma L10:  "es_abc f (abc a)" | lemma L10:  "es_abc f (abc a)" | ||
| by (induct a) simp_all | by (induct a) simp_all | ||
| + | |||
| + | (* ivamenjim *) | ||
| + | (* Igual que el anterior pero usando auto *) | ||
| + | lemma lej10b: "es_abc f (abc n)" | ||
| + | by (induct n) auto | ||
| text {*    | text {*    | ||
| Línea 289: | Línea 405: | ||
| *} | *} | ||
| − | (* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal *) | + | (* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal | 
| − | + |    marcarmor13 antsancab1 jeamacpov *)   | |
| lemma lej11:   | lemma lej11:   | ||
| − |    assumes " es_abc profundidad a" | + |    assumes "es_abc profundidad a" | 
| − |    shows "a = (abc (profundidad a))" | + |    shows   "a = (abc (profundidad a))" | 
| using assms | using assms | ||
| by (induct a) auto | by (induct a) auto | ||
| − | |||
| (* Otra forma de escribir lo mismo *) | (* Otra forma de escribir lo mismo *) | ||
| − | (* anaprarod *) | + | (* anaprarod crigomgom rubgonmar ferrenseg ivamenjim paupeddeg juacabsou | 
| + |    dancorgar bowma lucnovdos pabrodmac *)   | ||
| lemma "es_abc profundidad a ⟶ (a = (abc (profundidad a)))" | lemma "es_abc profundidad a ⟶ (a = (abc (profundidad a)))" | ||
| by (induct a) auto | by (induct a) auto | ||
| + | (* danrodcha*) | ||
| + | lemma 11:"es_abc profundidad a ⟹ (a = (abc (profundidad a)))" | ||
| + | by (induct a) simp_all | ||
| text {*    | text {*    | ||
| Línea 313: | Línea 432: | ||
| (* migtermor *) | (* migtermor *) | ||
| fun medida_nula :: "arbol => nat" where | fun medida_nula :: "arbol => nat" where | ||
| − | + |   "medida_nula H       = 0" | |
| | "medida_nula (N i d) = 0" | | "medida_nula (N i d) = 0" | ||
| Línea 320: | Línea 439: | ||
| oops | oops | ||
| (* Quickcheck encuentra el siguiente contraejemplo: | (* Quickcheck encuentra el siguiente contraejemplo: | ||
| − |    a= N H (N H H)   | + |    a = N H (N H H)   | 
|    Tras evaluar: |    Tras evaluar: | ||
|    es_abc medida_nula a = True |    es_abc medida_nula a = True | ||
|    es_abc size a = False*) |    es_abc size a = False*) | ||
| − | + | (* anaprarod  wilmorort pablucoto serrodcal danrodcha marcarmor13 | |
| − | (* anaprarod  wilmorort pablucoto serrodcal *) | + |    ferrenseg ivamenjim paupeddeg juacabsou rubgonmar bowma lucnovdos antsancab1 jeamacpov *)   | 
| lemma "es_abc f a =  es_abc size a" | lemma "es_abc f a =  es_abc size a" | ||
| quickcheck | quickcheck | ||
| Línea 335: | Línea 454: | ||
|    es_abc f a = True |    es_abc f a = True | ||
|    es_abc size a = False *) |    es_abc size a = False *) | ||
| + | oops | ||
| + | (* el contraejemplo que encuentra es la medida constante a1 *) | ||
| + | |||
| + | (*crigomgom *) | ||
| + | (* Como en la primera de las soluciones he usado la función constante 0 | ||
| + |    pero he usado una expresión lambda *)  | ||
| + | lemma "es_abc (λx. 0::nat) a = es_abc size a" | ||
| + | quickcheck | ||
| + | oops | ||
| + | |||
| + | (* dancorgar *) | ||
| + | fun medida :: "arbol => bool" where | ||
| + |   "medida H       = True" | ||
| + | | "medida (N i d) = ((profundidad i) = (size d))" | ||
| + | |||
| + | theorem "es_abc size a = es_abc medida a" | ||
| + | quickcheck | ||
| oops | oops | ||
| + | (* pabrodmac *) | ||
| + | fun todossoniguales :: "arbol => nat" where | ||
| + |   "todossoniguales H = 1" | ||
| + | | "todossoniguales (N i d) = 1" | ||
| + | |||
| + | value "todossoniguales (H) = 1" | ||
| + | value "todossoniguales (N (N H H) (N H H)) = 1" | ||
| + | value "todossoniguales (N (N (N H H) (N H H)) (N (N H H) (N H H))) = 1" | ||
| + | |||
| + | |||
| + | lemma "es_abc todossoniguales a = es_abc size a" | ||
| + | oops | ||
| end | end | ||
| </source> | </source> | ||
Revisión actual del 12:11 16 jul 2018
chapter {* R7: Árboles binarios completos *}
theory R7_Arboles_binarios_completos
imports Main 
begin 
text {*  
  En esta relación se piden demostraciones automáticas (lo más cortas
  posibles). Para ello, en algunos casos es necesario incluir lemas
  auxiliares (que se demuestran automáticamente) y usar ejercicios
  anteriores. 
  --------------------------------------------------------------------- 
  Ejercicio 1. Definir el tipo de datos arbol para representar los
  árboles binarios que no tienen información ni en los nodos y ni en las
  hojas. Por ejemplo, el árbol
          ·
         / \
        /   \
       ·     ·
      / \   / \
     ·   · ·   · 
  se representa por "N (N H H) (N H H)".
  --------------------------------------------------------------------- 
*}
datatype arbol = H | N arbol arbol
value "N (N H H) (N H H) = (N (N H H) (N H H) :: arbol)"
text {*  
  --------------------------------------------------------------------- 
  Ejercicio 2. Definir la función
     hojas :: "arbol => nat" 
  tal que (hojas a) es el número de hojas del árbol a. Por ejemplo,
     hojas (N (N H H) (N H H)) = 4
  --------------------------------------------------------------------- 
*}
(* fraortmoy marcarmor13 josgarsan fracorjim1 jeamacpov *)
fun hojas :: "arbol => nat" where
  "hojas H       = Suc 0"
| "hojas (N a b) = hojas a + hojas b"
value "hojas (N (N H H) (N H H)) = 4"
(* marpoldia1 anaprarod paupeddeg migtermor wilmorort pablucoto 
   ivamenjim serrodcal crigomgom rubgonmar  danrodcha ferrenseg
   manmorjim1 juacabsou lucnovdos dancorgar bowma antsancab1 pabrodmac *)
(* Es muy parecida a la definición anterior *)
fun hojas2 :: "arbol => nat" where
  "hojas2 H       = 1" 
| "hojas2 (N i d) = hojas2 i + hojas2 d"
 
value "hojas2 (N (N H H) (N H H)) = 4"
(* anaprarod *)
(* Equivalencia de las definiciones *)
lemma "hojas a = hojas2 a"
by (induct a) simp_all
text {*  
  --------------------------------------------------------------------- 
  Ejercicio 4. Definir la función
     profundidad :: "arbol => nat" 
  tal que (profundidad a) es la profundidad del árbol a. Por ejemplo,
     profundidad (N (N H H) (N H H)) = 2
  --------------------------------------------------------------------- 
*}
(* fraortmoy marpoldia1 anaprarod migtermor wilmorort marcarmor13
   dancorgar antsancab1 jeamacpov pabrodmac *) 
fun profundidad :: "arbol => nat" where
  "profundidad H = 0"
| "profundidad (N a b) = (if profundidad a > profundidad b
                          then 1 + profundidad a 
                          else 1 + profundidad b)"
value "profundidad (N (N H H) (N H H)) = 2"
(* anaprarod wilmorort pablucoto ivamenjim serrodcal crigomgom rubgonmar 
   danrodcha ferrenseg josgarsan juacabsou lucnovdos bowma pabrodmac *)
fun profundidad2 :: "arbol => nat" where
  "profundidad2 H       = 0"
| "profundidad2 (N i d) = 1 + (max (profundidad2 i) (profundidad2 d))"
value "profundidad2 (N (N H H) (N H H)) = 2"
(* anaprarod *)
(* Equivalencia de las definiciones *)
lemma "profundidad a= profundidad2 a"
by (induct a) auto
(* paupeddeg *)
fun maximo :: "nat ×  nat => nat" where
  "maximo (a,b) = (if a > b then a else b)"
fun profundidad3 :: "arbol => nat" where
  "profundidad3 H       = 0"
| "profundidad3 (N i d) = 1 + maximo (profundidad3 i, profundidad3 d)"
(* ivamenjim: llamando a la función anterior profundidad3 *)
lemma "profundidad a = profundidad3 a"
by (induct a) auto
(* ivamenjim manmorjim1 fracorjim1 *)
fun profundidad4 :: "arbol => nat" where
  "profundidad4 H       = 0"
| "profundidad4 (N i d) = Suc (max (profundidad4 i) (profundidad4 d))"
lemma "profundidad a = profundidad4 a"
by (induct a) auto
text {*  
  --------------------------------------------------------------------- 
  Ejercicio 5. Definir la función
     abc :: "nat ⇒ arbol" 
  tal que (abc n) es el árbol binario completo de profundidad n. Por
  ejemplo,  
     abc 3 = N (N (N H H) (N H H)) (N (N H H) (N H H))
  --------------------------------------------------------------------- 
*}
(* fraortmoy marpoldia1 anaprarod paupeddeg migtermor  wilmorort 
   serrodcal crigomgom rubgonmar danrodcha ferrenseg josgarsan
   manmorjim1 juacabsou fracorjim1 lucnovdos dancorgar bowma antsancab1 pabrodmac *)
fun abc :: "nat ⇒ arbol" where
  "abc 0       = H"
| "abc (Suc n) = (N (abc n) (abc n))"
value "abc 3 = N (N (N H H) (N H H)) (N (N H H) (N H H))"
(* ivamenjim pablucoto marcarmor13 jeamacpov *)
fun abc2 :: "nat ⇒ arbol" where
  "abc2 0 = H"
| "abc2 t = N (abc2 (t-1)) (abc2 (t-1))"
value "abc2 3 = N (N (N H H) (N H H)) (N (N H H) (N H H))"
(* ivamenjim: Metaejercicio de demostración *)
lemma "abc t = abc2 t"
by (induct t) auto
text {*  
  --------------------------------------------------------------------- 
  Ejercicio 6. Un árbol binario a es completo respecto de la medida f si
  a es una hoja o bien a es de la forma (N i d) y se cumple que tanto i
  como d son árboles binarios completos respecto de f y, además, 
  f(i) = f(r).
  Definir la función
     es_abc :: "(arbol => 'a) => arbol => bool
  tal que (es_abc f a) se verifica si a es un árbol binario completo
  respecto de f.
  --------------------------------------------------------------------- 
*}
(* fraortmoy anaprarod migtermor serrodcal crigomgom rubgonmar 
   danrodcha ferrenseg juacabsou josgarsan fracorjim1 lucnovdos bowma *)
fun es_abc :: "(arbol => 'a) => arbol => bool" where
  "es_abc _ H       = True"
| "es_abc f (N a b) = (es_abc f a ∧ es_abc f b ∧ (f a = f b))"
(* marpoldia1 paupeddeg ivamenjim pablucoto marcarmor13 manmorjim1
   dancorgar antsancab1 jeamacpov pabrodmac *) 
fun es_abc2 :: "(arbol => 'a) => arbol => bool" where
  "es_abc2 f H       = True" 
| "es_abc2 f (N i d) = ((f i = f d) ∧ (es_abc2 f i) ∧ (es_abc2 f d))"
(* anaprarod *)
(* Equivalencia de las definiciones *)
lemma "es_abc f a = es_abc2 f a"
by (induct a) auto
text {*  
  --------------------------------------------------------------------- 
  Nota. (size a) es el número de nodos del árbol a. Por ejemplo,
     size (N (N H H) (N H H)) = 3
  --------------------------------------------------------------------- 
*}
value "size (N (N H H) (N H H)) = 3"
value "size (N (N (N H H) (N H H)) (N (N H H) (N H H))) = 7"
text {*  
  --------------------------------------------------------------------- 
  Nota. Tenemos 3 funciones de medida sobre los árboles: número de
  hojas, número de nodos y profundidad. A cada una le corresponde un
  concepto de completitud. En los siguientes ejercicios demostraremos
  que los tres conceptos de completitud son iguales.
  --------------------------------------------------------------------- 
*}
text {*  
  --------------------------------------------------------------------- 
  Ejercicio 7. Demostrar que un árbol binario a es completo respecto de
  la profundidad syss es completo respecto del número de hojas.
  --------------------------------------------------------------------- 
*}
(* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal
   fracorjim1 josgarsan lucnovdos bowma antsancab1 jeamacpov *) 
lemma abc_prof_num_hojas:
  assumes "es_abc profundidad a"
  shows   "hojas a = 2^(profundidad a)"
using assms
by (induct a) auto
(* Otra forma de escribir lo mismo *)
(* anaprarod crigomgom ivamenjim paupeddeg juacabsou *)
lemma AUX7: "es_abc profundidad a ⟶ (hojas a = 2^(profundidad a))"
by (induct a) simp_all
(* Otra forma de escribir lo mismo *)
(* danrodcha *)
lemma aux1: "es_abc profundidad (a::arbol) ⟹ (hojas a = 2^ (profundidad a))"
by (induct a) simp_all
(* fraortmoy marpoldia1 migtermor anaprarod wilmorort serrodcal
   crigomgom rubgonmar ivamenjim danrodcha marcarmor13 paupeddeg
   juacabsou bowma antsancab1 *) 
(* También funciona con AUX7 *)
lemma lej7: "es_abc profundidad a = es_abc hojas a"
by (induct a) (auto simp add: abc_prof_num_hojas)
(* danrodcha *)
lemma 7: "es_abc profundidad a = es_abc hojas a"
apply (induct a) 
apply simp
apply (auto simp add: aux1)
done
(* ferrenseg *)
lemma [simp]: "es_abc profundidad a ⟶ hojas a = 2 ^ (profundidad a)"
by (induct a) auto
(* Comentario: Uso de la declaración simp *)
theorem es_abc_profundidad_hojas: 
  "es_abc profundidad a = es_abc hojas a"
by (induct a) auto
(* Comentario: Dependencia de la declaración simp. *)
(* dancorgar *)
lemma rel_hojas_prof: "es_abc hojas a ∧ es_abc profundidad a
      ⟹ hojas a = 2 ^ profundidad a"
by (induct a) (auto)
theorem "es_abc hojas a = es_abc profundidad a"
by (induct a) (auto simp add: rel_hojas_prof)
(* pabrodmac *)
lemma lemaaux1:"es_abc hojas a⟶(hojas a = 2^(profundidad a))"
by (induct a) auto
lemma 1:"es_abc profundidad a = es_abc hojas a "
by (induct a) (auto simp add: lemaaux1)
text {*  
  --------------------------------------------------------------------- 
  Ejercicio 8. Demostrar que un árbol binario a es completo respecto del
  número de hojas syss es completo respecto del número de nodos.
  --------------------------------------------------------------------- 
*}
(* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal
   marcarmor13 josgarsan lucnovdos bowma antsancab1 jeamacpov *) 
lemma abc_hojas_num_nodos:
  assumes "es_abc hojas a"
  shows   "Suc (size a) = hojas a"
using assms
by (induct a) auto
(* Comentario sobre orientación de igualdades. *)
(* Otra forma de escribir lo mismo *)
(* anaprarod crigomgom paupeddeg juacabsou rubgonmar *)
lemma AUX8: "es_abc hojas a ⟶ (hojas a = (Suc (size a)))"
by (induct a) auto
(* fraortmoy marpoldia1 migtermor anaprarod wilmorort pablucoto
   serrodcal antsancab1 *) 
lemma lej8: "es_abc hojas a = es_abc size a"
by (induct a) (auto simp add:abc_hojas_num_nodos [symmetric])
(* Comentario sobre orientación de igualdades. *)
(* anaprarod crigomgom paupeddeg juacabsou rubgonmar *)
(* Usando AUX8 *)
lemma L8: "es_abc hojas a = es_abc size a"
by (induct a) (auto simp add: AUX8)
(* ivamenjim *)
(* Teorema auxiliar *)
lemma auxEj8: "hojas a = size a + 1"
by (induct a) auto
(* ivamenjim *)
lemma lej8b: "es_abc hojas a = es_abc size a"
by (induct a) (auto simp add: auxEj8)
(* danrodcha *)
lemma aux3: "es_abc hojas a ⟹ (hojas a = 1 + size a)"
by (induct a) simp_all
(* danrodcha *)
lemma 8: "es_abc hojas a = es_abc size a"
apply (induct a) 
apply simp
apply (auto simp add: aux3)
done
(* ferrenseg *)
lemma [simp]: "hojas a = size a + 1"
by (induct a) auto
 
theorem es_abc_hojas_size: "es_abc hojas a = es_abc size a"
by (induct a) auto
(* fracorjim1 *)
lemma aux10 : "hojas (a::arbol) = Suc(size a)"
apply (induct a)
apply auto
done
    
lemma es_abc_hojas_size_10 : "es_abc hojas (a::arbol) = es_abc size a"
apply (induct a)
apply (auto simp add: aux10)
done
(* dancorgar *)
lemma rel_hojas_size: "es_abc hojas a ∧ es_abc size a
      ⟹ hojas a = (size a) + 1"
by (induct a) (auto)
theorem "es_abc hojas a = es_abc size a"
by (induct a) (auto simp add: rel_hojas_size)
(* pabrodmac *)
lemma lemaaux2:"es_abc size a⟶(hojas a  = Suc(size a)) "
by (induct a) auto
lemma 2:"es_abc hojas a = es_abc size a "
by (induct a) (auto simp add: lemaaux2)
text {*  
  --------------------------------------------------------------------- 
  Ejercicio 9. Demostrar que un árbol binario a es completo respecto de
  la profundidad syss es completo respecto del número de nodos.
  --------------------------------------------------------------------- 
*}
(* fraortmoy marpoldia1 migtermor anaprarod  wilmorort pablucoto 
   serrodcal crigomgom rubgonmar danrodcha ivamenjim marcarmor13
   paupeddeg juacabsou josgarsan bowma lucnovdos antsancab1 jeamacpov *)
lemma lej9:  "es_abc profundidad a = es_abc size a"
by (simp add: lej7 lej8)
(* ferrenseg *)
corollary es_abc_size_profundidad: "es_abc size a = es_abc profundidad a"
by (simp add: es_abc_profundidad_hojas es_abc_hojas_size)
(* pabrodmac *)
lemma lemaaux3:"es_abc profundidad a⟶(Suc(size a)= 2^(profundidad a)) "
by (induct a) auto
lemma "es_abc profundidad a = es_abc size a "
by (simp add: 1 2 )
text {*  
  --------------------------------------------------------------------- 
  Ejercicio 10. Demostrar que (abc n) es un árbol binario completo.
  --------------------------------------------------------------------- 
*}
(* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal
   crigomgom marcarmor13 paupeddeg juacabsou dancorgar lucnovdos jeamacpov pabrodmac  *)
lemma lej10: "es_abc profundidad (abc n)"
by (induct n) auto
(* anaprarod rubgonmar danrodcha ferrenseg ivamenjim
   paupeddeg juacabsou bowma antsancab1 *)
(* con un demostrador más débil *)
(* y en general para cualquier medida *)
lemma L10:  "es_abc f (abc a)"
by (induct a) simp_all
(* ivamenjim *)
(* Igual que el anterior pero usando auto *)
lemma lej10b: "es_abc f (abc n)"
by (induct n) auto
text {*  
  --------------------------------------------------------------------- 
  Ejercicio 11. Demostrar que si a es un árbolo binario completo
  respecto de la profundidad, entonces a es igual a
  (abc (profundidad a)).
  --------------------------------------------------------------------- 
*}
(* fraortmoy marpoldia1 migtermor wilmorort pablucoto serrodcal
   marcarmor13 antsancab1 jeamacpov *) 
lemma lej11: 
  assumes "es_abc profundidad a"
  shows   "a = (abc (profundidad a))"
using assms
by (induct a) auto
(* Otra forma de escribir lo mismo *)
(* anaprarod crigomgom rubgonmar ferrenseg ivamenjim paupeddeg juacabsou
   dancorgar bowma lucnovdos pabrodmac *) 
lemma "es_abc profundidad a ⟶ (a = (abc (profundidad a)))"
by (induct a) auto
(* danrodcha*)
lemma 11:"es_abc profundidad a ⟹ (a = (abc (profundidad a)))"
by (induct a) simp_all
text {*  
  --------------------------------------------------------------------- 
  Ejercicio 12. Encontrar una medida f tal que (es_abc f) es distinto de 
  (es_abc size).
  --------------------------------------------------------------------- 
*}
(* migtermor *)
fun medida_nula :: "arbol => nat" where
  "medida_nula H       = 0"
| "medida_nula (N i d) = 0"
lemma "es_abc medida_nula a = es_abc size a"
quickcheck
oops
(* Quickcheck encuentra el siguiente contraejemplo:
  a = N H (N H H) 
  Tras evaluar:
  es_abc medida_nula a = True
  es_abc size a = False*)
(* anaprarod  wilmorort pablucoto serrodcal danrodcha marcarmor13
   ferrenseg ivamenjim paupeddeg juacabsou rubgonmar bowma lucnovdos antsancab1 jeamacpov *) 
lemma "es_abc f a =  es_abc size a"
quickcheck
(* Quickcheck found a counterexample:
  f = λx. a⇩1   
  a = N H (N H H)
Evaluated terms:
  es_abc f a = True
  es_abc size a = False *)
oops
(* el contraejemplo que encuentra es la medida constante a1 *)
(*crigomgom *)
(* Como en la primera de las soluciones he usado la función constante 0
   pero he usado una expresión lambda *) 
lemma "es_abc (λx. 0::nat) a = es_abc size a"
quickcheck
oops
(* dancorgar *)
fun medida :: "arbol => bool" where
  "medida H       = True"
| "medida (N i d) = ((profundidad i) = (size d))"
theorem "es_abc size a = es_abc medida a"
quickcheck
oops
(* pabrodmac *)
fun todossoniguales :: "arbol => nat" where
  "todossoniguales H = 1"
| "todossoniguales (N i d) = 1"
value "todossoniguales (H) = 1"
value "todossoniguales (N (N H H) (N H H)) = 1"
value "todossoniguales (N (N (N H H) (N H H)) (N (N H H) (N H H))) = 1"
lemma "es_abc todossoniguales a = es_abc size a"
oops
end
