Acciones

Diferencia entre revisiones de «Definiciones inductivas»

De Lógica matemática y fundamentos (2018-19)

 
Línea 1: Línea 1:
 
<source lang="isabelle">
 
<source lang="isabelle">
chapter {* Tema 9: Definiciones inductivas *}
+
chapter ‹Tema 9: Definiciones inductivas›
  
 
theory T9_Definiciones_inductivas
 
theory T9_Definiciones_inductivas
Línea 6: Línea 6:
 
begin
 
begin
  
section {* El conjunto de los números pares *}
+
section ‹El conjunto de los números pares›
  
text {*
+
text
 
   · El conjunto de los números pares se define inductivamente como el
 
   · El conjunto de los números pares se define inductivamente como el
 
     menor conjunto que contiene al 0 y es cerrado por la operación (+2).
 
     menor conjunto que contiene al 0 y es cerrado por la operación (+2).
Línea 16: Línea 16:
  
 
   · Veremos cómo se escriben las dos definiciones en Isabelle/HOL y cómo
 
   · Veremos cómo se escriben las dos definiciones en Isabelle/HOL y cómo
     se demuestra su equivalencia.
+
     se demuestra su equivalencia.
*}
 
  
subsection {* Definición inductiva del conjunto de los pares *}
+
subsection ‹Definición inductiva del conjunto de los pares›
  
 
inductive_set par :: "nat set" where
 
inductive_set par :: "nat set" where
Línea 25: Línea 24:
 
| paso [intro!]: "n ∈ par ⟹ (Suc (Suc n)) ∈ par"
 
| paso [intro!]: "n ∈ par ⟹ (Suc (Suc n)) ∈ par"
  
text {*
+
text
 
   · Una definición inductiva está formada con reglas de introducción.
 
   · Una definición inductiva está formada con reglas de introducción.
  
Línea 32: Línea 31:
 
     · par.paso:  n ∈ par ⟹ Suc (Suc n) ∈ par
 
     · par.paso:  n ∈ par ⟹ Suc (Suc n) ∈ par
 
     · par.simps:  (a ∈ par) = (a = 0 ∨ (∃n. a = Suc (Suc n) ∧ n ∈ par))
 
     · par.simps:  (a ∈ par) = (a = 0 ∨ (∃n. a = Suc (Suc n) ∧ n ∈ par))
*}
+
  
subsection {* Uso de las reglas de introducción *}
+
thm par.cero
 +
thm par.paso
 +
thm par.simps
  
text {*
+
subsection ‹Uso de las reglas de introducción›
 +
 
 +
text
 
   Lema: Los números de la forma 2*k son pares.
 
   Lema: Los números de la forma 2*k son pares.
*}
+
  
 
― ‹La demostración aplicativa es›
 
― ‹La demostración aplicativa es›
Línea 46: Línea 49:
 
     (* 1. 2 * 0 ∈ par
 
     (* 1. 2 * 0 ∈ par
 
         2. ⋀k. 2 * k ∈ par ⟹ 2 * Suc k ∈ par *)
 
         2. ⋀k. 2 * k ∈ par ⟹ 2 * Suc k ∈ par *)
   apply auto
+
   apply simp_all
 
     (* *)
 
     (* *)
 
   done
 
   done
Línea 59: Línea 62:
 
   "2*k ∈ par"
 
   "2*k ∈ par"
 
proof (induct k)
 
proof (induct k)
   show "2 * 0 ∈ par" by auto
+
   show "2 * 0 ∈ par"  
 +
    by auto
 
next
 
next
   show "⋀k. 2 * k ∈ par ⟹ 2 * Suc k ∈ par" by auto
+
   show "⋀k. 2 * k ∈ par ⟹ 2 * Suc k ∈ par"  
 +
    by auto
 
qed
 
qed
  
text {*
+
text
 
   · Nota: Nuestro objetivo es demostrar la equivalencia de la definición
 
   · Nota: Nuestro objetivo es demostrar la equivalencia de la definición
 
     anterior y la definición mediante divisibilidad (even).
 
     anterior y la definición mediante divisibilidad (even).
 
    
 
    
 
   · Lema: Si n es divisible por 2, entonces es par.
 
   · Lema: Si n es divisible por 2, entonces es par.
*}
+
  
lemma even_imp_par: "even n ⟹ n ∈ par"
+
lemma even_imp_par: "even n ⟹ n ∈ par"  
   by auto
+
   using dobles_son_pares_3 by blast
  
subsection {* Regla de inducción *}
+
subsection ‹Regla de inducción›
  
text {*
+
text ‹Entre las reglas generadas por la definión de par está la de
  Entre las reglas generadas por la definión de par está la de
 
 
   inducción:
 
   inducción:
 
   · par.induct: ⟦ x ∈ par;  
 
   · par.induct: ⟦ x ∈ par;  
Línea 83: Línea 87:
 
                 ⋀n. ⟦n ∈ par; P n⟧ ⟹ P (Suc (Suc n))⟧  
 
                 ⋀n. ⟦n ∈ par; P n⟧ ⟹ P (Suc (Suc n))⟧  
 
                 ⟹ P x
 
                 ⟹ P x
*}
+
  
text {*
+
thm par.induct
  Lema: Los números pares son divisibles por 2.
+
 
*}
+
text ‹Lema: Los números pares son divisibles por 2.
  
 
― ‹Demostración aplicativa›
 
― ‹Demostración aplicativa›
Línea 126: Línea 130:
 
lemma par_imp_even_3:  
 
lemma par_imp_even_3:  
 
   "n ∈ par ⟹ even n"
 
   "n ∈ par ⟹ even n"
   by (induction rule:par.induct) simp_all
+
   by (induction rule: par.induct) simp_all
  
 
― ‹Demostración declarativa›
 
― ‹Demostración declarativa›
Línea 132: Línea 136:
 
   "n ∈ par ⟹ even n"
 
   "n ∈ par ⟹ even n"
 
proof (induction rule: par.induct)
 
proof (induction rule: par.induct)
   show "even 0" by simp
+
   show "even 0"  
 +
    by simp
 
next
 
next
   fix n::nat
+
   fix n :: nat
 
   assume H1: "n ∈ par" and
 
   assume H1: "n ∈ par" and
 
         H2: "even n"
 
         H2: "even n"
   have "∃k. n = 2*k" using H2 by (simp add: dvd_def)
+
   have "∃k. n = 2*k"  
   then obtain k where "n = 2*k" ..
+
    using H2 by (simp add: dvd_def)
   then have "Suc (Suc n) = 2*(k+1)" by simp
+
   then obtain k where "n = 2*k"  
   then have "∃k. Suc (Suc n) = 2*k" ..
+
    by (rule exE)
   then show "even (Suc (Suc n))" by (simp add: dvd_def)
+
   then have "Suc (Suc n) = 2*(k+1)"  
 +
    by simp
 +
   then have "∃k. Suc (Suc n) = 2*k"  
 +
    by (rule exI)
 +
   then show "even (Suc (Suc n))"  
 +
    by (simp add: dvd_def)
 
qed
 
qed
  
Línea 153: Línea 163:
 
   assume H1: "n ∈ par" and
 
   assume H1: "n ∈ par" and
 
         H2: "even n"
 
         H2: "even n"
   then show "even (Suc (Suc n))" by simp
+
   then show "even (Suc (Suc n))"  
 +
    by simp
 
qed
 
qed
  
text {*
+
text ‹Lema: Un número n es par syss es divisible por 2.
  Lema: Un número n es par syss es divisible por 2.  
 
*}
 
  
theorem par_iff_even: "(n ∈ par) = (even n)"
+
theorem par_iff_even: "(n ∈ par) = (even n)"  
   by (blast intro: even_imp_par par_imp_even)
+
   using even_imp_par par_imp_even_5 by blast
  
subsection{* Generalización y regla de inducción *}
+
subsection ‹Generalización y regla de inducción›
  
text {*
+
text
 
   · Antes de aplicar inducción se debe de generalizar la fórmula a
 
   · Antes de aplicar inducción se debe de generalizar la fórmula a
 
     probar.
 
     probar.
Línea 174: Línea 183:
  
 
   · El siguiente intento falla:
 
   · El siguiente intento falla:
*}
+
  
 
lemma "Suc (Suc n) ∈ par ⟹ n ∈ par"
 
lemma "Suc (Suc n) ∈ par ⟹ n ∈ par"
Línea 182: Línea 191:
 
oops
 
oops
  
text {*
+
text
 
   En el intento anterior, los subobjetivos generados son
 
   En el intento anterior, los subobjetivos generados son
 
     1. n ∈ par
 
     1. n ∈ par
Línea 189: Línea 198:
  
 
   Se ha perdido la información sobre Suc (Suc n).
 
   Se ha perdido la información sobre Suc (Suc n).
*}
+
  
text {*
+
text ‹Reformulación del lema: Si n es par, entonces n-2 también lo es.
  Reformulación del lema: Si n es par, entonces n-2 también lo es.
 
*}
 
  
 
― ‹La demostración aplicativa es›
 
― ‹La demostración aplicativa es›
Línea 212: Línea 219:
 
― ‹La demostración estructurada es›
 
― ‹La demostración estructurada es›
 
lemma "n ∈  par ⟹ n - 2 ∈ par"
 
lemma "n ∈  par ⟹ n - 2 ∈ par"
proof (induction rule:par.induct)
+
proof (induction rule: par.induct)
   show "0 - 2 ∈ par" by auto
+
   show "0 - 2 ∈ par"  
 +
    by auto
 
next
 
next
   show "⋀n. ⟦n ∈ par; n - 2 ∈ par⟧ ⟹ Suc (Suc n) - 2 ∈ par" by auto
+
   show "⋀n. ⟦n ∈ par; n - 2 ∈ par⟧ ⟹ Suc (Suc n) - 2 ∈ par"  
 +
    by auto
 
qed
 
qed
  
text {*
+
text ‹Con el lema anterior se puede demostrar el original.
  Con el lema anterior se puede demostrar el original.
 
*}
 
  
 
― ‹La demostración aplicativa es›
 
― ‹La demostración aplicativa es›
Línea 233: Línea 240:
 
― ‹La demostración automática es›
 
― ‹La demostración automática es›
 
lemma Suc_Suc_par_imp_par:  
 
lemma Suc_Suc_par_imp_par:  
   "Suc (Suc n) ∈ par ⟹ n ∈ par"
+
   "Suc (Suc n) ∈ par ⟹ n ∈ par"  
 
   by (drule par_imp_par_menos_2, simp)
 
   by (drule par_imp_par_menos_2, simp)
  
Línea 243: Línea 250:
 
   have "Suc (Suc n) - 2 ∈ par"  
 
   have "Suc (Suc n) - 2 ∈ par"  
 
     using assms by (rule par_imp_par_menos_2)
 
     using assms by (rule par_imp_par_menos_2)
   then show "n ∈ par" by simp  
+
   then show "n ∈ par"  
 +
    by simp  
 
qed
 
qed
  
text {*
+
text ‹Lemma. Un número natural n es par syss n+2 es par.
  Lemma. Un número natural n es par syss n+2 es par.
 
*}
 
  
 
lemma [iff]: "((Suc (Suc n)) ∈ par) = (n ∈ par)"
 
lemma [iff]: "((Suc (Suc n)) ∈ par) = (n ∈ par)"
   by (blast dest: Suc_Suc_par_imp_par)
+
   using Suc_Suc_par_imp_par by blast
  
text {*
+
text ‹Se usa el atributo "iff" porque sirve como regla de  
  Se usa el atributo "iff" porque sirve como regla de simplificación.
+
  simplificación.
*}
 
  
subsection {* Definiciones mutuamente inductivas *}
+
subsection ‹Definiciones mutuamente inductivas›
  
text {*
+
text ‹Definición cruzada de los conjuntos inductivos de los pares y de los  
  Definición cruzada de los conjuntos inductivos de los pares y de los  
+
   impares:
   impares:
 
*}
 
  
 
inductive_set
 
inductive_set
Línea 272: Línea 275:
 
| ImparesI: "n ∈ Pares  ⟹ Suc n ∈ Impares"
 
| ImparesI: "n ∈ Pares  ⟹ Suc n ∈ Impares"
  
text {*
+
text ‹El esquema de inducción generado por la definición anterior es
  El esquema de inducción generado por la definición anterior es
 
 
   · Pares_Impares.induct:
 
   · Pares_Impares.induct:
 
     ⟦P1 0;  
 
     ⟦P1 0;  
Línea 279: Línea 281:
 
     ⋀n. ⟦n ∈ Pares;  P1 n⟧ ⟹ P2 (Suc n)⟧
 
     ⋀n. ⟦n ∈ Pares;  P1 n⟧ ⟹ P2 (Suc n)⟧
 
     ⟹ (x1 ∈ Pares ⟶ P1 x1) ∧ (x2 ∈ Impares ⟶ P2 x2)
 
     ⟹ (x1 ∈ Pares ⟶ P1 x1) ∧ (x2 ∈ Impares ⟶ P2 x2)
*}
+
 +
 
 +
thm Pares_Impares.induct
  
text {*
+
text ‹Ejemplo de demostración usando el esquema anterior.
  Ejemplo de demostración usando el esquema anterior.
 
*}
 
  
 
― ‹Demostración aplicativa›
 
― ‹Demostración aplicativa›
Línea 301: Línea 303:
 
― ‹La demostración declarativa es›
 
― ‹La demostración declarativa es›
 
lemma "(m ∈ Pares ⟶ even m) ∧ (n ∈ Impares ⟶ even (Suc n))"
 
lemma "(m ∈ Pares ⟶ even m) ∧ (n ∈ Impares ⟶ even (Suc n))"
proof (induction rule:Pares_Impares.induct)
+
proof (induction rule: Pares_Impares.induct)
   show "even (0::nat)" by simp
+
   show "even (0::nat)"  
 +
    by simp
 
next
 
next
 
   fix n :: "nat"
 
   fix n :: "nat"
 
   assume H1: "n ∈ Impares" and
 
   assume H1: "n ∈ Impares" and
 
         H2: "even (Suc n)"
 
         H2: "even (Suc n)"
   show "even (Suc n)" using H2 by simp
+
   show "even (Suc n)"  
 +
    using H2 by simp
 
next
 
next
 
   fix n :: "nat"
 
   fix n :: "nat"
 
   assume H1: "n ∈ Pares" and
 
   assume H1: "n ∈ Pares" and
 
         H2: "even n"
 
         H2: "even n"
   have "∃k. n = 2*k" using H2 by (simp add: dvd_def)
+
   have "∃k. n = 2*k"  
   then obtain k where "n = 2*k" ..
+
    using H2 by (simp add: dvd_def)
   then have "Suc (Suc n) = 2*(k+1)" by auto
+
   then obtain k where "n = 2*k"  
   then have "∃k. Suc (Suc n) = 2*k" ..
+
    by (rule exE)
   then show "even (Suc (Suc n))" by (simp add: dvd_def)
+
   then have "Suc (Suc n) = 2*(k+1)"  
 +
    by auto
 +
   then have "∃k. Suc (Suc n) = 2*k"  
 +
    by (rule exI)
 +
   then show "even (Suc (Suc n))"  
 +
    by (simp add: dvd_def)
 
qed
 
qed
  
subsection {* Definición inductiva de predicados *}
+
subsection ‹Definición inductiva de predicados›
  
text {*
+
text ‹Definición inductiva del predicado es_par tal que (es_par n) se
  Definición inductiva del predicado es_par tal que (es_par n) se
+
   verifica si n es par.
   verifica si n es par.
 
*}
 
  
 
inductive es_par :: "nat ⇒ bool" where
 
inductive es_par :: "nat ⇒ bool" where
 
   "es_par 0"  
 
   "es_par 0"  
| "es_par n ⟹ es_par (Suc(Suc n))"
+
| "es_par n ⟹ es_par (Suc (Suc n))"
  
text {*
+
text ‹Heurística para elegir entre definir conjuntos o predicados:
  Heurística para elegir entre definir conjuntos o predicados:
 
 
   · si se va a combinar con operaciones conjuntistas, definir conjunto;
 
   · si se va a combinar con operaciones conjuntistas, definir conjunto;
   · en caso contrario, definir predicado.
+
   · en caso contrario, definir predicado.
*}
 
  
 
end
 
end
 
</source>
 
</source>

Revisión actual del 20:21 27 may 2020

chapter Tema 9: Definiciones inductivas

theory T9_Definiciones_inductivas
imports Main
begin

section El conjunto de los números pares

text 
  · El conjunto de los números pares se define inductivamente como el
    menor conjunto que contiene al 0 y es cerrado por la operación (+2).

  · El conjunto de los números pares también puede definirse como los 
    naturales divisible por 2.

  · Veremos cómo se escriben las dos definiciones en Isabelle/HOL y cómo
    se demuestra su equivalencia.

subsection Definición inductiva del conjunto de los pares

inductive_set par :: "nat set" where
  cero [intro!]: "0 ∈ par" 
| paso [intro!]: "n ∈ par ⟹ (Suc (Suc n)) ∈ par"

text 
  · Una definición inductiva está formada con reglas de introducción.

  · La definición inductiva genera varios teoremas:
    · par.cero:   0  par
    · par.paso:   n  par  Suc (Suc n)  par
    · par.simps:  (a  par) = (a = 0  (n. a = Suc (Suc n)  n  par))


thm par.cero
thm par.paso
thm par.simps

subsection Uso de las reglas de introducción

text 
  Lema: Los números de la forma 2*k son pares.


 La demostración aplicativa es
lemma dobles_son_pares [intro!]: 
  "2*k ∈ par"
  apply (induct k) 
     (* 1. 2 * 0 ∈ par
        2. ⋀k. 2 * k ∈ par ⟹ 2 * Suc k ∈ par *)
   apply simp_all
     (* *)
  done

 La demostración automática es
lemma dobles_son_pares_2: 
  "2*k ∈ par"
  by (induct k) auto

 La demostración estructurada es
lemma dobles_son_pares_3:
  "2*k ∈ par"
proof (induct k)
  show "2 * 0 ∈ par" 
    by auto
next
  show "⋀k. 2 * k ∈ par ⟹ 2 * Suc k ∈ par" 
    by auto
qed

text 
  · Nota: Nuestro objetivo es demostrar la equivalencia de la definición
    anterior y la definición mediante divisibilidad (even).
  
  · Lema: Si n es divisible por 2, entonces es par.


lemma even_imp_par: "even n ⟹ n ∈ par" 
  using dobles_son_pares_3 by blast

subsection Regla de inducción 

text Entre las reglas generadas por la definión de par está la de
  inducción:
  · par.induct:  x  par; 
                 P 0; 
                 n. n  par; P n  P (Suc (Suc n)) 
                 P x


thm par.induct

text Lema: Los números pares son divisibles por 2. 

 Demostración aplicativa
lemma par_imp_even: 
  "n ∈ par ⟹ even n"
  apply (induction rule: par.induct)
     (* 1. even 0
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)
   apply (simp only: dvd_def)
     (* 1. ∃k. 0 = 2 * k
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)
   apply (rule_tac x=0 in exI)
     (* 1. 0 = 2 * 0
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)
   apply simp
     (* ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)
  apply (simp only: dvd_def)
     (* ⋀n. ⟦n ∈ par; ∃k. n = 2 * k⟧ ⟹ ∃k. Suc (Suc n) = 2 * k *)
  apply (erule exE)
     (* ⋀n k. ⟦n ∈ par; n = 2 * k⟧ ⟹ ∃k. Suc (Suc n) = 2 * k*)
  apply (rule_tac x="k+1" in exI)
     (* ⋀n k. ⟦n ∈ par; n = 2 * k⟧ ⟹ Suc (Suc n) = 2 * (k + 1) *)
  apply simp
     (* *)
  done

  demostración aplicativa
lemma par_imp_even_2: 
  "n ∈ par ⟹ even n"
  apply (induction rule: par.induct)
     (* 1. even 0
        2. ⋀n. ⟦n ∈ par; even n⟧ ⟹ even (Suc (Suc n)) *)
   apply simp_all
     (* *)
  done

 Demostración automática
lemma par_imp_even_3: 
  "n ∈ par ⟹ even n"
  by (induction rule: par.induct) simp_all

 Demostración declarativa
lemma par_imp_even_4: 
  "n ∈ par ⟹ even n"
proof (induction rule: par.induct)
  show "even 0" 
    by simp
next
  fix n :: nat
  assume H1: "n ∈ par" and
         H2: "even n"
  have "∃k. n = 2*k" 
    using H2 by (simp add: dvd_def)
  then obtain k where "n = 2*k" 
    by (rule exE)
  then have "Suc (Suc n) = 2*(k+1)" 
    by simp
  then have "∃k. Suc (Suc n) = 2*k" 
    by (rule exI)
  then show "even (Suc (Suc n))" 
    by (simp add: dvd_def)
qed

  demostración declarativa
lemma par_imp_even_5: 
  "n ∈ par ⟹ even n"
proof (induction rule: par.induct)
  show "even 0" by simp
next
  fix n::nat
  assume H1: "n ∈ par" and
         H2: "even n"
  then show "even (Suc (Suc n))" 
    by simp
qed

text Lema: Un número n es par syss es divisible por 2.

theorem par_iff_even: "(n ∈ par) = (even n)" 
  using even_imp_par par_imp_even_5 by blast

subsection Generalización y regla de inducción

text 
  · Antes de aplicar inducción se debe de generalizar la fórmula a
    probar.
 
  · Vamos a ilustrar el principio anterior en el caso de los conjuntos
    inductivamente definidos, con el siguiente ejemplo: si n+2 es par,
    entonces n también lo es.

  · El siguiente intento falla:


lemma "Suc (Suc n) ∈ par ⟹ n ∈ par"
  apply (erule par.induct) 
    (* 1. n ∈ par
       2. ⋀na. ⟦na ∈ par; n ∈ par⟧ ⟹ n ∈ par *)
oops

text 
  En el intento anterior, los subobjetivos generados son
     1. n  par
     2. na. na  par; n  par  n  par
  que no se pueden demostrar.

  Se ha perdido la información sobre Suc (Suc n).


text Reformulación del lema: Si n es par, entonces n-2 también lo es.

 La demostración aplicativa es
lemma par_imp_par_menos: 
  "n ∈ par ⟹ n - 2 ∈ par"
  apply (induction rule: par.induct) 
     (* 1. 0 - 2 ∈ par
        2. ⋀n. ⟦n ∈ par; n - 2 ∈ par⟧ ⟹ Suc (Suc n) - 2 ∈ par *)
   apply auto
     (* *)
  done

 La demostración automática es
lemma par_imp_par_menos_2: 
  "n ∈ par ⟹ n - 2 ∈ par"
  by (induction rule: par.induct) auto

 La demostración estructurada es
lemma "n ∈  par ⟹ n - 2 ∈ par"
proof (induction rule: par.induct)
  show "0 - 2 ∈ par" 
    by auto
next
  show "⋀n. ⟦n ∈ par; n - 2 ∈ par⟧ ⟹ Suc (Suc n) - 2 ∈ par" 
    by auto
qed

text Con el lema anterior se puede demostrar el original.

 La demostración aplicativa es
lemma 
  "Suc (Suc n) ∈ par ⟹ n ∈ par"
  apply (drule par_imp_par_menos_2)
    (* Suc (Suc n) - 2 ∈ par ⟹ n ∈ par *)
  apply simp
    (* *)
  done

 La demostración automática es
lemma Suc_Suc_par_imp_par: 
  "Suc (Suc n) ∈ par ⟹ n ∈ par" 
  by (drule par_imp_par_menos_2, simp)

 La demostración declarativa es
lemma
  assumes "Suc (Suc n) ∈ par" 
  shows   "n ∈ par"
proof -
  have "Suc (Suc n) - 2 ∈ par" 
    using assms by (rule par_imp_par_menos_2)
  then show "n ∈ par" 
    by simp 
qed

text Lemma. Un número natural n es par syss n+2 es par.

lemma [iff]: "((Suc (Suc n)) ∈ par) = (n ∈ par)"
  using Suc_Suc_par_imp_par by blast

text Se usa el atributo "iff" porque sirve como regla de 
  simplificación.

subsection Definiciones mutuamente inductivas

text Definición cruzada de los conjuntos inductivos de los pares y de los 
  impares:

inductive_set
  Pares    :: "nat set" and
  Impares  :: "nat set"
where
  ceroP:    "0 ∈ Pares"
| ParesI:   "n ∈ Impares ⟹ Suc n ∈ Pares"
| ImparesI: "n ∈ Pares   ⟹ Suc n ∈ Impares"

text El esquema de inducción generado por la definición anterior es
  · Pares_Impares.induct:
    P1 0; 
     n. n  Impares; P2 n  P1 (Suc n);
     n. n  Pares;   P1 n  P2 (Suc n)
     (x1  Pares  P1 x1)  (x2  Impares  P2 x2)


thm Pares_Impares.induct

text Ejemplo de demostración usando el esquema anterior.

 Demostración aplicativa
lemma "(m ∈ Pares ⟶ even m) ∧ (n ∈ Impares ⟶ even (Suc n))"
  apply (induction rule: Pares_Impares.induct)
      (* 1. even 0
         2. ⋀n. ⟦n ∈ Impares; even (Suc n)⟧ ⟹ even (Suc n)
         3. ⋀n. ⟦n ∈ Pares; even n⟧ ⟹ even (Suc (Suc n))*)
    apply auto
      (* *)
  done

 Demostración automática
lemma "(m ∈ Pares ⟶ even m) ∧ (n ∈ Impares ⟶ even (Suc n))"
  by (induction rule: Pares_Impares.induct) auto

 La demostración declarativa es
lemma "(m ∈ Pares ⟶ even m) ∧ (n ∈ Impares ⟶ even (Suc n))"
proof (induction rule: Pares_Impares.induct)
  show "even (0::nat)" 
    by simp
next
  fix n :: "nat"
  assume H1: "n ∈ Impares" and
         H2: "even (Suc n)"
  show "even (Suc n)" 
    using H2 by simp
next
  fix n :: "nat"
  assume H1: "n ∈ Pares" and
         H2: "even n"
  have "∃k. n = 2*k" 
    using H2 by (simp add: dvd_def)
  then obtain k where "n = 2*k" 
    by (rule exE)
  then have "Suc (Suc n) = 2*(k+1)" 
    by auto
  then have "∃k. Suc (Suc n) = 2*k" 
    by (rule exI)
  then show "even (Suc (Suc n))" 
    by (simp add: dvd_def)
qed

subsection Definición inductiva de predicados

text Definición inductiva del predicado es_par tal que (es_par n) se
  verifica si n es par.

inductive es_par :: "nat ⇒ bool" where
  "es_par 0" 
| "es_par n ⟹ es_par (Suc (Suc n))"

text Heurística para elegir entre definir conjuntos o predicados:
  · si se va a combinar con operaciones conjuntistas, definir conjunto;
  · en caso contrario, definir predicado.

end