Acciones

T1 2

De Demostración automática de teoremas (2014-15)

Revisión del 12:18 13 abr 2015 de Mjoseh (discusión | contribuciones) (Página creada con '<source lang = "isar"> header {* Verificación de la ordenación por mezcla *} theory Ordenacion_por_mezclas imports Main begin text {* ---------------------------------------...')
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
header {* Verificación de la ordenación por mezcla *}

theory Ordenacion_por_mezclas
imports Main
begin

text {* ---------------------------------------------------------------------------------
  En este trabajo se describe el algoritmo de ordenación de listas por mezclas y se
  propone comprobar que es correcto.

  El algoritmo de ordenación de listas por mezclas construye una lista ordenada a partir 
  de la lista original, para ello divide la lista original en dos trozos, los ordena
  siguiendo el mismo método y finalmente mezcla los resultados. Por ejemplo, dada la
  lista [2,7,5,1] el algoritmo actúa como se describe a continuación:
  - Lista a ordenar: [2,7,5,1]
    Trozos de la lista: [2,7] y [5,1]
  -- Lista a ordenar: [2,7]
     Trozos de la lista: [2] y [7]
  --- Lista a ordenar: [2]
      La lista está ordenada
  --- Lista a ordenar: [7]
      La lista está ordenada
  -- La mezcla ordenada de [2] y [7] es [2,7]
  -- Lista a ordenar [5,1]
     Trozos de la lista: [5] y [1]
  --- Lista a ordenar: [5]
      La lista está ordenada
  --- Lista a ordenar: [1]
      La lista está ordenada
  -- La mezcla ordenada de [5] y [1] es [1,5]
  - La mezcla ordenada de [2,7] y [1,5] es [1,2,5,7]

  Para implementar este algoritmo de ordenación se definen las siguientes funciones:
-------------------------------------------------------------------------------------- *}

text {* --------------------------------------------------------------------------------
  Consideramos 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 {* ---------------------------------------------------------------------------------
  consideramos la función
     ordena :: int list ⇒ int list
  tal que '(ordena 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, 
     ordena [3,2,5,2] = [2,2,3,5]
-------------------------------------------------------------------------------------- *}

fun ordena :: "int list ⇒ int list" where
  "ordena [] = []" 
| "ordena [x] = [x]" 
| "ordena xs = mezcla (ordena (take (length xs div 2) xs)) 
                      (ordena (drop (length xs div 2) xs))"

value "ordena [3,2,5,2]" -- "= [2,2,3,5]"

section {* Corrección del algoritmo de ordenación *}

text {* ---------------------------------------------------------------------------------
  La corrección del algoritmo de ordenación consiste en comprobar dos propiedades:
  - El resultado del algoritmo de ordenación tiene los mismos elementos que la lista
    original.
  - El resultado del algoritmo de ordenación es una lista ordenada.

  A continuación definimos las funciones necesarias para comprobar la corrección del 
  algoritmo de ordenación.
-------------------------------------------------------------------------------------- *}

text {* ---------------------------------------------------------------------------------
  Consideramos la función
     menor :: int ⇒ int list ⇒ bool
  tal que '(menor a xs)' se verifica si el elemento '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 {* ---------------------------------------------------------------------------------
  Consideramos 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 {* ---------------------------------------------------------------------------------
  Consideramos 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"

text {* ---------------------------------------------------------------------------------
  Propiedad 1: El resultado del algoritmo de ordenación tiene los mismos elementos que la
  lista original.
-------------------------------------------------------------------------------------- *}

lemma cuenta_mezcla: 
  "cuenta (mezcla xs ys) n = cuenta xs n + cuenta ys n"
oops

lemma cuenta_append: 
  "(cuenta xs x + cuenta ys x) = cuenta (xs @ ys) x"
oops

theorem cuenta_ordena: 
  "cuenta (ordena xs) x = cuenta xs x"
oops

text {* ---------------------------------------------------------------------------------
  Propiedad 2: El resultado del algoritmo de ordenación es una lista ordenada.
-------------------------------------------------------------------------------------- *}

lemma menor_menor: 
  "x ≤ y ⟹ menor y xs ⟶ menor x xs"
oops

lemma menor_mezcla:
  assumes "menor x ys" 
          "menor x zs" 
  shows   "menor x (mezcla ys zs)"
oops

text {* ---------------------------------------------------------------------------------
  Indicación: En este lema puede ser necesario utilizar las siguientes propiedades:
  · 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)"
oops

theorem ordenada_ordena:
  "ordenada (ordena xs)"
oops

text {* ------------------------------------------------------------------------------ *}
 
end