Tema 6b: Verificación de la ordenación por mezcla
De Razonamiento automático (2016-17)
Revisión del 13:11 16 jul 2018 de WikiSysop (discusión | contribuciones) (Texto reemplazado: «isar» por «isabelle»)
chapter {* T6b: Verificación de la ordenación por mezcla *}
theory T6b_Verificacion_de_la_ordenacion_por_mezcla_sol
imports Main
begin
text {*
En esta relación de ejercicios se define el algoritmo de ordenación de
listas por mezcla y se demuestra que es correcto.
*}
section {* Ordenación de listas *}
text {*
---------------------------------------------------------------------
Ejercicio 1. Definir la función
menor :: int ⇒ int list ⇒ bool
tal que (menor a xs) se verifica si a es menor o igual que todos los
elementos de xs.Por ejemplo,
menor 2 [3,2,5] = True
menor 2 [3,0,5] = False
------------------------------------------------------------------ *}
fun menor :: "int ⇒ int list ⇒ bool" where
"menor a [] = True"
| "menor a (x#xs) = (a ≤ x ∧ menor a xs)"
value "menor 2 [3,2,5] = True"
value "menor 2 [3,0,5] = False"
text {*
---------------------------------------------------------------------
Ejercicio 2. Definir la función
ordenada :: int list ⇒ bool
tal que (ordenada xs) se verifica si xs es una lista ordenada de
manera creciente. Por ejemplo,
ordenada [2,3,3,5] = True
ordenada [2,4,3,5] = False
------------------------------------------------------------------ *}
fun ordenada :: "int list ⇒ bool" where
"ordenada [] = True"
| "ordenada (x#xs) = (menor x xs & ordenada xs)"
value "ordenada [2,3,3,5] = True"
value "ordenada [2,4,3,5] = False"
text {*
---------------------------------------------------------------------
Ejercicio 3. Definir la función
cuenta :: int list => int => nat
tal que (cuenta xs y) es el número de veces que aparece el elemento y
en la lista xs. Por ejemplo,
cuenta [1,3,4,3,5] 3 = 2
------------------------------------------------------------------ *}
fun cuenta :: "int list => int => nat" where
"cuenta [] y = 0"
| "cuenta (x#xs) y = (if x=y
then Suc(cuenta xs y)
else cuenta xs y)"
value "cuenta [1,3,4,3,5] 3 = 2"
section {* Ordenación por mezcla *}
text {*
---------------------------------------------------------------------
Ejercicio 4. Definir la función
mezcla :: int list ⇒ int list ⇒ int list
tal que (mezcla xs ys) es la lista obtenida mezclando las listas
ordenadas xs e ys. Por ejemplo,
mezcla [1,2,5] [3,5,7] = [1,2,3,5,5,7]
------------------------------------------------------------------ *}
fun mezcla :: "int list ⇒ int list ⇒ int list" where
"mezcla [] ys = ys"
| "mezcla xs [] = xs"
| "mezcla (x # xs) (y # ys) = (if x ≤ y
then x # mezcla xs (y # ys)
else y # mezcla (x # xs) ys)"
value "mezcla [1,2,5] [3,5,7] = [1,2,3,5,5,7]"
text {*
---------------------------------------------------------------------
Ejercicio 5. Definir la función
ordenaM :: int list ⇒ int list
tal que (ordenaM xs) es la lista obtenida ordenando la lista xs
mediante mezclas; es decir, la divide en dos mitades, las ordena y las
mezcla. Por ejemplo,
ordenaM [3,2,5,2] = [2,2,3,5]
------------------------------------------------------------------ *}
fun ordenaM :: "int list ⇒ int list" where
"ordenaM [] = []"
| "ordenaM [x] = [x]"
| "ordenaM xs =
(let mitad = length xs div 2 in
mezcla (ordenaM (take mitad xs))
(ordenaM (drop mitad xs)))"
value "ordenaM [3,2,5,2] = [2,2,3,5]"
text {*
---------------------------------------------------------------------
Ejercicio 6. Sea x ≤ y. Si y es menor o igual que todos los elementos
de xs, entonces x es menor o igual que todos los elementos de xs
------------------------------------------------------------------ *}
lemma menor_menor:
"x ≤ y ⟹ menor y xs ⟶ menor x xs"
by (induct xs) auto
text {*
---------------------------------------------------------------------
Ejercicio 7. Demostrar que el número de veces que aparece n en la
mezcla de dos listas es igual a la suma del número de apariciones en
cada una de las listas
------------------------------------------------------------------ *}
lemma cuenta_mezcla:
"cuenta (mezcla xs ys) n = cuenta xs n + cuenta ys n"
by (induct xs ys rule: mezcla.induct) auto
text {*
---------------------------------------------------------------------
Ejercicio 8. Demostrar que si x es menor que todos los elementos de
ys y de zs, entonces también lo es de su mezcla.
------------------------------------------------------------------ *}
lemma menor_mezcla:
assumes "menor x ys"
"menor x zs"
shows "menor x (mezcla ys zs)"
using assms
by (induct ys zs rule: mezcla.induct) simp_all
text {*
---------------------------------------------------------------------
Ejercicio 9. Demostrar que la mezcla de dos listas ordenadas es una
lista ordenada.
Indicación: Usar los siguientes lemas
· linorder_not_le: (¬ x ≤ y) = (y < x)
· order_less_le: (x < y) = (x ≤ y ∧ x ≠ y)
------------------------------------------------------------------ *}
lemma ordenada_mezcla:
assumes "ordenada xs"
"ordenada ys"
shows "ordenada (mezcla xs ys)"
using assms
by (induct xs ys rule: mezcla.induct)
(auto simp add: menor_mezcla
menor_menor
linorder_not_le
order_less_le)
text {*
---------------------------------------------------------------------
Ejercicio 10. Demostrar que si x es mayor que 1, entonces el mínimo de
x y su mitad es menor que x.
------------------------------------------------------------------ *}
lemma min_mitad:
"1 < x ⟹ min x (x div 2::int) < x"
by simp
text {*
---------------------------------------------------------------------
Ejercicio 11. Demostrar que si x es mayor que 1, entonces x menos su
mitad es menor que x.
------------------------------------------------------------------ *}
lemma menos_mitad:
"1 < x ⟹ x - x div (2::int) < x"
by arith
text {*
---------------------------------------------------------------------
Ejercicio 11. Demostrar que (ordenaM xs) está ordenada.
------------------------------------------------------------------ *}
theorem ordenada_ordenaM:
"ordenada (ordenaM xs)"
by (induct xs rule: ordenaM.induct)
(auto simp add: ordenada_mezcla)
text {*
---------------------------------------------------------------------
Ejercicio 12. Demostrar que el número de apariciones de un elemento en
la concatenación de dos listas es la suma del número de apariciones en
cada una.
------------------------------------------------------------------ *}
lemma cuenta_conc:
"cuenta (xs @ ys) x = cuenta xs x + cuenta ys x"
by (induct xs) auto
text {*
---------------------------------------------------------------------
Ejercicio 13. Demostrar que las listas xs y (ordenaM xs) tienen los
mismos elementos.
------------------------------------------------------------------ *}
theorem cuenta_ordenaM:
"cuenta (ordenaM xs) x = cuenta xs x"
by (induct xs rule: ordenaM.induct)
(auto simp add: cuenta_mezcla
cuenta_conc [symmetric])
end